多个 Android Widget 实例仅更新最后一个小部件

Posted

技术标签:

【中文标题】多个 Android Widget 实例仅更新最后一个小部件【英文标题】:Multiple Android Widget instances only updating last widget 【发布时间】:2012-03-09 18:44:56 【问题描述】:

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

更新-我发现未决意图的设置器有问题-每次我单击图像视图时-意图都会发送最后定义的小部件的外部详细信息- 这意味着在预添加的小部件上定义的其他待处理意图被较新的小部件运行

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

我的小部件 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" />

我的清单 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;
            
    

我的配置活动

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);

【问题讨论】:

【参考方案1】:

问题不在于您的 configActivity,而在于您的 widgetProvider。我遇到了与您相同的问题,但使用您指定的link 解决了。您需要在 buildRemoteView 中为您的 configIntent 设置“被黑”意图。

【讨论】:

【参考方案2】:

当我在 2.2 或 2.3 版本的模拟器上测试我的应用程序时,我遇到了同样的问题。在真实设备上,一切都应该可以正常工作。此外,就我而言,模拟器 4.0 工作正常。无论如何,我建议您在真实设备上进行测试。

【讨论】:

嘿,我已经在真机上测试过了。还没有运气

以上是关于多个 Android Widget 实例仅更新最后一个小部件的主要内容,如果未能解决你的问题,请参考以下文章

Android Widget 更新服务,多个 onclick 监听器

Android 无法实例化一个或多个类

使用仅来自一个 NSMutableArray 的多个部分填充 tableview

在QML :: Image视图上更新多个QImages仅显示最后发送的QImages

无法实例化以下类:- android.support.v7.widget.Toolbar

Android Studio Widget 更新更快