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

本文涉及的产品
密钥管理服务KMS,1000个密钥,100个凭据,1个月
简介:

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

相关文章
|
8天前
|
IDE Android开发 iOS开发
探索Android与iOS开发的差异:平台选择对项目成功的影响
【9月更文挑战第27天】在移动应用开发的世界中,Android和iOS是两个主要的操作系统平台。每个系统都有其独特的开发环境、工具和用户群体。本文将深入探讨这两个平台的关键差异点,并分析这些差异如何影响应用的性能、用户体验和最终的市场表现。通过对比分析,我们将揭示选择正确的开发平台对于确保项目成功的重要作用。
|
5天前
|
开发框架 移动开发 Android开发
安卓与iOS开发中的跨平台解决方案:Flutter入门
【9月更文挑战第30天】在移动应用开发的广阔舞台上,安卓和iOS两大操作系统各自占据半壁江山。开发者们常常面临着选择:是专注于单一平台深耕细作,还是寻找一种能够横跨两大系统的开发方案?Flutter,作为一种新兴的跨平台UI工具包,正以其现代、响应式的特点赢得开发者的青睐。本文将带你一探究竟,从Flutter的基础概念到实战应用,深入浅出地介绍这一技术的魅力所在。
22 7
|
8天前
|
开发框架 前端开发 Android开发
安卓与iOS开发中的跨平台解决方案
【9月更文挑战第27天】在移动应用开发的广阔天地中,安卓和iOS两大操作系统如同双子星座般耀眼。开发者们在这两大平台上追逐着创新的梦想,却也面临着选择的难题。如何在保持高效的同时,实现跨平台的开发?本文将带你探索跨平台开发的魅力所在,揭示其背后的技术原理,并通过实际案例展示其应用场景。无论你是安卓的忠实拥趸,还是iOS的狂热粉丝,这篇文章都将为你打开一扇通往跨平台开发新世界的大门。
|
5天前
|
缓存 Java Linux
探索安卓开发:从新手到专家的旅程
【9月更文挑战第30天】在这篇文章中,我们将一起踏上一段激动人心的旅程,探索安卓开发的广阔世界。无论你是刚入门的新手,还是希望提升技能的开发者,本文都将为你提供宝贵的知识和指导。我们将深入探讨安卓开发的基础知识、关键概念、实用工具和最佳实践,帮助你在安卓开发领域取得更大的成功。让我们一起开启这段精彩的旅程吧!
|
6天前
|
监控 安全 Java
Kotlin 在公司上网监控中的安卓开发应用
在数字化办公环境中,公司对员工上网行为的监控日益重要。Kotlin 作为一种基于 JVM 的编程语言,具备简洁、安全、高效的特性,已成为安卓开发的首选语言之一。通过网络请求拦截,Kotlin 可实现网址监控、访问时间记录等功能,满足公司上网监控需求。其简洁性有助于快速构建强大的监控应用,并便于后续维护与扩展。因此,Kotlin 在安卓上网监控应用开发中展现出广阔前景。
9 1
|
Android开发
Android中webView不能正常加载Twitter连接
问题描述: 利用webView打开twitter的连接时不能成功,显示一片空白. 解决方式: 为webView设置().setDomStorageEnabled 即:mWebView.
1189 0
|
21天前
|
Android开发 开发者 Kotlin
探索安卓开发中的新特性
【9月更文挑战第14天】本文将引导你深入理解安卓开发领域的一些最新特性,并为你提供实用的代码示例。无论你是初学者还是经验丰富的开发者,这篇文章都会给你带来新的启示和灵感。让我们一起探索吧!
|
16天前
|
Android开发 开发者
安卓开发中的自定义视图:从入门到精通
【9月更文挑战第19天】在安卓开发的广阔天地中,自定义视图是一块充满魔力的土地。它不仅仅是代码的堆砌,更是艺术与科技的完美结合。通过掌握自定义视图,开发者能够打破常规,创造出独一无二的用户界面。本文将带你走进自定义视图的世界,从基础概念到实战应用,一步步展示如何用代码绘出心中的蓝图。无论你是初学者还是有经验的开发者,这篇文章都将为你打开一扇通往创意和效率的大门。让我们一起探索自定义视图的秘密,将你的应用打造成一件艺术品吧!
40 10
|
9天前
|
存储 开发工具 Android开发
使用.NET MAUI开发第一个安卓APP
【9月更文挑战第24天】使用.NET MAUI开发首个安卓APP需完成以下步骤:首先,安装Visual Studio 2022并勾选“.NET Multi-platform App UI development”工作负载;接着,安装Android SDK。然后,创建新项目时选择“.NET Multi-platform App (MAUI)”模板,并仅针对Android平台进行配置。了解项目结构,包括`.csproj`配置文件、`Properties`配置文件夹、平台特定代码及共享代码等。
|
18天前
|
Java Linux Android开发
深入理解Android开发:从基础到高级
【9月更文挑战第17天】本文将深入探讨Android开发的各个方面,包括应用开发、操作系统等。我们将通过代码示例来展示如何创建一个简单的Android应用,并解释其背后的原理。无论你是初学者还是有经验的开发者,这篇文章都将为你提供有价值的信息和启示。
下一篇
无影云桌面