feat: foreground service & automatic reconnecting
This commit is contained in:
@@ -22,6 +22,8 @@ android {
|
|||||||
|
|
||||||
buildConfigField "String", "API_BASE_URL", "\"${props['apiBaseUrl']}\""
|
buildConfigField "String", "API_BASE_URL", "\"${props['apiBaseUrl']}\""
|
||||||
buildConfigField "String", "API_KEY", "\"${props['apiKey']}\""
|
buildConfigField "String", "API_KEY", "\"${props['apiKey']}\""
|
||||||
|
buildConfigField "String", "SERVICE_UUID", "\"6e400001-b5a3-f393-e1a9-e50e24dcac9e\""
|
||||||
|
buildConfigField "String", "CHAR_UUID", "\"6e400005-b5a3-f393-e1a9-e50e24dcac9e\""
|
||||||
}
|
}
|
||||||
|
|
||||||
buildTypes {
|
buildTypes {
|
||||||
|
|||||||
@@ -17,6 +17,9 @@
|
|||||||
android:name="android.permission.ACCESS_FINE_LOCATION"
|
android:name="android.permission.ACCESS_FINE_LOCATION"
|
||||||
android:maxSdkVersion="30" />
|
android:maxSdkVersion="30" />
|
||||||
|
|
||||||
|
<uses-permission
|
||||||
|
android:name="android.permission.FOREGROUND_SERVICE" />
|
||||||
|
|
||||||
<uses-permission
|
<uses-permission
|
||||||
android:name="android.permission.BLUETOOTH_SCAN"
|
android:name="android.permission.BLUETOOTH_SCAN"
|
||||||
android:usesPermissionFlags="neverForLocation"
|
android:usesPermissionFlags="neverForLocation"
|
||||||
@@ -39,7 +42,6 @@
|
|||||||
<activity
|
<activity
|
||||||
android:name=".MainActivity"
|
android:name=".MainActivity"
|
||||||
android:exported="true"
|
android:exported="true"
|
||||||
android:label="@string/app_name"
|
|
||||||
android:theme="@style/Theme.SensorTestingApp">
|
android:theme="@style/Theme.SensorTestingApp">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.MAIN" />
|
<action android:name="android.intent.action.MAIN" />
|
||||||
@@ -47,6 +49,7 @@
|
|||||||
<category android:name="android.intent.category.LAUNCHER" />
|
<category android:name="android.intent.category.LAUNCHER" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
|
<service android:name=".BLEService" android:foregroundServiceType="connectedDevice" />
|
||||||
</application>
|
</application>
|
||||||
|
|
||||||
</manifest>
|
</manifest>
|
||||||
69
app/src/main/java/com/example/sensortestingapp/BLEService.kt
Normal file
69
app/src/main/java/com/example/sensortestingapp/BLEService.kt
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
package com.example.sensortestingapp
|
||||||
|
|
||||||
|
import android.app.NotificationChannel
|
||||||
|
import android.app.NotificationManager
|
||||||
|
import android.app.PendingIntent
|
||||||
|
import android.app.Service
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
|
import android.os.Build
|
||||||
|
import android.os.IBinder
|
||||||
|
import androidx.core.app.NotificationCompat
|
||||||
|
import androidx.core.content.ContextCompat
|
||||||
|
|
||||||
|
class BLEService : Service() {
|
||||||
|
private val CHANNEL_ID = "BLEService Kotlin"
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
|
||||||
|
fun startService(context: Context, message: String) {
|
||||||
|
val startIntent = Intent(context,
|
||||||
|
BLEService::class.java)
|
||||||
|
startIntent.putExtra("inputExtra", message)
|
||||||
|
ContextCompat.startForegroundService(context, startIntent)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun stopService(context: Context) {
|
||||||
|
val stopIntent = Intent(context, BLEService::class.java)
|
||||||
|
context.stopService(stopIntent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
|
||||||
|
|
||||||
|
//do heavy work on a background thread
|
||||||
|
val input = intent?.getStringExtra("inputExtra")
|
||||||
|
createNotificationChannel()
|
||||||
|
val notificationIntent = Intent(this, MainActivity::class.java)
|
||||||
|
|
||||||
|
val pendingIntent: PendingIntent =
|
||||||
|
Intent(this, MainActivity::class.java).let { notificationIntent ->
|
||||||
|
PendingIntent.getActivity(this, 0, notificationIntent,
|
||||||
|
PendingIntent.FLAG_IMMUTABLE)
|
||||||
|
}
|
||||||
|
val notification = NotificationCompat.Builder(this, CHANNEL_ID)
|
||||||
|
.setContentTitle("BLEService Service Kotlin Example")
|
||||||
|
.setContentText(input)
|
||||||
|
//.setSmallIcon(R.drawable.ic_notification)
|
||||||
|
.setContentIntent(pendingIntent)
|
||||||
|
.build()
|
||||||
|
|
||||||
|
startForeground(1, notification)
|
||||||
|
//stopSelf();
|
||||||
|
return START_NOT_STICKY
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onBind(intent: Intent): IBinder? {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createNotificationChannel() {
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||||
|
val serviceChannel = NotificationChannel(CHANNEL_ID, "BLEService Service Channel",
|
||||||
|
NotificationManager.IMPORTANCE_DEFAULT)
|
||||||
|
|
||||||
|
val manager = getSystemService(NotificationManager::class.java)
|
||||||
|
manager!!.createNotificationChannel(serviceChannel)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
package com.example.sensortestingapp
|
package com.example.sensortestingapp
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
|
import android.app.Service
|
||||||
import android.bluetooth.BluetoothAdapter
|
import android.bluetooth.BluetoothAdapter
|
||||||
import android.bluetooth.BluetoothDevice
|
import android.bluetooth.BluetoothDevice
|
||||||
import android.bluetooth.BluetoothDevice.BOND_BONDED
|
import android.bluetooth.BluetoothDevice.BOND_BONDED
|
||||||
@@ -14,12 +15,14 @@ import android.bluetooth.BluetoothGattDescriptor
|
|||||||
import android.bluetooth.BluetoothProfile
|
import android.bluetooth.BluetoothProfile
|
||||||
import android.bluetooth.BluetoothProfile.STATE_DISCONNECTED
|
import android.bluetooth.BluetoothProfile.STATE_DISCONNECTED
|
||||||
import android.bluetooth.le.ScanCallback
|
import android.bluetooth.le.ScanCallback
|
||||||
|
import android.bluetooth.le.ScanFilter
|
||||||
import android.bluetooth.le.ScanResult
|
import android.bluetooth.le.ScanResult
|
||||||
import android.bluetooth.le.ScanSettings
|
import android.bluetooth.le.ScanSettings
|
||||||
import android.content.BroadcastReceiver
|
import android.content.BroadcastReceiver
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.content.IntentFilter
|
import android.content.IntentFilter
|
||||||
|
import android.os.ParcelUuid
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import java.util.UUID
|
import java.util.UUID
|
||||||
import java.util.concurrent.ConcurrentHashMap
|
import java.util.concurrent.ConcurrentHashMap
|
||||||
@@ -198,7 +201,7 @@ fun ByteArray.toHexString(): String =
|
|||||||
joinToString(separator = "", prefix = "0x") { String.format("%02X", it) }
|
joinToString(separator = "", prefix = "0x") { String.format("%02X", it) }
|
||||||
|
|
||||||
@SuppressLint("MissingPermission")
|
@SuppressLint("MissingPermission")
|
||||||
class ConnectionManager(val context: Context, bleAdapter: BluetoothAdapter) {
|
class ConnectionManager(val context: Context, bleAdapter: BluetoothAdapter) {
|
||||||
|
|
||||||
private val deviceGattMap = ConcurrentHashMap<BluetoothDevice, BluetoothGatt>()
|
private val deviceGattMap = ConcurrentHashMap<BluetoothDevice, BluetoothGatt>()
|
||||||
private val operationQueue = ConcurrentLinkedQueue<BleOperationType>()
|
private val operationQueue = ConcurrentLinkedQueue<BleOperationType>()
|
||||||
@@ -209,6 +212,8 @@ class ConnectionManager(val context: Context, bleAdapter: BluetoothAdapter) {
|
|||||||
.setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY)
|
.setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY)
|
||||||
.build()
|
.build()
|
||||||
|
|
||||||
|
private val scanFilters = listOf( ScanFilter.Builder().setServiceUuid(ParcelUuid.fromString(BuildConfig.SERVICE_UUID)).build())
|
||||||
|
|
||||||
private val bleScanner by lazy {
|
private val bleScanner by lazy {
|
||||||
bleAdapter.bluetoothLeScanner
|
bleAdapter.bluetoothLeScanner
|
||||||
}
|
}
|
||||||
@@ -274,6 +279,8 @@ class ConnectionManager(val context: Context, bleAdapter: BluetoothAdapter) {
|
|||||||
broadcastReceiver,
|
broadcastReceiver,
|
||||||
IntentFilter(BluetoothDevice.ACTION_BOND_STATE_CHANGED)
|
IntentFilter(BluetoothDevice.ACTION_BOND_STATE_CHANGED)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var isScanning = false
|
var isScanning = false
|
||||||
@@ -307,7 +314,7 @@ class ConnectionManager(val context: Context, bleAdapter: BluetoothAdapter) {
|
|||||||
fun startScan() {
|
fun startScan() {
|
||||||
if (!isScanning) {
|
if (!isScanning) {
|
||||||
isScanning = true
|
isScanning = true
|
||||||
bleScanner.startScan(null, scanSettings, scanCallback)
|
bleScanner.startScan( null, scanSettings, scanCallback)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -428,7 +435,7 @@ class ConnectionManager(val context: Context, bleAdapter: BluetoothAdapter) {
|
|||||||
with(operation) {
|
with(operation) {
|
||||||
Log.w("ConnectionManager", "Connecting to ${device.address}")
|
Log.w("ConnectionManager", "Connecting to ${device.address}")
|
||||||
device.connectGatt(
|
device.connectGatt(
|
||||||
context, false, callback, BluetoothDevice.TRANSPORT_LE
|
context, true, callback, BluetoothDevice.TRANSPORT_LE
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
@@ -520,6 +527,7 @@ class ConnectionManager(val context: Context, bleAdapter: BluetoothAdapter) {
|
|||||||
|
|
||||||
is SetNotification -> with(operation) {
|
is SetNotification -> with(operation) {
|
||||||
val characteristic = gatt.getService(serviceId)?.getCharacteristic(charId);
|
val characteristic = gatt.getService(serviceId)?.getCharacteristic(charId);
|
||||||
|
|
||||||
if (characteristic == null) {
|
if (characteristic == null) {
|
||||||
Log.e("ConnectionManager", "Char $charId (${serviceId}) not found!")
|
Log.e("ConnectionManager", "Char $charId (${serviceId}) not found!")
|
||||||
signalEndOfOperation(operation)
|
signalEndOfOperation(operation)
|
||||||
|
|||||||
@@ -25,9 +25,8 @@ import java.util.UUID
|
|||||||
import java.util.stream.Collectors
|
import java.util.stream.Collectors
|
||||||
|
|
||||||
|
|
||||||
// Kirby service uuid: 6e400001-b5a3-f393-e1a9-e50e24dcac9e
|
private val SERVICE_UUID = UUID.fromString(BuildConfig.SERVICE_UUID)
|
||||||
private val DEMO_SERVICE_UUID = UUID.fromString("6e400001-b5a3-f393-e1a9-e50e24dcac9e")
|
private val CHAR_UUID = UUID.fromString(BuildConfig.CHAR_UUID)
|
||||||
private val DEMO_CHAR_UUID = UUID.fromString("6e400005-b5a3-f393-e1a9-e50e24dcac9e")
|
|
||||||
|
|
||||||
enum class DeviceStatus {
|
enum class DeviceStatus {
|
||||||
CONNECTED, BONDED, SUBSCRIBED, MISSING
|
CONNECTED, BONDED, SUBSCRIBED, MISSING
|
||||||
@@ -40,8 +39,27 @@ class KirbyDevice(
|
|||||||
private val bleDevice: BluetoothDevice,
|
private val bleDevice: BluetoothDevice,
|
||||||
private val onStateChange: (device: KirbyDevice) -> Unit,
|
private val onStateChange: (device: KirbyDevice) -> Unit,
|
||||||
|
|
||||||
) : BleListener(bleDevice.address), DeviceListEntry {
|
) : BleListener(bleDevice.address), DeviceListEntry {
|
||||||
private val queue : RequestQueue = Volley.newRequestQueue(context)
|
private val queue: RequestQueue = Volley.newRequestQueue(context)
|
||||||
|
|
||||||
|
fun subscribe() {
|
||||||
|
|
||||||
|
connectionManager.enableNotification(
|
||||||
|
bleDevice, SERVICE_UUID, CHAR_UUID
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun readIaq() {
|
||||||
|
connectionManager.readChar(bleDevice, SERVICE_UUID, CHAR_UUID)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onSuccessfulCharRead(
|
||||||
|
gatt: BluetoothGatt,
|
||||||
|
characteristic: BluetoothGattCharacteristic
|
||||||
|
) {
|
||||||
|
addMeasurement(characteristic)
|
||||||
|
onStateChange(this)
|
||||||
|
}
|
||||||
|
|
||||||
override fun onScanResult(callbackType: Int, result: ScanResult) {
|
override fun onScanResult(callbackType: Int, result: ScanResult) {
|
||||||
rssi = result.rssi
|
rssi = result.rssi
|
||||||
@@ -51,6 +69,7 @@ class KirbyDevice(
|
|||||||
override fun onConnect(gatt: BluetoothGatt) {
|
override fun onConnect(gatt: BluetoothGatt) {
|
||||||
statuses.add(DeviceStatus.CONNECTED)
|
statuses.add(DeviceStatus.CONNECTED)
|
||||||
statuses.remove(DeviceStatus.MISSING)
|
statuses.remove(DeviceStatus.MISSING)
|
||||||
|
|
||||||
onStateChange(this)
|
onStateChange(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -65,14 +84,6 @@ class KirbyDevice(
|
|||||||
onStateChange(this)
|
onStateChange(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onSuccessfulCharRead(
|
|
||||||
gatt: BluetoothGatt,
|
|
||||||
characteristic: BluetoothGattCharacteristic
|
|
||||||
) {
|
|
||||||
addMeasurement(characteristic)
|
|
||||||
onStateChange(this)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onCharChange(gatt: BluetoothGatt, characteristic: BluetoothGattCharacteristic) {
|
override fun onCharChange(gatt: BluetoothGatt, characteristic: BluetoothGattCharacteristic) {
|
||||||
addMeasurement(characteristic)
|
addMeasurement(characteristic)
|
||||||
onStateChange(this)
|
onStateChange(this)
|
||||||
@@ -82,6 +93,7 @@ class KirbyDevice(
|
|||||||
gatt: BluetoothGatt,
|
gatt: BluetoothGatt,
|
||||||
descriptor: BluetoothGattDescriptor,
|
descriptor: BluetoothGattDescriptor,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
statuses.add(DeviceStatus.SUBSCRIBED)
|
statuses.add(DeviceStatus.SUBSCRIBED)
|
||||||
onStateChange(this)
|
onStateChange(this)
|
||||||
}
|
}
|
||||||
@@ -116,25 +128,23 @@ class KirbyDevice(
|
|||||||
override var rssi: Int? = null
|
override var rssi: Int? = null
|
||||||
|
|
||||||
private fun addMeasurement(characteristic: BluetoothGattCharacteristic) {
|
private fun addMeasurement(characteristic: BluetoothGattCharacteristic) {
|
||||||
if (characteristic.service.uuid == DEMO_SERVICE_UUID && characteristic.uuid == DEMO_CHAR_UUID) {
|
val hexPayload = characteristic.value.toHexString()
|
||||||
|
val payload = Payload(hexPayload)
|
||||||
val hexPayload = characteristic.value.toHexString()
|
val base64Payload = Base64.getEncoder().encodeToString(characteristic.value)
|
||||||
val payload = Payload(hexPayload)
|
Log.i("BleListener", "Char received: $payload")
|
||||||
val base64Payload = Base64.getEncoder().encodeToString(characteristic.value)
|
measurements.add(payload)
|
||||||
Log.i("BleListener", "Demo char received: $payload")
|
publishMeasurement(base64Payload)
|
||||||
measurements.add(payload)
|
|
||||||
publishMeasurement(base64Payload)
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun publishMeasurement(payload: String) {
|
private fun publishMeasurement(payload: String) {
|
||||||
val accessKey = BuildConfig.API_BASE_URL
|
val accessKey = BuildConfig.API_KEY
|
||||||
val url = BuildConfig.API_KEY
|
val url = BuildConfig.API_BASE_URL
|
||||||
val eui = "0000${bleDevice.address}"
|
val eui = "0000${bleDevice.address.replace(":", "")}"
|
||||||
|
|
||||||
val postData = JSONObject()
|
val postData = JSONObject()
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
Log.i("POST", "Transmitting for $eui: $payload")
|
||||||
postData.put("accessKey", accessKey)
|
postData.put("accessKey", accessKey)
|
||||||
postData.put("metricPayload", payload)
|
postData.put("metricPayload", payload)
|
||||||
postData.put("eui", eui)
|
postData.put("eui", eui)
|
||||||
@@ -145,7 +155,7 @@ class KirbyDevice(
|
|||||||
val request = JsonObjectRequest(
|
val request = JsonObjectRequest(
|
||||||
Request.Method.POST, url, postData,
|
Request.Method.POST, url, postData,
|
||||||
{ response ->
|
{ response ->
|
||||||
Log.i("sendDataResponse","Response is: $response")
|
Log.i("sendDataResponse", "Response is: $response")
|
||||||
}
|
}
|
||||||
) { error -> error.printStackTrace() }
|
) { error -> error.printStackTrace() }
|
||||||
|
|
||||||
@@ -257,7 +267,7 @@ class KirbyDevice(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun execute() {
|
override fun execute() {
|
||||||
connectionManager.readChar(bleDevice, DEMO_SERVICE_UUID, DEMO_CHAR_UUID)
|
readIaq()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -272,9 +282,7 @@ class KirbyDevice(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun execute() {
|
override fun execute() {
|
||||||
connectionManager.enableNotification(
|
subscribe()
|
||||||
bleDevice, DEMO_SERVICE_UUID, DEMO_CHAR_UUID
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -307,7 +315,7 @@ class KirbyDevice(
|
|||||||
|
|
||||||
override fun execute() {
|
override fun execute() {
|
||||||
connectionManager.disableNotification(
|
connectionManager.disableNotification(
|
||||||
bleDevice, DEMO_SERVICE_UUID, DEMO_CHAR_UUID
|
bleDevice, SERVICE_UUID, CHAR_UUID
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -341,7 +349,6 @@ data class Payload(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
fun bytesToUInt16(arr: ByteArray, start: Int): Int {
|
fun bytesToUInt16(arr: ByteArray, start: Int): Int {
|
||||||
return ByteBuffer.wrap(arr, start, 2)
|
return ByteBuffer.wrap(arr, start, 2)
|
||||||
.order(ByteOrder.LITTLE_ENDIAN).short.toInt() and 0xFFFF
|
.order(ByteOrder.LITTLE_ENDIAN).short.toInt() and 0xFFFF
|
||||||
@@ -371,21 +378,18 @@ private fun payloadToMeasurements(payload: Payload): List<Measurement> {
|
|||||||
override fun getIcon(): Int? {
|
override fun getIcon(): Int? {
|
||||||
return R.drawable.baseline_access_time_24
|
return R.drawable.baseline_access_time_24
|
||||||
}
|
}
|
||||||
},
|
}, object : Measurement {
|
||||||
object : Measurement {
|
override fun getLabel(): String {
|
||||||
override fun getLabel(): String {
|
return "Payload"
|
||||||
return "Payload"
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getFormattedValue(): String {
|
|
||||||
return payload.payload
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getIcon(): Int? {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
)
|
override fun getFormattedValue(): String {
|
||||||
|
return payload.payload
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getIcon(): Int? {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
@@ -75,7 +75,7 @@ class MainActivity : AppCompatActivity() {
|
|||||||
|
|
||||||
setSupportActionBar(binding.toolbar)
|
setSupportActionBar(binding.toolbar)
|
||||||
|
|
||||||
|
BLEService.startService(applicationContext, "hello ble service")
|
||||||
|
|
||||||
binding.fab.setOnClickListener { view ->
|
binding.fab.setOnClickListener { view ->
|
||||||
if (!hasRequiredRuntimePermissions()) {
|
if (!hasRequiredRuntimePermissions()) {
|
||||||
@@ -103,10 +103,10 @@ class MainActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun isKirbyDevice(device: BluetoothDevice): Boolean {
|
private fun isKirbyDevice(device: BluetoothDevice): Boolean {
|
||||||
Log.i("kby", "found device ${device.name}")
|
|
||||||
return (device.name ?: "").lowercase().contains("kirby")
|
return (device.name ?: "").lowercase().contains("kirby")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private fun setupDevicesList() {
|
private fun setupDevicesList() {
|
||||||
binding.devicesList.apply {
|
binding.devicesList.apply {
|
||||||
adapter = deviceListAdapter
|
adapter = deviceListAdapter
|
||||||
@@ -134,7 +134,8 @@ class MainActivity : AppCompatActivity() {
|
|||||||
|
|
||||||
private fun addBondedDevices(): Unit {
|
private fun addBondedDevices(): Unit {
|
||||||
bluetoothAdapter.bondedDevices.filter { isKirbyDevice(it) }.forEach {
|
bluetoothAdapter.bondedDevices.filter { isKirbyDevice(it) }.forEach {
|
||||||
newKirbyDevice(it)
|
val kirbyDevice = newKirbyDevice(it)
|
||||||
|
kirbyDevice.subscribe()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -179,13 +180,15 @@ class MainActivity : AppCompatActivity() {
|
|||||||
|
|
||||||
private fun newKirbyDevice(bleDevice: BluetoothDevice): KirbyDevice {
|
private fun newKirbyDevice(bleDevice: BluetoothDevice): KirbyDevice {
|
||||||
|
|
||||||
val device = KirbyDevice( this.applicationContext, connectionManager, bleDevice) {
|
val device = KirbyDevice(this.applicationContext, connectionManager, bleDevice) {
|
||||||
val i = kirbyDevices.indexOfFirst { d -> d === it }
|
val i = kirbyDevices.indexOfFirst { d -> d === it }
|
||||||
runOnUiThread {
|
runOnUiThread {
|
||||||
deviceListAdapter.notifyItemChanged(i)
|
deviceListAdapter.notifyItemChanged(i)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
connectionManager.register(device)
|
connectionManager.register(device)
|
||||||
|
connectionManager.connect(bleDevice)
|
||||||
|
connectionManager.discoverServices(bleDevice)
|
||||||
kirbyDevices.add(device)
|
kirbyDevices.add(device)
|
||||||
deviceListAdapter.notifyItemInserted(kirbyDevices.size - 1)
|
deviceListAdapter.notifyItemInserted(kirbyDevices.size - 1)
|
||||||
return device
|
return device
|
||||||
|
|||||||
Reference in New Issue
Block a user