Share images and videos in Android 7 as well as older versions

Hi,

I am looking for a way to share images and videos through unity. All the examples I saw share fine in Android 6 but do not share in Android 7 due to new security in Android 7

AndroidJavaException: android.os.FileUriExposedException: … exposed beyond app through ClipData.Item.geUri()

See

and also if you know java android.os.FileUriExposedException: file:///storage/emulated/0/test.txt exposed beyond app through Intent.getData() - Stack Overflow

I am not a Java guy… does someone have an example on how to share images and videos in Android 7 as well as older versions?

Thanks!

If you can, just set you target API to 23 and it should work on android 7 too (I have the same problem but I’m having trouble setting the API to 23 due to manifest issues)

thanks a lot for your answer!

let me guess… firebase issues as it needs android:targetSdkVersion=“24” ?
its catch 22

Unity IAP, but yeah it needs version 24. If setting a lower target API is not an option, try this tutorial, it may inspire you as it explains how to use FileProvider: http://addcomponent.com/android-camera-complete-tutorial/

By the way what files do you want to be able to share? (what’s the use case?)

This one might work for you as it uses ContentProvider: GitHub - yasirkula/UnityNativeShare: A Unity plugin to natively share files (images, videos, documents, etc.) and/or plain text on Android & iOS

I didn’t have an Android 7 device to test it on, though.

1 Like

I have managed to get everything to work with the FileProvider making an Android plugin in Visual Studio with this tutorial: http://addcomponent.com/android-camera-complete-tutorial/
This tutorial is only for opening the camera, taking a picture and retrieving the picture’s path in Unity, but similarly I could add new Fragment classes to share a screenshot and open the gallery (I’ll be happy to put the code here if someone needs it).

Looking a your link yasirkula I’m very relieved to see that taking the screenshot in Unity and then passing the path of the image to the plugin is not so crazy after all! I tried for hours to take the screenshot in the plugin but couldn’t get anything but white images, so I used the same technique as they did. Glad to see it’s something other people have done too!

Now everything works in Android 7 while compiling with API 24+ as the target.

I have tried your plugin on android 7.

2 issues:

  1. you need to add Assets\Plugins\Android\res\xml\provider_paths.xml
    with
<?xml version="1.0" encoding="utf-8"?>

so android:resource=" @ /provider_paths"/> in AndroidManifest.xml wont throw an error

  1. android throws this error after reaching the app you wan to share through:
    ava.lang.IllegalArgumentException: Unable to find configured root for content://com.myapp/devroot/storage/emulated/0/DCIM/175322.jpg
    at android.support.v4.content.FileProvider$SimplePathStrategy.getFileForUri(FileProvider.java:739)
    at android.support.v4.content.FileProvider.getType(FileProvider.java:474)
    at android.content.ContentProvider$Transport.getType(ContentProvider.java:251)
    at android.content.ContentProviderNative.onTransact(ContentProviderNative.java:149)
    at android.os.Binder.execTransact(Binder.java:565)

hope i helped. hope you can make it work on android 7 :slight_smile:

1 Like

can you share the final plugin? :slight_smile:

I don’t think I can nor should. I just followed the tutorial and there are several places where you need to modify variable names and such to match your project, so my plugin wouldn’t help at all as you would need to modify it by following the tutorial. Basically the tutorial is the guy sharing his plugin and explaining each step, so it’s what exactly what you need.

If you are stuck at a specific step of the tutorial let me know, but first make sure you follow his steps exactly. If you miss 1 step it won’t work.

I am getting confused by the “android.support.v4.content.FileProvider” lines. I initially couldn’t get android.support library to work on Unity so I copy&pasted the source code of android.support.v4.content.FileProvider to
com.yasirkula.unity.UnitySSContentProvider and used that class instead. It is, therefore, surprising to see the android.support.v4.content.FileProvider on the stacktrace.

Can you test it on an older device without applying the step 1) you offered?

without the res dir Unity was not able to compile the apk:
AndroidManifest.xml:16: error: Error: No resource found that matches the given name (at ‘resource’ with value ’ @ /provider_paths’).

android.support.v4.content.FileProvider - you are right. it was from another AndroidManifest.xml in the project. once i left only your section it worked!

thanks a lot for creating this plugin!

1 Like

Hey!!! It definitly worked in my samsung galaxy S7 with android 7.0!!! I was looking for an easy solution for sharing video on android and your code just magically worked!!! Thank you so much!!! You saved my day :))))))

Not an expert at this stuff. But will this UnityNativeShare work on Android 8, or will it throw FileUriExposedException? I have a piece of code that uses the URI class and file:// - works on anything before Android 8.

I haven’t tested it on Android 8 but I keep hearing that Android apps now need a ContentProvider for sharing files and my plugin does use a ContentProvider. So, it theoretically should work.

Hi, yasirkula! I’d love to kindly thank you for your plugin! Works like a charm (tested only on Android 7)

1 Like

Hi, yasirkula your plugin solve my the problem that i was having with a a video to share on youtube. What i wanna know now is if is there a way to set the app package to share on a specific social network not open the general chooser ? Thanks in advice.

You’ll have to rebuild NativeShare.jar in Android Studio after making the following change at line 44 of NativeShare.java:

intent.setComponent( new ComponentName( “package name”, “class name” ) );
context.startActivity( intent );

For this method to work, you’ll need the package name of the specific social network and the name of the class that handles sharing for that app.

Please note that I haven’t tested this method myself and it may throw error(s) if the specific social network is not installed on user’s phone.

Thanks for the quick response, the social network is youtube the package is : com.google.android.youtube but i dont know the class. Did you know where i can find it ?

It might be com.google.android.youtube.UploadIntentHandlingActivity or UploadIntentHandlingActivity or neither. I am not sure, sorry.

After talking to yasikula about how to rebuild .jar i post this information here that might be useful for someone who is not accquainted with android studio:

You should import these two .java files to your project: https://github.com/yasirkula/UnityNativeShare/tree/master/JAR Source

Don’t forget to make the necessary change at line 44 of NativeShare.java. Then, open build.gradle in Gradle Scripts in Project view and change apply plugin: ‘com.android.application’ to apply plugin: ‘com.android.library’. Click “Build-Make Project”. If it gives an error at some applicationId line, delete that line and try again.

After the build is complete, go to PROJECT_PATH/app/build/outputs/aar and open app-debug.aar with Winrar or another archive tool. Extract classes.jar to your desktop and rename it as NativeShare.jar. Then, download the original NativeShare.jar to somewhere else: https://github.com/yasirkula/UnityN…reDemo/Assets/Plugins/Android/NativeShare.jar

Open both .jar files with Winrar and make sure that they both have exact same file/folder hierarchy. Delete any additional files/folders from your NativeShare.jar.

Finally, you can replace the NativeShare.jar at Assets/Plugins/Android with yours.

And the class and the package to youtube sharing is:
Package: com.google.android.youtube
Class: com.google.android.youtube.UploadIntentHandlingActivity

Cheers.

2 Likes