程序锁学习(指纹识别的基础)------阿冬专栏

来源:互联网 发布:蓝梦数据恢复 编辑:程序博客网 时间:2024/05/12 19:16

高级工具--程序锁界面设计(一)


转载自:http://blog.csdn.net/asmcvc/article/details/18356007

界面效果图:


在加载安装的应用程序列表时,显示进度条:


布局文件:

[html] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. <?xml version="1.0" encoding="utf-8"?>  
  2.   
  3. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  4.     android:orientation="vertical" android:layout_width="match_parent"  
  5.     android:layout_height="match_parent">  
  6.     <TextView style="@style/title_center_text"  
  7.         android:text="程序锁"/>  
  8.     <View style="@style/splitter_view"/>  
  9.   
  10.     <RelativeLayout  
  11.         android:layout_height="fill_parent"  
  12.         android:layout_width="fill_parent">  
  13.         <LinearLayout  
  14.             android:id="@+id/ll_applock_loading"  
  15.             android:gravity="center"  
  16.             android:orientation="vertical"  
  17.             android:visibility="invisible"  
  18.             android:layout_height="fill_parent"  
  19.             android:layout_width="fill_parent">  
  20.             <ProgressBar  
  21.                 android:layout_height="wrap_content"  
  22.                 android:layout_width="wrap_content" />  
  23.             <TextView style="@style/content_text"  
  24.                 android:text="正在加载程序信息……"/>  
  25.         </LinearLayout>  
  26.         <ListView  
  27.             android:fastScrollEnabled="true"  
  28.             android:id="@+id/lv_applock"  
  29.             android:layout_height="match_parent"  
  30.             android:layout_width="match_parent"/>  
  31.     </RelativeLayout>  
  32. </LinearLayout>  
实际上在加载过程中进度控件是覆盖掉ListView的,当加载完毕后发送消息通知,消息处理过程隐藏掉进度控件即可。

ListView的每一个item的布局:

[html] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. <?xml version="1.0" encoding="utf-8"?>  
  2.   
  3. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  4.     android:orientation="horizontal" android:layout_width="match_parent"  
  5.     android:layout_height="wrap_content">  
  6.     <ImageView  
  7.         android:id="@+id/iv_applock_icon"  
  8.         android:layout_height="wrap_content"  
  9.         android:layout_width="wrap_content"  
  10.         android:layout_alignParentLeft="true"/>  
  11.     <TextView style="@style/content_text"  
  12.         android:id="@+id/iv_applock_name"  
  13.         android:layout_toRightOf="@+id/iv_applock_icon"/>  
  14.     <ImageView  
  15.         android:id="@+id/iv_applock_status"  
  16.         android:layout_height="wrap_content"  
  17.         android:layout_width="wrap_content"  
  18.         android:layout_alignParentRight="true"/>  
  19. </RelativeLayout>  
用来显示程序图标的ImageView,显示应用程序名的TextView,和锁定状态的ImageView。


界面在加载时先获取已安装的程序列表,保存应用程序的信息用一个AppInfo类来表示:

