Mastering Android Widget Development - Part2


SDK Version: 
M3

In Mastering Android Widget Development - Part1 we have gone trough the basics of appwidgets. Now we start to develop the example application, which couts time left to a given date.

First implement the configuration activity. It will contain a DatePicker, an OK button and a Cancel button, defined in the configuration.xml layout:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout
  3.   xmlns:android="http://schemas.android.com/apk/res/android"
  4.   android:layout_width="wrap_content"
  5.   android:layout_height="wrap_content"
  6.   android:orientation="vertical">
  7.         <DatePicker android:layout_width="wrap_content"
  8.         android:layout_height="wrap_content"
  9.         android:id="@+id/DatePicker">
  10.         </DatePicker>
  11.        
  12.         <LinearLayout
  13.         android:id="@+id/LinearLayout01";
  14.         android:layout_width="wrap_content"
  15.         android:layout_height="wrap_content"
  16.         android:orientation="horizontal">
  17.        
  18.                 <Button android:layout_width="wrap_content"
  19.                 android:layout_height="wrap_content"
  20.                 android:id="@+id/okbutton"
  21.                 android:text="OK"></Button>
  22.                 <Button android:layout_width="wrap_content"
  23.                 android:layout_height="wrap_content"
  24.                 android:text="Cancel"
  25.                 android:id="@+id/cancelbutton"></Button>
  26.         </LinearLayout>
  27. </LinearLayout>

We store the choosen date in SharedPreferences, if OK is pressed, and cancel widget creation on cancel button.
The code below shows the configuration activity with comments.

  1. package com.helloandroid.countdownexample;
  2.  
  3. import java.util.Date;
  4.  
  5. import android.app.Activity;
  6. import android.appwidget.AppWidgetManager;
  7. import android.content.Context;
  8. import android.content.Intent;
  9. import android.content.SharedPreferences;
  10. import android.os.Bundle;
  11. import android.view.View;
  12. import android.view.View.OnClickListener;
  13. import android.widget.Button;
  14. import android.widget.DatePicker;
  15.  
  16. public class CountdownConfiguration extends Activity {
  17.         private Context self = this;
  18.         private int appWidgetId;
  19.  
  20.         @Override
  21.         protected void onCreate(Bundle savedInstanceState) {
  22.                 super.onCreate(savedInstanceState);
  23.                 // get the appWidgetId of the appWidget being configured
  24.                 Intent launchIntent = getIntent();
  25.                 Bundle extras = launchIntent.getExtras();
  26.                 appWidgetId = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID,
  27.                                 AppWidgetManager.INVALID_APPWIDGET_ID);
  28.  
  29.                 // set the result for cancel first
  30.                 // if the user cancels, then the appWidget
  31.                 // should not appear
  32.                 Intent cancelResultValue = new Intent();
  33.                 cancelResultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID,
  34.                                 appWidgetId);
  35.                 setResult(RESULT_CANCELED, cancelResultValue);
  36.                 // show the user interface of configuration
  37.                 setContentView(R.layout.configuration);
  38.  
  39.                 // the OK button
  40.                 Button ok = (Button) findViewById(R.id.okbutton);
  41.                 ok.setOnClickListener(new OnClickListener() {
  42.                         @Override
  43.                         public void onClick(View arg0) {
  44.                                 // get the date from DatePicker
  45.                                 DatePicker dp = (DatePicker) findViewById(R.id.DatePicker);
  46.                                 GregorianCalendar date = new GregorianCalendar(dp.getYear(), dp
  47.                                                 .getMonth(), dp.getDayOfMonth());
  48.  
  49.                                 // save the goal date in SharedPreferences
  50.                                 // we can only store simple types only like long
  51.                                 // if multiple widget instances are placed
  52.                                 // each can have own goal date
  53.                                 // so store it under a name that contains appWidgetId
  54.                                 SharedPreferences prefs = self.getSharedPreferences("prefs", 0);
  55.                                 SharedPreferences.Editor edit = prefs.edit();
  56.                                 edit.putLong("goal" + appWidgetId, date.getTime());
  57.                                 edit.commit();
  58.  
  59.                                 // change the result to OK
  60.                                 Intent resultValue = new Intent();
  61.                                 resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID,
  62.                                                 appWidgetId);
  63.                                 setResult(RESULT_OK, resultValue);
  64.                                 // finish closes activity
  65.                                 // and sends the OK result
  66.                                 // the widget will be be placed on the home screen
  67.                                 finish();
  68.                         }
  69.                 });
  70.  
  71.                 // cancel button
  72.                 Button cancel = (Button) findViewById(R.id.cancelbutton);
  73.                 cancel.setOnClickListener(new OnClickListener() {
  74.                         @Override
  75.                         public void onClick(View arg0) {
  76.                                 // finish sends the already configured cancel result
  77.                                 // and closes activity
  78.                                 finish();
  79.                         }
  80.                 });
  81.         }
  82. }

We must also register the activity in the AndroidManifest.xml:

  1. <activity
  2. android:name="CountdownConfiguration&quot;
  3. android:label="@string/app_name">
  4. <intent-filter>
  5.     <action
  6.         android:name="android.appwidget.action.APPWIDGET_CONFIGURE" />
  7.     </intent-filter>
  8. </activity>

Now, lets place something on the appWidget itself to be wisible.
We crate a layout for this named countdownwidget.xml:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout
  3.   xmlns:android="http://schemas.android.com/apk/res/android"
  4.   android:layout_width="wrap_content"
  5.   android:layout_height="wrap_content" android:orientation="vertical">
  6.  
  7. <TextView android:id="@+id/TextView01" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello!"></TextView>
  8. </LinearLayout>

And for last today we show this layout on the widget with the code below in the CountdownWidget class onUpdate method.
It loops trough all of the given appwidgetIds and sets up the layout for each.

  1. for (int appWidgetId : appWidgetIds) {
  2.                 RemoteViews remoteView = new RemoteViews(context.getPackageName(),
  3.                                 R.layout.countdownwidget);
  4.                 appWidgetManager.updateAppWidget(appWidgetId, remoteView);
  5.         }
  6. super.onUpdate(context, appWidgetManager, appWidgetIds);

To be continued...