6

I have an app that uses Universal Image Loader to download photos from the internet, cache them to data/data/com.myapp/cache and display in ImageViews.

I also wanted to add sharing (WhatsApp, Facebook, Instagram, Dropbox etc.) to my app, so I tried to use this code:

Intent intent = new Intent();
intent.setAction(Intent.ACTION_SEND);
intent.putExtra(Intent.EXTRA_STREAM, photoUri);
intent.setType("image/jpeg");
startActivity(Intent.createChooser(intent, "Share image"));

photoUri was the uri in cache folder which other apps don't have permission to read.

So I googled/stackoverflowed and found out that I need to use FileProvider.

I configured the FileProvider as follows (as was written here) in my manifest:

<provider
    android:name="android.support.v4.content.FileProvider"
    android:authorities="com.myapp.fileprovider"
    android:exported="false"
    android:grantUriPermissions="true">
    <meta-data
        android:name="android.support.FILE_PROVIDER_PATHS"
        android:resource="@xml/file_paths" />
</provider>

And the file_paths.xml:

<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <cache-path name="photo_cache" path="/"/>
</paths>

Then I use the following code in my activity in button onClickListener:

File photoFile = ImageLoader.getInstance().getDiscCache().get("HTTP LINK HERE"); 
// returns File of "/data/data/com.myapp/cache/-1301123243"
Uri photoUri = FileProvider.getUriForFile(MyActivity.this, "com.myapp.fileprovider", photoFile);
// returns Uri of "content://com.myapp.fileprovider/photo_cache/-1301123243"
photoUri = Uri.parse(photoUri.toString() + ".jpg");
// then I add .jpg to file name

// Create intent
Intent intent = new Intent();
intent.setAction(Intent.ACTION_SEND);
intent.putExtra(Intent.EXTRA_STREAM, photoUri);
intent.setType("image/jpeg");

// Grant permissions to all apps that can handle this intent
// thanks to this answer http://stackoverflow.com/a/18332000
List<ResolveInfo> resInfoList = getPackageManager().queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
for (ResolveInfo resolveInfo : resInfoList) {
    String packageName = resolveInfo.activityInfo.packageName;
    grantUriPermission(packageName, photoUri, 
        Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
}

// And start
startActivity(Intent.createChooser(intent, "Share image"));

However, depending on the app I'm getting strange exceptions. Like this:

1974-1974/com.whatsapp W/Bundle﹕ Key android.intent.extra.STREAM expected ArrayList but value was a android.net.Uri$HierarchicalUri.  The default value <null> was returned.
1974-1974/com.whatsapp W/Bundle﹕ Attempt to cast generated internal exception:
java.lang.ClassCastException: android.net.Uri$HierarchicalUri cannot be cast to java.util.ArrayList
        at android.os.Bundle.getParcelableArrayList(Bundle.java:1223)
        at android.content.Intent.getParcelableArrayListExtra(Intent.java:4425)
        at com.whatsapp.ContactPicker.d(ContactPicker.java:320)
        at com.whatsapp.ContactPicker.onCreate(ContactPicker.java:306)
        at android.app.Activity.performCreate(Activity.java:5104)

Or I just see logs like this:

591-963/system_process W/ActivityManager﹕ Permission denied: checkComponentPermission()

And of course apps themselves give me toasts with errors (that they can't open or download the file).

I tried, googled, stackoverflowed A LOT, so now I'm posting here. I guess I'm doing it right, maybe just some little thing is wrong...

Any help will be appreciated!

Makks129
  • 576
  • 5
  • 20
  • can you put internet permission in android xml file – Riskhan Oct 29 '13 at 11:08
  • @kTekkie I don't think you understood the question right, sorry – Makks129 Oct 29 '13 at 12:50
  • @Makks129 are you fetching images using JSON, if yes so can you share a sample code with me or is there simillar i can fork on github, my requirement is : Universal Image Loader + with JSON in a GridView ---- don't want to use constant links for images – Sun Aug 07 '14 at 12:47

1 Answers1

0

I think this might be an an issue with either the FileProvider infrastructure or the application you're sharing with.

I have been trying to use this this support to share images w/ other applications. It works fine w/ Gallery, Drive, Gmail and Keep. It fails with Photos and Google+.

I see entries like the following in LogCat which leads me to believe that the Uri is being passed from one Activity to another. However, the (temporary) permission set in the Intent is being lost.

11-19 21:14:06.031: I/ActivityManager(433): Displayed com.google.android.apps.plus/.phone.HostPhotoViewIntentActivity: +848ms

Rich T
  • 1,711
  • 1
  • 11
  • 5
  • Did you try this approach with Instagram, Facebook or Messenger? It should be working, but it doesn't appear so. – Mario Lenci Feb 25 '16 at 11:43