android统计手机应用使用时长以及开启次数

今天遇到一个需求,需要将手机里面的应用启动次数以及使用时长给统计出来。首先想到的就是需要开启“允许查看应用的使用情况”这个权限。具体在“设置--安全--有权查看使用情况的应用”。废话不多说,开始撸码。

AndroidManifest.xml中配置权限:

<uses-permission
    android:name="android.permission.PACKAGE_USAGE_STATS"
    tools:ignore="ProtectedPermissions" />

主要用到的类有:

DateTransUtils(时间转换工具类):
package com.testappicon.ustate;

import android.util.Log;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;

/**
 * 
 */

public class DateTransUtils {

    private static final SimpleDateFormat dateFormat  = new SimpleDateFormat("M-d-yyyy");

    public static final long DAY_IN_MILLIS = 24 * 60 * 60 * 1000;

    /*
     * 将时间戳转换为时间
     */
    public static String stampToDate(String stamp){
        String res;
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        long lt = new Long(stamp);
        Date date = new Date(lt);
        res = simpleDateFormat.format(date);
        return res;
    }
    public static String stampToDate(long stamp){
        String res;
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date date = new Date(stamp);
        res = simpleDateFormat.format(date);
        return res;
    }

    //获取今日某时间的时间戳
    public static long getTodayStartStamp(int hour,int minute,int second){
        Calendar cal = Calendar.getInstance();
        cal.setTimeInMillis(System.currentTimeMillis());
        cal.set(Calendar.HOUR_OF_DAY, hour);
        cal.set(Calendar.MINUTE, minute);
        cal.set(Calendar.SECOND, second);
        long todayStamp = cal.getTimeInMillis();

        Log.i("Wingbu"," DateTransUtils-getTodayStartStamp()  获取当日" + hour+ ":" + minute+ ":" + second+ "的时间戳 :" + todayStamp);

        return todayStamp;
    }

    //获取当日00:00:00的时间戳,东八区则为早上八点
    public static long getZeroClockTimestamp(long time){
        long currentStamp = time;
        currentStamp -= currentStamp % DAY_IN_MILLIS;
        Log.i("Wingbu"," DateTransUtils-getZeroClockTimestamp()  获取当日00:00:00的时间戳,东八区则为早上八点 :" + currentStamp);
        return currentStamp;
    }

    //获取最近7天的日期,用于查询这7天的系统数据
    public static ArrayList<String> getSearchDays(){
        ArrayList<String> dayList = new ArrayList<>();
        for(int i = 0 ; i < 7 ; i++){
            dayList.add(getDateString(i));
        }
        return dayList;
    }

    //获取dayNumber天前,当天的日期字符串
    public static String getDateString(int dayNumber){
        long time = System.currentTimeMillis() - dayNumber * DAY_IN_MILLIS;
        Log.i("Wingbu"," DateTransUtils-getDateString()  获取查询的日期 :" + dateFormat.format(time));
        return dateFormat.format(time);
    }
}
EventUtils(获取系统数据类)
package com.testappicon.ustate;

import android.annotation.TargetApi;
import android.app.usage.UsageEvents;
import android.app.usage.UsageStats;
import android.app.usage.UsageStatsManager;
import android.content.Context;
import android.os.Build;
import android.util.Log;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Map;

/**
 * 获取系统的数据,包括event和Usage
 *
 * .
 */

public class EventUtils {

    public  static final String TAG         = "EventUtils";
    private static final SimpleDateFormat dateFormat  = new SimpleDateFormat("M-d-yyyy HH:mm:ss");


    @SuppressWarnings("ResourceType")
    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    public static ArrayList<UsageEvents.Event> getEventList(Context context, long startTime, long endTime){
        ArrayList<UsageEvents.Event> mEventList = new ArrayList<>();
        Log.i(TAG," EventUtils-getEventList()   Range start:" + startTime);
        Log.i(TAG," EventUtils-getEventList()   Range end:" +endTime);
        Log.i(TAG," EventUtils-getEventList()   Range start:" + dateFormat.format(startTime));
        Log.i(TAG," EventUtils-getEventList()   Range end:" + dateFormat.format(endTime));

        UsageStatsManager mUsmManager = (UsageStatsManager) context.getSystemService("usagestats");
        UsageEvents events = mUsmManager.queryEvents(startTime, endTime);

        while (events.hasNextEvent()) {
            UsageEvents.Event e = new UsageEvents.Event();
            events.getNextEvent(e);
            if (e != null && (e.getEventType() == 1 || e.getEventType() == 2)) {
                Log.i(TAG," EventUtils-getEventList()  "+e.getTimeStamp()+"   event:" + e.getClassName() + "   type = " + e.getEventType());
                mEventList.add(e);
            }
        }

        return mEventList;
    }

