Android 2.2 SDK提供了一个可管理和操作设备的API叫DevicePolicyManager,使用这个API你可以接管手机的应用权限,对手机做出很多大胆的操作,比如锁屏,恢复出厂设置(这么和谐的东西要是在中国是不大可能提供给你的),还有设置密码、强制清除密码,修改密码、设置屏幕灯光渐暗时间间隔等操作。这个API可谓是直接可以将你做的应用程序变成系统的老大哥了。虽说是这样,但应用程序可做老大只是对于你本身应用程序有效,别人也可以做类似的应用程序,这个与别人的权限是不起冲突的。

  好了,废话不说,上界面:

android 设备管理器 权限_ide

具体的编写代码的流程:

1.因为这个API是用的2.2提供的API,所以必须将sdkVersion设置为8,像这样<uses-sdk android:minSdkVersion="8" />,这是必须的。

2.注册一个广播服务类,用以监听权限的变化:

<?xml version="1.0" encoding="utf-8"?>
<device-admin xmlns:android="http://schemas.android.com/apk/res/android">
    <uses-policies>
        <limit-password />
        <watch-login />
        <reset-password />
        <force-lock />
        <wipe-data />
    </uses-policies>
</device-admin>

          android:permission 表示此功能需要的权限,android:name="android.app.action.DEVICE_ADMIN_ENABLED" 表示此动作的跳转界面

<meta-data android:name="android.app.device_admin"
                android:resource="@xml/device_admin" />

表示这个应用可以管理的权限清单,xml清单如下:

<?xml version="1.0" encoding="utf-8"?>
<device-admin xmlns:android="http://schemas.android.com/apk/res/android">
    <uses-policies>
        <limit-password />
        <watch-login />
        <reset-password />
        <force-lock />
        <wipe-data />
    </uses-policies>
</device-admin>

广播服务类的JAVA代码,重写一些必要的实现函数:

 

package 
   com.terry.device;

 
  import 
   android.app.admin.DeviceAdminReceiver;
 
  import 
   android.content.Context;
 
  import 
   android.content.Intent;
 
  import 
   android.content.SharedPreferences;
 
  import 
   android.widget.Toast;

 
  public 
    
  class 
   deviceAdminReceiver  
  extends 
   DeviceAdminReceiver {

     
  /** 
  
     * 获取设备存储的数值
     * 
     *  
  @param 
   context
     *  
  @return 
  
      
  */ 
  
     
  public 
    
  static 
   SharedPreferences getDevicePreference(Context context) {
         
  return 
   context.getSharedPreferences(
                DeviceAdminReceiver. 
  class 
  .getName(),  
  0 
  );
    }

     
  // 
   密码的特点 
  
 
       
  public 
    
  static 
   String PREF_PASSWORD_QUALITY  
  = 
    
  " 
  password_quality 
  " 
  ;
     
  // 
   密码的长度 
  
 
       
  public 
    
  static 
   String PREF_PASSWORD_LENGTH  
  = 
    
  " 
  password_length 
  " 
  ;

     
  public 
    
  static 
   String PREF_MAX_FAILED_PW  
  = 
    
  " 
  max_failed_pw 
  " 
  ;

     
  void 
   showToast(Context context, CharSequence text) {
        Toast.makeText(context, text, Toast.LENGTH_SHORT).show();
    }

    @Override
     
  public 
    
  void 
   onEnabled(Context context, Intent intent) {
         
  // 
   TODO Auto-generated method stub 
  
 
          showToast(context,  
  " 
  设备管理:可用 
  " 
  );
    }

    @Override
     
  public 
    
  void 
   onDisabled(Context context, Intent intent) {
         
  // 
   TODO Auto-generated method stub 
  
 
          showToast(context,  
  " 
  设备管理:不可用 
  " 
  );
    }

    @Override
     
  public 
   CharSequence onDisableRequested(Context context, Intent intent) {
         
  // 
   TODO Auto-generated method stub 
  
 
           
  return 
    
  " 
  这是一个可选的消息,警告有关禁止用户的请求 
  " 
  ;
    }

    @Override
     
  public 
    
  void 
   onPasswordChanged(Context context, Intent intent) {
         
  // 
   TODO Auto-generated method stub 
  
 
          showToast(context,  
  " 
  设备管理:密码己经改变 
  " 
  );
    }

    @Override
     
  public 
    
  void 
   onPasswordFailed(Context context, Intent intent) {
         
  // 
   TODO Auto-generated method stub 
  
 
          showToast(context,  
  " 
  设备管理:改变密码失败 
  " 
  );
    }

    @Override
     
  public 
    
  void 
   onPasswordSucceeded(Context context, Intent intent) {
         
  // 
   TODO Auto-generated method stub 
  
 
          showToast(context,  
  " 
  设备管理:改变密码成功 
  " 
  );
    }

}



