广播接收器检查互联网连接在安卓应用程序

我正在开发一个用于检查互联网连接的android广播接收器。

问题是我的广播接收器被调用了两次。我希望它只在网络可用时被调用。如果它不可用,我不想被通知。

这是广播接收机

public class NetworkChangeReceiver extends BroadcastReceiver {


@Override
public void onReceive(final Context context, final Intent intent) {
final ConnectivityManager connMgr = (ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);


final android.net.NetworkInfo wifi = connMgr
.getNetworkInfo(ConnectivityManager.TYPE_WIFI);


final android.net.NetworkInfo mobile = connMgr
.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);


if (wifi.isAvailable() || mobile.isAvailable()) {
// Do something


Log.d("Network Available ", "Flag No 1");
}
}
}

这是manifest.xml

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.broadcastreceiverforinternetconnection"
android:versionCode="1"
android:versionName="1.0" >


<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="17" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>


<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<receiver android:name=".NetworkChangeReceiver" >
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
<action android:name="android.net.wifi.WIFI_STATE_CHANGED" />
</intent-filter>
</receiver>
</application>


</manifest>
318956 次浏览

回答你第一个问题:你的广播接收器被调用两次,因为

你已经添加了两个<intent-filter>

  1. 网络连接变化:
    <action android:name="android.net.conn.CONNECTIVITY_CHANGE" /> < / p > < / >

  2. WiFi状态变化:
    <action android:name="android.net.wifi.WIFI_STATE_CHANGED" /> < / p > < / >

只用一个:
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" /> . < / p >

它将只响应一个操作而不是两个。更多信息请参见在这里

回答你的第二个问题(你想让接收者只呼叫一次,如果互联网连接可用):

你的代码是完美的;只有在互联网可用时才通知。

更新

如果你只是想检查手机是否与互联网相连,你可以使用这种方法来检查你的连接。

public boolean isOnline(Context context) {


ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo netInfo = cm.getActiveNetworkInfo();
//should check null because in airplane mode it will be null
return (netInfo != null && netInfo.isConnected());
}
public static boolean isNetworkAvailable(Context context) {
boolean isMobile = false, isWifi = false;


NetworkInfo[] infoAvailableNetworks = getConnectivityManagerInstance(
context).getAllNetworkInfo();


if (infoAvailableNetworks != null) {
for (NetworkInfo network : infoAvailableNetworks) {


if (network.getType() == ConnectivityManager.TYPE_WIFI) {
if (network.isConnected() && network.isAvailable())
isWifi = true;
}
if (network.getType() == ConnectivityManager.TYPE_MOBILE) {
if (network.isConnected() && network.isAvailable())
isMobile = true;
}
}
}


return isMobile || isWifi;
}


/* You can write such method somewhere in utility class and call it NetworkChangeReceiver like below */
public class NetworkChangedReceiver extends BroadcastReceiver
{
@Override
public void onReceive(Context context, Intent intent) {


if (isNetworkAvailable(context))
{
Toast.makeText(context, "Network Available Do operations",Toast.LENGTH_LONG).show();




}
}
}

只有当网络状态变为已连接而不是已断开时,才会调用上述广播接收器。

试试这个

public class ConnectionBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {




if (<Check internet connection available >) {
Toast.makeText(context, "connect to the internet", Toast.LENGTH_LONG).show();


/*upload background upload service*/
Intent serviceIntent = new Intent(context,<your service class>);
context.startService(serviceIntent);




}else{
Toast.makeText(context, "Connection failed", Toast.LENGTH_LONG).show();


}
}
}

一旦互联网连接触发,这(BroadcastReciever)将被加载

public class NetworkChangeReceiver extends BroadcastReceiver {


@Override
public void onReceive(final Context context, final Intent intent) {
if (checkInternet(context)) {
Toast.makeText(context, "Network Available Do operations", Toast.LENGTH_LONG).show();
}
}


boolean checkInternet(Context context) {
ServiceManager serviceManager = new ServiceManager(context);
return serviceManager.isNetworkAvailable()
}
}

ServiceManager.java

public class ServiceManager {


Context context;


public ServiceManager(Context base) {
context = base;
}


public boolean isNetworkAvailable() {
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = cm.getActiveNetworkInfo();
return networkInfo != null && networkInfo.isConnected();
}
}

权限:

 <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />

