android开发分享getRunningTasks在Android L中不起作用

在Android L中,Google禁用了getRunningTasks。 现在只能返回自己的应用任务和主页启动器。 我不能再获得其他的应用程序任务。 我们的应用需要这种方法来确定当前顶级应用 任何人有另一种方法来做到这一点?

我在Google中search过,除此之外,没有更多的话题可以参考: https : //code.google.com/p/android-developer-preview/issues/detail?id = 29

    对于我最近开发的一个项目,我还需要检测何时启动某些应用程序。 我所有的研究都是以getRunningTasks方法为基础的,这个方法从Lollipop开始已经被废弃了。 然而,令我惊讶的是,我发现一些应用程序locking应用程序仍然在棒棒糖设备上工作,所以他们必须想出一个解决scheme来解决这个问题。 所以我挖了一点。 这是我发现的:

    一些示例代码来检测何时启动默认日历应用程序:

    public class DetectCalendarLaunchRunnable implements Runnable { @Override public void run() { String[] activePackages; if (Build.VERSION.SDK_INT > Build.VERSION_CODES.KITKAT_WATCH) { activePackages = getActivePackages(); } else { activePackages = getActivePackagesCompat(); } if (activePackages != null) { for (String activePackage : activePackages) { if (activePackage.equals("com.google.android.calendar")) { //Calendar app is launched, do something } } } mHandler.postDelayed(this, 1000); } String[] getActivePackagesCompat() { final List<ActivityManager.RunningTaskInfo> taskInfo = mActivityManager.getRunningTasks(1); final ComponentName componentName = taskInfo.get(0).topActivity; final String[] activePackages = new String[1]; activePackages[0] = componentName.getPackageName(); return activePackages; } String[] getActivePackages() { final Set<String> activePackages = new HashSet<String>(); final List<ActivityManager.RunningAppProcessInfo> processInfos = mActivityManager.getRunningAppProcesses(); for (ActivityManager.RunningAppProcessInfo processInfo : processInfos) { if (processInfo.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND) { activePackages.addAll(Arrays.asList(processInfo.pkgList)); } } return activePackages.toArray(new String[activePackages.size()]); } } 

    注意:getRunningAppProcesses也用于debugging或“构build面向用户的stream程pipe理UI”。 不知道谷歌是否会像使用getRunningTasks一样来closures这个后门。

    所以不,你不能得到topActivity了。 但有一点点破解你可以达到类似的结果。

    正如MKY提到的, getRunningTasks()方法不适用于获取棒棒糖中的当前应用程序。

    正如sunxin8086写的,获取正在运行的应用程序的一种方法是使用getRunningAppsProcesses()方法。 但是,条件info.importance == IMPORTANCE_FOREGROUND无法唯一确定当前应用程序。

    确定当前前台应用程序的更好方法可能是检查RunningAppProcessInfo对象中的processState字段。 这个字段是一个隐藏的字段,但你可以在RunningAppProcessInfo类中看到它。 如果这个值是ActivityManager.PROCESS_STATE_TOP (也是隐藏的静态常量),那么这个过程就是当前的前台进程。

    例如代码是

     final int PROCESS_STATE_TOP = 2; ActivityManager.RunningAppProcessInfo currentInfo = null; Field field = null; try { field = ActivityManager.RunningAppProcessInfo.class.getDeclaredField("processState"); } catch (Exception ignored) { } ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); List<ActivityManager.RunningAppProcessInfo> appList = am.getRunningAppProcesses(); for (ActivityManager.RunningAppProcessInfo app : appList) { if (app.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND && app.importanceReasonCode == ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN) { Integer state = null; try { state = field.getInt(app); } catch (Exception e) { } if (state != null && state == PROCESS_STATE_TOP) { currentInfo = app; break; } } } return currentInfo; 

    注意: pre-Lolipop中不存在processState字段。 在运行上面的代码之前,请检查Build.VERSION.SDK_INT >= 21 。 上面的代码只适用于棒棒糖+。

    加斯顿的另一种方法(与此截然不同)和“当前应用”的含义与这种方法略有不同。

    请为您的目的select一个。


    [编辑]

    正如Sam指出的,我通过PROCESS_STATE_TOP修改了START_TASK_TO_FRONT 。 (两个值都是2)

    [EDIT2]

    山姆有一个新的发现! 要唯一确定前台应用程序,还需要一个条件

     process.importanceReasonCode == 0 

    是必要的。 上面的代码已经更新。 谢谢!

    这里有一个确切的解决scheme,以获得您的Android L / Lollipop设备和Android M /棉花糖设备上的当前顶级活动。

    首先调用这行代码:(一次)

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

    上面的代码将打开一个名为“使用访问权限的应用程序”的屏幕。 只需检查单选button以开启/允许使用访问。 现在在您的服务或任何你想要的地方调用以下方法:

     public void getTopActivtyFromLolipopOnwards() { String topPackageName; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { UsageStatsManager mUsageStatsManager = (UsageStatsManager) getSystemService(Context.USAGE_STATS_SERVICE); long time = System.currentTimeMillis(); // We get usage stats for the last 10 seconds List < UsageStats > stats = mUsageStatsManager.queryUsageStats(UsageStatsManager.INTERVAL_DAILY, time - 1000 * 10, time); // Sort the stats by the last time used if (stats != null) { SortedMap < Long, UsageStats > mySortedMap = new TreeMap < Long, UsageStats > (); for (UsageStats usageStats: stats) { mySortedMap.put(usageStats.getLastTimeUsed(), usageStats); } if (mySortedMap != null && !mySortedMap.isEmpty()) { topPackageName = mySortedMap.get(mySortedMap.lastKey()).getPackageName(); Log.e("TopPackage Name", topPackageName); } } } } 

    添加权限

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

    这将返回当前正在运行的活动的包名称,无论是Facebook或WhatsApp。

    这种方法的唯一的复杂性是你需要提示用户允许应用程序使用统计…即第一步。

    希望! 这有助于每个人。

     private String getProcess() throws Exception { if (Build.VERSION.SDK_INT >= 21) { return getProcessNew(); } else { return getProcessOld(); } } //API 21 and above private String getProcessNew() throws Exception { String topPackageName = null; UsageStatsManager usage = (UsageStatsManager) context.getSystemService(Constant.USAGE_STATS_SERVICE); long time = System.currentTimeMillis(); List<UsageStats> stats = usage.queryUsageStats(UsageStatsManager.INTERVAL_DAILY, time - ONE_SECOND * 10, time); if (stats != null) { SortedMap<Long, UsageStats> runningTask = new TreeMap<Long,UsageStats>(); for (UsageStats usageStats : stats) { runningTask.put(usageStats.getLastTimeUsed(), usageStats); } if (runningTask.isEmpty()) { return null; } topPackageName = runningTask.get(runningTask.lastKey()).getPackageName(); } return topPackageName; } //API below 21 @SuppressWarnings("deprecation") private String getProcessOld() throws Exception { String topPackageName = null; ActivityManager activity = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); List<RunningTaskInfo> runningTask = activity.getRunningTasks(1); if (runningTask != null) { RunningTaskInfo taskTop = runningTask.get(0); ComponentName componentTop = taskTop.topActivity; topPackageName = componentTop.getPackageName(); } return topPackageName; } //required permissions <uses-permission android:name="android.permission.PACKAGE_USAGE_STATS"/> <uses-permission android:name="android.permission.GET_TASKS"/> 

    我认为它不可能得到其他应用程序的任务,

    这是文档说的

    通过在即将发布的版本中引入新的并发文档和活动任务function(请参阅下面的“最近的并发文档和活动”屏幕 ),现在不推荐使用ActivityManager.getRecentTasks()方法来提高用户的隐私性。 为了向后兼容,这个方法仍然返回一小部分数据,包括调用应用程序自己的任务以及其他一些非敏感的任务(比如Home)。 如果您的应用程序使用此方法来检索自己的任务,请使用android.app.ActivityManager.getAppTasks()来检索该信息。

    查看Android L的api概述

      以上就是android开发分享getRunningTasks在Android L中不起作用相关内容,想了解更多android开发(异常处理)及android游戏开发关注计算机技术网(www.ctvol.com)!)。

      本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

      ctvol管理联系方式QQ:251552304

      本文章地址:https://www.ctvol.com/addevelopment/520570.html

      (0)
      上一篇 2020年12月7日
      下一篇 2020年12月7日

      精彩推荐