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

相关文章
|
4天前
|
Linux 编译器 Android开发
FFmpeg开发笔记(九)Linux交叉编译Android的x265库
在Linux环境下,本文指导如何交叉编译x265的so库以适应Android。首先,需安装cmake和下载android-ndk-r21e。接着,下载x265源码,修改crosscompile.cmake的编译器设置。配置x265源码,使用指定的NDK路径,并在配置界面修改相关选项。随后,修改编译规则,编译并安装x265,调整pc描述文件并更新PKG_CONFIG_PATH。最后,修改FFmpeg配置脚本启用x265支持,编译安装FFmpeg,将生成的so文件导入Android工程,调整gradle配置以确保顺利运行。
24 1
FFmpeg开发笔记(九)Linux交叉编译Android的x265库
|
27天前
|
Java Android开发
Android 开发获取通知栏权限时会出现两个应用图标
Android 开发获取通知栏权限时会出现两个应用图标
12 0
|
24天前
|
Java Android开发 开发者
构建高效Android应用:Kotlin协程的实践与优化
在响应式编程范式日益盛行的今天,Kotlin协程作为一种轻量级的线程管理解决方案,为Android开发带来了性能和效率的双重提升。本文旨在探讨Kotlin协程的核心概念、实践方法及其在Android应用中的优化策略,帮助开发者构建更加流畅和高效的应用程序。通过深入分析协程的原理与应用场景,结合实际案例,本文将指导读者如何优雅地解决异步任务处理,避免阻塞UI线程,从而优化用户体验。
|
1天前
|
数据库 Android开发 开发者
安卓应用开发:构建高效用户界面的策略
【4月更文挑战第24天】 在竞争激烈的移动应用市场中,一个流畅且响应迅速的用户界面(UI)是吸引和保留用户的关键。针对安卓平台,开发者面临着多样化的设备和系统版本,这增加了构建高效UI的复杂性。本文将深入分析安卓平台上构建高效用户界面的最佳实践,包括布局优化、资源管理和绘制性能的考量,旨在为开发者提供实用的技术指南,帮助他们创建更流畅的用户体验。
|
1天前
|
调度 Android开发 开发者
构建高效Android应用:探究Kotlin协程的优势与实践
【4月更文挑战第24天】随着移动开发技术的不断演进,提升应用性能和用户体验已成为开发者的核心任务。在Android平台上,Kotlin语言凭借其简洁性和功能性成为主流选择之一。特别是Kotlin的协程功能,它为异步编程提供了一种轻量级的解决方案,使得处理并发任务更加高效和简洁。本文将深入探讨Kotlin协程在Android开发中的应用,通过实际案例分析协程如何优化应用性能,以及如何在项目中实现协程。
|
3天前
|
Java Android开发
Android Mediatek 应用层重置USB设备功能
Android Mediatek 应用层重置USB设备功能
11 0
|
18天前
|
移动开发 API Android开发
构建高效Android应用:探究Kotlin协程的优势与实践
【4月更文挑战第7天】 在移动开发领域,性能优化和应用响应性的提升一直是开发者追求的目标。近年来,Kotlin语言因其简洁性和功能性在Android社区中受到青睐,特别是其对协程(Coroutines)的支持,为编写异步代码和处理并发任务提供了一种更加优雅的解决方案。本文将探讨Kotlin协程在Android开发中的应用,揭示其在提高应用性能和简化代码结构方面的潜在优势,并展示如何在实际项目中实现和优化协程。
|
18天前
|
XML 开发工具 Android开发
构建高效的安卓应用:使用Jetpack Compose优化UI开发
【4月更文挑战第7天】 随着Android开发不断进化,开发者面临着提高应用性能与简化UI构建流程的双重挑战。本文将探讨如何使用Jetpack Compose这一现代UI工具包来优化安卓应用的开发流程,并提升用户界面的流畅性与一致性。通过介绍Jetpack Compose的核心概念、与传统方法的区别以及实际集成步骤,我们旨在提供一种高效且可靠的解决方案,以帮助开发者构建响应迅速且用户体验优良的安卓应用。
|
20天前
|
监控 算法 Android开发
安卓应用开发:打造高效启动流程
【4月更文挑战第5天】 在移动应用的世界中,用户的第一印象至关重要。特别是对于安卓应用而言,启动时间是用户体验的关键指标之一。本文将深入探讨如何优化安卓应用的启动流程,从而减少启动时间,提升用户满意度。我们将从分析应用启动流程的各个阶段入手,提出一系列实用的技术策略,包括代码层面的优化、资源加载的管理以及异步初始化等,帮助开发者构建快速响应的安卓应用。
|
20天前
|
Java Android开发
Android开发之使用OpenGL实现翻书动画
本文讲述了如何使用OpenGL实现更平滑、逼真的电子书翻页动画,以解决传统贝塞尔曲线方法存在的卡顿和阴影问题。作者分享了一个改造后的外国代码示例,提供了从前往后和从后往前的翻页效果动图。文章附带了`GlTurnActivity`的Java代码片段,展示如何加载和显示书籍图片。完整工程代码可在作者的GitHub找到:https://github.com/aqi00/note/tree/master/ExmOpenGL。
22 1
Android开发之使用OpenGL实现翻书动画