大阪市中央区 システムソフトウェア開発会社

営業時間:平日09:15〜18:15
MENU

Androidアプリからメーラーを起動

著者:北本 敦
公開日:2022/05/03
最終更新日:2022/05/03
カテゴリー:技術情報
タグ:

北本です。
ブログ記事の題材にするために作成するAndroidアプリのネタを考えていました。

弊社の社員の多くは、私も含め様々な現場に出て作業しているので、労働時間を管理するため、もし残業をした場合はメール等で報告をしています(そもそも残業をほとんどしていない人も多いみたいですが)。今回はそこから発想したネタです。

以下のような画面のアプリを作成します。

残業時間を入力するEditTextと、「メールアプリを起動」ボタンがあるだけのシンプルな画面です。
ボタンをタップすると
アドレス「test@example.com」
件名「残業」
本文「本日の残業は{残業時間に入力した値}時間です。」
が入力された状態でメールアプリが起動するようにします。

 

OvertimeWorkReportという名前でプロジェクトを作成し、ビューバインディングを有効にしてから、画面作成とコーディングを行います。

※ビューバインディングを有効にする方法については以前の記事をご参照ください。

画面レイアウトXML
activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <Button
        android:id="@+id/buttonLaunchMailer"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="24dp"
        android:text="メールアプリを起動"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent" />

    <TextView
        android:id="@+id/textViewOvertime"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="残業時間"
        app:layout_constraintBottom_toBottomOf="@+id/editTextOvertime"
        app:layout_constraintEnd_toStartOf="@+id/editTextOvertime"
        app:layout_constraintTop_toTopOf="@+id/editTextOvertime" />

    <EditText
        android:id="@+id/editTextOvertime"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:ems="10"
        android:inputType="numberDecimal"
        app:layout_constraintBottom_toTopOf="@+id/buttonLaunchMailer"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.542"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

コード
MainActivity.kt

package com.example.overtimeworkreport

import android.content.Intent
import android.net.Uri
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import com.example.overtimeworkreport.databinding.ActivityMainBinding

class MainActivity : AppCompatActivity() {
    private lateinit var binding: ActivityMainBinding
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)

        binding.buttonLaunchMailer.setOnClickListener{
            val addresses = arrayOf("test@example.com")
            val subject = "残業"
            val text = "本日の残業は${binding.editTextOvertime.text}時間です。"

            val intent = Intent(Intent.ACTION_SENDTO).apply{
                data = Uri.parse("mailto:")
                putExtra(Intent.EXTRA_EMAIL, addresses)
                putExtra(Intent.EXTRA_SUBJECT, subject)
                putExtra(Intent.EXTRA_TEXT, text)
            }
            if(intent.resolveActivity(packageManager) != null){
                startActivity(intent)
            }
        }
    }
}

暗黙的インテントでアクションにACTION_SENDTOを設定することで、メッセージ送信アプリを呼び出します。ここで、dataにURI文字列「mailto:」を渡すことで、呼び出すのをメールアプリに限定できるようです。さらに、エクストラに値を設定することで、宛先、件名、本文なども連携できます。
・EXTRA_EMAIL:宛先
・EXTRA_SUBJECT:件名
・EXTRA_TEXT:本文

if(intent.resolveActivity(packageManager) != null)ではインテントを処理できるアプリが存在するかをチェックし、存在すればstartActivityでアプリを起動します。

参考:https://developer.android.com/guide/components/intents-common?hl=ja#Email

 

上記のようなコードを書くだけだと、古いバージョンのAndroidでは期待通りに動作するものの、API 30だと、メールアプリがインストールされているはずなのに、intent.resolveActivity(packageManager)がnullになってしまい起動できませんでした。

 

API 30以降で動作させるには、以下のようにマニフェストに<queries>要素を追加する必要があります。

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.overtimeworkreport">
    <queries>
        <intent>
            <action android:name="android.intent.action.SENDTO" />
            <data android:scheme="mailto" />
        </intent>
    </queries>

    <!-- 中略 -->

</manifest>

初めはactionを追加するだけではうまくいかず戸惑いました。
どうやらdataの方も追加する必要もあったようです。

動かしてみると以下のようになります。

タップ後

今回作ったものに関しては、取り敢えずメールアプリを起動させられるかを試すのが目的でしたので、残業時間の箇所以外は決め打ちで汎用性がなく使い物にならない代物です。次の機会があれば、文言等をカスタマイズできるようにしたり、残業時間をデフォルトで初期入力するなど、もう少しまともに使えるようにしてみたいと思います。

    上に戻る