diff --git a/.idea/jarRepositories.xml b/.idea/jarRepositories.xml
index 9c83340..511d6b9 100644
--- a/.idea/jarRepositories.xml
+++ b/.idea/jarRepositories.xml
@@ -61,5 +61,10 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/build.gradle b/app/build.gradle
index a0dec4d..cb3d5ea 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -105,8 +105,10 @@ dependencies {
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
implementation 'com.squareup.retrofit2:retrofit:2.5.0'
implementation 'com.squareup.retrofit2:converter-gson:2.5.0'
- implementation 'com.squareup.okhttp3:okhttp:4.9.0'
- implementation 'com.lzy.net:okgo:3.0.4'
+ implementation 'com.squareup.okhttp3:okhttp:4.9.3'
+ implementation ('com.lzy.net:okgo:3.0.4') {
+ exclude group: 'com.squareup.okhttp3' // 排除 OkGo 自带的 OkHttp 3.8.1
+ }
implementation 'org.greenrobot:eventbus:3.1.1'
implementation 'com.alibaba:arouter-api:1.5.0'
implementation 'com.github.bumptech.glide:glide:4.9.0'
diff --git a/app/src/main/java/qianmu/container/app/Constant.java b/app/src/main/java/qianmu/container/app/Constant.java
index 7615668..1d05948 100644
--- a/app/src/main/java/qianmu/container/app/Constant.java
+++ b/app/src/main/java/qianmu/container/app/Constant.java
@@ -25,8 +25,8 @@ public class Constant {
// public static String androidBoardType = ""; //设备板子型号 无固定版
// public static String androidBoardType = "ys"; // 设备板子型号 ys(亿晟) 北京颐堤港定制touch
// public static String androidBoardType = "xwst"; //设备板子型号 xwst(欣威视通3399)
- // public static String androidBoardType = "xwst2"; //设备板子型号 xwst2(欣威视通3588、T982、3576)
- public static String androidBoardType = "zc"; //设备板子型号 zc(卓策主板——王府井喜悦、杨浦中心医院)
+ public static String androidBoardType = "xwst2"; //设备板子型号 xwst2(欣威视通3588、T982、3576)
+ // public static String androidBoardType = "zc"; //设备板子型号 zc(卓策主板——王府井喜悦、杨浦中心医院)
// public static String androidBoardType = "sx"; //设备板子型号 sx(视想)
// public static String androidBoardType = "nova"; //设备板子型号 诺瓦盒子 华贸LED
// public static String androidBoardType = "huidu"; //设备板子型号 huidu(灰度主板) 罗湖寻车机
diff --git a/app/src/main/java/qianmu/container/app/MyApplication.java b/app/src/main/java/qianmu/container/app/MyApplication.java
index a35e0be..b97ee56 100644
--- a/app/src/main/java/qianmu/container/app/MyApplication.java
+++ b/app/src/main/java/qianmu/container/app/MyApplication.java
@@ -114,59 +114,22 @@ public class MyApplication extends Application {
}
}
- // private RefWatcher refWatcher;
- // public static RefWatcher getRefWatcher(Context context) {
- // MyApplication application = (MyApplication) context.getApplicationContext();
- // return application.refWatcher;
- // }
-
// 初始化下载框架
private void initOkGo() {
try {
int currentApiVersion = android.os.Build.VERSION.SDK_INT;
- OkHttpClient client;
- try{
- OkHttpClient.Builder builder = new OkHttpClient.Builder();
- builder.readTimeout(10, TimeUnit.SECONDS);
- builder.writeTimeout(10, TimeUnit.SECONDS);
- builder.connectTimeout(10, TimeUnit.SECONDS);
- builder.sslSocketFactory(SSLSocketClient.getSSLSocketFactory());// 过滤https证书
- builder.hostnameVerifier(SSLSocketClient.getHostnameVerifier());
- client = builder.build();
- } catch(Exception e) {
- client = createOkHttpClient(this);
- }
+ OkHttpClient.Builder builder = new OkHttpClient.Builder();
+ builder.readTimeout(10, TimeUnit.SECONDS);
+ builder.writeTimeout(10, TimeUnit.SECONDS);
+ builder.connectTimeout(10, TimeUnit.SECONDS);
+ builder.sslSocketFactory(SSLSocketClient.getSSLSocketFactory(), SSLSocketClient.getX509TrustManager());
+ builder.hostnameVerifier(SSLSocketClient.getHostnameVerifier());
+ OkHttpClient client = builder.build();
OkGo.getInstance().init(this).setOkHttpClient(client).setRetryCount(0);
} catch (Throwable t) {
LoggerUtil.e("initOkGo", StringUtil.getThrowableStr(t));
}
}
-
- public OkHttpClient createOkHttpClient(Context context) {
- try {
- // 获取系统默认信任管理器
- TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(
- TrustManagerFactory.getDefaultAlgorithm());
- trustManagerFactory.init((KeyStore) null);
- TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
- X509TrustManager trustManager = (X509TrustManager) trustManagers[0];
-
- // 初始化 SSL 上下文
- SSLContext sslContext = SSLContext.getInstance("TLS");
- sslContext.init(null, new TrustManager[]{trustManager}, null);
-
- // 构建 OkHttpClient(3.x 版本同样需要显式传入 trustManager)
- return new OkHttpClient.Builder()
- .sslSocketFactory(sslContext.getSocketFactory(), trustManager) // 关键
- .connectTimeout(15, TimeUnit.SECONDS)
- .readTimeout(15, TimeUnit.SECONDS)
- .writeTimeout(15, TimeUnit.SECONDS)
- .build();
- } catch (Exception e) {
- throw new RuntimeException("OkHttp 初始化失败", e);
- }
- }
-
// 页面常亮
private void initWakeLock() {
powerManager = (PowerManager) this.getSystemService(Service.POWER_SERVICE);
diff --git a/app/src/main/java/qianmu/container/http/retrofit/RetrofitUtil.java b/app/src/main/java/qianmu/container/http/retrofit/RetrofitUtil.java
index 535ed3d..7dbf264 100644
--- a/app/src/main/java/qianmu/container/http/retrofit/RetrofitUtil.java
+++ b/app/src/main/java/qianmu/container/http/retrofit/RetrofitUtil.java
@@ -13,6 +13,7 @@ import javax.net.ssl.X509TrustManager;
import okhttp3.OkHttpClient;
import qianmu.container.app.Constant;
import qianmu.container.util.LoggerUtil;
+import qianmu.container.util.SSLSocketClient;
import qianmu.container.util.StringUtil;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
@@ -35,28 +36,9 @@ public class RetrofitUtil {
private static OkHttpClient initOkHttpClient(int timeout) {
try {
- final TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() {
- @Override
- public void checkClientTrusted(X509Certificate[] chain, String authType) {
- }
-
- @Override
- public void checkServerTrusted(X509Certificate[] chain, String authType) {
- }
-
- @Override
- public X509Certificate[] getAcceptedIssuers() {
- return new X509Certificate[0];
- }
- }};
- final SSLContext sslContext = SSLContext.getInstance("TLS");
- sslContext.init(null, trustAllCerts, new SecureRandom());
- final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
-
- return new OkHttpClient.Builder().sslSocketFactory(sslSocketFactory)
+ return new OkHttpClient.Builder().sslSocketFactory(SSLSocketClient.getSSLSocketFactory(), SSLSocketClient.getX509TrustManager())
.retryOnConnectionFailure(true)
-// .addInterceptor(new BaseInterceptor())
- .hostnameVerifier(org.apache.http.conn.ssl.SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER)
+ .hostnameVerifier(SSLSocketClient.getHostnameVerifier())
.connectTimeout(timeout, TimeUnit.SECONDS).readTimeout(timeout, TimeUnit.SECONDS)
.writeTimeout(timeout, TimeUnit.SECONDS).build();
} catch (Throwable t) {
diff --git a/app/src/main/java/qianmu/container/mqtt/MQTTService.java b/app/src/main/java/qianmu/container/mqtt/MQTTService.java
index 8311d06..3b305ca 100644
--- a/app/src/main/java/qianmu/container/mqtt/MQTTService.java
+++ b/app/src/main/java/qianmu/container/mqtt/MQTTService.java
@@ -182,8 +182,9 @@ public class MQTTService extends Service {
// 用户名
conOpt.setUserName(userName);
// 密码
- conOpt.setPassword(passWord.toCharArray()); //将字符串转换为字符串数组
-
+ if(!StringUtil.isEmpty(passWord)){
+ conOpt.setPassword(passWord.toCharArray()); //将字符串转换为字符串数组
+ }
// conOpt.setAutomaticReconnect(true);
// last will message
diff --git a/app/src/main/java/qianmu/container/socket/CustomSSLSocketFactory.java b/app/src/main/java/qianmu/container/socket/CustomSSLSocketFactory.java
new file mode 100644
index 0000000..1323fe0
--- /dev/null
+++ b/app/src/main/java/qianmu/container/socket/CustomSSLSocketFactory.java
@@ -0,0 +1,66 @@
+package qianmu.container.socket;
+
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.Socket;
+import java.net.UnknownHostException;
+import javax.net.ssl.SSLSocket;
+import javax.net.ssl.SSLSocketFactory;
+
+public class CustomSSLSocketFactory extends SSLSocketFactory {
+ private final SSLSocketFactory delegate;
+
+ public CustomSSLSocketFactory(SSLSocketFactory delegate) {
+ this.delegate = delegate;
+ }
+
+ @Override
+ public String[] getDefaultCipherSuites() {
+ return delegate.getDefaultCipherSuites();
+ }
+
+ @Override
+ public String[] getSupportedCipherSuites() {
+ return delegate.getSupportedCipherSuites();
+ }
+
+ @Override
+ public Socket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException {
+ Socket socket = delegate.createSocket(s, host, port, autoClose);
+ return wrapSocket(socket);
+ }
+
+ @Override
+ public Socket createSocket(String host, int port) throws IOException, UnknownHostException {
+ Socket socket = delegate.createSocket(host, port);
+ return wrapSocket(socket);
+ }
+
+ @Override
+ public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException, UnknownHostException {
+ Socket socket = delegate.createSocket(host, port, localHost, localPort);
+ return wrapSocket(socket);
+ }
+
+ @Override
+ public Socket createSocket(InetAddress host, int port) throws IOException {
+ Socket socket = delegate.createSocket(host, port);
+ return wrapSocket(socket);
+ }
+
+ @Override
+ public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException {
+ Socket socket = delegate.createSocket(address, port, localAddress, localPort);
+ return wrapSocket(socket);
+ }
+
+ // 关键:包装 Socket,确保使用我们的 TrustManager 逻辑
+ private Socket wrapSocket(Socket socket) {
+ if (socket instanceof SSLSocket) {
+ // 可在此处强制设置 TLS 版本等参数(如 Android 14 要求的 TLSv1.2+)
+ ((SSLSocket) socket).setEnabledProtocols(new String[]{"TLSv1.2", "TLSv1.3"});
+ }
+ return socket;
+ }
+}
diff --git a/app/src/main/java/qianmu/container/util/SSLSocketClient.java b/app/src/main/java/qianmu/container/util/SSLSocketClient.java
index 9570830..f4c53a2 100644
--- a/app/src/main/java/qianmu/container/util/SSLSocketClient.java
+++ b/app/src/main/java/qianmu/container/util/SSLSocketClient.java
@@ -1,15 +1,22 @@
package qianmu.container.util;
+import android.annotation.SuppressLint;
+
+import java.security.KeyStore;
import java.security.SecureRandom;
import java.security.cert.X509Certificate;
+import java.util.Arrays;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
+import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;
+import qianmu.container.socket.CustomSSLSocketFactory;
+
/**
* Created by Android Studio.
* User: linzhibin
@@ -18,47 +25,43 @@ import javax.net.ssl.X509TrustManager;
*/
public class SSLSocketClient {
- //获取这个SSLSocketFactory
+ // 全局唯一 TrustManager(必须与 SSLSocketFactory 绑定)
+ private static final X509TrustManager X509 = new X509TrustManager() {
+ @SuppressLint("TrustAllX509TrustManager")
+ @Override
+ public void checkClientTrusted(X509Certificate[] chain, String authType) {}
+
+ @SuppressLint("TrustAllX509TrustManager")
+ @Override
+ public void checkServerTrusted(X509Certificate[] chain, String authType) {}
+
+ @Override
+ public X509Certificate[] getAcceptedIssuers() {
+ return new X509Certificate[0];
+ }
+ };
+
+ // 获取包装后的 SSLSocketFactory(强制绑定 TrustManager)
public static SSLSocketFactory getSSLSocketFactory() {
try {
- SSLContext sslContext = SSLContext.getInstance("SSL");
- sslContext.init(null, getTrustManager(), new SecureRandom());
- return sslContext.getSocketFactory();
+ // 1. 使用 TLSv1.2 协议(Android 14 强制要求)
+ SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
+ // 2. 绑定我们的 TrustManager
+ sslContext.init(null, new TrustManager[]{X509}, new SecureRandom());
+ // 3. 用自定义类包装,避免系统替换
+ return new CustomSSLSocketFactory(sslContext.getSocketFactory());
} catch (Exception e) {
- throw new RuntimeException(e);
+ throw new RuntimeException("创建 SSLSocketFactory 失败", e);
}
}
- //获取TrustManager
- public static TrustManager[] getTrustManager() {
- TrustManager[] trustAllCerts = new TrustManager[]{
- new X509TrustManager() {
- @Override
- public void checkClientTrusted(X509Certificate[] chain, String authType) {
- }
-
- @Override
- public void checkServerTrusted(X509Certificate[] chain, String authType) {
- }
-
- @Override
- public X509Certificate[] getAcceptedIssuers() {
- return new X509Certificate[0];
- }
- }
- };
- return trustAllCerts;
+ // 获取 HostnameVerifier
+ public static HostnameVerifier getHostnameVerifier() {
+ return (s, sslSession) -> true; // 生产环境需严格校验
}
- //获取HostnameVerifier
- public static HostnameVerifier getHostnameVerifier() {
- HostnameVerifier hostnameVerifier = new HostnameVerifier() {
- @Override
- public boolean verify(String s, SSLSession sslSession) {
- return true;
- }
- };
- return hostnameVerifier;
+ // 暴露 TrustManager 供 OkHttp 绑定
+ public static X509TrustManager getX509TrustManager() {
+ return X509;
}
-
}