检查网络状态:

private void checkInternetConnection() {


if (br == null) {


br = new BroadcastReceiver() {


@Override
public void onReceive(Context context, Intent intent) {


Bundle extras = intent.getExtras();


NetworkInfo info = (NetworkInfo) extras
.getParcelable("networkInfo");


State state = info.getState();
Log.d("TEST Internet", info.toString() + " "
+ state.toString());


if (state == State.CONNECTED) {
Toast.makeText(getApplicationContext(), "Internet connection is on", Toast.LENGTH_LONG).show();


} else {
Toast.makeText(getApplicationContext(), "Internet connection is Off", Toast.LENGTH_LONG).show();
}


}
};


final IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
registerReceiver((BroadcastReceiver) br, intentFilter);
}
}

记得在onDestroy中注销服务。

干杯! !

public class AsyncCheckInternet extends AsyncTask<String, Void, Boolean> {


public static final int TIME_OUT = 10 * 1000;


private OnCallBack listener;


public interface OnCallBack {


public void onBack(Boolean value);
}


public AsyncCheckInternet(OnCallBack listener) {
this.listener = listener;
}


@Override
protected void onPreExecute() {
}


@Override
protected Boolean doInBackground(String... params) {


ConnectivityManager connectivityManager = (ConnectivityManager) General.context
.getSystemService(Context.CONNECTIVITY_SERVICE);


NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();


if ((networkInfo != null && networkInfo.isConnected())
&& ((networkInfo.getType() == ConnectivityManager.TYPE_WIFI) || (networkInfo
.getType() == ConnectivityManager.TYPE_MOBILE))) {
HttpURLConnection urlc;
try {
urlc = (HttpURLConnection) (new URL("http://www.google.com")
.openConnection());
urlc.setConnectTimeout(TIME_OUT);
urlc.connect();
if (urlc.getResponseCode() == HttpURLConnection.HTTP_OK) {
return true;
} else {
return false;
}
} catch (MalformedURLException e) {
e.printStackTrace();
return false;


} catch (IOException e) {
e.printStackTrace();
return false;


}
} else {
return false;
}
}


@Override
protected void onPostExecute(Boolean result) {
if (listener != null) {
listener.onBack(result);
}
}

我知道这个帖子已经很老了,而且已经有了完整的答案,但我觉得下面的帖子可能会帮助到一些人。

问题正文中的代码包含一个这里没有人解决的错误。 @Nikhil正在检查wifi/手机是否可用,而不是是否连接

解决方法如下:

@Override
public void onReceive(final Context context, final Intent intent) {
final ConnectivityManager connMgr = (ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);


final android.net.NetworkInfo wifi = connMgr
.getNetworkInfo(ConnectivityManager.TYPE_WIFI);


final android.net.NetworkInfo mobile = connMgr
.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);


if (wifi.isConnected() || mobile.isConnected()) {
// do stuff
}
}

清单:

<receiver android:name=".your.namepackage.here.ConnectivityReceiver">
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE"/>
</intent-filter>
</receiver>

接收方的类:

public class ConnectivityReceiver extends BroadcastReceiver{


@Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
switch (action) {
case ConnectivityManager.CONNECTIVITY_ACTION:
DebugUtils.logDebug("BROADCAST", "network change");
if(NetworkUtils.isConnect()){
//do action here
}
break;
}
}
}

和类utils,如example:

public class NetworkUtils {


public static boolean isConnect() {
ConnectivityManager connectivityManager = (ConnectivityManager) Application.getInstance().getSystemService(Context.CONNECTIVITY_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
Network[] netArray = connectivityManager.getAllNetworks();
NetworkInfo netInfo;
for (Network net : netArray) {
netInfo = connectivityManager.getNetworkInfo(net);
if ((netInfo.getTypeName().equalsIgnoreCase("WIFI") || netInfo.getTypeName().equalsIgnoreCase("MOBILE")) && netInfo.isConnected() && netInfo.isAvailable()) {
//if (netInfo.getState().equals(NetworkInfo.State.CONNECTED)) {
Log.d("Network", "NETWORKNAME: " + netInfo.getTypeName());
return true;
}
}
} else {
if (connectivityManager != null) {
@SuppressWarnings("deprecation")
NetworkInfo[] netInfoArray = connectivityManager.getAllNetworkInfo();
if (netInfoArray != null) {
for (NetworkInfo netInfo : netInfoArray) {
if ((netInfo.getTypeName().equalsIgnoreCase("WIFI") || netInfo.getTypeName().equalsIgnoreCase("MOBILE")) && netInfo.isConnected() && netInfo.isAvailable()) {
//if (netInfo.getState() == NetworkInfo.State.CONNECTED) {
Log.d("Network", "NETWORKNAME: " + netInfo.getTypeName());
return true;
}
}
}
}
}
return false;
}
}

