目次
概要
Flutterを使用していて、時にサービスの内容をユーザーに通知したりするときもあるだろう。
そんなときはFlutterで入力した内容を元にメールアプリを起動することができる。
手段は二つ。
- Flutterアプリ内でメールアプリを起動する
- Flutterアプリからメールアプリに切り替える
これはWebブラウザでも、アプリ内でWebページを表示するか、ブラウザで表示するかのようなものだ。
今回は、「Flutterアプリからメールアプリに切り替える」というものをやってみる。
実装方法
メール送信に必要なパッケージを追加する
dependencies:
flutter:
sdk: flutter
url_launcher: ^6.2.2
追加したら以下のコマンドを実行してパッケージのインストール状態を更新しよう。
$ flutter pub upgrade
ソースコード
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'SendMailView/SendMailView.dart';
void main() async{
runApp(const ProviderScope(child: MyApp()));
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepOrange),
useMaterial3: true,
),
home: SendMailView(),
);
}
}
import 'package:flutter_riverpod/flutter_riverpod.dart';
final sendMailModelProvider = Provider((ref) => SendMailModel());
class SendMailModel {
}
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'SendMailModel.dart';
final sendMailRepositoryProvider = Provider((ref) => SendMailRepositoryImpl(model: ref.read(sendMailModelProvider)));
abstract class SendMailRepository {
}
class SendMailRepositoryImpl implements SendMailRepository {
SendMailRepositoryImpl({required SendMailModel model}): _model = model;
final SendMailModel _model;
}
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'SendMailViewModel.dart';
class SendMailView extends ConsumerWidget {
SendMailView({Key? key}) : super(key: key);
SendMailViewModel _viewModel = SendMailViewModel();
@override
Widget build(BuildContext context, WidgetRef ref) {
return Scaffold(
appBar: AppBar(
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
title: const Text("メールを送ろう"),
),
body: Builder(
builder: ((context) => SingleChildScrollView(
child: Column(
children: [
_sendTo(),
_mailTitle(),
_carbonCopiesTextField(),
_blindCarbonCopiesTextField(),
_mailMassage(),
_sendButton()
]
)
))
)
);
}
Widget _sendTo() {
return Column(
children: [
const Text("宛先"),
TextField(
controller: _viewModel.recipientsEditingController,
obscureText: false,
decoration: const InputDecoration(
border: OutlineInputBorder(),
labelText: "",
),
)
],
);
}
Widget _mailTitle() {
return Column(
children: [
const Text("件名"),
TextField(
controller: _viewModel.titleEditingController,
obscureText: false,
decoration: const InputDecoration(
border: OutlineInputBorder(),
labelText: "",
),
)
],
);
}
Widget _carbonCopiesTextField() {
return Column(
children: [
const Text("CC:"),
TextField(
controller: _viewModel.carbonCopiesEditingController,
obscureText: false,
decoration: const InputDecoration(
border: OutlineInputBorder(),
labelText: "",
),
)
],
);
}
Widget _blindCarbonCopiesTextField() {
return Column(
children: [
const Text("BCC:"),
TextField(
controller: _viewModel.blindCarbonCopiesEditingController,
obscureText: false,
decoration: const InputDecoration(
border: OutlineInputBorder(),
labelText: "",
),
)
],
);
}
Widget _mailMassage() {
return Column(
children: [
const Text("本文"),
TextField(
controller: _viewModel.mailBodyEditingController,
obscureText: false,
maxLines: 6,
keyboardType: TextInputType.multiline,
decoration: const InputDecoration(
border: OutlineInputBorder(),
labelText: "",
),
),
],
);
}
Widget _sendButton() {
return OutlinedButton(
onPressed: () { _viewModel.sendMail(); },
child: const Text("送信")
);
}
}
import 'package:flutter/widgets.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_email_sender/flutter_email_sender.dart';
import 'package:url_launcher/url_launcher.dart';
import 'SendMailRepository.dart';
final sendMailViewModelProvider = ChangeNotifierProvider((ref) => SendMailViewModel(repository: ref.read(sendMailRepositoryProvider)));
class SendMailViewModel extends ChangeNotifier {
SendMailRepository? repository;
var recipientsEditingController = TextEditingController();
var titleEditingController = TextEditingController();
var carbonCopiesEditingController = TextEditingController();
var blindCarbonCopiesEditingController = TextEditingController();
var mailBodyEditingController = TextEditingController();
SendMailViewModel({this.repository}) {
}
void sendMail() {
launchMailApp();
}
Future<bool> launchMailApp() {
final Uri emailUri = Uri(
scheme: 'mailto',
path: recipientsEditingController.text,
queryParameters: {
'subject': titleEditingController.text,
'cc':carbonCopiesEditingController.text,
'bcc':blindCarbonCopiesEditingController.text,
'body':mailBodyEditingController.text
}
);
return launchUrl(
emailUri
);
}
}
スクリーンショット
左:入力画面
右:送信ボタン押下時の


詳細
今回の目玉はこれだ。
まずはインストールしたパッケージをimportしよう。
これを書かないとメールアプリを立ち上げるのに必要なものが使えない。
import 'package:url_launcher/url_launcher.dart';
そして、launchMailAppメソッドの中身が大事だ。
URIオブジェクトを生成して、launchUrlメソッドに渡してあげればメールアプリを立ち上げることができる。
大元は画面遷移と変わらない。リンクをタップするとLINEが立ち上がったりする経験があると思う。
void sendMail() {
launchMailApp();
}
Future<bool> launchMailApp() {
final Uri emailUri = Uri(
scheme: 'mailto',
path: recipientsEditingController.text,
queryParameters: {
'subject': titleEditingController.text,
'cc':carbonCopiesEditingController.text,
'bcc':blindCarbonCopiesEditingController.text,
'body':mailBodyEditingController.text
}
);
return launchUrl(
emailUri
);
}
設定内容は以下のようになる。
引数名(キー名) | 内容 |
scheme | 使用するアプリ名 メールの場合は「mailto」になる |
path | メールの宛先 「,」で区切ることで複数相手に送信することができる |
queryParameters | URIに補助的な情報を格納するためのもの。 会員制のサイトへアクセスすると、 URLの「?」以降にユーザーIDが表示されていたりすると思う。 それと同じようなものだ。 |
subject | メールの件名 |
cc | CCの宛先。 「,」で区切ることで複数人を設定できる |
bcc | BCCの宛先。 「,」で区切ることで複数人を設定できる |
body | メールの本文 |
そして、それらを設定してlaunchUrlメソッドに上記で作成したオブジェクトを渡すと、
その入力内容が入力された状態でメールアプリを起動することができる。
ただ、注意点として、AndroidにおいてもiOSにおいても、端末の標準メールアプリにログインしておくことが大前提だ。
もし企業で使うなら、その企業アカウントでログインした端末上で操作しよう。
また、今回はTextFieldに入力された文字列を取得したり、TextFieldが複数行入力できたりと、いろいろと使える項目も含まれている。