    @SuppressWarnings("ResourceType")
    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    public static ArrayList<UsageStats> getUsageList(Context context, long startTime, long endTime) {

        Log.i(TAG," EventUtils-getUsageList()   Range start:" + startTime);
        Log.i(TAG," EventUtils-getUsageList()   Range end:" + endTime);
        Log.i(TAG," EventUtils-getUsageList()   Range start:" + dateFormat.format(startTime));
        Log.i(TAG," EventUtils-getUsageList()   Range end:" + dateFormat.format(endTime));

        ArrayList<UsageStats> list = new ArrayList<>();

        UsageStatsManager mUsmManager = (UsageStatsManager) context.getSystemService("usagestats");
        Map<String, UsageStats> map = mUsmManager.queryAndAggregateUsageStats(startTime, endTime);
        for (Map.Entry<String, UsageStats> entry : map.entrySet()) {
            UsageStats stats = entry.getValue();
            if(stats.getTotalTimeInForeground() > 0){
                list.add(stats);
                Log.i(TAG," EventUtils-getUsageList()   stats:" + stats.getPackageName() + "   TotalTimeInForeground = " + stats.getTotalTimeInForeground());
            }
        }

        return list;
    }
}
OneTimeDetails
package com.testappicon.ustate;

import android.annotation.TargetApi;
import android.app.usage.UsageEvents;
import android.os.Build;

import java.util.ArrayList;

/**
 *
 *
 *
 */

public class OneTimeDetails {
    private String pkgName;
    private long                          useTime;
    private ArrayList<UsageEvents.Event> OneTimeDetailEventList;

    public OneTimeDetails(String pkg, long useTime, ArrayList<UsageEvents.Event> oneTimeDetailList) {
        this.pkgName = pkg;
        this.useTime = useTime;
        OneTimeDetailEventList = oneTimeDetailList;
    }

    public String getPkgName() {
        return pkgName;
    }

    public void setPkgName(String pkgName) {
        this.pkgName = pkgName;
    }

    public long getUseTime() {
        return useTime;
    }

    public void setUseTime(long useTime) {
        this.useTime = useTime;
    }

    public ArrayList<UsageEvents.Event> getOneTimeDetailEventList() {
        return OneTimeDetailEventList;
    }

    public void setOneTimeDetailEventList(ArrayList<UsageEvents.Event> oneTimeDetailEventList) {
        OneTimeDetailEventList = oneTimeDetailEventList;
    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    public String getStartTime(){
        String startTime = null;
        if(OneTimeDetailEventList.size() > 0){
            //startTime = DateUtils.formatSameDayTime(OneTimeDetailEventList.get(0).getTimeStamp(), System.currentTimeMillis(), DateFormat.MEDIUM, DateFormat.MEDIUM).toString();
            startTime = DateTransUtils.stampToDate(OneTimeDetailEventList.get(0).getTimeStamp());
        }
        return startTime;
    }
    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    public String getStopTime(){
        String stopTime = null;
        if(OneTimeDetailEventList.size() > 0){
            //stopTime = DateUtils.formatSameDayTime(OneTimeDetailEventList.get(OneTimeDetailEventList.size()-1).getTimeStamp(), System.currentTimeMillis(), DateFormat.MEDIUM, DateFormat.MEDIUM).toString();
            stopTime = DateTransUtils.stampToDate(OneTimeDetailEventList.get(OneTimeDetailEventList.size()-1).getTimeStamp());
        }
        return stopTime;
    }
}
PackageInfo(每个应用的封装)
package com.testappicon.ustate;

/**
 * 统计数据---记录每个应用的包名,使用时长和使用次数
 * <p>
 * 
 */

public class PackageInfo {
    private int mUsedCount;
    private long mUsedTime;
    private String mPackageName;
    private String mAppName;

