version:1.1
fix: add:应用使用数据统计
This commit is contained in:
@@ -1,9 +1,11 @@
|
||||
package com.uiui.os.utils;
|
||||
|
||||
import android.app.Application;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.text.TextUtils;
|
||||
@@ -17,7 +19,7 @@ import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class ApkUtils {
|
||||
public class APKUtils {
|
||||
private static String[] excludePackageName = {BuildConfig.APPLICATION_ID};
|
||||
|
||||
|
||||
@@ -56,6 +58,7 @@ public class ApkUtils {
|
||||
|
||||
/**
|
||||
* 获取第三方应用
|
||||
*
|
||||
* @param context
|
||||
* @return
|
||||
*/
|
||||
@@ -77,6 +80,29 @@ public class ApkUtils {
|
||||
return applicationInfos;
|
||||
}
|
||||
|
||||
public static PackageInfo getPackageInfo(Context context, String pkg) {
|
||||
PackageManager packageManager = context.getPackageManager();
|
||||
PackageInfo packageInfo = null;
|
||||
try {
|
||||
packageInfo = packageManager.getPackageInfo(pkg, 0);
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return packageInfo;
|
||||
}
|
||||
|
||||
public static ApplicationInfo getApplicationInfo(Context context, String pkg) {
|
||||
PackageManager packageManager = context.getPackageManager();
|
||||
ApplicationInfo applicationInfo = null;
|
||||
try {
|
||||
applicationInfo = packageManager.getApplicationInfo(pkg, 0);
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return applicationInfo;
|
||||
}
|
||||
|
||||
public static void openApp(Context context, String packageName) {
|
||||
Intent intent = context.getPackageManager().getLaunchIntentForPackage(packageName);
|
||||
if (intent != null) {
|
||||
@@ -86,14 +112,14 @@ public class ApkUtils {
|
||||
}
|
||||
|
||||
|
||||
public static Intent getAppOpenIntentByPackageName(Context context,String packageName){
|
||||
public static Intent getAppOpenIntentByPackageName(Context context, String packageName) {
|
||||
//Activity完整名
|
||||
String mainAct = null;
|
||||
//根据包名寻找
|
||||
PackageManager pkgMag = context.getPackageManager();
|
||||
Intent intent = new Intent(Intent.ACTION_MAIN);
|
||||
intent.addCategory(Intent.CATEGORY_LAUNCHER);
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED|Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED | Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
|
||||
List<ResolveInfo> list = pkgMag.queryIntentActivities(intent,
|
||||
PackageManager.GET_ACTIVITIES);
|
||||
@@ -138,4 +164,20 @@ public class ApkUtils {
|
||||
return false;
|
||||
}
|
||||
|
||||
public static String getAPPVersionName(Context context, String packageName) {
|
||||
String versionName = "0";
|
||||
|
||||
if (TextUtils.isEmpty(packageName)) {
|
||||
return versionName;
|
||||
}
|
||||
PackageManager pm = context.getPackageManager();
|
||||
try {
|
||||
PackageInfo packageInfo = pm.getPackageInfo(packageName, 0);
|
||||
versionName = packageInfo.versionName;
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return versionName;
|
||||
}
|
||||
|
||||
}
|
||||
287
app/src/main/java/com/uiui/os/utils/AlarmUtils.java
Normal file
287
app/src/main/java/com/uiui/os/utils/AlarmUtils.java
Normal file
@@ -0,0 +1,287 @@
|
||||
package com.uiui.os.utils;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.AlarmManager;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Environment;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.core.content.ContextCompat;
|
||||
|
||||
import com.arialyy.aria.core.Aria;
|
||||
import com.blankj.utilcode.util.FileUtils;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import com.tencent.mmkv.MMKV;
|
||||
import com.uiui.os.bean.AlarmClockData;
|
||||
import com.uiui.os.service.MainService;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.lang.reflect.Type;
|
||||
import java.math.BigInteger;
|
||||
import java.security.MessageDigest;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class AlarmUtils {
|
||||
@SuppressLint("StaticFieldLeak")
|
||||
private static AlarmUtils sInstance;
|
||||
private static String TAG = AlarmUtils.class.getSimpleName();
|
||||
private Context mContext;
|
||||
private AlarmManager alarmManager;
|
||||
private MMKV mmkv = MMKV.defaultMMKV();
|
||||
|
||||
|
||||
private AlarmUtils(Context context) {
|
||||
this.mContext = context;
|
||||
alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
|
||||
}
|
||||
|
||||
public static void init(Context context) {
|
||||
if (sInstance == null) {
|
||||
sInstance = new AlarmUtils(context);
|
||||
}
|
||||
}
|
||||
|
||||
public static AlarmUtils getInstance() {
|
||||
if (sInstance == null) {
|
||||
throw new IllegalStateException("You must be init AmapManager first");
|
||||
}
|
||||
return sInstance;
|
||||
}
|
||||
|
||||
private List<AlarmClockData> alarmClockDataList;
|
||||
private HashSet<PendingIntent> pendingIntents;
|
||||
|
||||
public void setAlarmClockData(List<AlarmClockData> data) {
|
||||
this.alarmClockDataList = data;
|
||||
if (pendingIntents == null) {
|
||||
pendingIntents = getOldPendingIntents();
|
||||
}
|
||||
for (PendingIntent pendingIntent : pendingIntents) {
|
||||
alarmManager.cancel(pendingIntent);
|
||||
}
|
||||
List<AlarmClockData> newData = mergeData(data);
|
||||
for (AlarmClockData clockData : newData) {
|
||||
setAlarm(clockData);
|
||||
}
|
||||
String jsonString = new Gson().toJson(newData);
|
||||
Log.e(TAG, "setAlarmClockData: " + jsonString);
|
||||
mmkv.encode("AlarmClock", jsonString);
|
||||
}
|
||||
|
||||
private List<AlarmClockData> mergeData(List<AlarmClockData> data) {
|
||||
HashMap<Integer, AlarmClockData> oldData = getOldData();
|
||||
List<AlarmClockData> tempData = new ArrayList<>();
|
||||
for (AlarmClockData alarm : data) {
|
||||
AlarmClockData oldAlarm = oldData.get(alarm.getId());
|
||||
if (oldAlarm == null) {
|
||||
tempData.add(alarm);
|
||||
} else {
|
||||
if (oldAlarm.equals(alarm)) {
|
||||
tempData.add(oldAlarm);
|
||||
} else {
|
||||
tempData.add(alarm);
|
||||
}
|
||||
}
|
||||
}
|
||||
return tempData;
|
||||
}
|
||||
|
||||
public void setAlarmString(List<AlarmClockData> alarmClockData) {
|
||||
String jsonString = new Gson().toJson(alarmClockData);
|
||||
Log.e(TAG, "setAlarmString: " + jsonString);
|
||||
mmkv.encode("AlarmClock", jsonString);
|
||||
}
|
||||
|
||||
public HashMap<Integer, AlarmClockData> getOldData() {
|
||||
String jsonString = mmkv.decodeString("AlarmClock", "");
|
||||
Log.e(TAG, "getOldPendingIntents: " + jsonString);
|
||||
if (TextUtils.isEmpty(jsonString)) {
|
||||
return new HashMap<>();
|
||||
} else {
|
||||
Type type = new TypeToken<List<AlarmClockData>>() {
|
||||
}.getType();
|
||||
Gson gson = new Gson();
|
||||
List<AlarmClockData> data = gson.fromJson(jsonString, type);
|
||||
HashMap hashMap = new HashMap();
|
||||
for (AlarmClockData clockData : data) {
|
||||
hashMap.put(clockData.getId(), clockData);
|
||||
}
|
||||
return hashMap;
|
||||
}
|
||||
}
|
||||
|
||||
private HashSet<PendingIntent> getOldPendingIntents() {
|
||||
HashSet<PendingIntent> pendingIntents = new HashSet<>();
|
||||
HashMap<Integer, AlarmClockData> data = getOldData();
|
||||
for (AlarmClockData alarmClockData : data.values()) {
|
||||
pendingIntents.add(getPendingIntent(alarmClockData));
|
||||
}
|
||||
return pendingIntents;
|
||||
}
|
||||
|
||||
private PendingIntent getPendingIntent(AlarmClockData alarmClock) {
|
||||
Intent intent = new Intent(MainService.ALARMWAKEUP);
|
||||
intent.putExtra("title", alarmClock.getRemarks());
|
||||
intent.putExtra("id", alarmClock.getId());
|
||||
PendingIntent startPendingIntent = PendingIntent.getBroadcast(mContext, alarmClock.getId(), intent, PendingIntent.FLAG_CANCEL_CURRENT);
|
||||
return startPendingIntent;
|
||||
}
|
||||
|
||||
private long getTimestamp(String timeString) {
|
||||
if (TextUtils.isEmpty(timeString)) {
|
||||
return 0;
|
||||
}
|
||||
if (timeString.length() == 8) {
|
||||
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("HH:mm:ss");
|
||||
try {
|
||||
Date date = simpleDateFormat.parse(timeString);
|
||||
long timestamp = date.getTime() + getZeroTiemstamp();
|
||||
return timestamp;
|
||||
} catch (ParseException e) {
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||
try {
|
||||
Date date = simpleDateFormat.parse(timeString);
|
||||
long timestamp = date.getTime();
|
||||
return timestamp;
|
||||
} catch (ParseException e) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private long getZeroTiemstamp() {
|
||||
long nowTime = System.currentTimeMillis();
|
||||
long dayMillisecond = 60 * 60 * 24 * 1000;
|
||||
long zeroTime = ((nowTime) / dayMillisecond) * dayMillisecond;
|
||||
Log.e(TAG, "getZeroTiemstamp: " + zeroTime);
|
||||
return zeroTime;
|
||||
}
|
||||
|
||||
private static final int ONCE = 1;
|
||||
private static final int LOOP = 2;
|
||||
|
||||
public void setAlarm(AlarmClockData alarm) {
|
||||
int id = alarm.getId();
|
||||
int type = alarm.getType();
|
||||
String timeString = alarm.getTime();
|
||||
long timestamp = getTimestamp(timeString);
|
||||
String title = alarm.getRemarks();
|
||||
boolean finished = alarm.isFinished();
|
||||
String url = alarm.getVoice();
|
||||
String md5 = alarm.getVoice_md5();
|
||||
if (!TextUtils.isEmpty(url)) {
|
||||
ariaDownload(url, md5);
|
||||
}
|
||||
if (type == ONCE) {
|
||||
if (!finished) {
|
||||
if (timestamp < System.currentTimeMillis()) {
|
||||
Intent intent = new Intent(MainService.ALARMWAKEUP);
|
||||
intent.putExtra("title", title);
|
||||
intent.putExtra("id", id);
|
||||
mContext.sendBroadcast(intent);
|
||||
} else {
|
||||
setOnceAlarm(MainService.ALARMWAKEUP, title, id, timestamp);
|
||||
}
|
||||
}
|
||||
} else if (type == LOOP) {
|
||||
setDayLoopAlarm(MainService.ALARMWAKEUP, title, id, timestamp);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param action
|
||||
* @param requestCode
|
||||
* @param timestamp 设置一次性闹钟
|
||||
*/
|
||||
public void setOnceAlarm(String action, String extra, int requestCode, long timestamp) {
|
||||
Intent intent = new Intent(action);
|
||||
intent.putExtra("title", extra);
|
||||
intent.putExtra("id", requestCode);
|
||||
PendingIntent startPendingIntent = PendingIntent.getBroadcast(mContext, requestCode, intent, PendingIntent.FLAG_CANCEL_CURRENT);
|
||||
pendingIntents.add(startPendingIntent);
|
||||
alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, timestamp, startPendingIntent);
|
||||
Log.e(TAG, "setOnceAlarm: " + "id: " + requestCode + " title: " + extra + " timeString: " + timestamp);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param action
|
||||
* @param requestCode
|
||||
* @param timestamp 设置循环周期为一天的闹钟
|
||||
*/
|
||||
public void setDayLoopAlarm(String action, String extra, int requestCode, long timestamp) {
|
||||
setLoopAlarm(action, extra, requestCode, AlarmManager.INTERVAL_DAY, timestamp);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param action
|
||||
* @param requestCode
|
||||
* @param timestamp 设置循环周期为一小时的闹钟
|
||||
*/
|
||||
public void setHourLoopAlarm(String action, String extra, int requestCode, long timestamp) {
|
||||
setLoopAlarm(action, extra, requestCode, AlarmManager.INTERVAL_HOUR, timestamp);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param action
|
||||
* @param requestCode
|
||||
* @param intervalMillis
|
||||
* @param timestamp 循环闹钟
|
||||
*/
|
||||
public void setLoopAlarm(String action, String extra, int requestCode, long intervalMillis, long timestamp) {
|
||||
Intent intent = new Intent(action);
|
||||
intent.putExtra("title", extra);
|
||||
intent.putExtra("id", requestCode);
|
||||
PendingIntent startPendingIntent = PendingIntent.getBroadcast(mContext, requestCode, intent, PendingIntent.FLAG_CANCEL_CURRENT);
|
||||
pendingIntents.add(startPendingIntent);
|
||||
alarmManager.setWindow(AlarmManager.RTC_WAKEUP, timestamp, intervalMillis, startPendingIntent);
|
||||
Log.e(TAG, "setLoopAlarm: " + "title: " + extra + " timeString: " + timestamp);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void ariaDownload(String url, String md5) {
|
||||
String fileName = Utils.getFileNamefromURL(url);
|
||||
File file = new File(Utils.getDownLoadPath(mContext) + fileName);
|
||||
if (file.exists() && !file.isDirectory()) {
|
||||
String fileMD5 = FileUtils.getFileMD5ToString(file);
|
||||
Log.e("ariaDownload", "fileOnlineMD5=" + md5);
|
||||
Log.e("ariaDownload", "fileMD5=" + fileMD5);
|
||||
if (!md5.equals(fileMD5)) {
|
||||
Aria.download(this)
|
||||
.load(url) //读取下载地址
|
||||
.setFilePath(Utils.getDownLoadPath(mContext) + fileName)
|
||||
// .ignoreFilePathOccupy()
|
||||
.setExtendField(md5)
|
||||
.create(); //启动下载}
|
||||
} else {
|
||||
Log.e("ariaDownload", "fileName = " + fileName + " exists");
|
||||
}
|
||||
} else {
|
||||
Aria.download(this)
|
||||
.load(url) //读取下载地址
|
||||
.setFilePath(Utils.getDownLoadPath(mContext) + fileName)
|
||||
// .ignoreFilePathOccupy()
|
||||
.setExtendField(md5)
|
||||
.create(); //启动下载}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
103
app/src/main/java/com/uiui/os/utils/CmdUtil.java
Normal file
103
app/src/main/java/com/uiui/os/utils/CmdUtil.java
Normal file
@@ -0,0 +1,103 @@
|
||||
package com.uiui.os.utils;
|
||||
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
|
||||
public class CmdUtil {
|
||||
private static final String TAG = "CmdUtil";
|
||||
|
||||
private static final String COMMAND_SH = "sh";
|
||||
private static final String COMMAND_EXIT = "exit\n";
|
||||
private static final String COMMAND_LINE_END = "\n";
|
||||
|
||||
|
||||
/**
|
||||
* 运行命令
|
||||
*
|
||||
* @param command 命令
|
||||
* @return 结果
|
||||
*/
|
||||
public static Result execute(String command) {
|
||||
Log.i(TAG, "execute() command = " + command);
|
||||
Result result = new Result();
|
||||
|
||||
if (TextUtils.isEmpty(command)) {
|
||||
Log.w(TAG, "WARNING: command should not be null or empty");
|
||||
return result;
|
||||
}
|
||||
|
||||
Process process = null;
|
||||
DataOutputStream dos = null;
|
||||
|
||||
try {
|
||||
process = Runtime.getRuntime().exec(COMMAND_SH);
|
||||
dos = new DataOutputStream(process.getOutputStream());
|
||||
dos.write(command.trim().getBytes());
|
||||
dos.writeBytes(COMMAND_LINE_END);
|
||||
dos.flush();
|
||||
dos.writeBytes(COMMAND_EXIT);
|
||||
dos.flush();
|
||||
result.code = process.waitFor();
|
||||
result.success = readBuffer(new BufferedReader(new InputStreamReader(process.getInputStream())));
|
||||
result.error = readBuffer(new BufferedReader(new InputStreamReader(process.getErrorStream())));
|
||||
Log.i(TAG, "result = " + result);
|
||||
} catch (IOException ioe) {
|
||||
ioe.printStackTrace();
|
||||
Log.e(TAG, ioe.getMessage());
|
||||
} catch (InterruptedException ie) {
|
||||
ie.printStackTrace();
|
||||
Log.e(TAG, ie.getMessage());
|
||||
} finally {
|
||||
try {
|
||||
if (null != dos) {
|
||||
dos.close();
|
||||
}
|
||||
} catch (IOException ioe) {
|
||||
ioe.printStackTrace();
|
||||
Log.e(TAG, ioe.getMessage());
|
||||
}
|
||||
if (null != process) {
|
||||
process.destroy();
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static String readBuffer(BufferedReader bufferedReader) throws IOException {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
String s;
|
||||
while ((s = bufferedReader.readLine()) != null) {
|
||||
sb.append(s);
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Command执行结果
|
||||
*/
|
||||
public static final class Result {
|
||||
|
||||
public static final int SUCCESS = 0;
|
||||
public static final int ERROR = -1;
|
||||
|
||||
public int code = ERROR;
|
||||
public String error;
|
||||
public String success;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Result{" +
|
||||
"code=" + code +
|
||||
", error='" + error + '\'' +
|
||||
", success='" + success + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
116
app/src/main/java/com/uiui/os/utils/ForegroundAppUtil.java
Normal file
116
app/src/main/java/com/uiui/os/utils/ForegroundAppUtil.java
Normal file
@@ -0,0 +1,116 @@
|
||||
package com.uiui.os.utils;
|
||||
|
||||
import android.app.ActivityManager;
|
||||
import android.app.usage.UsageStats;
|
||||
import android.app.usage.UsageStatsManager;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Build;
|
||||
import android.provider.Settings;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class ForegroundAppUtil {
|
||||
|
||||
private static final long END_TIME = System.currentTimeMillis();
|
||||
private static final long TIME_INTERVAL = 7 * 24 * 60 * 60 * 1000L;
|
||||
private static final long START_TIME = END_TIME - TIME_INTERVAL;
|
||||
|
||||
public static final String TOPAPP_KEY = "TOP_ALWAYS_SHOW_APP_NAME";
|
||||
private static String TAG = ForegroundAppUtil.class.getSimpleName();
|
||||
|
||||
public static String getForegroundPackageName(Context context) {
|
||||
//系统应用可以直接获取
|
||||
ActivityManager mActivityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
|
||||
List<ActivityManager.RunningTaskInfo> runningTaskInfos = mActivityManager.getRunningTasks(1);
|
||||
return runningTaskInfos.get(0).topActivity.getPackageName();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取栈顶的应用包名
|
||||
*/
|
||||
public static String getForegroundActivityName(Context context) {
|
||||
String currentClassName = "";
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
|
||||
ActivityManager manager = (ActivityManager) context.getApplicationContext().getSystemService(Context.ACTIVITY_SERVICE);
|
||||
currentClassName = manager.getRunningTasks(1).get(0).topActivity.getPackageName();
|
||||
} else {
|
||||
UsageStats initStat = getForegroundUsageStats(context, START_TIME, END_TIME);
|
||||
if (initStat != null) {
|
||||
currentClassName = initStat.getPackageName();
|
||||
}
|
||||
}
|
||||
return currentClassName;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断当前应用是否在前台
|
||||
*/
|
||||
public static boolean isForegroundApp(Context context) {
|
||||
return TextUtils.equals(getForegroundActivityName(context), context.getPackageName());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取时间段内,
|
||||
*/
|
||||
public static long getTotleForegroundTime(Context context) {
|
||||
UsageStats usageStats = getCurrentUsageStats(context, START_TIME, END_TIME);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
return usageStats != null ? usageStats.getTotalTimeInForeground() : 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取记录前台应用的UsageStats对象
|
||||
*/
|
||||
private static UsageStats getForegroundUsageStats(Context context, long startTime, long endTime) {
|
||||
UsageStats usageStatsResult = null;
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
List<UsageStats> usageStatses = getUsageStatsList(context, startTime, endTime);
|
||||
if (usageStatses == null || usageStatses.isEmpty()) return null;
|
||||
for (UsageStats usageStats : usageStatses) {
|
||||
if (usageStatsResult == null || usageStatsResult.getLastTimeUsed() < usageStats.getLastTimeUsed()) {
|
||||
usageStatsResult = usageStats;
|
||||
}
|
||||
}
|
||||
}
|
||||
return usageStatsResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取记录当前应用的UsageStats对象
|
||||
*/
|
||||
public static UsageStats getCurrentUsageStats(Context context, long startTime, long endTime) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
List<UsageStats> usageStatses = getUsageStatsList(context, startTime, endTime);
|
||||
if (usageStatses == null || usageStatses.isEmpty()) return null;
|
||||
for (UsageStats usageStats : usageStatses) {
|
||||
if (TextUtils.equals(usageStats.getPackageName(), context.getPackageName())) {
|
||||
return usageStats;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过UsageStatsManager获取List<UsageStats>集合
|
||||
*/
|
||||
public static List<UsageStats> getUsageStatsList(Context context, long startTime, long endTime) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
UsageStatsManager manager = (UsageStatsManager) context.getApplicationContext().getSystemService(Context.USAGE_STATS_SERVICE);
|
||||
//UsageStatsManager.INTERVAL_WEEKLY,UsageStatsManager的参数定义了5个,具体查阅源码
|
||||
List<UsageStats> usageStatses = manager.queryUsageStats(UsageStatsManager.INTERVAL_BEST, startTime, endTime);
|
||||
if (usageStatses == null || usageStatses.size() == 0) {// 没有权限,获取不到数据
|
||||
Intent intent = new Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS);
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
context.getApplicationContext().startActivity(intent);
|
||||
return null;
|
||||
}
|
||||
return usageStatses;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
112
app/src/main/java/com/uiui/os/utils/MD5Util.java
Normal file
112
app/src/main/java/com/uiui/os/utils/MD5Util.java
Normal file
@@ -0,0 +1,112 @@
|
||||
package com.uiui.os.utils;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
||||
public class MD5Util {
|
||||
|
||||
public static String packetMD5(String str) {
|
||||
MessageDigest messageDigest = null;
|
||||
try {
|
||||
messageDigest = MessageDigest.getInstance("MD5");
|
||||
|
||||
messageDigest.reset();
|
||||
|
||||
messageDigest.update(str.getBytes("UTF-8"));
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
System.out.println("NoSuchAlgorithmException caught!");
|
||||
System.exit(-1);
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
byte[] byteArray = messageDigest.digest();
|
||||
|
||||
StringBuffer md5StrBuff = new StringBuffer();
|
||||
|
||||
for (int i = 0; i < byteArray.length; i++) {
|
||||
if (Integer.toHexString(0xFF & byteArray[i]).length() == 1)
|
||||
md5StrBuff.append("0").append(
|
||||
Integer.toHexString(0xFF & byteArray[i]));
|
||||
else
|
||||
md5StrBuff.append(Integer.toHexString(0xFF & byteArray[i]));
|
||||
}
|
||||
|
||||
return md5StrBuff.toString();
|
||||
}
|
||||
|
||||
@SuppressLint("DefaultLocale")
|
||||
public static String getUpperMD5Str(String str) {
|
||||
MessageDigest messageDigest = null;
|
||||
|
||||
try {
|
||||
messageDigest = MessageDigest.getInstance("MD5");
|
||||
|
||||
messageDigest.reset();
|
||||
|
||||
messageDigest.update(str.getBytes("UTF-8"));
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
System.out.println("NoSuchAlgorithmException caught!");
|
||||
System.exit(-1);
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
byte[] byteArray = messageDigest.digest();
|
||||
|
||||
StringBuffer md5StrBuff = new StringBuffer();
|
||||
|
||||
for (int i = 0; i < byteArray.length; i++) {
|
||||
if (Integer.toHexString(0xFF & byteArray[i]).length() == 1)
|
||||
md5StrBuff.append("0").append(
|
||||
Integer.toHexString(0xFF & byteArray[i]));
|
||||
else
|
||||
md5StrBuff.append(Integer.toHexString(0xFF & byteArray[i]));
|
||||
}
|
||||
|
||||
return md5StrBuff.toString().toUpperCase();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取16位的MD5 值得
|
||||
*
|
||||
* @param str
|
||||
* @return
|
||||
*/
|
||||
@SuppressLint("DefaultLocale")
|
||||
public static String getUpperMD5Str16(String str) {
|
||||
MessageDigest messageDigest = null;
|
||||
|
||||
try {
|
||||
messageDigest = MessageDigest.getInstance("MD5");
|
||||
|
||||
messageDigest.reset();
|
||||
|
||||
messageDigest.update(str.getBytes("UTF-8"));
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
System.out.println("NoSuchAlgorithmException caught!");
|
||||
System.exit(-1);
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
byte[] byteArray = messageDigest.digest();
|
||||
|
||||
StringBuffer md5StrBuff = new StringBuffer();
|
||||
|
||||
for (int i = 0; i < byteArray.length; i++) {
|
||||
if (Integer.toHexString(0xFF & byteArray[i]).length() == 1)
|
||||
md5StrBuff.append("0").append(
|
||||
Integer.toHexString(0xFF & byteArray[i]));
|
||||
else
|
||||
md5StrBuff.append(Integer.toHexString(0xFF & byteArray[i]));
|
||||
}
|
||||
|
||||
return md5StrBuff.toString().toUpperCase().substring(8, 24);
|
||||
}
|
||||
|
||||
}
|
||||
93
app/src/main/java/com/uiui/os/utils/TimeUtils.java
Normal file
93
app/src/main/java/com/uiui/os/utils/TimeUtils.java
Normal file
@@ -0,0 +1,93 @@
|
||||
package com.uiui.os.utils;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.util.Log;
|
||||
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
|
||||
public class TimeUtils {
|
||||
@SuppressLint("StaticFieldLeak")
|
||||
private static TimeUtils sInstance;
|
||||
private Context mContext;
|
||||
|
||||
private SimpleDateFormat ruleSDF = new SimpleDateFormat("HH:mm:ss");
|
||||
private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||
private String TAG = TimeUtils.class.getSimpleName();
|
||||
|
||||
private TimeUtils(Context context) {
|
||||
this.mContext = context;
|
||||
}
|
||||
|
||||
public static void init(Context context) {
|
||||
if (sInstance == null) {
|
||||
sInstance = new TimeUtils(context);
|
||||
}
|
||||
}
|
||||
|
||||
public static TimeUtils getInstance() {
|
||||
if (sInstance == null) {
|
||||
throw new IllegalStateException("You must be init TimeUtils first");
|
||||
}
|
||||
return sInstance;
|
||||
}
|
||||
|
||||
private static String normalStartTime = "8:00:00";
|
||||
private static String unusualStartTime = "22:00:00";
|
||||
|
||||
private String appPackageName;
|
||||
private long endTime = 0;
|
||||
private long startTime = 0;
|
||||
|
||||
public void setAppPackageName(String name) {
|
||||
this.appPackageName = name;
|
||||
}
|
||||
|
||||
public String getAppPackageName() {
|
||||
return appPackageName;
|
||||
}
|
||||
|
||||
public void setStartTime(long time) {
|
||||
this.startTime = time;
|
||||
}
|
||||
|
||||
public long getStartTime() {
|
||||
return startTime;
|
||||
}
|
||||
|
||||
public void setEndTime(long time) {
|
||||
this.endTime = time;
|
||||
}
|
||||
|
||||
public long getEndTime() {
|
||||
return endTime;
|
||||
}
|
||||
|
||||
private static final long DAY_TIME = 1000 * 60 * 60 * 24;
|
||||
|
||||
public boolean isNormalTime() {
|
||||
long nowTime = System.currentTimeMillis();
|
||||
String nowTimeString = ruleSDF.format(new Date(nowTime)); // 时间戳转换日期
|
||||
try {
|
||||
Date startDate = ruleSDF.parse(normalStartTime);
|
||||
Date endDate = ruleSDF.parse(unusualStartTime);
|
||||
Date now = ruleSDF.parse(nowTimeString);
|
||||
Log.e(TAG, "isScreenshot: startDate = " + startDate);
|
||||
Log.e(TAG, "isScreenshot: endDate = " + endDate);
|
||||
Log.e(TAG, "isScreenshot: now = " + now);
|
||||
if (startDate.getTime() <= now.getTime() && now.getTime() <= endDate.getTime()) {
|
||||
return true;
|
||||
} else if (endDate.getTime() < now.getTime() && now.getTime() <= startDate.getTime() + DAY_TIME) {
|
||||
return false;
|
||||
}
|
||||
} catch (ParseException e) {
|
||||
e.printStackTrace();
|
||||
Log.e(TAG, "isScreenshot: " + e.getMessage());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
93
app/src/main/java/com/uiui/os/utils/ToastUtil.java
Normal file
93
app/src/main/java/com/uiui/os/utils/ToastUtil.java
Normal file
@@ -0,0 +1,93 @@
|
||||
package com.uiui.os.utils;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.graphics.Color;
|
||||
import android.os.Build;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.util.Log;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.blankj.utilcode.util.ToastUtils;
|
||||
import com.uiui.os.BuildConfig;
|
||||
|
||||
|
||||
/**
|
||||
* Created by haoge on 2017/3/2.
|
||||
*/
|
||||
|
||||
public class ToastUtil {
|
||||
private static final String TAG = ToastUtil.class.getSimpleName();
|
||||
@SuppressLint("StaticFieldLeak")
|
||||
private static Context mContext;
|
||||
private static Handler mainHandler = new Handler(Looper.getMainLooper());
|
||||
private static Toast debugToast;
|
||||
private static Toast toast;
|
||||
|
||||
|
||||
@SuppressLint("ShowToast")
|
||||
public static void init(Context context) {
|
||||
mContext = context;
|
||||
toast = Toast.makeText(mContext, "", Toast.LENGTH_SHORT);
|
||||
debugToast = Toast.makeText(mContext, "", Toast.LENGTH_SHORT);
|
||||
|
||||
}
|
||||
|
||||
private static long time1 = 0L;
|
||||
private static long time2 = 0L;
|
||||
|
||||
public static void show(final String msg) {
|
||||
ToastUtils.make()
|
||||
// .setBgColor(ColorUtils.getColor(R.color.toast_color))
|
||||
.setTextColor(Color.DKGRAY)
|
||||
// .setGravity(Gravity.CENTER, 0, 0)
|
||||
.setNotUseSystemToast()
|
||||
.show(msg);
|
||||
}
|
||||
|
||||
public static void betaShow(final String msg) {
|
||||
if ( BuildConfig.DEBUG) {
|
||||
ToastUtils.make()
|
||||
// .setBgColor(ColorUtils.getColor(R.color.toast_color))
|
||||
.setTextColor(Color.RED)
|
||||
// .setGravity(Gravity.CENTER, 0, 0)
|
||||
.setNotUseSystemToast()
|
||||
.setDurationIsLong(true)
|
||||
.show(msg);
|
||||
} else {
|
||||
Log.e(TAG, "debugShow: " + msg);
|
||||
}
|
||||
}
|
||||
|
||||
private static Toast mToast = null;
|
||||
|
||||
//android 8.0以后限制
|
||||
//https://www.jianshu.com/p/d9813ad03d59
|
||||
//https://www.jianshu.com/p/050ce052b873
|
||||
public static void showToast(Context context, String text, int duration) {
|
||||
if (Build.VERSION.SDK_INT == Build.VERSION_CODES.P) {
|
||||
Toast.makeText(context, text, duration).show();
|
||||
} else {
|
||||
if (mToast == null) {
|
||||
mToast = Toast.makeText(context, text, duration);
|
||||
} else {
|
||||
mToast.setText(text);
|
||||
mToast.setDuration(duration);
|
||||
}
|
||||
mToast.show();
|
||||
}
|
||||
}
|
||||
|
||||
// public static void showInCenter(String msg) {
|
||||
// mainHandler.post(() -> {
|
||||
// if (toast != null) {
|
||||
// toast.setGravity(Gravity.CENTER, 0, 0);
|
||||
// toast.setText(msg);
|
||||
// toast.show();
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
|
||||
|
||||
}
|
||||
@@ -1,13 +1,66 @@
|
||||
package com.uiui.os.utils;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.content.ContextWrapper;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.os.BatteryManager;
|
||||
import android.os.Build;
|
||||
import android.os.Environment;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.core.content.ContextCompat;
|
||||
|
||||
import com.uiui.os.BuildConfig;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.lang.reflect.Method;
|
||||
import java.math.BigInteger;
|
||||
import java.security.MessageDigest;
|
||||
|
||||
public class Utils {
|
||||
/**
|
||||
* 获取设备序列号
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@SuppressLint("MissingPermission")
|
||||
public static String getSerial() {
|
||||
String serial = "unknow";
|
||||
try {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {//9.0+
|
||||
serial = Build.getSerial();
|
||||
} else if (Build.VERSION.SDK_INT > Build.VERSION_CODES.N) {//8.0+
|
||||
serial = Build.SERIAL;
|
||||
} else {//8.0-
|
||||
Class<?> c = Class.forName("android.os.SystemProperties");
|
||||
Method get = c.getMethod("get", String.class);
|
||||
serial = (String) get.invoke(c, "ro.serialno");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Log.e("e", "读取设备序列号异常:" + e.toString());
|
||||
}
|
||||
if (BuildConfig.DEBUG) {
|
||||
// return "QNG2DKB00463";
|
||||
}
|
||||
return serial;
|
||||
}
|
||||
|
||||
public static String getDeviceSN() {
|
||||
String serial = null;
|
||||
try {
|
||||
Class<?> c = Class.forName("android.os.SystemProperties");
|
||||
Method get = c.getMethod("get", String.class);
|
||||
serial = (String) get.invoke(c, "persist.sys.hrSerial");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return serial;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取电量
|
||||
*
|
||||
@@ -23,4 +76,14 @@ public class Utils {
|
||||
}
|
||||
}
|
||||
|
||||
public static String getDownLoadPath(Context context) {
|
||||
String path = ContextCompat.getExternalFilesDirs(context, Environment.DIRECTORY_DOWNLOADS)[0].getAbsolutePath();
|
||||
return path + File.separator;
|
||||
}
|
||||
|
||||
public static String getFileNamefromURL(String url) {
|
||||
int position = url.lastIndexOf("/");
|
||||
return url.substring(position + 1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user