Sous Android 4.x, il suffisait de mettre un fichier APK dans/system/priv-app, et le gestionnaire de paquets a reconnu ce nouveau fichier et a (dés) installé l'application ou le service correspondant.
Depuis Android L, il ne semble pas suffisant de simplement placer le fichier dans ce répertoire - un redémarrage du système est nécessaire pour forcer Android à reconnaître ce changement.
Quelqu'un a-t-il une idée pour contourner cela? Peut-être avec un setprop ctl.restart xxx
ou en tuant un service dédié?
MODIFIER:
Voici quelques journaux de logcat:
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
(mais le fichier a été déplacé car l'implémentation racine actuelle de Nexus 7 Android Android L P2 désactive SELinux pour les commandes root!)
-> APK NON chargé et non répertorié dans app-list -> PAS comme prévu, APK va s'installer automatiquement une fois placé dans le dossier priv-app sur Android 4.4.
reboot
I/PackageManager( 567): /system/priv-app/AARSCService.apk changed; collecting certs
-> APK IS chargé et répertorié dans app-list -> comme prévu
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
(mais le fichier a été déplacé car l'implémentation racine actuelle de Nexus 7 Android Android L P2 désactive SELinux pour les commandes root!)
-> APK toujours chargé et répertorié dans app-list, le service dans l'application peut toujours être lié à partir d'une autre application -> PAS comme prévu, l'APK sera automatiquement désinstallé une fois supprimé du dossier priv-app sur Android 4.4.
reboot
W/PackageManager( 570): System package eu.airaudio.aarscservice no longer exists; wiping its data
-> APK n'est plus chargé, ni listé dans app-list -> comme prévu
EDIT 2:
Il existe le même comportement sur l'émulateur Android L (21) non root - bien sûr, sans l'avertissement SELinux . Mais l'APK est également juste (dés) installé après le redémarrage (= kill zygote).
En comparant le code source de PackageManagerService
entre KitKat et Lollipop, vous pouvez constater des changements importants, et certains sont évidemment liés à ce changement.
PackageManagerService.Java
sur Lollipop
PackageManagerService.Java
sur KitKat
Le changement le plus important apporté au sujet de la question est la suppression de toutes les références à AppDirObserver
(une classe imbriquée de PackageManagerService
) initialisée pour surveiller tous les répertoires (l'image jointe montre une comparaison du code pertinent où elle a été utilisée. KitKat, à droite le code et à gauche montre Lollipop)
Je n'ai toujours pas trouvé de solution à ce problème, mais cela pourrait aider quelqu'un à le comprendre.
Selon vos messages logcat, il semble que la variable PackageManagerService
ne voit même pas les modifications apportées au dossier/fichier.
Voici un moyen de contourner/déclencher une nouvelle analyse, de simuler un événement "démarrage terminé" avec une action de diffusion:
adb Shell am broadcast -a Android.intent.action.BOOT_COMPLETED
Cela devrait déclencher une nouvelle analyse par la variable PackageManagerService
pms analysera /system/app(priv-app)
au démarrage. il suffit donc de tuer le processus systemserver
:) cela fonctionne sur mon émulateur Lollipop. prenez juste un peu de temps pour montrer "mettre à niveau Android, opt app app ..."
Fragment:
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
J'ai eu exactement le même problème… .. Il se trouve que lorsque j'ai copié le paquet sur priv-app, il a été copié avec une permission différente
Autorisations de tous les paquets dans priv-app (et app):
rwx-r-x-r-x
Permission du paquet que j'ai recopié:
rwx--------
Un simple chmod -R a+rw <path/to/package>
a résolu le problème
EDIT: Assurez-vous que votre/système/n’est pas en lecture seule en émettant mount -o remount,rw /system/