Android手机扫描mDNS服务
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服务相关推荐
- Android手机扫描识别银行卡技术
Android手机扫描识别银行卡技术 1.Android手机扫描识别银行卡技术背景分析 手机支付.网络支付已经非常成熟,消费者已经习惯了使用手机支付宝进行支付,用手机银行进行消费和转账.但是,整个线上 ...
- 如何实现android手机扫描条码到数据库查询信息并打印
请问各位前辈,如何实现android手机扫描条码,然后到数据库查询资料,并打印出来. 我到网上查询资料说要使用zxing扫描条码,但要怎么实现呢?或者思路如何?谢谢!
- android ip地址扫描,Android:手机扫描局域网所有ip,并进行socket通讯
android 手机局域网扫描PC机: 利用android的ping命令扫描局域网内所有ip, 并对其进行socket通信 import java.io.DataInputStream; import ...
- Android手机扫描,电脑复制内容----手机实现无线扫码枪功能
1.通过Android手机安装二维码通实现扫描功能:二维码通APK 2.通过二维码通.exe电脑程序实现二维码接受功能并进行填入写入框:二维码通.exe
- 查看Android手机与谷歌服务的通信状态日志
在开发谷歌服务相关的东西或者使用谷歌服务相关的东西时,在判断和查找当前操作的问题时,谷歌服务当前的连接状态就异常重要了.不然谷歌服务都没连上,一味的折腾自己的程序也不能解决问题. 使用手机指令查看谷歌 ...
- android筛选账单,如何从Android手机扫描账单收据并从中获取数据?
If you have plenty of time but zero budget – your choice is Tesseract. It is definitely the best amo ...
- android 手机获取公网ip_KSWEB 旧手机搭建网站服务
? 感谢你阅读「 Android 应用 」的第 113篇分享文章 KSWEB 是一款由俄罗斯开发者开发的一款可以在 Android 手机上安装建站相关服务的应用,支持 Lighttpd.Nginx.A ...
- android 实现3d扫描,DIY:让Android手机轻松变3D扫描仪
新酷产品第一时间免费试玩,还有众多优质达人分享独到生活经验,快来新浪众测,体验各领域最前沿.最有趣.最好玩的产品吧~!下载客户端还能获得专享福利哦! 本文来自cnBeta 想让你的手机变成3D扫描仪吗 ...
- 国行Android手机使用google全套GMS服务小结
由于众所周知的原因,国行手机是不能内置google服务的,但作为铁杆google粉,没有GMS的Android不是完整的Android,NEXUS系列机器又由于各种原因买不到或者不想选购,那么也只 ...
最新文章
- 四个步骤实现层级清晰的导航栏
- 比特币现金扬声器系列II将领先的比特币一起带来
- python读取大文件-Python如何读取、拆分大文件
- Firefox下div层被Flash遮住的解决方法
- 简单深入两个虚拟内存API VirtualAlloc及VritualCopy
- (十一)Jmeter另一种调试工具 HTTP Mirror Server
- 2016-2017 ACM-ICPC Southwestern European Regional Programming Contest (SWERC 2016)
- 基于Servlet的技术问答网站系统实现(附源码)
- unity3D使用User32.dll
- java-Web(js)作业
- FreeRTOS学习教程整理
- android电源管理白名单,刷BIOS工具分享(白名单,高级菜单,电源管理)
- 购物车程序流程图01
- LZJ流体质量计算机价格,LZJ-ⅢC型流体质量计算机
- VML 魅力初现--美少女图(vml可以这样强大?)
- 锐龙R3-3300X和i5-9400f哪个好?
- 数学归纳法及例题分析
- Linux下自动化工具
- webservice 菜鸟探索之旅
- 云原生分布式监控系统?看鹅厂 T11 架构师如何整活儿