fix(android): request NEARBY_WIFI_DEVICES at runtime so mDNS discovery works on real devices
apple / swift (push) Successful in 53s
ci / web (push) Successful in 30s
ci / docs-site (push) Successful in 38s
android / android (push) Successful in 3m23s
deb / build-publish (push) Successful in 2m4s
decky / build-publish (push) Successful in 12s
docker / build-push (--build-arg FEDORA_VERSION=44, ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora44-rpm) (push) Successful in 5s
docker / build-push (., web/Dockerfile, punktfunk-web) (push) Successful in 5s
docker / build-push (ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora-rpm) (push) Successful in 3s
docker / build-push (ci, ci/rust-ci.Dockerfile, punktfunk-rust-ci) (push) Successful in 4s
docker / build-push (docs-site, docs-site/Dockerfile, punktfunk-docs) (push) Successful in 4s
ci / bench (push) Successful in 4m31s
rpm / build-publish (bazzite, punktfunk-fedora-rpm) (push) Successful in 8m8s
docker / deploy-docs (push) Successful in 5s
rpm / build-publish (fedora-44, punktfunk-fedora44-rpm) (push) Successful in 7m58s
ci / rust (push) Successful in 4m4s
apple / swift (push) Successful in 53s
ci / web (push) Successful in 30s
ci / docs-site (push) Successful in 38s
android / android (push) Successful in 3m23s
deb / build-publish (push) Successful in 2m4s
decky / build-publish (push) Successful in 12s
docker / build-push (--build-arg FEDORA_VERSION=44, ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora44-rpm) (push) Successful in 5s
docker / build-push (., web/Dockerfile, punktfunk-web) (push) Successful in 5s
docker / build-push (ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora-rpm) (push) Successful in 3s
docker / build-push (ci, ci/rust-ci.Dockerfile, punktfunk-rust-ci) (push) Successful in 4s
docker / build-push (docs-site, docs-site/Dockerfile, punktfunk-docs) (push) Successful in 4s
ci / bench (push) Successful in 4m31s
rpm / build-publish (bazzite, punktfunk-fedora-rpm) (push) Successful in 8m8s
docker / deploy-docs (push) Successful in 5s
rpm / build-publish (fedora-44, punktfunk-fedora44-rpm) (push) Successful in 7m58s
ci / rust (push) Successful in 4m4s
NsdManager service discovery needs NEARBY_WIFI_DEVICES on Android 13+. The app DECLARED it but never REQUESTED it, so on a real device the permission stayed denied and discoverServices silently found nothing — no prompt, no hosts. (It only worked on the emulator because the permission was granted via `adb pm grant`.) Request it (mirroring the mic RECORD_AUDIO flow) when the connect screen appears, and start/restart discovery once granted; on API < 33 discovery starts immediately (the permission doesn't apply there). The advertised hosts the Apple clients already see will then appear here too. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
package io.unom.punktfunk
|
||||
|
||||
import android.Manifest
|
||||
import android.content.Context
|
||||
import android.content.pm.PackageManager
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
@@ -13,8 +14,10 @@ import android.view.WindowManager
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.activity.SystemBarStyle
|
||||
import androidx.activity.compose.BackHandler
|
||||
import androidx.activity.compose.rememberLauncherForActivityResult
|
||||
import androidx.activity.compose.setContent
|
||||
import androidx.activity.enableEdgeToEdge
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.gestures.awaitEachGesture
|
||||
import androidx.compose.foundation.gestures.awaitFirstDown
|
||||
@@ -244,11 +247,22 @@ private fun ConnectScreen(settings: Settings, onConnected: (Long) -> Unit) {
|
||||
|
||||
// mDNS discovery scoped to this screen; NsdManager callbacks arrive on the main thread, so the
|
||||
// onChange callback can set Compose state directly. (Emulator SLIRP drops multicast → empty.)
|
||||
// NsdManager discovery needs NEARBY_WIFI_DEVICES on Android 13+ (a runtime permission) — without
|
||||
// it discoverServices silently finds nothing. Request it once, then (re)start discovery on grant.
|
||||
val discovery = remember { HostDiscovery(context) }
|
||||
var discovered by remember { mutableStateOf<List<DiscoveredHost>>(emptyList()) }
|
||||
DisposableEffect(Unit) {
|
||||
var nearbyGranted by remember { mutableStateOf(hasNearbyPermission(context)) }
|
||||
val nearbyLauncher = rememberLauncherForActivityResult(
|
||||
ActivityResultContracts.RequestPermission(),
|
||||
) { granted -> nearbyGranted = granted }
|
||||
LaunchedEffect(Unit) {
|
||||
if (!nearbyGranted && Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||
nearbyLauncher.launch(Manifest.permission.NEARBY_WIFI_DEVICES)
|
||||
}
|
||||
}
|
||||
DisposableEffect(nearbyGranted) {
|
||||
discovery.onChange = { discovered = it }
|
||||
discovery.start()
|
||||
if (nearbyGranted) discovery.start()
|
||||
onDispose {
|
||||
discovery.onChange = null
|
||||
discovery.stop()
|
||||
@@ -576,6 +590,12 @@ private fun ConnectScreen(settings: Settings, onConnected: (Long) -> Unit) {
|
||||
}
|
||||
}
|
||||
|
||||
/** NsdManager discovery needs NEARBY_WIFI_DEVICES on API 33+; below that it doesn't apply. */
|
||||
private fun hasNearbyPermission(context: Context): Boolean =
|
||||
Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU ||
|
||||
ContextCompat.checkSelfPermission(context, Manifest.permission.NEARBY_WIFI_DEVICES) ==
|
||||
PackageManager.PERMISSION_GRANTED
|
||||
|
||||
/** Left-aligned section header above each block of the connect screen. */
|
||||
@Composable
|
||||
private fun SectionLabel(text: String) {
|
||||
|
||||
Reference in New Issue
Block a user