启动配置活动时调用Widget onUpdate

Gia*_*nzi 25 android broadcastreceiver android-widget android-manifest android-appwidget

我正在实现一个小部件,我面临以下问题:

1) onUpdate当我将小部件添加到主屏幕时调用,即使我指定了配置活动.一旦我将它添加到主屏幕,APPWIDGET_ENABLED就会发送广播,然后发送,APPWIDGET_UPDATE然后启动配置活动..这是一个错误吗?onUpdate在配置活动返回之前,我应该如何理解被调用的方法?我可以通过共享偏好值来实现,但我希望它的行为与开发人员指南中的内容相同,即onUpdate不应该调用该方法.

2) onUpdate每秒都没有被调用updatePeriodMillis,这已被设置为10000,即10用于测试目的的秒数.我receiver在Manifest文件中的声明中是否遗漏了什么?我一直收到Lint警告导出的接收器不需要许可,但我认为这是一个Lint问题而不是我的错. 编辑:我刚刚在参考文档中找到了这个:注意:updatePeriodMillis请求的更新不会每30分钟发送一次.因此,我不会更新窗口小部件的频率是正确的,我将时间更改为1800000毫秒.

3)我想将自己的广播操作传递给窗口小部件提供程序,receiver在Manifest中添加另一个阻止相同提供程序类的块是正确的还是我应该在intent-filter包含该APPWIDGET_UPDATE 操作的内容中添加另一个意图操作?顺便说一下,我评论了我的第二个receiver区块,这不是上述问题的原因.我创建了另一个receiver 块,因为我想将其声明为未导出,以便intent-filter 仅通过我的应用程序代码而不是其他任何人触发操作.

AndroidManifest.xml中

    <receiver android:name="MyWidgetProvider" 
        android:exported="true">
        <intent-filter>
            <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
        </intent-filter>

        <meta-data
            android:name="android.appwidget.provider"
            android:resource="@xml/my_widget_info" />
    </receiver>
    <receiver android:name="MyWidgetProvider" 
        android:exported="false">
        <intent-filter>
            <action android:name="org.test.mywidget.FORCE_SMALL_WIDGET_UPDATE" />
        </intent-filter>
    </receiver>
Run Code Online (Sandbox Code Playgroud)

my_widget_info.xml

<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
    android:minWidth="294dp"
    android:minHeight="110dp"
    android:updatePeriodMillis="1800000"
    android:initialLayout="@layout/my_widget_layout"
    android:configure="org.test.mywidget.MyWidgetConfiguration" 
    android:resizeMode="none">
</appwidget-provider>
Run Code Online (Sandbox Code Playgroud)

kan*_*idj 1

深入源码后给出答案:

1)这是预期的行为,请参见此处

当用户添加App Widget时也会调用此方法

2)看来你已经找到了自己的答案。对于其他寻找文档的人,请转到此处

注意:使用 updatePeriodMillis 请求的更新每 30 分钟发送一次不会超过一次

3)由于AppWidgetProvider扩展BroadcastReceiver但未声明为最终,您可以从第二个接收器添加操作

<receiver android:name="MyWidgetProvider" 
        android:exported="true">
        <intent-filter>
            <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
            <action android:name="org.test.mywidget.FORCE_SMALL_WIDGET_UPDATE" />
        </intent-filter>

        <meta-data
            android:name="android.appwidget.provider"
            android:resource="@xml/my_widget_info" />
    </receiver>
Run Code Online (Sandbox Code Playgroud)

那么你可以在MyWidgetProvider类中重写 onReceive ,如果该操作是你的自定义操作,则处理它,否则调用 super.onRecieve(Context context, Intent Intent) ,如下所示:

@Override
public void onReceive(Context context, Intent intent) {
    if(intent.getAction()
         .equals("org.test.mywidget.FORCE_SMALL_WIDGET_UPDATE")){
        // handle your action
    } else {
        super.onRecieve(context, intent);
    }
}
Run Code Online (Sandbox Code Playgroud)

根据指南:

AppWidgetProvider 只是一个便利类。如果您想直接接收 App Widget 广播,您可以实现自己的 BroadcastReceiver 或重写 onReceive(Context, Intent) 回调。

需要注意的一件事是,无论您是否将自己的操作添加到 Intent 中以供提供程序处理,对远程视图的更新都只会在 updatePeriodMillis 处调用。

祝你好运,编码愉快!

  • 1) 是的,但是下一句告诉我们`但是,如果你声明了一个配置Activity,` **当用户添加App Widget时不会调用**`这个方法,而是在后续更新时调用` (12认同)