From ab4cef21f0322980854a996b004a0e0fef3b3598 Mon Sep 17 00:00:00 2001 From: qinglong Date: Sun, 24 May 2026 10:00:01 +0800 Subject: [PATCH] =?UTF-8?q?=E5=90=88=E5=B9=B6=E6=A8=A1=E5=9D=97APPBase=20?= =?UTF-8?q?=E5=90=8C=E6=AD=A5=E6=9C=80=E6=96=B0=E6=97=B6=E9=97=B4=E6=A0=87?= =?UTF-8?q?=E7=AD=BEappbase-v15.20.21?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- appbase/build.properties | 8 +- libappbase/build.properties | 8 +- .../studio/libappbase/views/AboutView.java | 61 ++++++++- .../views/DebugSwitchInfoImageView.java | 127 ++++++++++++++++++ .../res/layout-night/layout_about_view.xml | 5 +- .../src/main/res/layout/layout_about_view.xml | 5 +- 6 files changed, 198 insertions(+), 16 deletions(-) create mode 100644 libappbase/src/main/java/cc/winboll/studio/libappbase/views/DebugSwitchInfoImageView.java diff --git a/appbase/build.properties b/appbase/build.properties index 0fab579..f2d536c 100644 --- a/appbase/build.properties +++ b/appbase/build.properties @@ -1,8 +1,8 @@ #Created by .winboll/winboll_app_build.gradle -#Wed May 20 16:12:13 HKT 2026 -stageCount=21 +#Sun May 24 09:53:05 HKT 2026 +stageCount=22 libraryProject=libappbase baseVersion=15.20 -publishVersion=15.20.20 +publishVersion=15.20.21 buildCount=0 -baseBetaVersion=15.20.21 +baseBetaVersion=15.20.22 diff --git a/libappbase/build.properties b/libappbase/build.properties index 0fab579..f2d536c 100644 --- a/libappbase/build.properties +++ b/libappbase/build.properties @@ -1,8 +1,8 @@ #Created by .winboll/winboll_app_build.gradle -#Wed May 20 16:12:13 HKT 2026 -stageCount=21 +#Sun May 24 09:53:05 HKT 2026 +stageCount=22 libraryProject=libappbase baseVersion=15.20 -publishVersion=15.20.20 +publishVersion=15.20.21 buildCount=0 -baseBetaVersion=15.20.21 +baseBetaVersion=15.20.22 diff --git a/libappbase/src/main/java/cc/winboll/studio/libappbase/views/AboutView.java b/libappbase/src/main/java/cc/winboll/studio/libappbase/views/AboutView.java index 050a8b6..633bd04 100644 --- a/libappbase/src/main/java/cc/winboll/studio/libappbase/views/AboutView.java +++ b/libappbase/src/main/java/cc/winboll/studio/libappbase/views/AboutView.java @@ -1,6 +1,8 @@ package cc.winboll.studio.libappbase.views; +import android.app.AlertDialog; import android.content.Context; +import android.content.DialogInterface; import android.content.Intent; import android.content.pm.PackageManager; import android.net.Uri; @@ -12,6 +14,7 @@ import android.widget.ImageButton; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; +import android.widget.Toast; import cc.winboll.studio.libappbase.GlobalApplication; import cc.winboll.studio.libappbase.LogUtils; import cc.winboll.studio.libappbase.R; @@ -74,12 +77,12 @@ public class AboutView extends LinearLayout { private EditText metDevUserPassword; // ===================================== 页面视图控件 ===================================== - private DebugSwitchImageView ivAppIcon; + private DebugSwitchInfoImageView ivAppIcon; private TextView tvAppNameVersion; private TextView tvAppDesc; private LinearLayout llFunctionContainer; private ImageButton ibSebugStepOver; - private ImageButton ibSigngetDialog; + private ImageButton ibDebugUnlock; private ImageButton ibWinBoLLHostDialog; // ===================================== 构造方法(按参数从少到多排序) ===================================== @@ -193,12 +196,12 @@ public class AboutView extends LinearLayout { llFunctionContainer = findViewById(R.id.ll_function_container); // 功能按钮绑定 ibSebugStepOver = findViewById(R.id.ib_debug_step_over); - ibSigngetDialog = findViewById(R.id.ib_signgetdialog); + ibDebugUnlock = findViewById(R.id.ib_debug_unlock); ibWinBoLLHostDialog = findViewById(R.id.ib_winbollhostdialog); // 调试按钮统一只在调试模式显示 ibWinBoLLHostDialog.setVisibility(GlobalApplication.isDebugging() ? View.VISIBLE : View.GONE); - //ibSigngetDialog.setVisibility(GlobalApplication.isDebugging() ? View.VISIBLE : View.GONE); + //ibDebugUnlock.setVisibility(GlobalApplication.isDebugging() ? View.VISIBLE : View.GONE); ibSebugStepOver.setVisibility(GlobalApplication.isDebugging() ? View.VISIBLE : View.GONE); // 绑定按钮点击事件 @@ -310,6 +313,47 @@ public class AboutView extends LinearLayout { LogUtils.d(TAG, "initAboutPageView():视图组装完成,功能项加载完毕"); } + // ===================================== 调试解锁弹窗 ===================================== + private void showDebugUnlockDialog() { + final AlertDialog dialog = new AlertDialog.Builder(mContext).create(); + dialog.setTitle("应用调试解锁"); + dialog.setCanceledOnTouchOutside(true); + + final EditText etToken = new EditText(mContext); + etToken.setHint("请输入调试Token"); + dialog.setView(etToken); + + dialog.setButton(DialogInterface.BUTTON_POSITIVE, "调试解锁", (DialogInterface.OnClickListener) null); + dialog.setButton(DialogInterface.BUTTON_NEGATIVE, "关闭", (DialogInterface.OnClickListener) null); + dialog.setOnShowListener(new DialogInterface.OnShowListener() { + @Override + public void onShow(DialogInterface d) { + dialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + String inputToken = etToken.getText().toString().trim(); + String savedToken = DebugSwitchInfoImageView.getDebugToken(); + if (savedToken != null && savedToken.equals(inputToken)) { + GlobalApplication.setIsDebugging(true); + GlobalApplication.saveDebugStatus(GlobalApplication.getInstance()); + Toast.makeText(mContext, "调试解锁成功,重启应用后生效", Toast.LENGTH_SHORT).show(); + } else { + Toast.makeText(mContext, "调试Token不匹配", Toast.LENGTH_SHORT).show(); + dialog.dismiss(); + } + } + }); + dialog.getButton(AlertDialog.BUTTON_NEGATIVE).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + dialog.dismiss(); + } + }); + } + }); + dialog.show(); + } + // ===================================== 内部工具/事件方法 ===================================== /** * 绑定功能按钮点击事件,处理正版校验、调试地址配置弹窗唤起 @@ -335,6 +379,15 @@ public class AboutView extends LinearLayout { new DebugHostDialog(mContext).show(); } }); + + // 应用调试解锁按钮 + ibDebugUnlock.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + LogUtils.d(TAG, "ibDebugUnlock onClick:弹出调试解锁对话框"); + showDebugUnlockDialog(); + } + }); LogUtils.d(TAG, "setBtnClickListener():功能按钮点击事件绑定完成"); } diff --git a/libappbase/src/main/java/cc/winboll/studio/libappbase/views/DebugSwitchInfoImageView.java b/libappbase/src/main/java/cc/winboll/studio/libappbase/views/DebugSwitchInfoImageView.java new file mode 100644 index 0000000..72679ed --- /dev/null +++ b/libappbase/src/main/java/cc/winboll/studio/libappbase/views/DebugSwitchInfoImageView.java @@ -0,0 +1,127 @@ +package cc.winboll.studio.libappbase.views; + +import android.app.AlertDialog; +import android.content.ClipData; +import android.content.ClipboardManager; +import android.content.Context; +import android.content.DialogInterface; +import android.content.SharedPreferences; +import android.util.AttributeSet; +import android.view.View; +import android.widget.ImageView; +import java.util.UUID; +import cc.winboll.studio.libappbase.GlobalApplication; + +/** + * @Author 豆包&ZhanGSKen + * @Date 2026/04/06 19:32 + * @Describe 应用Logo控件,连续点击6次弹出调试Token对话框,支持复制与重置 + */ +public class DebugSwitchInfoImageView extends ImageView { + + public static final String TAG = "DebugSwitchInfoImageView"; + + // 连续点击计数 + private int mClickCount = 0; + // 目标点击次数 + private static final int TARGET_CLICK_COUNT = 7; + + private static String mDebugToken = null; + private static final String SP_DEBUG_TOKEN = "debug_token_prefs"; + private static final String KEY_DEBUG_TOKEN = "debug_token"; + + public static String getDebugToken() { + if (mDebugToken != null) { + return mDebugToken; + } + Context context = GlobalApplication.getInstance(); + if (context != null) { + SharedPreferences sp = context.getSharedPreferences(SP_DEBUG_TOKEN, Context.MODE_PRIVATE); + mDebugToken = sp.getString(KEY_DEBUG_TOKEN, null); + if (mDebugToken == null) { + mDebugToken = UUID.randomUUID().toString(); + sp.edit().putString(KEY_DEBUG_TOKEN, mDebugToken).apply(); + } + } + return mDebugToken; + } + + public static void resetDebugToken() { + Context context = GlobalApplication.getInstance(); + if (context != null) { + mDebugToken = UUID.randomUUID().toString(); + SharedPreferences sp = context.getSharedPreferences(SP_DEBUG_TOKEN, Context.MODE_PRIVATE); + sp.edit().putString(KEY_DEBUG_TOKEN, mDebugToken).apply(); + } + } + + private void showDebugTokenDialog() { + final AlertDialog dialog = new AlertDialog.Builder(getContext()).create(); + dialog.setTitle("调试Token"); + dialog.setMessage(getDebugToken()); + dialog.setCanceledOnTouchOutside(true); + dialog.setButton(DialogInterface.BUTTON_POSITIVE, "复制到剪贴板", (DialogInterface.OnClickListener) null); + dialog.setButton(DialogInterface.BUTTON_NEUTRAL, "重置", (DialogInterface.OnClickListener) null); + dialog.setButton(DialogInterface.BUTTON_NEGATIVE, "关闭", (DialogInterface.OnClickListener) null); + dialog.setOnShowListener(new DialogInterface.OnShowListener() { + @Override + public void onShow(DialogInterface d) { + dialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + ClipboardManager cm = (ClipboardManager) getContext().getSystemService(Context.CLIPBOARD_SERVICE); + cm.setPrimaryClip(ClipData.newPlainText("DebugToken", getDebugToken())); + } + }); + dialog.getButton(AlertDialog.BUTTON_NEUTRAL).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + resetDebugToken(); + dialog.setMessage(getDebugToken()); + } + }); + dialog.getButton(AlertDialog.BUTTON_NEGATIVE).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + dialog.dismiss(); + } + }); + } + }); + dialog.show(); + } + + public DebugSwitchInfoImageView(Context context) { + super(context); + init(); + } + + public DebugSwitchInfoImageView(Context context, AttributeSet attrs) { + super(context, attrs); + init(); + } + + public DebugSwitchInfoImageView(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + init(); + } + + public DebugSwitchInfoImageView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { + super(context, attrs, defStyleAttr, defStyleRes); + init(); + } + + private void init() { + setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + mClickCount++; + if (mClickCount >= TARGET_CLICK_COUNT) { + mClickCount = 0; + showDebugTokenDialog(); + } + } + }); + } +} + diff --git a/libappbase/src/main/res/layout-night/layout_about_view.xml b/libappbase/src/main/res/layout-night/layout_about_view.xml index a1753ff..09db2eb 100644 --- a/libappbase/src/main/res/layout-night/layout_about_view.xml +++ b/libappbase/src/main/res/layout-night/layout_about_view.xml @@ -15,7 +15,7 @@ android:paddingRight="16dp" android:paddingBottom="16dp"> - diff --git a/libappbase/src/main/res/layout/layout_about_view.xml b/libappbase/src/main/res/layout/layout_about_view.xml index a1753ff..09db2eb 100644 --- a/libappbase/src/main/res/layout/layout_about_view.xml +++ b/libappbase/src/main/res/layout/layout_about_view.xml @@ -15,7 +15,7 @@ android:paddingRight="16dp" android:paddingBottom="16dp"> -