5

每当我使用 registerService 函数时,它都会给出代码错误 0 的异常。 1) 我正在创建一个本地聊天服务应用程序,我需要在其中进行本地服务广播,并且在这样做的同时,无论我做什么,我都被卡住了,注册总是以错误代码 0 失败。我在 onResume() 或 onPause() 块中没有多个注册实例。2) Logcat 只显示

尝试完成输入事件,但输入事件接收器已被释放。

每当我点击右上角的注册服务按钮时。

这是我的代码:

public String mServiceName = "nearByDevices";
NsdServiceInfo mService;
/**
 * ATTENTION: This was auto-generated to implement the App Indexing API.
 * See https://g.co/AppIndexing/AndroidStudio for more information.
 */
private GoogleApiClient client;

   public void registerService(int port) {
    // Create the NsdServiceInfo object, and populate it.
         // Cancel any previous registration request
       initializeRegistrationListener();
       NsdServiceInfo serviceInfo  = new NsdServiceInfo();
       serviceInfo.setServiceName(mServiceName);
       serviceInfo.setServiceType(SERVICE_TYPE);

    serviceInfo.setPort(port);
       NsdHelper(this);
       mNsdManager = (NsdManager) mContext.getSystemService(Context.NSD_SERVICE);
       mNsdManager.registerService(serviceInfo,NsdManager.PROTOCOL_DNS_SD, mRegistrationListener);


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



public void initializeRegistrationListener() {
    mRegistrationListener = new NsdManager.RegistrationListener() {
        @Override
        public void onServiceRegistered(NsdServiceInfo NsdServiceInfo) {
            mServiceName = NsdServiceInfo.getServiceName();
            Toast.makeText(MainActivity.this, "Service registered:" + mServiceName, Toast.LENGTH_LONG).show();
        }

        @Override
        public void onRegistrationFailed(NsdServiceInfo arg0, int arg1) {
            Toast.makeText(MainActivity.this, "Service registration failed:" + arg1, Toast.LENGTH_LONG).show();
        }
        @Override
        public void onServiceUnregistered(NsdServiceInfo arg0) {
            Toast.makeText(MainActivity.this, "Service unregistered:" + arg0.getServiceName(), Toast.LENGTH_LONG).show();
        }

        @Override
        public void onUnregistrationFailed(NsdServiceInfo serviceInfo, int errorCode) {
            Toast.makeText(MainActivity.this, "Service unregistration failed:" + errorCode, Toast.LENGTH_LONG).show();
        }
    };
}
public void initializeDiscoveryListener() {

    // Instantiate a new DiscoveryListener
    mDiscoveryListener = new NsdManager.DiscoveryListener() {

        //  Called as soon as service discovery begins.
        @Override
        public void onDiscoveryStarted(String regType) {
            Toast.makeText(MainActivity.this, "Service Discovery Started", Toast.LENGTH_LONG).show();
        }

        @Override
        public void onServiceFound(NsdServiceInfo service) {
            // A service was found!  Do something with it.
            Toast.makeText(MainActivity.this, "Service Discovery Success:" + service.getServiceName(), Toast.LENGTH_LONG).show();
            if (!service.getServiceType().equals(SERVICE_TYPE)) {
                // Service type is the string containing the protocol and
                // transport layer for this service.
                Toast.makeText(MainActivity.this, "Unknown Service Type" + service.getServiceType(), Toast.LENGTH_LONG).show();
            } else if (service.getServiceName().equals(mServiceName)) {

                Toast.makeText(MainActivity.this, "Same Machine" + mServiceName, Toast.LENGTH_LONG).show();
            } else {
                devices.add((service.getServiceName()).toString());                }
        }
        @Override
        public void onServiceLost(NsdServiceInfo service) {
            Toast.makeText(MainActivity.this, "Service Lost:" + service.getServiceName(), Toast.LENGTH_LONG).show();
            if (mService == service) {
                mService = null;
            }
        }
        @Override
        public void onDiscoveryStopped(String serviceType) {
            Toast.makeText(MainActivity.this, "Discovery Stopped" + serviceType, Toast.LENGTH_LONG).show();
        }
        @Override
        public void onStartDiscoveryFailed(String serviceType, int errorCode) {
            Toast.makeText(MainActivity.this, "Discovery failed. Error Code" + errorCode, Toast.LENGTH_LONG).show();
        }
        @Override
        public void onStopDiscoveryFailed(String serviceType, int errorCode) {
            Toast.makeText(MainActivity.this, "Discovery failed. Error Code" + errorCode, Toast.LENGTH_LONG).show();
        }
    };
}
        public void initializeResolveListener() {
            mResolveListener = new NsdManager.ResolveListener() {

                @Override
                public void onResolveFailed(NsdServiceInfo serviceInfo, int errorCode) {
                    // Called when the resolve fails.  Use the error code to debug.
                    Log.e(TAG, "Resolve failed" + errorCode);
                }

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

                    if (serviceInfo.getServiceName().equals(mServiceName)) {
                        Log.d(TAG, "Same IP.");
                        return;
                    }
                    mService = serviceInfo;
                    int port = mService.getPort();
                    InetAddress host = mService.getHost();
                }



    };
}
    public void discoverServices() {
    stopDiscovery();  // Cancel any existing discovery request
    initializeDiscoveryListener();
    mNsdManager.discoverServices(
            SERVICE_TYPE, NsdManager.PROTOCOL_DNS_SD, mDiscoveryListener);
}
public void stopDiscovery() {
    if (mDiscoveryListener != null) {
        try {
            mNsdManager.stopServiceDiscovery(mDiscoveryListener);
        } finally {
        }
        mDiscoveryListener = null;
    }
} public NsdServiceInfo getChosenServiceInfo() {
    return mService;
}
public void tearDown() {
    if (mRegistrationListener != null) {
        try {
            mNsdManager.unregisterService(mRegistrationListener);
        } finally {
        }
        mRegistrationListener = null;
    }
}

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);
    //initializeServerSocket();
    devices = new ArrayList<String>();


    ArrayAdapter adapter = new ArrayAdapter(this, R.layout.main_listview, devices);
    ListView listView = (ListView) findViewById(R.id.device_list);
    if(devices.isEmpty()) {
    devices.add("No Devices Nearby");
        listView.setAdapter(adapter);
    }
    else
    listView.setAdapter(adapter);
    // ATTENTION: This was auto-generated to implement the App Indexing API.
    // See https://g.co/AppIndexing/AndroidStudio for more information.
    client = new GoogleApiClient.Builder(this).addApi(AppIndex.API).build();

}


