diff --git a/api/build.gradle b/api/build.gradle
index 349835d8e..434f9b7d3 100644
--- a/api/build.gradle
+++ b/api/build.gradle
@@ -37,7 +37,8 @@ dependencies {
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: '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
}
diff --git a/astrid/assets/logback.xml b/astrid/assets/logback.xml
new file mode 100644
index 000000000..2446f9fa8
--- /dev/null
+++ b/astrid/assets/logback.xml
@@ -0,0 +1,18 @@
+
+
+
+
+ %logger{0}
+
+
+ [ %thread ] %msg%n
+
+
+
+
+
+
+
+
diff --git a/astrid/assets/subtasks_horizontal.png b/astrid/assets/subtasks_horizontal.png
deleted file mode 100644
index cdb7666b5..000000000
Binary files a/astrid/assets/subtasks_horizontal.png and /dev/null differ
diff --git a/astrid/assets/subtasks_vertical.png b/astrid/assets/subtasks_vertical.png
deleted file mode 100644
index a2df9f709..000000000
Binary files a/astrid/assets/subtasks_vertical.png and /dev/null differ
diff --git a/astrid/src/main/java/com/todoroo/astrid/activity/EditPreferences.java b/astrid/src/main/java/com/todoroo/astrid/activity/EditPreferences.java
index f004e10e1..c8f8bd250 100644
--- a/astrid/src/main/java/com/todoroo/astrid/activity/EditPreferences.java
+++ b/astrid/src/main/java/com/todoroo/astrid/activity/EditPreferences.java
@@ -19,6 +19,7 @@ import android.preference.Preference.OnPreferenceClickListener;
import android.preference.PreferenceGroup;
import android.preference.PreferenceManager;
import android.preference.PreferenceScreen;
+import android.speech.tts.TextToSpeech;
import android.text.TextUtils;
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.TodorooPreferenceActivity;
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 org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.tasks.R;
import org.tasks.preferences.Preferences;
import org.tasks.widget.WidgetHelper;
@@ -62,8 +65,10 @@ import javax.inject.Inject;
*/
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_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_PERFORMANCE_PREF_CHANGED = 3;
@@ -74,6 +79,7 @@ public class EditPreferences extends TodorooPreferenceActivity {
@Inject TaskService taskService;
@Inject Preferences preferences;
@Inject CalendarAlarmScheduler calendarAlarmScheduler;
+ @Inject VoiceOutputAssistant voiceOutputAssistant;
private VoiceInputAssistant voiceInputAssistant;
@@ -359,6 +365,13 @@ public class EditPreferences extends TodorooPreferenceActivity {
return false;
}
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+
+ voiceOutputAssistant.shutdown();
+ }
+
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_CODE_SYNC && resultCode == SyncProviderPreferences.RESULT_CODE_SYNCHRONIZE) {
@@ -373,7 +386,17 @@ public class EditPreferences extends TodorooPreferenceActivity {
return;
}
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) {
// 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 {
- VoiceOutputService.getVoiceOutputInstance();
- if(newValue) {
- VoiceOutputService.getVoiceOutputInstance().checkIsTTSInstalled();
+ if(enabled && !voiceOutputAssistant.isTTSInitialized()) {
+ Intent checkIntent = new Intent();
+ checkIntent.setAction(TextToSpeech.Engine.ACTION_CHECK_TTS_DATA);
+ startActivityForResult(checkIntent, REQUEST_CODE_TTS_CHECK);
+ } else if (!enabled && voiceOutputAssistant.isTTSInitialized()) {
+ voiceOutputAssistant.shutdown();
}
} catch (VerifyError e) {
- // doesn't work :(
+ log.error(e.getMessage(), e);
preference.setEnabled(false);
preferences.setBoolean(preference.getKey(), false);
}
diff --git a/astrid/src/main/java/com/todoroo/astrid/activity/TaskEditFragment.java b/astrid/src/main/java/com/todoroo/astrid/activity/TaskEditFragment.java
index 3bbb81451..5c52b4de8 100755
--- a/astrid/src/main/java/com/todoroo/astrid/activity/TaskEditFragment.java
+++ b/astrid/src/main/java/com/todoroo/astrid/activity/TaskEditFragment.java
@@ -41,6 +41,7 @@ import android.widget.LinearLayout;
import android.widget.ScrollView;
import android.widget.Toast;
+import com.todoroo.andlib.service.ContextManager;
import com.todoroo.andlib.utility.AndroidUtilities;
import com.todoroo.andlib.utility.DateUtilities;
import com.todoroo.andlib.utility.DialogUtilities;
@@ -285,8 +286,8 @@ ViewPager.OnPageChangeListener, EditNoteActivity.UpdatesChangedListener {
private void instantiateEditNotes() {
if (showEditComments) {
long idParam = getActivity().getIntent().getLongExtra(TOKEN_ID, -1L);
- editNotes = new EditNoteActivity(metadataService, userActivityDao, taskService, this, getView(),
- idParam);
+ editNotes = new EditNoteActivity(preferences, metadataService, userActivityDao,
+ taskService, this, getView(), idParam);
editNotes.setLayoutParams(new FrameLayout.LayoutParams(LayoutParams.FILL_PARENT,
LayoutParams.WRAP_CONTENT));
@@ -541,7 +542,11 @@ ViewPager.OnPageChangeListener, EditNoteActivity.UpdatesChangedListener {
voiceNoteAssistant = new VoiceInputAssistant(voiceAddNoteButton, REQUEST_VOICE_RECOG);
voiceNoteAssistant.setAppend();
voiceNoteAssistant.setLanguageModel(RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
- voiceNoteAssistant.configureMicrophoneButton(TaskEditFragment.this, prompt);
+ if (preferences.getBoolean(R.string.p_voiceInputEnabled, true) && VoiceRecognizer.voiceInputAvailable(ContextManager.getContext())) {
+ voiceNoteAssistant.configureMicrophoneButton(TaskEditFragment.this, prompt);
+ } else {
+ voiceNoteAssistant.hideVoiceButton();
+ }
}
loadMoreContainer();
}
diff --git a/astrid/src/main/java/com/todoroo/astrid/notes/EditNoteActivity.java b/astrid/src/main/java/com/todoroo/astrid/notes/EditNoteActivity.java
index c71d4fb30..c6fe68e86 100644
--- a/astrid/src/main/java/com/todoroo/astrid/notes/EditNoteActivity.java
+++ b/astrid/src/main/java/com/todoroo/astrid/notes/EditNoteActivity.java
@@ -35,7 +35,6 @@ import com.todoroo.andlib.data.TodorooCursor;
import com.todoroo.andlib.service.ContextManager;
import com.todoroo.andlib.sql.Query;
import com.todoroo.andlib.utility.DateUtilities;
-import com.todoroo.andlib.utility.Preferences;
import com.todoroo.astrid.actfm.ActFmCameraModule;
import com.todoroo.astrid.actfm.ActFmCameraModule.CameraResultCallback;
import com.todoroo.astrid.actfm.ActFmCameraModule.ClearImageCallback;
@@ -56,6 +55,7 @@ import com.todoroo.astrid.timers.TimerActionControlSet.TimerActionListener;
import org.json.JSONObject;
import org.tasks.R;
+import org.tasks.preferences.Preferences;
import java.util.ArrayList;
import java.util.Collections;
@@ -69,6 +69,7 @@ public class EditNoteActivity extends LinearLayout implements TimerActionListene
private Task task;
+ private final Preferences preferences;
private final MetadataService metadataService;
private final UserActivityDao userActivityDao;
private final TaskService taskService;
@@ -98,6 +99,7 @@ public class EditNoteActivity extends LinearLayout implements TimerActionListene
}
public EditNoteActivity(
+ Preferences preferences,
MetadataService metadataService,
UserActivityDao userActivityDao,
TaskService taskService,
@@ -105,7 +107,7 @@ public class EditNoteActivity extends LinearLayout implements TimerActionListene
View parent,
long t) {
super(fragment.getActivity());
-
+ this.preferences = preferences;
this.metadataService = metadataService;
this.userActivityDao = userActivityDao;
this.taskService = taskService;
@@ -159,7 +161,7 @@ public class EditNoteActivity extends LinearLayout implements TimerActionListene
commentButton = commentsBar.findViewById(R.id.commentButton);
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) {
commentField.setOnFocusChangeListener(new OnFocusChangeListener() {
diff --git a/astrid/src/main/java/com/todoroo/astrid/reminders/NotificationFragment.java b/astrid/src/main/java/com/todoroo/astrid/reminders/NotificationFragment.java
index 59444bf59..3d7528695 100644
--- a/astrid/src/main/java/com/todoroo/astrid/reminders/NotificationFragment.java
+++ b/astrid/src/main/java/com/todoroo/astrid/reminders/NotificationFragment.java
@@ -12,6 +12,7 @@ import com.todoroo.astrid.activity.TaskListFragment;
import com.todoroo.astrid.service.TaskService;
import org.tasks.R;
+import org.tasks.preferences.Preferences;
import javax.inject.Inject;
@@ -32,6 +33,7 @@ public class NotificationFragment extends TaskListFragment {
// --- implementation
@Inject TaskService taskService;
+ @Inject Preferences preferences;
@Override
protected void initializeData() {
@@ -48,6 +50,6 @@ public class NotificationFragment extends TaskListFragment {
String title = extras.getString(Notifications.EXTRAS_TEXT);
long taskId = extras.getLong(TOKEN_ID);
- new ReminderDialog(taskService, (AstridActivity) getActivity(), taskId, title).show();
+ new ReminderDialog(preferences, taskService, (AstridActivity) getActivity(), taskId, title).show();
}
}
diff --git a/astrid/src/main/java/com/todoroo/astrid/reminders/Notifications.java b/astrid/src/main/java/com/todoroo/astrid/reminders/Notifications.java
index 527b3b84f..f2e4b871c 100644
--- a/astrid/src/main/java/com/todoroo/astrid/reminders/Notifications.java
+++ b/astrid/src/main/java/com/todoroo/astrid/reminders/Notifications.java
@@ -23,7 +23,6 @@ import com.todoroo.astrid.dao.TaskDao;
import com.todoroo.astrid.dao.TaskDao.TaskCriteria;
import com.todoroo.astrid.data.Task;
import com.todoroo.astrid.utility.Constants;
-import com.todoroo.astrid.voice.VoiceOutputService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -91,12 +90,6 @@ public class Notifications extends InjectingBroadcastReceiver {
if (!showTaskNotification(id, type, reminder)) {
notificationManager.cancel((int) id);
}
-
- try {
- VoiceOutputService.getVoiceOutputInstance().onDestroy();
- } catch (VerifyError e) {
- // unavailable
- }
}
/**
diff --git a/astrid/src/main/java/com/todoroo/astrid/reminders/ReminderDialog.java b/astrid/src/main/java/com/todoroo/astrid/reminders/ReminderDialog.java
index 01b43ae11..24589ddcc 100644
--- a/astrid/src/main/java/com/todoroo/astrid/reminders/ReminderDialog.java
+++ b/astrid/src/main/java/com/todoroo/astrid/reminders/ReminderDialog.java
@@ -18,13 +18,13 @@ import android.widget.TimePicker;
import android.widget.Toast;
import com.todoroo.andlib.utility.DateUtilities;
-import com.todoroo.andlib.utility.Preferences;
import com.todoroo.astrid.activity.AstridActivity;
import com.todoroo.astrid.api.AstridApiConstants;
import com.todoroo.astrid.data.Task;
import com.todoroo.astrid.service.TaskService;
import org.tasks.R;
+import org.tasks.preferences.Preferences;
import java.util.Date;
@@ -38,9 +38,12 @@ import static org.tasks.date.DateTimeUtils.newDate;
*/
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) {
super(activity, R.style.ReminderDialog);
+ this.preferences = preferences;
final SnoozeCallback dialogSnooze = new SnoozeCallback() {
@Override
@@ -121,7 +124,7 @@ public class ReminderDialog extends Dialog {
* Snooze and re-trigger this alarm
*/
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();
now.setHours(now.getHours() + 1);
int hour = now.getHours();
diff --git a/astrid/src/main/java/com/todoroo/astrid/reminders/ShowNotificationReceiver.java b/astrid/src/main/java/com/todoroo/astrid/reminders/ShowNotificationReceiver.java
index 74da4f4d7..2dbea155e 100644
--- a/astrid/src/main/java/com/todoroo/astrid/reminders/ShowNotificationReceiver.java
+++ b/astrid/src/main/java/com/todoroo/astrid/reminders/ShowNotificationReceiver.java
@@ -12,7 +12,7 @@ import android.telephony.TelephonyManager;
import com.todoroo.andlib.utility.AndroidUtilities;
import com.todoroo.andlib.utility.DateUtilities;
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.tasks.R;
@@ -40,6 +40,7 @@ public class ShowNotificationReceiver extends InjectingBroadcastReceiver {
@Inject NotificationManager notificationManager;
@Inject Preferences preferences;
+ @Inject VoiceOutputAssistant voiceOutputAssistant;
@Override
public void onReceive(Context context, Intent intent) {
@@ -194,7 +195,8 @@ public class ShowNotificationReceiver extends InjectingBroadcastReceiver {
}
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 {
@@ -207,11 +209,13 @@ public class ShowNotificationReceiver extends InjectingBroadcastReceiver {
private final int previousAlarmVolume;
private final String text;
private NotificationManager notificationManager;
+ private final VoiceOutputAssistant voiceOutputAssistant;
public NotificationRunnable(int ringTimes, int notificationId, Notification notification,
boolean voiceReminder, boolean maxOutVolume,
AudioManager audioManager, int previousAlarmVolume,
- String text, NotificationManager notificationManager) {
+ String text, NotificationManager notificationManager,
+ VoiceOutputAssistant voiceOutputAssistant) {
this.ringTimes = ringTimes;
this.notificationId = notificationId;
this.notification = notification;
@@ -221,6 +225,7 @@ public class ShowNotificationReceiver extends InjectingBroadcastReceiver {
this.previousAlarmVolume = previousAlarmVolume;
this.text = text;
this.notificationManager = notificationManager;
+ this.voiceOutputAssistant = voiceOutputAssistant;
}
@Override
@@ -230,7 +235,7 @@ public class ShowNotificationReceiver extends InjectingBroadcastReceiver {
AndroidUtilities.sleepDeep(500);
}
Flags.set(Flags.REFRESH); // Forces a reload when app launches
- if ((voiceReminder || maxOutVolumeForMultipleRingReminders)) {
+ if (voiceReminder || maxOutVolumeForMultipleRingReminders) {
AndroidUtilities.sleepDeep(2000);
for (int i = 0; i < 50; i++) {
AndroidUtilities.sleepDeep(500);
@@ -244,7 +249,7 @@ public class ShowNotificationReceiver extends InjectingBroadcastReceiver {
audioManager.setStreamVolume(AudioManager.STREAM_ALARM, previousAlarmVolume, 0);
}
if (voiceReminder) {
- VoiceOutputService.getVoiceOutputInstance().queueSpeak(text);
+ voiceOutputAssistant.speak(text);
}
} catch (VerifyError e) {
// unavailable
diff --git a/astrid/src/main/java/com/todoroo/astrid/ui/QuickAddBar.java b/astrid/src/main/java/com/todoroo/astrid/ui/QuickAddBar.java
index 108390d87..7bee45ac5 100644
--- a/astrid/src/main/java/com/todoroo/astrid/ui/QuickAddBar.java
+++ b/astrid/src/main/java/com/todoroo/astrid/ui/QuickAddBar.java
@@ -385,7 +385,7 @@ public class QuickAddBar extends LinearLayout {
return voiceRecognizer;
}
public void startVoiceRecognition() {
- voiceRecognizer.startVoiceRecognition(activity, fragment);
+ voiceRecognizer.startVoiceRecognition(preferences, activity, fragment);
}
public void setupRecognizerApi() {
diff --git a/astrid/src/main/java/com/todoroo/astrid/voice/Api6VoiceOutputAssistant.java b/astrid/src/main/java/com/todoroo/astrid/voice/Api6VoiceOutputAssistant.java
deleted file mode 100644
index 8840204ff..000000000
--- a/astrid/src/main/java/com/todoroo/astrid/voice/Api6VoiceOutputAssistant.java
+++ /dev/null
@@ -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 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;
- }
- }
-
-}
diff --git a/astrid/src/main/java/com/todoroo/astrid/voice/VoiceInputAssistant.java b/astrid/src/main/java/com/todoroo/astrid/voice/VoiceInputAssistant.java
index befe470e0..8a942d59e 100644
--- a/astrid/src/main/java/com/todoroo/astrid/voice/VoiceInputAssistant.java
+++ b/astrid/src/main/java/com/todoroo/astrid/voice/VoiceInputAssistant.java
@@ -20,7 +20,6 @@ import android.widget.ImageButton;
import com.todoroo.andlib.service.ContextManager;
import com.todoroo.andlib.utility.AndroidUtilities;
import com.todoroo.andlib.utility.DialogUtilities;
-import com.todoroo.andlib.utility.Preferences;
import com.todoroo.astrid.utility.Constants;
import junit.framework.Assert;
@@ -175,17 +174,17 @@ public class VoiceInputAssistant {
}
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.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- startVoiceRecognitionActivity(fragment, prompt);
- }
- });
- } else {
- voiceButton.setVisibility(View.GONE);
- }
+ voiceButton.setVisibility(View.VISIBLE);
+ voiceButton.setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ startVoiceRecognitionActivity(fragment, prompt);
+ }
+ });
+ }
+
+ public void hideVoiceButton() {
+ voiceButton.setVisibility(View.GONE);
}
public void showVoiceInputMarketSearch(DialogInterface.OnClickListener onFail) {
diff --git a/astrid/src/main/java/com/todoroo/astrid/voice/VoiceOutputAssistant.java b/astrid/src/main/java/com/todoroo/astrid/voice/VoiceOutputAssistant.java
new file mode 100644
index 000000000..7fe060885
--- /dev/null
+++ b/astrid/src/main/java/com/todoroo/astrid/voice/VoiceOutputAssistant.java
@@ -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() {{
+ 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);
+ }
+ }
+ }
+}
diff --git a/astrid/src/main/java/com/todoroo/astrid/voice/VoiceOutputService.java b/astrid/src/main/java/com/todoroo/astrid/voice/VoiceOutputService.java
deleted file mode 100644
index 0578a6f67..000000000
--- a/astrid/src/main/java/com/todoroo/astrid/voice/VoiceOutputService.java
+++ /dev/null
@@ -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
- *
- */
-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;
- }
-
-}
diff --git a/astrid/src/main/java/com/todoroo/astrid/voice/VoiceRecognizer.java b/astrid/src/main/java/com/todoroo/astrid/voice/VoiceRecognizer.java
index 1f428daf4..d7eb04bcb 100644
--- a/astrid/src/main/java/com/todoroo/astrid/voice/VoiceRecognizer.java
+++ b/astrid/src/main/java/com/todoroo/astrid/voice/VoiceRecognizer.java
@@ -16,12 +16,12 @@ import android.support.v4.app.Fragment;
import android.widget.EditText;
import android.widget.ImageButton;
-import com.todoroo.astrid.voice.RecognizerApi.RecognizerApiListener;
import com.todoroo.andlib.utility.AndroidUtilities;
-import com.todoroo.andlib.utility.Preferences;
import com.todoroo.astrid.utility.Constants;
+import com.todoroo.astrid.voice.RecognizerApi.RecognizerApiListener;
import org.tasks.R;
+import org.tasks.preferences.Preferences;
import java.util.List;
@@ -77,13 +77,13 @@ public class VoiceRecognizer {
return instance;
}
- public void startVoiceRecognition(Context context, Fragment fragment) {
+ public void startVoiceRecognition(Preferences preferences, Context context, Fragment fragment) {
if (speechRecordingAvailable(context) && recognizerApi != null) {
recognizerApi.start(Constants.PACKAGE,
context.getString(R.string.audio_speak_now));
} else {
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;
}
voiceInputAssistant.startVoiceRecognitionActivity(fragment, prompt);
diff --git a/astrid/src/main/java/org/tasks/preferences/ActivityPreferences.java b/astrid/src/main/java/org/tasks/preferences/ActivityPreferences.java
index 88d01e3ca..68bcb358b 100644
--- a/astrid/src/main/java/org/tasks/preferences/ActivityPreferences.java
+++ b/astrid/src/main/java/org/tasks/preferences/ActivityPreferences.java
@@ -46,7 +46,7 @@ public class ActivityPreferences extends Preferences {
public int getEditDialogTheme() {
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;
if (themeSetting == R.style.Tasks) {
if (ics) {