2016-04-23 14 views
0

私はクラスDistanceAnnouncerを持っています。これは、Android Text-to-speechエンジンを使用して2つの場所間の距離をアナウンスします。Android TTSでサウンドが聞こえません - 間違ったコンテキストですか?

public class DistanceAnnouncer { 
    private TextToSpeech speaker; 

    public DistanceAnnouncer(Context context) { 
     speaker = new TextToSpeech(context, new TextToSpeech.OnInitListener() { 
     ... 

の距離は、この方法でユーザーに話されて:...私のMainActivity私はクラスレベルのオブジェクトを作成するには

public void speak(Location targetLocation, Location currentLocation) { 
    float distanceInMeters = targetLocation.distanceTo(currentLocation); 
    speaker.speak(String.valueOf(distanceInMeters) + " meters",TextToSpeech.QUEUE_FLUSH,null); 

protected void onCreate(Bundle savedInstanceState) { 

    distanceAnnouncer = new DistanceAnnouncer(this); 

それがこのように構成され、以下に示すダイアログボタンをクリックすると、匿名メソッドで使用されます。これは正常に動作します。しかし、今私は、より少ないメモリを使用するコードをリファクタリングしたいし、クラスレベルの変数を取り除きたい。それをテストするために、私は新しいテストオブジェクトを作成し、コンテキストとしてMainActivity.thisを与えました(コンストラクタがthisを受け取るクラスレベルのオブジェクトではありません)。古いオブジェクトはまだ動作し、新しいオブジェクトは動作しません。例外はありません。コードは実行されますが、サウンドはありません。

コード:

public void NewTargetButtonClicked(View view) { 
     final EditText entryEditText = new EditText(this); 

     AlertDialog.Builder alert = new AlertDialog.Builder(this); 
     alert.setTitle(R.string.enter_coordinates_prompt); 
     alert.setView(entryEditText); 
     alert.setCancelable(true); 
     alert.setPositiveButton(R.string.ok_button_text, new DialogInterface.OnClickListener() { 
      @Override 
      public void onClick(DialogInterface dialog, int which) { 
       if (entryEditText.getText() == null) return; 

       Location newLocation = getLocationFromCoords(entryEditText.getText().toString()); 
       //pagaidām protam apstrādāt tikai decimālgrādus 
       if (!(newLocation == null)) { 
        mTargetLocation = newLocation; 
        refreshDistance(); 
        Button targetButton = (Button) MainActivity.this.findViewById(R.id.newTargetButton); 
        targetButton.setText(R.string.set_new_target); 

        DistanceAnnouncer newDistanceAnnouncer = new DistanceAnnouncer(MainActivity.this); 
        //THIS DOESN'T WORK:      
        newDistanceAnnouncer.speak(mTargetLocation,mCurrentLocation); 

        //THIS WORKS: 
        distanceAnnouncer.speak(mTargetLocation,mCurrentLocation); 

        CheckBox speakCheckbox = (CheckBox) MainActivity.this.findViewById(R.id.speakDistanceCheckbox); 
        speakCheckbox.setVisibility(View.VISIBLE); 
       } 
      } 
     }); 
     AlertDialog alertDialog = alert.create(); 

     alertDialog.show(); 
    } 

私は、これは文脈上の問​​題である疑いがある、が、2つのコンテキスト間の差は、この場合では何ですか?彼らは同じでなければならないのですか?

EDIT:フルDistanceAnnouncerクラスコード:

package com.blueit.audioguide; 

import android.app.Activity; 
import android.content.Context; 
import android.location.Location; 
import android.speech.tts.TextToSpeech; 

import java.util.Locale; 

/** 
* Created by janeks on 23.04.2016.. 
*/ 
public class DistanceAnnouncer { 
    private TextToSpeech speaker; 

    public DistanceAnnouncer(Context context) { 
     speaker = new TextToSpeech(context, new TextToSpeech.OnInitListener() { 
      @Override 
      public void onInit(int status) { 
       if(status != TextToSpeech.ERROR) { 
        speaker.setLanguage(Locale.ENGLISH); 
       } 
      } 
     }); 
    } 

    public void speak(Location targetLocation, Location currentLocation) { 
     if (targetLocation == null) return; 
     if (currentLocation == null) return; 

     if ((!(targetLocation == null)) && (!(currentLocation == null))) { 
      float distanceInMeters = targetLocation.distanceTo(currentLocation); 
      if (distanceInMeters < 1000) { 
       distanceInMeters = Math.round(distanceInMeters); 
       speaker.speak(String.valueOf(distanceInMeters) + " meters",TextToSpeech.QUEUE_FLUSH,null); 
      } else if ((distanceInMeters >= 1000) && (distanceInMeters <= 100000)) { 
       float distanceInKilometers = distanceInMeters/1000; 
       distanceInKilometers = Math.round(distanceInKilometers * 10)/10; 
       speaker.speak(String.valueOf(distanceInKilometers) + " kilometers",TextToSpeech.QUEUE_FLUSH,null); 
      } else if (distanceInMeters > 100000) { 
       float distanceInKilometers = distanceInMeters/1000; 
       distanceInKilometers = Math.round(distanceInKilometers); 
       speaker.speak(String.valueOf(distanceInKilometers) + " kilometers",TextToSpeech.QUEUE_FLUSH,null); 
      } 
     } else { 

     } 
    } 
} 

編集2:テキスト読み上げによってフィルタリングアプリケーションログ:

04-23 16:00:03.911 30815-30815/com.blueit.audioguide I/TextToSpeech: Sucessfully bound to com.google.android.tts 
04-23 16:00:03.988 30815-30815/com.blueit.audioguide I/TextToSpeech: Connected to ComponentInfo{com.google.android.tts/com.google.android.tts.service.GoogleTTSService} 
04-23 16:00:03.995 30815-30932/com.blueit.audioguide I/TextToSpeech: Set up connection to ComponentInfo{com.google.android.tts/com.google.android.tts.service.GoogleTTSService} 
04-23 16:01:35.048 30815-30815/com.blueit.audioguide I/TextToSpeech: Sucessfully bound to com.google.android.tts 
04-23 16:01:44.346 30815-30815/com.blueit.audioguide W/TextToSpeech: speak failed: not bound to TTS engine 

システムがシステムTTSサービスへの最初のものを接続しなくように思えます2番目のもの。しかし、どのような理由で?私も最初のものを削除しようとしたが、2回目を残していた(おそらくアクティビティごとにいくつかのTTSが許されていないのだろうか?

答えて

1

MainActivityのメンバ変数としてDistanceAnnouncerインスタンスをそのまま使用してください。

AlertDialogに常に新しいインスタンスを作成する際の問題は、TTSエンジンが即座に利用できないことです。今、あなたはonInit()が実行される前に、それが正しく、すなわち初期化されている前に、その後、TTSエンジントラフを話すことを試みる... ...

DistanceAnnouncer newDistanceAnnouncer = new DistanceAnnouncer(MainActivity.this); 

//THIS DOESN'T WORK:      
newDistanceAnnouncer.speak(mTargetLocation,mCurrentLocation); 

を呼び出します。

関連する問題