增加一个广播接收器,可以监听网络连接的变化。然后使用ConnectivityManager检查设备是否连接到internet。详细的理解请参考这个帖子视频。下面是代码:

public class NetworkStateChangeReceiver extends BroadcastReceiver {
public static final String NETWORK_AVAILABLE_ACTION = "com.ajit.singh.NetworkAvailable";
public static final String IS_NETWORK_AVAILABLE = "isNetworkAvailable";


@Override
public void onReceive(Context context, Intent intent) {
Intent networkStateIntent = new Intent(NETWORK_AVAILABLE_ACTION);
networkStateIntent.putExtra(IS_NETWORK_AVAILABLE,  isConnectedToInternet(context));
LocalBroadcastManager.getInstance(context).sendBroadcast(networkStateIntent);
}


private boolean isConnectedToInternet(Context context) {
try {
if (context != null) {
ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
return networkInfo != null && networkInfo.isConnected();
}
return false;
} catch (Exception e) {
Log.e(NetworkStateChangeReceiver.class.getName(), e.getMessage());
return false;
}
}
}

我写这个接收器是为了在屏幕上显示通知,这就是为什么你会看到一个带有网络状态的本地广播。下面是显示通知的代码。

public class MainActivity extends AppCompatActivity {


@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);


IntentFilter intentFilter = new IntentFilter(NetworkStateChangeReceiver.NETWORK_AVAILABLE_ACTION);
LocalBroadcastManager.getInstance(this).registerReceiver(new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
boolean isNetworkAvailable = intent.getBooleanExtra(IS_NETWORK_AVAILABLE, false);
String networkStatus = isNetworkAvailable ? "connected" : "disconnected";


Snackbar.make(findViewById(R.id.activity_main), "Network Status: " + networkStatus, Snackbar.LENGTH_LONG).show();
}
}, intentFilter);
}
}

活动监听网络接收器广播的意图,并在屏幕上显示通知。

对于想动态注册广播的人:

BroadcastReceiver mWifiReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (checkWifiConnect()) {
Log.d(TAG, "wifi has connected");
// TODO
}
}
};


private void registerWifiReceiver() {
IntentFilter filter = new IntentFilter();
filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
mContext.registerReceiver(mWifiReceiver, filter);
}


private void unregisterWifiReceiver() {
mContext.unregisterReceiver(mWifiReceiver);
}


private boolean checkWifiConnect() {
ConnectivityManager manager = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = manager.getActiveNetworkInfo();
if (networkInfo != null
&& networkInfo.getType() == ConnectivityManager.TYPE_WIFI
&& networkInfo.isConnected()) {
return true;
}
return false;
}

每次使用广播接收器检查互联网状态:

internet status implementation

谷歌驱动器上可用的完整源代码

AndroidManifest.xml

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.INTERNET"/>
<receiver android:name=".receivers.NetworkChangeReceiver">
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
</intent-filter>
</receiver>

BroadcastReciever

package com.keshav.networkchangereceiverexample.receivers;


import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.util.Log;


import static com.keshav.networkchangereceiverexample.MainActivity.dialog;


public class NetworkChangeReceiver extends BroadcastReceiver
{
@Override
public void onReceive(Context context, Intent intent)
{
try
{
if (isOnline(context)) {
dialog(true);
Log.e("keshav", "Online Connect Intenet ");
} else {
dialog(false);
Log.e("keshav", "Conectivity Failure !!! ");
}
} catch (NullPointerException e) {
e.printStackTrace();
}
}


private boolean isOnline(Context context) {
try {
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo netInfo = cm.getActiveNetworkInfo();
//should check null because in airplane mode it will be null
return (netInfo != null && netInfo.isConnected());
} catch (NullPointerException e) {
e.printStackTrace();
return false;
}
}
}

