IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> Android 设备管理员 -> 正文阅读

[移动开发]Android 设备管理员

一、概述

DevicePolicyManager API可管理和操作设备,使用这个API你可以接管手机的应用权限,比如锁屏,恢复出厂设置,还有设置密码、强制清除密码,修改密码、设置屏幕灯光渐暗时间间隔等操作。

二、客户需求

1.需要三方应用调用setDeviceOwner().

2.使用反射方法调用,如下图:

在这里插入图片描述

三、解题步骤

1.Android系统提供一种方案

代码如下:

Intent intent = new Intent(
	DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN);
intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN,
	mComponentName);
intent.putExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION, "提示文字");
startActivityForResult(intent, 1);

尝试该方案得到如下结果:
在这里插入图片描述

2.分析方案

搜索广播发现在此地方接收广播处理:
路径:vendor/mediatek/proprietary/packages/apps/MtkSettings/src/com/android/settings/applications/specialaccess/deviceadmin/DeviceAdminAdd.java
代码如下(示例):

		if (DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN.equals(getIntent().getAction())) {
            mRefreshing = false;
            if (mDPM.isAdminActive(who)) {
                if (mDPM.isRemovingAdmin(who, android.os.Process.myUserHandle().getIdentifier())) {
                    Log.w(TAG, "Requested admin is already being removed: " + who);
                    finish();
                    return;
                }

                ArrayList<DeviceAdminInfo.PolicyInfo> newPolicies = mDeviceAdmin.getUsedPolicies();
                for (int i = 0; i < newPolicies.size(); i++) {
                    DeviceAdminInfo.PolicyInfo pi = newPolicies.get(i);
                    if (!mDPM.hasGrantedPolicy(who, pi.ident)) {
                        mRefreshing = true;
                        break;
                    }
                }
                if (!mRefreshing) {
                    // Nothing changed (or policies were removed) - return immediately
                    setResult(Activity.RESULT_OK);
                    finish();
                    return;
                }
            }
        }

点击同意之后处理的方法:
路径:vendor/mediatek/proprietary/packages/apps/MtkSettings/src/com/android/settings/applications/specialaccess/deviceadmin/DeviceAdminAdd.java
方法:

	void addAndFinish() {
        try {
            logSpecialPermissionChange(true, mDeviceAdmin.getComponent().getPackageName());
            mDPM.setActiveAdmin(mDeviceAdmin.getComponent(), mRefreshing);
            EventLog.writeEvent(EventLogTags.EXP_DET_DEVICE_ADMIN_ACTIVATED_BY_USER,
                mDeviceAdmin.getActivityInfo().applicationInfo.uid);

            unrestrictAppIfPossible(BatteryUtils.getInstance(this));

            setResult(Activity.RESULT_OK);
        } catch (RuntimeException e) {
            // Something bad happened...  could be that it was
            // already set, though.
            Log.w(TAG, "Exception trying to activate admin "
                    + mDeviceAdmin.getComponent(), e);
            if (mDPM.isAdminActive(mDeviceAdmin.getComponent())) {
                setResult(Activity.RESULT_OK);
            }
        }
        if (mAddingProfileOwner) {
            try {
                mDPM.setProfileOwner(mDeviceAdmin.getComponent(),
                        mProfileOwnerName, UserHandle.myUserId());
            } catch (RuntimeException re) {
                setResult(Activity.RESULT_CANCELED);
            }
        }
        finish();
    }

3.结合客户需求

1.新建类WangPosManager

路径:frameworks/base/core/java/android/os/WangPosManager.java

2.广播接收处理方法并点击同意按钮

