From 82db4c359c6d89b9432bcb6bfe383028a19f21ed Mon Sep 17 00:00:00 2001 From: tongtongstudio Date: Tue, 27 Oct 2026 11:10:47 +0800 Subject: [PATCH] =?UTF-8?q?feat(app):=20=E7=A6=81=E7=94=A8=E5=BA=94?= =?UTF-8?q?=E7=94=A8=E5=90=AF=E5=8A=A8=E6=8B=A6=E6=88=AA=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3=E4=B8=8B=E5=8F=91=E6=B8=85=E5=8D=95=E5=B9=B6?= =?UTF-8?q?=E5=AE=9E=E6=97=B6=E5=88=B7=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/build.gradle | 4 +- .../sn/hook/AoleyunActivityController.java | 96 ++++++++++++++++++- .../aoleyun/sn/service/main/MainService.java | 2 +- .../java/com/aoleyun/sn/utils/ApkUtils.java | 2 +- 4 files changed, 97 insertions(+), 7 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 95b929e..dd72d79 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -18,8 +18,8 @@ android { defaultConfig { applicationId "com.aoleyun.sn" - versionCode 254 - versionName "1.6.1023" + versionCode 256 + versionName "1.6.1026" //There are no CERT files because If the mini sdk version is 23+, the AGP will ignore the V1 scheme signature. minSdkVersion 24 diff --git a/app/src/main/java/com/aoleyun/sn/hook/AoleyunActivityController.java b/app/src/main/java/com/aoleyun/sn/hook/AoleyunActivityController.java index 123fcbb..4725925 100644 --- a/app/src/main/java/com/aoleyun/sn/hook/AoleyunActivityController.java +++ b/app/src/main/java/com/aoleyun/sn/hook/AoleyunActivityController.java @@ -1,7 +1,14 @@ package com.aoleyun.sn.hook; import android.app.IActivityController; +import android.content.ContentResolver; +import android.content.Context; import android.content.Intent; +import android.database.ContentObserver; +import android.os.Handler; +import android.os.Looper; +import android.provider.Settings; +import android.text.TextUtils; import android.util.Log; import com.aoleyun.sn.comm.CommonConfig; @@ -9,17 +16,101 @@ import com.aoleyun.sn.utils.ApkUtils; import com.hjq.toast.Toaster; import com.tencent.mmkv.MMKV; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; + public class AoleyunActivityController extends IActivityController.Stub { private static final String TAG = "AoleyunActivityController"; private MMKV mMMKV = MMKV.mmkvWithID(CommonConfig.MMKV_ID, MMKV.MULTI_PROCESS_MODE); + private final Context mContext; + + /** + * 当前需要禁止启动的包名:本地默认禁用({@link ApkUtils#DEFAULT_DISABLE_APP_MAP}) + * + 接口下发禁用(getSnAppAttr 在线禁用、getIconControl 应用管控禁用), + * 统一由 {@link ApkUtils#getKeepDisablePkgs(Context)} 汇总。 + *

+ * activityStarting 每次启动 activity 都会被系统同步回调,这里做进程内缓存, + * 避免每次都跨进程读 Settings.Global;清单变化由 Settings 的 ContentObserver 刷新。 + */ + private volatile Set mDisablePkgs = Collections.emptySet(); + + /** + * 禁用清单变化时刷新缓存(清单由本进程写入 Settings.Global,写入后系统会通知这里) + */ + private final ContentObserver mDisablePkgsObserver = new ContentObserver(new Handler(Looper.getMainLooper())) { + @Override + public void onChange(boolean selfChange) { + refreshDisablePkgs(); + } + }; + + public AoleyunActivityController(Context context) { + mContext = context == null ? null : context.getApplicationContext(); + refreshDisablePkgs(); + registerDisablePkgsObserver(); + } + + /** + * 刷新需要禁止启动的包名 + */ + private void refreshDisablePkgs() { + if (mContext == null) { + return; + } + Set pkgs = new HashSet<>(ApkUtils.getKeepDisablePkgs(mContext)); + //内置的禁用应用(disableSystemapp)同样不允许启动 + pkgs.addAll(ApkUtils.disableSystemapp); + mDisablePkgs = Collections.unmodifiableSet(pkgs); + Log.e(TAG, "refreshDisablePkgs: " + pkgs); + } + + /** + * 监听禁用清单对应的 Settings 项 + */ + private void registerDisablePkgsObserver() { + if (mContext == null) { + return; + } + try { + ContentResolver resolver = mContext.getContentResolver(); + resolver.registerContentObserver(Settings.Global.getUriFor(CommonConfig.AOLE_ACTION_DISABLE_APP), + false, mDisablePkgsObserver); + resolver.registerContentObserver(Settings.Global.getUriFor(CommonConfig.AOLE_ACTION_HIDE_DESKTOP_ICON), + false, mDisablePkgsObserver); + resolver.registerContentObserver(Settings.Global.getUriFor(CommonConfig.AOLE_ACTION_SHOW_DESKTOP_ICON), + false, mDisablePkgsObserver); + } catch (Exception e) { + Log.e(TAG, "registerDisablePkgsObserver: " + e.getMessage()); + } + } + + /** + * 提示应用已被禁用。 + *

+ * activityStarting 运行在 binder 线程上,Toast 对该线程有 Looper 要求, + * 因此这里兜底捕获异常,避免拦截失败变成进程异常。 + */ + private void showDisableTip() { + try { + Toaster.show("应用已被禁用"); + } catch (Exception e) { + Log.e(TAG, "showDisableTip: " + e.getMessage()); + } + } @Override public boolean activityStarting(Intent intent, String pkg) { Log.e(TAG, "activityStarting: " + pkg + ", intent= " + intent); - if (ApkUtils.disableSystemapp.contains(pkg)) { - Toaster.show("应用已被禁用"); + if (TextUtils.isEmpty(pkg)) { + return true; + } + //本地默认禁用应用 + 接口下发的禁用应用,禁止启动 + if (mDisablePkgs.contains(pkg)) { + Log.e(TAG, "activityStarting: 应用已被禁用,拦截启动 " + pkg); + showDisableTip(); return false; } return true; @@ -72,4 +163,3 @@ public class AoleyunActivityController extends IActivityController.Stub { } } - diff --git a/app/src/main/java/com/aoleyun/sn/service/main/MainService.java b/app/src/main/java/com/aoleyun/sn/service/main/MainService.java index 18b9bdc..f697678 100644 --- a/app/src/main/java/com/aoleyun/sn/service/main/MainService.java +++ b/app/src/main/java/com/aoleyun/sn/service/main/MainService.java @@ -543,7 +543,7 @@ public class MainService extends BaseService implements NetworkUtils.OnNetworkSt IActivityManager activityManager = ActivityManagerNative.getDefault(); try { - activityManager.setActivityController(new AoleyunActivityController(), false); + activityManager.setActivityController(new AoleyunActivityController(MainService.this), false); } catch (RemoteException e) { Log.e(TAG, "setActivityController: " + e.getMessage()); } diff --git a/app/src/main/java/com/aoleyun/sn/utils/ApkUtils.java b/app/src/main/java/com/aoleyun/sn/utils/ApkUtils.java index 24eef41..2aec203 100644 --- a/app/src/main/java/com/aoleyun/sn/utils/ApkUtils.java +++ b/app/src/main/java/com/aoleyun/sn/utils/ApkUtils.java @@ -393,7 +393,7 @@ public class ApkUtils { this.add("org.chromium.chrome"); this.add("com.onyx.appmarket"); this.add("com.onyx.aiassistant"); - this.add("com.onyx.android.production.test"); +// this.add("com.onyx.android.production.test"); this.add("com.onyx.dict"); this.add("com.onyx.mail"); this.add("com.onyx.musicplayer");