Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Call Android Email intent from Unity script

I have a feedback button in unity game, if the user clicks on it then it should launch an default email app with subject, email address filled already. I have done this in Android app but how to call it from unity?

Are there any other better approaches for feedback other than this?

like image 828
Chandra Eskay Avatar asked May 19 '16 06:05

Chandra Eskay


2 Answers

What you are doing is plugin. You don't need plugin for this.

You can simply send email with:

void sendEmail(string toEmail, string emailSubject, string emailBody)
{
    emailSubject = System.Uri.EscapeUriString(emailSubject);
    emailBody = System.Uri.EscapeUriString(emailSubject);
    Application.OpenURL("mailto:" + toEmail + "?subject=" + emailSubject + "&body=" + emailBody);
}

To send, call:

sendEmail("[email protected]", "Test", "This is a text\r\nAnother test\r\nAnd another text");

This will work on PC, Android and iOS. I don't know for Mac.

Now if you still want to use Android API's, you still don't need to make a plugin for this. You can use AndroidJavaObject and write your email code with Android API.

private static void SendMail(string subject, string body, bool useHTML)
{
    using (var intentClass = new AndroidJavaClass("android.content.Intent"))
    {
        // intent = new Intent(Intent.ACTION_SEND);
        using (var intentObject = new AndroidJavaObject("android.content.Intent", intentClass.GetStatic<string>("ACTION_SEND")))
        {
            // Setting text type
            if (useHTML)
                // intent.setType("text/html");
                intentObject.Call<AndroidJavaObject>("setType", "text/html");
            else
                // intent.setType("message/rfc822");
                intentObject.Call<AndroidJavaObject>("setType", "message/rfc822");

            // intent.putExtra(Intent.EXTRA_SUBJECT, emailSubject);
            intentObject.Call<AndroidJavaObject>("putExtra", intentClass.GetStatic<string>("EXTRA_SUBJECT"), subject);

            // Setting emailBody
            if (useHTML)
            {
                // intent.putExtra(Intent.EXTRA_TEXT, Html.fromHtml(emailBody));
                using (var html = new AndroidJavaClass("android.text.Html"))
                {
                    var htmlBody = html.CallStatic<AndroidJavaObject>("fromHtml", body);
                    intentObject.Call<AndroidJavaObject>("putExtra", intentClass.GetStatic<string>("EXTRA_TEXT"), htmlBody);
                }
            }
            else
            {
                intentObject.Call<AndroidJavaObject>("putExtra", intentClass.GetStatic<string>("EXTRA_TEXT"), body);
            }
            using (var unity = new AndroidJavaClass("com.unity3d.player.UnityPlayer"))
            {
                using (var currentActivity = unity.GetStatic<AndroidJavaObject>("currentActivity"))
                {
                    currentActivity.Call("startActivity", intentObject);
                }
            }
        }
    }
}

And to call it SendMail("test", "Message", false);. You can improve it and add more features to it. This last example was lifted from here.

like image 184
Programmer Avatar answered Oct 03 '22 22:10

Programmer


@Programmer's (native-method) answer is correct; but when the user is prompted to select an app to send the email, there's a good chance the user will have the possibility to select apps other than e-mail apps; e.g. WhatsApp. We don't want this to happen. As stated in the docs the way we could ensure that only e-mail apps will be shown to the user, is to use Intent.ACTION_SENDTO and intent.setData(Uri.parse("mailto:").

private void SendMail(string subject, string body)
{
    using (var intentClass = new AndroidJavaClass("android.content.Intent"))
    {
        // intent = new Intent(Intent.ACTION_SEND);
        using (var intentObject = new AndroidJavaObject("android.content.Intent", intentClass.GetStatic<string>("ACTION_SENDTO")))
        {
            //intent.setData(Uri.parse("mailto:"));
            var uriClass = new AndroidJavaClass("android.net.Uri");
            var uriObject = uriClass.CallStatic<AndroidJavaObject>("parse", "mailto:");
            intentObject.Call<AndroidJavaObject>("setData", uriObject);

            // intent.putExtra(Intent.EXTRA_SUBJECT, emailSubject);
            intentObject.Call<AndroidJavaObject>("putExtra", intentClass.GetStatic<string>("EXTRA_SUBJECT"), subject);
            //intentObject.Call<AndroidJavaObject>("putExtra", intentClass.GetStatic<string>("EXTRA_EMAIL"), "[email protected]");
            string[] email = { "[email protected]" };
            intentObject.Call<AndroidJavaObject>("putExtra", intentClass.GetStatic<string>("EXTRA_EMAIL"), email);

            // Setting emailBody
            intentObject.Call<AndroidJavaObject>("putExtra", intentClass.GetStatic<string>("EXTRA_TEXT"), body);
            using (var unity = new AndroidJavaClass("com.unity3d.player.UnityPlayer"))
            {
                using (var currentActivity = unity.GetStatic<AndroidJavaObject>("currentActivity"))
                {
                    currentActivity.Call("startActivity", intentObject);
                }
            }
        }
    }
}

Replace [email protected] with the e-mail you intend to send the e-mail to.

The question is, why do all this hassle instead of simply sending the e-mail like stated below:

void sendEmail(string toEmail, string emailSubject, string emailBody)
{
    emailSubject = System.Uri.EscapeUriString(emailSubject);
    emailBody = System.Uri.EscapeUriString(emailSubject);
    Application.OpenURL("mailto:" + toEmail + "?subject=" + emailSubject + 
"&body=" + emailBody);
}

You might want to add HTML or some non-Latin text (e.g. Japanese, Arabic) to your e-mail's body. using System.Uri.EscapeUriString is going to mess that up. In that case, the native method will be your method of choice.

like image 40
Flying Oyster Avatar answered Oct 03 '22 22:10

Flying Oyster