@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.menu_main, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();

    //noinspection SimplifiableIfStatement
    switch (id) {
        case R.id.register:
           // initializeServerSocket();
            registerService(65010);
            return true;
        case R.id.discover:
            discoverServices();
            return true;
        default:
            return super.onOptionsItemSelected(item);
    }


}

@Override
public void onStart() {
    super.onStart();

    // ATTENTION: This was auto-generated to implement the App Indexing API.
    // See https://g.co/AppIndexing/AndroidStudio for more information.
    client.connect();
    Action viewAction = Action.newAction(
            Action.TYPE_VIEW, // TODO: choose an action type.
            "Main Page", // TODO: Define a title for the content shown.
            // TODO: If you have web page content that matches this app activity's content,
            // make sure this auto-generated web page URL is correct.
            // Otherwise, set the URL to null.
            Uri.parse("http://host/path"),
            // TODO: Make sure this auto-generated app deep link URI is correct.
            Uri.parse("android-app://com.example.devesh1.mynewapp/http/host/path")
    );
    AppIndex.AppIndexApi.start(client, viewAction);
}

@Override
public void onStop() {
    super.onStop();

    // ATTENTION: This was auto-generated to implement the App Indexing API.
    // See https://g.co/AppIndexing/AndroidStudio for more information.
    Action viewAction = Action.newAction(
            Action.TYPE_VIEW, // TODO: choose an action type.
            "Main Page", // TODO: Define a title for the content shown.
            // TODO: If you have web page content that matches this app activity's content,
            // make sure this auto-generated web page URL is correct.
            // Otherwise, set the URL to null.
            Uri.parse("http://host/path"),
            // TODO: Make sure this auto-generated app deep link URI is correct.
            Uri.parse("android-app://com.example.devesh1.mynewapp/http/host/path")
    );
    AppIndex.AppIndexApi.end(client, viewAction);
    client.disconnect();
}

}
4

1 回答 1

18

我在尝试使用 NsdManager 注册服务时也遇到了这个问题。最后我发现服务类型必须遵守NsdManager 文档中作为示例描述的格式。澄清一下,格式是:“_name._communicationprotocol” 例如:“_ipp._tcp”和“_http._tcp”。如果没有,将导致 onRegistrationFailed 回调,errorCode=0

顺便提一句。来自 NsdManager 的调试日志不会像来自您的应用程序一样输出到 Logcat。您必须使用“无过滤器”查看日志才能查看来自 NSD 服务的调试信息

更新:再次偶然发现此错误。正在搜索_name._tcp.local但我应该只搜索_name._tcp

于 2016-05-11T10:54:23.237 回答