您的位置:首页 > 移动开发 > Android开发

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

2011-10-09 11:42 537 查看
 
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 方法。
系统源码:

    /**

     * 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 信息。 什么意思呢? 就是定义可用的权限。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)

第一步: 写一个布局文件,该布局上有四个按钮, 分别对应 "激活设备管理权限" 、 "禁用设备管理权限"、"系统锁"、"自定义锁"。 其中"自定义锁"在下一篇博文中讲。本次暂时不用。布局文件如下:

<?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>

复制代码

效果图:


2011-5-8 13:53:44 上传
下载附件(8.44 KB)

下面就对应的一个个实现功能。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><action android: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参数为附加的说明。就这样,一个激活功能就完成了。 激活页面如下:


2011-5-8 13:53:45 上传
下载附件(22.4 KB)

上图中" 设备管理软件说明: 我们不是黑客,请放心!" 对应的是 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>

复制代码

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


2011-5-8 13:53:37 上传
下载附件(28.68 KB)

强制屏幕锁定功能, 可以应用于一些安全软件, 比如手机安全卫士, 当手机丢失后,用户发送指令短信、或者邮件到该手机上, 让手机强制锁屏。 这样的话,及时别人捡到了,也无法使用。 不过一般手机用户可能不一定会设定手机锁,因此调用系统锁可能并没有多大作用,因此下一篇我们做一个自定义锁, 该锁只在需要时启用。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息