44

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

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>

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>
4

1 回答 1

0

在深入研究源代码后提供答案:

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

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

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

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

3)由于AppWidgetProviderextendsBroadcastReceiver但未声明为final,您可以从第二个接收器添加操作

<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>

那么你可以在你的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);
    }
}

根据指南:

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

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

祝你好运,编码愉快!

于 2018-02-28T21:45:34.720 回答