Error en servicio NSD de Android 6.0

NSD es un servicio que se США локальный para descubrir otras aplicaciones que ejecutan el mismo servicio en la red. Чиновник Estoy intentando hacer funcionar el ejemplo de NSD que ese encuentra en el sitio de Android.

Сольный en Android El problema es que al seleccionar Search la aplicación se cae 6 (Tengo una tablet подставляют андроид 4.4.4 y никакой da el error). Al volver abrir la app sucede lo mismo. Ошибка El es el siguiente:

java.lang.IllegalStateException: Could not execute method for android:onClick
    at android.view.View$DeclaredOnClickListener.onClick(View.java:4741)
    at android.view.View.performClick(View.java:5698)
    at android.widget.TextView.performClick(TextView.java:10846)
    at android.view.View$PerformClick.run(View.java:22565)
    at android.os.Handler.handleCallback(Handler.java:739)
    at android.os.Handler.dispatchMessage(Handler.java:95)
    at android.os.Looper.loop(Looper.java:158)
    at android.app.ActivityThread.main(ActivityThread.java:7230)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)
 Caused by: java.lang.reflect.InvocationTargetException
    at java.lang.reflect.Method.invoke(Native Method)
    at android.view.View$DeclaredOnClickListener.onClick(View.java:4736)
    at android.view.View.performClick(View.java:5698) 
    at android.widget.TextView.performClick(TextView.java:10846) 
    at android.view.View$PerformClick.run(View.java:22565) 
    at android.os.Handler.handleCallback(Handler.java:739) 
    at android.os.Handler.dispatchMessage(Handler.java:95) 
    at android.os.Looper.loop(Looper.java:158) 
    at android.app.ActivityThread.main(ActivityThread.java:7230) 
    at java.lang.reflect.Method.invoke(Native Method) 
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120) 
 Caused by: java.lang.IllegalArgumentException: listener already in use
    at android.net.nsd.NsdManager.discoverServices(NsdManager.java:559)
    at com.miaplicacion.configurador.NsdHelper.discoverServices(NsdHelper.java:140)
    at com.miaplicacion.configurador.NsdChatActivity.clickDiscover(NsdChatActivity.java:58)
    at java.lang.reflect.Method.invoke(Native Method) 
    at android.view.View$DeclaredOnClickListener.onClick(View.java:4736) 
    at android.view.View.performClick(View.java:5698) 
    at android.widget.TextView.performClick(TextView.java:10846) 
    at android.view.View$PerformClick.run(View.java:22565) 
    at android.os.Handler.handleCallback(Handler.java:739) 
    at android.os.Handler.dispatchMessage(Handler.java:95) 
    at android.os.Looper.loop(Looper.java:158) 
    at android.app.ActivityThread.main(ActivityThread.java:7230) 
    at java.lang.reflect.Method.invoke(Native Method) 
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120) 

Принципал Creo que el error es por que "слушатель, уже используемый". Pero никакой se Комо solucionarlo.

Сын Estos Лос códigos adicionales:

activity_main.xml (el código del botón)

NsdChatActivity (щелчок el código de la Activity que recibe el evento)

public void clickDiscover(View v) {
    mNsdHelper.discoverServices();
}

NsdHelper

public void discoverServices() {
    mNsdManager.discoverServices(
            SERVICE_TYPE, NsdManager.PROTOCOL_DNS_SD, mDiscoveryListener);
}

2
задан 23.03.2017, 22:51
2 ответа

Реальная проблема в этом примере на NSD:

Caused by: java.lang. IllegalArgumentException: listener already in используйте

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

//mNsdManager.resolveService(service, mResolveListener); //Incorrecto.
mNsdManager.resolveService(service, new MyResolveListener());

Класс в вопросе ser¦ - в:

private class MyResolveListener implements NsdManager.ResolveListener {
    @Override
    public void onResolveFailed(NsdServiceInfo serviceInfo, int errorCode) {
        Log.e(TAG, "*Jorgesys Resolve failed" + errorCode);
    }

    @Override
    public void onServiceResolved(NsdServiceInfo serviceInfo) {
        Log.e(TAG, "*Jorgesys Resolve Succeeded. " + serviceInfo);

        if (serviceInfo.getServiceName().equals(mServiceName)) {
            Log.d(TAG, "Same IP.");
            return;
        }
        mService = serviceInfo;
    }
}

Добавил класс полного NsdHelper:

