2

我正在尝试从活动中触发文本到语音服务,并且基于某些事件的活动会导致将适当的字符串发送到说出的服务。

这是我的 TTSService:

public class TTSService extends Service implements TextToSpeech.OnInitListener{

    private String str;
    private TextToSpeech mTts;
    private static final String TAG="TTSService";
    public static TTSService sInstance;



    @Override

    public IBinder onBind(Intent arg0) {

        return null;
    }


    @Override
    public void onCreate() {

        mTts = new TextToSpeech(this,
                this  // OnInitListener
        );
        mTts.setSpeechRate(0.5f);
        Log.v(TAG, "oncreate_service");
        str ="turn left please ";
        super.onCreate();
        sInstance=this;
    }


    @Override
    public void onDestroy() {
        // TODO Auto-generated method stub
        if (mTts != null) {
            mTts.stop();
            mTts.shutdown();
        }
        super.onDestroy();
    }


    @Override
    public void onInit(int status) {
        Log.v(TAG, "oninit");
        if (status == TextToSpeech.SUCCESS) {
            int result = mTts.setLanguage(Locale.US);
            if (result == TextToSpeech.LANG_MISSING_DATA ||
                    result == TextToSpeech.LANG_NOT_SUPPORTED) {
                Log.v(TAG, "Language is not available.");
            } else {

                sayHello(str);

            }
        } else {
            Log.v(TAG, "Could not initialize TextToSpeech.");
        }
    }
    public void sayHello(String str) {
        mTts.speak(str,
                TextToSpeech.QUEUE_FLUSH,
                null);
    }
}

这是我创建服务的活动代码:

public void onCreate(Bundle savedInstanceState) {
         //rest of code.....
        Intent serviceIntent = new Intent();
        serviceIntent.setAction("com.packagename.texttospeech.TTSService");
        startService(serviceIntent);
}

这是活动的 onSensorChanged 事件处理程序:

 @Override
    public void onSensorChanged(SensorEvent event) {
        float distance = event.values[0];
        while(TTSService.sInstance==null){
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
            }
        }
        TTSService.sInstance.sayHello(Float.valueOf(distance).toString());

    }

现在,当我运行上面的活动时,它挂起并且没有响应。

在删除上面的 while 循环时,我得到以下错误跟踪:

ERROR/AndroidRuntime(7469): FATAL EXCEPTION: main
        java.lang.NullPointerException
        at com.packagename.texttospeech.SensorTestActivity.onSensorChanged(SensorTestActivity.java:51)
        at android.hardware.SensorManager$ListenerDelegate$1.handleMessage(SensorManager.java:456)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:123)
        at android.app.ActivityThread.main(ActivityThread.java:4633)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:521)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:858)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
        at dalvik.system.NativeStart.main(Native Method)

很明显,问题在于行(SensorTestActivity.java:51)中:

TTSService.sInstance.sayHello(Float.valueOf(distance).toString());

这里的sInstancenull 表明 TTSServiceonCreate()尚未完成。那么我应该如何让我的活动等到TTSService准备好使用?

4

1 回答 1

2

那么我应该如何让我的活动等到 TTSService 准备好使用?

你没有。最有可能的是,您完全摆脱了该服务,因为它似乎没有必要。有活动TextToSpeech直接使用。

如果您有明确的理由说明您的应用需要将其置于服务中:

步骤#1:删除public static TTSService sInstancesayHello()方法。

步骤#2:摆脱你现有的startService()电话。

步骤#3:替换TTSService.sInstance.sayHello(Float.valueOf(distance).toString());startService()调用,向服务发送命令,其中要说的消息作为String额外添加。

第 4 步:在onStartCommand()您的服务中,如果 TTS 初始化完成,请调用speak()说出请求的字符串(从额外中提取)。如果 TTS 初始化尚未完成,请将字符串附加到ArrayList<String>.

第 5 步:在onInit()中,将您的NullPointerException-generating调用替换为每个内容sayHello()的循环。ArrayList<String>speak()

这样,您的活动就不会关心 TTS 引擎是否已准备好。它只是将请求发送到服务,服务将其排入队列,直到 TTS 准备好,然后播放。

于 2013-08-06T14:02:21.163 回答