Android N下多用户数据切换的注意事项

来源:互联网 发布:淘宝电器节 编辑:程序博客网 时间:2024/06/05 16:47

By Jing.chen

在多用户系统里,切换用户后需要重新获取数据、监听数据以保证不同的用户数据不同。比如在systemui里,导航栏按键的组合方式,在机主(Host)模式下设置back键在后,在访客(Guest)模式下back键在前,切换不同的用户应该显示正确的组合方式,本文介绍从SettingsProvider和contentProvider获取多用户数据。

一、从SettingsProvider获取多用户数据

1.    获取UserID

mCurrentUserId =ActivityManager.getCurrentUser();//只有系统应用才能获取到

2.    根据UserID去获取数据:

systemui是通过ContentObserver去监听导航栏组合方式变化的,导航栏组合方式的值是存在SettingsProvider里的,

private class NaviBarControlsModeObserverextends ContentObserver
{

    public NaviBarControlsModeObserver(Handlerhandler)
    {
        super(handler);
    }

    @Override
   
public void onChange(booleanselfChange){
        // TODO Auto-generated method stub
       
super.onChange(selfChange);

              //根据UserId去获取值,getIntForUser方法是hideapi
       intnaviBarType = Settings.Secure.getIntForUser(mContext.getContentResolver(),
               NavigationBarInflaterView.NAVIGATION_BAR_CONTROLS_MODE,
               NavigationBarInflaterView.NAVIGATION_BAR_LEFT_BACK_MODE,mCurrentUserId);
       
LogUtils.d(TAG,"------------NaviBarControlsModeObserver,naviBarType:"+naviBarType);

        if (mNavigationBarView!= null) {
            mNavigationBarView.setNavigationBarControlsMode(mCurrentUserId,false);
        }
    }

}

 

3.     ContentObserver的注册监听,需要根据UserID去注册:

private NaviBarControlsModeObservermNaviBarControlsModeObserver =null;

mNaviBarControlsModeObserver= new NaviBarControlsModeObserver(newHandler());

//根据UserId去注册ContentObserver

mContext.getContentResolver().registerContentObserver(
        Settings.Secure.getUriFor(NavigationBarInflaterView.NAVIGATION_BAR_CONTROLS_MODE),true,
        mNaviBarControlsModeObserver,mCurrentUserId);

 

4.    监听用户切换

当切换用户后,需要重新对ContentObserver进行监听注册,因切换用户后ContentObserver并没有接收到变化通知,所以还需要主动去重新获取当前用户的导航栏组合方式,systemui是通过监听Intent.ACTION_USER_SWITCHED广播从而知道用户变化,接收到用户变化后重新注册监听、获取数据。

private final BroadcastReceivermBroadcastReceiver = new BroadcastReceiver(){
    @Override
   
public void onReceive(Contextcontext, Intent intent) {
        String action =intent.getAction();
        if (Intent.ACTION_USER_SWITCHED.equals(action)){

                     //获取当前UserId
            mCurrentUserId =intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
            updateCurrentProfilesCache();

           updateLockscreenNotificationSetting();

            userSwitched(mCurrentUserId);
        }

       }

}

 

public void userSwitched(intnewUserId) {

…..

mContext.getContentResolver().unregisterContentObserver(mNaviBarControlsModeObserver);

mContext.getContentResolver().registerContentObserver(
        Settings.Secure.getUriFor(NavigationBarInflaterView.NAVIGATION_BAR_CONTROLS_MODE),true,
        mNaviBarControlsModeObserver,mCurrentUserId);

int naviBarType = Settings.Secure.getIntForUser(mContext.getContentResolver(),
               NavigationBarInflaterView.NAVIGATION_BAR_CONTROLS_MODE,
               NavigationBarInflaterView.NAVIGATION_BAR_LEFT_BACK_MODE,mCurrentUserId);
       
LogUtils.d(TAG,"------------NaviBarControlsModeObserver,naviBarType:"+naviBarType);

        if (mNavigationBarView!= null) {
            mNavigationBarView.setNavigationBarControlsMode(mCurrentUserId,false);
        }

……

}

 

二、  从contentProvider获取多用户数据

以上的数据是保存在Settings provider里的,如果是从ContentProvider里获取多用户数据,方法又不同,主要在于Context的获取:

Context c = null;
UserManager um = UserManager.get(mContext);
int activeUserId= ActivityManager.getCurrentUser();//获取当前UserID
if((UserManager.isSplitSystemUser()&& activeUserId == UserHandle.USER_SYSTEM)){
       c =mContext;
}else {
       for (UserInfo ui : um.getUsers()) {
              if (ui.id== activeUserId) {

                     //根据当前用户创建context
                     c = mContext.createPackageContextAsUser(mContext.getPackageName(),0, ui.getUserHandle());
              }
       }
}
if(c!=null) {
       cursor = c.getContentResolver().query(Uri.parse(URI),null,null,null,null);
}

获取UserID及监听用户切换同上。

 

总结:多用户系统下数据的获取、存储需要根据UserID来获取,用户切换后需主动去重新注册监听、获取数据。