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

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

锁定效果:

2011-5-8 13:53:39 上传 下载附件 (50.99 KB) 2011-5-8 13:53:41 上传 下载附件 (58.37 KB)

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

DevicePolicyManager

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

DeviceAdminReceiver

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

系统源码:

  1. /**
  2. * Intercept standard device administrator broadcasts.Implementations
  3. * should not override this method; it is better to implement the
  4. * convenience callbacks for each action.
  5. */
  6. @Override
  7. public void onReceive(Context context, Intent intent) {
  8. String action = intent.getAction();
  9. if (ACTION_PASSWORD_CHANGED.equals(action)) {
  10. onPasswordChanged(context, intent);
  11. } else if (ACTION_PASSWORD_FAILED.equals(action)) {
  12. onPasswordFailed(context, intent);
  13. } else if (ACTION_PASSWORD_SUCCEEDED.equals(action)) {
  14. onPasswordSucceeded(context, intent);
  15. } else if (ACTION_DEVICE_ADMIN_ENABLED.equals(action)) {
  16. onEnabled(context, intent);
  17. } else if (ACTION_DEVICE_ADMIN_DISABLE_REQUESTED.equals(action)) {
  18. CharSequence res = onDisableRequested(context, intent);
  19. if (res != null) {
  20. Bundle extras = getResultExtras(true);
  21. extras.putCharSequence(EXTRA_DISABLE_WARNING, res);
  22. }
  23. } else if (ACTION_DEVICE_ADMIN_DISABLED.equals(action)) {
  24. onDisabled(context, intent);
  25. }
  26. }
复制代码 DeviceAdminInfo定义设备管理类的 meta 信息。 什么意思呢? 就是定义可用的权限。define policy that this device admin can use。比如 DeviceAdminReceiver.USES_POLICY_FORCE_LOCK , 这个就是本次要用的"强制锁定屏幕"的权限. 不过这些权限一般都直接通过XML文件来定义。 稍后你就会看到。 下面我们就来看下如何实现屏幕锁定。注意,此处讲的屏幕锁定, 其实还是调用的系统的锁定方式。在 "设置" - “位置与安全” - "更改屏幕锁定" 中可以设置锁定方式,一共有四种:1. 无锁2. 图案锁 (就是九宫图)3. PIN锁4. 密码锁你的手机设置了哪个锁, 调用这个API时就会显示哪个锁 !(锁定类型设置画面) 2011-5-8 13:53:42 上传 下载附件 (11.9 KB) 第一步: 写一个布局文件,该布局上有四个按钮, 分别对应 "激活设备管理权限" 、 "禁用设备管理权限"、"系统锁"、"自定义锁"。 其中"自定义锁"在下一篇博文中讲。本次暂时不用。布局文件如下:
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <RelativeLayout
  3. xmlns:android="http://schemas.android.com/apk/res/android"
  4. android:gravity="center"
  5. android:id="@+id/rlTextDescBlock"
  6. android:layout_width="wrap_content"
  7. android:layout_height="wrap_content">
  8. <LinearLayout
  9. android:id="@+id/layout1"
  10. android:orientation="horizontal"
  11. android:layout_width="fill_parent"
  12. android:layout_height="wrap_content"
  13. android:layout_marginTop="30px">
  14. <Button
  15. android:id="@+id/active"
  16. android:textSize="14.0sp"
  17. android:textStyle="bold"
  18. android:textColor="#ff5779a7"
  19. android:background="@drawable/detail_redirect_button_bg"
  20. android:layout_width="fill_parent"
  21. android:layout_height="wrap_content"
  22. android:layout_marginLeft="10.0dip"
  23. android:text="激活"
  24. android:layout_weight="1.0" />
  25. <Button
  26. android:id="@+id/unactive"
  27. android:textSize="14.0sp"
  28. android:textStyle="bold"
  29. android:textColor="#ff5779a7"
  30. android:background="@drawable/detail_comment_button_bg"
  31. android:paddingRight="10.0dip"
  32. android:layout_width="fill_parent"
  33. android:layout_height="wrap_content"
  34. android:layout_marginRight="10.0dip"
  35. android:text="禁用"
  36. android:layout_weight="1.0" />
  37. </LinearLayout>

  38. <LinearLayout
  39. android:layout_below="@id/layout1"
  40. android:orientation="horizontal"
  41. android:layout_width="fill_parent"
  42. android:layout_height="wrap_content"
  43. android:layout_marginTop="30px">
  44. <Button
  45. android:id="@+id/syslock"
  46. android:textSize="14.0sp"
  47. android:textStyle="bold"
  48. android:textColor="#ff5779a7"
  49. android:background="@drawable/detail_redirect_button_bg"
  50. android:layout_width="fill_parent"
  51. android:layout_height="wrap_content"
  52. android:layout_marginLeft="10.0dip"
  53. android:text="系统锁屏"
  54. android:layout_weight="1.0" />
  55. <Button
  56. android:id="@+id/custlock"
  57. android:textSize="14.0sp"
  58. android:textStyle="bold"
  59. android:textColor="#ff5779a7"
  60. android:background="@drawable/detail_comment_button_bg"
  61. android:paddingRight="10.0dip"
  62. android:layout_width="fill_parent"
  63. android:layout_height="wrap_content"
  64. android:layout_marginRight="10.0dip"
  65. android:text="自定义锁屏"
  66. android:layout_weight="1.0" />
  67. </LinearLayout>
  68. </RelativeLayout>
