diff --git a/android-aac-enc/src/com/todoroo/aacenc/RecognizerApi.java b/android-aac-enc/src/com/todoroo/aacenc/RecognizerApi.java index e0a41187b..64c35a9ca 100644 --- a/android-aac-enc/src/com/todoroo/aacenc/RecognizerApi.java +++ b/android-aac-enc/src/com/todoroo/aacenc/RecognizerApi.java @@ -125,6 +125,7 @@ public class RecognizerApi implements RecognitionListener { } public void destroy() { + sr.setRecognitionListener(null); sr.destroy(); } diff --git a/astrid/src/com/todoroo/astrid/activity/EditPreferences.java b/astrid/src/com/todoroo/astrid/activity/EditPreferences.java index 0b84d2db2..3374a01a2 100644 --- a/astrid/src/com/todoroo/astrid/activity/EditPreferences.java +++ b/astrid/src/com/todoroo/astrid/activity/EditPreferences.java @@ -62,6 +62,7 @@ import com.todoroo.astrid.utility.Constants; import com.todoroo.astrid.utility.Flags; import com.todoroo.astrid.voice.VoiceInputAssistant; import com.todoroo.astrid.voice.VoiceOutputService; +import com.todoroo.astrid.voice.VoiceRecognizer; import com.todoroo.astrid.welcome.tutorial.WelcomeWalkthrough; import com.todoroo.astrid.widget.TasksWidget; @@ -503,7 +504,7 @@ public class EditPreferences extends TodorooPreferenceActivity { return; final Resources r = getResources(); - if (!voiceInputAssistant.isVoiceInputAvailable()) { + if (!VoiceRecognizer.voiceInputAvailable(this)) { if (AndroidUtilities.getSdkVersion() > 6) { DialogUtilities.okCancelDialog(this, r.getString(R.string.EPr_voiceInputInstall_dlg), diff --git a/astrid/src/com/todoroo/astrid/ui/QuickAddBar.java b/astrid/src/com/todoroo/astrid/ui/QuickAddBar.java index cf4f9b6b4..840fb53b0 100644 --- a/astrid/src/com/todoroo/astrid/ui/QuickAddBar.java +++ b/astrid/src/com/todoroo/astrid/ui/QuickAddBar.java @@ -24,7 +24,6 @@ import android.widget.TextView.OnEditorActionListener; import android.widget.Toast; import com.timsu.astrid.R; -import com.todoroo.aacenc.RecognizerApi; import com.todoroo.aacenc.RecognizerApi.RecognizerApiListener; import com.todoroo.andlib.service.Autowired; import com.todoroo.andlib.service.ContextManager; @@ -57,6 +56,7 @@ import com.todoroo.astrid.service.StatisticsConstants; import com.todoroo.astrid.service.StatisticsService; import com.todoroo.astrid.service.TaskService; import com.todoroo.astrid.utility.Flags; +import com.todoroo.astrid.voice.VoiceRecognizer; /** * Quick Add Bar lets you add tasks. @@ -86,8 +86,10 @@ public class QuickAddBar extends LinearLayout implements RecognizerApiListener { @Autowired MetadataService metadataService; @Autowired ActFmPreferenceService actFmPreferenceService; - //private VoiceInputAssistant voiceInputAssistant; - private RecognizerApi recognizerApi; +// private VoiceInputAssistant voiceInputAssistant; +// private RecognizerApi recognizerApi; + + private VoiceRecognizer voiceRecognizer; private Activity activity; private TaskListFragment fragment; @@ -156,20 +158,11 @@ public class QuickAddBar extends LinearLayout implements RecognizerApiListener { // prepare and set listener for voice add button voiceAddButton = (ImageButton) findViewById( R.id.voiceAddButton); - int prompt = R.string.voice_edit_title_prompt; - if (Preferences.getBoolean(R.string.p_voiceInputCreatesTask, false)) - prompt = R.string.voice_create_prompt; -// voiceInputAssistant = new VoiceInputAssistant(fragment, -// voiceAddButton, quickAddBox); -// voiceInputAssistant.configureMicrophoneButton(prompt); - findViewById(R.id.voiceAddButton).setOnClickListener(new OnClickListener() { + + voiceAddButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { - if (currentVoiceFile == null) - currentVoiceFile = Long.toString(DateUtilities.now()); - - recognizerApi.setTemporaryFile(currentVoiceFile); - recognizerApi.start(); + startVoiceRecognition(); } }); @@ -189,7 +182,7 @@ public class QuickAddBar extends LinearLayout implements RecognizerApiListener { if (addOnService.hasPowerPack() && Preferences.getBoolean(R.string.p_voiceInputEnabled, true) - /*&& voiceInputAssistant.isVoiceInputAvailable()*/) { + && VoiceRecognizer.voiceInputAvailable(activity)) { voiceAddButton.setVisibility(View.VISIBLE); } else { voiceAddButton.setVisibility(View.GONE); @@ -348,7 +341,7 @@ public class QuickAddBar extends LinearLayout implements RecognizerApiListener { .append("_audio.mp4"); String filePath = filePathBuilder.toString(); System.err.println("Saving to " + filePath); - recognizerApi.convert(filePath); + voiceRecognizer.convert(filePath); currentVoiceFile = null; Metadata fileMetadata = FileMetadata.createNewFileMetadata(task.getId(), filePath, FileMetadata.FILE_TYPE_AUDIO); @@ -449,17 +442,19 @@ public class QuickAddBar extends LinearLayout implements RecognizerApiListener { return false; } - public void setupRecognizerApi() { - if (recognizerApi != null) - recognizerApi.destroy(); + public void startVoiceRecognition() { + if (VoiceRecognizer.speechRecordingAvailable(activity) && currentVoiceFile == null) { + currentVoiceFile = Long.toString(DateUtilities.now()); + } + voiceRecognizer.startVoiceRecognition(activity, currentVoiceFile); + } - recognizerApi = new RecognizerApi(activity); - recognizerApi.setListener(this); + public void setupRecognizerApi() { + voiceRecognizer = VoiceRecognizer.instantiateVoiceRecognizer(activity, this, fragment, voiceAddButton, quickAddBox); } public void destroyRecognizerApi() { - recognizerApi.destroy(); - recognizerApi = null; + voiceRecognizer.destroyRecognizerApi(); } @Override @@ -469,7 +464,7 @@ public class QuickAddBar extends LinearLayout implements RecognizerApiListener { @Override public void onSpeechError(int error) { - recognizerApi.cancel(); + voiceRecognizer.cancel(); int errorStr = 0; switch(error) { diff --git a/astrid/src/com/todoroo/astrid/voice/VoiceInputAssistant.java b/astrid/src/com/todoroo/astrid/voice/VoiceInputAssistant.java index b7ac7edc0..79887b477 100644 --- a/astrid/src/com/todoroo/astrid/voice/VoiceInputAssistant.java +++ b/astrid/src/com/todoroo/astrid/voice/VoiceInputAssistant.java @@ -2,15 +2,12 @@ package com.todoroo.astrid.voice; import java.security.InvalidParameterException; import java.util.ArrayList; -import java.util.List; import junit.framework.Assert; import android.app.Activity; import android.content.ActivityNotFoundException; import android.content.DialogInterface; import android.content.Intent; -import android.content.pm.PackageManager; -import android.content.pm.ResolveInfo; import android.speech.RecognizerIntent; import android.support.v4.app.Fragment; import android.util.Log; @@ -270,29 +267,8 @@ public class VoiceInputAssistant { return null; } - /** - * Call this to see if your phone supports voiceinput in its current configuration. - * If this method returns false, it could also mean that Google Voicesearch is simply - * not installed. - * If this method returns true, internal use of it enables the registered microphone-button. - * - * @return whether this phone supports voiceinput - */ - public boolean isVoiceInputAvailable() { - // Check to see if a recognition activity is present - PackageManager pm = null; - if (fragment == null) { - pm = ContextManager.getContext().getPackageManager(); - } else { - pm = fragment.getActivity().getPackageManager(); - } - List activities = pm.queryIntentActivities( - new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH), 0); - return (activities.size() != 0); - } - public void configureMicrophoneButton(final int prompt) { - if (Preferences.getBoolean(R.string.p_voiceInputEnabled, true) && isVoiceInputAvailable()) { + if (Preferences.getBoolean(R.string.p_voiceInputEnabled, true) && VoiceRecognizer.voiceInputAvailable(ContextManager.getContext())) { voiceButton.setVisibility(View.VISIBLE); voiceButton.setOnClickListener(new OnClickListener() { public void onClick(View v) { diff --git a/astrid/src/com/todoroo/astrid/voice/VoiceRecognizer.java b/astrid/src/com/todoroo/astrid/voice/VoiceRecognizer.java new file mode 100644 index 000000000..93af823ce --- /dev/null +++ b/astrid/src/com/todoroo/astrid/voice/VoiceRecognizer.java @@ -0,0 +1,100 @@ +package com.todoroo.astrid.voice; + +import java.util.List; + +import android.content.Context; +import android.content.Intent; +import android.content.pm.PackageManager; +import android.content.pm.ResolveInfo; +import android.speech.RecognizerIntent; +import android.speech.SpeechRecognizer; +import android.support.v4.app.Fragment; +import android.widget.EditText; +import android.widget.ImageButton; + +import com.timsu.astrid.R; +import com.todoroo.aacenc.RecognizerApi; +import com.todoroo.aacenc.RecognizerApi.RecognizerApiListener; +import com.todoroo.andlib.utility.AndroidUtilities; +import com.todoroo.andlib.utility.Preferences; + +public class VoiceRecognizer { + + protected RecognizerApi recognizerApi; + protected VoiceInputAssistant voiceInputAssistant; + + public static boolean speechRecordingAvailable(Context context) { + return AndroidUtilities.getSdkVersion() >= 8 && SpeechRecognizer.isRecognitionAvailable(context); + } + + /** + * Call this to see if your phone supports voiceinput in its current configuration. + * If this method returns false, it could also mean that Google Voicesearch is simply + * not installed. + * If this method returns true, internal use of it enables the registered microphone-button. + * + * @return whether this phone supports voiceinput + */ + public static boolean voiceInputAvailable(Context context) { + PackageManager pm = context.getPackageManager(); + List activities = pm.queryIntentActivities( + new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH), 0); + return (activities.size() != 0); + } + + private VoiceRecognizer() { + // + } + + private static VoiceRecognizer instance = null; + + public static VoiceRecognizer instantiateVoiceRecognizer(Context context, RecognizerApiListener listener, + Fragment fragment, ImageButton voiceAddButton, EditText quickAddBox) { + synchronized(VoiceRecognizer.class) { + if (instance == null) + instance = new VoiceRecognizer(); + } + + if (speechRecordingAvailable(context)) { + if (instance.recognizerApi != null) + instance.recognizerApi.destroy(); + + instance.recognizerApi = new RecognizerApi(context); + instance.recognizerApi.setListener(listener); + } else { + instance.voiceInputAssistant = new VoiceInputAssistant(fragment, + voiceAddButton, quickAddBox); + } + return instance; + } + + public void startVoiceRecognition(Context context, String currentVoiceFile) { + if (speechRecordingAvailable(context)) { + + recognizerApi.setTemporaryFile(currentVoiceFile); + recognizerApi.start(); + } else { + int prompt = R.string.voice_edit_title_prompt; + if (Preferences.getBoolean(R.string.p_voiceInputCreatesTask, false)) + prompt = R.string.voice_create_prompt; + voiceInputAssistant.startVoiceRecognitionActivity(prompt); + } + } + + public void destroyRecognizerApi() { + if (instance != null && instance.recognizerApi != null) { + instance.recognizerApi.destroy(); + instance.recognizerApi = null; + } + } + + public void cancel() { + if (instance != null && instance.recognizerApi != null) + instance.recognizerApi.cancel(); + } + + public void convert(String filePath) { + if (instance != null && instance.recognizerApi != null) + instance.recognizerApi.convert(filePath); + } +}