android - 启动配置 Activity 时调用的小部件 onUpdate

标签 android android-widget broadcastreceiver android-manifest android-appwidget

我正在实现一个小部件,但遇到以下问题:

1) 当我将小部件添加到主屏幕时会调用 onUpdate,即使我指定了配置 Activity 。我将它添加到主屏幕后,立即发送 APPWIDGET_ENABLED 广播,然后发送 APPWIDGET_UPDATE 然后启动配置 Activity 。这是一个错误吗?我应该如何理解在配置 Activity 返回之前调用的 onUpdate 方法?我可以通过共享首选项值来做到这一点,但我希望它的行为与开发人员指南中所写的一样,即不应调用 onUpdate 方法。

2) onUpdate 不是每 updatePeriodMillis 秒调用一次,已设置为 10000,即 10 秒用于测试目的。我是否遗漏了 Manifest 文件中的 receiver 声明中的某些内容?我不断收到 Lint 警告导出的接收器不需要许可,但我认为这是 Lint 问题,而不是我的错。 编辑:我刚刚在引用文档中找到了这一点:注意:使用 updatePeriodMillis 请求的更新不会每 30 分钟发送一次以上。 所以正确的是小部件未更新我指定的频率,我已将时间更改为 1800000 毫秒。

3) 我想将我自己的广播操作传递给小部件提供程序,在 Manifest 中添加另一个 receiver block 针对同一提供程序类是否正确或应该我只在包含 APPWIDGET_UPDATE 操作的 intent-filter 中添加了另一个 Intent 操作?顺便说一句,我已经评论了我的第二个 receiver block ,这不是上述问题的原因。我创建了另一个 receiver  block ,因为我想将其声明为未导出,以便让 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>

最佳答案

深挖源码后给出答案:

1) 这是预期行为,请参阅 here

This method is also called when the user adds the App Widget

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

Note: Updates requested with updatePeriodMillis will not be delivered more than once every 30 minutes

3) 由于 AppWidgetProvider 扩展了 BroadcastReceiver 但未声明为 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 is just a convenience class. If you would like to receive the App Widget broadcasts directly, you can implement your own BroadcastReceiver or override the onReceive(Context, Intent) callback.

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

祝你好运,编码愉快!

关于android - 启动配置 Activity 时调用的小部件 onUpdate,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11739098/

相关文章:

android - 在没有日期选择器的情况下使用 DatePicker

android - 最佳实践 - 每次都保留引用或实例化?

android - 如何在 sleep 模式下接收硬件按键事件?

android - 在 Android 小部件中自动滚动 TextView?

java - 当 JSONArray 大于 261​​ 时应用程序崩溃

Android - 用于检测耳机按钮点击的广播接收器不适用于 API 23(棉花糖)

Android 应用小部件 ListView onclick 监听器

android - 将 ImageView 从 PNG 替换为 GIF

java - Android - 如何将数据从主要 Activity 发送到加载的 fragment

java - ConcurrentModificationException java.util.ArrayList$Itr.next