项目中要求 写一个统计桌面各个应用的使用情况的卡片,包括使用时间, 点击次数,使用流量。android 提供了一个
UsageStatsManager 的类可以使用。记录 应用的信息。
使用之前要加上
<uses-permission android:name="android.permission.PACKAGE_USAGE_STATS"/><!--使用时长-->UsageStatsManager manager = (UsageStatsManager)context.getApplicationContext().getSystemService(Context.USAGE_STATS_SERVICE);
该类中有两个方法如下:
//第一种 List<UsageStats> stats = manager.queryUsageStats(UsageStatsManager.INTERVAL_BEST, startTime, endTime);//第二种
final UsageEvents usageEvents = manager.queryEvents(startTime, right);
第一种方案
可以统计 每天的使用情况,24小时之内, 但是统计的数据不准确。要是统计每小时 应用的使用情况, 就不行了,因为返回的数据,不精确。有可能连着的时间段 的数据 是一样的 。
HashMap<String, UseTimeLengthAppInfo> tempMap = new HashMap<>(); UsageStatsManager manager = (UsageStatsManager) context.getApplicationContext().getSystemService(Context.USAGE_STATS_SERVICE); if (manager != null) { List<UsageStats> stats = manager.queryUsageStats(UsageStatsManager.INTERVAL_BEST, startTime, endTime); for (UsageStats usageStats : stats) { long totalTimeInForeground = usageStats.getTotalTimeInForeground(); if (totalTimeInForeground == 0) { continue; } final long appUseStartTime = getAppUseStartTime(usageStats); final long appUseEndTime = getAppUseEndTime(usageStats); String tempPackageName = usageStats.getPackageName(); final boolean isLauncherExist = isInstallApp(context, tempPackageName); if (!isLauncherExist) { continue; } final int count = getLauncherCount(usageStats); PackageManager packageManager = context.getPackageManager(); final PackageInfo packageInfo = packageManager.getPackageInfo(tempPackageName, 0); if (packageInfo == null) { continue; } ApplicationInfo appInfo = packageInfo.applicationInfo; if (appInfo == null) { continue; } String applicationName = (String) packageManager.getApplicationLabel(appInfo); Drawable drawable = appInfo.loadIcon(packageManager); UseTimeLengthAppInfo appUseInfo = tempMap.get(tempPackageName); if (appUseInfo == null) { appUseInfo = new UseTimeLengthAppInfo() .setAppTitle(applicationName) .setDrawable(drawable) .setLauncherCount(count) .setAppUseTime(totalTimeInForeground) .setPackageName(tempPackageName) .setStartTime(long2Time(appUseStartTime)) .setEndTime(long2Time(appUseEndTime)); } else { long appUseTime = appUseInfo.getAppUseTime(); int launcherCount = appUseInfo.getLauncherCount(); appUseInfo.setAppUseTime(appUseTime + totalTimeInForeground) .setLauncherCount(launcherCount + count); } tempMap.put(tempPackageName, appUseInfo); } Collection<UseTimeLengthAppInfo> values = tempMap.values(); mReturnList.addAll(values);public static int getLauncherCount(UsageStats usageStats) throws Exception { Field field = usageStats.getClass().getDeclaredField("mAppLaunchCount"); return field.getInt(usageStats); } public static long getAppUseStartTime(UsageStats usageStats) throws Exception { Field fieldBegin = usageStats.getClass().getDeclaredField("mBeginTimeStamp"); return fieldBegin.getLong(usageStats); } public static long getAppUseEndTime(UsageStats usageStats) throws Exception { Field fieldEnd = usageStats.getClass().getDeclaredField("mEndTimeStamp"); return fieldEnd.getLong(usageStats); }
第二种方案
是依据 每个时间段的事件 来记录数据,这个还是比较准确的 ,亲测有效。
TimeAndCountInfo info = new TimeAndCountInfo(); HashMap<String, ArrayList<UsageEvents.Event>> packageEvents = new HashMap<>(); UsageStatsManager manager = (UsageStatsManager) context.getApplicationContext().getSystemService(Context.USAGE_STATS_SERVICE); if (manager == null) return info; final UsageEvents usageEvents = manager.queryEvents(startTime, right); while (usageEvents.hasNextEvent()){ UsageEvents.Event event = new UsageEvents.Event(); usageEvents.getNextEvent(event); final String packageName = event.getPackageName(); if (!pkName.equals(packageName)){ continue; } ArrayList<UsageEvents.Event> eventList = packageEvents.get(packageName); if(eventList == null){ eventList = new ArrayList<UsageEvents.Event>(); }else { eventList.add(event); } packageEvents.put(packageName,eventList); } if (packageEvents.size() == 0){ return info; } final ArrayList<UsageEvents.Event> list = packageEvents.get(pkName); if (list == null || list.size() == 0){ return info; } long tempStart = 0; long tempEnd = 0; long totalTime = 0; long lastStart = 0; int totalCount = 0; int showCountFlag = 0; for (UsageEvents.Event event : list) { final int eventType = event.getEventType(); if (eventType == UsageEvents.Event.MOVE_TO_FOREGROUND || eventType == UsageEvents.Event.FOREGROUND_SERVICE_START){ tempStart = event.getTimeStamp(); showCountFlag += 1; } if (eventType == UsageEvents.Event.MOVE_TO_BACKGROUND || eventType == UsageEvents.Event.ACTIVITY_STOPPED || eventType == UsageEvents.Event.FOREGROUND_SERVICE_STOP){ tempEnd = event.getTimeStamp(); lastStart = 0; showCountFlag = 0; } if (tempStart == 0 && tempEnd != 0) { tempEnd = 0; } if (showCountFlag >= 2 && tempStart != 0 && tempEnd == 0){ if (lastStart != 0){ final long tempGap = tempStart - lastStart; totalTime += tempGap>0?tempGap:0; } lastStart = tempStart; } if (tempStart != 0 && tempEnd != 0) { final long gap = Math.abs(tempEnd - tempStart); totalTime += Math.abs(gap); totalCount += 1; tempStart = 0; tempEnd = 0; } } info.setUseCount(totalCount); final String frontProcessPackageName = getCurrentFrontProcessPackageName(context); //这个方法主要是 解决,应用一直在前台,数据不更新的问题 if (!TextUtils.isEmpty(frontProcessPackageName)){ final ArrayList<UsageEvents.Event> eventList = packageEvents.get(frontProcessPackageName); if (eventList != null){ final UsageEvents.Event event = eventList.get(eventList.size() - 1); final int eventType = event.getEventType(); final long currentTimeMillis = System.currentTimeMillis(); if (eventType == UsageEvents.Event.MOVE_TO_FOREGROUND || (eventType == UsageEvents.Event.ACTIVITY_STOPPED && isTopActivityByPkName(frontProcessPackageName))){ final long timeStamp = event.getTimeStamp(); if (timeStamp != 0){ totalTime += (currentTimeMillis - timeStamp); } } } } info.setUseTime(totalTime);
获取应用使用的流量
使用NetworkStatsManager,里面包含了应用的 流量使用情况。
记得 加上 这个权限
<uses-permission android:name="android.permission.READ_PHONE_STATE" /> <!--应用流量-->
通过 getSystemService 创建 对象。
//第一步 NetworkStatsManager networkStatsManager = (NetworkStatsManager) context.getSystemService(Context.NETWORK_STATS_SERVICE);//第二步
NetworkStats summaryStats; NetworkStats.Bucket summaryBucket = new NetworkStats.Bucket(); HashMap<Integer,Long> map = new HashMap<>(LauncherModel.sBgDataModel.itemsIdMap.size()); try { summaryStats = networkStatsManager.querySummary(networkType, null, startTime, endTime); // final int uid = getUidByPackageName(context, pkName); do { summaryStats.getNextBucket(summaryBucket); int summaryUid = summaryBucket.getUid(); String packages= getPackagesForUid(context, summaryUid); if (TextUtils.isEmpty(packages)){ continue; } if (!isLauncherApp(packages)){ continue; } // final long startTimeStamp = summaryBucket.getStartTimeStamp(); // final long endTimeStamp = summaryBucket.getEndTimeStamp(); long summaryTotal = summaryBucket.getRxBytes() + summaryBucket.getTxBytes(); final Long summary = map.get(summaryUid); if (summary == null){ map.put(summaryUid,summaryTotal); }else{ map.put(summaryUid,summary+summaryTotal); } } while (summaryStats.hasNextBucket()); } catch (Exception e) { e.printStackTrace(); printLog("getSpecialAppByPkName RemoteException --> "); }