android网络设备搜寻Nsd服务基本用法

注:文章大部分内容来源于http://blog.csdn.net/gophers/article/details/37968501,以下为个人梳理内容,限于水平,错误难免,望包含指正!

公司研发的主机使用Bonjour暴露自己的ip以供客户端搜寻,个人改写上述文章源码后大致整理流程如下,最终成功获得局域网下目标主机的ip地址

1.设置需要查找的设备的ServiceName和ServiceType,均为事先定义好的字符串:

//    目标设备名称及类型
    public static final String SERVICE_NAME = "test";
    public static final String SERVICE_TYPE = "_nb._tcp.";

2.配置Nsd服务的参数对象NsdServiceInfo,端口设为0对应自动获取IP(常用)

//        注册网络服务的名称、类型、端口
        NsdServiceInfo nsdServiceInfo = new NsdServiceInfo();
        nsdServiceInfo.setServiceName(SERVICE_NAME);
        nsdServiceInfo.setServiceType(SERVICE_TYPE);
        nsdServiceInfo.setPort(0);
3.准备Nsd服务所需NsdManager对象及三种Nsd服务回调监听器

//    nsdManager对象
    NsdManager nsdManager = null;
    //    注册监听器
    NsdManager.RegistrationListener registerListener = null;
    //    解析监听器
    NsdManager.ResolveListener resolveListener = null;
    //    搜寻监听器
    NsdManager.DiscoveryListener discoverListener = null;
4.创建三类监听器之一:注册监听器

// 实现一个网络服务的注册事件监听器,监听器的对象应该保存起来以便之后进行注销
        NsdManager.RegistrationListener nsRegListener = new NsdManager.RegistrationListener() {
            @Override
            public void onUnregistrationFailed(NsdServiceInfo arg0, int arg1) {
                Toast.makeText(getApplicationContext(), "Unregistration Failed", Toast.LENGTH_SHORT).show();
                LogErr("注销失败");
            }

            @Override
            public void onServiceUnregistered(NsdServiceInfo arg0) {
                Toast.makeText(getApplicationContext(), "Service Unregistered", Toast.LENGTH_SHORT).show();
                LogDebug("注销完成");
            }

            @Override
            public void onServiceRegistered(NsdServiceInfo arg0) {
                Toast.makeText(getApplicationContext(), "Service Registered", Toast.LENGTH_SHORT).show();
                LogDebug("注册完成");
            }

            @Override
            public void onRegistrationFailed(NsdServiceInfo arg0, int arg1) {
                Toast.makeText(getApplicationContext(), "Registration Failed", Toast.LENGTH_SHORT).show();
                LogErr("注册失败");
            }
        };
        return nsRegListener;
    }

5.创建三类监听器之二解析监听器

/**
     * 获取解析监听器
     *
     * @return
     */
    public NsdManager.ResolveListener getResolveListener() {
        NsdManager.ResolveListener listener = new NsdManager.ResolveListener() {
            @Override
            public void onResolveFailed(NsdServiceInfo nsdServiceInfo, int i) {
                LogErr("解析失败");
            }

            @Override
            public void onServiceResolved(NsdServiceInfo nsdServiceInfo) {
                LogDebug("解析成功,名称-->" + nsdServiceInfo.getHost());
//                注销服务
                unregisterNsdService();
            }
        };
        return listener;
    }

6.创建三类监听器之三搜寻监听器

/**
     * 调用设置好的nsdManager 搜寻服务
     *
     * @param nsdManager
     */
    public NsdManager.DiscoveryListener discoverService(NsdManager nsdManager) {
        NsdManager.DiscoveryListener nsDicListener = new NsdManager.DiscoveryListener() {
            @Override
            public void onStopDiscoveryFailed(String serviceType, int errorCode) {
                Toast.makeText(getApplicationContext(), "Stop Discovery Failed", Toast.LENGTH_SHORT).show();
                LogErr("Stop Discovery Failed");
            }

            @Override
            public void onStartDiscoveryFailed(String serviceType, int errorCode) {
                Toast.makeText(getApplicationContext(), "Start Discovery Failed", Toast.LENGTH_SHORT).show();
                LogErr("Start Discovery Failed");
            }

            @Override
            public void onServiceLost(NsdServiceInfo serviceInfo) {
                Toast.makeText(getApplicationContext(), "Service Lost", Toast.LENGTH_SHORT).show();
                LogErr("Service Lost");
            }

            @Override
            public void onServiceFound(NsdServiceInfo serviceInfo) {
                // 发现网络服务时就会触发该事件
                // 可以通过switch或if获取那些你真正关心的服务
                Toast.makeText(getApplicationContext(), "Service Found", Toast.LENGTH_SHORT).show();
                LogDebug("Service Found,serviceName-->" + serviceInfo.getServiceName());
            }

            @Override
            public void onDiscoveryStopped(String serviceType) {
                Toast.makeText(getApplicationContext(), "Discovery Stopped", Toast.LENGTH_SHORT).show();
                LogDebug("Discovery Stopped");
            }

            @Override
            public void onDiscoveryStarted(String serviceType) {
                Toast.makeText(getApplicationContext(), "Discovery Started", Toast.LENGTH_SHORT).show();
                LogDebug("Discovery Started");
            }
        };
        return nsDicListener;
    }

