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
  • 前言 本文介紹一款使用 C# 與 WPF 開發的音頻播放器,其界面簡潔大方,操作體驗流暢。該播放器支持多種音頻格式(如 MP4、WMA、OGG、FLAC 等),並具備標記、實時歌詞顯示等功能。 另外,還支持換膚及多語言(中英文)切換。核心音頻處理採用 FFmpeg 組件,獲得了廣泛認可,目前 Git ...
  • OAuth2.0授權驗證-gitee授權碼模式 本文主要介紹如何筆者自己是如何使用gitee提供的OAuth2.0協議完成授權驗證並登錄到自己的系統,完整模式如圖 1、創建應用 打開gitee個人中心->第三方應用->創建應用 創建應用後在我的應用界面,查看已創建應用的Client ID和Clien ...
  • 解決了這個問題:《winForm下,fastReport.net 從.net framework 升級到.net5遇到的錯誤“Operation is not supported on this platform.”》 本文內容轉載自:https://www.fcnsoft.com/Home/Sho ...
  • 國內文章 WPF 從裸 Win 32 的 WM_Pointer 消息獲取觸摸點繪製筆跡 https://www.cnblogs.com/lindexi/p/18390983 本文將告訴大家如何在 WPF 裡面,接收裸 Win 32 的 WM_Pointer 消息,從消息裡面獲取觸摸點信息,使用觸摸點 ...
  • 前言 給大家推薦一個專為新零售快消行業打造了一套高效的進銷存管理系統。 系統不僅具備強大的庫存管理功能,還集成了高性能的輕量級 POS 解決方案,確保頁面載入速度極快,提供良好的用戶體驗。 項目介紹 Dorisoy.POS 是一款基於 .NET 7 和 Angular 4 開發的新零售快消進銷存管理 ...
  • ABP CLI常用的代碼分享 一、確保環境配置正確 安裝.NET CLI: ABP CLI是基於.NET Core或.NET 5/6/7等更高版本構建的,因此首先需要在你的開發環境中安裝.NET CLI。這可以通過訪問Microsoft官網下載並安裝相應版本的.NET SDK來實現。 安裝ABP ...
  • 問題 問題是這樣的:第三方的webapi,需要先調用登陸介面獲取Cookie,訪問其它介面時攜帶Cookie信息。 但使用HttpClient類調用登陸介面,返回的Headers中沒有找到Cookie信息。 分析 首先,使用Postman測試該登陸介面,正常返回Cookie信息,說明是HttpCli ...
  • 國內文章 關於.NET在中國為什麼工資低的分析 https://www.cnblogs.com/thinkingmore/p/18406244 .NET在中國開發者的薪資偏低,主要因市場需求、技術棧選擇和企業文化等因素所致。歷史上,.NET曾因微軟的閉源策略發展受限,儘管後來推出了跨平臺的.NET ...
  • 在WPF開發應用中,動畫不僅可以引起用戶的註意與興趣,而且還使軟體更加便於使用。前面幾篇文章講解了畫筆(Brush),形狀(Shape),幾何圖形(Geometry),變換(Transform)等相關內容,今天繼續講解動畫相關內容和知識點,僅供學習分享使用,如有不足之處,還請指正。 ...
  • 什麼是委托? 委托可以說是把一個方法代入另一個方法執行,相當於指向函數的指針;事件就相當於保存委托的數組; 1.實例化委托的方式: 方式1:通過new創建實例: public delegate void ShowDelegate(); 或者 public delegate string ShowDe ...