更新窗口小部件列表视图

时间:2016-04-23 03:01:35

标签: android listview android-widget

在我的小部件中,我有一个刷新按钮,用于告诉(自定义)列表视图数据集已更改。现在,我点击刷新按钮时调用了onRecieve回调,但传递的意图包是null,所以我不能在ID上调用onUpdate。

我检查了添加额外内容的函数,它说它添加的整数数组长度为1且非null,我不知道为什么这不起作用:/希望有人在这里可以帮我一把

感谢。

WidgetProvider.java

public class WidgetProvider extends AppWidgetProvider {

    @Override
    public void onDeleted(Context context, int[] appWidgetIds)
    {
        super.onDeleted(context, appWidgetIds);
    }

    @Override
    public void onDisabled(Context context)
    {
        super.onDisabled(context);
    }

    @Override
    public void onEnabled(Context context)
    {
        super.onEnabled(context);
    }

    @Override
    public void onReceive(Context context, Intent intent)
    {
        System.out.println("RECIEVED SOMETHING:" + intent.getAction());
        AppWidgetManager appWidgetMgr = AppWidgetManager.getInstance(context);

        Bundle extras = intent.getExtras();
        int[] ids = extras.getIntArray(AppWidgetManager.EXTRA_APPWIDGET_IDS); //NPE ON THIS LINE, EXTRAS IS NULL

        System.out.println("SENDING AN UPDATE");
        onUpdate(context, appWidgetMgr, ids);

        super.onReceive(context, intent);
    }

    protected PendingIntent getPendingSelfIntent(Context context, String action, int[] ids) {
        Intent intent = new Intent(context, getClass());
        intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, ids);
        System.out.println("PUTTING ARRAY OF LEN: " + ids.length);
        intent.setAction(action);
        return PendingIntent.getBroadcast(context, 0, intent, 0);
    }

    @Override
    public void onUpdate(Context context, AppWidgetManager appWidgetManager,
                         int[] appWidgetIds)
    {
        for(int i=0;i<appWidgetIds.length;i++)
        {
            System.out.println("CHECK");
            RemoteViews rv = new RemoteViews(context.getPackageName(),
                    R.layout.app_widget);

            Intent intent = new Intent(context, WidgetService.class);
            intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID,
                    appWidgetIds[i]);
            intent.setData(Uri.parse(intent.toUri(Intent.URI_INTENT_SCHEME)));

            rv.setRemoteAdapter(R.id.list, intent);

            rv.setOnClickPendingIntent(R.id.refresh, getPendingSelfIntent(context,
                    "refresh", appWidgetIds));

            appWidgetManager.updateAppWidget(appWidgetIds[i], rv);
        }
        super.onUpdate(context, appWidgetManager, appWidgetIds);
    }
}

编辑:新的onRecieve功能,同样的错误:

    @Override
    public void onReceive(Context context, Intent intent)
    {
        if("refresh".equals(intent.getAction())) {
            System.out.println("RECIEVED SOMETHING:" + intent.getAction());
            AppWidgetManager appWidgetMgr = AppWidgetManager.getInstance(context);

            Bundle extras = intent.getExtras();

            int[] ids = extras.getIntArray(AppWidgetManager.EXTRA_APPWIDGET_IDS);

            System.out.println("SENDING AN UPDATE");
            onUpdate(context, appWidgetMgr, ids);
        }

        super.onReceive(context, intent);
    }

1 个答案:

答案 0 :(得分:1)

如果查看source for AppWidgetProvider,则会为每个标准小部件操作首先调用onReceive(),而不仅仅是您的自定义代码。您应该将代码包装在if检查中,以确保它是您按下的按钮。

// In onReceive()
if ("refresh".equals(intent.getAction())) {
  // Do your code
}

您还会在PendingIntent documentation

中注明
  

由于这种行为,为了检索PendingIntent,重要的是要知道两个Intent何时被认为是相同的。人们常犯的一个错误是使用Intents创建多个PendingIntent对象,这些对象只在其“额外”内容中有所不同,期望每次都获得不同的PendingIntent。这不会发生。用于匹配的Intent部分与Intent.filterEquals定义的部分相同。如果你使用两个与Intent.filterEquals相同的Intent对象,那么你将获得两个相同的PendingIntent。

     

...

     

如果您一次只需要一个PendingIntent激活您将使用的任何Intent,那么您也可以使用标志FLAG_CANCEL_CURRENT或FLAG_UPDATE_CURRENT来取消或修改与您提供的Intent关联的当前PendingIntent。< / p>

因此,您还应将PendingIntent.getBroadcast()的通话更新为

return PendingIntent.getBroadcast(context, 0, intent,
  PendingIntent.FLAG_UPDATE_CURRENT);

当然,另一种方法是只需拨打AppWidgetManager#getAppWidgetIds()并轻松设置任何额外内容。