应用程序不被删除,获得admin权限,锁屏

本文深入探讨了Android设备管理器API的使用,包括如何通过API实现锁屏、恢复出厂设置、设置密码等功能,以及如何利用这些功能对设备进行精细化管理。文章详细介绍了API的注册、权限申请、接收广播事件以及具体操作代码实现,帮助开发者掌握设备管理的高级特性。

应用程序不能卸载是因为在手机的安全-->设备管理器中进行了激活,只要取消激活就能删除


所以以下操作是为了对应用进行激活,从而导致不能随便卸载应用


android手机锁屏必须要获得admin权限,如果一个应用获得了admin权限,则普通的卸载将不能删除此软件


参考:http://labs.chinamobile.com/mblog/532767_73990


        【LockScreenActivity】

        // 自动获得Admin权限以及锁屏
        DevicePolicyManager dManager = (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE);
        ComponentName name = new ComponentName(LockScreenActivity.this, IDeviceAdminReceiver.class);//当前activity和获得权限的receiver
        if (dManager.isAdminActive(name))
        {
            Log.d(TAG, "Lock success");
            dManager.lockNow();
        }
        else
        {
            Log.d(TAG, "Lock fail");
            Intent intent = new Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN);
            intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, name);
            intent.putExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION, "Additional text explaining why this needs to be added.");
            startActivityForResult(intent, 1);
        }


【IDeviceAdminReceiver】

public class IDeviceAdminReceiver extends DeviceAdminReceiver
{


    private Handler mHandler;


    public static final int GET_ADMIN = 250;


    public void setObserver(Handler handler)
    {
        this.mHandler = handler;
    }


    private static final String TAG = "MyAdmin";


    // implement onEnabled(), onDisabled(), …
    public void onEnabled(Context context, Intent intent)
    {
        if (mHandler != null)
        {
            mHandler.sendEmptyMessage(GET_ADMIN);
        }
        Log.d(TAG, "MyAdmin enabled");
    }


    public void onDisabled(Context context, Intent intent)
    {
        Log.d(TAG, "MyAdmin disabled");
    }
}


【AndroidManifest.xml】

        <receiver
            android:description="@string/phone_receiverDescription"
            android:label="@string/app_name"
            android:name="com.XXXXXX.IDeviceAdminReceiver"
            android:permission="android.permission.BIND_DEVICE_ADMIN" >表示此功能需要的权限
            <meta-data
                android:name="android.app.device_admin"
                android:resource="@xml/idevice_admin" />表示这个应用可以管理的权限清单,xml清单如下:


            <intent-filter >
                <action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />表示此动作的跳转界面
            </intent-filter>
        </receiver>


【idevice_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>


-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

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();
            }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值