【问题标题】:Changing a widget's icon from onUpdate从 onUpdate 更改小部件的图标
【发布时间】:2011-07-20 20:56:08
【问题描述】:

我有一个小部件,用于在每次收到更新广播时更改其图标。但是,小部件永远无法正确显示其图标,显示文本“问题加载小部件”。 Logcat 消息是:

WARN/AppWidgetHostView(612): updateAppWidget couldn't find any view, using error view
WARN/AppWidgetHostView(612): android.widget.RemoteViews$ActionException: can't find view: 0x7f060003

我的 onUpdate 的代码是:

public class ImageWidgetProvider extends AppWidgetProvider{
private  static final String TAG = "Steve";

public static final int[] IMAGES = { R.drawable.ic_launcher_alarmclock,
    /*and many more*/};

@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds){

    for (int appWidgetId : appWidgetIds) {
        Log.d(TAG, "onUpdate:");
        int imageNum = (new java.util.Random().nextInt(IMAGES.length));
        Log.d(TAG, Integer.toString(IMAGES[imageNum]));
        RemoteViews remoteView = new RemoteViews(context.getPackageName(), R.layout.widget);
        remoteView.setImageViewResource(R.id.image_in_widget, IMAGES[imageNum]);
        appWidgetManager.updateAppWidget(appWidgetId, remoteView);
    }

}
}

现在,当我将鼠标悬停在“R.id.image_in_widget”上时,它会显示其值等于 0x7f060003 - 根据 Logcat 无法找到的视图。使用第二条 Log 语句,我验证了 IMAGES[imageNum] 确实引用了 IMAGES 数组中的随机图像。 (如果它很重要,它会以十进制值而不是十六进制值的形式出现。)任何想法我做错了什么?非常感谢!

--

编辑:这是小部件的布局文件,其中声明了 image_in_widget ImageView。

<?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">

<ImageView android:name="@+id/image_in_widget"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"/>
</LinearLayout>

【问题讨论】:

  • 真的很奇怪。看来你做的一切都是对的。您在布局文件中使用允许的 UI 组件,它应该可以正常工作。这个“问题加载小部件”会在您将小部件放在屏幕上后立即显示,对吗?我真的不知道是什么原因......对不起。也许尝试在 1.6 模拟器上运行您的小部件?
  • 是的,“问题加载小部件”立即显示。在 v1.6 模拟器中相同。感谢您的尝试 - 我很高兴看到不只是我认为这很奇怪 :)

标签: android android-widget


【解决方案1】:

发生这种情况的另一个原因(对于那些在网上搜索这个问题的人,比原始海报更多):

如果您有单独的横向和纵向布局,则这两个布局都必须包含您在更新期间引用的任何视图。如果您引用仅在一种模式下出现的视图,例如纵向视图,那么在横向视图中,您将在小部件框中收到“问题加载小部件”消息。

简单的解决方案是在您不希望这些视图出现的模式下将可见性设置为“GONE”。

【讨论】:

  • Bam,这解决了一些可能需要几个小时才能弄清楚的问题。感谢您的提示。
  • 我刚刚用 api 10 进行了这个测试,原因是这样的。我正在为未出现在所有布局中的视图设置属性。在以后的 api 版本中,这似乎不再是问题(这些调用被忽略了)。
【解决方案2】:

Android 1.5 存在不为小部件调用 OnDelete 的问题。

将此代码放入您的 AppWidgetProvider 中,它应该可以解决问题

public void onReceive(Context context, Intent intent) {
    // v1.5 fix that doesn't call onDelete Action
    final String action = intent.getAction();
    if (AppWidgetManager.ACTION_APPWIDGET_DELETED.equals(action)) {
        final int appWidgetId = intent.getExtras().getInt(
                AppWidgetManager.EXTRA_APPWIDGET_ID,
                AppWidgetManager.INVALID_APPWIDGET_ID);
        if (appWidgetId != AppWidgetManager.INVALID_APPWIDGET_ID) {
            this.onDeleted(context, new int[] { appWidgetId });
        }
    } else {
        super.onReceive(context, intent);
    }
}

【讨论】:

  • 谢谢。我之前看到过这个错误,但认为它不相关,但在这个编程之旅中,我的直觉多次被证明是错误的......一旦我回到这个项目,我会试一试。
【解决方案3】:

也许它不适用于您的示例,但我也遇到了与应用程序小部件类似的问题。在 android 1.5 中,主屏幕小部件存在一个烦人的问题。在特定情况下,应用程序小部件在内存中仍处于活动状态,但不再可见。
您正在通过 appWidgetIds 进行枚举,请检查此数组是否包含您期望的 id 数量。只需放置另一个 Log.d() 来记录 ID。也许您也有一些“幽灵”小部件。
你用的是什么安卓版本?

【讨论】:

  • 有趣...我确实在为 Android v1.5 编程。这让我在 Logcat 中看到的一些奇怪的事情变得有意义 - 调试来自我已删除的另一个小部件的行。我刚刚尝试添加更多调试行,它从 37 开始计数(即使我在主屏幕上没有那么多小部件),但正确的数组只有 1 个条目。这告诉我们什么?对我来说,这似乎意味着这不是问题的根源,但请让我知道您的想法。
  • 确实,这不是您的问题的根源。但是您的代码似乎没问题,您能否提供一些附加信息: 1. 如何更新您的小部件(手动或通过 appwidget-provider 文件中的 android:updatePeriodMillis 更新)? 2. 我假设您的小部件布局文件包含 ID 为 image_in_widget 的 ImageView,对吗? 3. appwidget-provider中是否设置了初始布局?
  • 1.我尝试通过广播意图的配置活动来更新它,更简单地使用 xml 文件中的 android:updatePeriodMillis 行。 2. 确实如此。据我所知,该 id 已被正确识别,因为它在 R.java 文件中被赋予了一个值。 3. 不,我没有在其他任何地方设置初始布局。我会尝试这样做,看看会发生什么。
  • 实际上,到目前为止,我阅读的所有示例似乎都没有声明初始布局,因此除非您认为我应该声明,否则我将保留代码原样。顺便说一句,我在上面的主帖中添加了小部件的 xml 布局。再次感谢您迄今为止的帮助!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-02
  • 1970-01-01
  • 2017-06-27
相关资源
最近更新 更多