2

アクティビティから Text to Speech サービスを起動しようとしていますが、特定のイベントに基づくアクティビティにより、適切な文字列がサービスに送信されて発言します。

ここに私の 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());

ここでsInstanceは null であり、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()要求された文字列 (extra からプル) を呼び出して話します。TTS の初期化がまだ完了していない場合は、文字列をArrayList<String>.

ステップ #5:で、 -generating呼び出しをそれぞれのコンテンツのループonInit()に置き換えます。NullPointerExceptionsayHello()ArrayList<String>speak()

このように、アクティビティは TTS エンジンの準備ができているかどうかを気にしません。リクエストをサービスに送信するだけで、TTS の準備が整うまでキューに入れられ、その時点で再生されます。

于 2013-08-06T14:02:21.163 に答える