草庐IT

android - 多个 Android Widget 实例只更新最后一个 widget

coder 2023-12-15 原文

我尝试使用这个 link 解决我的问题

update - I figured out that there is something wrong with the setter of the pending intent- every time I click on the imageview- the intent sends the extre details of the last defined widget- meaning that the other pending intents that where defined on the pre-added widgets were run-over by the newer widgets

我有一个应用程序小部件,可以显示用户选择的图片。(很多小部件 - 许多图片) 我的问题是:无论我按下屏幕上的哪个小部件 - 只有最后添加的小部件才会更新: 这是我的代码

我的小部件 xml 提供程序代码

<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
    android:initialLayout="@layout/widget_Test"
    android:minHeight="146dip"
    android:minWidth="146dip"
    android:updatePeriodMillis="0" />

我的 list xml 代码

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.test"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk android:minSdkVersion="8" />

    <uses-permission android:name="android.permission.BIND_REMOTEVIEWS" >
    </uses-permission>

    <application
            android:icon="@drawable/icon"
            android:label="@string/app_name" >
            <activity
                    android:name=".Activities.WidgetConfig"
                    android:screenOrientation="portrait" >

                    <!-- prbbly delete this line -->
                    <action android:name="android.appwidget.action.APPWIDGET_CONFIGURE" />
            </activity>
            <!-- Test Widget -->
            <receiver
                    android:name=".Simple.Widget"
                    android:label="@string/app_widget_Test" >
                    <intent-filter>
                            <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
                    </intent-filter>

                    <meta-data
                            android:name="android.appwidget.provider"
                            android:resource="@xml/widget_Test_provider" />
            </receiver>

            <service android:name=".Simple.Widget$TestWidgetService" />
    </application>

</manifest>

小部件提供者

public class Widget extends AppWidgetProvider
{
    public static String PREFENCES_WIDGET_CONFIGURE = "ActionConfigureWidget";
    public  static int[] widgets;

    @Override
    public void onUpdate(Context context, AppWidgetManager appWidgetManager,
                    int[] appWidgetIds)
    {
            Intent svcIntent = new Intent(context, TESTWidgetService.class);
            widgets = appWidgetIds;
            context.startService(svcIntent);
    }

    public static class TESTWidgetService extends Service
    {
            @Override
            public void onStart(Intent intent, int startId)
            {
                    super.onStart(intent, startId);
                    // Update the widget
                    RemoteViews remoteView = buildRemoteView(this);

                    // Push update to homescreen
                    Mngr.getInstance().pushUpdate(remoteView,
                                    getApplicationContext(), Widget.class);

                    // No more updates so stop the service and free resources
                    stopSelf();
            }

            public RemoteViews buildRemoteView(Context context)
            {
                    RemoteViews remoteViews = new RemoteViews(context.getPackageName(),
                                    R.layout.widget_TEST);
                    if (widgets != null)
                    {
                            int length = widgets.length;

                            for (int i = 0; i < length; i++)
                            {
                                    Intent configIntent = new Intent(context,
                                                    WidgetConfig.class);

                                    configIntent.setAction(Widget.PREFENCES_WIDGET_CONFIGURE);
                                    String number = AppWidgetManager.EXTRA_APPWIDGET_ID
                                                    + "number";
                                    configIntent.putExtra(number, length);
                                    String widgetID = AppWidgetManager.EXTRA_APPWIDGET_ID + i;
                                    int id = widgets[i];
                                    configIntent.putExtra(widgetID, id);
                                    PendingIntent runTESTPendingIntent = PendingIntent
                                                    .getActivity(context, 0, configIntent,
                                                                    PendingIntent.FLAG_UPDATE_CURRENT);

                                    remoteViews.setOnClickPendingIntent(R.id.TESTWidgetImage,
                                                    runTESTPendingIntent);

                                    Mngr controller = Mngr.getInstance();

                                    controller.updateTESTWidget(context, remoteViews);
                            }
                    }
                    return remoteViews;
            }

            @Override
            public void onConfigurationChanged(Configuration newConfig)
            {
                    int oldOrientation = this.getResources().getConfiguration().orientation;

                    if (newConfig.orientation != oldOrientation)
                    {
                            // Update the widget
                            RemoteViews remoteView = buildRemoteView(this);

                            // Push update to homescreen
                            Mngr.getInstance().pushUpdate(remoteView,
                                            getApplicationContext(), Widget.class);
                    }
            }

            @Override
            public IBinder onBind(Intent arg0)
            {
                    // TODO Auto-generated method stub
                    return null;
            }
    }
}

我的配置 Activity

