欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Android程序鎖的實(shí)現(xiàn)以及邏輯

 更新時(shí)間:2016年10月22日 14:37:41   作者:ganchuanpu  
本篇文章主要是介紹Android程序鎖的實(shí)現(xiàn)以及邏輯,它的目的是可以給程序加鎖,上過(guò)鎖的程序可以解鎖,有興趣的朋友可以了解一下。

本項(xiàng)目是一個(gè)比較有趣的項(xiàng)目源碼,可以給其他項(xiàng)目加鎖,程序鎖的原理是一個(gè)“看門(mén)狗”的服務(wù)定時(shí)監(jiān)視頂層activity,如果activity對(duì)應(yīng)的包名是之前上鎖的應(yīng)用程序的,則彈出一個(gè)頁(yè)面要求輸入解鎖密碼。

效果如下:

1.基本思路

①.創(chuàng)建已加鎖應(yīng)用的數(shù)據(jù)庫(kù)(字段:_id,packagename),如果應(yīng)用已加鎖,將加鎖應(yīng)用的包名維護(hù)到數(shù)據(jù)庫(kù)中

②.已加鎖+未加鎖 == 手機(jī)中所有應(yīng)用(AppInfoProvider)

2.已加鎖和未加鎖的數(shù)據(jù)適配器

class MyAdapter extends BaseAdapter{
 private boolean isLock;
 /**
 * @param isLock 用于區(qū)分已加鎖和未加鎖應(yīng)用的標(biāo)示 true已加鎖數(shù)據(jù)適配器 false未加鎖數(shù)據(jù)適配器
 */
 public MyAdapter(boolean isLock) {
 this.isLock = isLock;
 }
 @Override
 public int getCount() {
 if(isLock){
  tv_lock.setText("已加鎖應(yīng)用:"+mLockList.size());
  return mLockList.size();
 }else{
  tv_unlock.setText("未加鎖應(yīng)用:"+mUnLockList.size());
  return mUnLockList.size();
 }
 }

 @Override
 public AppInfo getItem(int position) {
 if(isLock){
  return mLockList.get(position);
 }else{
  return mUnLockList.get(position);
 }
 }

 @Override
 public long getItemId(int position) {
 return position;
 }

 @Override
 public View getView(int position, View convertView, ViewGroup parent) {
 ViewHolder holder = null;
 if(convertView == null){
  convertView = View.inflate(getApplicationContext(), R.layout.listview_islock_item, null);
  holder = new ViewHolder();
  holder.iv_icon = (ImageView) convertView.findViewById(R.id.iv_icon);
  holder.tv_name = (TextView) convertView.findViewById(R.id.tv_name);
  holder.iv_lock = (ImageView) convertView.findViewById(R.id.iv_lock);
  
  convertView.setTag(holder);
 }else{
  holder = (ViewHolder) convertView.getTag();
 }
 final AppInfo appInfo = getItem(position);
 final View animationView = convertView;
 
 holder.iv_icon.setBackgroundDrawable(appInfo.icon);
 holder.tv_name.setText(appInfo.name);
 if(isLock){
  holder.iv_lock.setBackgroundResource(R.drawable.lock);
 }else{
  holder.iv_lock.setBackgroundResource(R.drawable.unlock);
 }
 holder.iv_lock.setOnClickListener(new OnClickListener() {
  @Override
  public void onClick(View v) {
  //添加動(dòng)畫(huà)效果,動(dòng)畫(huà)默認(rèn)是非阻塞的,所以執(zhí)行動(dòng)畫(huà)的同時(shí),動(dòng)畫(huà)以下的代碼也會(huì)執(zhí)行
  animationView.startAnimation(mTranslateAnimation);//500毫秒
  //對(duì)動(dòng)畫(huà)執(zhí)行過(guò)程做事件監(jiān)聽(tīng),監(jiān)聽(tīng)到動(dòng)畫(huà)執(zhí)行完成后,再去移除集合中的數(shù)據(jù),操作數(shù)據(jù)庫(kù),刷新界面
  mTranslateAnimation.setAnimationListener(new AnimationListener() {
   @Override
   public void onAnimationStart(Animation animation) {
   //動(dòng)畫(huà)開(kāi)始的是調(diào)用方法
   }
   @Override
   public void onAnimationRepeat(Animation animation) {
   //動(dòng)畫(huà)重復(fù)時(shí)候調(diào)用方法
   }
   //動(dòng)畫(huà)執(zhí)行結(jié)束后調(diào)用方法
   @Override
   public void onAnimationEnd(Animation animation) {
   if(isLock){
    //已加鎖------>未加鎖過(guò)程
    //1.已加鎖集合刪除一個(gè),未加鎖集合添加一個(gè),對(duì)象就是getItem方法獲取的對(duì)象
    mLockList.remove(appInfo);
    mUnLockList.add(appInfo);
    //2.從已加鎖的數(shù)據(jù)庫(kù)中刪除一條數(shù)據(jù)
    mDao.delete(appInfo.packageName);
    //3.刷新數(shù)據(jù)適配器
    mLockAdapter.notifyDataSetChanged();
   }else{
    //未加鎖------>已加鎖過(guò)程
    //1.已加鎖集合添加一個(gè),未加鎖集合移除一個(gè),對(duì)象就是getItem方法獲取的對(duì)象
    mLockList.add(appInfo);
    mUnLockList.remove(appInfo);
    //2.從已加鎖的數(shù)據(jù)庫(kù)中插入一條數(shù)據(jù)
    mDao.insert(appInfo.packageName);
    //3.刷新數(shù)據(jù)適配器
    mUnLockAdapter.notifyDataSetChanged();
   }
   }
  });
  }
 });
 return convertView;
 }
}
mLockAdapter = new MyAdapter(true);
lv_lock.setAdapter(mLockAdapter);
  
