Android 手機衛士15--程式鎖

来源:http://www.cnblogs.com/ganchuanpu/archive/2016/10/22/5986643.html
-Advertisement-
Play Games

1.基本思路 ①.創建已加鎖應用的資料庫(欄位:_id,packagename),如果應用已加鎖,將加鎖應用的包名維護到資料庫中 ②.已加鎖+未加鎖 == 手機中所有應用(AppInfoProvider) 2.已加鎖和未加鎖的數據適配器 1 class MyAdapter extends BaseA ...


 

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

 

 1 public class EnterPsdActivity extends Activity {
 2     private String packagename;
 3     private TextView tv_app_name;
 4     private ImageView iv_app_icon;
 5     private EditText et_psd;
 6     private Button bt_submit;
 7 
 8     @Override
 9     protected void onCreate(Bundle savedInstanceState) {
10         super.onCreate(savedInstanceState);
11         //獲取包名
12         packagename = getIntent().getStringExtra("packagename");
13         setContentView(R.layout.activity_enter_psd);
14         initUI();
15         initData();
16     }
17 
18     private void initData() {
19         //通過傳遞過來的包名獲取攔截應用的圖標以及名稱
20         PackageManager pm = getPackageManager();
21         try {
22             ApplicationInfo applicationInfo = pm.getApplicationInfo(packagename,0);
23             Drawable icon = applicationInfo.loadIcon(pm);
24             iv_app_icon.setBackgroundDrawable(icon);
25             tv_app_name.setText(applicationInfo.loadLabel(pm).toString());
26         } catch (NameNotFoundException e) {
27             e.printStackTrace();
28         }
29         
30         bt_submit.setOnClickListener(new OnClickListener() {
31             @Override
32             public void onClick(View v) {
33                 String psd = et_psd.getText().toString();
34                 if(!TextUtils.isEmpty(psd)){
35                     if(psd.equals("123")){
36                         //解鎖,進入應用,告知看門口不要再去監聽以及解鎖的應用,發送廣播
37                         Intent intent = new Intent("android.intent.action.SKIP");
38                         intent.putExtra("packagename",packagename);
39                         sendBroadcast(intent);
40                         
41                         finish();
42                     }else{
43                         ToastUtil.show(getApplicationContext(), "密碼錯誤");
44                     }
45                 }else{
46                     ToastUtil.show(getApplicationContext(), "請輸入密碼");
47                 }
48             }
49         });
50     }
51 
52     private void initUI() {
53         tv_app_name = (TextView) findViewById(R.id.tv_app_name);
54         iv_app_icon = (ImageView) findViewById(R.id.iv_app_icon);
55         
56         et_psd = (EditText) findViewById(R.id.et_psd);
57         bt_submit = (Button) findViewById(R.id.bt_submit);
58     }
59     
60     @Override
61     public void onBackPressed() {
62         //通過隱式意圖,跳轉到桌面
63         Intent intent = new Intent(Intent.ACTION_MAIN);
64         intent.addCategory(Intent.CATEGORY_HOME);
65         startActivity(intent);
66         super.onBackPressed();
67     }
68 }
EnterPsdActivity

 

5.隱藏最近打開的activity

<activity
           android:excludeFromRecents="true"
           android:name="com.itheima.mobilesafe.EnterPwdActivity"
           android:launchMode="singleInstance" />

  

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 為了讓裡面支持中文,我們加入這句話header("content-type:text/html;charset=utf-8"),此時的tigong.php如下 用我們的瀏覽器跑一下,如圖:將地址欄的信息地址複製一份,用postman測一下數據,如果不知道什麼是postman,請自行百度,後面的數據交 ...
  • 一、概述: 所有的應用程式都需要“數據”支持。對於大多數的Web應用程式來說,數據是在伺服器端進行組織和整理,然後由客戶端(瀏覽器端)通過網路請求獲取。隨著瀏覽器的處理能力不斷增強,可以在瀏覽器端存儲和操縱應用程式需要的數據,因此越來越多的網站開始考慮,將大量數據儲存在本地客戶端,這樣可以減少用戶等 ...
  • public class MainActivity extends Activity { Button bt; Context context; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate ...
  • 1.指定動畫一直旋轉 android:repeatCount 重覆的次數,預設為0,必須是int,可以為-1表示不停止 1 public class AnitVirusActivity extends Activity { 2 protected static final int SCANING = ...
  • (三)通信和聯網 3.1顯示Web信息 1.WebView通過loadUrl()方法直接訪問網頁時,點擊跳轉鏈接會打開系統預設的瀏覽器,若要攔截WebView事件,可為其添加WebViewClient 2.WebView預設不支持JavaScript,要通過setJavaScriptEnabled( ...
  • iOS進階之編寫彈性動畫條紋動畫(樂譜)圓圈波紋動畫彈性圓圈動畫數字轉變動畫談談iOS中粘性動畫以及果凍效果的實現一個彈性側滑菜單另一個數字轉變動畫 ...
  • (二)用戶交互 2.14轉發觸摸事件 1.TouchDelegate很適合簡單的觸摸轉發,它指定任意的矩形區域來向小視圖轉發觸摸事件,其缺點是每個被轉發的事件都會轉發到代理視圖的中間位置 2.自定義觸摸轉發 在onTouch中改變event事件信息 2.15阻止觸摸竊賊 1. 調用requestDi ...
  • 關於CAShapeLayer的一些實用案例和技巧實現遮罩音量大小動態改變的控制項圓形進度條iOS 利用CAShapeLayer的FillRule屬性生成一個空心遮罩的layerfillrule屬性。和電腦圖形學有關為視圖添加絲滑的水波紋利用餘弦函數 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...