Управление пакетами приложений

Рейтинг: 75.8% · 12 голосов
Полный курс по Android Debug Bridge: установка, подключение, shell, логи, dumpsys, автоматизация, root, беспроводная отладка. Уроки по главам с обсуждением.
Ответить
Аватара пользователя
android_roman
Сообщения: 45
Зарегистрирован: 11 май 2026, 05:31

Управление пакетами приложений

Сообщение android_roman »

АкадемияADB: Android Debug BridgeГлава 7 из 29
Оглавление курса (29)
  1. Введение в Android Debug Bridge
  2. Установка и настройка рабочей среды
  3. Подключение устройства (проводное и беспроводное)
  4. Базовые команды ADB и управление сервером
  5. Команды состояния и перезагрузки
  6. Навигация по файловой системе
  7. Управление пакетами приложений (вы здесь)
  8. Логирование с помощью logcat
  9. Системные дампы и диагностика (dumpsys)
  10. Анализ производительности в реальном времени
  11. Эмуляция ввода (input)
  12. Управление Activity и Intent (am)
  13. Работа с оконным менеджером (wm)
  14. Захват экрана и запись видео
  15. Root-доступ и его применение
  16. Модификация системных настроек через settings
  17. Команды для поставщиков контента (content)
  18. Резервное копирование и восстановление (backup)
  19. Проброс портов и туннелирование
  20. Беспроводная отладка (Wi-Fi)
  21. Взаимодействие с эмуляторами
  22. Написание скриптов на Bash/CMD/PowerShell
  23. ADB в языках программирования
  24. Автоматизация тестирования с ADB
  25. Безопасность и лучшие практики
  26. ADB на Android TV, Wear OS и IoT
  27. Восстановление и низкоуровневые операции
  28. Расширенные возможности оболочки и инструменты
  29. Отладка самого ADB и устранение неполадок
В прошлой главе мы ходили по файловой системе, теперь займемся тем, ради чего ADB чаще всего и ставят: установка, удаление и инспекция приложений. Внутри Android за это отвечает сервис Package Manager, а у нас к нему два входа. Первый, команда adb install и ее родственники, работает с хост-машины и сама передает файл на устройство. Второй, утилита pm внутри adb shell, оперирует тем, что уже лежит на устройстве, и умеет заметно больше.

Установка APK, adb install:

Базовый сценарий: APK лежит на компьютере, ставим на подключенное устройство.

Код: Выделить всё

$ adb install app-release.apk
Performing Streamed Install
Success
Свежие platform-tools (35.x и новее) используют потоковую установку: файл уходит прямо в установщик, без промежуточного копирования в /data/local/tmp. На старых устройствах adb сам откатится на схему push плюс pm install.

Если пакет уже стоит, установка упадет:

Код: Выделить всё

adb: failed to install app-release.apk: Failure [INSTALL_FAILED_ALREADY_EXISTS: Attempt to re-install com.example.app without first uninstalling.]
Лечится опцией -r (reinstall), данные приложения при этом сохраняются:

Код: Выделить всё

adb install -r app-release.apk
Это самая ходовая опция, в скриптах сборки ее пишут не глядя.

Опция -d разрешает даунгрейд, то есть установку версии с меньшим versionCode поверх более новой. Без нее получите INSTALL_FAILED_VERSION_DOWNGRADE:

Код: Выделить всё

adb install -r -d app-1.0.apk
Нюанс, о который спотыкаются все: на обычных пользовательских (user) сборках Android даунгрейд разрешен только для приложений с флагом android:debuggable. На эмуляторах и userdebug-прошивках -d работает для любых пакетов. Поэтому ситуация "на эмуляторе откатывается, на моем Samsung нет" не баг, а политика системы. Обход без root один: снести пакет и поставить старую версию заново.

Опция -g сразу выдает приложению все runtime-разрешения, заявленные в манифесте (работает с Android 6.0). Незаменима в автотестах, не придется прокликивать диалоги:

Код: Выделить всё

adb install -r -g app-debug.apk
Опция -t разрешает ставить APK, собранные с флагом testOnly. Такие создает Android Studio при обычном Run. Если вытащить такой файл из build/outputs и поставить руками, будет отказ:

