Подтвердить что ты не робот

Разработка 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, он работал.

Теперь единственная проблема, с которой я сталкиваюсь, заключается в том, что при перезагрузке она не устанавливает изображение, и я получаю восклицательный знак с мертвым зеленым роботом. Я продолжу расследование.

Я надеюсь, что этот пост поможет кому-либо с той же проблемой. Я также буду рад ответить на любые вопросы.

4b9b3361

Ответ 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

  • Добавить android:sharedUserId="android.uid.system" в AndroidManifest.xml
  • Нажмите apk на system/priv-app
  • а затем

    adb root
    adb shell setenforce 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+.