Слушатель уже используется (сервисное обнаружение)

Я не могу разрешить одну услугу, пока другой решается? Если это то, что означает ошибка... Каким образом ждать, пока он не будет разрешен?

@Override
public void onServiceFound(NsdServiceInfo service) {
    Log.d(TAG, "Service found. " + service);
    if (service.getServiceType().equals(SERVICE_TYPE)) {
        if (service.getServiceName().contains(mServiceName)) {
            mNsdManager.resolveService(service, mResolveListener);
        }
    }
}

java.lang.IllegalArgumentException: прослушиватель уже используется в android.net.nsd.NsdManager.resolveService(NsdManager.java:613)             на com.example.miguel.broadcast.LocalService $2.onServiceFound(LocalService.java:145)

Ответ 1

Вам не нужно ждать! Если вы посмотрите на javadocs для   resolveService (Служебная информация NsdServiceInfo, слушатель NsdManager.ResolveListener) здесь вы заметите, что для прослушивателя параметров он говорит: "получать обратный вызов при успехе или неудаче. Не может быть пустым. Невозможно использовать для активного разрешения службы".

Поэтому для этого нужно просто выполнить следующее:

mNsdManager.resolveService(service, new MyResolveListener());

Где MyResolveListener:

private class MyResolveListener implements NsdManager.ResolveListener {
        @Override
        public void onResolveFailed(NsdServiceInfo serviceInfo, int errorCode) {
            //your code
        }

        @Override
        public void onServiceResolved(NsdServiceInfo serviceInfo) {
            //your code
        }
    }

надеюсь, что это поможет:)

Ответ 2

У меня тоже была эта проблема, и я следил за реализацией Android NsdHelper, изложенной в NsdChat здесь. В этом примере показано создание единственного NsdManager.ResolveListener mResolveListener в классе NsdHelper и использование этого ResolveListener для всех вызовов NsdManager.resolveService.

Из здесь Я читал, что "отдельный слушатель должен использоваться для каждого активного запроса регистрации или обнаружения".

Поэтому вместо использования переменной класса mResolveListener создайте новый прослушиватель каждый раз, когда вы вызываете mNsdManager.resolveService:

@Override
public void onServiceFound(NsdServiceInfo serviceInfo) {
    Log.d(TAG, "Service found: "+ serviceInfo);
    if (serviceInfo.getServiceType().equals(SERVICE_TYPE)){
        mNsdManager.resolveService(serviceInfo, new NsdManager.ResolveListener() {
            @Override
            public void onResolveFailed(NsdServiceInfo serviceInfo, int errorCode) {
                Log.e(TAG, "Resolve Failed: " + serviceInfo);
            }
            @Override
            public void onServiceResolved(NsdServiceInfo serviceInfo) {
                Log.i(TAG, "Service Resolved: " + serviceInfo);
            }
        });
    }
}

Ответ 3

Вам нужно убедиться, что вы не проходите в уже прослушанном объекте-слушателе. Вы можете увидеть фиксацию, которая привела к такому изменению поведения здесь.

Вот текст сообщения фиксации:

Документируйте и соблюдайте правило "один запрос на слушателя"

API и реализация NsdManager подразумевают, что отдельный Слушатель должен использоваться для каждой активной регистрации или обнаружения запрос. Это формально не документировано или не соблюдается надлежащим образом, и странные и непредсказуемые вещи случаются, если приложение использует Слушатель для нескольких запросов одновременно.

Обновите документацию, чтобы сделать это явным требованием.

Принудительное ограничение при отправке нового запроса для обработка; если прослушиватель уже используется для отслеживания активного запрос, исключение.

Документируйте тот факт, что приложения должны отменить регистрацию служб и отменить службы, когда приложение остановлено (в KitKat и ранее релизы, они будут протекать, если это не сделано.)

Переупорядочить операцию "освободить слушателя", чтобы произойти до слушателя обратный вызов, так что слушатель может повторно использоваться приложением один раз обратный вызов был введен - это устраняет состояние гонки. Документируйте это.

Pass 2: опечатки, добавлена ​​документация об уровне API, изменена на использование явно определенное возвращаемое значение для "занятого слушателя".

Кроме того, просто предупреждение о том, что если вы загрузили образец проекта NsdChat с сайта разработчиков Android (т.е. NsdChat.zip или что-то в этом роде), этот код проекта, скорее всего, устарел.

Попробуйте использовать последний код на главной ветки вместо этого... вы можете скопировать и вставить его в свой образец проекта из здесь.