android 多用户笔记

本文详细介绍了Android系统中的多用户模式,包括其实现原理、关键API及数据隔离机制。此外,还介绍了如何通过不同方法访问多用户环境下的ContentProvider数据,并提供了系统设置Provider的多用户接口示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

多用户,即是为一部手机实现多个相互隔离的使用环境。利用多用户,既可以实现多个用户共享一部手机,例如:儿童模式等受限用户的应用;也可以为一个用户提供多种使用环境,例如为政企员工开发的工作模式。

在android里,有两种userId:一种是linux进程的userId、即linux操作系统的userId。android系统就是通过把每个应用分别指派为不同的linux user,来实现的app沙箱环境。

另一种userid才是本文所讨论的多用户的id,主用户的userId=0,开机自动运行并且不会关闭。其他user id从10开始,通过createUser创建。(希望不要混淆了两种userid)

三个getuserid的api:

UserHandle.myUserId()  //获取当前进程的userId

UserHandle.getUserId(Binder.getCallingUid()) //获取调用者进程的userId
ActivityManager.getCurrentUser() //获取运行在前台的userId,注意此方法需要申请跨用户权限

开启多用户,/frameworks/base/core/res/res/values/config.xml中,将属性<integer name="config_multiuserMaximumUsers">8</integer>设置成大于1的值,ams的一个工具类UserController中定义了static final int MAX_RUNNING_USERS = 3; 同时最多可以运行3个用户,当启动的用户超过3个时,android会基于最近最少使用缓存算法,来关闭多余的用户。主用户永远不会被关闭。

多用户的元数据:

/data/system/users/userlist.xml  是用户列表
/data/system/users/0.xml (10.xml) 等是每个用户的信息
/data/system/users/0(10等)目录,是系统相关的多用户数据,如系统设置等。
/data/user/0(10等)/app_dir/ 是app的数据
外部存储的挂在路径:/storage/emulator/0(10等)/ , 因为mount路径不同,所以不同用户的外部存储也是独立的。


如何访问其他用户的provider数据的三种方法:

1、改变uri:multiUser_uri = ContentProvider.maybeAddUserId(CONTENT_URI, user.id) //通过URI指定启动不同用户的provider进程,此api会将将uri改为(userid@uri),从而匹配指定用户下的provider进程。

2、启动调用者进程为指定用户的进程,然后用原uri即可访问指定用户下的provider数据

Context.startActivityAsUser(Intent, UserHandle) //启动指定用户的进程
Context.bindServiceAsUser(Intent, …, UserHandle) //启动指定用户的进程
Context.startServiceAsUser(Intent, …, UserHandle) //启动指定用户的进程

3、将provider设置为singleuser属性,这样该provider只有在主用户下存在一份数据。注意,该属性会使export属性失效。
android:SingleUser=true 设置此标记的provider,在多用户下只有一份存储数据。


数据的监控和通知:如果你想知道另一个用户的provider数据发生变化,那么必须调用以下接口对指定用户的数据进行监控,或者当数据发生变化时,通知的用户指定为UserHandle.ALL
    public final void registerContentObserver(Uri uri, … )
    public final void registerContentObserver(Uri uri, … , int userHandle)
系统settings provider多用户接口:
    Settings.Secure.getIntForUser(…);
    Settings.Secure.putIntForUser(…);

getContext().getContentResolver().notifyChange(MmsSms.CONTENT_URI, null, true, UserHandle.USER_ALL);

Context.sendBroadcastAsUser(Intent, … , UserHandle)
    Context.registerReceiverAsUser(mIntent, UserHandle.ALL, …)


跨用户访问需要的权限:
INTERACT_ACROSS_USERS (signature|system) 

INTERACT_ACROSS_USERS_FULL (signature)

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值