aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/org/broeuschmeul/android/gps/bluetooth/provider/BlueetoothGpsManager.java362
-rw-r--r--src/org/broeuschmeul/android/gps/bluetooth/provider/BluetoothGpsActivity.java120
-rw-r--r--src/org/broeuschmeul/android/gps/bluetooth/provider/BluetoothGpsProviderService.java74
-rw-r--r--src/org/broeuschmeul/android/gps/nmea/util/NmeaParser.java69
4 files changed, 337 insertions, 288 deletions
diff --git a/src/org/broeuschmeul/android/gps/bluetooth/provider/BlueetoothGpsManager.java b/src/org/broeuschmeul/android/gps/bluetooth/provider/BlueetoothGpsManager.java
index e114b45..92c5c3e 100644
--- a/src/org/broeuschmeul/android/gps/bluetooth/provider/BlueetoothGpsManager.java
+++ b/src/org/broeuschmeul/android/gps/bluetooth/provider/BlueetoothGpsManager.java
@@ -24,18 +24,20 @@ import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
-import java.io.OutputStream;
-import java.io.PrintStream;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
-import java.util.Locale;
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;
@@ -43,124 +45,119 @@ import android.bluetooth.BluetoothSocket;
import android.content.Context;
import android.content.SharedPreferences;
import android.location.Criteria;
+import android.content.Intent;
import android.location.LocationManager;
-import android.location.LocationProvider;
import android.location.GpsStatus.NmeaListener;
import android.preference.PreferenceManager;
import android.provider.Settings;
+import android.os.SystemClock;
import android.util.Log;
-import android.util.PrintStreamPrinter;
public class BlueetoothGpsManager {
- private class ConnectedThread extends Thread {
- private final InputStream in;
- private final OutputStream out;
- private final PrintStream out2;
-
- public ConnectedThread(BluetoothSocket socket) {
- InputStream tmpIn = null;
- OutputStream tmpOut = null;
- PrintStream tmpOut2 = null;
- try {
- tmpIn = socket.getInputStream();
- tmpOut = socket.getOutputStream();
- if (tmpOut != null){
- tmpOut2 = new PrintStream(tmpOut, false, "US-ASCII");
- }
- } catch (IOException e) {
- Log.e("BT test", "error while getting socket streams", e);
- }
- in = tmpIn;
- out = tmpOut;
- out2 = tmpOut2;
- }
+ 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("BT test", "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.e("BT test", "data: "+System.currentTimeMillis()+" "+s + "xxx");
notifyNmeaSentence(s+"\r\n");
-// parser.parseNmeaSentence(s);
-// // writer.println(s);
-// addNMEAString(s);
-// nmeaSentenceHandler.ob
+ lastRead = SystemClock.uptimeMillis();
+ } else {
+ Log.e("BT test", "data: not ready "+System.currentTimeMillis());
+ SystemClock.sleep(500);
}
- } catch (IOException e) {
- Log.e("BT test", "error while getting data", e);
- } finally {
- disable();
+ now = SystemClock.uptimeMillis();
}
- }
-
- /**
- * Write to the connected OutStream.
- * @param buffer The bytes to write
- */
- public void write(byte[] buffer) {
- try {
- out.write(buffer);
- } catch (IOException e) {
-// Log.e(TAG, "Exception during write", e);
- }
- }
- /**
- * Write to the connected OutStream.
- * @param buffer The data to write
- */
- public void write(String buffer) {
- try {
- out2.print(buffer);
- out.flush();
- } catch (IOException e) {
-// Log.e(TAG, "Exception during write", e);
- }
- }
+ } catch (IOException e) {
+ Log.e("BT test", "error while getting data", e);
+ setMockLocationProviderOutOfService();
+ } finally {
+ disableIfNeeded();
+ }
}
+ }
private Service callingService;
- private BluetoothDevice gpsDevice;
private BluetoothSocket gpsSocket;
private String gpsDeviceAddress;
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 boolean mockGpsEnabled = true;
-// private String mockLocationProvider = LocationManager.GPS_PROVIDER;
- private ConnectedThread connectedThread;
-
-// private Handler nmeaSentenceHandler = new Handler();
+ private ConnectedGps connectedGps;
+ 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);
}
-
/**
* @return true if the bluetooth GPS is enabled
*/
- public boolean isEnabled() {
+ public synchronized boolean isEnabled() {
return enabled;
}
- public synchronized void enable() {
+ public synchronized boolean enable() {
+ notificationManager.cancel(R.string.service_closed_because_connection_problem_notification_title);
if (! enabled){
- this.enabled = true;
final BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (bluetoothAdapter == null) {
// Device does not support Bluetooth
Log.e("BT test", "Device does not support Bluetooth");
} else if (!bluetoothAdapter.isEnabled()) {
-// Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
-// startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
+ // Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
+ // startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
Log.e("BT test", "Bluetooth is not enabled");
} else if (Settings.Secure.getInt(callingService.getContentResolver(),Settings.Secure.ALLOW_MOCK_LOCATION, 0)==0){
Log.e("BT test", "Mock location provider OFF");
@@ -169,71 +166,97 @@ public class BlueetoothGpsManager {
) {
Log.e("BT test", "GPS location provider OFF");
} else {
- BluetoothDevice gpsDevice = bluetoothAdapter.getRemoteDevice(gpsDeviceAddress);
- if (gpsDevice == null){
- Log.e("BT test", "GPS device not found");
- } else {
- Log.e("BT test", "current device: "+gpsDevice.getName() + " -- " + gpsDevice.getAddress());
- try {
- gpsSocket = gpsDevice.createRfcommSocketToServiceRecord(UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"));
- } catch (IOException e) {
- Log.e("BT test", "Error during connection", e);
- }
- if (gpsSocket == null){
- Log.e("BT test", "Error while establishing connection: no socket");
- } else {
-//// mockGpsEnabled = locationManager.isProviderEnabled(mockLocationProvider);
-// LocationProvider prov = locationManager.getProvider(mockLocationProvider);
-// Log.e("BT test", "Mock power: "+prov.getPowerRequirement()+" "+prov.getAccuracy()+" "+locationManager.isProviderEnabled(mockLocationProvider));
-// locationManager.addTestProvider(mockLocationProvider, false, true,false, false,
-// true, true, true, Criteria.POWER_HIGH, Criteria.ACCURACY_FINE);
-//// locationManager.setTestProviderEnabled(mockLocationProvider, true);
-// prov = locationManager.getProvider(mockLocationProvider);
-// Log.e("BT test", "Mock power: "+prov.getPowerRequirement()+" "+prov.getAccuracy()+" "+locationManager.isProviderEnabled(mockLocationProvider));
-
- Runnable connectThread = new Runnable() {
+ final BluetoothDevice gpsDevice = bluetoothAdapter.getRemoteDevice(gpsDeviceAddress);
+ if (gpsDevice == null){
+ Log.e("BT test", "GPS device not found");
+ } else {
+ Log.e("BT test", "current device: "+gpsDevice.getName() + " -- " + gpsDevice.getAddress());
+ try {
+ gpsSocket = gpsDevice.createRfcommSocketToServiceRecord(UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"));
+ } catch (IOException e) {
+ Log.e("BT test", "Error during connection", e);
+ }
+ if (gpsSocket == null){
+ Log.e("BT test", "Error while establishing connection: no socket");
+ } 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
- gpsSocket.connect();
- connectedThread = new ConnectedThread(gpsSocket);
- connectedThread.start();
-// String command = callingService.getString(R.string.sirf_gll_on);
-// String sentence = String.format((Locale)null,"$%s*%X\r\n", command, parser.computeChecksum(command));
-// String command1 = callingService.getString(R.string.sirf_gll_off);
-// String sentence1 = String.format((Locale)null,"$%s*%X\r\n", command1, parser.computeChecksum(command1));
-// String command2 = callingService.getString(R.string.sirf_vtg_off);
-// String sentence2 = String.format((Locale)null,"$%s*%X\r\n", command2, parser.computeChecksum(command2));
-// try {
-// Thread.sleep(5000);
-// } catch (InterruptedException e) {
-// // TODO Auto-generated catch block
-// e.printStackTrace();
-// }
-// Log.e("BT test", "sending NMEA sentence: "+"$PSRF105,1*3E\r\n");
-// connectedThread.write("$PSRF105,1*3E\r\n");
-// Log.e("BT test", "sending NMEA sentence: "+sentence1);
-// connectedThread.write(sentence1);
-// Log.e("BT test", "sending NMEA sentence: "+sentence2);
-// connectedThread.write(sentence2);
- } catch (IOException connectException) {
- // Unable to connect; close everything and get out
- Log.e("BT test", "error while connecting to socket", connectException);
- disable();
-// callingService.stopSelf();
- }
+ try {
+ connected = false;
+ Log.e("BT test", "current device: "+gpsDevice.getName() + " -- " + gpsDevice.getAddress());
+ if ((bluetoothAdapter.isEnabled()) && (nbRetriesRemaining > 0 )){
+ try {
+ if (gpsSocket != null){
+ Log.e("BT test", "trying to close old socket");
+ gpsSocket.close();
+ }
+ } catch (IOException e) {
+ Log.e("BT test", "Error during disconnection", e);
+ }
+ try {
+ gpsSocket = gpsDevice.createRfcommSocketToServiceRecord(UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"));
+ } catch (IOException e) {
+ Log.e("BT test", "Error during connection", e);
+ }
+ if (gpsSocket == null){
+ Log.e("BT test", "Error while establishing connection: no socket");
+ } 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
+ gpsSocket.connect();
+ // connection obtained so reset the number of connection try
+ connected = true;
+ nbRetriesRemaining = 1+maxConnectionRetries ;
+ notificationManager.cancel(R.string.connection_problem_notification_title);
+ connectedGps = new ConnectedGps(gpsSocket);
+ connectionAndReadingPool.execute(connectedGps);
+ }
+ }
+ } catch (IOException connectException) {
+ // Unable to connect
+ Log.e("BT test", "error while connecting to socket", connectException);
+ } finally {
+ nbRetriesRemaining--;
+ if (! connected) {
+ disableIfNeeded();
+ }
+ }
}
};
+ this.enabled = true;
notificationPool = Executors.newSingleThreadExecutor();
- notificationPool.execute(connectThread);
-// enableMockLocationProvider(LocationManager.GPS_PROVIDER);
- }
- }
- }
+ connectionAndReadingPool = Executors.newSingleThreadScheduledExecutor();
+ connectionAndReadingPool.scheduleWithFixedDelay(connectThread, 5000, 60000, TimeUnit.MILLISECONDS);
+ }
+ }
+ }
+ }
+ return this.enabled;
+ }
+
+ private synchronized void disableIfNeeded(){
+ if (enabled){
+ if (nbRetriesRemaining > 0){
+ // Unable to connect
+ Log.e("BT test", "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();
+ }
}
}
@@ -241,38 +264,27 @@ public class BlueetoothGpsManager {
if (enabled){
enabled = false;
if (gpsSocket != null){
- try {
- gpsSocket.close();
- } catch (IOException closeException) {
- Log.e("BT test", "error while closing socket", closeException);
- }
+ try {
+ gpsSocket.close();
+ } catch (IOException closeException) {
+ Log.e("BT test", "error while closing socket", closeException);
+ }
}
nmeaListeners.clear();
disableMockLocationProvider();
notificationPool.shutdown();
-//// locationManager.setTestProviderEnabled(mockLocationProvider, mockGpsEnabled);
-// LocationProvider prov = locationManager.getProvider(mockLocationProvider);
-// Log.e("BT test", "Mock power: "+prov.getPowerRequirement()+" "+prov.getAccuracy()+" "+locationManager.isProviderEnabled(mockLocationProvider));
-// locationManager.clearTestProviderEnabled(mockLocationProvider);
-// prov = locationManager.getProvider(mockLocationProvider);
-// Log.e("BT test", "Mock power: "+prov.getPowerRequirement()+" "+prov.getAccuracy()+" "+locationManager.isProviderEnabled(mockLocationProvider));
-// locationManager.clearTestProviderStatus(mockLocationProvider);
-// locationManager.removeTestProvider(mockLocationProvider);
-// prov = locationManager.getProvider(mockLocationProvider);
-// Log.e("BT test", "Mock power: "+prov.getPowerRequirement()+" "+prov.getAccuracy()+" "+locationManager.isProviderEnabled(mockLocationProvider));
-// Log.e("BT test", "removed mock GPS");
-
+ connectionAndReadingPool.shutdown();
+ notificationManager.cancel(R.string.connection_problem_notification_title);
callingService.stopSelf();
}
}
-
public void enableMockLocationProvider(String gpsName){
if (parser != null){
parser.enableMockLocationProvider(gpsName);
}
}
-
+
public void disableMockLocationProvider(){
if (parser != null){
parser.disableMockLocationProvider();
@@ -299,7 +311,12 @@ public class BlueetoothGpsManager {
}
return mockLocationProvider;
}
-
+
+ private void setMockLocationProviderOutOfService(){
+ if (parser != null){
+ parser.setMockLocationProviderOutOfService();
+ }
+ }
public boolean addNmeaListener(NmeaListener listener){
if (!nmeaListeners.contains(listener)){
@@ -307,25 +324,28 @@ public class BlueetoothGpsManager {
}
return true;
}
-
+
public void removeNmeaListener(NmeaListener listener){
- nmeaListeners.remove(listener);
+ nmeaListeners.remove(listener);
}
-
+
private void notifyNmeaSentence(final String nmeaSentence){
if (enabled){
- parser.parseNmeaSentence(nmeaSentence);
+ final String recognizedSentence = parser.parseNmeaSentence(nmeaSentence);
final long timestamp = System.currentTimeMillis();
- synchronized(nmeaListeners) {
- for(final NmeaListener listener : nmeaListeners){
- notificationPool.execute(new Runnable(){
- @Override
- public void run() {
- listener.onNmeaReceived(timestamp, nmeaSentence);
- }
- });
+ if (recognizedSentence != null){
+ Log.e("BT test", "NMEA : "+timestamp+" "+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 8ce8e62..e09ae34 100644
--- a/src/org/broeuschmeul/android/gps/bluetooth/provider/BluetoothGpsActivity.java
+++ b/src/org/broeuschmeul/android/gps/bluetooth/provider/BluetoothGpsActivity.java
@@ -21,8 +21,6 @@
package org.broeuschmeul.android.gps.bluetooth.provider;
import java.util.Set;
-import java.util.prefs.Preferences;
-import java.util.zip.CheckedInputStream;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
@@ -35,7 +33,6 @@ import android.preference.ListPreference;
import android.preference.Preference;
import android.preference.PreferenceActivity;
import android.preference.PreferenceManager;
-import android.preference.PreferenceScreen;
import android.preference.Preference.OnPreferenceChangeListener;
import android.util.Log;
@@ -48,18 +45,18 @@ import android.util.Log;
public class BluetoothGpsActivity extends PreferenceActivity implements OnPreferenceChangeListener, OnSharedPreferenceChangeListener {
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();
- }
- /* (non-Javadoc)
+ /** 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();
+ }
+
+ /* (non-Javadoc)
* @see android.app.Activity#onResume()
*/
@Override
@@ -69,37 +66,58 @@ public class BluetoothGpsActivity extends PreferenceActivity implements OnPrefer
}
private void updateDevicePreferenceSummary(){
- // update bluetooth device summary
+ // 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));
- }
+ 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
+ // update bluetooth device summary
updateDevicePreferenceSummary();
// update bluetooth device list
- ListPreference prefDevices = (ListPreference)findPreference(BluetoothGpsProviderService.PREF_BLUETOOTH_DEVICE);
- Set<BluetoothDevice> 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.e("BT test", "device: "+device.getName() + " -- " + device.getAddress());
- entryValues[i] = device.getAddress();
- entries[i] = device.getName();
- i++;
- }
+ ListPreference prefDevices = (ListPreference)findPreference(BluetoothGpsProviderService.PREF_BLUETOOTH_DEVICE);
+ Set<BluetoothDevice> 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.e("BT test", "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.e("BT test", "loc. provider: "+s);
+ Log.e("BT test", "loc. provider: "+pref.getSummary());
+ } else {
+ String s = getString(R.string.pref_mock_gps_name_summary, mockProvider);
+ pref.setSummary(s);
+ Log.e("BT test", "loc. provider: "+s);
+ Log.e("BT test", "loc. provider: "+pref.getSummary());
+ }
+ this.onContentChanged();
}
-
+
@Override
protected void onDestroy() {
super.onDestroy();
@@ -113,32 +131,30 @@ public class BluetoothGpsActivity extends PreferenceActivity implements OnPrefer
}
@Override
- public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
- String key) {
+ 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));
- }
+ boolean val = sharedPreferences.getBoolean(key, false);
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 if (val){
+ startService(new Intent(BluetoothGpsProviderService.ACTION_START_GPS_PROVIDER));
} else {
- startService(new Intent(BluetoothGpsProviderService.ACTION_STOP_TRACK_RECORDING));
+ 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();
}
} \ No newline at end of file
diff --git a/src/org/broeuschmeul/android/gps/bluetooth/provider/BluetoothGpsProviderService.java b/src/org/broeuschmeul/android/gps/bluetooth/provider/BluetoothGpsProviderService.java
index 0ab972b..ef2410d 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,31 +55,31 @@ 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_MIN_DISTANCE = "trackMinDistance";
- public static final String PREF_TRACK_MIN_TIME = "trackMinTime";
public static final String PREF_TRACK_FILE_DIR = "trackFileDirectory";
public static final String PREF_TRACK_FILE_PREFIX = "trackFilePrefix";
public static final String PREF_BLUETOOTH_DEVICE = "bluetoothDevice";
- private LocationManager lm;
- 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);
- lm = (LocationManager)this.getSystemService(Context.LOCATION_SERVICE);
+ toast = Toast.makeText(getApplicationContext(), "NMEA track recording... on", Toast.LENGTH_SHORT);
}
@Override
@@ -88,12 +87,9 @@ public class BluetoothGpsProviderService extends Service implements NmeaListener
// super.onStart(intent, startId);
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
SharedPreferences.Editor edit = sharedPreferences.edit();
-// long minTime = Long.parseLong(sharedPreferences.getString(PREF_TRACK_MIN_TIME, this.getString(R.string.defaultTrackMinTime)));
-// float minDistance = Float.parseFloat(sharedPreferences.getString(PREF_TRACK_MIN_DISTANCE, this.getString(R.string.defaultTrackMinDistance)));
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(BluetoothGpsProviderService.class.getName(), "prefs minTime: "+minTime);
-// Log.d(BluetoothGpsProviderService.class.getName(), "prefs minDistance: "+minDistance);
Log.d(BluetoothGpsProviderService.class.getName(), "prefs device addr: "+deviceAddress);
}
if (ACTION_START_GPS_PROVIDER.equals(intent.getAction())){
@@ -102,24 +98,24 @@ public class BluetoothGpsProviderService extends Service implements NmeaListener
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);
if (BluetoothAdapter.checkBluetoothAddress(deviceAddress)){
- gpsManager = new BlueetoothGpsManager(this, deviceAddress);
- gpsManager.enableMockLocationProvider(LocationManager.GPS_PROVIDER);
- gpsManager.enable();
- if (! sharedPreferences.getBoolean(PREF_START_GPS_PROVIDER, false)){
- edit.putBoolean(PREF_START_GPS_PROVIDER,true);
+ 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);
+ gpsManager.enableMockLocationProvider(mockProvider);
+ boolean enabled = gpsManager.enable();
+ if (sharedPreferences.getBoolean(PREF_START_GPS_PROVIDER, false) != enabled){
+ edit.putBoolean(PREF_START_GPS_PROVIDER,enabled);
edit.commit();
}
- toast.setText(this.getString(R.string.msg_gps_provider_started));
- toast.show();
+ if (enabled) {
+ startForeground(R.string.foreground_gps_provider_started_notification, notification);
+ toast.setText(this.getString(R.string.msg_gps_provider_started));
+ toast.show();
+ }
} 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 +139,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));
@@ -224,10 +218,6 @@ public class BluetoothGpsProviderService extends Service implements NmeaListener
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();
-// } 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(){
@@ -283,22 +273,4 @@ public class BluetoothGpsProviderService extends Service implements NmeaListener
public void onNmeaReceived(long timestamp, String data) {
addNMEAString(data);
}
-
-// private void startBluetoothGps(String deviceAddress){
-// Notification notification = new Notification(R.drawable.icon, this.getString(R.string.foreground_service_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_service_started_notification), myPendingIntent);
-// startForeground(R.string.foreground_service_started_notification, notification);
-// if (BluetoothAdapter.checkBluetoothAddress(deviceAddress)){
-// gpsManager = new BlueetoothGpsManager(this, deviceAddress);
-// gpsManager.enable();
-// gpsManager.enableMockLocationProvider(LocationManager.GPS_PROVIDER);
-// toast.setText(this.getString(R.string.msg_started));
-// toast.show();
-//// } else {
-//// toast.setText(this.getString(R.string.msg_invalid_device));
-//// toast.show();
-// }
-// }
}
diff --git a/src/org/broeuschmeul/android/gps/nmea/util/NmeaParser.java b/src/org/broeuschmeul/android/gps/nmea/util/NmeaParser.java
index be4e973..2f67441 100644
--- a/src/org/broeuschmeul/android/gps/nmea/util/NmeaParser.java
+++ b/src/org/broeuschmeul/android/gps/nmea/util/NmeaParser.java
@@ -45,20 +45,22 @@ public class NmeaParser {
private float precision = 10f;
private boolean mockGpsEnabled = false;
private String mockLocationProvider = null;
-
+
+ private int mockStatus = LocationProvider.OUT_OF_SERVICE;
+
private Location fix = new Location(mockLocationProvider);
-
+
public NmeaParser(){
this(5f);
}
public NmeaParser(float precision){
this.precision = precision;
}
-
+
public void setLocationManager(LocationManager lm){
this.lm = lm;
}
-
+
public void enableMockLocationProvider(String gpsName){
LocationProvider prov;
if (gpsName != null && gpsName != "" ){
@@ -73,7 +75,6 @@ public class NmeaParser {
}
lm.addTestProvider(mockLocationProvider, false, true,false, false, true, true, true, Criteria.POWER_HIGH, Criteria.ACCURACY_FINE);
if (! LocationManager.GPS_PROVIDER.equals(mockLocationProvider)){
- // mockGpsEnabled = locationManager.isProviderEnabled(mockLocationProvider);
lm.setTestProviderEnabled(mockLocationProvider, true);
}
mockGpsEnabled = true;
@@ -86,7 +87,7 @@ public class NmeaParser {
}
}
}
-
+
public void disableMockLocationProvider(){
LocationProvider prov;
if (mockLocationProvider != null && mockLocationProvider != "" && mockGpsEnabled){
@@ -96,10 +97,8 @@ public class NmeaParser {
}
mockGpsEnabled = false;
if (! LocationManager.GPS_PROVIDER.equals(mockLocationProvider)){
- // mockGpsEnabled = locationManager.isProviderEnabled(mockLocationProvider);
lm.setTestProviderEnabled(mockLocationProvider, false);
}
- // locationManager.setTestProviderEnabled(mockLocationProvider, mockGpsEnabled);
prov = lm.getProvider(mockLocationProvider);
if (prov != null){
Log.e("BT test", "Mock provider: "+prov.getName()+" "+prov.getPowerRequirement()+" "+prov.getAccuracy()+" "+lm.isProviderEnabled(mockLocationProvider));
@@ -121,6 +120,7 @@ public class NmeaParser {
}
mockLocationProvider = null;
mockGpsEnabled = false;
+ mockStatus = LocationProvider.OUT_OF_SERVICE;
}
/**
@@ -129,16 +129,19 @@ 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){
- //R.drawable.stat
fixTime = null;
hasGGA = false;
hasRMC=false;
@@ -151,13 +154,32 @@ 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.e(this.getClass().getSimpleName(), "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.e(this.getClass().getSimpleName(), "New mockStatus notified to Location Manager: " + status + " "+mockLocationProvider);
+ }
+ this.fix = null;
+ this.mockStatus = status;
+ }
+ }
+
// parse NMEA Sentence
- public void parseNmeaSentence(String gpsSentence){
+ public String parseNmeaSentence(String gpsSentence){
+ String nmeaSentence = null;
Log.e("BT test", "data: "+System.currentTimeMillis()+" "+gpsSentence);
Pattern xx = Pattern.compile("\\$([^*$]*)\\*([0-9A-F][0-9A-F])?\r\n");
Matcher m = xx.matcher(gpsSentence);
if (m.matches()){
+ nmeaSentence = m.group(0);
String sentence = m.group(1);
String checkSum = m.group(2);
Log.e("BT test", "data: "+System.currentTimeMillis()+" "+sentence+" cheksum; "+checkSum +" control: "+String.format("%X",computeChecksum(sentence)));
@@ -223,6 +245,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);
@@ -253,7 +279,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
@@ -294,6 +325,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);
@@ -319,6 +354,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
@@ -405,6 +445,7 @@ public class NmeaParser {
// Mode indicator, (A=autonomous, D=differential, E=Estimated, N=not valid, S=Simulator )
}
}
+ return nmeaSentence;
}
public double parseNmeaLatitude(String lat,String orientation){