为什么我的小部件没有更新?

时间:2012-05-28 18:13:22

标签: android android-widget

我正在尝试制作一个简单的小部件,它缓慢地旋转/迭代一组用户遇到麻烦的提示卡(类似于Windows手机实时磁贴)。

我能够创建窗口小部件并显示默认文本,我设置为说“Nothing loaded”,我收到回调,但窗口小部件文本没有更新。

我已经浏览了android文档以及堆栈溢出但无法找到答案。我想也许我的ComponentName不正确,所以我只是在我的小部件管理器中获取小部件数组并迭代它们。它 获取小部件列表,这看起来是正确的......

我做错了什么?

非常感谢, 猪

public class MistakeArchiveWidgetProvider extends AppWidgetProvider 
{
  @Override
  public void onUpdate(Context context, AppWidgetManager appWidgetManager,
      int[] appWidgetIds)
  {
    Timer timer = new Timer();
    timer.scheduleAtFixedRate(new MyTime(context, appWidgetManager), 1, 60000);

    // When the widget is clicked, launch the app.
    for (int i = 0; i < appWidgetIds.length; i++) 
    {
        int appWidgetId = appWidgetIds[i];

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

        // Get the layout for the App Widget and attach an on-click listener
        // to the button
        RemoteViews views = new RemoteViews(context.getPackageName(),
            R.layout.mistake_archive_widget);
        views.setOnClickPendingIntent(R.id.STATIC_CUE, pendingIntent);
        views.setOnClickPendingIntent(R.id.STATIC_ANSWER, pendingIntent);

        // Tell the AppWidgetManager to perform an update on the current app widget
        appWidgetManager.updateAppWidget(appWidgetId, views);
    }
  }

  private class MyTime extends TimerTask
  {
    public MyTime(Context context, AppWidgetManager appWidgetManager)
    {
      this.m_appWidgetManager = appWidgetManager;
      m_remoteViews = new RemoteViews(context.getPackageName(), 
          R.layout.mistake_archive_widget);

      m_componentName = new ComponentName(context, MistakeArchiveWidgetProvider.class);
      m_context = context;
    }

    @Override
    public void run()
    {
      MistakeArchive archive = new MistakeArchive();
      if(archive.restoreState(m_context))
      {
        SharedPreferences prefs = 
            PreferenceManager.getDefaultSharedPreferences(m_context);

        int activeIndex = prefs.getInt(
            MyPrefs.PREFKEY_ACTIVE_MISTAKE_ARCHIVE_HASH_INDEX, 0);

        activeIndex++;
        SharedPreferences.Editor editor = prefs.edit();
        editor.putInt(MyPrefs.PREFKEY_ACTIVE_MISTAKE_ARCHIVE_HASH_INDEX, 
            activeIndex);
        editor.commit();

        CueLine cueLine = archive.getMistake(activeIndex);
        if(cueLine != null)
        {
          m_remoteViews.setTextViewText(R.id.STATIC_CUE, cueLine.GetCue());
          m_remoteViews.setViewVisibility(R.id.STATIC_CUE, View.VISIBLE);
          m_remoteViews.setTextViewText(R.id.STATIC_ANSWER, cueLine.GetAnswer());

          int[] appWidgetIds = m_appWidgetManager.getAppWidgetIds(m_componentName);
          for (int i = 0; i < appWidgetIds.length; i++) 
          {
            m_appWidgetManager.updateAppWidget(i, m_remoteViews);
          }
        }
      }
    }

    RemoteViews m_remoteViews;
    AppWidgetManager m_appWidgetManager;
    ComponentName m_componentName;
    Context m_context;
  }
}

在我的清单xml中我有:

 <receiver android:name="myApp.MistakeArchiveWidgetProvider" android:label="@string/IDST_APP_NAME">
   <intent-filter>
      <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
   </intent-filter>
   <meta-data android:name="android.appwidget.provider"
            android:resource="@xml/mistake_archive_widget_provider" />
 </receiver>

mistake_archive_widget_provider.xml:

<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
   android:minWidth="50dip"
   android:minHeight="50dip"
   android:updatePeriodMillis="10000"
   android:initialLayout="@layout/mistake_archive_widget"
/>

mistake_archive_widget.xml:

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" 
    android:orientation="vertical"
    android:background="@drawable/widget_background"
    >

        <TextView
            android:id="@+id/STATIC_CUE"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:gravity="center"
            android:layout_weight="1"
            android:textStyle="bold"
            android:visibility="gone" 
            android:text=""
            />

        <TextView android:id="@+id/STATIC_ANSWER"
                  android:layout_width="fill_parent"
                  android:layout_height="fill_parent"
                  android:gravity="center"
                  android:layout_weight="1"
                  android:text="@string/IDST_NO_CUES_LOADED"
                  />

</LinearLayout>

1 个答案:

答案 0 :(得分:0)

好的我明白了:不要使用TimerTask。这不能按预期工作。我很确定我正在跟踪一个告诉我这样做的地方的例子,但第二个想法,它看起来有缺陷。

我更改了所有内容,以便在onUpdate()中完成,并删除所有计时器内容。 Android会以每30分钟一次的最高速率调用此功能。

现在也很简单:)

解决方案:

public class MistakeArchiveWidgetProvider extends AppWidgetProvider 
{
  @Override
  public void onUpdate(Context context, AppWidgetManager appWidgetManager,
      int[] appWidgetIds)
  {
    // When the widget is clicked, launch the app.
    for (int widgetIndex = 0; widgetIndex < appWidgetIds.length; widgetIndex++) 
    {
      int appWidgetId = appWidgetIds[widgetIndex];

      RemoteViews views = new RemoteViews(context.getPackageName(),
          R.layout.mistake_archive_widget);

      // Get the layout for the App Widget and attach an on-click listener.
      {
        Intent intent = new Intent(context, QuizActivity.class);
        PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);

        views.setOnClickPendingIntent(R.id.STATIC_CUE, pendingIntent);
        views.setOnClickPendingIntent(R.id.STATIC_ANSWER, pendingIntent);
      }

      views.setTextViewText(R.id.STATIC_CUE, cueString);
      views.setTextViewText(R.id.STATIC_ANSWER, cueAnswer);

      // Tell the AppWidgetManager to perform an update on the current app widget
      appWidgetManager.updateAppWidget(appWidgetId, views);
    }
  }
}