Files
CubeAoleyunSN/app/src/main/java/com/aoleyun/sn/statistics/StatisticsInfo.java
fanhuitong 3018660216 version:1.0
update:2021-10-13 18:52:13
fix:去除okgo,rxAndroid1,优化依赖
add:切换到奥乐云平台
2021-10-13 18:54:20 +08:00

284 lines
11 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package com.aoleyun.sn.statistics;
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 androidx.annotation.RequiresApi;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import static com.aoleyun.sn.statistics.AppInformation.bootTime;
public class StatisticsInfo {
final public static int DAY = 0;
final public static int WEEK = 1;
final public static int MONTH = 2;
final public static int YEAR = 3;
private ArrayList<AppInformation> ShowList;
private ArrayList<AppInformation> AppInfoList;
private List<UsageStats> result;
private long totalTime;
private int totalTimes;
private int style;
public StatisticsInfo(Context context) {
try {
this.style = 0;
setUsageStatsList(context);
setShowList();
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
}
public StatisticsInfo(Context context, int style) {
try {
this.style = style;
setUsageStatsList(context);
setShowList();
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
}
//将次数和时间为0的应用信息过滤掉
private void setShowList() {
this.ShowList = new ArrayList<>();
totalTime = 0;
for (int i = 0; i < AppInfoList.size(); i++) {
if (AppInfoList.get(i).getUsedTimebyDay() > 0) { //&& AppInfoList.get(i).getTimes() > 0) {
this.ShowList.add(AppInfoList.get(i));
totalTime += AppInfoList.get(i).getUsedTimebyDay();
totalTimes += AppInfoList.get(i).getTimes();
}
}
//将显示列表中的应用按显示顺序排序
for (int i = 0; i < this.ShowList.size() - 1; i++) {
for (int j = 0; j < this.ShowList.size() - i - 1; j++) {
if (this.ShowList.get(j).getUsedTimebyDay() < this.ShowList.get(j + 1).getUsedTimebyDay()) {
AppInformation temp = this.ShowList.get(j);
this.ShowList.set(j, this.ShowList.get(j + 1));
this.ShowList.set(j + 1, temp);
}
}
}
}
//统计当天的应用使用时间
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
private void setUsageStatsList(Context context) throws NoSuchFieldException {
UsageStatsManager m = (UsageStatsManager) context.getSystemService(Context.USAGE_STATS_SERVICE);
this.AppInfoList = new ArrayList<>();
if (m != null) {
Calendar calendar = Calendar.getInstance();
long now = calendar.getTimeInMillis();
long begintime = getBeginTime();
if (style == DAY) {
this.result = m.queryUsageStats(UsageStatsManager.INTERVAL_BEST, begintime, now);
AppInfoList = getAccurateDailyStatsList(context, result, m, begintime, now);
} else {
if (style == WEEK)
this.result = m.queryUsageStats(UsageStatsManager.INTERVAL_WEEKLY, begintime, now);
else if (style == MONTH)
this.result = m.queryUsageStats(UsageStatsManager.INTERVAL_MONTHLY, begintime, now);
else if (style == YEAR)
this.result = m.queryUsageStats(UsageStatsManager.INTERVAL_YEARLY, begintime, now);
else {
this.result = m.queryUsageStats(UsageStatsManager.INTERVAL_BEST, begintime, now);
}
List<UsageStats> Mergeresult = MergeList(this.result);
for (UsageStats usageStats : Mergeresult) {
this.AppInfoList.add(new AppInformation(usageStats, context));
}
calculateLaunchTimesAfterBootOn(context, AppInfoList);
}
}
}
/**
* 根据UsageEvents来对当天的操作次数和开机后运行时间来进行精确计算
*/
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
private ArrayList<AppInformation> getAccurateDailyStatsList(Context context, List<UsageStats> result, UsageStatsManager m, long begintime, long now) {
//针对每个packageName建立一个 使用信息
HashMap<String, AppInformation> mapData = new HashMap<>();
//得到包名
for (UsageStats stats : result) {
if (stats.getLastTimeUsed() > begintime && stats.getTotalTimeInForeground() > 0) {
if (mapData.get(stats.getPackageName()) == null) {
AppInformation information = new AppInformation(stats, context);
//重置总运行时间 开机操作次数
information.setTimes(0);
information.setUsedTimebyDay(0);
mapData.put(stats.getPackageName(), information);
}
}
}
//这个是相对比较精确的
long bootTime = bootTime();
UsageEvents events = m.queryEvents(bootTime, now);
UsageEvents.Event e = new UsageEvents.Event();
while (events.hasNextEvent()) {
events.getNextEvent(e);
String packageName = e.getPackageName();
AppInformation information = mapData.get(packageName);
if (information == null) {
continue;
}
//这里在同时计算开机后的操作次数和运行时间,所以如果获取到的时间戳是昨天的话就得过滤掉 continue
if (e.getEventType() == UsageEvents.Event.MOVE_TO_FOREGROUND) {
information.timesPlusPlus();
if (e.getTimeStamp() < begintime){
continue;
}
information.setTimeStampMoveToForeground(e.getTimeStamp());
} else if (e.getEventType() == UsageEvents.Event.MOVE_TO_BACKGROUND) {
if (e.getTimeStamp() < begintime){
continue;
}
information.setTimeStampMoveToBackGround(e.getTimeStamp());
//当前应用是在昨天进入的前台0点后转入了后台所以会先得到MOVE_TO_BACKGROUND 的timeStamp
if (information.getTimeStampMoveToForeground() < 0) {
//从今天开始计算即可
information.setTimeStampMoveToForeground(begintime);
}
}
information.calculateRunningTime();
}
//再计算一次当前应用的运行时间因为当前应用最后得不到MOVE_TO_BACKGROUND 的timeStamp
AppInformation information = mapData.get(context.getPackageName());
information.setTimeStampMoveToBackGround(now);
information.calculateRunningTime();
return new ArrayList<>(mapData.values());
}
/**
* 根据UsageEvents 精确计算APP开机的启动(activity打开的)次数
*/
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
private void calculateLaunchTimesAfterBootOn(Context context, List<AppInformation> AppInfoList) {
UsageStatsManager m = (UsageStatsManager) context.getSystemService(Context.USAGE_STATS_SERVICE);
if (m == null || AppInfoList == null || AppInfoList.size() < 1) {
return;
}
//针对每个packageName建立一个 使用信息
HashMap<String, AppInformation> mapData = new HashMap<>();
UsageEvents events = m.queryEvents(bootTime(), System.currentTimeMillis());
for (AppInformation information : AppInfoList) {
mapData.put(information.getPackageName(), information);
information.setTimes(0);
}
UsageEvents.Event e = new UsageEvents.Event();
while (events.hasNextEvent()) {
events.getNextEvent(e);
String packageName = e.getPackageName();
AppInformation information = mapData.get(packageName);
if (information == null) {
continue;
}
if (e.getEventType() == UsageEvents.Event.MOVE_TO_FOREGROUND) {
information.timesPlusPlus();
}
}
}
private long getBeginTime() {
Calendar calendar = Calendar.getInstance();
long begintime;
if (style == WEEK) {
//int weekDay = calendar.get(Calendar.DAY_OF_WEEK);
calendar.add(Calendar.DATE, -7);
begintime = calendar.getTimeInMillis();
} else if (style == MONTH) {
//int mounthDay = calendar.get(Calendar.DAY_OF_MONTH);
calendar.add(Calendar.DATE, -30);
begintime = calendar.getTimeInMillis();
} else if (style == YEAR) {
calendar.add(Calendar.YEAR, -1);
begintime = calendar.getTimeInMillis();
} else {
//剩下的输入均显示当天的数据
int hour = calendar.get(Calendar.HOUR_OF_DAY);
int minute = calendar.get(Calendar.MINUTE);
int second = calendar.get(Calendar.SECOND);
calendar.add(Calendar.SECOND, -1 * second);
calendar.add(Calendar.MINUTE, -1 * minute);
calendar.add(Calendar.HOUR, -1 * hour);
begintime = calendar.getTimeInMillis();
}
return begintime;
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
private List<UsageStats> MergeList(List<UsageStats> result) {
List<UsageStats> Mergeresult = new ArrayList<>();
long begintime;
begintime = getBeginTime();
for (int i = 0; i < result.size(); i++) {
if (result.get(i).getLastTimeUsed() > begintime) {
int num = FoundUsageStats(Mergeresult, result.get(i));
if (num >= 0) {
UsageStats u = Mergeresult.get(num);
u.add(result.get(i));
Mergeresult.set(num, u);
} else Mergeresult.add(result.get(i));
}
}
return Mergeresult;
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
private int FoundUsageStats(List<UsageStats> Mergeresult, UsageStats usageStats) {
for (int i = 0; i < Mergeresult.size(); i++) {
if (Mergeresult.get(i).getPackageName().equals(usageStats.getPackageName())) {
return i;
}
}
return -1;
}
public long getTotalTime() {
return totalTime;
}
public int getTotalTimes() {
return totalTimes;
}
public ArrayList<AppInformation> getShowList() {
return ShowList;
}
}