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.
Abhishek 14 August 2015
Hey, This works very good, Thanks a lot for posting it , but i request you to tell how to add some text with the Screenshot, I dont want to place just a screenshot on share but a simple text string with it ..
Thanks
Sourav mishra 4 August 2015
how can i get the callback that which app is selected to share.
João Ferreira 29 July 2015
Hi! That works perfectly! Do you know any way to share it in IOS?
Best regards
ManHay 23 July 2015
Hey! Thanks and it’s also working smooth! However I have 1 problem if you can help please. I wish to add a text when you share it already not just the image. Is it possible please? I am trying to add simple text like “hey check this out” but it’s not really working. Thanks and regards! Hope to hear a replay very soon 🙂
Chris M 22 July 2015
I found this post really useful so I combined it with iOS sharing and put it up on GitHub. I have credited you with the Android portion, let me know if that’s not OK. Thanks for sharing! https://github.com/ChrisMaire/unity-native-sharing
tribio 4 August 2015 — Post Author
That’s great! 😉
tribio 19 July 2015 — Post Author
@chriskelly
Hi, sorry but I can’t help you here…
I advice you to check more unity tutorials before trying to include this code in your project.
And a bit of android development, just to have clear what you are doing 🙂 instead copy and paste 🙂
tribio 19 July 2015 — Post Author
Sorry for the late replay, but wordpress didn’t noticed me about the comments! (damn!!)
Anyway I think the problem is the one I just wrote at the end of the post:
Grant the Writing Access to External (SDCard) in PlayerSettings, otherwise you won’t be able to share pictures.
Sorry it was my fault, I should have explained it since the beginning!
Le me know!
saul 14 July 2015
@tribio
eh hello tribio had a drawback with the code , use it as this in your post but when I select an application tells me not to have to process the file
chriskelly 11 July 2015
hi I’m pretty new to unity and I have been using Uscript so I don’t have a clue about c#. how do I run the script when a button is clicked on unity 5? with u script I would put it all in a function then run it link it through the inspector. how do I do this with the c# tutorial script?
thanks
Ian 8 July 2015
I changed the code a little to use the Unity UI system but it doesn’t seem to work. Below is the code I have. Please help me I’ve been struggling with this for 2 days! Whenever I click share it says this picture cannot be used.
bool isProcessing;
public void Share(){
//This is called when the user clicks the Share button
if(!isProcessing){
StartCoroutine(ShareScreenshot());
}
public IEnumerator ShareScreenshot()
{
isProcessing = true;
// wait for graphics to render
yield return new WaitForEndOfFrame();
//———————————————————————————————————————————————————————————– PHOTO
// create the texture
Texture2D screenTexture = new Texture2D(Screen.width, Screen.height,TextureFormat.RGB24,true);
// put buffer into texture
screenTexture.ReadPixels(new Rect(0f, 0f, Screen.width, Screen.height),0,0);
// apply
screenTexture.Apply();
//———————————————————————————————————————————————————————————– PHOTO
byte[] dataToSave = screenTexture.EncodeToPNG();
string destination = Path.Combine(Application.persistentDataPath,System.DateTime.Now.ToString(“yyyy-MM-dd-HHmmss”) + “.png”);
File.WriteAllBytes(destination, dataToSave);
if(!Application.isEditor)
{
// block to open the file and share it ————START
AndroidJavaClass intentClass = new AndroidJavaClass(“android.content.Intent”);
AndroidJavaObject intentObject = new AndroidJavaObject(“android.content.Intent”);
intentObject.Call(“setAction”, intentClass.GetStatic(“ACTION_SEND”));
AndroidJavaClass uriClass = new AndroidJavaClass(“android.net.Uri”);
AndroidJavaObject uriObject = uriClass.CallStatic(“parse”,”file://” + destination);
intentObject.Call(“putExtra”, intentClass.GetStatic(“EXTRA_STREAM”), uriObject);
//intentObject.Call(“putExtra”, intentClass.GetStatic(“EXTRA_TEXT”), “testo”);
//intentObject.Call(“putExtra”, intentClass.GetStatic(“EXTRA_SUBJECT”), “SUBJECT”);
intentObject.Call(“setType”, “image/jpeg”);
AndroidJavaClass unity = new AndroidJavaClass(“com.unity3d.player.UnityPlayer”);
AndroidJavaObject currentActivity = unity.GetStatic(“currentActivity”);
// option one:
currentActivity.Call(“startActivity”, intentObject);
// option two:
//AndroidJavaObject jChooser = intentClass.CallStatic(“createChooser”, intentObject, “Testing”);
//currentActivity.Call(“startActivity”, jChooser);
// block to open the file and share it ————END
}
isProcessing = false;
}
Piero 12 June 2015
i change your code for pick image
intentClass.GetStatic(“ACTION_PICK”)
but i don’t know how to get path of Image that i pick because i can’t use onActivityResult() without another plugin
Plz Help me
This is code
public void OpenDialogue(){
#region [ Intent intent = new Intent(); ]
//instantiate the class Intent
AndroidJavaClass intentClass = new AndroidJavaClass(“android.content.Intent”);
//instantiate the object Intent
AndroidJavaObject intentObject = new AndroidJavaObject(“android.content.Intent”);
//Intent i = new Intent(
// Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
// startActivityForResult(i, RESULT_LOAD_IMAGE);
#endregion [ Intent intent = new Intent(); ]
#region [ intent.setAction(Intent.ACTION_VIEW); ]
//call setAction setting ACTION_SEND as parameter
//string J = ;
intentObject.Call(“setAction”, intentClass.GetStatic(“ACTION_PICK”));
#endregion [ intent.setAction(Intent.ACTION_PICK); ]
#region [ intent.setData(Uri.parse(“content://media/internal/images/media”)); ]
//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(“parse”, “content://media/internal/images/media”);
//call putExtra with the uri object of the file
intentObject.Call(“putExtra”, intentClass.GetStatic(“EXTRA_STREAM”), uriObject);
#endregion [ intent.setData(Uri.parse(“content://media/internal/images/media”)); ]
//set the type of file
intentObject.Call(“setType”, “image/jpeg”);
#region [ startActivity(intent); ]
//instantiate the class UnityPlayer
AndroidJavaClass unity = new AndroidJavaClass(“com.unity3d.player.UnityPlayer”);
//instantiate the object currentActivity
AndroidJavaObject currentActivity = unity.GetStatic(“currentActivity”);
//call the activity with our Intent
// intentObject.GetStatic
currentActivity.Call(“startActivityForResult”, intentObject);
//intentObject.
// Debug.Log( J);
// GameObject.Find(“dsfsdfs”).transform.gameObject.GetComponent().text = J ;
#endregion [ startActivity(intent); ]
// Texture2D texture = new Texture2D (1024,1024);
// if (texture == null) {
// EditorUtility.DisplayDialog (
// “Select Texture”,
// “You Must Select a Texture first!”,
// “Ok”);
// return;
// }
// string path = EditorUtility.OpenFilePanel(
// “Overwrite with png”,
// “”,
// “png”);
//
// if (path.Length != 0) {
// WWW www = new WWW(“file:///” + path);
// www .loa(texture);
// }
// OpenFileDialog open = new OpenFileDialog();
// open.Filter = “Image Files(*.jpg; *.jpeg; *.gif; *.bmp)|*.jpg; *.jpeg; *.gif; *.bmp”;
// if (open.ShowDialog() == DialogResult.OK)
// {
// // display image in picture box
// // pictureBox1.Image = new Bitmap(open.FileName);
// // image file path
// // textBox1.Text = open.FileName;
// }
}
tribio 11 June 2015 — Post Author
@tyson
Not yet, sorry…
I guess the fastest way is to save them in the sdcard then use my code 🙂
tyson 11 June 2015
@meta
hey did you manage to find out how to share sprites located in /Resources folder?
tribio 4 June 2015 — Post Author
@Pioj
Hi Pioj, the zip project is for Unity4, and the code should be exactly the same in Unity5.
I used it for Hungry Pixel and it works fine. 🙂
Thank you for your feedback! 😉
Pioj 4 June 2015
Please, update the info & zip link, in case you’ve improved the code for be compatible with Unity5…
Thank you