Flutterでメールを送る方法[コピペで3分!]

image

はじめに

Flutterでアプリを作成する際に、

  • 「メールを送りたい!」
  • 「ユーザーにメールを送ってもらいたい!」
    というケースが多々あると思います。(お問い合わせ機能など)
    この記事を読めば、数分で実装完了しちゃうと思います。

以下のようなサンプルアプリを使って説明します。
メールアプリ

開発環境

  • Flutter version 2.10.3
  • Dart version 2.16.1
  • DevTools version 2.9.2

flutter_email_senderをインストール

Flutter製のアプリからメールを送信するために、flutter_email_senderというパッケージを使用します。
以下のコマンドで、flutter_email_senderをインストールしてください。

flutter pub add flutter_email_sender
flutter pub get

詳しくはflutter_email_senderのインストール画面を参考にしてください。

Android用のセットアップ

androidの場合は、android/app/src/main/AndroidManifest.xmlに以下のコードを追加してください。
package="com.mycompany.myappの部分はあなたのアプリのパッケージ名を入れてください。

<manifest package="com.mycompany.myapp">
  <queries>
    <intent>
      <action android:name="android.intent.action.SENDTO" />
      <data android:scheme="mailto" />
    </intent>
  </queries>
</manifest>

参考
https://pub.dev/packages/flutter_email_sender#android-setup

flutter_email_senderのコードサンプル

以下でサンプルコードをご紹介します。

メール送信処理

Future<void> _sendEmail() async {
    final email = Email(
      body: _bodyController.text,
      subject: _subjectController.text,
      recipients: [_emailController.text],
      cc: [_ccController.text],
      bcc: [_bccController.text],
      isHTML: false,
    );

    await FlutterEmailSender.send(email);
  }

メール送信アプリのコード全文

import 'package:flutter/material.dart';
import 'package:flutter_email_sender/flutter_email_sender.dart';

void main() => runApp(const MailApp());

class MailApp extends StatelessWidget {
  const MailApp({Key? key}) : super(key: key);

  
  Widget build(BuildContext context) {
    return const MaterialApp(
      home: MailScreen(),
    );
  }
}

class MailScreen extends StatefulWidget {
  const MailScreen({Key? key}) : super(key: key);

  
  State<MailScreen> createState() => _MailScreenState();
}

class _MailScreenState extends State<MailScreen> {
  late TextEditingController _emailController;
  late TextEditingController _bodyController;
  late TextEditingController _subjectController;
  late TextEditingController _ccController;
  late TextEditingController _bccController;

  
  void initState() {
    super.initState();
    _emailController = TextEditingController();
    _bodyController = TextEditingController();
    _subjectController = TextEditingController();
    _ccController = TextEditingController();
    _bccController = TextEditingController();
  }

  
  void dispose() {
    _emailController.dispose();
    _bodyController.dispose();
    _subjectController.dispose();
    _ccController.dispose();
    _bccController.dispose();
    super.dispose();
  }

  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('メール送信')),
      body: SingleChildScrollView(
        child: Padding(
          padding: const EdgeInsets.symmetric(horizontal: 16),
          child: Column(
            children: [
              const SizedBox(height: 40),
              TextFormField(
                controller: _emailController,
                decoration: InputDecoration(hintText: '宛先'),
              ),
              const SizedBox(height: 20),
              TextFormField(
                controller: _ccController,
                decoration: InputDecoration(hintText: 'cc'),
              ),
              const SizedBox(height: 20),
              TextFormField(
                controller: _bccController,
                decoration: InputDecoration(hintText: 'bcc'),
              ),
              const SizedBox(height: 20),
              TextFormField(
                controller: _subjectController,
                decoration: InputDecoration(hintText: '件名'),
              ),
              const SizedBox(height: 20),
              TextFormField(
                controller: _bodyController,
                decoration: InputDecoration(hintText: '本文'),
              ),
              const SizedBox(height: 20),
              ElevatedButton(onPressed: _sendEmail, child: Text('送信する')),
              const SizedBox(height: 40),
            ],
          ),
        ),
      ),
    );
  }

  Future<void> _sendEmail() async {
    final email = Email(
      body: _bodyController.text,
      subject: _subjectController.text,
      recipients: [_emailController.text],
      cc: [_ccController.text],
      bcc: [_bccController.text],
      isHTML: false,
    );

    await FlutterEmailSender.send(email);
  }
}

注意点

iosシミュレータなど、メールアプリが入っていない端末でテストすると以下のようなエラーになってしまいます。
Unhandled Exception: PlatformException(not_available, No email clients found!, null, null)
androidやiosの実機でテストしてみてください。

android実機でのテスト例

実機テストは圧倒的にandroidの方がやりやすいので、androidでテストしてみました。

メールアドレスの入力

テストのメールアドレスを以下のように入力してみます。
メールアドレス入力後の画面

メール送信ボタンを押下

メール送信ボタンを押下すると、端末内のメールアプリに遷移します。
ログインしているアカウントのメールアドレスから、指定したメールアドレスにメールを送信する形になります。
端末のメールアプリの画面
ちゃんとメールのサンプルアプリで入力した内容が、端末内のアプリに反映されていますね!

メールアドレスのバリデーション(+α)

メールアドレスを入力する際に、正しい形式で入力されているかチェックしたいケースもあると思います。
Flutterで正規表現を用いたemailのvalidationを実装という記事も書いているので、こちらが参考になると思います。

最後に

いかがでしたか。
こんなにも簡単にメール送信機能が実装できてしまいます。
アプリのお問い合わせなど、どのアプリでも必要になってくる機能だと思います。
ぜひ参考にしてください。

参考

https://pub.dev/packages/flutter_email_sender

お知らせ

5月28日開催のアプリ開発講座の参加者募集中!!

5月28日開催のアプリ開発講座の参加者募集中!!

5月28日にアプリ開発講座を開催します!会場は岐阜県美濃加茂市のコワーキングスペース「こやぁね」です。興味のある方は是非ご参加ください!

Read More
可茂IT塾ではFlutterインターンを募集しています!

可茂IT塾ではFlutterインターンを募集しています!

可茂IT塾ではFlutterインターンを募集しています!可茂IT塾のエンジニアの判断で、一定以上のスキルをを習得した方には有給でのインターンも受け入れています。

Read More

お知らせ

5月28日開催のアプリ開発講座の参加者募集中!!

5月28日開催のアプリ開発講座の参加者募集中!!

5月28日にアプリ開発講座を開催します!会場は岐阜県美濃加茂市のコワーキングスペース「こやぁね」です。興味のある方は是非ご参加ください!

Read More
可茂IT塾ではFlutterインターンを募集しています!

可茂IT塾ではFlutterインターンを募集しています!

可茂IT塾ではFlutterインターンを募集しています!可茂IT塾のエンジニアの判断で、一定以上のスキルをを習得した方には有給でのインターンも受け入れています。

Read More