Fix voice stuff on Android 1.5

pull/14/head
Tim Su 15 years ago
parent 19ee36f9f1
commit 5eb20de821

@ -21,13 +21,14 @@ import com.todoroo.andlib.service.DependencyInjectionService;
import com.todoroo.andlib.service.ExceptionService; import com.todoroo.andlib.service.ExceptionService;
import com.todoroo.andlib.service.NotificationManager; import com.todoroo.andlib.service.NotificationManager;
import com.todoroo.andlib.service.NotificationManager.AndroidNotificationManager; import com.todoroo.andlib.service.NotificationManager.AndroidNotificationManager;
import com.todoroo.andlib.utility.AndroidUtilities;
import com.todoroo.andlib.utility.DateUtilities; import com.todoroo.andlib.utility.DateUtilities;
import com.todoroo.andlib.utility.Preferences; import com.todoroo.andlib.utility.Preferences;
import com.todoroo.astrid.dao.TaskDao; import com.todoroo.astrid.dao.TaskDao;
import com.todoroo.astrid.data.Task; import com.todoroo.astrid.data.Task;
import com.todoroo.astrid.service.AstridDependencyInjector; import com.todoroo.astrid.service.AstridDependencyInjector;
import com.todoroo.astrid.utility.Constants; import com.todoroo.astrid.utility.Constants;
import com.todoroo.astrid.voice.VoiceOutputAssistant; import com.todoroo.astrid.voice.VoiceOutputService;
public class Notifications extends BroadcastReceiver { public class Notifications extends BroadcastReceiver {
@ -96,7 +97,11 @@ public class Notifications extends BroadcastReceiver {
notificationManager.cancel((int)id); notificationManager.cancel((int)id);
} }
// shutdown the VoiceOutputAssistant for now // shutdown the VoiceOutputAssistant for now
VoiceOutputAssistant.getInstance().onDestroy(); try {
VoiceOutputService.getVoiceOutputInstance().onDestroy();
} catch (VerifyError e) {
// unavailable
}
} }
// --- notification creation // --- notification creation
@ -274,15 +279,17 @@ public class Notifications extends BroadcastReceiver {
notificationManager.notify(notificationId, notification); notificationManager.notify(notificationId, notification);
if (voiceReminder) { if (voiceReminder) {
while (audioManager.getMode() == AudioManager.MODE_RINGTONE) { for(int i = 0; i < 50; i++) {
try { if(audioManager.getMode() != AudioManager.MODE_RINGTONE)
Thread.sleep(50); break;
} catch (InterruptedException e) { AndroidUtilities.sleepDeep(100);
// TODO Auto-generated catch block }
e.printStackTrace(); try {
} System.err.println("QUEUESPEAK " + text);
VoiceOutputService.getVoiceOutputInstance().queueSpeak(text);
} catch (VerifyError e) {
// unavailable
} }
VoiceOutputAssistant.getInstance().queueSpeak(text);
} }
} }

