本次追加覆盖 FCM/APNs 用户通知的前台、后台和锁屏语音。uniPush、消息中心 body、原业务 payload、商家/骑手默认声音保持原规则。不使用 VoIP,不新增通知或声音下载接口。服务端默认推送通道仍为 uni,测试入口直接使用原生发送。
音频位于 assets/native-wav,完整文件和渠道映射见 manifest.json。63 个 WAV:9 场景 × 7 语种,16 kHz、单声道、16-bit Linear PCM,均不足 30 秒。由用户提供的 MP3 转换,原目录未修改;zh-CN/zh-TW 的语音分别统一选用提供的 zh-Hans/zh-Hant 源文件,不合并或覆盖原文件。
| 场景字段 | 值 | 文件名前缀 |
|---|---|---|
| eventScene | RIDER_ACCEPTED | rider_accepted |
| eventScene | ORDER_DELIVERING | order_delivering |
| eventScene | ORDER_DELIVERED | order_delivered |
| eventScene | MERCHANT_ACCEPTED | merchant_accepted |
| eventScene | MERCHANT_READY | merchant_ready |
| eventScene | PAYMENT_SUCCEEDED | payment_succeeded |
| eventScene | ORDER_CANCELLED | order_cancelled |
| eventType | FLASH_PICKUP_STOP_COMPLETED | flash_pickup_stop_completed |
| eventType | FLASH_DELIVERY_STOP_COMPLETED | flash_delivery_stop_completed |
文件格式:{场景小写}_{语言后缀}.wav,例如 rider_accepted_zh_hant.wav。
| 传入/已保存语言示例 | 资源后缀 |
|---|---|
| zhHant、zh-Hant、zh-TW、zh_TW、tw、zh-Hant-TW | zh_hant |
| zhHans、zh-Hans、zh-CN、zh_CN、zh-Hans-CN | zh_hans |
| en、en-US | en |
| th、th-TH | th |
| id、id-ID、in | id |
| ms、ms-MY | ms |
| tl、fil、fil-PH | tl |
| 未设置、空白、未知(含 vi、未指定繁简的 zh) | zh_hant |
业务通知读取现有 GET /changeLanguages?lang=zhHant&id=用户ID 保存的语言,使用与该接口相同的 Jedis DB 0 和原始用户 ID 键;App 在登录/切换语言时需调用既有接口。此处不改造该旧接口权限或签名。缓存不可用时通知仍发送,声音使用繁中。测试入口直接读请求 language,不查用户或语言缓存。缺场景/未知场景不猜语音,保留原默认通知声音。
将 WAV 作为资源加入用户 App target,确认文件真正包含在安装包的 bundle 中;也可使用系统支持的 Library/Sounds 目录。后端 aps.sound 直接指定文件名,同时在 userInfo 顶层放 sound,供前台处理。
{
"aps": {
"alert": {"title": "订单通知", "body": "骑手已接单"},
"sound": "rider_accepted_zh_hant.wav"
},
"sound": "rider_accepted_zh_hant.wav",
"payload": "{\"eventScene\":\"RIDER_ACCEPTED\"}"
}
WAV 是 Apple 支持的系统通知声音格式,不需要再转 CAF;不能只改 MP3 扩展名。申请通知及声音权限。前台可在系统回调允许 sound,或按顶层 sound 手动播放,二选一以免双响。后台/锁屏由系统播放,点击通知、加载历史消息、恢复前台不补播。静音、专注模式及用户权限可能抑制声音,后端不能强制绕过。
APNs 网关仍按现有 apns-environment 选择,与本功能无关;签名环境必须匹配 Token。测试接口成功仅表示推送服务接受,不表示手机已播放。
将 WAV 复制到用户 App 原生工程 res/raw/,文件名保持小写字母与下划线。首次启动时按 manifest 创建全部 63 个声音渠道,确保后台通知到达前渠道已存在。渠道 ID 为 user_voice_{不含扩展名的资源名}_v1,例如 user_voice_rider_accepted_zh_hant_v1。
创建渠道时:IMPORTANCE_HIGH,sound URI 指向该 raw 资源,AudioAttributes 使用 USAGE_NOTIFICATION;渠道名称需由 App 国际化。后端发送 notification + data:
{
"android": {
"priority": "high",
"notification": {
"sound": "rider_accepted_zh_hant",
"default_sound": false,
"channel_id": "user_voice_rider_accepted_zh_hant_v1"
}
},
"data": {
"sound": "rider_accepted_zh_hant.wav",
"channelId": "user_voice_rider_accepted_zh_hant_v1",
"payload": "{\"eventScene\":\"RIDER_ACCEPTED\"}"
}
}
Android 8+ 以渠道声音为准,后端传 sound 无法覆盖已有渠道设置;渠道缺失可能回退默认渠道。渠道一旦创建便不能靠重新 setSound 修改,未来更换绑定声音需双方约定新版本渠道 ID。Android 13+ 申请通知权限。后台/锁屏使用系统通知;前台由 App 根据 data.sound 播放,或使用 data.channelId 发本地通知,二选一。用户关闭渠道声音时不能保证响铃。
匿名 POST /system/push/testNative,Content-Type: application/json,不切换业务推送模式,不需要用户 ID。沿用已有 token 手填方式,新增可选 language;场景仍在 payload 中,payload 是字符串。
{
"appType": "user",
"platform": "android",
"deviceToken": "填写手机当前原生Token",
"title": "语音测试",
"content": "骑手已接单",
"language": "zhHant",
"payload": "{\"eventScene\":\"RIDER_ACCEPTED\"}"
}
iOS 将 platform 改为 ios 并填写对应 APNs Token。闪送站点示例:payload 使用 {"eventType":"FLASH_PICKUP_STOP_COMPLETED"} 的 JSON 字符串。省略 language 或传未知值,应使用繁中声音。老请求不含场景时仍按原默认声音发送。