7.实例化NsdManager对象并设置以上三种监听器

//        获取注册监听器
        registerListener = getRegistrationListener();
//        注册网络服务的名称、类型、端口
        NsdServiceInfo nsdServiceInfo = new NsdServiceInfo();
        nsdServiceInfo.setServiceName(SERVICE_NAME);
        nsdServiceInfo.setServiceType(SERVICE_TYPE);
        nsdServiceInfo.setPort(port);
//        获取系统网络服务管理器,准备之后进行注册
        nsdManager = (NsdManager) getApplicationContext().getSystemService(Context.NSD_SERVICE);
//        设置注册监听器并开始注册
        nsdManager.registerService(nsdServiceInfo, NsdManager.PROTOCOL_DNS_SD, registerListener);
//        设置解析服监听器
        resolveListener = getResolveListener();
        nsdManager.resolveService(nsdServiceInfo, resolveListener);
//        设置搜寻监听器并开始搜寻
        discoverListener = discoverService(nsdManager);
        nsdManager.discoverServices(SERVICE_NAME, NsdManager.PROTOCOL_DNS_SD, discoverListener);


完成以上步骤,运行即可搜寻网络下ServiceName为"test",ServiceType为"_nb._tcp."的设备了,如愿获得了公司网络下主机的正确IP(...2.188):


注意事项

1.Internet权限

2.据说这个服务耗电量非常大不知是真是假,搜寻到服务后最好注销服务:

/**
     * 搜寻完成 注销服务
     */
    private void unregisterNsdService() {
        if (null != nsdManager) {
            nsdManager.stopServiceDiscovery(discoverListener);
            nsdManager.unregisterService(registerListener);
            LogDebug("注销完成!");
        }
    }

一知半解,不会看API,误人子弟媳妇概不负责,欢迎交流


  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
Android应用程序中搜索MDNS服务,可以使用Android网络框架中的Network Service Discovery(NSD)API。以下是搜索MDNS服务的一般步骤: 1. 创建NsdManager实例: ``` NsdManager nsdManager = (NsdManager) context.getSystemService(Context.NSD_SERVICE); ``` 2. 创建NsdManager.DiscoveryListener实例,并实现onDiscoveryStarted、onServiceFound、onServiceLost和onDiscoveryStopped等回调方法: ``` NsdManager.DiscoveryListener discoveryListener = new NsdManager.DiscoveryListener() { @Override public void onDiscoveryStarted(String regType) { // 发现服务 } @Override public void onServiceFound(NsdServiceInfo serviceInfo) { // 找到服务 } @Override public void onServiceLost(NsdServiceInfo serviceInfo) { // 丢失服务 } @Override public void onDiscoveryStopped(String serviceType) { // 停止搜索 } @Override public void onStartDiscoveryFailed(String serviceType, int errorCode) { // 开始搜索失败 } @Override public void onStopDiscoveryFailed(String serviceType, int errorCode) { // 停止搜索失败 } }; ``` 3. 创建NsdManager.ResolveListener实例,并实现onServiceResolved回调方法: ``` NsdManager.ResolveListener resolveListener = new NsdManager.ResolveListener() { @Override public void onResolveFailed(NsdServiceInfo serviceInfo, int errorCode) { // 解析服务信息失败 } @Override public void onServiceResolved(NsdServiceInfo serviceInfo) { // 解析服务信息成功 } }; ``` 4. 开始搜索MDNS服务: ``` nsdManager.discoverServices("_http._tcp", NsdManager.PROTOCOL_DNS_SD, discoveryListener); ``` 其中,第一个参数是服务的类型,可以根据实际情况进行修改。第二个参数是协议类型,NSD API支持DNS-SD协议和mDNS协议,这里使用DNS-SD协议。第三个参数是DiscoveryListener实例。 5. 在onServiceFound回调方法中,获取到NsdServiceInfo实例,然后调用它的resolve方法解析服务信息: ``` nsdManager.resolveService(serviceInfo, resolveListener); ``` 其中,第一个参数是NsdServiceInfo实例,第二个参数是ResolveListener实例。 6. 在onServiceResolved回调方法中,获取到服务的IP地址和端口号等信息,然后可以使用它们来连接服务。 注意,搜索MDNS服务需要在AndroidManifest.xml中添加以下权限: ``` <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE" /> ``` 同时,如果应用程序运行在Android 9.0及以上版本的设备上,则需要在AndroidManifest.xml中添加以下配置: ``` <application ... android:usesCleartextTraffic="true" ... > ```
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值