Compare commits

...

7 Commits

11 changed files with 152 additions and 52 deletions

View File

@@ -1,8 +1,8 @@
#Created by .winboll/winboll_app_build.gradle
#Wed Mar 25 20:36:14 HKT 2026
stageCount=15
#Mon Apr 06 20:39:30 HKT 2026
stageCount=18
libraryProject=libappbase
baseVersion=15.15
publishVersion=15.15.14
publishVersion=15.15.17
buildCount=0
baseBetaVersion=15.15.15
baseBetaVersion=15.15.18

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">AppBase+</string>
<string name="app_name">APPBase+</string>
</resources>

View File

@@ -46,7 +46,7 @@ public class AboutActivity extends Activity {
appInfo.setAppName(getString(R.string.app_name));
appInfo.setAppIcon(R.drawable.ic_winboll);
appInfo.setAppDescription(getString(R.string.app_description));
appInfo.setAppGitName("APPBase");
appInfo.setAppGitName("WinBoLL");
appInfo.setAppGitOwner("Studio");
appInfo.setAppGitAPPBranch(branchName);
appInfo.setAppGitAPPSubProjectFolder(branchName);

View File

@@ -21,9 +21,12 @@ public class App extends GlobalApplication {
*/
@Override
public void onCreate() {
super.onCreate(); // 调用父类初始化逻辑(如基础库配置、全局上下文设置)
//setIsDebugging(false);
setIsDebugging(BuildConfig.DEBUG);
super.onCreate();
// 如果应用不在调试状态,就根据编译类型设置调试状态
if (isDebugging() != true) {
setIsDebugging(BuildConfig.DEBUG);
}
// 初始化 Toast 工具类(传入应用全局上下文,确保 Toast 可在任意地方调用)
ToastUtils.init(getApplicationContext());
}

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">AppBase</string>
<string name="app_name">APPBase</string>
<string name="app_description">WinBoLL 安卓手机端安卓应用开发基础类库。</string>
<string name="app_normal">Click here is switch to Normal APP</string>
<string name="app_debug">Click here is switch to APP DEBUG</string>

View File

@@ -1,8 +1,8 @@
#Created by .winboll/winboll_app_build.gradle
#Wed Mar 25 20:36:14 HKT 2026
stageCount=15
#Mon Apr 06 20:39:30 HKT 2026
stageCount=18
libraryProject=libappbase
baseVersion=15.15
publishVersion=15.15.14
publishVersion=15.15.17
buildCount=0
baseBetaVersion=15.15.15
baseBetaVersion=15.15.18

View File

@@ -19,7 +19,7 @@ import cc.winboll.studio.libappbase.utils.ApkSignUtils;
* @LastEditTime 2026-01-24 18:45:00
* @Describe 签名显示+正版校验对话框展示应用签名字节位信息调用网络接口完成正版合法性校验实时返回校验结果
*/
public class AppValidationDialog extends Dialog {
public class APPValidationDialog extends Dialog {
// ===================================== 全局常量 =====================================
public static final String TAG = "AppValidationDialog";
// 签名字节位分组大小
@@ -37,7 +37,7 @@ public class AppValidationDialog extends Dialog {
private String clientHash;
// ===================================== 构造方法 =====================================
public AppValidationDialog(Context context, String projectName, String versionName) {
public APPValidationDialog(Context context, String projectName, String versionName) {
super(context, R.style.DialogStyle);
this.mContext = context;
this.projectName = projectName;

View File

@@ -18,7 +18,7 @@ import cc.winboll.studio.libappbase.LogUtils;
import cc.winboll.studio.libappbase.R;
import cc.winboll.studio.libappbase.ToastUtils;
import cc.winboll.studio.libappbase.dialogs.DebugHostDialog;
import cc.winboll.studio.libappbase.dialogs.AppValidationDialog;
import cc.winboll.studio.libappbase.dialogs.APPValidationDialog;
import cc.winboll.studio.libappbase.models.APPInfo;
/**
@@ -76,10 +76,11 @@ public class AboutView extends LinearLayout {
private EditText metDevUserPassword;
// ===================================== 页面视图控件 =====================================
private ImageView ivAppIcon;
private DebugSwitchImageView ivAppIcon;
private TextView tvAppNameVersion;
private TextView tvAppDesc;
private LinearLayout llFunctionContainer;
private ImageButton ibSebugStepOver;
private ImageButton ibSigngetDialog;
private ImageButton ibWinBoLLHostDialog;
@@ -128,10 +129,10 @@ public class AboutView extends LinearLayout {
return;
}
initDefaultParams();
initAppBaseInfo();
initAppVersionInfo();
initAPPBaseInfo();
initAPPVersionInfo();
initServerConfig();
initAppLinkInfo();
initAPPLinkInfo();
initReleaseAPKInfo();
initAboutPageView();
LogUtils.d(TAG, "initAll():所有初始化流程执行完成");
@@ -185,30 +186,35 @@ public class AboutView extends LinearLayout {
* 加载XML布局并绑定所有视图控件初始化按钮点击事件
*/
private void initViewFromXml() {
LogUtils.d(TAG, "initViewFromXml():开始加载布局并绑定控件");
View.inflate(mContext, R.layout.layout_about_view, this);
// 基础控件绑定
ivAppIcon = findViewById(R.id.iv_app_icon);
tvAppNameVersion = findViewById(R.id.tv_app_name_version);
tvAppDesc = findViewById(R.id.tv_app_desc);
llFunctionContainer = findViewById(R.id.ll_function_container);
// 功能按钮绑定
ibSigngetDialog = findViewById(R.id.ib_signgetdialog);
ibWinBoLLHostDialog = findViewById(R.id.ib_winbollhostdialog);
// 调试地址按钮动态显隐
ibWinBoLLHostDialog.setVisibility(GlobalApplication.isDebugging() ? View.VISIBLE : View.GONE);
// 绑定按钮点击事件
setBtnClickListener();
LogUtils.d(TAG, "initViewFromXml():布局加载+控件绑定+事件初始化完成");
}
LogUtils.d(TAG, "initViewFromXml():开始加载布局并绑定控件");
View.inflate(mContext, R.layout.layout_about_view, this);
// 基础控件绑定
ivAppIcon = findViewById(R.id.iv_app_icon);
tvAppNameVersion = findViewById(R.id.tv_app_name_version);
tvAppDesc = findViewById(R.id.tv_app_desc);
llFunctionContainer = findViewById(R.id.ll_function_container);
// 功能按钮绑定
ibSebugStepOver = findViewById(R.id.ib_debug_step_over);
ibSigngetDialog = findViewById(R.id.ib_signgetdialog);
ibWinBoLLHostDialog = findViewById(R.id.ib_winbollhostdialog);
// 调试按钮统一只在调试模式显示
ibWinBoLLHostDialog.setVisibility(GlobalApplication.isDebugging() ? View.VISIBLE : View.GONE);
//ibSigngetDialog.setVisibility(GlobalApplication.isDebugging() ? View.VISIBLE : View.GONE);
ibSebugStepOver.setVisibility(GlobalApplication.isDebugging() ? View.VISIBLE : View.GONE);
// 绑定按钮点击事件
setBtnClickListener();
LogUtils.d(TAG, "initViewFromXml():布局加载+控件绑定+事件初始化完成");
}
/**
* 从APPInfo实体读取应用基础核心配置赋值到本地属性
*/
private void initAppBaseInfo() {
LogUtils.d(TAG, "initAppBaseInfo()开始读取APPInfo基础配置");
private void initAPPBaseInfo() {
LogUtils.d(TAG, "initAPPBaseInfo()开始读取APPInfo基础配置");
if (mAPPInfo == null) {
LogUtils.w(TAG, "initAppBaseInfo()跳过执行APPInfo为null");
LogUtils.w(TAG, "initAPPBaseInfo()跳过执行APPInfo为null");
return;
}
mszAppName = mAPPInfo.getAppName() == null ? "" : mAPPInfo.getAppName();
@@ -218,22 +224,22 @@ public class AboutView extends LinearLayout {
mszAppDescription = mAPPInfo.getAppDescription() == null ? "" : mAPPInfo.getAppDescription();
mnAppIcon = (mAPPInfo.getAppIcon() != 0) ? mAPPInfo.getAppIcon() : mnAppIcon;
mIsAddDebugTools = mAPPInfo.isAddDebugTools();
LogUtils.d(TAG, "initAppBaseInfo():基础配置读取完成,应用名=" + mszAppName + ",调试开关=" + mIsAddDebugTools);
LogUtils.d(TAG, "initAPPBaseInfo():基础配置读取完成,应用名=" + mszAppName + ",调试开关=" + mIsAddDebugTools);
}
/**
* 从包管理中获取当前应用版本号,初始化版本相关信息
*/
private void initAppVersionInfo() {
LogUtils.d(TAG, "initAppVersionInfo():开始初始化应用版本信息");
private void initAPPVersionInfo() {
LogUtils.d(TAG, "initAPPVersionInfo():开始初始化应用版本信息");
try {
mszAppVersionName = mContext.getPackageManager().getPackageInfo(mContext.getPackageName(), 0).versionName;
} catch (PackageManager.NameNotFoundException e) {
LogUtils.e(TAG, "initAppVersionInfo()获取版本号失败默认赋值unknown", e);
LogUtils.e(TAG, "initAPPVersionInfo()获取版本号失败默认赋值unknown", e);
mszAppVersionName = "unknown";
}
mszCurrentAppPackageName = String.format("%s_%s.apk", mszAppVersionName, mszAppVersionName);
LogUtils.d(TAG, "initAppVersionInfo():版本信息初始化完成,版本号=" + mszAppVersionName + "当前APK名=" + mszCurrentAppPackageName);
LogUtils.d(TAG, "initAPPVersionInfo():版本信息初始化完成,版本号=" + mszAppVersionName + "当前APK名=" + mszCurrentAppPackageName);
}
/**
@@ -246,10 +252,10 @@ public class AboutView extends LinearLayout {
/**
* 初始化应用相关链接(主页+Git源码地址根据分支配置动态拼接Git地址
*/
private void initAppLinkInfo() {
LogUtils.d(TAG, "initAppLinkInfo():开始初始化应用链接信息");
private void initAPPLinkInfo() {
LogUtils.d(TAG, "initAPPLinkInfo():开始初始化应用链接信息");
if (mAPPInfo == null) {
LogUtils.w(TAG, "initAppLinkInfo()跳过执行APPInfo为null");
LogUtils.w(TAG, "initAPPLinkInfo()跳过执行APPInfo为null");
return;
}
mszHomePage = mAPPInfo.getAppHomePage() == null ? "" : mAPPInfo.getAppHomePage();
@@ -261,7 +267,7 @@ public class AboutView extends LinearLayout {
mAPPInfo.getAppGitOwner(), mszAppGitName,
mAPPInfo.getAppGitAPPBranch(), mAPPInfo.getAppGitAPPSubProjectFolder());
}
LogUtils.d(TAG, "initAppLinkInfo():链接信息初始化完成,应用主页=" + mszHomePage + "Git地址=" + mszGitea);
LogUtils.d(TAG, "initAPPLinkInfo():链接信息初始化完成,应用主页=" + mszHomePage + "Git地址=" + mszGitea);
}
/**
@@ -312,12 +318,22 @@ public class AboutView extends LinearLayout {
*/
private void setBtnClickListener() {
LogUtils.d(TAG, "setBtnClickListener():开始绑定功能按钮点击事件");
// 正版校验弹窗
// 取消调试状态按钮
ibSebugStepOver.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
LogUtils.d(TAG, "ibSebugStepOver onClick取消调试状态按钮已点击");
GlobalApplication.setIsDebugging(false);
GlobalApplication.saveDebugStatus(GlobalApplication.getInstance());
ToastUtils.show("已取消调试状态,重启应用可生效。");
}
});
// 正版校验弹窗
ibSigngetDialog.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
LogUtils.d(TAG, "ibSigngetDialog onClick唤起应用正版校验弹窗");
new AppValidationDialog(mContext, mszAppGitName, mszAppVersionName).show();
new APPValidationDialog(mContext, mszAppGitName, mszAppVersionName).show();
}
});
// 调试地址配置弹窗

View File

@@ -0,0 +1,61 @@
package cc.winboll.studio.libappbase.views;
import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.widget.ImageView;
import android.widget.Toast;
import cc.winboll.studio.libappbase.GlobalApplication;
/**
* @Author 豆包&ZhanGSKen<zhangsken@qq.com>
* @Date 2026/04/06 19:32
* @Describe 具有调试模式切换功能的应用Logo控件连续点击10次弹出提示
*/
public class DebugSwitchImageView extends ImageView {
public static final String TAG = "DebugSwitchImageView";
// 连续点击计数
private int mClickCount = 0;
// 目标点击次数
private static final int TARGET_CLICK_COUNT = 10;
public DebugSwitchImageView(Context context) {
super(context);
init();
}
public DebugSwitchImageView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public DebugSwitchImageView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
public DebugSwitchImageView(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) {
// 达到10次弹出Toast
Toast.makeText(getContext(), "连续点击已达到10次现在开启应用调试功能。", Toast.LENGTH_SHORT).show();
GlobalApplication.setIsDebugging(true);
GlobalApplication.saveDebugStatus(GlobalApplication.getInstance());
// 重置计数,可再次触发
mClickCount = 0;
}
}
});
}
}