[java] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. package com.example.mobilesafe.engine;  
  2.   
  3. import android.graphics.drawable.Drawable;  
  4.   
  5. /** 
  6.  * Created by sing on 14-1-15. 
  7.  * desc: 
  8.  */  
  9. public class AppInfo {  
  10.   
  11.     private static final String TAG = "AppInfo";  
  12.   
  13.     //包名  
  14.     private String packname;  
  15.   
  16.     //应用程序版本号  
  17.     private String version;  
  18.   
  19.     //应用程序名  
  20.     private String appname;  
  21.   
  22.     //应用程序图标  
  23.     private Drawable appicon;  
  24.   
  25.     //标识是否是用户层应用  
  26.     private boolean userpp;  
  27.   
  28.     public String getPackname() {  
  29.         return packname;  
  30.     }  
  31.   
  32.     public void setPackname(String packname) {  
  33.         this.packname = packname;  
  34.     }  
  35.   
  36.     public String getVersion() {  
  37.         return version;  
  38.     }  
  39.   
  40.     public void setVersion(String version) {  
  41.         this.version = version;  
  42.     }  
  43.   
  44.     public String getAppname() {  
  45.         return appname;  
  46.     }  
  47.   
  48.     public void setAppname(String appname) {  
  49.         this.appname = appname;  
  50.     }  
  51.   
  52.     public Drawable getAppicon() {  
  53.         return appicon;  
  54.     }  
  55.   
  56.     public void setAppicon(Drawable appicon) {  
  57.         this.appicon = appicon;  
  58.     }  
  59.   
  60.     public boolean isUserpp() {  
  61.         return userpp;  
  62.     }  
  63.   
  64.     public void setUserpp(boolean userpp) {  
  65.         this.userpp = userpp;  
  66.     }  
  67. }  
获取安装的应用程序列表:

