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

お知らせ

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

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

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

Read More
U30可茂ITインターンハッカソン

U30可茂ITインターンハッカソン

12月28,29日開催。2日間でアプリ開発の企画から完成までを目指す!U30可茂ITインターンハッカソンを開催します。

Read More

タグ

Flutter (110)初心者向け (28)イベント (18)Google Apps Script (15)Nextjs (12)可茂IT塾 (8)Firebase (7)riverpod (6)React (6)ChatGPT (5)vscode (5)デザイン (5)新卒 (4)就活 (4)Figma (4)Dart (4)JavaScript (4)お知らせ (4)FlutterWeb (3)Prisma (3)NestJS (3)Slack (3)TypeScript (3)ワーケーション (3)インターン (3)設計 (2)線型計画法 (2)事例 (2)Git (2)Image (2)File (2)Material Design (2)画像 (2)iOS (2)アプリ開発 (2)React Hooks (2)tailwindcss (2)社会人 (2)大学生 (2)RSS (1)Google (1)Web (1)CodeRunner (1)個人開発 (1)Android (1)Unity (1)WebView (1)Twitter (1)フルリモート (1)TextScaler (1)textScaleFactor (1)学生向け (1)supabase (1)Java (1)Spring Boot (1)shell script (1)正規表現 (1)パワーポイント (1)趣味 (1)モンスターボール (1)CSS (1)SCSS (1)Cupertino (1)ListView (1)就活浪人 (1)既卒 (1)保守性 (1)iPad (1)シェアハウス (1)スクレイピング (1)PageView (1)画面遷移 (1)flutter_hooks (1)Gmail (1)GoogleWorkspace (1)ShaderMask (1)google map (1)Google Places API (1)GCPコンソール (1)Google_ML_Kit (1)Vercel (1)Google Domains (1)DeepLeaning (1)深層学習 (1)Google Colab (1)コード生成 (1)GitHub Copilot (1)オンラインオフィス (1)オブジェクト指向 (1)クラスの継承 (1)ポリモーフィズム (1)LINE (1)Bitcoin (1)bitFlyer (1)コミュニティー (1)文系エンジニア (1)Freezed (1)permission_handler (1)flutter_local_notifications (1)markdown (1)GlobalKey (1)ValueKey (1)Key (1)アイコン (1)go_router (1)debug (1)datetime_picker (1)Apple Store Connect (1)FlutterGen (1)デバッグ (1)Widget Inspector (1)検索機能 (1)Shader (1)Navigator (1)メール送信 (1)Firebase App Distribution (1)Fastlane (1)Dio (1)CustomClipper (1)ClipPath (1)カスタム認証 (1)アニメーション (1)Arduino (1)ESP32 (1)経験談 (1)フリーランス (1)mac (1)csv (1)docker (1)GithubActions (1)Dialog (1)BI (1)LifeHack (1)ショートカット (1)Chrome (1)高校生 (1)キャリア教育 (1)非同期処理 (1)生体認証 (1)BackdropFilter (1)レビュー (1)getAuth (1)Algolia (1)コンサルティング (1)Symbol (1)

お知らせ

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

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

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

Read More
U30可茂ITインターンハッカソン

U30可茂ITインターンハッカソン

12月28,29日開催。2日間でアプリ開発の企画から完成までを目指す!U30可茂ITインターンハッカソンを開催します。

Read More