Say-my-texts-commits
Threads by month
- ----- 2026 -----
- June
- May
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- 143 discussions
Author: kmorin
Date: 2014-03-24 22:11:15 +0100 (Mon, 24 Mar 2014)
New Revision: 4
Url: http://forge.chorem.org/projects/say-my-texts/repository/revisions/4
Log:
fixes #1003 Read out loud when the phone is connected by bluetooth to a headset or car system
Modified:
trunk/src/org/chorem/android/saymytexts/NewTextBroadcastReceiver.java
trunk/src/org/chorem/android/saymytexts/SayMyTextService.java
trunk/src/org/chorem/android/saymytexts/SayMyTextsApplication.java
Modified: trunk/src/org/chorem/android/saymytexts/NewTextBroadcastReceiver.java
===================================================================
--- trunk/src/org/chorem/android/saymytexts/NewTextBroadcastReceiver.java 2014-03-22 11:16:53 UTC (rev 3)
+++ trunk/src/org/chorem/android/saymytexts/NewTextBroadcastReceiver.java 2014-03-24 21:11:15 UTC (rev 4)
@@ -1,18 +1,13 @@
package org.chorem.android.saymytexts;
+import android.bluetooth.BluetoothClass;
import android.bluetooth.BluetoothDevice;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
-import android.content.SharedPreferences;
-import android.media.AudioManager;
import android.os.Bundle;
-import android.preference.PreferenceManager;
import android.telephony.SmsMessage;
-import java.util.ArrayList;
-import java.util.List;
-
/**
* Receives the SMSs and if the headset is plugged, start the service to say it out loud.
*
@@ -21,70 +16,52 @@
*/
public class NewTextBroadcastReceiver extends BroadcastReceiver {
- protected static final List<BluetoothDevice> BT_DEVICES = new ArrayList<>();
-
@Override
public void onReceive(Context context, Intent intent) {
+ Intent serviceIntent = new Intent(context, SayMyTextService.class);
+
String action = intent.getAction();
if ("android.provider.Telephony.SMS_RECEIVED".equals(action)) {
- SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(context);
- String readingEnabledKey = context.getString(R.string.preference_enable_reading_key);
- boolean readingEnabled = sharedPref.getBoolean(readingEnabledKey, true);
+ // get the SMS message passed in
+ Bundle bundle = intent.getExtras();
+ if (bundle != null) {
+ SmsMessage[] msgs = null;
+ String messageReceived = "";
- // if the headset is plugged
- AudioManager am = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
-// if (am.isWiredHeadsetOn() || !BT_DEVICES.isEmpty()) {
- if (readingEnabled && (am.isWiredHeadsetOn() ||
- am.isBluetoothScoAvailableOffCall() && am.isBluetoothScoOn()
- || am.isBluetoothA2dpOn())) {
+ // retrieve the SMS message received
+ Object[] pdus = (Object[]) bundle.get("pdus");
+ msgs = new SmsMessage[pdus.length];
+ for (int i = 0; i < msgs.length; i++) {
+ msgs[i] = SmsMessage.createFromPdu((byte[]) pdus[i]);
+ messageReceived += msgs[i].getDisplayMessageBody() + " ";
+ }
- // get the SMS message passed in
- Bundle bundle = intent.getExtras();
+ // Get the Sender Phone Number
+ String senderPhoneNumber = msgs[0].getDisplayOriginatingAddress();
- if (bundle != null) {
- SmsMessage[] msgs = null;
- String messageReceived = "";
+ // start the service to say it out loud
+ serviceIntent.putExtra(SayMyTextService.INTENT_EXTRA_SMS_BODY, messageReceived);
+ serviceIntent.putExtra(SayMyTextService.INTENT_EXTRA_SMS_SENDER, senderPhoneNumber);
+ context.startService(serviceIntent);
+ }
- // retrieve the SMS message received
- Object[] pdus = (Object[]) bundle.get("pdus");
- msgs = new SmsMessage[pdus.length];
- for (int i = 0; i < msgs.length; i++) {
- msgs[i] = SmsMessage.createFromPdu((byte[]) pdus[i]);
- messageReceived += msgs[i].getDisplayMessageBody() + " ";
- }
+ } else {
+ BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
- // Get the Sender Phone Number
- String senderPhoneNumber = msgs[0].getDisplayOriginatingAddress();
-
- if (am.isBluetoothScoAvailableOffCall()) {
- am.startBluetoothSco();
- } else {
- am.stopBluetoothSco();
- }
- // start the service to say it out loud
- Intent serviceIntent = new Intent(context, SayMyTextService.class);
- serviceIntent.putExtra(SayMyTextService.INTENT_EXTRA_SMS_BODY, messageReceived);
- serviceIntent.putExtra(SayMyTextService.INTENT_EXTRA_SMS_SENDER, senderPhoneNumber);
+ if (BluetoothDevice.ACTION_ACL_CONNECTED.equals(action)) {
+ int majorDeviceClass = device.getBluetoothClass().getMajorDeviceClass();
+ if (majorDeviceClass == BluetoothClass.Device.Major.AUDIO_VIDEO) {
+ serviceIntent.putExtra(SayMyTextService.INTENT_EXTRA_BT_DEVICE, device);
+ serviceIntent.putExtra(SayMyTextService.INTENT_EXTRA_ADD_BT_DEVICE, true);
context.startService(serviceIntent);
}
- }
- } else {
-// BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
-//
-// if (BluetoothDevice.ACTION_ACL_CONNECTED.equals(action)) {
-// int majorDeviceClass = device.getBluetoothClass().getMajorDeviceClass();
-// Toast.makeText(context, "ACTION_ACL_CONNECTED " + majorDeviceClass, Toast.LENGTH_LONG).show();
-// if (majorDeviceClass == BluetoothClass.Device.Major.AUDIO_VIDEO) {
-// Toast.makeText(context, "device ok", Toast.LENGTH_LONG).show();
-// BT_DEVICES.add(device);
-// }
-//
-// } else {
-// Toast.makeText(context, "btHeadsetConnected false", Toast.LENGTH_LONG).show();
-// BT_DEVICES.remove(device);
-// }
+ } else {
+ serviceIntent.putExtra(SayMyTextService.INTENT_EXTRA_BT_DEVICE, device);
+ serviceIntent.putExtra(SayMyTextService.INTENT_EXTRA_ADD_BT_DEVICE, false);
+ context.startService(serviceIntent);
+ }
}
}
}
Modified: trunk/src/org/chorem/android/saymytexts/SayMyTextService.java
===================================================================
--- trunk/src/org/chorem/android/saymytexts/SayMyTextService.java 2014-03-22 11:16:53 UTC (rev 3)
+++ trunk/src/org/chorem/android/saymytexts/SayMyTextService.java 2014-03-24 21:11:15 UTC (rev 4)
@@ -1,22 +1,32 @@
package org.chorem.android.saymytexts;
import android.app.Service;
+import android.bluetooth.BluetoothDevice;
+import android.content.BroadcastReceiver;
import android.content.ContentResolver;
+import android.content.Context;
import android.content.Intent;
+import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.database.Cursor;
+import android.media.AudioManager;
import android.net.Uri;
import android.os.IBinder;
import android.preference.PreferenceManager;
import android.provider.BaseColumns;
import android.provider.ContactsContract;
import android.speech.tts.TextToSpeech;
+import android.speech.tts.UtteranceProgressListener;
+import android.telephony.PhoneStateListener;
+import android.telephony.TelephonyManager;
import android.util.Log;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
+import java.util.Map;
/**
* Service which say out loud the text passed in the intent
@@ -26,25 +36,63 @@
*/
public class SayMyTextService extends Service implements TextToSpeech.OnInitListener {
- private static final String TAG = "SayMyTextActivity";
+ private static final String TAG = "SayMyTextService";
+ /** Body of the SMS */
public static final String INTENT_EXTRA_SMS_BODY = "smsBody";
+ /** Number of the sender of the SMS */
public static final String INTENT_EXTRA_SMS_SENDER = "smsSender";
+ /** Bluetooth device which has just connected or disconnected */
+ public static final String INTENT_EXTRA_BT_DEVICE = "btDevice";
+ /** If true, the device has just connected, else disconnected */
+ public static final String INTENT_EXTRA_ADD_BT_DEVICE = "addBtDevice";
+ /** utterance id when the bluetooth device is connected */
+ protected static final String BT_UTTERANCE_ID = "btUtteranceId";
+
+ protected AudioManager audioManager;
+
+ /** null if the texttospeech is not initialized */
+ protected Boolean canSpeak = null;
+
protected TextToSpeech textToSpeech;
- // texts to read, received before the textospeech is ready
+
+ /** texts to read, received before the textospeech is ready or while a call is in progress */
protected List<String> awaitingTexts = new ArrayList<>();
+ /** bluetooth devices which are currently connected */
+ protected Map<BluetoothDevice, Integer> bluetoothDevices = new HashMap<>();
+
+ /**
+ * Listener to clal state change
+ */
+ protected final PhoneStateListener callStateListener = new PhoneStateListener() {
+ @Override
+ public void onCallStateChanged(int state, String incomingNumber) {
+ super.onCallStateChanged(state, incomingNumber);
+ if (canSpeak != null) {
+ setCanSpeak(state == TelephonyManager.CALL_STATE_IDLE);
+ }
+ }
+ };
+
@Override
public void onCreate() {
super.onCreate();
textToSpeech = new TextToSpeech(this, this);
+
+ audioManager = (AudioManager) getSystemService(AUDIO_SERVICE);
+
+ TelephonyManager tm = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
+ tm.listen(callStateListener, PhoneStateListener.LISTEN_CALL_STATE);
}
@Override
public void onDestroy() {
super.onDestroy();
+ TelephonyManager tm = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
+ tm.listen(callStateListener, PhoneStateListener.LISTEN_NONE);
textToSpeech.shutdown();
}
@@ -55,65 +103,169 @@
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
- super.onStartCommand(intent, flags, startId);
+ int result = super.onStartCommand(intent, flags, startId);
- String sms = intent.getStringExtra(INTENT_EXTRA_SMS_BODY);
- String sender = intent.getStringExtra(INTENT_EXTRA_SMS_SENDER);
- sender = getContactDisplayNameByNumber(sender);
- String text = getString(R.string.sms_received, sender, sms);
+ SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
+ String readingEnabledKey = getString(R.string.preference_enable_reading_key);
+ boolean readingEnabled = sharedPref.getBoolean(readingEnabledKey, true);
- if (awaitingTexts != null) {
- awaitingTexts.add(text);
- } else {
- readText(text);
+ if (intent != null) {
+ BluetoothDevice device = intent.getParcelableExtra(INTENT_EXTRA_BT_DEVICE);
+ // if a device is passed to the service
+ // add or remove the device from the connected devices
+ if (device != null) {
+ boolean addBtDevice = intent.getBooleanExtra(INTENT_EXTRA_ADD_BT_DEVICE, false);
+ if (addBtDevice) {
+ bluetoothDevices.put(device, device.getBluetoothClass().getDeviceClass());
+ } else {
+ bluetoothDevices.remove(device);
+ }
+
+
+ // else if the user enabled the reading and
+ // if the headset is plugged, or if there is a bluetooth device connected
+ } else if (readingEnabled && (audioManager.isWiredHeadsetOn() || !bluetoothDevices.isEmpty())) {
+
+ String sms = intent.getStringExtra(INTENT_EXTRA_SMS_BODY);
+ String sender = intent.getStringExtra(INTENT_EXTRA_SMS_SENDER);
+ sender = getContactDisplayNameByNumber(sender);
+ String text = getString(R.string.sms_received, sender, sms);
+
+ if (canSpeak != null && canSpeak) {
+ requestReading(text);
+ } else {
+ awaitingTexts.add(text);
+ }
+ }
+
+ result = START_STICKY;
}
- return START_STICKY;
+ return result;
}
@Override
public void onInit(int status) {
- Log.d(TAG, "initialized " + status);
if (status == TextToSpeech.SUCCESS) {
+ // init texttospeech
+ textToSpeech.setOnUtteranceProgressListener(new UtteranceProgressListener() {
+ @Override
+ public void onStart(String utteranceId) {
+ }
+
+ @Override
+ public void onError(String utteranceId) {
+ Log.e(TAG, "Error speaking: " + utteranceId);
+ }
+
+ @Override
+ public void onDone(String utteranceId) {
+ // when the text has been read by the bluetooth device, stop the connection
+ audioManager.stopBluetoothSco();
+ audioManager.setMode(AudioManager.MODE_NORMAL);
+ }
+ });
+
+ TelephonyManager tm = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
+ setCanSpeak(tm.getCallState() == TelephonyManager.CALL_STATE_IDLE);
+
+ } else {
+ setCanSpeak(null);
+ textToSpeech = new TextToSpeech(this, this);
+ }
+ }
+
+ /**
+ * Sets if the texts can be read
+ *
+ * @param canSpeak null if the texttospeech is not ready,
+ * false if a call is in progress
+ * true otherwise
+ */
+ protected void setCanSpeak(Boolean canSpeak) {
+ this.canSpeak = canSpeak;
+ if (canSpeak != null && canSpeak) {
for (String text : awaitingTexts) {
- readText(text);
+ requestReading(text);
}
- awaitingTexts = null;
+ awaitingTexts.clear();
+ }
+ }
+ /**
+ * Requests the reading of one text through the wired headset or bluetooth device
+ * @param text the text to read
+ */
+ protected void requestReading(String text) {
+ requestReading(Collections.singletonList(text));
+ }
+
+ /**
+ * Requests the reading of a list of texts through the wired headset or bluetooth device
+ * @param texts the texts to read
+ */
+ protected void requestReading(List<String> texts) {
+ if (bluetoothDevices.isEmpty()) {
+ readText(texts, false);
} else {
- textToSpeech = new TextToSpeech(this, this);
+ requestReadingOverBt(texts);
}
}
/**
+ * Starts the connection with the bluetooth device and requests the reading
+ * @param texts the texts to read
+ */
+ protected void requestReadingOverBt(final List<String> texts) {
+ registerReceiver(new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ int state = intent.getExtras().getInt(AudioManager.EXTRA_SCO_AUDIO_STATE);
+ if (state == AudioManager.SCO_AUDIO_STATE_CONNECTED) {
+ context.unregisterReceiver(this);
+ readText(texts, true);
+ }
+ }
+ }, new IntentFilter(AudioManager.ACTION_SCO_AUDIO_STATE_UPDATED));
+ audioManager.setMode(AudioManager.MODE_IN_CALL);
+ audioManager.startBluetoothSco();
+ }
+
+ /**
* Reads the texts out loud
- * @param text the text to read
+ * @param texts the texts to read
+ * @param btConnected if true, adds the utterance id for the bluetooth device
*/
- protected void readText(String text) {
+ protected void readText(List<String> texts, boolean btConnected) {
HashMap<String, String> params = new HashMap<>();
-// params.put(TextToSpeech.Engine.KEY_PARAM_STREAM, String.valueOf(AudioManager.STREAM_VOICE_CALL));
+ params.put(TextToSpeech.Engine.KEY_PARAM_STREAM, String.valueOf(AudioManager.STREAM_VOICE_CALL));
+ if (btConnected) {
+ params.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, BT_UTTERANCE_ID);
+ }
SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
String heisendroidModeEnabledKey = getString(R.string.preference_enable_heisendroid_mode_key);
boolean heisendroidModeEnabled = sharedPref.getBoolean(heisendroidModeEnabledKey, true);
- if (heisendroidModeEnabled) {
- textToSpeech.setLanguage(Locale.US);
- textToSpeech.setSpeechRate(0.3f);
- textToSpeech.setPitch(0.1f);
- textToSpeech.speak("Say my text.", TextToSpeech.QUEUE_ADD, params);
- }
+ for (String text : texts) {
+ if (heisendroidModeEnabled) {
+ textToSpeech.setLanguage(Locale.US);
+ textToSpeech.setSpeechRate(0.3f);
+ textToSpeech.setPitch(0.1f);
+ textToSpeech.speak("Say my text.", TextToSpeech.QUEUE_ADD, params);
+ }
- textToSpeech.setLanguage(Locale.getDefault());
- textToSpeech.setSpeechRate(1f);
- textToSpeech.setPitch(1f);
- textToSpeech.speak(text, TextToSpeech.QUEUE_ADD, params);
+ textToSpeech.setLanguage(Locale.getDefault());
+ textToSpeech.setSpeechRate(1f);
+ textToSpeech.setPitch(1f);
+ textToSpeech.speak(text, TextToSpeech.QUEUE_ADD, params);
- if (heisendroidModeEnabled) {
- textToSpeech.setLanguage(Locale.US);
- textToSpeech.setSpeechRate(0.3f);
- textToSpeech.setPitch(0.1f);
- textToSpeech.speak("You're goddamn right.", TextToSpeech.QUEUE_ADD, params);
+ if (heisendroidModeEnabled) {
+ textToSpeech.setLanguage(Locale.US);
+ textToSpeech.setSpeechRate(0.3f);
+ textToSpeech.setPitch(0.1f);
+ textToSpeech.speak("You're goddamn right.", TextToSpeech.QUEUE_ADD, params);
+ }
}
}
Modified: trunk/src/org/chorem/android/saymytexts/SayMyTextsApplication.java
===================================================================
--- trunk/src/org/chorem/android/saymytexts/SayMyTextsApplication.java 2014-03-22 11:16:53 UTC (rev 3)
+++ trunk/src/org/chorem/android/saymytexts/SayMyTextsApplication.java 2014-03-24 21:11:15 UTC (rev 4)
@@ -7,7 +7,7 @@
/**
* @author Kevin Morin (Code Lutin)
- * @since x.x
+ * @since 1.0
*/
@ReportsCrashes(formKey = "", // will not be used
mailTo = "Say-my-texts-devel(a)list.chorem.org",
1
0
r3 - in trunk: . res res/values res/values-fr res/xml src/org/chorem/android/saymytexts
by kmorin@users.chorem.org 22 Mar '14
by kmorin@users.chorem.org 22 Mar '14
22 Mar '14
Author: kmorin
Date: 2014-03-22 12:16:53 +0100 (Sat, 22 Mar 2014)
New Revision: 3
Url: http://forge.chorem.org/projects/say-my-texts/repository/revisions/3
Log:
fixes #996 HeisenDroid mode
fixes #998 Make the settings page
fixes #1002 Use ACRA
refs50 #1003 Read out loud when the phone is connected by bluetooth to a headset or car system
Added:
trunk/res/values/preference_keys.xml
trunk/res/xml/
trunk/res/xml/preferences.xml
trunk/src/org/chorem/android/saymytexts/SayMyTextsApplication.java
Removed:
trunk/res/drawable-hdpi/
trunk/res/drawable-ldpi/
trunk/res/drawable-mdpi/
trunk/res/drawable-xhdpi/
trunk/res/layout/
Modified:
trunk/AndroidManifest.xml
trunk/res/values-fr/strings.xml
trunk/res/values/strings.xml
trunk/src/org/chorem/android/saymytexts/NewTextBroadcastReceiver.java
trunk/src/org/chorem/android/saymytexts/SayMyTextService.java
trunk/src/org/chorem/android/saymytexts/SettingsActivity.java
Modified: trunk/AndroidManifest.xml
===================================================================
--- trunk/AndroidManifest.xml 2014-03-21 13:56:58 UTC (rev 2)
+++ trunk/AndroidManifest.xml 2014-03-22 11:16:53 UTC (rev 3)
@@ -14,12 +14,14 @@
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
+ <uses-permission android:name="android.permission.BLUETOOTH" />
<uses-feature android:name="android.hardware.telephony" android:required="true"/>
<supports-screens android:smallScreens="true"/>
- <application android:label="@string/app_name"
+ <application android:name=".SayMyTextsApplication"
+ android:label="@string/app_name"
android:icon="@drawable/logo"
android:description="@string/app_description">
@@ -38,8 +40,18 @@
android:enabled="true">
<intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
+ <action android:name="android.bluetooth.device.action.ACL_CONNECTED" />
+ <action android:name="android.bluetooth.device.action.ACL_DISCONNECT_REQUESTED" />
+ <action android:name="android.bluetooth.device.action.ACL_DISCONNECTED" />
</intent-filter>
</receiver>
+ <!-- Crash report dialog-->
+ <activity android:name="org.acra.CrashReportDialog"
+ android:theme="@android:style/Theme.Holo.Dialog"
+ android:launchMode="singleInstance"
+ android:excludeFromRecents="true"
+ android:finishOnTaskLaunch="true" />
+
</application>
</manifest>
Added: trunk/res/values/preference_keys.xml
===================================================================
--- trunk/res/values/preference_keys.xml (rev 0)
+++ trunk/res/values/preference_keys.xml 2014-03-22 11:16:53 UTC (rev 3)
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="preference_enable_reading_key">enable_reading</string>
+ <string name="preference_enable_heisendroid_mode_key">enable_heisendroid_mode</string>
+ <string name="preference_test_sms_key">test_sms</string>
+</resources>
\ No newline at end of file
Modified: trunk/res/values/strings.xml
===================================================================
--- trunk/res/values/strings.xml 2014-03-21 13:56:58 UTC (rev 2)
+++ trunk/res/values/strings.xml 2014-03-22 11:16:53 UTC (rev 3)
@@ -5,6 +5,19 @@
<string name="sms_received">Message received from %1$s: %2$s</string>
- <string name="test_sms_button_label">Test by sending an SMS to myself</string>
+ <!-- Preferences -->
+ <string name="preference_enable_reading_label">SMS reading</string>
+ <string name="preference_enable_heisendroid_mode_label">Heisendroid mode</string>
+ <string name="preference_test_sms_label">Test by sending an SMS to myself</string>
<string name="test_sms_content">Heisendroïd</string>
+
+ <!--ACRA-->
+ <string name="crash_toast_text">Ooooops ! the application crashed, but a report has been sent to my developer to help fix the issue !</string>
+ <string name="crash_dialog_title">say My Texts has crashed</string>
+ <string name="crash_dialog_text">An unexpected error occurred forcing the
+ application to stop. Please help us fix this by sending us error data,
+ all you have to do is click OK.</string>
+ <string name="crash_dialog_comment_prompt">You might add your comments about the problem below:</string>
+ <string name="crash_dialog_ok_toast">Thank you !</string>
+
</resources>
Modified: trunk/res/values-fr/strings.xml
===================================================================
--- trunk/res/values-fr/strings.xml 2014-03-21 13:56:58 UTC (rev 2)
+++ trunk/res/values-fr/strings.xml 2014-03-22 11:16:53 UTC (rev 3)
@@ -5,6 +5,18 @@
<string name="sms_received">Message reçu de %1$s : %2$s</string>
- <string name="test_sms_button_label">Tester en m\'envoyant un SMS</string>
+ <!-- Preferences -->
+ <string name="preference_enable_reading_label">Lecture des SMS</string>
+ <string name="preference_enable_heisendroid_mode_label">Mode Heisendroid</string>
+ <string name="preference_test_sms_label">Tester en m\'envoyant un SMS</string>
<string name="test_sms_content">Heisendroïd</string>
+
+ <!--ACRA-->
+ <string name="crash_toast_text">Erreur innatendue, préparation du rapport de bug</string>
+ <string name="crash_dialog_title">say My Texts a planté</string>
+ <string name="crash_dialog_text">Une erreur inattendue s\'est produite et a forcé l\'application à s\'arrêter.
+ Si vous voulez nous aider à corriger ce bug, merci de nous envoyer les données par mail en appuyant sur OK.</string>
+ <string name="crash_dialog_comment_prompt">Vous pouvez ajouter un commentaire ci-dessous:</string>
+ <string name="crash_dialog_ok_toast">Merci !</string>
+
</resources>
Added: trunk/res/xml/preferences.xml
===================================================================
--- trunk/res/xml/preferences.xml (rev 0)
+++ trunk/res/xml/preferences.xml 2014-03-22 11:16:53 UTC (rev 3)
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
+
+ <SwitchPreference android:key="@string/preference_enable_reading_key"
+ android:title="@string/preference_enable_reading_label"
+ android:defaultValue="true" />
+
+ <SwitchPreference android:key="@string/preference_enable_heisendroid_mode_key"
+ android:title="@string/preference_enable_heisendroid_mode_label"
+ android:defaultValue="false" />
+
+ <Preference android:key="@string/preference_test_sms_key"
+ android:title="@string/preference_test_sms_label"
+ android:persistent="false"/>
+
+</PreferenceScreen>
\ No newline at end of file
Modified: trunk/src/org/chorem/android/saymytexts/NewTextBroadcastReceiver.java
===================================================================
--- trunk/src/org/chorem/android/saymytexts/NewTextBroadcastReceiver.java 2014-03-21 13:56:58 UTC (rev 2)
+++ trunk/src/org/chorem/android/saymytexts/NewTextBroadcastReceiver.java 2014-03-22 11:16:53 UTC (rev 3)
@@ -1,12 +1,18 @@
package org.chorem.android.saymytexts;
+import android.bluetooth.BluetoothDevice;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
+import android.content.SharedPreferences;
import android.media.AudioManager;
import android.os.Bundle;
+import android.preference.PreferenceManager;
import android.telephony.SmsMessage;
+import java.util.ArrayList;
+import java.util.List;
+
/**
* Receives the SMSs and if the headset is plugged, start the service to say it out loud.
*
@@ -15,35 +21,70 @@
*/
public class NewTextBroadcastReceiver extends BroadcastReceiver {
+ protected static final List<BluetoothDevice> BT_DEVICES = new ArrayList<>();
+
@Override
public void onReceive(Context context, Intent intent) {
- // get the SMS message passed in
- Bundle bundle = intent.getExtras();
+ String action = intent.getAction();
+ if ("android.provider.Telephony.SMS_RECEIVED".equals(action)) {
- if (bundle != null) {
- SmsMessage[] msgs = null;
- String messageReceived = "";
+ SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(context);
+ String readingEnabledKey = context.getString(R.string.preference_enable_reading_key);
+ boolean readingEnabled = sharedPref.getBoolean(readingEnabledKey, true);
- // retrieve the SMS message received
- Object[] pdus = (Object[]) bundle.get("pdus");
- msgs = new SmsMessage[pdus.length];
- for (int i = 0; i < msgs.length; i++) {
- msgs[i] = SmsMessage.createFromPdu((byte[]) pdus[i]);
- messageReceived += msgs[i].getDisplayMessageBody() + " ";
- }
+ // if the headset is plugged
+ AudioManager am = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
+// if (am.isWiredHeadsetOn() || !BT_DEVICES.isEmpty()) {
+ if (readingEnabled && (am.isWiredHeadsetOn() ||
+ am.isBluetoothScoAvailableOffCall() && am.isBluetoothScoOn()
+ || am.isBluetoothA2dpOn())) {
- // Get the Sender Phone Number
- String senderPhoneNumber = msgs[0].getDisplayOriginatingAddress();
+ // get the SMS message passed in
+ Bundle bundle = intent.getExtras();
- // if the headset is plugged
- AudioManager am = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
- if (am.isWiredHeadsetOn()) {
- // start the service to say it out loud
- Intent serviceIntent = new Intent(context, SayMyTextService.class);
- serviceIntent.putExtra(SayMyTextService.INTENT_EXTRA_SMS_BODY, messageReceived);
- serviceIntent.putExtra(SayMyTextService.INTENT_EXTRA_SMS_SENDER, senderPhoneNumber);
- context.startService(serviceIntent);
+ if (bundle != null) {
+ SmsMessage[] msgs = null;
+ String messageReceived = "";
+
+ // retrieve the SMS message received
+ Object[] pdus = (Object[]) bundle.get("pdus");
+ msgs = new SmsMessage[pdus.length];
+ for (int i = 0; i < msgs.length; i++) {
+ msgs[i] = SmsMessage.createFromPdu((byte[]) pdus[i]);
+ messageReceived += msgs[i].getDisplayMessageBody() + " ";
+ }
+
+ // Get the Sender Phone Number
+ String senderPhoneNumber = msgs[0].getDisplayOriginatingAddress();
+
+ if (am.isBluetoothScoAvailableOffCall()) {
+ am.startBluetoothSco();
+ } else {
+ am.stopBluetoothSco();
+ }
+ // start the service to say it out loud
+ Intent serviceIntent = new Intent(context, SayMyTextService.class);
+ serviceIntent.putExtra(SayMyTextService.INTENT_EXTRA_SMS_BODY, messageReceived);
+ serviceIntent.putExtra(SayMyTextService.INTENT_EXTRA_SMS_SENDER, senderPhoneNumber);
+ context.startService(serviceIntent);
+ }
}
+
+ } else {
+// BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
+//
+// if (BluetoothDevice.ACTION_ACL_CONNECTED.equals(action)) {
+// int majorDeviceClass = device.getBluetoothClass().getMajorDeviceClass();
+// Toast.makeText(context, "ACTION_ACL_CONNECTED " + majorDeviceClass, Toast.LENGTH_LONG).show();
+// if (majorDeviceClass == BluetoothClass.Device.Major.AUDIO_VIDEO) {
+// Toast.makeText(context, "device ok", Toast.LENGTH_LONG).show();
+// BT_DEVICES.add(device);
+// }
+//
+// } else {
+// Toast.makeText(context, "btHeadsetConnected false", Toast.LENGTH_LONG).show();
+// BT_DEVICES.remove(device);
+// }
}
}
}
Modified: trunk/src/org/chorem/android/saymytexts/SayMyTextService.java
===================================================================
--- trunk/src/org/chorem/android/saymytexts/SayMyTextService.java 2014-03-21 13:56:58 UTC (rev 2)
+++ trunk/src/org/chorem/android/saymytexts/SayMyTextService.java 2014-03-22 11:16:53 UTC (rev 3)
@@ -1,18 +1,20 @@
package org.chorem.android.saymytexts;
-import android.app.IntentService;
import android.app.Service;
import android.content.ContentResolver;
import android.content.Intent;
+import android.content.SharedPreferences;
import android.database.Cursor;
import android.net.Uri;
import android.os.IBinder;
+import android.preference.PreferenceManager;
import android.provider.BaseColumns;
import android.provider.ContactsContract;
import android.speech.tts.TextToSpeech;
import android.util.Log;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
import java.util.Locale;
@@ -31,7 +33,7 @@
protected TextToSpeech textToSpeech;
// texts to read, received before the textospeech is ready
- protected List<String> awaitingTexts = new ArrayList<String>();
+ protected List<String> awaitingTexts = new ArrayList<>();
@Override
public void onCreate() {
@@ -65,6 +67,7 @@
} else {
readText(text);
}
+
return START_STICKY;
}
@@ -87,25 +90,30 @@
* @param text the text to read
*/
protected void readText(String text) {
- // TODO kmorin 20140321 check heisendroid mode when done
- if (false) {
+ HashMap<String, String> params = new HashMap<>();
+// params.put(TextToSpeech.Engine.KEY_PARAM_STREAM, String.valueOf(AudioManager.STREAM_VOICE_CALL));
+
+ SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
+ String heisendroidModeEnabledKey = getString(R.string.preference_enable_heisendroid_mode_key);
+ boolean heisendroidModeEnabled = sharedPref.getBoolean(heisendroidModeEnabledKey, true);
+
+ if (heisendroidModeEnabled) {
textToSpeech.setLanguage(Locale.US);
textToSpeech.setSpeechRate(0.3f);
textToSpeech.setPitch(0.1f);
- textToSpeech.speak("Say my text.", TextToSpeech.QUEUE_ADD, null);
+ textToSpeech.speak("Say my text.", TextToSpeech.QUEUE_ADD, params);
}
textToSpeech.setLanguage(Locale.getDefault());
textToSpeech.setSpeechRate(1f);
textToSpeech.setPitch(1f);
- textToSpeech.speak(text, TextToSpeech.QUEUE_ADD, null);
+ textToSpeech.speak(text, TextToSpeech.QUEUE_ADD, params);
- // TODO kmorin 20140321 check heisendroid mode when done
- if (false) {
+ if (heisendroidModeEnabled) {
textToSpeech.setLanguage(Locale.US);
textToSpeech.setSpeechRate(0.3f);
textToSpeech.setPitch(0.1f);
- textToSpeech.speak("You're goddamn right.", TextToSpeech.QUEUE_ADD, null);
+ textToSpeech.speak("You're goddamn right.", TextToSpeech.QUEUE_ADD, params);
}
}
Added: trunk/src/org/chorem/android/saymytexts/SayMyTextsApplication.java
===================================================================
--- trunk/src/org/chorem/android/saymytexts/SayMyTextsApplication.java (rev 0)
+++ trunk/src/org/chorem/android/saymytexts/SayMyTextsApplication.java 2014-03-22 11:16:53 UTC (rev 3)
@@ -0,0 +1,32 @@
+package org.chorem.android.saymytexts;
+
+import android.app.Application;
+import org.acra.ACRA;
+import org.acra.ReportingInteractionMode;
+import org.acra.annotation.ReportsCrashes;
+
+/**
+ * @author Kevin Morin (Code Lutin)
+ * @since x.x
+ */
+@ReportsCrashes(formKey = "", // will not be used
+ mailTo = "Say-my-texts-devel(a)list.chorem.org",
+ mode = ReportingInteractionMode.DIALOG,
+ resToastText = R.string.crash_toast_text, // optional, displayed as soon as the crash occurs, before collecting data which can take a few seconds
+ resDialogText = R.string.crash_dialog_text,
+ resDialogIcon = android.R.drawable.ic_dialog_info, //optional. default is a warning sign
+ resDialogTitle = R.string.crash_dialog_title, // optional. default is your application name
+ resDialogCommentPrompt = R.string.crash_dialog_comment_prompt, // optional. when defined, adds a user text field input with this text resource as a label
+ resDialogOkToast = R.string.crash_dialog_ok_toast) // optional. displays a Toast message when the user accepts to send a report.
+
+public class SayMyTextsApplication extends Application {
+
+ private static final String TAG = "SayMyTextsApplication";
+
+ @Override
+ public void onCreate() {
+ ACRA.init(this);
+ super.onCreate();
+ }
+
+}
Modified: trunk/src/org/chorem/android/saymytexts/SettingsActivity.java
===================================================================
--- trunk/src/org/chorem/android/saymytexts/SettingsActivity.java 2014-03-21 13:56:58 UTC (rev 2)
+++ trunk/src/org/chorem/android/saymytexts/SettingsActivity.java 2014-03-22 11:16:53 UTC (rev 3)
@@ -8,9 +8,10 @@
import android.media.AudioManager;
import android.net.Uri;
import android.os.Bundle;
+import android.preference.Preference;
+import android.preference.PreferenceFragment;
import android.telephony.SmsManager;
import android.telephony.TelephonyManager;
-import android.view.View;
/**
* Activity to set settings
@@ -25,18 +26,11 @@
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- }
+ getFragmentManager().beginTransaction()
+ .replace(android.R.id.content, new SettingsFragment())
+ .commit();
- public void sendSMS(View source) {
- TelephonyManager tMgr = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
- String phoneNumber = tMgr.getLine1Number();
- String message = getString(R.string.test_sms_content);
-
- PendingIntent pi = PendingIntent.getActivity(this, -1, new Intent(this, SettingsActivity.class), 0);
- SmsManager sms = SmsManager.getDefault();
- sms.sendTextMessage(phoneNumber, null, message, pi, null);
}
// Used only for tests - TODO kmorin 20140321 remove when sure we do not need it
@@ -55,4 +49,36 @@
c.close();
}
}
+
+ public static class SettingsFragment extends PreferenceFragment {
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ // Load the preferences from an XML resource
+ addPreferencesFromResource(R.xml.preferences);
+
+ Preference testPreference = findPreference(getString(R.string.preference_test_sms_key));
+ testPreference.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
+ @Override
+ public boolean onPreferenceClick(Preference preference) {
+ sendSMS();
+ return true;
+ }
+ });
+ }
+
+ protected void sendSMS() {
+ Context context = getActivity();
+
+ TelephonyManager tMgr = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
+ String phoneNumber = tMgr.getLine1Number();
+ String message = getString(R.string.test_sms_content);
+
+ PendingIntent pi = PendingIntent.getActivity(context, -1, new Intent(context, SettingsActivity.class), 0);
+ SmsManager sms = SmsManager.getDefault();
+ sms.sendTextMessage(phoneNumber, null, message, pi, null);
+ }
+ }
}
1
0
Author: kmorin
Date: 2014-03-21 14:56:58 +0100 (Fri, 21 Mar 2014)
New Revision: 2
Url: http://forge.chorem.org/projects/say-my-texts/repository/revisions/2
Log:
add ignores
Modified:
trunk/
trunk/src/org/chorem/android/saymytexts/SayMyTextService.java
Property changes on: trunk
___________________________________________________________________
Added: svn:ignore
+ *.idea
gen
target
local.properties
*.iml
Modified: trunk/src/org/chorem/android/saymytexts/SayMyTextService.java
===================================================================
--- trunk/src/org/chorem/android/saymytexts/SayMyTextService.java 2014-03-21 13:45:03 UTC (rev 1)
+++ trunk/src/org/chorem/android/saymytexts/SayMyTextService.java 2014-03-21 13:56:58 UTC (rev 2)
@@ -30,7 +30,7 @@
public static final String INTENT_EXTRA_SMS_SENDER = "smsSender";
protected TextToSpeech textToSpeech;
- // text to read, received before the textospeech is ready
+ // texts to read, received before the textospeech is ready
protected List<String> awaitingTexts = new ArrayList<String>();
@Override
1
0