以下の tweet に関する話。
アプリからメール作成しようとした時に URI 指定すると Gmail では件名と本文が消えてしまう?
— nash (@nashcft) December 26, 2019
ACTION_SENDTO の Intent の食べ方が Gmail と Outlook で違うのなんなの...
— nash (@nashcft) December 26, 2019
Intent の data に設定する mailto: に送信先をつなげるのではなく EXTRA_EMAIL で渡せば Gmail でも送信先と件名と本文全部食べてくれる
— nash (@nashcft) December 26, 2019
発端
開発中のアプリでアプリ内から件名や本文テンプレート入りのメールを送る機能を実装して人に見てもらったら件名と本文が出ないんだけどって報告が来て、調べてみると件名や本文が送る内容によって出たり出なかったりした。あと報告で使われてたアプリが 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 では Intent に与える data (URI) の mailto:
の後にメールアドレスが続くと、 extra で指定したパラメータを無視するという挙動をとるらしいことがわかった。そこで、data ではメールアドレスを指定せず mailto:
のみとし、かわりに Intent
がデフォルトで持っている key の一つである EXTRA_EMAIL
で送信先を指定するようにしたところ、 Gmail でも送信先、件名、本文全てを作成するメールに反映してくれるようになった。
この設定で 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 見に行ったら普通にこう書けよって解説あったのでちゃんとリファレンス読んで実装しようねってなった。
それはそうと挙動確認用のサンプルコードがあるので、Gmail と Outlook 以外のメールアプリを使用した場合の挙動はどうなるの? というのが気になったらお使いください。