Compare commits

...

11 Commits

Author SHA1 Message Date
f36ee0d9b1 <appbase>APK 15.20.9 release Publish. 2026-05-12 09:16:45 +08:00
fe0b2f97ea 重构日志窗口UI主题颜色系统,统一使用toolbarTextColor和toolbarBackgroundColor
【主要变更】

1. 新增主题颜色属性
   - 新增 toolbarTextColor 属性定义(普通模式:黑色, 深色模式:#E0E0E0)
   - 新增 toolbarBackgroundColor 属性定义(普通模式:绿色, 深色模式:深蓝色)

2. 移除废弃颜色属性
   - 移除 buttonTextColor 属性定义
   - 移除 buttonBackgroundColor 属性定义

3. 更新布局文件(普通模式+深色模式)
   - view_log.xml: TextView(LV:)、CheckBox(Selectable/ALL) 使用 toolbarTextColor
   - view_log.xml: Button(Clean/Copy) 使用 toolbarBackgroundColor
   - item_logtag.xml: CheckBox 使用 toolbarTextColor
   - activity_main.xml: 所有Button使用 toolbarBackgroundColor
   - activity_crash_test.xml: 所有Button使用 toolbarBackgroundColor
   - activity_nfc_rsa_operate.xml: Button使用 toolbarBackgroundColor
   - dialog_winboll_host.xml: Button使用 toolbarBackgroundColor

4. 更新Java代码
   - LogView.java: CheckBox和TextView使用主题属性获取 toolbarTextColor
   - LogTagSpinner.java: 下拉框文本颜色使用 toolbarTextColor

5. 更新样式定义
   - styles.xml: 主题属性引用新的 toolbarTextColor/toolbarBackgroundColor
   - attrs.xml: 移除废弃属性,保留 toolbarTextColor/toolbarBackgroundColor
   - colors.xml: 添加新的颜色定义

【适配说明】
- 统一普通模式和深色模式的颜色管理
- 确保日志窗口所有控件颜色与主窗口保持一致
2026-05-12 09:13:16 +08:00
43da2bc03a 统一日志窗口Clean/Copy按钮样式与主窗口保持一致 2026-05-12 00:33:14 +08:00
6baca2779d 同步build.gradle至origin/winboll分支最新配置 2026-05-11 21:13:50 +08:00
ff8cb2fb42 <libappbase>Library Release 15.20.8 2026-05-11 20:30:07 +08:00
e42219ac5a <appbase>APK 15.20.8 release Publish. 2026-05-11 20:29:55 +08:00
42112eb677 LibAppBase: 添加崩溃通知分享日志功能
- 在崩溃通知中添加"分享日志"按钮,点击可分享崩溃日志
- 新增 ShareLogActivity 窗口类处理分享逻辑
- 崩溃日志先保存到缓存文件,再读取分享
- 移除广播接收器方案,简化实现
- 更新 AndroidManifest 注册新 Activity

修改文件:
- libappbase/src/main/AndroidManifest.xml
- libappbase/src/main/java/.../utils/CrashHandleNotifyUtils.java
- libappbase/src/main/java/.../utils/ShareLogActivity.java (新增)

影响范围: 崩溃通知功能
2026-05-11 20:27:40 +08:00
f3114a8121 <libappbase>Library Release 15.20.7 2026-05-11 19:10:54 +08:00
b5b29b8a77 <appbase>APK 15.20.7 release Publish. 2026-05-11 19:10:34 +08:00
01b0a7736d feat(CrashHandleNotifyUtils): 增强崩溃通知摘要提取与展示逻辑
- 新增正则表达式解析崩溃日志,提取异常类型、消息、原因及堆栈信息
- 实现 extractBriefInfo() 方法,生成结构化的崩溃摘要
- 优化通知内容展示:异常类型 + 错误信息 + 关键堆栈(最多3行)
- 添加摘要最大长度控制(200字符),防止内容过长
- 新增展开通知布局文件支持
2026-05-11 19:02:51 +08:00
d20923eaee <libappbase>Library Release 15.20.6 2026-05-11 16:56:33 +08:00
29 changed files with 505 additions and 135 deletions

View File

@@ -1,8 +1,8 @@
#Created by .winboll/winboll_app_build.gradle #Created by .winboll/winboll_app_build.gradle
#Mon May 11 16:56:19 HKT 2026 #Tue May 12 09:16:45 HKT 2026
stageCount=7 stageCount=10
libraryProject=libappbase libraryProject=libappbase
baseVersion=15.20 baseVersion=15.20
publishVersion=15.20.6 publishVersion=15.20.9
buildCount=0 buildCount=0
baseBetaVersion=15.20.7 baseBetaVersion=15.20.10

View File

@@ -31,7 +31,7 @@
android:text="关于应用" android:text="关于应用"
android:textSize="16sp" android:textSize="16sp"
android:textColor="?attr/activityTextColor" android:textColor="?attr/activityTextColor"
android:background="?attr/buttonBackgroundColor" android:background="?attr/toolbarBackgroundColor"
android:paddingVertical="12dp" android:paddingVertical="12dp"
android:layout_marginHorizontal="24dp" android:layout_marginHorizontal="24dp"
android:onClick="onAboutActivity" android:onClick="onAboutActivity"
@@ -43,7 +43,7 @@
android:text="应用崩溃测试" android:text="应用崩溃测试"
android:textSize="16sp" android:textSize="16sp"
android:textColor="?attr/activityTextColor" android:textColor="?attr/activityTextColor"
android:background="?attr/buttonBackgroundColor" android:background="?attr/toolbarBackgroundColor"
android:paddingVertical="12dp" android:paddingVertical="12dp"
android:layout_marginHorizontal="24dp" android:layout_marginHorizontal="24dp"
android:onClick="onCrashTest" android:onClick="onCrashTest"
@@ -55,7 +55,7 @@
android:text="应用日志测试" android:text="应用日志测试"
android:textSize="16sp" android:textSize="16sp"
android:textColor="?attr/activityTextColor" android:textColor="?attr/activityTextColor"
android:background="?attr/buttonBackgroundColor" android:background="?attr/toolbarBackgroundColor"
android:paddingVertical="12dp" android:paddingVertical="12dp"
android:layout_marginHorizontal="24dp" android:layout_marginHorizontal="24dp"
android:onClick="onLogTest" android:onClick="onLogTest"
@@ -67,7 +67,7 @@
android:text="应用日志测试(新窗口)" android:text="应用日志测试(新窗口)"
android:textSize="16sp" android:textSize="16sp"
android:textColor="?attr/activityTextColor" android:textColor="?attr/activityTextColor"
android:background="?attr/buttonBackgroundColor" android:background="?attr/toolbarBackgroundColor"
android:paddingVertical="12dp" android:paddingVertical="12dp"
android:layout_marginHorizontal="24dp" android:layout_marginHorizontal="24dp"
android:onClick="onLogTestNewTask" android:onClick="onLogTestNewTask"
@@ -79,7 +79,7 @@
android:text="应用吐司测试" android:text="应用吐司测试"
android:textSize="16sp" android:textSize="16sp"
android:textColor="?attr/activityTextColor" android:textColor="?attr/activityTextColor"
android:background="?attr/buttonBackgroundColor" android:background="?attr/toolbarBackgroundColor"
android:paddingVertical="12dp" android:paddingVertical="12dp"
android:layout_marginHorizontal="24dp" android:layout_marginHorizontal="24dp"
android:onClick="onToastUtilsTest" android:onClick="onToastUtilsTest"
@@ -93,7 +93,7 @@
android:text="多开窗口" android:text="多开窗口"
android:textSize="16sp" android:textSize="16sp"
android:textColor="?attr/activityTextColor" android:textColor="?attr/activityTextColor"
android:background="?attr/buttonBackgroundColor" android:background="?attr/toolbarBackgroundColor"
android:paddingVertical="12dp" android:paddingVertical="12dp"
android:layout_marginHorizontal="24dp" android:layout_marginHorizontal="24dp"
android:onClick="onMultiInstance" android:onClick="onMultiInstance"

View File

@@ -35,7 +35,7 @@
android:text="返回" android:text="返回"
android:textSize="16sp" android:textSize="16sp"
android:textColor="?attr/activityTextColor" android:textColor="?attr/activityTextColor"
android:background="?attr/buttonBackgroundColor" android:background="?attr/toolbarBackgroundColor"
android:paddingVertical="12dp" android:paddingVertical="12dp"
android:layout_marginHorizontal="24dp" android:layout_marginHorizontal="24dp"
android:onClick="onBack" android:onClick="onBack"
@@ -47,7 +47,7 @@
android:text="测试崩溃" android:text="测试崩溃"
android:textSize="16sp" android:textSize="16sp"
android:textColor="?attr/activityTextColor" android:textColor="?attr/activityTextColor"
android:background="?attr/buttonBackgroundColor" android:background="?attr/toolbarBackgroundColor"
android:paddingVertical="12dp" android:paddingVertical="12dp"
android:layout_marginHorizontal="24dp" android:layout_marginHorizontal="24dp"
android:onClick="onTestCrash" android:onClick="onTestCrash"

View File

@@ -31,7 +31,7 @@
android:text="关于应用" android:text="关于应用"
android:textSize="16sp" android:textSize="16sp"
android:textColor="?attr/activityTextColor" android:textColor="?attr/activityTextColor"
android:background="?attr/buttonBackgroundColor" android:background="?attr/toolbarBackgroundColor"
android:paddingVertical="12dp" android:paddingVertical="12dp"
android:layout_marginHorizontal="24dp" android:layout_marginHorizontal="24dp"
android:onClick="onAboutActivity" android:onClick="onAboutActivity"
@@ -43,7 +43,7 @@
android:text="应用崩溃测试" android:text="应用崩溃测试"
android:textSize="16sp" android:textSize="16sp"
android:textColor="?attr/activityTextColor" android:textColor="?attr/activityTextColor"
android:background="?attr/buttonBackgroundColor" android:background="?attr/toolbarBackgroundColor"
android:paddingVertical="12dp" android:paddingVertical="12dp"
android:layout_marginHorizontal="24dp" android:layout_marginHorizontal="24dp"
android:onClick="onCrashTest" android:onClick="onCrashTest"
@@ -55,7 +55,7 @@
android:text="应用日志测试" android:text="应用日志测试"
android:textSize="16sp" android:textSize="16sp"
android:textColor="?attr/activityTextColor" android:textColor="?attr/activityTextColor"
android:background="?attr/buttonBackgroundColor" android:background="?attr/toolbarBackgroundColor"
android:paddingVertical="12dp" android:paddingVertical="12dp"
android:layout_marginHorizontal="24dp" android:layout_marginHorizontal="24dp"
android:onClick="onLogTest" android:onClick="onLogTest"
@@ -67,7 +67,7 @@
android:text="应用日志测试(新窗口)" android:text="应用日志测试(新窗口)"
android:textSize="16sp" android:textSize="16sp"
android:textColor="?attr/activityTextColor" android:textColor="?attr/activityTextColor"
android:background="?attr/buttonBackgroundColor" android:background="?attr/toolbarBackgroundColor"
android:paddingVertical="12dp" android:paddingVertical="12dp"
android:layout_marginHorizontal="24dp" android:layout_marginHorizontal="24dp"
android:onClick="onLogTestNewTask" android:onClick="onLogTestNewTask"
@@ -79,7 +79,7 @@
android:text="应用吐司测试" android:text="应用吐司测试"
android:textSize="16sp" android:textSize="16sp"
android:textColor="?attr/activityTextColor" android:textColor="?attr/activityTextColor"
android:background="?attr/buttonBackgroundColor" android:background="?attr/toolbarBackgroundColor"
android:paddingVertical="12dp" android:paddingVertical="12dp"
android:layout_marginHorizontal="24dp" android:layout_marginHorizontal="24dp"
android:onClick="onToastUtilsTest" android:onClick="onToastUtilsTest"
@@ -93,7 +93,7 @@
android:text="多开窗口" android:text="多开窗口"
android:textSize="16sp" android:textSize="16sp"
android:textColor="?attr/activityTextColor" android:textColor="?attr/activityTextColor"
android:background="?attr/buttonBackgroundColor" android:background="?attr/toolbarBackgroundColor"
android:paddingVertical="12dp" android:paddingVertical="12dp"
android:layout_marginHorizontal="24dp" android:layout_marginHorizontal="24dp"
android:onClick="onMultiInstance" android:onClick="onMultiInstance"

View File

@@ -6,8 +6,9 @@
<style name="MyDebugActivityTheme" parent="DebugActivityTheme"> <style name="MyDebugActivityTheme" parent="DebugActivityTheme">
<item name="colorTittle">?attr/mainWindowDarkTextColor</item> <item name="colorTittle">?attr/mainWindowDarkTextColor</item>
<item name="colorTittleBackgound">@color/buttonBackgroundColor</item> <item name="colorTittleBackgound">?attr/toolbarBackgroundColor</item>
<item name="colorText">?attr/debugTextColor</item> <item name="colorText">?attr/debugTextColor</item>
<item name="colorTextBackgound">?attr/mainWindowDarkBackgroundColor</item> <item name="colorTextBackgound">?attr/mainWindowDarkBackgroundColor</item>
<item name="toolbarTextColor">@color/toolbarTextColor</item>
</style> </style>
</resources> </resources>

View File

@@ -6,8 +6,9 @@
<style name="MyDebugActivityTheme" parent="DebugActivityTheme"> <style name="MyDebugActivityTheme" parent="DebugActivityTheme">
<item name="colorTittle">?attr/mainWindowTextColor</item> <item name="colorTittle">?attr/mainWindowTextColor</item>
<item name="colorTittleBackgound">@color/buttonBackgroundColor</item> <item name="colorTittleBackgound">?attr/toolbarBackgroundColor</item>
<item name="colorText">?attr/debugTextColor</item> <item name="colorText">?attr/debugTextColor</item>
<item name="colorTextBackgound">?attr/mainWindowBackgroundColor</item> <item name="colorTextBackgound">?attr/mainWindowBackgroundColor</item>
<item name="toolbarTextColor">@color/toolbarTextColor</item>
</style> </style>
</resources> </resources>

View File

@@ -93,11 +93,12 @@ allprojects {
} }
subprojects { subprojects {
// 1. 对纯 Java 模块的 JavaCompile 任务配置(强制Java 7 // 1. 对纯 Java 模块的 JavaCompile 任务配置(升级为 Java 11
tasks.withType(JavaCompile) { tasks.withType(JavaCompile) {
options.compilerArgs << "-parameters" options.compilerArgs << "-parameters"
sourceCompatibility = JavaVersion.VERSION_1_7 sourceCompatibility = JavaVersion.VERSION_1_7
targetCompatibility = JavaVersion.VERSION_1_7 targetCompatibility = JavaVersion.VERSION_1_7
// 可选:确保编码一致
options.encoding = "UTF-8" options.encoding = "UTF-8"
} }
} }

