1.发布新包

This commit is contained in:
2025-10-13 09:22:04 +08:00
parent 85756d85c6
commit 22c4e40d24
7 changed files with 283 additions and 5 deletions

View File

@@ -260,8 +260,7 @@
android:id="@+id/iv_login_bg" android:id="@+id/iv_login_bg"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="@dimen/dp_42" android:layout_height="@dimen/dp_42"
android:src="@drawable/theme_bg" android:src="@drawable/theme_bg" />
/>
<TextView <TextView
android:layout_width="wrap_content" android:layout_width="wrap_content"

View File

@@ -29,7 +29,7 @@ isBuildModule=false
android.injected.testOnly=false android.injected.testOnly=false
APP_VERSION_NAME=1.2.7 APP_VERSION_NAME=1.2.7
APP_VERSION_CODE=180 APP_VERSION_CODE=181
org.gradle.jvm.toolchain.useLegacyAdapters=false org.gradle.jvm.toolchain.useLegacyAdapters=false
#org.gradle.java.home=C\:\\Users\\qx\\.jdks\\ms-17.0.15 #org.gradle.java.home=C\:\\Users\\qx\\.jdks\\ms-17.0.15

View File

@@ -108,7 +108,7 @@ public class RetrofitClient {
sslContext.init(null, new TrustManager[]{trustAllCert}, new SecureRandom()); sslContext.init(null, new TrustManager[]{trustAllCert}, new SecureRandom());
final OkHttpClient client = new OkHttpClient.Builder() final OkHttpClient client = new OkHttpClient.Builder()
// .addInterceptor(new LoggerInterceptor("HttpLog", true)) // .addInterceptor(new LogInterceptor())
.addInterceptor(new DataLoggingInterceptor(new DataLogger())) .addInterceptor(new DataLoggingInterceptor(new DataLogger()))
.addInterceptor(new AccessTokenInterceptor(headers)) .addInterceptor(new AccessTokenInterceptor(headers))
.proxy(Proxy.NO_PROXY) .proxy(Proxy.NO_PROXY)

View File

@@ -867,7 +867,7 @@ public class AgoraManager {
VD_360x360, VD_360x360,
FRAME_RATE_FPS_15, FRAME_RATE_FPS_15,
STANDARD_BITRATE, STANDARD_BITRATE,
ORIENTATION_MODE_FIXED_PORTRAIT ORIENTATION_MODE_ADAPTIVE
)); ));
rtcEngine.startScreenCapture(screenCaptureParameters); rtcEngine.startScreenCapture(screenCaptureParameters);

View File

