Java 安卓:互联网连接变化监听器

Java 安卓:互联网连接变化监听器,java,android,connectivity,Java,Android,Connectivity,我已经有了监听连接更改的代码- public class NetworkStateReceiver extends BroadcastReceiver { public void onReceive(Context context, Intent intent) { Log.d("app","Network connectivity change"); if(intent.getExtras() != null) { NetworkInfo ni =

我已经有了监听连接更改的代码-

public class NetworkStateReceiver extends BroadcastReceiver
{
  public void onReceive(Context context, Intent intent)
  {
    Log.d("app","Network connectivity change");

    if(intent.getExtras() != null)
    {
      NetworkInfo ni = (NetworkInfo) intent.getExtras().get(ConnectivityManager.EXTRA_NETWORK_INFO);
      if(ni != null && ni.getState() == NetworkInfo.State.CONNECTED)
      {
        Log.i("app", "Network " + ni.getTypeName() + " connected");
      }
    }

    if(intent.getExtras().getBoolean(ConnectivityManager.EXTRA_NO_CONNECTIVITY, Boolean.FALSE))
    {
      Log.d("app", "There's no network connectivity");
    }
  }
}
我用这个代码检查互联网连接-

但问题是,如果网络突然失去互联网连接而没有任何连接改变,那么这段代码是无用的。有没有办法创建广播接收器侦听器以更改Internet连接?我有一个web应用程序,突然更改Internet连接可能会导致问题。

试试这个

public class NetworkUtil {
    public static final int TYPE_WIFI = 1;
    public static final int TYPE_MOBILE = 2;
    public static final int TYPE_NOT_CONNECTED = 0;
    public static final int NETWORK_STATUS_NOT_CONNECTED = 0;
    public static final int NETWORK_STATUS_WIFI = 1;
    public static final int NETWORK_STATUS_MOBILE = 2;

    public static int getConnectivityStatus(Context context) {
        ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);

        NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
        if (null != activeNetwork) {
            if(activeNetwork.getType() == ConnectivityManager.TYPE_WIFI)
                return TYPE_WIFI;

            if(activeNetwork.getType() == ConnectivityManager.TYPE_MOBILE)
                return TYPE_MOBILE;
        } 
        return TYPE_NOT_CONNECTED;
    }

    public static int getConnectivityStatusString(Context context) {
        int conn = NetworkUtil.getConnectivityStatus(context);
        int status = 0;
        if (conn == NetworkUtil.TYPE_WIFI) {
            status = NETWORK_STATUS_WIFI;
        } else if (conn == NetworkUtil.TYPE_MOBILE) {
            status = NETWORK_STATUS_MOBILE;
        } else if (conn == NetworkUtil.TYPE_NOT_CONNECTED) {
            status = NETWORK_STATUS_NOT_CONNECTED;
        }
        return status;
    }
}
对于广播接收机

public class NetworkChangeReceiver extends BroadcastReceiver {

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

        int status = NetworkUtil.getConnectivityStatusString(context);
        Log.e("Sulod sa network reciever", "Sulod sa network reciever");
        if ("android.net.conn.CONNECTIVITY_CHANGE".equals(intent.getAction())) {
            if (status == NetworkUtil.NETWORK_STATUS_NOT_CONNECTED) {
                new ForceExitPause(context).execute();
            } else {
                new ResumeForceExitPause(context).execute();
            }
       }
    }
}
别忘了将其放入您的AndroidManifest.xml中

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


希望这能帮你干杯

更新

针对Android 7.0(API级别24)及更高版本的应用程序不会收到 如果他们声明了广播接收器,则连接性\u操作广播 在他们的舱单上。应用程序仍将接收连接操作 如果他们将其广播接收器注册到 并且该上下文仍然有效

您需要通过
registerReceiver()
方法注册接收器:

 IntentFilter intentFilter = new IntentFilter("android.net.conn.CONNECTIVITY_CHANGE");
 mCtx.registerReceiver(new NetworkBroadcastReceiver(), intentFilter);
这应该起作用:

public class ConnectivityChangeActivity extends Activity {

    private BroadcastReceiver networkChangeReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            Log.d("app","Network connectivity change");
        }
    };

    @Override
    protected void onResume() {
        super.onResume();

        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
        registerReceiver(networkChangeReceiver, intentFilter);
    }

    @Override
    protected void onPause() {
        super.onPause();

        unregisterReceiver(networkChangeReceiver);
    }
}

这是我的实现,您可以在应用范围内提供:

class NetworkStateHelper @Inject constructor(
        private val context: Context
) {
    private val cache: BehaviorSubject<Boolean> = BehaviorSubject.create()

    private val receiver = object : BroadcastReceiver() {
        override fun onReceive(c: Context?, intent: Intent?) {
            cache.onNext(isOnlineOrConnecting())
        }
    }

    init {
        val intentFilter = IntentFilter()
        intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION)
        context.registerReceiver(receiver, intentFilter)
        cache.onNext(isOnlineOrConnecting())
    }

    fun subscribe(): Observable<Boolean> {
        return cache
    }

    fun isOnlineOrConnecting(): Boolean {
        val cm = context.applicationContext.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
        val netInfo = cm.activeNetworkInfo
        return netInfo != null && netInfo.isConnectedOrConnecting
    }
}
类networkstateheloper@Inject构造函数(
私有val上下文:上下文
) {
私有val缓存:BehaviorSubject=BehaviorSubject.create()
private val receiver=对象:BroadcastReceiver(){
覆盖接收(c:Context?,intent:intent?){
cache.onNext(isOnlineOrConnecting())
}
}
初始化{
val intentFilter=intentFilter()
intentFilter.addAction(ConnectionManager.CONNECTIVITY_操作)
registerReceiver(接收者、意图过滤器)
cache.onNext(isOnlineOrConnecting())
}
fun subscribe():可观察{
返回缓存
}
乐趣IsOnlineorConnection():布尔值{
val cm=context.applicationContext.getSystemService(context.CONNECTIVITY_服务)作为ConnectionManager
val netInfo=cm.activeNetworkInfo
返回netInfo!=null&&netInfo.isConnectedOrConnecting
}
}
我使用了这个rxjava和dagger2库

