Android权限延时动态声明机制和可行的解决方案
Android权限延时动态声明机制和可行的解决方案核心结论Android系统权限无法真正做到运行时动态声明但可以通过以下方案实现类似效果方案一动态功能模块官方推荐原理说明┌─────────────────────────────────────────────────────────┐│ Base APK (主应用) ││ ┌─────────────────────────────────────────────────┐ ││ │ AndroidManifest.xml │ ││ │ - INTERNET (基础权限) │ ││ │ - ACCESS_NETWORK_STATE │ ││ └─────────────────────────────────────────────────┘ │└─────────────────────────────────────────────────────────┘││ 运行时按需下载▼┌─────────────────────────────────────────────────────────┐│ Dynamic Feature APK (功能模块) ││ ┌─────────────────────────────────────────────────┐ ││ │ AndroidManifest.xml │ ││ │ - READ_PHONE_STATE (敏感权限) │ ││ │ - WRITE_EXTERNAL_STORAGE │ ││ │ - CAMERA │ ││ └─────────────────────────────────────────────────┘ ││ ││ 功能游戏下载、二维码扫描、文件存储等 │└─────────────────────────────────────────────────────────┘实现步骤1. 修改项目结构app/├── src/main/ # 主模块│ └── AndroidManifest.xml # 仅基础权限│dynamic_feature/ # 动态功能模块├── src/main/│ └── AndroidManifest.xml # 敏感权限在此声明└── build.gradle2. 主模块 build.gradle 配置// app/build.gradleandroid {// 启用动态功能模块支持dynamicFeatures [:dynamic_feature]}3. 动态功能模块 build.gradle// dynamic_feature/build.gradleplugins {id com.android.dynamic-feature}android {namespace com.jiyou.express.feature}dependencies {implementation project(:app)}4. 动态模块 AndroidManifest.xml!-- dynamic_feature/src/main/AndroidManifest.xml --manifest xmlns:androidhttp://schemas.android.com/apk/res/androidxmlns:disthttp://schemas.android.com/apk/distributionpackagecom.jiyou.express.feature!-- 模块专属权限安装此模块时才生效 --uses-permission android:nameandroid.permission.READ_PHONE_STATE /uses-permission android:nameandroid.permission.WRITE_EXTERNAL_STORAGE /uses-permission android:nameandroid.permission.CAMERA /uses-permission android:nameandroid.permission.REQUEST_INSTALL_PACKAGES /dist:moduledist:instantfalsedist:titlestring/title_featuredist:fusing dist:includetrue //dist:moduleapplicationactivity android:name.FeatureActivity //application/manifest5. 运行时动态加载模块public class FeatureManager {private SplitInstallManager installManager;public FeatureManager(Context context) {installManager SplitInstallManagerFactory.create(context);}/*** 按需加载功能模块同时加载模块中的权限*/public void loadFeatureModule(String moduleName, OnFeatureLoadedCallback callback) {// 检查模块是否已安装if (installManager.installedModules.contains(moduleName)) {callback.onLoaded(true);return;}// 创建安装请求SplitInstallRequest request SplitInstallRequest.newBuilder().addModule(moduleName).build();// 监听安装状态installManager.registerListener(state - {if (state.moduleNames().contains(moduleName)) {switch (state.status()) {case SplitInstallSessionStatus.DOWNLOADED:// 模块下载完成需要重启应用以激活权限callback.onNeedRestart();break;case SplitInstallSessionStatus.INSTALLED:// 模块安装完成权限已生效callback.onLoaded(true);break;case SplitInstallSessionStatus.FAILED:callback.onLoaded(false);break;}}});// 开始安装installManager.startInstall(request);}public interface OnFeatureLoadedCallback {void onLoaded(boolean success);void onNeedRestart();}}方案二插件化热加载原理示意宿主APK├── 权限仅 INTERNET, ACCESS_NETWORK_STATE├── 功能资讯浏览│└── 加载插件APK运行时 dex 加载├── 权限插件自己的 Manifest宿主运行时代理├── 功能游戏下载、扫码等└── 通过反射/代理方式调用宿主能力核心实现基于 RePlugin// 1. 宿主中加载插件RePlugin.startActivity(context,RePlugin.createIntent(plugin_game_download,com.jiyou.plugin.DownloadActivity));// 2. 插件独立打包拥有独立权限声明// 插件 Manifest 中的权限在插件运行时生效方案三On-Demand资源加载权限代理核心思路┌─────────────────────────────────────────┐│ 宿主应用极游快报 ││ - 声明INTERNET ││ - 代理服务提供文件存储、下载能力 │└─────────────────────────────────────────┘││ AIDL / ContentProvider 通信▼┌─────────────────────────────────────────┐│ 代理服务应用系统级/预装 ││ - 声明所有敏感权限 ││ - 功能文件存储、下载管理、设备信息 ││ - 用户授权后为宿主应用提供服务 │└─────────────────────────────────────────┘方案对比方案权限延时生效复杂度适用场景动态功能模块✅ 支持⭐⭐⭐Google官方方案适合大多数场景插件化框架✅ 支持⭐⭐⭐⭐⭐需要完全隔离大厂方案代理服务应用✅ 支持⭐⭐⭐⭐需要系统配合/预装多APK分包❌ 不支持⭐仅发布时区分非延时推荐采用Dynamic Feature Module方案
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2507477.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!