View File

@@ -1,8 +1,8 @@
#Created by .winboll/winboll_app_build.gradle #Created by .winboll/winboll_app_build.gradle
#Mon May 11 16:56:19 HKT 2026 #Tue May 12 09:16:45 HKT 2026
stageCount=7 stageCount=10
libraryProject=libappbase libraryProject=libappbase
baseVersion=15.20 baseVersion=15.20
publishVersion=15.20.6 publishVersion=15.20.9
buildCount=0 buildCount=0
baseBetaVersion=15.20.7 baseBetaVersion=15.20.10

View File

@@ -47,6 +47,13 @@
<activity android:name="cc.winboll.studio.libappbase.activities.FTPBackupsActivity"/> <activity android:name="cc.winboll.studio.libappbase.activities.FTPBackupsActivity"/>
<activity
android:name=".utils.ShareLogActivity"
android:label="ShareLogActivity"
android:exported="true"
android:launchMode="singleTask"
android:theme="@android:style/Theme.NoDisplay"/>
</application> </application>
</manifest> </manifest>

View File

@@ -8,6 +8,7 @@ package cc.winboll.studio.libappbase;
import android.content.ClipData; import android.content.ClipData;
import android.content.ClipboardManager; import android.content.ClipboardManager;
import android.content.Context; import android.content.Context;
import android.content.res.TypedArray;
import android.os.Handler; import android.os.Handler;
import android.os.Message; import android.os.Message;
import android.text.Editable; import android.text.Editable;
@@ -248,7 +249,10 @@ public class LogView extends RelativeLayout {
} }
mSelectAllTAGCheckBox.setLayoutParams(layoutParams2); mSelectAllTAGCheckBox.setLayoutParams(layoutParams2);
//mSelectAllTAGCheckBox.setPadding(0,0,0,0); //mSelectAllTAGCheckBox.setPadding(0,0,0,0);
mSelectAllTAGCheckBox.setTextColor(mContext.getResources().getColor(R.color.white)); TypedArray ta1 = mContext.obtainStyledAttributes(new int[] { R.attr.toolbarTextColor });
int toolbarTextColor1 = ta1.getColor(0, mContext.getResources().getColor(R.color.white));
ta1.recycle();
mSelectAllTAGCheckBox.setTextColor(toolbarTextColor1);
mSelectAllTAGCheckBox.setOnClickListener(new View.OnClickListener(){ mSelectAllTAGCheckBox.setOnClickListener(new View.OnClickListener(){
@Override @Override
public void onClick(View v) { public void onClick(View v) {
@@ -502,10 +506,17 @@ public class LogView extends RelativeLayout {
} }
holder.tvText.setLayoutParams(layoutParams); holder.tvText.setLayoutParams(layoutParams);
holder.tvText.setPadding(0,0,0,0); holder.tvText.setPadding(0,0,0,0);
holder.tvText.setTextColor(mContext.getResources().getColor(R.color.white)); TypedArray ta2 = mContext.obtainStyledAttributes(new int[] { R.attr.toolbarTextColor });
int toolbarTextColor2 = ta2.getColor(0, mContext.getResources().getColor(R.color.white));
ta2.recycle();
holder.tvText.setTextColor(toolbarTextColor2);
holder.cbChecked.setChecked(item.isChecked()); holder.cbChecked.setChecked(item.isChecked());
holder.cbChecked.setLayoutParams(layoutParams); holder.cbChecked.setLayoutParams(layoutParams);
holder.cbChecked.setPadding(0,0,0,0); holder.cbChecked.setPadding(0,0,0,0);
TypedArray ta3 = mContext.obtainStyledAttributes(new int[] { R.attr.toolbarTextColor });
int toolbarTextColor3 = ta3.getColor(0, mContext.getResources().getColor(R.color.white));
ta3.recycle();
holder.cbChecked.setTextColor(toolbarTextColor3);
holder.cbChecked.setOnClickListener(new View.OnClickListener(){ holder.cbChecked.setOnClickListener(new View.OnClickListener(){
@Override @Override

View File

@@ -1,16 +1,23 @@
package cc.winboll.studio.libappbase.utils; package cc.winboll.studio.libappbase.utils;
import android.app.Application;
import android.app.Notification; import android.app.Notification;
import android.app.NotificationManager; import android.app.NotificationManager;
import android.app.PendingIntent; import android.app.PendingIntent;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.net.Uri;
import android.os.Build; import android.os.Build;
import android.text.TextUtils; import android.text.TextUtils;
import cc.winboll.studio.libappbase.CrashHandler; import cc.winboll.studio.libappbase.CrashHandler;
import cc.winboll.studio.libappbase.LogUtils; import cc.winboll.studio.libappbase.LogUtils;
import cc.winboll.studio.libappbase.R;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
/** /**
* 应用崩溃处理通知实用工具集(类库兼容版) * 应用崩溃处理通知实用工具集(类库兼容版)
@@ -18,7 +25,7 @@ import cc.winboll.studio.libappbase.LogUtils;
* 适配说明:移除固定包名依赖,通过外部传入宿主包名,支持任意应用集成使用 * 适配说明:移除固定包名依赖,通过外部传入宿主包名,支持任意应用集成使用
* @Author 豆包&ZhanGSKen<zhangsken@qq.com> * @Author 豆包&ZhanGSKen<zhangsken@qq.com>
* @CreateTime 2025/11/29 21:12:00 * @CreateTime 2025/11/29 21:12:00
* @EditTime 2026/05/11 15:38:21 * @EditTime 2026/05/11 21:55:00
*/ */
public class CrashHandleNotifyUtils { public class CrashHandleNotifyUtils {
@@ -34,8 +41,24 @@ public class CrashHandleNotifyUtils {
private static final int API_LEVEL_ANDROID_12 = 31; private static final int API_LEVEL_ANDROID_12 = 31;
/** PendingIntent.FLAG_IMMUTABLE 常量值API 31+ */ /** PendingIntent.FLAG_IMMUTABLE 常量值API 31+ */
private static final int FLAG_IMMUTABLE = 0x00000040; private static final int FLAG_IMMUTABLE = 0x00000040;
/** 通知内容最大行数控制在3行超出部分省略 */ /** 通知摘要最大长度 */
private static final int NOTIFICATION_MAX_LINES = 3; private static final int SUMMARY_MAX_LENGTH = 200;
/** 分享日志请求码 */
private static final int REQUEST_CODE_SHARE_LOG = 0x002;
/** 缓存崩溃日志子目录 */
private static final String CRASH_LOG_CACHE_SUBDIR = "crashnotify";
/** 缓存崩溃日志文件名 */
private static final String CRASH_LOG_CACHE_FILENAME = "crash_log.txt";
// ====================== 静态成员 ======================
private static String sHostPackageName = "";
private static String sCrashLogCacheFilePath = "";
// ====================== 正则表达式定义 ======================
private static final String REGEX_EXCEPTION_TYPE = "([\\w.]+Exception|[\\w.]+Error)";
private static final String REGEX_EXCEPTION_MESSAGE = "(?<=:\\s)(.+?)(?=\\n|\\r|$)";
private static final String REGEX_STACK_TRACE = "\\s+at\\s+([\\w.$]+)\\.([\\w<>]+)\\(([^:]+\\.java):(\\d+)\\)";
private static final String REGEX_CAUSE = "(?<=Caused by:\\s)" + REGEX_EXCEPTION_TYPE + "\\s*:";
// ====================== 对外核心方法 ====================== // ====================== 对外核心方法 ======================
/** /**
@@ -45,18 +68,29 @@ public class CrashHandleNotifyUtils {
* @param errorLog 崩溃日志内容 * @param errorLog 崩溃日志内容
* @param reportCrashActivity 崩溃详情跳转Activity类 * @param reportCrashActivity 崩溃详情跳转Activity类
*/ */
public static void handleUncaughtException(final Application hostApp, public static void handleUncaughtException(final android.app.Application hostApp,
final String hostPackageName, final String hostPackageName,
final String errorLog, final String errorLog,
final Class<?> reportCrashActivity) { final Class<?> reportCrashActivity) {
LogUtils.d(TAG, "handleUncaughtException 进入方法"); LogUtils.d(TAG, "handleUncaughtException 进入方法");
// 校验入参
if (hostApp == null || TextUtils.isEmpty(hostPackageName) || TextUtils.isEmpty(errorLog)) { if (hostApp == null || TextUtils.isEmpty(hostPackageName) || TextUtils.isEmpty(errorLog)) {
LogUtils.e(TAG, "handleUncaughtException 参数为空校验不通过"); LogUtils.e(TAG, "handleUncaughtException 参数为空校验不通过");
return; return;
} }
sHostPackageName = hostPackageName;
final String hostAppName = getHostAppName(hostApp, hostPackageName); final String hostAppName = getHostAppName(hostApp, hostPackageName);
sendCrashNotification(hostApp, hostPackageName, hostAppName, errorLog, reportCrashActivity); final String crashLogFilePath = saveCrashLogToCache(hostApp, errorLog);
if (TextUtils.isEmpty(crashLogFilePath)) {
LogUtils.e(TAG, "保存崩溃日志到缓存文件失败");
return;
}
sCrashLogCacheFilePath = crashLogFilePath;
final Intent shareIntent = new Intent(hostApp, ShareLogActivity.class);
shareIntent.putExtra(ShareLogActivity.EXTRA_CRASH_LOG_FILEPATH, crashLogFilePath);
shareIntent.putExtra(ShareLogActivity.EXTRA_CRASH_LOG_SUBJECT, "崩溃日志");
shareIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
final PendingIntent sharePendingIntent = createSharePendingIntent(hostApp, shareIntent);
sendCrashNotification(hostApp, hostPackageName, hostAppName, errorLog, reportCrashActivity, sharePendingIntent);
} }
/** /**
@@ -65,7 +99,7 @@ public class CrashHandleNotifyUtils {
* @param intent 携带崩溃信息Intent * @param intent 携带崩溃信息Intent
* @param reportCrashActivity 崩溃详情Activity * @param reportCrashActivity 崩溃详情Activity
*/ */
public static void handleUncaughtException(final Application hostApp, public static void handleUncaughtException(final android.app.Application hostApp,
final Intent intent, final Intent intent,
final Class<?> reportCrashActivity) { final Class<?> reportCrashActivity) {
LogUtils.d(TAG, "handleUncaughtException 重载方法进入"); LogUtils.d(TAG, "handleUncaughtException 重载方法进入");
@@ -78,6 +112,16 @@ public class CrashHandleNotifyUtils {
handleUncaughtException(hostApp, hostPackageName, errorLog, reportCrashActivity); handleUncaughtException(hostApp, hostPackageName, errorLog, reportCrashActivity);
} }
/**
* 资源释放
* @param hostContext 宿主上下文
*/
public static void release(final Context hostContext) {
LogUtils.d(TAG, "release 执行资源释放");
sHostPackageName = "";
sCrashLogCacheFilePath = "";
}
// ====================== 内部工具方法 ====================== // ====================== 内部工具方法 ======================
/** /**
* 获取宿主应用名称 * 获取宿主应用名称
@@ -96,6 +140,79 @@ public class CrashHandleNotifyUtils {
} }
} }
/**
* 保存崩溃日志到缓存文件
* @param hostContext 宿主上下文
* @param crashLog 崩溃日志内容
* @return 缓存文件路径,失败返回空字符串
*/
private static String saveCrashLogToCache(final Context hostContext, final String crashLog) {
if (hostContext == null || TextUtils.isEmpty(crashLog)) {
return "";
}
BufferedReader reader = null;
FileOutputStream fos = null;
try {
final File cacheDir = new File(hostContext.getCacheDir(), CRASH_LOG_CACHE_SUBDIR);
if (!cacheDir.exists()) {
cacheDir.mkdirs();
}
final File cacheFile = new File(cacheDir, CRASH_LOG_CACHE_FILENAME);
if (cacheFile.exists()) {
cacheFile.delete();
}
cacheFile.createNewFile();
fos = new FileOutputStream(cacheFile);
fos.write(crashLog.getBytes("UTF-8"));
fos.flush();
LogUtils.d(TAG, "saveCrashLogToCache 保存崩溃日志到缓存: " + cacheFile.getAbsolutePath());
return cacheFile.getAbsolutePath();
} catch (Exception e) {
LogUtils.e(TAG, "saveCrashLogToCache 异常", e);
return "";
} finally {
if (reader != null) {
try { reader.close(); } catch (Exception e) {}
}
if (fos != null) {
try { fos.close(); } catch (Exception e) {}
}
}
}
/**
* 读取缓存的崩溃日志文件内容
* @param hostContext 宿主上下文
* @return 日志内容,失败返回空字符串
*/
private static String readCachedCrashLog(final Context hostContext) {
if (hostContext == null || TextUtils.isEmpty(sCrashLogCacheFilePath)) {
return "";
}
BufferedReader reader = null;
try {
final File cacheFile = new File(sCrashLogCacheFilePath);
if (!cacheFile.exists()) {
LogUtils.w(TAG, "readCachedCrashLog 缓存文件不存在");
return "";
}
reader = new BufferedReader(new InputStreamReader(new FileInputStream(cacheFile), "UTF-8"));
final StringBuilder sb = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
sb.append(line).append("\n");
}
return sb.toString();
} catch (Exception e) {
LogUtils.e(TAG, "readCachedCrashLog 异常", e);
return "";
} finally {
if (reader != null) {
try { reader.close(); } catch (Exception e) {}
}
}
}
/** /**
* 发送崩溃系统通知 * 发送崩溃系统通知
* @param hostContext 宿主上下文 * @param hostContext 宿主上下文
@@ -103,19 +220,20 @@ public class CrashHandleNotifyUtils {
* @param hostAppName 宿主应用名 * @param hostAppName 宿主应用名
* @param errorLog 崩溃日志 * @param errorLog 崩溃日志
* @param reportCrashActivity 跳转Activity * @param reportCrashActivity 跳转Activity
* @param sharePendingIntent 分享日志PendingIntent
*/ */
private static void sendCrashNotification(final Context hostContext, private static void sendCrashNotification(final Context hostContext,
final String hostPackageName, final String hostPackageName,
final String hostAppName, final String hostAppName,
final String errorLog, final String errorLog,
final Class<?> reportCrashActivity) { final Class<?> reportCrashActivity,
final PendingIntent sharePendingIntent) {
final NotificationManager notificationManager = final NotificationManager notificationManager =
(NotificationManager) hostContext.getSystemService(Context.NOTIFICATION_SERVICE); (NotificationManager) hostContext.getSystemService(Context.NOTIFICATION_SERVICE);
if (notificationManager == null) { if (notificationManager == null) {
LogUtils.e(TAG, "获取NotificationManager失败"); LogUtils.e(TAG, "获取NotificationManager失败");
return; return;
} }
// 8.0以上创建通知渠道
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
createCrashNotifyChannel(hostContext, notificationManager); createCrashNotifyChannel(hostContext, notificationManager);
} }
@@ -125,11 +243,30 @@ public class CrashHandleNotifyUtils {
LogUtils.e(TAG, "构建跳转PendingIntent失败"); LogUtils.e(TAG, "构建跳转PendingIntent失败");
return; return;
} }
final Notification notification = buildNotification(hostContext, hostAppName, errorLog, jumpIntent); final Notification notification = buildNotification(hostContext, hostPackageName, hostAppName, errorLog, jumpIntent, sharePendingIntent);
notificationManager.notify(CRASH_NOTIFY_ID, notification); notificationManager.notify(CRASH_NOTIFY_ID, notification);
LogUtils.d(TAG, "崩溃通知发送成功,宿主包名:" + hostPackageName); LogUtils.d(TAG, "崩溃通知发送成功,宿主包名:" + hostPackageName);
} }
/**
* 创建分享日志PendingIntent
* @param hostContext 宿主上下文
* @param shareIntent 分享意图
* @return PendingIntent实例
*/
private static PendingIntent createSharePendingIntent(final Context hostContext, final Intent shareIntent) {
int flags = PendingIntent.FLAG_UPDATE_CURRENT;
if (Build.VERSION.SDK_INT >= API_LEVEL_ANDROID_12) {
flags |= FLAG_IMMUTABLE;
}
return PendingIntent.getActivity(
hostContext,
REQUEST_CODE_SHARE_LOG,
shareIntent,
flags
);
}
/** /**
* 创建通知渠道适配Android O及以上 * 创建通知渠道适配Android O及以上
* @param hostContext 宿主上下文 * @param hostContext 宿主上下文
@@ -186,34 +323,40 @@ public class CrashHandleNotifyUtils {
/** /**
* 构建Notification通知实例 * 构建Notification通知实例
* @param hostContext 宿主上下文 * @param hostContext 宿主上下文
* @param hostPackageName 宿主包名
* @param hostAppName 宿主应用名 * @param hostAppName 宿主应用名
* @param errorLog 崩溃日志 * @param errorLog 崩溃日志
* @param jumpIntent 点击跳转意图 * @param jumpIntent 点击跳转意图
* @param shareIntent 分享日志意图
* @return 构建好的Notification * @return 构建好的Notification
*/ */
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
private static Notification buildNotification(final Context hostContext, private static Notification buildNotification(final Context hostContext,
final String hostPackageName,
final String hostAppName, final String hostAppName,
final String errorLog, final String errorLog,
final PendingIntent jumpIntent) { final PendingIntent jumpIntent,
final PendingIntent shareIntent) {
Notification.Builder builder = new Notification.Builder(hostContext); Notification.Builder builder = new Notification.Builder(hostContext);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
builder.setChannelId(CRASH_NOTIFY_CHANNEL_ID); builder.setChannelId(CRASH_NOTIFY_CHANNEL_ID);
} }
Notification.BigTextStyle bigTextStyle = new Notification.BigTextStyle(); final String briefInfo = extractBriefInfo(errorLog);
bigTextStyle.setSummaryText("日志已省略,下拉查看完整内容"); final Notification.BigTextStyle bigTextStyle = new Notification.BigTextStyle();
bigTextStyle.bigText(errorLog);
bigTextStyle.setBigContentTitle(hostAppName + " 崩溃"); bigTextStyle.setBigContentTitle(hostAppName + " 崩溃");
bigTextStyle.bigText(briefInfo);
bigTextStyle.setSummaryText("点击查看详情");
builder.setStyle(bigTextStyle); builder.setStyle(bigTextStyle);
builder.setSmallIcon(hostContext.getApplicationInfo().icon) builder.setSmallIcon(hostContext.getApplicationInfo().icon)
.setContentTitle(hostAppName + " 崩溃") .setContentTitle(hostAppName + " 崩溃")
.setContentText(getShortContent(errorLog)) .setContentText(briefInfo.split("\n")[0])
.setContentIntent(jumpIntent) .setContentIntent(jumpIntent)
.setAutoCancel(true) .setAutoCancel(true)
.setWhen(System.currentTimeMillis()) .setWhen(System.currentTimeMillis())
.setPriority(Notification.PRIORITY_DEFAULT); .setPriority(Notification.PRIORITY_DEFAULT);
if (shareIntent != null) {
builder.addAction(android.R.drawable.ic_menu_send, "分享日志", shareIntent);
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
return builder.build(); return builder.build();
} else { } else {
@@ -226,20 +369,75 @@ public class CrashHandleNotifyUtils {
* @param content 原始日志 * @param content 原始日志
* @return 缩略文案 * @return 缩略文案
*/ */
private static String getShortContent(final String content) { private static String getShortContent(final String errorLog) {
if (content == null || content.isEmpty()) { if (errorLog == null || errorLog.isEmpty()) {
return "无崩溃日志"; return "无崩溃日志";
} }
final int maxLength = 80; final String brief = extractBriefInfo(errorLog);
return content.length() <= maxLength ? content : content.substring(0, maxLength) + "..."; final String firstLine = brief.split("\n")[0];
if (firstLine.length() > 80) {
return firstLine.substring(0, 80) + "...";
}
return firstLine;
} }
/** /**
* 资源释放预留方法 * 使用正则表达式从崩溃日志中提取简要信息
* @param hostContext 宿主上下文 * @param crashLog 完整崩溃日志
* @return 简要崩溃信息
*/ */
public static void release(final Context hostContext) { private static String extractBriefInfo(final String crashLog) {
LogUtils.d(TAG, "CrashHandleNotifyUtils 执行资源释放"); if (crashLog == null || crashLog.isEmpty()) {
return "无崩溃日志";
}
final StringBuilder brief = new StringBuilder();
try {
java.util.regex.Pattern exceptionPattern = java.util.regex.Pattern.compile(REGEX_EXCEPTION_TYPE);
java.util.regex.Matcher exceptionMatcher = exceptionPattern.matcher(crashLog);
if (exceptionMatcher.find()) {
brief.append(exceptionMatcher.group(1));
}
java.util.regex.Pattern messagePattern = java.util.regex.Pattern.compile(REGEX_EXCEPTION_MESSAGE);
java.util.regex.Matcher messageMatcher = messagePattern.matcher(crashLog);
if (messageMatcher.find()) {
String message = messageMatcher.group(1).trim();
if (message.length() > 100) {
message = message.substring(0, 100) + "...";
}
if (brief.length() > 0) {
brief.append(" - ");
}
brief.append(message);
}
java.util.regex.Pattern causePattern = java.util.regex.Pattern.compile(REGEX_CAUSE);
java.util.regex.Matcher causeMatcher = causePattern.matcher(crashLog);
if (causeMatcher.find()) {
if (brief.length() > 0) {
brief.append("\n");
}
brief.append("原因: ").append(causeMatcher.group(1));
}
java.util.regex.Pattern stackPattern = java.util.regex.Pattern.compile(REGEX_STACK_TRACE);
java.util.regex.Matcher stackMatcher = stackPattern.matcher(crashLog);
int lineCount = 0;
while (stackMatcher.find() && lineCount < 3) {
if (brief.length() > 0) {
brief.append("\n");
}
brief.append(" at ").append(stackMatcher.group(1)).append(".")
.append(stackMatcher.group(2)).append("(")
.append(stackMatcher.group(3)).append(":")
.append(stackMatcher.group(4)).append(")");
lineCount++;
}
if (brief.length() == 0) {
brief.append(crashLog.length() > SUMMARY_MAX_LENGTH ? crashLog.substring(0, SUMMARY_MAX_LENGTH) + "..." : crashLog);
}
} catch (Exception e) {
LogUtils.e(TAG, "提取崩溃简要信息失败", e);
brief.setLength(0);
brief.append(crashLog.length() > SUMMARY_MAX_LENGTH ? crashLog.substring(0, SUMMARY_MAX_LENGTH) + "..." : crashLog);
}
return brief.toString();
} }
} }

View File

@@ -0,0 +1,91 @@
package cc.winboll.studio.libappbase.utils;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
/**
* 分享崩溃日志窗口类
* @Author ZhanGSKen<zhangsken@qq.com>
* @CreateTime 2026/05/11 22:30:00
*/
public class ShareLogActivity extends Activity {
public static final String TAG = "ShareLogActivity";
public static final String EXTRA_CRASH_LOG_FILEPATH = "crash_log_filepath";
public static final String EXTRA_CRASH_LOG_SUBJECT = "crash_log_subject";
@Override
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d(TAG, "onCreate 进入方法");
final Intent intent = getIntent();
if (intent == null) {
Log.e(TAG, "onCreate intent 为空");
finish();
return;
}
final String crashLogFilePath = intent.getStringExtra(EXTRA_CRASH_LOG_FILEPATH);
if (crashLogFilePath == null || crashLogFilePath.isEmpty()) {
Log.e(TAG, "onCreate crashLogFilePath 为空");
Toast.makeText(this, "日志文件路径无效", Toast.LENGTH_SHORT).show();
finish();
return;
}
final String subject = intent.getStringExtra(EXTRA_CRASH_LOG_SUBJECT);
handleShareCrashLog(crashLogFilePath, subject);
}
private void handleShareCrashLog(final String crashLogFilePath, final String subject) {
Log.d(TAG, "handleShareCrashLog crashLogFilePath = " + crashLogFilePath);
final File crashLogFile = new File(crashLogFilePath);
if (!crashLogFile.exists()) {
Log.e(TAG, "handleShareCrashLog 文件不存在");
Toast.makeText(this, "日志文件不存在", Toast.LENGTH_SHORT).show();
finish();
return;
}
BufferedReader reader = null;
try {
reader = new BufferedReader(new InputStreamReader(new FileInputStream(crashLogFile), "UTF-8"));
final StringBuilder sb = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
sb.append(line).append("\n");
}
final String logContent = sb.toString();
final Intent shareIntent = new Intent(Intent.ACTION_SEND);
shareIntent.setType("text/plain");
shareIntent.putExtra(Intent.EXTRA_TEXT, logContent);
if (subject != null && !subject.isEmpty()) {
shareIntent.putExtra(Intent.EXTRA_SUBJECT, subject);
} else {
shareIntent.putExtra(Intent.EXTRA_SUBJECT, "崩溃日志");
}
startActivity(Intent.createChooser(shareIntent, "分享日志到"));
Log.d(TAG, "handleShareCrashLog 分享成功");
} catch (Exception e) {
Log.e(TAG, "handleShareCrashLog 异常", e);
Toast.makeText(this, "分享失败: " + e.getMessage(), Toast.LENGTH_SHORT).show();
} finally {
if (reader != null) {
try { reader.close(); } catch (Exception e) {}
}
finish();
}
}
}

View File

@@ -3,6 +3,7 @@ package cc.winboll.studio.libappbase.widget;
import android.content.Context; import android.content.Context;
import android.graphics.Color; import android.graphics.Color;
import android.text.TextUtils; import android.text.TextUtils;
import android.content.res.TypedArray;
import android.util.AttributeSet; import android.util.AttributeSet;
import android.util.TypedValue; import android.util.TypedValue;
import android.view.View; import android.view.View;
@@ -153,9 +154,12 @@ public class LogTagSpinner extends Spinner {
itemTv.setPadding(mTextPadding, 0, mTextPadding, 0); itemTv.setPadding(mTextPadding, 0, mTextPadding, 0);
// 4. 文字对齐(垂直居中+靠左,符合常规 UI 设计) // 4. 文字对齐(垂直居中+靠左,符合常规 UI 设计)
//itemTv.setGravity(View.GRAVITY_CENTER_VERTICAL | View.GRAVITY_START); //itemTv.setGravity(View.GRAVITY_CENTER_VERTICAL | View.GRAVITY_START);
// 5. 文字颜色(统一深色,可改为项目颜色资源 // 5. 文字颜色(使用主题属性 ?attr/toolbarTextColor
itemTv.setTextColor(this.mContext.getColor(R.color.white)); TypedArray ta = mContext.obtainStyledAttributes(new int[] { R.attr.toolbarTextColor });
itemTv.setBackgroundColor(this.mContext.getColor(R.color.btn_gray_normal)); int toolbarTextColor = ta.getColor(0, mContext.getResources().getColor(R.color.white));
ta.recycle();
itemTv.setTextColor(toolbarTextColor);
itemTv.setBackgroundColor(this.mContext.getResources().getColor(R.color.btn_gray_normal));
// 6. 文字溢出处理(最多 2 行,超出省略,避免长标签换行过多) // 6. 文字溢出处理(最多 2 行,超出省略,避免长标签换行过多)
itemTv.setSingleLine(false); itemTv.setSingleLine(false);
itemTv.setMaxLines(2); itemTv.setMaxLines(2);

View File

@@ -50,8 +50,8 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="功能按钮待激活" android:text="功能按钮待激活"
android:textSize="16sp" android:textSize="16sp"
android:textColor="?attr/buttonTextColor" android:textColor="?attr/toolbarTextColor"
android:backgroundTint="?attr/buttonBackgroundColor" android:backgroundTint="?attr/toolbarBackgroundColor"
android:padding="14dp" android:padding="14dp"
android:enabled="false"/> android:enabled="false"/>

View File

@@ -53,8 +53,8 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="确认" android:text="确认"
android:textSize="14sp" android:textSize="14sp"
android:backgroundTint="?attr/buttonBackgroundColor" android:backgroundTint="?attr/toolbarBackgroundColor"
android:textColor="?attr/buttonTextColor"/> android:textColor="?attr/toolbarTextColor"/>
</LinearLayout> </LinearLayout>

View File

@@ -18,6 +18,7 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="@dimen/log_button_height" android:layout_height="@dimen/log_button_height"
android:textSize="@dimen/log_text_size" android:textSize="@dimen/log_text_size"
android:textColor="?attr/toolbarTextColor"
android:id="@+id/viewlogtagCheckBox1"/> android:id="@+id/viewlogtagCheckBox1"/>
</LinearLayout> </LinearLayout>

View File

@@ -20,8 +20,8 @@
android:layout_height="@dimen/log_button_height" android:layout_height="@dimen/log_button_height"
android:textSize="@dimen/log_text_size" android:textSize="@dimen/log_text_size"
android:text="Clean" android:text="Clean"
android:textColor="?attr/colorText" android:textColor="?attr/activityTextColor"
android:backgroundTint="?attr/colorTittleBackgound" android:background="?attr/toolbarBackgroundColor"
android:layout_centerVertical="true" android:layout_centerVertical="true"
android:id="@+id/viewlogButtonClean" android:id="@+id/viewlogButtonClean"
android:layout_marginLeft="5dp"/> android:layout_marginLeft="5dp"/>
@@ -36,7 +36,7 @@
android:layout_centerVertical="true" android:layout_centerVertical="true"
android:id="@+id/viewlogTextView1" android:id="@+id/viewlogTextView1"
android:background="?attr/colorTittleBackgound" android:background="?attr/colorTittleBackgound"
android:textColor="?attr/colorText"/> android:textColor="?attr/toolbarTextColor"/>
<cc.winboll.studio.libappbase.widget.LogTagSpinner <cc.winboll.studio.libappbase.widget.LogTagSpinner
android:layout_width="wrap_content" android:layout_width="wrap_content"
@@ -56,14 +56,14 @@
android:background="?attr/colorTittleBackgound" android:background="?attr/colorTittleBackgound"
android:id="@+id/viewlogCheckBoxSelectable" android:id="@+id/viewlogCheckBoxSelectable"
android:padding="@dimen/log_text_padding" android:padding="@dimen/log_text_padding"
android:textColor="?attr/colorText"/> android:textColor="?attr/toolbarTextColor"/>
<Button <Button
android:layout_width="@dimen/log_button_width" android:layout_width="@dimen/log_button_width"
android:layout_height="@dimen/log_button_height" android:layout_height="@dimen/log_button_height"
android:textSize="@dimen/log_text_size" android:textSize="@dimen/log_text_size"
android:textColor="?attr/colorText" android:textColor="?attr/activityTextColor"
android:backgroundTint="?attr/colorTittleBackgound" android:background="?attr/toolbarBackgroundColor"
android:text="Copy" android:text="Copy"
android:layout_alignParentRight="true" android:layout_alignParentRight="true"
android:layout_centerVertical="true" android:layout_centerVertical="true"
@@ -89,7 +89,7 @@
android:padding="2dp" android:padding="2dp"
android:id="@+id/viewlogCheckBox1" android:id="@+id/viewlogCheckBox1"
android:background="?attr/colorTittleBackgound" android:background="?attr/colorTittleBackgound"
android:textColor="?attr/colorText" android:textColor="?attr/toolbarTextColor"
android:layout_marginLeft="5dp" android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"/> android:layout_marginRight="5dp"/>

View File

@@ -50,8 +50,8 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="功能按钮待激活" android:text="功能按钮待激活"
android:textSize="16sp" android:textSize="16sp"
android:textColor="?attr/buttonTextColor" android:textColor="?attr/toolbarTextColor"
android:backgroundTint="?attr/buttonBackgroundColor" android:backgroundTint="?attr/toolbarBackgroundColor"
android:padding="14dp" android:padding="14dp"
android:enabled="false"/> android:enabled="false"/>

View File

@@ -53,8 +53,8 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="确认" android:text="确认"
android:textSize="14sp" android:textSize="14sp"
android:backgroundTint="?attr/buttonBackgroundColor" android:backgroundTint="?attr/toolbarBackgroundColor"
android:textColor="?attr/buttonTextColor"/> android:textColor="?attr/toolbarTextColor"/>
</LinearLayout> </LinearLayout>

View File

@@ -18,6 +18,7 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="@dimen/log_button_height" android:layout_height="@dimen/log_button_height"
android:textSize="@dimen/log_text_size" android:textSize="@dimen/log_text_size"
android:textColor="?attr/toolbarTextColor"
android:id="@+id/viewlogtagCheckBox1"/> android:id="@+id/viewlogtagCheckBox1"/>
</LinearLayout> </LinearLayout>

View File

@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="12dp">
<TextView
android:id="@+id/notification_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="16sp"
android:textStyle="bold"
android:textColor="#333333"
android:singleLine="true"
android:ellipsize="end" />
<TextView
android:id="@+id/notification_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:textSize="14sp"
android:textColor="#666666"
android:minHeight="200dp" />
</LinearLayout>

View File

@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="12dp">
<TextView
android:id="@+id/notification_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="16sp"
android:textStyle="bold"
android:textColor="#333333"
android:singleLine="true"
android:ellipsize="end" />
<TextView
android:id="@+id/notification_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:textSize="13sp"
android:textColor="#666666"
android:scrollbars="vertical" />
</LinearLayout>

View File

@@ -20,8 +20,8 @@
android:layout_height="@dimen/log_button_height" android:layout_height="@dimen/log_button_height"
android:textSize="@dimen/log_text_size" android:textSize="@dimen/log_text_size"
android:text="Clean" android:text="Clean"
android:textColor="?attr/colorText" android:textColor="?attr/activityTextColor"
android:backgroundTint="?attr/colorTittleBackgound" android:background="?attr/toolbarBackgroundColor"
android:layout_centerVertical="true" android:layout_centerVertical="true"
android:id="@+id/viewlogButtonClean" android:id="@+id/viewlogButtonClean"
android:layout_marginLeft="5dp"/> android:layout_marginLeft="5dp"/>
@@ -36,7 +36,7 @@
android:layout_centerVertical="true" android:layout_centerVertical="true"
android:id="@+id/viewlogTextView1" android:id="@+id/viewlogTextView1"
android:background="?attr/colorTittleBackgound" android:background="?attr/colorTittleBackgound"
android:textColor="?attr/colorText"/> android:textColor="?attr/toolbarTextColor"/>
<cc.winboll.studio.libappbase.widget.LogTagSpinner <cc.winboll.studio.libappbase.widget.LogTagSpinner
android:layout_width="wrap_content" android:layout_width="wrap_content"
@@ -56,14 +56,14 @@
android:background="?attr/colorTittleBackgound" android:background="?attr/colorTittleBackgound"
android:id="@+id/viewlogCheckBoxSelectable" android:id="@+id/viewlogCheckBoxSelectable"
android:padding="@dimen/log_text_padding" android:padding="@dimen/log_text_padding"
android:textColor="?attr/colorText"/> android:textColor="?attr/toolbarTextColor"/>
<Button <Button
android:layout_width="@dimen/log_button_width" android:layout_width="@dimen/log_button_width"
android:layout_height="@dimen/log_button_height" android:layout_height="@dimen/log_button_height"
android:textSize="@dimen/log_text_size" android:textSize="@dimen/log_text_size"
android:textColor="?attr/colorText" android:textColor="?attr/activityTextColor"
android:backgroundTint="?attr/colorTittleBackgound" android:background="?attr/toolbarBackgroundColor"
android:text="Copy" android:text="Copy"
android:layout_alignParentRight="true" android:layout_alignParentRight="true"
android:layout_centerVertical="true" android:layout_centerVertical="true"
@@ -89,7 +89,7 @@
android:padding="2dp" android:padding="2dp"
android:id="@+id/viewlogCheckBox1" android:id="@+id/viewlogCheckBox1"
android:background="?attr/colorTittleBackgound" android:background="?attr/colorTittleBackgound"
android:textColor="?attr/colorText" android:textColor="?attr/toolbarTextColor"
android:layout_marginLeft="5dp" android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"/> android:layout_marginRight="5dp"/>

View File

@@ -20,11 +20,7 @@
<attr name="aboutViewDividerColor" format="color" /> <attr name="aboutViewDividerColor" format="color" />
</declare-styleable> </declare-styleable>
<!-- ButtonStyle 样式属性 -->
<declare-styleable name="ButtonStyle">
<attr name="buttonBackgroundColor" format="color" />
<attr name="buttonTextColor" format="color" />
</declare-styleable>
<!-- DialogStyle 样式属性 --> <!-- DialogStyle 样式属性 -->
<declare-styleable name="DialogStyle"> <declare-styleable name="DialogStyle">

View File

@@ -63,7 +63,9 @@
<!-- ============== 主题颜色 ============== --> <!-- ============== 主题颜色 ============== -->
<color name="mainWindowBackgroundColor">#FF0D1B2A</color> <color name="mainWindowBackgroundColor">#FF0D1B2A</color>
<color name="mainWindowTextColor">#FFE0E0E0</color> <color name="mainWindowTextColor">#FFE0E0E0</color>
<color name="buttonBackgroundColor">#FF1E3A5F</color> <color name="toolbarTextColor">#FFE0E0E0</color>
<color name="toolbarBackgroundColor">#FF1E3A5F</color>
<color name="debugTextColor">#FF00FF00</color> <color name="debugTextColor">#FF00FF00</color>
</resources> </resources>

View File

@@ -8,12 +8,12 @@
<item name="aboutViewTextColor">?attr/mainWindowDarkTextColor</item> <item name="aboutViewTextColor">?attr/mainWindowDarkTextColor</item>
<item name="aboutViewTitleColor">?attr/mainWindowDarkTextColor</item> <item name="aboutViewTitleColor">?attr/mainWindowDarkTextColor</item>
<item name="aboutViewDividerColor">?attr/mainWindowTextColor</item> <item name="aboutViewDividerColor">?attr/mainWindowTextColor</item>
<item name="buttonBackgroundColor">@color/buttonBackgroundColor</item>
<item name="buttonTextColor">?attr/mainWindowDarkTextColor</item>
<item name="dialogBackgroundColor">?attr/mainWindowDarkBackgroundColor</item> <item name="dialogBackgroundColor">?attr/mainWindowDarkBackgroundColor</item>
<item name="dialogTextColor">?attr/mainWindowDarkTextColor</item> <item name="dialogTextColor">?attr/mainWindowDarkTextColor</item>
<item name="toolbarBackgroundColor">?attr/buttonBackgroundColor</item> <item name="toolbarBackgroundColor">@color/toolbarBackgroundColor</item>
<item name="toolbarTextColor">?attr/mainWindowDarkTextColor</item> <item name="toolbarTextColor">@color/toolbarTextColor</item>
<item name="textViewBackgroundColor">?attr/mainWindowDarkBackgroundColor</item> <item name="textViewBackgroundColor">?attr/mainWindowDarkBackgroundColor</item>
<item name="textViewTextColor">?attr/mainWindowDarkTextColor</item> <item name="textViewTextColor">?attr/mainWindowDarkTextColor</item>
<item name="editTextBackgroundColor">?attr/mainWindowDarkBackgroundColor</item> <item name="editTextBackgroundColor">?attr/mainWindowDarkBackgroundColor</item>
@@ -29,12 +29,14 @@
<!-- DebugActivityTheme 深色模式样式 --> <!-- DebugActivityTheme 深色模式样式 -->
<style name="DebugActivityTheme" parent="@android:style/Theme.DeviceDefault.NoActionBar"> <style name="DebugActivityTheme" parent="@android:style/Theme.DeviceDefault.NoActionBar">
<item name="android:statusBarColor">@color/mainWindowBackgroundColor</item> <item name="android:statusBarColor">@color/toolbarBackgroundColor</item>
<item name="colorTittle">?attr/mainWindowDarkTextColor</item> <item name="colorTittle">?attr/mainWindowDarkTextColor</item>
<item name="colorTittleBackgound">@color/buttonBackgroundColor</item> <item name="colorTittleBackgound">@color/toolbarBackgroundColor</item>
<item name="colorText">?attr/debugTextColor</item> <item name="colorText">?attr/debugTextColor</item>
<item name="colorTextBackgound">?attr/mainWindowDarkBackgroundColor</item> <item name="colorTextBackgound">?attr/mainWindowDarkBackgroundColor</item>
<item name="debugTextColor">@color/debugTextColor</item> <item name="debugTextColor">@color/debugTextColor</item>
<item name="toolbarTextColor">@color/toolbarTextColor</item>
</style> </style>
<!-- DialogStyle 对话框样式 --> <!-- DialogStyle 对话框样式 -->

View File

@@ -26,11 +26,7 @@
<attr name="aboutViewDividerColor" format="color" /> <attr name="aboutViewDividerColor" format="color" />
</declare-styleable> </declare-styleable>
<!-- ButtonStyle 样式属性 -->
<declare-styleable name="ButtonStyle">
<attr name="buttonBackgroundColor" format="color" />
<attr name="buttonTextColor" format="color" />
</declare-styleable>
<!-- DialogStyle 样式属性 --> <!-- DialogStyle 样式属性 -->
<declare-styleable name="DialogStyle"> <declare-styleable name="DialogStyle">

View File

@@ -63,7 +63,9 @@
<!-- ============== 主题颜色 ============== --> <!-- ============== 主题颜色 ============== -->
<color name="mainWindowBackgroundColor">#FFF5F5F5</color> <color name="mainWindowBackgroundColor">#FFF5F5F5</color>
<color name="mainWindowTextColor">#FF000000</color> <color name="mainWindowTextColor">#FF000000</color>
<color name="buttonBackgroundColor">#FF00B322</color> <color name="toolbarTextColor">#FF000000</color>
<color name="toolbarBackgroundColor">#FF00B322</color>
<color name="debugTextColor">#FF808080</color> <color name="debugTextColor">#FF808080</color>
</resources> </resources>

View File

@@ -8,12 +8,12 @@
<item name="aboutViewTextColor">?attr/mainWindowTextColor</item> <item name="aboutViewTextColor">?attr/mainWindowTextColor</item>
<item name="aboutViewTitleColor">?attr/mainWindowTextColor</item> <item name="aboutViewTitleColor">?attr/mainWindowTextColor</item>
<item name="aboutViewDividerColor">?attr/mainWindowDarkTextColor</item> <item name="aboutViewDividerColor">?attr/mainWindowDarkTextColor</item>
<item name="buttonBackgroundColor">@color/buttonBackgroundColor</item>
<item name="buttonTextColor">?attr/mainWindowTextColor</item>
<item name="dialogBackgroundColor">?attr/mainWindowBackgroundColor</item> <item name="dialogBackgroundColor">?attr/mainWindowBackgroundColor</item>
<item name="dialogTextColor">?attr/mainWindowTextColor</item> <item name="dialogTextColor">?attr/mainWindowTextColor</item>
<item name="toolbarBackgroundColor">?attr/buttonBackgroundColor</item> <item name="toolbarBackgroundColor">@color/toolbarBackgroundColor</item>
<item name="toolbarTextColor">?attr/mainWindowTextColor</item> <item name="toolbarTextColor">@color/toolbarTextColor</item>
<item name="textViewBackgroundColor">?attr/mainWindowBackgroundColor</item> <item name="textViewBackgroundColor">?attr/mainWindowBackgroundColor</item>
<item name="textViewTextColor">?attr/mainWindowTextColor</item> <item name="textViewTextColor">?attr/mainWindowTextColor</item>
<item name="editTextBackgroundColor">?attr/mainWindowBackgroundColor</item> <item name="editTextBackgroundColor">?attr/mainWindowBackgroundColor</item>
@@ -29,12 +29,14 @@
<!-- DebugActivityTheme 普通模式样式 --> <!-- DebugActivityTheme 普通模式样式 -->
<style name="DebugActivityTheme" parent="@android:style/Theme.DeviceDefault.Light.NoActionBar"> <style name="DebugActivityTheme" parent="@android:style/Theme.DeviceDefault.Light.NoActionBar">
<item name="android:statusBarColor">@color/buttonBackgroundColor</item> <item name="android:statusBarColor">@color/toolbarBackgroundColor</item>
<item name="colorTittle">?attr/mainWindowTextColor</item> <item name="colorTittle">?attr/mainWindowTextColor</item>
<item name="colorTittleBackgound">@color/buttonBackgroundColor</item> <item name="colorTittleBackgound">@color/toolbarBackgroundColor</item>
<item name="colorText">?attr/debugTextColor</item> <item name="colorText">?attr/debugTextColor</item>
<item name="colorTextBackgound">?attr/mainWindowBackgroundColor</item> <item name="colorTextBackgound">?attr/mainWindowBackgroundColor</item>
<item name="debugTextColor">@color/debugTextColor</item> <item name="debugTextColor">@color/debugTextColor</item>
<item name="toolbarTextColor">@color/toolbarTextColor</item>
</style> </style>
<!-- DialogStyle 对话框样式 --> <!-- DialogStyle 对话框样式 -->