From 1825612d546cda23a4072dfcbe4c99de4394b5db Mon Sep 17 00:00:00 2001 From: Semper-Viventem Date: Sat, 27 Sep 2025 21:29:07 -0700 Subject: [PATCH 1/2] Fix some common crashes --- app/build.gradle.kts | 4 +-- .../java/f/cking/software/data/DataModule.kt | 2 +- .../software/data/helpers/BleScannerHelper.kt | 25 +++++++++++++++--- .../software/data/helpers/IntentHelper.kt | 7 +++-- .../f/cking/software/service/BgScanService.kt | 26 ++++++++++++------- app/src/main/res/values/strings.xml | 1 + 6 files changed, 46 insertions(+), 19 deletions(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 9ab19801..be125364 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -26,8 +26,8 @@ android { minSdk = 29 targetSdk = 36 - versionCode = 1708536377 - versionName = "0.31.0-beta" + versionCode = 1708536378 + versionName = "0.31.1-beta" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" diff --git a/app/src/main/java/f/cking/software/data/DataModule.kt b/app/src/main/java/f/cking/software/data/DataModule.kt index 29b415c3..72c1bdfd 100644 --- a/app/src/main/java/f/cking/software/data/DataModule.kt +++ b/app/src/main/java/f/cking/software/data/DataModule.kt @@ -35,7 +35,7 @@ class DataModule( single { DevicesRepository(get()) } single { PermissionHelper(get(), get(), get()) } single { ActivityProvider() } - single { IntentHelper(get(), get()) } + single { IntentHelper(get(), get(), get()) } single { RadarProfilesRepository(get()) } single { LocationProvider(get(), get(), get(), get()) } single { LocationRepository(get()) } diff --git a/app/src/main/java/f/cking/software/data/helpers/BleScannerHelper.kt b/app/src/main/java/f/cking/software/data/helpers/BleScannerHelper.kt index 42f739bb..ee8a4d37 100644 --- a/app/src/main/java/f/cking/software/data/helpers/BleScannerHelper.kt +++ b/app/src/main/java/f/cking/software/data/helpers/BleScannerHelper.kt @@ -58,8 +58,14 @@ class BleScannerHelper( private val callback = object : ScanCallback() { @SuppressLint("MissingPermission") - override fun onScanResult(callbackType: Int, result: ScanResult) { + override fun onScanResult(callbackType: Int, result: ScanResult?) { super.onScanResult(callbackType, result) + + if (result == null || result.device == null) { + Timber.e(IllegalArgumentException("Scan result is null")) + return + } + result.scanRecord?.serviceUuids?.map { bleFiltersProvider.previouslyNoticedServicesUUIDs.add(it.uuid.toString()) } val addressType: Int? = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.VANILLA_ICE_CREAM) { result.device.addressType @@ -75,7 +81,7 @@ class BleScannerHelper( scanRecordRaw = result.scanRecord?.bytes, rssi = result.rssi, addressType = addressType, - deviceClass = result.device.bluetoothClass.deviceClass, + deviceClass = result.device?.bluetoothClass?.deviceClass, isPaired = isPaired, serviceUuids = result.scanRecord?.serviceUuids?.map { it.uuid.toString() }.orEmpty(), isConnectable = result.isConnectable, @@ -143,19 +149,23 @@ class BleScannerHelper( Timber.tag(TAG_CONNECT).d("Connecting to device $address") trySend(DeviceConnectResult.Connecting) } + BluetoothProfile.STATE_CONNECTED -> { Timber.tag(TAG_CONNECT).d("Connected to device $address") trySend(DeviceConnectResult.Connected(gatt)) } + BluetoothProfile.STATE_DISCONNECTING -> { Timber.tag(TAG_CONNECT).d("Disconnecting from device $address") trySend(DeviceConnectResult.Disconnecting) } + BluetoothProfile.STATE_DISCONNECTED -> { Timber.tag(TAG_CONNECT).d("Disconnected from device $address") handleDisconnect(status, gatt) close(gatt) } + else -> { Timber.tag(TAG_CONNECT).e("Error while connecting to device $address. Error code: $status") trySend(DeviceConnectResult.DisconnectedWithError.UnspecifiedConnectionError(gatt, status)) @@ -168,26 +178,32 @@ class BleScannerHelper( BluetoothGatt.GATT_SUCCESS -> { trySend(DeviceConnectResult.Disconnected) } + CONNECTION_FAILED_TO_ESTABLISH -> { Timber.tag(TAG_CONNECT).e("Error while connecting to device $address. Error code: $status") trySend(DeviceConnectResult.DisconnectedWithError.ConnectionFailedToEstablish(gatt, status)) } + CONNECTION_FAILED_BEFORE_INITIALIZING -> { Timber.tag(TAG_CONNECT).e("Error while connecting to device $address. Error code: $status") trySend(DeviceConnectResult.DisconnectedWithError.ConnectionFailedBeforeInitializing(gatt, status)) } + CONNECTION_TERMINATED -> { Timber.tag(TAG_CONNECT).e("Error while connecting to device $address. Error code: $status") trySend(DeviceConnectResult.DisconnectedWithError.ConnectionTerminated(gatt, status)) } + BluetoothGatt.GATT_CONNECTION_TIMEOUT -> { Timber.tag(TAG_CONNECT).e("Error while connecting to device $address. Error code: $status") trySend(DeviceConnectResult.DisconnectedWithError.ConnectionTimeout(gatt, status)) } + BluetoothGatt.GATT_FAILURE -> { Timber.tag(TAG_CONNECT).e("Error while connecting to device $address. Error code: $status") trySend(DeviceConnectResult.DisconnectedWithError.ConnectionFailedTooManyClients(gatt, status)) } + else -> { Timber.tag(TAG_CONNECT).e("Error while connecting to device $address. Error code: $status") trySend(DeviceConnectResult.DisconnectedWithError.UnspecifiedConnectionError(gatt, status)) @@ -259,6 +275,7 @@ class BleScannerHelper( Timber.tag(tag).i("Try disconnect from ${gatt.device.address}") gatt.disconnect() } + BluetoothProfile.STATE_DISCONNECTED -> { Timber.tag(tag).i("Disconnected. Closing connection ${gatt.device.address}") gatt.close() @@ -309,7 +326,9 @@ class BleScannerHelper( sealed interface DeviceConnectResult { data class AvailableServices(val gatt: BluetoothGatt, val services: List) : DeviceConnectResult - data class CharacteristicRead(val gatt: BluetoothGatt, val characteristic: BluetoothGattCharacteristic, val valueEncoded64: String) : DeviceConnectResult + data class CharacteristicRead(val gatt: BluetoothGatt, val characteristic: BluetoothGattCharacteristic, val valueEncoded64: String) : + DeviceConnectResult + data class FailedReadCharacteristic(val gatt: BluetoothGatt, val characteristic: BluetoothGattCharacteristic) : DeviceConnectResult data class DescriptorRead(val gatt: BluetoothGatt, val descriptor: BluetoothGattDescriptor, val valueEncoded64: String) : DeviceConnectResult data object Connecting : DeviceConnectResult diff --git a/app/src/main/java/f/cking/software/data/helpers/IntentHelper.kt b/app/src/main/java/f/cking/software/data/helpers/IntentHelper.kt index e956bc07..d8ae655e 100644 --- a/app/src/main/java/f/cking/software/data/helpers/IntentHelper.kt +++ b/app/src/main/java/f/cking/software/data/helpers/IntentHelper.kt @@ -3,13 +3,11 @@ package f.cking.software.data.helpers import android.annotation.SuppressLint import android.app.Activity import android.bluetooth.BluetoothAdapter +import android.content.Context import android.content.Intent import android.net.Uri import android.provider.Settings -import f.cking.software.data.helpers.IntentHelper.ScreenNavigation.BACKGROUND_LOCATION_DESCRIPTION import f.cking.software.data.helpers.IntentHelper.ScreenNavigation.Companion.toNavigationCommand -import f.cking.software.data.helpers.IntentHelper.ScreenNavigation.MAIN -import f.cking.software.data.helpers.IntentHelper.ScreenNavigation.entries import f.cking.software.openUrl import f.cking.software.ui.MainActivity import f.cking.software.ui.ScreenNavigationCommands @@ -19,6 +17,7 @@ import f.cking.software.utils.navigation.Router class IntentHelper( private val activityProvider: ActivityProvider, private val router: Router, + private val context: Context, ) { /** @@ -75,7 +74,7 @@ class IntentHelper( } fun openScreenIntent(screenName: ScreenNavigation): Intent { - val intent = Intent(activityProvider.requireActivity(), MainActivity::class.java) + val intent = Intent(context, MainActivity::class.java) intent.setAction(ACTION_OPEN_SCREEN) intent.putExtra(SCREEN_NAME, screenName.name) return intent diff --git a/app/src/main/java/f/cking/software/service/BgScanService.kt b/app/src/main/java/f/cking/software/service/BgScanService.kt index 2d1c2771..f6c30956 100644 --- a/app/src/main/java/f/cking/software/service/BgScanService.kt +++ b/app/src/main/java/f/cking/software/service/BgScanService.kt @@ -7,6 +7,8 @@ import android.content.pm.ServiceInfo import android.os.Handler import android.os.IBinder import android.os.Looper +import android.widget.Toast +import f.cking.software.R import f.cking.software.data.helpers.BleScannerHelper import f.cking.software.data.helpers.LocationProvider import f.cking.software.data.helpers.NotificationsHelper @@ -95,14 +97,20 @@ class BgScanService : Service() { scan() } else { Timber.d("Background service launched") - startForeground( - NotificationsHelper.FOREGROUND_NOTIFICATION_ID, - notificationsHelper.buildForegroundNotification( - NotificationsHelper.ServiceNotificationContent.NoDataYet, - createCloseServiceIntent(this) - ), - ServiceInfo.FOREGROUND_SERVICE_TYPE_CONNECTED_DEVICE or ServiceInfo.FOREGROUND_SERVICE_TYPE_LOCATION, - ) + try { + startForeground( + NotificationsHelper.FOREGROUND_NOTIFICATION_ID, + notificationsHelper.buildForegroundNotification( + NotificationsHelper.ServiceNotificationContent.NoDataYet, + createCloseServiceIntent(this) + ), + ServiceInfo.FOREGROUND_SERVICE_TYPE_CONNECTED_DEVICE or ServiceInfo.FOREGROUND_SERVICE_TYPE_LOCATION, + ) + } catch (e: Exception) { + reportError(e) + Toast.makeText(this, R.string.unable_to_run_service_erro_toast, Toast.LENGTH_LONG).show() + stopSelf() + } permissionHelper.checkOrRequestPermission( onRequestPermissions = { _, _, _ -> @@ -156,7 +164,7 @@ class BgScanService : Service() { private fun handleScanResult(batch: List) { scope.launch { - val notificationContent: NotificationsHelper.ServiceNotificationContent = if (batch.isNotEmpty()){ + val notificationContent: NotificationsHelper.ServiceNotificationContent = if (batch.isNotEmpty()) { handleNonEmptyBatch(batch) } else { handleEmptyBatch() diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 116cb01e..66df9a1c 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -295,6 +295,7 @@ refresh + Unable to launch scanning service. BLE scanner is started but there is no data yet %s known devices around %s total devices around From 744b717542f607527cfac6bdb33318a6e78c43e3 Mon Sep 17 00:00:00 2001 From: Semper-Viventem Date: Sat, 27 Sep 2025 21:38:18 -0700 Subject: [PATCH 2/2] Fix some common crashes --- app/src/main/java/f/cking/software/data/helpers/IntentHelper.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/f/cking/software/data/helpers/IntentHelper.kt b/app/src/main/java/f/cking/software/data/helpers/IntentHelper.kt index d8ae655e..e0b351f2 100644 --- a/app/src/main/java/f/cking/software/data/helpers/IntentHelper.kt +++ b/app/src/main/java/f/cking/software/data/helpers/IntentHelper.kt @@ -52,7 +52,7 @@ class IntentHelper( fun openAppSettings() { val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS) - val uri = Uri.fromParts("package", activityProvider.requireActivity().getPackageName(), null) + val uri = Uri.fromParts("package", context.packageName, null) intent.data = uri activityProvider.requireActivity().startActivity(intent) }