version:1.6.0403

bugfixes:
add:增加时间管控
This commit is contained in:
2026-04-09 15:43:24 +08:00
parent 2029f7020f
commit b9c5337032
14 changed files with 334 additions and 36 deletions

View File

@@ -29,8 +29,8 @@ android {
defaultConfig { defaultConfig {
applicationId "com.aoleyun.sn" applicationId "com.aoleyun.sn"
versionCode 208 versionCode 210
versionName "1.6.0317" versionName "1.6.0403"
//There are no CERT files because If the mini sdk version is 23+, the AGP will ignore the V1 scheme signature. //There are no CERT files because If the mini sdk version is 23+, the AGP will ignore the V1 scheme signature.
minSdkVersion 24 minSdkVersion 24

View File

@@ -0,0 +1,26 @@
package com.aoleyun.sn.bean;
import java.io.Serializable;
public class TimeControlApp implements Serializable {
private static final long serialVersionUID = 5184143240402181001L;
String app_package;
String app_name;
public String getApp_package() {
return app_package;
}
public void setApp_package(String app_package) {
this.app_package = app_package;
}
public String getApp_name() {
return app_name;
}
public void setApp_name(String app_name) {
this.app_name = app_name;
}
}

View File

@@ -0,0 +1,18 @@
package com.aoleyun.sn.bean;
import java.io.Serializable;
import java.util.List;
public class TimeControlData implements Serializable {
private static final long serialVersionUID = 8902745668847718218L;
List<TimeControlInfo> periods;
public List<TimeControlInfo> getPeriods() {
return periods;
}
public void setPeriods(List<TimeControlInfo> periods) {
this.periods = periods;
}
}

View File

@@ -0,0 +1,36 @@
package com.aoleyun.sn.bean;
import java.io.Serializable;
import java.util.List;
public class TimeControlInfo implements Serializable {
private static final long serialVersionUID = 4988631077105878200L;
String start_time;
String end_time;
List<TimeControlApp> app;
public String getStart_time() {
return start_time;
}
public void setStart_time(String start_time) {
this.start_time = start_time;
}
public String getEnd_time() {
return end_time;
}
public void setEnd_time(String end_time) {
this.end_time = end_time;
}
public List<TimeControlApp> getApp() {
return app;
}
public void setApp(List<TimeControlApp> app) {
this.app = app;
}
}

View File

@@ -91,6 +91,9 @@ public class CommonConfig {
/*壁纸地址*/ /*壁纸地址*/
public static final String WALLPAPER_URL_KEY = "wallpaper_url"; public static final String WALLPAPER_URL_KEY = "wallpaper_url";
/*时间管控json*/
public static final String TIME_CONTROL_DATA_KEY = "time_dontrol_data_json_string";
/** /**
* 管控系统指令 * 管控系统指令

View File

@@ -6,6 +6,7 @@ import android.util.Log;
import com.aoleyun.sn.comm.CommonConfig; import com.aoleyun.sn.comm.CommonConfig;
import com.aoleyun.sn.utils.JgyUtils; import com.aoleyun.sn.utils.JgyUtils;
import com.hjq.toast.Toaster;
import com.tencent.mmkv.MMKV; import com.tencent.mmkv.MMKV;
public class AoleyunActivityController extends IActivityController.Stub { public class AoleyunActivityController extends IActivityController.Stub {
@@ -20,12 +21,17 @@ public class AoleyunActivityController extends IActivityController.Stub {
// return false; // return false;
// } // }
if (JgyUtils.getInstance().checkTimePeriod(pkg)) {
//false 则不会启动,直接返回。 //false 则不会启动,直接返回。
if (JgyUtils.getInstance().isCloudLessonMod(pkg)) { if (JgyUtils.getInstance().isCloudLessonMod(pkg)) {
return true; return true;
} else { } else {
return false; return false;
} }
} else {
Toaster.show("专注模式只允许使用指定应用");
return false;
}
} }
@Override @Override

View File

@@ -55,6 +55,8 @@ import com.aoleyun.sn.bean.SnRunLog;
import com.aoleyun.sn.bean.SnSetting; import com.aoleyun.sn.bean.SnSetting;
import com.aoleyun.sn.bean.SnTimeControl; import com.aoleyun.sn.bean.SnTimeControl;
import com.aoleyun.sn.bean.StudentsInfo; import com.aoleyun.sn.bean.StudentsInfo;
import com.aoleyun.sn.bean.TimeControlData;
import com.aoleyun.sn.bean.TimeControlInfo;
import com.aoleyun.sn.bean.TopApp; import com.aoleyun.sn.bean.TopApp;
import com.aoleyun.sn.bean.Wallpaper; import com.aoleyun.sn.bean.Wallpaper;
import com.aoleyun.sn.bean.WhitelistBean; import com.aoleyun.sn.bean.WhitelistBean;
@@ -623,6 +625,13 @@ public class NetInterfaceManager {
.observeOn(AndroidSchedulers.mainThread()); .observeOn(AndroidSchedulers.mainThread());
} }
public Observable<BaseResponse<TimeControlData>> getTimeObservable() {
return mRetrofit.create(SnTimeControlApi.class)
.getTimeControl(Utils.getSerial(mContext))
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread());
}
public Observable<BaseResponse<ScreenLockState>> getScreenLockObservable() { public Observable<BaseResponse<ScreenLockState>> getScreenLockObservable() {
return mRetrofit.create(ScreenLockStateApi.class) return mRetrofit.create(ScreenLockStateApi.class)
.getScreenLockState(Utils.getSerial(mContext)) .getScreenLockState(Utils.getSerial(mContext))
@@ -2027,6 +2036,8 @@ public class NetInterfaceManager {
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
} else if ("G10".equals(Build.MODEL) || "D1".equals(Build.MODEL)) {
Settings.System.putString(mContext.getContentResolver(), CommonConfig.APP_VIEW_CLICK_DISABLED, "com.ttstd.utils:12345");
} else { } else {
Settings.System.putString(mContext.getContentResolver(), CommonConfig.APP_VIEW_CLICK_DISABLED, "com.arivoc.wordhd:2131624676,2131624689;com.ttstd.utils:12345"); Settings.System.putString(mContext.getContentResolver(), CommonConfig.APP_VIEW_CLICK_DISABLED, "com.arivoc.wordhd:2131624676,2131624689;com.ttstd.utils:12345");
} }
@@ -3609,7 +3620,7 @@ public class NetInterfaceManager {
}; };
} }
@Deprecated
public void getSnTimeControl(boolean refresh, BehaviorSubject<ActivityEvent> lifecycle, onCompleteCallback callback) { public void getSnTimeControl(boolean refresh, BehaviorSubject<ActivityEvent> lifecycle, onCompleteCallback callback) {
ConnectMode connectMode = ConnectMode.ONE_MINUTE; ConnectMode connectMode = ConnectMode.ONE_MINUTE;
if (refresh) { if (refresh) {
@@ -3630,13 +3641,14 @@ public class NetInterfaceManager {
} }
} }
@Deprecated
public void getSnTimeControl(BehaviorSubject<ActivityEvent> lifecycle, onCompleteCallback callback) { public void getSnTimeControl(BehaviorSubject<ActivityEvent> lifecycle, onCompleteCallback callback) {
getSnTimeObservable() getSnTimeObservable()
.compose(RxLifecycle.bindUntilEvent(lifecycle, ActivityEvent.DESTROY)) .compose(RxLifecycle.bindUntilEvent(lifecycle, ActivityEvent.DESTROY))
.subscribe(getSnTimeObserver(callback)); .subscribe(getSnTimeObserver(callback));
} }
@Deprecated
public void getSnTimeControl() { public void getSnTimeControl() {
getSnTimeObservable() getSnTimeObservable()
.subscribe(getSnTimeObserver(null)); .subscribe(getSnTimeObserver(null));
@@ -3689,6 +3701,54 @@ public class NetInterfaceManager {
}; };
} }
public void getTimeControl(BehaviorSubject<ActivityEvent> lifecycle, onCompleteCallback callback) {
getTimeObservable()
.compose(RxLifecycle.bindUntilEvent(lifecycle, ActivityEvent.DESTROY))
.subscribe(getTimeObserver(callback));
}
public void getTimeControl() {
getTimeObservable()
.subscribe(getTimeObserver(null));
}
private Observer<BaseResponse<TimeControlData>> getTimeObserver(onCompleteCallback callback) {
return new Observer<BaseResponse<TimeControlData>>() {
@Override
public void onSubscribe(@NonNull Disposable d) {
Log.e("getTimeObserver", "onSubscribe: ");
}
@Override
public void onNext(@NonNull BaseResponse<TimeControlData> response) {
Log.e("getTimeObserver", "onNext: " + response);
if (response.code == OK) {
TimeControlData timeControlData = response.data;
List<TimeControlInfo> periods = timeControlData.getPeriods();
mMMKV.encode(CommonConfig.TIME_CONTROL_DATA_KEY, GsonUtils.toJSONString(periods));
} else {
mMMKV.remove(CommonConfig.TIME_CONTROL_DATA_KEY);
}
}
@Override
public void onError(@NonNull Throwable e) {
Log.e("getTimeObserver", "onError: " + e.getMessage());
onComplete();
}
@Override
public void onComplete() {
Log.e("getTimeObserver", "onComplete: ");
JgyUtils.getInstance().syncTimePeriod();
if (callback != null) {
callback.onComplete();
}
}
};
}
public interface GetAppinsideWebCallback { public interface GetAppinsideWebCallback {
void onComplete(); void onComplete();
} }

View File

@@ -103,7 +103,9 @@ public class UrlAddress {
/*获取系统设置*/ /*获取系统设置*/
public static final String GET_FIRMWARE = "firmware/get"; public static final String GET_FIRMWARE = "firmware/get";
/*获取时间管控*/ /*获取时间管控*/
@Deprecated
public static final String GET_SN_TIME_CONTROL = "Sn/getSnTimeControl"; public static final String GET_SN_TIME_CONTROL = "Sn/getSnTimeControl";
public static final String GET_TIME_CONTROL = "android/control/time-control";
/*获取WiFi名和密码*/ /*获取WiFi名和密码*/
public static final String GET_WIFI_ALIAS_PW = "And/SnControl/getWifi"; public static final String GET_WIFI_ALIAS_PW = "And/SnControl/getWifi";
/*获取远程关机时间*/ /*获取远程关机时间*/

View File

@@ -2,6 +2,7 @@ package com.aoleyun.sn.network.api.get;
import com.aoleyun.sn.bean.BaseResponse; import com.aoleyun.sn.bean.BaseResponse;
import com.aoleyun.sn.bean.SnTimeControl; import com.aoleyun.sn.bean.SnTimeControl;
import com.aoleyun.sn.bean.TimeControlData;
import com.aoleyun.sn.network.UrlAddress; import com.aoleyun.sn.network.UrlAddress;
import io.reactivex.rxjava3.core.Observable; import io.reactivex.rxjava3.core.Observable;
@@ -13,4 +14,9 @@ public interface SnTimeControlApi {
Observable<BaseResponse<SnTimeControl>> getSnTimeControl( Observable<BaseResponse<SnTimeControl>> getSnTimeControl(
@Query("sn") String sn @Query("sn") String sn
); );
@GET(UrlAddress.GET_TIME_CONTROL)
Observable<BaseResponse<TimeControlData>> getTimeControl(
@Query("sn") String sn
);
} }

View File

@@ -1113,6 +1113,7 @@ public class PushManager {
private void getTimeControl(String extras) { private void getTimeControl(String extras) {
NetInterfaceManager.getInstance().getSnTimeControl(); NetInterfaceManager.getInstance().getSnTimeControl();
NetInterfaceManager.getInstance().getTimeControl();
} }
private void getTopApp(String extras) { private void getTopApp(String extras) {

View File

@@ -556,7 +556,14 @@ public class MainSPresenter implements MainSContact.Presenter {
mView.getSnTimeControlFinish(); mView.getSnTimeControlFinish();
} else { } else {
NetInterfaceManager.getInstance() NetInterfaceManager.getInstance()
.getSnTimeControl(true, getLifecycle(), new NetInterfaceManager.onCompleteCallback() { .getSnTimeControl(getLifecycle(), new NetInterfaceManager.onCompleteCallback() {
@Override
public void onComplete() {
mView.getSnTimeControlFinish();
}
});
NetInterfaceManager.getInstance()
.getTimeControl(getLifecycle(), new NetInterfaceManager.onCompleteCallback() {
@Override @Override
public void onComplete() { public void onComplete() {
mView.getSnTimeControlFinish(); mView.getSnTimeControlFinish();

View File

@@ -109,7 +109,7 @@ public class MainService extends Service implements MainSContact.MainView, Netwo
String WiFiAlias = Utils.getWifiAlias(this); String WiFiAlias = Utils.getWifiAlias(this);
Log.e("OnNetworkStatusChanged", "onConnected: " + WiFiAlias); Log.e("OnNetworkStatusChanged", "onConnected: " + WiFiAlias);
JgyUtils.getInstance().addNetworkConnectedTime(System.currentTimeMillis() / 1000); JgyUtils.getInstance().addNetworkConnectedTime(System.currentTimeMillis() / 1000);
mPresenter.sendNetwork(JgyUtils.getInstance().getNetworkConnectedTime()); // mPresenter.sendNetwork(JgyUtils.getInstance().getNetworkConnectedTime());
if (JgyUtils.getInstance().isScreenOn()) { if (JgyUtils.getInstance().isScreenOn()) {
TimeTask task = new TimeTask(); TimeTask task = new TimeTask();
task.execute("ntp.aliyun.com"); task.execute("ntp.aliyun.com");
@@ -922,22 +922,21 @@ public class MainService extends Service implements MainSContact.MainView, Netwo
@SuppressLint("NewApi") @SuppressLint("NewApi")
@Override @Override
public void onReceive(Context context, Intent intent) { public void onReceive(Context context, Intent intent) {
Log.e(TAG, "onReceive: " + intent.getAction()); Log.e("TimeChangedReceiver", "onReceive: " + intent.getAction());
if (Intent.ACTION_DATE_CHANGED.equals(intent.getAction())) { switch (intent.getAction()) {
Log.e("TimeChangedReceiver", "onReceive:" + "data changed"); case Intent.ACTION_DATE_CHANGED:
} else if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) { case Intent.ACTION_TIME_CHANGED:
Log.e("TimeChangedReceiver", "onReceive:" + "time changed"); case Intent.ACTION_TIMEZONE_CHANGED:
} else if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { case Intent.ACTION_TIME_TICK:
Log.e("TimeChangedReceiver", "onReceive:" + "timezone changed");
} else if (Intent.ACTION_TIME_TICK.equals(intent.getAction())) {
Log.e("TimeChangedReceiver", "onReceive:" + "time tick");
checkShutdownTime(); checkShutdownTime();
checkUploadLogTime(); checkUploadLogTime();
setFloatingWindow(); setFloatingWindow();
} else if (ACTION_UPDATE.equals(intent.getAction())) { JgyUtils.getInstance().checkTimePeriod();
break;
case ACTION_UPDATE:
setFloatingWindow(); setFloatingWindow();
// mPresenter.getScreenLockState(); // mPresenter.getScreenLockState();
Log.e("TimeChangedReceiver", "onReceive:" + "date update"); break;
} }
timeChangedStart.onstar(System.currentTimeMillis()); timeChangedStart.onstar(System.currentTimeMillis());
} }
@@ -1064,6 +1063,7 @@ public class MainService extends Service implements MainSContact.MainView, Netwo
} }
} }
private interface TopApp { private interface TopApp {
void open(Long time); void open(Long time);
} }

View File

@@ -55,6 +55,8 @@ import com.aoleyun.sn.bean.LessonJson;
import com.aoleyun.sn.bean.NetAndLaunchBean; import com.aoleyun.sn.bean.NetAndLaunchBean;
import com.aoleyun.sn.bean.NetAndLaunchData; import com.aoleyun.sn.bean.NetAndLaunchData;
import com.aoleyun.sn.bean.TTAppground; import com.aoleyun.sn.bean.TTAppground;
import com.aoleyun.sn.bean.TimeControlApp;
import com.aoleyun.sn.bean.TimeControlInfo;
import com.aoleyun.sn.comm.CommonConfig; import com.aoleyun.sn.comm.CommonConfig;
import com.aoleyun.sn.comm.JGYActions; import com.aoleyun.sn.comm.JGYActions;
import com.aoleyun.sn.comm.PackageNames; import com.aoleyun.sn.comm.PackageNames;
@@ -98,6 +100,9 @@ import java.net.Inet4Address;
import java.net.InetAddress; import java.net.InetAddress;
import java.net.NetworkInterface; import java.net.NetworkInterface;
import java.net.SocketException; import java.net.SocketException;
import java.time.LocalDate;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Enumeration; import java.util.Enumeration;
@@ -143,6 +148,8 @@ public class JgyUtils {
private LessonJson mLessonJson; private LessonJson mLessonJson;
private TimeUtils.ContralTime mContralTime; private TimeUtils.ContralTime mContralTime;
private List<TimeControlInfo> mAppPeriods;
public static final int UnknowPlatform = 0; public static final int UnknowPlatform = 0;
public static final int MTKPlatform = 1; public static final int MTKPlatform = 1;
@@ -230,6 +237,7 @@ public class JgyUtils {
bindEbaifenService(); bindEbaifenService();
} }
refresh(); refresh();
syncTimePeriod();
} }
public static void init(Context context) { public static void init(Context context) {
@@ -1028,9 +1036,6 @@ public class JgyUtils {
return; return;
} }
if (appIDList == null || appIDList.isEmpty()) { if (appIDList == null || appIDList.isEmpty()) {
if ("G10".equals(Build.MODEL) || "D1".equals(Build.MODEL)) {
Settings.System.putString(mContext.getContentResolver(), CommonConfig.APP_VIEW_CLICK_DISABLED, "com.arivoc.wordhd:2131624676,2131624689;com.ttstd.utils:12345");
} else {
try { try {
Settings.System.putString(crv, CommonConfig.APP_VIEW_CLICK_DISABLED, null); Settings.System.putString(crv, CommonConfig.APP_VIEW_CLICK_DISABLED, null);
// TODO: 2024/9/11 修复1.4.0907版本数据为空系统报错 // TODO: 2024/9/11 修复1.4.0907版本数据为空系统报错
@@ -1039,7 +1044,6 @@ public class JgyUtils {
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
}
} else { } else {
String s = appIDList.stream().map(new Function<AppID, String>() { String s = appIDList.stream().map(new Function<AppID, String>() {
@Override @Override
@@ -3916,4 +3920,133 @@ public class JgyUtils {
return JsonParser.parseString(new Gson().toJson(this)).getAsJsonObject().toString(); return JsonParser.parseString(new Gson().toJson(this)).getAsJsonObject().toString();
} }
} }
private String getTopActivityInfo() {
ActivityManager manager = (ActivityManager) mContext.getApplicationContext().getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningTaskInfo> runningTaskInfos = manager.getRunningTasks(1);
if (runningTaskInfos != null && !runningTaskInfos.isEmpty()) {
ComponentName componentName = runningTaskInfos.get(0).topActivity;
if (componentName != null) {
String currentClassName = componentName.getPackageName();
return currentClassName;
}
}
return "";
}
public boolean inOpenTimePeriod(TimeControlInfo timeControlInfo) {
String startTimeStr = timeControlInfo.getStart_time();
String endTimeStr = timeControlInfo.getEnd_time();
// 获取当前日期和时间
LocalDate currentDate = LocalDate.now();
LocalTime currentTime = LocalTime.now();
// 解析时间并比较
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm");
LocalTime startTime = LocalTime.parse(startTimeStr, formatter);
LocalTime endTime = LocalTime.parse(endTimeStr, formatter);
boolean inTime = !currentTime.isBefore(startTime) && !currentTime.isAfter(endTime);
return inTime;
}
public void syncTimePeriod() {
String jsonString = mMMKV.decodeString(CommonConfig.TIME_CONTROL_DATA_KEY, "");
if (TextUtils.isEmpty(jsonString)) {
mAppPeriods = null;
return;
}
Gson gson = new Gson();
Type type = new TypeToken<List<TimeControlInfo>>() {
}.getType();
try {
mAppPeriods = gson.fromJson(jsonString, type);
Log.e(TAG, "checkTimePeriod: periods = " + mAppPeriods);
checkTimePeriod();
} catch (Exception e) {
Log.e(TAG, "checkTimePeriod: Exception = " + e.getMessage());
}
}
public void checkTimePeriod() {
if (mAppPeriods == null || mAppPeriods.isEmpty()) {
return;
}
String foregroundPackage = getTopActivityInfo();
if (ApkUtils.isSystemApp(mContext, foregroundPackage)) {
Log.d(TAG, "checkTimePeriod: " + foregroundPackage + " is system app, skip");
return;
}
Set<String> packageNames = mAppPeriods.stream()
.filter(new Predicate<TimeControlInfo>() {
@Override
public boolean test(TimeControlInfo timeControlInfo) {
return inOpenTimePeriod(timeControlInfo);
}
})
.map(new Function<TimeControlInfo, List<String>>() {
@Override
public List<String> apply(TimeControlInfo timeControlInfo) {
return timeControlInfo.getApp().stream().map(new Function<TimeControlApp, String>() {
@Override
public String apply(TimeControlApp timeControlApp) {
return timeControlApp.getApp_package();
}
}).collect(Collectors.toList());
}
})
//使用 stream 和 flatMap 将所有元素合并
.flatMap(List::stream)
.collect(Collectors.toSet());
Log.d(TAG, "checkTimePeriod: " + packageNames);
if (packageNames.contains(foregroundPackage)) {
Log.e(TAG, "checkTimePeriod: " + foregroundPackage + " skip");
} else {
gotoLauncher();
}
}
/**
* @param pkgName
* @return true为可以打开
*/
public boolean checkTimePeriod(String pkgName) {
if (mAppPeriods == null || mAppPeriods.isEmpty()) {
return true;
}
if (ApkUtils.isSystemApp(mContext, pkgName)) {
Log.d(TAG, "checkTimePeriod: " + pkgName + " is system app, skip");
return true;
}
Set<String> packageNames = mAppPeriods.stream()
.filter(new Predicate<TimeControlInfo>() {
@Override
public boolean test(TimeControlInfo timeControlInfo) {
return inOpenTimePeriod(timeControlInfo);
}
})
.map(new Function<TimeControlInfo, List<String>>() {
@Override
public List<String> apply(TimeControlInfo timeControlInfo) {
return timeControlInfo.getApp().stream().map(new Function<TimeControlApp, String>() {
@Override
public String apply(TimeControlApp timeControlApp) {
return timeControlApp.getApp_package();
}
}).collect(Collectors.toList());
}
})
//使用 stream 和 flatMap 将所有元素合并
.flatMap(List::stream)
.collect(Collectors.toSet());
Log.d(TAG, "checkTimePeriod: " + packageNames);
if (packageNames.contains(pkgName)) {
return true;
} else {
return false;
}
}
} }

View File

@@ -874,7 +874,7 @@ public class Utils {
@SuppressLint({"MissingPermission", "HardwareIds"}) @SuppressLint({"MissingPermission", "HardwareIds"})
public static String getSn() { public static String getSn() {
// if (BuildConfig.DEBUG) { // if (BuildConfig.DEBUG) {
// return "GMG1096250930004"; // return "LTPHR23040000006";
// } // }
String serial = "unknow"; String serial = "unknow";
try { try {