复制代码


 

 

DeviceAdminReceiver是扩展于BroadcastReceiver。

 

下面先来看看操作效果,点击启用管理:

android 设备管理器 权限_移动开发_02

数据显示不完全 ,往下拉将看到:

android 设备管理器 权限_java_03

中间有一句话叫做:“设备管理可以对系统的一些安全进行设置”,这句话来源于上面的广播receiver中的description:android:description="@string/description",点击激活会触发广播类响应上面广播类弹出Toast。启用管理代码:

 


/** 
  
     * 设备管理可用的点击事件
     * 
     *  
  @author 
   terry
     * 
      
  */ 
  
     
  class 
   enableAdminClickEvent  
  implements 
   OnClickListener {

        @Override
         
  public 
    
  void 
   onClick(View v) {
             
  // 
   TODO Auto-generated method stub 
  
 
              Intent intent  
  = 
    
  new 
   Intent(
                    DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN);
            intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN,
                    mDeviceComponentName);
            intent.putExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION,
                     
  " 
  这里可以输入一些额外的说明,比如提示用户什么的 
  " 
  );
            startActivityForResult(intent, RESULT_ENABLE);
        }

    }



复制代码


 

 

 

锁屏操作,由于是模拟器不能做到真正错屏,只能停到初始模拟器进来需要解锁的状态,屏幕不会变暗。锁屏代码:

 


/** 
  
     * 锁屏
     * 
     *  
  @author 
   terry
     * 
      
  */ 
  
     
  class 
   force_lock  
  implements 
   OnClickListener {

        @Override
         
  public 
    
  void 
   onClick(View v) {
             
  // 
   TODO Auto-generated method stub 
  
 
               
  if 
   (mAM.isUserAMonkey()) {
                AlertDialog.Builder builder  
  = 
    
  new 
   AlertDialog.Builder(
                        deviceActivity. 
  this 
  );
                builder.setMessage( 
  " 
  你不能对此屏幕进行操作,因为你不是管理员 
  " 
  );
                builder.setPositiveButton( 
  " 
  I admit defeat 
  " 
  ,  
  null 
  );
                builder.show();
                 
  return 
  ;
            }
             
  boolean 
   active  
  = 
   mDPM.isAdminActive(mDeviceComponentName);
             
  if 
   (active) {
                mDPM.lockNow();
            }
        }
    }



复制代码


 

 

屏幕在设置相应时间后灯光变暗效果:

 


/** 
  
     * 屏幕自动变暗
     * 
     *  
  @author 
   terry
     * 
      
  */ 
  
     
  class 
   timeoutClickEvent  
  implements 
   OnClickListener {

        @Override
         
  public 
    
  void 
   onClick(View v) {
             
  // 
   TODO Auto-generated method stub 
  
 
               
  if 
   (mAM.isUserAMonkey()) {
                AlertDialog.Builder builder  
  = 
    
  new 
   AlertDialog.Builder(
                        deviceActivity. 
  this 
  );
                builder.setMessage( 
  " 
  你不能对我的屏幕进行操作,因为你不是管理员 
  " 
  );
                builder.setPositiveButton( 
  " 
  I admit defeat 
  " 
  ,  
  null 
  );
                builder.show();
                 
  return 
  ;
            }
             
  boolean 
   active  
  = 
   mDPM.isAdminActive(mDeviceComponentName);
             
  if 
   (active) {
                 
  long 
   timeout  
  = 
    
  1000L 
    
  * 
   Long.parseLong(et.getText().toString());
                mDPM.setMaximumTimeToLock(mDeviceComponentName, timeout);
            }
        }
    }



复制代码


 

 

由于是模拟器,恢复出厂设置清除数据后,将无法重新开机,必须重新启动机子,在真机上是没有问题的,测试的时候必须小心,以免将你的数据清除掉。恢复出厂设置代码:

 


