基於熱點的短距離傳輸

                                                                                無網絡環境下的Android端數據傳輸

      對於無網絡的數據傳輸方式:

  1. NFC :適用於體量小指令數據傳輸,大數據量傳輸,速度較慢且不穩定,但是建立連接過程很快。
  2. WIFI直連:傳輸速度快,可傳輸數據量大,但是連接過程複雜。
  3. 藍牙:常規的藍牙區別於低功耗藍牙(沒有涉及),常規藍牙需要發現設備,配對設備
  4. 熱點TCP/IP方式

      方式很多,就先記錄下嘗試過的一種吧:第四種方式

  • 服務端創建網絡

      創建熱點,這裏採用的是反射機制調用系統的API方法,創建約定的名稱的熱點,創建成功之後會自動打開wifi熱點

public boolean setWifiApEnabled() {
  // disable WiFi in any case
        //wifi和熱點不能同時打開,所以打開熱點的時候需要關閉wifi
    mWifiManager.setWifiEnabled(false);
    try {
        //熱點的配置類
        WifiConfiguration apConfig = new WifiConfiguration();
        //配置熱點的名稱(可以在名字後面加點隨機數什麼的)
        apConfig.SSID = GlobData.WIFIAPSSID;
        //配置熱點的密碼
        apConfig.preSharedKey = GlobData.WIFIAPPASSWORD;
        /***配置熱點的其他信息  加密方式**/
        apConfig.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
        apConfig.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
        //用WPA密碼方式保護
        apConfig.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
        apConfig.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
        apConfig.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
        apConfig.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
        apConfig.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
        apConfig.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
        //通過反射調用設置熱點
        Method method = mWifiManager.getClass().getMethod("setWifiApEnabled", WifiConfiguration.class, Boolean.TYPE);
        //返回熱點打開狀態
        return (Boolean) method.invoke(mWifiManager, apConfig, true);
    } catch (Exception e) {
        return false;
    }
}
  • 客戶端連接網絡
  1. 掃描附近的網絡,添加廣播接收網絡變化及掃描結果
  2. 添加網絡,當掃描結果包含已約定SSID的熱點,則添加到WiFi列表
  3. 連接該網絡網絡,
/**
 * 是否已連接指定wifi
 */
public boolean isConnected(String ssid) {
    WifiInfo wifiInfo = mWifiManager.getConnectionInfo();
    if (wifiInfo == null) {
        return false;
    }
    switch (wifiInfo.getSupplicantState()) {
        case AUTHENTICATING:
        case ASSOCIATING:
        case ASSOCIATED:
        case FOUR_WAY_HANDSHAKE:
        case GROUP_HANDSHAKE:
        case COMPLETED:
            return wifiInfo.getSSID().replace("\"", "").equals(ssid);
        default:
            return false;
    }
}

public boolean connect(@NonNull String ssid, @NonNull String password) {
    boolean isConnected = isConnected(ssid);//當前已連接至指定wifi
    if (isConnected) {
        return true;
    }
    int id = -1;
    for (WifiConfiguration c:mWifiManager.getConfiguredNetworks()){
        if(c.SSID.equals("\"" + GlobData.WIFIAPSSID + "\"")){
            id = c.networkId;
        }
        mWifiManager.disableNetwork(c.networkId);
    }
    if(-1==id){
        int networkId = mWifiManager.addNetwork(CreateWifiInfo(ssid, password, 3));
        if(-1!=networkId){
            id =networkId;
        }
    }
    if(-1==id){
        for (WifiConfiguration c:mWifiManager.getConfiguredNetworks()){
            if(c.SSID.equals(GlobData.WIFIAPSSID)){
                id = c.networkId;
                break;
            }
        }
    }
    if(-1!=id){
        boolean result = mWifiManager.enableNetwork(id, true);
        return true;
    }
    return false;
}

     

  • 服務端開放ServerSoket
public class ServerThread extends Thread {

    private ServerSocket serverSocket = null;
    private Handler handler;
    private Socket  socket;
    private volatile boolean isRun =true;
    private InputStream inputStream;
    private OutputStream outputStream;