[java] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. package com.example.mobilesafe.engine;  
  2.   
  3. import android.content.Context;  
  4. import android.content.pm.ApplicationInfo;  
  5. import android.content.pm.PackageInfo;  
  6. import android.content.pm.PackageManager;  
  7.   
  8. import java.util.ArrayList;  
  9. import java.util.List;  
  10.   
  11. /** 
  12.  * Created by sing on 14-1-15. 
  13.  * desc: 
  14.  */  
  15. public class AppInfoProvider {  
  16.     private static final String TAG = "AppInfoProvider";  
  17.   
  18.     private PackageManager pm;  
  19.   
  20.     public AppInfoProvider(Context context) {  
  21.         pm = context.getPackageManager();  
  22.     }  
  23.   
  24.     public List<AppInfo> getInstalledApps() {  
  25.         List<PackageInfo> packageInfos = pm.getInstalledPackages(PackageManager.GET_UNINSTALLED_PACKAGES);  
  26.         List<AppInfo> appInfos = new ArrayList<AppInfo>();  
  27.   
  28.         for (PackageInfo info : packageInfos) {  
  29.             AppInfo appinfo = new AppInfo();  
  30.             appinfo.setPackname(info.packageName);  
  31.             appinfo.setVersion(info.versionName);  
  32.             appinfo.setAppname(info.applicationInfo.loadLabel(pm).toString());  
  33.             appinfo.setAppicon(info.applicationInfo.loadIcon(pm));  
  34.             appinfo.setUserpp(filterApp(info.applicationInfo));  
  35.             appInfos.add(appinfo);  
  36.             appinfo = null;  
  37.         }  
  38.   
  39.         return appInfos;  
  40.     }  
  41.   
  42.     public boolean filterApp(ApplicationInfo info) {  
  43.         if ((info.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0) {  
  44.             return false;  
  45.         } else if ((info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {  
  46.             return true;  
  47.         }  
  48.   
  49.         return false;  
  50.     }  
  51. }  

用户点击ListView的某一个item时,应进行锁定或解锁,锁定时将应用程序的包名存入到数据库中,以备后面监控使用。

操作数据库的类:

[java] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. package com.example.mobilesafe.db;  
  2.   
  3. import android.content.Context;  
  4. import android.database.Cursor;  
  5. import android.database.sqlite.SQLiteDatabase;  
  6.   
  7. import java.util.ArrayList;  
  8. import java.util.List;  
  9.   
  10. /** 
  11.  * Created by sing on 14-1-15. 
  12.  * desc:对于锁定的app包名存储在数据库中 
  13.  */  
  14. public class AppLockDao {  
  15.     private static final String TAG = "AppLockDao";  
  16.   
  17.     private AppLockDBOpenHelper helper;  
  18.   
  19.     public AppLockDao(Context context) {  
  20.         helper = new AppLockDBOpenHelper(context);  
  21.     }  
  22.   
  23.     /** 
  24.      * 查找指定的包名程序是否被锁定 
  25.      * @param packname 
  26.      * @return 
  27.      */  
  28.     public boolean find(String packname) {  
  29.         boolean result = false;  
  30.   
  31.         SQLiteDatabase db = helper.getReadableDatabase();  
  32.         if (db.isOpen()) {  
  33.             Cursor cursor = db.rawQuery("select * from applock where packname=?"new String[]{packname});  
  34.             if (cursor.moveToFirst()) {  
  35.                 result = true;  
  36.             }  
  37.             cursor.close();  
  38.             db.close();  
  39.         }  
  40.         return result;  
  41.     }  
  42.   
  43.     /** 
  44.      * 数据库中添加一个包名,也就是对这个包名程序进行锁定 
  45.      * @param packname 
  46.      * @return 
  47.      */  
  48.     public boolean add(String packname) {  
  49.         if (find(packname)) {  
  50.             return false;  
  51.         }  
  52.   
  53.         SQLiteDatabase db = helper.getWritableDatabase();  
  54.         if (db.isOpen()) {  
  55.             db.execSQL("insert into applock (packname) values (?)"new String[]{packname});  
  56.             db.close();  
  57.         }  
  58.   
  59.         return find(packname);  
  60.     }  
  61.   
  62.     /** 
  63.      * 删除某包名,下次不再对其锁定 
  64.      * @param packname 
  65.      */  
  66.     public void delete(String packname) {  
  67.         SQLiteDatabase db = helper.getWritableDatabase();  
  68.         if (db.isOpen()) {  
  69.             db.execSQL("delete from applock where packname=?"new String[]{packname});  
  70.             db.close();  
  71.         }  
  72.     }  
  73.   
  74.     /** 
  75.      * 查询所有被锁定的应用程序包名 
  76.      * @return 
  77.      */  
  78.     public List<String> findAll() {  
  79.         List<String> packnames = new ArrayList<String>();  
  80.         SQLiteDatabase db = helper.getReadableDatabase();  
  81.         if (db.isOpen()) {  
  82.             Cursor cursor = db.rawQuery("select packname from applock"null);  
  83.             while (cursor.moveToNext()) {  
  84.                 packnames.add(cursor.getString(0));  
  85.             }  
  86.             cursor.close();  
  87.             db.close();  
  88.         }  
  89.   
  90.         return packnames;  
  91.     }  
  92. }  
其中AppLockDBOpenHelper:

[java] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. package com.example.mobilesafe.db;  
  2.   
  3. import android.content.Context;  
  4. import android.database.sqlite.SQLiteDatabase;  
  5. import android.database.sqlite.SQLiteOpenHelper;  
  6.   
  7. /** 
  8.  * Created by sing on 14-1-15. 
  9.  * desc: 
  10.  */  
  11. public class AppLockDBOpenHelper extends SQLiteOpenHelper {  
  12.     private static final String TAG = "AppLockDBOpenHelper";  
  13.   
  14.     public AppLockDBOpenHelper(Context context) {  
  15.         //参数一:应用上下文,参数二:数据库名称  
  16.         //参数三:游标工厂对象,null表示使用系统默认的游标工厂对象,参数四:版本号  
  17.         super(context, "applock.db"null1);  
  18.     }  
  19.   
  20.     /** 
  21.      * 数据库第一次被创建的时候执行该方法 
  22.      * 在该方法中,一般用于指定数据库的表结构 
  23.      */  
  24.     @Override  
  25.     public void onCreate(SQLiteDatabase db) {  
  26.         //创建程序锁的表 (表中包含_id,包名 )  
  27.         db.execSQL("create table applock (_id integer primary key autoincrement, packname varchar(20))");  
  28.     }  
  29.   
  30.     /** 
  31.      * 当数据库的版本号 发生增加的时候调用的方法. 
  32.      * 一般用于升级程序后,更新数据库的表结构. 
  33.      */  
  34.     @Override  
  35.     public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i2) {  
  36.   
  37.     }  
  38. }  

至此,提供功能的类全部编写完毕,主activity:AppLockerActivity的代码:

[java] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. package com.example.mobilesafe;  
  2.   
  3. import android.app.Activity;  
  4. import android.os.Bundle;  
  5. import android.os.Handler;  
  6. import android.os.Message;  
  7. import android.view.View;  
  8. import android.view.ViewGroup;  
  9. import android.view.animation.Animation;  
  10. import android.view.animation.TranslateAnimation;  
  11. import android.widget.AdapterView;  
  12. import android.widget.BaseAdapter;  
  13. import android.widget.ImageView;  
  14. import android.widget.ListView;  
  15. import android.widget.TextView;  
  16.   
  17. import com.example.mobilesafe.R;  
  18. import com.example.mobilesafe.db.AppLockDao;  
  19. import com.example.mobilesafe.engine.AppInfo;  
  20. import com.example.mobilesafe.engine.AppInfoProvider;  
  21.   
  22. import java.util.List;  
  23.   
  24. /** 
  25.  * Created by sing on 14-1-10. 
  26.  * desc: 
  27.  */  
  28. public class AppLockerActivity extends Activity {  
  29.   
  30.     public static final String TAG = "AppLockerActivity";  
  31.   
  32.     private ListView lv_applock;  
  33.     private View ll_loading;  
  34.   
  35.     private AppInfoProvider provider;  
  36.     private List<AppInfo> appInfos;  
  37.     private AppLockDao dao;  
  38.     private List<String> lockedPacknames;  
  39.   
  40.     private Handler handler = new Handler(){  
  41.         @Override  
  42.         public void handleMessage(Message msg) {  
  43.             ll_loading.setVisibility(View.INVISIBLE);  
  44.             lv_applock.setAdapter(new AppLockAdapter());  
  45.         }  
  46.     };  
  47.   
  48.     public void onCreate(Bundle savedInstanceState) {  
  49.         super.onCreate(savedInstanceState);  
  50.         setContentView(R.layout.applockeractivity_layout);  
  51.   
  52.         lv_applock = (ListView) findViewById(R.id.lv_applock);  
  53.         ll_loading = findViewById(R.id.ll_applock_loading);  
  54.   
  55.         provider = new AppInfoProvider(this);  
  56.         dao = new AppLockDao(this);  
  57.         lockedPacknames = dao.findAll();  
  58.   
  59.         ll_loading.setVisibility(View.VISIBLE);  
  60.         new Thread(){  
  61.             public void run() {  
  62.                 appInfos = provider.getInstalledApps();  
  63.                 handler.sendEmptyMessage(0);  
  64.             }  
  65.         }.start();  
  66.   
  67.         lv_applock.setOnItemClickListener(new AdapterView.OnItemClickListener() {  
  68.             @Override  
  69.             public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {  
  70.                 AppInfo appInfo = (AppInfo) lv_applock.getItemAtPosition(i);  
  71.                 String packname = appInfo.getPackname();  
  72.                 ImageView iv = (ImageView) view.findViewById(R.id.iv_applock_status);  
  73.                 TranslateAnimation ta = new TranslateAnimation(Animation.RELATIVE_TO_SELF, 0,  
  74.                         Animation.RELATIVE_TO_SELF, 0.2f,  
  75.                         Animation.RELATIVE_TO_SELF, 0,  
  76.                         Animation.RELATIVE_TO_SELF, 0);  
  77.                 ta.setDuration(200);  
  78.                 if (lockedPacknames.contains(packname)) {  
  79.                     dao.delete(packname);  
  80.                     iv.setImageResource(R.drawable.unlock);  
  81.                     lockedPacknames.remove(packname);  
  82.                 }else {  
  83.                     dao.add(packname);  
  84.                     iv.setImageResource(R.drawable.lock);  
  85.                     lockedPacknames.add(packname);  
  86.                 }  
  87.                 view.startAnimation(ta);  
  88.             }  
  89.         });  
  90.     }  
  91.   
  92.     private class AppLockAdapter extends BaseAdapter {  
  93.         @Override  
  94.         public int getCount() {  
  95.             return appInfos.size();  
  96.         }  
  97.   
  98.         @Override  
  99.         public Object getItem(int i) {  
  100.             return appInfos.get(i);  
  101.         }  
  102.   
  103.         @Override  
  104.         public long getItemId(int i) {  
  105.             return i;  
  106.         }  
  107.   
  108.         @Override  
  109.         public View getView(int i, View view, ViewGroup viewGroup) {  
  110.             View v;  
  111.             ViewHolder holder;  
  112.   
  113.             if (view==null) {  
  114.                 v = View.inflate(getApplicationContext(), R.layout.app_lock_item, null);  
  115.                 holder = new ViewHolder();  
  116.                 holder.iv_icon = (ImageView) v.findViewById(R.id.iv_applock_icon);  
  117.                 holder.iv_status = (ImageView) v.findViewById(R.id.iv_applock_status);  
  118.                 holder.tv_name = (TextView) v.findViewById(R.id.iv_applock_name);  
  119.                 v.setTag(holder);  
  120.             }else{  
  121.                 v = view;  
  122.                 holder = (ViewHolder)view.getTag();  
  123.             }  
  124.   
  125.             AppInfo appInfo = appInfos.get(i);  
  126.             holder.iv_icon.setImageDrawable(appInfo.getAppicon());  
  127.             holder.tv_name.setText(appInfo.getAppname());  
  128.             if (lockedPacknames.contains(appInfo.getPackname())) {  
  129.                 holder.iv_status.setImageResource(R.drawable.lock);  
  130.             }else{  
  131.                 holder.iv_status.setImageResource(R.drawable.unlock);  
  132.             }  
  133.   
  134.             return v;  
  135.         }  
  136.     }  
  137.   
  138.     public static class ViewHolder {  
  139.         ImageView iv_icon;  
  140.         ImageView iv_status;  
  141.         TextView tv_name;  
  142.     }  
  143. }  

这里使用了一个动画效果,当点击时相对左移一定距离,效果图:


程序锁原理(二)------阿冬专栏

程序锁的原理是一个“看门狗”的服务定时监视顶层activity,如果activity对应的包名是之前上锁的应用程序的,则弹出一个页面要求输入解锁密码,此页面不运行用户按“BACK”键返回,否则便能不输入密码直接进入应用程序了。如果密码输入正确则进入应用程序。

创建一个Android component,kind为service,类名为:WatchDogService:

[java] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. package com.example.mobilesafe.service;  
  2.   
  3. import android.app.ActivityManager;  
  4. import android.app.Service;  
  5. import android.content.Intent;  
  6. import android.database.ContentObserver;  
  7. import android.net.Uri;  
  8. import android.os.Binder;  
  9. import android.os.Handler;  
  10. import android.os.IBinder;  
  11. import android.util.Log;  
  12.   
  13. import com.example.mobilesafe.EnterPswdActivity;  
  14. import com.example.mobilesafe.db.AppLockDao;  
  15. import com.example.mobilesafe.engine.IService;  
  16.   
  17. import java.util.ArrayList;  
  18. import java.util.List;  
  19.   
  20. /** 
  21.  * Created by sing on 14-1-16. 
  22.  * desc: 
  23.  */  
  24. public class WatchDogService extends Service {  
  25.   
  26.     public static final String TAG = "WatchDogService";  
  27.   
  28.     boolean flag;  
  29.   
  30.     private Intent pswdIntent;  
  31.   
  32.     private List<String> lockPacknames;  
  33.     private List<String> tempStopProtectPacknames;  
  34.   
  35.     private AppLockDao dao;  
  36.   
  37.     public IBinder onBind(Intent intent) {  
  38.         return null;  
  39.     }  
  40.   
  41.     @Override  
  42.     public void onDestroy() {  
  43.         flag = false;  
  44.         getContentResolver().unregisterContentObserver(observer);  
  45.         observer = null;  
  46.         super.onDestroy();  
  47.     }  
  48.   
  49.     @Override  
  50.     public void onCreate() {  
  51.         //注册内容观察者  
  52.         Uri uri = Uri.parse("content://com.example.mobilesafe.applock/");  
  53.         observer = new MyObserver(new Handler());  
  54.         getContentResolver().registerContentObserver(uri, true, observer);  
  55.   
  56.         super.onCreate();  
  57.         dao = new AppLockDao(this);  
  58.         flag = true;  
  59.         lockPacknames = dao.findAll();  
  60.         tempStopProtectPacknames = new ArrayList<String>();  
  61.         pswdIntent = new Intent(this, EnterPswdActivity.class);  
  62.         //服务没有任务栈,如果要开启一个在任务栈中运行的activity,需要为其创建一个任务栈  
  63.         pswdIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);  
  64.         new Thread() {  
  65.             @Override  
  66.             public void run() {  
  67.                 while (flag) {  
  68.                     ActivityManager am = (ActivityManager) getSystemService(ACTIVITY_SERVICE);  
  69.                     //获取当前正在栈顶运行的activity  
  70.                     ActivityManager.RunningTaskInfo taskInfo = am.getRunningTasks(1).get(0);  
  71.                     String packname = taskInfo.topActivity.getPackageName();  
  72.                     Log.i(TAG, packname);  
  73.                     if (tempStopProtectPacknames.contains(packname)) {  
  74.                         try {  
  75.                             Thread.sleep(200);  
  76.                         } catch (InterruptedException e) {  
  77.                             e.printStackTrace();  
  78.                         }  
  79.                         continue;  
  80.                     }  
  81.   
  82.                     pswdIntent.putExtra("packname", packname);  
  83.                     if (lockPacknames.contains(packname)) {  
  84.                         startActivity(pswdIntent);  
  85.                     }  
  86.                     try {  
  87.                         Thread.sleep(200);  
  88.                     } catch (InterruptedException e) {  
  89.                         e.printStackTrace();  
  90.                     }  
  91.   
  92.                 }  
  93.             }  
  94.         }.start();  
  95.     }  
  96.   
  97.     public void tempStopProtect(String packname) {  
  98.         tempStopProtectPacknames.add(packname);  
  99.     }  
  100. }  

密码输入页面的类EnterPswdActivity:

[java] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. package com.example.mobilesafe;  
  2.   
  3. import android.app.Activity;  
  4. import android.content.ComponentName;  
  5. import android.content.Intent;  
  6. import android.content.ServiceConnection;  
  7. import android.content.pm.PackageInfo;  
  8. import android.content.pm.PackageManager;  
  9. import android.os.Bundle;  
  10. import android.os.IBinder;  
  11. import android.view.KeyEvent;  
  12. import android.view.View;  
  13. import android.widget.Button;  
  14. import android.widget.EditText;  
  15. import android.widget.ImageView;  
  16. import android.widget.TextView;  
  17. import android.widget.Toast;  
  18.   
  19. import com.example.mobilesafe.engine.IService;  
  20. import com.example.mobilesafe.service.WatchDogService;  
  21.   
  22. /** 
  23.  * Created by sing on 14-1-16. 
  24.  * desc: 
  25.  */  
  26. public class EnterPswdActivity extends Activity {  
  27.     public static final String TAG = "EnterPswdActivity";  
  28.   
  29.     private ImageView iv_icon;  
  30.     private TextView tv_name;  
  31.     private EditText et_pswd;  
  32.     private Button bt_enter;  
  33.   
  34.     private Intent serviceIntent;  
  35.   
  36.     private IService iService;  
  37.   
  38.     private MyConn conn;  
  39.   
  40.     private String packname;  
  41.   
  42.     public void onCreate(Bundle savedInstanceState) {  
  43.         super.onCreate(savedInstanceState);  
  44.         setContentView(R.layout.enterpswd_layout);  
  45.   
  46.         iv_icon = (ImageView) findViewById(R.id.iv_icon);  
  47.         tv_name = (TextView) findViewById(R.id.tv_name);  
  48.         et_pswd = (EditText) findViewById(R.id.et_pswd);  
  49.         bt_enter = (Button) findViewById(R.id.bt_enter);  
  50.         bt_enter.setOnClickListener(new View.OnClickListener() {  
  51.             @Override  
  52.             public void onClick(View view) {  
  53.                 String pswd = et_pswd.getText().toString().trim();  
  54.                 if (pswd.isEmpty()) {  
  55.                     Toast.makeText(EnterPswdActivity.this,"密码不能为空",0).show();  
  56.                     return;  
  57.                 }  
  58.                 if (pswd.equals("123")) {  
  59.                     iService.callTempStopProtect(packname);  
  60.                     finish();  
  61.                 }else{  
  62.                     Toast.makeText(EnterPswdActivity.this,"密码不正确",0).show();  
  63.                     return;  
  64.                 }  
  65.             }  
  66.         });  
  67.   
  68.         //获取到激活当前activity的意图,也就是WatchDogService传递的pswdIntent  
  69.         Intent intent = getIntent();  
  70.         packname = intent.getStringExtra("packname");  
  71.   
  72.         serviceIntent = new Intent(this, WatchDogService.class);  
  73.         conn = new MyConn();  
  74.   
  75.         //绑定服务(非startService),执行WatchDogService中的onCreate-onBing方法  
  76.         //如果绑定成功,WatchDogService中onBing方法返回一个IBinder给conn.ServiceConnection  
  77.         bindService(serviceIntent, conn, BIND_AUTO_CREATE);  
  78.   
  79.         try {  
  80.             PackageInfo info = getPackageManager().getPackageInfo(packname, 0);  
  81.             iv_icon.setImageDrawable(info.applicationInfo.loadIcon(getPackageManager()));  
  82.             tv_name.setText(info.applicationInfo.loadLabel(getPackageManager()));  
  83.         } catch (PackageManager.NameNotFoundException e) {  
  84.             e.printStackTrace();  
  85.         }  
  86.   
  87.     }  
  88.   
  89.     private class MyConn implements ServiceConnection {  
  90.         @Override  
  91.         public void onServiceConnected(ComponentName componentName, IBinder iBinder) {  
  92.             iService = (IService) iBinder;  
  93.         }  
  94.   
  95.         @Override  
  96.         public void onServiceDisconnected(ComponentName componentName) {  
  97.   
  98.         }  
  99.     }  
  100.   
  101.     @Override  
  102.     protected void onDestroy() {  
  103.         super.onDestroy();  
  104.   
  105.         //接触绑定  
  106.         unbindService(conn);  
  107.     }  
  108.   
  109.     /** 
  110.      * 不允许用户按back键后退 
  111.      * @param keyCode 
  112.      * @param event 
  113.      * @return 
  114.      */  
  115.     @Override  
  116.     public boolean onKeyDown(int keyCode, KeyEvent event) {  
  117.         if (event.getAction()==KeyEvent.ACTION_DOWN && event.getKeyCode()==KeyEvent.KEYCODE_BACK) {  
  118.             return true;  
  119.         }  
  120.         return super.onKeyDown(keyCode, event);  
  121.     }  
  122. }  

布局文件:

[html] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. <?xml version="1.0" encoding="utf-8"?>  
  2.   
  3. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  4.     android:orientation="vertical"  
  5.     android:layout_height="wrap_content"  
  6.     android:layout_width="match_parent" >  
  7.   
  8.     <RelativeLayout style="@style/relativelayout">  
  9.         <ImageView  
  10.             android:id="@+id/iv_icon"  
  11.             android:layout_alignParentLeft="true"  
  12.             android:layout_height="wrap_content"  
  13.             android:layout_width="wrap_content"/>  
  14.         <TextView style="@style/content_text"  
  15.             android:id="@+id/tv_name"  
  16.             android:gravity="center"  
  17.             android:layout_centerVertical="true"  
  18.             android:layout_toRightOf="@+id/iv_icon"/>  
  19.     </RelativeLayout>  
  20.   
  21.     <EditText  
  22.         android:id="@+id/et_pswd"  
  23.         android:layout_height="match_parent"  
  24.         android:layout_width="match_parent" />  
  25.     <Button  
  26.         android:id="@+id/bt_enter"  
  27.         android:text="确定"  
  28.         android:gravity="center"  
  29.         android:layout_height="match_parent"  
  30.         android:layout_width="match_parent" />  
  31. </LinearLayout>  

这里EnterPswdActivity类重载了对onKeyDown消息的处理,如果用户按键为KEYCODE_BACK则直接返回,防止用户在密码输入界面通过按“BACK”键进入到被锁定的应用程序界面。

EnterPswdActivity在启动时通过getIntent获取WatchDogService传递来的intent,进而通过getStringExtra("packname")获取被锁定的应用程序包名。进而通过getPackageManager获取包名对应的应用程序信息:图标和应用程序名。将这两个信息显示提示给用户,也即说明即将进入哪个被锁定的应用程序界面。

如图:


最后通过bindService绑定服务,如果绑定成功WatchDogService中onBing方法返回一个IBinder给conn.ServiceConnection:

[java] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. private class MyConn implements ServiceConnection {  
  2.     @Override  
  3.     public void onServiceConnected(ComponentName componentName, IBinder iBinder) {  
  4.         iService = (IService) iBinder;  
  5.     }  
  6.   
  7.     @Override  
  8.     public void onServiceDisconnected(ComponentName componentName) {  
  9.   
  10.     }  
  11. }  
接口IService很简单:

[java] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. package com.example.mobilesafe.engine;  
  2.   
  3. /** 
  4.  * Created by sing on 14-1-16. 
  5.  * desc:使看门狗服务停止对packname保护的接口 
  6.  */  
  7. public interface IService {  
  8.     public void callTempStopProtect(String packname);  
  9. }  


绑定服务这一过程是为了让WatchDogService返回一个操作接口,目的是在输入密码成功后调用该接口,使得能够进入被锁定的应用程序界面,临时不再被锁定。WatchDogService需要在onBind函数中返回一个对象:

[java] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. private MyBinder binder;  
  2.   
  3. public IBinder onBind(Intent intent) {  
  4.     binder = new MyBinder();  
  5.     return binder;  
  6. }  
  7.   
  8. private class MyBinder extends Binder implements IService {  
  9.     @Override  
  10.     public void callTempStopProtect(String packname) {  
  11.         tempStopProtect(packname);  
  12.     }  
  13. }  
WatchDogService在绑定成功时创建了一个实现了IService接口的Binder对象给EnterPswdActivity.MyConn.onServiceConnected,用户正确输入密码后EnterPswdActivity调用该接口函数callTempStopProtect,该函数又调用WatchDogService的tempStopProtect:

[java] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. private List<String> tempStopProtectPacknames;  
  2. public void tempStopProtect(String packname) {  
  3.     tempStopProtectPacknames.add(packname);  
  4. }  
将临时解锁的应用程序包名添加到临时停止保护的列表里去,在服务的监控线程中,如果发现应用程序包名已经在此列表里的话,便不再弹出对话框要求输入密码,会认为之前已经成功进入过了。

[java] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. if (tempStopProtectPacknames.contains(packname)) {  
  2.     try {  
  3.         Thread.sleep(200);  
  4.     } catch (InterruptedException e) {  
  5.         e.printStackTrace();  
  6.     }  
  7.     continue;  
  8. }  


0 0
原创粉丝点击