MainActivity.java

package com.keshav.networkchangereceiverexample;


import android.content.BroadcastReceiver;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.Color;
import android.net.ConnectivityManager;
import android.os.Build;
import android.os.Handler;
import android.os.Looper;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.TextView;


import com.keshav.networkchangereceiverexample.receivers.NetworkChangeReceiver;


public class MainActivity extends AppCompatActivity {


private BroadcastReceiver mNetworkReceiver;
static TextView tv_check_connection;


@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv_check_connection=(TextView) findViewById(R.id.tv_check_connection);
mNetworkReceiver = new NetworkChangeReceiver();
registerNetworkBroadcastForNougat();


}


public static void dialog(boolean value){


if(value){
tv_check_connection.setText("We are back !!!");
tv_check_connection.setBackgroundColor(Color.GREEN);
tv_check_connection.setTextColor(Color.WHITE);


Handler handler = new Handler();
Runnable delayrunnable = new Runnable() {
@Override
public void run() {
tv_check_connection.setVisibility(View.GONE);
}
};
handler.postDelayed(delayrunnable, 3000);
}else {
tv_check_connection.setVisibility(View.VISIBLE);
tv_check_connection.setText("Could not Connect to internet");
tv_check_connection.setBackgroundColor(Color.RED);
tv_check_connection.setTextColor(Color.WHITE);
}
}




private void registerNetworkBroadcastForNougat() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
registerReceiver(mNetworkReceiver, new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
registerReceiver(mNetworkReceiver, new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
}
}


protected void unregisterNetworkChanges() {
try {
unregisterReceiver(mNetworkReceiver);
} catch (IllegalArgumentException e) {
e.printStackTrace();
}
}


@Override
public void onDestroy() {
super.onDestroy();
unregisterNetworkChanges();
}
}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.keshav.networkchangereceiverexample.MainActivity">


<TextView
android:id="@+id/tv_check_connection"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Connection establised !"
android:padding="25dp"
app:layout_constraintBottom_toBottomOf="parent"
android:gravity="center"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />


</LinearLayout>

CONNECTIVITY_ACTION文档:

针对Android 7.0 (API级别24)及以上的应用程序,如果它们在manifest中声明了广播接收器,则不会接收此广播。如果应用程序向context . registerreceiver()注册了BroadcastReceiver,并且该context仍然有效,那么应用程序仍然会接收广播。

广播接收机代码检查互联网连接变化:

public class BroadCastDetecter extends BroadcastReceiver {
public static boolean internet_status = false;
public static void checkInternetConenction(Context context) {
internet_status = false;
ConnectivityManager check = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
if (check != null) {
NetworkInfo[] info = check.getAllNetworkInfo();
if (info != null)
for (int i = 0; i < info.length; i++)
{
if (info[i].getState() == NetworkInfo.State.CONNECTED) {
internet_status = true;
}
}
if(internet_status)
{
//do what you want to if internet connection is available
}
}
}


@Override
public void onReceive(Context context, Intent intent)
{
try {
checkInternetConenction(context);
}catch(Exception e){


}
}
}

在manifest文件中添加:

 <receiver android:name=".BroadCastDetecter">
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
</intent-filter>
</receiver>

这里有一种适合活动、片段或上下文的方法。它也会自动注销,如果你做的活动/片段(在onDestroy),如果你希望:

abstract class ConnectionBroadcastReceiver : BroadcastReceiver() {
companion object {
@JvmStatic
fun registerWithoutAutoUnregister(context: Context, connectionBroadcastReceiver: ConnectionBroadcastReceiver) {
context.registerReceiver(connectionBroadcastReceiver, IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION))
}


@JvmStatic
fun registerToFragmentAndAutoUnregister(context: Context, fragment: Fragment, connectionBroadcastReceiver: ConnectionBroadcastReceiver) {
val applicationContext = context.applicationContext
registerWithoutAutoUnregister(applicationContext, connectionBroadcastReceiver)
fragment.lifecycle.addObserver(object : LifecycleObserver {
@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
fun onDestroy() {
applicationContext.unregisterReceiver(connectionBroadcastReceiver)
}
})
}


@JvmStatic
fun registerToActivityAndAutoUnregister(activity: AppCompatActivity, connectionBroadcastReceiver: ConnectionBroadcastReceiver) {
registerWithoutAutoUnregister(activity, connectionBroadcastReceiver)
activity.lifecycle.addObserver(object : LifecycleObserver {
@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
fun onDestroy() {
activity.unregisterReceiver(connectionBroadcastReceiver)
}
})
}


@JvmStatic
fun hasInternetConnection(context: Context): Boolean {
val info = (context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager).activeNetworkInfo
return !(info == null || !info.isConnectedOrConnecting)
}
}


