0

我正在尝试制作一个简单的小部件,该小部件在用户遇到问题的一组提示卡上缓慢旋转/迭代(类似于 windows phone live tile)。

我能够创建小部件,它显示了我设置为“未加载任何内容”之类的默认文本,并且我收到了回调,但小部件文本未更新。

我已经浏览了 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>

error_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"
/>

error_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>
4

1 回答 1

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);
    }
  }
}
于 2012-05-29T16:57:04.170 回答