From 76b0332035cd2c7f26254748381121eca5626343 Mon Sep 17 00:00:00 2001 From: Shuming Liu Date: Wed, 26 Aug 2026 11:49:02 +0800 Subject: [PATCH] add docs --- docs/wechat-share-app-name.md | 257 ++++++++++++++++++++++++++++++++++ 1 file changed, 257 insertions(+) create mode 100644 docs/wechat-share-app-name.md diff --git a/docs/wechat-share-app-name.md b/docs/wechat-share-app-name.md new file mode 100644 index 0000000..f47ced2 --- /dev/null +++ b/docs/wechat-share-app-name.md @@ -0,0 +1,257 @@ +# 微信分享返回提示显示“八哥口语”改造备忘 + +## 背景 + +当前 Android 配音分享使用系统 `Intent.ACTION_SEND`,入口位于: + +```kotlin +android/sample-app/src/main/java/cn/learningpad/oraltrainer/sample/MainActivity.kt +``` + +`shareMergedDubbing()` 会构造一个 `ACTION_SEND` Intent,然后通过 `startActivity(Intent.createChooser(...))` 调起微信或其他应用。 + +这种方式下,微信只能识别到“第三方应用通过系统分享调起”,无法可靠关联到微信开放平台登记的 App 信息,因此完成后的返回提示通常显示为“留在微信 / 返回第三方工具”。 + +要让提示变成“返回八哥口语”,需要改为微信官方 OpenSDK 分享,并在微信开放平台完成应用登记。 + +## 目标 + +1. 配音链接通过微信 OpenSDK 分享为网页卡片。 +2. 微信完成页返回提示能识别并显示“八哥口语”。 +3. 保留现有上传分享链接的逻辑,只替换最终调起微信的方式。 + +## 需要提前准备的信息 + +| 项目 | 当前值 | +|---|---| +| 应用名称 | 八哥口语 | +| Android 包名 | `cn.learningpad.oraltrainer.sample` | +| Gradle namespace | `cn.learningpad.oraltrainer.sample` | +| 微信回调 Activity 包名 | `cn.learningpad.oraltrainer.sample.wxapi` | +| 回调 Activity 类名 | `WXEntryActivity` | +| 本地名称资源 | `android:label="@string/app_name"` | + +还需要从微信开放平台获取: + +- 微信 AppID +- 应用签名 MD5 +- 已审核通过的移动应用信息 + +## 一、微信开放平台登记 + +1. 登录 [微信开放平台](https://open.weixin.qq.com/)。 +2. 进入“管理中心”,创建或打开移动应用。 +3. 填写应用名称为“八哥口语”。 +4. 配置 Android 应用信息: + - 包名:`cn.learningpad.oraltrainer.sample` + - 签名:使用正式签名 APK 的应用签名 MD5 +5. 提交审核,等待微信开放平台通过。 +6. 审核通过后记录微信 AppID。 + +注意:微信校验的是正式签名。Debug 构建如果也要联调,需要在开放平台补充 Debug 签名,或临时使用与正式签名一致的构建配置。 + +## 二、获取正式签名 MD5 + +安装已签名的 APK 后执行: + +```bash +adb shell dumpsys package cn.learningpad.oraltrainer.sample | grep -A 2 "Signatures" +``` + +更稳妥的方式是使用微信官方提供的生成签名工具,或在本地用正式 keystore 查询证书指纹: + +```bash +keytool -list -v -alias -keystore +``` + +将结果中的 `MD5` 去掉冒号并转为小写后填入微信开放平台。 + +## 三、添加微信 OpenSDK + +修改文件: + +```text +android/sample-app/build.gradle.kts +``` + +在 `dependencies` 中加入: + +```kotlin +implementation("com.tencent.mm.opensdk:wechat-sdk-android:6.7.0") +``` + +建议实施时检查 Maven 上是否有更新稳定版;如果没有特殊需求,可继续固定当前版本,避免 SDK 行为漂移。 + +## 四、初始化微信 API + +建议在 `MainActivity` 中增加: + +```kotlin +private lateinit var wxApi: IWXAPI +``` + +在创建 Activity 或进入配音功能前初始化: + +```kotlin +wxApi = WXAPIFactory.createWXAPI(this, WECHAT_APP_ID, true) +wxApi.registerApp(WECHAT_APP_ID) +``` + +`WECHAT_APP_ID` 应放入构建配置、Manifest metadata 或私有配置中,不要硬编码在业务代码里。 + +## 五、替换系统分享调用 + +保留现有 `uploadDubShare()`,拿到 `shareUrl` 后改用: + +```kotlin +val webpage = WXWebpageObject().apply { + webpageUrl = shareUrl +} + +val message = WXMediaMessage(webpage).apply { + title = "我的口语配音" + description = item.title +} + +val request = SendMessageToWX.Req().apply { + message = message + transaction = "dub_share" + scene = SendMessageToWX.Req.WXSceneSession +} + +if (!wxApi.sendReq(request)) { + setDubbingStatus("分享失败:未检测到可用的微信客户端") +} else { + setDubbingStatus("已生成分享链接:$shareUrl") +} +``` + +如需支持朋友圈,把 `scene` 改为: + +```kotlin +SendMessageToWX.Req.WXSceneTimeline +``` + +当前需求主要是发给好友或群聊,建议先保持 `WXSceneSession`。 + +## 六、新增微信回调 Activity + +必须严格按包名规则创建: + +```text +android/sample-app/src/main/java/cn/learningpad/oraltrainer/sample/wxapi/WXEntryActivity.kt +``` + +示例内容: + +```kotlin +package cn.learningpad.oraltrainer.sample.wxapi + +import android.app.Activity +import android.content.pm.PackageManager +import android.os.Bundle +import com.tencent.mm.opensdk.modelbase.BaseReq +import com.tencent.mm.opensdk.modelbase.BaseResp +import com.tencent.mm.opensdk.openapi.IWXAPI +import com.tencent.mm.opensdk.openapi.IWXAPIEventHandler +import com.tencent.mm.opensdk.openapi.WXAPIFactory + +class WXEntryActivity : Activity(), IWXAPIEventHandler { + private lateinit var api: IWXAPI + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + val info = packageManager.getApplicationInfo( + packageName, + PackageManager.GET_META_DATA + ) + val appId = info.metaData.getString("com.tencent.wechat.APP_ID").orEmpty() + api = WXAPIFactory.createWXAPI(this, appId, true) + api.handleIntent(intent, this) + finish() + } + + override fun onReq(req: BaseReq) {} + + override fun onResp(resp: BaseResp) { + finish() + } +} +``` + +## 七、注册回调 Activity + +修改: + +```text +android/sample-app/src/main/AndroidManifest.xml +``` + +在 `` 内添加: + +```xml + +``` + +`android:label="@string/app_name"` 对应中文资源里的“八哥口语”: + +```text +android/sample-app/src/main/res/values-zh/strings.xml +``` + +## 八、配置 AppID + +推荐方式是在 Manifest 中加: + +```xml + +``` + +并在 `build.gradle.kts` 中加: + +```kotlin +manifestPlaceholders["wechatAppId"] = "替换为微信AppID" +``` + +正式项目建议不要直接提交真实密钥类配置。虽然微信 AppID 本身不是私钥,但仍更适合放到本地配置或 CI 注入。 + +## 九、验收清单 + +- [ ] 正式签名包安装成功。 +- [ ] 点击“分享配音”后不再走系统分享面板,而是直接拉起微信。 +- [ ] 微信好友会话中出现网页卡片,标题为“我的口语配音”。 +- [ ] 卡片点击后能正常打开配音分享页。 +- [ ] 分享完成后,微信返回提示显示“八哥口语”相关文案,而不是“第三方工具”。 +- [ ] 从微信返回后,八哥口语仍停留在原界面。 +- [ ] 未安装微信时给出明确失败提示,不崩溃。 +- [ ] Debug 与 Release 的包名和签名策略确认无误。 + +## 十、容易踩坑的点 + +1. **包名必须完全一致** + `WXEntryActivity` 必须放在 `cn.learningpad.oraltrainer.sample.wxapi` 下,否则微信无法回调。 + +2. **签名必须是开放平台登记的那个** + Debug 签名和 Release 签名不同时,OpenSDK 可能无法正常调起或回调。 + +3. **应用名称以微信开放平台为准** + 只修改 Android 本地 `app_name` 不一定足够;微信返回文案依赖开放平台登记的应用信息。 + +4. **不要删除现有网页分享逻辑** + `uploadDubShare()` 仍然负责生成服务端分享链接,微信 OpenSDK 只负责把这个链接作为网页对象发送。 + +5. **旧版本微信兼容性** + 如果用户微信版本过低,`sendReq()` 可能返回 false。应给用户明确提示。 + +## 结论 + +这个问题的根因是当前实现使用系统 `ACTION_SEND`,而不是微信官方 OpenSDK。 +要显示“返回八哥口语”,必须完成微信开放平台登记、正式签名绑定,并把分享路径切换为 `IWXAPI.sendReq()`。