0

I have a method where a Url is queried from my database and sent as an extra before opening the activity where you can zoom, pan, etc.

topLevelMessageImage.setOnClickListener(v -> {

                    ParseQuery<ParseObject> imageQuery = new ParseQuery<>(ParseConstants.CLASS_YEET);
                    imageQuery.whereEqualTo(ParseConstants.KEY_OBJECT_ID, topLevelCommentObject.getObjectId());
                    imageQuery.findInBackground((user, e2) -> {
                        if (e2 == null) for (ParseObject userObject : user) {

                            if (userObject.getParseFile("image") != null) {
                                String imageURL = userObject.getParseFile("image").getUrl();
                                Log.w(getClass().toString(), imageURL);

                                // Asynchronously display the message image downloaded from Parse
                                if (imageURL != null) {

                                    Intent intent = new Intent(getApplicationContext(), MediaPreviewActivity.class);
                                    intent.putExtra("imageUrl", imageURL);
                                    this.startActivity(intent);

                                }

                            }
                        }
                    });
                });

When the activity starts, I get the following exception:

10-01 20:46:08.202 16149-16460/com.yitter.android E/SubsamplingScaleImageView: Failed to initialise bitmap decoder


java.io.FileNotFoundException: No content provider: https://parsefiles.back4app.com/GDprTC66bNMp3mXWNvWJbZhWwjedoucvp6NlNKVl/03a8e1618392395811c9830333c0443f_6cf1e0ef-47af-4ddc-88cc-196debd77a9a.jpeg
                                                                                   at android.content.ContentResolver.openTypedAssetFileDescriptor(ContentResolver.java:1090)
                                                                                   at android.content.ContentResolver.openAssetFileDescriptor(ContentResolver.java:942)
                                                                                   at android.content.ContentResolver.openInputStream(ContentResolver.java:662)
                                                                                   at com.davemorrissey.labs.subscaleview.decoder.SkiaImageRegionDecoder.init(SkiaImageRegionDecoder.java:67)
                                                                                   at com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView$TilesInitTask.doInBackground(SubsamplingScaleImageView.java:1415)
                                                                                   at com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView$TilesInitTask.doInBackground(SubsamplingScaleImageView.java:1391)
                                                                                   at android.os.AsyncTask$2.call(AsyncTask.java:295)
                                                                                   at java.util.concurrent.FutureTask.run(FutureTask.java:237)
                                                                                   at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234)
                                                                                   at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
                                                                                   at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
                                                                                   at java.lang.Thread.run(Thread.java:818)

I suppose I can't just feed the SubsamplingScaleImageView a Url eh? I guess I can't use Picasso either? What should I do instead?

private void locateImageView() {

Bundle bundle = getIntent().getExtras();
if (bundle != null) {
    if (bundle.getString("imageUrl") != null) {
        String imageUrl = bundle.getString("imageUrl");
        Log.w(getClass().toString(), imageUrl);

        imageView = (SubsamplingScaleImageView) findViewById(R.id.image);

        URL url = new URL(imageUrl);
        URI uri = url.toURI();

        imageView.setImage(ImageSource.uri(String.valueOf(uri)));

        /*Picasso.with(getApplicationContext())
                .load(imageUrl)
                .placeholder(R.color.placeholderblue)
                .memoryPolicy(MemoryPolicy.NO_CACHE).into(((SubsamplingScaleImageView) findViewById(R.id.image)));*/
    }
}

I tried this and it worked...

try {
                    URL url = new URL(imageUrl);
                    HttpURLConnection connection = (HttpURLConnection) url.openConnection();
                    connection.setDoInput(true);
                    connection.connect();
                    InputStream input = connection.getInputStream();
                    Bitmap myBitmap = BitmapFactory.decodeStream(input);

                    imageView.setImage(ImageSource.bitmap(myBitmap);

                } catch (IOException e) {
                    // Log exception
                    Log.w(getClass().toString(), e);
                }
Martin Erlic
  • 5,467
  • 22
  • 81
  • 153

1 Answers1

1

I suppose I can't just feed the SubsamplingScaleImageView a Url eh?

It cannot handle http/https URLs, if that is what you mean.

I guess I can't use Picasso either?

Not really. Its role is to load a full bitmap, which is not what you want.

What should I do instead?

Download the image yourself, using your favorite HTTP client API (HttpUrlConnection, OkHttp, etc.) to a file. Then, load the file into the SubsamplingScaleImageView.

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • Fair enough. Can you explain the last bit, as in the syntax for loading the file. Is it imageView.setImage(ImageSource.File(???); Something like that? – Martin Erlic Oct 01 '16 at 18:54
  • @santafebound: Your existing code should be fine, so long as the value you pass into `uri()` is a URL with a `file:///` scheme. The easiest way to get that is `Uri.fromFile(...).toString()`, where `...` is a `File` object representing your download. – CommonsWare Oct 01 '16 at 18:58
  • Thanks for the advice. It worked! I posted my updated code above. – Martin Erlic Oct 01 '16 at 18:58
  • @santafebound: Um, well, actually, your code is loading the entire `Bitmap`. That will only work for smallish images. The point behind `SubsamplingScaleImageView` is to handle **big** images, in which case you want it to be the one loading the data. – CommonsWare Oct 01 '16 at 18:59