Android 之 Wi-Fi通信

阅读前提:本文通信所用的模块是STM32中的EPS8266模块与三星Note3-N9500进行通信。STM32作为客户端,三星Note3-N9500作为服务端,在两者通信的过程中并无借助路由器作为中介者。但需要获取Note3-N9500中所在的IP地址,将IP地址应用到STM32所编写的程序当中

1.在AndroidManifest中添加权限

    /**允许程序改变网络状态*/
    "android.permission.CHANGE_NETWORK_STATE"/>
    /**允许程序改变Wi-Fi的状态*/
    "android.permission.CHANGE_WIFI_STATE"/>
    /**允许程序获取网络状态信息*/
    "android.permission.ACCESS_NETWORK_STATE"/>
    /**允许程序访问Wi-Fi网络状态信息*/
    "android.permission.ACCESS_WIFI_STATE"/>
    /**允许程序唤醒锁定*/
    "android.permission.WAKE_LOCK"/>
    /**允许程序访问网络*/
    "android.permission.INTERNET"/>

2.创建WiFiUtil工具类

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 java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.ServerSocket;
import java.util.List;

public class WiFiUtil {

    private String TAG = "WiFiUtil";
    private static WiFiUtil INSTANCE;
    private WifiManager wifiManager;
    private WifiManager.WifiLock wifiLock;
    private ServerSocket serverSocket;

    private WiFiUtil(Context context){

        wifiManager = (WifiManager) context.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
    }

    public static WiFiUtil getInstance(Context context){

        if (INSTANCE == null){

            INSTANCE = new WiFiUtil(context);
        }

        return INSTANCE;
    }

    /**打开Wi-Fi*/
    public void openWiFi(){

        if (!wifiManager.isWifiEnabled()){

            wifiManager.setWifiEnabled(true);
        }

    }

    /**关闭Wi-Fi*/
    public void closeWiFi(){

        if (wifiManager.isWifiEnabled()){

            wifiManager.setWifiEnabled(false);
        }

    }

    /**检查当前Wi-Fi网卡状态*/
    private void checkWiFiState(){

        int state = wifiManager.getWifiState();

        if (state == WifiManager.WIFI_STATE_DISABLING){
            Log.d(TAG,"WIFI_STATE_DISABLED->Wi-Fi网卡不可用");
        }else if (state == WifiManager.WIFI_STATE_DISABLED){
            Log.d(TAG,"WIFI_STATE_DISABLED->Wi-Fi网卡正在关闭");
        }else if (state == WifiManager.WIFI_STATE_ENABLING){
            Log.d(TAG,"WIFI_STATE_ENABLING->Wi-Fi网卡正在打开");
        }else if (state == WifiManager.WIFI_STATE_ENABLED){
            Log.d(TAG,"WIFI_STATE_ENABLED->Wi-Fi网卡可用");
        }else if (state == WifiManager.WIFI_STATE_UNKNOWN){
            Log.d(TAG,"WIFI_STATE_UNKNOWN->Wi-Fi网卡状态未知");
        }

    }

    /**开始扫描设备周围Wi-Fi热点*/
    private void startScan(){

        if (wifiManager.startScan()){
            Log.d(TAG,"扫描设备周围Wi-Fi热点成功");
        }else{
            Log.d(TAG,"扫描设备周围Wi-Fi热点失败");
        }
    }

    /**获取设备周围Wi-Fi热点信息*/
    private List getWiFiList(){
        Log.d(TAG,"获取设备周围Wi-Fi热点信息");
        return  wifiManager.getScanResults();
    }

    /**获取当前连接Wi-Fi热点信息*/
    private WifiInfo getConnectWiFiInfo(){

        /**
         *Log.d("获取NetWorkID:",String.valueOf(wifiInfo.getNetworkId()));
         *Log.d("获取BSSID:",wifiInfo.getBSSID());
         *Log.d("获取SSID:",wifiInfo.getSSID());
         *Log.d("获取IP地址:",String.valueOf(wifiInfo.getIpAddress()));
         *Log.d("获取Mac地址:",wifiInfo.getMacAddress());
         *Log.d("获取连接的速度:",wifiInfo.getSupplicantState().toString());
         *Log.d("获取客户端的连通性",wifiInfo.getDetailedStateOf(wifiInfo.getSupplicantState()).toString());
        */

        Log.d(TAG,"获取当前连接Wi-Fi热点信息");
        return wifiManager.getConnectionInfo();
    }

