Question

I have an image url I parse form json that I want to load into an android widget onto the homescreen. Right now I am trying to do it this way but its wrong:

ImageDownloadTask imageD = new ImageDownloadTask(image);
            views.setImageViewBitmap(R.id.image, imageD.execute(image));

image is a string holding a url to an image that needs to be downloaded and I am trying to set it to R.id.image

I found another stack question and tried this as a result:

views.setBitmap(R.id.image, "setImageBitmap",BitmapFactory.decodeStream(new URL(image).openStream()));

And when I use that nothing in the app loads at all, none of the text views get set.

My third try was this:

 //get beer data
            JSONObject o = new JSONObject(result);
            String name = getName(o);
            String image = getImage(o);
            String abv = getABV(o);
            String ibu = getIBU(o);
            String glass = getGlass(o);
            String beerBreweryName = getBreweryName(o);
            String beerBreweryStyle = getBreweryStyle(o);
            String beerDescription = getDescription(o);

            InputStream in = new java.net.URL(image).openStream();
            Bitmap bitmap = BitmapFactory.decodeStream(in);



            views.setTextViewText(R.id.beerTitle, name);
            views.setTextViewText(R.id.beerBreweryName, beerBreweryName);
            views.setTextViewText(R.id.beerStyleName, beerBreweryStyle);
            views.setImageViewBitmap(R.id.image, bitmap);

This gave the same result as the last attempt, it would not even set any text views....

Just tried another attempt after one of the answers posted below:

RemoteViews views = new RemoteViews(c.getPackageName(), R.layout.widget_test);

            //get beer data
            JSONObject o = new JSONObject(result);
            String name = getName(o);
            String imageURL = getImage(o);
            String abv = getABV(o);
            String ibu = getIBU(o);
            String glass = getGlass(o);
            String beerBreweryName = getBreweryName(o);
            String beerBreweryStyle = getBreweryStyle(o);
            String beerDescription = getDescription(o);

            Log.d("widgetImage" , imageURL);
            views.setImageViewUri(R.id.image, Uri.parse(imageURL));

            views.setTextViewText(R.id.beerTitle, name);
            views.setTextViewText(R.id.beerBreweryName, beerBreweryName);
            views.setTextViewText(R.id.beerStyleName, beerBreweryStyle);




            mgr.updateAppWidget(appWidgetIds, views);

This attempt lets all the text views load, but no image ever shows up.

Was it helpful?

Solution 2

Got a lot of help from multiple sources for this question. The big problem for me why a bunch of the attempts I tried listed above seemed to lock the widget app and not load anything is because I can not download the image and set it in a UI thread.

To accomplish this I had to move everything to the do in background of my async task and not in the onPostExecute.

OTHER TIPS

The way to do this reliably is to use setImageViewURI on the remote ImageView. The trick is that the URI you give it is a content:// URI which then points back to a content provider that you export from your application. In your content provider you can do anything you need to do to supply the image bytes.

For example, in your manifest:

<provider android:name=".ImageContentProvider" android:authorities="com.example.test" android:exported="true" />

And your provider:

public class ImageContentProvider extends ContentProvider {

    // (Removed overrides that do nothing) 

    @Override
    public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException {
        List<String> segs = uri.getPathSegments();

        // Download the image content here, get the info you need from segs

        return ParcelFileDescriptor.open(new File(path), ParcelFileDescriptor.MODE_READ_ONLY);
    }
}

And then your URL is something like:

content://com.example.test/something-you-can-define/here

This is necessary because your remote image view is not running in your process. You are much more limited in what you can do because everything must be serialized across the process boundary. The URI can serialize just fine but if you try to send a megabyte of image data with setImageViewBitmap, it's probably going to fail (depending on available device memory).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top