android 手机多用户探索,如何在主用户删除其他用户

一 先放结论

删除其他用户的方法

			DevicePolicyManager dpm = (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE);
			ComponentName mName = new ComponentName(this, TestMadmin.class);
            for(int i=1;i<=100;i++){
        
                try {
                  UserHandle  userHandle = UserHandle.getUserHandleForUid(i);
                    //需要设备管理器权限
                    dpm.removeUser(mName ,userHandle );
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

二 什么是多用户

随意找的一篇多用户功能说明
https://baijiahao.baidu.com/s?id=1631589461286423218&wfr=spider&for=pc
效果类似系统多开,两个用户之间数据分离,互不影响

三 如何删除其他用户

DevicePolicyManager 有一个方法:

public boolean removeUser(@NonNull ComponentName admin, UserHandle userHandle) 

那么第一想法是遍历出所有UserHandle ,再依次删除。
实际操作中尝试使用

UserManager systemService = (UserManager) getSystemService(Context.USER_SERVICE);
List<UserHandle> userProfiles = systemService.getUserProfiles();
Log.i("test","userProfiles "+userProfiles.size());

获取到的userProfiles 的size = 0。
嗯,和想象不太一样。
然后在找的时候发现DevicePolicyManager也有一个getBindDeviceAdminTargetUsers方法,返回是一个UserHandle的List集合。

DevicePolicyManager dpm = (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE);
ComponentName mName = new ComponentName(this, TestMadmin.class);
List<UserHandle> listh = dpm.getBindDeviceAdminTargetUsers(mName );
Log.i("test","getBindDeviceAdminTargetUsers "+listh.size());

size=1,及当前主用户的UserHandle。但我的设备明明创建了多个用户。所以这种方法也抛弃。

尝试自己new一个UserHandle,通过UserHandle.getUserHandleForUid可以得到一个UserHandle ,但是我并不知道其他用户的uid。我尝试用1~10的遍历来一个个试其他账户的UID。假如我找对了其中一个uid,那么这个多用户应该是可以被删除掉的。

ComponentName mName = new ComponentName(this, TestMadmin.class);
for(int i=1;i<=10;i++){
    try {
        UserHandle  userHandle = UserHandle.getUserHandleForUid(i);
        dpm.removeUser(mName ,userHandle );
    } catch (Exception e) {
        e.printStackTrace();
    }

}

我创建了3个用户,成功删除2个其他用户。!? 成功一半。
将for循环放大到100。全部删除。我的手机最大只能创建3个用户+1个访客,共4个用户,100能够完美删除,甚至2/30可能都够了。

UserHandle.getUserHandleForUid只有api24+才有,对于api23及以下的,可以将调用getUserHandleForUid里面的方法拿出来调用。

/**
 * Returns the user for a given uid.
 * @param uid A uid for an application running in a particular user.
 * @return A {@link UserHandle} for that user.
 */
public static UserHandle getUserHandleForUid(int uid) {
    return of(getUserId(uid));
}
/** @hide */
@SystemApi
public static UserHandle of(@UserIdInt int userId) {
    return userId == USER_SYSTEM ? SYSTEM : new UserHandle(userId);
}

“of”方法是hide的,可以通过反射获取

userHandle = (UserHandle) UserHandle.class.getMethod("of",int.class).invoke(null,i);

所以,对于api23的设备,删除方法应该是这样:

ComponentName mName = new ComponentName(this, TestMadmin.class);
for(int i=1;i<=100;i++){
    try {
        userHandle = (UserHandle) UserHandle.class.getMethod("of",int.class).invoke(null,i);
        dpm.removeUser(mName ,userHandle );
    } catch (Exception e) {
        e.printStackTrace();
    }
}

关于ComponentName 和 DevicePolicyManager 的详细内容,将会在设备管理器一章中讲解。

发布了3 篇原创文章 · 获赞 0 · 访问量 104

猜你喜欢

转载自blog.csdn.net/qq_35501560/article/details/103973689