2015-01-21 183 views
21

我正在創建一個應用程序鎖定應用程序,如何獲得lollipop.getRunningTaskinfo方法中的當前正在運行的任務已棄用在棒棒糖api中,然後如何解決問題。如何獲取TopActivity名稱或獲取棒棒糖當前正在運行的應用程序包名稱?

+0

您可以使用UsageStatsManager要查詢的事件(不使用狀態),但按照文件,最後分(實際秒)被切斷,防止非系統應用程序知道當前正在運行的應用程序。 – 2015-01-21 12:00:11

回答

29

試試這個:

ActivityManager mActivityManager =(ActivityManager)this.getSystemService(Context.ACTIVITY_SERVICE); 

if(Build.VERSION.SDK_INT > 20){ 
String mPackageName = mActivityManager.getRunningAppProcesses().get(0).processName; 
} 
else{ 
    String mpackageName = mActivityManager.getRunningTasks(1).get(0).topActivity.getPackageName(); 
} 

我們可以得到使用usagestats機:

public static String getTopAppName(Context context) { 
    ActivityManager mActivityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); 
    String strName = ""; 
    try { 
     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { 
      strName = getLollipopFGAppPackageName(context); 
     } else { 
      strName = mActivityManager.getRunningTasks(1).get(0).topActivity.getClassName(); 
     } 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
    return strName; 
} 


private static String getLollipopFGAppPackageName(Context ctx) { 

    try { 
     UsageStatsManager usageStatsManager = (UsageStatsManager) ctx.getSystemService("usagestats"); 
     long milliSecs = 60 * 1000; 
     Date date = new Date(); 
     List<UsageStats> queryUsageStats = usageStatsManager.queryUsageStats(UsageStatsManager.INTERVAL_DAILY, date.getTime() - milliSecs, date.getTime()); 
     if (queryUsageStats.size() > 0) { 
      Log.i("LPU", "queryUsageStats size: " + queryUsageStats.size()); 
     } 
     long recentTime = 0; 
     String recentPkg = ""; 
     for (int i = 0; i < queryUsageStats.size(); i++) { 
      UsageStats stats = queryUsageStats.get(i); 
      if (i == 0 && !"org.pervacio.pvadiag".equals(stats.getPackageName())) { 
       Log.i("LPU", "PackageName: " + stats.getPackageName() + " " + stats.getLastTimeStamp()); 
      } 
      if (stats.getLastTimeStamp() > recentTime) { 
       recentTime = stats.getLastTimeStamp(); 
       recentPkg = stats.getPackageName(); 
      } 
     } 
     return recentPkg; 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
    return ""; 
} 

//要啓用USAGE_STATS

// Declare USAGE_STATS permisssion in manifest 

    <uses-permission 
    android:name="android.permission.PACKAGE_USAGE_STATS" 
    tools:ignore="ProtectedPermissions" /> 


    Intent intent = new Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS); 
    startActivity(intent); 
+0

這將返回進程名稱而不是包名稱。他們有時不同。 – Sam 2015-05-16 03:15:19

+0

這似乎使用基本活動,而不是API 20的頂級活動。它不應該是最重要的活動嗎? – Sam 2015-05-16 03:16:08

+1

我認爲它返回應用程序基礎包名稱。 – WenChao 2015-07-28 04:59:00

0

可以這樣實現.....

ActivityManager am =(ActivityManager)context.getSystemService(ACTIVITY_SERVICE); 
List<ActivityManager.RunningTaskInfo> tasks = am.getRunningTasks(1); 
ActivityManager.RunningTaskInfo task = tasks.get(0); // current task 
ComponentName rootActivity = task.baseActivity; 


rootActivity.getPackageName();//*currently active applications package name* 

對於棒棒糖:

ActivityManager mActivityManager =(ActivityManager)this.getSystemService(Context.ACTIVITY_SERVICE); 

if(Build.VERSION.SDK_INT > 20){ 
    String activityName =mActivityManager.getRunningAppProcesses().get(0).processName; 
} 
else{ 
String activityName = mActivityManager.getRunningTasks(1).get(0).topActivity.getPackageName(); 
} 

