0

I followed the answers of Saving an image from ImageView into internal storage but I still can't save anything.. My code is here :

 public void buttonPickImage(View view) {

        FileOutputStream fos;

        bitmap = ((BitmapDrawable)imageView.getDrawable()).getBitmap();

        Random rng = new Random();
        int n = rng.nextInt(1000);




        try {

            File sdCard = Environment.getExternalStorageDirectory();
            File dir = new File(sdCard.getAbsolutePath() + "/BAC");
            bool = dir.mkdir();

            File file = new File(dir, "BAC_"+n+".jpg");


            fos = new FileOutputStream(file);
            bitmap.compress(Bitmap.CompressFormat.JPEG,100,fos);
            fos.flush();
            fos.close();
            Toast.makeText(getApplicationContext(),"Image sauvegardée"+bool,Toast.LENGTH_SHORT).show();

        }catch (java.io.IOException e){
            e.printStackTrace();
            Toast.makeText(getApplicationContext(),"IOException: " + e.getMessage(),Toast.LENGTH_SHORT).show();
        }

    }

With this method I get the IOExeception with messae : java.io.FileNotFoundException: /storage/emulated/0/BAC/BAC_396.jpg: open failed: ENOENT (No such file or directory)

I also tried this to save it to internal storage but its not working for me : https://www.tutorialspoint.com/how-to-write-an-image-file-in-internal-storage-in-android With this method, program runs but boolean mkdir gives me false.

Thanks for helping me

Antoine Berger
  • 85
  • 1
  • 10
  • 1
    `dir.mkdir();` Only call mkdir if the directory does not exist yet. And if you fo check the return value. If it returns false display a toast to inform the user. And return. Dont continue as that makes no sense if the directory does not exist. Please try and then adapt your code here too. – blackapps Jul 31 '20 at 10:36
  • You did not tell which toast is displayed. So how would we know? – blackapps Jul 31 '20 at 10:38
  • 1
    `"not working"`. That should be `"IOException: " + e.getMessage()` to inform the user better. – blackapps Jul 31 '20 at 10:40
  • You also did not post relevant lines from the logcat. You probably have an IOException but did not inform us. – blackapps Jul 31 '20 at 10:46
  • `to internal storage but its not working for me` Well what happened instead? What are the errors? – blackapps Jul 31 '20 at 10:50
  • @blackapps I edit my qtn with the error message. Toast displayed is "not working". I know the text is not accurate but it was for testing on my computer, not for users – Antoine Berger Jul 31 '20 at 11:57
  • When I try the internal storage solution, I get the first toast (successful) and no error, but nthing is saved in my storage – Antoine Berger Jul 31 '20 at 11:58
  • It is time you do all the things suggested for mkdir. Pretty strange you did not even react to my first comment. – blackapps Jul 31 '20 at 12:13
  • `text is not accurate but it was for testing on my computer, not for users ` No good. If you do not display e.getMessage() you know nothing. – blackapps Jul 31 '20 at 12:14
  • `... I get the first toast (successful) and no error, but nthing is saved in my storage ` How did you check that? – blackapps Jul 31 '20 at 13:39
  • I checked the run tab and logcat. I updated my post again to show you what happens with mkdir and egetMessages for both cases – Antoine Berger Jul 31 '20 at 15:05
  • `I checked the run tab and logcat.` ?? To find a file? Further you did change noting concerning mkdir() and e.getMessage(). You did not adapt your code here. – blackapps Jul 31 '20 at 15:50
  • `With this method, program runs but boolean mkdir gives me false.` There is no mkdir used in that example. – blackapps Jul 31 '20 at 16:10
  • No, to find an error. I checked the file in the storage of device. Sorry I updated with mkddir use – Antoine Berger Aug 01 '20 at 10:56
  • `bool = dir.mkdir();` ???????? – blackapps Aug 01 '20 at 11:21
  • I did this to get the boolean value of mkdir as you told me in the first reponse. It's just a variable to be displayed in toast – Antoine Berger Aug 01 '20 at 11:27
  • No it is not just a variable to be displayed in a toast. Where do you check its value? You should do that immediately on the following line. And then display a toast if false and return. I said that before. You now blindly continue. I told you all yesterday and you still did not adapt your code. Sigh.. Further you now also did not tell us if it was false or true. And.. i also told you to only call mkdir if the directory does not exist yet. That you did not implement either. – blackapps Aug 01 '20 at 11:33

1 Answers1

1

Finally got it working using Media Store instead of getExternalStorageDirectory as

This method was deprecated in API level 29. To improve user privacy, direct access to shared/external storage devices is deprecated. When an app targets Build.VERSION_CODES.Q, the path returned from this method is no longer directly accessible to apps. Apps can continue to access content stored on shared/external storage by migrating to alternatives such as Context#getExternalFilesDir(String), MediaStore, or Intent#ACTION_OPEN_DOCUMENT.

MediaStore is also useful as it allows you to get the image in your android gallery app.

So my solution is :

ImageView imageView = findViewById(R.id.image);
        Bitmap bitmap = ((BitmapDrawable)imageView.getDrawable()).getBitmap();

        ContentValues values = new ContentValues();
        values.put(MediaStore.Images.Media.TITLE, "any_picture_name");
        values.put(MediaStore.Images.Media.BUCKET_ID, "test");
        values.put(MediaStore.Images.Media.DESCRIPTION, "test Image taken");
        values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
        Uri uri = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
        OutputStream outstream;
        try {
            outstream = getContentResolver().openOutputStream(uri);
            bitmap.compress(Bitmap.CompressFormat.JPEG, 70, outstream);
            outstream.close();
            Toast.makeText(getApplicationContext(),"Success",Toast.LENGTH_LONG).show();
        } catch (IOException e) {
            e.printStackTrace();
            Toast.makeText(getApplicationContext(),e.getMessage(),Toast.LENGTH_LONG).show();
        }

Still thank you @blackapps for explaining me some basics things about the IOexception, mkdir and toasts. It'll be useful anyway.

Antoine Berger
  • 85
  • 1
  • 10