本文转自:http://blog.csdn.net/kongxiuqi/article/details/52524500 这里将原文规整了一下。
WIFI状态变化会发送系统广播,一些可用的系统广播在WifiManger类中可以看到。
广播一:WIFI 开关状态变化的监听
/**
* Broadcast intent action indicating that Wi-Fi has been enabled, disabled,
* enabling, disabling, or unknown. One extra provides this state as an int.
* Another extra provides the previous state, if available.
*
* @see #EXTRA_WIFI_STATE
* @see #EXTRA_PREVIOUS_WIFI_STATE
*/
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String WIFI_STATE_CHANGED_ACTION = "android.net.wifi.WIFI_STATE_CHANGED";
// 自定义个Broadcast,并在Broadcast中判断这个WIFI功能的打开与关闭(与WIFI是否连接无关)
if (WifiManager.WIFI_STATE_CHANGED_ACTION.equals(intent.getAction())) {
int wifiState = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE, 0);
swtch(wifiState) {
case WifiManager.WIFI_STATE_DISABLED:
Log.d("Tag", "--- WIFI状态:已关闭WIFI功能 ---");
break;
case WifiManager.WIFI_STATE_DISABLING:
Log.d("Tag", "--- WIFI状态:正在关闭WIFI功能 ---");
break;
}
}
各个状态的值如下:
/**
* Wi-Fi is currently being disabled. The state will change to {@link #WIFI_STATE_DISABLED} if
* it finishes successfully.
*
* @see #WIFI_STATE_CHANGED_ACTION
* @see #getWifiState()
*/
public static final int WIFI_STATE_DISABLING = 0; // Wifi功能正在关闭中
/**
* Wi-Fi is disabled.
*
* @see #WIFI_STATE_CHANGED_ACTION
* @see #getWifiState()
*/
public static final int WIFI_STATE_DISABLED = 1; // Wifi功能已经关闭
/**
* Wi-Fi is currently being enabled. The state will change to {@link #WIFI_STATE_ENABLED} if
* it finishes successfully.
*
* @see #WIFI_STATE_CHANGED_ACTION
* @see #getWifiState()
*/
public static final int WIFI_STATE_ENABLING = 2; // Wifi功能正在打开中
/**
* Wi-Fi is enabled.
*
* @see #WIFI_STATE_CHANGED_ACTION
* @see #getWifiState()
*/
public static final int WIFI_STATE_ENABLED = 3; // Wifi功能已经打开
/**
* Wi-Fi is in an unknown state. This state will occur when an error happens while enabling
* or disabling.
*
* @see #WIFI_STATE_CHANGED_ACTION
* @see #getWifiState()
*/
public static final int WIFI_STATE_UNKNOWN = 4; // Wifi处于未知状态
广播二:WIFI 连接状态变化的监听
/**
* Broadcast intent action indicating that the state of Wi-Fi connectivity
* has changed. One extra provides the new state
* in the form of a {@link android.net.NetworkInfo} object. If the new
* state is CONNECTED, additional extras may provide the BSSID and WifiInfo of
* the access point.
*
* as a {@code String}.
* @see #EXTRA_NETWORK_INFO
* @see #EXTRA_BSSID
* @see #EXTRA_WIFI_INFO
*/
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String NETWORK_STATE_CHANGED_ACTION = "android.net.wifi.STATE_CHANGE";
// 监听WIFI的连接状态即是否连上了一个有效无线路由。
// 当上边广播的状态是WifiManager.WIFI_STATE_DISABLING,和WIFI_STATE_DISABLED的时候,根本不会接到这个广播(因为WIFI功能未打开,所以不可能连接上有效WIFI)。
// 当上边广播接到广播是WifiManager.WIFI_STATE_ENABLED状态的同时也会接到这个广播,当然刚打开WIFI肯定还没有连接到有效的无线
if (WifiManager.NETWORK_STATE_CHANGED_ACTION.equals(intent.getAction())) {
Parcelable parcelableExtra = intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
if (null != parcelableExtra) {
NetworkInfo networkInfo = (NetworkInfo) parcelableExtra;
NetworkInfo.State state = networkInfo.getState();
boolean isConnected = state == NetworkInfo.State.CONNECTED;
// WIFI已连接
if (isConnected) {
// ...
}
// WIFI未连接
else {
// ...
}
}
}
广播三:WIFI 列表扫描完成
/**
* An access point scan has completed, and results are available from the supplicant.
* Call {@link #getScanResults()} to obtain the results. {@link #EXTRA_RESULTS_UPDATED}
* indicates if the scan was completed successfully.
*/
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String SCAN_RESULTS_AVAILABLE_ACTION = "android.net.wifi.SCAN_RESULTS";
wifi扫描完成,获取wili列表 可以通过wifimanager的startScan主动发起扫描,扫描完成后会发送这个广播
if (WifiManager.SCAN_RESULTS_AVAILABLE_ACTION.equals(intent.getAction())) {
Log.e(TAG, "WifiManager.SCAN_RESULTS_AVAILABLE_ACTION");
WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
List<ScanResult> list = wifiManager.getScanResults();
for (int i = 0; i < list.size(); i++) {
Log.e(TAG, list.get(i).toString());
Log.e(TAG, "ScanResult SSID = " + list.get(i).SSID);
}
}
getScanResults()只能得到当前可用的WIFI列表,获取所有WIFI列表需用如下方法(该方法可以获取以前连接过的WIFI)
/**
* Return a list of all the networks configured in the supplicant.
* Not all fields of WifiConfiguration are returned. Only the following
* fields are filled in:
* networkId
* SSID
* BSSID
* priority
* allowedProtocols
* allowedKeyManagement
* allowedAuthAlgorithms
* allowedPairwiseCiphers
* allowedGroupCiphers
*
* @return a list of network configurations in the form of a list
* of {@link WifiConfiguration} objects. Upon failure to fetch or
* when when Wi-Fi is turned off, it can be null.
*/
public List<WifiConfiguration> getConfiguredNetworks() {
try {
return mService.getConfiguredNetworks();
} catch (RemoteException e) {
Log.w(TAG, "Caught RemoteException trying to get configured networks: " + e);
return null;
}
}
广播四:补充
/**
* Broadcast intent action indicating that a connection to the supplicant has
* been established (and it is now possible
* to perform Wi-Fi operations) or the connection to the supplicant has been
* lost. One extra provides the connection state as a boolean, where {@code true}
* means CONNECTED.
* @see #EXTRA_SUPPLICANT_CONNECTED
*/
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String SUPPLICANT_CONNECTION_CHANGE_ACTION =
"android.net.wifi.supplicant.CONNECTION_CHANGE";
另外还有一个监听网络状态变化的广播 ConnectivityManager.CONNECTIVITY_ACTION
/**
* A change in network connectivity has occurred. A default connection has either
* been established or lost. The NetworkInfo for the affected network is
* sent as an extra; it should be consulted to see what kind of
* connectivity event occurred.
* <p/>
* If this is a connection that was the result of failing over from a
* disconnected network, then the FAILOVER_CONNECTION boolean extra is
* set to true.
* <p/>
* For a loss of connectivity, if the connectivity manager is attempting
* to connect (or has already connected) to another network, the
* NetworkInfo for the new network is also passed as an extra. This lets
* any receivers of the broadcast know that they should not necessarily
* tell the user that no data traffic will be possible. Instead, the
* receiver should expect another broadcast soon, indicating either that
* the failover attempt succeeded (and so there is still overall data
* connectivity), or that the failover attempt failed, meaning that all
* connectivity has been lost.
* <p/>
* For a disconnect event, the boolean extra EXTRA_NO_CONNECTIVITY
* is set to {@code true} if there are no connected networks at all.
*/
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String CONNECTIVITY_ACTION = "android.net.conn.CONNECTIVITY_CHANGE";
如果我们需要判断手机进入到某个WIFI的范围就可以通过该广播,以及扫描wifi列表进行实现,代码如下:
public class NetworkConnectChangedReceiver extends BroadcastReceiver {
private static final String TAG = NetworkConnectChangedReceiver.class.getSimpleName();
@Override
public void onReceive(Context context, Intent intent) {
// 处理扫描完成广播,根据扫描结果比对是否进入了某个特定wifi范围
if (WifiManager.SCAN_RESULTS_AVAILABLE_ACTION.equals(intent.getAction())) {
Log.e(TAG, "WifiManager.SCAN_RESULTS_AVAILABLE_ACTION");
WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
List<ScanResult> list = wifiManager.getScanResults();
// 此处循环遍历,可以根据SSID 或者MAC,与某个指定wifi进行对比,如果相等可以认为进入了该wifi的范围
for (int i = 0; i < list.size(); i++) {
Log.e(TAG, list.get(i).toString());
Log.e(TAG, "ScanResult SSID = " + list.get(i).SSID);
}
}
// 这个监听网络连接的设置,包括WIFI和移动数据的打开和关闭。
// 最好用的还是这个监听。WIFI如果打开,关闭,以及连接上可用的连接都会接到监听。见log
// 这个广播的最大弊端是比上边两个广播的反应要慢,如果只是要监听wifi,我觉得还是用上边两个配合比较合适
if (ConnectivityManager.CONNECTIVITY_ACTION.equals(intent.getAction())) {
ConnectivityManager manager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo gprs = manager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
NetworkInfo wifi = manager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
Log.i(TAG, "网络状态改变:" + wifi.isConnected() + " 3g:" + gprs.isConnected());
Log.e(TAG, "ConnectivityManager.CONNECTIVITY_ACTION");
NetworkInfo info = intent
.getParcelableExtra(ConnectivityManager.EXTRA_NETWORK_INFO);
if (info != null) {
Log.e(TAG, "info.getTypeName()" + info.getTypeName());
Log.e(TAG, "getSubtypeName()" + info.getSubtypeName());
Log.e(TAG, "getState()" + info.getState());
Log.e(TAG, "getDetailedState()"
+ info.getDetailedState().name());
Log.e(TAG, "getDetailedState()" + info.getExtraInfo());
Log.e(TAG, "getType()" + info.getType());
if (NetworkInfo.State.CONNECTED == info.getState()) {
} else if (info.getType() == 1) {
if (NetworkInfo.State.DISCONNECTING == info.getState()) {
Log.e(TAG, "disconnect");
}
}
}
// 开启wifi扫描,扫描完成后发送广播
WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
wifiManager.startScan();
}
}
}
以上所有的广播接收器需要动态注册,如下:
mIntentFilter = new IntentFilter();
mIntentFilter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
mIntentFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
mIntentFilter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
mIntentFilter.addAction(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION);
mIntentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
registerReceiver(mReceiver, mIntentFilter);
或者在AndroidManifest中静态注册
<receiver android:name=".receiver.NetworkConnectChangedReceiver">
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
<action android:name="android.net.wifi.WIFI_STATE_CHANGED" />
<action android:name="android.net.wifi.STATE_CHANGE" />
<action android:name="android.net.wifi.SCAN_RESULTS" />
</intent-filter>
</receiver>
最后需要在AndroidManifest中配置权限
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />