实现WiFi的 扫描 链接
主要是通过wifi 硬件的扫描来获取一些周边的wifi 热点信息
我们在进行wifi 搜索的时候,一般会搜到一些信息:wifi 的名字、 信号的强弱、wifi 的安全模式 如WPA\WPE.
实例化这个类,我们可以得到以下几个信息:
BSSID :
小范围几个无线设备连接所获取的地址,比如几台笔记本通过无线网卡进行连接,双方的无线网卡分配的地址。
SSID :
wifi 网络的名字,用来区分不同的网络接入点。
Capabilities :
网络接入的性能,这里主要是判断网络的加密方式。
Frequency :
频率,每个频道交互的MHz数。
Level :
等级,主要来判断网络连接的优先数。
在我们链接一个wifi 的时候需要获取的一些网络信息,更多是加密方式方面
Wifi Configuration.AuthAlgorthm
用来判断加密方法
WifiConfiguration.CroupCipher
获取使用GroupCipher的方法来进行加密
WifiConfiguration.KeyMgmt
获取使用KeyMgmt进行
WifiConfiguration.PairwiseCipher
获取使用WPA方式加密
WifiConfiguration.Protocol
获取使用那一种协议进行加密
WifiConfiguration.Status
获取当前网络状态
可以通过这个类来获取已经联通的wifi链接,获取当前的链接信息,主要是wifi 链接的基本信息
getBSSID()
获取DSSID
getDetailedStateOf()
获取客户端的连通性
getHiddenSSID()
获取SSID是否被隐藏
getIpAddress()
获取IP地址
getLinkSpeed()
获取链接的速度
getMacAddress()
获取Mac 地址
getRssi()
获得 网络的信号
getSSID()
获得SSID
getSupplicanState()
返回具体客户端状态的信息
用来管理我们的wifi链接,这里已经定义好了一些类,这个类里面预先定义了许多常量,我们可以直接使用,不用再次创建。
addNetwork(WifiConfiguration config)
通过获取的网络的链接状态信息,来添加网络
calculateSignalLevel(int rssi, int numLevels)
计算信号的等级
compareSignalLevel(int rssiA , int rssiB)
对比链接A 和 链接B
createWifiLock(int locktype, String tag)
创建一个wifi 锁, 锁定当前的wifi 链接
disableNetwork(int netId)
让一个网络连接失效
disconnect()
断开链接
enableNetwork(int netId, Boolean diaableOthers)
链接一个链接
getConfiguredNetWorks()
获取网络连接状态
getConnectionInfo()
获取当前连接信息
getDhcpInfo()
获取Dhcp的信息
getScanResulats()
获取扫描测试的结果
getWifiState()
获取一个wifi 接入点是否有效
isWifiEnabled()
判断一个wifi 链接是否有效
pingSupplicant()
ping 一个链接是否可以联通
removeNetwork()
移除一个网络
saveConfiguration()
保留一个配置信息
setWifiEnabled()
让一个链接有效
startScan()
开始扫描
updateNetwork(WifiConfiguration config)
更新一个网络连接的信息
WifiManagerLock
是wifiManager的子类,在普通的状态下,如果我们的wifi 状态处于闲置状态,那么网络的联通就会暂时中断。但是如果我们把当前的网络状态锁上,那wifi 联通将会保持在一定状态,当然解锁之后就会恢复常态。
可以扫描周围的WiFi 并且链接到指定的wifi , 有密码 和 无密码 都可。
具体代码分析,详见代码注释
if (serverId == null) {
//获取服务端的IP
DhcpInfo info = wifiManager.getDhcpInfo();
serverId = intToIp(info.serverAddress);
System.out.println("server Ip:" + serverId);
}
#####2)、广播监听WiFi是不是链接到 网络 ,wifi 是否
开启或者关闭
//wifi 网络连接上与否
if (intent.getAction().equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {
NetworkInfo info = intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
if (info.getState().equals(NetworkInfo.State.DISCONNECTED)) {
Log.i(TAG, "wifi断开");
showConn.setText("正在尝试连接···" );
isSocketConnected = false;
clientConnectClose();
System.out.println("wifi 网络断开 socket = null 广播监听");
} else if (info.getState().equals(NetworkInfo.State.CONNECTED)) {
WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
WifiInfo wifiInfo = wifiManager.getConnectionInfo();
//获取当前wifi名称
Log.i(TAG, "连接到网络 " + wifiInfo.getSSID());
System.out.println("链接到网络 广播监听");
showConn.setText(initShowConn());
}
}
//wifi打开与否
if (intent.getAction().equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) {
int wifistate = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE, WifiManager.WIFI_STATE_DISABLED);
if (wifistate == WifiManager.WIFI_STATE_DISABLED) {
Log.i(TAG, "系统关闭wifi");
isSocketConnected = false;
clientConnectClose();
} else if (wifistate == WifiManager.WIFI_STATE_ENABLED) {
Log.i(TAG, "系统开启wifi");
//initWifiList();
}
}
1)对于客户端 socket 的修改
修改为 :
(1) 新建线程 初始化 socket
(2) 新建线程 为发送数据的线程
(3) 新建线程 为接受服务端发来的数据
这样很好的将创建,发送,接受 模块化
//在想链接服务端的地方添加
new Thread(linkrunnable).start();//开启链接数据线程
··········
// 开启链接socket线程
Runnable linkrunnable = new Runnable() {
@Override
public void run() {
initClientSocket();
System.out.println(TAG + "initClientSocket");
}
};
·················
public void initClientSocket() {
try {
if (serverId == null) {
//获取服务端的IP
DhcpInfo info = mWifiManager.getDhcpInfo();
serverId = intToIp(info.serverAddress);
System.out.println("server Ip:" + serverId);
}
if (socket == null || socket.isClosed() || !socket.isConnected()){
socket = new Socket(serverId, 8086);
System.out.println(TAG + "creat new socket:" + socket );
}
isSocketConnected = true;
//初始化输出流
output = new PrintStream(socket.getOutputStream(),true,"utf-8");
System.out.println("new socket");
System.out.println("server socket:" + socket);
//链接socket 的时候就创建接收消息的线程
readThread = new ReadThread();
readThread.start(); //开启接受服务端数据的线程
} catch (IOException e) {
// TODO Auto-generated catch block
System.out.println("服务器未开启");
e.printStackTrace();
clientConnectClose();
}
}
//接受服务端发来信息的线程
private class ReadThread extends Thread {
@Override
public void run() {
super.run();
try {
System.out.println("进入接受服务端数据 isSocketConnected :" + isSocketConnected);
while (isSocketConnected) {
if (socket != null && !socket.isClosed() && socket.isConnected()) {
System.out.println("client socket listen");
/*****
* readLine()方法在进行读取一行时,只有遇到回车(\r)或者换行符(\n)才会返回读取结果,
* 这就是“读取一行的意思”,重要的是readLine()返回的读取内容中并不包含换行符或者回车符;
*并且,当realLine()读取到的内容为空时,并不会返回 null,而是会一直阻塞,
* 只有当读取的输入流发生错误或者被关闭时,readLine()方法才会返回null。
* 所以对应的发送端使用 println() /或者加上 /n /r 等
*/
clientInputStream = socket.getInputStream();
clientInputStreamReader = new InputStreamReader(clientInputStream);
clientBufferReader = new BufferedReader (clientInputStreamReader);
//br_client_in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
clientReceive = clientBufferReader.readLine();
System.out.println("服务端返回数据:" + clientReceive);
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
clientConnectClose();
}
//如果wifi 链接状态发生改变
if (!isSocketConnected) {
clientConnectClose();
}
}
}
·············
//向服务端发送数据的线程
public class SendReserveData extends Thread {
private String msg;
public SendReserveData (String msg){
this.msg = msg;
}
@Override
public void run() {
//向服务端发数据
try {
if (output != null) {
System.out.println(TAG + msg);
output.println(msg);
output.flush();
} else {
System.out.println(TAG + "output is null");
}
} catch (UnknownError e) {
e.printStackTrace();
}
}
}
···················
//开启向服务端发送数据的线程
new SendReserveData("hello this is client").start();
1)发送数据,却没有接收
是因为read 在读取数据的时候是依照 \n \t 等判断是否结束的,可以在发送的数据后面加上 “\n” ,或者使用 out.println(str);
2)socket 断开之后 ,整个APP 就闪退
是socket 突然断开链接之后,出现的错误没有被捕捉,将每一个 socket , socket 的输入 输出流 放到 try {} carch () {} 之中。
demo下载链接:
wifi 扫描链接
wifi 连接/数据传输
文件参考:
Android手机通过wifi进行数据传输
https://blog.csdn.net/taily_duan/article/details/53514046
Android WiFi开发教程(一)——WiFi热点的创建与关闭
https://blog.csdn.net/a1533588867/article/details/52459284
通过wifi与设备进行通信(Android)
https://blog.csdn.net/songnigo6/article/details/52290199
Android设备之间通过Wifi通信
https://www.cnblogs.com/sowhat4999/p/5673514.html
android 之TCP客户端编程
https://www.cnblogs.com/yangfengwu/p/5212570.html
【Android Socket专题】: TCP通信客户端app的demo的实现
https://blog.csdn.net/shankezh/article/details/70763579
使用readLine()方法遇到的坑
https://blog.csdn.net/neon_z/article/details/53707170