aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.project6
-rw-r--r--AndroidManifest.xml2
-rw-r--r--readme.textile20
-rw-r--r--res/values-en/strings.xml15
-rw-r--r--res/values-fr/strings.xml30
-rw-r--r--res/values/constants.xml8
-rw-r--r--res/values/strings.xml29
-rw-r--r--res/xml/pref.xml52
-rw-r--r--src/org/broeuschmeul/android/gps/bluetooth/provider/BlueetoothGpsManager.java274
-rw-r--r--src/org/broeuschmeul/android/gps/bluetooth/provider/BluetoothGpsActivity.java378
-rw-r--r--src/org/broeuschmeul/android/gps/bluetooth/provider/BluetoothGpsProviderService.java52
-rw-r--r--src/org/broeuschmeul/android/gps/nmea/util/NmeaParser.java60
-rw-r--r--version.txt14
13 files changed, 621 insertions, 319 deletions
diff --git a/.project b/.project
index 5f1d113..3b27c42 100644
--- a/.project
+++ b/.project
@@ -6,6 +6,11 @@
</projects>
<buildSpec>
<buildCommand>
+ <name>org.eclipse.mylyn.wikitext.ui.wikiTextValidationBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
<name>com.android.ide.eclipse.adt.ResourceManagerBuilder</name>
<arguments>
</arguments>
@@ -29,5 +34,6 @@
<natures>
<nature>com.android.ide.eclipse.adt.AndroidNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
+ <nature>org.eclipse.mylyn.wikitext.ui.wikiTextNature</nature>
</natures>
</projectDescription>
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index ff0e02d..ff68a9a 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -20,7 +20,7 @@
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.broeuschmeul.android.gps.bluetooth.provider"
- android:versionCode="101"
+ android:versionCode="112"
android:versionName="@string/versionName">
<application android:icon="@drawable/icon" android:label="@string/app_name" android:allowClearUserData="true">
<activity android:name=".BluetoothGpsActivity"
diff --git a/readme.textile b/readme.textile
new file mode 100644
index 0000000..da41bde
--- /dev/null
+++ b/readme.textile
@@ -0,0 +1,20 @@
+BlueGps4Droid 1.1.2
+* Add verifications: if bluetooth or mock locations are not enabled, the service is not started.
+* Add alert messages to explain why the service cannot be started if bluetooth or mock locations are not enabled
+* If device doesn't have an internal GPS, the bluetooth GPS provider will be enabled automatically
+
+BlueGps4Droid 1.1.1
+* Bug fix (Ticket #4: Connection service is not properly closed https://sourceforge.net/p/bluegps4droid/tickets/4/).
+* Add notifications when the connection with the GPS fails and when the connection service is closed because of two many connection retry.
+* Add settings to choose the number of connection retries before exiting.
+
+BlueGps4Droid 1.1 (does not work properly because of bug #4. Use either version 1.0 or 1.1.1 !)
+* Reconnect automatically when the connection with the GPS is lost (5 attempts in 5 minutes)
+* Replace Android default internal GPS or use a new location provider
+* Send status notifications when GPS loses fix or is disconnected.
+
+BlueGps4Droid 1.0
+* Connect to bluetooth GPS (NMEA) and replace the internal GPS of an Android device.
+* Record GPS tracks in NMEA files
+* Compatible with Android version 2.0 and above
+* English and French translations \ No newline at end of file
diff --git a/res/values-en/strings.xml b/res/values-en/strings.xml
index 52b03b6..2dcd198 100644
--- a/res/values-en/strings.xml
+++ b/res/values-en/strings.xml
@@ -20,10 +20,21 @@
-->
<resources>
<!-- we use the defaults values
- <string name="pref_recording_params_title">Recording parameters</string>
- <string name="pref_recording_title">Enable/Disable</string>
+ <string name="pref_start_gps_title">Start/Stop GPS</string>
+ <string name="pref_start_gps_summary_off">Bluetooth GPS is off</string>
+ <string name="pref_start_gps_summary_on">Bluetooth GPS is on</string>
+ <string name="pref_start_gps_params_title">GPS Options</string>
+ <string name="pref_gps_location_provider_title">Location provider options</string>
+ <string name="pref_gps_location_provider_summary">Bluetooth GPS will replace internal GPS</string>
+ <string name="pref_replace_std_gps_title">Replace internal GPS</string>
+ <string name="pref_replace_std_gps_summary_on">Bluetooth GPS will replace internal GPS</string>
+ <string name="pref_replace_std_gps_summary_off">Bluetooth GPS will use a new location provider</string>
+ <string name="pref_mock_gps_name_title">Mock location provider name</string>
+ <string name="pref_mock_gps_name_summary">Bluetooth GPS name: %s</string>
+ <string name="pref_recording_title">Enable/Disable NMEA log</string>
<string name="pref_recording_summary_off">Track recording is off</string>
<string name="pref_recording_summary_on">Track recording is on</string>
+ <string name="pref_recording_params_title">Recording parameters</string>
<string name="pref_mintime_title">Time between records</string>
<string name="pref_mintime_summary">Time between records in milliseconds</string>
<string name="pref_mindistance_title">Distance between records</string>
diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml
index 98ec99a..b00db70 100644
--- a/res/values-fr/strings.xml
+++ b/res/values-fr/strings.xml
@@ -22,8 +22,17 @@
<string name="app_name">BlueGps</string>
<string name="pref_start_gps_title">Start/Stop GPS</string>
- <string name="pref_start_gps_summary_off">le GPS Bluetooth est arrêté</string>
- <string name="pref_start_gps_summary_on">le GPS Bluetooth est démarré</string>
+ <string name="pref_start_gps_summary_off">Le GPS Bluetooth est arrêté</string>
+ <string name="pref_start_gps_summary_on">Le GPS Bluetooth est démarré</string>
+ <string name="pref_gps_location_provider_title">Location provider options</string>
+ <string name="pref_gps_location_provider_summary">Le GPS Bluetooth remplacera le GPS interne</string>
+ <string name="pref_replace_std_gps_title">Remplacer le GPS interne</string>
+ <string name="pref_replace_std_gps_summary_on">Le GPS Bluetooth remplacera le GPS interne</string>
+ <string name="pref_replace_std_gps_summary_off">Un nouveau location provider sera utilisé</string>
+ <string name="pref_mock_gps_name_title">Nom du location provider</string>
+ <string name="pref_mock_gps_name_summary">Nom du GPS Bluetooth : %s</string>
+ <string name="pref_connection_retries_title">Nombre de connexions</string>
+ <string name="pref_connection_retries_summary">"Nombre d'essais avant fermeture : %s"</string>
<string name="pref_recording_title">Activer/Désactiver NMEA log</string>
<string name="pref_recording_summary_off">Enregistrement du GPS inactif</string>
<string name="pref_recording_summary_on">Enregistrement du GPS actif</string>
@@ -40,10 +49,12 @@
<string name="msg_gps_provider_started">GPS Bluetooth... démarré</string>
<string name="msg_gps_provider_stopped">GPS Bluetooth... arrêté</string>
<string name="msg_gps_provider_already_started">GPS Bluetooth... déjà démarré</string>
- <string name="msg_gps_provider_disabled">Oups ! Le GPS est désactivé</string>
- <string name="msg_bluetooth_unsupported">Oups ! Bluetooth non disponible</string>
- <string name="msg_bluetooth_disabled">Oups ! Bluetooth désactivé</string>
- <string name="msg_mock_location_disabled">Oups ! Positions fictives non autorisées</string>
+ <string name="msg_gps_provider_stopped_by_problem">"Oups ! %s"</string>
+ <string name="msg_two_many_connection_problems">Problèmes de connexion</string>
+ <string name="msg_gps_provider_disabled">Le GPS est désactivé</string>
+ <string name="msg_bluetooth_unsupported">Bluetooth non disponible</string>
+ <string name="msg_bluetooth_disabled">Bluetooth désactivé</string>
+ <string name="msg_mock_location_disabled">Positions fictives non autorisées</string>
<string name="msg_bluetooth_gps_unavaible">Impossible de se connecter au GPS</string>
<string name="msg_nmea_recording_started">Enregistrement des traces NMEA... démarré</string>
<string name="msg_nmea_recording_stopped">Enregistrement des traces NMEA... arrêté</string>
@@ -51,6 +62,13 @@
<string name="foreground_service_started_notification_title">BlueGps</string>
<string name="foreground_gps_provider_started_notification">GPS Bluetooth démarré.</string>
<string name="foreground_nmea_recording_started_notification">Enregistrement des données NMEA en cours.</string>
+ <string name="connection_problem_notification_title">BlueGps : problème de connexion</string>
+ <plurals name="connection_problem_notification">
+ <item quantity="one">"Encore un essai avant fermeture"</item>
+ <item quantity="other">"Encore %d essais avant fermeture"</item>
+ </plurals>
+ <string name="service_closed_because_connection_problem_notification_title">BlueGps arrêté</string>
+ <string name="service_closed_because_connection_problem_notification">"Motif : %s"</string>
<string name="about_title">À propos</string>
<string name="about_version">BluetoothGPS4Droid version</string>
diff --git a/res/values/constants.xml b/res/values/constants.xml
index f0abbff..6ac5ca9 100644
--- a/res/values/constants.xml
+++ b/res/values/constants.xml
@@ -19,15 +19,21 @@
along with BluetoothGPS4Droid. If not, see : http://www.gnu.org/licenses/.
-->
<resources>
- <string name="versionName">1.0.1</string>
+ <string name="versionName">1.1.2</string>
<string name="pref_start_gps_key">startGps</string>
+ <string name="pref_gps_location_provider_key">gpsLocationProviderKey</string>
+ <string name="pref_replace_std_gps_key">replaceStdtGps</string>
+ <string name="pref_mock_gps_name_key">mockGpsName</string>
+ <string name="pref_connection_retries_key">connectionRetries</string>
<string name="pref_recording_key">trackRecording</string>
<string name="pref_trackfile_directory_key">trackFileDirectory</string>
<string name="pref_trackfile_prefix_key">trackFilePrefix</string>
<string name="pref_bluetooth_device_key">bluetoothDevice</string>
<string name="pref_about_key">about</string>
+ <string name="defaultConnectionRetries">0</string>
<string name="defaultTrackFileDirectory">/sdcard/nmea</string>
<string name="defaultTrackFilePrefix">btnmeatrack</string>
+ <string name="defaultMockGpsName">bluetooth_gps</string>
</resources>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 808b330..62902d3 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -24,6 +24,18 @@
<string name="pref_start_gps_title">Start/Stop GPS</string>
<string name="pref_start_gps_summary_off">Bluetooth GPS is off</string>
<string name="pref_start_gps_summary_on">Bluetooth GPS is on</string>
+ <string name="pref_gps_location_provider_title">Location provider options</string>
+ <string name="pref_gps_location_provider_summary">Bluetooth GPS will replace internal GPS</string>
+ <string name="pref_replace_std_gps_title">Replace internal GPS</string>
+ <string name="pref_replace_std_gps_summary_on">Bluetooth GPS will replace internal GPS</string>
+ <!--
+ <string name="pref_replace_std_gps_summary_off">Internal GPS will remain available</string>
+ -->
+ <string name="pref_replace_std_gps_summary_off">Bluetooth GPS will use a new location provider</string>
+ <string name="pref_mock_gps_name_title">Mock location provider name</string>
+ <string name="pref_mock_gps_name_summary">Bluetooth GPS name: %s</string>
+ <string name="pref_connection_retries_title">Connection retry number</string>
+ <string name="pref_connection_retries_summary">Number of attempts before exiting: %s</string>
<string name="pref_recording_title">Enable/Disable NMEA log</string>
<string name="pref_recording_summary_off">Track recording is off</string>
<string name="pref_recording_summary_on">Track recording is on</string>
@@ -40,10 +52,12 @@
<string name="msg_gps_provider_started">Bluetooth GPS... started</string>
<string name="msg_gps_provider_stopped">Bluetooth GPS... stopped</string>
<string name="msg_gps_provider_already_started">Bluetooth GPS... is already on</string>
- <string name="msg_gps_provider_disabled">Cannot start: GPS is disabled</string>
- <string name="msg_bluetooth_unsupported">Cannot start: Bluetooth is not supported</string>
- <string name="msg_bluetooth_disabled">Cannot start: Bluetooth is disabled</string>
- <string name="msg_mock_location_disabled">Cannot start: Mock locations disabled</string>
+ <string name="msg_gps_provider_stopped_by_problem">"Cannot start: %s"</string>
+ <string name="msg_two_many_connection_problems">Too many connection problems</string>
+ <string name="msg_gps_provider_disabled">GPS is disabled</string>
+ <string name="msg_bluetooth_unsupported">Bluetooth is not supported</string>
+ <string name="msg_bluetooth_disabled">Bluetooth is disabled</string>
+ <string name="msg_mock_location_disabled">Mock locations disabled</string>
<string name="msg_bluetooth_gps_unavaible">Cannot connect to bluetooth GPS</string>
<string name="msg_nmea_recording_started">GPS NMEA recording... started</string>
<string name="msg_nmea_recording_stopped">GPS NMEA recording... stopped</string>
@@ -51,6 +65,13 @@
<string name="foreground_service_started_notification_title">BlueGps</string>
<string name="foreground_gps_provider_started_notification">BlueGps service started</string>
<string name="foreground_nmea_recording_started_notification">BlueGps NMEA recording service started</string>
+ <string name="connection_problem_notification_title">BlueGps: connection problem</string>
+ <plurals name="connection_problem_notification">
+ <item quantity="one">Will retry one more time before closing</item>
+ <item quantity="other">Will retry %d more times before closing</item>
+ </plurals>
+ <string name="service_closed_because_connection_problem_notification_title">BlueGps stopped</string>
+ <string name="service_closed_because_connection_problem_notification">"Reason: %s"</string>
<string name="about_title">About</string>
<string name="about_version">BluetoothGPS4Droid version</string>
diff --git a/res/xml/pref.xml b/res/xml/pref.xml
index e49a4a7..af0cb0c 100644
--- a/res/xml/pref.xml
+++ b/res/xml/pref.xml
@@ -27,15 +27,41 @@
android:key="@string/pref_bluetooth_device_key"
android:summary="@string/pref_bluetooth_device_summary" />
<CheckBoxPreference
- android:enabled="true"
+ android:dependency="@string/pref_bluetooth_device_key"
android:key="@string/pref_start_gps_key"
android:persistent="true"
- android:disableDependentsState = "false"
+ android:disableDependentsState="true"
android:title="@string/pref_start_gps_title"
android:summaryOn="@string/pref_start_gps_summary_on"
android:summaryOff="@string/pref_start_gps_summary_off" />
- <CheckBoxPreference
+ <PreferenceScreen
android:dependency="@string/pref_start_gps_key"
+ android:shouldDisableView="true"
+ android:key="@string/pref_gps_location_provider_key"
+ android:summary="@string/pref_gps_location_provider_summary"
+ android:title="@string/pref_gps_location_provider_title" >
+ <CheckBoxPreference
+ android:key="@string/pref_replace_std_gps_key"
+ android:persistent="true"
+ android:disableDependentsState="true"
+ android:defaultValue="true"
+ android:title="@string/pref_replace_std_gps_title"
+ android:summaryOn="@string/pref_replace_std_gps_summary_on"
+ android:summaryOff="@string/pref_replace_std_gps_summary_off" />
+ <EditTextPreference
+ android:dependency="@string/pref_replace_std_gps_key"
+ android:key="@string/pref_mock_gps_name_key"
+ android:title="@string/pref_mock_gps_name_title"
+ android:defaultValue="@string/defaultMockGpsName"
+ android:summary="@string/pref_mock_gps_name_summary" />
+ <EditTextPreference
+ android:key="@string/pref_connection_retries_key"
+ android:title="@string/pref_connection_retries_title"
+ android:defaultValue="@string/defaultConnectionRetries"
+ android:inputType="numberDecimal"
+ android:summary="@string/pref_connection_retries_summary" />
+ </PreferenceScreen>
+ <CheckBoxPreference
android:enabled="true"
android:key="@string/pref_recording_key"
android:persistent="true"
@@ -43,16 +69,16 @@
android:summaryOn="@string/pref_recording_summary_on"
android:summaryOff="@string/pref_recording_summary_off" />
<PreferenceScreen android:title="@string/pref_recording_params_title" >
- <EditTextPreference
- android:key="@string/pref_trackfile_directory_key"
- android:title="@string/pref_trackfile_directory_title"
- android:defaultValue="@string/defaultTrackFileDirectory"
- android:summary="@string/pref_trackfile_directory_summary" />
- <EditTextPreference
- android:key="@string/pref_trackfile_prefix_key"
- android:title="@string/pref_trackfile_prefix_title"
- android:defaultValue="@string/defaultTrackFilePrefix"
- android:summary="@string/pref_trackfile_prefix_summary" />
+ <EditTextPreference
+ android:key="@string/pref_trackfile_directory_key"
+ android:title="@string/pref_trackfile_directory_title"
+ android:defaultValue="@string/defaultTrackFileDirectory"
+ android:summary="@string/pref_trackfile_directory_summary" />
+ <EditTextPreference
+ android:key="@string/pref_trackfile_prefix_key"
+ android:title="@string/pref_trackfile_prefix_title"
+ android:defaultValue="@string/defaultTrackFilePrefix"
+ android:summary="@string/pref_trackfile_prefix_summary" />
</PreferenceScreen>
<Preference
android:key="@string/pref_about_key"
diff --git a/src/org/broeuschmeul/android/gps/bluetooth/provider/BlueetoothGpsManager.java b/src/org/broeuschmeul/android/gps/bluetooth/provider/BlueetoothGpsManager.java
index 60f315f..335539a 100644
--- a/src/org/broeuschmeul/android/gps/bluetooth/provider/BlueetoothGpsManager.java
+++ b/src/org/broeuschmeul/android/gps/bluetooth/provider/BlueetoothGpsManager.java
@@ -30,54 +30,72 @@ import java.util.List;
import java.util.UUID;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
import org.broeuschmeul.android.gps.nmea.util.NmeaParser;
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
import android.app.Service;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.Context;
import android.content.SharedPreferences;
+import android.content.Intent;
import android.location.LocationManager;
import android.location.GpsStatus.NmeaListener;
import android.preference.PreferenceManager;
import android.provider.Settings;
+import android.os.SystemClock;
import android.util.Log;
public class BlueetoothGpsManager {
private static final String LOG_TAG = "BlueGPS";
// private static final String LOG_TAG = BlueetoothGpsManager.class.getSimpleName();
+
+ private class ConnectedGps extends Thread {
+ private final InputStream in;
+
+ public ConnectedGps(BluetoothSocket socket) {
+ InputStream tmpIn = null;
+ try {
+ tmpIn = socket.getInputStream();
+ } catch (IOException e) {
+ Log.e(LOG_TAG, "error while getting socket streams", e);
+ }
+ in = tmpIn;
+ }
- private class ConnectedThread extends Thread {
- private final InputStream in;
-
- public ConnectedThread(BluetoothSocket socket) {
- InputStream tmpIn = null;
- try {
- tmpIn = socket.getInputStream();
- } catch (IOException e) {
- Log.e(LOG_TAG, "error while getting socket streams", e);
- }
- in = tmpIn;
- }
-
- public void run() {
- try {
- BufferedReader reader = new BufferedReader(new InputStreamReader(in,"US-ASCII"));
- String s;
- while((enabled && (s = reader.readLine()) != null)){
+ public void run() {
+ try {
+ BufferedReader reader = new BufferedReader(new InputStreamReader(in,"US-ASCII"));
+ String s;
+ long now = SystemClock.uptimeMillis();
+ long lastRead = now;
+ while((enabled) && (now < lastRead+5000 )){
+ if (reader.ready()){
+ s = reader.readLine();
Log.v(LOG_TAG, "data: "+System.currentTimeMillis()+" "+s);
notifyNmeaSentence(s+"\r\n");
+ lastRead = SystemClock.uptimeMillis();
+ } else {
+ Log.d(LOG_TAG, "data: not ready "+System.currentTimeMillis());
+ SystemClock.sleep(500);
}
- } catch (IOException e) {
- Log.e(LOG_TAG, "error while getting data", e);
- } finally {
- disable();
+ now = SystemClock.uptimeMillis();
}
- }
+ } catch (IOException e) {
+ Log.e(LOG_TAG, "error while getting data", e);
+ setMockLocationProviderOutOfService();
+ } finally {
+ disableIfNeeded();
+ }
}
+ }
private Service callingService;
private BluetoothSocket gpsSocket;
@@ -85,20 +103,48 @@ public class BlueetoothGpsManager {
private NmeaParser parser = new NmeaParser(10f);
private boolean enabled = false;
private ExecutorService notificationPool;
+ private ScheduledExecutorService connectionAndReadingPool;
private List<NmeaListener> nmeaListeners = Collections.synchronizedList(new LinkedList<NmeaListener>());
private LocationManager locationManager;
private SharedPreferences sharedPreferences;
- private ConnectedThread connectedThread;
+ private ConnectedGps connectedGps;
private int disableReason = 0;
+ private Notification connectionProblemNotification;
+ private Notification serviceStoppedNotification;
+ private Context appContext;
+ private NotificationManager notificationManager;
+ private int maxConnectionRetries;
+ private int nbRetriesRemaining;
+ private boolean connected = false;
- public BlueetoothGpsManager(Service callingService, String deviceAddress) {
+ public BlueetoothGpsManager(Service callingService, String deviceAddress, int maxRetries) {
this.gpsDeviceAddress = deviceAddress;
this.callingService = callingService;
+ this.maxConnectionRetries = maxRetries;
+ this.nbRetriesRemaining = 1+maxRetries;
+ this.appContext = callingService.getApplicationContext();
locationManager = (LocationManager)callingService.getSystemService(Context.LOCATION_SERVICE);
sharedPreferences = PreferenceManager.getDefaultSharedPreferences(callingService);
+ notificationManager = (NotificationManager)callingService.getSystemService(Context.NOTIFICATION_SERVICE);
parser.setLocationManager(locationManager);
+
+ connectionProblemNotification = new Notification();
+ connectionProblemNotification.icon = R.drawable.icon;
+ Intent stopIntent = new Intent(BluetoothGpsProviderService.ACTION_STOP_GPS_PROVIDER);
+ // PendingIntent stopPendingIntent = PendingIntent.getService(appContext, 0, stopIntent, PendingIntent.FLAG_CANCEL_CURRENT);
+ PendingIntent stopPendingIntent = PendingIntent.getService(appContext, 0, stopIntent, PendingIntent.FLAG_CANCEL_CURRENT);
+ connectionProblemNotification.contentIntent = stopPendingIntent;
+
+ serviceStoppedNotification = new Notification();
+ serviceStoppedNotification.icon=R.drawable.icon;
+ Intent restartIntent = new Intent(BluetoothGpsProviderService.ACTION_START_GPS_PROVIDER);
+ PendingIntent restartPendingIntent = PendingIntent.getService(appContext, 0, restartIntent, PendingIntent.FLAG_CANCEL_CURRENT);
+ serviceStoppedNotification.setLatestEventInfo(appContext,
+ appContext.getString(R.string.service_closed_because_connection_problem_notification_title),
+ appContext.getString(R.string.service_closed_because_connection_problem_notification),
+ restartPendingIntent);
}
-
+
private void setDisableReason(int reasonId){
disableReason = reasonId;
}
@@ -106,7 +152,7 @@ public class BlueetoothGpsManager {
public int getDisableReason(){
return disableReason;
}
-
+
/**
* @return true if the bluetooth GPS is enabled
*/
@@ -114,7 +160,8 @@ public class BlueetoothGpsManager {
return enabled;
}
- public synchronized void enable() {
+ public synchronized boolean enable() {
+ notificationManager.cancel(R.string.service_closed_because_connection_problem_notification_title);
if (! enabled){
Log.d(LOG_TAG, "enabling Bluetooth GPS manager");
final BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
@@ -131,14 +178,14 @@ public class BlueetoothGpsManager {
Log.e(LOG_TAG, "Mock location provider OFF");
disable(R.string.msg_mock_location_disabled);
// } else if ( (! locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER))
-// // && (sharedPreferences.getBoolean(BluetoothGpsProviderService.PREF_REPLACE_STD_GPS, true))
+// && (sharedPreferences.getBoolean(BluetoothGpsProviderService.PREF_REPLACE_STD_GPS, true))
// ) {
// Log.e(LOG_TAG, "GPS location provider OFF");
// disable(R.string.msg_gps_provider_disabled);
} else {
- BluetoothDevice gpsDevice = bluetoothAdapter.getRemoteDevice(gpsDeviceAddress);
- if (gpsDevice == null){
- Log.e(LOG_TAG, "GPS device not found");
+ final BluetoothDevice gpsDevice = bluetoothAdapter.getRemoteDevice(gpsDeviceAddress);
+ if (gpsDevice == null){
+ Log.e(LOG_TAG, "GPS device not found");
disable(R.string.msg_bluetooth_gps_unavaible);
} else {
Log.e(LOG_TAG, "current device: "+gpsDevice.getName() + " -- " + gpsDevice.getAddress());
@@ -151,41 +198,100 @@ public class BlueetoothGpsManager {
if (gpsSocket == null){
Log.e(LOG_TAG, "Error while establishing connection: no socket");
disable(R.string.msg_bluetooth_gps_unavaible);
- } else {
-
- Runnable connectThread = new Runnable() {
+ } else {
+ Runnable connectThread = new Runnable() {
@Override
public void run() {
- // Cancel discovery because it will slow down the connection
- bluetoothAdapter.cancelDiscovery();
- try {
- // Connect the device through the socket. This will block
- // until it succeeds or throws an exception
- Log.v(LOG_TAG, "connecting to socket");
- gpsSocket.connect();
- Log.d(LOG_TAG, "connected to socket");
- Log.v(LOG_TAG, "starting socket reading thread");
- connectedThread = new ConnectedThread(gpsSocket);
- connectedThread.start();
- Log.v(LOG_TAG, "socket reading thread started");
- } catch (IOException connectException) {
- // Unable to connect; So close everything and get out
- Log.e(LOG_TAG, "error while connecting to socket", connectException);
- disable(R.string.msg_bluetooth_gps_unavaible);
- // callingService.stopSelf();
- }
+ try {
+ connected = false;
+ Log.v(LOG_TAG, "current device: "+gpsDevice.getName() + " -- " + gpsDevice.getAddress());
+ if ((bluetoothAdapter.isEnabled()) && (nbRetriesRemaining > 0 )){
+ try {
+ if (gpsSocket != null){
+ Log.d(LOG_TAG, "trying to close old socket");
+ gpsSocket.close();
+ }
+ } catch (IOException e) {
+ Log.e(LOG_TAG, "Error during disconnection", e);
+ }
+ try {
+ gpsSocket = gpsDevice.createRfcommSocketToServiceRecord(UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"));
+ } catch (IOException e) {
+ Log.e(LOG_TAG, "Error during connection", e);
+ gpsSocket = null;
+ }
+ if (gpsSocket == null){
+ Log.e(LOG_TAG, "Error while establishing connection: no socket");
+ disable(R.string.msg_bluetooth_gps_unavaible);
+ } else {
+ // Cancel discovery because it will slow down the connection
+ bluetoothAdapter.cancelDiscovery();
+ // we increment the number of connection try
+ // Connect the device through the socket. This will block
+ // until it succeeds or throws an exception
+ Log.v(LOG_TAG, "connecting to socket");
+ gpsSocket.connect();
+ Log.d(LOG_TAG, "connected to socket");
+ connected = true;
+ // reset eventual disabling cause
+// setDisableReason(0);
+ // connection obtained so reset the number of connection try
+ nbRetriesRemaining = 1+maxConnectionRetries ;
+ notificationManager.cancel(R.string.connection_problem_notification_title);
+ Log.v(LOG_TAG, "starting socket reading task");
+ connectedGps = new ConnectedGps(gpsSocket);
+ connectionAndReadingPool.execute(connectedGps);
+ Log.v(LOG_TAG, "socket reading thread started");
+ }
+// } else if (! bluetoothAdapter.isEnabled()) {
+// setDisableReason(R.string.msg_bluetooth_disabled);
+ }
+ } catch (IOException connectException) {
+ // Unable to connect
+ Log.e(LOG_TAG, "error while connecting to socket", connectException);
+ // disable(R.string.msg_bluetooth_gps_unavaible);
+ } finally {
+ nbRetriesRemaining--;
+ if (! connected) {
+ disableIfNeeded();
+ }
+ }
}
};
this.enabled = true;
Log.d(LOG_TAG, "Bluetooth GPS manager enabled");
Log.v(LOG_TAG, "starting notification thread");
notificationPool = Executors.newSingleThreadExecutor();
+ Log.v(LOG_TAG, "starting connection and reading thread");
+ connectionAndReadingPool = Executors.newSingleThreadScheduledExecutor();
Log.v(LOG_TAG, "starting connection to socket task");
- notificationPool.execute(connectThread);
-// enableMockLocationProvider(LocationManager.GPS_PROVIDER);
- }
- }
- }
+ connectionAndReadingPool.scheduleWithFixedDelay(connectThread, 5000, 60000, TimeUnit.MILLISECONDS);
+ }
+ }
+ }
+ }
+ return this.enabled;
+ }
+
+ private synchronized void disableIfNeeded(){
+ if (enabled){
+ if (nbRetriesRemaining > 0){
+ // Unable to connect
+ Log.e(LOG_TAG, "Unable to establish connection");
+ connectionProblemNotification.when = System.currentTimeMillis();
+ String pbMessage = appContext.getResources().getQuantityString(R.plurals.connection_problem_notification, nbRetriesRemaining, nbRetriesRemaining);
+ connectionProblemNotification.setLatestEventInfo(appContext,
+ appContext.getString(R.string.connection_problem_notification_title),
+ pbMessage,
+ connectionProblemNotification.contentIntent);
+ connectionProblemNotification.number = 1 + maxConnectionRetries - nbRetriesRemaining;
+ notificationManager.notify(R.string.connection_problem_notification_title, connectionProblemNotification);
+ } else {
+// notificationManager.cancel(R.string.connection_problem_notification_title);
+// serviceStoppedNotification.when = System.currentTimeMillis();
+// notificationManager.notify(R.string.service_closed_because_connection_problem_notification_title, serviceStoppedNotification);
+ disable(R.string.msg_two_many_connection_problems);
+ }
}
}
@@ -196,6 +302,15 @@ public class BlueetoothGpsManager {
}
public synchronized void disable() {
+ notificationManager.cancel(R.string.connection_problem_notification_title);
+ if (getDisableReason() != 0){
+ serviceStoppedNotification.when = System.currentTimeMillis();
+ serviceStoppedNotification.setLatestEventInfo(appContext,
+ appContext.getString(R.string.service_closed_because_connection_problem_notification_title),
+ appContext.getString(R.string.service_closed_because_connection_problem_notification, appContext.getString(getDisableReason())),
+ serviceStoppedNotification.contentIntent);
+ notificationManager.notify(R.string.service_closed_because_connection_problem_notification_title, serviceStoppedNotification);
+ }
if (enabled){
Log.d(LOG_TAG, "disabling Bluetooth GPS manager");
enabled = false;
@@ -209,18 +324,19 @@ public class BlueetoothGpsManager {
nmeaListeners.clear();
disableMockLocationProvider();
notificationPool.shutdown();
+ connectionAndReadingPool.shutdown();
callingService.stopSelf();
Log.d(LOG_TAG, "Bluetooth GPS manager disabled");
}
}
-
+
public void enableMockLocationProvider(String gpsName){
if (parser != null){
Log.d(LOG_TAG, "enabling mock locations provider: "+gpsName);
parser.enableMockLocationProvider(gpsName);
}
}
-
+
public void disableMockLocationProvider(){
if (parser != null){
Log.d(LOG_TAG, "disabling mock locations provider");
@@ -248,7 +364,12 @@ public class BlueetoothGpsManager {
}
return mockLocationProvider;
}
-
+
+ private void setMockLocationProviderOutOfService(){
+ if (parser != null){
+ parser.setMockLocationProviderOutOfService();
+ }
+ }
public boolean addNmeaListener(NmeaListener listener){
if (!nmeaListeners.contains(listener)){
@@ -257,34 +378,39 @@ public class BlueetoothGpsManager {
}
return true;
}
-
+
public void removeNmeaListener(NmeaListener listener){
Log.d(LOG_TAG, "removing NMEA listener");
nmeaListeners.remove(listener);
}
-
+
private void notifyNmeaSentence(final String nmeaSentence){
if (enabled){
Log.v(LOG_TAG, "parsing and notifying NMEA sentence: "+nmeaSentence);
+ String sentence = null;
try {
- parser.parseNmeaSentence(nmeaSentence);
+ sentence = parser.parseNmeaSentence(nmeaSentence);
} catch (SecurityException e){
Log.e(LOG_TAG, "error while parsing NMEA sentence: "+nmeaSentence, e);
// a priori Mock Location is disabled
+ sentence = null;
disable(R.string.msg_mock_location_disabled);
}
+ final String recognizedSentence = sentence;
final long timestamp = System.currentTimeMillis();
- synchronized(nmeaListeners) {
- Log.v(LOG_TAG, "notifying NMEA sentence: "+nmeaSentence);
- for(final NmeaListener listener : nmeaListeners){
- notificationPool.execute(new Runnable(){
- @Override
- public void run() {
- listener.onNmeaReceived(timestamp, nmeaSentence);
- }
- });
+ if (recognizedSentence != null){
+ Log.v(LOG_TAG, "notifying NMEA sentence: "+recognizedSentence);
+ synchronized(nmeaListeners) {
+ for(final NmeaListener listener : nmeaListeners){
+ notificationPool.execute(new Runnable(){
+ @Override
+ public void run() {
+ listener.onNmeaReceived(timestamp, recognizedSentence);
+ }
+ });
+ }
}
}
}
- }
+ }
}
diff --git a/src/org/broeuschmeul/android/gps/bluetooth/provider/BluetoothGpsActivity.java b/src/org/broeuschmeul/android/gps/bluetooth/provider/BluetoothGpsActivity.java
index 07fff46..0b79286 100644
--- a/src/org/broeuschmeul/android/gps/bluetooth/provider/BluetoothGpsActivity.java
+++ b/src/org/broeuschmeul/android/gps/bluetooth/provider/BluetoothGpsActivity.java
@@ -1,179 +1,199 @@
-/*
- * Copyright (C) 2010 Herbert von Broeuschmeul
- * Copyright (C) 2010 BluetoothGPS4Droid Project
- *
- * This file is part of BluetoothGPS4Droid.
- *
- * BluetoothGPS4Droid is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * BluetoothGPS4Droid is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with BluetoothGPS4Droid. If not, see <http://www.gnu.org/licenses/>.
- */
-
-package org.broeuschmeul.android.gps.bluetooth.provider;
-
-import java.util.HashSet;
-import java.util.Set;
-
-import android.app.AlertDialog;
-import android.bluetooth.BluetoothAdapter;
-import android.bluetooth.BluetoothDevice;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
-import android.os.Bundle;
-import android.preference.CheckBoxPreference;
-import android.preference.ListPreference;
-import android.preference.Preference;
-import android.preference.PreferenceActivity;
-import android.preference.PreferenceManager;
-import android.preference.Preference.OnPreferenceChangeListener;
-import android.text.method.LinkMovementMethod;
-import android.util.Log;
-import android.view.View;
-import android.widget.TextView;
-
-/**
- * A PreferenceActivity Class used to configure, start and stop the NMEA tracker service.
- *
- * @author Herbert von Broeuschmeul
- *
- */
-public class BluetoothGpsActivity extends PreferenceActivity implements OnPreferenceChangeListener, OnSharedPreferenceChangeListener {
-
- private static final String LOG_TAG = "BlueGPS";
-// private static final String LOG_TAG = BluetoothGpsActivity.class.getSimpleName();
-
- private SharedPreferences sharedPref ;
- private BluetoothAdapter bluetoothAdapter = null;
-
- /** Called when the activity is first created. */
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- addPreferencesFromResource(R.xml.pref);
- sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
- sharedPref.registerOnSharedPreferenceChangeListener(this);
- bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
- Preference pref = findPreference(BluetoothGpsProviderService.PREF_ABOUT);
- pref.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
- @Override
- public boolean onPreferenceClick(Preference preference) {
- BluetoothGpsActivity.this.displayAboutDialog();
- return true;
- }
- });
- }
-
- /* (non-Javadoc)
- * @see android.app.Activity#onResume()
- */
- @Override
- protected void onResume() {
- this.updateDevicePreferenceList();
- super.onResume();
- }
-
- private void updateDevicePreferenceSummary(){
- // update bluetooth device summary
- String deviceName = "";
- ListPreference prefDevices = (ListPreference)findPreference(BluetoothGpsProviderService.PREF_BLUETOOTH_DEVICE);
- String deviceAddress = sharedPref.getString(BluetoothGpsProviderService.PREF_BLUETOOTH_DEVICE, null);
- if (BluetoothAdapter.checkBluetoothAddress(deviceAddress)){
- deviceName = bluetoothAdapter.getRemoteDevice(deviceAddress).getName();
- }
- prefDevices.setSummary(getString(R.string.pref_bluetooth_device_summary, deviceName));
- }
-
- private void updateDevicePreferenceList(){
- // update bluetooth device summary
- updateDevicePreferenceSummary();
- // update bluetooth device list
- ListPreference prefDevices = (ListPreference)findPreference(BluetoothGpsProviderService.PREF_BLUETOOTH_DEVICE);
- Set<BluetoothDevice> pairedDevices = new HashSet<BluetoothDevice>();
- if (bluetoothAdapter != null){
- pairedDevices = bluetoothAdapter.getBondedDevices();
- }
- String[] entryValues = new String[pairedDevices.size()];
- String[] entries = new String[pairedDevices.size()];
- int i = 0;
- // Loop through paired devices
- for (BluetoothDevice device : pairedDevices) {
- // Add the name and address to the ListPreference enties and entyValues
- Log.d(LOG_TAG, "device: "+device.getName() + " -- " + device.getAddress());
- entryValues[i] = device.getAddress();
- entries[i] = device.getName();
- i++;
- }
- prefDevices.setEntryValues(entryValues);
- prefDevices.setEntries(entries);
- }
-
- @Override
- protected void onDestroy() {
- super.onDestroy();
- sharedPref.unregisterOnSharedPreferenceChangeListener(this);
- }
-
- private void displayAboutDialog(){
- View messageView = getLayoutInflater().inflate(R.layout.about, null, false);
- // we need this to enable html links
- TextView textView = (TextView) messageView.findViewById(R.id.about_license);
- textView.setMovementMethod(LinkMovementMethod.getInstance());
- // When linking text, force to always use default color. This works
- // around a pressed color state bug.
- int defaultColor = textView.getTextColors().getDefaultColor();
- textView.setTextColor(defaultColor);
- textView = (TextView) messageView.findViewById(R.id.about_sources);
- textView.setTextColor(defaultColor);
-
- AlertDialog.Builder builder = new AlertDialog.Builder(this);
- builder.setTitle(R.string.about_title);
- builder.setIcon(R.drawable.gplv3_icon);
- builder.setView(messageView);
- builder.show();
- }
-
- @Override
- public boolean onPreferenceChange(Preference preference, Object newValue) {
- // TODO Auto-generated method stub
- return false;
- }
-
- @Override
- public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
- if (BluetoothGpsProviderService.PREF_START_GPS_PROVIDER.equals(key)){
- boolean val = false;
- if (val = sharedPreferences.getBoolean(key, false)){
- startService(new Intent(BluetoothGpsProviderService.ACTION_START_GPS_PROVIDER));
- } else {
- startService(new Intent(BluetoothGpsProviderService.ACTION_STOP_GPS_PROVIDER));
- }
- CheckBoxPreference pref = (CheckBoxPreference)findPreference(key);
- if (pref.isChecked() != val){
- pref.setChecked(val);
- }
- } else if (BluetoothGpsProviderService.PREF_TRACK_RECORDING.equals(key)){
- boolean val = false;
- if (val = sharedPreferences.getBoolean(key, false)){
- startService(new Intent(BluetoothGpsProviderService.ACTION_START_TRACK_RECORDING));
- } else {
- startService(new Intent(BluetoothGpsProviderService.ACTION_STOP_TRACK_RECORDING));
- }
- CheckBoxPreference pref = (CheckBoxPreference)findPreference(key);
- if (pref.isChecked() != val){
- pref.setChecked(val);
- }
- } else if (BluetoothGpsProviderService.PREF_BLUETOOTH_DEVICE.equals(key)){
- updateDevicePreferenceSummary();
- }
- }
-} \ No newline at end of file
+/*
+ * Copyright (C) 2010 Herbert von Broeuschmeul
+ * Copyright (C) 2010 BluetoothGPS4Droid Project
+ *
+ * This file is part of BluetoothGPS4Droid.
+ *
+ * BluetoothGPS4Droid is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * BluetoothGPS4Droid is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with BluetoothGPS4Droid. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package org.broeuschmeul.android.gps.bluetooth.provider;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import android.app.AlertDialog;
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothDevice;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
+import android.os.Bundle;
+import android.preference.CheckBoxPreference;
+import android.preference.ListPreference;
+import android.preference.Preference;
+import android.preference.PreferenceActivity;
+import android.preference.PreferenceManager;
+import android.preference.Preference.OnPreferenceChangeListener;
+import android.text.method.LinkMovementMethod;
+import android.util.Log;
+import android.view.View;
+import android.widget.TextView;
+
+/**
+ * A PreferenceActivity Class used to configure, start and stop the NMEA tracker service.
+ *
+ * @author Herbert von Broeuschmeul
+ *
+ */
+public class BluetoothGpsActivity extends PreferenceActivity implements OnPreferenceChangeListener, OnSharedPreferenceChangeListener {
+
+ private static final String LOG_TAG = "BlueGPS";
+// private static final String LOG_TAG = BluetoothGpsActivity.class.getSimpleName();
+
+ private SharedPreferences sharedPref ;
+ private BluetoothAdapter bluetoothAdapter = null;
+
+ /** Called when the activity is first created. */
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ addPreferencesFromResource(R.xml.pref);
+ sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
+ sharedPref.registerOnSharedPreferenceChangeListener(this);
+ bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
+ Preference pref = findPreference(BluetoothGpsProviderService.PREF_ABOUT);
+ pref.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
+ @Override
+ public boolean onPreferenceClick(Preference preference) {
+ BluetoothGpsActivity.this.displayAboutDialog();
+ return true;
+ }
+ });
+ }
+
+ /* (non-Javadoc)
+ * @see android.app.Activity#onResume()
+ */
+ @Override
+ protected void onResume() {
+ this.updateDevicePreferenceList();
+ super.onResume();
+ }
+
+ private void updateDevicePreferenceSummary(){
+ // update bluetooth device summary
+ String deviceName = "";
+ ListPreference prefDevices = (ListPreference)findPreference(BluetoothGpsProviderService.PREF_BLUETOOTH_DEVICE);
+ String deviceAddress = sharedPref.getString(BluetoothGpsProviderService.PREF_BLUETOOTH_DEVICE, null);
+ if (BluetoothAdapter.checkBluetoothAddress(deviceAddress)){
+ deviceName = bluetoothAdapter.getRemoteDevice(deviceAddress).getName();
+ }
+ prefDevices.setSummary(getString(R.string.pref_bluetooth_device_summary, deviceName));
+ }
+
+ private void updateDevicePreferenceList(){
+ // update bluetooth device summary
+ updateDevicePreferenceSummary();
+ // update bluetooth device list
+ ListPreference prefDevices = (ListPreference)findPreference(BluetoothGpsProviderService.PREF_BLUETOOTH_DEVICE);
+ Set<BluetoothDevice> pairedDevices = new HashSet<BluetoothDevice>();
+ if (bluetoothAdapter != null){
+ pairedDevices = bluetoothAdapter.getBondedDevices();
+ }
+ String[] entryValues = new String[pairedDevices.size()];
+ String[] entries = new String[pairedDevices.size()];
+ int i = 0;
+ // Loop through paired devices
+ for (BluetoothDevice device : pairedDevices) {
+ // Add the name and address to the ListPreference enties and entyValues
+ Log.v(LOG_TAG, "device: "+device.getName() + " -- " + device.getAddress());
+ entryValues[i] = device.getAddress();
+ entries[i] = device.getName();
+ i++;
+ }
+ prefDevices.setEntryValues(entryValues);
+ prefDevices.setEntries(entries);
+ Preference pref = (Preference)findPreference(BluetoothGpsProviderService.PREF_TRACK_RECORDING);
+ pref.setEnabled(sharedPref.getBoolean(BluetoothGpsProviderService.PREF_START_GPS_PROVIDER, false));
+ pref = (Preference)findPreference(BluetoothGpsProviderService.PREF_MOCK_GPS_NAME);
+ String mockProvider = sharedPref.getString(BluetoothGpsProviderService.PREF_MOCK_GPS_NAME, getString(R.string.defaultMockGpsName));
+ pref.setSummary(getString(R.string.pref_mock_gps_name_summary,mockProvider));
+ pref = (Preference)findPreference(BluetoothGpsProviderService.PREF_CONNECTION_RETRIES);
+ String maxConnRetries = sharedPref.getString(BluetoothGpsProviderService.PREF_CONNECTION_RETRIES, getString(R.string.defaultConnectionRetries));
+ pref.setSummary(getString(R.string.pref_connection_retries_summary,maxConnRetries));
+ pref = (Preference)findPreference(BluetoothGpsProviderService.PREF_GPS_LOCATION_PROVIDER);
+ if (sharedPref.getBoolean(BluetoothGpsProviderService.PREF_REPLACE_STD_GPS, true)){
+ String s = getString(R.string.pref_gps_location_provider_summary);
+ pref.setSummary(s);
+ Log.v(LOG_TAG, "loc. provider: "+s);
+ Log.v(LOG_TAG, "loc. provider: "+pref.getSummary());
+ } else {
+ String s = getString(R.string.pref_mock_gps_name_summary, mockProvider);
+ pref.setSummary(s);
+ Log.v(LOG_TAG, "loc. provider: "+s);
+ Log.v(LOG_TAG, "loc. provider: "+pref.getSummary());
+ }
+ this.onContentChanged();
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ sharedPref.unregisterOnSharedPreferenceChangeListener(this);
+ }
+
+ private void displayAboutDialog(){
+ View messageView = getLayoutInflater().inflate(R.layout.about, null, false);
+ // we need this to enable html links
+ TextView textView = (TextView) messageView.findViewById(R.id.about_license);
+ textView.setMovementMethod(LinkMovementMethod.getInstance());
+ // When linking text, force to always use default color. This works
+ // around a pressed color state bug.
+ int defaultColor = textView.getTextColors().getDefaultColor();
+ textView.setTextColor(defaultColor);
+ textView = (TextView) messageView.findViewById(R.id.about_sources);
+ textView.setTextColor(defaultColor);
+
+ AlertDialog.Builder builder = new AlertDialog.Builder(this);
+ builder.setTitle(R.string.about_title);
+ builder.setIcon(R.drawable.gplv3_icon);
+ builder.setView(messageView);
+ builder.show();
+ }
+
+ @Override
+ public boolean onPreferenceChange(Preference preference, Object newValue) {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ @Override
+ public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
+ if (BluetoothGpsProviderService.PREF_START_GPS_PROVIDER.equals(key)){
+ boolean val = sharedPreferences.getBoolean(key, false);
+ CheckBoxPreference pref = (CheckBoxPreference)findPreference(key);
+ if (pref.isChecked() != val){
+ pref.setChecked(val);
+ } else if (val){
+ startService(new Intent(BluetoothGpsProviderService.ACTION_START_GPS_PROVIDER));
+ } else {
+ startService(new Intent(BluetoothGpsProviderService.ACTION_STOP_GPS_PROVIDER));
+ }
+ } else if (BluetoothGpsProviderService.PREF_TRACK_RECORDING.equals(key)){
+ boolean val = sharedPreferences.getBoolean(key, false);
+ CheckBoxPreference pref = (CheckBoxPreference)findPreference(key);
+ if (pref.isChecked() != val){
+ pref.setChecked(val);
+ } else if (val){
+ startService(new Intent(BluetoothGpsProviderService.ACTION_START_TRACK_RECORDING));
+ } else {
+ startService(new Intent(BluetoothGpsProviderService.ACTION_STOP_TRACK_RECORDING));
+ }
+ } else if (BluetoothGpsProviderService.PREF_BLUETOOTH_DEVICE.equals(key)){
+ updateDevicePreferenceSummary();
+ }
+ this.updateDevicePreferenceList();
+ }
+}
diff --git a/src/org/broeuschmeul/android/gps/bluetooth/provider/BluetoothGpsProviderService.java b/src/org/broeuschmeul/android/gps/bluetooth/provider/BluetoothGpsProviderService.java
index 4f322c0..41ec34e 100644
--- a/src/org/broeuschmeul/android/gps/bluetooth/provider/BluetoothGpsProviderService.java
+++ b/src/org/broeuschmeul/android/gps/bluetooth/provider/BluetoothGpsProviderService.java
@@ -35,7 +35,6 @@ import android.app.Notification;
import android.app.PendingIntent;
import android.app.Service;
import android.bluetooth.BluetoothAdapter;
-import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.location.Location;
@@ -56,12 +55,16 @@ import android.widget.Toast;
*
*/
public class BluetoothGpsProviderService extends Service implements NmeaListener, LocationListener {
-
+
public static final String ACTION_START_TRACK_RECORDING = "org.broeuschmeul.android.gps.bluetooth.tracker.nmea.intent.action.START_TRACK_RECORDING";
public static final String ACTION_STOP_TRACK_RECORDING = "org.broeuschmeul.android.gps.bluetooth.tracker.nmea.intent.action.STOP_TRACK_RECORDING";
public static final String ACTION_START_GPS_PROVIDER = "org.broeuschmeul.android.gps.bluetooth.provider.nmea.intent.action.START_GPS_PROVIDER";
public static final String ACTION_STOP_GPS_PROVIDER = "org.broeuschmeul.android.gps.bluetooth.provider.nmea.intent.action.STOP_GPS_PROVIDER";
public static final String PREF_START_GPS_PROVIDER = "startGps";
+ public static final String PREF_GPS_LOCATION_PROVIDER = "gpsLocationProviderKey";
+ public static final String PREF_REPLACE_STD_GPS = "replaceStdtGps";
+ public static final String PREF_MOCK_GPS_NAME = "mockGpsName";
+ public static final String PREF_CONNECTION_RETRIES = "connectionRetries";
public static final String PREF_TRACK_RECORDING = "trackRecording";
public static final String PREF_TRACK_FILE_DIR = "trackFileDirectory";
public static final String PREF_TRACK_FILE_PREFIX = "trackFilePrefix";
@@ -71,16 +74,16 @@ public class BluetoothGpsProviderService extends Service implements NmeaListener
private static final String LOG_TAG = "BlueGPS";
// private static final String LOG_TAG = BluetoothGpsProviderService.class.getSimpleName();
- private BlueetoothGpsManager gpsManager = null;
+ private BlueetoothGpsManager gpsManager = null;
private PrintWriter writer;
private File trackFile;
private boolean preludeWritten = false;
private Toast toast ;
-
+
@Override
public void onCreate() {
super.onCreate();
- toast = Toast.makeText(getApplicationContext(), "NMEA track recording... on", Toast.LENGTH_SHORT);
+ toast = Toast.makeText(getApplicationContext(), "NMEA track recording... on", Toast.LENGTH_SHORT);
}
@Override
@@ -89,37 +92,36 @@ public class BluetoothGpsProviderService extends Service implements NmeaListener
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
SharedPreferences.Editor edit = sharedPreferences.edit();
String deviceAddress = sharedPreferences.getString(PREF_BLUETOOTH_DEVICE, null);
+ int maxConRetries = Integer.parseInt(sharedPreferences.getString(PREF_CONNECTION_RETRIES, this.getString(R.string.defaultConnectionRetries)));
if (Config.LOGD){
Log.d(LOG_TAG, "prefs device addr: "+deviceAddress);
}
if (ACTION_START_GPS_PROVIDER.equals(intent.getAction())){
if (gpsManager == null){
if (BluetoothAdapter.checkBluetoothAddress(deviceAddress)){
- gpsManager = new BlueetoothGpsManager(this, deviceAddress);
- gpsManager.enable();
- if (gpsManager.isEnabled()){
- gpsManager.enableMockLocationProvider(LocationManager.GPS_PROVIDER);
- if (! sharedPreferences.getBoolean(PREF_START_GPS_PROVIDER, false)){
- edit.putBoolean(PREF_START_GPS_PROVIDER,true);
- edit.commit();
- }
+ String mockProvider = LocationManager.GPS_PROVIDER;
+ if (! sharedPreferences.getBoolean(PREF_REPLACE_STD_GPS, true)){
+ mockProvider = sharedPreferences.getString(PREF_MOCK_GPS_NAME, getString(R.string.defaultMockGpsName));
+ }
+ gpsManager = new BlueetoothGpsManager(this, deviceAddress, maxConRetries);
+ boolean enabled = gpsManager.enable();
+ if (sharedPreferences.getBoolean(PREF_START_GPS_PROVIDER, false) != enabled){
+ edit.putBoolean(PREF_START_GPS_PROVIDER,enabled);
+ edit.commit();
+ }
+ if (enabled) {
+ gpsManager.enableMockLocationProvider(mockProvider);
Notification notification = new Notification(R.drawable.icon, this.getString(R.string.foreground_gps_provider_started_notification), System.currentTimeMillis());
Intent myIntent = new Intent(this, BluetoothGpsActivity.class);
PendingIntent myPendingIntent = PendingIntent.getActivity(this, 0, myIntent, PendingIntent.FLAG_CANCEL_CURRENT);
notification.setLatestEventInfo(getApplicationContext(), this.getString(R.string.foreground_service_started_notification_title), this.getString(R.string.foreground_gps_provider_started_notification), myPendingIntent);
startForeground(R.string.foreground_gps_provider_started_notification, notification);
toast.setText(this.getString(R.string.msg_gps_provider_started));
- toast.show();
+ toast.show();
} else {
stopSelf();
}
} else {
-// if (! sharedPreferences.getBoolean(PREF_START_GPS_PROVIDER, true)){
-// edit.putBoolean(PREF_START_GPS_PROVIDER,false);
-// edit.commit();
-// }
-// toast.setText(this.getString(R.string.msg_invalid_device));
-// toast.show();
stopSelf();
}
} else {
@@ -143,8 +145,6 @@ public class BluetoothGpsProviderService extends Service implements NmeaListener
edit.putBoolean(PREF_TRACK_RECORDING,false);
edit.commit();
}
-// toast.setText(this.getString(R.string.msg_device_not_started));
-// toast.show();
}
} else {
toast.setText(this.getString(R.string.msg_nmea_recording_already_started));
@@ -185,7 +185,7 @@ public class BluetoothGpsProviderService extends Service implements NmeaListener
gpsManager = null;
if (manager != null){
if (manager.getDisableReason() != 0){
- toast.setText(manager.getDisableReason());
+ toast.setText(getString(R.string.msg_gps_provider_stopped_by_problem, getString(manager.getDisableReason())));
toast.show();
} else {
toast.setText(R.string.msg_gps_provider_stopped);
@@ -208,7 +208,7 @@ public class BluetoothGpsProviderService extends Service implements NmeaListener
}
super.onDestroy();
}
-
+
private void beginTrack(){
SimpleDateFormat fmt = new SimpleDateFormat("_yyyy-MM-dd_HH-mm-ss'.nmea'");
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
@@ -227,10 +227,6 @@ public class BluetoothGpsProviderService extends Service implements NmeaListener
Log.e(LOG_TAG, "Error while writing the prelude of the NMEA file: "+trackFile.getAbsolutePath(), e);
// there was an error while writing the prelude of the NMEA file, stopping the service...
stopSelf();
-// } catch (SecurityException e) {
-// Log.e(BluetoothGpsProviderService.class.getName(), "Error while writing the prelude of the NMEA file: "+trackFile.getAbsolutePath(), e);
-// // there was an error while writing the prelude of the NMEA file, stopping the service...
-// stopSelf();
}
}
private void endTrack(){
diff --git a/src/org/broeuschmeul/android/gps/nmea/util/NmeaParser.java b/src/org/broeuschmeul/android/gps/nmea/util/NmeaParser.java
index d19dbde..21df4ce 100644
--- a/src/org/broeuschmeul/android/gps/nmea/util/NmeaParser.java
+++ b/src/org/broeuschmeul/android/gps/nmea/util/NmeaParser.java
@@ -49,20 +49,22 @@ public class NmeaParser {
private boolean mockGpsAutoEnabled = false;
private boolean mockGpsEnabled = false;
private String mockLocationProvider = null;
-
+
+ private int mockStatus = LocationProvider.OUT_OF_SERVICE;
+
private Location fix = null;
-
+
public NmeaParser(){
this(5f);
}
public NmeaParser(float precision){
this.precision = precision;
}
-
+
public void setLocationManager(LocationManager lm){
this.lm = lm;
}
-
+
public void enableMockLocationProvider(String gpsName){
try {
LocationProvider prov;
@@ -98,7 +100,7 @@ public class NmeaParser {
disableMockLocationProvider();
}
}
-
+
public void disableMockLocationProvider(){
try {
LocationProvider prov;
@@ -137,6 +139,7 @@ public class NmeaParser {
mockLocationProvider = null;
mockGpsEnabled = false;
mockGpsAutoEnabled = false;
+ mockStatus = LocationProvider.OUT_OF_SERVICE;
}
}
@@ -146,14 +149,18 @@ public class NmeaParser {
public boolean isMockGpsEnabled() {
return mockGpsEnabled;
}
-
+
+ public void setMockLocationProviderOutOfService(){
+ notifyStatusChanged(LocationProvider.OUT_OF_SERVICE, null, System.currentTimeMillis());
+ }
+
/**
* @return the mockLocationProvider
*/
public String getMockLocationProvider() {
return mockLocationProvider;
}
-
+
private void notifyFix(Location fix) throws SecurityException {
fixTime = null;
hasGGA = false;
@@ -167,7 +174,24 @@ public class NmeaParser {
this.fix = null;
}
}
-
+
+ private void notifyStatusChanged(int status, Bundle extras, long updateTime){
+ fixTime = null;
+ hasGGA = false;
+ hasRMC=false;
+ if (this.mockStatus != status){
+ Log.d(LOG_TAG, "New mockStatus: "+System.currentTimeMillis()+" "+status);
+ if (lm != null && mockGpsEnabled){
+ lm.setTestProviderStatus(mockLocationProvider, status, extras, updateTime);
+ // lm.setTestProviderStatus(mockLocationProvider, status, extras, SystemClock.elapsedRealtime());
+ // lm.setTestProviderStatus(mockLocationProvider, status, extras, 50);
+ Log.v(LOG_TAG, "New mockStatus notified to Location Manager: " + status + " "+mockLocationProvider);
+ }
+ this.fix = null;
+ this.mockStatus = status;
+ }
+ }
+
// parse NMEA Sentence
public String parseNmeaSentence(String gpsSentence) throws SecurityException {
String nmeaSentence = null;
@@ -241,6 +265,10 @@ public class NmeaParser {
// time in seconds since last DGPS update
// DGPS station ID number
if (quality != null && !quality.equals("") && !quality.equals("0") ){
+ if (this.mockStatus != LocationProvider.AVAILABLE){
+ long updateTime = parseNmeaTime(time);
+ notifyStatusChanged(LocationProvider.AVAILABLE, null, updateTime);
+ }
if (! time.equals(fixTime)){
notifyFix(fix);
fix = new Location(mockLocationProvider);
@@ -271,7 +299,12 @@ public class NmeaParser {
if (hasGGA && hasRMC){
notifyFix(fix);
}
- }
+ } else if(quality.equals("0")){
+ if (this.mockStatus != LocationProvider.TEMPORARILY_UNAVAILABLE){
+ long updateTime = parseNmeaTime(time);
+ notifyStatusChanged(LocationProvider.TEMPORARILY_UNAVAILABLE, null, updateTime);
+ }
+ }
} else if (command.equals("GPRMC")){
/* $GPRMC,123519,A,4807.038,N,01131.000,E,022.4,084.4,230394,003.1,W*6A
@@ -312,6 +345,10 @@ public class NmeaParser {
// for NMEA 0183 version 3.00 active the Mode indicator field is added
// Mode indicator, (A=autonomous, D=differential, E=Estimated, N=not valid, S=Simulator )
if (status != null && !status.equals("") && status.equals("A") ){
+ if (this.mockStatus != LocationProvider.AVAILABLE){
+ long updateTime = parseNmeaTime(time);
+ notifyStatusChanged(LocationProvider.AVAILABLE, null, updateTime);
+ }
if (! time.equals(fixTime)){
notifyFix(fix);
fix = new Location(mockLocationProvider);
@@ -337,6 +374,11 @@ public class NmeaParser {
if (hasGGA && hasRMC){
notifyFix(fix);
}
+ } else if(status.equals("V")){
+ if (this.mockStatus != LocationProvider.TEMPORARILY_UNAVAILABLE){
+ long updateTime = parseNmeaTime(time);
+ notifyStatusChanged(LocationProvider.TEMPORARILY_UNAVAILABLE, null, updateTime);
+ }
}
} else if (command.equals("GPGSA")){
/* $GPGSA,A,3,04,05,,09,12,,,24,,,,,2.5,1.3,2.1*39
diff --git a/version.txt b/version.txt
index b6db377..767abbf 100644
--- a/version.txt
+++ b/version.txt
@@ -1,10 +1,20 @@
-BlueGps4Droid 1.0.1
+BlueGps4Droid 1.1.2
* Add verifications: if bluetooth or mock locations are not enabled, the service is not started.
* Add alert messages to explain why the service cannot be started if bluetooth or mock locations are not enabled
* If device doesn't have an internal GPS, the bluetooth GPS provider will be enabled automatically
+
+BlueGps4Droid 1.1.1
+ * Bug fix (Ticket #4: Connection service is not properly closed https://sourceforge.net/p/bluegps4droid/tickets/4/).
+ * Add notifications when the connection with the GPS fails and when the connection service is closed because of two many connection retry.
+ * Add settings to choose the number of connection retries before exiting.
+BlueGps4Droid 1.1 (does not work properly because of bug #4. Use either version 1.0 or 1.1.1 !)
+ * Reconnect automatically when the connection with the GPS is lost (5 attempts in 5 minutes)
+ * Replace Android default internal GPS or use a new location provider
+ * Send status notifications when GPS loses fix or is disconnected.
+
BlueGps4Droid 1.0
* Connect to bluetooth GPS (NMEA) and replace the internal GPS of an Android device.
* Record GPS tracks in NMEA files
* Compatible with Android version 2.0 and above
- * English and French translations \ No newline at end of file
+ * English and French translations \ No newline at end of file