override fun onReceive(context: Context, intent: Intent) {
val hasConnection = !intent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, false)
//        Log.d("AppLog", "conenctivity changed. hasConnection? $hasConnection")
onConnectionChanged(hasConnection)
}


abstract fun onConnectionChanged(hasConnection: Boolean)
}

在片段中的用法:

    ConnectionBroadcastReceiver.registerToFragmentAndAutoUnregister(activity!!, this, object : ConnectionBroadcastReceiver() {
override fun onConnectionChanged(hasConnection: Boolean) {
// Log.d("AppLog", "onConnectionChanged:" + hasConnection)
}
})

首先,我们将创建一个类来检查网络状态的连通性。所以让我们创建一个类:

public class AppStatus {
private static AppStatus instance = new AppStatus();
static Context context;
ConnectivityManager connectivityManager;
NetworkInfo wifiInfo, mobileInfo;
boolean connected = false;


public static AppStatus getInstance(Context ctx) {
context = ctx.getApplicationContext();
return instance;
}


public boolean isOnline() {
try {
connectivityManager = (ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);


NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
connected = networkInfo != null && networkInfo.isAvailable() &&
networkInfo.isConnected();
return connected;




} catch (Exception e) {
System.out.println("CheckConnectivity Exception: " + e.getMessage());
Log.v("connectivity", e.toString());
}
return connected;
}
}

现在创建一个新的Broadcast接收器类:

public class ConnectivityReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (AppStatus.getInstance(context).isOnline()) {


Intent intent1=new Intent(context,DisplayAct.class);
intent1.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent1);








} else {


Toast.makeText(context, "Please !! Make your network ON", Toast.LENGTH_SHORT).show();


}
}
}

现在在清单上注册您的广播接收器:

<receiver android:name=".ConnectivityReceiver">
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE"/>
</intent-filter>
</receiver>

使用https://github.com/JobGetabu/DroidNet更容易

 @Override
public void onInternetConnectivityChanged(boolean isConnected) {


if (isConnected) {
//do Stuff with internet
netIsOn();
} else {
//no internet
netIsOff();
}
}


private void netIsOn(){...}


private void netIsOff(){...}

这只检查网络接口是否可用,并不保证特定的网络服务可用,例如,可能有低信号或服务器停机

  private boolean isNetworkInterfaceAvailable(Context context) {
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
return activeNetwork != null && activeNetwork.isConnectedOrConnecting();
}

如果你想建立一个真正的连接,以确保你的连接可以从服务器或任何url收集数据:

  private boolean isAbleToConnect(String url, int timeout) {
try {
URL myUrl = new URL(url);
URLConnection connection = myUrl.openConnection();
connection.setConnectTimeout(timeout);
connection.connect();
return true;
} catch (Exception e) {
Log.i("exception", "" + e.getMessage());
return false;
}
}

这个函数需要被包装在后台线程中:

final String action = intent.getAction();
if (intent.getAction().equals(ConnectivityManager.CONNECTIVITY_ACTION)) {
checkConnectivity(context);
}
}




private void checkConnectivity(final Context context) {
if (!isNetworkInterfaceAvailable(context)) {
Toast.makeText(context, "You are OFFLINE!", Toast.LENGTH_SHORT).show();
return;
}


final Handler handler = new Handler();
new Thread(new Runnable() {
@Override
public void run() {
final boolean isConnected = isAbleToConnect("http://www.google.com", 1000);
handler.post(new Runnable() {
@Override
public void run() {
if (isConnected)
Toast.makeText(context, "You are ONLINE!", Toast.LENGTH_SHORT).show();
else
Toast.makeText(context, "You are OFFLINE!", Toast.LENGTH_SHORT).show();
}
});


}
}).start();


}

添加所需权限:

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET"/>

在manifest文件的application下添加以下一行:

android:usesCleartextTraffic="true"

将接收者添加到清单文件:

