博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android项目实战_手机安全卫士程序锁
阅读量:7059 次
发布时间:2019-06-28

本文共 12593 字,大约阅读时间需要 41 分钟。

###1.两个页面切换的实现

1. 可以使用Fragment,调用FragmentTransaction的hide和show方法
2. 可以使用两个布局,设置visibility的VISIABLE和INVISIABLE
3. 可以使用一套布局,切换不同的显示数据

###2.已加锁、未加锁界面数据的获取思路

1. 获取所有的应用
2. 这些应用只可能是未加锁或者已加锁
3. 根据数据库中存储的已加锁的情况,将所有数据分别装到已加锁和未加锁两个集合中

###3.动画播放需要注意什么

1. 动画的播放是非阻塞式的,相当于开启了一个子线程定期的刷新UI
2. 如果想在动画播完之后执行一些操作,需要设置监听器

ta.setAnimationListener(new AnimationListener() {

@Override
public void onAnimationStart(Animation animation) {
//动画开始播放了。。。
}
@Override
public void onAnimationRepeat(Animation animation) {
//动画重复播放了。
}
@Override
public void onAnimationEnd(Animation animation) {
//动画播放完毕了。
//从当前页面把应用程序条目给移除
unlockPackinfos.remove(position);
unlockItemsAdapter.notifyDataSetChanged();
//把数据加入到已加锁的列表里面
lockedPackinfos.add(packInfo);
lockedItemsAdapter.notifyDataSetChanged();
}
});

###4.程序锁的工作原理

1. 开启一个服务一直去监听最新开启的应用
2. 判断新开启的应用是否是已加锁的应用
3. 如果是已加锁应用,弹出输入密码对话框

4. 获取正在运行的应用,需要权限<uses-permission android:name="android.permission.GET_TASKS"/>

//获取到当前手机的任务栈

List<RunningTaskInfo> infos = am.getRunningTasks(1000);
//获取任务栈最上面的Activity
String packname = infos.get(0).topActivity.getPackageName();
System.out.println("正在运行:"+packname);

###5.非Activity里启动Activity有什么要注意的

需要设置flag————Intent.FLAG_ACTIVITY_NEW_TASK

Intent intent = new Intent(WatchDogService.this,EnterPasswordActivity.class);

intent.putExtra("packname", packname);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);

###6.如何监听返回键,打开桌面

@Override

public void onBackPressed() {
// <action android:name="android.intent.action.MAIN" />
// <category android:name="android.intent.category.HOME" />
// <category android:name="android.intent.category.DEFAULT" />
Intent intent = new Intent();
intent.setAction("android.intent.action.MAIN");
intent.addCategory("android.intent.category.HOME");
intent.addCategory("android.intent.category.DEFAULT");
startActivity(intent);
}

###7.Activity的启动模式