    public PackageInfo(int mUsedCount, long mUsedTime, String mPackageName,String appName) {
        this.mUsedCount = mUsedCount;
        this.mUsedTime = mUsedTime;
        this.mPackageName = mPackageName;
        this.mAppName=appName;
    }

    public void addCount() {
        mUsedCount++;
    }

    public int getmUsedCount() {
        return mUsedCount;
    }

    public void setmUsedCount(int mUsedCount) {
        this.mUsedCount = mUsedCount;
    }

    public long getmUsedTime() {
        return mUsedTime;
    }

    public void setmUsedTime(long mUsedTime) {
        this.mUsedTime = mUsedTime;
    }

    public String getmPackageName() {
        return mPackageName;
    }

    public void setmPackageName(String mPackageName) {
        this.mPackageName = mPackageName;
    }

    public String getmAppName() {
        return mAppName;
    }

    public void setmAppName(String mAppName) {
        this.mAppName = mAppName;
    }

    @Override
    public boolean equals(Object o) {
        //return super.equals(o);
        if (o == null) return false;
        if (this == o) return true;
        PackageInfo standardDetail = (PackageInfo) o;
        if (standardDetail.getmPackageName().equals(this.mPackageName)) {
            return true;
        } else {
            return false;
        }
    }

    @Override
    public int hashCode() {
        //return super.hashCode();
        return (mPackageName + mUsedTime).hashCode();
    }

    @Override
    public String toString() {
        return "PackageInfo{" +
                "mUsedCount=" + mUsedCount +
                ", mUsedTime=" + mUsedTime +
                ", mPackageName='" + mPackageName + '\'' +
                ", mAppName='" + mAppName + '\'' +
                '}';
    }
}
UseTimeDataManager(主要操作类)
package com.testappicon.ustate;

import android.annotation.TargetApi;
import android.app.usage.UsageEvents;
import android.app.usage.UsageStats;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.os.Build;
import android.text.TextUtils;
import android.text.format.DateUtils;
import android.util.Log;


import java.lang.reflect.Field;
import java.text.DateFormat;
import java.util.ArrayList;

/**
 * 主要的数据操作的类
 * <p>
 * 
 */

public class UseTimeDataManager {
    public static final String TAG = "Carden";

    private static UseTimeDataManager mUseTimeDataManager;

    private Context mContext;

    private int mDayNum;
    private long mStartTime;
    private long mEndTime;

    //记录从系统中读取的数据
    private ArrayList<UsageEvents.Event> mEventList;
    private ArrayList<UsageEvents.Event> mEventListChecked;
    private ArrayList<UsageStats> mStatsList;

    //记录打开一次应用,使用的activity详情
    private ArrayList<OneTimeDetails> mOneTimeDetailList = new ArrayList<>();

    //记录某一次打开应用的使用情况(查询某一次使用情况的时候,用于界面显示)
    private OneTimeDetails mOneTimeDetails;

    //主界面数据
    private ArrayList<PackageInfo> mPackageInfoList = new ArrayList<>();


    public UseTimeDataManager(Context context) {
        this.mContext = context;
    }

    public static UseTimeDataManager getInstance(Context context) {
        if (mUseTimeDataManager == null) {
            mUseTimeDataManager = new UseTimeDataManager(context);
        }

        return mUseTimeDataManager;
    }

    /**
     * 主要的数据获取函数
     *
     * @param dayNumber 查询若干天前的数据
     * @return int        0 : event usage 均查询到了
     * 1 : event 未查询到 usage 查询到了
     * 2 : event usage 均未查询到
     */
    public int refreshData(int dayNumber) {
        mDayNum = dayNumber;
        mEventList = getEventList(dayNumber);
        mStatsList = getUsageList(dayNumber);

        if (mEventList == null || mEventList.size() == 0) {
            Log.i(TAG, " UseTimeDataManager-refreshData()   未查到events");

            if (mStatsList == null || mStatsList.size() == 0) {
                Log.i(TAG, " UseTimeDataManager-refreshData()   未查到stats");
                return 2;
            }

            return 1;
        }

        //获取数据之后,进行数据的处理
        mEventListChecked = getEventListChecked();
        refreshOneTimeDetailList(0);
        refreshPackageInfoList();
//        sendEventBus();
        return 0;
    }

