While learning Unity3D and developing my indie game for Android – Makura – last week, I was trying to set up a button to take a screenshot and share the image opening the default list of Android of the current social apps installed on the device.
I have been stuck for a while, getting errors using AndroidJavaClass and AndroidJavaObject on Unity to call the Java classes of Android.
Once I solved the problem I wanted to share the code on my blog, because I couldn’t find anywhere a solution.
The exact problem was including the jpg of the screenshot as uri for the EXTRA_STREAM parameter of the Intent java object, and let it open properly with other apps.
Below the code in C#:
//instantiate the class Intent AndroidJavaClass intentClass = new AndroidJavaClass("android.content.Intent"); //instantiate the object Intent AndroidJavaObject intentObject = new AndroidJavaObject("android.content.Intent"); //call setAction setting ACTION_SEND as parameter intentObject.Call<AndroidJavaObject>("setAction", intentClass.GetStatic<string>("ACTION_SEND")); //instantiate the class Uri AndroidJavaClass uriClass = new AndroidJavaClass("android.net.Uri"); //instantiate the object Uri with the parse of the url's file AndroidJavaObject uriObject = uriClass.CallStatic<AndroidJavaObject>("parse","file:///sdcard/expl.jpg"); //call putExtra with the uri object of the file intentObject.Call<AndroidJavaObject>("putExtra", intentClass.GetStatic<string>("EXTRA_STREAM"), uriObject); //set the type of file intentObject.Call<AndroidJavaObject>("setType", "image/jpeg"); //instantiate the class UnityPlayer AndroidJavaClass unity = new AndroidJavaClass("com.unity3d.player.UnityPlayer"); //instantiate the object currentActivity AndroidJavaObject currentActivity = unity.GetStatic<AndroidJavaObject>("currentActivity"); //call the activity with our Intent currentActivity.Call("startActivity", intentObject);
I hope this could help someone else!
Don’t hesitate to leave me a comment with your experiences or questions!
**————————–
UPDATE 13 MAY 2014
**————————–
Finally I had the time to make an example project for this utility.
I’ve heard that some of you had troubles to make it work, so I decided to create a kind of tutorial and share it so you can download it and test it!
My computer runs Windows 7 64bit, Unity Free 4.3.4f1, Java jdk1.7.0_55 and jre7.
At the moment the code is working perfectly, inside the zip file you can find “ShareTest.apk” to test the example on your device.
I really hope to help and make many people happy as, I wasnβt expecting this, but it seems that simple plugins like this are still sold! (Why am I sharing this, so?!!!)
Guys, let me know if you have still troubles! π
For Windows users: be sure you have JDK and JRE installed ( link ) and that the JAVA_HOME and Path are correctly set up ( if you don’t know what I’m talking check here ore here)
**————————–
UPDATE 19 JULY 2015
**————————–
IMPORTANT:
Grant the Writing Access to External (SDCard) in PlayerSettings, otherwise you won’t be able to share pictures.
**————————–
UPDATE 23 September 2019
**————————–
This code doesnβt work anymore on the latest Android OS.
You can target Android 6 and it works fine, but if you want to publish it on Google Play, it wonβt be accepted.
tribio 8 January 2015 — Post Author
@Ben
I would say…
execute the ‘StartCoroutine (ShareScreenshot ())’ on the loading scene instead?
Ben 8 January 2015
So instead of taking a picture of the score screen , which i have the screenshot object in currently, I’d like to first transition to the start menu which has my game’s name and share that screen. I have i the script like this:
private void OnMouseDown(){
Application.LoadLevel(“start menu”);//the scene I’d like the screenshot of
audio.PlayOneShot (button, 5f);
StartCoroutine (ShareScreenshot ());
}
But this doesn’t transition the scene fast enough and ends up taking the current screenshot. Then when I return to the game, it then transitions. Any suggestions as to how to transition first and take that scene’s screenshot?
tribio 28 December 2014 — Post Author
@Tom Tong
Thanks Tom! π
Sorry but I can’t help you for this one…
Tom Tong 27 December 2014
Your source code is awesome. I would like to let user select photo from his photo gallery. And the photo will be used in my Unity android app.
How could I modify your code to achieve this? Thank you.
Ben 28 November 2014
@tribio
It works!!!! Thanks you so much. It was on internal only before.
I just played your game Speedy Wheel and gave it 5 stars…really fun. Did you do any marketing for it, and if so, any insight you may share?
tribio 28 November 2014 — Post Author
Yeah! π
Thank you very much for the stars, I really need them π
No marketing yet, I’m sill working on it.. it’s not completed π I have lots of ideas for that wheel!!
Ben 28 November 2014
@tribio
I’m not sure how I’d enable it the write access? Is it in Unity, or?
Also will the user also have to have their write access to External sdcard enabled? if they don’t they’ll be pretty confused, right?
tribio 28 November 2014 — Post Author
PlayerSetting — Other Settings — Write Access — select “External” π
For the user doesn’t change anything…try and let me know! π
Ben 28 November 2014
@tribio
That’s probably why, I don’t have a sd card installed. Is there a way to write to internal storage, because if someone who wants to share doesn’t have a sd card, they will have the same problem I’m having.
Thank you for all your help.
tribio 28 November 2014 — Post Author
Yes, I know…
but in your project is it still enabled?
Ben 28 November 2014
@tribio
For some reason, everything works fine until the picture tries to be sent to the sharing app. I get to choose the app I want to use, but it then stops because apparently the picture can’t load. I’ve tried with Twitter, gmail, facebook, etc. It might even take me to the app, but then fails to post or transfer the picture. Any insight?
The only thing I changed is how the sharScreenshot method is called. This is what I have:
private void OnMouseDown(){
StartCoroutine (ShareScreenshot ());
}
My game object doesn’t have a GUITexture, if that matters.
tribio 28 November 2014 — Post Author
have you enabled the write access to External sdcard? it may be the problem…
or maybe the path of the picture is wrong? use file.exists and show the result in debug mode (using logcat maybe) to be sure.
let me know π
Ben 27 November 2014
Hey, I love this post. Is there an easy implementation you can show me as to how to share a set image/image of my choice every time rather than the screenshot?
Thanks in advance.
tribio 27 November 2014 — Post Author
Hi Ben,
sorry I don’t have an exmaple of that, maybe I’ll write another post for that.. π
derry 14 November 2014
thanks very useful
Ona 28 October 2014
I have a little problem with that, I hope you help me?
I want to do share by apps likes: mail, twitter and pinterest. Your code works great, but I NEED to have every app in separate button. And now, problem:
I’ve made three buttons. Every of them has the same code. When I’m opening dialog window I can choose which app should I use. But when I click that ALWAYS USE THIS APP for this button – e.g. it remember that I used “mail” on all buttons. How can I change that?
I hope I wrote it understandly, my english isn’t good and it’s hard to translate. But I will be really grateful if you tell me what should I change? I don’t understand javaobject very well.
tribio 28 October 2014 — Post Author
Hi Ona,
I understand what you need, but unfortunately I can’t help you here… you don’t need to use my plugin for that, you may need the facebook plugin (that’s free) and for twitter it could be enough just a link (find more info online)..
this code just do the same action for the same app π
You should find a solution for every button you want.
Uray 16 October 2014
Awesome snippet to share screenshots! Thanks a lot for this.
Just one question, is there any way to filter the applications shown in the dialog?
tribio 16 October 2014 — Post Author
Thanks for the feedback!
I don’t think we can filter the apps shown, it’s something external to the game…
tribio 18 August 2014 — Post Author
@Raja
Good!!! I’m happy it worked!!!! π
Raja 18 August 2014
Yes it worked Thanks a lot man,i am strugling for this since 1 week. i used fb sdk but iam not satisfied with that,you are saved me thank you so much bro.
Raja 18 August 2014
intentObject.Call(“putExtra”, intentClass.GetStatic(“EXTRA_STREAM”), uriObject);
For this line Iam getting this error
The type arguments for method `UnityEngine.AndroidJavaObject.GetStatic(string)’ cannot be inferred from the usage. Try specifying the type arguments explicitly.
Please help me sir.