Reputation: 562
I've got a widget with an ImageView
, whose source I'm setting with a URI to an image on the user's device. I set it with RemoteViews.setImageViewUri()
in the onUpdate
of the widget's provider. The strangest thing is happening: I can't see the widget or the image while the widget is stationary on my home screen, but when I pick it up and start moving it, the image appears!
Here are some screen shots illustrating this:
Here's the layout for the widget:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/picture_widget_parent"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="@dimen/widget_margin" >
<ImageView
android:id="@+id/the_picture"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:contentDescription="@string/image_content_description"
android:scaleType="centerCrop" />
</RelativeLayout>
And here's my AppWidgetProvider:
public class WidgetProvider extends AppWidgetProvider {
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
super.onUpdate(context, appWidgetManager, appWidgetIds);
updateAllWidgets(context, appWidgetManager, appWidgetIds);
}
private void updateAllWidgets(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
PuppyFramePersistenceManager persistenceManager = new PuppyFramePersistenceManager(context);
for(int i = 0; i < appWidgetIds.length; i++) {
int appWidgetId = appWidgetIds[i];
RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.puppyframe_widget);
Intent configIntent = new Intent(context, AlbumsActivity.class);
Uri.withAppendedPath(Uri.parse("pw" + i + "://widget/id/"), String.valueOf(appWidgetId));
configIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
PendingIntent configPendingIntent = PendingIntent.getActivity(context, 0, configIntent, 0);
remoteViews.setOnClickPendingIntent(R.id.picture_widget_parent, configPendingIntent);
String currentAlbumId = persistenceManager.getCurrentAlbumIdForAppWidgetId(appWidgetId);
if(currentAlbumId != null) {
Uri imageUri = Uri.parse(persistenceManager.getAlbumWithId(currentAlbumId).getImagePaths().get(0));
remoteViews.setImageViewUri(R.id.the_picture, imageUri);
}
appWidgetManager.updateAppWidget(appWidgetId, remoteViews);
}
}
}
This is my AndroidManifest.xml:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.boztalay.puppyframe"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="14"
android:targetSdkVersion="17" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity android:name="com.boztalay.puppyframe.configuration.albums.AlbumsActivity" >
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_CONFIGURE" />
</intent-filter>
</activity>
<activity android:name="com.boztalay.puppyframe.configuration.editalbum.EditAlbumActivity" />
<receiver android:name="com.boztalay.puppyframe.widget.PuppyFrameWidgetProvider" >
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="@xml/puppyframe_info" />
</receiver>
<service android:name="com.boztalay.puppyframe.widget.ScreenOnService"></service>
</application>
</manifest>
And lastly, this is my widget provider info:
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:minWidth="40dp"
android:minHeight="40dp"
android:minResizeWidth="40dp"
android:minResizeHeight="40dp"
android:updatePeriodMillis="21600000"
android:initialLayout="@layout/puppyframe_widget"
android:configure="com.boztalay.puppyframe.configuration.albums.AlbumsActivity"
android:resizeMode="horizontal|vertical"
android:widgetCategory="home_screen">
</appwidget-provider>
Thanks!
Upvotes: 1
Views: 1411
Reputation: 562
The issue ultimately has to do with the size of the images. With the very large images that the phone's camera takes, it would cause this bug. But with smaller ones on the phone, they appeared just fine. What I had to do was actually resize and cache the images that are too big, which I deemed to be 75% of the phone's screen's resolution.
Upvotes: 0
Reputation: 15290
The way the AppWidgetManager
interacts with your AppWidgetProvider
is not as documented. The documentation claims that if you have a configure activity, onUpdate
is not called.
In fact, onUpdate
is called before the configure activity starts. It's not called when the activity finishes. Looking at your onUpdate
, it appears that if the appwidget isn't configured yet, it leaves the ImageView
blank. Even without seeing your configure activity, I guess that what's going on is this:
AppWidgetManager
creates the new widget and calls onUpdate
. Because the new widget is not yet configured, you don't set the ImageView
to an image.RESULT_OK
. The widget is now configured, but hasn't been updated again, so the ImageView
is still blank.AppWidgetManager
calls onUpdate
again. This time, your code reads the widget configuration and sets the ImageView
. Now the widget shows the chosen image.The answer is that when your configure activity finishes, it should send an intent to your AppWidgetProvider
to have it update again. This isn't a panacea, though, as there are other bugs in AppWidgetProvider
. For example, if you do an orientation change while the configure activity is running, restarting it, the AppWidgetProvider
hides the appwidget from the screen, even after you finish and return RESULT_OK
. Changing the orientation again while the launcher is showing (after the configure activity has finished) makes the appwidget appear.
The reason I know all this is that I've had the same problems writing a similar app, which may be helpful to you if you're struggling with this functionality. Showr displays images on the home screen or lock screen. The images can be chosen from other apps on the device (such as the Gallery), downloaded from a URL, or updated from an RSS or Atom feed. It even scales the images to an appropriate size and can crop them to fit the appwidget. It's a free download from Google Play.
Upvotes: 1