mDNS即组播DNS(multicast DNS)。使用5353端口,在内网没有DNS服务器时,就会出现此组播信息。mDNS 基于 UDP 协议。.com/

在一个局域网内,每个进入局域网的主机,如果开启了mDNS服务的话,都会向局域网内的所有主机组播一个消息,告诉局域网内所有设备自己提供什么服务,服务名称,IP,端口等信息。比如A主机提供了某服务,A开启了mDNS,向局域网内广播发送mDNS消息:我的IP是 192.168.1.101,端口是9091。如果局域网中的B需要该服务,则 B 主机向局域网内广播 mDNS 服务请求,并且最终获得有一个IP地址为 192.168.1.100,端口号是 9091 的主机,也就是 A 主机提供 的服务 服务,所以 B 主机就知道了 A 主机的 IP 地址和端口号了。在我的第一篇文章中发送UDP数据包的IP和端口就是通过此方法获取的。

IPActivity.java:


package com.wifi.main;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.jmdns.JmDNS;
import javax.jmdns.ServiceEvent;
import javax.jmdns.ServiceInfo;
import javax.jmdns.ServiceListener;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.wifi.WifiManager;
import android.net.wifi.WifiManager.MulticastLock;
import android.os.Bundle;
import android.os.Handler;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import com.example.jushi_blub.R;
import com.wifi.connect.WIFIAdmin;
import com.wifi.mdns.Utils;
import com.wifi.utils.MyApplication;
import com.wifi.utils.WifiUtils;

public class IPActivity extends Activity implements OnClickListener{
public static final String TAG = "IPActivity";  
    private Button StartConnect,scan;
    //目的主机ip和端口
    private EditText IP,Port;
    //本机监听端口
    //private EditText LOCAL_PORT;
    private TextView destination,porttext;
    
    //目的ip和端口
    private String Server_IP;
    private String Server_Port;
    
    private Map<String, Object> map;
    private MyApplication myApplication;
    
    private WIFIAdmin wifiAdmin;
    private WifiManager mWifiManager;
    
    Handler handler = new Handler();
    
    //mdns服务类型
    private String type = "_udpserver._udp.local.";
//    private String type = "_sleep-proxy._udp.local.";
    private JmDNS jmdns = null;
    private ServiceListener listener = null;
    private ServiceInfo serviceInfo;
    
    //组播锁
    private MulticastLock lock;
    //展示扫描的mDNS服务
    private ListView mlistView;
    private Utils utils = new Utils();
    
  //存放扫描的mDNS服务
private List<Map<String, Object>> mdnsList= new ArrayList<Map<String,Object>>();
    private Map<String, Object> mdnsMap;
private boolean flag =true;
    
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_ip);
        initViews();
        
        mlistView.setOnItemClickListener(new OnItemClickListener() {

@Override
public void onItemClick(AdapterView<?> arg0, View arg1, int position,
long id) {

AlertDialog.Builder alert = new AlertDialog.Builder(IPActivity.this);
Server_IP = mdnsList.get(position).get("Service_IP").toString();  
Server_Port = mdnsList.get(position).get("Service_Port").toString();  
            alert.setTitle(Server_IP);  
            alert.setMessage("点击获取");

alert.setPositiveButton("获取", new DialogInterface.OnClickListener(){  
                @Override  
                public void onClick(DialogInterface dialog, int which) {  
                    IP.setText(Server_IP);
                    Port.setText(Server_Port);
                    
                }  
            });  
            alert.setNegativeButton("取消", new DialogInterface.OnClickListener(){  
                @Override  
                public void onClick(DialogInterface dialog, int which) {  
                    //  
                    //mWifiAdmin.removeWifi(mWifiAdmin.getNetworkId());  
                }  
            }); 
            alert.create();  
            alert.show();  
            
}
});
       
    }
    
    //开启查找服务
    private void setUp() {
    //打开组播 
        openBroadcast();
        
        try {
        //InetAddress ip = InetAddress.getByName("192.168.0.108");
        jmdns = JmDNS.create();
        //创建mDNS服务
        //serviceInfo = ServiceInfo.create(type, "AndroidTest",5353, "plain test service from android");
        //jmdns.registerService(serviceInfo);
            
            //监听mDNS服务
            jmdns.addServiceListener(type, listener = new ServiceListener() {

@Override
                public void serviceResolved(ServiceEvent event) {
//            mdnsMap = new HashMap<String, Object>();
//
//            mdnsMap.put("Service_IP", ev.getInfo().getHostAddress());
//             mdnsMap.put("Service_Port", ev.getInfo().getPort());
//             if (!mdnsList.contains(mdnsMap)) {
//             mdnsList.add(mdnsMap);
//             }
           
            //ServiceInfo serviceInfo = jmdns.getServiceInfo(type, "light udpServer",1);
           
            String addr = "";
                if (event.getInfo().getHostAddress() != null && event.getInfo().getInetAddress()!=null) {
                        addr = event.getInfo().getHostAddress();
                    }
                mdnsMap = new HashMap<String, Object>();
               
                mdnsMap.put("Service_IP", addr);
                mdnsMap.put("Service_Port", event.getInfo().getPort());
                mdnsMap.put("service_Name", event.getName());
               
                if (!mdnsList.contains(mdnsMap)) {
                mdnsList.add(mdnsMap);
                }
               
                }

@Override
                public void serviceRemoved(ServiceEvent ev) {
                 
                }

@Override
                public void serviceAdded(ServiceEvent event) {
                    // Required to force serviceResolved to be called again (after the first search)
                    jmdns.requestServiceInfo(event.getType(), event.getName(), 1);
                }
});
            
        } catch (IOException e) {
            e.printStackTrace();
            return;
        } 
    }
    
 
    @Override
    protected void onStart() {
    super.onStart();

}
    
    
    /**
     * 打开wifi组播服务
     */
    public void openBroadcast() {
    mWifiManager = (WifiManager) getSystemService(android.content.Context.WIFI_SERVICE);  
    if (!mWifiManager.isWifiEnabled()) {
    mWifiManager.setWifiEnabled(true);
}
    lock =mWifiManager.createMulticastLock(getClass().getSimpleName());  
    lock.setReferenceCounted(true);  
    lock.acquire();//to receive multicast packets  
    }

