As we had experienced that after a device power cycle , Android Tv box won’t return the usage stats of installed application. Here is a workaround I followed .
We fetch the details of installed application then store only last used time in a Hash map.
And we used a custom comparator to compare via last time used and sort our Installed application details list (ResolveInfo) , for recently used app list.
Now to overcome the situation of device power cycle scenario, We are maintaining a Hash map locally in app . Where we will store the installed App’s Last used time as Long millis (epoch) . lastTimeUsedMap = new HashMap(); And we update the map every time we get a new data from UsageStatsManager.
We simplify the map object and store as string in shared preference.
And after reboot first we will find in usage stats if installed package is having a time stamp or not . If not we will get the time from stored MAP .
publicvoidinit(long currentTimeMillis) { synchronized (mLock) { for (File f : mIntervalDirs) { f.mkdirs(); if (!f.exists()) { thrownewIllegalStateException("Failed to create directory " + f.getAbsolutePath()); } }
checkVersionAndBuildLocked(); indexFilesLocked();
//这里会删除掉未来数据 //比如我使用机器的时候是2022年1月1号,此时记录的是这天的时间,但是重启后时间丢失了,变成了出厂设置时间,例如2018年1月1号,这就造成了数据的未来时 // Delete files that are in the future. for (TimeSparseArray<AtomicFile> files : mSortedStatFiles) { finalintstartIndex= files.closestIndexOnOrAfter(currentTimeMillis); if (startIndex < 0) { continue; }
finalintfileCount= files.size(); for (inti= startIndex; i < fileCount; i++) { files.valueAt(i).delete(); }
// Remove in a separate loop because any accesses (valueAt) // will cause a gc in the SparseArray and mess up the order. for (inti= startIndex; i < fileCount; i++) { files.removeAt(i); } } } }
voidflushToDisk() { synchronized (mLock) { // Before flush to disk, report FLUSH_TO_DISK event to signal UsageStats to update app // usage. In case of abrupt power shutdown like battery drain or cold temperature, // all UsageStats has correct data up to last flush to disk. // The FLUSH_TO_DISK event is an internal event, it will not show up in IntervalStats' // EventList. Eventevent=newEvent(FLUSH_TO_DISK, SystemClock.elapsedRealtime()); event.mPackage = DEVICE_EVENT_PACKAGE_NAME; reportEventToAllUserId(event); flushToDiskLocked(); } mAppStandby.flushToDisk(); //注意有些机器的date命令设置这个时间会减少8小时,所以根据实际情况手动调整一下:SystemProperties.set("persist.sys.reboot.time", String.valueOf(System.currentTimeMillis() / 1000 + 8 * 60 * 60 + 60)); SystemProperties.set("persist.sys.reboot.time", String.valueOf(System.currentTimeMillis() / 1000)); }
#!/system/bin/sh time=$(getprop persist.sys.reboot.time) current_time=$(date +%s) if [ -n "$time" ] && [ "$time" -gt "$current_time" ]; then date @$time set hwclock -w fi
init.rc
1 2 3 4 5
service set_time /vendor/bin/set_time.sh classmain userroot grouproot oneshot