How can I update a widget on receiving a broadcast? - android

I'm working on a widget that displays information from a completely separate app. The separate app sends a broadcast when its data is changed, and I want to refresh/update my widget upon receiving this broadcast.
I can't seem to work out how to update a widget from within a BroadcastReceiver however. Is there a way to do this? Or another method to get the same result?

If the separate app has special action for its broadcast, you can add the intent filter to the manifest of your widget. Something like this:
<receiver android:name="ExampleAppWidgetProvider" >
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
<action android:name="SEPARATE_APP_ACTION" />
</intent-filter>
<meta-data android:name="android.appwidget.provider"
android:resource="#xml/example_appwidget_info" />
</receiver>
And just process it in onRecive method of you AppWidgetProvider.
HTH.

Related

How to declare a receiver for a widget to handle your own broadcast along with system broadcast

Suppose I want to define a receiver for my own widget and I want it to handle my own broadcast org.test.mywidget.MY_ACTION along with the APPWIDGET_xxx system broadcasts, what is the correct way to define it, if I want it to handle my own broadcast only if it is sent from the same app package? I tried the following XML code but in this way the APPWIDGET_DELETE action was no more delivered to the widget provider:
<receiver
android:name="MyWidgetProvider">
<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>
The XML above has the problem I've mentioned (no DELETED events delivered) and it also does not seem good to me, since the receiver is redefined.. So I compacted everything as follows:
<receiver
android:name="MyWidgetProvider">
<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>
This works, APPWIDGET_UPDATE, APPWIDGET_DELETE and my own broadcast are all delivered but now I have a question: are now other apps able to deliver a broadcast intent with the action org.test.mywidget.FORCE_SMALL_WIDGET_UPDATE to my widget, since the android:exported value is set to true by default? Maybe I'm missing some basic concept related to this exported value, so I would be glad if some of you can make me understand everything better :)
if I want it to handle my own broadcast only if it is sent from the same app package?
You do not need, or even want, an action string if it is all going to be within your own package. Just use the Intent constructor that takes a Java class object as the second parameter, and use that for sending broadcasts to be picked up by the receiver.
I tried the following XML code but in this way the APPWIDGET_DELETE action was no more delivered to the widget provider
That is because there is no <intent-filter> referencing that action string in your code.
are now other apps able to deliver a broadcast intent with the action org.test.mywidget.FORCE_SMALL_WIDGET_UPDATE to my widget, since the android:exported value is set to true by default?
Yes. Of course, third party apps can send APPWIDGET_UPDATE broadcasts, or even hack an Intent that identifies your component directly, and you will receive those as well.
I suspect that the right answer, in your case, is to simply implement a second BroadcastReceiver, one with no <intent-filter>, that handles operations that you solely want to be within your package. Or, if you do not need to use a PendingIntent for this BroadcastReceiver, consider LocalBroadcastManager from the Android Support package.

Handling onClick and receiver events in Android widgets

Currently I have a service, TimerService, that broadcasts updates, milestones, and alerts.
In the manifest file:
<!-- WIDGET! -->
<service android:name=".UpdateWidgetService" android:permission="android.permission.BIND_REMOTEVIEWS" ></service>
<receiver
android:icon="#drawable/icon"
android:label="JustInTime"
android:name="com.JustInTime.widget.WidgetProvider" >
<intent-filter >
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="#xml/widget_info" />
</receiver>
Would the UpdateWidgetService register receivers for the TimerService? It seems wrong that one service is listening to another service like this. Also, is it normal to register onClick functionality within the widget, or do you have to use setOnClickPendingIntent?
Goal: To have a widget that works like an alarm clock that listen to broadcasts from a service and then updates the widget as it needs. This update should update the UI, where there are several view items.
If you have good widget examples from this, please share. Most of them are very basic from what I see.

AppWidgetProvider: not called onEnabled method

I have widget that display data from content provider. I want to know when data in content provider changes. As far as I know way to do it is
context.getContentResolver().registerContentObserver
But AppWidgetProvider.onEnabled method is not called when I add first instance of the widget.
That's why I can't make registerContentObserver.
The same with onDisabled.
How to solve this problem?
Thanks
You need to add android.appwidget.action.APPWIDGET_ENABLED as another action:
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
<action android:name="android.appwidget.action.APPWIDGET_ENABLED" />
<action android:name="android.appwidget.action.APPWIDGET_DELETED" />
<action android:name="android.appwidget.action.APPWIDGET_DISABLED" />
</intent-filter>
Without that, you will not receive the broadcast that triggers onEnabled().
note: APPWIDGET_DELETED for onDeleted(...),
APPWIDGET_DISABLED for onDisabled(...)
An AppWidgetProvider (or any other manifest-registered BroadcastReceiver) cannot call registerContentObserver(). The entity that is changing your content will need to update your app widget, or you will need to implement some sort of polling mechanism (e.g., check for new content based on android:updatePeriodMillis).

How to get "all" (or the MAIN/LAUNCHER) android intent

i want receive all start app intents (i think MAIN/LAUNCHER, see below) to log how often i used the application. So i do not want create an activity... I tried several receiver blocks, but for now nothing works:
with, without priority, only the action, both, only the category and so on..
<receiver android:name=".Receiver" android:enabled="true"
android:process=".e">
<intent-filter priority="100000" android:priority="100000">
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</receiver>
Have anyone an idea?
Thanks
I want receive all start app intents
You cannot do that, sorry.

About API Demo Remote Service example in android

I am studying RemoteService example in Android's APISample. In the
manifest file, it declares the service like this:
My question is how can I specify the service to be 'auto-start', i.e.
it gets start whenever the phone start?
<service android:name=".app.RemoteService" android:process=":remote" >
<intent-filter>
<!-- These are the interfaces supported by the service, which
you can bind to. -->
<action
android:name="com.example.android.apis.app.IRemoteService" />
<action
android:name="com.example.android.apis.app.ISecondary" />
<!-- This is an action code you can use to select the service
without explicitly supplying the implementation class. -->
<action android:name="com.example.android.apis.app.REMOTE_SERVICE" />
</intent-filter>
</service>
First, you do not want to do that.
Second, you cannot do that directly. You will need to set up a BroadcastReceiver to watch for the BOOT_COMPLETED broadcast Intent, and have that receiver start the service.

Categories

Resources