2

My Android App downloads some images from the internet using facebook's Fresco library. For displaying these images in a WebView and sharing them, I use Fresco to retrieve the images and write them to a temporary file in my App's internal cache dir:

final File tempFile = new File(new File(cx.getCacheDir(), "fresco_cache/"), filename);
saveInputStream(tempFile, is, new FileSaverCallback() {
    @Override
    public void onSuccess() {
        Uri localUri = CacheContentProvider.getContentUriFromUrlOrUri(url);
        callback.onSuccess(url, localUri.toString());
    }

    @Override
    public void onFailure() {
        callback.onFailure(url);
    }
});

Then, I have a custom ContentProvider for providing access to these files. The provider successfully resolves the Uri, because I use the images internally by their content URI instead of the real file path. However, when I try to share an image using

Intent shareIntent = new Intent();
shareIntent.setAction(Intent.ACTION_SEND);
shareIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse(ARG_IMAGE_URI));
shareIntent.setType("image/*");
startActivity(Intent.createChooser(shareIntent, "Share"));

the sharing doesn't work with most applications, but does work with a few. I can, for instance, attach the file to an email using K-9, but cannot share it with Google Keep (It says: "Error importing data").

My ContentProvider is registered like this:

<provider
    android:name=".helpers.CacheContentProvider"
    android:authorities="my.app.files"
    android:exported="true"
    android:grantUriPermissions="true"/>

I checked, that the openFile() function is correctly called and returns a valid ParcelFileOpener:

@Override
public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException {
    final File f = getFileForUri(getContentUriFromUrlOrUri(uri.toString()));

    if (f.exists())
        return ParcelFileDescriptor.open(f, ParcelFileDescriptor.MODE_READ_ONLY);

    throw new FileNotFoundException(uri.getPath());
}

How can I debug that issue? What could I do wrong?

Edit: The sharing used to work with the old implementation of my code, where I used Universal Image Loader instead of Fresco. The only difference I see is that now the images are saved to the interal cache, while before they were saved to /sdcard/data/my.app/...

janoliver
  • 7,744
  • 14
  • 60
  • 103
  • Are you trying to use content provider in API level below 20 ? – dex Dec 06 '15 at 10:26
  • No, comileSdkVersion and targetSdkVersion are 23. Also, the sharing used to work with the old implementation of my code, where I used Universal Image Loader instead of Fresco. The only difference I see is that now the images are saved to the interal cache, while before they were saved to `/sdcard/data/my.app/..`. – janoliver Dec 06 '15 at 10:28
  • My point was content provider doesn't work properly with API level below 21 and there was bug in Android , confirmed by Google.Anyways can you please check if URI you are sending has at-least read permission ? – dex Dec 06 '15 at 11:02
  • Permissions of the files are 600. I think, other apps can read the files: I have an app to upload images to some cloud storage thing. Before uploading, it shows the correct thumbnails of my images, as well as the filesizes and so on. Only when I click "upload" it fails with some error message. It appears as if there is a non-closed stream or something like that. – janoliver Dec 06 '15 at 11:37
  • You're probably running into poorly-written clients, ones that expect a `DATA` column. See [this SO answer](http://stackoverflow.com/a/25020642/115145) and [this helper class](https://github.com/commonsguy/cwac-provider#usage-legacycompatcursorwrapper). – CommonsWare Dec 06 '15 at 12:35
  • My `ContentProvider` specifies a DATA column. – janoliver Dec 06 '15 at 15:03

1 Answers1

0

Turns out there are missing permissions when some package wants to access my application's internal files. I wasn't able to figure out how to properly grant these permissions, albeit trying everything I found in the many SO posts on this topic. Switching to external storage instead of the internal one solved this.

janoliver
  • 7,744
  • 14
  • 60
  • 103