【问题标题】:How do I pass data from a widget config class to a widget provider class via intents?如何通过意图将数据从小部件配置类传递到小部件提供者类?
【发布时间】:2015-01-10 20:20:51
【问题描述】:

我不会删除这个问题,因为 commons 在下面提出了一些很好的观点,但我确实修改了代码并在这里提出了不同的问题:How do I retrieve shared preferences data in a Widget Service class without passing in incorrect default values or getting null pointer errors?

我正在开发一个应用程序,该应用程序接受用户的输入选择并将它们传递给小部件。它目前正在运行一项服务来管理它并且运行良好,但我无法弄清楚如何有效地将字符串从一个传递到另一个。到目前为止,这是我的代码:

        //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
                    */
     }
}

【问题讨论】:

    标签: android android-intent widget appwidgetprovider extras


    【解决方案1】:

    如何从小部件配置类中检索 Widget Provider 类中的 extras,以及在收到它们后如何将它们传递给服务?

    你从不做任何事情开始。

    您的AppWidgetProvider 只是一种更新应用小部件内容的方法,Android 在添加应用小部件时以及根据应用小部件元数据请求定期更新时专门使用的方法.此外,请记住,AppWidgetProvider 的实例只使用一次,然后就被丢弃。

    如果您想在其他地方更新您的应用小部件,去更新应用小部件,方法是创建 RemoteViews 并将它们提供给 AppWidgetManager。您的AppWidgetProvider 与此无关。引用the documentation:

    当 App Widget 使用配置 Activity 时,Activity 负责在配置完成时更新 App Widget。您可以通过直接从 AppWidgetManager 请求更新来做到这一点。

    如果您想要更新应用程序小部件逻辑的通用实现,请将其设置为您的配置 ActivityAppWidgetProvider 以及任何其他需要更新的通用类应用小部件内容。

    所以,当用户通过activity配置app widget时,你需要:

    • 通过AppWidgetManager 自行更新应用小部件,以及

    • 保留配置数据(在数据库、SharedPreferences 或其他类型的文件中),以便将来用于更新

    【讨论】:

    • 非常彻底的回答!我想我应该改写一下,我正在尝试将字符串从 widgetconfig 传递到更新小部件的服务。我不能使用共享首选项,因为将有多个小部件要更新,如何在没有共享首选项或数据库的情况下将数据从 widgetconfig 传递到 MailWidgetUpdateService 类? (顺便说一句,我刚刚更新了我的答案)
    • @Silmarilos:“我不能使用共享首选项,因为会有多个小部件要更新”——每个小部件实例使用不同的 SharedPreferences 文件。或者使用数据库。或者使用另一种文件(例如 JSON)。不管是谁在现在更新应用小部件,您都需要保留这些数据以便能够在以后更新应用小部件。 “我如何将数据从 widgetconfig 传递到 MailWidgetUpdateService”——让 activity 调用 startService() 并使用 Intent 标识服务并包含相关的附加功能。
    • CommonsWare:感谢您的帮助,在正确的轨道上!我正在使用共享首选项发送一个唯一 ID 的项目,但问题是当服务尝试读取它时,它要么返回默认值,要么在第一次循环中返回空指针,这意味着我认为它发送了 2 个 ID,尽管我只发送了一个。关于如何解决这个问题的任何想法?我更新了上面的代码以获得更详细的解释。
    • @Silmarilos:抱歉,我在遵循您的代码时遇到了一些困难,因为您一直在更改其中的一部分,但没有更改其他部分。 Stack Overflow 的设计并不是为了让您更改问题的内容,因为它会让回答问题的人和将来尝试使用问题自己寻求帮助的人都变得困难。如果您有大量后续问题,请提出新的 Stack Overflow 问题。他们不会没有足够的空间来提问。 :-)
    • 感谢commons的指导,我改了题结构,代码,然后在这里重新贴:stackoverflow.com/questions/27882598/…。希望有人能像你在这里帮助我找到正确的答案。再次感谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-22
    相关资源
    最近更新 更多