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

简介:

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

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


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


1
2
3
public  enum  SecurityMode {
     OPEN, WEP, WPA, WPA2
}


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


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
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
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文件中记得添加权限支持哦:


1
2
3
<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>


本文转自 Jhuster 51CTO博客,原文链接:http://blog.51cto.com/ticktick/1410080,如需转载请自行联系原作者

相关文章
|
3月前
|
移动开发 前端开发 Android开发
【02】建立各项目录和页面标准化产品-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
【02】建立各项目录和页面标准化产品-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
367 12
【02】建立各项目录和页面标准化产品-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
|
3月前
|
移动开发 JavaScript 应用服务中间件
【06】优化完善落地页样式内容-精度优化-vue加vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
【06】优化完善落地页样式内容-精度优化-vue加vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
369 5
【06】优化完善落地页样式内容-精度优化-vue加vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
|
3月前
|
移动开发 Rust JavaScript
【01】首页建立-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
【01】首页建立-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
815 4
【01】首页建立-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
|
4月前
|
开发工具 Android开发
X Android SDK file not found: adb.安卓开发常见问题-Android SDK 缺少 `adb`(Android Debug Bridge)-优雅草卓伊凡
X Android SDK file not found: adb.安卓开发常见问题-Android SDK 缺少 `adb`(Android Debug Bridge)-优雅草卓伊凡
630 11
X Android SDK file not found: adb.安卓开发常见问题-Android SDK 缺少 `adb`(Android Debug Bridge)-优雅草卓伊凡
|
3月前
|
移动开发 Android开发
【03】建立隐私关于等相关页面和内容-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
【03】建立隐私关于等相关页面和内容-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
209 0
|
XML API Android开发
Android WIFI使用简述(上)
Android WIFI使用简述(上)
948 1
|
Android开发 Python
Python封装ADB获取Android设备wifi地址的方法
Python封装ADB获取Android设备wifi地址的方法
396 0
|
Android开发
Android 状态栏WiFi图标的显示逻辑
Android 状态栏WiFi图标的显示逻辑
762 0
|
Android开发
Android获取当前连接的wifi名称
Android获取当前连接的wifi名称
812 6
|
Android开发
android连接指定wifi
android连接指定wifi
577 0

热门文章

最新文章