提交图

245 次代码提交

作者 SHA1 备注 提交日期
XuqmGroup
33dcc48cbf fix(sdk-core): 移除 ConfigCache,直接解密 rawBytes 避免 signingKey 丢失
ConfigFileReader.readWithCache() 缓存路径不包含 signingKey 字段,
导致二次启动时 signingKey=null。autoInitializeFromBytes 改为直接
在 IO 线程对传入的 rawBytes 执行 PBKDF2 解密(约 100ms),
彻底避免缓存导致的字段缺失问题。版本升级至 1.1.7-SNAPSHOT。

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-26 11:47:17 +08:00
XuqmGroup
e6fcdefacd fix(push): 修复 VIVO push initialize 调用失败问题
PushClient.initialize() 无参版本为 private,v4.x SDK 公开方法为
initialize(PushConfig)。通过反射构建 PushConfig.Builder().build()
后调用正确的公开方法。同时移除已废弃的 persistRegId()——v4.x SDK 的
regId 通过 onReceiveRegId 回调异步返回,不再提供同步 getRegId()。

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-25 18:36:03 +08:00
XuqmGroup
fc43885f1e feat(push): 通知点击事件通过回调给 App,不在 SDK 内解析业务逻辑
- 新增 PushNotificationClickEvent(vendor/title/content/params/skipContent)
- PushSDK.setNotificationClickListener 供 App 注册通知点击回调
- PushSDK.dispatchNotificationClick(internal):触发回调 + 启动宿主 Activity
  携带原始 extras(EXTRA_PUSH_PARAMS/EXTRA_PUSH_SKIP_CONTENT/EXTRA_PUSH_VENDOR),
  冷启动场景由 App 自行从 Intent extras 解析
- XuqmVivoPushReceiver 仅负责把 UPSNotificationMessage 转为 event 后分发,
  不做任何业务层解析(URL 跳转逻辑由 App 实现)
- 删除 PushDeepLinkHandler(职责越界)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-25 18:03:37 +08:00
XuqmGroup
f63ae07bcb feat(push): 添加推送通知点击 URL 跳转支持
- 新增 PushDeepLinkHandler:通过 getLaunchIntentForPackage 启动宿主 App
  并携带 xuqm_push_url extra,供 MainActivity 读取后导航 WebView
- XuqmVivoPushReceiver.onNotificationMessageClicked 提取 params["url"]
  或 skipContent,调用 PushDeepLinkHandler.open()

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-25 18:00:33 +08:00
XuqmGroup
978312956c fix(push): 修复 UnvarnishedMessage.content -> message 编译错误
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-25 17:27:11 +08:00
XuqmGroup
344efbb0aa feat(push): 完成 VIVO 推送集成 + Xiaomi 凭据强校验
- XuqmVivoPushReceiver 从 BroadcastReceiver 改为继承 OpenClientPushMessageReceiver,通过 onReceiveRegId 回调获取 regId(修复之前 extractRegId 的脆弱 key 匹配)
- VIVO receiver android:exported 从 false 改为 true(跨进程广播必须可导出)
- VivoPushService 失败日志级别从 Log.w 提升为 Log.e
- Xiaomi/VIVO 凭据必须来自控制台,获取不到时抛出异常(移除 meta-data 本地兜底)
- PushSDK.loadVendorConfig 失败时向上抛异常,不再 swallow

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-25 16:57:18 +08:00
XuqmGroup
4f4f8564df fix(webview): 恢复文件选择器使用 ACTION_GET_CONTENT 保持原有 UI
ACTION_OPEN_DOCUMENT 打开的是 SAF 文档选择器,缺少文档、图片、最近等
快捷入口,体验不及 ACTION_GET_CONTENT 的系统底部弹窗。

真正修复 vivo/OPPO URI 权限问题的是 copyUriToWebViewCache(),选择文件后
将内容复制到本地 file:// 路径再传给 WebView,与 Intent 类型无关。
故改回 ACTION_GET_CONTENT,恢复原有选择器界面。

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-24 14:38:25 +08:00
XuqmGroup
7306041d79 fix(file): 解决文件下载和时间戳处理问题
- 实现文件名扩展名推断逻辑,从URL路径自动提取并添加扩展名
- 添加下载错误处理和日志记录功能
- 在下载失败时显示错误通知而非成功通知
- 将服务器时间戳处理统一调整为CST(亚洲/上海)时区
- 更新sdk-core版本号至1.1.6-SNAPSHOT
2026-06-23 16:43:19 +08:00
XuqmGroup
3d62a6ed72 fix: docx MIME 检测 + Fingerprint 协程帧稳定性
sdk-webview:
  选文件时 DISPLAY_NAME 在 vivo content://media/external/file/ URI
  上返回 null,导致扩展名推断失效;ContentResolver.getType() 对 .docx
  返回 application/msword(错误)→ allowed 检查拒绝文件。
  修复:DISPLAY_NAME 为 null 时回退查 MediaStore.DATA 提取文件名;
  优先使用扩展名推断的 MIME 而非 ContentResolver 的返回值,
  避免厂商 ROM 返回错误 MIME 的干扰。copyUriToWebViewCache 同步修复。

