Android:获取当前打开的应用程序的堆栈(数组)

lRa*_*dha 3 java android

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

lRa*_*dha 5

几天来,我一直在使用表情符号键盘。我花了三天的时间才能获得前台应用程序包的名称来发送表情符号图像,因为每当我要发送图像时,它都会弹出窗口intentchooser,选择其中一个可以处理图像的应用程序。

Google弃用了getRunningTasks()用于获取当前正在运行的应用程序的方法,因此所有教程和链接均不适用于我。

然后我想到了使用来获取设备上当前正在运行的应用程序堆栈的方法ResolveInfo,但是它也无法正常工作。

最后,我找到了API 21中引入的新类,该类UsageStatsManager对我有用。这个github链接提供了如何使用此类来获取正在运行的应用程序的程序包名称。

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

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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

不要忘记添加权限:

<uses-permission android:name = "android.permission.PACKAGE_USAGE_STATS"
                     tools:ignore = "ProtectedPermissions"/>
Run Code Online (Sandbox Code Playgroud)

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

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);
}
Run Code Online (Sandbox Code Playgroud)

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

希望这会有所帮助。