nashcft's blog

時々何か書く。

Android: アプリからメールアプリを開く時の Intent の設定とメールアプリの挙動について

以下の tweet に関する話。

発端

開発中のアプリでアプリ内から件名や本文テンプレート入りのメールを送る機能を実装して人に見てもらったら件名と本文が出ないんだけどって報告が来て、調べてみると件名や本文が送る内容によって出たり出なかったりした。あと報告で使われてたアプリが Gmail だったのだけど Outlook で開いてみたらどのメールもちゃんと件名と本文が反映されてることがわかった。

その時のコードの雰囲気と挙動

大雑把に問題の箇所を取り出すと以下のような感じ:

fun createEmail() {
  startActivity(createMailToIntent(address, subject, text))
}

fun createMailToIntent(
  address: String?,
  subject: String,
  text: String
): Intent {
  val intent = Intent(Intent.ACTION_SENDTO, Uri.parse("mailto:${address ?: ""}")).apply {
    putExtra(Intent.EXTRA_SUBJECT, subject)
    putExtra(Intent.EXTRA_TEXT, text)
    flags = Intent.FLAG_ACTIVITY_NEW_TASK
  }
  return Intent.createChooser(intent, "Select an app."))
}

作成するメールの種類と Gmail, Outlook の挙動を確認すると、送信先メールアドレスの有無が関係しているようだった:

  • メールアドレスなし
    • Gmail -> 件名・本文が反映される
    • Outlook -> 件名・本文が反映される
  • メールアドレスあり
    • Gmail -> 件名・本文が反映されない
    • Outlook -> 件名・本文が反映される

調べてわかったこと

Gmail では Intent に与える data (URI) の mailto: の後にメールアドレスが続くと、 extra で指定したパラメータを無視するという挙動をとるらしいことがわかった。そこで、data ではメールアドレスを指定せず mailto: のみとし、かわりに Intent がデフォルトで持っている key の一つである EXTRA_EMAIL送信先を指定するようにしたところ、 Gmail でも送信先、件名、本文全てを作成するメールに反映してくれるようになった。

developer.android.com

この設定で Outlook を選択しても同様に送信先と件名、本文を反映してくれたので、今回はとりあえず extra で指定する方法に修正することにした。

この後ちょっと気になってURIと extra の両方でメールアドレスを設定したときに Outlook はどう処理するのかというのを試してみたところ全部作成メールに反映してくれた。なのでこの場合 mailto: の後のアドレスと EXTRA_EMAIL で指定したアドレスの2つが to: に入力されてしまい、まあ意図的にこういう送信先設定はしないよねということで使い道はなさそう。

修正後のコード

fun createEmail() {
  startActivity(createMailToIntent(address, subject, text))
}

fun createMailToIntent(
  address: String?,
  subject: String,
  text: String
): Intent {
  val intent = Intent(Intent.ACTION_SENDTO, Uri.parse("mailto:")).apply {
    putExtra(Intent.EXTRA_EMAIL, arrayOf(address ?: ""))
    putExtra(Intent.EXTRA_SUBJECT, subject)
    putExtra(Intent.EXTRA_TEXT, text)
    flags = Intent.FLAG_ACTIVITY_NEW_TASK
  }
  return Intent.createChooser(intent, "Select an app."))
}

おわりに

ここまで書いてから Android Developer 見に行ったら普通にこう書けよって解説あったのでちゃんとリファレンス読んで実装しようねってなった。

developer.android.com

それはそうと挙動確認用のサンプルコードがあるので、GmailOutlook 以外のメールアプリを使用した場合の挙動はどうなるの? というのが気になったらお使いください。

github.com