Honeycomb home screen widgets
satya - Saturday, February 26, 2011 9:44:02 AM
Do I ever need to override onReceive?
A widget provider is essentially a receiver. So anyone can send a broadcase message to it.
Typically this is done by explicitly creating an intent with that receriver classname and sending it with a custom action.
when this is done the custom action needs to be dealt with in the onReceive method.
when you overload the onReceive() you also need to call the super so that it can move the default actions to the respective derived methods.
satya - Sunday, February 27, 2011 10:32:46 AM
new method: notifyAppWidgetViewChanged
what does this do?
Tell a view that it needs to refresh its data.
what call backs will it call?
satya - Sunday, February 27, 2011 10:44:18 AM
The content providers need to change data and tell views
tellt he widget managr to tellt heir views tor refresh.
satya - Sunday, February 27, 2011 10:49:00 AM
As a result....
you will need to register a content observer against the provider and then tell the widget manager that the view has changed.
You will need to set this up in the "enable" of the widget.
satya - Sunday, February 27, 2011 11:07:08 AM
Nature of onupdate for listview
setup the remoteviews that contains lists
set the adapters for the remote views
set the call backs for buttons so that they issue more broadcast intents to self
override onreceive to respond to callbacks
In onreceive tell the views that they changed their data
set the remoteviews that it is going to get its adapter through a remote service
satya - Monday, February 28, 2011 10:43:54 AM
An example listview widget layout from google
satya - Monday, February 28, 2011 10:48:23 AM
essence of that layout
<FrameLayout...>
<ListView id="@+id/somelistviewid" ..../>
<TextView id="@+id/emptylistviewid"..../>
</FrameLayout>
satya - Monday, February 28, 2011 10:52:18 AM
How is this layout loaded
final RemoteViews rv =
new RemoteViews(context.getPackageName(), R.layout.widget_layout);
rv.setRemoteAdapter(appWidgetIds[i], R.id.weather_list, intent);
Ofcourse the layout id R.layout.widget_layout belongs to the entire layout of the widget where as the R.id.weather_list belongs to just the id of the list view similar to the one above.
satya - Monday, February 28, 2011 11:02:49 AM
The way you construct a remoteview is much like before.
RemoteViews views =
new RemoteViews
(context.getPackageName(), R.layout.bday_widget);
satya - Monday, February 28, 2011 11:05:50 AM
A configure activity, if present, is responsible for an explcit update...
A configur activity, if present, must do very similar things that an "onUpdate" method does.
However the "onUpdate" method should watch out to see if configure activity is not finished (if the update is too frequent). (I think...)
satya - Monday, February 28, 2011 11:07:42 AM
Here is an example of a common update chore
Code/strategy similar to the following can be used both by the configure activity and the onupdate method.
public static void updateAppWidget(Context context,
AppWidgetManager appWidgetManager,
BDayWidgetModel widgetModel)
{
RemoteViews views =
new RemoteViews(context.getPackageName(),
R.layout.bday_widget);
views.setTextViewText(R.id.bdw_w_name
, widgetModel.getName() + ":" + widgetModel.iid);
views.setTextViewText(R.id.bdw_w_date
, widgetModel.getBday());
//update the name
views.setTextViewText(R.id.bdw_w_days,
Long.toString(widgetModel.howManyDays()));
Intent defineIntent = new Intent(Intent.ACTION_VIEW,
Uri.parse("http://www.google.com"));
PendingIntent pendingIntent =
PendingIntent.getActivity(context,
0 /* no requestCode */,
defineIntent,
0 /* no flags */);
views.setOnClickPendingIntent(R.id.bdw_w_button_buy, pendingIntent);
// Tell the widget manager
appWidgetManager.updateAppWidget(widgetModel.iid, views);
}
satya - Tuesday, March 01, 2011 9:01:54 AM
whats new in widgets in honeycomb
Quoting from Google
Home screen widgets are popular with users because they offer fast access to application-specific data directly from the home screen. Android 3.0 lets developers take home screen widgets to the next level, offering more types of content and new modes of interaction with users. Developers can now use more standard UI widget types home screen widgets, including widgets that let users flip through collections of content as 3D stacks, grids, or lists. Users can interact with the home screen widgets in new ways, such as by using touch gestures to scroll and flip the content displayed in a widget
satya - Tuesday, March 01, 2011 9:03:00 AM
explicitly stated new widgets
3d stack
grids
lists
satya - Tuesday, March 01, 2011 9:27:47 AM
RemoteViews.RemoteView
RemoteViews.RemoteView
satya - Tuesday, March 01, 2011 9:34:29 AM
As of 2.3 the allowed remote views are
As of 2.3 the allowed remote views are
Go to android.widget.RemoteViews.Remoteview click "use"
satya - Tuesday, March 01, 2011 9:36:23 AM
as of 2.3 these are
absolutelayout
framelayout
linearlayout
relativelayout
analogclock
button
chronometer
datetimeview
imagebutton
iamgeview
progressbar
textview
viewflipper
satya - Tuesday, March 01, 2011 9:57:56 AM
You can also do this with eclipse
highlight RemoteView
References
in Project
satya - Tuesday, March 01, 2011 9:59:44 AM
The allowed views that are remote are
absolutelayout
framelayout
linearlayout
relativelayout
analogclock
button
chronometer
imagebutton
progressbar
Gridview
stackview
textview
datetimeview
iamgeview
AdapterViewFlipper
viewflipper
satya - Friday, March 04, 2011 1:50:13 PM
A List RemoteView: wiget provider responsiblities
//basic setup
load the layout with the list view in it
identify the list view with an id
set a remote adapter factory for the list view id
//setup an onclick callback with an action
Configure an intent to self invoke
create a pending intent out of this intent
pending intent needs to be be uniquie for this widget id
call setOnClickPendingIntentTemplate
set this pending intent for any list item click
//provide a custom onreceive
override onreceive to get this special pendign intent
define a special action for this pending intent
for all other actions call the base onreceive
satya - Friday, March 04, 2011 1:50:43 PM
A List RemoteView: list view factory responsiblities
provide a list item view
this view goes inside the list
create an intent with extras pointing to this row
pass the intent through setOnClickFillIntent
this row information will then be attached
to the previous pending intent template
satya - Friday, March 04, 2011 1:51:14 PM
working with custom actions in the widget provider
//Define an action string in your provider
public static final String ACTION_LIST_CLICK =
"com.androidbook.homewidgets.listclick";
//Override your onReceive to specialize it
@Override
public void onReceive(Context context, Intent intent)
{
if (intent.getAction().equals(BDayWidgetProvider.ACTION_LIST_CLICK))
{
//this action is not one widget actions
//this is a specific action that is directed here
dealwithListAction(context,intent);
return;
}
//make sure you call this
super.onReceive(context, intent);
}
public void dealwithListAction(Context context, Intent intent)
{
Toast t = Toast.makeText(context,"Clicked",Toast.LENGTH_SHORT);
t.show();
}
satya - Friday, March 04, 2011 1:51:46 PM
Setting up a list remoteveiw onclick to trigger a custom event
//setup a list view call back
//we need a pending intent that is unique for this widget id
//send a message to ourselves which we will catch in OnReceive
Intent onListClickIntent = new Intent(context,BDayWidgetProvider.class);
//set an action so that this receiver can distinguish it
//from other widget related actions
onListClickIntent.setAction(BDayWidgetProvider.ACTION_LIST_CLICK);
//because this receiver serves all instances of this app widget
//we need to know which specific instance this message is targeted for
onListClickIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
//Make this intent unique as we are getting ready
//to create a pending intent with it
//The touri method loads the extras as part of the uri string
//the data of this intent is not used at all except
//to establish this intent as a unique pending intent.
//See intent.filteEquals() method to see how intents are compared
//to see if they are unique.
onListClickIntent.setData(
Uri.parse(
onListClickIntent.toUri(Intent.URI_INTENT_SCHEME)));
//we need to deliver this intent later when
//the remote view is clicked as a broadcast intent
//to this same receiver.
final PendingIntent onListClickPendingIntent =
PendingIntent.getBroadcast(context, 0,
onListClickIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
//Set this pending intent as a template for
//the list item view.
//Each view in the list will then need to specify
//a set of additional extras to be appended to this template
//and then broadcast the final template.
//See how the remoteviewsfactory() sets up the each item
//in the list remoteview.
//See also docs for RemoteViews.setFillIntent()
rv.setPendingIntentTemplate(R.id.bdw_list_view_id,
onListClickPendingIntent);
satya - Friday, March 04, 2011 2:03:46 PM
Loading the list item and preparing it for the on click
public RemoteViews getViewAt(int position)
{
RemoteViews rv =
new RemoteViews(this.mContext.getPackageName(),
R.layout.item_layout);
this.loadItemOnClickExtras(rv, position);
return rv;
}
private void loadItemOnClickExtras(RemoteViews rv, int position)
{
Intent ei = new Intent();
ei.putExtra(BDayWidgetProvider.ACTION_LIST_ITEM_TEXT,
"Hello:" + position);
rv.setOnClickFillInIntent(R.id.widget_list_item_id, ei);
return;
}
satya - Friday, March 04, 2011 2:04:31 PM
Here is the view definition for the list item
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/widget_list_item_id"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Temporary"
/>
satya - Saturday, March 05, 2011 10:08:01 AM
Bottom line what is new in widgets for 3.0?
There a number of new remoteviews
Main ones are:
ListView
GridView
There are two classes introduced to support collection views
RemoteViewService
RemoteViewsFactory
There are two new methods to support list clciks
setOnClickPendingIntentTemplate()
setOnClickFillIntent
satya - Saturday, March 05, 2011 10:17:17 AM
Since API 3 you can choose to cancel the appwidget creation
Since API 3 you can choose to cancel the appwidget creation
you need to return result_cancelled. However if you press back it is not clear if this is deemed as result_cancel. I haven't checked. It should. but not sure.
satya - Saturday, March 05, 2011 10:24:40 AM
Couple of newer apis
notifyAppWidgetViewDataChanged
: The view is a collection view
partiallyUpdateAppWidget
: for thsi call the view state is not restored
satya - Saturday, March 05, 2011 10:26:01 AM
View state of remoteviews
AppWidgetManager will save teh remoteviews and restores them on configuration changes.
satya - Saturday, March 05, 2011 10:36:12 AM
it would be nice to have
a way for a package to explicily list and remove their widgets (essentially a cleanup operation)
Right now I can list the widgets but I have no way of removing them. May be that is a prerogative of the host?? But still as a package I would probably want to know.
satya - Tuesday, December 13, 2011 10:24:29 PM
Read up on RemoteViews service and factory at this link
Read up on RemoteViews service and factory at this link to get a full picture of how list widgets work.