Android UserManager创建用户

1.背景

客户反馈,普通应用做platform签名后可以创建用户,影响系统安全。

2.发现问题

自测试代码:

public void createUser() {
    try {
        UserManager mUserManager = (UserManager) getSystemService(Context.USER_SERVICE);
        mUserManager.createUser("test", 0);            

    } catch (Exception e) {
        e.printStackTrace();
    } catch (NoClassDefFoundError e) {
        e.printStackTrace();
    }
}

声明相关权限:

    <uses-permission android:name="android.permission.MANAGE_USERS"/>
    <uses-permission android:name="android.permission.CREATE_USERS"/>

编写代码时发现,eclipse根本调用不到createUser这个方法…
在这里插入图片描述
这是为什么呢?可能是系统隐藏了这个方法。
frameworks/base/core/java/android/os/UserManager.java

    /**
     * Creates a user with the specified name and options. For non-admin users, default user
     * restrictions are going to be applied.
     * Requires {@link android.Manifest.permission#MANAGE_USERS} permission.
     *
     * @param name the user's name
     * @param flags flags that identify the type of user and other properties.
     * @see UserInfo
     *
     * @return the UserInfo object for the created user, or null if the user could not be created.
     * @hide
     */
    public UserInfo createUser(String name, int flags) {
        UserInfo user = null;
        try {
            user = mService.createUser(name, flags);
            // TODO: Keep this in sync with
            // UserManagerService.LocalService.createUserEvenWhenDisallowed
            if (user != null && !user.isAdmin() && !user.isDemo()) {
                mService.setUserRestriction(DISALLOW_SMS, true, user.id);
                mService.setUserRestriction(DISALLOW_OUTGOING_CALLS, true, user.id);
            }
        } catch (RemoteException re) {
            throw re.rethrowFromSystemServer();
        }
        return user;
    }

果然,Android源码里面果然声明了@hide,那这个现象就是正常的了。那么,怎样才能调用createUser方法呢?

3.解决问题

3.1 反射调用

直接调用不行,那就尝试反射吧。

public void createUser() {
    try {
        UserManager mUserManager = (UserManager) getSystemService(Context.USER_SERVICE);
        //mUserManager.createUser("test", 0);

        // Class<?> cls = Class.forName("android.os.UserManager");
        Class<?> cls = UserManager.class;
        Method createUser = cls.getMethod("createUser", String.class, int.class);
        Log.d(TAG, "createUser = " + createUser.getName());
        Object objRet1 = createUser.invoke(mUserManager, "test", 0);
        Log.d(TAG, "ret = " + objRet1);

    } catch (Exception e) {
        e.printStackTrace();
    } catch (NoClassDefFoundError e) {
        e.printStackTrace();
    }
}

经验证,反射调用的这段代码是可以的。

3.2 引入layoutlib.jar

客户反馈不需要反射,应用可以直接调用这个方法。为什么我调用不了呢?继续分析,猜测跟layoutlib.jar有关,尝试eclipse工程引入layoutlib.jar。
在这里插入图片描述

如何引用layoutlib.jar就不多介绍了,很简单。如上图,引用layoutlib.jar。发现还是调用不了。究竟是什么原因呢?

import android.os.UserManager;

跟踪UserManager,发现这个类还是定义在android.jar里面,layoutlib.jar没有生效。
在这里插入图片描述
可能跟jar包的顺序有关,调整一下优先级,把layoutlib.jar调到第一位。
在这里插入图片描述
再看一下引用关系。
在这里插入图片描述
如上图,现在UserManager已经是layoutlib.jar里面的了,说明引用正确了。
现在确认一下能否调用createUser方法。
在这里插入图片描述
eclipse没有报错了,说明layoutlib.jar里面确实有UserManager的createUser方法。

4.为什么需要platform签名

看一下权限是如何定义的。
frameworks/base/core/res/AndroidManifest.xml

   <!-- @SystemApi @hide Allows an application to call APIs that allow it to query and manage
         users on the device. This permission is not available to
         third party applications. -->
    <permission android:name="android.permission.MANAGE_USERS"
        android:protectionLevel="signature|privileged" />

    <!-- @hide Allows an application to create, remove users and get the list of
         users on the device. Applications holding this permission can only create restricted,
         guest, managed, demo, and ephemeral users. For creating other kind of users,
         {@link android.Manifest.permission#MANAGE_USERS} is needed.
         This permission is not available to third party applications. -->
    <permission android:name="android.permission.CREATE_USERS"
        android:protectionLevel="signature" />

signature级别的权限,需要申请者和定义者具有相同的签名。
这两个权限是在framework-res.jar里面定义的,而framework-res.jar是platform签名,所以申请者也需要platform签名,才能得到这两个权限。
关于Android权限管理机制,参考这篇文章:
https://blog.csdn.net/xhaotianshenjian/article/details/81535259

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值