【Android设备管理】 利用DevicePolicyManager执行屏幕锁定

Android手机一般不用时,都会通过电源键来锁定屏幕同时关闭屏幕灯。

其实从API Level 8 (也就是Android 2.2) 开始, Android提供了DevicePolicyManager类, 可以让你的应用程序也能执行屏幕锁定等操作。

锁定效果:

下面我们来看一下具体如何操作。 要让自己的应用实现该屏幕锁定,主要需要用到以下几个类:

DevicePolicyManager

这是设备管理的主类。通过它可以实现屏幕锁定、屏幕亮度调节、出厂设置等功能。

DeviceAdminReceiver

该类继承自BroadcastReceiver。 从源码可以看到,其实就是实现了一个OnReceive方法,该方法中根据不同的Action,执行相应的操作。 比如,如果激活成功,那么Action就是ACTION_DEVICE_ADMIN_ENABLED, 据此调用onEnabled 方法。

系统源码:

/** * Intercept standard device administrator broadcasts. Implementations * should not override this method; it is better to implement the * convenience callbacks for each action. */ @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if (ACTION_PASSWORD_CHANGED.equals(action)) { onPasswordChanged(context, intent); } else if (ACTION_PASSWORD_FAILED.equals(action)) { onPasswordFailed(context, intent); } else if (ACTION_PASSWORD_SUCCEEDED.equals(action)) { onPasswordSucceeded(context, intent); } else if (ACTION_DEVICE_ADMIN_ENABLED.equals(action)) { onEnabled(context, intent); } else if (ACTION_DEVICE_ADMIN_DISABLE_REQUESTED.equals(action)) { CharSequence res = onDisableRequested(context, intent); if (res != null) { Bundle extras = getResultExtras(true); extras.putCharSequence(EXTRA_DISABLE_WARNING, res); } } else if (ACTION_DEVICE_ADMIN_DISABLED.equals(action)) { onDisabled(context, intent); } }

DeviceAdminInfo

定义设备管理类的meta 信息。 什么意思呢? 就是定义可用的权限。definepolicy that this device admin can use。

比如DeviceAdminReceiver.USES_POLICY_FORCE_LOCK , 这个就是本次要用的"强制锁定屏幕"的权限. 不过这些权限一般都直接通过XML文件来定义。 稍后你就会看到。


下面我们就来看下如何实现屏幕锁定。

注意,此处讲的屏幕锁定, 其实还是调用的系统的锁定方式。

在 "设置" - “位置与安全” - "更改屏幕锁定" 中可以设置锁定方式,一共有四种:

1. 无锁

2. 图案锁 (就是九宫图)

3. PIN锁

4. 密码锁

你的手机设置了哪个锁, 调用这个API时就会显示哪个锁 !

(锁定类型设置画面)

第一步: 写一个布局文件,该布局上有四个按钮, 分别对应 "激活设备管理权限" 、 "禁用设备管理权限"、"系统锁"、"自定义锁"。

其中"自定义锁"在下一篇博文中讲。本次暂时不用。

布局文件如下:

<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:gravity="center" android:id="@+id/rlTextDescBlock" android:layout_width="wrap_content" android:layout_height="wrap_content"> <LinearLayout android:id="@+id/layout1" android:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_marginTop="30px"> <Button android:id="@+id/active" android:textSize="14.0sp" android:textStyle="bold" android:textColor="#ff5779a7" android:background="@drawable/detail_redirect_button_bg" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_marginLeft="10.0dip" android:text="激活" android:layout_weight="1.0" /> <Button android:id="@+id/unactive" android:textSize="14.0sp" android:textStyle="bold" android:textColor="#ff5779a7" android:background="@drawable/detail_comment_button_bg" android:paddingRight="10.0dip" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_marginRight="10.0dip" android:text="禁用" android:layout_weight="1.0" /> </LinearLayout> <LinearLayout android:layout_below="@id/layout1" android:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_marginTop="30px"> <Button android:id="@+id/syslock" android:textSize="14.0sp" android:textStyle="bold" android:textColor="#ff5779a7" android:background="@drawable/detail_redirect_button_bg" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_marginLeft="10.0dip" android:text="系统锁屏" android:layout_weight="1.0" /> <Button android:id="@+id/custlock" android:textSize="14.0sp" android:textStyle="bold" android:textColor="#ff5779a7" android:background="@drawable/detail_comment_button_bg" android:paddingRight="10.0dip" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_marginRight="10.0dip" android:text="自定义锁屏" android:layout_weight="1.0" /> </LinearLayout> </RelativeLayout>

