簡體   English   中英

Android:獲取當前打開的應用程序的堆棧(數組)

[英]Android: Get the stack (array) of currently opened applications

有沒有辦法獲取當前運行或打開的Android應用程序的列表,以便我可以找到在設備中運行的最后一個應用程序。 謝謝

我很快就開始使用表情符號鍵盤了。 我花了三天的時間來獲取前景應用程序包名稱以發送表情符號圖像,因為每當我想發送圖像時,它只是彈出intentchooser來選擇一個可以處理圖像作為附加功能的應用程序。

所有教程和鏈接都不適用於我,因為谷歌不贊成用於獲取當前正在運行的應用程序的getRunningTasks()方法。

然后我想到了使用ResolveInfo在設備上獲取當前正在運行的應用程序的堆棧,但它也沒有用。

最后,我在API 21中找到了一個名為UsageStatsManager的新類, UsageStatsManagerUsageStatsManager 此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;
    }
}

然后我只需使用以下代碼獲取應用程序包名稱的ArrayList:

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"/>

以下代碼檢查我們的應用程序是否有權獲取其他應用程序狀態:

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);
}

上面的代碼將打開一個訪問設置頁面,使我們的應用程序能夠獲取其他應用程序使用情況統計信息(一次)。

希望這會有所幫助。

我使用這段代碼來查看系統中安裝的軟件包名稱的實際列表:

            try {
                Process process = Runtime.getRuntime().exec("pm list packages");
                BufferedReader bufferedReader = new BufferedReader(
                                         new InputStreamReader(process.getInputStream()));

                int read;
                char[] buffer = new char[4096];
                StringBuffer output = new StringBuffer();

                while ((read = bufferedReader.read(buffer)) > 0) {
                    output.append(buffer, 0, read);
                }
                bufferedReader.close();
                process.waitFor();

                Log.d("your tag", output.toString());
            } catch (IOException ioe) {
                ioe.printStackTrace();
            } catch (InterruptedException ie) {
                ie.printStackTrace();
            }

我確信通過包和PID你可以調整ADB shell控制台中的命令來查找有關應用列表的時間信息,但我認為你不能看到最后一個應用程序在系統上打開,盡管我不知道知道shell控制台使用的所有命令......

Runtime.getRuntime().exec("top -n 1 -d 1");

例如,此命令顯示設備中的不同進程及其資源消耗。

在以下文檔中與他們會面: https//developer.android.com/studio/command-line

有關:

如果你想要它更具反應性,我實際上只是通過LiveData處理類似的場景。 查看我的博客文章: https//bmcreations.dev/blog/foreground-app-observing-with-lifecycle-components

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM