Android應用鎖之獲取棧頂Activity
1、在早期的安卓版本當中,我們可以使用ActivityManager. getRunningTasks 方法來獲取當前執行棧頂程式。
ActivityManager安卓官方API文件實現的核心程式碼如下:
List<PackageInfo> packages = getPackageManager(). getInstalledPackages(0); ActivityManager mActivityManager; mActivityManager = (ActivityManager) this.getSystemService( Context.ACTIVITY_SERVICE); ComponentName topActivity = mActivityManager. getRunningTasks(1).get(0).topActivity; String packageName = topActivity.getPackageName();
需要開啟這個許可權:需要注意的是:在官方文件裡面明確說明,該方法在sdk 21之後就被棄用了。This method was deprecated in API level 21.所以下面要介紹API 21之後的實現方式。
2、 Android 5.0下如何獲取棧頂Activity需要使用的是getRunningAppProcesses方法來實現。完整實現的程式碼如下:
String packname = ""; /* Android5.0之後獲取程式鎖的方式是不一樣的*/ if (Build.VERSION.SDK_INT > 20) { // 5.0及其以後的版本 List<RunningAppProcessInfo> tasks = am.getRunningAppProcesses(); if (null != tasks && tasks.size() > 0) { packname = tasks.get(0).processName; } } else{ // 5.0之前 // 獲取正在執行的任務棧(一個應用程式佔用一個任務棧) 最近使用的任務棧會在最前面 // 1表示給集合設定的最大容量 List<RunningTaskInfo> infos = am.getRunningTasks(1); // 獲取最近執行的任務棧中的棧頂Activity(即使用者當前操作的activity)的包名 packname = infos.get(0).topActivity.getPackageName(); }
需要說明的是,還有人提到了另外一種實現的方式,和這個略微不同,據說都能在Android 5.0 當中實現。具體的方式如下:
if (Build.VERSION.SDK_INT > 21) { // 5.0及其以後的版本 List<ActivityManager.AppTask> tasks = mActivityManager.getAppTasks(); if (null != tasks && tasks.size() > 0) { for (ActivityManager.AppTask task:tasks){ packageName = task.getTaskInfo().baseIntent.getComponent().getPackageName(); lable = getPackageManager().getApplicationLabel(getPackageManager().getApplicationInfo(packageName, PackageManager.GET_META_DATA)).toString(); //Log.i(TAG,packageName + lable); } } } else{ // 5.0之前 // 獲取正在執行的任務棧(一個應用程式佔用一個任務棧) 最近使用的任務棧會在最前面 // 1表示給集合設定的最大容量 List<RunningTaskInfo> infos = am.getRunningTasks(1); // 獲取最近執行的任務棧中的棧頂Activity(即使用者當前操作的activity)的包名 packageName = mActivityManager.getRunningTasks(1).get(0).topActivity.getPackageName(); //Log.i(TAG,packageName); }
另外還有一種方式,大家可以看一看,不過整個第二種都用的不多,所以大家也沒必要深究。
public void updateServiceNotification(String message) { if (!PreferenceUtils.getPrefBoolean(this, PreferenceConstants.FOREGROUND, true)) return; String title = PreferenceUtils.getPrefString(this, PreferenceConstants.ACCOUNT, ""); Notification n = new Notification(R.drawable.login_default_avatar, title, System.currentTimeMillis()); n.flags = Notification.FLAG_ONGOING_EVENT | Notification.FLAG_NO_CLEAR; Intent notificationIntent = new Intent(this, MainActivity.class); notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); n.contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT); n.setLatestEventInfo(this, title, message, n.contentIntent); startForeground(SERVICE_NOTIFICATION, n); } Runnable monitorStatus = new Runnable() { public void run() { try { L.i("monitorStatus is running... " + mPackageName); mMainHandler.removeCallbacks(monitorStatus); // 如果在後臺執行並且連線上了 if (!isAppOnForeground()) { L.i("app run in background..."); // if (isAuthenticated())//不判斷是否連線上了。 updateServiceNotification(getString(R.string.run_bg_ticker)); return;// 服務已在前臺執行,可以停止重複執行此任務 } else { stopForeground(true); } mMainHandler.postDelayed(monitorStatus, 1000L); } catch (Exception e) { e.printStackTrace(); L.i("monitorStatus:"+e.getMessage()); } } }
在後來的Android 5.1當中上述方法貌似都不能實現了,這是谷歌出於對使用者隱私的保護而採取的措施。
3、Android 5.1及以上的實現方式使用的方法是:usageStatsManager.queryUsageStats
要使用這個方法,需要在手機設定中開啟該應用的這個許可權。首先需要在manifest.xml當中加入下面的許可權:同時在手機當中也需要使用者手動開啟該許可權的開關。否則將不能獲取當前執行的應用。實現的核心程式碼如下:
private String getRunningApp() {
long ts = System.currentTimeMillis();
List<UsageStats> queryUsageStats = usageStatsManager.queryUsageStats(
UsageStatsManager.INTERVAL_BEST,ts-2000, ts);
if (queryUsageStats == null || queryUsageStats.isEmpty()) {
return null;
}
UsageStats recentStats = null;
for (UsageStats usageStats : queryUsageStats) {
if (recentStats == null ||
recentStats.getLastTimeUsed() < usageStats.getLastTimeUsed()) {
recentStats = usageStats;
}
}
return recentStats.getPackageName();
}
使用這個方法還有兩點需要加以注意:
1、首先要判斷應用是否已經獲取到UsageState的許可權,如果已經獲取,不用做別的操作。
2、應用沒獲取許可權,應當給出一個跳轉的方式,直接跳到該設定的頁面。針對這兩個問題,下面將給出是否有許可權和頁面跳轉的程式碼:
//判斷呼叫該裝置中“有權檢視使用許可權的應用”這個選項的APP有沒有開啟 private boolean isNoSwitch() { long ts = System.currentTimeMillis(); UsageStatsManager usageStatsManager = (UsageStatsManager) getApplicationContext() .getSystemService("usagestats"); List queryUsageStats = usageStatsManager.queryUsageStats( UsageStatsManager.INTERVAL_BEST, 0, ts); if (queryUsageStats == null || queryUsageStats.isEmpty()) { return false; } return true; } //然後就是跳轉的程式碼了: if (isNoOption()) { buttonGuide.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent( Settings.ACTION_USAGE_ACCESS_SETTINGS); startActivity(intent); } });
目前幾乎所有的應用鎖都採用的第3和第1的方式來實現,需要加一個判斷當前版本號的語句。在5.1之後我還沒有找到別的實現方式,如果大家有什麼更好的實現方式,歡迎留言討論。一個簡單的應用鎖實現,能夠在安卓5.1之後的系統完美執行。
https://github.com/liaoxd/asLockApp
原文連結:http://www.jianshu.com/p/eb531b2d1d8e
相關文章
- Android Activity Deeplink啟動來源獲取原始碼分析Android原始碼
- Android探索之旅 | 用ADB獲取應用APK名AndroidAPK
- Linux應用程式獲取執行緒棧的資訊Linux執行緒
- Android之Activity全面解析Android
- Android之獲取手機UDIDAndroid
- Flutter獲取IOS bundle id和Android應用包名FlutteriOSAndroid
- Android技術棧(一)從Activity遷移到FragmentAndroidFragment
- Android基本控制元件和Activity的基本應用Android控制元件
- Android進階;Activity的棧與跳轉(筆記)Android筆記
- Android之Activity基類封裝Android封裝
- Android基礎之Activity全解析Android
- flutter 獲取應用快取以及清除快取Flutter快取
- 應用程式和Activity
- Android的基本控制元件和Activity的應用總結Android控制元件
- android檢視當前應用的的包名和activityAndroid
- Android四大元件之ActivityAndroid元件
- Android全面解析之Activity生命週期Android
- Android 四大元件之 ActivityAndroid元件
- 深入理解Android 之 Activity啟動流程(Android 10)Android
- 直播系統程式碼,Android獲取、設定鎖屏密碼Android密碼
- Android四大元件之Activity篇Android元件
- Appium 在 Android10 系統無法獲取應用 webview 頁面元素APPAndroidWebView
- Android之android:theme設定在Application 和 Activity的區別AndroidAPP
- HarmonyOS NEXT應用開發之Axios獲取解析網路資料iOS
- 應用程式基礎知識:activity和intent——Android開發祕籍IntentAndroid
- Web應用怎樣獲取Access Token?Web
- Linux應用程式設計:用一種討巧方式,來獲取執行緒棧的使用資訊Linux程式設計執行緒
- 用xgboost獲取特徵重要性及應用特徵
- 棧的應用
- Android知識點回顧之Activity基礎Android
- ADB命令獲取Android UIDAndroidUI
- 超簡單獲取快應用摘要值
- 前端資料結構(1)之棧及其應用前端資料結構
- 應用被其他app開啟時,不同啟動模式下activity任務棧的變化APP模式
- Android Activity 重建之狀態儲存與恢復Android
- 【Android】安卓四大元件之Activity(二)Android安卓元件
- Android中WebView跨域漏洞分析和應用克隆問題情景還原(免Root獲取應用沙盒資料)...AndroidWebView跨域
- android獲取位置並上傳Android
- android 獲取手機號碼Android