mirror of
https://github.com/aljazceru/Android-nRF-Toolbox.git
synced 2026-01-09 09:44:22 +01:00
Fix crashes observed on Firebase console (#130)
* Switch getParcelableExtra to IntentCompat * Fix MissingForegroundServiceTypeException * Fix UART server * Move foreground service permissions to one place
This commit is contained in:
committed by
GitHub
parent
9c1ac06894
commit
391a4e0b6d
@@ -51,5 +51,7 @@ class NrfToolboxApplication : Application() {
|
||||
super.onCreate()
|
||||
|
||||
analytics.logEvent(AppOpenEvent)
|
||||
|
||||
uartServer.start(this)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,7 +34,9 @@
|
||||
|
||||
<uses-permission android:name="android.permission.BLUETOOTH" />
|
||||
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
|
||||
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
|
||||
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_CONNECTED_DEVICE" />
|
||||
|
||||
</manifest>
|
||||
@@ -37,8 +37,6 @@ import android.app.NotificationManager
|
||||
import android.app.PendingIntent
|
||||
import android.content.Intent
|
||||
import android.os.Build
|
||||
import android.os.Build.VERSION.SDK_INT
|
||||
import android.os.Parcelable
|
||||
import androidx.annotation.RequiresApi
|
||||
import androidx.core.app.NotificationCompat
|
||||
import androidx.core.content.ContextCompat
|
||||
@@ -135,11 +133,6 @@ abstract class NotificationService : LifecycleService() {
|
||||
nm.cancel(NOTIFICATION_ID)
|
||||
}
|
||||
|
||||
inline fun <reified T : Parcelable> Intent.parcelable(key: String): T? = when {
|
||||
SDK_INT >= 33 -> getParcelableExtra(key, T::class.java)
|
||||
else -> @Suppress("DEPRECATION") getParcelableExtra(key) as? T
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val NOTIFICATION_ID = 200
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
~ Copyright (c) 2022, Nordic Semiconductor
|
||||
~ All rights reserved.
|
||||
~
|
||||
@@ -31,8 +30,10 @@
|
||||
-->
|
||||
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<application>
|
||||
<service android:name=".repository.CGMService" />
|
||||
<service
|
||||
android:name=".repository.CGMService"
|
||||
android:exported="false"
|
||||
android:foregroundServiceType="connectedDevice" />
|
||||
</application>
|
||||
</manifest>
|
||||
</manifest>
|
||||
|
||||
@@ -33,6 +33,7 @@ package no.nordicsemi.android.cgms.repository
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Intent
|
||||
import androidx.core.content.IntentCompat
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import kotlinx.coroutines.flow.catch
|
||||
@@ -107,7 +108,7 @@ internal class CGMService : NotificationService() {
|
||||
|
||||
repository.setServiceRunning(true)
|
||||
|
||||
val device = intent!!.getParcelableExtra<ServerDevice>(DEVICE_DATA)!!
|
||||
val device = IntentCompat.getParcelableExtra(intent!!, DEVICE_DATA, ServerDevice::class.java)!!
|
||||
|
||||
startGattClient(device)
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
~ Copyright (c) 2022, Nordic Semiconductor
|
||||
~ All rights reserved.
|
||||
~
|
||||
@@ -37,7 +36,10 @@
|
||||
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
|
||||
|
||||
<application>
|
||||
<service android:name=".repository.CSCService" />
|
||||
<service
|
||||
android:name=".repository.CSCService"
|
||||
android:exported="false"
|
||||
android:foregroundServiceType="connectedDevice" />
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
|
||||
@@ -33,6 +33,7 @@ package no.nordicsemi.android.csc.repository
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Intent
|
||||
import androidx.core.content.IntentCompat
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import kotlinx.coroutines.flow.catch
|
||||
@@ -73,7 +74,7 @@ internal class CSCService : NotificationService() {
|
||||
|
||||
repository.setServiceRunning(true)
|
||||
|
||||
val device = intent!!.getParcelableExtra<ServerDevice>(DEVICE_DATA)!!
|
||||
val device = IntentCompat.getParcelableExtra(intent!!, DEVICE_DATA, ServerDevice::class.java)!!
|
||||
|
||||
startGattClient(device)
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
~ Copyright (c) 2022, Nordic Semiconductor
|
||||
~ All rights reserved.
|
||||
~
|
||||
@@ -33,7 +32,10 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<application>
|
||||
<service android:name=".service.HRSService" />
|
||||
<service
|
||||
android:name=".service.HRSService"
|
||||
android:exported="false"
|
||||
android:foregroundServiceType="connectedDevice" />
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
@@ -33,6 +33,7 @@ package no.nordicsemi.android.hrs.service
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Intent
|
||||
import androidx.core.content.IntentCompat
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import kotlinx.coroutines.flow.catch
|
||||
@@ -75,7 +76,7 @@ internal class HRSService : NotificationService() {
|
||||
|
||||
repository.setServiceRunning(true)
|
||||
|
||||
val device = intent!!.getParcelableExtra<ServerDevice>(DEVICE_DATA)!!
|
||||
val device = IntentCompat.getParcelableExtra(intent!!, DEVICE_DATA, ServerDevice::class.java)!!
|
||||
|
||||
startGattClient(device)
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
~ Copyright (c) 2022, Nordic Semiconductor
|
||||
~ All rights reserved.
|
||||
~
|
||||
@@ -33,7 +32,10 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<application>
|
||||
<service android:name=".repository.HTSService" />
|
||||
<service
|
||||
android:name=".repository.HTSService"
|
||||
android:exported="false"
|
||||
android:foregroundServiceType="connectedDevice" />
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
@@ -33,6 +33,7 @@ package no.nordicsemi.android.hts.repository
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Intent
|
||||
import androidx.core.content.IntentCompat
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import kotlinx.coroutines.flow.catch
|
||||
@@ -73,7 +74,7 @@ internal class HTSService : NotificationService() {
|
||||
|
||||
repository.setServiceRunning(true)
|
||||
|
||||
val device = intent!!.getParcelableExtra<ServerDevice>(DEVICE_DATA)!!
|
||||
val device = IntentCompat.getParcelableExtra(intent!!, DEVICE_DATA, ServerDevice::class.java)!!
|
||||
|
||||
startGattClient(device)
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
~ Copyright (c) 2022, Nordic Semiconductor
|
||||
~ All rights reserved.
|
||||
~
|
||||
@@ -33,6 +32,9 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<application>
|
||||
<service android:name=".repository.PRXService"/>
|
||||
<service
|
||||
android:name=".repository.PRXService"
|
||||
android:exported="false"
|
||||
android:foregroundServiceType="connectedDevice" />
|
||||
</application>
|
||||
</manifest>
|
||||
|
||||
@@ -33,6 +33,7 @@ package no.nordicsemi.android.prx.repository
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Intent
|
||||
import androidx.core.content.IntentCompat
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import kotlinx.coroutines.flow.catch
|
||||
@@ -92,7 +93,7 @@ internal class PRXService : NotificationService() {
|
||||
|
||||
repository.setServiceRunning(true)
|
||||
|
||||
val device = intent!!.getParcelableExtra<ServerDevice>(DEVICE_DATA)!!
|
||||
val device = IntentCompat.getParcelableExtra(intent!!, DEVICE_DATA, ServerDevice::class.java)!!
|
||||
|
||||
startServer(device)
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
~ Copyright (c) 2022, Nordic Semiconductor
|
||||
~ All rights reserved.
|
||||
~
|
||||
@@ -33,6 +32,9 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<application>
|
||||
<service android:name=".repository.RSCSService"/>
|
||||
<service
|
||||
android:name=".repository.RSCSService"
|
||||
android:exported="false"
|
||||
android:foregroundServiceType="connectedDevice" />
|
||||
</application>
|
||||
</manifest>
|
||||
|
||||
@@ -33,6 +33,7 @@ package no.nordicsemi.android.rscs.repository
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Intent
|
||||
import androidx.core.content.IntentCompat
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import kotlinx.coroutines.flow.catch
|
||||
@@ -73,7 +74,7 @@ internal class RSCSService : NotificationService() {
|
||||
|
||||
repository.setServiceRunning(true)
|
||||
|
||||
val device = intent!!.getParcelableExtra<ServerDevice>(DEVICE_DATA)!!
|
||||
val device = IntentCompat.getParcelableExtra(intent!!, DEVICE_DATA, ServerDevice::class.java)!!
|
||||
|
||||
startGattClient(device)
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
~ Copyright (c) 2022, Nordic Semiconductor
|
||||
~ All rights reserved.
|
||||
~
|
||||
@@ -33,7 +32,10 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<application>
|
||||
<service android:name=".repository.UARTService" />
|
||||
<service
|
||||
android:name=".repository.UARTService"
|
||||
android:exported="false"
|
||||
android:foregroundServiceType="connectedDevice" />
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
@@ -14,7 +14,6 @@ import no.nordicsemi.android.kotlin.ble.core.MockServerDevice
|
||||
import no.nordicsemi.android.kotlin.ble.core.advertiser.BleAdvertisingConfig
|
||||
import no.nordicsemi.android.kotlin.ble.core.data.BleGattPermission
|
||||
import no.nordicsemi.android.kotlin.ble.core.data.BleGattProperty
|
||||
import no.nordicsemi.android.kotlin.ble.profile.gls.RecordAccessControlPointInputParser
|
||||
import no.nordicsemi.android.kotlin.ble.server.main.ServerBleGatt
|
||||
import no.nordicsemi.android.kotlin.ble.server.main.service.ServerBleGattCharacteristic
|
||||
import no.nordicsemi.android.kotlin.ble.server.main.service.ServerBleGattCharacteristicConfig
|
||||
@@ -39,116 +38,20 @@ class UartServer @Inject constructor(
|
||||
|
||||
lateinit var server: ServerBleGatt
|
||||
|
||||
lateinit var glsCharacteristic: ServerBleGattCharacteristic
|
||||
lateinit var glsContextCharacteristic: ServerBleGattCharacteristic
|
||||
lateinit var racpCharacteristic: ServerBleGattCharacteristic
|
||||
lateinit var rxCharacteristic: ServerBleGattCharacteristic
|
||||
lateinit var txCharacteristic: ServerBleGattCharacteristic
|
||||
lateinit var batteryLevelCharacteristic: ServerBleGattCharacteristic
|
||||
|
||||
private var lastRequest = DataByteArray()
|
||||
|
||||
val YOUNGEST_RECORD = DataByteArray.from(
|
||||
0x07,
|
||||
0x00,
|
||||
0x00,
|
||||
0xDC.toByte(),
|
||||
0x07,
|
||||
0x01,
|
||||
0x01,
|
||||
0x0C,
|
||||
0x1E,
|
||||
0x05,
|
||||
0x00,
|
||||
0x00,
|
||||
0x26,
|
||||
0xD2.toByte(),
|
||||
0x11
|
||||
)
|
||||
val OLDEST_RECORD = DataByteArray.from(
|
||||
0x07,
|
||||
0x04,
|
||||
0x00,
|
||||
0xDC.toByte(),
|
||||
0x07,
|
||||
0x01,
|
||||
0x01,
|
||||
0x0C,
|
||||
0x1E,
|
||||
0x11,
|
||||
0x00,
|
||||
0x00,
|
||||
0x82.toByte(),
|
||||
0xD2.toByte(),
|
||||
0x11
|
||||
)
|
||||
|
||||
val records = listOf(
|
||||
YOUNGEST_RECORD,
|
||||
DataByteArray.from(
|
||||
0x07,
|
||||
0x01,
|
||||
0x00,
|
||||
0xDC.toByte(),
|
||||
0x07,
|
||||
0x01,
|
||||
0x01,
|
||||
0x0C,
|
||||
0x1E,
|
||||
0x08,
|
||||
0x00,
|
||||
0x00,
|
||||
0x3D,
|
||||
0xD2.toByte(),
|
||||
0x11
|
||||
),
|
||||
DataByteArray.from(
|
||||
0x07,
|
||||
0x02,
|
||||
0x00,
|
||||
0xDC.toByte(),
|
||||
0x07,
|
||||
0x01,
|
||||
0x01,
|
||||
0x0C,
|
||||
0x1E,
|
||||
0x0B,
|
||||
0x00,
|
||||
0x00,
|
||||
0x54,
|
||||
0xD2.toByte(),
|
||||
0x11
|
||||
),
|
||||
DataByteArray.from(
|
||||
0x07,
|
||||
0x03,
|
||||
0x00,
|
||||
0xDC.toByte(),
|
||||
0x07,
|
||||
0x01,
|
||||
0x01,
|
||||
0x0C,
|
||||
0x1E,
|
||||
0x0E,
|
||||
0x00,
|
||||
0x00,
|
||||
0x6B,
|
||||
0xD2.toByte(),
|
||||
0x11
|
||||
),
|
||||
OLDEST_RECORD
|
||||
)
|
||||
|
||||
val racp = DataByteArray.from(0x06, 0x00, 0x01, 0x01)
|
||||
|
||||
fun start(
|
||||
context: Context,
|
||||
device: MockServerDevice = MockServerDevice(
|
||||
name = "GLS Server",
|
||||
name = "UART Server",
|
||||
address = "55:44:33:22:11"
|
||||
),
|
||||
) = scope.launch {
|
||||
val rxCharacteristic = ServerBleGattCharacteristicConfig(
|
||||
UART_RX_CHARACTERISTIC_UUID,
|
||||
listOf(BleGattProperty.PROPERTY_NOTIFY),
|
||||
listOf(BleGattProperty.PROPERTY_NOTIFY, BleGattProperty.PROPERTY_WRITE),
|
||||
listOf()
|
||||
)
|
||||
|
||||
@@ -197,57 +100,20 @@ class UartServer @Inject constructor(
|
||||
}
|
||||
|
||||
private fun setUpConnection(connection: ServerBluetoothGattConnection) {
|
||||
// val glsService = connection.services.findService(GLS_SERVICE_UUID)!!
|
||||
// glsCharacteristic = glsService.findCharacteristic(GLUCOSE_MEASUREMENT_CHARACTERISTIC)!!
|
||||
// glsContextCharacteristic = glsService.findCharacteristic(GLUCOSE_MEASUREMENT_CONTEXT_CHARACTERISTIC)!!
|
||||
// racpCharacteristic = glsService.findCharacteristic(RACP_CHARACTERISTIC)!!
|
||||
val glsService = connection.services.findService(UART_SERVICE_UUID)!!
|
||||
rxCharacteristic = glsService.findCharacteristic(UART_RX_CHARACTERISTIC_UUID)!!
|
||||
txCharacteristic = glsService.findCharacteristic(UART_TX_CHARACTERISTIC_UUID)!!
|
||||
|
||||
rxCharacteristic.value.onEach {
|
||||
txCharacteristic.setValue(it)
|
||||
}.launchIn(scope)
|
||||
|
||||
val batteryService = connection.services.findService(BATTERY_SERVICE_UUID)!!
|
||||
batteryLevelCharacteristic = batteryService.findCharacteristic(
|
||||
BATTERY_LEVEL_CHARACTERISTIC_UUID
|
||||
)!!
|
||||
|
||||
|
||||
// startGlsService(connection)
|
||||
// startBatteryService(connection)
|
||||
}
|
||||
|
||||
private fun startGlsService(connection: ServerBluetoothGattConnection) {
|
||||
racpCharacteristic.value
|
||||
.onEach { lastRequest = it }
|
||||
.launchIn(scope)
|
||||
}
|
||||
|
||||
internal fun continueWithResponse() {
|
||||
sendResponse(lastRequest)
|
||||
}
|
||||
|
||||
private fun sendResponse(request: DataByteArray) {
|
||||
if (request == RecordAccessControlPointInputParser.reportNumberOfAllStoredRecords()) {
|
||||
sendAll(glsCharacteristic)
|
||||
racpCharacteristic.setValue(racp)
|
||||
} else if (request == RecordAccessControlPointInputParser.reportLastStoredRecord()) {
|
||||
sendLast(glsCharacteristic)
|
||||
racpCharacteristic.setValue(racp)
|
||||
} else if (request == RecordAccessControlPointInputParser.reportFirstStoredRecord()) {
|
||||
sendFirst(glsCharacteristic)
|
||||
racpCharacteristic.setValue(racp)
|
||||
}
|
||||
}
|
||||
|
||||
private fun sendFirst(characteristics: ServerBleGattCharacteristic) {
|
||||
characteristics.setValue(records.first())
|
||||
}
|
||||
|
||||
private fun sendLast(characteristics: ServerBleGattCharacteristic) {
|
||||
characteristics.setValue(records.last())
|
||||
}
|
||||
|
||||
private fun sendAll(characteristics: ServerBleGattCharacteristic) = scope.launch {
|
||||
records.forEach {
|
||||
characteristics.setValue(it)
|
||||
delay(100)
|
||||
}
|
||||
startBatteryService(connection)
|
||||
}
|
||||
|
||||
private fun startBatteryService(connection: ServerBluetoothGattConnection) {
|
||||
|
||||
@@ -33,6 +33,7 @@ package no.nordicsemi.android.uart.repository
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Intent
|
||||
import androidx.core.content.IntentCompat
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import kotlinx.coroutines.flow.catch
|
||||
@@ -78,7 +79,7 @@ internal class UARTService : NotificationService() {
|
||||
|
||||
repository.setServiceRunning(true)
|
||||
|
||||
val device = intent!!.parcelable<ServerDevice>(DEVICE_DATA)!!
|
||||
val device = IntentCompat.getParcelableExtra(intent!!, DEVICE_DATA, ServerDevice::class.java)!!
|
||||
|
||||
startGattClient(device)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user