前言:
遇到一个Android+web服务的项目, 做app端时遇到要扫描wifi内的其他ip地址, 之后在网上找了好久, 试过WifiManager不过只能获取bssid,据说就是mac地址,但不是ip啊,然后想使用android底层的Linus的shell命令,搞了不天也不懂...好在最后参考网上帖子. 总算是有眉目了,但是后边说项目不用了,我去...但是不能浪费,
虽然不是完全版,还有问题,但是可以运行,或许以后用的着.另外,不喜勿喷!
思路:
app连接wifi后,会存在一个ip地址, 和电脑一样,那么局域网内的其他机器也在这个网段, 所以
通过本地ip获得相应网段,然后通过ping遍历网段ip,获取同网段局域网ip,以达到目的!
代码:
1,给app分配权限
<!--允许应用程序改变网络状态-->
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
<!--允许应用程序改变WIFI连接状态-->
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
<!--允许应用程序访问WIFI网卡的网络信息-->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<!--允许应用程序完全使用网络-->
<uses-permission android:name="android.permission.INTERNET"/>
<!--允许访问网络状态-->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
2,NetUtil.java
import android.content.Context;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.util.Log;
import android.widget.Toast;
import java.io.File;
import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;
/**
* 获得当前网络信息,已经扫描同网段的ip
* Created by Albert.Ma on 2015/8/25.
*/
public class NetUtil {
private Context context;
private String localIpAddress;//本地ip地址 如 192.168.0.1
private String networkSegment;//本地网段 如 192.168.0.
private int ipIndex;//ip最后位 如 1
private volatile List<String> ipListInSameSegment = new ArrayList<>();//存放同网段的ip
private boolean isRoot=false;//是否root
private String ping = "ping -c 3 -w 10 ";//-c 是指ping的次数 -w 100 以秒为单位指定超时间
private Runtime runtime = Runtime.getRuntime();
private Process process = null;
//定义WifiManager对象
private WifiManager mWifiManager;
//定义WifiInfo对象
private WifiInfo mWifiInfo;
//扫描出的网络连接列表
private List<ScanResult> mWifiList;
//网络连接列表
private List<WifiConfiguration> mWifiConfiguration;
//定义一个WifiLock
WifiManager.WifiLock mWifiLock;
//判断是否root
private final static int kSystemRootStateUnknow = -1;
private final static int kSystemRootStateDisable = 0;
private final static int kSystemRootStateEnable = 1;
private static int systemRootState = kSystemRootStateUnknow;
public NetUtil(Context context){
this.context = context;
//取得WifiManager对象
mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
//取得WifiInfo对象
mWifiInfo = mWifiManager.getConnectionInfo();
mWifiManager.startScan();
//得到扫描结果
mWifiList = mWifiManager.getScanResults();
//得到配置好的网络连接
mWifiConfiguration = mWifiManager.getConfiguredNetworks();
//设置本地ip
String ip = getLocalIpAddress().toString();
localIpAddress = ip.substring(1, ip.length());
networkSegment = this.localIpAddress.substring(0, this.localIpAddress.lastIndexOf(".") + 1);
}
/**
* 获取本地ip
*/
public InetAddress getLocalIpAddress() {
int hostAddress = mWifiInfo.getIpAddress();
byte[] addressBytes = { (byte)(0xff & hostAddress),
(byte)(0xff & (hostAddress >> 8)),
(byte)(0xff & (hostAddress >> 16)),
(byte)(0xff & (hostAddress >> 24)) };
try {
return InetAddress.getByAddress(addressBytes);
} catch (UnknownHostException e) {
throw new AssertionError();
}
}
/**
* 扫描同网段的ip
*/
public List<String> scanIpInSameSegment(){
if(this.localIpAddress == null || "".equals(this.localIpAddress)){
// Toast.makeText(context, "扫描失败,请检查wifi网络", Toast.LENGTH_LONG).show();
return null;
}
if(!NetUtil.isRootSystem()){
Toast.makeText(context, "扫描网络ip需要root权限,请先root后再尝试!", Toast.LENGTH_LONG).show();
return null;
}
//产生256个线程测试ip
for(int i=0;i<256;i++){
ipIndex = i;
new Thread(new Runnable() {
@Override
public synchronized void run() {
String currentIp = networkSegment + ipIndex;
String command = ping + currentIp;
try {
process = runtime.exec(command);
int result = process.waitFor();
if (result == 0) {
System.out.println("连接成功:" + currentIp);
Log.i("IP", "连接成功:" + currentIp);
ipListInSameSegment.add(currentIp);
} else {
System.out.println("连接失败:" + currentIp);
Log.i("IP", "连接失败:" + currentIp);
}
} catch (IOException e1) {
e1.printStackTrace();
} catch (InterruptedException e2) {
e2.printStackTrace();
} finally {
process.destroy();
}
}
}).start();
}
return ipListInSameSegment;
}
/**
* 获得root权限
*/
public void getRootPermission(){
if(NetUtil.isRootSystem()){
return;
}
try {
String rootCommand = "su";
process = runtime.exec(rootCommand);
int result = process.waitFor();
if (result == 0) {
this.isRoot = true;
Log.i("IP", "Root成功");
Toast.makeText(context, "Root成功", Toast.LENGTH_SHORT).show();
} else {
Log.i("IP", "Root失败");
Toast.makeText(context, "Root失败", Toast.LENGTH_SHORT).show();
}
// //输出结果
// BufferedReader in = new BufferedReader(new InputStreamReader(proc.getInputStream()));
// String line = null;
// while ((line = in.readLine()) != null) {
// Log.i("IP", ">>>:" + line);
// }
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
/**
* 判断是否已经root
*/
public static boolean isRootSystem() {
if (systemRootState == kSystemRootStateEnable) {
return true;
} else if (systemRootState == kSystemRootStateDisable) {
return false;
}
File f = null;
final String kSuSearchPaths[] = { "/system/bin/", "/system/xbin/",
"/system/sbin/", "/sbin/", "/vendor/bin/" };
try {
for (int i = 0; i < kSuSearchPaths.length; i++) {
f = new File(kSuSearchPaths[i] + "su");
if (f != null && f.exists()) {
systemRootState = kSystemRootStateEnable;
return true;
}
}
} catch (Exception e) {
}
systemRootState = kSystemRootStateDisable;
return false;
}
}
3,调用
NetUtil netUtil =new NetUtil(this);
netUtil.getRootPermission();
List<String> ipList = netUtil.scanIpInSameSegment();
String ips ="扫描到的ip:\n";
for(String str:ipList){
ips+=str+"\n";
}
Toast.makeText(LoginActivity.this,ips,Toast.LENGTH_SHORT).show();
4.效果
5.说明
NetUtil包括调用android内的WifiManger,通过它获得本地wifi信息包括ip(例如192.168.0.1), 获得网段,也就是192.168.0.X,X代表要遍历的ip最后一段,其中使用当前运行时状态,用来ping其他ip测试是否连通,注意:
使用Runtime.exec(command)ping时,必须获得root权限,否则不同.这也是网上很多的ping例子但是,不通的原因,或许像我这种小白菜不知道要root.这让我浪费好多时间啊 .然后NetUtil后边有获取root和判断是否root的方法.
6.权限问题
里面使用256个进程去ping, 这里没有做处理,导致主线程运行完了,这256个线程还没跑完, 返回的结果可能不对,需要使用debug,让256个线程跑完后再继续运行主线程才能到达预期效果. 提供个连接或许能有帮助 http://blog.csdn.net/escaflone/article/details/10418651
- 大小: 242 KB
- 大小: 240 KB
分享到:
相关推荐
一个快速IP扫描工具,可以更快的找出那些IP没有被使用!
可以实现手机之间连接WIFI情况下局域网实时传送文件,支持自建WIFI热点
Android开发WIFI局域网对讲机WifiTalk,只能用炫酷来形容,感兴趣就下载看看吧
简单初级的局域网IP扫描工具及源码,由VS2010编写,可用于局域网IP扫描和对应IP计算机名扫描。
在网上找了好久没找到vb.net的局域网主机IP扫描代码,全是C#的,没办法,只好花了点时间从C#代码转化为vb.net代码,看来喜欢vb.net的朋友们要加油了。 该代码可以扫描局域网IP地址集(只能扫描到在线的),希望能对...
C# 局域网IP扫描 实例源码(网络操作)
扫描局域网的ip工具很 能够对局域网的ip进行扫描 呵呵 对于局域网ip扫描的用户 是个不错的工具
实现局域网IP扫描获取局域网IP等,希望有助于你的管理等
VC++MFC扫描局域网的IP和主机名MAC地址.rar VC++MFC扫描局域网的IP和主机名MAC地址.rar VC++MFC扫描局域网的IP和主机名MAC地址.rar VC++MFC扫描局域网的IP和主机名MAC地址.rar VC++MFC扫描局域网的IP和主机名MAC地址...
SuperScan 局域网ip扫描 SuperScan 局域网ip扫描 SuperScan 局域网ip扫描
扫描局域网对应ip的mac地址工具,通过arp学习到对应ip的mac地址
netscan 跨网段扫描局域网扫描IP地址
一款局域网IP扫描工具,可以自动搜素局域网内所有IP地址。
Android WifiChat This repository contains the source code for the WifiChat. Please see the issues section to report any bugs or feature requests and to see the list of known issues. Debug mode: // src...
【Shell学习】扫描局域网IP方法.txt
Android WiFi Camera (无线局域网IP摄像头) 支持闪光灯,可以远程截取图片
该软件使用VB编写,SOCKET编程 可以扫描局域网内所有在线的计算机 并显示计算机名,IP地址 需要的加我QQ 191817533 编程交流群 14934250
局域网扫描器 包括IP+Mac+计算机名
visual c++局域网的IP地址扫描器,可扫描到局域网的所有机器的名称,IP地址及MAC地址
VC扫描局域网IP和主机名源代码