Android小部件中的TextView不更新

6

我的小部件中的TextView在放置在主屏幕时正确设置了正确的信息。但是,当我在主应用程序中更新信息时,小部件仍然显示旧信息。

清单:

<receiver android:name=".WidgetProvider" android:label="@string/app_name" android:exported="false">
    <intent-filter>
        <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
    </intent-filter>

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

WidgetProvider.java:

package com.example.huskeliste;

import android.app.PendingIntent;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.Context;
import android.content.Intent;
import android.widget.RemoteViews;

public class WidgetProvider extends AppWidgetProvider {

    @Override
    public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
        final int N = appWidgetIds.length;

        for (int i = 0; i < N; i++) {
            int widgetId = appWidgetIds[i];

            DBAdapter info = new DBAdapter(context);

            info.open();
            String data = info.getTextViewData();
            info.close();

            Intent intent = new Intent(context, Main.class);
            PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);

            RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget);
            views.setOnClickPendingIntent(R.id.loWidget, pendingIntent);
            views.setTextViewText(R.id.txtView, data);
            appWidgetManager.updateAppWidget(widgetId, views);
        }
    }
}

res-widget.xml:

<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
    android:initialLayout="@layout/widget"
    android:minWidth="294dp"
    android:minHeight="72dp"
    android:updatePeriodMillis="1800000">
</appwidget-provider>

布局 - widget.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/loWidget"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" 
    android:gravity="center"
    android:layout_margin="1dp"
    android:background="@drawable/background">

    <TextView
        android:id="@+id/txtView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="22dp"
        android:textColor="#ffffff"
        android:text="" />
</LinearLayout>

background.xml:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <gradient android:startColor="#CC111111" android:endColor="#CC111111" android:angle="0" />
    <padding android:left="4dp" android:top="1dp" android:right="4dp" android:bottom="1dp" />
    <corners android:radius="3dp" />
</shape>

从DBAdapter.java获取getTextViewData():
public String getTextViewData() {
    String[] columns = new String[] { KEY_NAME };
    Cursor c = ourDatabase.query(DATABASE_TABLE, columns, null, null, null, null, null);

    String result = "";

    for (c.moveToFirst(); !c.isAfterLast(); c.moveToNext()) {           
        if (result.length() > 0) {
            result += ", ";
        }

        result += c.getString(0);
    }

    return result;
}

有人知道我的代码缺少什么吗?

2个回答

5
你需要在Widget提供者的XML中设置以毫秒为单位的更新间隔。示例代码如下:Example code
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
    android:minWidth="294dp"
    android:minHeight="72dp"
    android:updatePeriodMillis="86400000"
    android:previewImage="@drawable/preview"
    android:initialLayout="@layout/example_appwidget"
    android:configure="com.example.android.ExampleAppWidgetConfigure" 
    android:resizeMode="horizontal|vertical"
    android:widgetCategory="home_screen|keyguard"
    android:initialKeyguardLayout="@layout/example_keyguard">
</appwidget-provider>

然而,您应该知道系统不能保证小部件经常更新。此外,如果您希望小部件更频繁地更新(例如,在配置更改后,就像您的问题一样),您需要手动更新。以下是我的操作步骤:

在此示例中,我的Widget类仅称为Widget.class:

public class Widget extends AppWidgetProvider {

    // TODO: Don't forget to override the onUpdate method also

    @Override
    public void onReceive(Context context, Intent intent) {
        if (intent.getAction().equals("update_widget")) {
            // Manual or automatic widget update started

            RemoteViews remoteViews = new RemoteViews(context.getPackageName(),
                    R.layout.widget);

            // Update text, images, whatever - here
            remoteViews.setTextViewText(R.id.yourTextID, "My updated text");

            // Trigger widget layout update
            AppWidgetManager.getInstance(context).updateAppWidget(
                    new ComponentName(context, Widget.class), remoteViews);
        }
    }

}

请确保将布局和TextView替换为对您的小部件布局的引用。

然后,每当您想要更新您的小部件(例如在主活动的onPause方法中或每当单击保存按钮时),您都可以调用一个PendingIntent

Intent updateWidget = new Intent(context, Widget.class); // Widget.class is your widget class
updateWidget.setAction("update_widget");
PendingIntent pending = PendingIntent.getBroadcast(context, 0, updateWidget, PendingIntent.FLAG_CANCEL_CURRENT);
pending.send();

谢谢您的快速回复。在Main.java中,Intent updateWidget = new Intent(context, WidgetProvider.class); 中的"context"为空。我应该将context设置为什么? - user1759708
1
那是您的Activity上下文。您可以在那里使用getBaseContext()this - Dzhuneyt
在我添加了onReceiver之后,更新似乎不起作用了。当我添加小部件或重新启动设备后,它不会更新。有什么建议可以解决这个问题吗? - user1759708
谢谢,但我不认为这是我的问题。第一段代码在添加小部件并重新启动设备/手机时更新小部件。但是没有更改。当我添加了你的代码后,它会在更改时更新,但现在它不会在添加或重新启动设备/手机时更新。我不确定如何将代码粘贴为注释,但是onUpdate中的代码与onReceive中的代码基本相同。但使用其他变量名称。 - user1759708
在onReceiver中使用"super.onReceive(context, intent);"修复了它 :) - user1759708
显示剩余3条评论

0

供日后参考:

如果您想要更新小部件上的数据,请调用

appWidgetManager.updateAppWidgetOptions(appWidgetId,newOps);

在您的配置活动中调用AppWidgetManager。 并且在您的AppWidgetProvider类中重写onAppWidgetOptionsChanged方法以获取newOptions并运行逻辑。

完整答案请参见link


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接