大纲
- Wifi传输概述
WifiP2pManager
类的介绍和使用- Wifi热点创建相关技术
- 基于Wifi的文件传输方法
- Demo的展示与介绍
- 小结
1. Wifi传输概述
1.1 步骤
- 发现对方IP地址:涉及
WifiP2pManager
和Wifi热点的创建 - 监听端口,建立Socket通讯
- 传输文件或其他信息
1.2 应用
- 应用、照片、视频等文件的分发和传输
- 手机与手机,手机与PC网页的通讯、文件传输
2. WifiP2pManager
类的介绍和使用
该方法提供了对WiFi peer-to-peer传输的管理API,从而使得应用可以发现可用的peer,设置到peer的连接以及查询peer列表。本质上其功能也可以通过UDP广播实现。
2.1 简介
WiFi p2p常用方法
|
|
WiFi p2p常用监听器
|
|
2.2 初始化
2.2.1 对wifi p2p intent广播进行监听
|
|
2.2.2 创建wifi p2p应用
- 申请权限
|
|
- 初始化
WiFiP2PManager
,设置IntentFilter
并注册广播接收对象
|
|
2.3 发现方法
|
|
3. Wifi热点创建相关技术
安卓系统将热点控制API设置为@hide
属性,需要使用反射机制调用。Wifi热点的创建相关技术主要分为两步:
创建
WifiConfiguration
, 调用setWifiApEnabled
函数讲配置文件写入系统,从而开启Wifi热点。1234567891011121314151617181920212223242526272829303132333435363738private void createWifiAp(String ssid, String password) {if (mWifiManager.isWifiEnabled()) {mWifiManager.setWifiEnabled(false);}mNetConfig = new WifiConfiguration();mNetConfig.SSID = ssid;mNetConfig.preSharedKey = password;mNetConfig.status = WifiConfiguration.Status.ENABLED;mNetConfig.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);mNetConfig.allowedProtocols.set(WifiConfiguration.Protocol.RSN);mNetConfig.allowedProtocols.set(WifiConfiguration.Protocol.WPA);mNetConfig.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);mNetConfig.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);mNetConfig.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);mNetConfig.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);mNetConfig.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);//NONE);try {Method setWifiApMethod = mWifiManager.getClass().getMethod("setWifiApEnabled", WifiConfiguration.class, boolean.class);boolean apstatus = (Boolean) setWifiApMethod.invoke(mWifiManager, mNetConfig, true);Method isWifiApEnabledmethod = mWifiManager.getClass().getMethod("isWifiApEnabled");while (!(Boolean) isWifiApEnabledmethod.invoke(mWifiManager)) {};Method getWifiApStateMethod = mWifiManager.getClass().getMethod("getWifiApState");int apstate = (Integer) getWifiApStateMethod.invoke(mWifiManager);Method getWifiApConfigurationMethod = mWifiManager.getClass().getMethod("getWifiApConfiguration");mNetConfig = (WifiConfiguration) getWifiApConfigurationMethod.invoke(mWifiManager);Log.d("CLIENT", "\nSSID:" + mNetConfig.SSID + "\nPassword:" + mNetConfig.preSharedKey + "\n");} catch (Exception e) {Log.e(TAG, e.toString());e.printStackTrace();}}下载端连接后,扫描
/proc/net/arp
文件获取连接到主机的IP。当然也可以等下载机访问我们指定的主机网址,再通过请求知道下载机的IP地址,这里暂不累述。1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859/*** Gets a list of the clients connected to the Hotspot* @param onlyReachables {@code false} if the list should contain unreachable (probably disconnected) clients, {@code true} otherwise* @param reachableTimeout Reachable Timout in miliseconds* @param finishListener, Interface called when the scan method finishes*/public void getClientList(final boolean onlyReachables, final int reachableTimeout, final FinishScanListener finishListener) {Runnable runnable = new Runnable() {public void run() {BufferedReader br = null;final ArrayList<ClientScanResult> result = new ArrayList<ClientScanResult>();try {br = new BufferedReader(new FileReader("/proc/net/arp"));String line;while ((line = br.readLine()) != null) {String[] splitted = line.split(" +");if ((splitted != null) && (splitted.length >= 4)) {// Basic sanity checkString mac = splitted[3];if (mac.matches("..:..:..:..:..:..")) {boolean isReachable = InetAddress.getByName(splitted[0]).isReachable(reachableTimeout);if (!onlyReachables || isReachable) {result.add(new ClientScanResult(splitted[0], splitted[3], splitted[5], isReachable));}}}}} catch (Exception e) {Log.e(this.getClass().toString(), e.toString());} finally {try {br.close();} catch (IOException e) {Log.e(this.getClass().toString(), e.getMessage());}}// Get a handler that can be used to post to the main threadHandler mainHandler = new Handler(context.getMainLooper());Runnable myRunnable = new Runnable() {public void run() {finishListener.onFinishScan(result);}};mainHandler.post(myRunnable);}};Thread mythread = new Thread(runnable);mythread.start();}
4. 基于Wifi的文件传输方法
基于WiFi的数据传输主要有两个技术点:一方面是文件传输,另一方面是下载端的网页实时获得文件传输的进度。前者可以直接使用ServerSocket
实现,后者对于双方均安装我们的下载app的情况没有难度,但对于一边是app发送文件,一边是网页打开连接下载文件,就需要基于JavaScript
的XMLHttpRequest
可以实现主机和下载机网页的信息交流。
4.1 使用ServerSocket
传输数据
|
|
4.2 使用XMLHttpRequest
在网页上实时获取下载进度
|
|
5. Demo的展示与介绍
wifi热点的创建和文件传输
6. 小结
6.1 基于安卓的wifi传输 ==能做到什么==?
- 局域网内,安装我们APP的手机之间的互相发现和连接
- 热点的创建和定制
- 免流量的高速、稳定的数据传输,相对于蓝牙和NFC具有很大优势
- 一方安装了APP,另一方仍可通过热点连接,基于网页JS实现与主机APP的信息交互
6.2 基于安卓的wifi传输 ==不能做到什么==?==有哪些坑==?
- 没有底层权限,很多服务器常见的设置都无法完成,比如无法设置
IPTable
- 安卓网页的局限,浏览器对JS的支持性和PC端不同,需要额外设计
- 部分安卓厂商自己修改了官方的热点API,比如HTC,这使得在这些手机上创建热点需要额外配置