1.基本思路
①.创建已加锁应用的数据库(字段:_id,packagename),如果应用已加锁,将加锁应用的包名维护到数据库中
②.已加锁+未加锁 == 手机中所有应用(AppInfoProvider)
2.已加锁和未加锁的数据适配器
1 class MyAdapter extends BaseAdapter{ 2 private boolean isLock; 3 /** 4 * @param isLock 用于区分已加锁和未加锁应用的标示 true已加锁数据适配器 false未加锁数据适配器 5 */ 6 public MyAdapter(boolean isLock) { 7 this.isLock = isLock; 8 } 9 @Override 10 public int getCount() { 11 if(isLock){ 12 tv_lock.setText("已加锁应用:"+mLockList.size()); 13 return mLockList.size(); 14 }else{ 15 tv_unlock.setText("未加锁应用:"+mUnLockList.size()); 16 return mUnLockList.size(); 17 } 18 } 19 20 @Override 21 public AppInfo getItem(int position) { 22 if(isLock){ 23 return mLockList.get(position); 24 }else{ 25 return mUnLockList.get(position); 26 } 27 } 28 29 @Override 30 public long getItemId(int position) { 31 return position; 32 } 33 34 @Override 35 public View getView(int position, View convertView, ViewGroup parent) { 36 ViewHolder holder = null; 37 if(convertView == null){ 38 convertView = View.inflate(getApplicationContext(), R.layout.listview_islock_item, null); 39 holder = new ViewHolder(); 40 holder.iv_icon = (ImageView) convertView.findViewById(R.id.iv_icon); 41 holder.tv_name = (TextView) convertView.findViewById(R.id.tv_name); 42 holder.iv_lock = (ImageView) convertView.findViewById(R.id.iv_lock); 43 44 convertView.setTag(holder); 45 }else{ 46 holder = (ViewHolder) convertView.getTag(); 47 } 48 final AppInfo appInfo = getItem(position); 49 final View animationView = convertView; 50 51 holder.iv_icon.setBackgroundDrawable(appInfo.icon); 52 holder.tv_name.setText(appInfo.name); 53 if(isLock){ 54 holder.iv_lock.setBackgroundResource(R.drawable.lock); 55 }else{ 56 holder.iv_lock.setBackgroundResource(R.drawable.unlock); 57 } 58 holder.iv_lock.setOnClickListener(new OnClickListener() { 59 @Override 60 public void onClick(View v) { 61 //添加动画效果,动画默认是非阻塞的,所以执行动画的同时,动画以下的代码也会执行 62 animationView.startAnimation(mTranslateAnimation);//500毫秒 63 //对动画执行过程做事件监听,监听到动画执行完成后,再去移除集合中的数据,操作数据库,刷新界面 64 mTranslateAnimation.setAnimationListener(new AnimationListener() { 65 @Override 66 public void onAnimationStart(Animation animation) { 67 //动画开始的是调用方法 68 } 69 @Override 70 public void onAnimationRepeat(Animation animation) { 71 //动画重复时候调用方法 72 } 73 //动画执行结束后调用方法 74 @Override 75 public void onAnimationEnd(Animation animation) { 76 if(isLock){ 77 //已加锁------>未加锁过程 78 //1.已加锁集合删除一个,未加锁集合添加一个,对象就是getItem方法获取的对象 79 mLockList.remove(appInfo); 80 mUnLockList.add(appInfo); 81 //2.从已加锁的数据库中删除一条数据 82 mDao.delete(appInfo.packageName); 83 //3.刷新数据适配器 84 mLockAdapter.notifyDataSetChanged(); 85 }else{ 86 //未加锁------>已加锁过程 87 //1.已加锁集合添加一个,未加锁集合移除一个,对象就是getItem方法获取的对象 88 mLockList.add(appInfo); 89 mUnLockList.remove(appInfo); 90 //2.从已加锁的数据库中插入一条数据 91 mDao.insert(appInfo.packageName); 92 //3.刷新数据适配器 93 mUnLockAdapter.notifyDataSetChanged(); 94 } 95 } 96 }); 97 } 98 }); 99 return convertView; 100 } 101 }
MyAdapter
mLockAdapter = new MyAdapter(true); lv_lock.setAdapter(mLockAdapter); mUnLockAdapter = new MyAdapter(false); lv_unlock.setAdapter(mUnLockAdapter);
3.已加锁和未加锁条目点击事件处理
holder.iv_lock.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { //添加动画效果,动画默认是非阻塞的,所以执行动画的同时,动画以下的代码也会执行 animationView.startAnimation(mTranslateAnimation);//500毫秒 //对动画执行过程做事件监听,监听到动画执行完成后,再去移除集合中的数据,操作数据库,刷新界面 mTranslateAnimation.setAnimationListener(new AnimationListener() { @Override public void onAnimationStart(Animation animation) { //动画开始的是调用方法 } @Override public void onAnimationRepeat(Animation animation) { //动画重复时候调用方法 } //动画执行结束后调用方法 @Override public void onAnimationEnd(Animation animation) { if(isLock){ //已加锁------>未加锁过程 //1.已加锁集合删除一个,未加锁集合添加一个,对象就是getItem方法获取的对象 mLockList.remove(appInfo); mUnLockList.add(appInfo); //2.从已加锁的数据库中删除一条数据 mDao.delete(appInfo.packageName); //3.刷新数据适配器 mLockAdapter.notifyDataSetChanged(); }else{ //未加锁------>已加锁过程 //1.已加锁集合添加一个,未加锁集合移除一个,对象就是getItem方法获取的对象 mLockList.add(appInfo); mUnLockList.remove(appInfo); //2.从已加锁的数据库中插入一条数据 mDao.insert(appInfo.packageName); //3.刷新数据适配器 mUnLockAdapter.notifyDataSetChanged(); } } }); } });
4.程序锁必须在服务中去维护
①基本思路
1.判断当前开启的应用(现在手机可见任务栈)
2.如果开启的应用在已加锁的列表中,弹出拦截界面
3.看门狗服务,一直(死循环(子线程,可控))对开启的应用做监听
1 public class WatchDogService extends Service { 2 private boolean isWatch; 3 private AppLockDao mDao; 4 private List<String> mPacknameList; 5 private InnerReceiver mInnerReceiver; 6 private String mSkipPackagename; 7 private MyContentObserver mContentObserver; 8 @Override 9 public void onCreate() { 10 //维护一个看门狗的死循环,让其时刻监测现在开启的应用,是否为程序锁中要去拦截的应用 11 mDao = AppLockDao.getInstance(this); 12 isWatch = true; 13 watch(); 14 15 IntentFilter intentFilter = new IntentFilter(); 16 intentFilter.addAction("android.intent.action.SKIP"); 17 18 mInnerReceiver = new InnerReceiver(); 19 registerReceiver(mInnerReceiver, intentFilter); 20 21 22 //注册一个内容观察者,观察数据库的变化,一旦数据有删除或者添加,则需要让mPacknameList重新获取一次数据 23 mContentObserver = new MyContentObserver(new Handler()); 24 getContentResolver().registerContentObserver( 25 Uri.parse("content://applock/change"), true, mContentObserver); 26 super.onCreate(); 27 } 28 29 class MyContentObserver extends ContentObserver{ 30 31 public MyContentObserver(Handler handler) { 32 super(handler); 33 } 34 35 //一旦数据库发生改变时候调用方法,重新获取包名所在集合的数据 36 @Override 37 public void onChange(boolean selfChange) { 38 new Thread(){ 39 public void run() { 40 mPacknameList = mDao.findAll(); 41 }; 42 }.start(); 43 super.onChange(selfChange); 44 } 45 } 46 47 class InnerReceiver extends BroadcastReceiver{ 48 @Override 49 public void onReceive(Context context, Intent intent) { 50 //获取发送广播过程中传递过来的包名,跳过次包名检测过程 51 mSkipPackagename = intent.getStringExtra("packagename"); 52 } 53 } 54 55 private void watch() { 56 //1,子线程中,开启一个可控死循环 57 new Thread(){ 58 public void run() { 59 mPacknameList = mDao.findAll(); 60 while(isWatch){ 61 //2.监测现在正在开启的应用,任务栈 62 //3.获取activity管理者对象 63 ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE); 64 //4.获取正在开启应用的任务栈 65 List<RunningTaskInfo> runningTasks = am.getRunningTasks(1); 66 RunningTaskInfo runningTaskInfo = runningTasks.get(0); 67 //5.获取栈顶的activity,然后在获取此activity所在应用的包名 68 String packagename = runningTaskInfo.topActivity.getPackageName(); 69 70 //如果任务栈指向应用有切换,将mSkipPackagename空字符串 71 72 //6.拿此包名在已加锁的包名集合中去做比对,如果包含次包名,则需要弹出拦截界面 73 if(mPacknameList.contains(packagename)){ 74 //如果现在检测的程序,以及解锁了,则不需要去弹出拦截界面 75 if(!packagename.equals(mSkipPackagename)){ 76 //7,弹出拦截界面 77 Intent intent = new Intent(getApplicationContext(),EnterPsdActivity.class); 78 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 79 intent.putExtra("packagename", packagename); 80 startActivity(intent); 81 } 82 } 83 //睡眠一下,时间片轮转 84 try { 85 Thread.sleep(500); 86 } catch (InterruptedException e) { 87 e.printStackTrace(); 88 } 89 } 90 }; 91 }.start(); 92 93 } 94 @Override 95 public IBinder onBind(Intent arg0) { 96 return null; 97 } 98 @Override 99 public void onDestroy() { 100 //停止看门狗循环 101 isWatch = false; 102 //注销广播接受者 103 if(mInnerReceiver!=null){ 104 unregisterReceiver(mInnerReceiver); 105 } 106 //注销内容观察者 107 if(mContentObserver!=null){ 108 getContentResolver().unregisterContentObserver(mContentObserver); 109 } 110 super.onDestroy(); 111 } 112 }
WatchDogService
时间: 2024-10-21 00:10:38