@@ -0,0 +1,276 @@
package com.xscm.moduleutil.utils.logger;
import android.util.Log;
import androidx.annotation.NonNull;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.TimeUnit;
import okhttp3.Interceptor;
import okhttp3.MediaType;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import okhttp3.ResponseBody;
import okhttp3.internal.http.HttpHeaders;
import okio.Buffer;
import okio.BufferedSource;
/**
* OkHttp 日志拦截器,用于打印请求和响应详情
*/
public class LogInterceptor implements Interceptor {
private static final String TAG = "NetworkLog";
private static final Charset UTF8 = StandardCharsets.UTF_8;
// 日志开关可根据debug/release环境动态设置
private boolean isLogEnabled = true;
// 是否打印请求体
private boolean logRequestBody = true;
// 是否打印响应体
private boolean logResponseBody = true;
// 最大日志长度(避免过大的响应体导致日志刷屏)
private int maxLogLength = 2048;
public LogInterceptor() {
}
// 配置方法
public LogInterceptor setLogEnabled(boolean enabled) {
isLogEnabled = enabled;
return this;
}
public LogInterceptor setLogRequestBody(boolean logRequestBody) {
this.logRequestBody = logRequestBody;
return this;
}
public LogInterceptor setLogResponseBody(boolean logResponseBody) {
this.logResponseBody = logResponseBody;
return this;
}
public LogInterceptor setMaxLogLength(int maxLogLength) {
this.maxLogLength = maxLogLength;
return this;
}
@NonNull
@Override
public Response intercept(@NonNull Chain chain) throws IOException {
if (!isLogEnabled) {
return chain.proceed(chain.request());
}
Request request = chain.request();
// 打印请求日志
logRequest(request);
// 记录请求开始时间,用于计算耗时
long startNs = System.nanoTime();
Response response;
try {
response = chain.proceed(request);
} catch (Exception e) {
// 打印请求异常
Log.e(TAG, "请求失败: " + e.getMessage());
throw e;
}
// 计算请求耗时
long tookMs = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startNs);
// 打印响应日志
logResponse(response, tookMs);
return response;
}
/**
* 打印请求日志
*/
private void logRequest(Request request) {
try {
StringBuilder log = new StringBuilder();
log.append("\n==================== 请求开始 ====================\n");
// 请求行: 方法 + URL
log.append(String.format("方法: %s URL: %s\n", request.method(), request.url()));
// 请求头
log.append("请求头:\n");
for (String name : request.headers().names()) {
// 脱敏敏感头信息如Authorization、Cookie等
String value = isSensitiveHeader(name) ? "***" : request.headers().get(name);
log.append(String.format(" %s: %s\n", name, value));
}
// 请求体
if (logRequestBody && request.body() != null) {
RequestBody requestBody = request.body();
if (requestBody.contentLength() > 0) {
log.append("请求体:\n");
// 复制请求体(避免原请求体被消耗)
Buffer buffer = new Buffer();
requestBody.writeTo(buffer);
Charset charset = UTF8;
MediaType contentType = requestBody.contentType();
if (contentType != null) {
charset = contentType.charset(UTF8);
}
// 读取请求体内容
String body = buffer.readString(charset);
// 格式化JSON如果是JSON类型
if (isJson(contentType)) {
body = formatJson(body);
}
// 截断过长的日志
log.append(truncateLog(body)).append("\n");
}
}
log.append("==================== 请求结束 ====================\n");
Log.d(TAG, log.toString());
} catch (Exception e) {
Log.e(TAG, "打印请求日志失败: " + e.getMessage());
}
}
/**
* 打印响应日志
*/
private void logResponse(Response response, long tookMs) {
try {
StringBuilder log = new StringBuilder();
log.append("\n==================== 响应开始 ====================\n");
// 响应行: 状态码 + 消息 + 耗时
log.append(String.format("状态码: %d 消息: %s 耗时: %dms\n",
response.code(), response.message(), tookMs));
// 响应头
log.append("响应头:\n");
for (String name : response.headers().names()) {
log.append(String.format(" %s: %s\n", name, response.headers().get(name)));
}
// 响应体
if (logResponseBody && HttpHeaders.hasBody(response)) {
ResponseBody responseBody = response.body();
if (responseBody != null) {
BufferedSource source = responseBody.source();
source.request(Long.MAX_VALUE); // 读取整个响应体
Buffer buffer = source.buffer();
Charset charset = UTF8;
MediaType contentType = responseBody.contentType();
if (contentType != null) {
charset = contentType.charset(UTF8);
}
// 读取响应体内容
String body = buffer.clone().readString(charset);
// 格式化JSON
if (isJson(contentType)) {
body = formatJson(body);
}
// 截断过长的日志
log.append("响应体:\n").append(truncateLog(body)).append("\n");
}
}
log.append("==================== 响应结束 ====================\n");
Log.d(TAG, log.toString());
} catch (Exception e) {
Log.e(TAG, "打印响应日志失败: " + e.getMessage());
}
}
/**
* 判断是否为JSON类型
*/
private boolean isJson(MediaType mediaType) {
if (mediaType == null) return false;
return mediaType.type().equals("application") &&
mediaType.subtype().equals("json");
}
/**
* 格式化JSON字符串增强可读性
*/
private String formatJson(String json) {
try {
// 简单格式化可根据需要使用更复杂的JSON格式化库
StringBuilder formatted = new StringBuilder();
int indent = 0;
boolean inQuotes = false;
char lastChar = ' ';
for (char c : json.toCharArray()) {
if (c == '"' && lastChar != '\\') {
inQuotes = !inQuotes;
}
if (!inQuotes) {
switch (c) {
case '{':
case '[':
formatted.append(c).append("\n");
indent += 4;
formatted.append(" ".repeat(indent));
break;
case '}':
case ']':
formatted.append("\n");
indent -= 4;
formatted.append(" ".repeat(indent)).append(c);
break;
case ',':
formatted.append(c).append("\n").append(" ".repeat(indent));
break;
case ':':
formatted.append(" : ");
break;
default:
formatted.append(c);
break;
}
} else {
formatted.append(c);
}
lastChar = c;
}
return formatted.toString();
} catch (Exception e) {
// 格式化失败时返回原始字符串
return json;
}
}
/**
* 截断过长的日志
*/
private String truncateLog(String log) {
if (log.length() <= maxLogLength) {
return log;
}
return log.substring(0, maxLogLength) + "\n...[日志过长,已截断]...";
}
/**
* 判断是否为敏感头信息(需要脱敏)
*/
private boolean isSensitiveHeader(String headerName) {
String lowerHeader = headerName.toLowerCase();
return lowerHeader.contains("authorization") ||
lowerHeader.contains("cookie") ||
lowerHeader.contains("token") ||
lowerHeader.contains("secret");
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 55 KiB

View File

@@ -173,6 +173,7 @@
<TextView <TextView
android:id="@+id/tv_relation" android:id="@+id/tv_relation"
android:gravity="center"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="@dimen/dp_18" android:layout_height="@dimen/dp_18"
android:layout_marginTop="@dimen/dp_1" android:layout_marginTop="@dimen/dp_1"
@@ -198,6 +199,7 @@
app:layout_constraintTop_toTopOf="parent" /> app:layout_constraintTop_toTopOf="parent" />
<TextView <TextView
android:gravity="center"
android:id="@+id/tv_gift" android:id="@+id/tv_gift"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="@dimen/dp_18" android:layout_height="@dimen/dp_18"
@@ -223,6 +225,7 @@
app:layout_constraintTop_toTopOf="parent" /> app:layout_constraintTop_toTopOf="parent" />
<TextView <TextView
android:id="@+id/tv_timetg" android:id="@+id/tv_timetg"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="@dimen/dp_18" android:layout_height="@dimen/dp_18"