Android项目实战--手机卫士26--内容提供者与内容观察者
我们之前已经把那个手机防盗的基本上做出来的了,但是还是有不少问题的,今天我们就把这些问题修复一下,首先我们就把那个最重要的来修复一下先,就是我们输入密码之后,又会弹出输入密码的界面,这是因为我们没有把那个监听的任务栈暂时的停止,所以它就会又进行判断了,所以就又进入到输入密码的界面了,解决的方法思路就是我们在服务那里新建一个list用来存放那些不用被阻止的应用,当输入完密码之后,我们就先把那个已经输入密码了的加锁了的应用加入到list里面,这样子,我们输入密码后,就不会再弹出输入密码的界面的了。
但是这样子,问题就来了,因为那个list是在服务里面的,那么我们就要调用服务里面的方法啦,这也就回归到我们一开始说程序锁的时候说的通过startService然后再通过bindService来调用服务里面的方法,这样开启的服务既可以长期在后台运行,也可以调用它里面的方法。
调用服务里面的方法很简单的,我们就不多说啦,有不明白的,可以去看看我们之前写的文章调用服务里面的方法
首先我们先新建一个接口
com.xiaobin.security.iservice.IService
package com.xiaobin.security.service;import java.util.ArrayList;import java.util.List;import android.app.ActivityManager;import android.app.KeyguardManager;import android.app.ActivityManager.RunningTaskInfo;import android.app.Service;import android.content.Intent;import android.database.ContentObserver;import android.net.Uri;import android.os.Binder;import android.os.Handler;import android.os.IBinder;import com.xiaobin.security.dao.AppLockDao;import com.xiaobin.security.iservice.IService;import com.xiaobin.security.ui.LockActivity;public class WatchDogService extends Service{private AppLockDao dao;private List<String> apps;private ActivityManager activityManager;private Intent intent;private boolean flag = true;// 存放要停止保护的appprivate List<String> stopApps;private MyBinder myBinder;// 键盘的管理器private KeyguardManager keyguardManager;@Overridepublic IBinder onBind(Intent intent){return myBinder;}// 临时开启对某个应用的保护private void invokeMethodStartApp(String packageName){if (stopApps.contains(packageName)){stopApps.remove(packageName);}}// 临时停止对某个应用的保护private void invokeMethodStopApp(String packageName){stopApps.add(packageName);}@Overridepublic void onCreate(){super.onCreate();keyguardManager = (KeyguardManager) getSystemService(Service.KEYGUARD_SERVICE);myBinder = new MyBinder();dao = new AppLockDao(this);apps = dao.getAllPackageName();stopApps = new ArrayList<String>();activityManager = (ActivityManager) getSystemService(Service.ACTIVITY_SERVICE);// 注册一个内容观察者getContentResolver().registerContentObserver(Uri.parse("content://com.xiaobin.security.applockprovider"),true, new MyObserver(new Handler()));intent = new Intent(this, LockActivity.class);// 服务里面是没有任务栈的,所以要指定一个新的任务栈,不然是无法在服务里面启动activity的intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);new Thread(){public void run(){while (flag){try{// 当解锁后,就再一次输入密码if (keyguardManager.inKeyguardRestrictedInputMode()){stopApps.clear();}// 得到当前运行的任务栈,参数就是得到多少个任务栈,1就是只拿一个任务栈// 1对应的也就是正在运行的任务栈啦List<RunningTaskInfo> runningTaskInfos = activityManager.getRunningTasks(1);// 拿到当前运行的任务栈RunningTaskInfo runningTaskInfo = runningTaskInfos.get(0);// 拿到要运行的Activity的包名String packageName = runningTaskInfo.topActivity.getPackageName();System.out.println("当前在运行:" + packageName);// 这样,我们就可以临时的把一个应用取消保护if (stopApps.contains(packageName)){sleep(1000);continue;}if (apps.contains(packageName)){intent.putExtra("packageName", packageName);startActivity(intent);}else{}sleep(1000);}catch (InterruptedException e){e.printStackTrace();}}}}.start();}@Overridepublic void onDestroy(){super.onDestroy();flag = false;}// ==================================================================private class MyBinder extends Binder implements IService{@Overridepublic void startApp(String packageName){invokeMethodStartApp(packageName);}@Overridepublic void stopApp(String packageName){invokeMethodStopApp(packageName);}}private class MyObserver extends ContentObserver{public MyObserver(Handler handler){super(handler);// 重新更新apps里面的内容apps = dao.getAllPackageName();System.out.println("数据库的内容发生了改变");}}}
最后,和大家说一下
为了方便大家的交流,我创建了一个群,这样子大家有什么疑问也可以在群上交流
群号是298440981
今天源码下载