    //分类完成,初始化主界面所用到的数据
    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    public void refreshPackageInfoList() {
        mPackageInfoList.clear();
        for (int i = 0; i < mStatsList.size(); i++) {
            //屏蔽系统应用
            if (!isSystemApp(mContext,mStatsList.get(i).getPackageName())) {
                PackageInfo info = new PackageInfo(0, calculateUseTime(mStatsList.get(i).getPackageName()), mStatsList.get(i).getPackageName(), getApplicationNameByPackageName(mContext, mStatsList.get(i).getPackageName()));
                mPackageInfoList.add(info);
            }
        }

        for (int n = 0; n < mPackageInfoList.size(); n++) {
            String pkg = mPackageInfoList.get(n).getmPackageName();
            for (int m = 0; m < mOneTimeDetailList.size(); m++) {
                if (pkg.equals(mOneTimeDetailList.get(m).getPkgName())) {
                    mPackageInfoList.get(n).addCount();
                }
            }
        }
    }

    //按照使用时间的长短进行排序,获取应用使用情况列表
    public ArrayList<PackageInfo> getmPackageInfoListOrderByTime() {
        Log.i(TAG, " UseTimeDataManager-getmPackageInfoListOrderByTime()   排序前:mPackageInfoList.size()" + mPackageInfoList.size());

        for (int n = 0; n < mPackageInfoList.size(); n++) {
            for (int m = n + 1; m < mPackageInfoList.size(); m++) {
                if (mPackageInfoList.get(n).getmUsedTime() < mPackageInfoList.get(m).getmUsedTime()) {
                    PackageInfo temp = mPackageInfoList.get(n);
                    mPackageInfoList.set(n, mPackageInfoList.get(m));
                    mPackageInfoList.set(m, temp);
                }
            }
        }

        Log.i(TAG, " UseTimeDataManager-getmPackageInfoListOrderByTime()   排序后:mPackageInfoList.size()" + mPackageInfoList.size());
        return mPackageInfoList;
    }

    //按照使用次数的多少进行排序,获取应用使用情况列表
    public ArrayList<PackageInfo> getmPackageInfoListOrderByCount() {
        Log.i(TAG, " UseTimeDataManager-getmPackageInfoListOrderByCount()   排序前:mPackageInfoList.size()" + mPackageInfoList.size());

        for (int n = 0; n < mPackageInfoList.size(); n++) {
            for (int m = n + 1; m < mPackageInfoList.size(); m++) {
                if (mPackageInfoList.get(n).getmUsedCount() < mPackageInfoList.get(m).getmUsedCount()) {
                    PackageInfo temp = mPackageInfoList.get(n);
                    mPackageInfoList.set(n, mPackageInfoList.get(m));
                    mPackageInfoList.set(m, temp);
                }
            }
        }

        Log.i(TAG, " UseTimeDataManager-getmPackageInfoListOrderByCount()   排序后:mPackageInfoList.size()" + mPackageInfoList.size());
        return mPackageInfoList;
    }

    /**
     * @TargetApi(Build.VERSION_CODES.LOLLIPOP) private void sendEventBus(){
     * TimeEvent event = new TimeEvent(0,0);
     * if(mEventListChecked != null && mEventListChecked.size() > 0){
     * event.setmStartTime(mEventListChecked.get(0).getTimeStamp());
     * event.setmEndTime(mEventListChecked.get(mEventListChecked.size()-1).getTimeStamp());
     * }
     * MsgEventBus.getInstance().post(event);
     * }
     **/

