2015-01-21 108 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

相关问题