NsdManager discovery не работает на Android 9
Я пытался хорошо провести время, чтобы функция обнаружения NsdManager работала на Android 9. До этого она работала на любой версии Android без каких-либо проблем.
В целях тестирования я использую этот простой фрагмент кода, и в манифесте есть разрешение для "ИНТЕРНЕТ".
var nsdManager = context.getSystemService(Context.NSD_SERVICE) as NsdManager
nsdManager.discoverServices("_https._tcp", NsdManager.PROTOCOL_DNS_SD, object: NsdManager.DiscoveryListener {
override fun onDiscoveryStarted(serviceType: String?) {
println("DEBUG: onDiscoveryStarted $serviceType")
}
override fun onDiscoveryStopped(serviceType: String?) {
println("DEBUG: onDiscoveryStopped $serviceType")
}
override fun onServiceFound(serviceInfo: NsdServiceInfo?) {
println("DEBUG: onServiceFound $serviceInfo")
}
override fun onServiceLost(serviceInfo: NsdServiceInfo?) {
println("DEBUG: onServiceLost $serviceInfo")
}
override fun onStartDiscoveryFailed(serviceType: String?, errorCode: Int) {
println("DEBUG: onStartDiscoveryFailed $serviceType $errorCode")
}
override fun onStopDiscoveryFailed(serviceType: String?, errorCode: Int) {
println("DEBUG: onStopDiscoveryFailed $serviceType $errorCode")
}
})
Когда этот код выполняется, я не вижу сообщений отладки или ошибок в журналах.
С Wireshark я вижу транслируемый стандартный запрос mDNS для "_https._tcp.local" и все соответствующие ответы от всех ожидаемых устройств. Похоже, что ответы на Android не принимаются, потому что функция onServiceFound никогда не вызывается. На самом деле никакая функция, кроме "onDiscoveryStared", никогда не вызывается.
Я не видел каких-либо изменений на Android 9, почему это не должно работать, и любая помощь с радостью приветствуется. Возможно, я сделал что-то не так или пропустил изменения прав доступа в текущей версии Android.
ОБНОВЛЕНИЕ: На Samsung S9+ с текущей бета-версией Android 9 обнаружение службы работает без каких-либо проблем. На моем Pixel 3XL с другой стороны это не работает.
1 ответ
Хорошо, я нашел решение этой проблемы в старой проблеме Github. Очевидно, вам нужно иметь разрешение на многоадресную рассылку Wi-Fi и приобрести MulticastLock для получения многоадресных сообщений.
Мне еще не удалось найти какую-либо документацию по этому вопросу, и, похоже, это не является специфической проблемой для Android 9, а является настройкой по умолчанию в Google Pixel, чтобы отключить все прослушивание многоадресных пакетов для экономии заряда батареи.
Для тех, кто сталкивается с этой проблемой и не хочет погружаться в долгие проблемы, я добавил следующий код:
AndroidManifest.xml:
<uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE"/>
Браузер:
WifiManager wifi = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);
WifiManager.MulticastLock multicastLock = wifi.createMulticastLock("multicastLock");
multicastLock.setReferenceCounted(true);
multicastLock.acquire();
.
.
multicastLock.release(); // release after browsing