Dhizuku 设备所有者权限共享工具:架构原理、激活流程与 API 接入实践 移动开发【免费下载链接】DhizukuA tool that can share DeviceOwner permissions to other application.项目地址https://gitcode.com/gh_mirrors/dh/Dhizuku点击查看免费下载Dhizuku 是一款借鉴 Shizuku 设计思想的开源 Android 工具其核心能力是把系统的DeviceOwner设备所有者/ ProfileOwner资料所有者权限分享给其他应用让普通应用也能调用DevicePolicyManager中仅限设备所有者使用的 API。本文以 docs/README.md 为骨架结合仓库源码系统讲解 Dhizuku 的权限共享架构、激活流程、权限校验机制以及应用开发者如何通过 Dhizuku API 接入并获得设备所有者权限。一、Dhizuku 是什么从“单应用独占”到“多应用共享”在 Android 系统中DevicePolicyManager以下简称 DPM提供了一大批高级系统管理能力例如静默安装/卸载应用、管理账号、设置密码复杂度、授予运行时权限等。但按照系统设计只有被设置为Device Owner设备所有者或Profile Owner资料所有者的应用才能调用这些 API——这意味着这些能力默认被“独占”在单一系统级应用手中。Dhizuku 的定位见 docs/README.md正是打破这种独占参考 Shizuku 的设计思想将 DeviceOwner 权限分享给其余应用。它本身先成为设备所有者然后通过一套 Binder 服务与权限校验体系把 DPM 能力以受控的方式“借给”第三方应用使用。与之相对Shizuku 分享的是 ADBshell 权限能力而 Dhizuku 分享的是设备所有者这一层更深的系统权限两者互补但机制不同。支持版本根据 docs/README.md 的声明Dhizuku 支持Android 8.0API 26 Android 17API 36的系统版本覆盖了从 Oreo 到最新一代 Android 的绝大多数设备。这一点在源码中也有印证激活与权限相关代码同时兼容GET_SIGNING_CERTIFICATESAndroid P 及以上与旧版GET_SIGNATURES两套签名获取 API并对 Android 14UPSIDE_DOWN_CAKE前后setDeviceOwner/setProfileOwner方法签名差异做了分支处理见 ActivateViewModel.kt。二、核心架构权限如何从系统流转到第三方应用Dhizuku 的权限分享体系由四个核心组件协同完成它们在 AndroidManifest.xml 中均有注册组件类职责内容提供者MyDhizukuProvider对外暴露 Binder 服务入口其他应用通过 authority 连接并创建服务实例设备管理员接收器DhizukuDAReceiver接收设备所有者/资料所有者变更广播触发状态同步守护前台服务DaemonService常驻前台监听应用安装/卸载变化清理失效授权权限服务实现MyDhizukuService承载 DPM 代理调用并执行每次调用的权限校验2.1 服务入口ContentProvider 与 BinderMyDhizukuProvider.kt 继承自DhizukuProvider其onCreateService(client: IDhizukuClient)方法在第三方应用发起连接时创建MyDhizukuService实例并把设备管理员组件DhizukuState.admin一并传入。该 Provider 在 Manifest 中声明了两个 authorityprovider android:name.server.MyDhizukuProvider android:authorities${applicationId}.dhizuku_server.provider;${applicationId}.server.provider android:directBootAwaretrue android:enabledtrue android:exportedtrue intent-filter action android:name${applicationId}.server.provider / /intent-filter /providerdirectBootAwaretrue表示该组件在设备解锁前Direct Boot 模式也可访问配合设备所有者场景下锁屏前即需执行管理任务的需求。此外 Manifest 还声明了自定义权限${applicationId}.permission.APIprotectionLeveldangerous用于约束访问 API 的应用范围。2.2 状态中枢DhizukuState 与 DAReceiverDhizukuState.kt 是全局状态单例维护三个关键信息isDeviceOwner本应用是否为设备所有者isProfileOwner本应用是否为资料所有者isOwner isDeviceOwner || isProfileOwner任一所有者身份成立即视为“已激活”admin当前设备管理员组件ComponentName。DhizukuDAReceiver.kt 继承自DeviceAdminReceiver在收到DEVICE_ADMIN_ENABLED、DEVICE_OWNER_CHANGED、PROFILE_OWNER_CHANGED、PROFILE_PROVISIONING_COMPLETE等广播后转交DaemonReceiver调用DhizukuState.sync(context)刷新状态。状态同步时如果确认已成为所有者会自动执行两件事自动授予危险权限grantPermissions()扫描自身 Manifest 中声明的所有危险权限PROTECTION_DANGEROUS通过dpm.setPermissionGrantState(admin, admin.packageName, it, PERMISSION_GRANT_STATE_GRANTED)以设备所有者身份强制授予避免用户在激活后还需手动同意各类权限弹窗启动/停止守护服务autoDaemonService()在成为所有者时启动DaemonService含startForegroundService失去所有者身份时停止。DhizukuDAReceiver.onEnabled()还会根据isDeviceOwnerApp/isProfileOwnerApp的判断结果弹出对应文案的 Toast 提示用户当前以哪种所有者身份被授予权限见 DhizukuDAReceiver.kt。2.3 守护服务授权记录的“体检器”DaemonService.kt 是一个前台服务foregroundServiceTyperemoteMessaging通知渠道daemon_serviceID 1001除维持常驻外还承担授权数据治理职责启动时遍历数据库中全部授权记录删除所有未通过verify()校验的条目注册ACTION_PACKAGE_REMOVED、ACTION_PACKAGE_FULLY_REMOVED、ACTION_PACKAGE_CHANGED广播dataSchemepackage在应用被卸载、更换时按 UID 找到记录并重新校验校验失败即删除。verify()的校验逻辑与后续服务端权限校验保持一致要求allowApi true、blocked false且当前安装包的签名与库中记录的签名一致见 DaemonService.kt。这保证了一旦应用被卸载重装签名变化旧的授权不会残留避免权限被冒用。三、激活教程前置条件与两种激活路径[!IMPORTANT] 官方文档docs/README.md强烈建议在没有任何账户Accounts的设备上完成激活设置。如果设备已经登录过账号可能需要先移除这些账号再启用 Dhizuku设备上存在任何已配置账号时官方可能无法提供支持。之所以有这一限制是因为 Android 系统规定存在账号尤其是 Device Owner 相关账号时不允许设置设备所有者。这一约束同样体现在源码的失败分支中——通过 Shizuku 方式激活时如果setDeviceOwner返回失败会抛出异常提示 “Failed to set Device Owner. Please make sure there are no accounts on the device.”见 ActivateViewModel.kt。激活的核心路径有两条均由 ActivateViewModel.kt 实现3.1 路径一通过 Shizuku / Sui 激活这是日常使用最便捷的方式前提是设备已运行 ShizukuADB 授权或 SuiROOT 授权。激活流程如下collectData()扫描设备上所有声明了DeviceAdminReceiver.ACTION_DEVICE_ADMIN_ENABLED且非系统应用排除ApplicationInfo.FLAG_SYSTEM的设备管理员组件列出可激活目标用户选择目标后以设备所有者或资料所有者身份执行激活activateAsDeviceOwnerByShizuku()通过反射调用 DPM 隐藏方法先setActiveAdmin(who, true, userId)设置活动管理员再setDeviceOwner(who, ownerName, userId)设置设备所有者activateAsProfileOwnerByShizuku()对应setProfileOwner(...)设置资料所有者由于系统账号缓存刷新存在延迟激活前会delay(1500)等待 1.5 秒源码注释 “wait for the account cache be refreshed”调用成功后执行DhizukuState.sync(context)刷新状态并自动授予危险权限、启动守护服务。其中隐藏方法的调用通过requireBinderWrapperDevicePolicyManager()完成它反射取出DevicePolicyManager中的mService字段IDevicePolicyManagerBinder用ShizukuBinderWrapper包装后重新注入从而以 Shizuku 身份调用系统隐藏 API调用结束后再将原 Binder 还原见 ActivateViewModel.kt。在界面层ActivatePage.kt选择“资料所有者”模式时会弹出警示对话框profile_owner_warning提示用户 Profile Owner 与 Device Owner 的权限差异。3.2 路径二通过 Android 设备预配Provisioning激活对于未运行 Shizuku/Sui 的环境Dhizuku 还实现了 Android 官方的设备预配Device Provisioning流程对应 Manifest 中两个导出 ActivityProvisioningActivity.kt响应android.app.action.GET_PROVISIONING_MODE直接返回PROVISIONING_MODE_FULLY_MANAGED_DEVICE完全托管设备模式并setResult(RESULT_OK)即声明“本应用希望成为完全托管设备的所有者”FinalizeActivity.kt响应android.app.action.ADMIN_POLICY_COMPLIANCE作为预配完成后的收尾 Activity 直接返回成功。这两个 Activity 在 Manifest 中均声明了android:permissionandroid.permission.BIND_DEVICE_ADMIN确保只有系统预配流程才能拉起。使用这一路径时设备需处于未初始化或可通过adb shell dpm类命令触发预配的状态具体操作步骤官方在激活讨论帖中有详细图文指引。3.3 激活后的自动处理链无论走哪条路径激活成功后都会触发同一套状态机见 DhizukuState.ktisDeviceOwner/isProfileOwner 变为 true └─ grantPermissions()以所有者身份自动授予 Dhizuku 自身声明的全部危险权限 └─ autoDaemonService()启动 DaemonService 前台服务常驻 授权记录治理 └─ DhizukuDAReceiver.onEnabled()Toast 提示 已授予设备所有者/资料所有者权限四、权限校验机制第三方应用如何安全获得授权4.1 授权数据的持久化模型Dhizuku 使用 Room 数据库文件dhizuku.db存放于设备保护存储区createDeviceProtectedStorageContext()见 DhizukuRoom.kt维护授权记录实体 AppEntity.kt 的字段如下字段类型说明idLong主键自增uidInt被授权应用的 UID建有唯一索引signatureString被授权应用的签名 SHA-256十六进制大写默认空串allow_apiBoolean是否允许调用 Dhizuku APIblockedBoolean是否被拉黑默认 falsecreated_at/modified_atLong创建/修改时间戳其中uid与allow_api分别建有索引便于按 UID 查找和按授权状态筛选。数据库当前版本为 3并通过 Room 的AutoMigration(from1,to2)、AutoMigration(from2,to3)声明了自动迁移见 DhizukuRoom.kt。4.2 每次调用的四重校验第三方应用通过 Binder 调用 API 时服务端会执行MyDhizukuService.checkCallingPermission(func, callingUid, callingPid)进行鉴权见 MyDhizukuService.kt校验链依次为全局开关settingsRepo.isDhizukuEnabled必须为 true对应设置项dhizuku_enabled默认开启见 SettingsRepoImpl.kt存在授权记录按调用方 UID 查库findByUID(callingUid)必须命中启用且未拉黑entity.allowApi true且entity.blocked false白名单模式若settingsRepo.isWhitelistMode设置项whitelist_mode默认关闭为 true则仅允许allowApi的应用访问——即开启白名单后未被授权的应用一律拒绝签名一致性通过PackageManager读取调用方 UID 当前安装包的签名计算 SHA-256 后与库中记录的signature比对不一致则拒绝签名获取见 PackageInfoUtil.kt。这套机制意味着即使某个应用曾获得授权如果它被卸载后以不同签名重装、被用户拉黑、或全局开关被关闭都无法再调用 Dhizuku API——权限分享始终处于可审计、可撤销的状态。4.3 授权交互15 秒倒计时授权弹窗第三方应用首次调用Dhizuku.requestPermission()时会通过 Intentaction${applicationId}.action.request.permission见 AndroidManifest.xml拉起 RequestPermissionActivity.kt弹窗展示请求应用的图标、名称与说明文案内置15 秒倒计时AUTO_DENY_SECONDS 15配合环形饼图进度动画提示剩余时间超时未操作则自动拒绝timedOut后finish()用户点击“同意/拒绝”后结果写入 RoomappRepo.insert/update生成或更新AppEntity并通过IDhizukuRequestPermissionListener回调把PERMISSION_GRANTED/PERMISSION_DENIED返回给请求方若已开启白名单模式、全局开关关闭、或该应用已被拉黑则弹窗直接跳过并返回拒绝。4.4 应用管理授权、拉黑与回收应用管理界面由 AppManagementViewModel.kt 驱动它会列出所有声明了 Dhizuku API 权限DhizukuVariables.PERMISSION_API或已有授权记录的应用支持启用授权setEnabled(uid, true)写入/更新allowApi true拉黑setBlocked(uid, true)写入blocked true并强制allowApi false。当应用被取消授权或拉黑时AppRepoImpl.kt 的update()/delete()还会调用clearDelegatedScopes()若 Dhizuku 仍保有所有者身份则通过dpm.setDelegatedScopes(admin, packageName, emptyList())清空该应用此前被委托的设备管理作用域delegated scopes实现权限的彻底回收防止残留的委托权限被继续使用。五、开发者接入使用 Dhizuku API 获取设备所有者能力5.1 API 库与基础权限面向应用开发者的接入方式是官方提供的Dhizuku API库独立于本仓库的 AIDL/封装层本仓库的app模块即该 API 的主要消费方。接入步骤概述在应用 Manifest 中声明 Dhizuku 的 API 权限权限名形如com.rosan.dhizuku.permission.API由 Dhizuku 端定义protectionLeveldangerous见 AndroidManifest.xml初始化并请求授权Dhizuku.init()检查服务可用性Dhizuku.isPermissionGranted()检查是否已授权未授权时通过Dhizuku.requestPermission(listener)拉起授权弹窗——这一请求流程的封装见 DhizukuUtil.kt其中requireDhizukuPermissionGranted采用callbackFlow以挂起函数形式等待授权结果授权被拒或 Dhizuku 未激活时抛出DhizukuNotWorkException授权通过后即可调用DevicePolicyManager中设备所有者专属的 API。值得注意的是仓库在 ShizukuUtil.kt 中提供了平行的requireShizukuPermissionGranted说明Dhizuku 自身的激活能力同样依赖 Shizuku/Sui 权限——Dhizuku 与 Shizuku 是“依赖”而非“互斥”关系Shizuku 负责把 ADB/ROOT 能力带给 DhizukuDhizuku 再把它获得的 DeviceOwner 能力分享给普通应用。5.2 一个完整的调用链路示例以 Dhizuku 内部激活其他设备管理员组件为例ActivateViewModel.kt可以看到 API 的典型用法// 1. 确保 Dhizuku 已激活且已获得授权 requireDhizukuPermissionGranted { // 2. 通过 Dhizuku 包装 DevicePolicyManager 的 Binder requireBinderWrapperDevicePolicyManager(wrapper { Dhizuku.binderWrapper(it) }) { // 3. 以设备所有者身份执行 transferOwnership转移所有权 it.transferOwnership(Dhizuku.getOwnerComponent(), comp, null) } // 4. 刷新 Dhizuku 状态 DhizukuState.sync(context) }即第三方应用先向 Dhizuku 请求授权Dhizuku 服务端通过checkCallingPermission完成鉴权后把包装好的 DPM Binder 交给调用方调用方即可在其上执行原本只有设备所有者能做的操作。服务端鉴权与客户端调用之间的对应关系正是 MyDhizukuService.kt 中checkCallingPermission所承担的职责。5.3 版本与兼容性说明Dhizuku 自身声明支持 Android 8.0 17见 docs/README.md服务端通过getVersionName()暴露当前版本代码客户端可据此判断 API 兼容性见 MyDhizukuService.kt授权记录按 UID 签名双重绑定应用签名变更后需重新授权。六、翻译、捐赠与开源协议翻译Dhizuku 的界面字符串支持数十种语言仓库中每个语言目录对应一份strings.xml如 values-zh-rCN/strings.xml、values-ja/strings.xml 等社区可通过 Weblate 平台参与翻译与纠错官方介绍见 docs/README.md捐赠项目支持社区捐赠相关说明见 docs/DONATE.md 及简体中文版 docs/DONATE_zh_Hans.md开源协议Dhizuku 基于GNU General Public License v3GPL-3开源并承诺未来持续以该协议开放许可证全文见仓库根目录 LICENSE配套文档使用条款见 docs/TERMS.md隐私政策见 docs/PRIVACY.md。七、总结Dhizuku 通过“自己成为设备所有者 Binder 服务共享 签名/白名单双重鉴权 数据库授权治理”这一完整闭环把 Android 系统中最深层的一类权限DeviceOwner/ProfileOwner安全地下放给普通应用。其核心设计要点可归纳为共享而非劫持权限始终掌握在 Dhizuku 手中第三方应用每次调用都经过checkCallingPermission鉴权可治理可撤销授权记录持久化于 Room 数据库支持白名单模式、拉黑、签名变更自动失效、以及setDelegatedScopes作用域回收激活路径多样既可通过 Shizuku/Sui 便捷激活也实现了 Android 官方设备预配流程Provisioning并针对 Android 各版本隐藏 API 差异做了兼容处理对开发者友好通过 Dhizuku API普通应用即可获得静默安装、账号管理等设备所有者能力无需 ROOT 或刷机。对于想要在自己的应用中获得系统级管理能力的开发者Dhizuku 提供了一个经过实践检验、权限边界清晰的参考范式以本仓库的 server 目录为服务端参考以 data 目录的授权与设置模型为权限治理参考即可完整理解并复用这套“设备所有者权限共享”方案。赞分享移动开发【免费下载链接】DhizukuA tool that can share DeviceOwner permissions to other application.项目地址https://gitcode.com/gh_mirrors/dh/Dhizuku点击查看免费下载相关推荐Dhizuku Android 设备权限管理工具使用教程Dhizuku Android 设备权限管理工具使用教程 项目介绍 Dhizuku 是一个基于 Shizuku 设计思想的 Android 应用程序专门用于分移动开发Shevery的免电脑魔法Dhizuku设备所有者自动启动原理与配置Shevery的免电脑魔法Dhizuku设备所有者自动启动原理与配置 如果你不想每次启动 Shevery 都掏出一台电脑连数据线那么 Dhizuku 设备所Elsa 3 工作流连接共享授权将连接共享决策与授权管理分离的设计与实践Elsa 3 工作流连接共享授权将连接共享决策与授权管理分离的设计与实践 导读 本文基于 Elsa 3 工作流引擎仓库中的架构决策记录 doc/adr/202后端工作流自动化流程编排低代码上一篇Blue Laser Clean Glass Layout 技能演示指南用 PROMPT 驱动的暗色玻璃仪表盘布局复刻实战下一篇OpenUI 生成式 UI 标准框架OpenUI Lang、组件库驱动提示词与流式渲染实战指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考