Android:获取当前打开的应用程序的堆栈(数组) [英] Android: Get the stack (array) of currently opened applications

查看:88
本文介绍了Android:获取当前打开的应用程序的堆栈(数组)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有没有办法获取当前正在运行或已打开的Android应用程序的列表,以便我可以找到设备中运行的最后一个应用程序。谢谢

Is there any way to get the list of the currently running or opened android applications, so that I can found the last application running in the device. Thanks

推荐答案

我正在快速的几天里使用表情符号键盘。我花了三天的时间来获取前景应用程序包名称以发送表情符号图像,因为每当我想发送图像时它只需弹出 intentchooser 来选择其中一个应用程序那些可以处理图像作为额外的。

I was working on an emoji keyboard from fast few days. It take me three days to get the foreground application package name to send the emoji images, as whenever I want to send the images it just popups the intentchooser to choose one of the application those can handle the images as extras.

所有的教程和链接都不适合我,因为谷歌不推荐使用的 getRunningTasks()方法获取当前正在运行的应用程序。

All the tutorials and links does not work for me as google deprecated the getRunningTasks() method that was used to get the currently running applications.

然后我有一个绝妙的主意,使用 ResolveInfo ,但它没有用。

Then I got a brilliant idea to get the stack of the currently running applications on the device using ResolveInfo, but it did not work to.

最后我在API 21中引入了一个名为 UsageStatsManager的新类哪个适合我。 此github链接提供了如何使用此类来运行应用程序包名称。

Final I got a new class introduced in API 21 named UsageStatsManager which work for me. This github link provide how to use this class to get the running applications packagename.

以下是我的代码如何在顶部运行包名称应用程序:

Below is my code how I got the package name application running on the top:

public class UStats {
    public static final String TAG = UStats.class.getSimpleName();
    @SuppressLint("SimpleDateFormat")
    private static final SimpleDateFormat dateFormat = new SimpleDateFormat("M-d-yyyy HH:mm:ss");

    public static ArrayList<String> printCurrentUsageStatus(Context context) {
        return printUsageStats(getUsageStatsList(context));
    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    public static ArrayList<String> printUsageStats(List<UsageStats> usageStatsList) {
        HashMap<String, Integer> lastApp = new HashMap<String, Integer>();
        for (UsageStats u : usageStatsList) {
            lastApp.put(u.getPackageName(), (int) u.getLastTimeStamp());
            /*Log.d(TAG, "Pkg: " + u.getPackageName() + "\t" + "ForegroundTime: "
                    + u.getTotalTimeInForeground() + "\t" + "LastTimeStamp: " + new Date(u.getLastTimeStamp()));*/
        }
        Map<String, Integer> sortedMapAsc = sortByComparator(lastApp);
        ArrayList<String> firstApp = new ArrayList<>();
        for (Map.Entry<String, Integer> entry : sortedMapAsc.entrySet()) {
            String key = entry.getKey();
            //Integer value = entry.getValue();
            firstApp.add(key);
            /*System.out.println("package name: " + key + ", time " + new Date(Math.abs(value)));*/
        }

        return firstApp;
    }

    // To check the USAGE_STATS_SERVICE permission
    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    public static List<UsageStats> getUsageStatsList(Context context) {
        UsageStatsManager usm = getUsageStatsManager(context);
        Calendar calendar = Calendar.getInstance();
        long endTime = calendar.getTimeInMillis();
        calendar.add(Calendar.MINUTE, -1);
        long startTime = calendar.getTimeInMillis();

        Log.d(TAG, "Under getUsageStateList");
        Log.d(TAG, "Range start:" + dateFormat.format(startTime));
        Log.d(TAG, "Range end:" + dateFormat.format(endTime));

        List<UsageStats> usageStatsList = usm.queryUsageStats(UsageStatsManager.INTERVAL_DAILY, startTime, endTime);
        return usageStatsList;
    }

    // Sort the map in the ascending order of the timeStamp
    private static Map<String, Integer> sortByComparator(Map<String, Integer> unsortMap) {
        List<Map.Entry<String, Integer>> list = new LinkedList<>(unsortMap.entrySet());

        // Sorting the list based on values
        Collections.sort(list, new Comparator<Map.Entry<String, Integer>>() {
            public int compare(Map.Entry<String, Integer> o1,
                               Map.Entry<String, Integer> o2) {
                return o2.getValue().compareTo(o1.getValue());
            }
        });

        // Maintaining insertion order with the help of LinkedList
        Map<String, Integer> sortedMap = new LinkedHashMap<String, Integer>();
        for (Map.Entry<String, Integer> entry : list) {
            sortedMap.put(entry.getKey(), entry.getValue());
        }
        return sortedMap;
    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP_MR1)
    @SuppressWarnings("ResourceType")
    private static UsageStatsManager getUsageStatsManager(Context context) {
        UsageStatsManager usm = (UsageStatsManager) context.getSystemService(Context.USAGE_STATS_SERVICE);
        return usm;
    }
}

然后我只需获取应用程序包名称的ArrayList ,使用以下代码:

Then I simply get the ArrayList of the application package names, using the below code:

ArrayList<String> sortedApplication = UStats.printCurrentUsageStatus(SimpleIME.this);
Log.d("TAG", "applicationList: " + sortedApplication.toString());

别忘了添加权限:

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

以及以下代码,用于检查我们的应用程序是否有权获取其他应用程序状态:

and the below code to check that our application has the permission to get the other applications status:

if (UStats.getUsageStatsList(this).isEmpty()) {
    Intent intent = new Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS);
    Toast.makeText(MainActivity.this, "Enable Usage Access for YOUR_APP_NAME to use this app", Toast.LENGTH_LONG).show();
    startActivity(intent);
}

以上代码将打开访问设置页面,以使我们的应用程序能够获取其他应用程序使用统计数据(一次)。

The above code will open a access setting page to enable our application to get the other application usage stats (for once).

希望这会有所帮助。

这篇关于Android:获取当前打开的应用程序的堆栈(数组)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