我正在开发一个用于检查互联网连接的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>

当前回答

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" />

其他回答

到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()函数中,每当互联网连接或断开连接时,您都会收到通知。与此同时,您可以使用liveData或任何您喜欢的方式在其他活动/片段中广播这些更新。 官方文档链接:https://developer.android.com/training/monitoring-device-state/connectivity-status-type

警告:为android.net.conn.CONNECTIVITY_CHANGE声明一个broadcastreceiver对于目标为N或更高的应用程序是不建议使用的。一般来说,应用程序不应该依赖于这个广播,而是使用JobScheduler或GCMNetworkManager。

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

接下来的NetworkConnectionLiveData将处理所有的OS Version,直到现在,如果目标SDK小于Build.VERSION_CODES。棒棒糖,那么只有我们可以使用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
})
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);
    }
}

}

试试这个

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)将被加载

添加权限:

<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();
    }
}