XuqmGroup
265994042e
fix(sdk-webview): reject file picker result when MIME type doesn't match accepted types
...
Some devices show .doc files in the picker even when only .docx was
requested (accept=".docx"). Passing the .doc URI to the WebView renderer
could cause a native crash. Now we check the actual MIME type of the
selected file against the accepted list and cancel the upload if it does
not match, preventing the renderer from receiving an unexpected file type.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-23 11:27:21 +08:00
Jenkins CI
a481da7bad
ci: bump module versions [sdk-webview]
2026-06-23 11:24:23 +08:00
XuqmGroup
ade156456a
fix(sdk-webview): handle WebView renderer crash to prevent main process from dying
...
onRenderProcessGone was not overridden, so when the WebView sandboxed
renderer process crashed (e.g. during file upload of docx), Android
terminated the main app process as well (default return false behavior).
Now: return true to keep the host app alive, report the renderer crash
via BugCollect (reflection, no compile-time dependency), and reload the
page so the user is not stuck on a blank screen.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-23 11:23:03 +08:00
Jenkins CI
daaa40147d
ci: bump module versions [sdk-bugcollect,sdk-bugcollect-plugin]
2026-06-23 11:14:23 +08:00
XuqmGroup
50effbb274
fix(bugcollect-plugin): always inject xuqmBuildId manifest placeholder for all variants
...
The placeholder was only set when minifyEnabled=true, causing debug builds
to fail with "no value for <xuqmBuildId> is provided". Moved buildId
injection before the minify guard; mapping upload task registration stays
after it.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-23 11:12:49 +08:00
Jenkins CI
3554cbdf31
ci: bump module versions [sdk-bugcollect,sdk-bugcollect-plugin]
2026-06-23 11:08:19 +08:00
XuqmGroup
9d4de920a4
fix(bugcollect): 使用 manifest meta-data 传递 buildId,修复 namespace/applicationId 不一致导致反射失败
...
BuildConfig 反射方案在 applicationId 与 namespace 不同时(如 shijiaobao flavor)会抛出
ClassNotFoundException 导致 buildId=null。改为通过 manifestPlaceholders 注入 xuqmBuildId,
SDK 从 PackageManager.getApplicationInfo(GET_META_DATA) 读取,彻底绕开包名歧义。
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-22 17:50:16 +08:00
XuqmGroup
06f7b9d44d
feat(bugcollect): 为每次打包生成独立 buildId,支持相同版本多包溯源
...
- Gradle 插件在配置阶段生成 yyyyMMddHHmmss 格式的 buildId,通过
BuildConfig.XUQM_BUILD_ID 注入 APK,并作为 buildId 字段上传 sourcemap
- SDK 通过反射读取 BuildConfig.XUQM_BUILD_ID,在所有事件
(captureError/captureCrash/warn) 的 IssueEvent 中携带 buildId
- LogUploader 序列化时将 buildId 写入上报 JSON
- IssueEvent 新增 buildId 可选字段
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-22 16:46:41 +08:00
XuqmGroup
8e0193ceec
fix: BugCollect.buildDeviceInfo 和 appVersion 在 SDK 未初始化时安全降级
...
Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-19 02:17:26 +08:00
XuqmGroup
04eb0d13d3
fix: BugCollect.captureError 在 SDK 未初始化时不再崩溃
...
- captureError 检查 XuqmSDK.isInitialized() 再访问 appKey
- SDK 未初始化时将错误加入待处理队列,初始化后自动 flush
- captureCrash 也添加 isInitialized 检查
Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-19 02:05:06 +08:00
XuqmGroup
79463a5808
feat(core): 添加请求签名功能并扩展更新接口
...
- 在 SDKConfig 中新增 signingKey 配置项
- 在 ConfigFile 中添加 signingKey 序列化支持
- 实现 API 客户端请求签名拦截器,支持 HMAC-SHA256 签名
- 在 XuqmSDK 中管理 signingKey 的存储和读取
- 扩展 UpdateApi 接口增加 currentVersionName 参数
- 在 UpdateSDK 中集成设备信息和版本号上报功能
- 为 RN SDK 添加签名密钥管理和 HTTP 请求签名注入
- 实现跨平台的 HMAC-SHA256 签名算法支持
2026-06-19 01:27:56 +08:00
XuqmGroup
e3d03c0ea7
feat: 统一 deviceId 来源,所有 SDK 模块使用 XuqmSDK.deviceId
...
- DeviceUtils.getDeviceId() 统一委托 XuqmSDK.deviceId
- sdk-license: DeviceInfoProvider 改用 DeviceUtils
- sdk-push: 所有 getDeviceId(context) 改为 getDeviceId()
- sdk-update: checkUpdate 增加 deviceId/model/osVersion/vendor 参数
- DeviceUtils 新增 getDeviceInfo() 返回完整设备信息 Map
2026-06-18 23:37:59 +08:00
XuqmGroup
fd37f57fbf
feat(sdk-core): deviceId 优先使用 ANDROID_ID,卸载重装后仍可识别设备
...
- 优先读取 Settings.Secure.ANDROID_ID(绑定设备,非应用)
- 过滤已知无效值(9774d56d682e549c 等)
- ANDROID_ID 前缀 aid_ 区分来源
- 回退到随机 UUID(恢复出厂设置等场景)
2026-06-18 22:00:26 +08:00
Jenkins CI
5d1b07b997
ci: bump module versions [sdk-core,sdk-webview,sdk-bugcollect,sdk-bugcollect-plugin]
2026-06-18 21:22:59 +08:00
XuqmGroup
ffafd94a1e
chore(bugcollect): 清理调试日志,准备发布正式版本
2026-06-18 21:15:55 +08:00
XuqmGroup
84c9eb5e7a
fix(bugcollect): 修复上传流程 - pendingErrors 队列、动态 URL、相对路径补全
2026-06-18 20:12:00 +08:00
XuqmGroup
8d0dd0a41d
debug: uploadIssues 日志改为 Log.w
2026-06-18 19:45:14 +08:00
XuqmGroup
35bf96f89f
debug(bugcollect): 添加 uploadIssues 日志
2026-06-18 19:40:29 +08:00
XuqmGroup
64580b4b9e
debug(bugcollect): 添加 flush 日志排查上传流程
2026-06-18 19:36:17 +08:00
XuqmGroup
3f03f5c1de
fix(bugcollect): 平台配置下发后延迟重试 flush,修复事件丢失
...
- startCrashCapture 后延迟检查 bugCollectApiUrl,就绪后再次 flush
- 添加调试日志帮助排查上传流程
2026-06-18 19:29:18 +08:00
XuqmGroup
ceaaeca1fe
fix(bugcollect): LogQueue 动态获取 bugCollectApiUrl,修复上传 URL 为空问题
...
- LogQueue.logApiUrl 改为动态 getter,每次上传取最新 URL
- flush() 在 URL 为空时跳过,等下次定时 flush
- LogUploader.resolveUrl 自动补全相对路径
2026-06-18 19:16:02 +08:00
XuqmGroup
d742317c4d
fix(bugcollect): LogUploader 自动将相对路径补全为绝对 URL
...
- bugCollectApiUrl 为相对路径时,基于 XuqmSDK.platformUrl 拼接完整地址
- 修复 'Expected URL scheme http or https' 异常
2026-06-18 19:06:03 +08:00
XuqmGroup
3ded960383
fix(bugcollect): captureError 在 SDK 未就绪时暂存事件,就绪后自动 flush
...
- 添加 pendingErrors 队列,SDK 未初始化时 captureError 不再丢弃事件
- startCrashCapture 完成后自动 flush 暂存事件到上传队列
2026-06-18 18:56:37 +08:00
XuqmGroup
d5ce5ffabb
refactor(bugcollect): 移除 BugCollectInitProvider 减少框架开销
...
- 移除了 BugCollectInitProvider ContentProvider
- 改为通过 XuqmSDK afterInit 回调注册崩溃拦截器
- 消除了约 380ms 的 ContentProvider 框架启动开销
- 确保在 SDK 初始化完成后注册 UncaughtExceptionHandler
2026-06-18 17:07:12 +08:00
XuqmGroup
2b1857a8ff
fix(sdk-core): initBugCollect 反射调用 Kotlin object 需传单例实例
2026-06-18 17:01:21 +08:00
XuqmGroup
e180003386
fix(sdk-bugcollect): BugCollectInitProvider 添加 CrashCapture import
...
Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-18 16:25:35 +08:00
XuqmGroup
2c610b777d
fix(sdk-core): 修复编译错误 — KDoc 转义 + MasterKeys API
...
- ConfigFileReader: KDoc 中 *.xuqmconfig 改为 \*.xuqmconfig(避免 */ 被解析为注释结束)
- ConfigCache: MasterKey → MasterKeys(兼容当前 security-crypto 版本)
Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-18 16:04:57 +08:00
XuqmGroup
b7c7a2c385
perf(sdk-core): 合并 ContentProvider + PBKDF2 缓存,冷启动从 ~350ms 降到 ~7ms
...
优化内容:
- 新增 XuqmMergedProvider:合并 3 个 Provider 为 1 个,主线程只读文件字节
- 新增 ConfigCache:EncryptedSharedPreferences 持久化缓存解密结果
- ConfigFileReader 新增 readRawBytes() / readWithCache(),单例内存缓存
- XuqmSDK 新增 autoInitializeFromBytes():IO 线程完成解密+初始化
- BugCollectInitProvider 改为兼容 fallback,检查 isInitialized() 跳过
- XuqmInitializerProvider 标记 @Deprecated
性能对比:
优化前:主线程 ~350ms(PBKDF2 + 文件扫描 + 3 个 Provider 实例化)
优化后:主线程 ~7ms(文件发现 + 读字节),后续启动 ~3ms(读缓存)
Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-18 15:58:53 +08:00
XuqmGroup
1f1c0b4018
docs(readme): 更新文档说明新增日志监控模块
...
- 添加 sdk-bugcollect 模块说明及其功能描述
- 增加日志监控模块的依赖配置示例
- 更新初始化说明,区分自动初始化和手动初始化两种方式
- 添加推荐的配置文件自动初始化方式说明
2026-06-18 15:41:09 +08:00
XuqmGroup
6a5bfd1c10
fix(sdk-core): ConfigFileReader KDoc 注释中 */ 导致编译失败,转义为 \*
2026-06-18 15:30:09 +08:00
XuqmGroup
75c1d77965
feat(sdk-core): ConfigFileReader 新增 assets/config/ 目录支持
...
对齐 RN SDK 的 src/assets/config/ 目录约定:
搜索顺序:config/config.xuqmconfig → config/*.xuqmconfig → xuqm/config.xuqm → xuqm/*.xuqmconfig
旧路径 assets/xuqm/ 保持兼容。
Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-18 15:06:40 +08:00
XuqmGroup
ba6de0a5fd
perf(sdk): ContentProvider 异步初始化,减少冷启动阻塞时间
...
- XuqmInitializerProvider 改用 autoInitializeAsync(),TokenStore/DeviceId/ApiClient 移到 IO 线程
- XuqmSDK 新增 readAppKey() 公开方法,仅读取 config 不做初始化
- BugCollectInitProvider 适配异步初始化,直接读取 appKey 注册崩溃拦截器
- 同步阶段只做 config 文件读取(~5ms),主线程不再阻塞
2026-06-18 14:53:34 +08:00
XuqmGroup
0ec173677d
feat(webview): 添加 onProgressChanged 回调,支持页面加载进度监听
2026-06-18 14:05:43 +08:00
XuqmGroup
30ce89afcc
fix(file): 公共 Downloads 使用 MediaStore 写入,兼容华为设备
...
- Android 10+ 公共目录通过 MediaStore ContentResolver 写入
- 同时写入缓存文件供 openFile 使用
- 避免华为设备 mkdirs()/writeBytes() ENOENT 问题
2026-06-18 13:56:35 +08:00
XuqmGroup
d2873eda66
refactor(file): download 方法复用 resolveBaseDir,统一目录创建逻辑
2026-06-18 13:50:48 +08:00
XuqmGroup
a6b1905a66
fix(file): resolveBaseDir 多重尝试创建目录,兼容华为/小米设备
...
- mkdirs() 静默失败时,尝试 Runtime.exec('mkdir -p')
- 仍失败则回退到 Sandbox 目录,避免 ENOENT 崩溃
2026-06-18 13:50:14 +08:00
XuqmGroup
aeeba4fac8
feat(webview): 添加 onPageError 回调,支持页面加载失败检测
...
- XWebViewConfig 新增 onPageError(errorCode, description, failingUrl) 回调
- WebViewClient.onReceivedError 捕获主框架加载错误并回调
- App 层可据此显示重试 UI
2026-06-18 13:43:56 +08:00
XuqmGroup
d015fd7d40
fix(ci): 版本信息用逗号分隔,避免 Windows 管道符冲突
2026-06-18 12:59:05 +08:00
XuqmGroup
f797ec48d3
fix(ci): post 块中用 script 包裹 Groovy 变量声明
2026-06-18 12:48:30 +08:00
XuqmGroup
3e788e1c4e
fix(ci): 转义 PUBLISHED_VERSIONS 换行符,避免 Windows bat 解析多命令
2026-06-18 12:37:42 +08:00
XuqmGroup
6f216bc4c2
fix(ci): SNAPSHOT 版本基于下一版本号,避免与已发布的 release 冲突
...
- SNAPSHOT 模式:bumpVersion(baseVer) + '-SNAPSHOT',确保高于当前 release
- 解决 Gradle 解析 SNAPSHOT 时优先使用同版本号 release 的问题
2026-06-18 12:23:51 +08:00
XuqmGroup
f0276bb440
feat(webview): 添加blob下载功能并完善存储权限处理
...
- 添加pendingBlobDownload状态管理blob下载请求
- 实现API 30+系统上MANAGE_EXTERNAL_STORAGE权限检查
- 添加blob数据解码和文件保存功能
- 集成下载完成事件分发机制
- 完善存储权限对话框中的状态清理逻辑
- 实现blob下载成功后的相册保存或文件打开操作
2026-06-18 11:52:02 +08:00
XuqmGroup
aca0d009a8
feat(bugcollect): 使用 deviceId 作为 userId 兜底,保障影响设备数统计
...
- XuqmSDK 新增 deviceId 属性:首次生成 UUID 存入 SharedPreferences,后续不变
- BugCollect 上报事件时 userId 改为 getUserId() ?: deviceId,未登录也能统计影响设备数
- BugCollectInitProvider 崩溃拦截同步使用 deviceId 兜底
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-18 10:47:38 +08:00
XuqmGroup
77fef3a38b
refactor(bugcollect): 注册与 URL 完全解耦
...
注册 UncaughtExceptionHandler 不需要 URL:
- CrashCapture.start 移除 logApiUrl 参数,只需 appContext + appKey
- LogStorage.saveCrash 移除 logApiUrl,崩溃文件不再存储 URL
- LogQueue.uploadPendingCrashes 上传时直接取 XuqmSDK.bugCollectApiUrl,
URL 为 null 则跳过(下次启动重试),不依赖崩溃文件里的历史 URL
- BugCollect.startCrashCapture 移除 URL 构造逻辑
- BugCollectInitProvider Phase 1 纯粹只注册,彻底消除对 platformUrl 的依赖,
版本兼容问题从根本上消失
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-18 10:18:08 +08:00
XuqmGroup
be8eeba9e1
fix(bugcollect): BugCollectInitProvider 对旧版 sdk-core 防御降级
...
platformUrl 是新增属性,旧版 sdk-core 没有对应的 getPlatformUrl()。
改用 runCatching 包住调用,NoSuchMethodError 时记录警告、跳过崩溃拦截,
不再因版本不一致导致 app 启动崩溃。
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-18 10:16:05 +08:00
XuqmGroup
54b3163f53
refactor(bugcollect): 崩溃收集与上传分离,sdk-core 保持独立
...
设计问题:
- 之前用反射在 XuqmInitializerProvider 里调用 BugCollect,sdk-core 隐式依赖 sdk-bugcollect
- startCrashCapture 同时负责注册拦截器和触发上传,两者生命周期不同
新架构:
- sdk-core 完全干净,XuqmInitializerProvider 还原为只调用 autoInitialize
- sdk-bugcollect 自注册 BugCollectInitProvider(initOrder=89)
- Phase 1(同步):core init 完成后立即注册 UncaughtExceptionHandler,用
platformUrl 派生兜底 URL,落盘不依赖远端配置
- Phase 2(异步):awaitInitialization() 后用最新 bugCollectApiUrl 上传积压崩溃
- BugCollect.uploadPendingCrashes() 公开,供 Phase 2 调用
- startCrashCapture() 保持幂等,app 侧可选择性调用,不影响自动流程
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-18 10:11:08 +08:00
XuqmGroup
cc1557daf0
fix(bugcollect): 修复 fatal crash 不上报——startCrashCapture 从未被调用
...
根本原因链:
1. XuqmInitializerProvider 只调用 XuqmSDK.autoInitialize,从不调用 startCrashCapture
2. 即使调用,startCrashCapture 检查 bugCollectApiUrl == null 即提前返回;
而 bugCollectApiUrl 由远端配置下发,崩溃发生时往往尚未到达
3. UncaughtExceptionHandler 从未注册,崩溃文件没有写入,下次启动无数据可上报
修复:
- XuqmSDK 新增 platformUrl 属性(同步可用,初始化即有值)
- BugCollect.startCrashCapture 不再依赖 bugCollectApiUrl,
用 platformUrl + "/api/bugcollect/" 作为兜底 URL 写入崩溃文件
- LogQueue.uploadPendingCrashes 优先使用崩溃文件内保存的 logApiUrl
- XuqmInitializerProvider 通过反射调用 BugCollect.startCrashCapture,
在 SDK 初始化后立即注册 UncaughtExceptionHandler
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-18 10:05:43 +08:00
XuqmGroup
e300cbdb83
fix(bugcollect): 修复崩溃文件未写入导致 fatal crash 不上报的 bug
...
根本原因:CrashCapture 调用无 Context 的 LogStorage.saveCrash 重载,
该重载通过反射获取 packageName 失败时返回空字符串,
导致崩溃文件路径变为 /data/data//files/xuqm_crashes(无效),
mkdirs() 静默失败,崩溃文件未写入,下次启动无数据可上报。
修复:
- CrashCapture.start() 新增 appContext: Context 参数
- 改为调用带 Context 的 saveCrash 重载,依赖 context.filesDir 获取可靠路径
- BugCollect.startCrashCapture() 传入 XuqmSDK.appContext
- LogStorage 删除不可靠的无 Context 重载及 getPackageName() 反射代码
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-18 09:43:47 +08:00
XuqmGroup
58d479523e
fix: uniquePropNames 去重逻辑修复,避免重复 bump 版本
2026-06-17 19:14:37 +08:00
Jenkins CI
0a93127f01
ci: bump module versions [sdk-bugcollect,sdk-bugcollect-plugin]
2026-06-17 19:09:09 +08:00