0

I've an app that displays a picture to its users. It sounds really simple, but I've been at it for days now trying to troubleshoot the exact problem. So what'll happen is that user will:

  1. Click an image;
  2. The image will be saved to the user's External Storage;
  3. The image's Uri will be taken;
  4. An ImageView will open the image with this Uri;
  5. No image appeared, throws java.io.FileNotFoundException: /storage/emulated/....jpg: open failed: ENOENT (No such file or directory).

So I thought I didn't really pass the correct Uri and tried to troubleshoot from there. Then I accidentally rotated the screen and hey - my image is there! The the log file showed this when I rotated it a few times:

android.graphics.Bitmap@49361a20
android.graphics.Bitmap@495c42c8
android.graphics.Bitmap@496ac1e0
android.graphics.Bitmap@495b2b28

Is this displaying the memory location? Is it supposed to be different even after screen rotation?

With this information, is there anywhere else I should look into to solve this problem? I could rule out that the Uri is invalid, as it is showing the correct image after rotating the screen.

This is the code (of a utility class) involved to download the image clicked; This method seems to work well and the image is saved to the correct directory.

 public void downloadFile(String url) {
        File folder  = new File(Environment.getExternalStorageDirectory() + directory);
        String fileName = url.substring(url.lastIndexOf("/") + 1);
        String filePath = folder.getPath() + "/" + fileName;
        File file = new File(filePath);
        fileUri = Uri.fromFile(file);

        if (!folder.exists()) {
            Log.i(TAG, "Worka folder is not found, creating one now");
            folder.mkdir();
        } else {
            Log.i(TAG, "Worka folder is found");
            if (file.exists()) {
                Log.i(TAG, "Found a file with the same name, deleting/replacing it now");
                file.delete();
            }
        }

        DownloadManager downloadManager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);

        Uri downloadUri = Uri.parse(url);
        DownloadManager.Request request = new DownloadManager.Request(downloadUri);

        request.setAllowedNetworkTypes(
                DownloadManager.Request.NETWORK_MOBILE | DownloadManager.Request.NETWORK_WIFI)
                //.setAllowedOverRoaming(false).setTitle("Roaming is not available")
                .setDestinationInExternalPublicDir(directory, fileName);

        downloadManager.enqueue(request);
        Log.i(TAG, "downloadFile() is successful, " + fileName + " is saved to Worka directory");
}

public Uri getFilePath() {
        return fileUri;
}

To make sure it gets passed from an activity to another activity;

FileDownload fileDownload = new FileDownload(getApplicationContext());
                fileDownload.downloadFile(conversation.getMessage());
                Uri fileUri = fileDownload.getFilePath();

                if (fileUri != null) {
                    Log.i(TAG, "fileUri: " + fileUri.toString());
                    Intent intent = new Intent(BulletinPostActivity.this, ImageViewingActivity.class);
                    intent.putExtra("imageUri", fileUri.toString());
                    startActivity(intent);

Finally, getting Bitmap from the passed Uri:

I then tried using AsyncTask here, to make sure the bitmap gets loaded properly... but I'm unsure what to code to accomplish this.

 public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    ...

    String imagePath = getIntent().getStringExtra("imageUri");
    imageUri = Uri.parse(imagePath);

    touchImageView = (TouchImageView) findViewById(R.id.image_viewing_image_view);

    if (imageUri != null) {
        new loadBitmap(imageUri).execute();
    }
}

public class loadBitmap extends AsyncTask<Void, Integer, Bitmap> {

    Uri uri;

    public loadBitmap(Uri uri) {
        this.uri = uri;
    }

    @Override
    protected Bitmap doInBackground(Void... params) {
        getBitmap();
        return bitmap;
    }

    public Bitmap getBitmap() {
        try {
            Log.i(TAG, "Attempting to get the bitmap from imageUri");
            bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), imageUri);
            Log.i(TAG, "Successfully gotten the bitmap from imageUri: " + bitmap);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return bitmap;
    }

    @Override
    protected void onPostExecute(Bitmap bitmap) {
        if (bitmap == null) {
            getBitmap();
        } else {
            touchImageView.setImageBitmap(bitmap);
        }
    }
}
  • Are you accepting permissions to read external storage – Brahmam Yamani Mar 30 '16 at 05:10
  • @BrahmamYamani Yes! Sorry I've forgotten to mention this, writing and reading external storage permissions are indeed there. Otherwise I wouldn't be able to save and display the image... only after a screen rotation! – Reynolds R. G. G. Mar 30 '16 at 05:13
  • i think activity or fragment refreshing when screen is rotated , kept android:configChanges="orientation|screenSize" in manifest for every activity it will works – Brahmam Yamani Mar 30 '16 at 05:16
  • In your onPostExecute add invalidate() and requestLayout for rerendering layout. May help – bryan c Mar 30 '16 at 05:22
  • @BrahmamYamani That's it! I'm hoping the image would appear without refreshing the activity, in this case, rotating it. I'm sure I'm missing something when I'm trying to display the image with Uri. – Reynolds R. G. G. Mar 30 '16 at 05:22
  • @bryanc Thanks for the suggestion, I just tried that and it's still throwing the same error. – Reynolds R. G. G. Mar 30 '16 at 05:33
  • @ReynoldsR.G.G. are you sure file stored in external storage , first check the device have external storage or not and store the image ,check this link for storing image in external storage http://stackoverflow.com/questions/8330276/write-a-file-in-external-storage-in-android – Brahmam Yamani Mar 30 '16 at 05:43
  • @BrahmamYamani I appreciate your help on this. I did a double check on 2 devices to make sure the path of the saved images is indeed the external storage. Even if I made a mistake on this, the image still appears after a screen rotation. So I'm trying to troubleshoot to why it's not showing anything `onCreate`. – Reynolds R. G. G. Mar 30 '16 at 05:47
  • Use Third Party Library like Picasso , Glide, etc.... For dispalying image , These librarys are help's to display image fast and it compresses the size of image, it manages heap size and ram usage – Brahmam Yamani Mar 30 '16 at 05:55
  • i think downloaded image size is very high so it takes time to displaying, use third party library – Brahmam Yamani Mar 30 '16 at 05:56
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/107685/discussion-between-brahmam-yamani-and-reynolds-r-g-g). – Brahmam Yamani Mar 30 '16 at 06:03

0 Answers0