Android 2.2 SDK提供了一个可管理和操作设备的API叫DevicePolicyManager,使用这个API你可以接管手机的应用权限,对手机做出很多大胆的操作,比如锁屏,恢复出厂设置(这么和谐的东西要是在中国是不大可能提供给你的),还有设置密码、强制清除密码,修改密码、设置屏幕灯光渐暗时间间隔等操作。这个API可谓是直接可以将你做的应用程序变成系统的老大哥了。虽说是这样,但应用程序可做老大只是对于你本身应用程序有效,别人也可以做类似的应用程序,这个与别人的权限是不起冲突的。
好了,废话不说,上界面:
具体的编写代码的流程:
1.因为这个API是用的2.2提供的API,所以必须将sdkVersion设置为8,像这样<uses-sdk android:minSdkVersion="8" />,这是必须的。
2.注册一个广播服务类,用以监听权限的变化:
< receiver android:name =".deviceAdminReceiver" android:label ="@string/app_name" android:description ="@string/description" android:permission ="android.permission.BIND_DEVICE_ADMIN" > < meta-data android:name ="android.app.device_admin" android:resource ="@xml/device_admin" /> < intent-filter > < action android:name ="android.app.action.DEVICE_ADMIN_ENABLED" /> </ intent-filter > </ receiver >
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。
下面先来看看操作效果,点击启用管理:
数据显示不完全 ,往下拉将看到:
中间有一句话叫做:“设备管理可以对系统的一些安全进行设置”,这句话来源于上面的广播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的提供简化了很多烦琐的操作,就上面那些代码就可以实现了,完整代码如下:
DeviceActivity 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(); } }}
如果对你有帮助或者你现在有空闲,希望您能移下贵步帮我投下票,谢谢了:传送门
转载于:https://www.cnblogs.com/TerryBlog/archive/2010/12/16/1907721.html
相关资源:数据结构—成绩单生成器