View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportHeight="24"
android:viewportWidth="24">
<path
android:fillColor="#ff000000"
android:pathData="M19,7H16.19C15.74,6.2 15.12,5.5 14.37,5L16,3.41L14.59,2L12.42,4.17C11.96,4.06 11.5,4 11,4S10.05,4.06 9.59,4.17L7.41,2L6,3.41L7.62,5C6.87,5.5 6.26,6.21 5.81,7H3V9H5.09C5.03,9.33 5,9.66 5,10V11H3V13H5V14C5,14.34 5.03,14.67 5.09,15H3V17H5.81C7.26,19.5 10.28,20.61 13,19.65V19C13,18.43 13.09,17.86 13.25,17.31C12.59,17.76 11.8,18 11,18C8.79,18 7,16.21 7,14V10C7,7.79 8.79,6 11,6S15,7.79 15,10V14C15,14.19 15,14.39 14.95,14.58C15.54,14.04 16.24,13.62 17,13.35V13H19V11H17V10C17,9.66 16.97,9.33 16.91,9H19V7M13,9V11H9V9H13M13,13V15H9V13H13M16,16H22V22H16V16Z"/>
</vector>

View File

@@ -14,7 +14,7 @@
android:paddingRight="16dp"
android:paddingBottom="32dp">
<ImageView
<cc.winboll.studio.libappbase.views.DebugSwitchImageView
android:id="@+id/iv_app_icon"
android:layout_width="48dp"
android:layout_height="48dp"
@@ -58,6 +58,15 @@
android:layout_marginTop="16dp"
android:spacing="20dp">
<ImageButton
android:layout_width="48dp"
android:layout_height="48dp"
android:src="@drawable/ic_debug_step_over"
android:id="@+id/ib_debug_step_over"
android:scaleType="fitCenter"
android:adjustViewBounds="true"
android:background="@null"/>
<ImageButton
android:layout_width="48dp"
android:layout_height="48dp"