1

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
                    */
     }
}
Community
  • 1
  • 1
PGMacDesign
  • 6,092
  • 8
  • 41
  • 78

1 Answers1

4

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

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • Very thorough answer! I suppose I should rephrase, I am trying to get strings passed from widgetconfig to the service that updates the widget. I cannot use shared preferences as there will be multiple widgets to update, how do I go about passing data from the widgetconfig over to the MailWidgetUpdateService class without Shared preferences or a database? (Updated my answer a moment ago btw) – PGMacDesign Jan 10 '15 at 21:53
  • @Silmarilos: "I cannot use shared preferences as there will be multiple widgets to update" -- use different `SharedPreferences` files per widget instance. Or use a database. Or use another sort of file (e.g., JSON). Regardless of who is updating the app widget *now*, you need to persist this data to be able to update the app widget *later*. "how do I go about passing data from the widgetconfig over to the MailWidgetUpdateService" -- have the *activity* call `startService()` with an `Intent` identifying the service and containing relevant extras. – CommonsWare Jan 10 '15 at 22:43
  • CommonsWare: thank you for your help, on the right track! I am using the shared preferences to send a uniquely ID'd item over, but the issue is that when the service tries to read it, it either returns the default value or a null pointer ON THE FIRST loop through the IDs, meaning I think it is sending 2 IDs, even though I am only sending one personally. Any ideas on how to fix that? I updated my code above for a more detailed explanation. – PGMacDesign Jan 10 '15 at 23:49
  • @Silmarilos: Sorry, I am having some difficulty in following your code, as you have been changing parts of it but not others. Stack Overflow is not really designed for you to be changing the content of questions, as it makes it difficult for both those who answer questions and those who try to use the questions themselves for help in the future. If you have substantial follow-on questions, ask a fresh Stack Overflow question. It's not like they are going to run out of space for questions. :-) – CommonsWare Jan 10 '15 at 23:56
  • Thanks for your guidance commons, I changed the question structure, code, and then re-posted here: http://stackoverflow.com/questions/27882598/how-do-i-retrieve-shared-preferences-data-in-a-widget-service-class-without-pass . Hopefully someone will be as helpful as you were here in getting me towards the right answer. Thanks again! – PGMacDesign Jan 11 '15 at 00:17