From 4a24570ba09de30525d4d1ee6e1814ec90927237 Mon Sep 17 00:00:00 2001 From: Bananeweizen Date: Fri, 10 May 2013 17:16:07 +0200 Subject: #2710: speech output in compass --- main/src/cgeo/geocaching/speech/SpeechService.java | 160 +++++++++++++++++++++ 1 file changed, 160 insertions(+) create mode 100644 main/src/cgeo/geocaching/speech/SpeechService.java (limited to 'main/src/cgeo/geocaching/speech/SpeechService.java') diff --git a/main/src/cgeo/geocaching/speech/SpeechService.java b/main/src/cgeo/geocaching/speech/SpeechService.java new file mode 100644 index 0000000..0a367f8 --- /dev/null +++ b/main/src/cgeo/geocaching/speech/SpeechService.java @@ -0,0 +1,160 @@ +package cgeo.geocaching.speech; + +import cgeo.geocaching.DirectionProvider; +import cgeo.geocaching.geopoint.Geopoint; +import cgeo.geocaching.utils.GeoDirHandler; +import cgeo.geocaching.utils.Log; + +import org.apache.commons.lang3.StringUtils; + +import android.app.Activity; +import android.app.Service; +import android.content.Intent; +import android.os.IBinder; +import android.speech.tts.TextToSpeech; +import android.speech.tts.TextToSpeech.OnInitListener; + +import java.util.Locale; + +/** + * Service to speak the compass directions. + * + */ +public class SpeechService extends Service implements OnInitListener { + + private static final int SPEECH_PAUSE_SECONDS = 30; + private static final String EXTRA_TARGET_COORDS = "target"; + private static Activity startingActivity; + private static boolean isRunning = false; + /** + * Text to speech API of Android + */ + private TextToSpeech tts; + /** + * TTS has been initialized and we can speak. + */ + private boolean initialized = false; + protected float direction; + protected Geopoint position; + protected boolean directionInitialized; + protected boolean positionInitialized; + + GeoDirHandler geoHandler = new GeoDirHandler() { + @Override + protected void updateDirection(float newDirection) { + direction = DirectionProvider.getDirectionNow(startingActivity, newDirection); + directionInitialized = true; + updateCompass(); + } + + @Override + protected void updateGeoData(cgeo.geocaching.IGeoData newGeo) { + position = newGeo.getCoords(); + positionInitialized = true; + if (newGeo.getSpeed() > 5) { + direction = newGeo.getBearing(); + directionInitialized = true; + } + updateCompass(); + } + }; + /** + * remember when we talked the last time + */ + private long lastSpeechTime = 0; + private Geopoint target; + + @Override + public IBinder onBind(Intent intent) { + return null; + } + + protected void updateCompass() { + // make sure we have both sensor values before talking + if (!positionInitialized || !directionInitialized) { + return; + } + + // avoid any calculation, if the delay since the last output is not long enough + long now = System.currentTimeMillis(); + if (now - lastSpeechTime <= SPEECH_PAUSE_SECONDS * 1000) { + return; + } + + final String text = TextFactory.getText(position, target, direction); + if (StringUtils.isNotEmpty(text)) { + speak(text); + } + } + + @Override + public void onCreate() { + super.onCreate(); + tts = new TextToSpeech(this, this); + } + + @Override + public void onDestroy() { + geoHandler.stopGeoAndDir(); + if (tts != null) { + tts.stop(); + tts.shutdown(); + } + super.onDestroy(); + } + + @Override + public void onInit(int status) { + // The text to speech system takes some time to initialize. + if (status != TextToSpeech.SUCCESS) { + Log.e("Text to speech cannot be initialized."); + return; + } + + int switchLocale = tts.setLanguage(Locale.getDefault()); + + if (switchLocale == TextToSpeech.LANG_MISSING_DATA + || switchLocale == TextToSpeech.LANG_NOT_SUPPORTED) { + Log.e("Current languge not supported by text to speech."); + return; + } + + initialized = true; + + geoHandler.startGeoAndDir(); + } + + @Override + public int onStartCommand(Intent intent, int flags, int startId) { + if (intent != null) { + target = intent.getParcelableExtra(EXTRA_TARGET_COORDS); + } + return START_NOT_STICKY; + } + + private void speak(final String text) { + if (!initialized) { + return; + } + lastSpeechTime = System.currentTimeMillis(); + tts.speak(text, TextToSpeech.QUEUE_FLUSH, null); + } + + public static void startService(final Activity activity, Geopoint dstCoords) { + isRunning = true; + startingActivity = activity; + Intent talkingService = new Intent(activity, SpeechService.class); + talkingService.putExtra(EXTRA_TARGET_COORDS, dstCoords); + activity.startService(talkingService); + } + + public static void stopService(final Activity activity) { + isRunning = false; + activity.stopService(new Intent(activity, SpeechService.class)); + } + + public static boolean isRunning() { + return isRunning; + } + +} -- cgit v1.1