mUnLockAdapter = new MyAdapter(false);
lv_unlock.setAdapter(mUnLockAdapter);

3.已加鎖和未加鎖條目點(diǎn)擊事件處理

holder.iv_lock.setOnClickListener(new OnClickListener() {
 @Override
 public void onClick(View v) {
 //添加動(dòng)畫(huà)效果,動(dòng)畫(huà)默認(rèn)是非阻塞的,所以執(zhí)行動(dòng)畫(huà)的同時(shí),動(dòng)畫(huà)以下的代碼也會(huì)執(zhí)行
 animationView.startAnimation(mTranslateAnimation);//500毫秒
 //對(duì)動(dòng)畫(huà)執(zhí)行過(guò)程做事件監(jiān)聽(tīng),監(jiān)聽(tīng)到動(dòng)畫(huà)執(zhí)行完成后,再去移除集合中的數(shù)據(jù),操作數(shù)據(jù)庫(kù),刷新界面
 mTranslateAnimation.setAnimationListener(new AnimationListener() {
  @Override
  public void onAnimationStart(Animation animation) {
  //動(dòng)畫(huà)開(kāi)始的是調(diào)用方法
  }
  @Override
  public void onAnimationRepeat(Animation animation) {
  //動(dòng)畫(huà)重復(fù)時(shí)候調(diào)用方法
  }
  //動(dòng)畫(huà)執(zhí)行結(jié)束后調(diào)用方法
  @Override
  public void onAnimationEnd(Animation animation) {
  if(isLock){
   //已加鎖------>未加鎖過(guò)程
   //1.已加鎖集合刪除一個(gè),未加鎖集合添加一個(gè),對(duì)象就是getItem方法獲取的對(duì)象
   mLockList.remove(appInfo);
   mUnLockList.add(appInfo);
   //2.從已加鎖的數(shù)據(jù)庫(kù)中刪除一條數(shù)據(jù)
   mDao.delete(appInfo.packageName);
   //3.刷新數(shù)據(jù)適配器
   mLockAdapter.notifyDataSetChanged();
  }else{
   //未加鎖------>已加鎖過(guò)程
   //1.已加鎖集合添加一個(gè),未加鎖集合移除一個(gè),對(duì)象就是getItem方法獲取的對(duì)象
   mLockList.add(appInfo);
   mUnLockList.remove(appInfo);
   //2.從已加鎖的數(shù)據(jù)庫(kù)中插入一條數(shù)據(jù)
   mDao.insert(appInfo.packageName);
   //3.刷新數(shù)據(jù)適配器
   mUnLockAdapter.notifyDataSetChanged();
  }
  }
 });
 }
});

