【0074】【项目实战】-【手机安全卫士】-【14】高级工具-程序锁

1. 程序锁的效果

【说明】

【1】未加锁和已加锁的功能按钮,可以分类查看是否加锁;

【2】执行加锁之后的条目需要进行再分类;

【3】在下次进入程序中的是否加锁的标志需要读取,使用数据库(程序的数据量大,sp存储不合适)进行记录;

2.数据库

2.1【说明】需要建表

 

2.2  数据库的操作

【1】插入和删除操作即可;

 

【源码】/mobilesafe74/src/com/itheima/mobilesafe74/db/dao/AppLockDao.java

 1 package com.itheima.mobilesafe74.db.dao;
 2 
 3 
 4 import java.util.ArrayList;
 5 import java.util.List;
 6 
 7 import android.content.ContentValues;
 8 import android.content.Context;
 9 import android.database.Cursor;
10 import android.database.sqlite.SQLiteDatabase;
11 
12 import com.itheima.mobilesafe74.db.AppLockOpenHelper;
13 
14 public class AppLockDao {
15     private AppLockOpenHelper appLockOpenHelper;
16     //BlackNumberDao单例模式
17     //1,私有化构造方法
18     private AppLockDao(Context context){
19         //创建数据库已经其表机构
20         appLockOpenHelper = new AppLockOpenHelper(context);
21     }
22     //2,声明一个当前类的对象
23     private static AppLockDao appLockDao = null;
24     //3,提供一个静态方法,如果当前类的对象为空,创建一个新的
25     public static AppLockDao getInstance(Context context){
26         if(appLockDao == null){
27             appLockDao = new AppLockDao(context);
28         }
29         return appLockDao;
30     }
31     
32     //插入方法
33     public void insert(String packagename){
34         SQLiteDatabase db = appLockOpenHelper.getWritableDatabase();
35         
36         ContentValues contentValues = new ContentValues();
37         contentValues.put("packagename", packagename);
38         
39         db.insert("applock", null, contentValues);
40         db.close();
41     }
42     //删除方法
43     public void delete(String packagename){
44         SQLiteDatabase db = appLockOpenHelper.getWritableDatabase();
45         
46         ContentValues contentValues = new ContentValues();
47         contentValues.put("packagename", packagename);
48         
49         db.delete("applock", "packagename = ?", new String[]{packagename});
50         
51         db.close();
52     }
53     //查询所有
54     public List<String> findAll(){
55         SQLiteDatabase db = appLockOpenHelper.getWritableDatabase();
56         Cursor cursor = db.query("applock", new String[]{"packagename"}, null, null, null, null, null);
57         List<String> lockPackageList = new ArrayList<String>();
58         while(cursor.moveToNext()){
59             lockPackageList.add(cursor.getString(0));
60         }
61         cursor.close();
62         db.close();
63         return lockPackageList;
64     }
65 }

3. 程序锁布局结构

【说明】线性布局、listView;文本框;按钮;

              已加锁和未加锁的布局进行切换的显示和隐藏;

              已加锁和未加锁的布局一样;

【说明】在高级工具的程序锁中需要注册该按钮的点击事件;

【高级工具-程序锁的布局】

【点击事件的注册】

【新建布局文件】

【背景图片说明】需要使用四张图片,左右两张图片具有不同的圆角;

【布局】分开了未加锁和加锁

 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     <LinearLayout
 8         android:layout_width="match_parent"
 9         android:layout_height="wrap_content"
10         android:gravity="center"
11         android:orientation="horizontal" >
12 
13         <Button
14             android:id="@+id/bt_unlock"
15             android:layout_width="wrap_content"
16             android:layout_height="wrap_content"
17             android:background="@drawable/tab_left_pressed"
18             android:text="未加锁"
19             android:textColor="#fff"
20             android:textSize="18sp" />
21 
22         <Button
23             android:id="@+id/bt_lock"
24             android:layout_width="wrap_content"
25             android:layout_height="wrap_content"
26             android:text="已加锁"
27             android:background="@drawable/tab_right_default"
28             android:textColor="#fff"
29             android:textSize="18sp" />
30     </LinearLayout>
31     <LinearLayout 
32         android:id="@+id/ll_unlock"
33         android:orientation="vertical"
34         android:layout_width="match_parent"
35         android:layout_height="wrap_content">
36         <TextView 
37             android:id="@+id/tv_unlock"
38             android:layout_width="wrap_content"
39             android:layout_height="wrap_content"
40             android:text="未加锁应用"/>
41         <ListView 
42             android:id="@+id/lv_unlock"
43             android:layout_width="match_parent"
44             android:layout_height="match_parent"/>
45     </LinearLayout>
46     <LinearLayout 
47         android:id="@+id/ll_lock"
48         android:orientation="vertical"
49         android:visibility="gone"
50         android:layout_width="match_parent"
51         android:layout_height="wrap_content">
52         <TextView 
53             android:id="@+id/tv_lock"
54             android:layout_width="wrap_content"
55             android:layout_height="wrap_content"
56             android:text="未加锁应用"/>
57         <ListView 
58             android:id="@+id/lv_lock"
59             android:layout_width="match_parent"
60             android:layout_height="match_parent"/>
61     </LinearLayout>
62 </LinearLayout>