<receiver android:name=".ConnectivityChangeReceiver" >
<intent-filter>


<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
</intent-filter>
</receiver>

在活动中注册/取消注册BR:

@Override
protected void onStart() {
super.onStart();
IntentFilter filter = new IntentFilter("android.net.conn.CONNECTIVITY_CHANGE");
registerReceiver(connectivityChangeReceiver, filter);
}


@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(connectivityChangeReceiver);
}

这是整个Broadcast类:

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Handler;
import android.util.Log;
import android.widget.Toast;


import java.net.URL;
import java.net.URLConnection;


public class ConnectivityChangeReceiver extends BroadcastReceiver {




@Override
public void onReceive(final Context context, final Intent intent) {


final String action = intent.getAction();
if (intent.getAction().equals(ConnectivityManager.CONNECTIVITY_ACTION)) {
checkConnectivity(context);
}
}




private void checkConnectivity(final Context context) {
if (!isNetworkInterfaceAvailable(context)) {
Toast.makeText(context, "You are OFFLINE!", Toast.LENGTH_SHORT).show();
return;
}


final Handler handler = new Handler();
new Thread(new Runnable() {
@Override
public void run() {
final boolean isConnected = isAbleToConnect("http://www.google.com", 1000);
handler.post(new Runnable() {
@Override
public void run() {
if (isConnected)
Toast.makeText(context, "You are ONLINE!", Toast.LENGTH_SHORT).show();
else
Toast.makeText(context, "You are OFFLINE!", Toast.LENGTH_SHORT).show();
}
});


}
}).start();


}


//This only checks if the network interface is available, doesn't guarantee a particular network service is available, for example, there could be low signal or server downtime
private boolean isNetworkInterfaceAvailable(Context context) {
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
return activeNetwork != null && activeNetwork.isConnectedOrConnecting();
}


//This makes a real connection to an url and checks if you can connect to this url, this needs to be wrapped in a background thread
private boolean isAbleToConnect(String url, int timeout) {
try {
URL myUrl = new URL(url);
URLConnection connection = myUrl.openConnection();
connection.setConnectTimeout(timeout);
connection.connect();
return true;
} catch (Exception e) {
Log.i("exception", "" + e.getMessage());
return false;
}
}
}

添加权限:

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />

创建Receiver以检查连接

public class NetworkChangeReceiver extends BroadcastReceiver {


@Override
public void onReceive(final Context context, final Intent intent) {


if(checkInternet(context))
{
Toast.makeText(context, "Network Available Do operations",Toast.LENGTH_LONG).show();
}


}


boolean checkInternet(Context context) {
ServiceManager serviceManager = new ServiceManager(context);
if (serviceManager.isNetworkAvailable()) {
return true;
} else {
return false;
}
}


}

ServiceManager.java

public class ServiceManager {


Context context;


public ServiceManager(Context base) {
context = base;
}


public boolean isNetworkAvailable() {
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = cm.getActiveNetworkInfo();
return networkInfo != null && networkInfo.isConnected();
}
}

1)在manifest: -调用接收器如下代码

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.safal.checkinternet">


<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />


<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme"
tools:ignore="AllowBackup,GoogleAppIndexingWarning">
<receiver android:name=".NetworkChangeReceiver" >
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
</intent-filter>
</receiver>
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />


<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>


</manifest>

2)创建一个宽播接收器类:在这个类中添加网络检查的代码

package com.safal.checkinternet;


import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.util.Log;
import android.widget.Toast;


public class NetworkChangeReceiver extends BroadcastReceiver {


@Override
public void onReceive(final Context context, final Intent intent) {
if (isOnline(context)){
Toast.makeText(context, "Available", Toast.LENGTH_SHORT).show();
}else {
Toast.makeText(context, "Not Available", Toast.LENGTH_SHORT).show();
}
}
public boolean isOnline(Context context) {


ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
assert cm != null;
NetworkInfo netInfo = cm.getActiveNetworkInfo();
return (netInfo != null && netInfo.isConnected());
}
}

3)在您的活动中呼叫广播接收器:-

package com.safal.checkinternet;


import androidx.appcompat.app.AppCompatActivity;


import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;


public class MainActivity extends AppCompatActivity {


@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Call Broad cast Receiver
IntentFilter filter = new IntentFilter();
filter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
registerReceiver(new NetworkChangeReceiver(), filter);
}
}