public class WidgetConfig extends ListActivity // implements
{
    private Bundle m_extras;
    private ArrayList<Test> m_tests = null;
    private int mAppWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID;
    ImageAdapter m_adapter;

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.imagelist);

            Resources res = getResources();
            Mngr mngr = Mngr.getInstance();
            mngr.setResources(res);
            Context ctx = getApplicationContext();
            mngr.setContext(ctx);
            getTests();
            m_adapter = new ImageAdapter(ctx, R.layout.row, m_tests);
            ImageDownloader.Mode mode = ImageDownloader.Mode.CORRECT;
            m_adapter.getImageDownloader().setMode(mode);

            setListAdapter(m_adapter);

            Intent intent = getIntent();
            m_extras = intent.getExtras();
    }

    private void getTests()
    {
            m_tests = new ArrayList<Test>();

            Resources res = getResources();
            String[] TestNames = res.getStringArray(R.array.fav_Test_array);
            TypedArray imgs = getResources().obtainTypedArray(
                            R.array.fav_Test_integer);
            for (int i = 0; i < TestNames.length; i++)
            {
                Test o1 = new Test();
                String TestName = TestNames[i];
                int resID = imgs.getResourceId(i, -1);
                o1.setTestName(TestName);
                o1.setIMGID(resID);
                m_tests.add(o1);
            }
            imgs.recycle();

    }

    @Override
    protected void onListItemClick(ListView l, View v, int position, long id)
    {

        ListAdapter adapt = l.getAdapter();
        Object obj = adapt.getItem(position);
        if (obj != null)
        {
            Mngr mngr = Mngr.getInstance();
            Context context = getApplicationContext();
            String key = context.getString(R.string.TestWidget_string) + "_"
                + AppWidgetManager.EXTRA_APPWIDGET_ID;
            Test Test = (Test) obj;
            String val = Test.getIMGID().toString();
            mngr.putString(context, key, val);
            updateWidget();
        }

        super.onListItemClick(l, v, position, id);
    }

    private void updateWidget()
    {
        Context ctx = getApplicationContext();
        AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(ctx);
        setResult(RESULT_CANCELED);
        if (m_extras != null)
        {
            Intent resultValue = new Intent();

            int numberOfWidgets = m_extras.getInt(
                AppWidgetManager.EXTRA_APPWIDGET_ID + "number",
                AppWidgetManager.INVALID_APPWIDGET_ID);
            for (int i = 0; i < numberOfWidgets; i++)
            {

                String stringID = AppWidgetManager.EXTRA_APPWIDGET_ID + i;
                mAppWidgetId = m_extras.getInt(stringID,
                                AppWidgetManager.INVALID_APPWIDGET_ID);


                /*************************************************************/
                /*I Don't really know if I am using this piece of code right */
                Uri data = Uri.withAppendedPath(Uri.parse("ABCD"
                                + "://widget/id/"), String.valueOf(mAppWidgetId));
                resultValue.setData(data);
                /*************************************************************/

                RemoteViews views = new RemoteViews(ctx.getPackageName(),
                                R.layout.widget_Test);

                Mngr.getInstance().updateTestWidget(ctx, views);

                appWidgetManager.updateAppWidget(mAppWidgetId, views);
                resultValue.putExtra(stringID, mAppWidgetId);
            }

            setResult(RESULT_OK, resultValue);
            finish();
        }
    }
}

我的经理代码

public void updateTestWidget(Context context, RemoteViews remoteViews)
{
    String key = context.getString(R.string.TestWidget_string) + "_"
            + AppWidgetManager.EXTRA_APPWIDGET_ID;

    String s = getString(context, key, "");
    if (s != null && s.equals("") == false)
    {
        int resID = Integer.valueOf(s);
        remoteViews.setImageViewResource(R.id.TestWidgetImage, resID);
    }
}

public void pushUpdate(RemoteViews remoteView, Context ctx, Class<?> cls)
{
    ComponentName myWidget = new ComponentName(ctx, cls);
    AppWidgetManager manager = AppWidgetManager.getInstance(ctx);
    manager.updateAppWidget(myWidget, remoteView);
}

最佳答案

问题不在于您的 configActivity,而在于您的 widgetProvider。我遇到了和你一样的问题,但使用 link 解决了你指定的。您需要在 buildRemoteViewconfigIntent 上设置“hacked” Intent 。

关于android - 多个 Android Widget 实例只更新最后一个 widget,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9343978/