Код: Выделить всё

adb: failed to install app-debug.apk: Failure [INSTALL_FAILED_TEST_ONLY: installPackageLI]

Код: Выделить всё

adb install -t app-debug.apk
Опция --abi принудительно задает архитектуру, под которую ставится пакет. Пригодится, когда в APK лежат и 32-, и 64-битные нативные библиотеки, а проверить нужно именно 32-битную ветку:

Код: Выделить всё

adb install --abi armeabi-v7a app-release.apk
Допустимые значения: armeabi-v7a, arm64-v8a, x86_64. На чисто 64-битных устройствах (Pixel 7 и новее, многие флагманы 2023+) запрос armeabi-v7a завершится ошибкой INSTALL_FAILED_NO_MATCHING_ABIS.

Split APK и App Bundle:

Google Play давно раздает приложения в формате App Bundle, поэтому на устройстве приложение часто состоит из нескольких APK: базовый плюс сплиты под архитектуру, плотность экрана и язык. Один base.apk без сплитов не встанет, получите INSTALL_FAILED_MISSING_SPLIT. Для набора есть install-multiple:

Код: Выделить всё

$ adb install-multiple base.apk split_config.arm64_v8a.apk split_config.ru.apk split_config.xxhdpi.apk
Performing Streamed Install
Success
Все файлы должны принадлежать одному пакету и быть подписаны одним ключом. Опции -r, -d, -g, -t работают и здесь.

Не путайте с install-multi-package: эта команда ставит несколько независимых пакетов одной атомарной сессией, либо встанут все, либо ни один. Устройство должно быть на Android 10 или новее:

Код: Выделить всё

adb install-multi-package app.apk companion-watch.apk
Файл .aab напрямую через adb не ставится, это формат для магазина. Нужен bundletool:

Код: Выделить всё

java -jar bundletool.jar build-apks --bundle=app.aab --output=app.apks --connected-device
java -jar bundletool.jar install-apks --apks=app.apks
Удаление, adb uninstall:

Код: Выделить всё

$ adb uninstall com.example.app
Success
Ключ -k сохраняет данные и кэш приложения:

Код: Выделить всё

adb uninstall -k com.example.app
При повторной установке пакета с той же подписью приложение увидит старые данные. Подводный камень: убрать осиротевшие данные после -k без переустановки нельзя, придется поставить пакет обратно и удалить уже без -k, либо чистить /data руками с root (глава 15).

Отдельный прием против предустановленного хлама: pm uninstall с указанием пользователя удаляет приложение только для этого пользователя, системный раздел не трогает и root не требует:

Код: Выделить всё

$ adb shell pm uninstall --user 0 com.miui.analytics
Success
Вернуть обратно (Android 8.0+):

Код: Выделить всё

adb shell cmd package install-existing com.miui.analytics
Список пакетов, pm list packages:

Код: Выделить всё

$ adb shell pm list packages
package:com.android.settings
package:org.telegram.messenger
package:ru.vk.store
Фильтры сужают выборку: -3 только сторонние, -s только системные, -d отключенные, -e включенные, -u добавить удаленные с сохраненными данными. Опция -f показывает путь к APK, -i показывает установщика. Фильтры комбинируются, а в конце можно дописать подстроку для поиска по имени пакета.

Код: Выделить всё

$ adb shell pm list packages -3 yandex
package:ru.yandex.searchplugin
package:ru.yandex.taxi

Код: Выделить всё

$ adb shell pm list packages -f com.example.app
package:/data/app/~~7sKjf1Qw==/com.example.app-9hGt3A==/base.apk=com.example.app

Код: Выделить всё

$ adb shell pm list packages -i -3
package:org.telegram.messenger installer=com.android.vending
package:ru.yandex.searchplugin installer=ru.vk.store
package:com.example.app installer=null
installer=null означает установку через adb. Поле полезно при разборе багов "почему приложение не обновляется": ставилось из RuStore, а обновления ждут от Google Play.

pm path и dumpsys package:

Точные пути всех APK пакета выдает pm path:

Код: Выделить всё

