Saturday, April 28, 2012

Handling User Interaction with Android App Widgets in Android



In order to handle user interaction with an App Widget, the following tasks must be performed:
1.Set a unique click handler for each App Widget control
2.Have the click handler send a command to a registered receiver
3.Process the command received and perform any action necessary
4.Update the App Widget to reflect the changes
We include a button bar with three controls. Each of the buttons on the button bar will perform a specific action and clicking anywhere else in the App Widget will hide the button bar. The left-hand button (tool set) will launch the configuration Activity so users can change the time interval between image transitions in the slideshow. The middle button will pause or resume, the slideshow. The right-hand button allows the user to skip to the next image immediately.
Working with RemoteViews
In order to enable user interaction with a RemoteViews control, you must register for a PendingIntent to be triggered when a specific View within the RemoteViews object is clicked. This is done with a call to the setOnClickPendingIntent() method of the RemoteViews object. For instance, to add the PendingIntent for launching the Activity to configure the slideshow time interval.
PendingIntent pendingIntent = PendingIntent.getActivity
     (context, 0, configIntent,
     PendingIntent.FLAG_UPDATE_CURRENT);
  remoteView.
     setOnClickPendingIntent(R.id.config, pendingIntent);
Working with PendingIntents
the Intent had to be unique in order for the application to differentiate between specific instances of the App Widget, since more than one might exist. This was achieved by including the App Widget identifier in the Uri field, allowing each App Widget to have its own time interval.
Intent configIntent =
     new Intent(context, ImagesWidgetConfiguration.class);
  configIntent.putExtra(
     AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
  configIntent.setData(Uri.withAppendedPath(Uri.Parse
     (ImagesWidgetProvider.URI_SCHEME + "://widget/id/"),
     String.valueOf(appWidgetId)));
At first, it might seem like the state information could be encoded as part of the Intent being sent by the button handler. Remember, however, that the App Widget will also be updating on a regular schedule with the Intent sent by the Alarm. That Intent won't be changing and won't know the new state. In order to solve this problem, we create a new action type for the App Widget called ACTION_WIDGET_CONTROL and append the command to the Uri of the Intent. We then store the state of the App Widget in the SharedPreferences.
private PendingIntent makeControlPendingIntent
     (Context context, String command, int appWidgetId) {
     Intent active = new Intent();
     active.setAction(ACTION_WIDGET_CONTROL);
     active.putExtra(
        AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
     Uri data = Uri.withAppendedPath(
        Uri.parse(URI_SCHEME + "://widget/id/#"+command),
        String.valueOf(appWidgetId));
     active.setData(data);
     return(PendingIntent.getBroadcast(context,
        0, active, PendingIntent.FLAG_UPDATE_CURRENT));
  }

The block of code above creates a new Intent with an action of ACTION_WIDGET_CONTROL, which is simply a string.
The App Widget will be able to receive these broadcasts in its onReceive() handler method
else if (ACTION_WIDGET_CONTROL.equals(action)) {
     final int appWidgetId = intent.getIntExtra(
        AppWidgetManager.EXTRA_APPWIDGET_ID,
        AppWidgetManager.INVALID_APPWIDGET_ID);
     if (appWidgetId !=
        AppWidgetManager.INVALID_APPWIDGET_ID) {
        this.onHandleAction(
           context, appWidgetId, intent.getData());
  }
I have create ImageWidgetDemo , attached with this article.

No comments:

Post a Comment