android 手机应用时长

项目中要求 写一个统计桌面各个应用的使用情况的卡片,包括使用时间, 点击次数,使用流量。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  --> ");
        }

 

    

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值