复制代码
效果图: 2011-5-8 13:53:44 上传 下载附件 (8.44 KB) 下面就对应的一个个实现功能。1. "激活" 功能。STEP1:初始化设备管理需要的几个类:
  1. //获取设备管理服务
  2. policyManager = (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE);

  3. //AdminReceiver 继承自 DeviceAdminReceiver
  4. componentName = new ComponentName(this, AdminReceiver.class);
复制代码
其中: AdminReceiver 类的代码如下:
  1. package com.yfz.broadcast;
  2. import com.yfz.log.Logger;
  3. import android.app.admin.DeviceAdminInfo;
  4. import android.app.admin.DeviceAdminReceiver;
  5. import android.app.admin.DevicePolicyManager;
  6. import android.content.ComponentName;
  7. import android.content.Context;
  8. import android.content.Intent;
  9. import android.content.pm.ResolveInfo;
  10. import android.os.IBinder;
  11. import android.widget.Toast;
  12. public class AdminReceiver extends DeviceAdminReceiver {
  13. @Override
  14. public DevicePolicyManager getManager(Context context) {
  15. Logger.d("------" + "getManager" + "------");
  16. return super.getManager(context);
  17. }
  18. @Override
  19. public ComponentName getWho(Context context) {
  20. Logger.d("------" + "getWho" + "------");
  21. return super.getWho(context);
  22. }

  23. /**
  24. * 禁用
  25. */
  26. @Override
  27. public void onDisabled(Context context, Intent intent) {
  28. Logger.d("------" + "onDisabled" + "------");

  29. Toast.makeText(context, "禁用设备管理", Toast.LENGTH_SHORT).show();

  30. super.onDisabled(context, intent);
  31. }
  32. @Override
  33. public CharSequence onDisableRequested(Context context, Intent intent) {
  34. Logger.d("------" + "onDisableRequested" + "------");
  35. return super.onDisableRequested(context, intent);
  36. }

  37. /**
  38. * 激活
  39. */
  40. @Override
  41. public void onEnabled(Context context, Intent intent) {
  42. Logger.d("------" + "onEnabled" + "------");

  43. Toast.makeText(context, "启动设备管理", Toast.LENGTH_SHORT).show();

  44. super.onEnabled(context, intent);
  45. }
  46. @Override
  47. public void onPasswordChanged(Context context, Intent intent) {
  48. Logger.d("------" + "onPasswordChanged" + "------");
  49. super.onPasswordChanged(context, intent);
  50. }
  51. @Override
  52. public void onPasswordFailed(Context context, Intent intent) {
  53. Logger.d("------" + "onPasswordFailed" + "------");
  54. super.onPasswordFailed(context, intent);
  55. }
  56. @Override
  57. public void onPasswordSucceeded(Context context, Intent intent) {
  58. Logger.d("------" + "onPasswordSucceeded" + "------");
  59. super.onPasswordSucceeded(context, intent);
  60. }
  61. @Override
  62. public void onReceive(Context context, Intent intent) {
  63. Logger.d("------" + "onReceive" + "------");

  64. super.onReceive(context, intent);
  65. }
  66. @Override
  67. public IBinder peekService(Context myContext, Intent service) {
  68. Logger.d("------" + "peekService" + "------");
  69. return super.peekService(myContext, service);
  70. }

  71. }
