diff --git a/app/src/main/java/no/nordicsemi/android/nrftoolbox/proximity/DeviceAdapter.java b/app/src/main/java/no/nordicsemi/android/nrftoolbox/proximity/DeviceAdapter.java index 76c8c953..6dfcf125 100644 --- a/app/src/main/java/no/nordicsemi/android/nrftoolbox/proximity/DeviceAdapter.java +++ b/app/src/main/java/no/nordicsemi/android/nrftoolbox/proximity/DeviceAdapter.java @@ -24,15 +24,12 @@ package no.nordicsemi.android.nrftoolbox.proximity; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothGatt; -import android.support.v4.content.ContextCompat; -import android.support.v4.graphics.drawable.DrawableCompat; import android.support.v7.widget.RecyclerView; import android.text.TextUtils; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ImageButton; -import android.widget.ImageView; import android.widget.TextView; import java.util.List; @@ -142,6 +139,8 @@ public class DeviceAdapter extends RecyclerView.AdapterThis bug/feature can be tested using a proximity tag that does not release its connection when it got + * disconnected: + *
    + *
  1. Connect to your Proximity Tag.
  2. + *
  3. Verify that the bidirectional connection works - test the FIND ME button in nRF Toolbox and + * the FIND PHONE button on the tag.
  4. + *
  5. Disconnect from the tag
  6. + *
  7. When the device disappear from the list of devices click the FIND PHONE button on the tag. + * Your phone should still trigger an alarm, as the connection tag->phone is still active.
  8. + *
+ * In order to avoid this issue make sure that your tag disconnects gently from phone when it got disconnected itself. + *

+ * @param device the device that will no longer be used + */ + public void cancelConnection(final BluetoothDevice device) { if (mBluetoothGattServer != null) { mLogger.log(device, LogContract.Log.Level.VERBOSE, "[Server] Cancelling server connection..."); mLogger.log(device, LogContract.Log.Level.DEBUG, "server.cancelConnection(device)"); @@ -126,18 +199,28 @@ public class ProximityServerManager { private final BluetoothGattServerCallback mGattServerCallbacks = new BluetoothGattServerCallback() { @Override public void onServiceAdded(final int status, final BluetoothGattService service) { - // Adding another service from callback thread fails on Samsung S4 with Android 4.3 - mHandler.post(new Runnable() { - @Override - public void run() { - if (IMMEDIATE_ALERT_SERVICE_UUID.equals(service.getUuid())) { - addLinklossService(); - } else if (mOnServerOpenCallback != null) { - mOnServerOpenCallback.onGattServerOpen(); - mOnServerOpenCallback = null; + if (status == BluetoothGatt.GATT_SUCCESS) { + // Adding another service from callback thread fails on Samsung S4 with Android 4.3 + mHandler.post(new Runnable() { + @Override + public void run() { + if (IMMEDIATE_ALERT_SERVICE_UUID.equals(service.getUuid())) { + addLinklossService(); + } else { + mServerReady = true; + // Both services has been added + if (mOnServerOpenCallback != null) + mOnServerOpenCallback.onGattServerOpen(); + mOnServerOpenCallback = null; + } } - } - }); + }); + } else { + Log.e(TAG, "GATT Server failed to add service, status: " + status); + if (mOnServerOpenCallback != null) + mOnServerOpenCallback.onGattServerFailed(status); + mOnServerOpenCallback = null; + } } @Override diff --git a/app/src/main/java/no/nordicsemi/android/nrftoolbox/proximity/ProximityService.java b/app/src/main/java/no/nordicsemi/android/nrftoolbox/proximity/ProximityService.java index 5bb65393..d1dd9bae 100644 --- a/app/src/main/java/no/nordicsemi/android/nrftoolbox/proximity/ProximityService.java +++ b/app/src/main/java/no/nordicsemi/android/nrftoolbox/proximity/ProximityService.java @@ -24,6 +24,7 @@ package no.nordicsemi.android.nrftoolbox.proximity; import android.app.Notification; import android.app.NotificationManager; import android.app.PendingIntent; +import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.content.BroadcastReceiver; import android.content.Context; @@ -142,6 +143,9 @@ public class ProximityService extends BleMulticonnectProfileService implements P @Override protected void onServiceCreated() { + mServerManager = new ProximityServerManager(this); + mServerManager.setLogger(mBinder); + initializeAlarm(); registerReceiver(mDisconnectActionBroadcastReceiver, new IntentFilter(ACTION_DISCONNECT)); @@ -155,10 +159,8 @@ public class ProximityService extends BleMulticonnectProfileService implements P public void onServiceStopped() { cancelNotifications(); - // GATT server might have not been created if Bluetooth was disabled - if (mServerManager != null) { - mServerManager.closeGattServer(); - } + // Close the GATT server. If it hasn't been opened this method does nothing + mServerManager.closeGattServer(); unregisterReceiver(mDisconnectActionBroadcastReceiver); unregisterReceiver(mToggleAlarmActionBroadcastReceiver); @@ -169,29 +171,31 @@ public class ProximityService extends BleMulticonnectProfileService implements P @Override protected void onBluetoothEnabled() { // Start the GATT Server only if Bluetooth is enabled - mServerManager = new ProximityServerManager(this); - mServerManager.setLogger(mBinder); mServerManager.openGattServer(this, new ProximityServerManager.OnServerOpenCallback() { @Override public void onGattServerOpen() { // We are now ready to reconnect devices ProximityService.super.onBluetoothEnabled(); } + + @Override + public void onGattServerFailed(final int error) { + mServerManager.closeGattServer(); + showToast(getString(R.string.proximity_server_error, error)); + } }); } @Override protected void onBluetoothDisabled() { super.onBluetoothDisabled(); - if (mServerManager != null) { - mServerManager.closeGattServer(); - mServerManager = null; - } + // Close the GATT server + mServerManager.closeGattServer(); } @Override protected void onRebind() { - // when the activity rebinds to the service, remove the notification + // When the activity rebinds to the service, remove the notification cancelNotifications(); } @@ -209,22 +213,30 @@ public class ProximityService extends BleMulticonnectProfileService implements P } } + @Override + public void onServicesDiscovered(final BluetoothDevice device, final boolean optionalServicesFound) { + super.onServicesDiscovered(device, optionalServicesFound); + mServerManager.openConnection(device); + } + @Override public void onLinklossOccur(final BluetoothDevice device) { + mServerManager.cancelConnection(device); stopAlarm(device); super.onLinklossOccur(device); if (!mBinded) { createBackgroundNotification(); - createLinklossNotification(device); + if (BluetoothAdapter.getDefaultAdapter().isEnabled()) + createLinklossNotification(device); + else + cancelNotification(device); } } @Override public void onDeviceDisconnected(final BluetoothDevice device) { - if (mServerManager != null) { - mServerManager.cancelConnection(device); - } + mServerManager.cancelConnection(device); stopAlarm(device); super.onDeviceDisconnected(device); diff --git a/app/src/main/res/values/strings_proximity.xml b/app/src/main/res/values/strings_proximity.xml index 45ce6153..03ae8950 100644 --- a/app/src/main/res/values/strings_proximity.xml +++ b/app/src/main/res/values/strings_proximity.xml @@ -48,7 +48,7 @@ %s is getting away! YOUR TAGS - GATT Server enabled + GATT Server failed to start (error %d). PROXIMITY profile allows you to connect to multiple Proximity sensors. \nYou can find your valuables attached with Proximity tag by pressing the Locate button next to your device.