androidandroid-fileandroid-sharing

Receiving single file from external app is unreadable, but readable when multiple


I have a problem when receiving a file from an external app. I've been following the tutorial on https://developer.android.com/training/sharing/receive.html and it works fine until I want to handle the image in my code.

The problem I have is if I select and send only one file to my app, I am not able to read it after converting it from URI to a FILE object. However, if I send two or more images (the very same image selected before plus an additional one from the same directory), then I actually can read the files (all of them). Why is that? Even setting the file to setReadable(true); I can not read it afterwards.

Target SDK is 23 and yes, I already implemented the request for permission in the code that is needed from API 23+. So this can't be the problem. I need to be able to read the received files no matter if it was only one or a list of multiple.

On a side note: if I send any amount of images from the Google Photos app (one or multiple), I never can read the file. Images sent from the "ES File Explorer" app are readable in the code but not readable if I only send one single file to my app.

Here is my code snippet of the problematic part:

// THIS PART WORKS. RECEIVING MULTIPLE FILES ARE READABLE IN THE CODE BELOW.
void handleSendMultipleImages(Intent intent) {
    ArrayList<Uri> imageUris = intent.getParcelableArrayListExtra(Intent.EXTRA_STREAM);
    if (imageUris != null) {
        addImagesToNewOrExistingContact(imageUris);
    }
}

// THIS PART DOES NOT WORK. I CAN NOT READ THE FILE IN THE CODE BELOW.
private void addImageToNewOrExistingContactDialog(Uri imageUri) {
    ArrayList imageUris = new ArrayList<>();
    imageUris.add(imageUri);
    addImagesToNewOrExistingContact(imageUris);
}

private void addImagesToNewOrExistingContact(final ArrayList<Uri> imageUris) {

    for (Uri uri : imageUris) {
        File f = new File(uri.getPath());
        f.setReadable(true);
        f.setWritable(true);

        boolean readd = f.canRead(); // FALSE, but why?
        boolean exec = f.canExecute(); // FALSE, but why?
    }
}

Files I tested this with:
Selected two files from "ES File Explorer" and sent them to my app: file:///storage/emulated/0/Pictures/Adobe%C2%AE%20Photoshop%C2%AE%20Touch/1452348875289.jpg file:///storage/emulated/0/Pictures/Adobe%C2%AE%20Photoshop%C2%AE%20Touch/1455733673513.jpg

Both canRead() = TRUE

Selected one file from "ES File Explorer" and sent it to my app: content://media/external/images/media/33675

canRead() = FALSE

Actually the files content://media/external/images/media/33675 and file:///storage/emulated/0/Pictures/Adobe%C2%AE%20Photoshop%C2%AE%20Touch/1455733673513.jpg are the exact same files.

Selected two files from "Google Photos" and send them to my app: content://com.google.android.apps.photos.contentprovider/0/1/shared%3A%2Flocal%253A4541959b-3222-4ee0-b838-67049141b864%2FV2xDV01jNWhWVDRCQXRMY202YTh3NFNES1N4M01R/REQUIRE_ORIGINAL/NONE/1290260075 content://com.google.android.apps.photos.contentprovider/0/1/shared%3A%2Flocal%253A20e65034-795f-4300-9472-64a598afc4c1%2FV2xDV01jNWhWVDRCQXRMY202YTh3NFNES1N4M01R/REQUIRE_ORIGINAL/NONE/1096770166

Both canRead() = FALSE

Thanks for any help in advance.


Solution

  • Use openInputStream(uri) on getContentResolver(). No need for a File class.