$ adb shell pm path com.example.app
package:/data/app/~~7sKjf1Qw==/com.example.app-9hGt3A==/base.apk
package:/data/app/~~7sKjf1Qw==/com.example.app-9hGt3A==/split_config.arm64_v8a.apk
В связке с adb pull из главы 6 так вытаскивают APK с устройства, когда исходного файла нет под рукой.

Полное досье на пакет дает dumpsys package (подробнее о dumpsys в главе 9):

Код: Выделить всё

adb shell dumpsys package com.example.app
Вывод на сотни строк, ключевые поля такие:

Код: Выделить всё

    versionCode=1042 minSdk=26 targetSdk=35
    versionName=2.14.1
    firstInstallTime=2026-03-02 11:48:07
    lastUpdateTime=2026-06-09 09:15:33
    runtime permissions:
      android.permission.CAMERA: granted=true
      android.permission.POST_NOTIFICATIONS: granted=false
Чтобы не листать, фильтруйте:

Код: Выделить всё

adb shell "dumpsys package com.example.app | grep -E 'version|InstallTime|UpdateTime'"
Очистка данных, pm clear:

Код: Выделить всё

$ adb shell pm clear com.example.app
Success
Аналог кнопки "Очистить данные" в настройках: стираются базы, SharedPreferences, кэш и файлы во внутреннем хранилище, приложение возвращается к состоянию свежей установки. Заодно отзываются выданные runtime-разрешения, и это регулярно ломает автотесты: после pm clear выдавайте права заново через pm grant или ставьте пакет с -g. Для защищенных системных пакетов команда вернет Failed. На многопользовательских устройствах можно чистить адресно: pm clear --user 0 com.example.app.

Включение и отключение, pm enable и pm disable:

Полный pm disable из shell запрещен, это привилегия root:

Код: Выделить всё

$ adb shell pm disable com.android.chrome
Exception occurred while executing 'disable':
java.lang.SecurityException: Shell cannot change component state for com.android.chrome/null to 2
С root (adb root на userdebug или su на рутованном устройстве) команда проходит:

Код: Выделить всё

$ adb shell su -c "pm disable com.android.chrome"
Package com.android.chrome new state: disabled
Без root есть pm disable-user, он помечает пакет отключенным для конкретного пользователя:

Код: Выделить всё

$ adb shell pm disable-user --user 0 com.android.chrome
Package com.android.chrome new state: disabled-user
Приложение пропадает из лаунчера и не запускается, но остается на диске. Проверить список отключенных: pm list packages -d. Вернуть к жизни:

Код: Выделить всё

$ adb shell pm enable --user 0 com.android.chrome
Package com.android.chrome new state: enabled
Критичные пакеты вроде com.android.settings защищены, на них даже disable-user ответит ошибкой Cannot disable a protected package.

Разрешения, pm grant и pm revoke:

Команды работают только с runtime-разрешениями (protection level dangerous) и только если разрешение объявлено в манифесте приложения. Успех молчаливый, вывода нет:

Код: Выделить всё

adb shell pm grant com.example.app android.permission.CAMERA
adb shell pm revoke com.example.app android.permission.ACCESS_FINE_LOCATION
Две типовые ошибки. Первая, разрешения нет в манифесте:

Код: Выделить всё

$ adb shell pm grant com.example.app android.permission.READ_CONTACTS
Exception occurred while executing 'grant':
java.lang.SecurityException: Package com.example.app has not requested permission android.permission.READ_CONTACTS
Вторая, разрешение не runtime-типа. INTERNET выдается при установке навсегда, менять его нельзя:

Код: Выделить всё

$ adb shell pm grant com.example.app android.permission.INTERNET
Exception occurred while executing 'grant':
java.lang.SecurityException: Permission android.permission.INTERNET requested by com.example.app is not a changeable permission type
Текущее состояние смотрите в секции runtime permissions у dumpsys package. Спецразрешения вроде SYSTEM_ALERT_WINDOW или MANAGE_EXTERNAL_STORAGE через pm grant не выдаются, для них существует механизм appops, разберем его в главе 28.

Частые ошибки установки и что с ними делать:

INSTALL_FAILED_UPDATE_INCOMPATIBLE: подписи старой и новой версии не совпадают, классика при попытке накатить debug-сборку поверх релиза из маркета. Решение одно: удалить пакет и поставить заново, данные при этом теряются.

