Разработка Android RecoverySystem.installPackage() не может запретить запись в/cache/recovery/command
Мне было предложено написать небольшое простое приложение для Android-продукта. Устройство оснащено двумя изображениями системы Android с различными функциями. Приложение, которое я пишу, является просто доказательством концепции, когда при нажатии на кнопку он использует систему восстановления, чтобы заменить текущую ОС одним из изображений.
Устройство внедрено и приложение запускается как системное приложение.
Я использую
RecoverySystem.installPackage(context, packageFile);
(см. здесь для справки), чтобы заменить ОС одним из изображений. Это должно перезагрузить систему и инициализировать систему восстановления, чтобы установить изображение.
Проблема в том, что этот вызов завершился неудачно, потому что метод RecoverySystem.installPackage
не может получить доступ к файлу /cache/recovery/command. Я думаю, он пытается написать некоторые команды для восстановления системы, которые будут выполняться при перезагрузке, но не сработает. Вот исключение, которое я получаю:
02-27 16:44:39.463: E/BroadSign Resolution Switcher(4439): java.io.FileNotFoundException: /cache/recovery/command: open failed: EACCES (Permission denied)
02-27 16:44:39.463: E/BroadSign Resolution Switcher(4439): at libcore.io.IoBridge.open(IoBridge.java:416)
02-27 16:44:39.463: E/BroadSign Resolution Switcher(4439): at java.io.FileOutputStream.<init>(FileOutputStream.java:88)
02-27 16:44:39.463: E/BroadSign Resolution Switcher(4439): at java.io.FileOutputStream.<init>(FileOutputStream.java:73)
02-27 16:44:39.463: E/BroadSign Resolution Switcher(4439): at java.io.FileWriter.<init>(FileWriter.java:42)
02-27 16:44:39.463: E/BroadSign Resolution Switcher(4439): at android.os.RecoverySystem.bootCommand(RecoverySystem.java:381)
02-27 16:44:39.463: E/BroadSign Resolution Switcher(4439): at android.os.RecoverySystem.installPackage(RecoverySystem.java:330)
Итак, я предполагаю, что у меня нет надлежащего разрешения на доступ к этому файлу. Хотя вот разрешение, которое я установил в своем манифесте:
<uses-permission android:name="android.permission.REBOOT" />
<uses-permission android:name="android.permission.ACCESS_CACHE_FILESYSTEM" />
<uses-permission android:name="android.permission.DELETE_CACHE_FILES" />
Я знаю, что мне нужно разрешение REBOOT для RecoverySystem
. Однако я не знаю, актуальны ли два других. Я даже не знаю, нужно ли мне другое разрешение на создание/запись в файлы в разделе /cache.
Кто-нибудь знает, чего я могу потерять?
UPDATE:
Ну, похоже, я понял это. Разрешения были в конце концов. Все было правильно.
Когда я настраивал приложение как системное приложение, перемещая файл apk в /system/app, я еще не добавил все разрешения. Когда я запустил последний код на своем устройстве, он установил его в /data/app и узнал его как обновление для системного приложения. Из-за этого были распознаны только разрешения исходного системного приложения.
После того, как я снова настроил свой последний код для запуска из /system/app, он работал.
Теперь единственная проблема, с которой я сталкиваюсь, заключается в том, что при перезагрузке она не устанавливает изображение, и я получаю восклицательный знак с мертвым зеленым роботом. Я продолжу расследование.
Я надеюсь, что этот пост поможет кому-либо с той же проблемой. Я также буду рад ответить на любые вопросы.
Ответы
Ответ 1
До того, как мое приложение было установлено в /system/app, я стал ниже ошибки:
07-20 10:52:46.512 933-951/? W/RecoverySystem﹕ !!! REBOOTING TO INSTALL /storage/emulated/legacy/Download/Update.zip !!!
07-20 10:52:46.512 933-951/? W/System.err﹕ java.io.FileNotFoundException: /cache/recovery/command: open failed: EACCES (Permission denied)
07-20 10:52:46.512 933-951/? W/System.err﹕ at libcore.io.IoBridge.open(IoBridge.java:409)
07-20 10:52:46.512 933-951/? W/System.err﹕ at java.io.FileOutputStream.<init>(FileOutputStream.java:88)
07-20 10:52:46.512 933-951/? W/System.err﹕ at java.io.FileOutputStream.<init>(FileOutputStream.java:73)
07-20 10:52:46.512 933-951/? W/System.err﹕ at java.io.FileWriter.<init>(FileWriter.java:42)
07-20 10:52:46.512 933-951/? W/System.err﹕ at android.os.RecoverySystem.bootCommand(RecoverySystem.java:389)
07-20 10:52:46.522 933-951/? W/System.err﹕ at android.os.RecoverySystem.installPackage(RecoverySystem.java:337)
Я пробовал все разрешения, которые требовались, но я не мог продолжить.
Итак, с тех пор как я использовал API выше 4.2, я попытался разместить мое приложение в /system/priv-app
, и это сработало для меня.
Ответ 2
У меня проблема с вами при создании пользовательского приложения OtaUpdate в android 5.0.2, и я решил его. Я поделюсь с вами двумя шагами ниже:
- Добавить андроид: sharedUserId = "com.google.uid.shared" в AndroidManifest.xml
- Направьте свой apk в систему/приложение или систему/приватное приложение
Для android 4.1.2:
- Добавить android: sharedUserId = "android.uid.system" в AndroidManifest.xml
- Нажимаем apk на систему/приложение
Ответ 3
Для Android 5.1.0
Ответ 4
Я встретил ту же проблему в Android 8.
Если вы добавите android:sharedUserId="android.uid.system"
в AndroidManifest.xml
, он должен работать.
Ответ 5
Системные приложения (приложения с общим идентификатором пользователя, установленным на android.uid.system
) не могут устанавливать обновления системы на Android 5 и более поздних версиях - это запрещено политикой SELinux. Конкретно запись в /cache
запрещена для системных приложений.
Вам нужно будет удалить общий идентификатор пользователя. Вы все еще должны подписать приложение подписью платформы и убедиться, что у вас есть следующие разрешения:
-
android.permission.REBOOT
-
android.permission.ACCESS_CACHE_FILESYSTEM
- для записи в /cache
-
android.permission.RECOVERY
- требуется для API 21 для перезагрузки для восстановления
Это будет работать как на Kitkat, так и на Lollipop+.