Search code examples
androidandroid-galleryandroid-10.0

Android Q make photos saved in getExternalFilesDir() visible in Gallery


All I want is that my app photos can be visible both in phone gallery and inside my app.

I want to show all previous images made from my app and do it like this (I removed some code about populating recyclerView to make it more readable):

 @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ivPhoto = findViewById(R.id.photo);

        photoPaths = new ArrayList<>();
        File directory = getExternalFilesDir(Environment.DIRECTORY_DCIM);
        File[] files = directory.listFiles();
        if (files != null && files.length > 0) {
            for (File file : files) {
                photoPaths.add(file.getAbsolutePath());
            }
        }
        if (photoPaths.size() > 0) {
            File file = new File(photoPaths.get(0));
            try {
                ExifInterface exif = new ExifInterface(file.getCanonicalPath());
                String text = exif.getAttribute(ExifInterface.TAG_EXIF_VERSION);
                Toast.makeText(this, text, Toast.LENGTH_SHORT).show();
            } catch (IOException exception) {
                exception.printStackTrace();
            }
            Bitmap bitmap = BitmapFactory.decodeFile(photoPaths.get(0));
            ivPhoto.setImageBitmap(bitmap);
        }
}

This method I use to take photo from camera:

private void dispatchTakePictureIntent() {
        Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        takePictureIntent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION
                | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
        if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
            File photoFile = null;
            try {
                photoFile = createImageFile();
            } catch (IOException ex) {
                ex.printStackTrace();
            }
            if (photoFile == null) {
                return;
            }
            Uri photoURI;
            Uri photoURIQ;
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {

                ContentValues values = new ContentValues(2);
                values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
                values.put(MediaStore.Images.Media.RELATIVE_PATH, Environment.DIRECTORY_DCIM);

                photoURIQ = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
                takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURIQ);
            } else {
                photoURI = getUriForFile(this, "com.example.photometadata.fileprovider",
                        photoFile);

                takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
            }
            startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
        }
    }

Above code makes taken photo visible in Gallery, but of course there is no picture inside my app folder.

I can change that code to make next photos visible inside my app, but this way they will not be visible in Gallery.

I was trying to retrieve photo file from gallery and save it to getExternalStorageDir() folder in onActivityResult, but got EACCESS SecurityExeption. I tried something else, but nothing works as I want.


Solution

  • File directory = getExternalFilesDir(Environment.DIRECTORY_DCIM);

    The directory getExternalFilesDir()is an app specific directory.

    It cannot be scanned by the MediaStore.

    And as Gallery apps mostly query the MediaStore for images they will not see them then.

    Store them at a different place and or in a different way.