INSTALL_FAILED_INSUFFICIENT_STORAGE: кончилось место в /data. Проверьте adb shell df -h /data и почистите устройство.

INSTALL_FAILED_USER_RESTRICTED: фирменная боль владельцев Xiaomi и Poco. В настройках разработчика MIUI/HyperOS нужно отдельно включить "Установка через USB", иногда система требует войти в Mi-аккаунт и подождать.

INSTALL_PARSE_FAILED_NO_CERTIFICATES: APK не подписан или подпись повреждена. Релизные сборки подписывайте до установки.

Если adb install вообще молчит или ругается на device offline и unauthorized, это не про пакеты, вернитесь к главе 3 и проверьте подключение.

На этом с управлением пакетами все. Установленное приложение надо как-то запускать и дергать его экраны, этим займемся в главе 12 про am, а в следующей главе подключим logcat и посмотрим, что приложения пишут в лог.
👍7 ❤️2 🔥2 😄 🤔1
✔ Лучший ответ сформирован автоматически — mister37
android_roman писал(а):убрать осиротевшие данные после -k без переустановки нельзя вот это я узнал поздно. снес тестовое приложение с -k, потом сертификат подписи сменился, и все, обратно та же версия не встает (UPDATE_INCOMPATIBLE при установке поверх это понятно, но тут даже чистая установка видит старые данные с чужой подписью и отказывается). в итоге только через root вычистил /data/data. доб…
Перейти к ответу →
Аватара пользователя
mister37
Сообщения: 2
Зарегистрирован: 14 май 2026, 10:05

Re: Управление пакетами приложений

Сообщение mister37 »

✔ Лучший ответ — сформирован автоматически
android_roman писал(а):убрать осиротевшие данные после -k без переустановки нельзя
вот это я узнал поздно. снес тестовое приложение с -k, потом сертификат подписи сменился, и все, обратно та же версия не встает (UPDATE_INCOMPATIBLE при установке поверх это понятно, но тут даже чистая установка видит старые данные с чужой подписью и отказывается). в итоге только через root вычистил /data/data. добавьте кто-нибудь жирное предупреждение, что -k с истекающими debug-ключами это мина
👍 ❤️2 🔥 😄 🤔1
Аватара пользователя
oneandonly
Сообщения: 2
Зарегистрирован: 11 май 2026, 06:22

Re: Управление пакетами приложений

Сообщение oneandonly »

а если приложение скачано с apkmirror в формате .apkm или .xapk? подсказка для таких же как я: это обычный zip, распаковываете и скармливаете все apk внутри в adb install-multiple, встает нормально. единственное, сплиты под чужую архитектуру лучше не подсовывать, у меня с x86 сплитом ругнулось
👍2 ❤️1 🔥 😄 🤔
Аватара пользователя
PostgresLord
Сообщения: 2
Зарегистрирован: 11 май 2026, 04:17

Re: Управление пакетами приложений

Сообщение PostgresLord »

ставлю автотестовую сборку с -g на пикселе с андроидом 15, все разрешения выдались, а ACCESS_BACKGROUND_LOCATION все равно granted=false. это нормальное поведение или у меня руки? через pm grant отдельной командой выдается, но хотелось бы одной установкой
👍2 ❤️ 🔥2 😄 🤔
Аватара пользователя
grpc42
Сообщения: 1
Зарегистрирован: 24 май 2026, 08:56

Re: Управление пакетами приложений

Сообщение grpc42 »

по поводу борьбы с хламом, что лучше в итоге, pm uninstall --user 0 или pm disable-user? я правильно понял что после uninstall --user 0 настройки приложения теряются, а после disable-user остаются? на рабочем парке самсунгов хочу вырубить предустановленный фейсбук, но так чтобы откатывалось одной командой
👍 ❤️ 🔥 😄 🤔
Ответить
← Предыдущая глава
Навигация по файловой системе
Следующая глава →
Логирование с помощью logcat

Все главы курса «ADB: Android Debug Bridge»

Поделиться темой: ✈ Telegram VK

Вернуться в «ADB: Android Debug Bridge»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 1 гость