sdk-bugcollect:
  Fingerprint.compute 取 top3 stack 帧,Kotlin 协程 dispatcher 的
  第 2、3 帧在每次调度时不固定,相同逻辑错误产生不同指纹 → 多条 issue。
  修改为 top1(只取抛出点帧),保证同一位置抛出的异常总被归为一条。

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-23 15:19:51 +08:00
XuqmGroup
ab0dc90909 debug(webview): 文件选择器全链路日志 + 修复逗号分隔 acceptTypes
1. resolvePickerMimeTypes 对每个 entry 先按逗号拆分,再解析;
   修复部分 WebView 将 accept=".docx,.doc" 作为单个字符串传入
   导致 getMimeTypeFromExtension("docx,.doc") 返回 null → 变成 */*
   但实际 picker 仍以 */* 启动无过滤的问题。

2. 添加 XWV-FilePicker tag 日志,覆盖:
   - onShowFileChooser: acceptTypes / resolvedMimes / 分支选择
   - launchPickerWithPermission: 权限检查结果
   - storageReadPermissionLauncher: 权限申请结果
   - pickContentLauncher: uri / rawMime / displayName / extMime /
     actualMime / allowed / onReceiveValue 最终值
   - copyUriToWebViewCache: 开始/结束/字节数

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-23 15:09:56 +08:00
Jenkins CI
64e7ae57a2 ci: bump module versions [sdk-core,sdk-im,sdk-push,sdk-update,sdk-webview,sdk-license,sdk-bugcollect,sdk-bugcollect-plugin] 2026-06-23 15:00:47 +08:00
XuqmGroup
6d18af496b fix: 移除库模块 isMinifyEnabled 修复 Duplicate class 冲突
Android 库模块开启 isMinifyEnabled=true 时,R8 各自独立混淆,
将内部类重命名为 a.a / a.b 等短名打进 AAR;多个 AAR 合并到 App
时产生 Duplicate class 冲突。

修复:删除全部 7 个库模块 buildTypes.release 中的 isMinifyEnabled,
混淆由 App 的 R8 统一完成。将 proguard-rules.pro 中的保留规则
(manifest 注册类、反射调用入口、dontwarn)合并进各模块的
consumer-rules.pro 随 AAR 打包。

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-23 14:57:22 +08:00
XuqmGroup
7169e66ee9 fix(bugcollect): flush 时修正初始化前暂存事件的 appKey
SDK 通过 ContentProvider 异步初始化(sdkScope.launch),若应用层在
initialized=true 设置前调用 captureError,事件以 appKey="pending"
存入 pendingErrors。后续 flushPendingErrors 将其原样推送给 LogQueue,
服务端找不到对应应用而丢弃,导致上报丢失。

修复:flush 时检测 appKey=="pending" 并替换为真实值(appKey、userId、
release、buildId),确保早期捕获的错误能正常上报。

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-23 14:40:18 +08:00
Jenkins CI
584aba22b1 ci: bump module versions [sdk-webview] 2026-06-23 14:32:13 +08:00
XuqmGroup
7b66fcf333 fix(webview): 修复 Office 文件选择后无响应问题
ContentResolver.getType() 对 doc/docx/xls/xlsx 等 Office 文件经常
返回 "application/octet-stream" 而非精确 MIME 类型,导致 allowed
检查失败、文件被拒绝、H5 无响应。

修复:rawMime 为 null 或 application/octet-stream 时,从文件显示名
的扩展名推断精确 MIME(getMimeTypeFromExtension),使 .docx 能正确
匹配 accept 约束并进入缓存复制流程。

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-23 14:30:18 +08:00
Jenkins CI
efb9721ddf ci: bump module versions [sdk-webview] 2026-06-23 14:22:26 +08:00
XuqmGroup
059347988a fix(webview): 文件选择器权限检查 + content URI 本地缓存
1. 触发文件选择前检查存储读取权限:API < 33 检查
   READ_EXTERNAL_STORAGE,API 33+ 按 MIME 类型检查粒度媒体权限;
   权限不足时先申请,结果回调后再启动选择器。

2. 将选中文件的 content:// URI 复制到 app 私有缓存目录后再传给
   WebView,解决云盘、系统相册、媒体库等 content://media/ URI
   WebView 渲染进程无法读取导致 H5 上传内容为空的问题。
   同时修复了 doc/docx 无响应及 PDF 返回不可用 URI 的问题。

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-23 14:20:16 +08:00
Jenkins CI
1662ccc2ea ci: bump module versions [sdk-core,sdk-im,sdk-push,sdk-update,sdk-webview,sdk-license,sdk-bugcollect,sdk-bugcollect-plugin] 2026-06-23 14:00:07 +08:00
XuqmGroup
8fe22a8c96 fix(proguard/push): 补充 Firebase/GMS 及厂商推送 SDK 的 -dontwarn 规则
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-23 13:47:28 +08:00
XuqmGroup
fbe2a6b677 fix(proguard): sdk-core 保留全部类名,其余模块加 -dontwarn 避免跨模块 R8 缺类错误
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-23 13:44:19 +08:00
XuqmGroup
aac4bd7baa feat(proguard): 各模块开启 R8 混淆,添加 proguard-rules.pro 保留公开 API
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-23 13:35:10 +08:00
Jenkins CI
73fcba76fb ci: bump module versions [sdk-webview] 2026-06-23 11:28:41 +08:00
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