Android notifyappwidgetviewdatachanged无法处理我的小部件上的listview

Android notifyappwidgetviewdatachanged无法处理我的小部件上的listview,android,listview,widget,android-appwidget,Android,Listview,Widget,Android Appwidget,我尝试了很多解决方案,但几周后我一直无法解决这个问题:为什么“notifyappwidgetviewdatachanged”不起作用?如何更新放置在小部件上的listview?我错在哪里 这是我的课 小部件提供商: public class Widget_Provider extends AppWidgetProvider { public static final String ACTION_MOSTRAORARI = "fACTION_TOAST"; public static final

我尝试了很多解决方案,但几周后我一直无法解决这个问题:为什么“notifyappwidgetviewdatachanged”不起作用?如何更新放置在小部件上的listview?我错在哪里

这是我的课

小部件提供商:

public class Widget_Provider extends AppWidgetProvider
{
public static final String ACTION_MOSTRAORARI = "fACTION_TOAST";
public static final String EXTRA_STRING = "EXTRA_STRING";

@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
    // There may be multiple widgets active, so update all of them
    for (int appWidgetId : appWidgetIds)
    {
        RemoteViews views = updateWidgetListView(context, appWidgetId);

        final Intent onItemClick = new Intent(context, Widget_Provider.class);
        onItemClick.setAction(ACTION_MOSTRAORARI);
        onItemClick.setData(Uri.parse(onItemClick.toUri(Intent.URI_INTENT_SCHEME)));
        final PendingIntent onClickPendingIntent = PendingIntent.getBroadcast(context, 0, onItemClick, PendingIntent.FLAG_UPDATE_CURRENT);
        views.setPendingIntentTemplate(R.id.myStopList, onClickPendingIntent);

        appWidgetManager.updateAppWidget(appWidgetId, views);
    }
    super.onUpdate(context, appWidgetManager, appWidgetIds);
}

public RemoteViews updateWidgetListView(Context context, int appWidgetId)
{
    RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget);
    Intent svcIntent = new Intent(context, Widget_Service.class);
    svcIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
    svcIntent.setData(Uri.parse(svcIntent.toUri(Intent.URI_INTENT_SCHEME)));
    remoteViews.setRemoteAdapter(R.id.myStopList, svcIntent);
    return remoteViews;
}

@Override
public void onReceive(Context context, Intent intent)
{
    if (intent.getAction().equals(ACTION_MOSTRAORARI)) {

        if (MainUtils.isNewtworkAvailable(context)) 
        {
            String item = intent.getExtras().getString(EXTRA_STRING);
            Intent intentOrari = new Intent(context, Diag_MostraOrari.class);
            intentOrari.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
            context.startActivity(intentOrari);
        }
    }

    super.onReceive(context, intent);
}

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

@Override
public void onEnabled(Context context) {}

@Override
public void onDisabled(Context context) {}
}
小部件服务:

public class Widget_Service extends RemoteViewsService
{

@Override
public RemoteViewsFactory onGetViewFactory(Intent intent)
{
    Map<String, ArrayList<String>> map = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);

    /* ---
    * Here i fetch data from a local db and store it on "map"
    */ ---

    return (new Widget_ListProvider(this.getApplicationContext(), intent, map));
}

}

问题很明显:在RemoteViewsFactory中,有一个空方法
onDataSetChanged()
。但是当您触发notifyAppWidgetViewDataChanged()时,您将在
onDataSetChanged()
中得到回调。为了更好地理解,请查看此图片。

如果Diag_Line是一个配置活动,只需做如下操作:

 appWidgetManager.updateAppWidget(appWidgetIds, views); // views is a RemoteViews that you need to build
 appWidgetManager.notifyAppWidgetViewDataChanged(appWidgetIds, R.id.myStopList);
override fun onDataSetChanged() {
listOfArticles = newsDatabaseRepo.getSynchronouslySavedNews() as ArrayList<Articles>
还要检查官方文件

更新
给你一些提示。如果您使用的是小部件,请在后台远程查看所有获取数据和填充内容(IntentService是一种很好的方法)。所以,只需在这里创建IntentService并为小部件创建逻辑。如果你通过广播触发更新,别忘了让他成为前台(仅适用于Android O)。此外,您还可以检查是否为您设置了所有设置。

以便notifyAppWidgetViewDataChanged()正常工作

我们需要在RemoteViewSourceFactory的onDataSetChanged()方法中检索数据 像这样:

 appWidgetManager.updateAppWidget(appWidgetIds, views); // views is a RemoteViews that you need to build
 appWidgetManager.notifyAppWidgetViewDataChanged(appWidgetIds, R.id.myStopList);
override fun onDataSetChanged() {
listOfArticles = newsDatabaseRepo.getSynchronouslySavedNews() as ArrayList<Articles>
调用上述方法后,一旦我退出应用程序,我就能注意到我的小部件中的变化

因此,为了检查在notifyAppWidgetViewDataChanged()之后是否调用onDataSetChanged
我保留了一个调试点,调用了onDataSetChanged(),并按照此处的建议更新了列表

您在哪里尝试更新listview(如果您正在活动中更新,请发布一些代码)?我在onDataSetChanged方法中要写些什么?我做到了!我完全在RemoteViewsFactory中获取数据,然后在“onDataSetChanged”中再次获取数据,从而解决了这个问题。非常感谢你!我花了几个星期寻找这个问题的解决方案!再次感谢你,老兄@HeyAlex,这不会导致onDataSetChanged()被调用两次吗?我有一个网络呼叫,希望避免两次获取数据。
private fun refreshWidget() {
    val appWidgetManager =
        AppWidgetManager.getInstance(applicationContext)
    val thisAppWidget = ComponentName(
        applicationContext.packageName,
        MyAppWidgetProvider::class.java.name
    )
    val appWidgetIds = appWidgetManager.getAppWidgetIds(thisAppWidget)
    appWidgetManager.notifyAppWidgetViewDataChanged(appWidgetIds, R.id.stack_view)
}