React Native前台接收OneSignal通知时React Native TTS无法播放语音的问题排查
我明白你遇到的问题了——前台收到OneSignal通知时日志能正常打印,但React Native TTS就是不发声,确实挺闹心的。结合你的代码和日志信息,咱们一步步排查可能的原因:
先排查TTS初始化的异常处理
你当前的代码只处理了Tts.getInitStatus()成功的情况,但如果TTS引擎未初始化完成、或者系统没有可用的TTS引擎,这个Promise会直接reject,而你没有加catch块,导致后续的Tts.speak根本不会执行,也看不到错误日志。建议你补充异常处理,甚至手动触发初始化:const handleForegroundNotification = (event: any) => { console.log('Foreground Notification:', event); event.notification.display(); Tts.setDefaultLanguage('en'); Tts.getInitStatus() .then(() => { // 先替换成固定文本测试,排除其他函数干扰 Tts.speak("Payment accepted. 36500 rupiah"); }) .catch((err) => { console.error('TTS初始化状态检查失败:', err); // 尝试手动初始化TTS Tts.init() .then(() => Tts.speak("Payment accepted. 36500 rupiah")) .catch(initErr => console.error('手动初始化TTS失败:', initErr)); }); };另外,也可以在App启动的早期(比如
useEffect钩子中)就完成TTS初始化,避免通知到来时才临时初始化的延迟或失败。检查
numberToWords函数是否存在异常
如果numberToWords(36500)这个函数调用抛出错误(比如未正确引入、数字转换逻辑有bug),会直接终止then块的代码执行,导致Tts.speak被跳过。你可以先把这个函数去掉,换成上面代码里的固定数字文本测试,如果能正常发声,就重点排查numberToWords的逻辑问题。确认Android模拟器的TTS环境是否正常
Android模拟器默认可能没有预装可用的TTS引擎,或者对应的语言包未下载:- 打开模拟器的系统设置,进入「系统」>「语言和输入法」>「文字转语音输出」
- 检查是否有可用的TTS引擎(比如Google文字转语音),没有的话需要在应用商店下载安装
- 确保「英语(美国)」语言包已下载完成
- 可以在设置页面直接点击「播放示例」按钮,确认系统级的TTS功能正常
排查Android权限和前台播放限制
虽然TTS播放不需要录音权限,但Android 12+对前台应用的音频播放有一些细节要求,你可以检查AndroidManifest.xml里是否添加了必要的权限:<!-- TTS可能需要联网下载语言包 --> <uses-permission android:name="android.permission.INTERNET" /> <!-- 针对Android 12+的前台媒体播放权限 --> <uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK" />另外,你可以在App的其他场景(比如加一个测试按钮,点击后调用
Tts.speak)测试TTS是否能正常发声,如果按钮点击能出声,说明TTS本身没问题,问题出在OneSignal事件的处理时机上。检查事件处理的线程或时机问题
OneSignal的foregroundWillDisplay事件可能在非JS主线程触发,导致TTS调用不生效。你可以尝试把TTS的调用放到React Native的主线程队列里执行:import { InteractionManager } from 'react-native'; // 在then块里修改: InteractionManager.runAfterInteractions(() => { Tts.speak("Payment accepted. 36500 rupiah"); });或者用
setTimeout延迟100ms执行,避开通知显示的资源占用高峰,看看是否能触发发声。
内容来源于stack exchange

