mirror of
https://github.com/meshtastic/Meshtastic-Android.git
synced 2026-04-20 22:23:37 +00:00
fix(serial): refresh USB device list on Android 12+ attach and resume
Android 12+ delivers ACTION_USB_DEVICE_ATTACHED only to manifest-declared receivers; the runtime-registered UsbBroadcastReceiver inside UsbRepository never sees this event. Forward it explicitly from MainActivity so the serialDevices StateFlow refreshes and the device appears in the Connect → Serial tab without requiring the user to replug. Also re-poll in onResume() to handle process-restart or returning from another app while a USB device was already attached. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
parent
a6f8f456fd
commit
805f9a3cd2
2 changed files with 23 additions and 5 deletions
|
|
@ -59,6 +59,7 @@ import org.meshtastic.app.node.metrics.getTracerouteMapOverlayInsets
|
|||
import org.meshtastic.app.ui.MainScreen
|
||||
import org.meshtastic.core.barcode.rememberBarcodeScanner
|
||||
import org.meshtastic.core.navigation.DEEP_LINK_BASE_URI
|
||||
import org.meshtastic.core.network.repository.UsbRepository
|
||||
import org.meshtastic.core.nfc.NfcScannerEffect
|
||||
import org.meshtastic.core.resources.Res
|
||||
import org.meshtastic.core.resources.channel_invalid
|
||||
|
|
@ -91,6 +92,8 @@ import org.meshtastic.feature.node.metrics.TracerouteMapScreen
|
|||
class MainActivity : ComponentActivity() {
|
||||
private val model: UIViewModel by viewModel()
|
||||
|
||||
private val usbRepository: UsbRepository by inject()
|
||||
|
||||
/**
|
||||
* Activity-lifecycle-aware client that binds to the mesh service. Note: This is used implicitly as it registers
|
||||
* itself as a LifecycleObserver in its init block.
|
||||
|
|
@ -166,6 +169,16 @@ class MainActivity : ComponentActivity() {
|
|||
handleIntent(intent)
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
// Belt-and-suspenders for the Android 12+ attach-intent quirk: if the activity is
|
||||
// resumed while a USB device is already attached (e.g. process restart, returning
|
||||
// from another app), the manifest-declared attach intent may have already fired
|
||||
// before UsbRepository was constructed. Re-poll deviceList here so the UI reflects
|
||||
// reality without requiring the user to physically replug.
|
||||
usbRepository.refreshState()
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun AppCompositionLocals(content: @Composable () -> Unit) {
|
||||
CompositionLocalProvider(
|
||||
|
|
@ -257,6 +270,11 @@ class MainActivity : ComponentActivity() {
|
|||
|
||||
UsbManager.ACTION_USB_DEVICE_ATTACHED -> {
|
||||
Logger.d { "USB device attached" }
|
||||
// Android 12+ delivers ACTION_USB_DEVICE_ATTACHED only to manifest-declared
|
||||
// receivers, so the runtime-registered UsbBroadcastReceiver inside UsbRepository
|
||||
// never sees this event. Forward it explicitly so the serialDevices StateFlow
|
||||
// refreshes and the device shows up in the Connect → Serial tab.
|
||||
usbRepository.refreshState()
|
||||
showSettingsPage()
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -54,9 +54,7 @@ class UsbRepository(
|
|||
_serialDevices
|
||||
.mapLatest { serialDevices ->
|
||||
val serialProber = usbSerialProberLazy.value
|
||||
buildMap {
|
||||
serialDevices.forEach { (k, v) -> serialProber.probeDevice(v)?.let { driver -> put(k, driver) } }
|
||||
}
|
||||
buildMap { serialDevices.forEach { (k, v) -> serialProber.probeDevice(v)?.let { put(k, it) } } }
|
||||
}
|
||||
.stateIn(processLifecycle.coroutineScope, SharingStarted.Eagerly, emptyMap())
|
||||
|
||||
|
|
@ -83,6 +81,8 @@ class UsbRepository(
|
|||
processLifecycle.coroutineScope.launch(dispatchers.default) { refreshStateInternal() }
|
||||
}
|
||||
|
||||
private suspend fun refreshStateInternal() =
|
||||
withContext(dispatchers.default) { _serialDevices.emit(usbManagerLazy.value?.deviceList ?: emptyMap()) }
|
||||
private suspend fun refreshStateInternal() = withContext(dispatchers.default) {
|
||||
val devices = usbManagerLazy.value?.deviceList ?: emptyMap()
|
||||
_serialDevices.emit(devices)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue