【0064】【项目实战】-【手机安全卫士】-【4】
1.手势抽取过程&代码复用
1.1 功能描述
【说明】每个页面需要响应滑动事件,因此会抽出一个类,避免代码的复用;也是程序的优化;
将所有的Activity都继承与BaseSetupActivity;

1.2【新建类BaseSetupActivity】




【源码】/mobilesafe74/src/com/itheima/mobilesafe74/activity/BaseSetupActivity.java
1 package com.itheima.mobilesafe74.activity; 2 3 import com.itheima.mobilesafe74.R; 4 import com.itheima.mobilesafe74.utils.ConstantValue; 5 import com.itheima.mobilesafe74.utils.SpUtil; 6 import com.itheima.mobilesafe74.utils.ToastUtil; 7 8 import android.app.Activity; 9 import android.content.Intent; 10 import android.os.Bundle; 11 import android.text.TextUtils; 12 import android.view.GestureDetector; 13 import android.view.MotionEvent; 14 import android.view.View; 15 16 public abstract class BaseSetupActivity extends Activity { 17 private GestureDetector gestureDetector; 18 19 @Override 20 protected void onCreate(Bundle savedInstanceState) { 21 super.onCreate(savedInstanceState); 22 23 //2,创建手势管理的对象,用作管理在onTouchEvent(event)传递过来的手势动作 24 gestureDetector = new GestureDetector(this, new GestureDetector.SimpleOnGestureListener(){ 25 @Override 26 public boolean onFling(MotionEvent e1, MotionEvent e2, 27 float velocityX, float velocityY) { 28 //监听手势的移动 29 if(e1.getX()-e2.getX()>0){ 30 //调用子类的下一页方法,抽象方法 31 32 //在第一个界面上的时候,跳转到第二个界面 33 //在第二个界面上的时候,跳转到第三个界面 34 //....... 35 showNextPage(); 36 } 37 38 if(e1.getX()-e2.getX()<0){ 39 //调用子类的上一页方法 40 //在第一个界面上的时候,无响应,空实现 41 //在第二个界面上的时候,跳转到第1个界面 42 //....... 43 showPrePage(); 44 } 45 46 return super.onFling(e1, e2, velocityX, velocityY); 47 } 48 }); 49 } 50 51 //1,监听屏幕上响应的事件类型(按下(1次),移动(多次),抬起(1次)) 52 @Override 53 public boolean onTouchEvent(MotionEvent event) { 54 //3,通过手势处理类,接收多种类型的事件,用作处理 55 gestureDetector.onTouchEvent(event); 56 return super.onTouchEvent(event); 57 } 58 59 //下一页的抽象方法,由子类决定具体跳转到那个界面 60 protected abstract void showNextPage(); 61 //上一页的抽象方法,由子类决定具体跳转到那个界面 62 protected abstract void showPrePage(); 63 64 65 //点击下一页按钮的时候,根据子类的showNextPage方法做相应跳转 66 public void nextPage(View view){ 67 showNextPage(); 68 } 69 70 //点击上一页按钮的时候,根据子类的showPrePage方法做相应跳转 71 public void prePage(View view){ 72 showPrePage(); 73 } 74 }
1.3 基类的方法的实现
【源码】/mobilesafe74/src/com/itheima/mobilesafe74/activity/Setup1Activity.java
1 package com.itheima.mobilesafe74.activity; 2 3 import com.itheima.mobilesafe74.R; 4 import android.content.Intent; 5 import android.os.Bundle; 6 import android.view.GestureDetector; 7 import android.view.MotionEvent; 8 import android.view.View; 9 10 public class Setup1Activity extends BaseSetupActivity { 11 @Override 12 protected void onCreate(Bundle savedInstanceState) { 13 super.onCreate(savedInstanceState); 14 setContentView(R.layout.activity_setup1); 15 } 16 17 @Override 18 protected void showNextPage() { 19 Intent intent = new Intent(getApplicationContext(), Setup2Activity.class); 20 startActivity(intent); 21 22 finish(); 23 24 //开启平移动画 25 overridePendingTransition(R.anim.next_in_anim, R.anim.next_out_anim); 26 } 27 28 @Override 29 protected void showPrePage() { 30 //空实现 31 } 32 }
【源码】/mobilesafe74/src/com/itheima/mobilesafe74/activity/Setup2Activity.java
1 @Override 2 protected void showNextPage() { 3 4 String serialNumber = SpUtil.getString(this, ConstantValue.SIM_NUMBER, ""); 5 if(!TextUtils.isEmpty(serialNumber)){ 6 Intent intent = new Intent(getApplicationContext(), Setup3Activity.class); 7 startActivity(intent); 8 9 finish(); 10 11 overridePendingTransition(R.anim.next_in_anim, R.anim.next_out_anim); 12 }else{ 13 ToastUtil.show(this,"请绑定sim卡"); 14 } 15 16 } 17 18 @Override 19 protected void showPrePage() { 20 21 Intent intent = new Intent(getApplicationContext(), Setup1Activity.class); 22 startActivity(intent); 23 24 finish(); 25 26 overridePendingTransition(R.anim.pre_in_anim, R.anim.pre_out_anim); 27 28 }
【源码】/mobilesafe74/src/com/itheima/mobilesafe74/activity/Setup3Activity.java
1 @Override 2 protected void showNextPage() { 3 4 //点击按钮以后,需要获取输入框中的联系人,再做下一页操作 5 String phone = et_phone_number.getText().toString(); 6 7 //在sp存储了相关联系人以后才可以跳转到下一个界面 8 // String contact_phone = SpUtil.getString(getApplicationContext(), ConstantValue.CONTACT_PHONE, ""); 9 if(!TextUtils.isEmpty(phone)){ 10 Intent intent = new Intent(getApplicationContext(), Setup4Activity.class); 11 startActivity(intent); 12 13 finish(); 14 15 //如果现在是输入电话号码,则需要去保存 16 SpUtil.putString(getApplicationContext(), ConstantValue.CONTACT_PHONE, phone); 17 18 overridePendingTransition(R.anim.next_in_anim, R.anim.next_out_anim); 19 }else{ 20 ToastUtil.show(this,"请输入电话号码"); 21 } 22 23 } 24 @Override 25 protected void showPrePage() { 26 27 Intent intent = new Intent(getApplicationContext(), Setup2Activity.class); 28 startActivity(intent); 29 30 finish(); 31 32 overridePendingTransition(R.anim.pre_in_anim, R.anim.pre_out_anim); 33 34 } 35 }
【源码】/mobilesafe74/src/com/itheima/mobilesafe74/activity/Setup4Activity.java
1 @Override 2 protected void showNextPage() { 3 boolean open_security = SpUtil.getBoolean(this, ConstantValue.OPEN_SECURITY, false); 4 if(open_security){ 5 Intent intent = new Intent(getApplicationContext(), SetupOverActivity.class); 6 startActivity(intent); 7 8 finish(); 9 SpUtil.putBoolean(this, ConstantValue.SETUP_OVER, true); 10 11 overridePendingTransition(R.anim.next_in_anim, R.anim.next_out_anim); 12 }else{ 13 ToastUtil.show(getApplicationContext(), "请开启防盗保护"); 14 } 15 } 16 17 @Override 18 protected void showPrePage() { 19 Intent intent = new Intent(getApplicationContext(), Setup3Activity.class); 20 startActivity(intent); 21 22 finish(); 23 24 overridePendingTransition(R.anim.pre_in_anim, R.anim.pre_out_anim); 25 }
【界面滑动的效果】



2. 代码复用的回顾
【原理】抽象父类定义的抽象方法,子类继承父类;子类实现父类的抽象方法,在父类调用的时候会根据不同的子类实现的方法实现不同的功能;
【说明】子类会调用父类的onCreate方法,首先执行父类onCreate的方法;

【说明】父类的onCreate方法中首先会创建一个手势识别器的对象,然后监控手册的滑动动作;



3. 手机防盗界面的完成
3.1 效果

3.2【布局源码】
【虚线的生成】


1 <?xml version="1.0" encoding="utf-8"?> 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 android:layout_width="match_parent" 4 android:layout_height="match_parent" 5 android:orientation="vertical" >
6 <TextView 7 android:text="手机防盗" 8 style="@style/TitleStyle"/> 9 <RelativeLayout 10 android:padding="5dp" 11 android:layout_width="match_parent" 12 android:layout_height="wrap_content"> 13 <TextView 14 android:text="安全号码" 15 android:textSize="18sp" 16 android:layout_width="wrap_content" 17 android:layout_height="wrap_content"/> 18 <TextView 19 android:id="@+id/tv_phone" 20 android:textSize="18sp" 21 android:text="0000" 22 android:layout_alignParentRight="true" 23 android:layout_width="wrap_content" 24 android:layout_height="wrap_content"/> 25 <ImageView 26 android:background="@drawable/listview_divider" 27 android:layout_below="@id/tv_phone" //位置位于文字的下方 28 android:layout_width="match_parent" 29 android:layout_height="wrap_content"/>
30 </RelativeLayout> 31 <RelativeLayout 32 android:padding="5dp" 33 android:layout_width="match_parent" 34 android:layout_height="wrap_content"> 35 <TextView 36 android:text="防盗包含是否开启" 37 android:textSize="18sp" 38 android:layout_width="wrap_content" 39 android:layout_height="wrap_content"/> 40 <ImageView 41 android:id="@+id/iv_lock" 42 android:background="@drawable/lock" 43 android:layout_alignParentRight="true" 44 android:layout_width="25dp" 45 android:layout_height="25dp"/> 46 <ImageView 47 android:background="@drawable/listview_divider" 48 android:layout_below="@id/iv_lock" 49 android:layout_width="match_parent" 50 android:layout_height="wrap_content"/> 51 </RelativeLayout>
【说明】选中重新进入设置向导之后具有带有圆角的背景图片效果;
因此:需要使用将圆角的图片画出来;
【参考文档】




【最终的效果】




【对于选择器的调用】
52 <TextView 53 android:id="@+id/tv_reset_setup" 54 android:background="@drawable/selector_reset_setup_bg" //需要维护一个选择器,未选中的则是透明色,选中则是圆角矩形 55 android:text="重新进入设置向导" 56 android:textSize="18sp" 57 android:layout_width="match_parent" 58 android:layout_height="wrap_content"/>
59 <TextView 60 android:id="@+id/tv_reset_setup" 61 android:background="@android:color/darker_gray" 62 android:text="功能简介" 63 android:padding="5dp" 64 android:textSize="18sp" 65 android:layout_width="match_parent" 66 android:layout_height="wrap_content"/> 67 <TextView 68 android:layout_width="wrap_content" 69 android:layout_height="wrap_content" 70 android:textColor="#000" 71 android:textSize="18sp" 72 android:gravity="center_vertical" 73 android:drawableLeft="@android:drawable/star_big_on" 74 android:text="GPS追踪:#*location*#"/> 75 <TextView 76 android:layout_width="wrap_content" 77 android:layout_height="wrap_content" 78 android:textColor="#000" 79 android:textSize="18sp" 80 android:gravity="center_vertical" 81 android:drawableLeft="@android:drawable/star_big_on" 82 android:text="播放报警音乐:#*alarm*#"/> 83 84 <TextView 85 android:layout_width="wrap_content" 86 android:layout_height="wrap_content" 87 android:textColor="#000" 88 android:textSize="18sp" 89 android:gravity="center_vertical" 90 android:drawableLeft="@android:drawable/star_big_on" 91 android:text="数据销毁:#*wipedata*#"/> 92 <TextView 93 android:layout_width="wrap_content" 94 android:layout_height="wrap_content" 95 android:textColor="#000" 96 android:textSize="18sp" 97 android:gravity="center_vertical" 98 android:drawableLeft="@android:drawable/star_big_on" 99 android:text="远程锁屏:#*lockscreen*#"/> 100 101 </LinearLayout>
4. 为TextView增加点击事件选择


【功能1】选择的电话号码的回显

【功能2】textView响应点击事件


【效果】

5.sim卡变更报警功能的添加
【说明】在导航界面2中存在sim卡的选择,如果出现了更换了sim卡播放报警音乐;




【验证开关机是否接收到了广播】




【测试】5556接收到5554发送的短信;



6. 接受短信播放音乐
【说明】依次实现底部列表的功能

【报警音乐的功能】触发接收到短信的丢失手机,该手机就会报警;


【修改编译版本】


【编译版本改回4.3】

【固定做法】




7.GPS 定位功能
7.1 手机定位的三种方式
【说明】有三种方式:前两种方式定位的地点比较模糊,最后一种使用GPS的方法定位精确;

【纯真IP地址数据库】


【基站定位的示意图】

7.2 手机定位的demo




【gps测试】通过真机手机获取实时的经纬度坐标地址;





7.3 真实坐标转换为火星坐标
【说明】真实坐标转换为火星坐标,在火星地图上定位火星坐标才可以得到真实的地理位置;
【说明】下面的算法是进行真实坐标的修正;

【源码】/火星坐标/src/GpsUtils.java
1 public class GpsUtils { 2 public static void main(String[] args) { 3 try { 4 ModifyOffset instance = ModifyOffset.getInstance(ModifyOffset.class.getResourceAsStream("axisoffset.dat")); 5 //标准坐标转换成火星坐标的方法 6 PointDouble s2c = instance.s2c(new PointDouble(116.29090014,40.04308092)); 7 System.out.println(s2c); 8 // 116.29697876701547 9 // 40.044568322258456 10 11 // x=116.2969939685475, y=40.04434854834669 12 } catch (Exception e) { 13 e.printStackTrace(); 14 } 15 } 16 }
【源码】/火星坐标/src/ModifyOffset.java
1 import java.io.InputStream; 2 import java.io.ObjectInputStream; 3 4 /** 5 * 火星地球坐标转化.地图坐标修偏 6 * 7 */ 8 public class ModifyOffset { 9 private static ModifyOffset modifyOffset; 10 static double[] X = new double[660 * 450]; 11 static double[] Y = new double[660 * 450]; 12 13 14 private ModifyOffset(InputStream inputStream) throws Exception { 15 init(inputStream); 16 } 17 18 public synchronized static ModifyOffset getInstance(InputStream is) throws Exception { 19 if (modifyOffset == null) { 20 modifyOffset = new ModifyOffset(is); 21 } 22 return modifyOffset; 23 } 24 25 public void init(InputStream inputStream) throws Exception { 26 ObjectInputStream in = new ObjectInputStream(inputStream); 27 try { 28 int i = 0; 29 while (in.available() > 0) { 30 if ((i & 1) == 1) { 31 Y[(i - 1) >> 1] = in.readInt() / 100000.0d; 32 ; 33 } else { 34 X[i >> 1] = in.readInt() / 100000.0d; 35 ; 36 } 37 i++; 38 } 39 } finally { 40 if (in != null) 41 in.close(); 42 } 43 } 44 45 // standard -> china 标准坐标--->火星坐标 46 public PointDouble s2c(PointDouble pt) { 47 int cnt = 10; 48 double x = pt.x, y = pt.y; 49 while (cnt-- > 0) { 50 if (x < 71.9989d || x > 137.8998d || y < 9.9997d || y > 54.8996d) 51 return pt; 52 int ix = (int) (10.0d * (x - 72.0d)); 53 int iy = (int) (10.0d * (y - 10.0d)); 54 double dx = (x - 72.0d - 0.1d * ix) * 10.0d; 55 double dy = (y - 10.0d - 0.1d * iy) * 10.0d; 56 x = (x + pt.x + (1.0d - dx) * (1.0d - dy) * X[ix + 660 * iy] + dx 57 * (1.0d - dy) * X[ix + 660 * iy + 1] + dx * dy 58 * X[ix + 660 * iy + 661] + (1.0d - dx) * dy 59 * X[ix + 660 * iy + 660] - x) / 2.0d; 60 y = (y + pt.y + (1.0d - dx) * (1.0d - dy) * Y[ix + 660 * iy] + dx 61 * (1.0d - dy) * Y[ix + 660 * iy + 1] + dx * dy 62 * Y[ix + 660 * iy + 661] + (1.0d - dx) * dy 63 * Y[ix + 660 * iy + 660] - y) / 2.0d; 64 } 65 return new PointDouble(x, y); 66 } 67 68 // china -> standard(标准) 69 public PointDouble c2s(PointDouble pt) { 70 int cnt = 10; 71 double x = pt.x, y = pt.y; 72 while (cnt-- > 0) { 73 if (x < 71.9989d || x > 137.8998d || y < 9.9997d || y > 54.8996d) 74 return pt; 75 int ix = (int) (10.0d * (x - 72.0d)); 76 int iy = (int) (10.0d * (y - 10.0d)); 77 double dx = (x - 72.0d - 0.1d * ix) * 10.0d; 78 double dy = (y - 10.0d - 0.1d * iy) * 10.0d; 79 x = (x + pt.x - (1.0d - dx) * (1.0d - dy) * X[ix + 660 * iy] - dx 80 * (1.0d - dy) * X[ix + 660 * iy + 1] - dx * dy 81 * X[ix + 660 * iy + 661] - (1.0d - dx) * dy 82 * X[ix + 660 * iy + 660] + x) / 2.0d; 83 y = (y + pt.y - (1.0d - dx) * (1.0d - dy) * Y[ix + 660 * iy] - dx 84 * (1.0d - dy) * Y[ix + 660 * iy + 1] - dx * dy 85 * Y[ix + 660 * iy + 661] - (1.0d - dx) * dy 86 * Y[ix + 660 * iy + 660] + y) / 2.0d; 87 } 88 return new PointDouble(x, y); 89 } 90 91 } 92 93 class PointDouble { 94 double x, y; 95 96 PointDouble(double x, double y) { 97 this.x = x; 98 this.y = y; 99 } 100 101 public String toString() { 102 return "x=" + x + ", y=" + y; 103 } 104 }
7.4 发送经纬度坐标给指定手机


【说明】需要在关闭应用之后仍然可以一直拿到经纬度的坐标,因此需要开启服务;



【源码】/mobilesafe74/src/com/itheima/mobilesafe74/service/LocationService.java
1 package com.itheima.mobilesafe74.service; 2 3 import android.app.Service; 4 import android.content.Intent; 5 import android.location.Criteria; 6 import android.location.Location; 7 import android.location.LocationListener; 8 import android.location.LocationManager; 9 import android.os.Bundle; 10 import android.os.IBinder; 11 import android.telephony.SmsManager; 12 13 public class LocationService extends Service { 14 @Override 15 public void onCreate() { 16 super.onCreate(); 17 //获取手机的经纬度坐标 18 //1,获取位置管理者对象 19 LocationManager lm = (LocationManager) getSystemService(LOCATION_SERVICE); 20 //2,以最优的方式获取经纬度坐标() 最优的方式:会根据自己的环境条件进行判断使用哪种方式可以获取的地址位置更精确; 21 Criteria criteria = new Criteria(); 22 //允许花费 23 criteria.setCostAllowed(true); 24 criteria.setAccuracy(Criteria.ACCURACY_FINE);//指定获取经纬度的精确度的指定 25 String bestProvider = lm.getBestProvider(criteria, true); 26 //3,在一定时间间隔,移动一定距离后获取经纬度坐标 27 MyLocationListener myLocationListener = new MyLocationListener();
//实时获取地理位置的坐标; 28 lm.requestLocationUpdates(bestProvider, 0, 0, myLocationListener); 29 } 30 31 class MyLocationListener implements LocationListener{ 32 33 @Override 34 public void onLocationChanged(Location location) { 35 //经度 36 double longitude = location.getLongitude(); 37 //纬度 38 double latitude = location.getLatitude(); 39 40 //4,发送短信(添加权限) 41 SmsManager sms = SmsManager.getDefault(); 42 sms.sendTextMessage("5556", null, "longitude = "+longitude+",latitude = "+latitude, null, null); 43 } 44 45 @Override 46 public void onProviderDisabled(String provider) { 47 // TODO Auto-generated method stub 48 49 } 50 51 @Override 52 public void onProviderEnabled(String provider) { 53 // TODO Auto-generated method stub 54 55 } 56 57 @Override 58 public void onStatusChanged(String provider, int status, Bundle extras) { 59 60 } 61 62 } 63 @Override 64 public int onStartCommand(Intent intent, int flags, int startId) { 65 return super.onStartCommand(intent, flags, startId); 66 } 67 @Override 68 public IBinder onBind(Intent arg0) { 69 return null; 70 } 71 @Override 72 public void onDestroy() { 73 super.onDestroy(); 74 } 75 }
【效果】


8.设备管理器使用
8.1 管理员权限
【激活】激活之后就可以使用该应用的功能了;



8.2 文档的阅读




8.3 设备管理器的demo
8.3.1【增加xml内容】

【创建子类】问题1的解决



【创建节点和描述】问题2/3


【问题4】xml的说明文件



【开启激活界面】开启激活界面的activity

8.3.2 开启界面的布局

1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 2 xmlns:tools="http://schemas.android.com/tools" 3 android:layout_width="match_parent" 4 android:layout_height="match_parent" 5 android:orientation="vertical"> 6 7 <Button 8 android:id="@+id/bt_start" 9 android:layout_width="wrap_content" 10 android:layout_height="wrap_content" 11 android:text="一键开启" /> 12 <Button 13 android:id="@+id/bt_lock" 14 android:layout_width="wrap_content" 15 android:layout_height="wrap_content" 16 android:text="一键锁屏" /> 17 <Button 18 android:id="@+id/bt_wipedata" 19 android:layout_width="wrap_content" 20 android:layout_height="wrap_content" 21 android:text="一键清除数据" /> 22 <Button 23 android:id="@+id/bt_uninstall" 24 android:layout_width="wrap_content" 25 android:layout_height="wrap_content" 26 android:text="一键卸载" /> 27 28 </LinearLayout>
8.3.3 开启界面
【说明】其中包含有组件对象

1 package com.example.device; 2 3 import android.net.Uri; 4 import android.os.Bundle; 5 import android.app.Activity; 6 import android.app.admin.DevicePolicyManager; 7 import android.content.ComponentName; 8 import android.content.Context; 9 import android.content.Intent; 10 import android.view.Menu; 11 import android.view.View; 12 import android.view.View.OnClickListener; 13 import android.widget.Button; 14 import android.widget.Toast; 15 16 public class MainActivity extends Activity { 17 18 private ComponentName mDeviceAdminSample; //组件的定义 19 private DevicePolicyManager mDPM; 20 21 @Override 22 protected void onCreate(Bundle savedInstanceState) { 23 super.onCreate(savedInstanceState); 24 setContentView(R.layout.activity_main); 25 26 Button bt_start = (Button) findViewById(R.id.bt_start); 27 Button bt_lock = (Button) findViewById(R.id.bt_lock); 28 Button bt_wipedata = (Button) findViewById(R.id.bt_wipedata); 29 Button bt_uninstall = (Button) findViewById(R.id.bt_uninstall); 30 31 //(上下文环境,广播接受者对应的字节码文件) 32 33 //组件对象可以作为是否激活的判断标志,要创建一个组件 34 mDeviceAdminSample = new ComponentName(this, DeviceAdmin.class); 35 mDPM = (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE); 36 37 bt_start.setOnClickListener(new OnClickListener() { //开启设备管理器 38 @Override 39 public void onClick(View v) { 40 //开启设备管理器的activity 41 Intent intent = new Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN); 42 intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, mDeviceAdminSample); 43 intent.putExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION,"设备管理器"); 44 startActivity(intent); 45 } 46 }); 47 86 }



8.3.4 锁屏
【锁屏】


【效果】

【注意】如果关闭了设备管理器的,没有激活,还使用APP中的一键锁屏功能,则会出现程序崩溃;




【功能的完善】

【效果】在一键锁屏之后需要输入密码才可以进入到应用中;

8.3.5【擦除数据】


1 bt_wipedata.setOnClickListener(new OnClickListener() { 2 @Override 3 public void onClick(View v) { 4 if(mDPM.isAdminActive(mDeviceAdminSample)){ 5 mDPM.wipeData(0);//手机数据 6 // mDPM.wipeData(DevicePolicyManager.WIPE_EXTERNAL_STORAGE);//手机sd卡数据 7 }else{ 8 Toast.makeText(getApplicationContext(), "请先激活", 0).show(); 9 } 10 } 11 });
【效果】模拟器的测试的效果有BUG,会直接关机,但是数据没有清除;在真机上是可以完成的;

8.3.6 一键卸载

【系统自带的卸载界面】不是对话框,而是一个Activity;

【源码查看】需要使用到包名,因为包名是对一个应用程序的唯一标示;


【激活的应用的卸载】


【没有激活的应用的卸载】

8.4 将设备管理器的功能集成到项目中
【说明】需要在短信监听的代码中填写对应的功能;


1 bt_lock.setOnClickListener(new OnClickListener() { //锁屏功能 2 @Override 3 public void onClick(View v) { 4 //是否开启的判断 5 if(mDPM.isAdminActive(mDeviceAdminSample)){ 6 //激活--->锁屏 7 mDPM.lockNow(); 8 //锁屏同时去设置密码 9 mDPM.resetPassword("123", 0); 10 }else{ 11 Toast.makeText(getApplicationContext(), "请先激活", 0).show(); 12 } 13 } 14 }); 15 16 bt_wipedata.setOnClickListener(new OnClickListener() { //擦除数据 17 @Override 18 public void onClick(View v) { 19 if(mDPM.isAdminActive(mDeviceAdminSample)){ 20 mDPM.wipeData(0);//手机数据 21 // mDPM.wipeData(DevicePolicyManager.WIPE_EXTERNAL_STORAGE);//手机sd卡数据 22 }else{ 23 Toast.makeText(getApplicationContext(), "请先激活", 0).show(); 24 } 25 } 26 }); 27 28 bt_uninstall.setOnClickListener(new OnClickListener() { //一键卸载 29 @Override 30 public void onClick(View v) { 31 Intent intent = new Intent("android.intent.action.DELETE"); 32 intent.addCategory("android.intent.category.DEFAULT"); 33 intent.setData(Uri.parse("package:"+getPackageName())); 34 startActivity(intent); 35 } 36 });





浙公网安备 33010602011771号