diff --git a/app/src/main/java/com.alphasync/bluetooth/ConnectionEventListener.kt b/app/src/main/java/com.alphasync/bluetooth/ConnectionEventListener.kt
index 80dc66d..e5712d7 100644
--- a/app/src/main/java/com.alphasync/bluetooth/ConnectionEventListener.kt
+++ b/app/src/main/java/com.alphasync/bluetooth/ConnectionEventListener.kt
@@ -8,5 +8,5 @@ class ConnectionEventListener {
var onConnectionSetupComplete: ((BluetoothGatt) -> Unit)? = null
var onDisconnect: (() -> Unit)? = null
var onCharacteristicWrite: ((BluetoothDevice, BluetoothGattCharacteristic) -> Unit)? = null
-
+ var onBluetoothStatusChange: ((Boolean) -> Unit)? = null
}
diff --git a/app/src/main/java/com.alphasync/bluetooth/ConnectionManager.kt b/app/src/main/java/com.alphasync/bluetooth/ConnectionManager.kt
index 7938187..35b1d08 100644
--- a/app/src/main/java/com.alphasync/bluetooth/ConnectionManager.kt
+++ b/app/src/main/java/com.alphasync/bluetooth/ConnectionManager.kt
@@ -7,8 +7,13 @@ import android.bluetooth.BluetoothGattCallback
import android.bluetooth.BluetoothGattCharacteristic
import android.bluetooth.BluetoothManager
import android.bluetooth.BluetoothProfile
+import android.content.BroadcastReceiver
import android.content.Context
+import android.content.Intent
+import android.content.IntentFilter
import android.util.Log
+import androidx.core.content.ContextCompat
+import androidx.core.content.ContextCompat.RECEIVER_EXPORTED
import kotlinx.coroutines.delay
import kotlinx.coroutines.runBlocking
import java.lang.ref.WeakReference
@@ -21,6 +26,7 @@ class ConnectionManager(context: Context) {
context.getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager
}
private var btAdapter: BluetoothAdapter = btManager.adapter
+ private val btAdapterFilter = IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED)
private var btGatt: BluetoothGatt? = null
private var btGattIsConnecting: Boolean = false
private lateinit var callerContext: Context
@@ -58,6 +64,7 @@ class ConnectionManager(context: Context) {
btAddress = address
callerContext = context
+ ContextCompat.registerReceiver(context, bluetoothStateReceiver, btAdapterFilter, RECEIVER_EXPORTED)
val btDevice = btAdapter.getRemoteDevice(address)
if (btGattIsConnecting) {
Log.d(logTag, "Device is currently connecting.")
@@ -77,20 +84,25 @@ class ConnectionManager(context: Context) {
listeners.forEach { it.get()?.onDisconnect?.invoke() }
}
- btGattIsConnecting = false
- btGatt?.close()
- btGatt = null
+ disconnect()
connect(btAddress, callerContext)
}
+ @SuppressLint("MissingPermission")
+ private fun disconnect() {
+ btGattIsConnecting = false
+ btGatt?.disconnect()
+ btGatt = null
+ }
+
@SuppressLint("MissingPermission")
fun writeCharacteristic(
- characteristic: BluetoothGattCharacteristic,
- payload: ByteArray
- ) {
+ characteristicId: UUID,
+ payload: ByteArray)
+ {
if (isConnected) {
- btGatt?.findCharacteristic(characteristic.uuid)?.let { characteristic ->
+ btGatt?.findCharacteristic(characteristicId)?.let { characteristic ->
characteristic.value = payload
val initialSuccess = btGatt?.writeCharacteristic(characteristic)
if(initialSuccess!!) {
@@ -117,6 +129,21 @@ class ConnectionManager(context: Context) {
return null
}
+ private val bluetoothStateReceiver = object : BroadcastReceiver() {
+ override fun onReceive(context: Context?, intent: Intent?) {
+ if (intent?.action == BluetoothAdapter.ACTION_STATE_CHANGED) {
+ val state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR)
+ if(state == BluetoothAdapter.STATE_OFF) {
+ disconnect()
+ listeners.forEach { it.get()?.onBluetoothStatusChange?.invoke(false) }
+ } else if (state == BluetoothAdapter.STATE_ON) {
+ reconnect()
+ listeners.forEach { it.get()?.onBluetoothStatusChange?.invoke(true) }
+ }
+ }
+ }
+ }
+
private val callback = object : BluetoothGattCallback() {
@SuppressLint("MissingPermission")
override fun onConnectionStateChange(gatt: BluetoothGatt, status: Int, newState: Int) {
@@ -142,6 +169,7 @@ class ConnectionManager(context: Context) {
Log.d(logTag,"onConnectionStateChange: status $status encountered for $deviceAddress!")
reconnect()
}
+
}
@SuppressLint("MissingPermission")
diff --git a/app/src/main/java/com.alphasync/cameralink/MyCameraLinkService.kt b/app/src/main/java/com.alphasync/cameralink/MyCameraLinkService.kt
index 4a14bbf..ae987a8 100644
--- a/app/src/main/java/com.alphasync/cameralink/MyCameraLinkService.kt
+++ b/app/src/main/java/com.alphasync/cameralink/MyCameraLinkService.kt
@@ -31,7 +31,7 @@ class MyCameraLinkService: Service() {
private var cameraName: String = ""
private lateinit var notificationManager: NotificationManagerCompat
private val notificationChannel: String = "MyCameraLinkNotificationChannel"
- private val notificationConnectDisconnectId: Int = 1
+ private val notificationServiceStatusId: Int = 1
private val notificationGpsLostFoundId: Int = 2
fun isPairedToCamera(): Boolean {
@@ -92,7 +92,7 @@ class MyCameraLinkService: Service() {
.setContentText("Sending GPS to $cameraName")
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
.build()
- notificationManager.notify(notificationConnectDisconnectId, notificationBuilder)
+ notificationManager.notify(notificationServiceStatusId, notificationBuilder)
}
onGpsSignalLost = {
notificationManager.cancel(notificationGpsLostFoundId)
@@ -102,12 +102,12 @@ class MyCameraLinkService: Service() {
.setContentText("Sending GPS to $cameraName paused")
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
.build()
- notificationManager.notify(notificationConnectDisconnectId, notificationBuilder)
+ notificationManager.notify(notificationServiceStatusId, notificationBuilder)
}
onLocationReady = { location ->
val characteristic = connectionManager.characteristics.find { it.uuid.toString().contains("0000dd11")}
Log.d(logTag, "Writing to ${characteristic!!.uuid}: ${location.toHexString()}")
- connectionManager.writeCharacteristic(characteristic, location)
+ connectionManager.writeCharacteristic(characteristic.uuid, location)
}
}
}
@@ -115,38 +115,36 @@ class MyCameraLinkService: Service() {
private val connectionEventListener by lazy {
ConnectionEventListener().apply {
onConnectionSetupComplete = { _ ->
- notificationManager.cancel(notificationConnectDisconnectId)
+ notificationManager.cancel(notificationServiceStatusId)
val notificationBuilder = NotificationCompat.Builder(applicationContext, notificationChannel)
.setSmallIcon(R.drawable.ic_stat_name)
.setContentTitle("$cameraName connected!")
.setContentText("Sending GPS coordinates")
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
.build()
- notificationManager.notify(notificationConnectDisconnectId, notificationBuilder)
+ notificationManager.notify(notificationServiceStatusId, notificationBuilder)
sendEnableGpsCommands()
}
-
onDisconnect = {
sonyCommandGenerator.stopLocationReporting(myCameraLinkEventListener)
- notificationManager.cancel(notificationConnectDisconnectId)
+ notificationManager.cancel(notificationServiceStatusId)
val notificationBuilder = NotificationCompat.Builder(applicationContext, notificationChannel)
.setSmallIcon(R.drawable.ic_camera_disconnected)
.setContentTitle("$cameraName disconnected!")
.setContentText("GPS coordinates paused")
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
.build()
- notificationManager.notify(notificationConnectDisconnectId, notificationBuilder)
+ notificationManager.notify(notificationServiceStatusId, notificationBuilder)
tryReconnect()
}
-
onCharacteristicWrite = { _, sentCharacteristic: BluetoothGattCharacteristic ->
if (sentCharacteristic.uuid.toString().contains("0000dd30")) {
val characteristic = connectionManager.characteristics.find { it.uuid.toString().contains("0000dd31")}
if (characteristic != null) {
Log.d(logTag, "GPS Enable command: ${characteristic.uuid}")
- connectionManager.writeCharacteristic(characteristic, "01".hexToBytes())
+ connectionManager.writeCharacteristic(characteristic.uuid, "01".hexToBytes())
} else {
Log.d(logTag, "GPS Enable command: Cannot find characteristic containing 0000dd31")
}
@@ -155,6 +153,28 @@ class MyCameraLinkService: Service() {
startSendingCoordinatesToDevice()
}
}
+ onBluetoothStatusChange = { isEnabled: Boolean ->
+ if(!isEnabled) {
+ sonyCommandGenerator.stopLocationReporting(myCameraLinkEventListener)
+ notificationManager.cancel(notificationServiceStatusId)
+ val notificationBuilder = NotificationCompat.Builder(applicationContext, notificationChannel)
+ .setSmallIcon(R.drawable.ic_bluetooth_disabled)
+ .setContentTitle("Bluetooth disabled")
+ .setContentText("GPS coordinates paused")
+ .setPriority(NotificationCompat.PRIORITY_DEFAULT)
+ .build()
+ notificationManager.notify(notificationServiceStatusId, notificationBuilder)
+ } else {
+ notificationManager.cancel(notificationServiceStatusId)
+ val notificationBuilder = NotificationCompat.Builder(applicationContext, notificationChannel)
+ .setSmallIcon(R.drawable.ic_camera_disconnected)
+ .setContentTitle("$cameraName disconnected!")
+ .setContentText("GPS coordinates paused")
+ .setPriority(NotificationCompat.PRIORITY_DEFAULT)
+ .build()
+ notificationManager.notify(notificationServiceStatusId, notificationBuilder)
+ }
+ }
}
}
@@ -166,14 +186,13 @@ class MyCameraLinkService: Service() {
createNotificationChannel()
val notification = NotificationCompat.Builder(this, notificationChannel)
- .setContentTitle("Camera GPS link running")
- .setContentText("Paired to $cameraName")
- .setSmallIcon(R.drawable.ic_camera_back)
+ .setContentTitle("Connecting to $cameraName")
+ .setSmallIcon(R.drawable.ic_device_connecting)
.build()
ServiceCompat.startForeground(
this,
- 100,
+ notificationServiceStatusId,
notification,
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
ServiceInfo.FOREGROUND_SERVICE_TYPE_LOCATION or ServiceInfo.FOREGROUND_SERVICE_TYPE_CONNECTED_DEVICE
@@ -186,7 +205,7 @@ class MyCameraLinkService: Service() {
val characteristic = connectionManager.characteristics.find { it.uuid.toString().contains("0000dd30")}
if (characteristic != null) {
Log.d(logTag, "GPS Enable command: ${characteristic.uuid}")
- connectionManager.writeCharacteristic(characteristic, "01".hexToBytes())
+ connectionManager.writeCharacteristic(characteristic.uuid, "01".hexToBytes())
} else {
Log.d(logTag, "GPS Enable command: Cannot find characteristic containing 0000dd31")
}
@@ -218,7 +237,7 @@ class MyCameraLinkService: Service() {
}
override fun onBind(intent: Intent?): IBinder? {
- Log.d("MyService","Service being bound")
+ Log.d(logTag,"Service is being bound")
return binder
}
}
\ No newline at end of file
diff --git a/app/src/main/res/drawable-anydpi/ic_bluetooth_disabled.xml b/app/src/main/res/drawable-anydpi/ic_bluetooth_disabled.xml
new file mode 100644
index 0000000..a9f04bc
--- /dev/null
+++ b/app/src/main/res/drawable-anydpi/ic_bluetooth_disabled.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
diff --git a/app/src/main/res/drawable-anydpi/ic_device_connecting.xml b/app/src/main/res/drawable-anydpi/ic_device_connecting.xml
new file mode 100644
index 0000000..ba8e65b
--- /dev/null
+++ b/app/src/main/res/drawable-anydpi/ic_device_connecting.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
diff --git a/app/src/main/res/drawable-hdpi/ic_bluetooth_disabled.png b/app/src/main/res/drawable-hdpi/ic_bluetooth_disabled.png
new file mode 100644
index 0000000..a0999a6
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_bluetooth_disabled.png differ
diff --git a/app/src/main/res/drawable-hdpi/ic_device_connecting.png b/app/src/main/res/drawable-hdpi/ic_device_connecting.png
new file mode 100644
index 0000000..9b54ef1
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_device_connecting.png differ
diff --git a/app/src/main/res/drawable-mdpi/ic_bluetooth_disabled.png b/app/src/main/res/drawable-mdpi/ic_bluetooth_disabled.png
new file mode 100644
index 0000000..c3f5e8c
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_bluetooth_disabled.png differ
diff --git a/app/src/main/res/drawable-mdpi/ic_device_connecting.png b/app/src/main/res/drawable-mdpi/ic_device_connecting.png
new file mode 100644
index 0000000..48a33e3
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_device_connecting.png differ
diff --git a/app/src/main/res/drawable-xhdpi/ic_bluetooth_disabled.png b/app/src/main/res/drawable-xhdpi/ic_bluetooth_disabled.png
new file mode 100644
index 0000000..0619455
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_bluetooth_disabled.png differ
diff --git a/app/src/main/res/drawable-xhdpi/ic_device_connecting.png b/app/src/main/res/drawable-xhdpi/ic_device_connecting.png
new file mode 100644
index 0000000..4a9fc74
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_device_connecting.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/ic_bluetooth_disabled.png b/app/src/main/res/drawable-xxhdpi/ic_bluetooth_disabled.png
new file mode 100644
index 0000000..e4f855f
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_bluetooth_disabled.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/ic_device_connecting.png b/app/src/main/res/drawable-xxhdpi/ic_device_connecting.png
new file mode 100644
index 0000000..640c320
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_device_connecting.png differ