4.程序鎖必須在服務(wù)中去維護(hù)

①基本思路

  1. 判斷當(dāng)前開(kāi)啟的應(yīng)用(現(xiàn)在手機(jī)可見(jiàn)任務(wù)棧)
  2. 如果開(kāi)啟的應(yīng)用在已加鎖的列表中,彈出攔截界面
  3. 看門(mén)狗服務(wù),一直(死循環(huán)(子線(xiàn)程,可控))對(duì)開(kāi)啟的應(yīng)用做監(jiān)聽(tīng)
public class WatchDogService extends Service {
 private boolean isWatch;
 private AppLockDao mDao;
 private List<String> mPacknameList;
 private InnerReceiver mInnerReceiver;
 private String mSkipPackagename;
 private MyContentObserver mContentObserver;
 @Override
 public void onCreate() {
 //維護(hù)一個(gè)看門(mén)狗的死循環(huán),讓其時(shí)刻監(jiān)測(cè)現(xiàn)在開(kāi)啟的應(yīng)用,是否為程序鎖中要去攔截的應(yīng)用
 mDao = AppLockDao.getInstance(this);
 isWatch = true;
 watch();
 
 IntentFilter intentFilter = new IntentFilter(); 
 intentFilter.addAction("android.intent.action.SKIP");
 
 mInnerReceiver = new InnerReceiver();
 registerReceiver(mInnerReceiver, intentFilter);
 
 
 //注冊(cè)一個(gè)內(nèi)容觀察者,觀察數(shù)據(jù)庫(kù)的變化,一旦數(shù)據(jù)有刪除或者添加,則需要讓mPacknameList重新獲取一次數(shù)據(jù)
 mContentObserver = new MyContentObserver(new Handler());
 getContentResolver().registerContentObserver(
  Uri.parse("content://applock/change"), true, mContentObserver);
 super.onCreate();
 }
 
 class MyContentObserver extends ContentObserver{

 public MyContentObserver(Handler handler) {
  super(handler);
 }
 
 //一旦數(shù)據(jù)庫(kù)發(fā)生改變時(shí)候調(diào)用方法,重新獲取包名所在集合的數(shù)據(jù)
 @Override
 public void onChange(boolean selfChange) {
  new Thread(){
  public void run() {
   mPacknameList = mDao.findAll();
  };
  }.start();
  super.onChange(selfChange);
 }
 }
 
 class InnerReceiver extends BroadcastReceiver{
 @Override
 public void onReceive(Context context, Intent intent) {
  //獲取發(fā)送廣播過(guò)程中傳遞過(guò)來(lái)的包名,跳過(guò)次包名檢測(cè)過(guò)程
  mSkipPackagename = intent.getStringExtra("packagename");
 }
 }
 
