网上关于Android WIFI模块开发的博文已经很多,这里我也想给出我对WIFI模块编程的一些消化结果,将Android的一些API封装类,方便在各个Android APP中复用,简化程序的开发。
本文先给出一个扫描WIFI功能的封装成类,创建该类对象后,当你简单地调用search()函数后,后台会自动扫描当前的WIFI SSID,并以回调的形式通知你扫描结果,代码如下,需要注意的地方都用注释标注出来了。
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
|
package
com.example.testwifi;
import
java.util.ArrayList;
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.ScanResult;
import
android.net.wifi.WifiManager;
public
class
WifiSearcher {
private
static
final
int
WIFI_SEARCH_TIMEOUT =
20
;
//扫描WIFI的超时时间
private
Context mContext;
private
WifiManager mWifiManager;
private
WiFiScanReceiver mWifiReceiver;
private
Lock mLock;
private
Condition mCondition;
private
SearchWifiListener mSearchWifiListener;
private
boolean
mIsWifiScanCompleted =
false
;
public
static
enum
ErrorType {
SEARCH_WIFI_TIMEOUT,
//扫描WIFI超时(一直搜不到结果)
NO_WIFI_FOUND,
//扫描WIFI结束,没有找到任何WIFI信号
}
//扫描结果通过该接口返回给Caller
public
interface
SearchWifiListener {
public
void
onSearchWifiFailed(ErrorType errorType);
public
void
onSearchWifiSuccess(List<String> results);
}
public
WifiSearcher( Context context, SearchWifiListener listener ) {
mContext = context;
mSearchWifiListener = listener;
mLock =
new
ReentrantLock();
mCondition = mLock.newCondition();
mWifiManager=(WifiManager)mContext.getSystemService(Context.WIFI_SERVICE);
mWifiReceiver =
new
WiFiScanReceiver();
}
public
void
search() {
new
Thread(
new
Runnable() {
@Override
public
void
run() {
//如果WIFI没有打开,则打开WIFI
if
( !mWifiManager.isWifiEnabled() ) {
mWifiManager.setWifiEnabled(
true
);
}
//注册接收WIFI扫描结果的监听类对象
mContext.registerReceiver(mWifiReceiver,
new
IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));
//开始扫描
mWifiManager.startScan();
mLock.lock();
//阻塞等待扫描结果
try
{
mIsWifiScanCompleted =
false
;
mCondition.await(WIFI_SEARCH_TIMEOUT, TimeUnit.SECONDS);
if
( !mIsWifiScanCompleted ) {
mSearchWifiListener.onSearchWifiFailed(ErrorType.SEARCH_WIFI_TIMEOUT);
}
}
catch
(InterruptedException e) {
e.printStackTrace();
}
mLock.unlock();
//删除注册的监听类对象
mContext.unregisterReceiver(mWifiReceiver);
}
}).start();
}
//系统WIFI扫描结果消息的接收者
protected
class
WiFiScanReceiver
extends
BroadcastReceiver {
public
void
onReceive(Context c, Intent intent) {
//提取扫描结果
List<String> ssidResults =
new
ArrayList<String>();
List<ScanResult> scanResults = mWifiManager.getScanResults();
for
(ScanResult result : scanResults ) {
ssidResults.add(result.SSID);
}
//检测扫描结果
if
( ssidResults.isEmpty() ) {
mSearchWifiListener.onSearchWifiFailed(ErrorType.NO_WIFI_FOUND);
}
else
{
mSearchWifiListener.onSearchWifiSuccess(ssidResults);
}
mLock.lock();
mIsWifiScanCompleted =
true
;
mCondition.signalAll();
mLock.unlock();
}
}
}
|
代码中用到了Lock和Condition,就是为了阻塞地等待WIFI扫描的结果,以来可以在search函数内部直接完成监听对象的registerReceiver和unregisterReceiver,防止由于某些原因忘记unregisterReceiver导致程序crash,另一方面,针对某些Android系统可能不一定能够及时收到WIFI扫描结果而设置一个超时时间,这样,不至于UI一直长时间地等待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/1394948,如需转载请自行联系原作者