    //从系统中获取event数据
    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    private ArrayList<UsageEvents.Event> getEventList(int dayNumber) {
        ArrayList<UsageEvents.Event> mEventList = new ArrayList<>();
//        Calendar calendar = Calendar.getInstance();
//        long endTime = calendar.getTimeInMillis();
//        calendar.add(Calendar.YEAR, -1);
//        //long startTime = calendar.getTimeInMillis()- 3 * DateTransUtils.DAY_IN_MILLIS;
//        long startTime = calendar.getTimeInMillis();

        long endTime = 0, startTime = 0;
        if (dayNumber == 0) {
            endTime = System.currentTimeMillis();
            startTime = DateTransUtils.getZeroClockTimestamp(endTime);
        } else {
            endTime = DateTransUtils.getZeroClockTimestamp(System.currentTimeMillis() - (dayNumber - 1) * DateTransUtils.DAY_IN_MILLIS) - 1;
            startTime = endTime - DateTransUtils.DAY_IN_MILLIS + 1;
        }
        return EventUtils.getEventList(mContext, startTime, endTime);
    }

    //从系统中获取Usage数据
    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    private ArrayList<UsageStats> getUsageList(int dayNumber) {
        long endTime = 0, startTime = 0;
        if (dayNumber == 0) {
            endTime = System.currentTimeMillis();
            startTime = DateTransUtils.getZeroClockTimestamp(endTime);
        } else {
            endTime = DateTransUtils.getZeroClockTimestamp(System.currentTimeMillis() - (dayNumber - 1) * DateTransUtils.DAY_IN_MILLIS) - 1;
            startTime = endTime - DateTransUtils.DAY_IN_MILLIS + 1;
        }

        return EventUtils.getUsageList(mContext, startTime, endTime);
    }

    //仅保留 event 中 type 为 1或者2 的
    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    private ArrayList<UsageEvents.Event> getEventListChecked() {
        ArrayList<UsageEvents.Event> mList = new ArrayList<>();
        for (int i = 0; i < mEventList.size(); i++) {
            if (mEventList.get(i).getEventType() == 1 || mEventList.get(i).getEventType() == 2) {
                mList.add(mEventList.get(i));
            }
        }
        return mList;
    }