/** 
  
     * 恢复出厂设置
     * 
     *  
  @author 
   terry
     * 
      
  */ 
  
     
  class 
   resetClickEvent  
  implements 
   OnClickListener {

        @Override
         
  public 
    
  void 
   onClick(View v) {
             
  // 
   TODO Auto-generated method stub 
  
 
               
  if 
   (mAM.isUserAMonkey()) {
                 
  // 
   Don't trust monkeys to do the right thing! 
  
 
                  AlertDialog.Builder builder  
  = 
    
  new 
   AlertDialog.Builder(
                        deviceActivity. 
  this 
  );
                builder
                        .setMessage( 
  " 
  You can't wipe my data because you are a monkey! 
  " 
  );
                builder.setPositiveButton( 
  " 
  I admit defeat 
  " 
  ,  
  null 
  );
                builder.show();
                 
  return 
  ;
            }

            AlertDialog.Builder builder  
  = 
    
  new 
   Builder(deviceActivity. 
  this 
  );
            builder.setMessage( 
  " 
  将重置数据,你确定此操作吗? 
  " 
  );
            builder.setPositiveButton(android.R.string.ok,
                     
  new 
   DialogInterface.OnClickListener() {

                        @Override
                         
  public 
    
  void 
   onClick(DialogInterface dialog,  
  int 
   which) {
                             
  // 
   TODO Auto-generated method stub 
  
 
                              AlertDialog.Builder aler  
  = 
    
  new 
   AlertDialog.Builder(
                                    deviceActivity. 
  this 
  );
                            aler.setMessage( 
  " 
  删除数据后,系统将会重新启动.确定吗? 
  " 
  );
                            aler.setPositiveButton(android.R.string.ok,
                                     
  new 
   DialogInterface.OnClickListener() {

                                        @Override
                                         
  public 
    
  void 
   onClick(
                                                DialogInterface dialog,
                                                 
  int 
   which) {
                                             
  // 
   TODO Auto-generated method stub 
  
 
                                               
  boolean 
   active  
  = 
   mDPM
                                                    .isAdminActive(mDeviceComponentName);
                                             
  if 
   (active) {
                                                mDPM.wipeData( 
  0 
  );
                                            }
                                        }
                                    });
                            aler
                                    .setNeutralButton(android.R.string.cancel,
                                             
  null 
  );
                            aler.show();
                        }
                    });
            builder.setNeutralButton(android.R.string.cancel,  
  null 
  );
            builder.show();
        }
    }



复制代码


 

API的提供简化了很多烦琐的操作,就上面那些代码就可以实现了,完整代码如下:

package com.terry.device;

import android.app.Activity;
import android.app.ActivityManager;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.app.admin.DevicePolicyManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;

public class deviceActivity extends Activity {
    static final int RESULT_ENABLE = 1;
    DevicePolicyManager mDPM;
    ActivityManager mAM;
    ComponentName mDeviceComponentName;
    Button enableAdmin, disableAdmin, force_lock, btn_time_out, reset;
    EditText et;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        mDPM = (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE);
        mAM = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
        mDeviceComponentName = new ComponentName(deviceActivity.this,
                deviceAdminReceiver.class);
        setContentView(R.layout.main);

        findView();