代码如下:

    public void setDeviceOwner(Context context, ComponentName who) {
        Log.i(TAG, "setDeviceOwner who:" + who.getPackageName());
        mDPM = (DevicePolicyManager) context.getSystemService(Context.DEVICE_POLICY_SERVICE);
        // mDPM = IDevicePolicyManager.Stub.asInterface(
        //         ServiceManager.getService(Context.DEVICE_POLICY_SERVICE));
        PackageManager packageManager = context.getPackageManager();
        ActivityInfo ai;
        try {
            ai = packageManager.getReceiverInfo(who, PackageManager.GET_META_DATA);
        } catch (PackageManager.NameNotFoundException e) {
            Log.w(TAG, "Unable to retrieve device policy " + who, e);
            return;
        }
        if (!mDPM.isAdminActive(who)) {
            Log.i(TAG, "!isAdminActive");
            List<ResolveInfo> avail = packageManager.queryBroadcastReceivers(
                    new Intent(DeviceAdminReceiver.ACTION_DEVICE_ADMIN_ENABLED),
                    PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS);
            int count = avail == null ? 0 : avail.size();
            boolean found = false;
            for (int i=0; i<count; i++) {
                ResolveInfo ri = avail.get(i);
                Log.i(TAG, "ri.activityInfo.packageName:" + ri.activityInfo.packageName);
                Log.i(TAG, "ri.activityInfo.name:" + ri.activityInfo.name);
                if (ai.packageName.equals(ri.activityInfo.packageName)
                        && ai.name.equals(ri.activityInfo.name)) {
                    Log.i(TAG, "ai.packageName:" + ai.packageName);
                    Log.i(TAG, "ai.name:" + ai.name);
                    try {
                        // We didn't retrieve the meta data for all possible matches, so
                        // need to use the activity info of this specific one that was retrieved.
                        ri.activityInfo = ai;
                        found = true;
                    } catch (Exception e) {
                        Log.w(TAG, "Bad " + ri.activityInfo + " e:" + e.toString());
                    }
                    break;
                }
            }
            if (!found) {
                Log.w(TAG, "Request to add invalid device admin: " + who);
                return;
            }
        }

        ResolveInfo ri = new ResolveInfo();
        ri.activityInfo = ai;
        try {
            mDeviceAdmin = new DeviceAdminInfo(context, ri);
        } catch (XmlPullParserException e) {
            Log.w(TAG, "Unable to retrieve device policy " + who + " e:" + e.toString());
            return;
        } catch (IOException e) {
            Log.w(TAG, "Unable to retrieve device policy " + who + " e:" + e.toString());
            return;
        }
        mDPM.setActiveAdmin(mDeviceAdmin.getComponent(), true, 0);

        try {
            if (!mDPM.setDeviceOwner(mDeviceAdmin.getComponent(), "", 0)) {
                throw new RuntimeException(
                        "Can't set package " + mDeviceAdmin.getComponent() + " as device owner.");
            }
        } catch (Exception e) {
            // Need to remove the admin that we just added.
            android.util.Log.i(TAG, "setDeviceOwner e:" + e.toString());
            mDPM.removeActiveAdmin(mDeviceAdmin.getComponent()/*, UserHandle.USER_SYSTEM*/);
            throw e;
        }

        mDPM.setUserProvisioningState(
                DevicePolicyManager.STATE_USER_SETUP_FINALIZED, 0);
    }

四、调用方法

1.设置管理员

adminReceiver = new ComponentName(this, "com.example.b3111_pa_demo.AdminReciver");
mDevicePolicyManager = (DevicePolicyManager) getSystemService(DEVICE_POLICY_SERVICE);
setDeviceOwner(adminReceiver);
    public void setDeviceOwner(ComponentName componentName) {
        try {
            Class WangPosManagerClass = Class.forName("android.os.WangPosManager");
            Object WangPosManager = WangPosManagerClass.newInstance();
            Method method = WangPosManagerClass.getMethod("setDeviceOwner", Context.class, ComponentName.class);
            method.invoke(WangPosManager, this, componentName);
        } catch (Exception e) {
            Log.i(TAG, "setDeviceOwner exception e:" + e.toString());
        }
    }

2.其他

锁屏:mDPM.lockNow();
恢复出厂设置: mDPM.wipeData(0);
屏幕光亮时间间隔:mDPM.setMaximumTimeToLock(mDeviceComponentName, timeout);

五、补充

使用adb命令可直接将三方应用设为、取消设备管理员。

adb shell dpm set-device-owner com.example.b3111_pa_demo/.AdminReciver
adb shell dpm remove-active-admin com.example.b3111_pa_demo/.AdminReciver
  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2022-03-10 22:41:17  更:2022-03-10 22:42:26 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 17:07:07-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码