 private void watch() {
 //1,子線(xiàn)程中,開(kāi)啟一個(gè)可控死循環(huán)
 new Thread(){
  public void run() {
  mPacknameList = mDao.findAll();
  while(isWatch){
   //2.監(jiān)測(cè)現(xiàn)在正在開(kāi)啟的應(yīng)用,任務(wù)棧
   //3.獲取activity管理者對(duì)象
   ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
   //4.獲取正在開(kāi)啟應(yīng)用的任務(wù)棧
   List<RunningTaskInfo> runningTasks = am.getRunningTasks(1);
   RunningTaskInfo runningTaskInfo = runningTasks.get(0);
   //5.獲取棧頂?shù)腶ctivity,然后在獲取此activity所在應(yīng)用的包名
   String packagename = runningTaskInfo.topActivity.getPackageName();
   
   //如果任務(wù)棧指向應(yīng)用有切換,將mSkipPackagename空字符串
   
   //6.拿此包名在已加鎖的包名集合中去做比對(duì),如果包含次包名,則需要彈出攔截界面
   if(mPacknameList.contains(packagename)){
   //如果現(xiàn)在檢測(cè)的程序,以及解鎖了,則不需要去彈出攔截界面
   if(!packagename.equals(mSkipPackagename)){
    //7,彈出攔截界面
    Intent intent = new Intent(getApplicationContext(),EnterPsdActivity.class);
    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    intent.putExtra("packagename", packagename);
    startActivity(intent);
   }
   }
   //睡眠一下,時(shí)間片輪轉(zhuǎn)
   try {
   Thread.sleep(500);
   } catch (InterruptedException e) {
   e.printStackTrace();
   }
  }
  };
 }.start();
 
 }
 @Override
 public IBinder onBind(Intent arg0) {
 return null;
 }
 @Override
 public void onDestroy() {
 //停止看門(mén)狗循環(huán)
 isWatch = false;
 //注銷(xiāo)廣播接受者
 if(mInnerReceiver!=null){
  unregisterReceiver(mInnerReceiver);
 }
 //注銷(xiāo)內(nèi)容觀察者
 if(mContentObserver!=null){
  getContentResolver().unregisterContentObserver(mContentObserver);
 }
 super.onDestroy();
 }
}
public class EnterPsdActivity extends Activity {
 private String packagename;
 private TextView tv_app_name;
 private ImageView iv_app_icon;
 private EditText et_psd;
 private Button bt_submit;

 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 //獲取包名
 packagename = getIntent().getStringExtra("packagename");
 setContentView(R.layout.activity_enter_psd);
 initUI();
 initData();
 }

 private void initData() {
 //通過(guò)傳遞過(guò)來(lái)的包名獲取攔截應(yīng)用的圖標(biāo)以及名稱(chēng)
 PackageManager pm = getPackageManager();
 try {
  ApplicationInfo applicationInfo = pm.getApplicationInfo(packagename,0);
  Drawable icon = applicationInfo.loadIcon(pm);
  iv_app_icon.setBackgroundDrawable(icon);
  tv_app_name.setText(applicationInfo.loadLabel(pm).toString());
 } catch (NameNotFoundException e) {
  e.printStackTrace();
 }
 
 bt_submit.setOnClickListener(new OnClickListener() {
  @Override
  public void onClick(View v) {
  String psd = et_psd.getText().toString();
  if(!TextUtils.isEmpty(psd)){
   if(psd.equals("123")){
   //解鎖,進(jìn)入應(yīng)用,告知看門(mén)口不要再去監(jiān)聽(tīng)以及解鎖的應(yīng)用,發(fā)送廣播
   Intent intent = new Intent("android.intent.action.SKIP");
   intent.putExtra("packagename",packagename);
   sendBroadcast(intent);
   
   finish();
   }else{
   ToastUtil.show(getApplicationContext(), "密碼錯(cuò)誤");
   }
  }else{
   ToastUtil.show(getApplicationContext(), "請(qǐng)輸入密碼");
  }
  }
 });
 }

 private void initUI() {
 tv_app_name = (TextView) findViewById(R.id.tv_app_name);
 iv_app_icon = (ImageView) findViewById(R.id.iv_app_icon);
 
 et_psd = (EditText) findViewById(R.id.et_psd);
 bt_submit = (Button) findViewById(R.id.bt_submit);
 }
 
 @Override
 public void onBackPressed() {
 //通過(guò)隱式意圖,跳轉(zhuǎn)到桌面
 Intent intent = new Intent(Intent.ACTION_MAIN);
 intent.addCategory(Intent.CATEGORY_HOME);
 startActivity(intent);
 super.onBackPressed();
 }
}

