Android 手机卫士15--程序锁

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

Android 手机卫士15--程序锁的相关文章

[android] 手机卫士应用程序更新和签名

弹出升级对话框 获取AlertDialog.Builder对象,通过new出来 调用Builder对象的setTitle()方法,参数:文本 调用Builder对象的setMessage()方法,参数:文本,json传回来的信息 调用Builder对象的setPositiveButton()方法,设置确定按钮 参数:文本,OnClickListener对象,匿名内部类实现,重写onClick()方法, 方法里面下载APK,替换安装 调用Builder对象的setNegativeButton()方

[android] 手机卫士设备管理权限锁屏

设备管理员 Device Admin 获取DevicePolicyManager对象,通过getSystemService(DEVICE_POLICY_MANAGER),设备策略管理器 调用DevicePolicyManager对象的lockNow()方法,锁定,此时会报 安全异常 新建一个类MyAdmin继承系统的DeviceAdminReceiver,这个是广播接收者 清单文件进行注册 添加<receiver>节点,设置名称 设置权限 android:permission=”android

Android 手机卫士--弹出对话框

在<Android 手机卫士--解析json与消息机制发送不同类型消息>一文中,消息机制发送不同类型的信息还没有完全实现,在出现异常的时候,应该弹出吐司提示异常,代码如下: private Handler mHandler = new Handler() { // public void handleMessage(android.os.Message msg) { switch (msg.what) { case UPDATE_VERSION: //弹出对话框,提示用户更新 //showUp

Android 手机卫士--确认密码对话框编写

本文接着实现“确认密码”功能,也即是用户以前设置过密码,现在只需要输入确认密码 本文地址:http://www.cnblogs.com/wuyudong/p/5940718.html,转载请注明出处. 布局文件和<Android 手机卫士--设置密码对话框>中的布局基本类似,所有copy一下,修改一点细节就搞定: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:and

Android 手机卫士--签名文件说明&amp;包名说明

在<Android 手机卫士--打包生成apk维护到服务器>一文中,实现了新版本的apk到服务器,当打开客户端apk的时候,发现有新版本,提示更新.还实现了利用xutils工具实现了从服务器端下载apk 本文地址:http://www.cnblogs.com/wuyudong/p/5903484.html,转载请注明源地址. 本文实现下载本机apk的安装,过程很简单,参考<Android APK的安装> 代码如下: /** * 安装对应的apk * @param file 安装文件

手机卫士12_软件锁,应用程序相关

1,软件锁(功能描述:当软件处于以加锁的列表中时,打开这个软件会跳转到密码输入界面,输入正确会跳转到软件界面,否则密码错误) ①ui参考 不使用fragment,采用布局叠加隐藏,点击一个文本,就显示一个界面(列表ListView),另一个布局界面隐藏起来(frameLayout帧布局实现). ②程序未加锁界面的展现 找到所有关心的控件,默认把所有的应用程序未加锁界面列表中. 参考条目ui 额外:加锁的小图标带有状态选择器,点击变换图片 横线可以考虑加个宽度为1的imageView; ③点击条目

Android 手机卫士--安装过程中点击回退按钮

本文地址:http://www.cnblogs.com/wuyudong/p/5903707.html,转载请注明源地址. 在手机卫士之前的版本升级的对话框中: 有的用户暂时不想更新,没有点击“稍后再说”,而是选择点击回退按键,那么这时候的逻辑应该是让用户进入home界面而不是splash界面.所以需要添加代码逻辑来控制,添加的代码如下: builder.setOnCancelListener(new OnCancelListener() { @Override public void onCa

Android 手机卫士--阶段小结1

本文地址:http://www.cnblogs.com/wuyudong/p/5904528.html,转载请注明源地址. 本文对之前手机卫士开发进行一个小结. 1.SplashActivity 版本名称的展示,从清单配置文件中获取版本名称,PackageManager 服务端新版本的检测(本地版本号<服务器版本号) 展示logo 2.手机防盗 sim卡绑定:每一款手机都会有相应的卡的序列号,一旦替换掉原有电话卡,序列号会发生改变 3.手机卫士分包 基础课程分包方式,每一个类包名, com.it

Android 手机卫士12--进程管理

1.本进程不能被选中,所以先将checkbox隐藏掉--手机卫士 不能自杀 if(getItem(position).packageName.equals(getPackageName())){ holder.cb_box.setVisibility(View.GONE); }else{ holder.cb_box.setVisibility(View.VISIBLE); } 2.清理选中进程 private void clearAll() { //1,获取选中进程 //2,创建一个记录需要杀死