【效果】

4.逻辑编写

4.1【区分是否加锁的应用】

4.2【主线程接收子线程的消息】

4.3 已加锁未加锁数据适配器填充

【说明】通过适配器的构造方法的参数确定是否为加锁程序;

【单个条目的布局】加锁与未加锁的条目布局的区别:右侧图片的锁子的区别;

 

【布局】/mobilesafe74/res/layout/listview_islock_item.xml 

【说明】其中没有增加锁的图片,需要根据是否加锁设置进行临时的修改

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
 3     android:layout_width="match_parent"
 4     android:layout_height="wrap_content" >
 5     <ImageView
 6         android:id="@+id/iv_icon"
 7         android:layout_width="45dp"
 8         android:layout_height="45dp"/>
 9     <TextView 
10         android:id="@+id/tv_name"
11         android:text="应用名称"
12         android:textSize="18sp"
13         android:layout_centerVertical="true"
14         android:layout_toRightOf="@id/iv_icon"
15         android:layout_width="wrap_content"
16         android:layout_height="wrap_content"/>
17     <ImageView 
18         android:id="@+id/iv_lock"
19         android:layout_alignParentRight="true"
20          android:layout_centerVertical="true"
21         android:layout_width="25dp"
22         android:layout_height="25dp"/>
23     
24 </RelativeLayout>

【主线程对消息的处理】

【bug】

 【效果】

4.5 未加锁数目的汇总

【bug】问题的原因是将int类型值当做整数使用,在资源文件中找不到;

【修改】

4.6 加锁与未加锁按钮的点击处理

【加锁按钮的事件的处理】

 

 【未加锁按钮的点击事件】

5. 未加锁条目加载到已加锁的界面中的动画

5.1【效果】

【说明】平移动画的效果

5.2 动画的实现

【数据条目的位置的切换】数据条目操作存在两个地方:一个是适配器显示的链表中,一个是数据库中的数据需要删除;

【动画效果的添加】

【小技巧-临时变量的使用】中间赋值,内部类使用外部的对象,需要添加final,但是final修饰的值不能赋值;

                  技巧:使用中间值,将中间值使用final修饰,也可以在内存类中使用;

                 之前的值也可以进行赋值;

【动画的完整添加】

【BUG】动画执行到了下一个条目上;

 【问题的原因】出现问题的原因:

动画也在执行,数据也在改变;
因此出现了数据已经移除,动画
作用在了下一个顶上来的条目上了;

 

【解决方法】将动画的执行设置为阻塞式,只有在动画执行结束之后才可以移除数据;

                      增加动画的事件监听;

 

【效果】

6.看门狗循环检测开启应用是否为已加锁应用

6.1【BUG】图片的宽高没有设置

6.2 应用分类的互相切换

【ui说明】未加锁的应用加锁之后执行动画跳转到已加锁应用中;

              已加锁的应用解锁之后执行动画跳转到未加锁应用中;

6.3【应用逻辑说明】

 

 

6.4 程序锁服务的开启

【说明】需要状态和服务进行绑定;

 

【创建服务】

【监听逻辑】

【注意】

 

【注意】不能频繁的查询,需要延时;现在写的是1ms循环一次,手机会越运行的越来越卡;

6.5【拦截界面获取应用名称图标过程】

 

【新建拦截界面】

【加载拦截界面的布局】

【源码】

 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     <TextView 
 7         android:id="@+id/tv_app_name"
 8         android:text="拦截应用的名称"
 9         android:layout_width="wrap_content"
10         android:layout_height="wrap_content"/>
11     <ImageView
12         android:id="@+id/iv_app_icon"
13         android:background="@drawable/ic_launcher"
14         android:layout_width="45dp"
15         android:layout_height="45dp"/>
16     <EditText 
17         android:id="@+id/et_psd"
18         android:hint="请输入解锁密码"
19         android:inputType="textPassword"   //文本框的属性
20         android:layout_width="match_parent"
21         android:layout_height="wrap_content"/>
22      <Button 
23         android:id="@+id/bt_submit"
24         android:text="提交"
25         android:layout_width="wrap_content"
26         android:layout_height="wrap_content"/>
27 </LinearLayout>

 

【拦截界面的逻辑维护】

 1 package com.itheima.mobilesafe74.activity;
 2 
 3 import com.itheima.mobilesafe74.R;
 4 import com.itheima.mobilesafe74.utils.ToastUtil;
 5 
 6 import android.app.Activity;
 7 import android.content.Intent;
 8 import android.content.pm.ApplicationInfo;
 9 import android.content.pm.PackageManager;
