首页 > 其他分享 >Android 设备管理员

Android 设备管理员

时间:2023-11-21 15:02:25浏览次数:30  
标签:mDPM setDeviceOwner who DevicePolicyManager mDeviceAdmin 管理员 DEVICE Android 设备

一、概述

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

二、客户需求

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

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

Android 设备管理员_android

三、解题步骤

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);

尝试该方案得到如下结果:

Android 设备管理员_android_02

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

标签:mDPM,setDeviceOwner,who,DevicePolicyManager,mDeviceAdmin,管理员,DEVICE,Android,设备
From: https://blog.51cto.com/u_16367370/8503336

相关文章

  • Android并发编程高级面试题汇总(含详细解析 八)
    Android并发编程高级面试题汇总最全最细面试题讲解持续更新中......
  • android 获取cpu温度
    1、实力展示   2、核心代码分析 就是读取指定文件下,一些cpu信息文件,然后,对里面的数据进行筛选。有的机器上没有温度显示,大概率是下面的文件列表中,在当前机器上没有读权限,或者就直接没有列表中的文件。/***ScandevicelookingforCPUtemperatureinallwellknownlo......
  • 修改Android原生圆形ProgressBar颜色和环宽
    原生颜色和尺寸:修改颜色和圆环大小;效果:......
  • Android studio 打包jar包
    文章目录1、新建一个工程2、在工程中新建一个用于打包的模块3、主工程App的build中要加入依赖model4、在lib的build中编写task5、在libmodel中编写class文件6、打包jar7、jar包的调用1、新建一个工程新建一个空的工程2、在工程中新建一个用于打包的模块3、主工程App的build......
  • Android studio使用javadoc生成 api 说明文档
    文章目录1、工具下载2、实用工具添加注释3、使用该工具生成api文档4、查看生成的api文档5、帮助1、工具下载2、实用工具添加注释官方wikiTogeneratejavadocsforactiveelementpress“shift+alt+G”.Togeneratejavadocsforallelementsincurrentjavafilepre......
  • Android nice 进程优先级设置
    文章目录1.简介2.查看nice值3.修改nice的值1)adb命令修改2)在源码中修改1.简介在Android中,可以使用nice值来设定一个进程的优先级,系统的调度器可以根据nice值来合理的调度进程,主要特点如下:在Android中,nice的取值范围为**-20~19**在Android中,nice值的默认大小为0在Android......
  • Android Recyclerview的item间距实现
    Recyclerview中,提供了一个方法addItemDecoration给我们用于设置item的分割线下面提供几个常见的分割线效果注:下面的SizeUtils是AndroidUtilCode此库里的工具类,需要添加依赖,也可以自行修改封装的方法(主要是将dp单位转为px)以下代码已封装在我的库中stars-one/XAndroidUt......
  • Android系统开发 Android10版本自定义系统版本号
    前言  framework开发,此博客基于Android10版本,实现自定义系统版本号。找到修改位置需要修改的关键文件是buildinfo.sh搜索一下文件找到要改的目标文件这里建议将这个文件拷贝出来修改,各自的编译环境不同,拷贝或者传输文件的方式不同,这里各自发挥。下面是我在wsl里把文件拷......
  • Linux设备树完全解析
    1.Linux中说的设备树是什么?对于搞Linux驱动开发和BSP的工程师来说,总是不可避免的接触到设备树,那么设备树指的是什么呢?其实通常所说的设备树是指Linux内核里面的设备树文件,以.dts结尾,也叫做设备树源文件,这个文件可以通过一个叫dtc的程序把他编译成.dtb文件,编译后的文件就是Linux......
  • Android Studio 下发布项目成APK文件
    AndroidStudio下发布项目成APK文件一、环境和版本Windows10专业版AndroidStudioGiraffe|2022.3.1Patch2这个太重要IDE该版后菜单位置会发生变化二、操作过程操作过程非常简单找到菜单Buid点击弹出后,再找到BuildBundle(s)/APK(s)鼠标滑动后选中BuildAPK(s)点击即可。新......