效果图:

下面就对应的一个个实现功能。

1. "激活" 功能。

STEP1:初始化设备管理需要的几个类:

//获取设备管理服务 policyManager = (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE); //AdminReceiver 继承自 DeviceAdminReceiver componentName = new ComponentName(this, AdminReceiver.class);

其中:AdminReceiver 类的代码如下:

package com.yfz.broadcast; import com.yfz.log.Logger; import android.app.admin.DeviceAdminInfo; import android.app.admin.DeviceAdminReceiver; import android.app.admin.DevicePolicyManager; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.pm.ResolveInfo; import android.os.IBinder; import android.widget.Toast; public class AdminReceiver extends DeviceAdminReceiver { @Override public DevicePolicyManager getManager(Context context) { Logger.d("------" + "getManager" + "------"); return super.getManager(context); } @Override public ComponentName getWho(Context context) { Logger.d("------" + "getWho" + "------"); return super.getWho(context); } /** * 禁用 */ @Override public void onDisabled(Context context, Intent intent) { Logger.d("------" + "onDisabled" + "------"); Toast.makeText(context, "禁用设备管理", Toast.LENGTH_SHORT).show(); super.onDisabled(context, intent); } @Override public CharSequence onDisableRequested(Context context, Intent intent) { Logger.d("------" + "onDisableRequested" + "------"); return super.onDisableRequested(context, intent); } /** * 激活 */ @Override public void onEnabled(Context context, Intent intent) { Logger.d("------" + "onEnabled" + "------"); Toast.makeText(context, "启动设备管理", Toast.LENGTH_SHORT).show(); super.onEnabled(context, intent); } @Override public void onPasswordChanged(Context context, Intent intent) { Logger.d("------" + "onPasswordChanged" + "------"); super.onPasswordChanged(context, intent); } @Override public void onPasswordFailed(Context context, Intent intent) { Logger.d("------" + "onPasswordFailed" + "------"); super.onPasswordFailed(context, intent); } @Override public void onPasswordSucceeded(Context context, Intent intent) { Logger.d("------" + "onPasswordSucceeded" + "------"); super.onPasswordSucceeded(context, intent); } @Override public void onReceive(Context context, Intent intent) { Logger.d("------" + "onReceive" + "------"); super.onReceive(context, intent); } @Override public IBinder peekService(Context myContext, Intent service) { Logger.d("------" + "peekService" + "------"); return super.peekService(myContext, service); } }

继承了DeviceAdminReceiver,没有做什么特别操作,仅仅在激动、禁用时输出一个提示消息。

同时,像普通Broadcast类一样,该类也需要在 AndroidManifest.xml 文件中注册。

如下:

<!-- 设备管理 --> <receiver android:name=".broadcast.AdminReceiver" android:label="@string/device" android:description="@string/device_des" android:permission="android.permission.BIND_DEVICE_ADMIN"> <meta-data android:name="android.app.device_admin" android:resource="@xml/lock_screen" /> <intent-filter> <action android:name="android.app.action.DEVICE_ADMIN_ENABLED" /> </intent-filter> </receiver>

其中

android:permission="android.permission.BIND_DEVICE_ADMIN" 和

<intent-filter>

<actionandroid:name="android.app.action.DEVICE_ADMIN_ENABLED" />

</intent-filter>

是必须的。

android:resource="@xml/lock_screen" 对应的就是权限说明文件。

本次仅需要强制锁定权限。 如下:

<?xml version="1.0" encoding="UTF-8"?> <device-admin xmlns:android="http://schemas.android.com/apk/res/android"> <uses-policies> <!-- 强行锁定 --> <force-lock /> </uses-policies> </device-admin>

STEP2: "激活"按钮 执行代码:

