uni-app针对plus.runtime.install在安卓9.0+上无法执行的解决方案
uni-app针对plus.runtime.install在安卓9.0+上无法执行的解决方案
先确保你的IDE使用的是HBuilderX,老HBuilder用户请升级。
云打包配置
云打包时配置manifest.json
将targetSdkVersion
改为26或更高,最高建议28。
5+应用: 相关文档
uniapp: uniapp manifest配置
如果提交云端打包后调用plus.runtime.install
无法安装apk文件,请添加以下权限:
<uses-permission android:name="android.permission.INSTALL_PACKAGES"/>
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/>
如何添加权限?可参考。
TIPS
云打包配置修改完毕后。请重新提交云端打包。生成你的APK,该APK才有调用
plus.runtime.install
安装APK的能力。
离线打包配置
- 将
build.gradle
中的targetSdkVersion
调到26或者更高。 - 在
Androidmanifest.xml
添加provider节点,将里面的io.dcloud.HBuilder
改成自己应用的包名。
<provider
android:name="io.dcloud.common.util.DCloud_FileProvider"
android:authorities="XXXX.XXX.XX(当前的应用包名).dc.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/dcloud_file_provider" />
</provider>
- 在
Androidmanifest.xml
中添加权限。
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/>
注:最新版SDK已经将权限加入基础库里面使用时请下载最新版SDK
配置完权限请重新编译生成APK。该APK才有调用
plus.runtime.install
安装APK的能力。
针对uni-app
中plus.runtime.install
在安卓9.0(Pie)及以上版本无法执行的问题,这通常是由于Android系统对应用安装权限和方式做了更严格的限制。以下是一个解决方案的代码案例,展示了如何通过适配Android 9.0+的特定要求来解决安装问题。
解决方案概述
- 使用动态请求安装未知来源权限(针对Android 8.0及以上版本)。
- 使用
FileProvider
来处理文件URI(针对Android 7.0及以上版本,特别是针对内容URI的限制)。 - 调整APK安装逻辑以适应新的安装流程。
代码实现
1. 动态请求安装未知来源权限
在AndroidManifest.xml中声明权限请求代码(尽管这部分通常由uni-app框架处理,但了解背后的逻辑有助于调试):
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/>
在Java/Kotlin代码中动态请求权限(这部分通常需要在原生插件或自定义组件中实现):
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
Intent intent = new Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES_SETTINGS);
startActivityForResult(intent, REQUEST_CODE_INSTALL_PERMISSION);
}
2. 使用FileProvider
在AndroidManifest.xml
中配置FileProvider
:
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
</provider>
在res/xml/file_paths.xml
中定义文件路径:
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="my_images" path="." />
</paths>
3. 安装APK逻辑调整
在uni-app的JavaScript代码中,通过调用原生插件或使用plus.io
等API获取APK文件的URI,并使用Intent
进行安装:
// 假设已经获取到APK文件的本地路径
var apkPath = '_www/download/yourapp.apk';
// 在原生插件中处理FileProvider和Intent安装逻辑
plus.android.importClass('android.net.Uri');
plus.android.importClass('android.content.Intent');
plus.android.importClass('android.provider.DocumentsContract');
var fileUri = FileProvider.getUriForFile(main, 'your.package.name.fileprovider', new java.io.File(apkPath));
var intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(fileUri, 'application/vnd.android.package-archive');
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
main.startActivity(intent);
注意:上述JavaScript代码需要与原生Android代码结合使用,特别是FileProvider
和Intent
部分,通常需要在uni-app的原生插件或自定义组件中实现。此外,确保APK文件的路径和FileProvider
的配置正确无误。