无网络环境下的Android端数据传输
对于无网络的数据传输方式:
- NFC :适用于体量小指令数据传输,大数据量传输,速度较慢且不稳定,但是建立连接过程很快。
- WIFI直连:传输速度快,可传输数据量大,但是连接过程复杂。
- 蓝牙:常规的蓝牙区别于低功耗蓝牙(没有涉及),常规蓝牙需要发现设备,配对设备
- 热点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; } }
- 客户端连接网络
- 扫描附近的网络,添加广播接收网络变化及扫描结果
- 添加网络,当扫描结果包含已约定SSID的热点,则添加到WiFi列表
- 连接该网络网络,
/** * 是否已连接指定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(); } } } 这边是服务端发的数据,当然客户端服务端谁发都可以,视情况而定,至此一个简单的基于热点传输的例子就结束了