Android 5.0/Lollipop: принудительное повторное сканирование/system/priv-app
В Android 4.x достаточно было добавить APK файл в /system/priv -app, и диспетчер пакетов узнал, что новый файл и (не) установил соответствующее приложение или службу.
С Android L, кажется, недостаточно просто поместить файл в этот каталог - требуется перезагрузка системы, чтобы заставить Android распознать это изменение.
Есть ли у кого-нибудь идея, как обойти это? Может быть, с любым setprop ctl.restart xxx
или путем убийства выделенного сервиса?
EDIT:
Вот несколько журналов из logcat:
1. Перенесите APK из/в систему/в систему /priv -app (= установка)
su
mount -o remount rw /system
cd /system/priv-app
mv ../AARSCService.apk . // move from /system to /system/priv-app
W/mv ( 3268): type=1400 audit(0.0:53): avc: denied { rename } for name="AARSCService.apk" dev="mmcblk0p22" ino=23041 scontext=u:r:init:s0 tcontext=u:object_r:system_file:s0 tclass=file
(но файл HAS был перемещен как текущая корневая реализация для Nexus 7 Android Android L P2 отключает SELinux для корневых команд!)
- > APK NOT загружен и не указан в списке приложений → НЕ как ожидается, APK будет автоматически установлен после установки в папку priv-app на Android 4.4.
2. Перезагрузите устройство, используя APK внутри /system/priv -app
reboot
I/PackageManager( 567): /system/priv-app/AARSCService.apk changed; collecting certs
- > APK IS загружен и указан в списке приложений → как ожидалось
3. Переместить APK из /system/priv -app в/system (= deinstallation)
su
mount -o remount rw /system
cd /system/priv-app
mv AARSCService.apk .. // move from /system/priv-app to /system
W/mv ( 3189): type=1400 audit(0.0:31): avc: denied { rename } for name="AARSCService.apk" dev="mmcblk0p22" ino=23041 scontext=u:r:init:s0 tcontext=u:object_r:system_file:s0 tclass=file
(но файл HAS был перемещен как текущая корневая реализация для Nexus 7 Android Android L P2 отключает SELinux для корневых команд!)
- > APK по-прежнему загружается и отображается внутри списка приложений, сервис внутри приложения по-прежнему может быть связан с другим приложением → НЕ, как ожидалось, APK будет автоматически удалена после удаления из папки priv-app на Android 4.4.
4. Перезагрузите устройство, имея APK NOT inside/system/priv-app
reboot
W/PackageManager( 570): System package eu.airaudio.aarscservice no longer exists; wiping its data
- > APK больше не загружается и больше не отображается в списке приложений → как ожидалось
ИЗМЕНИТЬ 2:
Там же поведение на некорректном эмуляторе Android L (21) - конечно, без предупреждения SELinux.
Но APK также просто (un-) установлен после перезагрузки (= kill zygote).
Ответы
Ответ 1
Сравнивая исходный код PackageManagerService
между KitKat и Lollipop, вы можете увидеть значительные изменения и некоторые, которые, очевидно, связаны с этим изменением.
PackageManagerService.java
на Lollipop
PackageManagerService.java
на KitKat
Самым значительным изменением темы вопроса является удаление всех ссылок на AppDirObserver
(вложенный класс PackageManagerService
), который был инициализирован для контроля всех каталогов (приложенное изображение показывает сравнение соответствующего кода, где он был использован. Правая сторона показывает код KitKat и слева показывает Lollipop)
![enter image description here]()
Все еще не найдено решение для этого, но может помочь кому-то понять это.
Ответ 2
Основываясь на ваших сообщениях logcat, похоже, что PackageManagerService
даже не видит изменения папки/файла.
Вот один из способов обойти/запустить повторное сканирование, смоделировать событие "завершенное загрузку" с действием трансляции:
adb shell am broadcast -a android.intent.action.BOOT_COMPLETED
Это должно вызвать повторное сканирование с помощью PackageManagerService
Ответ 3
pms сканирует /system/app(priv-app)
при запуске. так просто убить процесс systemserver
:)
он работает на моем эмуляторе Lollipop. просто займите немного времени, показывая "upgrade android, opt app..."
Ответ 4
- Push apk to/system/priv-app/
- Команда запуска: adb shell > su > am restart (с помощью этой команды вы не потеряете соединение adb)
- Дождитесь загрузки системы - установка script может подождать чистого вывода команды: "adb shell dumpsys phone"
Отрывок:
def am_restart(self):
"""Restarts am waits for complete Android boot."""
self._log.info('Restarting application manager!')
ret, out, err = self.shell('am restart', require_root=True)
if ret != 0:
self.log_failure('am restart', ret, out, err)
return False
on_main_screen = False
while not on_main_screen:
sleep(2)
ret, out, err = self.shell('dumpsys phone')
if ret != 0:
self.log_failure('dumpsys phone', ret, out, err)
return False
if not (out or err):
on_main_screen = True
self._log.info('Application manager successfully restarted!')
return True
Ответ 5
У меня была такая же проблема.
Оказывается, когда я вернул пакет обратно в приватное приложение, оно было скопировано с другим разрешением.
Разрешения всех пакетов в приватном приложении (и приложении):
rwx-r-x-r-x
Разрешение пакета, который я скопировал:
rwx--------
Простой chmod -R a+rw <path/to/package>
решил проблему
EDIT:
Удостоверьтесь, что ваша/система/не является readonly, выпуская mount -o remount,rw /system/