    public  String getApplicationNameByPackageName(Context context, String packageName) {

        PackageManager pm = context.getPackageManager();
        String Name;
        try {
            Name = pm.getApplicationLabel(pm.getApplicationInfo(packageName, PackageManager.GET_META_DATA)).toString();
        } catch (PackageManager.NameNotFoundException e) {
            Name = "";
        }
        return Name;

    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    private ArrayList<UsageEvents.Event> getEventListCheckWithoutErrorData() {
        ArrayList<UsageEvents.Event> mList = new ArrayList<>();
        for (int i = 0; i < mEventList.size(); i++) {
            if (mEventList.get(i).getEventType() == 1 || mEventList.get(i).getEventType() == 2) {
                mList.add(mEventList.get(i));
            }
        }
        return mList;
    }

    //从 startIndex 开始分类event  直至将event分完
    //每次从0开始,将原本的 mOneTimeDetailList 清除一次,然后开始分类
    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    private void refreshOneTimeDetailList(int startIndex) {
        Log.i(TAG, "  refreshOneTimeDetailList()     startIndex : " + startIndex);

        if (startIndex == 0) {
            Log.i(TAG, "  refreshOneTimeDetailList()     每次从0开始,将原本的 mOneTimeDetailList 清除一次,然后开始分类 ");
            if (mOneTimeDetailList != null) {
                mOneTimeDetailList.clear();
            }
        }

        long totalTime = 0;
        int usedIndex = 0;
        String pkg = null;
        ArrayList<UsageEvents.Event> list = new ArrayList();
        for (int i = startIndex; i < mEventListChecked.size(); i++) {
            if (i == startIndex) {
                if (mEventListChecked.get(i).getEventType() == 2) {
                    Log.i(TAG, "  refreshOneTimeDetailList()     warning : 每次打开一个app  第一个activity的类型是 2     ");
                }
                pkg = mEventListChecked.get(i).getPackageName();
                list.add(mEventListChecked.get(i));
            } else {
                if (pkg != null) {
                    if (pkg.equals(mEventListChecked.get(i).getPackageName())) {
                        list.add(mEventListChecked.get(i));
                        if (i == mEventListChecked.size() - 1) {
                            usedIndex = i;
                        }
                    } else {
                        usedIndex = i;
                        break;
                    }
                }
            }
        }

        Log.i(TAG, "   mEventListChecked 分类:   before  check :   list.size() = " + list.size());
        checkEventList(list);
        Log.i(TAG, "   mEventListChecked 分类:   after  check :   list.size() = " + list.size());
//        startTime = list.get(0).getTimeStamp();
//        endTime   = list.get( list.size() - 1 ).getTimeStamp();
        Log.i(TAG, "   mEventListChecked 分类:  本次启动的包名:" + list.get(0).getPackageName() + "   时间:" + DateUtils.formatSameDayTime(list.get(0).getTimeStamp(), System.currentTimeMillis(), DateFormat.MEDIUM, DateFormat.MEDIUM));
        for (int i = 1; i < list.size(); i += 2) {
            if (list.get(i).getEventType() == 2 && list.get(i - 1).getEventType() == 1) {
                totalTime += (list.get(i).getTimeStamp() - list.get(i - 1).getTimeStamp());
            }
        }
        OneTimeDetails oneTimeDetails = new OneTimeDetails(pkg, totalTime, list);
        mOneTimeDetailList.add(oneTimeDetails);

        if (usedIndex < mEventListChecked.size() - 1) {
            refreshOneTimeDetailList(usedIndex);
        } else {
            Log.i(TAG, "  refreshOneTimeDetailList()     已经将  mEventListChecked 分类完毕   ");
        }

    }

    public ArrayList<OneTimeDetails> getPkgOneTimeDetailList(String pkg) {

        if ("all".equals(pkg)) {
            return mOneTimeDetailList;
        }

        ArrayList<OneTimeDetails> list = new ArrayList<>();
        if (mOneTimeDetailList != null && mOneTimeDetailList.size() > 0) {
            for (int i = 0; i < mOneTimeDetailList.size(); i++) {
                if (mOneTimeDetailList.get(i).getPkgName().equals(pkg)) {
                    list.add(mOneTimeDetailList.get(i));
                }
            }
        }
        return list;
    }

    // 采用回溯的思想:
    // 从头遍历EventList,如果发现异常数据,则删除该异常数据,并从头开始再次进行遍历,直至无异常数据
    // (异常数据是指:event 均为 type=1 和type=2 ,成对出现,一旦发现未成对出现的数据,即视为异常数据)
    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    private void checkEventList(ArrayList<UsageEvents.Event> list) {
        boolean isCheckAgain = false;
        for (int i = 0; i < list.size() - 1; i += 2) {
            if (list.get(i).getClassName().equals(list.get(i + 1).getClassName())) {
                if (list.get(i).getEventType() != 1) {
                    Log.i(UseTimeDataManager.TAG, "   EventList 出错  : " + list.get(i).getPackageName() + "  " + DateUtils.formatSameDayTime(list.get(i).getTimeStamp(), System.currentTimeMillis(), DateFormat.MEDIUM, DateFormat.MEDIUM).toString());
                    list.remove(i);
                    isCheckAgain = true;
                    break;
                }
                if (list.get(i + 1).getEventType() != 2) {
                    Log.i(UseTimeDataManager.TAG, "   EventList 出错 : " + list.get(i + 1).getPackageName() + "  " + DateUtils.formatSameDayTime(list.get(i + 1).getTimeStamp(), System.currentTimeMillis(), DateFormat.MEDIUM, DateFormat.MEDIUM).toString());
                    list.remove(i);
                    isCheckAgain = true;
                    break;
                }
            } else {
                //i和i+1的className对不上,则删除第i个数据,重新检查
                list.remove(i);
                isCheckAgain = true;
                break;
            }
        }
        if (isCheckAgain) {
            checkEventList(list);
        }
    }

    // =======================================
    // service use
    // =======================================

    public ArrayList<PackageInfo> getPkgInfoListFromEventList() {
        return mPackageInfoList;
    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    public ArrayList<PackageInfo> getPkgInfoListFromUsageList() throws IllegalAccessException {
        ArrayList<PackageInfo> result = new ArrayList<>();

        if (mStatsList != null && mStatsList.size() > 0) {
            for (int i = 0; i < mStatsList.size(); i++) {

                    result.add(new PackageInfo(getLaunchCount(mStatsList.get(i)), mStatsList.get(i).getTotalTimeInForeground(), mStatsList.get(i).getPackageName(), getApplicationNameByPackageName(mContext, mStatsList.get(i).getPackageName())));

            }
        }
        return result;
    }
    //判断app是否为系统qpp
    public  boolean isSystemApp(Context context, String packageName) {
        if (TextUtils.isEmpty(packageName)){
            return  false;
        }
        try {
            PackageManager pm = context.getPackageManager();
            ApplicationInfo ai = pm.getApplicationInfo(packageName, 0);
            return ai != null && (ai.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
            return false;
        }
    }
    // 利用反射,获取UsageStats中统计的应用使用次数
    private int getLaunchCount(UsageStats usageStats) throws IllegalAccessException {
        Field field = null;
        try {
            field = usageStats.getClass().getDeclaredField("mLaunchCount");
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }
        return (int) field.get(usageStats);
    }

    //根据event计算使用时间
    public long calculateUseTime(String pkg) {
        long useTime = 0;
        for (int i = 0; i < mOneTimeDetailList.size(); i++) {
            if (mOneTimeDetailList.get(i).getPkgName().equals(pkg)) {
                useTime += mOneTimeDetailList.get(i).getUseTime();
            }
        }
        Log.i(TAG, "  calculateUseTime : " + useTime);
        return useTime;
    }
    // =======================================
    // getter and setter
    // =======================================


    public int getmDayNum() {
        return mDayNum;
    }

    public void setmDayNum(int mDayNum) {
        this.mDayNum = mDayNum;
    }

    public ArrayList<OneTimeDetails> getmOneTimeDetailList() {
        return mOneTimeDetailList;
    }

    public OneTimeDetails getmOneTimeDetails() {
        return mOneTimeDetails;
    }

    public void setmOneTimeDetails(OneTimeDetails mOneTimeDetails) {
        this.mOneTimeDetails = mOneTimeDetails;
    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    public UsageStats getUsageStats(String pkg) {
        for (int i = 0; i < mStatsList.size(); i++) {
            if (mStatsList.get(i).getPackageName().equals(pkg)) {
                return mStatsList.get(i);
            }
        }
        return null;
    }
}
调用:

在Activity时初始化:

   mUseTimeDataManager = UseTimeDataManager.getInstance(MainActivity.this);
        mUseTimeDataManager.refreshData(0);

上传应用情况json数据到服务器:

  public String getJsonObjectStr() {
        String jsonAppdeTails = "";
        try {
            List<PackageInfo> packageInfos = mUseTimeDataManager.getmPackageInfoListOrderByTime();
            JSONObject jsonObject2 = new JSONObject();
            JSONArray jsonArray = new JSONArray();
            for (int i = 0; i < packageInfos.size(); i++) {
                try {
                    JSONObject jsonObject = new JSONObject();
                    jsonArray.put(i, jsonObject.accumulate("count", packageInfos.get(i).getmUsedCount()));
                    jsonArray.put(i, jsonObject.accumulate("name", packageInfos.get(i).getmPackageName()));
                    jsonArray.put(i, jsonObject.accumulate("time", packageInfos.get(i).getmUsedTime()));
                    jsonArray.put(i, jsonObject.accumulate("appname", packageInfos.get(i).getmAppName()));
                } catch (JSONException e) {
                    e.printStackTrace();
                    return "";
                }

            }
            jsonObject2.put("details", jsonArray);
            jsonAppdeTails = jsonObject2.toString();
        } catch (JSONException e) {
            e.printStackTrace();
            return "";
        }
        return jsonAppdeTails;
    }

返回数据为:

{"details":[{"count":28,"name":"com.testappicon","time":1731626,"appname":"Test SMS"},{"count":5,"name":"com.kkw.game.goldflower","time":216975,"appname":"game"},{"count":8,"name":"com.tencent.mm","time":206587,"appname":"微信"},{"count":3,"name":"com.github.shadowsocks","time":109991,"appname":"影梭"},{"count":4,"name":"com.amazon.mShop.android","time":46087,"appname":"亚马逊购物"}]}

由于屏蔽了系统应用,所以不会显示系统级应用信息。

就到这了,thanks!!

  • 21
    点赞
  • 89
    收藏
    觉得还不错? 一键收藏
  • 20
    评论
评论 20
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值