5.隱藏最近打開(kāi)的activity

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

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • android仿知乎標(biāo)題欄隨ScrollView滾動(dòng)變色

    android仿知乎標(biāo)題欄隨ScrollView滾動(dòng)變色

    這篇文章主要為大家詳細(xì)介紹了android仿知乎標(biāo)題欄隨ScrollView滾動(dòng)變色,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-06-06
  • Android編程實(shí)現(xiàn)應(yīng)用強(qiáng)制安裝到手機(jī)內(nèi)存的方法

    Android編程實(shí)現(xiàn)應(yīng)用強(qiáng)制安裝到手機(jī)內(nèi)存的方法

    這篇文章主要介紹了Android編程實(shí)現(xiàn)應(yīng)用強(qiáng)制安裝到手機(jī)內(nèi)存的方法,涉及Android中屬性設(shè)置的相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-11-11
  • Android手冊(cè)之Toolbar搜索聯(lián)動(dòng)及監(jiān)聽(tīng)小技巧

    Android手冊(cè)之Toolbar搜索聯(lián)動(dòng)及監(jiān)聽(tīng)小技巧

    這篇文章主要為大家介紹了Android手冊(cè)之Toolbar搜索聯(lián)動(dòng)及監(jiān)聽(tīng)小技巧示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-09-09
  • Android自定義view實(shí)現(xiàn)滑動(dòng)解鎖效果

    Android自定義view實(shí)現(xiàn)滑動(dòng)解鎖效果

    這篇文章主要為大家詳細(xì)介紹了Android自定義view實(shí)現(xiàn)滑動(dòng)解鎖效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-05-05
  • Android 單雙擊實(shí)現(xiàn)的方法步驟

    Android 單雙擊實(shí)現(xiàn)的方法步驟

    這篇文章主要介紹了Android 單雙擊實(shí)現(xiàn)的方法步驟,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-01-01
  • Android編程設(shè)計(jì)模式之命令模式詳解

    Android編程設(shè)計(jì)模式之命令模式詳解

    這篇文章主要介紹了Android編程設(shè)計(jì)模式之命令模式,詳細(xì)分析了命令模式的概念、功能、使用場(chǎng)景、用法及相關(guān)操作注意事項(xiàng),需要的朋友可以參考下
    2017-12-12
  • Android實(shí)現(xiàn)文字消除效果

    Android實(shí)現(xiàn)文字消除效果

    由于項(xiàng)目和語(yǔ)音識(shí)別相關(guān),有時(shí)候人在不經(jīng)意間交流的無(wú)效音頻會(huì)被識(shí)別出來(lái),并展示于界面,為了美觀,客戶(hù)要求我們將這些無(wú)效的識(shí)別文本用一個(gè)從右到左的動(dòng)畫(huà)給清除,于是便有了下述的技術(shù)實(shí)現(xiàn)。感興趣的朋友可以參考下
    2021-06-06
  • Android RecyclerView 滾動(dòng)到中間位置的方法示例

    Android RecyclerView 滾動(dòng)到中間位置的方法示例

    這篇文章主要介紹了Android RecyclerView 滾動(dòng)到中間位置的方法示例,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-03-03
  • Android安卓中循環(huán)錄像并檢測(cè)內(nèi)存卡容量

    Android安卓中循環(huán)錄像并檢測(cè)內(nèi)存卡容量

    這篇文章主要介紹了Android安卓中循環(huán)錄像并檢測(cè)內(nèi)存卡容量,當(dāng)內(nèi)存卡空間已滿(mǎn)時(shí),本文還實(shí)現(xiàn)自動(dòng)刪除視頻列表里面的第一個(gè)文件,需要的朋友可以參考下
    2015-06-06
  • Android基礎(chǔ)之使用Fragment控制切換多個(gè)頁(yè)面

    Android基礎(chǔ)之使用Fragment控制切換多個(gè)頁(yè)面

    Android官方已經(jīng)提供了Fragment的各種使用的Demo例子,在我們SDK下面的API Demo里面就包含了Fragment的各種使用例子,需要看Demo的朋友,直接看API Demo那個(gè)程序就可以了,不用到處去找。里面分開(kāi)不同功能,實(shí)現(xiàn)了不同的類(lèi)
    2013-07-07

最新評(píng)論