Category Archives: Part -4: Handling Multiple Instance of an App Widget

Part -4: Handling Multiple Instance of Same AppWidgetProvider


This app widget tutorial is with respect to the app widget present in Nepal Khabar present in the Google play store.

In the previous tutorials, I have written about
Basics of and App Widget
Multiple Sized Widdget
Handling User Interaction in Widgets
Now, I am going to write about Handling Multiple Instances of App Widget
To create multiple instance of an app widget, the most important factor is saving the widget id of a particular widget. When we update the app widget, then we must specify which widget we are updating through the app widget. To be able to distinguish between multiple instances of the same AppWidgetProvider, when registering the “onClick” event (intent) you must add an extra value with the widget ID (appWidgetId).
This can be done in following way:
Save the widget id in the preference.
How do you save the widget id in the preference?
Here is the code snippet that demonstrates how it can be done:

 public static void setWidgetId(Context context,int appWidgetId) {  
           Log.i("From set widget id", appWidgetId+"");  
           Editor editor = context.getSharedPreferences(  
                     PREFS_NAME_ID ,  
                     Context.MODE_PRIVATE).edit();  
           editor.putInt(PREFS_VALUE_ID, appWidgetId);  
           editor.commit();  
      }  

If you have any persitent data, which needs to stick in that particular widget, then save such data in SharedPrefernces.
But how to preserve their uniqueness while saving in shared preferences ?
Here is the code snippet that demonstrates how it can be done:

 public static void setWidgetNewsLanguage(Context context, String language,  
                int appWidgetId) {  
           Editor editor = context.getSharedPreferences(  
                     PREFS_NAME_LANGUAGE + String.valueOf(appWidgetId),  
                     Context.MODE_PRIVATE).edit();  
           editor.putString(PREFS_VALUE_LANGUAGE + String.valueOf(appWidgetId),  
                     language);  
           editor.commit();  
      }  

While updating the appwidget, how to handle the multiple instances of the same app widget
1. Get the widget id saved in shared preference
Here is the code snippet that demonstrates how it can be done:

      public static int getWidgetId(Context context) {  
           SharedPreferences sharedPreferences = context.getSharedPreferences(  
                     PREFS_NAME_ID ,Context.MODE_PRIVATE);  
           return sharedPreferences.getInt(  
                     PREFS_VALUE_ID , 0);  
      }  

2. Assign this widget Id to the given instance of app widget:

 int incomingAppWidgetId= getWidgetId(context);  
 if (incomingAppWidgetId != INVALID_APPWIDGET_ID) {  
           updateNewsAppWidget(appWidgetManager,incomingAppWidgetId, intent);  
      }  

3. Get persistent data related to this widget:

 public static String getWidgetNewsLanguage(Context context, int appWidgetId) {  
           SharedPreferences sharedPreferences = context.getSharedPreferences(  
                     PREFS_NAME_LANGUAGE + String.valueOf(appWidgetId),  
                     Context.MODE_PRIVATE);  
           return sharedPreferences.getString(  
                     PREFS_VALUE_LANGUAGE + String.valueOf(appWidgetId), null);  
      }  

4. Assign each pending intents, the retrieved widget ID:

 private void btnClick(RemoteViews views, int appWidgetId) {  
                Intent btnClickIntent = new Intent(this, this.getClass());  
                btnClickIntent.putExtra(EXTRA_APPWIDGET_ID, appWidgetId);  
                btnClickIntent.setAction(ACTION_WIDGET_CLICK);  
                PendingIntent btnClickPendingIntent = PendingIntent.getService(  
                          this, appWidgetId, btnClickIntent,  
                          PendingIntent.FLAG_UPDATE_CURRENT);  
                views.setOnClickPendingIntent(R.id.widgetNewsCategoryTitle,  
                          btnClickPendingIntent);  
           }  

5. Upate the given widget, by passing the retrieved widget ID

 public void updateNewsAppWidget(AppWidgetManager appWidgetManager,  
                     int appWidgetId, Intent intent) {  
                RemoteViews views = new RemoteViews(this.getPackageName(),  
                          R.layout.layout_appwidget_large);  
                ArrayList<News> 
                initializeButtonClicks(appWidgetId);  
                appWidgetManager.updateAppWidget(appWidgetId, views);  
           }  

6. If you want to store arraylist with respect to the given widget, then store it in the hash value with key as widget id and value as newslist. Make the dataholder static in save it in a different data holder class.

 //In DataHolder class  
 public class DataHolder {  
 public static HashMap<Integer, ArrayList<News>> WIDGET_HASH_MAP = new HashMap<Integer, ArrayList<News>>();  
 }  

Hence, your app widget is now ready to handle its multiple instances.
Part -4 of App Widget, marks the end of app widget series. I will meet you in my blog through some other tutorials.
Until then, Happy Coding

Advertisements