「应用分身」在 Android 系统层本质是一个 工作资料(Work Profile) ,对应的用户类型是 android.os.usertype.profile.MANAGED,由系统级应用通过 pm 命令或 UserManager 接口创建。本文从身份类型、创建、安装、卸载、启用/停止到 Root 解除限制,完整讲透。
用户类型的完整定义 Android 11 起,多用户被细分为多种「用户类型」,其中与分身相关的核心类型定义在 frameworks/base/core/java/android/os/UserManager.java:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 public static final String USER_TYPE_PROFILE_MANAGED = "android.os.usertype.profile.MANAGED" ;public static final String USER_TYPE_PROFILE_CLONE = "android.os.usertype.profile.CLONE" ;public static final String USER_TYPE_PROFILE_PRIVATE = "android.os.usertype.profile.PRIVATE" ; android.os.usertype.full.SYSTEM android.os.usertype.full.SECONDARY android.os.usertype.full.GUEST android.os.usertype.full.RESTRICTED
分身(MANAGED)与其它类型的区别
类型
用户类型字符串
创建者
用途
应用分身
profile.MANAGED
DPC / 系统 App
双开、工作资料、隔离应用
克隆分身
profile.CLONE
系统 App(Root)
跑同 App 第二个实例
次级用户
full.SECONDARY
设置/用户管理
独立桌面、独立账户
访客
full.GUEST
系统
临时共享设备
用 pm 命令创建应用分身 标准的多用户命令都能创建用户,但指定 --user-type 才能创建 MANAGED 类型的分身 :
1 2 3 4 5 6 7 8 # 创建名为「分身」的 MANAGED 类型用户(应用分身 / 工作资料) adb shell pm create-user --user-type android.os.usertype.profile.MANAGED 分身# 老版本写法(Android 9 及以下,默认就是 managed profile) adb shell pm create-user --profileOf 0 --managed 分身# 查看创建结果 adb shell pm list users
创建成功后输出用户 ID(通常是 10),后续安装、启停都靠它。
安装与卸载应用 分身用户里安装应用,指定 --user <ID>:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 # 只给分身用户安装(主用户不受影响) adb shell pm install-existing --user 10 包名# 从本地 APK 安装到分身 adb shell pm install --user 10 /sdcard/app.apk# 给分身用户卸载 adb shell pm uninstall --user 10 包名# 查看分身用户已安装的应用 adb shell pm list packages --user 10# 查看分身用户里某个应用的详细状态 adb shell pm dump 包名 --user 10
启用、停止与切换 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 # 启用分身用户(start,让后台服务可用) adb shell am start-user 10# 停止分身用户(stop,冻结后台与通知) adb shell am stop-user 10# 强制停止某个应用(只影响指定用户) adb shell am force-stop --user 10 包名# 用分身身份启动应用(多开的本质) adb shell am start --user 10 -n 包名/.MainActivity# 查看当前前台用户 adb shell am get-current-user# 删除分身用户(连带删除其全部数据) adb shell pm remove-user 10
Root:解除分身数量上限 MANAGED 类型每个主用户默认最多 1 个 (max-allowed-per-parent)。设备所有者或 Root 后可通过系统属性放宽:
1 2 3 4 5 6 7 8 9 10 11 # 解除「全量用户」上限(经典多用户) su -c "setprop fw.max_users 8"# 解除工作资料/分身 profile 数量上限 su -c "setprop persist.sys.max_profiles 8"# 显示多用户入口 su -c "setprop fw.show_multiuserui 1"# 验证 adb shell pm get-max-users
说明:persist.sys.max_profiles 是不少 ROM 用于放宽 profile 数量的属性;AOSP 里真正限制在 UserTypeDetails.maxAllowedPerParent,对应资源 config_user_types.xml。Root 后也可直接修改该配置并重启,或 settings put secure 相关项。
用 AIDL 接口创建分身 应用分身由系统 IUserManager 服务创建,核心 AIDL 方法是 createProfileForUserWithThrow:
1 2 3 4 5 6 7 UserInfo createProfileForUserWithThrow ( in String name, in String userType, int flags, int userId, in String[] disallowedPackages) ;
调用示例(系统签名 App / Root):
1 2 3 4 5 6 UserInfo info = userManager.createProfileForUser( "分身" , UserManager.USER_TYPE_PROFILE_MANAGED, 0 , UserHandle.USER_SYSTEM);int uid = info.id;
创建后标记「已完成设置」,分身应用才会出现在最近任务 里:
1 2 3 4 5 String cmdstr = String.format( "settings --user %d put secure user_setup_complete 1;" + "settings --user %d put global device_provisioned 1" , uid, uid); Runtime.getRuntime().exec(new String []{"sh" , "-c" , cmdstr});
分身的文件与数据隔离 分身用户拥有独立的存储空间:
1 2 3 4 5 # 主用户(系统用户)的数据 /data/user/0/包名/# 分身用户(MANAGED,用户 10)的数据 /data/user/10/包名/
工作资料与主资料严格隔离 ,主用户里的照片、视频、文件,分身应用无法直接读取 ,只能通过「分享 / 跨资料 Intent」传递:
1 2 3 4 5 6 Intent share = new Intent (Intent.ACTION_SEND); share.putExtra(Intent.EXTRA_STREAM, FileProvider.getUriForFile(context, "authority" , file)); share.setType("image/*" ); share.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); startActivity(share);
注意事项
MANAGED 分身默认受 DPC 管理,部分限制(如禁用相机)由策略控制。
删除分身会清空其全部数据,操作前务必备份。
系统应用通常不允许在分身中运行。
理解了 MANAGED 类型与 pm/am 命令,你就掌握了「应用分身」的全部底层原理。下一篇我们讲 CLONE 类型的「克隆分身」,两者的文件访问权限有本质区别。