背景
到目前为止,我可以通过以下代码使用 root(在应用程序内)安装 APK 文件:
pm install -t -f fullPathToApkFile
如果我想(尝试)安装到 sd-card :
pm install -t -s fullPathToApkFile
问题
最近,不确定来自哪个 Android 版本(至少在 Android P beta 上存在问题),上述方法失败,向我显示此消息:
avc: denied { read } for scontext=u:r:system_server:s0 tcontext=u:object_r:sdcardfs:s0 tclass=file permissive=0
System server has no access to read file context u:object_r:sdcardfs:s0 (from path /storage/emulated/0/Download/FDroid.apk, context u:r:system_server:s0)
Error: Unable to open file: /storage/emulated/0/Download/FDroid.apk
Consider using a file under /data/local/tmp/
Error: Can't open file: /storage/emulated/0/Download/FDroid.apk
Exception occurred while executing:
java.lang.IllegalArgumentException: Error: Can't open file: /storage/emulated/0/Download/FDroid.apk
at com.android.server.pm.PackageManagerShellCommand.setParamsSize(PackageManagerShellCommand.java:306)
at com.android.server.pm.PackageManagerShellCommand.runInstall(PackageManagerShellCommand.java:884)
at com.android.server.pm.PackageManagerShellCommand.onCommand(PackageManagerShellCommand.java:138)
at android.os.ShellCommand.exec(ShellCommand.java:103)
at com.android.server.pm.PackageManagerService.onShellCommand(PackageManagerService.java:21125)
at android.os.Binder.shellCommand(Binder.java:634)
at android.os.Binder.onTransact(Binder.java:532)
at android.content.pm.IPackageManager$Stub.onTransact(IPackageManager.java:2806)
at com.android.server.pm.PackageManagerService.onTransact(PackageManagerService.java:3841)
at android.os.Binder.execTransact(Binder.java:731)
这似乎也影响了流行的应用程序,例如无法恢复应用程序的“钛备份(专业版)”。
我试过的
查看所写的内容,它似乎没有安装 APK 文件的权限,而/data/local/tmp/
.
所以我尝试了接下来的事情,看看我是否能克服它:
- 设置对文件的访问权限 (
chmod 777
) - 没有帮助。 - 授予我的应用程序存储和REQUEST_INSTALL_PACKAGES的权限(使用ACTION_MANAGE_UNKNOWN_APP_SOURCES Intent) - 没有帮助。
/data/local/tmp/
使用官方 API创建文件的符号链接,使其位于.Os.symlink(fullPathToApkFile, symLinkFilePath)
这没有做任何事情。
使用此创建符号链接:
ln -sf $fullPathToApkFile $symLinkFilePath
这部分奏效了。该文件在那里,我可以在 Total Commander 应用程序中看到它,但是当我尝试检查它是否存在时,并且当我尝试从那里安装 APK 时,它失败了。
将文件复制/移动(使用
cp
或mv
)到/data/local/tmp/
路径,然后从那里安装。这行得通,但它有缺点:移动是有风险的,因为它会暂时隐藏原始文件,并且会更改原始文件的时间戳。复制是不好的,因为它使用额外的空间来安装(即使是临时的),而且这样做会浪费时间。使用以下命令(取自此处)复制 APK 文件,告诉它避免实际复制(意味着硬链接):
cp -p -r -l $fullPathToApkFile $tempFileParentPath"
这没有用。它给了我这个错误:
cp: /data/local/tmp/test.apk: Cross-device link
检查在安装应用程序的其他情况下会发生什么。当您通过 IDE 安装时,它实际上会在此特殊路径中创建 APK 文件,但如果您通过 Play Store、简单 APK 安装(通过 Intent)或 adb(通过 PC)安装,则不会。
问题
有没有办法克服在这个特殊路径上使用 root 安装 APK 的缺点?甚至可能完全避免处理这条路径?
为什么操作系统突然需要使用此路径?为什么不使用原始路径,就像安装应用程序的其他方法一样?安装应用程序的其他方法有什么作用,以某种方式避免使用空间路径?