    /**获取设备中已保存Wi-Fi热点信息*/
    private List getWiFiConfiguration(){
        Log.d(TAG,"获取设备中已保存Wi-Fi热点信息");
        return wifiManager.getConfiguredNetworks();
    }

    /**断开当前连接Wi-Fi热点*/
    private boolean disconnectWiFi(){
        Log.d(TAG,"断开当前连接Wi-Fi热点");
        return wifiManager.disconnect();
    }

    /**连接到指定Wi-Fi热点*/
    private boolean connectDefaultWiFi(int defaultNetWorkID){
        Log.d(TAG,"连接到指定Wi-Fi热点");
        return wifiManager.enableNetwork(defaultNetWorkID,true);
    }

    /**创建Wi-Fi锁*/
    private void createdWiFiLock(){
        wifiLock = wifiManager.createWifiLock(WifiManager.WIFI_MODE_FULL_HIGH_PERF,"SCM-CONNECTION");
        Log.d(TAG,"创建Wi-Fi锁");
    }

    /**锁定当前连接Wi-Fi热点*/
    private void lockConnectWiFi(){
        wifiLock.acquire();
        Log.d(TAG,"锁定当前Wi-Fi热点");
    }

    /**解锁当前连接Wi-Fi热点*/
    private void unlockConnectWiFi(){
        if (wifiLock.isHeld()){
            wifiLock.release();
        }
        Log.d(TAG,"解锁当前连接Wi-Fi热点");
    }

    /**设备开启Wi-Fi热点*/
    public void createdWiFiHotspots(String SSID,String PASSWORD){

        closeWiFi();

        /**设置WiFiConfiguration参数*/
        WifiConfiguration wifiConfiguration = new WifiConfiguration();
        /**Wi-Fi热点名称*/
        wifiConfiguration.SSID = SSID;
        /**Wi-Fi热点连接密码*/
        wifiConfiguration.preSharedKey = PASSWORD;
        /**Wi-Fi热点是否隐藏*/
        wifiConfiguration.hiddenSSID = false ;
        /**Wi-Fi热点配置是否启用*/
        wifiConfiguration.status = WifiConfiguration.Status.ENABLED;
        /**IEEE 802.11认证算法 OPEN*/
        wifiConfiguration.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
        /**组秘钥TKIP+CCMP*/
        wifiConfiguration.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
        wifiConfiguration.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
        /**秘钥管理WPA_PSK*/
        wifiConfiguration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
        /**对称秘钥TKIP+CCMP*/
        wifiConfiguration.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
        wifiConfiguration.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);

        try {
                Method Enable_Method = wifiManager.getClass().getMethod("setWifiApEnabled", WifiConfiguration.class, Boolean.TYPE);
                boolean status = (Boolean) Enable_Method.invoke(wifiManager, wifiConfiguration, true);

                if (status) {
                    Log.d(TAG,"SSID:"+SSID);
                    Log.d(TAG,"PASSWORD:"+PASSWORD);
                } else {
                    Log.d(TAG,"设备热点创建失败");
                }

        } catch (Exception e) {
            e.printStackTrace();
            Log.d(TAG,"设备热点创建失败");
        }