10 import android.content.pm.PackageManager.NameNotFoundException;
11 import android.graphics.drawable.Drawable;
12 import android.os.Bundle;
13 import android.text.TextUtils;
14 import android.view.KeyEvent;
15 import android.view.View;
16 import android.view.View.OnClickListener;
17 import android.widget.Button;
18 import android.widget.EditText;
19 import android.widget.ImageView;
20 import android.widget.TextView;
21 
22 public class EnterPsdActivity extends Activity {
23     private String packagename;
24     private TextView tv_app_name;
25     private ImageView iv_app_icon;
26     private EditText et_psd;
27     private Button bt_submit;
28 
29     @Override
30     protected void onCreate(Bundle savedInstanceState) {
31         super.onCreate(savedInstanceState);
32         //获取包名
33         packagename = getIntent().getStringExtra("packagename");
34         setContentView(R.layout.activity_enter_psd);
35         initUI();
36         initData();
37     }
38 
39     private void initData() {
40         //通过传递过来的包名获取拦截应用的图标以及名称
41         PackageManager pm = getPackageManager();
42         try {
43             ApplicationInfo applicationInfo = pm.getApplicationInfo(packagename,0);
44             Drawable icon = applicationInfo.loadIcon(pm);
45             iv_app_icon.setBackgroundDrawable(icon);  //设置图标
46             tv_app_name.setText(applicationInfo.loadLabel(pm).toString()); //设置应用的名称
47         } catch (NameNotFoundException e) {
48             e.printStackTrace();
49         }
50         //提交按钮的点击事件
51         bt_submit.setOnClickListener(new OnClickListener() {
52             @Override
53             public void onClick(View v) {
54                 String psd = et_psd.getText().toString();
55                 if(!TextUtils.isEmpty(psd)){
56                     if(psd.equals("123")){
57                         //解锁,进入应用,告知看狗口不要再去监听以及解锁的应用,发送广播
58                         Intent intent = new Intent("android.intent.action.SKIP");
59                         intent.putExtra("packagename",packagename);
60                         sendBroadcast(intent);
61                         //解锁:直接结束应用即可;
62                         finish();
63                     }else{
64                         ToastUtil.show(getApplicationContext(), "密码错误");
65                     }
66                 }else{
67                     ToastUtil.show(getApplicationContext(), "请输入密码");
68                 }
69             }
70         });
71     }
72 
73     private void initUI() {
74         tv_app_name = (TextView) findViewById(R.id.tv_app_name);
75         iv_app_icon = (ImageView) findViewById(R.id.iv_app_icon);
76         
77         et_psd = (EditText) findViewById(R.id.et_psd);
78         bt_submit = (Button) findViewById(R.id.bt_submit);
79     }
80     
81     @Override
82     public void onBackPressed() {
83         //通过隐式意图,跳转到桌面
84         Intent intent = new Intent(Intent.ACTION_MAIN);
85         intent.addCategory(Intent.CATEGORY_HOME);
86         startActivity(intent);
87         super.onBackPressed();
88     }
89 }

 【BUG】拿栈需要权限

【此时的效果及问题】不输入密码提示输入密码;密码错误提示;输入正确的密码之后进入到下一界面;但是进入了当前的应用界面(有问题!!!);

 

【问题的原因】栈的原因:

【1】在点击浏览器的时候,当前的应用是浏览器;

【2】当弹出加锁界面的时候,手机卫士成了当前的应用;

【3】手机卫士的拦截界面finish()之后,仍然存在在手机卫士的界面中;

 

【问题的解决】单独为拦截界面开启一个栈;

[配置拦截界面的栈的开启模式]

【新BUG】弹出浏览器之后又跳回来了;

【问题的原因】看门狗在一直监测,只要进入到加锁的应用就会一直监视进入到输入密码的界面; 

【问题的解决】发送广播,通知看门狗,过滤掉该应用,不要再弹出输入密码认证的界面;

[对广播的接收]

【效果】解决了跳回到安全卫士本身的问题;

7.数据库发生改变通知查询数据库所有数据方法重新调用

 【存在的bug】在程序锁服务打开的时候,将程序加锁,程序并未真正的加锁;

【说明】在重新关闭-打开加锁服务,此时刚才打开的加锁配置生效了;

【解决的办法】内容观察者

 

【测试效果】加锁测试:可以弹出应用的密码输入框;

                     解锁测试:在解锁之后,应用不再弹出输入密码框;

8.程序锁回退按钮处理

8.1【存在的问题】

【1】点开手机卫士的应用,然后点击开浏览器(已加锁)的应用;看到后台具有两个应用;

【2】点击Home按键,将浏览器挂起;

【3】此时点击手机卫士,则会跳转到浏览器中;(此处不合理,可以已经知道是安全卫士为浏览器加的加锁

【解决的办法】将后台的安全卫士在后台不显示;

【4】现在点击开后台的手机卫士的界面:则显示的是手机卫士的密码输入界面,但是跳转之后的界面是桌面;(没有任何的意义)

 8.2  解决的办法

 

【效果】安全卫士的界面不再显示

9.程序锁回退按钮处理

9.1 存在的问题

【说明】点击回退按钮之后会返回到密码输入框,不是正常的逻辑;

9.2 问题的解决

【效果】

 10.程序锁结束服务处理

【说明】在Distroy的方法中进行【1】停止看门狗【2】注销广播接收者;【3】注销内容观察者;

 

posted @ 2018-02-11 10:47  OzTaking  阅读(288)  评论(0)    收藏  举报