应用签名校验模块测试完成。
This commit is contained in:
@@ -1,8 +1,8 @@
|
|||||||
#Created by .winboll/winboll_app_build.gradle
|
#Created by .winboll/winboll_app_build.gradle
|
||||||
#Thu Jan 22 16:27:07 GMT 2026
|
#Thu Jan 22 19:08:20 GMT 2026
|
||||||
stageCount=7
|
stageCount=7
|
||||||
libraryProject=libappbase
|
libraryProject=libappbase
|
||||||
baseVersion=15.15
|
baseVersion=15.15
|
||||||
publishVersion=15.15.6
|
publishVersion=15.15.6
|
||||||
buildCount=18
|
buildCount=36
|
||||||
baseBetaVersion=15.15.7
|
baseBetaVersion=15.15.7
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
#Created by .winboll/winboll_app_build.gradle
|
#Created by .winboll/winboll_app_build.gradle
|
||||||
#Thu Jan 22 16:27:07 GMT 2026
|
#Thu Jan 22 19:08:20 GMT 2026
|
||||||
stageCount=7
|
stageCount=7
|
||||||
libraryProject=libappbase
|
libraryProject=libappbase
|
||||||
baseVersion=15.15
|
baseVersion=15.15
|
||||||
publishVersion=15.15.6
|
publishVersion=15.15.6
|
||||||
buildCount=18
|
buildCount=36
|
||||||
baseBetaVersion=15.15.7
|
baseBetaVersion=15.15.7
|
||||||
|
|||||||
@@ -82,20 +82,25 @@ public class GlobalApplication extends Application {
|
|||||||
public static boolean isDebugging() {
|
public static boolean isDebugging() {
|
||||||
return isDebugging;
|
return isDebugging;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 新增:设置 WinBoLL 服务器主机地址(同时保存到 SP 持久化)
|
// 新增:设置 WinBoLL 服务器主机地址(同时保存到 SP 持久化)
|
||||||
public static void setWinbollHost(String host) {
|
public static void setWinbollHost(String host) {
|
||||||
if (sInstance == null) {
|
if (sInstance == null) {
|
||||||
LogUtils.e(TAG, "setWinbollHost: 应用未初始化,设置失败");
|
LogUtils.e(TAG, "setWinbollHost: 应用未初始化,设置失败");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// 更新内存中的字段
|
// 检查并补全末尾 / 核心改动
|
||||||
winbollHost = host;
|
if (host != null && !host.isEmpty() && !host.endsWith("/")) {
|
||||||
// 保存到 SP 持久化(私有模式,安全)
|
host += "/";
|
||||||
SharedPreferences sp = sInstance.getSharedPreferences(SP_NAME, Context.MODE_PRIVATE);
|
}
|
||||||
sp.edit().putString(SP_KEY_WINBOLL_HOST, host).apply();
|
// 更新内存中的字段
|
||||||
LogUtils.d(TAG, "setWinbollHost: 服务器地址已设置并持久化,host=" + host);
|
winbollHost = host;
|
||||||
}
|
// 保存到 SP 持久化(私有模式,安全)
|
||||||
|
SharedPreferences sp = sInstance.getSharedPreferences(SP_NAME, Context.MODE_PRIVATE);
|
||||||
|
sp.edit().putString(SP_KEY_WINBOLL_HOST, host).apply();
|
||||||
|
LogUtils.d(TAG, "setWinbollHost: 服务器地址已设置并持久化,host=" + host);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// 新增:获取 WinBoLL 服务器主机地址(优先内存,内存为空则从 SP 读取)
|
// 新增:获取 WinBoLL 服务器主机地址(优先内存,内存为空则从 SP 读取)
|
||||||
public static String getWinbollHost() {
|
public static String getWinbollHost() {
|
||||||
@@ -109,7 +114,7 @@ public class GlobalApplication extends Application {
|
|||||||
}
|
}
|
||||||
// 内存中不存在,从 SP 读取并更新到内存
|
// 内存中不存在,从 SP 读取并更新到内存
|
||||||
SharedPreferences sp = sInstance.getSharedPreferences(SP_NAME, Context.MODE_PRIVATE);
|
SharedPreferences sp = sInstance.getSharedPreferences(SP_NAME, Context.MODE_PRIVATE);
|
||||||
winbollHost = sp.getString(SP_KEY_WINBOLL_HOST, null);
|
winbollHost = sp.getString(SP_KEY_WINBOLL_HOST, "https://console.winboll.cc/");
|
||||||
LogUtils.d(TAG, "getWinbollHost: 从 SP 读取服务器地址,host=" + winbollHost);
|
LogUtils.d(TAG, "getWinbollHost: 从 SP 读取服务器地址,host=" + winbollHost);
|
||||||
return winbollHost;
|
return winbollHost;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ public class DebugHostDialog extends Dialog implements View.OnClickListener {
|
|||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
setContentView(R.layout.dialog_debug_host); // 绑定XML布局
|
setContentView(R.layout.dialog_winboll_host); // 绑定XML布局
|
||||||
setCancelable(true); // 点击外部可关闭
|
setCancelable(true); // 点击外部可关闭
|
||||||
initView();
|
initView();
|
||||||
initData();
|
initData();
|
||||||
|
|||||||
@@ -27,8 +27,7 @@ import okhttp3.Response;
|
|||||||
public class APPUtils {
|
public class APPUtils {
|
||||||
public static final String TAG = "APPUtils";
|
public static final String TAG = "APPUtils";
|
||||||
// 网络校验接口地址
|
// 网络校验接口地址
|
||||||
private static final String CHECK_API_URL = "https://console.winboll.cc/api/app-signatures-check";
|
private static final String CHECK_API_URI = "api/app-signatures-check";
|
||||||
private static final String CHECK_API_URL_DEGUG = "http://localhost:8080/api/app-signatures-check";
|
|
||||||
// OKHTTP客户端(单例复用)
|
// OKHTTP客户端(单例复用)
|
||||||
private static OkHttpClient sOkHttpClient = new OkHttpClient();
|
private static OkHttpClient sOkHttpClient = new OkHttpClient();
|
||||||
// Gson解析实例
|
// Gson解析实例
|
||||||
@@ -62,7 +61,7 @@ public class APPUtils {
|
|||||||
|
|
||||||
// 3. 构建请求URL(拼接加密后的签名参数)
|
// 3. 构建请求URL(拼接加密后的签名参数)
|
||||||
String requestUrl = String.format("%s?signature=%s&validTime=%d",
|
String requestUrl = String.format("%s?signature=%s&validTime=%d",
|
||||||
GlobalApplication.isDebugging()?CHECK_API_URL_DEGUG:CHECK_API_URL,
|
GlobalApplication.getWinbollHost() + CHECK_API_URI,
|
||||||
encryptedSign, // 替换为加密后的签名
|
encryptedSign, // 替换为加密后的签名
|
||||||
certValidTime);
|
certValidTime);
|
||||||
LogUtils.d(TAG, "checkAppValid: 发起网络校验请求,URL=" + requestUrl);
|
LogUtils.d(TAG, "checkAppValid: 发起网络校验请求,URL=" + requestUrl);
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import cc.winboll.studio.libappbase.GlobalApplication;
|
|||||||
import cc.winboll.studio.libappbase.LogUtils;
|
import cc.winboll.studio.libappbase.LogUtils;
|
||||||
import cc.winboll.studio.libappbase.R;
|
import cc.winboll.studio.libappbase.R;
|
||||||
import cc.winboll.studio.libappbase.ToastUtils;
|
import cc.winboll.studio.libappbase.ToastUtils;
|
||||||
|
import cc.winboll.studio.libappbase.dialogs.DebugHostDialog;
|
||||||
import cc.winboll.studio.libappbase.dialogs.SignGetDialog;
|
import cc.winboll.studio.libappbase.dialogs.SignGetDialog;
|
||||||
import cc.winboll.studio.libappbase.models.APPInfo;
|
import cc.winboll.studio.libappbase.models.APPInfo;
|
||||||
|
|
||||||
@@ -128,6 +129,7 @@ public class AboutView extends LinearLayout {
|
|||||||
llFunctionContainer = findViewById(R.id.ll_function_container);
|
llFunctionContainer = findViewById(R.id.ll_function_container);
|
||||||
ibSigngetDialog = findViewById(R.id.ib_signgetdialog); // 新增按钮绑定
|
ibSigngetDialog = findViewById(R.id.ib_signgetdialog); // 新增按钮绑定
|
||||||
ibWinBoLLHostDialog = findViewById(R.id.ib_winbollhostdialog); // 新增按钮绑定
|
ibWinBoLLHostDialog = findViewById(R.id.ib_winbollhostdialog); // 新增按钮绑定
|
||||||
|
ibWinBoLLHostDialog.setVisibility(GlobalApplication.isDebugging()?View.VISIBLE:View.GONE);
|
||||||
setBtnClickListener(); // 新增绑定点击事件
|
setBtnClickListener(); // 新增绑定点击事件
|
||||||
LogUtils.d(TAG, "initViewFromXml 布局加载+视图绑定完成");
|
LogUtils.d(TAG, "initViewFromXml 布局加载+视图绑定完成");
|
||||||
}
|
}
|
||||||
@@ -141,6 +143,13 @@ public class AboutView extends LinearLayout {
|
|||||||
new SignGetDialog(mContext).show(); // 弹出对话框
|
new SignGetDialog(mContext).show(); // 弹出对话框
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
ibWinBoLLHostDialog.setOnClickListener(new OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
LogUtils.d(TAG, "签名获取按钮点击,弹出SignGetDialog");
|
||||||
|
new DebugHostDialog(mContext).show(); // 弹出对话框
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
android:padding="16dp"
|
android:padding="16dp"
|
||||||
@@ -19,7 +19,7 @@
|
|||||||
<!-- 地址输入框 -->
|
<!-- 地址输入框 -->
|
||||||
<EditText
|
<EditText
|
||||||
android:id="@+id/et_host_input"
|
android:id="@+id/et_host_input"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="300dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:hint="请输入服务器地址(如http://localhost:8080)"
|
android:hint="请输入服务器地址(如http://localhost:8080)"
|
||||||
android:textSize="14sp"
|
android:textSize="14sp"
|
||||||
@@ -1,11 +1,35 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<network-security-config>
|
<network-security-config>
|
||||||
<domain-config cleartextTrafficPermitted="true">
|
<domain-config cleartextTrafficPermitted="true">
|
||||||
<!-- 原有配置:允许 winboll.cc 及其子域名的明文流量 -->
|
<!-- 原有配置 保留 -->
|
||||||
<domain includeSubdomains="true">winboll.cc</domain>
|
<domain includeSubdomains="true">winboll.cc</domain>
|
||||||
<!-- 新增:允许 localhost 所有端口(* 匹配任意端口) -->
|
|
||||||
<domain includeSubdomains="true">localhost</domain>
|
<domain includeSubdomains="true">localhost</domain>
|
||||||
<domain includeSubdomains="true">127.0.0.1</domain> <!-- 兼容IP形式的本地地址 -->
|
<domain includeSubdomains="true">127.0.0.1</domain>
|
||||||
|
|
||||||
|
<!-- 精准配置10.8.0.0/24 前20个IP(10.8.0.0~10.8.0.19)-->
|
||||||
|
<domain includeSubdomains="false">10.8.0.0</domain>
|
||||||
|
<domain includeSubdomains="false">10.8.0.1</domain>
|
||||||
|
<domain includeSubdomains="false">10.8.0.2</domain>
|
||||||
|
<domain includeSubdomains="false">10.8.0.3</domain>
|
||||||
|
<domain includeSubdomains="false">10.8.0.4</domain>
|
||||||
|
<domain includeSubdomains="false">10.8.0.5</domain>
|
||||||
|
<domain includeSubdomains="false">10.8.0.6</domain>
|
||||||
|
<domain includeSubdomains="false">10.8.0.7</domain>
|
||||||
|
<domain includeSubdomains="false">10.8.0.8</domain>
|
||||||
|
<domain includeSubdomains="false">10.8.0.9</domain>
|
||||||
|
<domain includeSubdomains="false">10.8.0.10</domain>
|
||||||
|
<domain includeSubdomains="false">10.8.0.11</domain>
|
||||||
|
<domain includeSubdomains="false">10.8.0.12</domain>
|
||||||
|
<domain includeSubdomains="false">10.8.0.13</domain>
|
||||||
|
<domain includeSubdomains="false">10.8.0.14</domain>
|
||||||
|
<domain includeSubdomains="false">10.8.0.15</domain>
|
||||||
|
<domain includeSubdomains="false">10.8.0.16</domain>
|
||||||
|
<domain includeSubdomains="false">10.8.0.17</domain>
|
||||||
|
<domain includeSubdomains="false">10.8.0.18</domain>
|
||||||
|
<domain includeSubdomains="false">10.8.0.19</domain>
|
||||||
</domain-config>
|
</domain-config>
|
||||||
</network-security-config>
|
</network-security-config>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user