【移动开发】WIFI热点通信(一)
之前调查过Android中WIFI模块的使用,也写过两篇学习总结的文章(http://smallwoniu.blog.51cto.com/3911954/1334951),后来发现DEMO里面还是有许多不足之处,前段时间有不少人Q我,问到WIFI模块中的一些细节,小弟这里只能说声抱歉,因为当时的我也还没研究到那个层次呀。。。,后来毕业设计选题干脆直接选择了关于WIFI热点通信方面的题目,调查和整理了一些资料,进行了一段时间的学习算是弥补了自己的短板吧,主要还是希望自己能够更加全面的掌握这方面的知识。 废话不多说了!今天主要讲解WIFI热点通信的前期准备工作: 1.热点创建:创建指定名称的热点。 2.热点搜索:搜索附近可用热点,生成列表。 3.热点连接:在列表中点击指定名称的WIFI项,进行连接操作。 一.框架搭建 说明: 1.几个权限: 1 2 3 4 5 6 < uses-permission android:name = "android.permission.INTERNET" /> < uses-permission android:name = "android.permission.ACCESS_NETWORK_STATE" /> < uses-permission android:name = "android.permission.CHANGE_NETWORK_STATE" /> < uses-permission android:name = "android.permission.ACCESS_WIFI_STATE" /> < uses-permission android:name = "android.permission.CHANGE_WIFI_STATE" /> < uses-permission android:name = "android.permission.WAKE_LOCK" /> 2.相关类图: 二.模块讲解 接下来通过以下三个部分功能来逐一剖析,在此之前首先看一张最终的效果图加深以下印象: (由于本章讲解的部分是我的整个项目中的一部分,所以大家不用在意图片素材等其他细节) 2.1热点创建 点击WIFI管理界面中创建热点按钮,首先会检测当前WIFI是否可用,若可用则需将其关闭掉才能创建WIFI热点,因为手机热点把手机的接收GPRS或3G信号转化为WIFI信号再发出去,即你的手机就成了一个WIFI热点,所以共享和接收功能是不能同时进行的。之后就是创建指定名称的热点过程。热点创建时序图如下图所示。 几个核心方法: startApWifiHot() 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 /** *createahotwifi * *@paramwifiName */ public boolean startApWifiHot(StringwifiName){ Log.i(TAG, "intostartApWifiHot(StringwifiName)wifiName=" +wifiName); if (wifiManager.isWifiEnabled()){ wifiManager.setWifiEnabled( false ); } if (mWifiHotAdmin!= null ){ return mWifiHotAdmin.startWifiAp(wifiName); } Log.i(TAG, "outstartApWifiHot(StringwifiName)" ); return false ; } createWifiAp() 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 /** *starthotpot *@paramwifiName *@return */ private boolean createWifiAp(StringwifiName){ Log.i(TAG, "intostartWifiAp()启动一个Wifi热点!" ); Methodmethod1= null ; boolean ret= false ; try { //setWifiApEnabledis@hide,soreflect method1=mWifiManager.getClass().getMethod( "setWifiApEnabled" , WifiConfiguration. class , boolean . class ); WifiConfigurationapConfig=createPassHotWifiConfig(wifiName,Global.PASSWORD); ret=(Boolean)method1.invoke(mWifiManager,apConfig, true ); } catch (IllegalArgumentExceptione){ e.printStackTrace(); Log.d(TAG, "stratWifiAp()IllegalArgumentExceptione" ); } Log.i(TAG, "outstartWifiAp()启动一个Wifi热点!" ); return ret; } 2.2热点搜索 点击WIFI管理界面中搜索热点按钮,同创建一样,首先需要检测WIFI热点是否关闭,将其关闭掉后才能打开WIFI搜索功能。在搜索完成后系统会发送WIFI状态变化广播来通知消息栏,这里通过自定义广播接收器接收了搜索成功消息,最后通过回调MainActivity中disPlayWifiScanResult()来显示WIFI列表。 几个核心方法: scanWifiHot() 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 /**scanwifihot**/ public void scanWifiHot(){ Log.i(TAG, "intowifiHotScan()" ); if (mWifiHotAdmin.isWifiApEnabled(wifiManager)){ mWifiHotAdmin.closeWifiAp(); } if (!wifiIsOpen()){ //WIFIisclosecurrently //listentothespecifiedSSIDwifistate registerWifiStateBroadcast( "" ); mWifiStateReceiver.setOperationsType(OperationsType.SCAN); //openwifi openWifi(); } else { //WIFIisopencurrently scanNearWifiHots(); } Log.i(TAG, "outwifiHotScan()" ); } scanNearWifiHots() 1 2 3 4 5 6 /**scannearwifi**/ private void scanNearWifiHots(){ registerWifiScanBroadcast(); //startscan wifiManager.startScan(); } 说明:这里的扫描实现过程是通过调用系统中WifiManager中扫描功能。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 /** *Requestascanforaccesspoints.Returnsimmediately.Theavailability *oftheresultsismadeknownlaterbymeansofanasynchronouseventsent *oncompletionofthescan. *@return{@codetrue}iftheoperationsucceeded,i.e.,thescanwasinitiated */ public boolean startScan(){ try { mService.startScan( false ); return true ; } catch (RemoteExceptione){ return false ; } } 2.3热点连接 在搜索完成之后,需要在WIFI列表中找到游戏的热点,点击连接过程会处理一系列逻辑:当前WIFI可用、是否已经连接、注册WIFI状态变化广播等,之后,开启独立线程进行热点匹配连接,热点连接时序图如图所示。 几个核心方法: connectToHotpot() 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 /** *connecttohotpot * *@paramssid *@paramwifiList *@parampassword */ public void connectToHotpot(Stringssid,List<ScanResult>wifiList,Stringpassword){ if (ssid== null ||password.equals( "" )||!ssid.equals(Global.HOTPOT_NAME)){ Log.d(TAG, "WIFIssidisnullor" ); mWifiBroadCastOperator.disPlayWifiConnResult( false , null ); return ; } if (ssid.equalsIgnoreCase(mSSID)&&isConnecting){ Log.d(TAG, "samessidisconnecting!" ); mWifiBroadCastOperator.disPlayWifiConnResult( false , null ); return ; } if (!checkCoonectHotIsEnable(ssid,wifiList)){ Log.d(TAG, "ssidisnotinthewifiList!" ); mWifiBroadCastOperator.disPlayWifiConnResult( false , null ); return ; } if (!wifiIsOpen()){ //listentossidwifi registerWifiStateBroadcast(ssid); mWifiStateReceiver.setOperationsType(OperationsType.CONNECT); //openwifi openWifi(); } else { //realconnecting enableNetwork(ssid,password); } } enableNetwork() 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 /** *connectwifihotreallybythread * *@paramssid *@parampassword */ private void enableNetwork( final Stringssid, final Stringpassword){ //deletemoreconnetedwifi deleteMoreCon(ssid); registerWifiConnectBroadCast(); new Thread( new Runnable(){ @Override public void run(){ WifiConfigurationconfig=WifiHotConfigAdmin.createWifiNoPassInfo(ssid,password); //ifconnectissuccessful isConnecting=connectHotSpot(config); mSSID=ssid; if (!isConnecting){ Log.i(TAG, "intoenableNetwork(WifiConfigurationwifiConfig)isConnecting=" +isConnecting); return ; } } }).start(); } connectHotSpot() 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 /** *connectwifihotifsuccessful * *@paramwifiConfig *@return */ private boolean connectHotSpot(WifiConfigurationwifiConfig){ Log.i(TAG, "intoenableNetwork(WifiConfigurationwifiConfig)" ); //theIDofthenewlycreatednetworkdescription int wcgID=wifiManager.addNetwork(wifiConfig); Log.i(TAG, "intoenableNetwork(WifiConfigurationwifiConfig)wcID=" +wcgID); if (wcgID< 0 ){ return false ; } boolean flag=wifiManager.enableNetwork(wcgID, true ); Log.i(TAG, "outenableNetwork(WifiConfigurationwifiConfig)" ); return flag; } 说明:连接热点的过程实质上就是获取热点配置信息,之后将其添加到自己的网络信息中同时使其可用。 至此,WIFI热点通信的前期工作已经完成,连接的手机端已在同一局域网内,若再有手机连接进来会自动为其分配该网段内的IP地址,接下来我们要做的就是在IP地址上实现数据的传输通信。在下一章中准备实现一个多人聊天室功能,希望能够帮助到大家! 源码下载:http://down.51cto.com/data/1812897 本文转自zhf651555765 51CTO博客,原文链接:http://blog.51cto.com/smallwoniu/1536126,如需转载请自行联系原作者