/**
     * ListView的Item显示
     * @author Sunward
     *
     */
    public class MyAdapter extends BaseAdapter{
LayoutInflater inflater;
List<Map<String, Object>> list;

public MyAdapter(Context context, List<Map<String, Object>> list) {
this.inflater = LayoutInflater.from(context);
this.list = list;
}

@Override
public int getCount() {
return list.size();  
}

@Override
public Object getItem(int position) {
return list.get(position);  
}

@Override
public long getItemId(int position) {
return position;  
}

//忽略指定的警告
@SuppressLint({ "ViewHolder", "InflateParams" })  
@Override
public View getView(int position, View convertView, ViewGroup parent) {
//针对每一个数据(即每一个List ID)创建一个ListView实例,
View view = null;
view = inflater.inflate(R.layout.wifi_listitem, null);
Map<String, Object> result = list.get(position);
TextView wifi_ssid=(TextView) view.findViewById(R.id.ssid);  
ImageView wifi_level=(ImageView) view.findViewById(R.id.wifi_level); 
wifi_ssid.setText(result.get("service_Name")+" "+result.get("Service_IP"));  
            wifi_level.setImageResource(R.drawable.wifi);  
            //判断信号强度,显示对应的指示图标    
             return view;  
}

}
    
    
    /**
     * 控件初始化
     */
    public void initViews(){
    //连接
    StartConnect = (Button) findViewById(R.id.startCon);
    //扫描
    scan = (Button) findViewById(R.id.scanService);
    IP = (EditText) findViewById(R.id.IPText); 
        Port = (EditText) findViewById(R.id.PortText);
        //LOCAL_PORT = (EditText) findViewById(R.id.LOCAL_PORT);
        
        destination = (TextView) findViewById(R.id.destination);
        porttext = (TextView) findViewById(R.id.porttext);
        
        //扫描的mdns服务
        mlistView=(ListView) findViewById(R.id.mdns_list); 
        
        StartConnect.setOnClickListener(IPActivity.this);
        scan.setOnClickListener(this);
        
    }
    
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.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();
        if (id == R.id.wifi_config) {
        Intent intent = new Intent();
        intent.setClass(IPActivity.this, WIFIActivity.class);
        this.startActivity(intent);
        finish();
            return true;
        }
        return super.onOptionsItemSelected(item);
    }

