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>

背景.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;
}

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

4

1 回答 1

5

您需要在 Widget 提供程序 XML 中设置更新间隔(以毫秒为单位)。示例代码

<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();
于 2012-11-20T09:29:06.730 回答