Skip to content

Commit

Permalink
Prevent crash when starting service from background
Browse files Browse the repository at this point in the history
  • Loading branch information
Fabi019 committed Dec 29, 2024
1 parent e0b22c3 commit 2eb496f
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 32 deletions.
55 changes: 24 additions & 31 deletions app/src/main/java/dev/fabik/bluetoothhid/bt/BluetoothController.kt
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package dev.fabik.bluetoothhid.bt

import android.annotation.SuppressLint
import android.app.Activity
import android.bluetooth.BluetoothAdapter
import android.bluetooth.BluetoothDevice
import android.bluetooth.BluetoothHidDevice
Expand All @@ -17,7 +16,9 @@ import androidx.compose.runtime.setValue
import dev.fabik.bluetoothhid.R
import dev.fabik.bluetoothhid.utils.PreferenceStore
import dev.fabik.bluetoothhid.utils.getPreference
import kotlinx.coroutines.MainScope
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.launch
import java.util.concurrent.CountDownLatch
import java.util.concurrent.Executors
import java.util.concurrent.TimeUnit
Expand Down Expand Up @@ -219,42 +220,34 @@ class BluetoothController(var context: Context) {
if (!success) {
Log.d(TAG, "unsuccessful connection to device")

// Try to start service (doesn't matter if it already runs)
MainScope().launch {
// Catch ForegroundServiceStartNotAllowedException when app is in background
runCatching {
context.startForegroundService(
Intent(context, BluetoothService::class.java)
)
}.onFailure {
Log.e("BTService", "Failed to start service", it)
}
}

// Initialize latch to wait for service to be connected.
latch = CountDownLatch(1)

// Try to register proxy.
if (!register()) {
(context as? Activity)?.runOnUiThread {
Toast.makeText(
context,
context.getString(R.string.error_connecting_to_device),
Toast.LENGTH_SHORT
).show()
}

Intent(
context,
BluetoothService::class.java
).apply {
action = BluetoothService.ACTION_REGISTER
}.also {
(context as? Activity)?.runOnUiThread {
context.startForegroundService(it)
}
}
} else {
(context as? Activity)?.runOnUiThread {
Toast.makeText(
context,
context.getString(R.string.proxy_waiting),
Toast.LENGTH_SHORT
).show()
}

latch.await(5000, TimeUnit.MILLISECONDS)

if (register() && latch.await(5000, TimeUnit.MILLISECONDS)) {
// Retry connection again
hidDevice?.connect(device)
return
}

MainScope().launch {
Toast.makeText(
context,
context.getString(R.string.bt_proxy_error),
Toast.LENGTH_SHORT
).show()
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import android.content.pm.ServiceInfo
import android.os.Binder
import android.os.Build
import android.os.IBinder
import android.util.Log
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.mutableStateOf
Expand Down Expand Up @@ -144,7 +145,13 @@ fun rememberBluetoothControllerService(
if (startStop) {
ComposableLifecycle { _, event ->
when (event) {
Lifecycle.Event.ON_RESUME -> context.startForegroundService(intent)
Lifecycle.Event.ON_RESUME ->
// Catch ForegroundServiceStartNotAllowedException when app is in background
runCatching {
context.startForegroundService(intent)
}.onFailure {
Log.e("BTService", "Failed to start service", it)
}
Lifecycle.Event.ON_DESTROY -> {
if ((context as? Activity)?.isChangingConfigurations == false) {
context.stopService(intent)
Expand Down

0 comments on commit 2eb496f

Please sign in to comment.