Reputation: 67
I am attempting to create and send an email (using Gmail app) from user-supplied information entered into a simple Xamarin.Android mobile app. I am new to Xamarin.Android and have not been able to find clear guidance on this issue online.
Using the code below, I am able to gather text and create an email Intent that uses the user-provided email address and a hard-coded subject line. But the code for adding body text to the email is not working (the Gmail app opens and the email address and subject line are correct, but the body of the email is blank).
[Activity(Label = @"HelloWorld-TestMobileApp", MainLauncher = true, Icon = "@drawable/icon")]
public class MainActivity : Activity
{
public int ClickCount { get; set; } = 0;
public string EmailAddress { get; set; }
public string EmailText { get; set; }
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
// Set our view from the "main" layout resource
SetContentView(Resource.Layout.Main);
// Get our buttons from the layout resource,
// and attach a events to them
Button clickIncrementerButton = FindViewById<Button>(Resource.Id.ClickIncrementer);
Button sendEmailButton = FindViewById<Button>(Resource.Id.sendEmailButton);
EditText enterEmailAddressButton = FindViewById<EditText>(Resource.Id.editEmail);
EditText enterEmailTextButton = FindViewById<EditText>(Resource.Id.emailText);
clickIncrementerButton.Click += delegate
{
ClickCount++;
clickIncrementerButton.Text = string.Format("{0} clicks!", ClickCount);
};
enterEmailAddressButton.TextChanged += delegate
{
EmailAddress = enterEmailAddressButton.Text;
};
enterEmailTextButton.TextChanged += delegate
{
EmailText = enterEmailTextButton.Text;
};
sendEmailButton.Click += delegate
{
List<string> emailBody = new List<string>
{
"Hello from Xamarin.Android!\n",
"Number of clicks = " + ClickCount + "\n",
EmailText
};
var email = new Intent(Intent.ActionSend);
email.PutExtra(Intent.ExtraEmail, new string[] {EmailAddress}); // Working 09/24/2016
email.PutExtra(Intent.ExtraSubject, "Hello World Email"); // Working 09/24/2016
email.PutStringArrayListExtra(Intent.ExtraText, emailBody); // NOT Working 09/24/2016
email.SetType("message/rfc822");
try
{
StartActivity(email);
}
catch (Android.Content.ActivityNotFoundException ex)
{
Toast.MakeText(this, "There are no email applications installed.", ToastLength.Short).Show();
}
};
}
Can anyone show me how I can pre-format and include the email body text in the email Intent, without hard-coding the entire body text string? (Other email-sending critiques and guidance for Xamarin.Android apps is also welcome!)
I want to be able to include information that the user enters in the app, so I want to be able to include variables in the body text (I do not want to hard-code the body text).
Thank you!
Upvotes: 0
Views: 1585
Reputation: 14750
The problem is that the body has to be a text as well. Just combine your string list to one string by changing the line to:
email.PutExtra(Intent.ExtraText, string.Join("", emailBody));
BTW: You don't need to register for the changes of the TextViews. You can read their values directly when opening the intent. I'd write it like this:
[Activity(Label = @"HelloWorld-TestMobileApp", MainLauncher = true, Icon = "@drawable/icon")]
public class MainActivity2 : Activity
{
private Button _incrementerButton;
private Button _emailButton;
private EditText _addressField;
private EditText _emailField;
public int ClickCount { get; set; } = 0;
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
// Set our view from the "main" layout resource
SetContentView(Resource.Layout.Main);
// Get our buttons from the layout resource,
// and attach a events to them
_incrementerButton = FindViewById<Button>(Resource.Id.ClickIncrementer);
_emailButton = FindViewById<Button>(Resource.Id.sendEmailButton);
_addressField = FindViewById<EditText>(Resource.Id.editEmail);
_emailField = FindViewById<EditText>(Resource.Id.emailText);
}
protected override void OnStart()
{
base.OnStart();
// register event handlers
_incrementerButton.Click += IncrementerButtonOnClick;
_emailButton.Click += SendEmailButtonOnClick;
}
protected override void OnStop()
{
//deregister event handlers
_emailButton.Click -= SendEmailButtonOnClick;
_incrementerButton.Click -= IncrementerButtonOnClick;
base.OnStop();
}
private void IncrementerButtonOnClick(object sender, EventArgs eventArgs)
{
ClickCount++;
_incrementerButton.Text = string.Format("{0} clicks!", ClickCount);
}
private void SendEmailButtonOnClick(object sender, EventArgs eventArgs)
{
// build the body
var emailText = new StringBuilder();
emailText.AppendLine("Hello from Xamarin.Android!");
emailText.AppendFormat("Number of clicks = {0}", ClickCount);
emailText.AppendLine();
emailText.Append(_emailField.Text);
// build the intent
var email = new Intent(Intent.ActionSend);
email.PutExtra(Intent.ExtraEmail, new string[] { _addressField.Text });
email.PutExtra(Intent.ExtraSubject, "Hello World Email");
email.PutExtra(Intent.ExtraText, emailText.ToString());
email.SetType("message/rfc822");
try
{
StartActivity(email);
}
catch (Android.Content.ActivityNotFoundException ex)
{
Toast.MakeText(this, "There are no email applications installed.", ToastLength.Short).Show();
}
}
}
I'm using a StringBuilder
to create the E-Mail body. And implement the event handlers in methods instead of anonymous delegates. The reason is, that I want to be able to deregister the event handlers via -=
in OnStop
. This is always important, because not deregistered event handlers will cause memory leaks.
Upvotes: 1