复制代码
继承了DeviceAdminReceiver,没有做什么特别操作,仅仅在激动、禁用时输出一个提示消息。同时,像普通Broadcast类一样,该类也需要在AndroidManifest.xml 文件中注册。如下:
  1. <!-- 设备管理 -->
  2. <receiver android:name=".broadcast.AdminReceiver"
  3. android:label="@string/device"
  4. android:description="@string/device_des"
  5. android:permission="android.permission.BIND_DEVICE_ADMIN">
  6. <meta-data android:name="android.app.device_admin"
  7. android:resource="@xml/lock_screen" />
  8. <intent-filter>
  9. <action
  10. android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
  11. </intent-filter>
  12. </receiver>
复制代码
其中 android:permission="android.permission.BIND_DEVICE_ADMIN" 和<intent-filter><action android:name="android.app.action.DEVICE_ADMIN_ENABLED" /></intent-filter>是必须的。android:resource="@xml/lock_screen" 对应的就是权限说明文件。本次仅需要强制锁定权限。 如下:
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <device-admin
  3. xmlns:android="http://schemas.android.com/apk/res/android">
  4. <uses-policies>
  5. <!-- 强行锁定 -->
  6. <force-lock />
  7. </uses-policies>
  8. </device-admin>
复制代码 STEP2: "激活"按钮 执行代码:
  1. /**
  2. * 激活设备管理权限
  3. * 成功执行激活时,DeviceAdminReceiver中的 onEnabled 会响应
  4. */
  5. private void activeManage() {
  6. // 启动设备管理(隐式Intent) - 在AndroidManifest.xml中设定相应过滤器
  7. Intent intent = new Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN);

  8. //权限列表
  9. intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, componentName);

  10. //描述(additional explanation)
  11. intent.putExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION, "------ 其他描述 ------");

  12. startActivityForResult(intent, 0);
  13. }
复制代码
这边就是用了一个隐式Intent ,通过这个Intent (DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN)跳转到 权限提醒页面。 同时传递了两个参数EXTRA_DEVICE_ADMIN 、 EXTRA_ADD_EXPLANATION。EXTRA_DEVICE_ADMIN参数中说明了用到哪些权限, EXTRA_ADD_EXPLANATION参数为附加的说明。就这样,一个激活功能就完成了。 激活页面如下: 2011-5-8 13:53:45 上传 下载附件 (22.4 KB) 上图中" 设备管理软件说明: 我们不是黑客,请放心!" 对应的是 AndroidManifest.xml文件中android:description="@string/device_des"。"------ 其他描述 ------" 就是之前传的 EXTRA_ADD_EXPLANATION 参数。个人觉得两者要一个就可以了, 不知道为什么要提供两个。STEP 3: 点击"激活"。 此时该应用就拥有了设备管理权限。 激活时 AdminReceiver 类的onEnabled方法会被调用。 2. “禁用” 功能。 如果在上面选择了"激活", 那么你这个应用就可以一直使用这些权限了,不需要再次激活。 但是如果想"禁用",该怎么做呢?答案很简单,只要调用下面的方法即可.
  1. /**
  2. * 禁用设备管理权限
  3. * 成功执行禁用时,DeviceAdminReceiver中的 onDisabled 会响应
  4. */
  5. private void unActiveManage() {
  6. Logger.d("------ unActiveManage ------");
  7. boolean active = policyManager.isAdminActive(componentName);
  8. if (active) {
  9. policyManager.removeActiveAdmin(componentName);
  10. }
  11. }
复制代码

禁用时 AdminReceiver 类的onDisabled方法会被调用。3. “系统锁” 其实到这已经非常简单了,所有的配置及初始化,都在激活时做了。 下面直接上调用系统锁的代码:
  1. boolean active = policyManager.isAdminActive(componentName);
  2. if (active) {
  3. policyManager.lockNow();
  4. }