/** * 激活设备管理权限 * 成功执行激活时,DeviceAdminReceiver中的 onEnabled 会响应 */ private void activeManage() { // 启动设备管理(隐式Intent) - 在AndroidManifest.xml中设定相应过滤器 Intent intent = new Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN); //权限列表 intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, componentName); //描述(additional explanation) intent.putExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION, "------ 其他描述 ------"); startActivityForResult(intent, 0); }

这边就是用了一个隐式Intent ,通过这个Intent (DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN)跳转到 权限提醒页面。 同时传递了两个参数EXTRA_DEVICE_ADMIN 、EXTRA_ADD_EXPLANATION。

EXTRA_DEVICE_ADMIN参数中说明了用到哪些权限,EXTRA_ADD_EXPLANATION参数为附加的说明。

就这样,一个激活功能就完成了。 激活页面如下:

上图中" 设备管理软件说明: 我们不是黑客,请放心!" 对应的是AndroidManifest.xml文件中 android:description="@string/device_des"。

"------ 其他描述 ------" 就是之前传的EXTRA_ADD_EXPLANATION 参数。

个人觉得两者要一个就可以了, 不知道为什么要提供两个。

STEP 3: 点击"激活"。

此时该应用就拥有了设备管理权限。激活时AdminReceiver 类的 onEnabled方法会被调用。

2. “禁用” 功能。

如果在上面选择了"激活", 那么你这个应用就可以一直使用这些权限了,不需要再次激活。 但是如果想"禁用",该怎么做呢?

答案很简单,只要调用下面的方法即可.

/** * 禁用设备管理权限 * 成功执行禁用时,DeviceAdminReceiver中的 onDisabled 会响应 */ private void unActiveManage() { Logger.d("------ unActiveManage ------"); boolean active = policyManager.isAdminActive(componentName); if (active) { policyManager.removeActiveAdmin(componentName); } }

禁用时AdminReceiver 类的 onDisabled方法会被调用。

3. “系统锁”

其实到这已经非常简单了,所有的配置及初始化,都在激活时做了。

下面直接上调用系统锁的代码:

boolean active = policyManager.isAdminActive(componentName); if (active) { policyManager.lockNow(); }

到此为止, 屏幕锁定结束了。

附上主要类的代码:

package com.yfz; import com.yfz.broadcast.AdminReceiver; import com.yfz.log.Logger; import android.app.Activity; import android.app.ActivityManager; import android.app.AlertDialog; import android.app.admin.DevicePolicyManager; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; public class Lesson13 extends Activity implements OnClickListener { private DevicePolicyManager policyManager; private ComponentName componentName; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.lesson13); //获取设备管理服务 policyManager = (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE); //AdminReceiver 继承自 DeviceAdminReceiver componentName = new ComponentName(this, AdminReceiver.class); init(); } private void init() { Button active = (Button)findViewById(R.id.active); Button unactive = (Button)findViewById(R.id.unactive); Button syslock = (Button)findViewById(R.id.syslock); active.setOnClickListener(this); unactive.setOnClickListener(this); syslock.setOnClickListener(this); } @Override public void onClick(View v) { switch(v.getId()) { case R.id.active: activeManage(); break; case R.id.unactive: unActiveManage(); break; case R.id.syslock: systemLock(); break; default: break; } } /** * 激活设备管理权限 * 成功执行激活时,DeviceAdminReceiver中的 onEnabled 会响应 */ private void activeManage() { // 启动设备管理(隐式Intent) - 在AndroidManifest.xml中设定相应过滤器 Intent intent = new Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN); //权限列表 intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, componentName); //描述(additional explanation) intent.putExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION, "------ 其他描述 ------"); startActivityForResult(intent, 0); } /** * 禁用设备管理权限 * 成功执行禁用时,DeviceAdminReceiver中的 onDisabled 会响应 */ private void unActiveManage() { Logger.d("------ unActiveManage ------"); boolean active = policyManager.isAdminActive(componentName); if (active) { policyManager.removeActiveAdmin(componentName); } } /** * 调出系统锁 */ private void systemLock() { Logger.d("------ Lock Screen ------"); boolean active = policyManager.isAdminActive(componentName); if (active) { policyManager.lockNow(); } } }


最后说一下,设备管理拥有的权限,一共就5个。

看配置文件中的说明吧。

<?xml version="1.0" encoding="UTF-8"?> <device-admin xmlns:android="http://schemas.android.com/apk/res/android"> <uses-policies> <!-- 强行锁定 --> <force-lock /> <!-- 清除所有数据(恢复出厂设置) --> <wipe-data /> <!-- 重置密码 --> <reset-password /> <!-- 限制密码选择 --> <limit-password /> <!-- 监控登录尝试 --> <watch-login /> </uses-policies> </device-admin>

所有权限都申请时的效果图:

强制屏幕锁定功能, 可以应用于一些安全软件, 比如手机安全卫士, 当手机丢失后,用户发送指令短信、或者邮件到该手机上, 让手机强制锁屏。 这样的话,及时别人捡到了,也无法使用。

不过一般手机用户可能不一定会设定手机锁,因此调用系统锁可能并没有多大作用,因此下一篇我们做一个自定义锁, 该锁只在需要时启用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值