完全例如check this out...

+0

'getRunningTasks'不適用於Android 5中的某些任務。 – Sam 2015-05-16 03:17:03

+0

[getRunningAppProcesses](https://developer.android.com/reference/android/app/ActivityManager.html#getRunningAppProcesses())僅帶有警告在調試模式下使用它 – Clocker 2016-11-26 00:58:18

+0

@sam編輯我的答案。 – 2016-11-28 06:02:41

1

試試這個..這對我有效。

ActivityManager activityManager = (ActivityManager) getSystemService (Context.ACTIVITY_SERVICE); 

if (Build.VERSION.SDK_INT == Build.VERSION_CODES.LOLLIPOP)  
{ 

String packageName = activityManager.getRunningAppProcesses().get(0).processName; 
} 
else if(Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP) 
{ 
String packageName = ProcessManager.getRunningForegroundApps(getApplicationContext()).get(0).getPackageName(); 

} 
else 
{ 
String packageName = activityManager.getRunningTasks(1).get(0).topActivity.getPackageName(); 
} 
+3

什麼是ProcessManager? – 2016-08-29 07:46:20

+0

請注意,'.processName'並不總是成爲進程的包名稱。 – Sam 2016-11-04 22:08:52

+2

我只是做了一個快速的Google搜索,'ProcessManager'似乎是['AndroidProcesses'](https://github.com/jaredrummler/AndroidProcesses)庫中的不贊成使用的類。 – Sam 2016-11-04 22:12:55

2

在API 21或更高版本中運行應用程序的最佳解決方案是在下面試試。 這個工作對我來說

private String retriveNewApp() { 
    if (VERSION.SDK_INT >= 21) { 
     String currentApp = null; 
     UsageStatsManager usm = (UsageStatsManager) this.getSystemService(Context.USAGE_STATS_SERVICE); 
     long time = System.currentTimeMillis(); 
     List<UsageStats> applist = usm.queryUsageStats(UsageStatsManager.INTERVAL_DAILY, time - 1000 * 1000, time); 
     if (applist != null && applist.size() > 0) { 
      SortedMap<Long, UsageStats> mySortedMap = new TreeMap<>(); 
      for (UsageStats usageStats : applist) { 
       mySortedMap.put(usageStats.getLastTimeUsed(), usageStats); 
      } 
      if (mySortedMap != null && !mySortedMap.isEmpty()) { 
       currentApp = mySortedMap.get(mySortedMap.lastKey()).getPackageName(); 
      } 
     } 
     Log.e(TAG, "Current App in foreground is: " + currentApp); 

     return currentApp; 

    } 
    else { 

     ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE); 
     String mm=(manager.getRunningTasks(1).get(0)).topActivity.getPackageName(); 
     Log.e(TAG, "Current App in foreground is: " + mm); 
     return mm; 
    } 
} 
+0

關於SDK_INT> = 21的情況,哪些應用程序的進程仍然存在? – 2016-09-21 06:39:58

+0

不工作返回null – 2017-07-02 10:26:03

-2

我用得到頂級活動名稱的哈克的方式。 每當我創建或恢復某個活動時,我都將其名稱保存在Sharedpreferences中。我創建了兩個函數來保存並從SharedPreferences獲取頂級類。這總是覆蓋最後的活動並提供最高的活動。 我不必擔心權限和API級別。 非常簡單,但絕對不是最好的方式。

+1

對不起,但該問題詢問與您的應用程序名稱不同的包名 – Penn 2016-12-01 19:50:57

2

您可以使用AccessibilityService獲取當前正在運行的應用程序。 輔助功能服務提供了onAccessibilityEvent事件。

以下是一些示例代碼。

@Override 
    public void onAccessibilityEvent(AccessibilityEvent event) { 
     if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) { 
      if (event.getPackageName() != null && event.getClassName() != null) { 
       Log.d("Foreground App", event.getPackageName().toString()); 

      } 
     } 
    } 

你可以找到關於無障礙服務的詳細信息here

相關問題