连接操作在api 28+中。相反,只要您支持api 24+,就可以使用registerDefaultNetworkCallback

在科特林:

val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
connectivityManager?.let {
    it.registerDefaultNetworkCallback(object : ConnectivityManager.NetworkCallback() {
        override fun onAvailable(network: Network) {
            //take action when network connection is gained
        }
        override fun onLost(network: Network?) {
            //take action when network connection is lost
        }
    })
}
  • 首先在代码中添加依赖项,如
    implementation'com.treebo:internetavailabilitychecker:1.0.4'
  • 使用
    internetconnectivityliner
    实现类
  • public类MainActivity扩展AppCompatActivity实现InternetConnectivityListener{
    @凌驾
    创建时受保护的void(Bundle savedInstanceState){
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    InternetAvailabilityChecker.init(本);
    mInternetAvailabilityChecker=InternetAvailabilityChecker.getInstance();
    mInternetAvailabilityChecker.addInternetConnectivityListener(本);
    }
    @凌驾
    InternetConnectionyChanged上的公共无效(布尔值未连接){
    如果(未连接){
    alertDialog=新建alertDialog.Builder(this.create();
    alertDialog.setTitle(“互联网是否连接”);
    alertDialog.setMessage(“已连接”);
    alertDialog.setButton(alertDialog.BUTTON_中性,“确定”,
    新建DialogInterface.OnClickListener(){
    public void onClick(DialogInterface dialog,int which){
    dialog.dismise();
    }
    });
    alertDialog.show();
    }
    否则{
    alertDialog=新建alertDialog.Builder(this.create();
    alertDialog.setTitle(“互联网是否连接”);
    alertDialog.setMessage(“未连接”);
    alertDialog.setButton(alertDialog.BUTTON_中性,“确定”,
    新建DialogInterface.OnClickListener(){
    public void onClick(DialogInterface dialog,int which){
    dialog.dismise();
    }
    });
    alertDialog.show();
    }
    }
    }
    
    以下是使用
    registerDefaultNetworkCallback
    (以及API<24的
    registerNetworkCallback
    )的Java代码:


    实现'com.treebo:internetavailabilitychecker:1.0.1'

    public class MyApp extends Application {
        @Override
        public void onCreate() {
            super.onCreate();
            InternetAvailabilityChecker.init(this);
        }
    
        @Override
        public void onLowMemory() {
            super.onLowMemory();
            InternetAvailabilityChecker.getInstance().removeAllInternetConnectivityChangeListeners();
        }
    }
    

    我注意到没有人提到
    workmanager
    解决方案,它更好,支持大多数android设备

    您应该有一个具有网络约束的
    工作者
    ,只有在网络可用时才会触发,即:

    val constraints = Constraints.Builder().setRequiredNetworkType(NetworkType.CONNECTED).build()
    val worker = OneTimeWorkRequestBuilder<MyWorker>().setConstraints(constraints).build()
    

    我将此方法用作连接侦听器。为Lolipop+,Android JAVA语言工作

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
                NetworkRequest networkRequest = new NetworkRequest.Builder().build();
                connectivityManager.registerNetworkCallback(networkRequest, new ConnectivityManager.NetworkCallback() {
                    @Override
                    public void onAvailable(Network network) {
                        super.onAvailable(network);
                        Log.i("Tag", "active connection");
                    }
    
                    @Override
                    public void onLost(Network network) {
                        super.onLost(network);
                        Log.i("Tag", "losing active connection");
                        isNetworkConnected();
                    }
                });
            } 
    
    并在您的Android Manifest.xml中添加此权限

     <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
     <uses-permission android:name="android.permission.INTERNET" />
     <receiver
            android:name="NetworkChangeReceiver"
            android:label="NetworkChangeReceiver" >
            <intent-filter>
                <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
                <action android:name="android.net.wifi.WIFI_STATE_CHANGED" />
            </intent-filter>
        </receiver>
    
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    
    
    
    为什么需要检查(!“android.intent.action.BOOT_COMPLETED.”equals(intent.getAction())???它在gionee s plus设备中不起作用……还有其他方法吗?除了一个问题外,这很有效。我还尝试在我的Android电视盒上安装一个LAN/Ethernet连接的监听器。这适用于WiFi或移动连接,但不适用于LAN连接。我有这段代码来检查LAN连接的状态,但我需要一个侦听器来捕获internet状态的任何更改,而不仅仅是WiFi或移动网络:
    code
    NetworkInfo-activeNetwork=cm.getActiveNetworkInfo();布尔值isConnected=activeNetwork!=null&&activeNetwork.isConnectedOrConnecting()
    code
    在清单中注册这样的接收者以接收连接更改事件将不再适用于Android 7.0+发现网络连接的一个特殊情况,即没有互联网,但实际上有。原来
    getActiveNetworkInfo
    总是会返回断开连接