安卓N为何不发送android.net.conn.CONNECTIVITY_CHANGE广播?

19

我在一个沙盒Android N应用程序中定义了一个接收器:

<receiver
    android:exported="true"
    android:name="com.sandboxapplication.NetworkReceiver">
    <intent-filter>
        <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
    </intent-filter>
</receiver>

这相当简单:

public class NetworkReceiver extends BroadcastReceiver {
    private static final String TAG = NetworkReceiver.class.getName();
    @Override
    public void onReceive(Context context, Intent intent) {
        Log.i(TAG, "Received Network Change event.");
    }
}

如果我的build.gradle文件中的targetSdkVersion为23,则此接收器正常工作。但是,如果我将targetSdkVersion设置为24,则接收器永远不会接收任何内容。实际上,如果我在我的接收器中放置一个调试断点,Android Studio会给我视觉提示,看起来该类甚至从未加载到内存中。

我在Android N文档中漏掉了一些非常基本的东西吗?是否有一种新的方法来检测连接更改事件?


可能是[ConnectivityManager.CONNECTIVITY_ACTION已弃用]的重复问题(https://dev59.com/rVoV5IYBdhLWcg3wTdTN)。 - rds
3个回答

26

使用以下代码,在您的ActivityApplication类中注册接收器

IntentFilter intentFilter = new IntentFilter(); 
intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTI‌​ON); 
registerReceiver(new NetworkConnectionReceiver(), intentFilter); 

注意:如果您在Activity中注册此接收器,请不要忘记取消注册。

NetworkConnectionReceiver是一个由BroadcastReceiver扩展的类。只需将此类添加到您的应用程序中,并在onReceive(Context context, Intent intent)方法中执行操作。


在Nougat中,当应用程序被强制关闭时,广播接收器是否会触发? - Priya
1
@Priya 不,当应用程序被强制关闭时,进程和代码中注册的所有内容都会消失。无论如何,您只应在应用程序处于前台时收听此广播。 - BladeCoder

25

针对 Android N(牛轧糖) 的应用即使它们在清单文件中请求接收网络连接状态的通知,也不会接收到CONNECTIVITY_ACTION广播。但是如果这些应用在主线程上通过BroadcastReceiver请求通知,则仍然可以监听CONNECTIVITY_CHANGE事件。

要了解在Android N (Nougat)中发生了哪些变化,请参阅下面的链接。 Android N 行为变化


4
那可能是因为 https://developer.android.com/reference/android/net/ConnectivityManager.html#CONNECTIVITY_ACTION 没有丝毫提及这一点... 太浪费时间了。 - Daniel F
3
工作链接:https://developer.android.com/about/versions/nougat/android-7.0-changes.html - rmtheis
感谢您更新链接。 - Kalpesh Patel
1
@FrankZappa:在您的Activity或Application类中使用以下代码注册接收器 -IntentFilter intentFilter = new IntentFilter(); IntentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION); registerReceiver(new NetworkConnectionReceiver(), intentFilter);注意:如果在Activity中注册此接收器,请不要忘记取消注册。 - Ambar Jain
监测连通性变化 针对 Android 7.0 (API 级别 24) 及更高版本的应用,如果它们在清单文件中声明广播接收器,则无法接收 CONNECTIVITY_ACTION 广播。如果应用使用 Context.registerReceiver() 方法注册 BroadcastReceiver,并且该上下文仍然有效,则仍会接收 CONNECTIVITY_ACTION 广播。https://developer.android.com/training/monitoring-device-state/connectivity-monitoring - SChalice
显示剩余2条评论

3

同时,ConnectivityManager.CONNECTIVITY_ACTION已被弃用:

@deprecated 
apps should use the more versatile {@link #requestNetwork},
{@link #registerNetworkCallback} or {@link #registerDefaultNetworkCallback}
functions instead for faster and more detailed updates about the network
changes they care about.

因此应该使用registerDefaultNetworkCallback

ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
cm.registerDefaultNetworkCallback(new ConnectivityManager.NetworkCallback(){
    @Override
    public void onAvailable(Network network) {
        doOnNetworkConnected();
    }
});

1
添加此代码后,它会显示“调用需要API级别24(当前最低级别为21)”。对于较低的API级别设备,应该编写什么? - Ambar Jain
@AmbarJain 只需使用已弃用的方法即可。它不会从旧设备中删除。 - eleven
但是这只有在应用程序正在运行时才有效,对吧?如果应用程序没有运行,就没办法了。 - chitgoks
哎呀,真倒霉。看起来再也没有办法检测在线/离线了。当然,JobScheduler有限制,但仅适用于连接的网络类型。WorkManager的最小周期性重新运行时间为15分钟(太长了)。 - chitgoks

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接