Sending twitter/facebook intent with AndroidJNI

Hi, I am trying to send twitter and/or facebook messages from an unity app using the AndroidJNI api, and I end up with some problems. In short, what I am trying to do is the equivelent of the following java code:

	public static void share(String headline, String subject, String text) {
		final Intent intent = new Intent(Intent.ACTION_SEND);

		intent.setType("text/plain");
		intent.putExtra(Intent.EXTRA_SUBJECT, subject);
		intent.putExtra(Intent.EXTRA_TEXT, text);

		Activity activity = UnityPlayer.currentActivity;
		if (activity != null) {
			activity.startActivity(Intent.createChooser(intent, headline));
		}
	}

I have coded this in C# using AndroidJNI, and gotten the following code (sorry for the lengthy cut-n-paste here):

	private void share(string headline, string subject, string message)
	{
		// Find the UnityPlayer and get the static current activity
		IntPtr unityPlayer = AndroidJNI.FindClass("com.unity3d.player.UnityPlayer");
		IntPtr currentActivity = AndroidJNI.GetStaticFieldID(unityPlayer,"currentActivity", "Landroid/app/Activity;");
		
		// Get defenitions of Intent and it's constructor.
		IntPtr IntentClass = AndroidJNI.FindClass("android.content.Intent");
		IntPtr IntentConstructor = AndroidJNI.GetMethodID(IntentClass,"<init>","(Ljava/lang/String;)V");

		// Get the Activity defenition and startActivity method
		IntPtr ActivityClass = AndroidJNI.FindClass("android.app.Activity");
		IntPtr MethodStartActivity = AndroidJNI.GetMethodID(ActivityClass, "startActivity", "(Landroid/content/Intent;)V");
		
		// Get the values of the string actions we need
		jvalue ACTION_SEND = GetFieldString(IntentClass, "ACTION_SEND");
		jvalue EXTRA_SUBJECT = GetFieldString(IntentClass, "EXTRA_SUBJECT");
		jvalue EXTRA_TEXT = GetFieldString(IntentClass, "EXTRA_TEXT");
	
		// Construct the Intent object with the correct parameters
		jvalue[] intentParameters = new jvalue[1];
		intentParameters[0] = ACTION_SEND;
		IntPtr IntentObject = AndroidJNI.NewObject(IntentClass, IntentConstructor, intentParameters);

		// Get the methods setType, putExtra and createChooser
		IntPtr MethodSetType = AndroidJNI.GetMethodID(IntentClass, "setType", "(Ljava/lang/String;)Landroid/content/Intent;");
		IntPtr MethodPutExtra = AndroidJNI.GetMethodID(IntentClass, "putExtra", "(Ljava/lang/String;Ljava/lang/String;)Landroid/content/Intent;");
		IntPtr MethodCreateChooser = AndroidJNI.GetStaticMethodID(IntentClass, "createChooser", "(Landroid/content/Intent;Ljava/lang/CharSequence;)Landroid/content/Intent;");
		
		// Set Intent type
		jvalue[] setTypeParameters =  new jvalue[1];
		setTypeParameters[0] = new jvalue();
		setTypeParameters[0].l = AndroidJNI.NewStringUTF("text/plain");
		AndroidJNI.CallObjectMethod(IntentObject, MethodSetType, setTypeParameters);

		// Set subject
		jvalue[] subjectParameters =  new jvalue[2];
		subjectParameters[0] = EXTRA_SUBJECT;
		subjectParameters[1] = new jvalue();
		subjectParameters[1].l = AndroidJNI.NewStringUTF(subject);
		AndroidJNI.CallObjectMethod(IntentObject, MethodPutExtra, subjectParameters);

		// Set message
		jvalue[] messageParameters =  new jvalue[2];
		messageParameters[0] = EXTRA_TEXT;
		messageParameters[1] = new jvalue();
		messageParameters[1].l = AndroidJNI.NewStringUTF(message);
		AndroidJNI.CallObjectMethod(IntentObject, MethodPutExtra, messageParameters);
		
		// Create a global ref
		IntPtr GlobalIntentObject = AndroidJNI.NewGlobalRef(IntentObject);

		// Run the chooser
		jvalue[] chooserParameters =  new jvalue[2];
		messageParameters[0] = new jvalue();
		messageParameters[0].l = GlobalIntentObject;
		messageParameters[1] = new jvalue();
		messageParameters[1].l = AndroidJNI.NewStringUTF(headline);
		IntPtr choosedIntent = AndroidJNI.CallStaticObjectMethod(IntentClass, MethodCreateChooser, chooserParameters);
		
		// Send the Intent
		jvalue[] startActivityParameters =  new jvalue[1];
		startActivityParameters[0] = new jvalue();
		startActivityParameters[0].l = choosedIntent;
		AndroidJNI.CallVoidMethod(currentActivity, MethodStartActivity, startActivityParameters);
		
		// Delete the global ref
		AndroidJNI.DeleteGlobalRef(GlobalIntentObject);
	}
	
	private jvalue GetFieldString(IntPtr classPtr, string fieldName)
	{
		
		IntPtr fieldId = AndroidJNI.GetStaticFieldID(classPtr,fieldName, "Ljava/lang/String;");
		jvalue fieldValue = new jvalue();
		fieldValue.l = AndroidJNI.GetStaticObjectField(classPtr, fieldId);
		return (fieldValue);
	}

It seems to work perfectly, no error messages in logcat or exceptions or any thing indicating that it doesn’t work.
But I do not get any chooser dialog on the android.
It could be that I make something wrong in my code, but I have tested a lot of variants of it and I still can’t get anything to show on the android.
I am starting to suspect that maybe the OpenGL context unity is running is putting itself on top in such a way that the ACTION_SEND intent doesn’t show up.
If that is the case, is there any way to tell unity to either pause the drawing, or to let an intent draw on top?

Tested again today with Unity 3.3 and Android version 2.3, and it still doesn’t work.
Anybody having any hint at all about this, or could it be a Unity bug?

how you call the method ?

I need to share screenshot to social platforms on Android. I am looking for a solution like this.

Did you resolve your issue? I don’t want to write a plugin for such a simple thing.

You may need to give permission on Android Manifest.xml file.

I tried this method, but it didn’t work for me. The application crashed.

Anyway, I wrote a small plugin and that did the trick. I wrote about it in this post.

btw, afaik there is no need to give any permissions.

I highly recommend creating an Android plugin as opposed to attempting to use 1:1 C#/Java using JNI.
Try using oferei’s guide as a starting point for creating a simple plugin .jar that logs something to the console.
From there you have native access to anything Android, at which point writing any future native Android code becomes FAR easier and quicker.

Once you can get this working you’ll be able to rule out any problems with the interface between C# → Java itself.