diff --git a/src/main/java/de/dennisguse/opentracks/content/sensor/SensorState.java b/src/main/java/de/dennisguse/opentracks/content/sensor/SensorState.java
index 3ecda3685..5b7a942fb 100644
--- a/src/main/java/de/dennisguse/opentracks/content/sensor/SensorState.java
+++ b/src/main/java/de/dennisguse/opentracks/content/sensor/SensorState.java
@@ -8,6 +8,7 @@ public enum SensorState {
NONE,
CONNECTING,
CONNECTED,
+ DISCONNECTING,
DISCONNECTED;
public static String getStateAsString(SensorState state, Context c) {
@@ -18,6 +19,8 @@ public enum SensorState {
return c.getString(R.string.sensor_state_connecting);
case CONNECTED:
return c.getString(R.string.sensor_state_connected);
+ case DISCONNECTING:
+ return c.getString(R.string.sensor_state_disconnected);
case DISCONNECTED:
return c.getString(R.string.sensor_state_disconnected);
default:
diff --git a/src/main/java/de/dennisguse/opentracks/services/sensors/BluetoothConnectionManager.java b/src/main/java/de/dennisguse/opentracks/services/sensors/BluetoothConnectionManager.java
index 3f534773b..20be6bc1d 100644
--- a/src/main/java/de/dennisguse/opentracks/services/sensors/BluetoothConnectionManager.java
+++ b/src/main/java/de/dennisguse/opentracks/services/sensors/BluetoothConnectionManager.java
@@ -58,22 +58,37 @@ public class BluetoothConnectionManager {
private SensorState sensorState;
+ private BluetoothGatt bluetoothGatt;
+ private BluetoothDevice bluetoothDevice;
+
private BluetoothGattCallback connectCallback = new BluetoothGattCallback() {
@Override
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
- if (newState == BluetoothProfile.STATE_CONNECTED) {
- gatt.discoverServices();
- setState(SensorState.CONNECTED);
+ switch (newState) {
+ case BluetoothProfile.STATE_CONNECTING:
+ Log.d(TAG, "Connecting to sensor: " + gatt.getDevice());
+ setState(SensorState.CONNECTING);
+ case BluetoothProfile.STATE_CONNECTED:
+ Log.d(TAG, "Connected to sensor: " + gatt.getDevice());
+ setState(SensorState.CONNECTED);
- //Inform about status change
- Message message = handler.obtainMessage(MESSAGE_DEVICE_NAME);
- Bundle bundle = new Bundle();
- bundle.putString(KEY_DEVICE_NAME, gatt.getDevice().getName());
- message.setData(bundle);
- handler.sendMessage(message);
- return;
+ gatt.discoverServices();
+
+ //Inform about status change
+ Message message = handler.obtainMessage(MESSAGE_DEVICE_NAME);
+ Bundle bundle = new Bundle();
+ bundle.putString(KEY_DEVICE_NAME, gatt.getDevice().getName());
+ message.setData(bundle);
+ handler.sendMessage(message);
+ break;
+ case BluetoothProfile.STATE_DISCONNECTING:
+ Log.d(TAG, "Disconnecting from sensor: " + gatt.getDevice());
+ setState(SensorState.DISCONNECTING);
+
+ case BluetoothProfile.STATE_DISCONNECTED:
+ Log.d(TAG, "Disconnected from sensor: " + gatt.getDevice());
+ setState(SensorState.DISCONNECTED);
}
- Log.d(TAG, "Could not connect to bluetooth sensor: " + gatt.getDevice());
}
@Override
@@ -104,45 +119,42 @@ public class BluetoothConnectionManager {
*
* @param handler a handler for sending messages back to the UI activity
*/
- BluetoothConnectionManager(Context context, Handler handler) {
+ BluetoothConnectionManager(@NonNull Context context, @NonNull BluetoothDevice bluetoothDevice, @NonNull Handler handler) {
this.context = context;
+ this.bluetoothDevice = bluetoothDevice;
this.handler = handler;
this.sensorState = SensorState.NONE;
}
- /**
- * Gets the sensor state.
- */
+ public synchronized void connect() {
+ if (bluetoothGatt != null) {
+ Log.w(TAG, "Already connected; ignoring.");
+ }
+
+ Log.d(TAG, "Connecting to: " + bluetoothDevice);
+
+ setState(SensorState.CONNECTING);
+ bluetoothGatt = bluetoothDevice.connectGatt(this.context, true, this.connectCallback);
+ }
+
+ public synchronized void disconnect() {
+ if (bluetoothGatt == null) {
+ Log.w(TAG, "Cannot disconnect if not connected.");
+ return;
+ }
+ bluetoothGatt.close();
+ bluetoothGatt = null;
+ }
+
+ public synchronized boolean isSameBluetoothDevice(BluetoothDevice bluetoothDevice) {
+ return this.bluetoothDevice.equals(bluetoothDevice);
+ }
+
synchronized SensorState getSensorState() {
return sensorState;
}
- /**
- * Sets the sensor state.
- *
- * @param sensorState the sensor state
- */
private synchronized void setState(SensorState sensorState) {
this.sensorState = sensorState;
}
-
- /**
- * Resets the bluetooth connection manager.
- */
- public synchronized void reset() {
- //TODO Disconnect
- setState(SensorState.NONE);
- }
-
- /**
- * Connects to a bluetooth device.
- *
- * @param bluetoothDevice the bluetooth device
- */
- public synchronized void connect(BluetoothDevice bluetoothDevice) {
- Log.d(TAG, "connect to: " + bluetoothDevice);
-
- bluetoothDevice.connectGatt(this.context, false, this.connectCallback);
- setState(SensorState.CONNECTING);
- }
}
diff --git a/src/main/java/de/dennisguse/opentracks/services/sensors/BluetoothRemoteSensorManager.java b/src/main/java/de/dennisguse/opentracks/services/sensors/BluetoothRemoteSensorManager.java
index 4052fa083..edfed6733 100644
--- a/src/main/java/de/dennisguse/opentracks/services/sensors/BluetoothRemoteSensorManager.java
+++ b/src/main/java/de/dennisguse/opentracks/services/sensors/BluetoothRemoteSensorManager.java
@@ -23,18 +23,17 @@ import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.Log;
+import android.widget.Toast;
import java.util.ArrayList;
import de.dennisguse.opentracks.R;
import de.dennisguse.opentracks.content.sensor.SensorDataSet;
-import de.dennisguse.opentracks.content.sensor.SensorState;
import de.dennisguse.opentracks.util.PreferencesUtils;
import de.dennisguse.opentracks.util.UnitConversions;
/**
* Bluetooth sensor manager.
- * TODO: Handle a BluetoothGatt.STATE_DISCONNECTED
*
* @author Sandor Dornbush
*/
@@ -46,10 +45,6 @@ public class BluetoothRemoteSensorManager extends RemoteSensorManager {
private final Context context;
- private final BluetoothConnectionManager bluetoothConnectionManager;
-
- private SensorDataSet sensorDataSet = null;
-
// Handler that gets information back from the bluetoothConnectionManager
private final Handler messageHandler = new Handler(Looper.getMainLooper()) {
@Override
@@ -57,6 +52,8 @@ public class BluetoothRemoteSensorManager extends RemoteSensorManager {
switch (message.what) {
case BluetoothConnectionManager.MESSAGE_DEVICE_NAME:
String deviceName = message.getData().getString(BluetoothConnectionManager.KEY_DEVICE_NAME);
+ String toastMessage = context.getString(R.string.settings_sensor_connected, deviceName);
+ Toast.makeText(context, toastMessage, Toast.LENGTH_LONG).show();
break;
case BluetoothConnectionManager.MESSAGE_READ:
if (!(message.obj instanceof SensorDataSet)) {
@@ -72,12 +69,14 @@ public class BluetoothRemoteSensorManager extends RemoteSensorManager {
}
};
+ private SensorDataSet sensorDataSet = null;
+ private BluetoothConnectionManager bluetoothConnectionManager;
+
/**
* @param context the context
*/
BluetoothRemoteSensorManager(Context context) {
this.context = context;
- bluetoothConnectionManager = new BluetoothConnectionManager(context, messageHandler);
}
private static BluetoothAdapter getDefaultBluetoothAdapter() {
@@ -118,12 +117,7 @@ public class BluetoothRemoteSensorManager extends RemoteSensorManager {
}
@Override
- public boolean isEnabled() {
- return bluetoothAdapter != null && bluetoothAdapter.isEnabled();
- }
-
- @Override
- protected void setUpChannel() {
+ public void startSensor() {
if (!isEnabled()) {
Log.w(TAG, "Bluetooth not enabled.");
return;
@@ -134,26 +128,37 @@ public class BluetoothRemoteSensorManager extends RemoteSensorManager {
Log.w(TAG, "No bluetooth address.");
return;
}
- Log.w(TAG, "Connecting to bluetooth address: " + address);
+ Log.i(TAG, "Connecting to bluetooth address: " + address);
BluetoothDevice device;
try {
device = bluetoothAdapter.getRemoteDevice(address);
} catch (IllegalArgumentException e) {
- Log.d(TAG, "Unable to get remote device for: " + address, e);
+ Log.w(TAG, "Unable to get remote device for: " + address, e);
+
+ String toastMessage = context.getString(R.string.sensor_not_known, address);
+ Toast.makeText(context, toastMessage, Toast.LENGTH_LONG).show();
+
return;
}
- bluetoothConnectionManager.connect(device);
+
+ stopSensor();
+
+ bluetoothConnectionManager = new BluetoothConnectionManager(context, device, messageHandler);
+ bluetoothConnectionManager.connect();
}
@Override
- protected void tearDownChannel() {
- bluetoothConnectionManager.reset();
+ public void stopSensor() {
+ if (bluetoothConnectionManager != null) {
+ bluetoothConnectionManager.disconnect();
+ bluetoothConnectionManager = null;
+ }
}
@Override
- public SensorState getSensorState() {
- return bluetoothConnectionManager.getSensorState();
+ public boolean isEnabled() {
+ return bluetoothAdapter != null && bluetoothAdapter.isEnabled();
}
@Override
diff --git a/src/main/java/de/dennisguse/opentracks/services/sensors/RemoteSensorManager.java b/src/main/java/de/dennisguse/opentracks/services/sensors/RemoteSensorManager.java
index 2ef82f91d..42358a925 100644
--- a/src/main/java/de/dennisguse/opentracks/services/sensors/RemoteSensorManager.java
+++ b/src/main/java/de/dennisguse/opentracks/services/sensors/RemoteSensorManager.java
@@ -16,13 +16,7 @@
package de.dennisguse.opentracks.services.sensors;
-import android.util.Log;
-
-import java.util.Timer;
-import java.util.TimerTask;
-
import de.dennisguse.opentracks.content.sensor.SensorDataSet;
-import de.dennisguse.opentracks.content.sensor.SensorState;
/**
* Manage the connection to a remote sensor.
@@ -32,32 +26,14 @@ import de.dennisguse.opentracks.content.sensor.SensorState;
public abstract class RemoteSensorManager {
public static final long MAX_SENSOR_DATE_SET_AGE_MS = 5000;
- public static final long MAX_SENSOR_STATE_AGE_MS = 20000;
private static final String TAG = RemoteSensorManager.class.getSimpleName();
- private static final int RETRY_PERIOD_MS = 20000;
-
- private SensorState sensorState = SensorState.NONE;
- private long sensorStateTimestamp_ms = System.currentTimeMillis();
-
- private TimerTask timerTask;
- private Timer timer;
/**
* Returns true if the sensor is enabled.
*/
public abstract boolean isEnabled();
- /**
- * Sets up the sensor channel.
- */
- protected abstract void setUpChannel();
-
- /**
- * Tears down the sensor channel.
- */
- protected abstract void tearDownChannel();
-
/**
* Gets the sensor data set.
*/
@@ -66,61 +42,12 @@ public abstract class RemoteSensorManager {
/**
* Starts the sensor.
*/
- public void startSensor() {
- setUpChannel();
- timerTask = new TimerTask() {
- @Override
- public void run() {
- switch (getSensorState()) {
- case CONNECTING:
- if (System.currentTimeMillis() - sensorStateTimestamp_ms > MAX_SENSOR_STATE_AGE_MS) {
- Log.i(TAG, "Retry setUpChannel");
- setUpChannel();
- }
- break;
- case DISCONNECTED:
- setUpChannel();
- break;
- default: // NONE, CONNECTED or SENDING
- }
- }
- };
- timer = new Timer(RemoteSensorManager.class.getSimpleName());
- timer.schedule(timerTask, RETRY_PERIOD_MS, RETRY_PERIOD_MS);
- }
+ public abstract void startSensor();
/**
* Stops the sensor.
*/
- public void stopSensor() {
- if (timerTask != null) {
- timerTask.cancel();
- timerTask = null;
- }
- if (timer != null) {
- timer.cancel();
- timer.purge();
- timer = null;
- }
- tearDownChannel();
- }
-
- /**
- * Gets the sensor state.
- */
- public SensorState getSensorState() {
- return sensorState;
- }
-
- /**
- * Sets the sensor state.
- *
- * @param sensorState the sensor state
- */
- public void setSensorState(SensorState sensorState) {
- sensorStateTimestamp_ms = System.currentTimeMillis();
- this.sensorState = sensorState;
- }
+ public abstract void stopSensor();
/**
* Returns true if the sensor data set is valid.
diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml
index 983abdb15..902c61e1e 100644
--- a/src/main/res/values/strings.xml
+++ b/src/main/res/values/strings.xml
@@ -1054,7 +1054,9 @@ limitations under the License.
sending data.">
Sending
-
+
+ Sensor %1$s is not known. Please check the settings.
+