我被要求为基于Android的产品编写一个简单的小应用程序。该设备附带两个具有不同功能的Android系统映像。我正在编写的应用程序只是一个概念验证,当您单击按钮时,它使用恢复系统将当前操作系统替换为其中一个图像。
设备已植根,应用程序作为系统应用程序运行。
我用
RecoverySystem.installPackage(context, packageFile);
(see here for reference)用其中一个图像替换操作系统。这应该重新启动系统并初始化恢复系统以安装映像。
我遇到的问题是此调用失败,因为RecoverySystem.installPackage
方法似乎无法访问/ cache / recovery /命令文件。我想它试图为恢复系统编写一些命令,以便在重启时执行,但是失败了。这是我得到的例外:
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" />
我知道我需要RecoverySystem
的REBOOT权限。但是,我不知道其他两个是否相关。我甚至不知道是否需要一些其他权限来创建/写入/ cache分区中的文件。
有人知道我可能遗失的东西吗?
更新
好吧,看起来我想通了。权限毕竟是正确的。一切都是对的。
当我通过将apk文件移动到/ system / app将我的应用程序设置为系统应用程序时,我还没有放入所有权限。当我在设备上运行最新代码时,它将其安装在/ data / app中,并将其识别为系统应用程序的更新。因此,只识别原始系统应用程序的权限。
在我重新设置我的最新代码后直接从/ system / app运行后,它就可以了。
现在唯一的问题是,当它重新启动时,它不会安装图像,我最终会得到一个带有感叹号的死绿色机器人。我会继续调查。
我希望这篇文章可以帮助任何有同样问题的人。我也很乐意回答任何问题。
答案 0 :(得分:2)
在我的应用程序安装在/ 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)
我已经尝试了所有必需的权限,但我无法继续。
因此,当我使用4.2以上的API时,我尝试将我的应用放入/system/priv-app
,这对我有用。
答案 1 :(得分:0)
在 android 5.0.2 中创建自定义OtaUpdate应用程序时,我遇到了同样的问题,我已经解决了。我将与您分享以下两个步骤:
对于 android 4.1.2 :
答案 2 :(得分:0)
适用于Android 5.1.0
android:sharedUserId="android.uid.system"
system/priv-app
然后
adb root
adb shell setenforce 0
答案 3 :(得分:0)
我在android 8中遇到了同样的问题。
如果您在android:sharedUserId="android.uid.system"
中添加AndroidManifest.xml
,
它应该工作。
答案 4 :(得分:0)
系统应用程序(共享用户ID设置为android.uid.system
的应用程序)无法在Android 5及更高版本上安装系统更新-SELinux策略禁止这样做。具体来说,系统应用程序禁止写入/cache
。换句话说:
/cache
由system
用户拥有,因此您在system
UID下运行的应用可以对其进行写入。 但仅当SELinux被禁用/允许时。 android.permission.ACCESS_CACHE_FILESYSTEM
平台签名权限,则可以写入/cache
。您需要删除共享的用户ID。您仍然必须使用平台签名对应用程序进行签名,并确保您具有以下权限:
android.permission.REBOOT
android.permission.ACCESS_CACHE_FILESYSTEM
-写入/cache
android.permission.RECOVERY
-API 21要求重新启动才能恢复这将适用于Kitkat和Lollipop +。