        receiveDataFromSCM();

    }

    /**设备关闭Wi-Fi热点*/
    public void closedWiFiHotspots() {

        try {
                Method AP_Method = wifiManager.getClass().getMethod("getWifiApConfiguration");
                AP_Method.setAccessible(true);
                WifiConfiguration wifiConfiguration = (WifiConfiguration) AP_Method.invoke(wifiManager);
                Method Enable_Method = wifiManager.getClass().getMethod("setWifiApEnabled", WifiConfiguration.class, boolean.class);
                Enable_Method.invoke(wifiManager, wifiConfiguration, false);

        } catch (NoSuchMethodException e) {
                e.printStackTrace();
        } catch (IllegalArgumentException e) {
                e.printStackTrace();
        } catch (IllegalAccessException e) {
                e.printStackTrace();
        } catch (InvocationTargetException e) {
                e.printStackTrace();
        }

    }

    /**判断当前Wi-Fi热点是否为默认的Wi-Fi热点*/
    public void discriminationConnectWiFi(int defaultNetWorkID){

        WifiInfo wifiInfo = getConnectWiFiInfo();

        /**当前连接的NetWorkID*/
        int NetWorkID = wifiInfo.getNetworkId();

        /**当前Wi-Fi热点是否为指定Wi-Fi热点
         * true->对当前Wi-Fi热点进行锁定
         * false->对当前Wi-Fi热点进行断开,重新连接到指定Wi-Fi热点并且锁定
         * */
        if (defaultNetWorkID == NetWorkID){

            Log.d(TAG,"当前Wi-Fi是默认Wi-Fi");
            createdWiFiLock();
            lockConnectWiFi();

        }else {

            if (disconnectWiFi()){

                Log.d(TAG,"断开当前Wi-Fi连接成功");

                if (connectDefaultWiFi(defaultNetWorkID)){

                    Log.d(TAG,"连接到指定Wi-Fi成功");

                    createdWiFiLock();
                    lockConnectWiFi();

                }else {

                    Log.d(TAG,"连接到指定Wi-Fi失败");

                }

            }else {

                Log.d(TAG,"断开当前Wi-Fi连接失败");

            }

        }

    }

    /**Logcat设备中所有保留的Wi-Fi热点信息*/
    public void logoutAllWifiConfiguration(){

        final List wifiConfigurationList = getWiFiConfiguration();
        WifiConfiguration item;
        final int SIZE = wifiConfigurationList.size();
        for (int i=0 ; i"NetWorkID:"+String.valueOf(item.networkId));
              Log.d(TAG,"Statue:"+String.valueOf(item.status));
              Log.d(TAG,"SSID:"+item.SSID);

              if (item.BSSID == null) {
                  Log.d(TAG, "BSSID:null" );
              }else {
                  Log.d(TAG,"BSSID:"+item.BSSID);
              }

              Log.d(TAG,">>>>>>>>>>>>>>>>>>>>");
        }
    }

    /**创建Client端Socket*/


    /**创建Server端Socket*/
    private void receiveDataFromSCM() {

        new Thread(new ReceiveSCMDataRun(8080)).start();

    }

3.创建ReceiveSCMDataRun方法类

import android.util.Log;

import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class ReceiveSCMDataRun implements Runnable{

    private ServerSocket serverSocket;
    private Socket socket;

    public ReceiveSCMDataRun(int PORT){

        try{

            serverSocket = new ServerSocket(PORT);

        }catch (IOException e){

            e.printStackTrace();
        }

    }

    @Override
    public void run(){

        try {
            Log.d("socket","正在等待客户端的连接");
            socket = serverSocket.accept();
            Log.d("socket","连接成功");
        }catch (IOException e){
            e.printStackTrace();
        }

        /*一般情况下是每获取一个socket的入站连接,打开一个输入流,但Android服务端程序与单片机连接为一一对应关系,所以Android只接受一个客户端的入站连接*/
        while (true){

            try {

                /*获取客户端的输入流*/
                InputStream inputStream = socket.getInputStream();

                /*size用于检测inputStream中的是否有可读取的数据流*/
                int size = inputStream.available();

                /*temp存储读取一个字节*/
                byte[] temp = new byte[1];

                if (size != 0){

                    /*read(byte[] b[])方法会返回一个整型*/
                    inputStream.read(temp);
                    String HEXString = bytesToHexString(temp);

                    /*打印输出获取的数据*/
                    Log.d("HEXString",HEXString);

                    /*手动清空temp中的数据,避免占用内存*/
                    temp = null;
                }

            }catch (IOException e){
                e.printStackTrace();
            }catch (NullPointerException e){
                e.printStackTrace();
            }

        }

    }

    /**将输入的byte数组转换为16进制的字符串*/
    private String bytesToHexString(byte[] bytes){

        String HEXString = "";

        for (int i = 0;i < bytes.length; i++) {

            String hex = Integer.toHexString(bytes[i] & 0xFF);

            if (hex.length() == 1) {

                hex = '0' + hex;

            }

            HEXString += hex.toUpperCase();
        }

        return HEXString;
    }


}

你可能感兴趣的:(Android,Java)