        init();

    }

    void findView() {
        enableAdmin = (Button) findViewById(R.id.enable_admin);
        disableAdmin = (Button) findViewById(R.id.disable_admin);
        force_lock = (Button) findViewById(R.id.force_lock);
        btn_time_out = (Button) findViewById(R.id.time_out);
        et = (EditText) findViewById(R.id.et_time_out);
        reset = (Button) findViewById(R.id.reset);
    }

    void init() {
        enableAdmin.setOnClickListener(new enableAdminClickEvent());
        disableAdmin.setOnClickListener(new disableAdminClickEvent());
        force_lock.setOnClickListener(new force_lock());
        btn_time_out.setOnClickListener(new timeoutClickEvent());
        reset.setOnClickListener(new resetClickEvent());
    }

    void updateButtonState() {
        boolean active = mDPM.isAdminActive(mDeviceComponentName);
        if (active) {
            enableAdmin.setEnabled(false);
            disableAdmin.setEnabled(true);
            force_lock.setEnabled(true);
            btn_time_out.setEnabled(true);
            reset.setEnabled(true);
        } else {
            enableAdmin.setEnabled(true);
            disableAdmin.setEnabled(false);
            force_lock.setEnabled(false);
            btn_time_out.setEnabled(false);
            reset.setEnabled(false);
        }
    }

    @Override
    protected void onResume() {
        // TODO Auto-generated method stub
        super.onResume();
        updateButtonState();
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        // TODO Auto-generated method stub
        switch (requestCode) {
        case RESULT_ENABLE:
            if (resultCode == Activity.RESULT_OK) {
                Log.v("DeviceEnable", "deviceAdmin:enable");
            } else {
                Log.v("DeviceEnable", "deviceAdmin:disable");
            }
            break;

        }

        super.onActivityResult(requestCode, resultCode, data);
    }

    /**
     * 设备管理可用的点击事件
     * 
     * @author terry
     * 
     */
    class enableAdminClickEvent implements OnClickListener {

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            Intent intent = new Intent(
                    DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN);
            intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN,
                    mDeviceComponentName);
            intent.putExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION,
                    "这里可以输入一些额外的说明,比如提示用户什么的");
            startActivityForResult(intent, RESULT_ENABLE);
        }

    }

    /**
     * 设备管理不可用的点击事件
     * 
     * @author terry
     * 
     */
    class disableAdminClickEvent implements OnClickListener {

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            mDPM.removeActiveAdmin(mDeviceComponentName);
            updateButtonState();
        }

    }

    /**
     * 锁屏
     * 
     * @author terry
     * 
     */
    class force_lock implements OnClickListener {

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            if (mAM.isUserAMonkey()) {
                AlertDialog.Builder builder = new AlertDialog.Builder(
                        deviceActivity.this);
                builder.setMessage("你不能对此屏幕进行操作,因为你不是管理员");
                builder.setPositiveButton("I admit defeat", null);
                builder.show();
                return;
            }
            boolean active = mDPM.isAdminActive(mDeviceComponentName);
            if (active) {
                mDPM.lockNow();
            }
        }
    }

    /**
     * 屏幕自动变暗
     * 
     * @author terry
     * 
     */
    class timeoutClickEvent implements OnClickListener {

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            if (mAM.isUserAMonkey()) {
                AlertDialog.Builder builder = new AlertDialog.Builder(
                        deviceActivity.this);
                builder.setMessage("你不能对我的屏幕进行操作,因为你不是管理员");
                builder.setPositiveButton("I admit defeat", null);
                builder.show();
                return;
            }
            boolean active = mDPM.isAdminActive(mDeviceComponentName);
            if (active) {
                long timeout = 1000L * Long.parseLong(et.getText().toString());
                mDPM.setMaximumTimeToLock(mDeviceComponentName, timeout);
            }
        }
    }

    /**
     * 恢复出厂设置
     * 
     * @author terry
     * 
     */
    class resetClickEvent implements OnClickListener {

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            if (mAM.isUserAMonkey()) {
                // Don't trust monkeys to do the right thing!
                AlertDialog.Builder builder = new AlertDialog.Builder(
                        deviceActivity.this);
                builder
                        .setMessage("You can't wipe my data because you are a monkey!");
                builder.setPositiveButton("I admit defeat", null);
                builder.show();
                return;
            }

            AlertDialog.Builder builder = new Builder(deviceActivity.this);
            builder.setMessage("将重置数据,你确定此操作吗?");
            builder.setPositiveButton(android.R.string.ok,
                    new DialogInterface.OnClickListener() {

                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            // TODO Auto-generated method stub
                            AlertDialog.Builder aler = new AlertDialog.Builder(
                                    deviceActivity.this);
                            aler.setMessage("删除数据后,系统将会重新启动.确定吗?");
                            aler.setPositiveButton(android.R.string.ok,
                                    new DialogInterface.OnClickListener() {

                                        @Override
                                        public void onClick(
                                                DialogInterface dialog,
                                                int which) {
                                            // TODO Auto-generated method stub
                                            boolean active = mDPM
                                                    .isAdminActive(mDeviceComponentName);
                                            if (active) {
                                                mDPM.wipeData(0);
                                            }
                                        }
                                    });
                            aler
                                    .setNeutralButton(android.R.string.cancel,
                                            null);
                            aler.show();
                        }
                    });
            builder.setNeutralButton(android.R.string.cancel, null);
            builder.show();
        }
    }

}