小部件案例不适用于Oreo 8.1-收到消息:W/BroadcastQueue:不允许后台执行:接收Intent [英] widget case that doesn't work with Oreo 8.1 - message received: W/BroadcastQueue: Background execution not allowed: receiving Intent

查看:41
本文介绍了小部件案例不适用于Oreo 8.1-收到消息:W/BroadcastQueue:不允许后台执行:接收Intent的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的窗口小部件应用程序在除8 Oreo之外的所有Android版本上均可正常运行. 我收到一条W/BroadcastQueue: Background execution not allowed: receiving Intent消息.

My widget app is running fine on all android version except 8 Oreo. I get a W/BroadcastQueue: Background execution not allowed: receiving Intent message.

有一个来自CommonsWare的有趣的博客,但我不完全理解为什么它适用于我的案例. https://commonsware.com/blog/2017/04/11/android-o-implicit-broadcast-ban.html

There is an interesting blog from CommonsWare but I don't fully understand why it applies to my case. https://commonsware.com/blog/2017/04/11/android-o-implicit-broadcast-ban.html

我的情况看起来很简单:我有一个带有按钮的小部件,我想在单击文本时更改其按钮.

My case looks pretty simple: I have a widget with a button and I want to change the text's button when it is clicked.

解决此问题的正确方法是什么?

What is the right way to fix this issue?

TestWidget.java

TestWidget.java

public class TestWidget extends AppWidgetProvider {
    private static RemoteViews views;
    private static boolean buttonClicked = false;
    public static final String ACTION_AUTO_UPDATE = "AUTO_UPDATE";

    @Override
    public void onReceive(Context context, Intent intent)
    {
        super.onReceive(context, intent);

        if(intent.getAction().equals(ACTION_AUTO_UPDATE))
        {
                Log.i("TESTWID", "get onReceive");
        }
    }

    static void updateAppWidget(Context context, AppWidgetManager appWidgetManager,
                                int appWidgetId) {
        views = new RemoteViews(context.getPackageName(), R.layout.test_widget);
        views.setOnClickPendingIntent(R.id.wid_btn_tst, setButton(context));

        appWidgetManager.updateAppWidget(appWidgetId, views);
    }

    @Override
    public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
        Log.i("TESTWID", "onupdate ");

        for (int appWidgetId : appWidgetIds) {
            updateAppWidget(context, appWidgetManager, appWidgetId);
        }
    }

    public static PendingIntent setButton(Context context) {
        Intent intent = new Intent();
        intent.setAction("TEST");
        return PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
    }

    public static void pushWidgetUpdate(Context context, RemoteViews remoteViews) {
        ComponentName myWidget = new ComponentName(context, TestWidget.class);
        AppWidgetManager manager = AppWidgetManager.getInstance(context);
        manager.updateAppWidget(myWidget, remoteViews);
    }

}

TestWidgetReceiver.java

TestWidgetReceiver.java

public class TestWidgetReceiver extends BroadcastReceiver{
    private static boolean isButtonON = false;

    @Override
    public void onReceive(Context context, Intent intent) {
        Log.i("TESTWID", "onReceive "+intent.getAction());

        if(intent.getAction().equals("TEST")){
            updateWidgetButton(context, 2);
        }
    }

    private void updateWidgetButton(Context context, int index) {
        RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.test_widget);
        if(index == 2) {
            if(isButtonON) {
                remoteViews.setTextViewText(R.id.wid_btn_tst, "Test Off");
                isButtonON = false;
            }
            else{
                remoteViews.setTextViewText(R.id.wid_btn_tst, "Test On");
                isButtonON = true;
            }
        }

        TestWidget.pushWidgetUpdate(context.getApplicationContext(), remoteViews);
    }

}

Manifest.xml:

Manifest.xml:

<application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="Test"
        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=".TestWidget">
            <intent-filter>
                <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
            </intent-filter>
            <intent-filter>
                <action android:name="AUTO_UPDATE" />
            </intent-filter>
            <meta-data
                android:name="android.appwidget.provider"
                android:resource="@xml/test_widget_info" />
        </receiver>

        <receiver
            android:name=".TestWidgetReceiver"
            android:label="widgetBroadcastReceiver" >
            <intent-filter>
                <action android:name="TEST" />
            </intent-filter>

            <meta-data
                android:name="android.appwidget.provider"
                android:resource="@xml/test_widget_info" />
        </receiver>

    </application>

推荐答案

这很微妙,但这是因为隐式广播被用来触发您的TestWidgetReceiver.它是隐式的,因为它仅指定Intent的操作部分.通过在构造函数中指定接收器类,使广播Intent 显式:

It's subtle, but it is because of the implicit broadcast being used to trigger your TestWidgetReceiver. It is implicit because it is only specifying the action portion of the Intent. Make the broadcast Intent explicit by specifying the receiver class in the constructor:

public static PendingIntent setButton(Context context) {
    Intent intent = new Intent(context, TestWidgetReceiver.class);
    intent.setAction("TEST");
    return PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
}

这篇关于小部件案例不适用于Oreo 8.1-收到消息:W/BroadcastQueue:不允许后台执行:接收Intent的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