views:

959

answers:

4

Hi,

I have a widget that is meant to change its icon every time it receives the Update broadcast. However, the widget never manages to display its icon properly, displaying the text "Problem loading widget". The Logcat message is:

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

The code for my onUpdate is:

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);
    }

}
}

Now when I hover the mouse over "R.id.image_in_widget" it brings up that its value is equal to 0x7f060003 - the view that it can't find according to Logcat. Using the second Log statement, I verified that IMAGES[imageNum] does indeed refer to a random image from the IMAGES array. (In case it matters, it comes out as a decimal value rather than a hexadecimal one.) Any ideas what I'm doing wrong? Thanks a lot!

--

Edit: Here is the layout file for the widget, where the image_in_widget ImageView is declared.

<?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>
A: 

Hi!
Maybe it doesn't apply in your example, but I also had similiar problems with application widget. In android 1.5 there was an annoying issue with home screen widgets. In particular case applications widgets were still active in memory, but no longer visible.
You are enumerating through appWidgetIds, please check if this array contains exactly the number of ids that you expect. Just put another Log.d() to log the ids. Maybe you also have some "ghost" widgets.
What android version do you use?

Ramps
Interesting... I am indeed programming for Android v1.5. That makes sense of some of the odd things I was seeing in Logcat - debugging lines from another widget which I had deleted.I've just tried adding in more debugging lines and it is starting counting from 37 (even though I don't have that many widgets on the home screen), but the array correctly only has 1 entry. What does this tell us? To me, it seems like it means it's not the source of the problem, but please let me know what you think.
Steve H
Indeed, it's not the source of the problem in your case. But your code seems ok, so could you provide some additional info:1. How do you update your widget (manually or by android:updatePeriodMillis in your appwidget-provider file)?2. I assume your layout file for widget contains ImageView with id image_in_widget, right?3. do you set an initial layout in appwidget-provider?
Ramps
1. I've tried updating it via a configuration activity which broadcasts an intent, and more simply using the android:updatePeriodMillis line in the xml file.2. Indeed, it does. The id is properly recognised, as far as I can tell, as it's given a value in the R.java file.3. No, I haven't set an initial layout anywhere else. I'll try doing that to see what happens.
Steve H
Actually, all of the examples I've read so far don't seem to declare an initial layout so unless you think I should, I'll leave the code as it is. By the way, I've added in the widget's xml layout in the main post above.Thanks again for your help so far!
Steve H
+1  A: 

Android 1.5 has a problem not calling OnDelete for Widgets.

Put this code in your AppWidgetProvider and it should fix the problem

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);
    }
}
Tom
Thanks. I had seen that bug before but assumed it wasn't related, but my intuition has been shown to be wrong several times in this programming journey... Once I return to this project, I'll give it a go.
Steve H
A: 

(Question closed - I stopped working on this project a long time ago)

Steve H
A: 

Another reason this can happen (for those searching the web on this issue, moreso than the original poster):

If you have separate layouts for landscape vs. portrait, the two layouts both have to contain any views you reference during your update. If you reference a view that is only present in one mode, say portrait, then in landscape you'll get the "Problem Loading Widget" message in your widget box.

The simple solution is to set the visibility to "GONE" in the mode where you don't want those views to appear.

Kris Giesing