name - android activity title




如何在Android“L”上獲得最近的任務? (3)

@ user3742392答案很好,但是使用TreeMap查找上次使用的時間有點矯枉過正(特別是如果你想定期檢查頂級運行的應用程序)。

這是編輯後的答案,沒有使用簡單循環的TreeMap:

String topPackageName;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    UsageStatsManager mUsageStatsManager = (UsageStatsManager) getSystemService("usagestats");
    long currentTime = System.currentTimeMillis();
    // get usage stats for the last 10 seconds
    List<UsageStats> stats = mUsageStatsManager.queryUsageStats(UsageStatsManager.INTERVAL_DAILY, currentTime - 1000 * 10, currentTime);
    // search for app with most recent last used time
    if (stats != null) {
        long lastUsedAppTime = 0;
        for (UsageStats usageStats : stats) {
            if (usageStats.getLastTimeUsed() > lastUsedAppTime) {
                topPackageName = usageStats.getPackageName();
                lastUsedAppTime = usageStats.getLastTimeUsed();
            }
        }
    }
}

背景

我的應用程序允許在最近啟動時對應用程序列表進行排序。

問題

從Android“L”開始,函數getRecentTasks將返回當前應用程序已啟動的應用程序列表,如documentation中所述:

如果您的應用使用ActivityManager.getRecentTasks()...

通過在即將發布的版本中引入新的並發文檔和活動任務功能(請參閱下面的“最近的並發文檔和活動”屏幕),現在不推薦使用ActivityManager.getRecentTasks()方法來提高用戶隱私。 為了向後兼容,此方法仍然返回其數據的一小部分,包括調用應用程序自己的任務以及可能的一些其他非敏感任務(例如Home)。 如果您的應用使用此方法檢索自己的任務,請使用android.app.ActivityManager.getAppTasks()來檢索該信息。

使用ADT顯示此功能的文檔(當前在Internet上不可用)時寫入相同內容:

不推薦使用此方法。 從L開始,這種方法不再適用於第三方應用程序:因為引入以文檔為中心的最新版本意味著它可以將個人信息洩露給調用者。 為了向後兼容,它仍將返回其數據的一小部分:至少是調用者自己的任務(儘管請參閱getAppTasks()以獲取正確支持的方式來檢索該信息),以及可能還有一些其他任務,例如home不敏感。

我不明白為什麼採取這種行為,因為很容易看到用戶擁有哪些應用程序,甚至沒有任何許可。

事實上,這是我添加的這個功能的一個很大的限制,所以我希望有一種方法可以解決這個問題。

我試過的

目前,我只使用了一種關於最近推出了哪些應用程序的啟發式方法 - 我得到了正在運行的進程列表。

我也可以使用流程的重要性值,也許還可以使用“importanceReasonComponent”,但這只是所有的啟發式和猜測......

這個問題

有沒有辦法克服這個限制? 我沒有想到的任何解決方法?

也許這有可能與root? 還是BusyBox?



要獲取當前運行的top(Foreground)包名稱,您需要使用Android Lollipop中的Usage Stats API。

但請注意,用戶必須在每個應用程序的設置中批准訪問使用數據。 因此,您應該通過啟動設置操作直接提示用戶進行設置

Intent intent = new Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS);

要獲得頂級包名稱:

String topPackageName ;
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { 
    UsageStatsManager mUsageStatsManager = (UsageStatsManager)getSystemService("usagestats");                       
    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.isEmpty()) {
            topPackageName =  mySortedMap.get(mySortedMap.lastKey()).getPackageName();                                   
        }                                       
    }
}






android-task