|
Page 2 of 5
Broadcast receiver
To get any app to listen for broadcast receivers - especially widgets - we must set up the AndroidManifest.xml control file correctly. Heres the part we add for our TwitterWidget:
<receiver
android:name=".TwitterWidgetProvider">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="@xml/twitter_widget" />
</receiver>
We're setting up a listener here so that Androids APPWIDGET_UPDATE messages are picked up by our TwitterWidgetProvider class. It's so named because it's a child of Androids AppWidgetProvider class, and that's the one which gives most of the functionality needed to embed it in the App Widget Host I mentioned earlier. Here it is in full - don't worry about the details yet, just look at the names of the callbacks which are provided by the parent, i.e. marked "@Override", and notice there's only 2 here:
/*
* Copyright (c) 2011 OTAMate Technology Ltd. All Rights Reserved.
* http://www.androidacademy.com
*/
package com.androidacademy.tutorials.twitterwidget;
import android.app.PendingIntent;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.widget.RemoteViews;
public class TwitterWidgetProvider extends AppWidgetProvider {
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
SharedPreferences settings =
context.getSharedPreferences(Constants.SHARED_PREF_CONFIG, Context.MODE_PRIVATE);
final int noOfWidgets = appWidgetIds.length;
// Perform this loop procedure for each App Widget that belongs to this provider
for (int widgetNumber = 0; widgetNumber < noOfWidgets; widgetNumber++) {
int appWidgetId = appWidgetIds[widgetNumber];
// Create an Intent to launch our Activity
Intent intent = new Intent(context, TwitterWidgetActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
// Get the layout for the App Widget and attach an on-click listener
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget);
views.setOnClickPendingIntent(R.id.widgetFrame, pendingIntent);
views.setTextViewText(R.id.twitterText,
settings.getString(Constants.KEY_LAST_TWEET_TEXT, ""));
// Tell the AppWidgetManager to perform an update on the current App Widget
appWidgetManager.updateAppWidget(appWidgetId, views);
}
}
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (Constants.UPDATE.equals(action)) {
SharedPreferences settings =
context.getSharedPreferences(Constants.SHARED_PREF_CONFIG, Context.MODE_PRIVATE);
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget);
// We have to update the widget too in order to see the change
AppWidgetManager manager = AppWidgetManager.getInstance(context);
Intent clickIntent = new Intent(context, TwitterWidgetActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, clickIntent, 0);
views.setOnClickPendingIntent(R.id.widgetFrame, pendingIntent);
manager.updateAppWidget(new ComponentName(context, TwitterWidgetProvider.class), views);
views.setTextViewText(R.id.twitterText,
settings.getString(Constants.KEY_LAST_TWEET_TEXT, ""));
manager.updateAppWidget(new ComponentName(context, TwitterWidgetProvider.class), views);
} else {
super.onReceive(context, intent);
}
}
}
The onUpdate() method is called when the user adds the Widget to the home screen, or more formally when your Widget receives an APPWIDGET_UPDATE message which an App Widget Host will send when the Widget is added to the host. The other method is onReceive(), which is more of a programmatic approach under the developers control, as opposed to the system broadcast handler seen in onUpdate(). The onReceive() method is treat as a regular Intent handler, and as such is the way the RSS news feeds and clocks work, since they typically set up a process to fire these Intents at their Widgets at regular intervals.
|