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,如需转载请自行联系原作者

相关文章
|
16天前
|
Java Android开发
Android 开发获取通知栏权限时会出现两个应用图标
Android 开发获取通知栏权限时会出现两个应用图标
12 0
|
21天前
|
调度 数据库 Android开发
构建高效Android应用:Kotlin协程的实践与优化
在Android开发领域,Kotlin以其简洁的语法和平台友好性成为了开发的首选语言。其中,Kotlin协程作为处理异步任务的强大工具,它通过提供轻量级的线程管理机制,使得开发者能够在不阻塞主线程的情况下执行后台任务,从而提升应用性能和用户体验。本文将深入探讨Kotlin协程的核心概念,并通过实例演示如何在实际的Android应用中有效地使用协程进行网络请求、数据库操作以及UI的流畅更新。同时,我们还将讨论协程的调试技巧和常见问题的解决方法,以帮助开发者避免常见的陷阱,构建更加健壮和高效的Android应用。
29 4
|
23天前
|
移动开发 Java Android开发
构建高效Android应用:Kotlin协程的实践之路
【2月更文挑战第31天】 在移动开发领域,性能优化和流畅的用户体验一直是开发者追求的目标。随着Kotlin语言的流行,其异步编程解决方案——协程(Coroutines),为Android应用带来了革命性的并发处理能力。本文将深入探讨Kotlin协程的核心概念、设计原理以及在Android应用中的实际应用案例,旨在帮助开发者掌握这一强大的工具,从而提升应用的性能和响应能力。
|
25天前
|
移动开发 调度 Android开发
构建高效Android应用:探究Kotlin协程的优势与实践
【2月更文挑战第30天】 在移动开发领域,尤其是针对Android平台,性能优化和应用流畅度始终是开发者关注的重点。近年来,Kotlin语言凭借其简洁性和功能性成为Android开发的热门选择。其中,Kotlin协程作为一种轻量级的线程管理解决方案,为异步编程提供了强大支持,使得编写非阻塞性代码变得更加容易。本文将深入分析Kotlin协程的核心优势,并通过实际案例展示如何有效利用协程提升Android应用的性能和响应速度。
|
13天前
|
Java Android开发 开发者
构建高效Android应用:Kotlin协程的实践与优化
在响应式编程范式日益盛行的今天,Kotlin协程作为一种轻量级的线程管理解决方案,为Android开发带来了性能和效率的双重提升。本文旨在探讨Kotlin协程的核心概念、实践方法及其在Android应用中的优化策略,帮助开发者构建更加流畅和高效的应用程序。通过深入分析协程的原理与应用场景,结合实际案例,本文将指导读者如何优雅地解决异步任务处理,避免阻塞UI线程,从而优化用户体验。
|
7天前
|
移动开发 API Android开发
构建高效Android应用:探究Kotlin协程的优势与实践
【4月更文挑战第7天】 在移动开发领域,性能优化和应用响应性的提升一直是开发者追求的目标。近年来,Kotlin语言因其简洁性和功能性在Android社区中受到青睐,特别是其对协程(Coroutines)的支持,为编写异步代码和处理并发任务提供了一种更加优雅的解决方案。本文将探讨Kotlin协程在Android开发中的应用,揭示其在提高应用性能和简化代码结构方面的潜在优势,并展示如何在实际项目中实现和优化协程。
|
7天前
|
XML 开发工具 Android开发
构建高效的安卓应用:使用Jetpack Compose优化UI开发
【4月更文挑战第7天】 随着Android开发不断进化,开发者面临着提高应用性能与简化UI构建流程的双重挑战。本文将探讨如何使用Jetpack Compose这一现代UI工具包来优化安卓应用的开发流程,并提升用户界面的流畅性与一致性。通过介绍Jetpack Compose的核心概念、与传统方法的区别以及实际集成步骤,我们旨在提供一种高效且可靠的解决方案,以帮助开发者构建响应迅速且用户体验优良的安卓应用。
|
16天前
|
Android开发
Android开发小技巧:怎样在 textview 前面加上一个小图标。
Android开发小技巧:怎样在 textview 前面加上一个小图标。
10 0
|
16天前
|
Android开发
Android 开发 pickerview 自定义选择器
Android 开发 pickerview 自定义选择器
10 0
|
23天前
|
Java Android开发
Android开发系列全套课程
本系列课程面向有java基础,想进入企业从事android开发的计算机专业者。学习搭配实战案例,高效掌握岗位知识。
16 1