Logback-android, inject VoiceOutputAssistant

pull/189/head
Alex Baker 12 years ago
parent d57a1a1acf
commit f45cd0735d

@ -37,7 +37,8 @@ dependencies {
compile group: 'com.android.support', name: 'support-v4', version: '19.1.+' compile group: 'com.android.support', name: 'support-v4', version: '19.1.+'
compile group: 'org.slf4j', name: 'slf4j-android', version: '1.7.7', transitive: false
compile group: 'org.slf4j', name: 'slf4j-api', version: '1.7.7' compile group: 'org.slf4j', name: 'slf4j-api', version: '1.7.7'
compile group: 'com.github.tony19', name: 'logback-android-core', version: '1.1.1-2'
compile group: 'com.github.tony19', name: 'logback-android-classic', version: '1.1.1-2'
compile group: 'joda-time', name: 'joda-time', version: '2.3', transitive: false compile group: 'joda-time', name: 'joda-time', version: '2.3', transitive: false
} }

@ -0,0 +1,18 @@
<configuration>
<configuration>
<appender
name="LOGCAT"
class="ch.qos.logback.classic.android.LogcatAppender" >
<tagEncoder>
<pattern>%logger{0}</pattern>
</tagEncoder>
<encoder>
<pattern>[ %thread ] %msg%n</pattern>
</encoder>
</appender>
<root level="WARN" >
<appender-ref ref="LOGCAT" />
</root>
</configuration>
</configuration>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.6 KiB

@ -19,6 +19,7 @@ import android.preference.Preference.OnPreferenceClickListener;
import android.preference.PreferenceGroup; import android.preference.PreferenceGroup;
import android.preference.PreferenceManager; import android.preference.PreferenceManager;
import android.preference.PreferenceScreen; import android.preference.PreferenceScreen;
import android.speech.tts.TextToSpeech;
import android.text.TextUtils; import android.text.TextUtils;
import com.todoroo.andlib.service.ContextManager; import com.todoroo.andlib.service.ContextManager;
@ -39,9 +40,11 @@ import com.todoroo.astrid.utility.Constants;
import com.todoroo.astrid.utility.Flags; import com.todoroo.astrid.utility.Flags;
import com.todoroo.astrid.utility.TodorooPreferenceActivity; import com.todoroo.astrid.utility.TodorooPreferenceActivity;
import com.todoroo.astrid.voice.VoiceInputAssistant; import com.todoroo.astrid.voice.VoiceInputAssistant;
import com.todoroo.astrid.voice.VoiceOutputService; import com.todoroo.astrid.voice.VoiceOutputAssistant;
import com.todoroo.astrid.voice.VoiceRecognizer; import com.todoroo.astrid.voice.VoiceRecognizer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.tasks.R; import org.tasks.R;
import org.tasks.preferences.Preferences; import org.tasks.preferences.Preferences;
import org.tasks.widget.WidgetHelper; import org.tasks.widget.WidgetHelper;
@ -62,8 +65,10 @@ import javax.inject.Inject;
*/ */
public class EditPreferences extends TodorooPreferenceActivity { public class EditPreferences extends TodorooPreferenceActivity {
private static final Logger log = LoggerFactory.getLogger(EditPreferences.class);
private static final int REQUEST_CODE_SYNC = 0; private static final int REQUEST_CODE_SYNC = 0;
private static final int REQUEST_CODE_FILES_DIR = 2; private static final int REQUEST_CODE_FILES_DIR = 2;
private static final int REQUEST_CODE_TTS_CHECK = 2534;
public static final int RESULT_CODE_THEME_CHANGED = 1; public static final int RESULT_CODE_THEME_CHANGED = 1;
public static final int RESULT_CODE_PERFORMANCE_PREF_CHANGED = 3; public static final int RESULT_CODE_PERFORMANCE_PREF_CHANGED = 3;
@ -74,6 +79,7 @@ public class EditPreferences extends TodorooPreferenceActivity {
@Inject TaskService taskService; @Inject TaskService taskService;
@Inject Preferences preferences; @Inject Preferences preferences;
@Inject CalendarAlarmScheduler calendarAlarmScheduler; @Inject CalendarAlarmScheduler calendarAlarmScheduler;
@Inject VoiceOutputAssistant voiceOutputAssistant;
private VoiceInputAssistant voiceInputAssistant; private VoiceInputAssistant voiceInputAssistant;
@ -359,6 +365,13 @@ public class EditPreferences extends TodorooPreferenceActivity {
return false; return false;
} }
@Override
protected void onDestroy() {
super.onDestroy();
voiceOutputAssistant.shutdown();
}
@Override @Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) { protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_CODE_SYNC && resultCode == SyncProviderPreferences.RESULT_CODE_SYNCHRONIZE) { if (requestCode == REQUEST_CODE_SYNC && resultCode == SyncProviderPreferences.RESULT_CODE_SYNCHRONIZE) {
@ -373,7 +386,17 @@ public class EditPreferences extends TodorooPreferenceActivity {
return; return;
} }
try { try {
VoiceOutputService.getVoiceOutputInstance().handleActivityResult(requestCode, resultCode); if (requestCode == REQUEST_CODE_TTS_CHECK) {
if (resultCode == TextToSpeech.Engine.CHECK_VOICE_DATA_PASS) {
// success, create the TTS instance
voiceOutputAssistant.initTTS();
} else {
// missing data, install it
Intent installIntent = new Intent();
installIntent.setAction(TextToSpeech.Engine.ACTION_INSTALL_TTS_DATA);
startActivity(installIntent);
}
}
} catch (VerifyError e) { } catch (VerifyError e) {
// unavailable // unavailable
} }
@ -427,14 +450,17 @@ public class EditPreferences extends TodorooPreferenceActivity {
}); });
} }
private void onVoiceReminderStatusChanged(final Preference preference, boolean newValue) { private void onVoiceReminderStatusChanged(final Preference preference, boolean enabled) {
try { try {
VoiceOutputService.getVoiceOutputInstance(); if(enabled && !voiceOutputAssistant.isTTSInitialized()) {
if(newValue) { Intent checkIntent = new Intent();
VoiceOutputService.getVoiceOutputInstance().checkIsTTSInstalled(); checkIntent.setAction(TextToSpeech.Engine.ACTION_CHECK_TTS_DATA);
startActivityForResult(checkIntent, REQUEST_CODE_TTS_CHECK);
} else if (!enabled && voiceOutputAssistant.isTTSInitialized()) {
voiceOutputAssistant.shutdown();
} }
} catch (VerifyError e) { } catch (VerifyError e) {
// doesn't work :( log.error(e.getMessage(), e);
preference.setEnabled(false); preference.setEnabled(false);
preferences.setBoolean(preference.getKey(), false); preferences.setBoolean(preference.getKey(), false);
} }

@ -41,6 +41,7 @@ import android.widget.LinearLayout;
import android.widget.ScrollView; import android.widget.ScrollView;
import android.widget.Toast; import android.widget.Toast;
import com.todoroo.andlib.service.ContextManager;
import com.todoroo.andlib.utility.AndroidUtilities; import com.todoroo.andlib.utility.AndroidUtilities;
import com.todoroo.andlib.utility.DateUtilities; import com.todoroo.andlib.utility.DateUtilities;
import com.todoroo.andlib.utility.DialogUtilities; import com.todoroo.andlib.utility.DialogUtilities;
@ -285,8 +286,8 @@ ViewPager.OnPageChangeListener, EditNoteActivity.UpdatesChangedListener {
private void instantiateEditNotes() { private void instantiateEditNotes() {
if (showEditComments) { if (showEditComments) {
long idParam = getActivity().getIntent().getLongExtra(TOKEN_ID, -1L); long idParam = getActivity().getIntent().getLongExtra(TOKEN_ID, -1L);
editNotes = new EditNoteActivity(metadataService, userActivityDao, taskService, this, getView(), editNotes = new EditNoteActivity(preferences, metadataService, userActivityDao,
idParam); taskService, this, getView(), idParam);
editNotes.setLayoutParams(new FrameLayout.LayoutParams(LayoutParams.FILL_PARENT, editNotes.setLayoutParams(new FrameLayout.LayoutParams(LayoutParams.FILL_PARENT,
LayoutParams.WRAP_CONTENT)); LayoutParams.WRAP_CONTENT));
@ -541,7 +542,11 @@ ViewPager.OnPageChangeListener, EditNoteActivity.UpdatesChangedListener {
voiceNoteAssistant = new VoiceInputAssistant(voiceAddNoteButton, REQUEST_VOICE_RECOG); voiceNoteAssistant = new VoiceInputAssistant(voiceAddNoteButton, REQUEST_VOICE_RECOG);
voiceNoteAssistant.setAppend(); voiceNoteAssistant.setAppend();
voiceNoteAssistant.setLanguageModel(RecognizerIntent.LANGUAGE_MODEL_FREE_FORM); voiceNoteAssistant.setLanguageModel(RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
if (preferences.getBoolean(R.string.p_voiceInputEnabled, true) && VoiceRecognizer.voiceInputAvailable(ContextManager.getContext())) {
voiceNoteAssistant.configureMicrophoneButton(TaskEditFragment.this, prompt); voiceNoteAssistant.configureMicrophoneButton(TaskEditFragment.this, prompt);
} else {
voiceNoteAssistant.hideVoiceButton();
}
} }
loadMoreContainer(); loadMoreContainer();
} }

@ -35,7 +35,6 @@ import com.todoroo.andlib.data.TodorooCursor;
import com.todoroo.andlib.service.ContextManager; import com.todoroo.andlib.service.ContextManager;
import com.todoroo.andlib.sql.Query; import com.todoroo.andlib.sql.Query;
import com.todoroo.andlib.utility.DateUtilities; import com.todoroo.andlib.utility.DateUtilities;
import com.todoroo.andlib.utility.Preferences;
import com.todoroo.astrid.actfm.ActFmCameraModule; import com.todoroo.astrid.actfm.ActFmCameraModule;
import com.todoroo.astrid.actfm.ActFmCameraModule.CameraResultCallback; import com.todoroo.astrid.actfm.ActFmCameraModule.CameraResultCallback;
import com.todoroo.astrid.actfm.ActFmCameraModule.ClearImageCallback; import com.todoroo.astrid.actfm.ActFmCameraModule.ClearImageCallback;
@ -56,6 +55,7 @@ import com.todoroo.astrid.timers.TimerActionControlSet.TimerActionListener;
import org.json.JSONObject; import org.json.JSONObject;
import org.tasks.R; import org.tasks.R;
import org.tasks.preferences.Preferences;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
@ -69,6 +69,7 @@ public class EditNoteActivity extends LinearLayout implements TimerActionListene
private Task task; private Task task;
private final Preferences preferences;
private final MetadataService metadataService; private final MetadataService metadataService;
private final UserActivityDao userActivityDao; private final UserActivityDao userActivityDao;
private final TaskService taskService; private final TaskService taskService;
@ -98,6 +99,7 @@ public class EditNoteActivity extends LinearLayout implements TimerActionListene
} }
public EditNoteActivity( public EditNoteActivity(
Preferences preferences,
MetadataService metadataService, MetadataService metadataService,
UserActivityDao userActivityDao, UserActivityDao userActivityDao,
TaskService taskService, TaskService taskService,
@ -105,7 +107,7 @@ public class EditNoteActivity extends LinearLayout implements TimerActionListene
View parent, View parent,
long t) { long t) {
super(fragment.getActivity()); super(fragment.getActivity());
this.preferences = preferences;
this.metadataService = metadataService; this.metadataService = metadataService;
this.userActivityDao = userActivityDao; this.userActivityDao = userActivityDao;
this.taskService = taskService; this.taskService = taskService;
@ -159,7 +161,7 @@ public class EditNoteActivity extends LinearLayout implements TimerActionListene
commentButton = commentsBar.findViewById(R.id.commentButton); commentButton = commentsBar.findViewById(R.id.commentButton);
commentField = (EditText) commentsBar.findViewById(R.id.commentField); commentField = (EditText) commentsBar.findViewById(R.id.commentField);
final boolean showTimerShortcut = Preferences.getBoolean(R.string.p_show_timer_shortcut, false); final boolean showTimerShortcut = preferences.getBoolean(R.string.p_show_timer_shortcut, false);
if (showTimerShortcut) { if (showTimerShortcut) {
commentField.setOnFocusChangeListener(new OnFocusChangeListener() { commentField.setOnFocusChangeListener(new OnFocusChangeListener() {

@ -12,6 +12,7 @@ import com.todoroo.astrid.activity.TaskListFragment;
import com.todoroo.astrid.service.TaskService; import com.todoroo.astrid.service.TaskService;
import org.tasks.R; import org.tasks.R;
import org.tasks.preferences.Preferences;
import javax.inject.Inject; import javax.inject.Inject;
@ -32,6 +33,7 @@ public class NotificationFragment extends TaskListFragment {
// --- implementation // --- implementation
@Inject TaskService taskService; @Inject TaskService taskService;
@Inject Preferences preferences;
@Override @Override
protected void initializeData() { protected void initializeData() {
@ -48,6 +50,6 @@ public class NotificationFragment extends TaskListFragment {
String title = extras.getString(Notifications.EXTRAS_TEXT); String title = extras.getString(Notifications.EXTRAS_TEXT);
long taskId = extras.getLong(TOKEN_ID); long taskId = extras.getLong(TOKEN_ID);
new ReminderDialog(taskService, (AstridActivity) getActivity(), taskId, title).show(); new ReminderDialog(preferences, taskService, (AstridActivity) getActivity(), taskId, title).show();
} }
} }

@ -23,7 +23,6 @@ import com.todoroo.astrid.dao.TaskDao;
import com.todoroo.astrid.dao.TaskDao.TaskCriteria; import com.todoroo.astrid.dao.TaskDao.TaskCriteria;
import com.todoroo.astrid.data.Task; import com.todoroo.astrid.data.Task;
import com.todoroo.astrid.utility.Constants; import com.todoroo.astrid.utility.Constants;
import com.todoroo.astrid.voice.VoiceOutputService;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -91,12 +90,6 @@ public class Notifications extends InjectingBroadcastReceiver {
if (!showTaskNotification(id, type, reminder)) { if (!showTaskNotification(id, type, reminder)) {
notificationManager.cancel((int) id); notificationManager.cancel((int) id);
} }
try {
VoiceOutputService.getVoiceOutputInstance().onDestroy();
} catch (VerifyError e) {
// unavailable
}
} }
/** /**

@ -18,13 +18,13 @@ import android.widget.TimePicker;
import android.widget.Toast; import android.widget.Toast;
import com.todoroo.andlib.utility.DateUtilities; import com.todoroo.andlib.utility.DateUtilities;
import com.todoroo.andlib.utility.Preferences;
import com.todoroo.astrid.activity.AstridActivity; import com.todoroo.astrid.activity.AstridActivity;
import com.todoroo.astrid.api.AstridApiConstants; import com.todoroo.astrid.api.AstridApiConstants;
import com.todoroo.astrid.data.Task; import com.todoroo.astrid.data.Task;
import com.todoroo.astrid.service.TaskService; import com.todoroo.astrid.service.TaskService;
import org.tasks.R; import org.tasks.R;
import org.tasks.preferences.Preferences;
import java.util.Date; import java.util.Date;
@ -38,9 +38,12 @@ import static org.tasks.date.DateTimeUtils.newDate;
*/ */
public class ReminderDialog extends Dialog { public class ReminderDialog extends Dialog {
public ReminderDialog(final TaskService taskService, final AstridActivity activity, final long taskId, private final Preferences preferences;
public ReminderDialog(Preferences preferences, final TaskService taskService, final AstridActivity activity, final long taskId,
String title) { String title) {
super(activity, R.style.ReminderDialog); super(activity, R.style.ReminderDialog);
this.preferences = preferences;
final SnoozeCallback dialogSnooze = new SnoozeCallback() { final SnoozeCallback dialogSnooze = new SnoozeCallback() {
@Override @Override
@ -121,7 +124,7 @@ public class ReminderDialog extends Dialog {
* Snooze and re-trigger this alarm * Snooze and re-trigger this alarm
*/ */
private void snooze(Activity activity, OnTimeSetListener onTimeSet, SnoozeCallback snoozeCallback) { private void snooze(Activity activity, OnTimeSetListener onTimeSet, SnoozeCallback snoozeCallback) {
if(Preferences.getBoolean(R.string.p_rmd_snooze_dialog, false)) { if(preferences.getBoolean(R.string.p_rmd_snooze_dialog, false)) {
Date now = newDate(); Date now = newDate();
now.setHours(now.getHours() + 1); now.setHours(now.getHours() + 1);
int hour = now.getHours(); int hour = now.getHours();

@ -12,7 +12,7 @@ import android.telephony.TelephonyManager;
import com.todoroo.andlib.utility.AndroidUtilities; import com.todoroo.andlib.utility.AndroidUtilities;
import com.todoroo.andlib.utility.DateUtilities; import com.todoroo.andlib.utility.DateUtilities;
import com.todoroo.astrid.utility.Flags; import com.todoroo.astrid.utility.Flags;
import com.todoroo.astrid.voice.VoiceOutputService; import com.todoroo.astrid.voice.VoiceOutputAssistant;
import org.joda.time.DateTime; import org.joda.time.DateTime;
import org.tasks.R; import org.tasks.R;
@ -40,6 +40,7 @@ public class ShowNotificationReceiver extends InjectingBroadcastReceiver {
@Inject NotificationManager notificationManager; @Inject NotificationManager notificationManager;
@Inject Preferences preferences; @Inject Preferences preferences;
@Inject VoiceOutputAssistant voiceOutputAssistant;
@Override @Override
public void onReceive(Context context, Intent intent) { public void onReceive(Context context, Intent intent) {
@ -194,7 +195,8 @@ public class ShowNotificationReceiver extends InjectingBroadcastReceiver {
} }
singleThreadVoicePool.submit(new NotificationRunnable(ringTimes, notificationId, notification, voiceReminder, singleThreadVoicePool.submit(new NotificationRunnable(ringTimes, notificationId, notification, voiceReminder,
maxOutVolumeForMultipleRingReminders, audioManager, previousAlarmVolume, text, notificationManager)); maxOutVolumeForMultipleRingReminders, audioManager, previousAlarmVolume, text,
notificationManager, voiceOutputAssistant));
} }
private static class NotificationRunnable implements Runnable { private static class NotificationRunnable implements Runnable {
@ -207,11 +209,13 @@ public class ShowNotificationReceiver extends InjectingBroadcastReceiver {
private final int previousAlarmVolume; private final int previousAlarmVolume;
private final String text; private final String text;
private NotificationManager notificationManager; private NotificationManager notificationManager;
private final VoiceOutputAssistant voiceOutputAssistant;
public NotificationRunnable(int ringTimes, int notificationId, Notification notification, public NotificationRunnable(int ringTimes, int notificationId, Notification notification,
boolean voiceReminder, boolean maxOutVolume, boolean voiceReminder, boolean maxOutVolume,
AudioManager audioManager, int previousAlarmVolume, AudioManager audioManager, int previousAlarmVolume,
String text, NotificationManager notificationManager) { String text, NotificationManager notificationManager,
VoiceOutputAssistant voiceOutputAssistant) {
this.ringTimes = ringTimes; this.ringTimes = ringTimes;
this.notificationId = notificationId; this.notificationId = notificationId;
this.notification = notification; this.notification = notification;
@ -221,6 +225,7 @@ public class ShowNotificationReceiver extends InjectingBroadcastReceiver {
this.previousAlarmVolume = previousAlarmVolume; this.previousAlarmVolume = previousAlarmVolume;
this.text = text; this.text = text;
this.notificationManager = notificationManager; this.notificationManager = notificationManager;
this.voiceOutputAssistant = voiceOutputAssistant;
} }
@Override @Override
@ -230,7 +235,7 @@ public class ShowNotificationReceiver extends InjectingBroadcastReceiver {
AndroidUtilities.sleepDeep(500); AndroidUtilities.sleepDeep(500);
} }
Flags.set(Flags.REFRESH); // Forces a reload when app launches Flags.set(Flags.REFRESH); // Forces a reload when app launches
if ((voiceReminder || maxOutVolumeForMultipleRingReminders)) { if (voiceReminder || maxOutVolumeForMultipleRingReminders) {
AndroidUtilities.sleepDeep(2000); AndroidUtilities.sleepDeep(2000);
for (int i = 0; i < 50; i++) { for (int i = 0; i < 50; i++) {
AndroidUtilities.sleepDeep(500); AndroidUtilities.sleepDeep(500);
@ -244,7 +249,7 @@ public class ShowNotificationReceiver extends InjectingBroadcastReceiver {
audioManager.setStreamVolume(AudioManager.STREAM_ALARM, previousAlarmVolume, 0); audioManager.setStreamVolume(AudioManager.STREAM_ALARM, previousAlarmVolume, 0);
} }
if (voiceReminder) { if (voiceReminder) {
VoiceOutputService.getVoiceOutputInstance().queueSpeak(text); voiceOutputAssistant.speak(text);
} }
} catch (VerifyError e) { } catch (VerifyError e) {
// unavailable // unavailable

@ -385,7 +385,7 @@ public class QuickAddBar extends LinearLayout {
return voiceRecognizer; return voiceRecognizer;
} }
public void startVoiceRecognition() { public void startVoiceRecognition() {
voiceRecognizer.startVoiceRecognition(activity, fragment); voiceRecognizer.startVoiceRecognition(preferences, activity, fragment);
} }
public void setupRecognizerApi() { public void setupRecognizerApi() {

@ -1,139 +0,0 @@
/**
*
*/
package com.todoroo.astrid.voice;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.media.AudioManager;
import android.speech.tts.TextToSpeech;
import android.speech.tts.TextToSpeech.OnInitListener;
import android.util.Log;
import com.todoroo.andlib.service.ContextManager;
import com.todoroo.astrid.voice.VoiceOutputService.VoiceOutputAssistant;
import java.util.HashMap;
import java.util.Locale;
/**
* @author Arne Jans
*
*/
public class Api6VoiceOutputAssistant implements OnInitListener, VoiceOutputAssistant {
private static final int MY_DATA_CHECK_CODE = 2534;
private static final String TAG = "Astrid.VoiceOutputAssistant";
private final Context context;
private TextToSpeech mTts;
private boolean isTTSInitialized;
private boolean retryLastSpeak;
private String lastTextToSpeak;
private static final HashMap<String, String> ttsParams = new HashMap<>();
static {
ttsParams.put(TextToSpeech.Engine.KEY_PARAM_STREAM,
String.valueOf(AudioManager.STREAM_NOTIFICATION));
}
Api6VoiceOutputAssistant() {
this.context = ContextManager.getContext().getApplicationContext();
}
@Override
public void checkIsTTSInstalled() {
if (!isTTSInitialized && context instanceof Activity) {
Intent checkIntent = new Intent();
checkIntent.setAction(TextToSpeech.Engine.ACTION_CHECK_TTS_DATA);
((Activity) context).startActivityForResult(checkIntent,
MY_DATA_CHECK_CODE);
}
}
@Override
public void handleActivityResult(int requestCode, int resultCode) {
if (requestCode == MY_DATA_CHECK_CODE) {
if (resultCode == TextToSpeech.Engine.CHECK_VOICE_DATA_PASS) {
// success, create the TTS instance
initTTS();
} else {
// missing data, install it
Intent installIntent = new Intent();
installIntent.setAction(TextToSpeech.Engine.ACTION_INSTALL_TTS_DATA);
context.startActivity(installIntent);
}
}
}
private void initTTS() {
mTts = new TextToSpeech(context, this);
}
@Override
public void queueSpeak(String textToSpeak) {
if (mTts != null && isTTSInitialized) {
mTts.speak(textToSpeak, TextToSpeech.QUEUE_ADD, ttsParams);
while (mTts.isSpeaking()) {
try {
Thread.sleep(50);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
} else {
retryLastSpeak = true;
this.lastTextToSpeak = textToSpeak;
initTTS();
}
}
@Override
public void onInit(int status) {
// status can be either TextToSpeech.SUCCESS or TextToSpeech.ERROR.
if (status == TextToSpeech.SUCCESS && mTts != null) {
// Set preferred language to US english.
// Note that a language may not be available, and the result will indicate this.
int result = mTts.setLanguage(Locale.getDefault());
// Try this someday for some interesting results.
// int result mTts.setLanguage(Locale.FRANCE);
if (result == TextToSpeech.LANG_MISSING_DATA ||
result == TextToSpeech.LANG_NOT_SUPPORTED) {
// Language data is missing or the language is not supported.
Log.e(TAG, "Language is not available.");
} else {
// Check the documentation for other possible result codes.
// For example, the language may be available for the locale,
// but not for the specified country and variant.
mTts.speak("", 0, null);
// The TTS engine has been successfully initialized.
isTTSInitialized = true;
// if this request came from queueSpeak, then speak it and reset the memento
if (retryLastSpeak && this.lastTextToSpeak != null) {
this.queueSpeak(this.lastTextToSpeak);
retryLastSpeak = false;
lastTextToSpeak = null;
}
}
} else {
// Initialization failed.
Log.e(TAG, "Could not initialize TextToSpeech.");
}
}
/**
* Has to be called in onDestroy of the activity that uses this instance of VoiceOutputAssistant.
*/
@Override
public void onDestroy() {
if (mTts != null && isTTSInitialized) {
mTts.shutdown();
mTts = null;
isTTSInitialized = false;
}
}
}

@ -20,7 +20,6 @@ import android.widget.ImageButton;
import com.todoroo.andlib.service.ContextManager; import com.todoroo.andlib.service.ContextManager;
import com.todoroo.andlib.utility.AndroidUtilities; import com.todoroo.andlib.utility.AndroidUtilities;
import com.todoroo.andlib.utility.DialogUtilities; import com.todoroo.andlib.utility.DialogUtilities;
import com.todoroo.andlib.utility.Preferences;
import com.todoroo.astrid.utility.Constants; import com.todoroo.astrid.utility.Constants;
import junit.framework.Assert; import junit.framework.Assert;
@ -175,7 +174,6 @@ public class VoiceInputAssistant {
} }
public void configureMicrophoneButton(final Fragment fragment, final int prompt) { public void configureMicrophoneButton(final Fragment fragment, final int prompt) {
if (Preferences.getBoolean(R.string.p_voiceInputEnabled, true) && VoiceRecognizer.voiceInputAvailable(ContextManager.getContext())) {
voiceButton.setVisibility(View.VISIBLE); voiceButton.setVisibility(View.VISIBLE);
voiceButton.setOnClickListener(new OnClickListener() { voiceButton.setOnClickListener(new OnClickListener() {
@Override @Override
@ -183,9 +181,10 @@ public class VoiceInputAssistant {
startVoiceRecognitionActivity(fragment, prompt); startVoiceRecognitionActivity(fragment, prompt);
} }
}); });
} else {
voiceButton.setVisibility(View.GONE);
} }
public void hideVoiceButton() {
voiceButton.setVisibility(View.GONE);
} }
public void showVoiceInputMarketSearch(DialogInterface.OnClickListener onFail) { public void showVoiceInputMarketSearch(DialogInterface.OnClickListener onFail) {

@ -0,0 +1,118 @@
/**
*
*/
package com.todoroo.astrid.voice;
import android.content.Context;
import android.media.AudioManager;
import android.speech.tts.TextToSpeech;
import android.speech.tts.TextToSpeech.OnInitListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.tasks.injection.ForApplication;
import java.util.HashMap;
import java.util.Locale;
import java.util.UUID;
import javax.inject.Inject;
/**
* @author Arne Jans
*
*/
public class VoiceOutputAssistant implements OnInitListener {
private static final Logger log = LoggerFactory.getLogger(VoiceOutputAssistant.class);
private final Context context;
private TextToSpeech mTts;
private boolean isTTSInitialized;
private String lastTextToSpeak;
@Inject
public VoiceOutputAssistant(@ForApplication Context context) {
this.context = context;
}
public boolean isTTSInitialized() {
return isTTSInitialized;
}
public void initTTS() {
if(mTts == null) {
mTts = new TextToSpeech(context, this);
log.debug("Inititalized {}", mTts);
}
}
public void speak(String textToSpeak) {
if (mTts != null && isTTSInitialized) {
final String id = UUID.randomUUID().toString();
log.debug("{}: {} ({})", this, textToSpeak, id);
mTts.setOnUtteranceCompletedListener(new TextToSpeech.OnUtteranceCompletedListener() {
@Override
public void onUtteranceCompleted(String utteranceId) {
log.debug("{}: onUtteranceCompleted {}", utteranceId);
if(utteranceId.equals(id)) {
shutdown();
}
}
});
mTts.speak(textToSpeak, TextToSpeech.QUEUE_ADD, new HashMap<String, String>() {{
put(TextToSpeech.Engine.KEY_PARAM_STREAM, String.valueOf(AudioManager.STREAM_NOTIFICATION));
put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, id);
}});
} else {
lastTextToSpeak = textToSpeak;
initTTS();
}
}
public void onInit(int status) {
// status can be either TextToSpeech.SUCCESS or TextToSpeech.ERROR.
if (status == TextToSpeech.SUCCESS && mTts != null) {
// Set preferred language to US english.
// Note that a language may not be available, and the result will indicate this.
int result = mTts.setLanguage(Locale.getDefault());
// Try this someday for some interesting results.
// int result mTts.setLanguage(Locale.FRANCE);
if (result == TextToSpeech.LANG_MISSING_DATA) {
log.error("Language data missing");
} else if(result == TextToSpeech.LANG_NOT_SUPPORTED) {
log.error("Language not supported");
} else {
// Check the documentation for other possible result codes.
// For example, the language may be available for the locale,
// but not for the specified country and variant.
mTts.speak("", 0, null);
// The TTS engine has been successfully initialized.
isTTSInitialized = true;
// if this request came from speak, then speak it and reset the memento
if (lastTextToSpeak != null) {
speak(lastTextToSpeak);
lastTextToSpeak = null;
}
}
} else {
log.error("Could not initialize TextToSpeech.");
}
}
public void shutdown() {
if (mTts != null && isTTSInitialized) {
try {
mTts.shutdown();
log.debug("Shutdown {}", mTts);
mTts = null;
isTTSInitialized = false;
} catch(VerifyError e) {
log.error(e.getMessage(), e);
}
}
}
}

@ -1,73 +0,0 @@
/**
* Copyright (c) 2012 Todoroo Inc
*
* See the file "LICENSE" for the full license governing this code.
*/
package com.todoroo.astrid.voice;
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 void handleActivityResult(int requestCode, int resultCode);
public void queueSpeak(String textToSpeak);
public void onDestroy();
}
public static class NullVoiceOutputAssistant implements VoiceOutputAssistant {
@Override
public void checkIsTTSInstalled() {
//
}
@Override
public void handleActivityResult(int requestCode, int resultCode) {
}
@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;
}
}

@ -16,12 +16,12 @@ import android.support.v4.app.Fragment;
import android.widget.EditText; import android.widget.EditText;
import android.widget.ImageButton; import android.widget.ImageButton;
import com.todoroo.astrid.voice.RecognizerApi.RecognizerApiListener;
import com.todoroo.andlib.utility.AndroidUtilities; import com.todoroo.andlib.utility.AndroidUtilities;
import com.todoroo.andlib.utility.Preferences;
import com.todoroo.astrid.utility.Constants; import com.todoroo.astrid.utility.Constants;
import com.todoroo.astrid.voice.RecognizerApi.RecognizerApiListener;
import org.tasks.R; import org.tasks.R;
import org.tasks.preferences.Preferences;
import java.util.List; import java.util.List;
@ -77,13 +77,13 @@ public class VoiceRecognizer {
return instance; return instance;
} }
public void startVoiceRecognition(Context context, Fragment fragment) { public void startVoiceRecognition(Preferences preferences, Context context, Fragment fragment) {
if (speechRecordingAvailable(context) && recognizerApi != null) { if (speechRecordingAvailable(context) && recognizerApi != null) {
recognizerApi.start(Constants.PACKAGE, recognizerApi.start(Constants.PACKAGE,
context.getString(R.string.audio_speak_now)); context.getString(R.string.audio_speak_now));
} else { } else {
int prompt = R.string.voice_edit_title_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.voice_create_prompt; prompt = R.string.voice_create_prompt;
} }
voiceInputAssistant.startVoiceRecognitionActivity(fragment, prompt); voiceInputAssistant.startVoiceRecognitionActivity(fragment, prompt);

@ -46,7 +46,7 @@ public class ActivityPreferences extends Preferences {
public int getEditDialogTheme() { public int getEditDialogTheme() {
boolean ics = AndroidUtilities.getSdkVersion() >= 14; boolean ics = AndroidUtilities.getSdkVersion() >= 14;
int themeSetting = com.todoroo.andlib.utility.Preferences.getBoolean(R.string.p_use_dark_theme, false) ? R.style.Tasks : R.style.Tasks_Light; int themeSetting = getBoolean(R.string.p_use_dark_theme, false) ? R.style.Tasks : R.style.Tasks_Light;
int theme; int theme;
if (themeSetting == R.style.Tasks) { if (themeSetting == R.style.Tasks) {
if (ics) { if (ics) {

Loading…
Cancel
Save