/*
 * Copyright (C) 2012 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.example.android.nsdchat;

import android.content.Context;
import android.net.nsd.NsdServiceInfo;
import android.net.nsd.NsdManager;
import android.util.Log;

public class NsdHelper {

    Context mContext;

    NsdManager mNsdManager;
    NsdManager.ResolveListener mResolveListener;
    NsdManager.DiscoveryListener mDiscoveryListener;
    NsdManager.RegistrationListener mRegistrationListener;

    public static final String SERVICE_TYPE = "_http._tcp.";

    public static final String TAG = "NsdHelper";
    public String mServiceName = "NsdChat";

    NsdServiceInfo mService;

    public NsdHelper(Context context) {
        mContext = context;
        mNsdManager = (NsdManager) context.getSystemService(Context.NSD_SERVICE);
    }

    public void initializeNsd() {
        //initializeResolveListener();
        //initializeDiscoveryListener();
        //initializeRegistrationListener();
        //mNsdManager.init(mContext.getMainLooper(), this);
    }

    public void registerService(int port) {
        NsdServiceInfo serviceInfo  = new NsdServiceInfo();
        serviceInfo.setPort(port);
        serviceInfo.setServiceName(mServiceName);
        serviceInfo.setServiceType(SERVICE_TYPE);
        mRegistrationListener = new MyRegistrationListener(); //Jorgesys
        mNsdManager.registerService(
                serviceInfo, NsdManager.PROTOCOL_DNS_SD, mRegistrationListener);

    }

    public void discoverServices() {
        mDiscoveryListener = new MyDiscoveryListener(); //Jorgesys
        mNsdManager.discoverServices(
                SERVICE_TYPE, NsdManager.PROTOCOL_DNS_SD, mDiscoveryListener);
    }

    public void stopDiscovery() {
        mNsdManager.stopServiceDiscovery(mDiscoveryListener);
    }

    public NsdServiceInfo getChosenServiceInfo() {
        return mService;
    }

    public void tearDown() {
        mNsdManager.unregisterService(mRegistrationListener);
    }

    /*** New classes to avoid : java.lang.IllegalArgumentException: listener already in use ***/

    private class MyResolveListener implements NsdManager.ResolveListener {
        @Override
        public void onResolveFailed(NsdServiceInfo serviceInfo, int errorCode) {
            Log.e(TAG, "*Jorgesys Resolve failed" + errorCode);
        }

        @Override
        public void onServiceResolved(NsdServiceInfo serviceInfo) {
            Log.e(TAG, "*Jorgesys Resolve Succeeded. " + serviceInfo);

            if (serviceInfo.getServiceName().equals(mServiceName)) {
                Log.d(TAG, "Same IP.");
                return;
            }
            mService = serviceInfo;
        }
    }

    //mDiscoveryListener = new NsdManager.DiscoveryListener() {

    private class MyRegistrationListener implements NsdManager.RegistrationListener {

        @Override
        public void onServiceRegistered(NsdServiceInfo NsdServiceInfo) {
            mServiceName = NsdServiceInfo.getServiceName();
        }

        @Override
        public void onRegistrationFailed(NsdServiceInfo arg0, int arg1) {
        }

        @Override
        public void onServiceUnregistered(NsdServiceInfo arg0) {
        }

        @Override
        public void onUnregistrationFailed(NsdServiceInfo serviceInfo, int errorCode) {
        }
    }

    private class MyDiscoveryListener implements NsdManager.DiscoveryListener {
        @Override
        public void onDiscoveryStarted(String regType) {
            Log.d(TAG, "Service discovery started");
        }

        @Override
        public void onServiceFound(NsdServiceInfo service) {
            Log.d(TAG, "Service discovery success" + service);
            if (!service.getServiceType().equals(SERVICE_TYPE)) {
                Log.d(TAG, "Unknown Service Type: " + service.getServiceType());
            } else if (service.getServiceName().equals(mServiceName)) {
                Log.d(TAG, "Same machine: " + mServiceName);
            } else if (service.getServiceName().contains(mServiceName)){
                mNsdManager.resolveService(service, new MyResolveListener());
            }
        }

        @Override
        public void onServiceLost(NsdServiceInfo service) {
            Log.e(TAG, "service lost" + service);
            if (mService == service) {
                mService = null;
            }
        }

        @Override
        public void onDiscoveryStopped(String serviceType) {
            Log.i(TAG, "Discovery stopped: " + serviceType);
        }

        @Override
        public void onStartDiscoveryFailed(String serviceType, int errorCode) {
            Log.e(TAG, "Discovery failed: Error code:" + errorCode);
            mNsdManager.stopServiceDiscovery(this);
        }

        @Override
        public void onStopDiscoveryFailed(String serviceType, int errorCode) {
            Log.e(TAG, "Discovery failed: Error code:" + errorCode);
            mNsdManager.stopServiceDiscovery(this);
        }

    }
}
1
ответ дан 24.11.2019, 10:25

В documentaci¦n говорит:

NsdManager. DiscoveryListener: The listener notifies of в successful discovery and is used to stop discovery on this serviceType through в call on stopServiceDiscovery (NsdManager. DiscoveryListener). Cannot be null. Cannot be in используйте for an включите service discovery.

Проблема кажется века жизни твоего listener. Вероятно mDiscoveryListener, которые ты перемещаешь уже эта в использовании. Отнесись к создавать Listener осуществляя DiscoveryListener, на которых ты настаиваешь и сохраняешь в discoverServices.

public class MiDiscoveryListener implements DiscoveryListener{
    //...
}

и создай это в момент, когда ты начинаешь тем, что открываешь услуги.

public void discoverServices() {
    // Solamente tratemos de descubrir servicios si todavía no lo estamos haciendo
    if (null==mDiscoveryListener)
        mDiscoveryListener = new MiDiscoveryListener();
        mNsdManager.discoverServices(SERVICE_TYPE, NsdManager.PROTOCOL_DNS_SD, mDiscoveryListener);
    }
}

The application should call stopServiceDiscovery (NsdManager. DiscoveryListener) when discovery of this service type is не longer required, and/or whenever the application is paused or stopped.

onStop(){
    super.onStop();
    if (null!=mDiscoveryListener){
        mNsdManager.stopDiscovery(mDiscoveryListener);
        mDiscoveryListener=null;
    }
}

Вероятно у тебя будет, что diseñar немного mÃ: s точный жизненные циклы твоей активности, и когда начинается открытие услуг.

1
ответ дан 24.11.2019, 10:25
  • 1
    Я верю в то, что está так. Когда я говорю " пример документации oficial" я имею в виду того, который может загружаться из соединения, Восток - cò я говорю, что я завершаю developer.android.com/shareables/training/NsdChat.zip podrí схвати проверять, если у тебя есть возможность в android, 6? Дело в том, что в 4.4 точно тот же код не дает мне ошибку: ( – UselesssCat 24.03.2017, 00:52
  • 2
    Если, что он меняет между 4.4 и 6, состоит в том, что ты не можешь повторно использовать listener, но что ты должен работать с одним снова настоявшим. – Stefan Nolde 24.03.2017, 07:31