Android开发实践:WIFI连接功能的封装

   在上一篇文章《Android开发实践:WIFI扫描功能的封装》介绍了如何利用Andriod的API实现WIFI的扫描,本文则重点讲述一下如何连接WIFI吧,在此,也给出一个封装WIFI连接过程的类,提供简单的接口以供在各个代码工程中复用。

专业从事成都网站制作、成都网站建设,高端网站制作设计,微信小程序,网站推广的成都做网站的公司。优秀技术团队竭力真诚服务,采用H5建站+CSS3前端渲染技术,成都响应式网站建设公司,让网站在手机、平板、PC、微信下都能呈现。建站过程建立专项小组,与您实时在线互动,随时提供解决方案,畅聊想法和感受。

   与WIFI扫描类似,WIFI的连接同样是一个耗时的过程,所以需要放到线程中执行,通过回调来通知调用者连接结果。该回调接口的定义如下:

public interface WifiConnectListener {
    public void OnWifiConnectCompleted( boolean isConnected );
}

   从Android的WIFI Setting可以看出,一般添加一个新的WIFI连接,需要给出三个信息,一个是WIFI的SSID,一个是WIFI的密码,另一个是WIFI的加密类型,不同的加密方式,连接时程序中的配置是不同的,这里定义一个枚举,给出四种常见的加密类型:

public enum SecurityMode {
    OPEN, WEP, WPA, WPA2
}

   Android的WIFI连接过程,总体上分为三步,第一步,添加网络配置,第二步,根据网络配置连接WIFI,第三步,监听系统的WIFI连接状态消息。下面就直接给出示例代码,关键的地方都在代码中注释了。

package com.example.testwifi;
                     
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.wifi.SupplicantState;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
                                                                                                                  
public class WifiConnector {
                                                                                                        
    private static final int WIFI_CONNECT_TIMEOUT = 20; //连接WIFI的超时时间
                                                                                                        
    private Context mContext;
    private WifiManager mWifiManager;           
    private Lock mLock;
    private Condition mCondition;
    private WiFiConncetReceiver mWifiConnectReceiver;
    private WifiConnectListener mWifiConnectListener;
    private boolean mIsConnnected = false;
    private int mNetworkID = -1;
              
    //网络加密模式
    public enum SecurityMode {
        OPEN, WEP, WPA, WPA2
    }
                      
   //通知连接结果的监听接口
    public interface WifiConnectListener {
        public void OnWifiConnectCompleted( boolean isConnected );
    }
                        
    public WifiConnector( Context context , WifiConnectListener listener ) {
                                                                                                            
        mContext = context;   
                                                                                                            
        mLock = new ReentrantLock();
        mCondition = mLock.newCondition();
        mWifiManager=(WifiManager)mContext.getSystemService(Context.WIFI_SERVICE);   
                                                                                                            
        mWifiConnectReceiver = new WiFiConncetReceiver();  
                                                                                                            
        mWifiConnectListener = listener;
    }
                                                                                                                
    public void connect( final String ssid, final String password, final SecurityMode mode ) {
                                                                                                            
        new Thread(new Runnable() {
                                                                                                                
            @Override
            public void run() {
                                                                                                                    
                //如果WIFI没有打开,则打开WIFI
                if( !mWifiManager.isWifiEnabled() ) {
                    mWifiManager.setWifiEnabled(true);
                }
                                                                                                                            
                //注册连接结果监听对象
                mContext.registerReceiver(mWifiConnectReceiver, new IntentFilter(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION));
                                                                                                                    
                //连接指定SSID
                if( !onConnect(ssid,password,mode) ) {
                    mWifiConnectListener.OnWifiConnectCompleted(false);
                }
                else {
                    mWifiConnectListener.OnWifiConnectCompleted(true);
                }
                                                                                                                    
                //删除注册的监听类对象
                mContext.unregisterReceiver(mWifiConnectReceiver);         
            }
        }).start();            
    }
                                                                                                        
    protected boolean onConnect( String ssid, String password, SecurityMode mode ) {
                                                                                                            
        //添加新的网络配置
        WifiConfiguration cfg = new WifiConfiguration();
        cfg.SSID = "\"" + ssid + "\"";
        if( password !=null && !"".equals(password) ) {
            //这里比较关键,如果是WEP加密方式的网络,密码需要放到cfg.wepKeys[0]里面
            if( mode == SecurityMode.WEP ) {
                cfg.wepKeys[0]   = "\"" + password + "\"";
                cfg.wepTxKeyIndex = 0;
            }
            else {
                cfg.preSharedKey = "\"" + password + "\"";
            }                  
        }
        cfg.status = WifiConfiguration.Status.ENABLED;
         
        //添加网络配置
        mNetworkID = mWifiManager.addNetwork(cfg);
                                                                                                            
        mLock.lock();
                                                                                 
        mIsConnnected = false;
            
        //连接该网络
        if( !mWifiManager.enableNetwork(mNetworkID , true) ) {
            mLock.unlock();
            return false;
        }
                                                                                                            
        try {
            //等待连接结果
            mCondition.await(WIFI_CONNECT_TIMEOUT, TimeUnit.SECONDS);
        }
        catch (InterruptedException e) {
            e.printStackTrace();       
        }
                                                                                                            
        mLock.unlock();
                                                                                                            
        return mIsConnnected;
    }  
                                                                                                        
    //监听系统的WIFI连接消息
    protected class WiFiConncetReceiver extends BroadcastReceiver {
                                                                                                                    
        @Override
        public void onReceive(Context context, Intent intent) {
                                                                                                                
            if (!WifiManager.SUPPLICANT_STATE_CHANGED_ACTION.equals(intent.getAction())) {
                return;
            }          
                                                                                                                
            mLock.lock();
                                                                                                                
            WifiInfo info = mWifiManager.getConnectionInfo();
            if ( info.getNetworkId()==mNetworkID && info.getSupplicantState() == SupplicantState.COMPLETED ) {
                mIsConnnected = true;
                mCondition.signalAll();    
            }
                                                                                                                
            mLock.unlock();
        }
    }
}

   与WIFI扫描的封装代码类似,这里也用到了Lock和Condition,就是为了阻塞地等待WIFI连接的结果,保证正确的registerReceiver和unregisterReceiver网络连接状态监听对象,同时,设置了WIFI连接超时,防止由于WIFI模块的问题导致界面收不到回调而长时间“卡死”。

   另外,AndroidManifest.xml文件中记得添加权限支持哦:

<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"></uses-permission>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"></uses-permission>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission>

   这个WIFI连接类的封装就分享到这里啦,希望对初学者有帮助,java文件见博文后面的附件,有任何疑问欢迎留言或者来信lujun.hust@gmail.com交流,或者关注我的新浪微博 @卢_俊 获取最新的文章和资讯。

附件:http://down.51cto.com/data/2364418

名称栏目:Android开发实践:WIFI连接功能的封装
本文来源:https://www.cdcxhl.com/article28/geoejp.html

成都网站建设公司_创新互联,为您提供面包屑导航软件开发网站改版网站设计公司标签优化电子商务

广告

声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联

网站优化排名