我正在开发一个用于检查互联网连接的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>
添加权限:
<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);
}
}
我知道这个帖子已经很老了,而且已经有了完整的答案,但我觉得下面的帖子可能会帮助到一些人。
问题主体中的代码包含一个这里没有人解决的错误。
@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
}
}
增加一个广播接收器,可以监听网络连接的变化。然后使用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);
}
}
活动监听网络接收器广播的意图,并在屏幕上显示通知。
这里有一种适合活动、片段或上下文的方法。它也会自动注销,如果你做的活动/片段(在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)
}
})