/**
     * 返回键事件
     */
    @Override    
    public void onBackPressed() {    
        Intent intent = new Intent();
        intent.setClass(this, MainActivity.class);
        startActivity(intent);
        finish();
    } 
    
    /**
     * 按钮点击事件
     */
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.startCon:
myApplication = (MyApplication)this.getApplicationContext();
if (IP.getText().toString().trim().equals("")||
//LOCAL_PORT.getText().toString().trim().equals("")||
Port.getText().toString().trim().equals("")) {
Toast.makeText(IPActivity.this, "请输入完整", Toast.LENGTH_SHORT).show();  
}else {
Server_IP = IP.getText().toString();
Server_Port = Port.getText().toString();
Toast.makeText(IPActivity.this,Server_IP+"   "+Server_Port, Toast.LENGTH_SHORT).show();  
//Application存储全局变量
map = new HashMap<String, Object>();
map.put("IP", Server_IP);
map.put("Port", Server_Port);
map.put("LOCAL_PORT", 8929);

myApplication.setMap(map);
  
Intent intent = new Intent();  
intent.setClass(IPActivity.this,MainActivity.class);

startActivity(intent);  
finish();
}
break;

case R.id.scanService:
new Thread(){
        @Override  
           public void run()  
           {  
//         Looper.prepare();
setUp();
//加载扫描到的服务
//         Looper.loop();
           }  
        }.start();
        while(flag){  
        if (mdnsList.size()>0) {
        ListAdapter mAdapter = new MyAdapter(IPActivity.this, mdnsList);
        mlistView.setAdapter(mAdapter);  
        new WifiUtils.Utility().setListViewHeightBasedOnChildren(mlistView);  
        flag=false;
}
       
        } 
        break;
        default:  
            break;  
        }

}

}

布局文件activity_ip.xml:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.wifi.main.IPActivity" >
 
    <ListView
    android:id="@+id/mdns_list"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_below="@+id/startCon"
     >
</ListView>

<Button
        android:id="@+id/scanService"
        android:layout_width="100dp"
        android:layout_height="wrap_content"
        android:layout_below="@+id/IPText"
        android:layout_marginTop="80dp"
        android:layout_toRightOf="@+id/destination"
        android:text="扫描" />

<TextView
        android:id="@+id/porttext"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:layout_below="@+id/destination"
        android:layout_alignLeft="@+id/mdns_list"
        android:text="站点端口" />

<Button
        android:id="@+id/startCon"
        android:layout_width="100dp"
        android:layout_height="wrap_content"
        android:layout_alignBaseline="@+id/scanService"
        android:layout_alignBottom="@+id/scanService"
        android:layout_marginLeft="55dp"
        android:layout_toRightOf="@+id/scanService"
        android:text="连接" />

<TextView
        android:id="@+id/destination"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@+id/porttext"
        android:layout_alignParentTop="true"
        android:layout_marginTop="27dp"
        android:text="站点IP" />

<EditText
        android:id="@+id/PortText"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignBaseline="@+id/porttext"
        android:layout_alignBottom="@+id/porttext"
        android:layout_alignLeft="@+id/IPText"
        android:layout_alignRight="@+id/mdns_list"
        android:ems="10"
        android:height="35dip"
        android:hint="Port"
        android:width="60dip" />

<EditText
        android:id="@+id/IPText"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignBottom="@+id/destination"
        android:layout_alignRight="@+id/mdns_list"
        android:layout_toRightOf="@+id/porttext"
        android:ems="10"
        android:hint="Please input IP"
        android:width="160dip" >

<requestFocus />
    </EditText>

</RelativeLayout>

监听mDNS服务用的是jmDNS,大家可以去github下,里面也有教程,注意要下最新版本的,有的版本只能在Android5.1以下使用,很是头疼,当初我弄了好久也没找到问题所在。导入JmDNS的包,使用很简单,在上面的代码中,主要的部分是

jmdns.addServiceListener(type, listener = new ServiceListener() {

@Override
                public void serviceResolved(ServiceEvent event) {

String addr = "";
                if (event.getInfo().getHostAddress() != null && event.getInfo().getInetAddress()!=null) {
                        addr = event.getInfo().getHostAddress();
                    }
                mdnsMap = new HashMap<String, Object>();
                
                mdnsMap.put("Service_IP", addr);
                mdnsMap.put("Service_Port", event.getInfo().getPort());
                mdnsMap.put("service_Name", event.getName());
                
                if (!mdnsList.contains(mdnsMap)) {
                mdnsList.add(mdnsMap);
                }
                
                }
                @Override
                public void serviceRemoved(ServiceEvent ev) {
                 
                }
                @Override
                public void serviceAdded(ServiceEvent event) {
                    // Required to force serviceResolved to be called again (after the first search)
                    jmdns.requestServiceInfo(event.getType(), event.getName(), 1);
                }
});
            
      添加服务监听,type是监听类型,如http.tcp.local等,我们注册服务,向局域网内提供服务调用的是serviceAdded(ServiceEvent event) 方法;监听服务调用的是serviceResolved(ServiceEvent event);当不想提供服务调用的是serviceRemoved(ServiceEvent ev) 方法。

