如何检测何时在Android中建立WIFI连接?
我需要检测何时通过WIFI进行网络连接。 发送什么广播来建立有效的网络连接。 我需要验证HTTP的有效网络连接是否存在。 我应该听什么,以及需要做什么额外的测试才能知道存在有效的连接。
您可以注册一个BroadcastReceiver
,以便在WiFi连接建立时(或连接已更改)通知。
注册BroadcastReceiver
:
IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION); registerReceiver(broadcastReceiver, intentFilter);
然后在你的BroadcastReceiver
做这样的事情:
@Override public void onReceive(Context context, Intent intent) { final String action = intent.getAction(); if (action.equals(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION)) { if (intent.getBooleanExtra(WifiManager.EXTRA_SUPPLICANT_CONNECTED, false)){ //do stuff } else { // wifi connection was lost } } }
有关更多信息,请参阅BroadcastReceiver
和WifiManager
的文档
当然,你应该先检查一下设备是否已经连接到WiFi。
编辑:感谢ban-geoengineering,这里有一个方法来检查设备是否已经连接:
private boolean isConnectedViaWifi() { ConnectivityManager connectivityManager = (ConnectivityManager) appObj.getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo mWifi = connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI); return mWifi.isConnected(); }
最适合我的是:
AndroidManifest
<receiver android:name="com.AEDesign.communication.WifiReceiver" > <intent-filter android:priority="100"> <action android:name="android.net.wifi.STATE_CHANGE" /> </intent-filter> </receiver>
BroadcastReceiver类
public class WifiReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { NetworkInfo info = intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO); if(info != null && info.isConnected()) { // Do your work. // eg To check the Network Name or other info: WifiManager wifiManager = (WifiManager)context.getSystemService(Context.WIFI_SERVICE); WifiInfo wifiInfo = wifiManager.getConnectionInfo(); String ssid = wifiInfo.getSSID(); } } }
权限
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
对于我来说只有WifiManager.NETWORK_STATE_CHANGED_ACTION
作品。
注册广播接收机:
IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION); registerReceiver(broadcastReceiver, intentFilter);
并获得:
@Override public void onReceive(Context context, Intent intent) { final String action = intent.getAction(); if(action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)){ NetworkInfo info = intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO); boolean connected = info.isConnected(); //call your method } }
用户@JPM和@usman给出的答案确实非常有用。 它工作正常,但在我的情况下,它是在我的情况下多次接收4次,所以我的代码多次执行。
我做了一些修改,并按照我的要求,现在只有一次
这里是广播的java类。
public class WifiReceiver extends BroadcastReceiver { String TAG = getClass().getSimpleName(); private Context mContext; @Override public void onReceive(Context context, Intent intent) { mContext = context; if (intent.getAction().equals(ConnectivityManager.CONNECTIVITY_ACTION)) { ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo networkInfo = cm.getActiveNetworkInfo(); if (networkInfo != null && networkInfo.getType() == ConnectivityManager.TYPE_WIFI && networkInfo.isConnected()) { // Wifi is connected WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE); WifiInfo wifiInfo = wifiManager.getConnectionInfo(); String ssid = wifiInfo.getSSID(); Log.e(TAG, " -- Wifi connected --- " + " SSID " + ssid ); } } else if (intent.getAction().equalsIgnoreCase(WifiManager.WIFI_STATE_CHANGED_ACTION)) { int wifiState = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE, WifiManager.WIFI_STATE_UNKNOWN); if (wifiState == WifiManager.WIFI_STATE_DISABLED) { Log.e(TAG, " ----- Wifi Disconnected ----- "); } } } }
在AndroidManifest中
<receiver android:name=".util.WifiReceiver" android:enabled="true"> <intent-filter> <action android:name="android.net.wifi.WIFI_STATE_CHANGED" /> <action android:name="android.net.conn.CONNECTIVITY_CHANGE"/> </intent-filter> </receiver> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
如果您允许用户选择覆盖每次询问的正常行为,则可以启动WiFi连接。
我选择使用三种方法…
public boolean isOnline() { ConnectivityManager connMgr = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo networkInfo = connMgr.getActiveNetworkInfo(); return (networkInfo != null && networkInfo.isConnected()); }
这是快速检查是否有互联网连接无线或CellData。 从这里你可以选择你想要采取的行动。 它是否在飞行模式也需要检查。
在一个单独的线程。 我设置一个变量IpAddress =“”并轮询,直到我有一个有效的IP地址。
WifiManager wifi; wifi = (WifiManager) this.getSystemService(Context.WIFI_SERVICE); WifiInfo wifiInfo = wifi.getConnectionInfo(); int ipAddress = wifiInfo.getIpAddress(); String ip = null; ip = String.format("%d.%d.%d.%d", (ipAddress & 0xff), (ipAddress >> 8 & 0xff), (ipAddress >> 16 & 0xff), (ipAddress >> 24 & 0xff)); Log.e(" >>IP number Begin ",ip);
另一个代码片段…如果它不打开(用户事先许可)
if(wifi.isWifiEnabled()!=true)wifi.setWifiEnabled(true);
为了检测WIFI连接状态,我使用了ConnectivityManager类的CONNECTIVITY_ACTION:
IntentFilter filter=new IntentFilter(); filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION); registerReceiver(receiver, filter);
从您的BroadCastReceiver:
if (ConnectivityManager.CONNECTIVITY_ACTION.equals(action)) { int networkType = intent.getIntExtra( android.net.ConnectivityManager.EXTRA_NETWORK_TYPE, -1); if (ConnectivityManager.TYPE_WIFI == networkType) { NetworkInfo networkInfo = (NetworkInfo) intent .getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO); if (networkInfo != null) { if (networkInfo.isConnected()) { // TODO: wifi is connected } else { // TODO: wifi is not connected } } } }
PS:适合我的工作:)
这段代码根本不需要许可。 它仅限于Wi-Fi网络连接状态更改(不考虑任何其他网络)。 接收器静态发布在AndroidManifest.xml文件中,不需要导出,因为在每次网络连接状态改变时,系统protected broadcast
NETWORK_STATE_CHANGED_ACTION
将调用接收器。
AndroidManifest:
<receiver android:name=".WifiReceiver" android:enabled="true" android:exported="false"> <intent-filter> <!--protected-broadcast: Special broadcast that only the system can send--> <!--Corresponds to: android.net.wifi.WifiManager.NETWORK_STATE_CHANGED_ACTION--> <action android:name="android.net.wifi.STATE_CHANGE" /> </intent-filter> </receiver>
BroadcastReceiver类:
public class WifiReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { /* Tested (I didn't test with the WPS "Wi-Fi Protected Setup" standard): In API15 (ICE_CREAM_SANDWICH) this method is called when the new Wi-Fi network state is: DISCONNECTED, OBTAINING_IPADDR, CONNECTED or SCANNING In API19 (KITKAT) this method is called when the new Wi-Fi network state is: DISCONNECTED (twice), OBTAINING_IPADDR, VERIFYING_POOR_LINK, CAPTIVE_PORTAL_CHECK or CONNECTED (Those states can be obtained as NetworkInfo.DetailedState objects by calling the NetworkInfo object method: "networkInfo.getDetailedState()") */ /* * NetworkInfo object associated with the Wi-Fi network. * It won't be null when "android.net.wifi.STATE_CHANGE" action intent arrives. */ NetworkInfo networkInfo = intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO); if (networkInfo != null && networkInfo.isConnected()) { // TODO: Place the work here, like retrieving the access point's SSID /* * WifiInfo object giving information about the access point we are connected to. * It shouldn't be null when the new Wi-Fi network state is CONNECTED, but it got * null sometimes when connecting to a "virtualized Wi-Fi router" in API15. */ WifiInfo wifiInfo = intent.getParcelableExtra(WifiManager.EXTRA_WIFI_INFO); String ssid = wifiInfo.getSSID(); } } }
权限:
None
这里是我的代码的一个例子,考虑到用户的偏好只有连接到Wifi时允许通信。
我在尝试下载内容之前从IntentService
调用此代码。
请注意,如果没有任何类型的网络连接,则NetworkInfo
将为null
。
private boolean canConnect() { ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); boolean canConnect = false; boolean wifiOnly = SharedPreferencesUtils.wifiOnly(); NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo(); if(networkInfo != null) { if(networkInfo.isConnected()) { if((networkInfo.getType() == ConnectivityManager.TYPE_WIFI) || (networkInfo.getType() != ConnectivityManager.TYPE_WIFI && !wifiOnly)) { canConnect = true; } } } return canConnect; }
我用这个代码:
public class MainActivity extends Activity { . . . @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); . . . } @Override protected void onResume() { super.onResume(); IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION); registerReceiver(broadcastReceiver, intentFilter); } @Override protected void onPause() { super.onPause(); unregisterReceiver(broadcastReceiver); } private final BroadcastReceiver broadcastReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { final String action = intent.getAction(); if (action.equals(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION)) { if (intent.getBooleanExtra(WifiManager.EXTRA_SUPPLICANT_CONNECTED, false)) { // wifi is enabled } else { // wifi is disabled } } } }; }
我有两种方法来检测接收应用程序上下文的WIFI连接:
1)我的老方法
public boolean isConnectedWifi1(Context context) { try { ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo(); if (networkInfo != null) { NetworkInfo[] netInfo = connectivityManager.getAllNetworkInfo(); for (NetworkInfo ni : netInfo) { if ((ni.getTypeName().equalsIgnoreCase("WIFI")) && ni.isConnected()) { return true; } } } return false; } catch (Exception e) { Log.e(TAG, e.getMessage()); } return false; }
2)我的新方法(我目前使用这种方法):
public boolean isConnectedWifi(Context context) { ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo networkInfo = connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI); return networkInfo.isConnected(); }
对于所有享受CONNECTIVITY_CHANGE广播的用户,请注意,Android应用程序在Android O后台不会被解雇。
https://developer.android.com/about/versions/o/background.html