    public ServerThread(Handler handler) {
        this.handler = handler;
        try {
            serverSocket = new ServerSocket(GlobData.WIFIAPPORT);//監聽本機的12345端口
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    @Override
    public void run() {
        if(null==serverSocket){
            try {
                serverSocket = new ServerSocket(GlobData.WIFIAPPORT);//監聽本機的12345端口
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        while (isRun) {
            try {
                Log.i("ListennerThread", "阻塞");
                //阻塞,等待設備連接
                if (serverSocket != null) {
                    socket = serverSocket.accept();
                    Message message = Message.obtain();
                    message.what = GlobData.DEVICE_CONNECTED;
                    handler.sendMessage(message);
                    inputStream = socket.getInputStream();
                    outputStream = socket.getOutputStream();
                    new Thread(new Runnable() {
                        @Override
                        public void run() {
                            byte[] buffer = new byte[4*1024];
                            int bytes = 0;
                            try {
                                bytes = inputStream.read(buffer);
                            } catch (IOException e) {
                                e.printStackTrace();
                            }
                            if (bytes > 0) {
                                final byte[] data = new byte[bytes];
                                System.arraycopy(buffer, 0, data, 0, bytes);
                                Message message1 = Message.obtain();
                                message1.what = GlobData.SEND_MSG_SUCCSEE;
                                Bundle bundle = new Bundle();
                                bundle.putString("MSG", new String(data));
                                message1.setData(bundle);
                                handler.sendMessage(message1);

                                Log.i("ClinentConnectThread", "讀取到數據:" + new String(data));
                            }
                        }
                    }).start();
                }
            } catch (Exception e) {
                e.printStackTrace();
                interrupt();
            }
        }
    }


    /**
     * 發送數據
     */
    public void sendData(final String msg) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                if (outputStream != null) {
                    try {
//                        byte[] len =new byte[8]{msg.getBytes("UTF-8").length};
//                        outputStream.write(msg.getBytes("UTF-8"));
//                        outputStream.flush();
                        outputStream.write(msg.getBytes("UTF-8"));
                        outputStream.flush();
                        outputStream.write("tpriend".getBytes("UTF-8"));
                        outputStream.flush();
                    } catch (IOException e) {
                        e.printStackTrace();
                        Message message = Message.obtain();
                        message.what = GlobData.SEND_MSG_ERROR;
                        Bundle bundle = new Bundle();
                        bundle.putString("MSG", new String(msg));
                        message.setData(bundle);
                        handler.sendMessage(message);
                    }
                }
            }
        }).start();
    }

    public void close() {
        try {
            if(null!=outputStream){
                outputStream.close();
                outputStream = null;
            }
            if(null!=inputStream){
                inputStream.close();
                inputStream = null;
            }
            if (serverSocket != null) {
                serverSocket.close();
                serverSocket = null;
            }
            if (socket != null) {
                socket.close();
                socket=null;
            }
            this.isRun=false;
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
  • 客戶端連接Sokect

 

public class ClientThread extends Thread {

    private Socket socket;
    private Handler handler;
    private InputStream inputStream;
    private OutputStream outputStream;
    private volatile boolean isRun = true;

    public ClientThread(Socket socket, Handler handler) {
        this.socket = socket;
        this.handler = handler;
    }

    @Override
    public void run() {
        if (socket == null) {
            return;
        }
        handler.sendEmptyMessage(GlobData.DEVICE_CONNECTED);
        try {
            //獲取數據流
            inputStream = socket.getInputStream();
            outputStream = socket.getOutputStream();
            InputStream inputStream = socket.getInputStream();
            byte[] bytes = new byte[4*1024];
            int len = -1;
            StringBuilder sb = new StringBuilder();
                while ((isRun && (len = inputStream.read(bytes)) != -1)) {
                    // 注意指定編碼格式,發送方和接收方一定要統一,建議使用UTF-8
                    String str = new String(bytes, 0, len, "UTF-8");
                    if (str.contains("tpriend")) {
                        str =str.substring(0,str.indexOf("tpriend"));
                        sb.append(str);
                        Message message = Message.obtain();
                        message.what = GlobData.GET_MSG;
                        Bundle bundle = new Bundle();
                        bundle.putString("MSG", sb.toString());
                        message.setData(bundle);
                        handler.sendMessage(message);
                        sb = new StringBuilder();
                        new Thread(new Runnable() {
                            @Override
                            public void run() {
                                try {
                                    outputStream.write("tpriend".getBytes("UTF-8"));
                                } catch (IOException e) {
                                    e.printStackTrace();
                                }
                                try {
                                    outputStream.flush();
                                } catch (IOException e) {
                                    e.printStackTrace();
                                }
                            }
                        }).start();
                    } else {
                        sb.append(str);
                    }
                }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void close() {
        try {
            if(null!=outputStream){
                outputStream.close();
                outputStream = null;
            }
            if(null!=inputStream){
                inputStream.close();
                inputStream = null;
            }
            if (socket != null) {
                socket.close();
                socket=null;
            }
            this.isRun=false;
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

這邊是服務端發的數據,當然客戶端服務端誰發都可以,視情況而定,至此一個簡單的基於熱點傳輸的例子就結束了
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章