androidbonjournsdandroid-14nsdmanager

A Bonjour service that was discoverable in Android 13 is not discoverable in Android 14 using same codes with NsdManger


The codes have already used the method of acquiring multicastLock to receive multicast messages, most of the services can be found, but there are a few services with the same service type that cannot be found on Android 14 (which can be found on Android 13 or Android 12 using the same code and the same Android phone), I do not know whether it is because of the changes in the NsdManager on Android 14, or there are some bugs on Android 14. Any clue to fix this issue? The way I use to discover the services is:

nsdManager.discoverServices("myOwnServiceType._tcp", NsdManager.PROTOCOL_DNS_SD, nsdListener)

And the way to acquire and release MulticastLock is:

fun acquireMulticastLock() {
    if (multicastLock == null) {
        synchronized(this) {
            if (multicastLock == null) {
                val wifiManager = context.getSystemService(Context.WIFI_SERVICE) as WifiManager
                multicastLock = wifiManager.createMulticastLock("multicastLock")
                multicastLock?.setReferenceCounted(true)
            }
        }
    }
    multicastLock?.acquire()
}

fun releaseMulticastLock() {
    multicastLock?.release()
    multicastLock = null
}

MulticastLock was once added to enable the Google Pixel phone to receive multicast messages because the Google Pixel phone's default setting to disable all listening on multicast packages to preserve battery. Therefore, Bonjour service needs to acquire a MulticastLock to receive multicast messages in this case. But I tested on Android 14 removing this multicastLock or adding it back doesn't seem to make any difference.

These are all my attempts so far.


Solution

  • After trying RxDNSSD and JmDNS and finging the root cause inside NsdManger, the JmDNS solve my problem. Currently, I use version implementation 'org.jmdns:jmdns:3.5.9' and it works fine on Android 14, I tested it in several Android phone with OS 14, it can discover the service which cannot be discovered on Android 14 using NsdManger.

    The key to use JmDNS is

    1. implement the object : ServiceListener
    2. create the JmDNS Instance on a background thread using JmDNS.create()
    3. use jmdns.addServiceListener("${YourServiceType}.local.", jmdnsListener) to start browse and listener to the service
    4. remember to close the jmdns by using jmdns.close()
    5. MulticastLock is also needed to acquire in this case