@ -90,10 +90,6 @@
<!-- Quick Add Edit Box Hint--> <!-- Quick Add Edit Box Hint-->
<string name="TLA_quick_add_hint">Add to this list...</string> <string name="TLA_quick_add_hint">Add to this list...</string>
<!-- Voice Add Prompt Text -->
<string name="TLA_voice_add_prompt">Speak to add a task</string>
<string name="TLA_voice_edit_prompt">Speak to add to tasktitle</string>
<!-- ====================================================== TaskAdapter == --> <!-- ====================================================== TaskAdapter == -->
<!-- Format string to indicate task is hidden (%s => task name) --> <!-- Format string to indicate task is hidden (%s => task name) -->
@ -213,12 +209,6 @@
<!-- Third Tab - add-ons --> <!-- Third Tab - add-ons -->
<string name="TEA_tab_addons">Add-ons</string> <string name="TEA_tab_addons">Add-ons</string>
<!-- Prompt for tasktitle voiceinput -->
<string name="TEA_voice_edit_title_prompt">Speak to add to current title</string>
<!-- Prompt for tasknote voiceinput -->
<string name="TEA_voice_edit_note_prompt">Speak to add to current note</string>
<!-- Task title label --> <!-- Task title label -->
<string name="TEA_title_label">Title</string> <string name="TEA_title_label">Title</string>
@ -340,30 +330,11 @@
<!-- Preference: Task List Show Notes --> <!-- Preference: Task List Show Notes -->
<string name="EPr_showNotes_title">Show Notes In Task</string> <string name="EPr_showNotes_title">Show Notes In Task</string>
<!-- Preference: Task List recognition-service is not installed, but available -->
<string name="EPr_voiceInputInstall_dlg">Voice-input is not installed.\nDo you want to go to the market and install it?</string>
<!-- Preference: Task List recognition-service is not available for this system -->
<string name="EPr_voiceInputUnavailable_dlg">Unfortunately voice-input is not available for your system.\nIf possible, please update your system to 2.1 or later.</string>
<!-- Preference: Market is not available for this system -->
<string name="EPr_marketUnavailable_dlg">Unfortunately the market is not available for your system.\nIf possible, try downloading voicesearch from another source.</string>
<!-- Preference: Task List Show Voice-button if recognition-service is available -->
<string name="EPr_voiceInputEnabled_title">Enable voice-input</string>
<!-- Preference: Task List Voice-button directly creates tasks -->
<string name="EPr_voiceInputCreatesTask_title">Enable direct task-creation per voice</string>
<!-- Preference: Voice reminders if TTS-service is available -->
<string name="EPr_voiceRemindersEnabled_title">Enable voice-reminders</string>
<!-- Preference: Task List Show Notes Description (disabled) --> <!-- Preference: Task List Show Notes Description (disabled) -->
<string name="EPr_showNotes_desc_disabled">Notes will be displayed when you tap a task</string> <string name="EPr_showNotes_desc_disabled">Notes will be displayed when you tap a task</string>
<!-- Preference: Task List Show Notes Description (enabled) --> <!-- Preference: Task List Show Notes Description (enabled) -->
<string name="EPr_showNotes_desc_enabled">Notes will always be displayed</string> <string name="EPr_showNotes_desc_enabled">Notes will always be displayed</string>
<!-- Preference Category: Voice Title -->
<string name="EPr_voice_header">Voice</string>
<!-- Preference: Task List Voice Input Description (disabled) -->
<string name="EPr_voiceInput_desc_disabled">Voice-Button will be hidden</string>
<!-- Preference: Task List Voice Input Description (enabled) -->
<string name="EPr_voiceInput_desc_enabled">Voice-Button will be shown</string>
<!-- Preference Category: Defaults Title --> <!-- Preference Category: Defaults Title -->
<string name="EPr_defaults_header">New Task Defaults</string> <string name="EPr_defaults_header">New Task Defaults</string>

@ -3,15 +3,16 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"> <resources xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Voice Add Prompt Text --> <!-- Voice Add Prompt Text -->
<string name="voice_add_prompt">Speak to create a task</string> <string name="voice_create_prompt">Speak to create a task</string>
<string name="voice_edit_prompt">Speak to set task title</string> <string name="voice_edit_title_prompt">Speak to set task title</string>
<string name="voice_edit_note_prompt">Speak to set task notes</string>
<!-- Preference: Task List recognition-service is not installed, but available --> <!-- Preference: Task List recognition-service is not installed, but available -->
<string name="EPr_voiceInputInstall_dlg">Voice-input is not installed.\nDo you want to go to the market and install it?</string> <string name="EPr_voiceInputInstall_dlg">Voice-input is not installed.\nDo you want to go to the market and install it?</string>
<!-- Preference: Task List recognition-service is not available for this system --> <!-- Preference: Task List recognition-service is not available for this system -->
<string name="EPr_voiceInputUnavailable_dlg">Unfortunately voice-input is not available for your system.\nIf possible, please update your system to 2.1 or later.</string> <string name="EPr_voiceInputUnavailable_dlg">Unfortunately voice-input is not available for your system.\nIf possible, please update Android to 2.1 or later.</string>
<!-- Preference: Market is not available for this system --> <!-- Preference: Market is not available for this system -->
<string name="EPr_marketUnavailable_dlg">Unfortunately the market is not available for your system.\nIf possible, try downloading voicesearch from another source.</string> <string name="EPr_marketUnavailable_dlg">Unfortunately the market is not available for your system.\nIf possible, try downloading voice search from another source.</string>
<!-- Preference: Task List Show Voice-button if recognition-service is available --> <!-- Preference: Task List Show Voice-button if recognition-service is available -->
<string name="EPr_voiceInputEnabled_title">Voice Input</string> <string name="EPr_voiceInputEnabled_title">Voice Input</string>
<!-- Preference: voice button description (true) --> <!-- Preference: voice button description (true) -->

@ -46,7 +46,7 @@ import com.todoroo.astrid.service.TaskService;
import com.todoroo.astrid.utility.Constants; import com.todoroo.astrid.utility.Constants;
import com.todoroo.astrid.utility.Flags; import com.todoroo.astrid.utility.Flags;
import com.todoroo.astrid.voice.VoiceInputAssistant; import com.todoroo.astrid.voice.VoiceInputAssistant;
import com.todoroo.astrid.voice.VoiceOutputAssistant; import com.todoroo.astrid.voice.VoiceOutputService;
/** /**
* Displays the preference screen for users to edit their preferences * Displays the preference screen for users to edit their preferences
@ -248,7 +248,11 @@ public class EditPreferences extends TodorooPreferences {
@Override @Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) { protected void onActivityResult(int requestCode, int resultCode, Intent data) {
VoiceOutputAssistant.getInstance().handleActivityResult(requestCode, resultCode, data); try {
VoiceOutputService.getVoiceOutputInstance().handleActivityResult(requestCode, resultCode, data);
} catch (VerifyError e) {
// unavailable
}
super.onActivityResult(requestCode, resultCode, data); super.onActivityResult(requestCode, resultCode, data);
} }
@ -264,18 +268,24 @@ public class EditPreferences extends TodorooPreferences {
findPreference(r.getString(R.string.p_voiceRemindersEnabled)).setOnPreferenceChangeListener(new OnPreferenceChangeListener() { findPreference(r.getString(R.string.p_voiceRemindersEnabled)).setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
@Override @Override
public boolean onPreferenceChange(Preference pref, Object newValue) { public boolean onPreferenceChange(Preference pref, Object newValue) {
onVoiceReminderStatusChanged((Boolean)newValue); onVoiceReminderStatusChanged(pref, (Boolean)newValue);
return true; return true;
} }
}); });
} }
private void onVoiceReminderStatusChanged(boolean newValue) { private void onVoiceReminderStatusChanged(Preference preference, boolean newValue) {
System.err.println
("!!!! LAJLKSDJDS " + newValue);
if(!newValue) if(!newValue)
return; return;
VoiceOutputAssistant.getInstance().checkIsTTSInstalled(); try {
VoiceOutputService.getVoiceOutputInstance().checkIsTTSInstalled();
} catch (VerifyError e) {
((CheckBoxPreference)preference).setChecked(false);
}
} }
private void onVoiceInputStatusChanged(final Preference preference, boolean newValue) { private void onVoiceInputStatusChanged(final Preference preference, boolean newValue) {

@ -250,7 +250,7 @@ public final class TaskEditActivity extends TabActivity {
voiceAddNoteButton = (ImageButton) findViewById(R.id.voiceAddNoteButton); voiceAddNoteButton = (ImageButton) findViewById(R.id.voiceAddNoteButton);
voiceAddNoteButton.setVisibility(View.VISIBLE); voiceAddNoteButton.setVisibility(View.VISIBLE);
notesEditText = (EditText) findViewById(R.id.notes); notesEditText = (EditText) findViewById(R.id.notes);
int prompt = R.string.TEA_voice_edit_note_prompt; int prompt = R.string.voice_edit_note_prompt;
voiceNoteAssistant = new VoiceInputAssistant(this, voiceAddNoteButton, voiceNoteAssistant = new VoiceInputAssistant(this, voiceAddNoteButton,
notesEditText); notesEditText);
voiceNoteAssistant.setLanguageModel(RecognizerIntent.LANGUAGE_MODEL_FREE_FORM); voiceNoteAssistant.setLanguageModel(RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);

@ -383,9 +383,9 @@ public class TaskListActivity extends ListActivity implements OnScrollListener,
// prepare and set listener for voice add button // prepare and set listener for voice add button
voiceAddButton = (ImageButton) findViewById(R.id.voiceAddButton); voiceAddButton = (ImageButton) findViewById(R.id.voiceAddButton);
int prompt = R.string.TLA_voice_edit_prompt; int prompt = R.string.voice_edit_title_prompt;
if (Preferences.getBoolean(R.string.p_voiceInputCreatesTask, false)) if (Preferences.getBoolean(R.string.p_voiceInputCreatesTask, false))
prompt = R.string.TLA_voice_add_prompt; prompt = R.string.voice_create_prompt;
voiceInputAssistant = new VoiceInputAssistant(this,voiceAddButton,quickAddBox); voiceInputAssistant = new VoiceInputAssistant(this,voiceAddButton,quickAddBox);
voiceInputAssistant.configureMicrophoneButton(prompt); voiceInputAssistant.configureMicrophoneButton(prompt);

@ -30,7 +30,7 @@ public final class Constants {
/** /**
* Whether to turn on debugging logging and UI * Whether to turn on debugging logging and UI
*/ */
public static final boolean DEBUG = false; public static final boolean DEBUG = true;
/** /**
* Upgrade time * Upgrade time

@ -15,39 +15,33 @@ import android.speech.tts.TextToSpeech.OnInitListener;
import android.util.Log; import android.util.Log;
import com.todoroo.andlib.service.ContextManager; import com.todoroo.andlib.service.ContextManager;
import com.todoroo.astrid.voice.VoiceOutputService.VoiceOutputAssistant;
/** /**
* @author Arne Jans * @author Arne Jans
* *
*/ */
public class VoiceOutputAssistant implements OnInitListener { @SuppressWarnings("nls")
public class Api6VoiceOutputAssistant implements OnInitListener, VoiceOutputAssistant {
private static final int MY_DATA_CHECK_CODE = 2534; private static final int MY_DATA_CHECK_CODE = 2534;
private static final String TAG = "Astrid.VoiceOutputAssistant"; private static final String TAG = "Astrid.VoiceOutputAssistant";
private final Context context; private final Context context;
private static VoiceOutputAssistant instance = null;
private TextToSpeech mTts; private TextToSpeech mTts;
private boolean isTTSInitialized; private boolean isTTSInitialized;
private boolean retryLastSpeak; private boolean retryLastSpeak;
private String textToSpeak; private String lastTextToSpeak;
private static final HashMap<String, String> ttsParams = new HashMap(); private static final HashMap<String, String> ttsParams = new HashMap<String, String>();
static { static {
ttsParams.put(TextToSpeech.Engine.KEY_PARAM_STREAM, ttsParams.put(TextToSpeech.Engine.KEY_PARAM_STREAM,
String.valueOf(AudioManager.STREAM_NOTIFICATION)); String.valueOf(AudioManager.STREAM_NOTIFICATION));
} }
private VoiceOutputAssistant() { Api6VoiceOutputAssistant() {
this.context = ContextManager.getContext().getApplicationContext(); this.context = ContextManager.getContext().getApplicationContext();
} }
public static VoiceOutputAssistant getInstance() {
if (instance == null) {
instance = new VoiceOutputAssistant();
}
return instance;
}
public void checkIsTTSInstalled() { public void checkIsTTSInstalled() {
if (!isTTSInitialized && context instanceof Activity) { if (!isTTSInitialized && context instanceof Activity) {
Intent checkIntent = new Intent(); Intent checkIntent = new Intent();
@ -92,7 +86,7 @@ public class VoiceOutputAssistant implements OnInitListener {
} }
} else { } else {
retryLastSpeak = true; retryLastSpeak = true;
this.textToSpeak = textToSpeak; this.lastTextToSpeak = textToSpeak;
initTTS(); initTTS();
} }
} }
@ -120,10 +114,10 @@ public class VoiceOutputAssistant implements OnInitListener {
// The TTS engine has been successfully initialized. // The TTS engine has been successfully initialized.
isTTSInitialized = true; isTTSInitialized = true;
// if this request came from queueSpeak, then speak it and reset the memento // if this request came from queueSpeak, then speak it and reset the memento
if (retryLastSpeak && this.textToSpeak != null) { if (retryLastSpeak && this.lastTextToSpeak != null) {
this.queueSpeak(this.textToSpeak); this.queueSpeak(this.lastTextToSpeak);
retryLastSpeak = false; retryLastSpeak = false;
textToSpeak = null; lastTextToSpeak = null;
} }
} }
} else { } else {

@ -30,6 +30,7 @@ import com.todoroo.andlib.utility.Preferences;
* *
* @author Arne Jans * @author Arne Jans
*/ */
@SuppressWarnings("nls")
public class VoiceInputAssistant { public class VoiceInputAssistant {
/** requestcode for activityresult from voicerecognizer-intent */ /** requestcode for activityresult from voicerecognizer-intent */
@ -45,8 +46,6 @@ public class VoiceInputAssistant {
private final ImageButton voiceButton; private final ImageButton voiceButton;
private final EditText textField; private final EditText textField;
private boolean voiceInputAvailable;
private String languageModel = RecognizerIntent.LANGUAGE_MODEL_WEB_SEARCH; private String languageModel = RecognizerIntent.LANGUAGE_MODEL_WEB_SEARCH;
/** /**
@ -138,15 +137,15 @@ public class VoiceInputAssistant {
* If this method returns false, then it wasnt a request with a RecognizerIntent, so you can handle * If this method returns false, then it wasnt a request with a RecognizerIntent, so you can handle
* these other requests as you need. * these other requests as you need.
* *
* @param requestCode if this equals the requestCode specified by constructor, then results of voice-recognition * @param activityRequestCode if this equals the requestCode specified by constructor, then results of voice-recognition
* @param resultCode * @param resultCode
* @param data * @param data
* @return * @return
*/ */
public boolean handleActivityResult(int requestCode, int resultCode, Intent data) { public boolean handleActivityResult(int activityRequestCode, int resultCode, Intent data) {
boolean result = false; boolean result = false;
// handle the result of voice recognition, put it into the textfield // handle the result of voice recognition, put it into the textfield
if (requestCode == this.requestCode) { if (activityRequestCode == this.requestCode) {
// this was handled here, even if voicerecognition fails for any reason // this was handled here, even if voicerecognition fails for any reason
// so your program flow wont get chaotic if you dont explicitly state // so your program flow wont get chaotic if you dont explicitly state
// your own requestCodes. // your own requestCodes.

@ -0,0 +1,70 @@
package com.todoroo.astrid.voice;
import android.content.Intent;
import com.todoroo.andlib.utility.AndroidUtilities;
/**
* All API versions-friendly voice input / output.
* @author Tim Su <tim@todoroo.com>
*
*/
public class VoiceOutputService {
private static final int MIN_TTS_VERSION = 6;
private static VoiceOutputAssistant outputAssistant;
// --- voice output
public interface VoiceOutputAssistant {
public void checkIsTTSInstalled();
public boolean handleActivityResult(int requestCode, int resultCode, Intent data);
public void queueSpeak(String textToSpeak);
public void onDestroy();
}
public static class NullVoiceOutputAssistant implements VoiceOutputAssistant {
@Override
public void checkIsTTSInstalled() {
//
}
@Override
public boolean handleActivityResult(int requestCode, int resultCode,
Intent data) {
return false;
}
@Override
public void queueSpeak(String textToSpeak) {
//
}
@Override
public void onDestroy() {
//
}
}
public static VoiceOutputAssistant getVoiceOutputInstance() {
if(AndroidUtilities.getSdkVersion() >= MIN_TTS_VERSION) {
if (outputAssistant == null)
outputAssistant = new Api6VoiceOutputAssistant();
} else {
if(outputAssistant == null)
outputAssistant = new NullVoiceOutputAssistant();
}
return outputAssistant;
}
}
Loading…
Cancel
Save