From 580db768cb5679fbc11158e4207636efcabba9d6 Mon Sep 17 00:00:00 2001 From: ZhanGSKen Date: Sat, 15 Nov 2025 16:59:56 +0800 Subject: [PATCH] =?UTF-8?q?=E8=AE=BE=E7=BD=AE=E4=B8=8E=E5=BA=94=E7=94=A8?= =?UTF-8?q?=E7=BA=A7=E5=88=AB=E4=B8=8E=E5=85=A5=E5=8F=A3=E7=BA=A7=E5=88=AB?= =?UTF-8?q?=E6=A6=82=E5=BF=B5=E3=80=82=E5=9C=A8=E9=99=84=E5=8A=A0=E7=BB=84?= =?UTF-8?q?=E4=BB=B6=E6=B7=BB=E5=8A=A0=E4=B8=8E=E5=88=A0=E9=99=A4=E6=97=B6?= =?UTF-8?q?=EF=BC=8C=E5=B0=B1=E6=98=AF=E5=BA=94=E7=94=A8=E5=85=A5=E5=8F=A3?= =?UTF-8?q?=E7=9A=84=E6=B7=BB=E5=8A=A0=E4=B8=8E=E5=88=A0=E9=99=A4=E9=97=AE?= =?UTF-8?q?=E9=A2=98=E3=80=82=E5=BA=94=E7=94=A8=E7=BB=84=E4=BB=B6=E6=A0=B9?= =?UTF-8?q?=E6=8D=AE=E5=BA=94=E7=94=A8=E7=BA=A7=E5=88=AB=E6=9D=A5=E7=BB=84?= =?UTF-8?q?=E5=90=88=EF=BC=8C=E5=BA=94=E7=94=A8=E8=A7=86=E5=9B=BE=E5=85=83?= =?UTF-8?q?=E7=B4=A0=E6=A0=B9=E6=8D=AE=E5=BA=94=E7=94=A8=E5=85=A5=E5=8F=A3?= =?UTF-8?q?=E7=BA=A7=E5=88=AB=E6=9D=A5=E7=BB=84=E5=90=88=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- positions/build.gradle | 3 +- positions/build.properties | 4 +- positions/src/beta/res/xml/shortcutsmain.xml | 4 +- positions/src/beta/res/xml/shortcutsplus.xml | 4 +- positions/src/main/AndroidManifest.xml | 97 +++++++----- .../java/cc/winboll/studio/positions/App.java | 35 ++--- .../studio/positions/MainActivity.java | 36 +---- .../winboll/studio/positions/PointLevel.java | 43 +++++ .../activities/ShortcutActionActivity.java | 61 ++++++++ .../positions/activities/WinBoLLActivity.java | 69 +++++++- .../positions/models/AppConfigsModel.java | 13 ++ .../studio/positions/utils/APPPlusUtils.java | 13 +- .../positions/utils/ActivityAliasUtils.java | 148 ++++++++++++++++++ .../positions/utils/AppConfigsUtil.java | 20 ++- .../utils/MyActivityLifecycleCallbacks.java | 105 +++++++++++++ .../positions/views/PositionTaskListView.java | 6 +- positions/src/main/res/xml/shortcutsmain.xml | 4 +- positions/src/main/res/xml/shortcutsplus.xml | 4 +- 18 files changed, 551 insertions(+), 118 deletions(-) create mode 100644 positions/src/main/java/cc/winboll/studio/positions/PointLevel.java create mode 100644 positions/src/main/java/cc/winboll/studio/positions/activities/ShortcutActionActivity.java create mode 100644 positions/src/main/java/cc/winboll/studio/positions/utils/ActivityAliasUtils.java create mode 100644 positions/src/main/java/cc/winboll/studio/positions/utils/MyActivityLifecycleCallbacks.java diff --git a/positions/build.gradle b/positions/build.gradle index 219a09d8..558303e1 100644 --- a/positions/build.gradle +++ b/positions/build.gradle @@ -47,8 +47,6 @@ android { } dependencies { - api fileTree(dir: 'libs', include: ['*.jar']) - // https://mvnrepository.com/artifact/com.jzxiang.pickerview/TimePickerDialog api 'com.jzxiang.pickerview:TimePickerDialog:1.0.1' @@ -76,4 +74,5 @@ dependencies { api 'cc.winboll.studio:libaes:15.11.0' api 'cc.winboll.studio:libappbase:15.11.0' + api fileTree(dir: 'libs', include: ['*.jar']) } diff --git a/positions/build.properties b/positions/build.properties index 6765a193..690e51c5 100644 --- a/positions/build.properties +++ b/positions/build.properties @@ -1,8 +1,8 @@ #Created by .winboll/winboll_app_build.gradle -#Thu Nov 13 16:25:50 HKT 2025 +#Sat Nov 15 08:45:48 GMT 2025 stageCount=2 libraryProject= baseVersion=15.11 publishVersion=15.11.1 -buildCount=0 +buildCount=21 baseBetaVersion=15.11.2 diff --git a/positions/src/beta/res/xml/shortcutsmain.xml b/positions/src/beta/res/xml/shortcutsmain.xml index 896e6a2e..08d8f994 100644 --- a/positions/src/beta/res/xml/shortcutsmain.xml +++ b/positions/src/beta/res/xml/shortcutsmain.xml @@ -9,9 +9,9 @@ android:shortcutLongLabel="@string/open_appplus" android:shortcutDisabledMessage="@string/appplus_open_disabled"> diff --git a/positions/src/beta/res/xml/shortcutsplus.xml b/positions/src/beta/res/xml/shortcutsplus.xml index ce0fab89..78616e4d 100644 --- a/positions/src/beta/res/xml/shortcutsplus.xml +++ b/positions/src/beta/res/xml/shortcutsplus.xml @@ -9,9 +9,9 @@ android:shortcutLongLabel="@string/close_appplus" android:shortcutDisabledMessage="@string/appplus_close_disabled"> diff --git a/positions/src/main/AndroidManifest.xml b/positions/src/main/AndroidManifest.xml index 1c69bdb8..3d84da34 100644 --- a/positions/src/main/AndroidManifest.xml +++ b/positions/src/main/AndroidManifest.xml @@ -3,17 +3,32 @@ xmlns:android="http://schemas.android.com/apk/res/android" package="cc.winboll.studio.positions"> - + + + + + + + + + + + - - - - + + + + + + + + + - - + android:exported="true"> + @@ -48,12 +62,11 @@ + - - - - + + + + + - + android:resource="@xml/shortcutsmain"/> + - - - + + + + + - + android:resource="@xml/shortcutsplus"/> + - - - - + + - + + + + - - - - - - + + + + + + + + + - - + \ No newline at end of file diff --git a/positions/src/main/java/cc/winboll/studio/positions/App.java b/positions/src/main/java/cc/winboll/studio/positions/App.java index 6de5d9ae..474212d8 100644 --- a/positions/src/main/java/cc/winboll/studio/positions/App.java +++ b/positions/src/main/java/cc/winboll/studio/positions/App.java @@ -23,9 +23,8 @@ import android.widget.TextView; import android.widget.Toast; import cc.winboll.studio.libaes.utils.WinBoLLActivityManager; import cc.winboll.studio.libappbase.GlobalApplication; -import cc.winboll.studio.libappbase.LogUtils; import cc.winboll.studio.libappbase.ToastUtils; -import cc.winboll.studio.positions.activities.WinBoLLActivity; +import cc.winboll.studio.positions.utils.MyActivityLifecycleCallbacks; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.Closeable; @@ -47,8 +46,15 @@ public class App extends GlobalApplication { public static volatile AppLevel _mAppLevel = AppLevel.WUKONG; - private static Handler MAIN_HANDLER = new Handler(Looper.getMainLooper()); + public static final String COMPONENT_WUKONG = "cc.winboll.studio.positions.MainActivityWukong"; + public static final String COMPONENT_LAOJUN = "cc.winboll.studio.positions.MainActivityLaojun"; + public static final String ACTION_OPEN_APPPLUS = "cc.winboll.studio.positions.App.ACTION_OPEN_APPPLUS"; + public static final String ACTION_CLOSE_APPPLUS = "cc.winboll.studio.positions.App.ACTION_CLOSE_APPPLUS"; + private static Handler MAIN_HANDLER = new Handler(Looper.getMainLooper()); + + MyActivityLifecycleCallbacks mMyActivityLifecycleCallbacks; + @Override public void onCreate() { super.onCreate(); @@ -66,28 +72,9 @@ public class App extends GlobalApplication { //CrashHandler.getInstance().registerGlobal(this); //CrashHandler.getInstance().registerPart(this); + mMyActivityLifecycleCallbacks = new MyActivityLifecycleCallbacks(); + registerActivityLifecycleCallbacks(mMyActivityLifecycleCallbacks); } - - - public static void setAppLevel(WinBoLLActivity activity) { - // 根据应用当前启动入口设定整体应用级别 - String launchComponent = activity.getComponentName().getClassName(); - boolean isAliasLaunch = launchComponent.endsWith("MainActivityLaojun"); - - if (isAliasLaunch) { - // Alias入口启动逻辑(如切换应用级别、加载专属配置) - LogUtils.d(TAG, "通过Alias入口启动,切换为LAOJUN级别"); - //ToastUtils.show("通过Alias入口启动,切换为LAOJUN级别"); - App._mAppLevel = AppLevel.LAOJUN; // 结合之前定义的枚举 - // 执行Alias专属初始化... - } else { - // 原入口启动逻辑 - LogUtils.d(TAG, "通过原入口启动,默认WUKONG级别"); - //ToastUtils.show("通过原入口启动,默认WUKONG级别"); - App._mAppLevel = AppLevel.WUKONG; - } - - } public static void write(InputStream input, OutputStream output) throws IOException { byte[] buf = new byte[1024 * 8]; diff --git a/positions/src/main/java/cc/winboll/studio/positions/MainActivity.java b/positions/src/main/java/cc/winboll/studio/positions/MainActivity.java index e1deb539..e659b96c 100644 --- a/positions/src/main/java/cc/winboll/studio/positions/MainActivity.java +++ b/positions/src/main/java/cc/winboll/studio/positions/MainActivity.java @@ -34,11 +34,8 @@ import cc.winboll.studio.positions.utils.ServiceUtil; */ public class MainActivity extends WinBoLLActivity implements IWinBoLLActivity { public static final String TAG = "MainActivity"; - public static final String COMPONENT_WUKONG = "cc.winboll.studio.positions.MainActivityWukong"; - public static final String COMPONENT_LAOJUN = "cc.winboll.studio.positions.MainActivityLaojun"; - public static final String ACTION_OPEN_APPPLUS = "cc.winboll.studio.positions.MainActivity.ACTION_OPEN_APPPLUS"; - public static final String ACTION_CLOSE_APPPLUS = "cc.winboll.studio.positions.MainActivity.ACTION_CLOSE_APPPLUS"; - // 权限请求码(建议定义为类常量,避免魔法值) + + // 权限请求码(建议定义为类常量,避免魔法值) private static final int REQUEST_LOCATION_PERMISSIONS = 1001; private static final int REQUEST_BACKGROUND_LOCATION_PERMISSION = 1002; @@ -48,7 +45,7 @@ public class MainActivity extends WinBoLLActivity implements IWinBoLLActivity { private Toolbar mToolbar; // 服务相关:服务实例、绑定状态标记 //private DistanceRefreshService mDistanceService; - private boolean isServiceBound = false; + //private boolean isServiceBound = false; @Override @@ -89,13 +86,10 @@ public class MainActivity extends WinBoLLActivity implements IWinBoLLActivity { protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 关联主页面布局 - // 处理应用级别的切换请求 - handleSwitchRequest(); + // 处理启动时的分享 Intent handleShareIntent(getIntent()); - // 设置当前应用级别 - App.setAppLevel(this); // 1. 初始化顶部 Toolbar(保留原逻辑,设置页面标题) initToolbar(); @@ -109,22 +103,6 @@ public class MainActivity extends WinBoLLActivity implements IWinBoLLActivity { //bindDistanceService(); } - /** - * 处理应用图标快捷菜单的请求 - */ - private void handleSwitchRequest() { - Intent intent = getIntent(); - if (intent != null && "open_appplus".equals(intent.getDataString())) { - ToastUtils.show("已添加" + getString(R.string.app_name) + "附加组件"); - APPPlusUtils.openAPPPlus(this); - moveTaskToBack(true); - } - if (intent != null && "close_appplus".equals(intent.getDataString())) { - ToastUtils.show("已移除" + getString(R.string.app_name) + "附加组件"); - APPPlusUtils.closeAPPPlus(this); - moveTaskToBack(true); - } - } @Override protected void onNewIntent(Intent intent) { @@ -169,9 +147,9 @@ public class MainActivity extends WinBoLLActivity implements IWinBoLLActivity { mToolbar = (Toolbar) findViewById(R.id.toolbar); // Java 7 显式 findViewById + 强转 setSupportActionBar(mToolbar); // 给ActionBar设置标题(先判断非空,避免空指针异常) - /*if (getSupportActionBar() != null) { - getSupportActionBar().setTitle(getString(R.string.app_name)); - }*/ + AppLevel appLevel = AppConfigsUtil.getInstance(getApplicationContext()).getAppLevel(true); + getSupportActionBar().setTitle(getString(R.string.app_name)); + } /** diff --git a/positions/src/main/java/cc/winboll/studio/positions/PointLevel.java b/positions/src/main/java/cc/winboll/studio/positions/PointLevel.java new file mode 100644 index 00000000..3c78f4d3 --- /dev/null +++ b/positions/src/main/java/cc/winboll/studio/positions/PointLevel.java @@ -0,0 +1,43 @@ +package cc.winboll.studio.positions; + +/** + * @Author ZhanGSKen&豆包大模型 + * @Date 2025/11/15 15:14 + * @Describe 应用入口级别类型枚举 + */ +public enum PointLevel { + DORAEMON("doraemon", "叮铛级别"), + WUKONG("wukong", "悟空级别"), + LAOJUN("laojun", "老君级别"); + + public static final String TAG = "PointLevel"; + + // 枚举属性 + private final String code; // 编码(如 "wukong") + private final String desc; // 描述 + + // 构造方法(Java 7 需显式定义) + PointLevel(String code, String desc) { + this.code = code; + this.desc = desc; + } + + // Getter 方法(获取枚举属性) + public String getCode() { + return code; + } + + public String getDesc() { + return desc; + } + + // 可选:根据 code 获取枚举项(便于业务使用) + public static PointLevel getByCode(String code) { + for (PointLevel level : values()) { + if (level.code.equals(code)) { + return level; + } + } + return null; // 或抛出异常,根据业务需求调整 + } +} diff --git a/positions/src/main/java/cc/winboll/studio/positions/activities/ShortcutActionActivity.java b/positions/src/main/java/cc/winboll/studio/positions/activities/ShortcutActionActivity.java new file mode 100644 index 00000000..f0618cc6 --- /dev/null +++ b/positions/src/main/java/cc/winboll/studio/positions/activities/ShortcutActionActivity.java @@ -0,0 +1,61 @@ +package cc.winboll.studio.positions.activities; + +import android.app.Activity; +import android.content.Intent; +import android.os.Bundle; +import android.os.PersistableBundle; +import cc.winboll.studio.libappbase.ToastUtils; +import cc.winboll.studio.positions.R; +import cc.winboll.studio.positions.utils.APPPlusUtils; +import cc.winboll.studio.positions.utils.AppConfigsUtil; +import cc.winboll.studio.positions.AppLevel; + +/** + * @Author ZhanGSKen&豆包大模型 + * @Date 2025/11/15 13:45 + * @Describe 应用快捷方式活动类 + */ +public class ShortcutActionActivity extends Activity { + + public static final String TAG = "ShortcutActionActivity"; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + // 处理应用级别的切换请求 + handleSwitchRequest(); + finish(); + } + + + +// @Override +// public void onPostCreate(Bundle savedInstanceState, PersistableBundle persistentState) { +// super.onPostCreate(savedInstanceState, persistentState); +// finish(); +// } + +// @Override +// protected void onStart() { +// super.onStart(); +// } + + /** + * 处理应用图标快捷菜单的请求 + */ + private void handleSwitchRequest() { + Intent intent = getIntent(); + if (intent != null && "open_appplus".equals(intent.getDataString())) { + ToastUtils.show("已添加" + getString(R.string.app_name) + "附加组件"); + AppConfigsUtil.getInstance(getApplicationContext()).setAppLevel(AppLevel.LAOJUN); + APPPlusUtils.openAPPPlus(this); + //moveTaskToBack(true); + } + if (intent != null && "close_appplus".equals(intent.getDataString())) { + ToastUtils.show("已移除" + getString(R.string.app_name) + "附加组件"); + AppConfigsUtil.getInstance(getApplicationContext()).setAppLevel(AppLevel.WUKONG); + APPPlusUtils.closeAPPPlus(this); + //moveTaskToBack(true); + } + } +} diff --git a/positions/src/main/java/cc/winboll/studio/positions/activities/WinBoLLActivity.java b/positions/src/main/java/cc/winboll/studio/positions/activities/WinBoLLActivity.java index 3cf13b76..8f408770 100644 --- a/positions/src/main/java/cc/winboll/studio/positions/activities/WinBoLLActivity.java +++ b/positions/src/main/java/cc/winboll/studio/positions/activities/WinBoLLActivity.java @@ -12,11 +12,19 @@ import androidx.appcompat.app.AppCompatActivity; import cc.winboll.studio.libaes.interfaces.IWinBoLLActivity; import cc.winboll.studio.libaes.utils.WinBoLLActivityManager; import cc.winboll.studio.libappbase.LogUtils; +import cc.winboll.studio.libappbase.ToastUtils; +import cc.winboll.studio.positions.App; +import cc.winboll.studio.positions.PointLevel; +import cc.winboll.studio.positions.R; +import cc.winboll.studio.positions.utils.ActivityAliasUtils; +import cc.winboll.studio.positions.utils.AppConfigsUtil; public class WinBoLLActivity extends AppCompatActivity implements IWinBoLLActivity { public static final String TAG = "WinBoLLActivity"; + public static volatile PointLevel _mPointLevel = PointLevel.WUKONG; + @Override public Activity getActivity() { return this; @@ -30,18 +38,67 @@ public class WinBoLLActivity extends AppCompatActivity implements IWinBoLLActivi @Override protected void onResume() { super.onResume(); + //ToastUtils.show("onResume"); + + // ActivityAliasUtils 工具使用示例 + // +// // 获取真实的目标组件名(即使通过 alias 启动,也能拿到 OriginalActivity) +// String realTargetName = ActivityAliasUtils.getRealTargetNameFromIntent(this); +// LogUtils.d("AliasActivity", "真实组件名:" + realTargetName); + // 获取真实的目标组件名(即使通过 alias 启动,也能拿到 OriginalActivity) +// String realTargetName = ActivityAliasUtils.getRealTargetNameFromIntent(this); +// LogUtils.d(TAG, "真实组件名:" + realTargetName); +// ToastUtils.show(realTargetName); +// // 判断某个组件是否为 alias +// String componentName = "com.winboll.app.AliasActivity"; +// boolean isAlias = ActivityAliasUtils.isActivityAlias(getApplicationContext(), componentName); +// LogUtils.d("判断结果", componentName + " 是否为 alias:" + isAlias); // true +// // 获取启动当前 Activity 的组件名(兼容 alias 场景) +// String launchComponent = ActivityAliasUtils.getLaunchComponentName(this); +// LogUtils.d("MainActivity", "启动组件名:" + launchComponent); + + /* + * 应用入口逻辑模块 + */ + // + // 检查当前活动的启动组件名,设置应用入口级别。 + String launchComponent = ActivityAliasUtils.getLaunchComponentName(this); + LogUtils.d("MainActivity", "启动组件名:" + launchComponent); + ToastUtils.show(launchComponent); + // 当前应用处于活动暂停的状态时,就检查应用的入口组件名称,设置应用入口级别。 + if (WinBoLLActivity._mPointLevel == PointLevel.DORAEMON) { + if (launchComponent.equals(App.COMPONENT_WUKONG)) { + getSupportActionBar().setTitle(getString(R.string.appplus_name)); + ToastUtils.show("WUKONG"); + _mPointLevel = PointLevel.WUKONG; + } else if (launchComponent.equals(App.COMPONENT_LAOJUN)) { + getSupportActionBar().setTitle(getString(R.string.app_name)); + ToastUtils.show("LAOJUN"); + _mPointLevel = PointLevel.LAOJUN; + } else { + // 如果是其他应用组件入口,就关闭活动 + finish(); + } + } + + /* + * 应用级别设置模块 + */ + // 读取并配置应用级别 + App._mAppLevel = AppConfigsUtil.getInstance(getApplicationContext()).getAppLevel(true); + LogUtils.d(TAG, String.format("onResume %s", getTag())); } @Override public boolean onOptionsItemSelected(MenuItem item) { /*if (item.getItemId() == R.id.item_log) { - WinBoLLActivityManager.getInstance().startLogActivity(this); - return true; - } else if (item.getItemId() == R.id.item_home) { - startActivity(new Intent(this, MainActivity.class)); - return true; - }*/ + WinBoLLActivityManager.getInstance().startLogActivity(this); + return true; + } else if (item.getItemId() == R.id.item_home) { + startActivity(new Intent(this, MainActivity.class)); + return true; + }*/ // 在switch语句中处理每个ID,并在处理完后返回true,未处理的情况返回false。 return super.onOptionsItemSelected(item); } diff --git a/positions/src/main/java/cc/winboll/studio/positions/models/AppConfigsModel.java b/positions/src/main/java/cc/winboll/studio/positions/models/AppConfigsModel.java index feb0aa06..032adb98 100644 --- a/positions/src/main/java/cc/winboll/studio/positions/models/AppConfigsModel.java +++ b/positions/src/main/java/cc/winboll/studio/positions/models/AppConfigsModel.java @@ -9,12 +9,14 @@ package cc.winboll.studio.positions.models; import android.util.JsonWriter; import android.util.JsonReader; import java.io.IOException; +import cc.winboll.studio.positions.AppLevel; public class AppConfigsModel extends BaseBean { public static final String TAG = "AppConfigsModel"; boolean isEnableMainService; + AppLevel appLevel; public AppConfigsModel(boolean isEnableMainService) { this.isEnableMainService = isEnableMainService; @@ -24,6 +26,14 @@ public class AppConfigsModel extends BaseBean { this.isEnableMainService = false; } + public void setAppLevel(AppLevel appLevel) { + this.appLevel = appLevel; + } + + public AppLevel getAppLevel() { + return appLevel; + } + public void setIsEnableMainService(boolean isEnableMainService) { this.isEnableMainService = isEnableMainService; } @@ -42,6 +52,7 @@ public class AppConfigsModel extends BaseBean { public void writeThisToJsonWriter(JsonWriter jsonWriter) throws IOException { super.writeThisToJsonWriter(jsonWriter); jsonWriter.name("isEnableDistanceRefreshService").value(isEnableMainService()); + jsonWriter.name("appLevel").value(getAppLevel().ordinal()); } // JSON反序列化(加载位置数据,校验字段) @@ -52,6 +63,8 @@ public class AppConfigsModel extends BaseBean { } else { if (name.equals("isEnableDistanceRefreshService")) { setIsEnableMainService(jsonReader.nextBoolean()); + } else if (name.equals("appLevel")) { + setAppLevel((AppLevel.values()[jsonReader.nextInt()])); } else { return false; } diff --git a/positions/src/main/java/cc/winboll/studio/positions/utils/APPPlusUtils.java b/positions/src/main/java/cc/winboll/studio/positions/utils/APPPlusUtils.java index 7776cc10..d7474455 100644 --- a/positions/src/main/java/cc/winboll/studio/positions/utils/APPPlusUtils.java +++ b/positions/src/main/java/cc/winboll/studio/positions/utils/APPPlusUtils.java @@ -12,6 +12,7 @@ import android.content.pm.PackageManager; import android.os.Build; import android.widget.Toast; import cc.winboll.studio.libappbase.LogUtils; +import cc.winboll.studio.positions.App; import cc.winboll.studio.positions.MainActivity; public class APPPlusUtils { @@ -32,11 +33,11 @@ public class APPPlusUtils { } PackageManager pm = context.getPackageManager(); - ComponentName plusComponentLaojun = new ComponentName(context, MainActivity.COMPONENT_LAOJUN); - ComponentName plusComponentWuKong = new ComponentName(context, MainActivity.COMPONENT_WUKONG); + ComponentName plusComponentLaojun = new ComponentName(context, App.COMPONENT_LAOJUN); + //ComponentName plusComponentWuKong = new ComponentName(context, MainActivity.COMPONENT_WUKONG); try { - disableComponent(pm, plusComponentWuKong); + //disableComponent(pm, plusComponentWuKong); enableComponent(pm, plusComponentLaojun); // 2. 创建 Laojun 组件对应的快捷方式(自动去重) @@ -75,11 +76,11 @@ public class APPPlusUtils { } PackageManager pm = context.getPackageManager(); - ComponentName plusComponentLaojun = new ComponentName(context, MainActivity.COMPONENT_LAOJUN); - ComponentName plusComponentWuKong = new ComponentName(context, MainActivity.COMPONENT_WUKONG); + ComponentName plusComponentLaojun = new ComponentName(context, App.COMPONENT_LAOJUN); + //ComponentName plusComponentWuKong = new ComponentName(context, MainActivity.COMPONENT_WUKONG); disableComponent(pm, plusComponentLaojun); - enableComponent(pm, plusComponentWuKong); + //enableComponent(pm, plusComponentWuKong); return true; } diff --git a/positions/src/main/java/cc/winboll/studio/positions/utils/ActivityAliasUtils.java b/positions/src/main/java/cc/winboll/studio/positions/utils/ActivityAliasUtils.java new file mode 100644 index 00000000..619e5e62 --- /dev/null +++ b/positions/src/main/java/cc/winboll/studio/positions/utils/ActivityAliasUtils.java @@ -0,0 +1,148 @@ +package cc.winboll.studio.positions.utils; + +import android.content.Context; +import android.content.Intent; +import android.content.pm.ActivityInfo; +import android.content.pm.PackageManager; +import android.text.TextUtils; +import cc.winboll.studio.libappbase.LogUtils; + +/** + * @Author ZhanGSKen&豆包大模型 + * @Date 2025/11/15 15:23 + * @Describe Activity Alias 工具类(兼容 Android 所有版本,Java 7 语法) + * 用于获取 activity-alias 对应的原始 Activity 组件名、判断 alias 类型、获取启动组件名等 + */ +public class ActivityAliasUtils { + private static final String TAG = "ActivityAliasUtils"; + + /** + * 获取 activity-alias 指向的原始 Activity 组件名 + * + * @param context 上下文(建议用 ApplicationContext) + * @param aliasName activity-alias 的组件名(完整路径,如 ".AliasActivity" 或 "com.winboll.app.AliasActivity") + * @return 原始 Activity 的完整组件名(如 "com.winboll.app.OriginalActivity"),失败返回 null + */ + public static String getTargetActivityName(Context context, String aliasName) { + // 校验参数 + if (context == null || TextUtils.isEmpty(aliasName)) { + LogUtils.e(TAG, "getTargetActivityName: context is null or aliasName is empty"); + return null; + } + + // 补全组件名(若传入的是短名,自动拼接包名) + String fullAliasName = aliasName.startsWith(".") + ? context.getPackageName() + aliasName + : aliasName; + + try { + // 1. 获取 PackageManager + PackageManager packageManager = context.getPackageManager(); + + // 2. 解析 activity-alias 的 ActivityInfo(flag 必须设为 PackageManager.GET_META_DATA,否则可能获取不到 targetActivity) + ActivityInfo aliasActivityInfo = packageManager.getActivityInfo( + new android.content.ComponentName(context.getPackageName(), fullAliasName), + PackageManager.GET_META_DATA + ); + + // 3. 获取 targetActivity(原始 Activity 组件名) + String targetActivity = aliasActivityInfo.targetActivity; + if (TextUtils.isEmpty(targetActivity)) { + LogUtils.e(TAG, "getTargetActivityName: targetActivity is empty for alias " + fullAliasName); + return null; + } + + // 4. 补全原始 Activity 的完整包名(若 targetActivity 是短名) + String fullTargetName = targetActivity.startsWith(".") + ? context.getPackageName() + targetActivity + : targetActivity; + + LogUtils.d(TAG, "getTargetActivityName: alias=" + fullAliasName + ", target=" + fullTargetName); + return fullTargetName; + + } catch (PackageManager.NameNotFoundException e) { + LogUtils.e(TAG, "getTargetActivityName: alias not found - " + fullAliasName, e); + } catch (Exception e) { + LogUtils.e(TAG, "getTargetActivityName: unknown error", e); + } + return null; + } + + /** + * 判断某个组件名是否为 activity-alias(而非原始 Activity) + * + * @param context 上下文 + * @param componentName 待判断的组件名(完整路径) + * @return true:是 activity-alias;false:不是或判断失败 + */ + public static boolean isActivityAlias(Context context, String componentName) { + // 调用 getTargetActivityName,若返回非空,则说明是 alias + return !TextUtils.isEmpty(getTargetActivityName(context, componentName)); + } + + /** + * 从启动的 Intent 中获取实际的目标组件名(处理 alias 场景) + * 适用于 Activity 中获取自身真实组件名(原始 Activity 名) + * + * @param context 当前 Activity 上下文 + * @return 真实的目标组件名(原始 Activity 名,若为 alias 启动则返回原始 Activity,否则返回自身) + */ + public static String getRealTargetNameFromIntent(Context context) { + if (context == null) { + LogUtils.e(TAG, "getRealTargetNameFromIntent: context is null"); + return null; + } + + // 获取当前 Activity 的组件名(可能是 alias) + String currentComponentName = context.getClass().getName(); + // 检查是否为 alias,若是则返回 target,否则返回自身 + String targetName = getTargetActivityName(context, currentComponentName); + return TextUtils.isEmpty(targetName) ? currentComponentName : targetName; + } + + /** + * 获取当前活动上下文(Activity)的启动组件名(即启动时使用的组件名,可能是 alias 或原始 Activity) + * 场景:若通过 alias 启动 Activity,返回 alias 名;若直接启动原始 Activity,返回原始 Activity 名 + * + * @param context 当前 Activity 上下文(必须是 Activity 实例,不能是 ApplicationContext) + * @return 启动组件的完整名,失败返回 null + */ + public static String getLaunchComponentName(Context context) { + // 1. 校验上下文类型(必须是 Activity,否则无法获取启动 Intent) + if (context == null) { + LogUtils.e(TAG, "getLaunchComponentName: context is null"); + return null; + } + if (!(context instanceof android.app.Activity)) { + LogUtils.e(TAG, "getLaunchComponentName: context must be Activity instance, current is " + context.getClass().getName()); + return null; + } + + try { + // 2. 获取启动当前 Activity 的 Intent + android.app.Activity activity = (android.app.Activity) context; + Intent launchIntent = activity.getIntent(); + if (launchIntent == null) { + LogUtils.e(TAG, "getLaunchComponentName: launch Intent is null"); + return null; + } + + // 3. 从 Intent 中获取启动组件名(ComponentName) + android.content.ComponentName componentName = launchIntent.getComponent(); + if (componentName == null) { + LogUtils.e(TAG, "getLaunchComponentName: ComponentName is null in launch Intent"); + return null; + } + + // 4. 获取组件的完整类名(即启动时使用的组件名) + String launchComponentName = componentName.getClassName(); + LogUtils.d(TAG, "getLaunchComponentName: current launch component is " + launchComponentName); + return launchComponentName; + + } catch (Exception e) { + LogUtils.e(TAG, "getLaunchComponentName: failed to get launch component name", e); + return null; + } + } +} + diff --git a/positions/src/main/java/cc/winboll/studio/positions/utils/AppConfigsUtil.java b/positions/src/main/java/cc/winboll/studio/positions/utils/AppConfigsUtil.java index 3110de71..97b728f9 100644 --- a/positions/src/main/java/cc/winboll/studio/positions/utils/AppConfigsUtil.java +++ b/positions/src/main/java/cc/winboll/studio/positions/utils/AppConfigsUtil.java @@ -1,6 +1,8 @@ package cc.winboll.studio.positions.utils; import android.content.Context; +import cc.winboll.studio.positions.AppLevel; import cc.winboll.studio.positions.models.AppConfigsModel; +import cc.winboll.studio.positions.App; /** * @Author ZhanGSKen&豆包大模型 @@ -58,11 +60,27 @@ public class AppConfigsUtil { } public void setIsEnableMainService(boolean isEnableMainService) { - if(mAppConfigsModel == null) { + if (mAppConfigsModel == null) { mAppConfigsModel = new AppConfigsModel(); } mAppConfigsModel.setIsEnableMainService(isEnableMainService); saveConfigs(); } + + public AppLevel getAppLevel(boolean isReloadConfigs) { + if (isReloadConfigs) { + loadConfigs(); + } + return (mAppConfigsModel == null) ?AppLevel.WUKONG: mAppConfigsModel.getAppLevel(); + } + + public void setAppLevel(AppLevel appLevel) { + if (mAppConfigsModel == null) { + mAppConfigsModel = new AppConfigsModel(); + } + App._mAppLevel = appLevel; + mAppConfigsModel.setAppLevel(appLevel); + saveConfigs(); + } } diff --git a/positions/src/main/java/cc/winboll/studio/positions/utils/MyActivityLifecycleCallbacks.java b/positions/src/main/java/cc/winboll/studio/positions/utils/MyActivityLifecycleCallbacks.java new file mode 100644 index 00000000..cfeb878d --- /dev/null +++ b/positions/src/main/java/cc/winboll/studio/positions/utils/MyActivityLifecycleCallbacks.java @@ -0,0 +1,105 @@ +package cc.winboll.studio.positions.utils; + +import android.app.Activity; +import android.app.Application; +import android.content.Intent; +import android.os.Bundle; +import cc.winboll.studio.libappbase.LogUtils; +import cc.winboll.studio.libappbase.ToastUtils; +import cc.winboll.studio.positions.PointLevel; +import cc.winboll.studio.positions.activities.WinBoLLActivity; + +/** + * @Author ZhanGSKen&豆包大模型 + * @Date 2025/11/15 15:59 + * @Describe 应用活动窗口状态响应类 + * 主要用于设置应用级别与组件状态 + */ +public class MyActivityLifecycleCallbacks implements Application.ActivityLifecycleCallbacks { + + public static final String TAG = "MyActivityLifecycleCallbacks"; + + public String mInfo = ""; + + public MyActivityLifecycleCallbacks() { + + } + + void createActivityeInfo(Activity activity) { + StringBuilder sb = new StringBuilder(); + Intent receivedIntent = activity.getIntent(); + sb.append("\nCallingActivity : \n"); + if (activity.getCallingActivity() != null) { + sb.append(activity.getCallingActivity().getPackageName()); + } + sb.append("\nReceived Intent Package : \n"); + sb.append(receivedIntent.getPackage()); + + Bundle extras = receivedIntent.getExtras(); + if (extras != null) { + for (String key : extras.keySet()) { + sb.append("\nIntentInfo"); + sb.append("\n键: "); + sb.append(key); + sb.append(", 值: "); + sb.append(extras.get(key)); + //Log.d("IntentInfo", "键: " + key + ", 值: " + extras.get(key)); + } + } + mInfo = sb.toString(); + //Log.d("IntentInfo", "发送Intent的应用包名: " + senderPackage); + } + + public void showActivityeInfo() { + //ToastUtils.show("ActivityeInfo : " + mInfo); + LogUtils.d(TAG, "ActivityeInfo : " + mInfo); + } + + @Override + public void onActivityCreated(Activity activity, Bundle savedInstanceState) { + // 在这里可以做一些初始化相关的操作,例如记录Activity的创建时间等 + //System.out.println(activity.getLocalClassName() + " was created"); + LogUtils.d(TAG, activity.getLocalClassName() + " was created"); + createActivityeInfo(activity); + } + + @Override + public void onActivityStarted(Activity activity) { + //System.out.println(activity.getLocalClassName() + " was started"); + LogUtils.d(TAG, activity.getLocalClassName() + " was started"); + //createActivityeInfo(activity); + } + + @Override + public void onActivityResumed(Activity activity) { + //System.out.println(activity.getLocalClassName() + " was resumed"); + LogUtils.d(TAG, activity.getLocalClassName() + " was resumed"); + //createActivityeInfo(activity); + } + + @Override + public void onActivityPaused(Activity activity) { + ToastUtils.show("Activity Paused"); + // 应用从正在活动状态抽离出来时,设置应用入口级别状态,设置为时空虚幻而不确定的哆啦A梦级别。 + WinBoLLActivity._mPointLevel = PointLevel.DORAEMON; + //System.out.println(activity.getLocalClassName() + " was paused"); + LogUtils.d(TAG, activity.getLocalClassName() + " was paused"); + } + + @Override + public void onActivityStopped(Activity activity) { + //System.out.println(activity.getLocalClassName() + " was stopped"); + LogUtils.d(TAG, activity.getLocalClassName() + " was stopped"); + } + + @Override + public void onActivitySaveInstanceState(Activity activity, Bundle outState) { + // 可以在这里添加保存状态的自定义逻辑 + } + + @Override + public void onActivityDestroyed(Activity activity) { + //System.out.println(activity.getLocalClassName() + " was destroyed"); + LogUtils.d(TAG, activity.getLocalClassName() + " was destroyed"); + } +} diff --git a/positions/src/main/java/cc/winboll/studio/positions/views/PositionTaskListView.java b/positions/src/main/java/cc/winboll/studio/positions/views/PositionTaskListView.java index 8478fc45..f0d147c9 100644 --- a/positions/src/main/java/cc/winboll/studio/positions/views/PositionTaskListView.java +++ b/positions/src/main/java/cc/winboll/studio/positions/views/PositionTaskListView.java @@ -35,6 +35,8 @@ import java.util.List; import java.util.Locale; import cc.winboll.studio.positions.App; import cc.winboll.studio.positions.AppLevel; +import cc.winboll.studio.positions.activities.WinBoLLActivity; +import cc.winboll.studio.positions.PointLevel; public class PositionTaskListView extends LinearLayout { // 视图模式常量 @@ -486,9 +488,9 @@ public class PositionTaskListView extends LinearLayout { Button btnCancel = dialogView.findViewById(R.id.btn_dialog_cancel); Button btnSave = dialogView.findViewById(R.id.btn_dialog_save); HourglassView hourglassView = dialogView.findViewById(R.id.hourglassView); - if (App._mAppLevel == AppLevel.WUKONG) { + if (WinBoLLActivity._mPointLevel == PointLevel.WUKONG) { hourglassView.setVisibility(View.GONE); - } else if (App._mAppLevel == AppLevel.WUKONG) { + } else if (WinBoLLActivity._mPointLevel == PointLevel.LAOJUN) { hourglassView.setHourglassId("hourglass_001"); hourglassView.setHour(1); hourglassView.setMinute(30); diff --git a/positions/src/main/res/xml/shortcutsmain.xml b/positions/src/main/res/xml/shortcutsmain.xml index 01aa3697..5c0c0b4f 100644 --- a/positions/src/main/res/xml/shortcutsmain.xml +++ b/positions/src/main/res/xml/shortcutsmain.xml @@ -9,9 +9,9 @@ android:shortcutLongLabel="@string/open_appplus" android:shortcutDisabledMessage="@string/appplus_open_disabled"> diff --git a/positions/src/main/res/xml/shortcutsplus.xml b/positions/src/main/res/xml/shortcutsplus.xml index cc820554..a38aa913 100644 --- a/positions/src/main/res/xml/shortcutsplus.xml +++ b/positions/src/main/res/xml/shortcutsplus.xml @@ -9,9 +9,9 @@ android:shortcutLongLabel="@string/close_appplus" android:shortcutDisabledMessage="@string/appplus_close_disabled">