警告:Declaring a broadcastreceiver for android.net.conn.CONNECTIVITY_CHANGE is deprecated for apps targeting N and higher. In general, apps should not rely on this broadcast and instead use JobScheduler or GCMNetworkManager.

由于CONNECTIVITY_CHANGE已弃用,那么我们应该使用另一种方式来做相同的事情

遵循NetworkConnectionLiveData将处理到目前为止所有的操作系统版本,而且如果目标SDK小于Build.VERSION_CODES.LOLLIPOP,那么我们只能使用broadcastReceiver

最好的部分是这个类使用LiveData,所以不需要注册任何接收器使用LiveData,它将处理所有的事情

class NetworkConnectionLiveData(val context: Context) : LiveData<Boolean>() {


private var connectivityManager: ConnectivityManager = context.getSystemService(CONNECTIVITY_SERVICE) as ConnectivityManager


private lateinit var connectivityManagerCallback: ConnectivityManager.NetworkCallback


override fun onActive() {
super.onActive()
updateConnection()
when {
Build.VERSION.SDK_INT >= Build.VERSION_CODES.N -> connectivityManager.registerDefaultNetworkCallback(getConnectivityManagerCallback())
Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP -> lollipopNetworkAvailableRequest()
else -> {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
context.registerReceiver(networkReceiver, IntentFilter("android.net.conn.CONNECTIVITY_CHANGE"))
}
}
}
}


override fun onInactive() {
super.onInactive()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
connectivityManager.unregisterNetworkCallback(connectivityManagerCallback)
} else {
context.unregisterReceiver(networkReceiver)
}
}


@TargetApi(Build.VERSION_CODES.LOLLIPOP)
private fun lollipopNetworkAvailableRequest() {
val builder = NetworkRequest.Builder()
.addTransportType(android.net.NetworkCapabilities.TRANSPORT_CELLULAR)
.addTransportType(android.net.NetworkCapabilities.TRANSPORT_WIFI)
connectivityManager.registerNetworkCallback(builder.build(), getConnectivityManagerCallback())
}


private fun getConnectivityManagerCallback(): ConnectivityManager.NetworkCallback {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {


connectivityManagerCallback = object : ConnectivityManager.NetworkCallback() {
override fun onAvailable(network: Network?) {
postValue(true)
}


override fun onLost(network: Network?) {
postValue(false)
}
}
return connectivityManagerCallback
} else {
throw IllegalAccessError("Should not happened")
}
}


private val networkReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
updateConnection()
}
}


private fun updateConnection() {
val activeNetwork: NetworkInfo? = connectivityManager.activeNetworkInfo
postValue(activeNetwork?.isConnected == true)
}
}

使用LiveData到任何类:

NetworkConnectionLiveData(context ?: return)
.observe(viewLifecycleOwner, Observer { isConnected ->
if (!isConnected) {
// Internet Not Available
return@Observer
}
// Internet Available
})

到2022年,上述BroadcastReceiver方法都将失效。由于Android 7.0的限制,BroadcastReceiver方法将不再工作。检查互联网是否可用的最新和最简单的方法是使用以下代码。(工作在Android 12测试)

val networkRequest = NetworkRequest.Builder()
.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
.addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
.build()


private val networkCallback = object : ConnectivityManager.NetworkCallback() {
// network is available for use
override fun onAvailable(network: Network) {
super.onAvailable(network)
}


// Network capabilities have changed for the network
override fun onCapabilitiesChanged(
network: Network,
networkCapabilities: NetworkCapabilities
) {
super.onCapabilitiesChanged(network, networkCapabilities)
val unmetered = networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED)
}


// lost network connection
override fun onLost(network: Network) {
super.onLost(network)
}
}


val connectivityManager = getSystemService(ConnectivityManager::class.java) as ConnectivityManager
connectivityManager.requestNetwork(networkRequest, networkCallback
将这段代码放在一个函数中,并在activity/fragment的onCreate ()中调用它。在onAvailable ()onLost ()函数中,每次当internet连接或断开时,都会通知您。与此同时,您可以使用liveData或任何您喜欢的方式在其他活动/片段中广播这些更新。 官方文档链接:https://developer.android.com/training/monitoring-device-state/connectivity-status-type