version:2.0.3.6

update:
fix:修复桌面图标丢失,安装会出现教官壹两个图标
add:
This commit is contained in:
FHT
2021-04-14 10:42:08 +08:00
parent 22d36cba60
commit 79ea4abb18
146 changed files with 580 additions and 689 deletions

View File

@@ -0,0 +1,131 @@
package com.mjsheng.myappstore.statistics;
import android.app.usage.UsageStats;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.SystemClock;
import androidx.annotation.RequiresApi;
public class AppInformation {
private UsageStats usageStats;
private String packageName;
private String label;
private Drawable Icon;
private long UsedTimebyDay; //milliseconds
private Context context;
private int times;
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public AppInformation(UsageStats usageStats, Context context) {
this.usageStats = usageStats;
this.context = context;
try {
GenerateInfo();
} catch (PackageManager.NameNotFoundException | IllegalAccessException | NoSuchFieldException e) {
e.printStackTrace();
}
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
private void GenerateInfo() throws PackageManager.NameNotFoundException, NoSuchFieldException, IllegalAccessException {
PackageManager packageManager = context.getPackageManager();
this.packageName = usageStats.getPackageName();
if (this.packageName != null && !this.packageName.equals("")) {
ApplicationInfo applicationInfo = packageManager.getApplicationInfo(this.packageName, 0);
this.label = (String) packageManager.getApplicationLabel(applicationInfo);
this.UsedTimebyDay = usageStats.getTotalTimeInForeground();
this.times = (Integer) usageStats.getClass().getDeclaredField("mLaunchCount").get(usageStats);
if (this.UsedTimebyDay > 0) {
this.Icon = applicationInfo.loadIcon(packageManager);
}
}
}
public UsageStats getUsageStats() {
return usageStats;
}
public int getTimes() {
return times;
}
public void setTimes(int times) {
this.times = times;
}
public void setUsedTimebyDay(long usedTimebyDay) {
this.UsedTimebyDay = usedTimebyDay;
}
public Drawable getIcon() {
return Icon;
}
public long getUsedTimebyDay() {
return UsedTimebyDay;
}
public String getLabel() {
return label;
}
public String getPackageName() {
return packageName;
}
private long timeStampMoveToForeground = -1;
private long timeStampMoveToBackGround = -1;
public void setTimeStampMoveToForeground(long timeStampMoveToForeground) {
// if (timeStampMoveToForeground > bootTime()){
// timesPlusPlus();
// }
this.timeStampMoveToForeground = timeStampMoveToForeground;
}
public void timesPlusPlus(){
times++;
}
public void setTimeStampMoveToBackGround(long timeStampMoveToBackGround) {
this.timeStampMoveToBackGround = timeStampMoveToBackGround;
}
public long getTimeStampMoveToBackGround() {
return timeStampMoveToBackGround;
}
public long getTimeStampMoveToForeground() {
return timeStampMoveToForeground;
}
public void calculateRunningTime() {
if (timeStampMoveToForeground < 0 || timeStampMoveToBackGround < 0) {
return;
}
if (timeStampMoveToBackGround > timeStampMoveToForeground) {
UsedTimebyDay += (timeStampMoveToBackGround - timeStampMoveToForeground);
timeStampMoveToForeground = -1;
timeStampMoveToBackGround = -1;
}
}
// 返回开机时间,单位微妙
public static long bootTime() {
return System.currentTimeMillis() - SystemClock.elapsedRealtime();
}
}

View File

@@ -0,0 +1,283 @@
package com.mjsheng.myappstore.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.mjsheng.myappstore.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;
}
}