Reputation: 6104
I'm implementing a widget and I'm facing the following problems:
1) onUpdate
is called when I add the widget to the home screen, even if I specified a Configuration Activity. As soon as I add it to the home screen, the APPWIDGET_ENABLED
broadcast is sent, followed by the APPWIDGET_UPDATE
and then the configuration activity is launched.. Is this a bug? How should I understand in the onUpdate
method that is being invoked before the configuration activity has returned? I can do it through a shared preference value, but I'd like it to behave as written on the developer guide, i.e. the onUpdate
method should not be called.
2) onUpdate
is not called every updatePeriodMillis
seconds, which have been set to 10000
, i.e. 10
seconds for testing purposes.. Did I miss something in the receiver
declaration within the Manifest file? I keep receiving the Lint warning Exported receiver does not require permission but I think this is a Lint issue and not my fault.
EDIT: I've just found this within the reference docs: Note: Updates requested with updatePeriodMillis will not be delivered more than once every 30 minutes. So it is correct that the widget is not updated how often I'd specified and I've changed the time to 1800000
milliseconds.
3) I want to deliver my own broadcast action to the widget provider, is it correct to add another receiver
block in the Manifest targeting the same provider class or should I add only another intent action within the intent-filter
that contains the APPWIDGET_UPDATE
action? BTW, I've commented my second receiver
block and it is not the cause of the problems above. I created another receiver
block because I wanted to declare it as not exported, in order to let the intent-filter
action be triggered only by my app code and not anyone else.
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>
Upvotes: 47
Views: 4147
Reputation: 13932
Providing an answer after digging into the source code:
1) This is expected behavior see here
This method is also called when the user adds the App Widget
2) Seems you have found your own answer. For others looking for the docs go here
Note: Updates requested with updatePeriodMillis will not be delivered more than once every 30 minutes
3) Since the AppWidgetProvider
extends BroadcastReceiver
but is not declared final you can add the action from your second receiver
<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>
then you can override onReceive in your MyWidgetProvider
class and if the action is your custom action handle it, otherwise call to the super.onRecieve(Context context, Intent intent) like so:
@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);
}
}
as per the Guide:
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.
One thing to note with this, the update to the remote view will only be called at the updatePeriodMillis, regardless of you adding your own action to the Intent for the provider to handle.
Good Luck and Happy Coding!
Upvotes: 1