【问题标题】:Android: How the get notified on connectivity change on API > 23Android:如何在 API > 23 上获得有关连接更改的通知
【发布时间】:2018-02-03 18:29:59
【问题描述】:

在 API 23 之前,可以在 Manifest 中注册广播接收器,该接收器将在连接更改时触发。

<manifest>
    ...
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
    <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
    ...
    <receiver
        android:name=".NetworkStateChangeReceiver"
        android:exported="false">
        <intent-filter>
            <action android:name="android.net.conn.CONNECTIVITY_CHANGE"/>
         </intent-filter>
    </receiver>
</manifest>

来自 API > 23 不再起作用,但我找不到有关如何为较新的 API 解决此问题的示例!?刚才说了,程序化的实现是通过Context.registerReceiver(),但是manifest中没有说明如何解决这个问题。

这是在线 Android 文档的一部分:

https://developer.android.com/training/monitoring-device-state/connectivity-monitoring.html#MonitorChanges

面向 Android 7.0(API 级别 24)及更高版本的应用如果在清单中声明广播接收器,则不会接收 CONNECTIVITY_ACTION 广播。如果应用向 Context.registerReceiver() 注册 BroadcastReceiver 并且该上下文仍然有效,则应用仍将收到 CONNECTIVITY_ACTION 广播。

目标是获得有关连接更改的通知并记录更改,无论应用是否启动。

如果有人知道如何处理,请告诉我。

更新

按照第一个答案的说明,我创建了以下结构,但它仍然无法正常工作。 永远不会触发 BOOT_COMPLETED 接收器!?

清单:

<manifest>
    ...
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
    <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
    <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
    ...
    <receiver android:name=".StartUpBootReceiver" android:enabled="true" android:exported="false">
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED"/>
            <action android:name="android.intent.action.QUICKBOOT_POWERON"/>
            <!--For HTC devices-->
            <action android:name="com.htc.intent.action.QUICKBOOT_POWERON"/>

            <category android:name="android.intent.category.DEFAULT" />
        </intent-filter>
    </receiver>

    <service
        android:name=".MyService"
        android:exported="false"/>

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

****StartUpBootReceiver****

class StartUpBootReceiver : BroadcastReceiver() {

    override fun onReceive(context: Context, intent: Intent) {
        if (intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) {
            context.startService(Intent(context, MyService::class.java))
        }
    }

}

我的服务

class MyService : Service() {

val receiver = NetworkStateChangeReceiver()

    override fun onBind(p0: Intent?): IBinder? {
        return null
    }

    override fun onCreate() {
        super.onCreate()

        registerReceiver(
                receiver,
                IntentFilter(
                        ConnectivityManager.CONNECTIVITY_ACTION))

    }

    override fun onDestroy() {
        super.onDestroy()
        unregisterReceiver(receiver)
    }

}

NetworkStateChecngeReceiver

class NetworkStateChangeReceiver : BroadcastReceiver() {

    override fun onReceive(context: Context, intent: Intent) {
        Log.d(javaClass.simpleName, "### NetworkChange received")
    }
}

【问题讨论】:

    标签: android networking connection


    【解决方案1】:

    但没有关于如何在清单中解决这个问题的句子

    那是因为它无法在清单中直接解决。

    目标是获得有关连接更改的通知并记录更改,无论应用是否启动。

    这是不可能的。

    欢迎您:

    • 在清单中注册ACTION_BOOT_COMPLETED

    • 让您的接收器为该操作启动前台服务(即,使用Notification 进行用户控制的服务)

    • 让前台服务使用registerReceiver()ConnectivityManager 来了解连接变化

    对于大多数开发人员来说,目标不是找出连接变化,而是仅在有可能连接有效时才能够采取一些措施。为此,JobScheduler 和网络所需的工作将起作用。

    【讨论】:

    • 感谢您的回答,但即使我尝试设置:1. 引导接收器调用服务 2. 服务注册连接更改接收器它仍然无法正常工作。 :( BOOT_COMPLETE 接收器永远不会在 Android O 上得到通知,有什么建议吗?
    • @grumpyshoe:“Android O 上永远不会通知 BOOT_COMPLETE 接收器”——是的,确实如此。与自 3.1 左右以来的所有 Android 版本一样,清单注册的接收器在使用显式 Intent 启动应用程序组件之前不起作用。通常,这发生在用户启动您的启动器活动时。另外,请确保您在 Android 8.0+ 上使用 startForegroundService(),而不是 startService()
    • 好的,所以在安装并启动应用程序后,我启动了一个服务,该服务注册一个广播接收器以进行连接更改。但如果该应用程序已被杀死,则不再有广播接收器。你能举个小例子吗?我不知道我的概念中缺少什么。
    • @grumpyshoe:“但如果应用程序已被杀死,则不再有广播接收器” - 您的服务是前台服务吗(即,通过 setForeground() 启动?您的代码没有显示这一点,并且后台服务在 Android 8.0+ 上存活约 1 分钟。“我不知道我的概念中缺少什么”——坦率地说,你想要做的是谷歌试图让开发人员不这样做 这样做。我强烈建议您重新访问您的应用程序,并尝试消除实时了解连接变化的需要。俗话说,您是在逆流而上。
    • 感谢您的回复。所以也许完全不可能做我想做的事。我了解 JobSchedular & Co 的用法,但我尝试构建的内容如下:应用程序应在连接或断开连接时创建一个带有时间戳和 Wifi-Name 的小型数据库条目,以便用户了解他已连接多长时间一个无线网络。有没有另一种方法可以解决我现在看不到的这个用例?
    猜你喜欢
    • 2015-12-10
    • 1970-01-01
    • 2021-05-03
    • 1970-01-01
    • 2012-06-21
    • 2011-06-01
    • 2019-07-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多