复制代码
到此为止, 屏幕锁定结束了。附上主要类的代码:
  1. package com.yfz;
  2. import com.yfz.broadcast.AdminReceiver;
  3. import com.yfz.log.Logger;
  4. import android.app.Activity;
  5. import android.app.ActivityManager;
  6. import android.app.AlertDialog;
  7. import android.app.admin.DevicePolicyManager;
  8. import android.content.ComponentName;
  9. import android.content.Context;
  10. import android.content.Intent;
  11. import android.os.Bundle;
  12. import android.view.View;
  13. import android.view.View.OnClickListener;
  14. import android.widget.Button;
  15. public class Lesson13 extends Activity implements OnClickListener {

  16. private DevicePolicyManager policyManager;
  17. private ComponentName componentName;

  18. @Override
  19. protected void onCreate(Bundle savedInstanceState) {
  20. super.onCreate(savedInstanceState);
  21. setContentView(R.layout.lesson13);

  22. //获取设备管理服务
  23. policyManager = (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE);

  24. //AdminReceiver 继承自 DeviceAdminReceiver
  25. componentName = new ComponentName(this, AdminReceiver.class);

  26. init();
  27. }
  28. private void init() {
  29. Button active = (Button)findViewById(R.id.active);
  30. Button unactive = (Button)findViewById(R.id.unactive);
  31. Button syslock = (Button)findViewById(R.id.syslock);

  32. active.setOnClickListener(this);
  33. unactive.setOnClickListener(this);
  34. syslock.setOnClickListener(this);
  35. }
  36. @Override
  37. public void onClick(View v) {
  38. switch(v.getId()) {
  39. case R.id.active:
  40. activeManage();
  41. break;
  42. case R.id.unactive:
  43. unActiveManage();
  44. break;
  45. case R.id.syslock:
  46. systemLock();
  47. break;
  48. default:
  49. break;
  50. }
  51. }

  52. /**
  53. * 激活设备管理权限
  54. * 成功执行激活时,DeviceAdminReceiver中的 onEnabled 会响应
  55. */
  56. private void activeManage() {
  57. // 启动设备管理(隐式Intent) - 在AndroidManifest.xml中设定相应过滤器
  58. Intent intent = new Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN);

  59. //权限列表
  60. intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, componentName);

  61. //描述(additional explanation)
  62. intent.putExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION, "------ 其他描述 ------");

  63. startActivityForResult(intent, 0);
  64. }

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

  76. /**
  77. * 调出系统锁
  78. */
  79. private voidsystemLock() {
  80. Logger.d("------ Lock Screen ------");
  81. boolean active = policyManager.isAdminActive(componentName);
  82. if (active) {
  83. policyManager.lockNow();
  84. }
  85. }
  86. }
复制代码
最后说一下,设备管理拥有的权限,一共就5个。看配置文件中的说明吧。
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <device-admin
  3. xmlns:android="http://schemas.android.com/apk/res/android">
  4. <uses-policies>
  5. <!-- 强行锁定 -->
  6. <force-lock />
  7. <!-- 清除所有数据(恢复出厂设置) -->
  8. <wipe-data />
  9. <!-- 重置密码 -->
  10. <reset-password />
  11. <!-- 限制密码选择 -->
  12. <limit-password />
  13. <!-- 监控登录尝试 -->
  14. <watch-login />
  15. </uses-policies>
  16. </device-admin>
复制代码
所有权限都申请时的效果图: 2011-5-8 13:53:37 上传 下载附件 (28.68 KB) 强制屏幕锁定功能, 可以应用于一些安全软件, 比如手机安全卫士, 当手机丢失后,用户发送指令短信、或者邮件到该手机上, 让手机强制锁屏。 这样的话,及时别人捡到了,也无法使用。 不过一般手机用户可能不一定会设定手机锁,因此调用系统锁可能并没有多大作用,因此下一篇我们做一个自定义锁, 该锁只在需要时启用。

更多相关文章

  1. android支付宝客户端html5网页偶尔无法自动关闭问题
  2. Android(安卓)中动态加载.jar的实现步骤
  3. 再识Intent-实现调用Android内置浏览器打开网页
  4. 把Unity作为Android的子视图
  5. linux和android端的pthread学习
  6. Robotium源代码编译
  7. Android(安卓)Studio适当修改
  8. 我的第一个Android程序helloword及个人理解
  9. Android中的文件读写全面总结

随机推荐

  1. Android(安卓)8.1 MT6739 预置apk 可卸载
  2. Android(安卓)3.0新亮点,新机会
  3. Android环形进度条
  4. Android教程之Android(安卓)SDK1.5模拟器
  5. cocos2dx中利用xcode 调用java中的函数
  6. Android(安卓)GreenDao 3.0使用实例讲解
  7. android 多国语言对照表
  8. Ubuntu 下 Android(安卓)反编译 apk
  9. 使用Retrofit+LiveData时的Error/Loading
  10. android 监听EditText 的变化