• 【移动开发】WIFI热点通信(一)


    之前调查过Android中WIFI模块的使用,也写过两篇学习总结的文章(http://smallwoniu.blog.51cto.com/3911954/1334951),后来发现DEMO里面还是有许多不足之处,前段时间有不少人Q我,问到WIFI模块中的一些细节,小弟这里只能说声抱歉,因为当时的我也还没研究到那个层次呀。。。j_0065.gif,后来毕业设计选题干脆直接选择了关于WIFI热点通信方面的题目,调查和整理了一些资料,进行了一段时间的学习算是弥补了自己的短板吧j_0023.gif,主要还是希望自己能够更加全面的掌握这方面的知识。

        废话不多说了!今天主要讲解WIFI热点通信的前期准备工作:

              1.热点创建:创建指定名称的热点。

              2.热点搜索:搜索附近可用热点,生成列表。

              3.热点连接:在列表中点击指定名称的WIFI项,进行连接操作。

    一.框架搭建

    wKiom1O3YpuhZeJ_AAIVaeQ9nDg319.jpg

    说明:

        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.相关类图:

    wKioL1O3a7axy1MJAAUIokYZYMU090.jpg

    二.模块讲解

        接下来通过以下三个部分功能来逐一剖析,在此之前首先看一张最终的效果图加深以下印象:

    wKiom1Pg3p3AZvwFAAQOxnuufCQ678.jpg

    (由于本章讲解的部分是我的整个项目中的一部分,所以大家不用在意图片素材等其他细节)

    2.1热点创建

    点击WIFI管理界面中创建热点按钮,首先会检测当前WIFI是否可用,若可用则需将其关闭掉才能创建WIFI热点,因为手机热点把手机的接收GPRS或3G信号转化为WIFI信号再发出去,即你的手机就成了一个WIFI热点,所以共享和接收功能是不能同时进行的。之后就是创建指定名称的热点过程。热点创建时序图如下图所示。

    wKiom1O3ay2S4_tSAAIGewCcmek065.jpg

    几个核心方法:

    • startApWifiHot()

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    /**
     * create a hot wifi
     
     * @param wifiName
     */
    public boolean startApWifiHot(String wifiName) {
        Log.i(TAG, "into startApWifiHot(String wifiName) wifiName = " + wifiName);
        if (wifiManager.isWifiEnabled()) {
            wifiManager.setWifiEnabled(false);
        }
        if (mWifiHotAdmin != null) {
            return mWifiHotAdmin.startWifiAp(wifiName);
        }
        Log.i(TAG, "out startApWifiHot(String wifiName)");
        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
    /**
     * start hot pot
     * @param wifiName
     * @return
     */
    private boolean createWifiAp(String wifiName) {
        Log.i(TAG, "into startWifiAp() 启动一个Wifi 热点!");
        Method method1 = null;
        boolean ret = false;
        try {
            //setWifiApEnabled is @hide, so reflect 
            method1 = mWifiManager.getClass().getMethod("setWifiApEnabled",
                WifiConfiguration.classboolean.class);
            WifiConfiguration apConfig = createPassHotWifiConfig(wifiName,Global.PASSWORD);
            ret = (Boolean) method1.invoke(mWifiManager, apConfig, true);
        catch (IllegalArgumentException e) {
            e.printStackTrace();
            Log.d(TAG, "stratWifiAp() IllegalArgumentException e");
        
        Log.i(TAG, "out startWifiAp() 启动一个Wifi 热点!");
        return ret;
    }

    2.2热点搜索

     

    点击WIFI管理界面中搜索热点按钮,同创建一样,首先需要检测WIFI热点是否关闭,将其关闭掉后才能打开WIFI搜索功能。在搜索完成后系统会发送WIFI状态变化广播来通知消息栏,这里通过自定义广播接收器接收了搜索成功消息,最后通过回调MainActivity中disPlayWifiScanResult()来显示WIFI列表。

    wKioL1O3bzXxKBjIAANr_RN0a2s869.jpg

    几个核心方法:

    • scanWifiHot()

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    /** scan wifi hot **/
    public void scanWifiHot() {
        Log.i(TAG, "into wifiHotScan()");
        if(mWifiHotAdmin.isWifiApEnabled(wifiManager)) {
            mWifiHotAdmin.closeWifiAp();
        }
        if (!wifiIsOpen()) { // WIFI is close currently
            //listen to the specified SSID wifi state 
            registerWifiStateBroadcast("");
            mWifiStateReceiver.setOperationsType(OperationsType.SCAN);
           
            //open wifi
            openWifi();
        else // WIFI is open currently
            scanNearWifiHots();
        }
        Log.i(TAG, "out wifiHotScan()");
    }
    • scanNearWifiHots()

    1
    2
    3
    4
    5
    6
    /** scan near wifi **/
    private void scanNearWifiHots() {
        registerWifiScanBroadcast();
        //start scan
        wifiManager.startScan();
    }

    说明:这里的扫描实现过程是通过调用系统中WifiManager中扫描功能。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
        /**
         * Request a scan for access points. Returns immediately. The availability
         * of the results is made known later by means of an asynchronous event sent
         * on completion of the scan.
         * @return {@code true} if the operation succeeded, i.e., the scan was initiated
         */
        public boolean startScan() {
            try {
                mService.startScan(false);
                return true;
            catch (RemoteException e) {
                return false;
            }
        }

    2.3热点连接

     

    在搜索完成之后,需要在WIFI列表中找到游戏的热点,点击连接过程会处理一系列逻辑:当前WIFI可用、是否已经连接、注册WIFI状态变化广播等,之后,开启独立线程进行热点匹配连接,热点连接时序图如图所示。

    wKiom1O3c1Sih2-JAAKKfkedIa4048.jpg

            

    几个核心方法:

    • 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
    /**
     * connect to hotpot
     
     * @param ssid
     * @param wifiList
     * @param password
     */
    public void connectToHotpot(String ssid, List<ScanResult> wifiList, String password) {
        if (ssid == null || password.equals("") || !ssid.equals(Global.HOTPOT_NAME)) {
            Log.d(TAG, "WIFI ssid is null or ");
            mWifiBroadCastOperator.disPlayWifiConnResult(falsenull);
            return;
         }
         if (ssid.equalsIgnoreCase(mSSID) && isConnecting) {
            Log.d(TAG, "same ssid is  connecting!");
            mWifiBroadCastOperator.disPlayWifiConnResult(falsenull);
            return;
         }
        if (!checkCoonectHotIsEnable(ssid, wifiList)) {
            Log.d(TAG, "ssid is not in the wifiList!");
            mWifiBroadCastOperator.disPlayWifiConnResult(falsenull);
            return;
        }
        if (!wifiIsOpen()) {
            //listen to ssid wifi
            registerWifiStateBroadcast(ssid);
            mWifiStateReceiver.setOperationsType(OperationsType.CONNECT);
             
            //open wifi
            openWifi();
        else {
            // real connecting
            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
    /**
     * connect wifi hot really by thread
     
     * @param ssid
     * @param password
     */
    private void enableNetwork(final String ssid, final String password) {
        // delete more conneted wifi
        deleteMoreCon(ssid);
        registerWifiConnectBroadCast();
         
        new Thread(new Runnable() {
            @Override
            public void run() {
                 WifiConfiguration config = WifiHotConfigAdmin.createWifiNoPassInfo(ssid,             password);
                // if connect is successful
                isConnecting = connectHotSpot(config); 
                mSSID = ssid;
                if (!isConnecting) {
                    Log.i(TAG, "into enableNetwork(WifiConfiguration wifiConfig) isConnecting             =" + isConnecting);
                    return;
                }
            }
        }).start();
    }
    • connectHotSpot()

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
        /**
         * connect wifi hot if successful
         
         * @param wifiConfig
         * @return
         */
        private boolean connectHotSpot(WifiConfiguration wifiConfig) {
            Log.i(TAG, "into enableNetwork(WifiConfiguration wifiConfig)");
            
            //the ID of the newly created network description
            int wcgID = wifiManager.addNetwork(wifiConfig);
            Log.i(TAG, "into enableNetwork(WifiConfiguration wifiConfig) wcID = "+ wcgID);
            if (wcgID < 0) {
                return false;
            }
            boolean flag = wifiManager.enableNetwork(wcgID, true);
            Log.i(TAG, "out enableNetwork(WifiConfiguration wifiConfig)");
            return flag;
        }

    说明:连接热点的过程实质上就是获取热点配置信息,之后将其添加到自己的网络信息中同时使其可用。

    wKioL1Pg3-PD39kJAAQA7Tkq3xg371.jpg

      

      

    wKioL1Pg3-eQGEkAAAQN3cyNrBc871.jpg



        至此,WIFI热点通信的前期工作已经完成,连接的手机端已在同一局域网内,若再有手机连接进来会自动为其分配该网段内的IP地址,接下来我们要做的就是在IP地址上实现数据的传输通信。在下一章中准备实现一个多人聊天室功能,希望能够帮助到大家!

    源码下载:http://down.51cto.com/data/1812897

    本文出自 “狂奔的蜗牛” 博客,请务必保留此出处http://smallwoniu.blog.51cto.com/3911954/1536126

  • 相关阅读:
    找水王续
    找水王续
    本周学习进度
    Node.js 学习
    在Linux机器上安装MySQL
    ZStack串口通信
    Java编写串口程序
    ServerSocket
    ZigBee毕设
    ZigBee相关网站链接
  • 原文地址:https://www.cnblogs.com/dongweiq/p/4742180.html
Copyright © 2020-2023  润新知