首页 > 解决方案 > WiFi更改时未调用BroadcastReceiver

问题描述

我已经根据https://developer.android.com/guide/components/broadcasts实现了一个 BroadcastReceiver,但它似乎不起作用。

我的 Manifest.xml 的接收器部分如下所示(我使用 android.permission.ACCESS_NETWORK_STATE 和 android.permission.ACCESS_WIFI_STATE):

...
<receiver android:name=".BackgroundTask">
    <intent-filter>
        <action android:name="android.net.wifi.WIFI_STATE_CHANGED"/>
        <action android:name="android.net.wifi.STATE_CHANGE" />
    </intent-filter>
</receiver>
...

它在我的应用程序中声明。

我的 BroadcastReceiver 类如下所示:

public class BackgroundTask extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        System.out.println("Connection changed!");
        Toast.makeText(context, "Network state changed", Toast.LENGTH_LONG).show();
    }
}

既没有显示 toast,也没有在我的 logcat 上收到 println-ed 输出。我还阅读了建议我使用预定作业而不是接收器的注释,但我找不到如何使用它来监听网络变化的示例。

我想使用它的原因是因为我希望我的(后台)应用程序仅在我的手机连接到我的 WiFi 时运行 - 如果您对如何实现它有任何不同的建议,我也非常感谢。

顺便提一句。我使用的是安卓 8.0.0。

干杯,尼古拉

更新:

不知何故,它仍然无法正常工作。我忘记了什么吗?

显现:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="mypackagename">
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />

    <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">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <receiver android:name=".BootReceiver">
            <intent-filter>
                <action android:name="android.intent.action.ACTION_BOOT_COMPLETED"></action>
            </intent-filter>
        </receiver>
        <receiver android:name=".BackgroundPoller">
        </receiver>
    </application>
</manifest>

为了清楚起见,我将我的 BackgroundTask-Class 重命名为 BootReceiver:

public class BootReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        Log.d("INFO", "BootReceiver started");
        Intent newIntent = new Intent(context, BackgroundPoller.class);
        context.sendBroadcast(newIntent);
        Log.d("INFO", "BackgroundPoller activated");
    }
}

当我成功发送我的广播

adb.exe shell am broadcast -a android.intent.action.ACTION_BOOT_COMPLETED

我仍然没有得到日志输出。

标签: androidandroid-broadcastreceiver

解决方案


要绕过 Oreo 的广播接收器限制,您必须使用 Context.registerReceiver() 注册接收器。您可以通过继承 Application 并在 onCreate() 中注册接收器来做到这一点。这样做的唯一缺点是必须启动您的应用程序才能调用 Application.onCreate()。为了解决这个问题,您可以在清单中注册一个 ACTION_BOOT_COMPLETED 接收器,因为此操作不受限制。您的 ACTION_BOOT_COMPLETED 接收器不必做任何事情,但它会强制您的应用程序在启动时开始运行,因此 Application.onCreate() 将被调用。那么唯一的挑战是保持你的应用程序运行,因为如果用户不进入它,系统会杀死它。有几个选项可以解决这个问题。您可以编写一个前台服务,其唯一目的是让应用程序保持活力。或者也许使用 AlarmManager 安排一些将唤醒您的应用程序的意图,这将再次注册您的接收器。


推荐阅读