Mastering Android Widget Development - Part5 - Final


SDK Version: 
M3

In this last part of the tutorial we will implement buttons to the appWidget, which will directly interact with the appWidget functionality.
We will have 2 buttons, a plus button to add one more day to the target date, and a minus button to decrease time left by one day.

First add the buttons to the countdownwidget.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" android:orientation="vertical">
  6.  
  7. <TextView android:id="@+id/TextView01" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Time left"></TextView>
  8. <LinearLayout android:id="@+id/LinearLayout01"; android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal">
  9.         <Button android:layout_height="wrap_content" android:id="@+id/plusbutton" android:text="+" android:layout_width="60dip"></Button>
  10. <Button android:layout_height="wrap_content" android:layout_width="60dip" android:id="@+id/minusbutton" android:text="-"></Button>
  11. </LinearLayout>
  12. </LinearLayout>

Then add some constants to the CountdownService class we will use:

  1. public static final String PLUS = "plus";
  2. public static final String MINUS = "minus";
  3. public static final long  MODIFY= 86400;

Every time the appwidget updates we must set the button PendingIntents (using our previously defined method), so add this to the onStart method before we apply the changes with the appWidgetManager.updateAppWidget(appWidgetId, remoteView); line:

  1. remoteView.setOnClickPendingIntent(R.id.plusbutton,CountdownWidget.makeControlPendingIntent(getApplicationContext(),PLUS,appWidgetId));
  2. remoteView.setOnClickPendingIntent(R.id.minusbutton,CountdownWidget.makeControlPendingIntent(getApplicationContext(),MINUS,appWidgetId));

All is left to do some action on button press, the following code inserted after defining SharedPreferences in the onStart, will do the job:

  1. //plus button pressed
  2. if(command.equals(PLUS)){
  3.         SharedPreferences.Editor edit=prefs.edit();
  4.         edit.putLong("goal" + appWidgetId,prefs.getLong("goal" + appWidgetId, 0)+MODIFY);
  5.         edit.commit();
  6. //minus button pressed
  7. }else if(command.equals(MINUS)){
  8.         SharedPreferences.Editor edit=prefs.edit();
  9.         edit.putLong("goal" + appWidgetId,prefs.getLong("goal" + appWidgetId, 0)-MODIFY);
  10.         edit.commit();
  11. }

So in the onStart method we do some action depending on the given command, and refresh the widget in any case. Az you can see implementing the buttons was easy with the used architecture.

This is the final part of the tutorial, so i attached the final source to download.
The app is backward compatible to 1.5 since we used the deprecated onStart Service method. The AlarmManager does not fire refreshes when the fone is in sleep state, so the app wont use resources when it is not needed. I hope I was able to help understanding appWidgets.