android: permisos y MulticastLock para ver moviles en la misma wifi
El anuncio LAN de SSB va por UDP broadcast y Android lo filtra sin un MulticastLock. La oficial declara ACCESS_WIFI_STATE y CHANGE_WIFI_MULTICAST_STATE; esta no, asi que dos moviles en la misma red no se encontraban.
This commit is contained in:
parent
de5e8fba20
commit
ba057f0092
2 changed files with 26 additions and 0 deletions
|
|
@ -3,6 +3,10 @@
|
|||
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
<!-- descubrir otros moviles en la misma wifi: el anuncio LAN de SSB va por UDP
|
||||
broadcast/multicast, y Android lo filtra si no se coge un MulticastLock -->
|
||||
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
|
||||
<uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE" />
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_DATA_SYNC" />
|
||||
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import android.app.NotificationManager
|
|||
import android.app.Service
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.net.wifi.WifiManager
|
||||
import android.os.Build
|
||||
import android.os.IBinder
|
||||
import android.system.Os
|
||||
|
|
@ -33,16 +34,37 @@ class NodeService : Service() {
|
|||
@Volatile private var started = false
|
||||
}
|
||||
|
||||
// Sin esto Android tira los paquetes multicast/broadcast que llegan por wifi y el
|
||||
// descubrimiento LAN de SSB no ve a nadie: dos moviles en la misma red no se encuentran.
|
||||
private var multicastLock: WifiManager.MulticastLock? = null
|
||||
|
||||
override fun onBind(intent: Intent?): IBinder? = null
|
||||
|
||||
override fun onCreate() {
|
||||
super.onCreate()
|
||||
startForeground(NOTIF_ID, buildNotification())
|
||||
acquireMulticastLock()
|
||||
if (started) return
|
||||
started = true
|
||||
Thread({ runNode() }, "node-main").start()
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
try { multicastLock?.takeIf { it.isHeld }?.release() } catch (e: Throwable) { Log.w(TAG, "soltando MulticastLock", e) }
|
||||
super.onDestroy()
|
||||
}
|
||||
|
||||
private fun acquireMulticastLock() {
|
||||
if (multicastLock?.isHeld == true) return
|
||||
try {
|
||||
val wifi = applicationContext.getSystemService(Context.WIFI_SERVICE) as WifiManager
|
||||
multicastLock = wifi.createMulticastLock("oasis-lan").apply { setReferenceCounted(false); acquire() }
|
||||
} catch (e: Throwable) {
|
||||
// sin wifi o sin permiso: los pubs siguen funcionando, solo se pierde la LAN
|
||||
Log.w(TAG, "no se ha podido coger el MulticastLock; sin descubrimiento LAN", e)
|
||||
}
|
||||
}
|
||||
|
||||
private fun buildNotification(): Notification {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
val ch = NotificationChannel(CHANNEL, getString(R.string.node_channel), NotificationManager.IMPORTANCE_LOW)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue