NsdServiceInfo не содержит атрибутов на Android 6.0

В приложении Android, которое должно работать на Android 6+, я пытаюсь использовать обнаружение сетевых служб, чтобы проверить, доступны ли некоторые устройства в моей сети.

Основываясь на этой части официальной документации, я создал этот небольшой POC :

class MainActivity : AppCompatActivity() {

    companion object {
        private const val TAG = "POC"

        private const val SERVICE_TYPE = "_http._tcp."
    }

    private val serviceToResolve = mutableListOf<NsdServiceInfo>()

    private var index = 0

    public override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        findViewById<Button>(R.id.discover_btn).setOnClickListener {
            search()
        }

    }

    private fun search() {
        lifecycleScope.launch(Dispatchers.IO) {
            val serviceInfo = NsdServiceInfo().apply {
                serviceName = "MyServiceTest"
                serviceType = SERVICE_TYPE
                port = 80
            }

            val registrationListener = object : NsdManager.RegistrationListener {

                override fun onServiceRegistered(NsdServiceInfo: NsdServiceInfo) {}

                override fun onRegistrationFailed(serviceInfo: NsdServiceInfo, errorCode: Int) {}

                override fun onServiceUnregistered(arg0: NsdServiceInfo) {
                }

                override fun onUnregistrationFailed(serviceInfo: NsdServiceInfo, errorCode: Int) {}
            }

            val nsdManager = (getSystemService(Context.NSD_SERVICE) as NsdManager).apply {
                registerService(serviceInfo, NsdManager.PROTOCOL_DNS_SD, registrationListener)
            }

            // Instantiate a new DiscoveryListener
            val discoveryListener = object : NsdManager.DiscoveryListener {

                override fun onDiscoveryStarted(regType: String) {
                }

                override fun onServiceFound(service: NsdServiceInfo) {
                    serviceToResolve.add(service)
                }

                override fun onServiceLost(service: NsdServiceInfo) {}

                override fun onDiscoveryStopped(serviceType: String) {}

                override fun onStartDiscoveryFailed(serviceType: String, errorCode: Int) {
                    nsdManager.stopServiceDiscovery(this)
                }

                override fun onStopDiscoveryFailed(serviceType: String, errorCode: Int) {
                    nsdManager.stopServiceDiscovery(this)
                }
            }

            nsdManager.discoverServices(SERVICE_TYPE, NsdManager.PROTOCOL_DNS_SD, discoveryListener)

            delay(5000)

            resolveService(nsdManager)
        }
    }

    private fun resolveService(nsdManager: NsdManager) {
        if (serviceToResolve.size > index) {
            nsdManager.resolveService(serviceToResolve[index], object : NsdManager.ResolveListener {
                override fun onResolveFailed(serviceInfo: NsdServiceInfo?, errorCode: Int) {
                    index++
                    resolveService(nsdManager)
                }

                override fun onServiceResolved(serviceInfo: NsdServiceInfo?) {
                    Log.d(TAG, "onServiceResolved : $serviceInfo || ${serviceInfo?.attributes}")
                    index++
                    resolveService(nsdManager)
                }

            })
        } else {
            Log.d(TAG, "Nothing to resolve")
        }
    }

}

Этот код правильно работает с Android 7 по 11. Но не работает правильно на Android 6. Я могу правильно разрешить службы, но он не содержит никаких атрибутов в соответствии с журналом:

Log.d(TAG, "onServiceResolved : $serviceInfo || ${serviceInfo?.attributes}")

Например, вот результат на Android 6.0:

onServiceResolved : имя: TJA470 (TJA470-F40103), тип: ._http._tcp, хост: /10.0.0.177, порт: 80 || {}

А вот результат на Android 11:

onServiceResolved: имя: TJA470 (TJA470-F40103), тип: ._http._tcp, хост: /10.0.0.177, порт: 80, txtRecord: 1device.type=urn:schemas-hager-com:device:tja470:1device.modelName =TJA470 export=Yes$device.modelURL=http://www.hager.comdevice.hostName=TJA470-F40103device.manufacturer=Hagerdevice.ip=10.0.0.1771device.modelDescription=Hager Pilot Configuration+device.manufacturerURL=http:/ /www.hager.com(device.UDN=uuid:M2VSZEVUELAJYECHAJLU1708 device.UPC=470,device.serialNumber=M2VSZEVUELAJYECHAJLU1708device.modelNumber=3.1.15'presentationURL=http://TJA470-F40103:80*device.friendlyName=TJA470 (TJA470-F40103) || {device.type=[117, 114, 110, 58, 115, 99, 104, 101, 109, 97, 115, 45, 104, 97, 103, 101, 114, 45, 99 , 111, 109, 58, 100, 101, 118, 105, 99, 101, 58, 116, 106, 97, 52, 55, 48, 58, 49], device.modelName=[84, 74, 65, 52 , 55, 48], export=[89, 101, 115], device.modelURL=[104, 116, 116, 112, 58, 47, 47, 119, 119, 119, 46, 104, 97, 103, 101 , 114, 46, 99, 111, 109], device.hostName=[84, 74, 65, 52, 55, 48, 45, 70, 52, 48, 49, 48, 51], device.manufacturer=[72, 97, 103, 101, 114], device.ip=[49, 48, 46, 48, 46, 48, 46, 49, 55, 55], device.modelDescription=[72, 97, 103, 101, 114, 32, 80, 105, 108, 111, 116, 32, 67, 111, 110, 102, 105, 103, 117, 114, 97, 116, 105, 111, 110], device.manufacturerURL=[104, 116, 116, 112, 58, 47, 47, 119, 119, 119, 46, 104, 97, 103, 101, 114, 46, 99, 111, 109], устройство.УДН=[117, 117, 105, 100, 58, 77, 50, 86, 83, 90, 69, 86, 85, 69, 76, 65, 74, 89, 69, 67, 72, 65, 74, 76, 85, 49, 55, 48, 56], device.UPC=[52, 55, 48], device.serialNumber=[77, 50, 86, 83, 90, 69, 86, 85, 69, 76, 65, 74, 89, 69, 67, 72, 65, 74, 76, 85, 49, 55, 48, 56], device.modelNumber=[ 51, 46, 49, 46, 49, 53],URL представления=[104, 116, 116, 112, 58, 47, 47, 84, 74, 65, 52, 55, 48, 45, 70, 52, 48, 49, 48, 51, 58, 56, 48], device.friendlyName=[84, 74, 65, 52, 55, 48, 32, 40, 84, 74, 65, 52, 55, 48, 45, 70, 52, 48, 49, 48, 51, 41]}

Как видите, атрибуты присутствуют в Android 11, а не в Android 6.0. Это проблема NSD_SERVICE на Android 6.0 или проблема POC, которую я разработал?

Класс NsdServiceInfo был добавлен в API 16, а метод getAttributes был добавлен в API 21. Так что обычно все должно работать правильно на Android 6.0 :(


person rolandl    schedule 25.05.2021    source источник


Ответы (1)


Проблема не в моем коде, а в Android SDK согласно этому билету.

В Android 5 и 6 мне нужно использовать стороннюю библиотеку, например Jmdns.

person rolandl    schedule 01.06.2021