Search code examples
androidandroid-intentwidgetappwidgetproviderextras

How do I pass data from a widget config class to a widget provider class via intents?


I am not going to delete this question as commons brings up some excellent points below, but I did rework the code and ask the question differently here: How do I retrieve shared preferences data in a Widget Service class without passing in incorrect default values or getting null pointer errors?

I am working on an app that takes a user's input choices and passes them to a widget. It is currently running a service to manage it and it works well, but I cannot figure out how to pass a String from one to the other effectively. Here is my code so far:

        //First Widget config is called:
        public class WidgetConfig extends Activity{

            //Stuff happens here to get data from EditTexts and spinners and converts 
            //them to strings.
            //Eventually a button is pressed which enters all the information:

            public void onClick(View v) {
                //I have already tried shared preferences like this:
                //This was intended to give the shared preferences a unique identifier.
                //It does not work for what I am trying to do
                String str = Integer.toString(appWidgetId); 
                sp.putString(editor, str + "::" + "username", user_name);
                //The appWidgetID was unique and so I thought it would work as an
                //identifier for shared prefs.

                //This is the intent for opening the provider
                Intent intentUpdate = new Intent(context, MailWidgetProvider.class); 

                //I also attempted to put items here:
                intentUpdate.putExtra("username", user_name);

                //I left out the rest of the pending update code as it is irrelevant to this.
            }
        }


        //Next the AppWidgetProvider is called
        public class MailWidgetProvider extends AppWidgetProvider {

            public void onUpdate(Context context, AppWidgetManager appWidgetManager, 
                                  int[] appWidgetIds) {

                ComponentName thisWidget = new ComponentName(context, 
                                       MailWidgetProvider.class);
                int[] allWidgetIds = appWidgetManager.getAppWidgetIds(thisWidget);

                //This is the intent to open up and run the service
                Intent intent = new Intent(context.getApplicationContext(),                            
                                            MailWidgetUpdateService.class);

                intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, allWidgetIds);

                context.startService(intent);
            }

        }

    //Service Class
    public class MailWidgetUpdateService extends Service {
        public void onStart(Intent intent, int startId) {
                AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(this
                        .getApplicationContext());

                int[] allWidgetIds = intent.getIntArrayExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS);

                ComponentName thisWidget = new ComponentName(getApplicationContext(),
                        MailWidgetProvider.class);

                int[] allWidgetIds2 = appWidgetManager.getAppWidgetIds(thisWidget);

                //Loop through the IDs
                for (int widgetId : allWidgetIds) {

                    int awid = widgetId;
                    String str = Integer.toString(widgetId);

                    String user_name = sp.getString(settings, str + "::" + "chosen_accout_string", "Loading...");
                    Log.d(TRACKING_USERNAME, user_name);

                    /*
                    Issue Here, see explanation below
                    */
     }
}

Solution

  • How do I retrieve the extras in the Widget Provider class from the widget config class and how do I go about passing them on to the service after receiving them?

    You start by not doing much of any of that.

    Your AppWidgetProvider is merely one means of updating the app widget contents, one that will specifically be used by Android when your app widget is added and on periodic updates as requested by your app widget metadata. Moreover, bear in mind that an instance of your AppWidgetProvider is used just once and is then discarded.

    If you want to update your app widget in other places, go update the app widget, by creating the RemoteViews and giving them to an AppWidgetManager. Your AppWidgetProvider has nothing to do with it. To quote the documentation:

    When an App Widget uses a configuration Activity, it is the responsibility of the Activity to update the App Widget when configuration is complete. You can do so by requesting an update directly from the AppWidgetManager.

    If you want to have a common implementation of the update-the-app-widget logic, put that is some common class that is used by your configuration Activity, your AppWidgetProvider, and anything else that needs to update the app widget contents.

    So, when the user configures the app widget through the activity, you need to:

    • update the app widget yourself via the AppWidgetManager, and

    • hold onto the configuration data (in a database, SharedPreferences, or other sort of file) so that it can be used for future updates