AndroidTV:UsageStatsManager 在重新启动后不返回应用结果的详细信息
Posted
技术标签:
【中文标题】AndroidTV:UsageStatsManager 在重新启动后不返回应用结果的详细信息【英文标题】:AndroidTV: UsageStatsManager not returning details for apps results after Reboot 【发布时间】:2019-05-28 07:30:16 【问题描述】:我正在开发一个 android TV 应用(系统应用),我正在尝试使用 UsageStatsManager 来获取最近使用的应用列表。 通过以下方法,
UsageStatsManager usm = getUsageStatsManager(context);
Calendar calendar = Calendar.getInstance();
long endTime = calendar.getTimeInMillis();
calendar.add(Calendar.YEAR, -1)
final List<UsageStats> usageStatsList = usageStatsManager.queryUsageStats(UsageStatsManager.INTERVAL_YEARLY, startTime, endTime);
上述方法提供了正确的使用数据,但在设备重启后,它不会提供以前使用过的应用使用数据,直到该应用在重启后再次打开。
但相同的代码在 android Phone 中运行良好(重启后)。
我还在 Android TV 中尝试了来自 Github 的 sample App,它在 Android TV 中重新启动后也无法提供详细信息(但适用于 Mobile,两个操作系统版本 8)。
为什么它无法获取 Android TV 的应用使用数据?
TIA
【问题讨论】:
你找到解决办法了吗? 这似乎是 Android Tv 中的一个错误。我已经检查了一个有根的android电视盒,在路径“/data/system/usagestats/0/”中重新启动之前,我可以在每日使用统计记录中看到最后使用的时间。但是在同一个文件夹中重新启动后我没有不再查看以前使用的应用程序的数据。即使我检查了每周、每月和每年的数据,但结果相同。 【参考方案1】:@Nainal 是一种解决方法。
正如我们所经历的,在设备重启后,Android 电视盒不会返回已安装应用程序的使用统计信息。这是我遵循的解决方法。
我们获取已安装应用程序的详细信息,然后仅将上次使用的时间存储在哈希图中。 我们使用自定义比较器来比较上次使用的时间,并对我们的已安装应用程序详细信息列表 (ResolveInfo) 进行排序,以获得最近使用的应用程序列表。 现在为了克服设备重启场景的情况,我们在app本地维护一个Hash map。我们会将已安装 App 的 Last used time 存储为 Long millis (epoch) 。 lastTimeUsedMap = new HashMap(); 每次从 UsageStatsManager 获得新数据时,我们都会更新地图。我们简化了地图对象并以字符串形式存储在共享首选项中。
首先重新启动后,我们将在使用情况统计中找到已安装的软件包是否有时间戳。如果没有,我们将从存储的 MAP 中获取时间。
代码如下:
private void SortByRecentlyUsed(final List<ResolveInfo> info, final Context context)
/*load LastTimeUsedMap from pref*/
lastTimeUsedMap = loadLastTimeUsedMap(context);
UsageStatsManager usm = getUsageStatsManager(context);
Calendar calendar = Calendar.getInstance();
long endTime = calendar.getTimeInMillis();
calendar.add(Calendar.MONTH, -1);
long startTime = calendar.getTimeInMillis();
final List<UsageStats> usageStatsList = usm.queryUsageStats(UsageStatsManager.INTERVAL_BEST, startTime, endTime);
/*Update AppRecentTimeUsedMap with latest data from UsageStatsManager*/
updateAppRecentTimeUsedMap(usageStatsList,info);
class RecentUseComparator implements Comparator<ResolveInfo>
@Override
public int compare(ResolveInfo lhs, ResolveInfo rhs)
String lhsPackageName=lhs.activityInfo.applicationInfo.packageName;
String rhsPackageName=rhs.activityInfo.applicationInfo.packageName;
long lhsUsedTime = getLastUsedTime(lhsPackageName);
long rhsUsedTime = getLastUsedTime(rhsPackageName);
return (lhsUsedTime > rhsUsedTime) ? -1 : (lhsUsedTime == rhsUsedTime) ? 0 : 1;
private long getLastUsedTime(String packageDetails)
long appRecentUsedtime = -1;
if (appRecentTimeUsedMap.containsKey(packageDetails))
appRecentUsedtime = appRecentTimeUsedMap.get(packageDetails);
return appRecentUsedtime;
RecentUseComparator mRecentComp = new RecentUseComparator();
Collections.sort(info, mRecentComp);
/*Save the updated LastTimeUsedMap in pref*/
saveLastTimeUsedMap(lastTimeUsedMap, context);
private void updateAppRecentTimeUsedMap(List<UsageStats> usageStatsList,List<ResolveInfo> info)
String packageName=null;
if (usageStatsList != null)
for (ResolveInfo Rinfo : info)
packageName = Rinfo.activityInfo.applicationInfo.packageName;
boolean added = false;
for (UsageStats usageStats : usageStatsList)
if (packageName.equalsIgnoreCase(usageStats.getPackageName()))
appRecentTimeUsedMap.put(usageStats.getPackageName(), usageStats.getLastTimeUsed());
updateLastTimeUsedMap(usageStats.getPackageName(), usageStats.getLastTimeUsed());
added=true;
if (!added && lastTimeUsedMap.containsKey(packageName))
appRecentTimeUsedMap.put(packageName, lastTimeUsedMap.get(packageName));
private void updateLastTimeUsedMap(String packageName,Long timeStamp)
lastTimeUsedMap.put(packageName, timeStamp);
/**
* Return Map containing Package name and recent used time from preference
*
* @param context
* @return Map<String,Long>
*/
private Map<String,Long> loadLastTimeUsedMap(Context context)
Map<String,Long> outputMap = new HashMap<String,Long>();
SharedPreferences pSharedPref = context.getSharedPreferences(LAST_TIME_USED_PREFS, Context.MODE_PRIVATE);
try
if (pSharedPref != null)
String jsonString = pSharedPref.getString(LAST_TIME_USED_MAP, (new JSONObject()).toString());
JSONObject jsonObject = new JSONObject(jsonString);
Iterator<String> keysItr = jsonObject.keys();
while(keysItr.hasNext())
String key = keysItr.next();
Long value = jsonObject.getLong(key);
outputMap.put(key, value);
catch(Exception e)
e.printStackTrace();
return outputMap;
/**
* Save the updated map containing Package name and recent used time in preference
*
* @param inputMap
* @param context
*/
private void saveLastTimeUsedMap(Map<String,Long> inputMap, Context context)
final SharedPreferences sharedPreferences = context.getSharedPreferences(LAST_TIME_USED_PREFS,Context.MODE_PRIVATE);
if (sharedPreferences != null)
JSONObject jsonObject = new JSONObject(inputMap);
String jsonString = jsonObject.toString();
final SharedPreferences.Editor editor = sharedPreferences.edit();
editor.remove(LAST_TIME_USED_MAP).commit();
editor.putString(LAST_TIME_USED_MAP, jsonString);
editor.commit();
【讨论】:
以上是关于AndroidTV:UsageStatsManager 在重新启动后不返回应用结果的详细信息的主要内容,如果未能解决你的问题,请参考以下文章
Android Facebook SDK 3.23.0 - AndroidTV 上的 FB 登录
AndroidTV - 为 X 行自定义 ListRow。失去焦点
AndroidTV - 更改行标题的颜色 [BrowseFragment]