4

I'm trying to send an email programmatically in kotlin.

Here's my code, which I translated from a java example I found on the Web.

package com.example.emaildemo

import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;

class MainActivity: AppCompatActivity() {

    override fun onCreate(savedInstanceState:Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val editTextTo:EditText  = findViewById(R.id.editText)
        val editTextSubject:EditText = findViewById(R.id.editText2)
        val editTextMessage:EditText = findViewById(R.id.editText3)
        val button1:Button = findViewById(R.id.button)

        button1.setOnClickListener(View.OnClickListener{

          val to = editTextTo.getText().toString()
          val subject = editTextSubject.getText().toString()
          val message = editTextMessage.getText().toString()

          val intent = Intent(Intent.ACTION_SEND)
          val addressees = arrayOf(to)
          intent.putExtra(Intent.EXTRA_EMAIL, addressees)
          intent.putExtra(Intent.EXTRA_SUBJECT, subject)
          intent.putExtra(Intent.EXTRA_TEXT, message)
          intent.setType("message/rfc822")
          startActivity(Intent.createChooser(intent, "Select Email Sending App :"))
       })
   }
}

It seems to work correctly, except that the "TO" field isn't copied into the user's email app. The java code said:

intent.putExtra(Intent.EXTRA_EMAIL, new String[]{TO}); 

and the android developer docs say that Intent.EXTRA_EMAIL is "A string array of all "To" recipient email addresses." How should I define the addressees variable?

EDIT: I've discover that if I hard code my email address,

val addressees = arrayOf("me@email.com")

then the app works as expected. When I get to the email app, my address is in the "To:" field, and I can send mail to myself. If, however, the I type the same address in the program, it doesn't show up in the email client. Moreover, when I look at it under the debugger, the intent shows exactly the same values both ways. Curiouser and curiouser.

EDIT2

Here is my XML file. (Somehow I can't get the first two lines indented correctly.)

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:textSize="18dp"
    android:text="To"
    android:id="@+id/textView"
    android:layout_alignParentTop="true"
    android:layout_alignParentLeft="true"
    android:layout_alignParentStart="true" />

<EditText
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:id="@+id/editText"
    android:layout_below="@+id/textView"
    android:layout_centerHorizontal="true"
    />

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:textSize="18dp"
    android:text="Subject"
    android:id="@+id/textView2"
    android:layout_below="@+id/editText"
    android:layout_alignParentLeft="true"
    android:layout_alignParentStart="true" />

<EditText
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:id="@+id/editText2"
    android:layout_below="@+id/textView2"
    android:layout_centerHorizontal="true" />

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:textSize="18dp"
    android:text="Message"
    android:id="@+id/textView3"
    android:layout_below="@+id/editText2"
    android:layout_alignParentLeft="true"
    android:layout_alignParentStart="true" />

<EditText
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:inputType="textMultiLine"
    android:lines="4"
    android:id="@+id/editText3"
    android:layout_below="@+id/textView3"
    android:layout_centerHorizontal="true" />

<Button
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Click Here To Send Email from android application programmatically"
    android:id="@+id/button"
    android:layout_below="@+id/editText3"
    android:layout_centerHorizontal="true"
    android:layout_marginTop="44dp" />
</RelativeLayout>
Les
  • 10,335
  • 4
  • 40
  • 60
saulspatz
  • 5,011
  • 5
  • 36
  • 47
  • what's wrong about you? Kotlin `arrayOf(...)` is equivalent to Java `String[]`. – holi-java Jul 30 '17 at 18:13
  • @holi-java Then why doesn't this work? – saulspatz Jul 30 '17 at 18:21
  • :), I'm not an android developer, and you didn't give any information what happened that nobody know why didn't work. it seems to your mime-type is wrong, maybe this can helped you: https://stackoverflow.com/questions/8701634/send-email-intent – holi-java Jul 30 '17 at 18:23

2 Answers2

5

Your TO statement looks right, I don't think you need to be explicit (i.e, using arrayOf<String>(to)).

EDIT

Based on your last update, to is not being recognized as a String. The following code works...

            val to = "person@gmail.com"
            val subject = "Test"
            val message = "Test"

            val intent = Intent(Intent.ACTION_SEND)
            val addressees = arrayOf(to)
            intent.putExtra(Intent.EXTRA_EMAIL, addressees)
            intent.putExtra(Intent.EXTRA_SUBJECT, subject)
            intent.putExtra(Intent.EXTRA_TEXT, message)
            intent.setType("message/rfc822")
            startActivity(Intent.createChooser(intent, "Send Email using:"));

The call to editTextTo.getText().toString() is returning a builder or something other than a true String. Instead try calling arrayOf(to.toString())

EDIT2

Here is an example of code that works, i.e., fills in the "To" field in the email app.

package com.x.edittextexp

import android.content.Intent
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.view.View
import android.widget.Button
import android.widget.EditText

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val button: Button = findViewById(R.id.button)
        val editTextTo: EditText = findViewById(R.id.editTextTo)

        button.setOnClickListener(View.OnClickListener {
            val to = editTextTo.getText().toString()
            val subject = "Test"
            val message = "Test"

            val intent = Intent(Intent.ACTION_SEND)
            val addressees = arrayOf(to)
            intent.putExtra(Intent.EXTRA_EMAIL, addressees)
            intent.putExtra(Intent.EXTRA_SUBJECT, subject)
            intent.putExtra(Intent.EXTRA_TEXT, message)
            intent.setType("message/rfc822")
            startActivity(Intent.createChooser(intent, "Send Email using:"));
        })
    }
}

And the xml looks like this

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:orientation="vertical">

<EditText
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:inputType="textEmailAddress"
    android:hint="person@gmail.com"
    android:id="@+id/editTextTo"/>

<Button
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="BUTTON"
    android:id="@+id/button"/>
</LinearLayout>

As you can see, the differences are trivial, but this works and yours doesn't. I would suspect the problem is in your XML file. Could you post it?

Les
  • 10,335
  • 4
  • 40
  • 60
1

I tried Les's suggestion of using arrayOf(to.toString()), but android studio grayed out .toString() indicating that it knew it was a string already. Then I tried being more explicit:

val addressees: Array<String> = arrayOf(to)

and it worked! I don't understand this at all. It doesn't seem like kotlin should have any trouble with the type inference. Perhaps some guru will see this and explain it; I'd be interested and grateful.

saulspatz
  • 5,011
  • 5
  • 36
  • 47
  • my last edit uses the same construct, and Kotlin has no problem interfering the type. – Les Jul 31 '17 at 01:20
  • I had it defined as an array of CharSequence and that wasn't working. Thanks for the tip. – nasch Aug 30 '19 at 17:56