(1)standard:每次激活Activity时(startActivity),都创建Activity实例,并放入任务栈;
![](http://i.imgur.com/64EfO0V.png)

(2)singleTop:如果某个Activity自己激活自己,即任务栈栈顶就是该Activity,则不需要创建,其余情况都要创建Activity实例;

![](http://i.imgur.com/7iYx5y8.png)

(3)singleTask:如果要激活的那个Activity在任务栈中存在该实例,则不需要创建,只需要把此Activity放入栈顶,并把该Activity以上的Activity实例都pop;

![](http://i.imgur.com/lHBkS2d.png)

(4)singleInstance:会单独创建一个Activity栈;

![](http://i.imgur.com/adhFrrx.png)

###8.程序锁的优化

1. 将while循环里每次都创建的变量放到循环外面,只创建一次
//修改前
while(flag){
List<RunningTaskInfo> infos = am.getRunningTasks(1000);
String packname = infos.get(0).topActivity.getPackageName();

//修改后

List<RunningTaskInfo> infos;
String packname;
while(flag){
infos = am.getRunningTasks(1000);
packname = infos.get(0).topActivity.getPackageName();
2. 获取正在运行的应用时,只需要获取到第一个就可以了,将集合大小设置为1

//修改前

infos = am.getRunningTasks(1000);

//修改后

infos = am.getRunningTasks(1);
3. 每次都查询数据库比较耗时,将数据库的内容都查询出来,放到一个集合里,以后查询的时候就去查询内存中的集合数据

//修改前

if(dao.find(packname)){//每次都查询数据库

//修改后

1.在ApplockDao中添加一个查询所有已加锁应用的方法
public List<String> findAll() {
List<String> lockedPacknames = new ArrayList<String>();
SQLiteDatabase db = helper.getReadableDatabase();
Cursor cursor = db.rawQuery("select packname from lockinfo", null);
while (cursor.moveToNext()) {
lockedPacknames.add(cursor.getString(0));
}
cursor.close();
db.close();
return lockedPacknames;
}
2.声明一个成员变量,onCreate方法中将所有数据查询出来
private List<String> lockedPacknames;

@Override

public void onCreate() {
...
...
//获取的是数据库锁定的全部的包名
lockedPacknames = dao.findAll();
...
...
}

3.查询的时候直接去查询内存中的数据

if(lockedPacknames.contains(packname)){//查询内存

###9. 如何利用内容观察者同步数据库变化

1. 在AppLockDao中的add和delete方法中,加入修改数据库的通知
//添加或删除一条记录
Uri uri = Uri.parse("content://com.hb.mobilesafe.applockdb");
context.getContentResolver().notifyChange(uri, null);
2. 在WatchDogService中注册内容观察者

//注册内容观察者观察数据库内容的变化

Uri uri = Uri.parse("content://com.hb.mobilesafe.applockdb");
observer = new MyObserver(new Handler());
getContentResolver().registerContentObserver(uri, true, observer);

//内容观察者

private class MyObserver extends ContentObserver{

public MyObserver(Handler handler) {

super(handler);
}

//内容观察者观察到数据变化调用的方法

@Override
public void onChange(boolean selfChange) {
Log.i(TAG,"看门狗里面的内容观察者观察到了数据库变化。。。。");
lockedPacknames = dao.findAll();
super.onChange(selfChange);
}
}

上面的方式在观察到数据库的变化时,又重新查询了所有的数据,还是不够优化,实际上我们在add或者delete时只是对一条数据进行了操作,可以利用uri将add或者delete的数据通知出来

1. 在AppLockDao中的add和delete方法中,加入修改数据库的通知,通知时带出操作和所操作的包名

//添加数据

Uri uri = Uri.parse("content://com.hb.mobilesafe.applockdb?add="+packname);
context.getContentResolver().notifyChange(uri, null);

//删除数据

Uri uri = Uri.parse("content://com.hb.mobilesafe.applockdb?delete="+packname);
context.getContentResolver().notifyChange(uri, null);
2. 在WatchDogService中注册内容观察者,根据不同的uri,做出不同的操作

private class MyObserver extends ContentObserver{

public MyObserver(Handler handler) {

super(handler);
}
@Override
public void onChange(boolean selfChange, Uri uri) {
// TODO Auto-generated method stub
String query = uri.getQuery();
Log.i(TAG, "query--->"+query);
Set<String> names = uri.getQueryParameterNames();
for(String name : names){
Log.i(TAG, "name--->"+name);
List<String> parameters = uri.getQueryParameters(name);
for(String parameter : parameters){
Log.i(TAG, "parameter--->"+parameter);
}
}
super.onChange(selfChange);
}
}

//对应的log

query--->add=com.android.calculator2
name--->add
parameter--->com.android.calculator2

###10. 接收屏幕锁屏和亮起的广播

Intent.ACTION_SCREEN_ON
Intent.ACTION_SCREEN_OFF

1 package com.hb.mobilesafe.activities;  2   3 import java.util.ArrayList;  4 import java.util.List;  5   6 import android.app.Activity;  7 import android.content.pm.ApplicationInfo;  8 import android.content.pm.PackageManager;  9 import android.os.Bundle; 10 import android.view.View; 11 import android.view.View.OnClickListener; 12 import android.view.ViewGroup; 13 import android.view.Window; 14 import android.widget.BaseAdapter; 15 import android.widget.Button; 16 import android.widget.ImageView; 17 import android.widget.ListView; 18 import android.widget.TextView; 19  20 import com.hb.demo_mobilesafe.R; 21 import com.hb.mobilesafe.bean.ApplockInfo; 22 import com.hb.mobilesafe.dbdao.AppLockDao; 23  24 public class SoftLockActivity extends Activity implements OnClickListener { 25     private PackageManager pm; 26  27     private Button bt_unlock; 28     private Button bt_lock; 29     private TextView tv_unlocksoft; 30     private TextView tv_locksoft; 31     private ListView lv_unlocksoft; 32     private ListView lv_locksoft; 33  34     private MylocksoftAdapter unlockadapter; 35     private MylocksoftAdapter lockadapter; 36  37     private boolean flags=false; 38     private List
unlockList; 39 private List
lockList; 40 41 private AppLockDao dao; 42 43 @Override 44 protected void onCreate(Bundle savedInstanceState) { 45 // TODO Auto-generated method stub 46 super.onCreate(savedInstanceState); 47 requestWindowFeature(Window.FEATURE_NO_TITLE); 48 setContentView(R.layout.activity_softlock); 49 initView(); 50 } 51 /** 52 * 找Id 53 */ 54 private void initView() { 55 bt_unlock=(Button) findViewById(R.id.bt_unlock); 56 bt_lock=(Button) findViewById(R.id.bt_lock); 57 tv_unlocksoft=(TextView) findViewById(R.id.tv_unlocksoft); 58 tv_locksoft=(TextView) findViewById(R.id.tv_locksoft); 59 lv_unlocksoft=(ListView) findViewById(R.id.lv_unlocksoft); 60 lv_locksoft=(ListView) findViewById(R.id.lv_locksoft); 61 bt_unlock.setOnClickListener(this); 62 bt_lock.setOnClickListener(this); 63 getAllAppInfo(); 64 InitUI(); 65 66 } 67 /** 68 * 初始化界面 69 */ 70 private void InitUI() { 71 tv_locksoft.setVisibility(View.INVISIBLE); 72 lv_locksoft.setVisibility(View.INVISIBLE); 73 74 } 75 /** 76 * 获取手机上的APP 77 */ 78 public void getAllAppInfo(){ 79 pm = getPackageManager(); 80 dao = new AppLockDao(this); 81 List
all = dao.findAll(); 82 System.out.println("all :"+all); 83 List
appInfo = pm.getInstalledApplications(0); 84 unlockList = new ArrayList
(); 85 lockList = new ArrayList
(); 86 for (ApplicationInfo mInfo : appInfo) { 87 ApplockInfo lockInfo = new ApplockInfo(); 88 lockInfo.setIcon(mInfo.loadIcon(pm)); 89 lockInfo.setAppName(mInfo.loadLabel(pm).toString()); 90 lockInfo.setAppPackageName(mInfo.packageName); 91 //判断是加锁还是未加锁 92 if(all.contains(mInfo.packageName)){ 93 lockList.add(lockInfo); 94 }else{ 95 unlockList.add(lockInfo); 96 } 97 if(!flags){ 98 unlockadapter=new MylocksoftAdapter(); 99 lv_unlocksoft.setAdapter(unlockadapter);100 }else{101 lockadapter = new MylocksoftAdapter();102 lv_locksoft.setAdapter(lockadapter);103 104 }105 }106 }107 class MylocksoftAdapter extends BaseAdapter{108 109 private ApplockInfo info;110 111 @Override112 public int getCount() {113 if(!flags){114 tv_unlocksoft.setText("未加锁程序"+unlockList.size()+"个");115 return unlockList.size();116 }else{117 tv_locksoft.setText("已加锁程序"+lockList.size()+"个");118 return lockList.size();119 120 }121 }122 @Override123 public View getView(final int position, View convertView, ViewGroup parent) {124 ViewHolder holder=null;125 if(convertView != null){126 holder = (ViewHolder) convertView.getTag();127 }else{128 holder=new ViewHolder();129 convertView=View.inflate(SoftLockActivity.this, R.layout.unlock_item, null);130 holder.iv_appicon =(ImageView) convertView.findViewById(R.id.iv_appicon);131 holder.tv_appname= (TextView) convertView.findViewById(R.id.tv_appname);132 holder.iv_status=(ImageView) convertView.findViewById(R.id.iv_status);133 convertView.setTag(holder);134 }135 final ApplockInfo info = (ApplockInfo) getItem(position);136 holder.iv_appicon.setImageDrawable(info.getIcon());137 holder.tv_appname.setText(info.getAppName());138 if(!flags){139 holder.iv_status.setBackgroundResource(R.drawable.btn_lock_selector);140 }else{141 holder.iv_status.setBackgroundResource(R.drawable.btn_unlock_selector);142 143 }144 145 holder.iv_status.setOnClickListener(new OnClickListener() {146 147 @Override148 public void onClick(View v) {149 if(flags){150 /**151 * 已加锁152 */153 new Thread(){154 public void run() {155 dao.delete(lockList.get(position).getAppPackageName());156 unlockList.add(info);157 runOnUiThread(new Runnable() {158 public void run() {159 lockList.remove(info);160 tv_locksoft.setText("已加锁程序"+lockList.size()+"个");161 lockadapter.notifyDataSetChanged();162 }163 });164 165 };166 }.start();167 }else{168 /**169 * 未加锁170 */171 new Thread(){172 public void run() {173 dao.add(unlockList.get(position).getAppPackageName());174 lockList.add(info);175 runOnUiThread(new Runnable() {176 public void run() {177 unlockList.remove(info);178 tv_unlocksoft.setText("未加锁程序"+unlockList.size()+"个");179 unlockadapter.notifyDataSetChanged();180 }181 });182 183 };184 }.start();185 186 }187 }188 });189 190 return convertView;191 }192 @Override193 public Object getItem(int position) {194 if(!flags){195 info = unlockList.get(position);196 }else{197 info = lockList.get(position);198 }199 return info;200 }201 202 @Override203 public long getItemId(int position) {204 // TODO Auto-generated method stub205 return 0;206 }207 208 209 210 }211 static class ViewHolder{212 ImageView iv_appicon;213 TextView tv_appname;214 ImageView iv_status;215 }216 /**217 * 已加锁与未加锁的点击事件218 * 219 */220 @Override221 public void onClick(View v) {222 switch (v.getId()) {223 case R.id.bt_unlock:224 flags=false;225 tv_locksoft.setVisibility(View.INVISIBLE);226 lv_locksoft.setVisibility(View.INVISIBLE);227 tv_unlocksoft.setVisibility(View.VISIBLE);228 lv_unlocksoft.setVisibility(View.VISIBLE);229 unlockadapter=new MylocksoftAdapter();230 lv_unlocksoft.setAdapter(unlockadapter);231 break;232 233 case R.id.bt_lock:234 flags=true;235 tv_unlocksoft.setVisibility(View.INVISIBLE);236 lv_unlocksoft.setVisibility(View.INVISIBLE);237 tv_locksoft.setVisibility(View.VISIBLE);238 lv_locksoft.setVisibility(View.VISIBLE);239 lockadapter=new MylocksoftAdapter();240 lv_locksoft.setAdapter(lockadapter);241 break;242 }243 }244 245 }

xml:

1 
2
6 7
11 12
20 21
26 27
34
39 40
47
48 49 50
53 54
59 60
65 66
71 72
77 78 79
View Code

 到这里整个项目已接近尾声,但这里也有许多代码没有贴出来如果感兴趣的可以看看笔者的源码:http://pan.baidu.com/s/1i59msz7

转载于:https://www.cnblogs.com/boket/p/6991871.html

你可能感兴趣的文章
PowerShell记录脚本运行过程
查看>>
OpenSUSE下启动ssh和samba服务以及防火墙设置
查看>>
linux nethogs查看进程流量
查看>>
pip 安装报utf-8错解决办法
查看>>
django 中form在html中的简单使用
查看>>
lync 2013标准版安装
查看>>
【C#】在主线程中取消任务的运行方式
查看>>
POJ-2715(Water)
查看>>
防止集群多节点存储访问方法
查看>>
菜鸟学习Linux集群之概念篇
查看>>
我的友情链接
查看>>
使用yum时用Ctrl+C强制终止出现的Error: rpmdb open failed解决方案
查看>>
URPF
查看>>
Linux日志管理详解
查看>>
Linux 实用命令
查看>>
网站制作之网页技巧
查看>>
1672 区间交(贪心)
查看>>
WebService基础介绍
查看>>
jdbc的使用
查看>>
云计算概念--公有云和私有云介绍
查看>>