diff --git a/app/build.gradle b/app/build.gradle index 783c2b6..f8f0f0d 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -67,8 +67,8 @@ android { productFlavors { beta { flavorDimensions "default" - versionCode 27 - versionName "3.6" + versionCode 28 + versionName "3.7" } official { diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index b4d2a57..5436208 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -127,7 +127,7 @@ android:name=".service.RemoteService" android:enabled="true" android:exported="true" - android:process=":remote" /> + /> getHideAPP(); - //获取禁止打开的APP - List getForbidAPP(); - - //获取app设置 - String getAppTimeControl(); - //获取整机设置 - String getSnTimeControl(); - //获取系统设置 - String getSetting(); + //获取系统开关 + boolean isControl(); + //获取app是否在管控时间 + boolean inControl(String pkg); + //获取app禁用提示 + String getDisableContent(String pkg); } diff --git a/app/src/main/java/com/uiui/sn/Statistics/StatisticsInfo.java b/app/src/main/java/com/uiui/sn/Statistics/StatisticsInfo.java index 3dfc3ec..6177d62 100644 --- a/app/src/main/java/com/uiui/sn/Statistics/StatisticsInfo.java +++ b/app/src/main/java/com/uiui/sn/Statistics/StatisticsInfo.java @@ -31,6 +31,16 @@ public class StatisticsInfo { private int style; private Context mContext; + public StatisticsInfo(Context context) { + try { + this.style = 0; + setUsageStatsList(context); + setShowList(); + } catch (NoSuchFieldException e) { + e.printStackTrace(); + } + } + public StatisticsInfo(Context context, int style) { this.mContext = context; try { diff --git a/app/src/main/java/com/uiui/sn/activity/main/MainActivity.java b/app/src/main/java/com/uiui/sn/activity/main/MainActivity.java index 72422b7..baa0971 100644 --- a/app/src/main/java/com/uiui/sn/activity/main/MainActivity.java +++ b/app/src/main/java/com/uiui/sn/activity/main/MainActivity.java @@ -7,6 +7,7 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.ServiceConnection; +import android.content.pm.PackageManager; import android.graphics.Bitmap; import android.media.AudioManager; import android.os.AsyncTask; @@ -113,6 +114,13 @@ public class MainActivity extends BaseActivity implements MainAContact.MainView, NetworkUtils.registerNetworkStatusChangedListener(this); + try { + PackageManager pm = getPackageManager(); + pm.setApplicationEnabledSetting("com.uiui.os", PackageManager.COMPONENT_ENABLED_STATE_DISABLED, 0); + } catch (Exception e) { + Log.e(TAG, "initView: " + e.getMessage()); + } + setOnClickListener(); tv_customversion.setText(JGYUtils.getCustomVersion()); tv_sn.setText("IMEI:" + Utils.getIMEI(MainActivity.this)); @@ -175,7 +183,7 @@ public class MainActivity extends BaseActivity implements MainAContact.MainView, private MainServiceConnection mMainServiceConnection = new MainServiceConnection(); - private class MainServiceConnection implements ServiceConnection { + private class MainServiceConnection implements ServiceConnection { @Override public void onServiceConnected(ComponentName componentName, IBinder iBinder) { Log.e(TAG, "onServiceConnected: "); diff --git a/app/src/main/java/com/uiui/sn/base/BaseApplication.java b/app/src/main/java/com/uiui/sn/base/BaseApplication.java index 81be52f..05c5e78 100644 --- a/app/src/main/java/com/uiui/sn/base/BaseApplication.java +++ b/app/src/main/java/com/uiui/sn/base/BaseApplication.java @@ -14,6 +14,8 @@ import com.tencent.android.tpush.XGPushConfig; import com.tencent.android.tpush.XGPushManager; import com.tencent.mmkv.MMKV; import com.uiui.sn.BuildConfig; +import com.uiui.sn.desktop.RunningAppManager; +import com.uiui.sn.desktop.TimeControlManager; import com.uiui.sn.manager.AmapManager; import com.uiui.sn.manager.ConnectManager; import com.uiui.sn.manager.ControlManager; @@ -36,24 +38,24 @@ public class BaseApplication extends Application { public void onCreate() { super.onCreate(); //非主进程不初始化 -// if (SystemUtils.isMainProcessName(this, android.os.Process.myPid())) { - if (BuildConfig.DEBUG) { + if (SystemUtils.isMainProcessName(this, android.os.Process.myPid())) { + if (BuildConfig.DEBUG) { // ApkUtils.openApp(this, "com.android.settings"); - //静音 - AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE); - int ringMax = audioManager.getStreamMinVolumeInt(AudioManager.STREAM_RING); - audioManager.setStreamVolume(AudioManager.STREAM_RING, ringMax, 0); - int musicMax = audioManager.getStreamMinVolumeInt(AudioManager.STREAM_MUSIC); - int voiceMax = audioManager.getStreamMinVolumeInt(AudioManager.STREAM_VOICE_CALL); - audioManager.setStreamVolume(AudioManager.STREAM_VOICE_CALL, voiceMax, 0); - audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, musicMax, 0); //音乐音量 - Log.e(TAG, "debugTest: " + getExternalCacheDir()); - Log.e(TAG, "debugTest: " + getExternalFilesDir("cache")); - Log.e(TAG, "debugTest: " + getCacheDir()); - Log.e(TAG, "debugTest: " + Environment.getExternalStorageDirectory()); + //静音 + AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE); + int ringMax = audioManager.getStreamMinVolumeInt(AudioManager.STREAM_RING); + audioManager.setStreamVolume(AudioManager.STREAM_RING, ringMax, 0); + int musicMax = audioManager.getStreamMinVolumeInt(AudioManager.STREAM_MUSIC); + int voiceMax = audioManager.getStreamMinVolumeInt(AudioManager.STREAM_VOICE_CALL); + audioManager.setStreamVolume(AudioManager.STREAM_VOICE_CALL, voiceMax, 0); + audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, musicMax, 0); //音乐音量 + Log.e(TAG, "debugTest: " + getExternalCacheDir()); + Log.e(TAG, "debugTest: " + getExternalFilesDir("cache")); + Log.e(TAG, "debugTest: " + getCacheDir()); + Log.e(TAG, "debugTest: " + Environment.getExternalStorageDirectory()); + } + utilsInint(); } - utilsInint(); -// } } private void utilsInint() { @@ -69,6 +71,8 @@ public class BaseApplication extends Application { Aria.init(this); Aria.download(this).resumeAllTask(); JGYUtils.init(this); + RunningAppManager.init(this); + TimeControlManager.init(this); ControlManager.init(this); ControlPanelManager.init(this); DeviceManager.init(this); diff --git a/app/src/main/java/com/uiui/sn/bean/AppUsageTime.java b/app/src/main/java/com/uiui/sn/bean/AppUsageTime.java new file mode 100644 index 0000000..ee36d28 --- /dev/null +++ b/app/src/main/java/com/uiui/sn/bean/AppUsageTime.java @@ -0,0 +1,29 @@ +package com.uiui.sn.bean; + +import java.io.Serializable; + +public class AppUsageTime implements Serializable { + private static final long serialVersionUID = -2981074385838909527L; + + /*包名*/ + String pkg; + /*使用时间*/ + long usageTime; + + + public String getPkg() { + return pkg; + } + + public void setPkg(String pkg) { + this.pkg = pkg; + } + + public long getUsageTime() { + return usageTime; + } + + public void setUsageTime(long usageTime) { + this.usageTime = usageTime; + } +} diff --git a/app/src/main/java/com/uiui/sn/bean/RemainTime.java b/app/src/main/java/com/uiui/sn/bean/RemainTime.java new file mode 100644 index 0000000..00418c2 --- /dev/null +++ b/app/src/main/java/com/uiui/sn/bean/RemainTime.java @@ -0,0 +1,78 @@ +package com.uiui.sn.bean; + +import androidx.annotation.NonNull; + +import com.google.gson.Gson; +import com.google.gson.JsonParser; + +import java.io.Serializable; +import java.util.List; + +public class RemainTime implements Serializable { + private static final long serialVersionUID = 5651493620850107410L; + + /*包名*/ + String pkg; + /** + * 禁用类型 + * 1 应用已被禁用 + * 2 该应用今日可使用时间已用完 + * 3 APP设置了禁用时间段 + * 4 该应用跟随整机使用,整机剩余时间不足 + * 5 该应用跟随分类使用,分类剩余时间不足 + */ + int disableType; + /*禁用提示*/ + String content; + /*应用设置的可用时间*/ + long availableTime; + /*app使用时间*/ + List mAppUsageTimes; + + + public String getPkg() { + return pkg; + } + + public void setPkg(String pkg) { + this.pkg = pkg; + } + + public int getDisableType() { + return disableType; + } + + public void setDisableType(int disableType) { + this.disableType = disableType; + } + + public String getContent() { + return content; + } + + public void setContent(String content) { + this.content = content; + } + + public long getAvailableTime() { + return availableTime; + } + + public void setAvailableTime(long availableTime) { + this.availableTime = availableTime; + } + + public List getAppUsageTimes() { + return mAppUsageTimes; + } + + public void setAppUsageTimes(List appUsageTimes) { + this.mAppUsageTimes = appUsageTimes; + } + + @NonNull + @Override + public String toString() { + return JsonParser.parseString(new Gson().toJson(this)).getAsJsonObject().toString(); + } +} diff --git a/app/src/main/java/com/uiui/sn/desktop/AppRunTimeBean.java b/app/src/main/java/com/uiui/sn/desktop/AppRunTimeBean.java new file mode 100644 index 0000000..e273e5a --- /dev/null +++ b/app/src/main/java/com/uiui/sn/desktop/AppRunTimeBean.java @@ -0,0 +1,75 @@ +package com.uiui.sn.desktop; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import com.google.gson.Gson; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; + +import java.io.Serializable; + +public class AppRunTimeBean implements Serializable { + private static final long serialVersionUID = 3699088127005434759L; + + String packageName; + Long appRunTime; + + AppRunTimeBean() { + this.appRunTime = 0L; + } + + AppRunTimeBean(String pkg) { + this.packageName = pkg; + this.appRunTime = 0L; + } + + AppRunTimeBean(String pkg, long time) { + this.packageName = pkg; + this.appRunTime = time; + } + + public String getPackageName() { + return packageName; + } + + public void setPackageName(String packageName) { + this.packageName = packageName; + } + + public void reduceTime(Long time) { + this.appRunTime -= time; + } + + public Long getAppRunTime() { + return appRunTime; + } + + public void setAppRunTime(Long appRunTime) { + this.appRunTime = appRunTime; + } + + @NonNull + @Override + public String toString() { + Gson gson = new Gson(); + JsonObject jsonObject = JsonParser.parseString(gson.toJson(this)).getAsJsonObject(); + return jsonObject.toString(); + } + + @Override + public int hashCode() { + return super.hashCode(); + } + + @Override + public boolean equals(@Nullable Object obj) { + if (obj instanceof AppRunTimeBean) { + AppRunTimeBean appRunTimeBean = (AppRunTimeBean) obj; + return appRunTimeBean.packageName.equals(packageName) + && appRunTimeBean.appRunTime.equals(appRunTime); + } else { + return false; + } + } +} diff --git a/app/src/main/java/com/uiui/sn/bean/AppTimeControl.java b/app/src/main/java/com/uiui/sn/desktop/AppTimeControl.java similarity index 89% rename from app/src/main/java/com/uiui/sn/bean/AppTimeControl.java rename to app/src/main/java/com/uiui/sn/desktop/AppTimeControl.java index dc031ce..75f8bf4 100644 --- a/app/src/main/java/com/uiui/sn/bean/AppTimeControl.java +++ b/app/src/main/java/com/uiui/sn/desktop/AppTimeControl.java @@ -1,4 +1,10 @@ -package com.uiui.sn.bean; +package com.uiui.sn.desktop; + +import androidx.annotation.NonNull; + +import com.google.gson.Gson; +import com.google.gson.JsonParser; +import com.uiui.sn.bean.PartTime; import java.io.Serializable; import java.util.List; @@ -125,4 +131,10 @@ public class AppTimeControl implements Serializable { public void setTc_class_id(int tc_class_id) { this.tc_class_id = tc_class_id; } + + @NonNull + @Override + public String toString() { + return JsonParser.parseString(new Gson().toJson(this)).getAsJsonObject().toString(); + } } diff --git a/app/src/main/java/com/uiui/sn/bean/MachineControl.java b/app/src/main/java/com/uiui/sn/desktop/MachineControl.java similarity index 84% rename from app/src/main/java/com/uiui/sn/bean/MachineControl.java rename to app/src/main/java/com/uiui/sn/desktop/MachineControl.java index bbcffb8..1055e60 100644 --- a/app/src/main/java/com/uiui/sn/bean/MachineControl.java +++ b/app/src/main/java/com/uiui/sn/desktop/MachineControl.java @@ -1,4 +1,10 @@ -package com.uiui.sn.bean; +package com.uiui.sn.desktop; + +import androidx.annotation.NonNull; + +import com.google.gson.Gson; +import com.google.gson.JsonParser; +import com.uiui.sn.bean.PartTime; import java.io.Serializable; import java.util.List; @@ -86,4 +92,10 @@ public class MachineControl implements Serializable { public void setTime_part(List time_part) { this.time_part = time_part; } + + @NonNull + @Override + public String toString() { + return JsonParser.parseString(new Gson().toJson(this)).getAsJsonObject().toString(); + } } diff --git a/app/src/main/java/com/uiui/sn/desktop/RunningAppManager.java b/app/src/main/java/com/uiui/sn/desktop/RunningAppManager.java new file mode 100644 index 0000000..beb3fc9 --- /dev/null +++ b/app/src/main/java/com/uiui/sn/desktop/RunningAppManager.java @@ -0,0 +1,1267 @@ +package com.uiui.sn.desktop; + +import android.annotation.SuppressLint; +import android.app.ActivityManager; +import android.app.ActivityManagerNative; +import android.app.ActivityTaskManager; +import android.app.usage.UsageStats; +import android.app.usage.UsageStatsManager; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.content.pm.UserInfo; +import android.os.Build; +import android.os.PowerManager; +import android.os.RemoteException; +import android.provider.Settings; +import android.text.TextUtils; +import android.util.Log; + +import androidx.annotation.NonNull; +import androidx.annotation.RequiresApi; + +import com.google.gson.Gson; +import com.google.gson.reflect.TypeToken; +import com.tencent.mmkv.MMKV; +import com.uiui.sn.BuildConfig; +import com.uiui.sn.Statistics.AppInformation; +import com.uiui.sn.Statistics.StatisticsInfo; +import com.uiui.sn.bean.AppUsageTime; +import com.uiui.sn.bean.PartTime; +import com.uiui.sn.bean.RemainTime; +import com.uiui.sn.config.CommonConfig; +import com.uiui.sn.gson.GsonUtils; +import com.uiui.sn.network.NetInterfaceManager; +import com.uiui.sn.utils.JGYUtils; +import com.uiui.sn.utils.ToastUtil; + +import java.lang.reflect.Method; +import java.lang.reflect.Type; +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.time.LocalDateTime; +import java.time.ZoneOffset; +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Date; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.TimeUnit; +import java.util.function.Predicate; +import java.util.stream.Collectors; + +import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers; +import io.reactivex.rxjava3.core.Observable; +import io.reactivex.rxjava3.functions.Consumer; +import io.reactivex.rxjava3.schedulers.Schedulers; + +import static android.app.ActivityManager.RECENT_IGNORE_UNAVAILABLE; + +public class RunningAppManager { + private static final String TAG = RunningAppManager.class.getSimpleName(); + + @SuppressLint("StaticFieldLeak") + private static RunningAppManager mRunningAppManager; + private Context mContext; + private MMKV mMMKV = MMKV.defaultMMKV(); + + + public static final String RemainingTimeMap = "RemainingTimeMap_KEY"; + + public static final String GlobalUsageTimeMap = "GlobalUsageTimeMap_KEY"; + + //剩余时间 + private long globalRemainingTime = 0L; + + //存储每个单独有配置app剩余时间 + private HashMap mRemainingTimeMap = new HashMap<>(); + + //存储整机配置app使用时间 + private HashMap mGlobalUsageTime = new HashMap<>(); + + + //存储每个分类剩余时间 + HashMap mClassifyTimeMap = new HashMap<>(); + + public static long minuteTime = 60 * 1000; + public static long dayTime = minuteTime * 60 * 24; + + //日期格式化 + private static DateFormat dateFormat = new SimpleDateFormat("HH:mm"); + + /*当前时间*/ + 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; + + private RunningAppManager(Context context) { + if (context == null) { + throw new RuntimeException("Context is NULL"); + } + this.mContext = context; + registerTimeReceiver(mContext); + + String remainsTimeJson = mMMKV.decodeString(RemainingTimeMap, ""); + Log.e(TAG, "remainsTimeJson: " + remainsTimeJson); + Gson gson = new Gson(); + Type remainsTimeType = new TypeToken>() { + }.getType(); + HashMap remainingTimeMap = gson.fromJson(remainsTimeJson, remainsTimeType); + if (remainingTimeMap != null) { + mRemainingTimeMap = remainingTimeMap; + } + + String globalUsageTimeJson = mMMKV.decodeString(GlobalUsageTimeMap, ""); + Log.e(TAG, "globalUsageTimeJson: " + globalUsageTimeJson); + Type globalUsageTimeType = new TypeToken>() { + }.getType(); + HashMap appUsageTimeHashMap = gson.fromJson(globalUsageTimeJson, globalUsageTimeType); + if (appUsageTimeHashMap != null) { + mGlobalUsageTime = appUsageTimeHashMap; + } + inInterval(); + } + + public static void init(Context context) { + if (mRunningAppManager == null) { + mRunningAppManager = new RunningAppManager(context); + } + } + + public static RunningAppManager getInstance() { + if (mRunningAppManager == null) { + throw new IllegalStateException("You must be init RunningAppManager first"); + } + return mRunningAppManager; + } + + /** + * 初始化计时 + */ + private void inInterval() { + Observable.interval(1, TimeUnit.SECONDS) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(new Consumer() { + @Override + public void accept(Long aLong) throws Throwable { +// Log.e(TAG, "accept: " + aLong); + PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE); + boolean isScreenOn = pm.isScreenOn(); + if (!isScreenOn) { + return; + } + checkForegroundAppName(); + } + }); + } + + /** + * 检查前台app + */ + private void checkForegroundAppName() { + String topPackage = getTopActivityInfo(); + Log.e(TAG, "checkForegroundAppName: topPackage = " + topPackage); + String appPackageName = getAppPackageName(); + Log.d(TAG, "checkForegroundAppName: appPackageName = " + appPackageName); + if (allowPackage.contains(topPackage)) { + if (!TextUtils.isEmpty(appPackageName)) { + if (!topPackage.equals(appPackageName)) { + NetInterfaceManager.getInstance().sendCloseApp(appPackageName, new NetInterfaceManager.onCompleteCallback() { + @Override + public void onComplete() { + Log.e(TAG, "onComplete: "); + NetInterfaceManager.getInstance().getSnTimeControl(); + NetInterfaceManager.getInstance().getAppTimeControl(); + } + }); + } + } + mMMKV.encode(RUNNING_APP_PACKAGENAME, ""); + Log.d(TAG, "checkForegroundAppName: allow: " + topPackage); + return; + } + if (TextUtils.isEmpty(appPackageName)) { + recordPackageOpenTime(topPackage); + return; + } + long onClickTime = getOnClickTime(); + Log.e(TAG, "checkForegroundAppName: getAppPackageName = " + appPackageName); + if (appPackageName.equals(topPackage)) { + Log.e(TAG, "checkForegroundAppName: 没有切换应用"); + if (RunningAppManager.getInstance().inControlTime(appPackageName)) { + removeTask(topPackage); + gotoLauncher(); + } else { + Log.e(TAG, "checkForegroundAppName: 没有管控"); + reduceAppRemainingTime(topPackage, 1); + } + } else { + Log.e(TAG, "checkForegroundAppName: 切换应用:" + topPackage); + NetInterfaceManager.getInstance().sendCloseApp(appPackageName, new NetInterfaceManager.onCompleteCallback() { + @Override + public void onComplete() { + NetInterfaceManager.getInstance().getSnTimeControl(); + NetInterfaceManager.getInstance().getAppTimeControl(); + } + }); + reduceAppRemainingTime(topPackage, 1); + appPackageName = topPackage; + onClickTime = System.currentTimeMillis() / 1000; + if (RunningAppManager.getInstance().inControlTime(appPackageName)) { + Log.e(TAG, "checkForegroundAppName: 没有剩余时间2"); + removeTask(topPackage); + gotoLauncher(); + } else { + RunningAppManager.getInstance().recordPackageOpenTime(topPackage); + Log.e(TAG, "checkForegroundAppName: 没有管控2"); + } + } + saveAppRemainingTime(); + } + + private TimeChangedReceiver mTimeChangedReceiver; + + /** + * 监听时间和日期变化 + */ + private void registerTimeReceiver(Context context) { + mTimeChangedReceiver = new TimeChangedReceiver(); + IntentFilter filter = new IntentFilter(); + filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY); + filter.addAction(Intent.ACTION_DATE_CHANGED); + filter.addAction(Intent.ACTION_TIME_CHANGED); + filter.addAction(Intent.ACTION_TIMEZONE_CHANGED); + filter.addAction(Intent.ACTION_TIME_TICK); + context.registerReceiver(mTimeChangedReceiver, filter); + } + + @SuppressLint("SimpleDateFormat") + private SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss"); + + private class TimeChangedReceiver extends BroadcastReceiver { + @Override + public void onReceive(Context context, Intent intent) { + String action = intent.getAction(); + Log.e(TAG, "TimeChangedReceiver:" + action); + long time = System.currentTimeMillis(); + String finaWayDate = sdf.format(time); + if ("00:00:00".equals(finaWayDate)) { + mMMKV.encode(RemainingTimeMap, ""); + mMMKV.encode(GlobalUsageTimeMap, ""); + mRemainingTimeMap.clear(); + mGlobalUsageTime.clear(); + } + } + } + + public void killBackgroundProcesses(String processName) { +// gotoLauncher(); + // mIsScanning = true; + removeTask(processName); + ActivityManager activityManager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE); + String packageName = null; + try { + if (processName.indexOf(":") == -1) { + packageName = processName; + } else { + packageName = processName.split(":")[0]; + } + activityManager.killBackgroundProcesses(packageName); + // + Method forceStopPackage = activityManager.getClass() + .getDeclaredMethod("forceStopPackage", String.class); + forceStopPackage.setAccessible(true); + forceStopPackage.invoke(activityManager, packageName); + } catch (Exception e) { + e.printStackTrace(); + } + } + + /** + * 清除所有最近记录 + */ + public void removeAllTask(Context context) { + List list = getRecentTasks(ActivityManager.getMaxRecentTasksStatic(), getCurrentUserId()); + + for (ActivityManager.RecentTaskInfo info : list) { + if (info.realActivity != null) { + Log.e(TAG, "removeAllTask: " + info.realActivity.getPackageName()); + //排除自身 + if (BuildConfig.APPLICATION_ID.equals(info.realActivity.getPackageName())) { + continue; + } + } + try { + ActivityManagerNative.getDefault().removeTask(info.id); + } catch (RemoteException e) { + e.printStackTrace(); + Log.e(TAG, "removeAllTask: " + e.getMessage()); + } + } + } + + public void removeTask(String packageName) { + List list = getRecentTasks(ActivityManager.getMaxRecentTasksStatic(), getCurrentUserId()); + HashMap taskMap = new HashMap<>(); + for (ActivityManager.RecentTaskInfo info : list) { + taskMap.put(info.realActivity.getPackageName(), info.id); + } + try { + ActivityManagerNative.getDefault().removeTask(taskMap.get(packageName)); + } catch (RemoteException e) { + e.printStackTrace(); + Log.e(TAG, "removeTask: " + e.getMessage()); + } catch (NullPointerException e) { + Log.e(TAG, "removeTask: " + e.getMessage()); + } + } + + /** + * 如果界面正在最近任务列表,有些app可能不会被清理 + */ + private void gotoLauncher() { + Intent i = new Intent(Intent.ACTION_MAIN); + i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); //android123提示如果是服务里调用,必须加入new task标识 + i.addCategory(Intent.CATEGORY_HOME); + mContext.startActivity(i); + } + + + /** + * @return a list of the recents tasks. + * 获取近期任务列表 + */ + public List getRecentTasks(int numTasks, int userId) { + try { + return ActivityTaskManager.getService().getRecentTasks(numTasks, + RECENT_IGNORE_UNAVAILABLE, userId).getList(); + } catch (RemoteException e) { + Log.e(TAG, "Failed to get recent tasks " + e); + return new ArrayList<>(); + } + } + + /** + * @return the current user's id. + * 获取userId + */ + @RequiresApi(api = 30) + public int getCurrentUserId() { + UserInfo ui; + try { + ui = ActivityManager.getService().getCurrentUser(); + return ui != null ? ui.id : 0; + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + //缓存正在运行包名 + private static final String RUNNING_APP_PACKAGENAME = "running_app_package_name"; + //缓存app运行时间 + private static final String RUNNING_APP_RUN_TIME = "running_app_run_time"; + //缓存app起始运行时间 + private static final String RUNNING_APP_ONCLICK_TIME = "running_app_on_click_time"; + + /** + * 同时在前台运行的就只有一个 + * + * @param packageName + */ + public void recordPackageOpenTime(String packageName) { + mMMKV.encode(RUNNING_APP_PACKAGENAME, packageName); + mMMKV.encode(RUNNING_APP_ONCLICK_TIME, System.currentTimeMillis() / 1000); + } + + public String getAppPackageName() { + String packageName = mMMKV.decodeString(RUNNING_APP_PACKAGENAME, ""); + return packageName; + } + + public long getOnClickTime() { + long onClickTime = mMMKV.decodeLong(RUNNING_APP_ONCLICK_TIME, 0L); + return onClickTime; + } + + public void setAppRunTime(long time) { + mMMKV.encode(RUNNING_APP_RUN_TIME, time); + } + + public long getAppRunTime() { + long appRunTime = mMMKV.decodeLong(RUNNING_APP_RUN_TIME, 0L); + return appRunTime; + } + + public void setGlobalUsageTime(long time) { + this.globalRemainingTime = time; + } + + /** + * 同步剩余时间 + * + * @param appTimeControls + */ + public void syncAppRemainingTime(List appTimeControls) { + mRemainingTimeMap.clear(); + for (AppTimeControl appTimeControl : appTimeControls) { +// if (appTimeControl.getTc_use_type() != 3) { +// continue; +// } + AppRunTimeBean appRunTimeBean = new AppRunTimeBean(appTimeControl.getApp_package()); + appRunTimeBean.setAppRunTime(appTimeControl.getToday_time()); + mRemainingTimeMap.put(appTimeControl.getApp_package(), appRunTimeBean); + } + Log.e(TAG, "syncAppRemainingTime: Finish" + mRemainingTimeMap); + } + + /** + * 保存剩余时间到缓存 + */ + public void saveAppRemainingTime() { + String jsonString = GsonUtils.toJSONString(mRemainingTimeMap); + mMMKV.encode(RemainingTimeMap, jsonString); + String timeString = GsonUtils.toJSONString(mGlobalUsageTime); + mMMKV.encode(GlobalUsageTimeMap, timeString); + } + + private long getAppTodayRunTime(String pkg) { + AppInformation appInformation = getInfoFromPackageName(mContext, pkg); + if (appInformation == null) { + return 0; + } else { + return appInformation.getUsedTimebyDay() / 1000; + } + } + + public static AppInformation getInfoFromPackageName(Context context, String packageName) { + List list; + AppInformation app = null; + StatisticsInfo statisticsInfo = new StatisticsInfo(context); + list = statisticsInfo.getShowList(); + for (AppInformation appInformation : list) { + String name = appInformation.getPackageName(); + if (appInformation.getPackageName().equals(packageName)) { + return appInformation; + } + } + return app; + } + + /** + * 获取剩余时间 + * + * @param pkg + * @return + */ + public long getAppRemainingTime(String pkg) { + AppRunTimeBean timeBean = mRemainingTimeMap.get(pkg); + if (timeBean == null) { + return 0; + } else { + return timeBean.getAppRunTime(); + } + } + + /** + * 减少剩余时间 + * + * @param pkg + * @param time + */ + public void reduceAppRemainingTime(String pkg, long time) { + if (allowPackage.contains(pkg)) { + return; + } + int isControl = Settings.System.getInt(mContext.getContentResolver(), CommonConfig.KEY_IS_CONTROL, 1); + Log.e(TAG, "reduceAppRemainingTime: isControl = " + isControl); + //家长管控关闭始终可用 + if (isControl == 0) { + return; + } + boolean havaConfigure = TimeControlManager.getInstance().havaConfigure(pkg); + MachineControl machineControl = TimeControlManager.getInstance().getGlobalMachineControl(); + if (havaConfigure) { + AppTimeControl appTimeControl = TimeControlManager.getInstance().getAppTimeControl(pkg); + if (appTimeControl.getTc_use_type() == 2) { + AppUsageTime appUsageTime; + if (mGlobalUsageTime.get(pkg) == null) { + appUsageTime = new AppUsageTime(); + appUsageTime.setPkg(pkg); + appUsageTime.setUsageTime(1); + } else { + appUsageTime = mGlobalUsageTime.get(pkg); + appUsageTime.setUsageTime(appUsageTime.getUsageTime() + 1); + } + mGlobalUsageTime.put(pkg, appUsageTime); + } else { + mGlobalUsageTime.remove(pkg); + } + Log.e(TAG, "reduceAppRemainingTime: " + appTimeControl.getToday_time()); + long remainingTime = appTimeControl.getToday_time() - time; + if (remainingTime < 0) { + remainingTime = 0; + } + AppRunTimeBean timeBean = mRemainingTimeMap.get(pkg); + timeBean.setAppRunTime(remainingTime); + mRemainingTimeMap.put(pkg, timeBean); + appTimeControl.setToday_time(remainingTime); + TimeControlManager.getInstance().setAppTimeControl(pkg, appTimeControl); + } else { + Log.e(TAG, "reduceAppRemainingTime: " + machineControl.getToday_time()); + long remainingTime = machineControl.getToday_time() - time; + if (remainingTime < 0) { + remainingTime = 0; + } + machineControl.setToday_time(remainingTime); + TimeControlManager.getInstance().setGlobalMachineControl(machineControl); + } + } + + public HashSet allowPackage = new HashSet() {{ + this.add("com.android.launcher3"); + this.add("com.android.packageinstaller"); + this.add("com.android.systemui"); + this.add("com.android.settings"); + this.add("com.android.permissioncontroller"); + + this.add("com.uiui.sn"); + this.add("com.uiui.os"); + this.add("com.uiui.store"); + this.add("com.uiui.info"); + this.add("com.tt.ttutils"); + this.add(JGYUtils.fuxiaoying); + }}; + + /** + * 可用返回false,不可用返回true + * + * @param pkg + * @return + */ + public boolean inControlTime(String pkg) { + if (allowPackage.contains(pkg)) { + return false; + } + Log.e(TAG, "inControlTime: pkg = " + pkg); + int isControl = Settings.System.getInt(mContext.getContentResolver(), CommonConfig.KEY_IS_CONTROL, 1); + Log.e(TAG, "inControlTime: isControl = " + isControl); + //家长管控关闭始终可用 + if (isControl == 0) { + return false; + } + + boolean havaConfigure = TimeControlManager.getInstance().havaConfigure(pkg); + MachineControl machineControl = TimeControlManager.getInstance().getGlobalMachineControl(); + if (havaConfigure) { + //有单独设置 不管是分类整机还是其他都是这个设置 + AppTimeControl appTimeControl = TimeControlManager.getInstance().getAppTimeControl(pkg); + if (appTimeControl.getIs_control() == 0) { + ToastUtil.show("应用已被禁用"); + return true; + } + if (appTimeControl.getTc_use_type() == 0) { + return false; + } + //打开时间段管控 + if (appTimeControl.getIs_part() == 1) { + boolean inControlTime = inControlTime(machineControl, appTimeControl); + //判断是否在时间段内 + if (inControlTime) { + Log.e(TAG, "inControlTime: " + "应用在管控时间段不能打开" + appTimeControl.time_part.toString()); + ToastUtil.show("该应用" + partTime2String(appTimeControl)); + return true; + } else { + if (appTimeControl.getIs_quota() == 0) { + //要求设置了管控时间段没有设置使用额度也可以使用 + return false; + } + if (getAppRemainingTime(pkg) <= 0) { + //没有剩余时间 + ToastUtil.show("该应用今日可使用时间已用完"); + return true; + } else { + return false; + } + } + } else { + if (appTimeControl.getIs_quota() == 0) { + ToastUtil.show("没有使用额度"); + return true; + } + if (getAppRemainingTime(pkg) <= 0) { + //没有剩余时间 + ToastUtil.show("该应用今日可使用时间已用完"); + return true; + } else { + return false; + } + } + } else { + //根据整机 + if (machineControl == null) { + return false; + } + if (machineControl.is_quota == 1) { + if (haveUseTime(machineControl.getWork_time(), machineControl.getRest_time(), machineControl.getToday_time())) { + return false; + } else { + boolean inControlTime = inControlTime(machineControl); + if (inControlTime) { + Log.e(TAG, "inControlTime: " + "应用在管控时间段不能打开" + machineControl.time_part.toString()); + ToastUtil.show("该应用" + partTime2String(machineControl)); + } + return inControlTime; + } + } else { + //关闭整机额度开关 始终可用 + return false; + } + } + } + + private String partTime2String(AppTimeControl appTimeControl) { + List partTimes = appTimeControl.getTime_part(); + if (partTimes == null || partTimes.size() == 0) { + return "没有设置管控时段"; + } + StringBuilder stringBuilder = new StringBuilder(); + for (PartTime partTime : partTimes) { + if (getDayType() != partTime.getDay_type()) { + continue; + } + if (stringBuilder.length() == 0) { + if (appTimeControl.getPart_type() == 1) { + stringBuilder.append("仅限"); + } + } else { + stringBuilder.append(";"); + } + stringBuilder.append(partTime.getStart_time()) + .append("-").append(partTime.getEnd_time()); + } + if (appTimeControl.getPart_type() == 1) { + stringBuilder.append("使用"); + } else if (appTimeControl.getPart_type() == 0) { + stringBuilder.append("禁止使用"); + } + return stringBuilder.toString(); + } + + private String partTime2String(MachineControl machineControl) { + List partTimes = machineControl.getTime_part(); + if (partTimes == null || partTimes.size() == 0) { + return "没有设置管控时段"; + } + StringBuilder stringBuilder = new StringBuilder(); + for (PartTime partTime : partTimes) { + if (stringBuilder.length() > 0) { + stringBuilder.append(";"); + } + stringBuilder.append(partTime.getStart_time()) + .append("-").append(partTime.getEnd_time()); + if (machineControl.getPart_type() == 1) { + stringBuilder.append("可以使用"); + } else if (machineControl.getPart_type() == 0) { + stringBuilder.append("禁止使用"); + } + } + return stringBuilder.toString(); + } + + + public String getDisableContent(String pkg) { + RemainTime remainTime = new RemainTime(); + remainTime.setPkg(pkg); +// if (allowPackage.contains(pkg)) { +// return ""; +// } +// Log.e(TAG, "inControlTime: pkg = " + pkg); +// int is_control = Settings.System.getInt(mContext.getContentResolver(), CommonConfig.KEY_IS_CONTROL, 1); +// Log.e(TAG, "inControlTime: is_control = " + is_control); + //家长管控关闭始终可用 +// if (is_control == 0) { +// return ""; +// } + boolean havaConfigure = TimeControlManager.getInstance().havaConfigure(pkg); + MachineControl machineControl = TimeControlManager.getInstance().getGlobalMachineControl(); + if (havaConfigure) { + //有单独设置 不管是分类整机还是其他都是这个设置 + AppTimeControl appTimeControl = TimeControlManager.getInstance().getAppTimeControl(pkg); + if (appTimeControl.getIs_control() == 0) { + remainTime.setDisableType(1); + remainTime.setContent("应用已被禁用"); + return remainTime.toString(); + } +// if (appTimeControl.getTc_use_type() == 0) { +// return ""; +// } + //打开时间段管控 + if (appTimeControl.getIs_part() == 1) { + boolean inControlTime = inControlTime(machineControl, appTimeControl); + //判断是否在时间段内 + if (inControlTime) { + remainTime.setDisableType(3); + remainTime.setContent("该应用" + partTime2String(appTimeControl)); + return remainTime.toString(); + } else { +// if (appTimeControl.getIs_quota() == 0) { +// //要求设置了管控时间段没有设置使用额度也可以使用 +// return ""; +// } + if (getAppRemainingTime(pkg) <= 0) { + //没有剩余时间 + if (inWeekDay()) { + remainTime.setAvailableTime(appTimeControl.getWork_time()); + } else { + remainTime.setAvailableTime(appTimeControl.getRest_time()); + } + remainTime.setContent("该应用今日可使用时间已用完"); + //分类没有时间 + if (appTimeControl.getTc_use_type() == 1) { + remainTime.setDisableType(5); + remainTime.setAppUsageTimes(getAppClassificationTime(appTimeControl.getTc_class_id())); + } else if (appTimeControl.getTc_use_type() == 2) { + remainTime.setDisableType(4); + remainTime.setAppUsageTimes(getMachineTime()); + } else { + remainTime.setDisableType(2); + } + return remainTime.toString(); + } else { + return ""; + } + } + } else { +// if (appTimeControl.getIs_quota() == 0) { +// return "没有使用额度"; +// } + if (getAppRemainingTime(pkg) <= 0) { + //没有剩余时间 + if (appTimeControl.getTc_use_type() == 1) { + remainTime.setDisableType(5); + remainTime.setAppUsageTimes(getAppClassificationTime(appTimeControl.getTc_class_id())); + } else if (appTimeControl.getTc_use_type() == 2) { + remainTime.setDisableType(4); + remainTime.setAppUsageTimes(getMachineTime()); + } else { + remainTime.setDisableType(2); + } + remainTime.setContent("该应用今日可使用时间已用完"); + return remainTime.toString(); + } + return ""; + } + } else { + //根据整机 + if (machineControl == null) { + return ""; + } + if (machineControl.is_quota == 1) { + if (haveUseTime(machineControl.getWork_time(), machineControl.getRest_time(), machineControl.getToday_time())) { + return ""; + } else { + boolean inControlTime = inControlTime(machineControl); + if (inControlTime) { + remainTime.setDisableType(3); + remainTime.setContent("该应用" + partTime2String(machineControl)); + return remainTime.toString(); + } else { + return ""; + } + } + } else { + //关闭整机额度开关 始终可用 + return ""; + } + } + } + + private List getAppClassificationTime(int id) { + List appUsageTimes = new ArrayList<>(); + TimeControlManager.getInstance().getAppTimeControlMap().entrySet().stream().forEach((entry) -> { + if (entry.getValue().getTc_class_id() == id) { + String pkg = entry.getKey(); + if (TextUtils.isEmpty(pkg)) { + return; + } + AppUsageTime appUsageTime = new AppUsageTime(); + appUsageTime.setPkg(pkg); + AppRunTimeBean appRunTimeBean = mRemainingTimeMap.get(pkg); + long usageTime = appRunTimeBean.getAppRunTime(); + long time; + if (inWeekDay()) { + time = entry.getValue().getWork_time() - usageTime; + } else { + time = entry.getValue().getRest_time() - usageTime; + } + appUsageTime.setUsageTime(time); + if (time > 0) { + appUsageTimes.add(appUsageTime); + } + } + }); + return appUsageTimes; + } + + private List getMachineTime() { + List appUsageTimes = new ArrayList<>(); + if (mGlobalUsageTime == null) { + return appUsageTimes; + } + mGlobalUsageTime.entrySet().stream().forEach((entry) -> { + if (entry.getValue().getUsageTime() > 0) { + appUsageTimes.add(entry.getValue()); + } + }); + return appUsageTimes; + } + + private boolean haveUseTime(long workTime, long restTime, long todayTime) { + //不用去管工作日还是休息日,后台返回的就是剩余时间 +// if (inWeekDay()) { +// return workTime - todayTime <= 0; +// } else { +// return restTime - todayTime <= 0; +// } + Log.e(TAG, "haveUseTime: " + globalRemainingTime); + return !(globalRemainingTime > 0); + } + + + /** + * 整机使用额度 + * + * @param machineControl + * @return + */ + public boolean inControlTime(MachineControl machineControl) { + //整机使用时段开关 开启时 + if (machineControl.getIs_part() == 1) { + int partType = machineControl.getPart_type(); + HashSet weekdayPart = machineControl.getTime_part().stream().filter(partTime -> partTime.getDay_type() == 0).collect(Collectors.toCollection(HashSet::new)); + HashSet holidayPart = machineControl.getTime_part().stream().filter(partTime -> partTime.getDay_type() == 1).collect(Collectors.toCollection(HashSet::new)); + //工作日 + if (inWeekDay()) { + return inControlTime(partType, weekdayPart); + } else {//休息日 + return inControlTime(partType, holidayPart); + } + } else { + return false; + } + } + + public boolean inControlTime(HashSet partTimeHashSet) { + //没有设置管控时段的情况 + if (partTimeHashSet == null || partTimeHashSet.size() == 0) { + return false; + } else { + for (PartTime partTime : partTimeHashSet) { + if (inControlTime(partTime)) { + return true; + } + } + return false; + } + } + + /** + * 通过tc_use_type判断配置 + * + * @param machineControl + * @param appTimeControl + * @return + */ + public boolean inControlTime(MachineControl machineControl, AppTimeControl appTimeControl) { + //使用控制方式 0始终可用 1分类 2整机 3自由 + switch (appTimeControl.getTc_use_type()) { + case 0: + return false; + case 1: + case 3: + return isControlTime(appTimeControl); + case 2: + return inControlTime(machineControl); + default: + return true; + } + } + + /** + * 是否在禁用时间段内 + * + * @param appTimeControl + * @return + */ + public boolean isControlTime(AppTimeControl appTimeControl) { + //整机使用时段开关 开启时 + if (appTimeControl.getIs_part() == 1) { + int partType = appTimeControl.getPart_type(); + HashMap> partTimeMap = new HashMap(); + HashSet weekdayPart = new HashSet(appTimeControl.getTime_part().stream().filter(partTime -> partTime.getDay_type() == 0).collect(Collectors.toList())); + HashSet holidayPart = new HashSet(appTimeControl.getTime_part().stream().filter(partTime -> partTime.getDay_type() == 1).collect(Collectors.toList())); + partTimeMap.put(0, weekdayPart); + partTimeMap.put(1, holidayPart); + if (inWeekDay()) { + //工作日 + Set partTimeHashSet = partTimeMap.get(0); + //使用时间段-开放 + return inControlTime(partType, partTimeHashSet); + } else { + //休息日 + Set partTimeHashSet = partTimeMap.get(1); + return inControlTime(partType, partTimeHashSet); + } + } else { + if (inWeekDay()) { + //工作日 + + } else { + //休息日 + + } + //关闭的时候都可以运行 + return false; + } + } + + /** + * @param partType 使用时间段类型 0禁用 1开放 + * @param partTimeHashSet + * @return + */ + private boolean inControlTime(int partType, Set partTimeHashSet) { + if (partTimeHashSet != null) { + if (partType == 0) { + List inPartTimes = new ArrayList<>(); + for (PartTime partTime : partTimeHashSet) { + inPartTimes.add(inControlTime(partTime)); + } + //禁用时段需要满足所有 + return inPartTimes.indexOf(true) >= 0; + } else if (partType == 1) { + //开放时段只需要满足一个就行 + for (PartTime partTime : partTimeHashSet) { + if (inControlTime(partTime)) { + return false; + } + } + } + } + return true; + } + + private boolean inControlTime(PartTime partTime) { + String startTime = partTime.getStart_time(); + String endTime = partTime.getEnd_time(); + ContralTime contralTime = new ContralTime(startTime, endTime); + boolean inControlTime = contralTime.inControlTime(); + Log.e(TAG, "inControlTime: " + inControlTime); + return inControlTime; + } + + public static class ContralTime { + //format HH:mm + String startTime; + String endTime; + + public ContralTime() { + + } + + public ContralTime(String startT, String endT) { + this.startTime = startT; + this.endTime = endT; + } + + public String getStartTime() { + return startTime; + } + + + public void setStartTime(String startT) { + this.startTime = startT; + } + + public String getEndTime() { + return endTime; + } + + public void setEndTime(String endT) { + this.endTime = endT; + } + + public static DateFormat getDf() { + return dateFormat; + } + + public static void setDf(DateFormat d) { + dateFormat = d; + } + + public String getNowTimeString(long time) { + return dateFormat.format(new Date(time)); + } + + /*在时间段内返回 true,没有返回false*/ + public boolean inControlTime() { + long time = System.currentTimeMillis(); + return inControlTime(time); + } + + public boolean inControlTime(long time) { + return inControlTime(dateFormat.format(new Date(time))); + } + + public boolean inControlTime(String time) { + if (TextUtils.isEmpty(time)) { + throw new RuntimeException("Time is empty"); + } else { + if (!time.contains(":")) { + throw new RuntimeException("Time format error"); + } + } + try { + Date startDate = dateFormat.parse(startTime); + Date endDate = dateFormat.parse(endTime); + Date nowDate = dateFormat.parse(time); + if (startDate.getTime() > endDate.getTime()) { + //开始时间大于结束时间 列 16:00-01:00 + endDate.setTime(endDate.getTime() + dayTime); + } + Log.e(TAG, "inControlTime: " + (startDate.getTime() - minuteTime)); + assert nowDate != null; +// if (nowDate.getTime() <= startDate.getTime() - minuteTime || nowDate.getTime() >= endDate.getTime()) { + if (nowDate.getTime() >= startDate.getTime() && nowDate.getTime() <= endDate.getTime()) { + return true; + } else { + return false; + } + } catch (ParseException e) { + e.printStackTrace(); + } + return false; + } + + @NonNull + @Override + public String toString() { + return startTime + "\t-\t" + endTime; + } + } + + + /** + * 获取格式化后的时间 + * + * @param time 时间戳 + * @return 时间戳格式化文本 + */ + public String getDate(long time) { + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + String finaWayDate = sdf.format(time); + Log.e(TAG, "getDate: " + finaWayDate); + return finaWayDate; + } + + /** + * 获取周几 + * + * @return 周几的数字 + */ + public int getWeekDay() { + long time = System.currentTimeMillis(); + Log.e(TAG, "getWeekDay: " + time); + return getWeekDay(time); + } + + /** + * 获取周几 + * + * @param time 时间戳 + * @return 周几的数字 1-7 + */ + public int getWeekDay(long time) { + getDate(time); + Calendar now = Calendar.getInstance(); + now.setTimeInMillis(time); + //一周第一天是否为星期天 + boolean isFirstSunday = (now.getFirstDayOfWeek() == Calendar.SUNDAY); + //获取周几 + int weekDay = now.get(Calendar.DAY_OF_WEEK); + //若一周第一天为星期天,则-1 + if (isFirstSunday) { + weekDay = weekDay - 1; + if (weekDay == 0) { + weekDay = 7; + } + } + return weekDay; + } + + private String[] weekDays = {"星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期日"}; + + /** + * 获取星期几 + * + * @return 星期的文本 + */ + public String getWeekDayString() { + return weekDays[getWeekDay() - 1]; + } + + /** + * 获取星期几 + * + * @param time 时间戳 + * @return 星期的文本 + */ + public String getWeekDayString(long time) { + return weekDays[getWeekDay(time) - 1]; + } + + /** + * 是否未周末 + * + * @return 周末返回false 工作日返回true + */ + public boolean inWeekDay() { + long time = System.currentTimeMillis(); + return inWeekDay(time); + } + + public int getDayType() { + long time = System.currentTimeMillis(); + if (inWeekDay(time)) { + return 0; + } else { + return 1; + } + } + + /** + * 是否未周末 + * + * @param time 时间戳 + * @return 周末返回false 工作日返回true + */ + public boolean inWeekDay(long time) { + int weekDay = getWeekDay(time); + if (weekDay > 5) { + return false; + } else { + return true; + } + } + + public void checkTopAppPackageName() { + String topPackage = getTopActivityInfo(); + Log.e(TAG, "onReceive: " + topPackage); +// Log.e(TAG, "onReceive: getWeekDay: " + getWeekDay()); +// Log.e(TAG, "onReceive: getWeekDayString: " + getWeekDayString()); +// Log.e(TAG, "onReceive: inWeekDay: " + inWeekDay()); + } + + + private String getTopActivityInfo() { + ActivityManager manager = ((ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE)); + if (Build.VERSION.SDK_INT >= 21) { + List pis = manager.getRunningAppProcesses(); + ActivityManager.RunningAppProcessInfo topAppProcess = (ActivityManager.RunningAppProcessInfo) pis.get(0); + if (topAppProcess != null && topAppProcess.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND) { + return topAppProcess.processName; + + } + } else { +//getRunningTasks() is deprecated since API Level 21 (Android 5.0) + List localList = manager.getRunningTasks(1); + ActivityManager.RunningTaskInfo localRunningTaskInfo = (ActivityManager.RunningTaskInfo) localList.get(0); + return localRunningTaskInfo.topActivity.getPackageName(); + } + return ""; + } + + /** + * 获取栈顶的应用包名 + */ + public String getForegroundActivityName() { + String currentClassName = ""; + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { + ActivityManager manager = (ActivityManager) mContext.getApplicationContext().getSystemService(Context.ACTIVITY_SERVICE); + currentClassName = manager.getRunningTasks(1).get(0).topActivity.getPackageName(); + } else { + UsageStats initStat = getForegroundUsageStats(START_TIME, System.currentTimeMillis()); + if (initStat != null) { + currentClassName = initStat.getPackageName(); + } + } + Log.e(TAG, "getForegroundActivityName: " + currentClassName); + return currentClassName; + } + + /** + * 获取记录前台应用的UsageStats对象 + */ + private UsageStats getForegroundUsageStats(long startTime, long endTime) { + UsageStats usageStatsResult = null; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + List usageStatses = getUsageStatsList(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 UsageStats getCurrentUsageStats(long startTime, long endTime) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + List usageStatses = getUsageStatsList(startTime, endTime); + if (usageStatses == null || usageStatses.isEmpty()) { + return null; + } + for (UsageStats usageStats : usageStatses) { + if (TextUtils.equals(usageStats.getPackageName(), mContext.getPackageName())) { + return usageStats; + } + } + } + return null; + } + + /** + * 通过UsageStatsManager获取List集合 + */ + public List getUsageStatsList(long startTime, long endTime) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + UsageStatsManager manager = (UsageStatsManager) mContext.getApplicationContext().getSystemService(Context.USAGE_STATS_SERVICE); + //UsageStatsManager.INTERVAL_WEEKLY,UsageStatsManager的参数定义了5个,具体查阅源码 + List 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); + // TODO: 2022/6/27 每次都会弹出来 +// mContext.getApplicationContext().startActivity(intent); + return null; + } + return usageStatses; + } + return null; + } +} diff --git a/app/src/main/java/com/uiui/sn/desktop/TimeControlManager.java b/app/src/main/java/com/uiui/sn/desktop/TimeControlManager.java new file mode 100644 index 0000000..02124f1 --- /dev/null +++ b/app/src/main/java/com/uiui/sn/desktop/TimeControlManager.java @@ -0,0 +1,178 @@ +package com.uiui.sn.desktop; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.util.Log; + +import com.google.gson.Gson; +import com.google.gson.reflect.TypeToken; +import com.uiui.sn.disklrucache.CacheHelper; +import com.uiui.sn.network.UrlAddress; + +import java.lang.reflect.Type; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.stream.Collectors; + +public class TimeControlManager { + private static final String TAG = TimeControlManager.class.getSimpleName(); + + @SuppressLint("StaticFieldLeak") + private static TimeControlManager mTimeControlManager; + private Context mContext; + private CacheHelper mCacheHelper; + + private HashMap mClassifyTimeControlHashMap = new HashMap<>(); + /*分类的所有包名列表*/ + private HashMap mAppTimeControlMap = new HashMap<>(); + /*整机分类*/ + private MachineControl mGlobalMachineControl; + + private TimeControlManager(Context context) { + if (context == null) { + throw new RuntimeException("Context is NULL"); + } + this.mContext = context; + this.mCacheHelper = new CacheHelper(context); + } + + public static void init(Context context) { + if (mTimeControlManager == null) { + mTimeControlManager = new TimeControlManager(context); + } + } + + public static TimeControlManager getInstance() { + if (mTimeControlManager == null) { + throw new IllegalStateException("You must be init TimeControlManager first"); + } + return mTimeControlManager; + } + + public HashMap getAppTimeControlMap(){ + return mAppTimeControlMap; + } + + /** + * 判断是否有配置存在 + * + * @param pkg + * @return + */ + public boolean havaConfigure(String pkg) { + AppTimeControl appTimeControl = mAppTimeControlMap.get(pkg); + if (appTimeControl == null) { + Log.e(TAG, "havaConfigure: not"); + return false; + } else { + if (appTimeControl.getTc_use_type() == 1) { + Log.e(TAG, "havaConfigure: classify"); + return mClassifyTimeControlHashMap.get(appTimeControl.getTc_class_id()) != null; + } + Log.e(TAG, "havaConfigure: hava"); + return true; + } + } + + /** + * 获取整机配置 + * + * @return + */ + public MachineControl getGlobalMachineControl() { + Log.e(TAG, "getGlobalMachineControl: "); + if (mGlobalMachineControl == null) { + String jsonString = mCacheHelper.getAsString(UrlAddress.GET_SN_TIME_CONTROL); + //为 "" 是已经请求成功的 + if (jsonString == null) { + return null; + } else { + Gson gson = new Gson(); + Type Type = new TypeToken() { + }.getType(); + MachineControl machineControl = gson.fromJson(jsonString, Type); + return machineControl; + } + } else { + return mGlobalMachineControl; + } + } + + public void setGlobalMachineControl(MachineControl machineControl) { + this.mGlobalMachineControl = machineControl; + if (machineControl != null) { + RunningAppManager.getInstance().setGlobalUsageTime(machineControl.getRest_time()); + } + } + + /** + * 获取app的配置 + * + * @param pkg + * @return + */ + public AppTimeControl getAppTimeControl(String pkg) { + AppTimeControl temp = mAppTimeControlMap.get(pkg); + if (temp == null) { + String jsonString = mCacheHelper.getAsString(UrlAddress.GET_APP_TIME_CONTROL); + //为 "" 是已经请求成功的 + if (jsonString == null) { + return null; + } else { + Gson gson = new Gson(); + Type Type = new TypeToken>() { + }.getType(); + List appTimeControlList = gson.fromJson(jsonString, Type); + if (appTimeControlList == null) { + return null; + } + HashMap appTimeControlMap = new HashMap<>(); + for (AppTimeControl appTimeControl : appTimeControlList) { + appTimeControlMap.put(appTimeControl.getApp_package(), appTimeControl); + } + setAppTimeControlMap(appTimeControlList); + return appTimeControlMap.get(pkg); + } + } else { + return temp; + } + } + + public void setAppTimeControl(String pkg, AppTimeControl appTimeControl) { + this.mAppTimeControlMap.put(pkg, appTimeControl); + } + + + /** + * 设置app的配置 + * + * @param appTimeControlList + */ + public void setAppTimeControlMap(List appTimeControlList) { + if (appTimeControlList == null || appTimeControlList.size() == 0) { + return; + } + HashMap classifyTimeControlHashMap = new HashMap<>(); + List filterAppTimeControlList = appTimeControlList.stream().filter(appTimeControl -> { + //tc_use_type == 1 时用的是分类配置,配置都是一样的 + return appTimeControl.getTc_use_type() == 1; + }).collect(Collectors.toList()); + for (AppTimeControl appTimeControl : filterAppTimeControlList) { + classifyTimeControlHashMap.put(appTimeControl.getTc_class_id(), appTimeControl); + } + this.mClassifyTimeControlHashMap = classifyTimeControlHashMap; + + HashMap appTimeControlMap = new HashMap<>(); + List appTimeControls = new ArrayList<>(); + for (AppTimeControl appTimeControl : appTimeControlList) { + // TODO: 2022/6/30 修改为全部配置 +// if (appTimeControl.getTc_use_type() != 1) { + appTimeControlMap.put(appTimeControl.getApp_package(), appTimeControl); + appTimeControls.add(appTimeControl); +// } + } + RunningAppManager.getInstance().syncAppRemainingTime(appTimeControls); + this.mAppTimeControlMap = appTimeControlMap; + } +} diff --git a/app/src/main/java/com/uiui/sn/network/NetInterfaceManager.java b/app/src/main/java/com/uiui/sn/network/NetInterfaceManager.java index a4c85c3..8f65966 100644 --- a/app/src/main/java/com/uiui/sn/network/NetInterfaceManager.java +++ b/app/src/main/java/com/uiui/sn/network/NetInterfaceManager.java @@ -27,20 +27,22 @@ import com.trello.rxlifecycle4.android.ActivityEvent; import com.uiui.sn.BuildConfig; import com.uiui.sn.bean.AppInfo; import com.uiui.sn.bean.AppStart; -import com.uiui.sn.bean.AppTimeControl; +import com.uiui.sn.desktop.AppTimeControl; import com.uiui.sn.bean.AppUploadInfo; import com.uiui.sn.bean.AppletQRCode; import com.uiui.sn.bean.BaseResponse; import com.uiui.sn.bean.BatchID; import com.uiui.sn.bean.CloudLessonSetting; import com.uiui.sn.bean.Label; -import com.uiui.sn.bean.MachineControl; +import com.uiui.sn.desktop.MachineControl; import com.uiui.sn.bean.SnInfo; import com.uiui.sn.bean.SystemSettingsSet; import com.uiui.sn.bean.UserAvatarInfo; import com.uiui.sn.bean.browser.BrowserApiData; import com.uiui.sn.bean.browser.BrowserBean; import com.uiui.sn.config.CommonConfig; +import com.uiui.sn.desktop.RunningAppManager; +import com.uiui.sn.desktop.TimeControlManager; import com.uiui.sn.disklrucache.CacheHelper; import com.uiui.sn.gson.GsonUtils; import com.uiui.sn.manager.ConnectManager; @@ -49,6 +51,7 @@ import com.uiui.sn.manager.ControlManager; import com.uiui.sn.network.api.APPJump; import com.uiui.sn.network.api.AddAppInstall; import com.uiui.sn.network.api.AppTimeControlApi; +import com.uiui.sn.network.api.AppUsageRecordApi; import com.uiui.sn.network.api.BindDevices; import com.uiui.sn.network.api.Browser; import com.uiui.sn.network.api.BrowserLabel; @@ -136,7 +139,7 @@ public class NetInterfaceManager { private MMKV mMMKV = MMKV.defaultMMKV(); private Retrofit mRetrofit; private OkHttpClient okHttpClient; - private CacheHelper cacheHelper; + private CacheHelper mCacheHelper; private final ConcurrentHashMap requestIdsMap = new ConcurrentHashMap<>(); @@ -152,7 +155,7 @@ public class NetInterfaceManager { } this.mContext = context; this.crv = mContext.getContentResolver(); - this.cacheHelper = new CacheHelper(mContext); + this.mCacheHelper = new CacheHelper(mContext); if (null == mRetrofit) { if (okHttpClient == null) { @@ -442,6 +445,12 @@ public class NetInterfaceManager { .observeOn(AndroidSchedulers.mainThread()); } + public Observable getAppUsageRecordObservable(String pkg, String pkgName, Long open_time, Long close_time) { + return mRetrofit.create(AppUsageRecordApi.class) + .sendAppUsageRecord(Utils.getSerial(), pkg, pkgName, open_time, close_time) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()); + } /* * @@ -544,7 +553,7 @@ public class NetInterfaceManager { if (ConnectManager.getInstance().isNeedConnect(UrlAddress.SNINFO, connectMode)) { getSnInfo(lifecycle, callback); } else { - String jsonString = cacheHelper.getAsString(UrlAddress.SNINFO); + String jsonString = mCacheHelper.getAsString(UrlAddress.SNINFO); //为 "" 是已经请求成功的 if (jsonString == null) { getSnInfo(lifecycle, callback); @@ -574,7 +583,7 @@ public class NetInterfaceManager { Log.e("getSnInfo", "onNext: " + userInfoBaseResponse); SPUtils.put(mContext, CommonConfig.JGY_FIRST_CONNECT, 1); callback.onNext(userInfoBaseResponse); - cacheHelper.put(UrlAddress.SNINFO, GsonUtils.toJSONString(userInfoBaseResponse)); + mCacheHelper.put(UrlAddress.SNINFO, GsonUtils.toJSONString(userInfoBaseResponse)); int code = userInfoBaseResponse.code; if (userInfoBaseResponse.code == 200) { SPUtils.put(mContext, CommonConfig.isLogined, 1); @@ -592,10 +601,10 @@ public class NetInterfaceManager { SPUtils.put(mContext, "USERINFO_GRADE", snInfo.getGrade()); } } else if (code == 300) { - cacheHelper.put(UrlAddress.SNINFO, ""); + mCacheHelper.put(UrlAddress.SNINFO, ""); SPUtils.put(mContext, CommonConfig.isLogined, 0); } else if (code == 400) { - cacheHelper.put(UrlAddress.SNINFO, ""); + mCacheHelper.put(UrlAddress.SNINFO, ""); SPUtils.put(mContext, CommonConfig.isLogined, 2); } } @@ -629,7 +638,7 @@ public class NetInterfaceManager { if (ConnectManager.getInstance().isNeedConnect(UrlAddress.GET_BATCH, connectMode)) { setPushTags(lifecycle, callback); } else { - String jsonString = cacheHelper.getAsString(UrlAddress.GET_BATCH); + String jsonString = mCacheHelper.getAsString(UrlAddress.GET_BATCH); //为 "" 是已经请求成功的 if (jsonString == null) { setPushTags(lifecycle, callback); @@ -671,9 +680,9 @@ public class NetInterfaceManager { } else { Log.e("setPushTags", "onNext: " + "batch empty"); } - cacheHelper.put(UrlAddress.GET_BATCH, GsonUtils.toJSONString(response.data)); + mCacheHelper.put(UrlAddress.GET_BATCH, GsonUtils.toJSONString(response.data)); } else { - cacheHelper.put(UrlAddress.GET_BATCH, ""); + mCacheHelper.put(UrlAddress.GET_BATCH, ""); } mMMKV.encode(CommonConfig.DEVICES_TAG, set); } @@ -916,7 +925,7 @@ public class NetInterfaceManager { if (ConnectManager.getInstance().isNeedConnect(UrlAddress.GET_NEWESTAPPUPDATE, connectMode)) { checkAllAppUpdate(lifecycle, callback); } else { - String jsonString = cacheHelper.getAsString(UrlAddress.GET_NEWESTAPPUPDATE); + String jsonString = mCacheHelper.getAsString(UrlAddress.GET_NEWESTAPPUPDATE); //为 "" 是已经请求成功的 if (jsonString == null) { checkAllAppUpdate(lifecycle, callback); @@ -969,7 +978,7 @@ public class NetInterfaceManager { @Override public void onNext(@NonNull List appInfos) { Log.e("checkAllAppUpdate", "onNext: " + appInfos); - cacheHelper.put(UrlAddress.GET_NEWESTAPPUPDATE, GsonUtils.toJSONString(appInfos)); + mCacheHelper.put(UrlAddress.GET_NEWESTAPPUPDATE, GsonUtils.toJSONString(appInfos)); getAllAppUpdate(appInfos); } @@ -995,7 +1004,7 @@ public class NetInterfaceManager { if (ConnectManager.getInstance().isNeedConnect(JGYUtils.FUXIAOYING_KEY, connectMode)) { checkFXYAppUpdate(lifecycle, callback); } else { - String jsonString = cacheHelper.getAsString(JGYUtils.FUXIAOYING_KEY); + String jsonString = mCacheHelper.getAsString(JGYUtils.FUXIAOYING_KEY); //为 "" 是已经请求成功的 if (jsonString == null) { checkFXYAppUpdate(lifecycle, callback); @@ -1056,7 +1065,7 @@ public class NetInterfaceManager { @Override public void onNext(@NonNull List appInfos) { Log.e("checkFXYAppUpdate", "onNext: " + appInfos); - cacheHelper.put(JGYUtils.FUXIAOYING_KEY, GsonUtils.toJSONString(appInfos)); + mCacheHelper.put(JGYUtils.FUXIAOYING_KEY, GsonUtils.toJSONString(appInfos)); getAllAppUpdate(appInfos); } @@ -1136,7 +1145,7 @@ public class NetInterfaceManager { if (ConnectManager.getInstance().isNeedConnect(UrlAddress.GET_CLOUD_LESSON_SETTING, connectMode)) { getCloudLessonSetting(lifecycle, callback); } else { - String jsonString = cacheHelper.getAsString(UrlAddress.GET_CLOUD_LESSON_SETTING); + String jsonString = mCacheHelper.getAsString(UrlAddress.GET_CLOUD_LESSON_SETTING); //为 "" 是已经请求成功的 if (jsonString == null) { getCloudLessonSetting(lifecycle, callback); @@ -1185,7 +1194,7 @@ public class NetInterfaceManager { if (ConnectManager.getInstance().isNeedConnect(UrlAddress.GET_APPLET_QRCODE, connectMode)) { getQRCodeURL(lifecycle, callback); } else { - String jsonString = cacheHelper.getAsString(UrlAddress.GET_APPLET_QRCODE); + String jsonString = mCacheHelper.getAsString(UrlAddress.GET_APPLET_QRCODE); //为 "" 是已经请求成功的 if (jsonString == null) { getQRCodeURL(lifecycle, callback); @@ -1217,11 +1226,11 @@ public class NetInterfaceManager { Log.e("getQRCodeURL", "onNext: "); if (baseResponse.code == 200) { AppletQRCode appletQRCode = baseResponse.data; - cacheHelper.put(UrlAddress.GET_APPLET_QRCODE, GsonUtils.toJSONString(appletQRCode)); + mCacheHelper.put(UrlAddress.GET_APPLET_QRCODE, GsonUtils.toJSONString(appletQRCode)); String url = appletQRCode.getFile(); callback.onNext(url); } else { - cacheHelper.put(UrlAddress.GET_APPLET_QRCODE, ""); + mCacheHelper.put(UrlAddress.GET_APPLET_QRCODE, ""); callback.onNext(""); } } @@ -1858,7 +1867,7 @@ public class NetInterfaceManager { if (ConnectManager.getInstance().isNeedConnect(UrlAddress.GET_FORCE_INSTALL, connectMode)) { getForceInstall(lifecycle, callback); } else { - String jsonString = cacheHelper.getAsString(UrlAddress.GET_FORCE_INSTALL); + String jsonString = mCacheHelper.getAsString(UrlAddress.GET_FORCE_INSTALL); //为 "" 是已经请求成功的 if (jsonString == null) { getForceInstall(lifecycle, callback); @@ -1901,13 +1910,13 @@ public class NetInterfaceManager { int code = listBaseResponse.code; if (code == 200) { List appInfos = listBaseResponse.data; - cacheHelper.put(UrlAddress.GET_FORCE_INSTALL, GsonUtils.toJSONString(appInfos)); + mCacheHelper.put(UrlAddress.GET_FORCE_INSTALL, GsonUtils.toJSONString(appInfos)); if (null != appInfos && appInfos.size() != 0) { getForceInstallState(appInfos); } // JGYUtils.getInstance().deleteOtherApp(); } else { - cacheHelper.put(UrlAddress.GET_FORCE_INSTALL, ""); + mCacheHelper.put(UrlAddress.GET_FORCE_INSTALL, ""); boolean aole_force_app = Settings.System.putString(crv, CommonConfig.AOLE_ACTION_FORCE_APP, ""); Log.e(TAG, "aole_force_app:" + aole_force_app + ":" + ""); } @@ -1982,10 +1991,10 @@ public class NetInterfaceManager { String data = new Gson().toJson(BaseResponse.data.getAdmin()); Log.e("getSystemSettings", "onNext: " + data); ControlManager.getInstance().setSystemSetting(data); - cacheHelper.put(UrlAddress.GET_SETTINGS, GsonUtils.toJSONString(BaseResponse.data.getAdmin())); + mCacheHelper.put(UrlAddress.GET_SETTINGS, GsonUtils.toJSONString(BaseResponse.data.getAdmin())); } else { ControlManager.getInstance().setDisableSetting(); - cacheHelper.put(UrlAddress.GET_SETTINGS, ""); + mCacheHelper.put(UrlAddress.GET_SETTINGS, ""); } } @@ -2003,7 +2012,7 @@ public class NetInterfaceManager { } public String getSystemSettingsJson() { - return cacheHelper.getAsString(UrlAddress.GET_SETTINGS); + return mCacheHelper.getAsString(UrlAddress.GET_SETTINGS); } public void getTimeControl() { @@ -2210,6 +2219,9 @@ public class NetInterfaceManager { }); } + public static final String APP_TIME_CONTROL_UPDATE = "APP_TIME_CONTROL_UPDATE"; + public static final String SN_TIME_CONTROL_UPDATE = "SN_TIME_CONTROL_UPDATE"; + public void getAppTimeControl(boolean refresh, BehaviorSubject lifecycle, onCompleteCallback callback) { ConnectMode connectMode = ConnectMode.ONE_MINUTE; if (refresh) { @@ -2218,7 +2230,7 @@ public class NetInterfaceManager { if (ConnectManager.getInstance().isNeedConnect(UrlAddress.GET_APP_TIME_CONTROL, connectMode)) { getAppTimeControl(lifecycle, callback); } else { - String jsonString = cacheHelper.getAsString(UrlAddress.GET_APP_TIME_CONTROL); + String jsonString = mCacheHelper.getAsString(UrlAddress.GET_APP_TIME_CONTROL); //为 "" 是已经请求成功的 if (jsonString == null) { getAppTimeControl(lifecycle, callback); @@ -2233,7 +2245,7 @@ public class NetInterfaceManager { } public String getAppTimeControlJson() { - return cacheHelper.getAsString(UrlAddress.GET_APP_TIME_CONTROL); + return mCacheHelper.getAsString(UrlAddress.GET_APP_TIME_CONTROL); } public void getAppTimeControl(BehaviorSubject lifecycle, onCompleteCallback callback) { @@ -2261,13 +2273,22 @@ public class NetInterfaceManager { @Override public void onNext(@NonNull BaseResponse> listBaseResponse) { - Log.e("getAppTimeControlObserver", "onNext: "); + Log.e("getAppTimeControlObserver", "onNext: " + listBaseResponse); if (listBaseResponse.code == 200) { List appTimeControls = listBaseResponse.data; - cacheHelper.put(UrlAddress.GET_APP_TIME_CONTROL, GsonUtils.toJSONString(appTimeControls)); + // TODO: 2022/6/21 后台没数据时也返回200 + if (appTimeControls == null || appTimeControls.size() == 0) { + mCacheHelper.put(UrlAddress.GET_APP_TIME_CONTROL, ""); + } else { + TimeControlManager.getInstance().setAppTimeControlMap(appTimeControls); + mCacheHelper.put(UrlAddress.GET_APP_TIME_CONTROL, GsonUtils.toJSONString(appTimeControls)); + } } else { - cacheHelper.put(UrlAddress.GET_APP_TIME_CONTROL, ""); + mCacheHelper.put(UrlAddress.GET_APP_TIME_CONTROL, ""); } + Intent intent = new Intent(APP_TIME_CONTROL_UPDATE); + intent.putExtra("jsonString", GsonUtils.toJSONString(listBaseResponse.data)); + mContext.sendBroadcast(intent); } @Override @@ -2295,7 +2316,7 @@ public class NetInterfaceManager { if (ConnectManager.getInstance().isNeedConnect(UrlAddress.GET_SN_TIME_CONTROL, connectMode)) { getSnTimeControl(lifecycle, callback); } else { - String jsonString = cacheHelper.getAsString(UrlAddress.GET_SN_TIME_CONTROL); + String jsonString = mCacheHelper.getAsString(UrlAddress.GET_SN_TIME_CONTROL); //为 "" 是已经请求成功的 if (jsonString == null) { getSnTimeControl(lifecycle, callback); @@ -2310,7 +2331,7 @@ public class NetInterfaceManager { } public String getSnTimeControllJson() { - return cacheHelper.getAsString(UrlAddress.GET_SN_TIME_CONTROL); + return mCacheHelper.getAsString(UrlAddress.GET_SN_TIME_CONTROL); } public void getSnTimeControl(BehaviorSubject lifecycle, onCompleteCallback callback) { @@ -2341,10 +2362,14 @@ public class NetInterfaceManager { Log.e("getSnTimeControlObserver", "onNext: "); if (machineControlBaseResponse.code == 200) { MachineControl machineControl = machineControlBaseResponse.data; - cacheHelper.put(UrlAddress.GET_SN_TIME_CONTROL, GsonUtils.toJSONString(machineControl)); + TimeControlManager.getInstance().setGlobalMachineControl(machineControl); + mCacheHelper.put(UrlAddress.GET_SN_TIME_CONTROL, GsonUtils.toJSONString(machineControl)); } else { - cacheHelper.put(UrlAddress.GET_SN_TIME_CONTROL, ""); + mCacheHelper.put(UrlAddress.GET_SN_TIME_CONTROL, ""); } + Intent intent = new Intent(SN_TIME_CONTROL_UPDATE); + intent.putExtra("jsonString", GsonUtils.toJSONString(machineControlBaseResponse.data)); + mContext.sendBroadcast(intent); } @Override @@ -2363,4 +2388,44 @@ public class NetInterfaceManager { }; } + public void sendCloseApp(String packageName, onCompleteCallback completeCallback) { + PackageManager pm = mContext.getPackageManager(); + PackageInfo appInfo = null; + try { + appInfo = pm.getPackageInfo(packageName, 0); + } catch (PackageManager.NameNotFoundException e) { + e.printStackTrace(); + } + if (null != appInfo) { + String label = appInfo.applicationInfo.loadLabel(pm).toString(); + long openTime = RunningAppManager.getInstance().getOnClickTime(); + long closeTime = System.currentTimeMillis() / 1000; + NetInterfaceManager.getInstance().getAppUsageRecordObservable(packageName, label, openTime, closeTime) + .subscribe(new Observer() { + @Override + public void onSubscribe(@NonNull Disposable d) { + Log.e("SendcloseApp", "onSubscribe: "); + } + + @Override + public void onNext(@NonNull BaseResponse baseResponse) { + Log.e("SendcloseApp", "onNext: " + baseResponse); + } + + @Override + public void onError(@NonNull Throwable e) { + Log.e("SendcloseApp", "onError: " + e.getMessage()); + onComplete(); + } + + @Override + public void onComplete() { + Log.e("SendcloseApp", "onComplete: "); + completeCallback.onComplete(); + } + }); + } + } + + } diff --git a/app/src/main/java/com/uiui/sn/network/UrlAddress.java b/app/src/main/java/com/uiui/sn/network/UrlAddress.java index 4a21911..2cfb95a 100644 --- a/app/src/main/java/com/uiui/sn/network/UrlAddress.java +++ b/app/src/main/java/com/uiui/sn/network/UrlAddress.java @@ -64,6 +64,8 @@ public class UrlAddress { /*获取是否为网课模式*/ public static final String GET_CLOUD_LESSON_SETTING = "Control/getCloudLessonSetting"; + /*应用使用记录*/ + public static final String APP_USAGE_RECORD = "appUsageRecord"; /*获取公网IP*/ public static final String SHOUHU_CITYJSON = "http://pv.sohu.com/cityjson/"; diff --git a/app/src/main/java/com/uiui/sn/network/api/AppTimeControlApi.java b/app/src/main/java/com/uiui/sn/network/api/AppTimeControlApi.java index be608ec..b05abd6 100644 --- a/app/src/main/java/com/uiui/sn/network/api/AppTimeControlApi.java +++ b/app/src/main/java/com/uiui/sn/network/api/AppTimeControlApi.java @@ -1,7 +1,7 @@ package com.uiui.sn.network.api; -import com.uiui.sn.bean.AppTimeControl; +import com.uiui.sn.desktop.AppTimeControl; import com.uiui.sn.bean.BaseResponse; import com.uiui.sn.network.UrlAddress; diff --git a/app/src/main/java/com/uiui/sn/network/api/AppUsageRecordApi.java b/app/src/main/java/com/uiui/sn/network/api/AppUsageRecordApi.java new file mode 100644 index 0000000..a266d45 --- /dev/null +++ b/app/src/main/java/com/uiui/sn/network/api/AppUsageRecordApi.java @@ -0,0 +1,22 @@ +package com.uiui.sn.network.api; + + +import com.uiui.sn.bean.BaseResponse; +import com.uiui.sn.network.UrlAddress; + +import io.reactivex.rxjava3.core.Observable; +import retrofit2.http.Field; +import retrofit2.http.FormUrlEncoded; +import retrofit2.http.POST; + +public interface AppUsageRecordApi { + @FormUrlEncoded + @POST(UrlAddress.APP_USAGE_RECORD) + Observable sendAppUsageRecord( + @Field("sn") String sn, + @Field("app_package") String app_package, + @Field("app_name") String app_name, + @Field("open_time") Long open_time, + @Field("close_time") Long close_time + ); +} diff --git a/app/src/main/java/com/uiui/sn/network/api/MachineTimeControlApi.java b/app/src/main/java/com/uiui/sn/network/api/MachineTimeControlApi.java index b86145a..b9480f5 100644 --- a/app/src/main/java/com/uiui/sn/network/api/MachineTimeControlApi.java +++ b/app/src/main/java/com/uiui/sn/network/api/MachineTimeControlApi.java @@ -1,7 +1,7 @@ package com.uiui.sn.network.api; import com.uiui.sn.bean.BaseResponse; -import com.uiui.sn.bean.MachineControl; +import com.uiui.sn.desktop.MachineControl; import com.uiui.sn.network.UrlAddress; import io.reactivex.rxjava3.core.Observable; diff --git a/app/src/main/java/com/uiui/sn/service/RemoteService.java b/app/src/main/java/com/uiui/sn/service/RemoteService.java index 65246dc..13f4747 100644 --- a/app/src/main/java/com/uiui/sn/service/RemoteService.java +++ b/app/src/main/java/com/uiui/sn/service/RemoteService.java @@ -9,6 +9,8 @@ import android.util.Log; import com.google.gson.JsonObject; import com.uiui.sn.IGetInfoInterface; +import com.uiui.sn.config.CommonConfig; +import com.uiui.sn.desktop.RunningAppManager; import com.uiui.sn.network.NetInterfaceManager; import com.uiui.sn.service.main.MainService; import com.uiui.sn.utils.JGYUtils; @@ -48,52 +50,20 @@ public class RemoteService extends Service { } @Override - public String getSerial() throws RemoteException { - return Utils.getSerial(); + public boolean isControl() throws RemoteException { + int is_control = Settings.System.getInt(getContentResolver(), CommonConfig.KEY_IS_CONTROL, 1); + Log.e(TAG, "inControlTime: is_control = " + is_control); + return is_control == 1; } @Override - public String getUserInfo() throws RemoteException { - if (MainService.getPresenter() != null) { -// MainService.getPresenter().getUserInfo(); - } - String username = Settings.System.getString(getContentResolver(), "UserInfo_username"); - String avatar = Settings.System.getString(getContentResolver(), "UserInfo_avatar"); - int gread = (int) SPUtils.get(RemoteService.this, "int_grade", 0); - String gankaoUID = Settings.System.getString(getContentResolver(), "gankaoUID"); - JsonObject jsonObject = new JsonObject(); - jsonObject.addProperty("username", username); - jsonObject.addProperty("avatar", avatar); - jsonObject.addProperty("grade", gread); - jsonObject.addProperty("userid", gankaoUID); - jsonObject.addProperty("sn", Utils.getSerial()); - Log.e(TAG, "getUserInfo:" + jsonObject.toString()); - return jsonObject.toString(); + public boolean inControl(String pkg) throws RemoteException { + return RunningAppManager.getInstance().inControlTime(pkg); } @Override - public List getHideAPP() throws RemoteException { - return JGYUtils.getInstance().getHideList(); - } - - @Override - public List getForbidAPP() throws RemoteException { - return JGYUtils.getInstance().getForbidList(); - } - - @Override - public String getAppTimeControl() throws RemoteException { - return NetInterfaceManager.getInstance().getAppTimeControlJson(); - } - - @Override - public String getSnTimeControl() throws RemoteException { - return NetInterfaceManager.getInstance().getSnTimeControllJson(); - } - - @Override - public String getSetting() throws RemoteException { - return NetInterfaceManager.getInstance().getSystemSettingsJson(); + public String getDisableContent(String pkg) throws RemoteException { + return RunningAppManager.getInstance().getDisableContent(pkg); } }; } diff --git a/app/src/main/java/com/uiui/sn/tpush/MessageReceiver.java b/app/src/main/java/com/uiui/sn/tpush/MessageReceiver.java index 600196b..33f877a 100644 --- a/app/src/main/java/com/uiui/sn/tpush/MessageReceiver.java +++ b/app/src/main/java/com/uiui/sn/tpush/MessageReceiver.java @@ -478,6 +478,10 @@ public class MessageReceiver extends XGPushBaseReceiver { private static final String ACTION_DEFAULT_INPUT_METHOD = "78"; /*家长管控开关*/ private static final String ACTION_PARENTAL_CONTROL = "79"; + /*整机管控配置*/ + private static final String ACTION_WHOLE_MACHINE_QUOTA = "80"; + /*APP管控配置*/ + private static final String ACTION_APP_CONTROL = "81"; /*更新白名单*/ private static final String UPDATE_WHITE_LIST = "83"; @@ -780,6 +784,13 @@ public class MessageReceiver extends XGPushBaseReceiver { case ACTION_PARENTAL_CONTROL: NetInterfaceManager.getInstance().getSystemSettings(); break; + case ACTION_WHOLE_MACHINE_QUOTA: + NetInterfaceManager.getInstance().getAppTimeControl(); + NetInterfaceManager.getInstance().getSnTimeControl(); + break; + case ACTION_APP_CONTROL: + NetInterfaceManager.getInstance().getAppTimeControl(); + break; case UPDATE_WHITE_LIST: NetInterfaceManager.getInstance().getAllappPackage(); break; diff --git a/app/src/main/java/com/uiui/sn/utils/JGYUtils.java b/app/src/main/java/com/uiui/sn/utils/JGYUtils.java index be442d3..c107fd1 100644 --- a/app/src/main/java/com/uiui/sn/utils/JGYUtils.java +++ b/app/src/main/java/com/uiui/sn/utils/JGYUtils.java @@ -109,6 +109,7 @@ public class JGYUtils { }}; private HashSet fuxiaoyingApp = new HashSet() {{ + this.add(fxyywgj); this.add(gkwxhd); this.add(fuxiaoying); this.add(moshujia); @@ -118,6 +119,7 @@ public class JGYUtils { this.add(growthspace); }}; + public static final String fxyywgj = "com.fuying.chinese"; public static final String gkwxhd = "com.gankao.gkwxhd"; public static final String fuxiaoying = "com.fuying.fuxiaoying"; public static final String moshujia = "com.moshujiamm.moshujia";