效果图:

Android手机扫描mDNS服务相关推荐

  1. Android手机扫描识别银行卡技术

    Android手机扫描识别银行卡技术 1.Android手机扫描识别银行卡技术背景分析 手机支付.网络支付已经非常成熟,消费者已经习惯了使用手机支付宝进行支付,用手机银行进行消费和转账.但是,整个线上 ...

  2. 如何实现android手机扫描条码到数据库查询信息并打印

    请问各位前辈,如何实现android手机扫描条码,然后到数据库查询资料,并打印出来. 我到网上查询资料说要使用zxing扫描条码,但要怎么实现呢?或者思路如何?谢谢!

  3. android ip地址扫描,Android:手机扫描局域网所有ip,并进行socket通讯

    android 手机局域网扫描PC机: 利用android的ping命令扫描局域网内所有ip, 并对其进行socket通信 import java.io.DataInputStream; import ...

  4. Android手机扫描,电脑复制内容----手机实现无线扫码枪功能

    1.通过Android手机安装二维码通实现扫描功能:二维码通APK 2.通过二维码通.exe电脑程序实现二维码接受功能并进行填入写入框:二维码通.exe

  5. 查看Android手机与谷歌服务的通信状态日志

    在开发谷歌服务相关的东西或者使用谷歌服务相关的东西时,在判断和查找当前操作的问题时,谷歌服务当前的连接状态就异常重要了.不然谷歌服务都没连上,一味的折腾自己的程序也不能解决问题. 使用手机指令查看谷歌 ...

  6. android筛选账单,如何从Android手机扫描账单收据并从中获取数据?

    If you have plenty of time but zero budget – your choice is Tesseract. It is definitely the best amo ...

  7. android 手机获取公网ip_KSWEB 旧手机搭建网站服务

    ? 感谢你阅读「 Android 应用 」的第 113篇分享文章 KSWEB 是一款由俄罗斯开发者开发的一款可以在 Android 手机上安装建站相关服务的应用,支持 Lighttpd.Nginx.A ...

  8. android 实现3d扫描,DIY:让Android手机轻松变3D扫描仪

    新酷产品第一时间免费试玩,还有众多优质达人分享独到生活经验,快来新浪众测,体验各领域最前沿.最有趣.最好玩的产品吧~!下载客户端还能获得专享福利哦! 本文来自cnBeta 想让你的手机变成3D扫描仪吗 ...

  9. 国行Android手机使用google全套GMS服务小结

      由于众所周知的原因,国行手机是不能内置google服务的,但作为铁杆google粉,没有GMS的Android不是完整的Android,NEXUS系列机器又由于各种原因买不到或者不想选购,那么也只 ...

最新文章

  1. 四个步骤实现层级清晰的导航栏
  2. 比特币现金扬声器系列II将领先的比特币一起带来
  3. python读取大文件-Python如何读取、拆分大文件
  4. Firefox下div层被Flash遮住的解决方法
  5. 简单深入两个虚拟内存API VirtualAlloc及VritualCopy
  6. (十一)Jmeter另一种调试工具 HTTP Mirror Server
  7. 2016-2017 ACM-ICPC Southwestern European Regional Programming Contest (SWERC 2016)
  8. 基于Servlet的技术问答网站系统实现(附源码)
  9. unity3D使用User32.dll
  10. java-Web(js)作业
  11. FreeRTOS学习教程整理
  12. android电源管理白名单,刷BIOS工具分享(白名单,高级菜单,电源管理)
  13. 购物车程序流程图01
  14. LZJ流体质量计算机价格,LZJ-ⅢC型流体质量计算机
  15. VML 魅力初现--美少女图(vml可以这样强大?)
  16. 锐龙R3-3300X和i5-9400f哪个好?
  17. 数学归纳法及例题分析
  18. Linux下自动化工具
  19. webservice 菜鸟探索之旅
  20. 云原生分布式监控系统?看鹅厂 T11 架构师如何整活儿

热门文章

  1. Hadoop综合项目——二手房统计分析(可视化篇)
  2. 心理咨询真的会对我们起作用吗
  3. 将jsp变为html
  4. 纵横网络靶场刷题记录
  5. 原生table如何实现表格首行标题冻结
  6. JSP开发之TomcatEclipse环境搭建(创建项目运行一个简单的jsp文件)
  7. 全国计算机等级陕西一级题库,全国计算机等级考试一级试题库
  8. ROS中launch文件的编写
  9. 涨跌停计算器_涨跌停计算器手机版,新股涨停收益表
  10. 打开doc文档提示Word 遇到问题需要关闭以安全模式启动解决办法