基于热点的短距离传输

                                                                                无网络环境下的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();
        }
    }
}

这边是服务端发的数据,当然客户端服务端谁发都可以,视情况而定,至此一个简单的基于热点传输的例子就结束了
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章