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();
}
}
}
如果对你有帮助或者你现在有空闲,希望您能移下贵步帮我投下票,谢谢了:传送门