Android项目实战_手机安全卫士程序锁

###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<ApplockInfo> unlockList;
 39     private List<ApplockInfo> 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<String> all = dao.findAll();
 82         System.out.println("all :"+all);
 83         List<ApplicationInfo> appInfo = pm.getInstalledApplications(0);
 84         unlockList = new ArrayList<ApplockInfo>();
 85         lockList = new ArrayList<ApplockInfo>();
 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         @Override
112         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         @Override
123         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                 @Override
148                 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         @Override
193         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         @Override
203         public long getItemId(int position) {
204             // TODO Auto-generated method stub
205             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     @Override
221     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 <?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 
 7     <RelativeLayout
 8         android:layout_width="match_parent"
 9         android:layout_height="wrap_content"
10         android:background="#A1FF80" >
11 
12         <TextView
13             android:id="@+id/tv_title"
14             android:layout_width="match_parent"
15             android:layout_height="46dp"
16             android:layout_marginLeft="5dip"
17             android:gravity="center_vertical"
18             android:text="程序锁"
19             android:textSize="20sp" />
20 
21         <LinearLayout
22             android:layout_width="wrap_content"
23             android:layout_height="wrap_content"
24             android:layout_centerInParent="true"
25             android:orientation="horizontal" >
26 
27             <Button
28                 android:id="@+id/bt_unlock"
29                 android:layout_width="wrap_content"
30                 android:layout_height="30dip"
31                 android:background="#5300FF"
32                 android:text="未加锁"
33                 android:textColor="#ffffff" />
34             <TextView
35                 android:layout_width="1dip"
36                 android:layout_height="30dip"
37                 android:background="#ffffff"
38                 />
39 
40             <Button
41                 android:id="@+id/bt_lock"
42                 android:layout_width="wrap_content"
43                 android:layout_height="30dip"
44                 android:background="#5f00F0"
45                 android:text="已加锁"
46                 android:textColor="#ffffff" />
47         </LinearLayout>
48     </RelativeLayout>
49 
50     <RelativeLayout
51         android:layout_width="match_parent"
52         android:layout_height="match_parent" >
53 
54         <TextView
55             android:id="@+id/tv_locksoft"
56             android:layout_width="match_parent"
57             android:layout_height="wrap_content"
58             android:text="未加锁程序:12个" />
59 
60         <TextView
61             android:id="@+id/tv_unlocksoft"
62             android:layout_width="match_parent"
63             android:layout_height="wrap_content"
64             android:text="已加锁程序:5个" />
65 
66         <ListView
67             android:id="@+id/lv_locksoft"
68             android:layout_width="match_parent"
69             android:layout_height="match_parent"
70             android:layout_below="@id/tv_locksoft" />
71 
72         <ListView
73             android:id="@+id/lv_unlocksoft"
74             android:layout_width="match_parent"
75             android:layout_height="match_parent"
76             android:layout_below="@id/tv_unlocksoft" />
77     </RelativeLayout>
78 
79 </LinearLayout>
View Code

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

posted @ 2017-06-12 11:04  想今生得与失  阅读(467)  评论(0编辑  收藏  举报