有关android - 多个 Android Widget 实例只更新最后一个 widget的更多相关文章

  1. ruby-on-rails - Rails 3 中的多个路由文件 - 2

    Rails2.3可以选择随时使用RouteSet#add_configuration_file添加更多路由。是否可以在Rails3项目中做同样的事情? 最佳答案 在config/application.rb中:config.paths.config.routes在Rails3.2(也可能是Rails3.1)中,使用:config.paths["config/routes"] 关于ruby-on-rails-Rails3中的多个路由文件,我们在StackOverflow上找到一个类似的问题

  2. ruby-on-rails - 如何验证 update_all 是否实际在 Rails 中更新 - 2

    给定这段代码defcreate@upgrades=User.update_all(["role=?","upgraded"],:id=>params[:upgrade])redirect_toadmin_upgrades_path,:notice=>"Successfullyupgradeduser."end我如何在该操作中实际验证它们是否已保存或未重定向到适当的页面和消息? 最佳答案 在Rails3中,update_all不返回任何有意义的信息,除了已更新的记录数(这可能取决于您的DBMS是否返回该信息)。http://ar.ru

  3. ruby-on-rails - 在 Ruby 中循环遍历多个数组 - 2

    我有多个ActiveRecord子类Item的实例数组,我需要根据最早的事件循环打印。在这种情况下,我需要打印付款和维护日期,如下所示:ItemAmaintenancerequiredin5daysItemBpaymentrequiredin6daysItemApaymentrequiredin7daysItemBmaintenancerequiredin8days我目前有两个查询,用于查找maintenance和payment项目(非排他性查询),并输出如下内容:paymentrequiredin...maintenancerequiredin...有什么方法可以改善上述(丑陋的)代

  4. ruby - 使用 Vim Rails,您可以创建一个新的迁移文件并一次性打开它吗? - 2

    使用带有Rails插件的vim,您可以创建一个迁移文件,然后一次性打开该文件吗?textmate也可以这样吗? 最佳答案 你可以使用rails.vim然后做类似的事情::Rgeneratemigratonadd_foo_to_bar插件将打开迁移生成的文件,这正是您想要的。我不能代表textmate。 关于ruby-使用VimRails,您可以创建一个新的迁移文件并一次性打开它吗?,我们在StackOverflow上找到一个类似的问题: https://sta

  5. ruby-on-rails - Rails - 一个 View 中的多个模型 - 2

    我需要从一个View访问多个模型。以前,我的links_controller仅用于提供以不同方式排序的链接资源。现在我想包括一个部分(我假设)显示按分数排序的顶级用户(@users=User.all.sort_by(&:score))我知道我可以将此代码插入每个链接操作并从View访问它,但这似乎不是“ruby方式”,我将需要在不久的将来访问更多模型。这可能会变得很脏,是否有针对这种情况的任何技术?注意事项:我认为我的应用程序正朝着单一格式和动态页面内容的方向发展,本质上是一个典型的网络应用程序。我知道before_filter但考虑到我希望应用程序进入的方向,这似乎很麻烦。最终从任何

  6. ruby-on-rails - 渲染另一个 Controller 的 View - 2

    我想要做的是有2个不同的Controller,client和test_client。客户端Controller已经构建,我想创建一个test_clientController,我可以使用它来玩弄客户端的UI并根据需要进行调整。我主要是想绕过我在客户端中内置的验证及其对加载数据的管理Controller的依赖。所以我希望test_clientController加载示例数据集,然后呈现客户端Controller的索引View,以便我可以调整客户端UI。就是这样。我在test_clients索引方法中试过这个:classTestClientdefindexrender:template=>

  7. ruby-on-rails - 如何使用 instance_variable_set 正确设置实例变量? - 2

    我正在查看instance_variable_set的文档并看到给出的示例代码是这样做的:obj.instance_variable_set(:@instnc_var,"valuefortheinstancevariable")然后允许您在类的任何实例方法中以@instnc_var的形式访问该变量。我想知道为什么在@instnc_var之前需要一个冒号:。冒号有什么作用? 最佳答案 我的第一直觉是告诉你不要使用instance_variable_set除非你真的知道你用它做什么。它本质上是一种元编程工具或绕过实例变量可见性的黑客攻击

  8. ruby 正则表达式 - 如何替换字符串中匹配项的第 n 个实例 - 2

    在我的应用程序中,我需要能够找到所有数字子字符串,然后扫描每个子字符串,找到第一个匹配范围(例如5到15之间)的子字符串,并将该实例替换为另一个字符串“X”。我的测试字符串s="1foo100bar10gee1"我的初始模式是1个或多个数字的任何字符串,例如,re=Regexp.new(/\d+/)matches=s.scan(re)给出["1","100","10","1"]如果我想用“X”替换第N个匹配项,并且只替换第N个匹配项,我该怎么做?例如,如果我想替换第三个匹配项“10”(匹配项[2]),我不能只说s[matches[2]]="X"因为它做了两次替换“1fooX0barXg

  9. ruby - 多个属性的 update_column 方法 - 2

    我有一个具有一些属性的模型:attr1、attr2和attr3。我需要在不执行回调和验证的情况下更新此属性。我找到了update_column方法,但我想同时更新三个属性。我需要这样的东西:update_columns({attr1:val1,attr2:val2,attr3:val3})代替update_column(attr1,val1)update_column(attr2,val2)update_column(attr3,val3) 最佳答案 您可以使用update_columns(attr1:val1,attr2:val2

  10. ruby-on-rails - 如果 Object::try 被发送到一个 nil 对象,为什么它会起作用? - 2

    如果您尝试在Ruby中的nil对象上调用方法,则会出现NoMethodError异常并显示消息:"undefinedmethod‘...’fornil:NilClass"然而,有一个tryRails中的方法,如果它被发送到一个nil对象,它只返回nil:require'rubygems'require'active_support/all'nil.try(:nonexisting_method)#noNoMethodErrorexceptionanymore那么try如何在内部工作以防止该异常? 最佳答案 像Ruby中的所有其他对象

随机推荐