broadcastreceiver 内部的 TTS 呼叫传入 call/sms

TTS inside broadcastreceiver call for incoming call/sms

我正在开发呼叫名称播音员应用程序。但是我的项目在收到短信时不说话。它接收成功,但不能说。我认为从 BroadcastReceiver 调用 TTS 有问题。这是我的代码:

public class SMSAnnouncer extends BroadcastReceiver {

@Override
public void onReceive(Context context, Intent intent) {
    Bundle b = intent.getExtras();
    SmsMessage[] mensajes = null;
    String cadena = "";
    if (b != null) {
        Object[] objetos = (Object[]) b.get("pdus");
        mensajes = new SmsMessage[objetos.length];

        for (int i = 0; i < mensajes.length; i++) {
            mensajes[i] = SmsMessage.createFromPdu((byte[]) objetos[i]);
            cadena += "SMS de " + mensajes[i].getOriginatingAddress();
            cadena += "Compuesto por...";
            cadena += mensajes[i].getMessageBody().toString();
            cadena += "\n";
        }
        Toast.makeText(context, cadena, Toast.LENGTH_LONG).show();
        Speaker habla = new Speaker();
        habla.speak(cadena);
    }
}
}


public class Speaker extends Activity {

TextToSpeech ttp;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    ttp = new TextToSpeech(getApplicationContext(), new OnInitListener() {
        @Override
        public void onInit(int status) {
            if (status != TextToSpeech.ERROR) {
                Locale loc = new Locale("spa", "ESP");
                ttp.setSpeechRate(2);
                ttp.setLanguage(Locale.US);
                ttp.setSpeechRate(0.8f);
            }
        }
    });
}

void speak(String sms) {
    ttp.speak(sms, TextToSpeech.QUEUE_FLUSH, null);
}
}

<application
    android:icon="@drawable/icon"
    android:label="@string/app_name"
    android:theme="@style/AppTheme" >

    <activity
        android:name="com.callandsmsblocker.MainActivity"
        android:label="@string/app_name" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>

    <receiver android:name="com.callandsmsblocker.CallAnnouncer" >
        <intent-filter android:priority="1000" >
            <action android:name="android.intent.action.PHONE_STATE" >
            </action>
        </intent-filter>
    </receiver>

    <receiver android:name="com.callandsmsblocker.SMSAnnouncer" >
        <intent-filter android:priority="1000" >
            <action android:name="android.provider.Telephony.SMS_RECEIVED" />
        </intent-filter>
    </receiver>
</application>

来自 BroadcastReceiver 文档

A BroadcastReceiver object is only valid for the duration of the call to onReceive(Context, Intent). Once your code returns from this function, the system considers the object to be finished and no longer active.

TTS 对象的初始化是异步的。 TTS 对象在调用 onInit() 之前不会被初始化。在 onInit() 之前调用 speak 方法不是非法的,但不会产生声音。

onInit() 将在您的 onReceived() 代码的最后一行之后调用,即 habla.speak(cadena); 因此您的代码将不会产生声音。

您应该在 onReceived() 中启动一个 service 将文本消息作为 intent extra 传递,并让 service 实例化一个 TTS 对象并说出onInit().

中的消息