diff --git a/positions/build.properties b/positions/build.properties
index d46882a5..86aca6e3 100644
--- a/positions/build.properties
+++ b/positions/build.properties
@@ -1,8 +1,8 @@
#Created by .winboll/winboll_app_build.gradle
-#Mon Nov 10 00:53:37 GMT 2025
+#Mon Nov 10 03:35:32 GMT 2025
stageCount=18
libraryProject=
baseVersion=15.0
publishVersion=15.0.17
-buildCount=39
+buildCount=71
baseBetaVersion=15.0.18
diff --git a/positions/src/beta/res/xml/shortcuts.xml b/positions/src/beta/res/xml/shortcuts.xml
new file mode 100644
index 00000000..3b6d5865
--- /dev/null
+++ b/positions/src/beta/res/xml/shortcuts.xml
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/positions/src/main/AndroidManifest.xml b/positions/src/main/AndroidManifest.xml
index f0a8ba7e..e50e3a00 100644
--- a/positions/src/main/AndroidManifest.xml
+++ b/positions/src/main/AndroidManifest.xml
@@ -3,23 +3,14 @@
xmlns:android="http://schemas.android.com/apk/res/android"
package="cc.winboll.studio.positions">
-
+
-
-
-
-
-
-
-
-
-
-
+
+
-
-
-
-
-
-
-
-
-
-
+
+
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
+
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 8e7e5cbf..ebf92599 100644
--- a/positions/src/main/java/cc/winboll/studio/positions/MainActivity.java
+++ b/positions/src/main/java/cc/winboll/studio/positions/MainActivity.java
@@ -22,6 +22,7 @@ import cc.winboll.studio.positions.activities.LocationActivity;
import cc.winboll.studio.positions.activities.WinBoLLActivity;
import cc.winboll.studio.positions.utils.AppConfigsUtil;
import cc.winboll.studio.positions.utils.ServiceUtil;
+import cc.winboll.studio.positions.utils.AppIconSwitcher;
/**
* 主页面:仅负责
@@ -34,7 +35,7 @@ public class MainActivity extends WinBoLLActivity implements IWinBoLLActivity {
// 权限请求码(建议定义为类常量,避免魔法值)
private static final int REQUEST_LOCATION_PERMISSIONS = 1001;
private static final int REQUEST_BACKGROUND_LOCATION_PERMISSION = 1002;
-
+
// UI 控件:服务控制开关、顶部工具栏
private Switch mServiceSwitch;
private Button mManagePositionsButton;
@@ -82,6 +83,10 @@ public class MainActivity extends WinBoLLActivity implements IWinBoLLActivity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); // 关联主页面布局
+ // 处理应用级别的切换请求
+ handleSwitchRequest();
+
+ // 设置当前应用级别
App.setAppLevel(this);
// 1. 初始化顶部 Toolbar(保留原逻辑,设置页面标题)
@@ -95,7 +100,20 @@ public class MainActivity extends WinBoLLActivity implements IWinBoLLActivity {
// 4. 绑定服务(仅用于获取服务实时状态,不影响服务独立运行)
//bindDistanceService();
}
-
+
+ /**
+ * 处理快捷菜单的「切换入口」请求
+ */
+ private void handleSwitchRequest() {
+ Intent intent = getIntent();
+ if (intent != null && "switch_launcher_main".equals(intent.getDataString())) {
+ ToastUtils.show("应用级别切换到悟空笔记");
+ AppIconSwitcher.switchToWukongIcon(this);
+ } else if (intent != null && "switch_launcher_laojun".equals(intent.getDataString())) {
+ ToastUtils.show("應用級別切換到老君道說");
+ AppIconSwitcher.switchToLaojunIcon(this);
+ }
+ }
@Override
protected void onDestroy() {
@@ -117,8 +135,8 @@ public class MainActivity extends WinBoLLActivity implements IWinBoLLActivity {
setSupportActionBar(mToolbar);
// 给ActionBar设置标题(先判断非空,避免空指针异常)
/*if (getSupportActionBar() != null) {
- getSupportActionBar().setTitle(getString(R.string.app_name));
- }*/
+ getSupportActionBar().setTitle(getString(R.string.app_name));
+ }*/
}
/**
diff --git a/positions/src/main/java/cc/winboll/studio/positions/utils/AppIconSwitcher.java b/positions/src/main/java/cc/winboll/studio/positions/utils/AppIconSwitcher.java
new file mode 100644
index 00000000..535242b7
--- /dev/null
+++ b/positions/src/main/java/cc/winboll/studio/positions/utils/AppIconSwitcher.java
@@ -0,0 +1,222 @@
+package cc.winboll.studio.positions.utils;
+
+/**
+ * @Author ZhanGSKen&豆包大模型
+ * @Date 2025/11/10 09:51
+ * @Describe 应用图标切换工具类(启用组件时创建对应快捷方式)
+ */
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.os.Build;
+import android.util.Log;
+import android.widget.Toast;
+import cc.winboll.studio.positions.R;
+
+public class AppIconSwitcher {
+ public static final String TAG = "AppIconSwitcher";
+
+ // 组件名常量(需与 AndroidManifest 一致)
+ private static final String WUKONG_ACTIVITY = "cc.winboll.studio.positions.MainActivityWukong";
+ private static final String LAOJUN_ACTIVITY = "cc.winboll.studio.positions.MainActivityLaojun";
+
+ // 快捷方式配置(名称+图标,需与实际资源匹配)
+ private static final String WUKONG_SHORTCUT_NAME = "位置服务-Wukong";
+ private static final int WUKONG_SHORTCUT_ICON = R.drawable.ic_launcher; // Wukong 图标资源
+ private static final String LAOJUN_SHORTCUT_NAME = "位置服务-Laojun";
+ private static final int LAOJUN_SHORTCUT_ICON = R.mipmap.ic_launcher; // Laojun 图标资源
+
+ /**
+ * 切换到 Laojun 图标:禁用 Wukong,启用 Laojun + 创建 Laojun 快捷方式
+ */
+ public static boolean switchToLaojunIcon(Context context) {
+ if (context == null) {
+ Log.e(TAG, "切换失败:上下文为空");
+ Toast.makeText(context, "图标切换失败", Toast.LENGTH_SHORT).show();
+ return false;
+ }
+
+ PackageManager pm = context.getPackageManager();
+ ComponentName wukongComponent = new ComponentName(context, WUKONG_ACTIVITY);
+ ComponentName laojunComponent = new ComponentName(context, LAOJUN_ACTIVITY);
+
+ try {
+ // 1. 禁用 Wukong 组件,启用 Laojun 组件
+ disableComponent(pm, wukongComponent);
+ enableComponent(pm, laojunComponent);
+
+ // 2. 创建 Laojun 组件对应的快捷方式(自动去重)
+ boolean shortcutCreated = createComponentShortcut(context, laojunComponent, LAOJUN_SHORTCUT_NAME, LAOJUN_SHORTCUT_ICON);
+
+ // 3. 通知桌面刷新图标
+ context.sendBroadcast(new Intent(Intent.ACTION_PACKAGE_CHANGED)
+ .setData(android.net.Uri.parse("package:" + context.getPackageName())));
+
+ // 4. 反馈结果
+ String logMsg = shortcutCreated ? "启用 Laojun + 快捷方式创建成功" : "启用 Laojun 成功,快捷方式创建失败";
+ String toastMsg = shortcutCreated ? "图标切换为 Laojun,已创建快捷方式" : "图标切换为 Laojun,快捷方式创建失败";
+ Log.d(TAG, logMsg);
+ Toast.makeText(context, toastMsg, Toast.LENGTH_SHORT).show();
+
+ return true;
+
+ } catch (Exception e) {
+ Log.e(TAG, "Laojun 图标切换失败:" + e.getMessage());
+ // 失败兜底:启用 Wukong 组件
+ enableComponent(pm, wukongComponent);
+ Toast.makeText(context, "图标切换失败", Toast.LENGTH_SHORT).show();
+ return false;
+ }
+ }
+
+ /**
+ * 切换到 Wukong 图标:启用 Wukong,禁用 Laojun + 创建 Wukong 快捷方式
+ */
+ public static boolean switchToWukongIcon(Context context) {
+ if (context == null) {
+ Log.e(TAG, "切换失败:上下文为空");
+ Toast.makeText(context, "图标切换失败", Toast.LENGTH_SHORT).show();
+ return false;
+ }
+
+ PackageManager pm = context.getPackageManager();
+ ComponentName wukongComponent = new ComponentName(context, WUKONG_ACTIVITY);
+ ComponentName laojunComponent = new ComponentName(context, LAOJUN_ACTIVITY);
+
+ try {
+ // 1. 启用 Wukong 组件,禁用 Laojun 组件
+ enableComponent(pm, wukongComponent);
+ disableComponent(pm, laojunComponent);
+
+ // 2. 创建 Wukong 组件对应的快捷方式(自动去重)
+ boolean shortcutCreated = createComponentShortcut(context, wukongComponent, WUKONG_SHORTCUT_NAME, WUKONG_SHORTCUT_ICON);
+
+ // 3. 通知桌面刷新图标
+ context.sendBroadcast(new Intent(Intent.ACTION_PACKAGE_CHANGED)
+ .setData(android.net.Uri.parse("package:" + context.getPackageName())));
+
+ // 4. 反馈结果
+ String logMsg = shortcutCreated ? "启用 Wukong + 快捷方式创建成功" : "启用 Wukong 成功,快捷方式创建失败";
+ String toastMsg = shortcutCreated ? "图标切换为 Wukong,已创建快捷方式" : "图标切换为 Wukong,快捷方式创建失败";
+ Log.d(TAG, logMsg);
+ Toast.makeText(context, toastMsg, Toast.LENGTH_SHORT).show();
+
+ return true;
+
+ } catch (Exception e) {
+ Log.e(TAG, "Wukong 图标切换失败:" + e.getMessage());
+ // 失败兜底:启用 Wukong 组件
+ enableComponent(pm, wukongComponent);
+ Toast.makeText(context, "图标切换失败", Toast.LENGTH_SHORT).show();
+ return false;
+ }
+ }
+
+ /**
+ * 创建指定组件的桌面快捷方式(自动去重,兼容 Android 8.0+)
+ * @param component 目标组件(如 LAOJUN_ACTIVITY)
+ * @param name 快捷方式名称
+ * @param iconRes 快捷方式图标资源ID
+ * @return 是否创建成功
+ */
+ private static boolean createComponentShortcut(Context context, ComponentName component, String name, int iconRes) {
+ if (context == null || component == null || name == null || iconRes == 0) {
+ Log.e(TAG, "快捷方式创建失败:参数为空");
+ return false;
+ }
+
+ // Android 8.0+(API 26+):使用 ShortcutManager(系统推荐)
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+ try {
+ PackageManager pm = context.getPackageManager();
+ android.content.pm.ShortcutManager shortcutManager = context.getSystemService(android.content.pm.ShortcutManager.class);
+ if (shortcutManager == null || !shortcutManager.isRequestPinShortcutSupported()) {
+ Log.e(TAG, "系统不支持创建快捷方式");
+ return false;
+ }
+
+ // 检查是否已存在该组件的快捷方式(去重)
+ for (android.content.pm.ShortcutInfo info : shortcutManager.getPinnedShortcuts()) {
+ if (component.getClassName().equals(info.getIntent().getComponent().getClassName())) {
+ Log.d(TAG, "快捷方式已存在:" + component.getClassName());
+ return true;
+ }
+ }
+
+ // 构建启动目标组件的意图
+ Intent launchIntent = new Intent(Intent.ACTION_MAIN)
+ .setComponent(component)
+ .addCategory(Intent.CATEGORY_LAUNCHER)
+ .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
+
+ // 构建快捷方式信息
+ android.content.pm.ShortcutInfo shortcutInfo = new android.content.pm.ShortcutInfo.Builder(context, component.getClassName())
+ .setShortLabel(name)
+ .setLongLabel(name)
+ .setIcon(android.graphics.drawable.Icon.createWithResource(context, iconRes))
+ .setIntent(launchIntent)
+ .build();
+
+ // 请求创建快捷方式(需用户确认)
+ shortcutManager.requestPinShortcut(shortcutInfo, null);
+ return true;
+
+ } catch (Exception e) {
+ Log.e(TAG, "Android O+ 快捷方式创建失败:" + e.getMessage());
+ return false;
+ }
+ } else {
+ // Android 8.0 以下:使用广播(兼容旧机型)
+ try {
+ // 构建启动目标组件的意图
+ Intent launchIntent = new Intent(Intent.ACTION_MAIN)
+ .setComponent(component)
+ .addCategory(Intent.CATEGORY_LAUNCHER)
+ .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
+
+ // 构建创建快捷方式的广播意图
+ Intent installIntent = new Intent("com.android.launcher.action.INSTALL_SHORTCUT");
+ installIntent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, launchIntent);
+ installIntent.putExtra(Intent.EXTRA_SHORTCUT_NAME, name);
+ installIntent.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE,
+ Intent.ShortcutIconResource.fromContext(context, iconRes));
+ installIntent.putExtra("duplicate", false); // 禁止重复创建
+
+ context.sendBroadcast(installIntent);
+ return true;
+
+ } catch (Exception e) {
+ Log.e(TAG, "Android O- 快捷方式创建失败:" + e.getMessage());
+ return false;
+ }
+ }
+ }
+
+ /**
+ * 启用组件(带状态检查,避免重复操作)
+ */
+ private static void enableComponent(PackageManager pm, ComponentName component) {
+ if (pm.getComponentEnabledSetting(component) != PackageManager.COMPONENT_ENABLED_STATE_ENABLED) {
+ pm.setComponentEnabledSetting(
+ component,
+ PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
+ PackageManager.DONT_KILL_APP | PackageManager.SYNCHRONOUS
+ );
+ }
+ }
+
+ /**
+ * 禁用组件(带状态检查,避免重复操作)
+ */
+ private static void disableComponent(PackageManager pm, ComponentName component) {
+ if (pm.getComponentEnabledSetting(component) != PackageManager.COMPONENT_ENABLED_STATE_DISABLED) {
+ pm.setComponentEnabledSetting(
+ component,
+ PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
+ PackageManager.DONT_KILL_APP | PackageManager.SYNCHRONOUS
+ );
+ }
+ }
+}
+
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 5608dbf6..8478fc45 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
@@ -33,6 +33,8 @@ import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Locale;
+import cc.winboll.studio.positions.App;
+import cc.winboll.studio.positions.AppLevel;
public class PositionTaskListView extends LinearLayout {
// 视图模式常量
@@ -380,7 +382,7 @@ public class PositionTaskListView extends LinearLayout {
// 步骤3:刷新Adapter(局部刷新+范围通知,避免列表错乱)
notifyItemRemoved(position);
notifyItemRangeChanged(position, mAdapterData.size());
-
+
LogUtils.d(TAG, "Adapter已移除任务,刷新列表(位置索引=" + position + ")");
// 步骤4:通知外部(如Activity)任务已更新
@@ -457,7 +459,7 @@ public class PositionTaskListView extends LinearLayout {
}
});
}
-
+
private String genSelectedTimeText(long timeMillis) {
// 2. 格式化时间字符串(Java 7 用 SimpleDateFormat,需处理 ParseException)
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm", Locale.getDefault());
@@ -484,11 +486,15 @@ 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);
- hourglassView.setHourglassId("hourglass_001");
- hourglassView.setHour(1);
- hourglassView.setMinute(30);
- hourglassView.setEnabled(false); // 开启开关
-
+ if (App._mAppLevel == AppLevel.WUKONG) {
+ hourglassView.setVisibility(View.GONE);
+ } else if (App._mAppLevel == AppLevel.WUKONG) {
+ hourglassView.setHourglassId("hourglass_001");
+ hourglassView.setHour(1);
+ hourglassView.setMinute(30);
+ hourglassView.setEnabled(false); // 开启开关
+ }
+
// 绑定外层对话框内的控件
diff --git a/positions/src/main/res/values/strings.xml b/positions/src/main/res/values/strings.xml
index 68fdf541..4dfd1953 100644
--- a/positions/src/main/res/values/strings.xml
+++ b/positions/src/main/res/values/strings.xml
@@ -1,4 +1,7 @@
Positions
Positions
+ 切换到悟空笔记
+ 切换到老君道說
+ 切换功能不可用
diff --git a/positions/src/main/res/xml/shortcuts.xml b/positions/src/main/res/xml/shortcuts.xml
new file mode 100644
index 00000000..c14f0a72
--- /dev/null
+++ b/positions/src/main/res/xml/shortcuts.xml
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+