対象者
- Flutterを用いて電話発信やメール送信機能をアプリケーションに組み込みたい開発者
はじめに
Flutterアプリで電話を発信したり、メールを送信したいと思いまして、試しで実装しました。Androidは動作確認しましたが、iOSはしておりません(なんか、テスト環境で動かなそうだし)。
それにしても、何年も使ってきたurl_launcherですが、電話やメールを送るのに使用するのは初めてです!
ソース
Androidの設定
まずはAndroidの設定から見ていきましょう。AndroidManifest.xmlファイルを開き、以下のように追加します。
<queries>
<!-- Call support scheme -->
<intent>
<action android:name="android.intent.action.VIEW" />
<data android:scheme="tel" />
</intent>
<!-- Email support scheme -->
<intent>
<action android:name="android.intent.action.VIEW" />
<data android:scheme="mailto" />
</intent>
</queries>
iOSの設定
次にiOSの設定を見ていきます。Runner/Info.plistファイルを開き、以下のように追加します。
<key>LSApplicationQueriesSchemes</key>
<array>
<string>tel</string>
<string>mailto</string>
</array>
これらのスキームをプラットフォームに宣言することで、それらを使用することができます。
パッケージのインストール
次に、url_launcherパッケージをpubspec.yamlファイルに追加します。
flutter pub add url_launcher
flutter pub get
プログラム
パッケージをインポートします。
import 'package:url_launcher/url_launcher.dart';
電話の発信
117(時報)に電話を掛けるプログラムです。
void openPhoneCall() async {
final Uri callLaunchUri = Uri(
scheme: 'tel',
path: '117',
);
canLaunchUrl(callLaunchUri).then((value) {
if (value) {
launchUrl(callLaunchUri).then((value) {
print('launchUrl result: $value');
});
} else {
print('cannot call');
}
});
}
ここでは、url_launcherパッケージを利用してます。スキーム(電話の場合はtel)がミソです。
canLaunchUrlで該当のURLにアクセス可能か確認し、可能そうであればlaunchUrlで実行します。
メールの送信
メーラを起動するプログラムです。
void openEmail() {
final Uri emailLaunchUri = Uri(
scheme: 'mailto',
path: 'testtest@gmail.com',
query: _encodeQueryParameters(<String, String>{
'subject': 'It is subject',
'body': 'It is message',
}),
);
canLaunchUrl(emailLaunchUri).then((value) {
if (value) {
launchUrl(emailLaunchUri).then((value) {
print('launchUrl result: $value');
});
} else {
print('cannot call');
}
});
}
String? _encodeQueryParameters(Map<String, String> params) {
return params.entries
.map((MapEntry<String, String> e) =>
'${Uri.encodeComponent(e.key)}=${Uri.encodeComponent(e.value)}')
.join('&');
}
クエリパラメータをエンコードするためのヘルパーメソッドを使用しています。メールの送信では、スキームはmailtoを使用し、クエリにはメール送信用の2つのパラメータ、subjectとbodyを定義します。
電話の発信 by flutter_phone_direct_calle
url_launcherパッケージの記事書いていたら、「flutter_phone_direct_caller」というパッケージがあった。(Androidでは)こちらは、電話画面が表示した途端に電話が掛かるので、ユーザの手間が減ると思われる。(いきなり電話が掛かって驚くかも知れませんが)
flutter pub add flutter_phone_direct_caller
flutter pub get
import 'package:flutter_phone_direct_caller/flutter_phone_direct_caller.dart';
Future<bool?> _callNumber() {
const number = '117'; //set the number here
return FlutterPhoneDirectCaller.callNumber(number);
}
まとめ
この記事では、Flutterを使用して電話発信やメール送信機能を追加する方法を学びました。具体的には、url_launcherパッケージを使用し、特定のスキーム(電話の場合は’tel’、メールの場合は’mailto’)を使用してデバイスのデフォルトの通話やメールアプリを起動する方法を見てきました。この方法で、電話番号やメールアドレスを変更すれば、アプリから通話・メール送信することができます。
また、電話発信用の「flutter_phone_direct_caller」も紹介しました。
参考
全ソース
import 'package:flutter/material.dart';
import 'package:flutter_phone_direct_caller/flutter_phone_direct_caller.dart';
import 'package:url_launcher/url_launcher.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Column(
children: [
FilledButton(
onPressed: openPhoneCall,
child: Text('call'),
),
FilledButton(
onPressed: openEmail,
child: Text('email'),
),
FilledButton(
onPressed: _callNumber,
child: Text('call'),
),
],
));
}
void openPhoneCall() async {
final Uri callLaunchUri = Uri(
scheme: 'tel',
path: '117',
);
canLaunchUrl(callLaunchUri).then((value) {
if (value) {
launchUrl(callLaunchUri).then((value) {
print('launchUrl result: $value');
});
} else {
print('cannot call');
}
});
}
void openEmail() {
final Uri emailLaunchUri = Uri(
scheme: 'mailto',
path: 'testtest@gmail.com',
query: _encodeQueryParameters(<String, String>{
'subject': 'It is subject',
'body': 'It is message',
}),
);
canLaunchUrl(emailLaunchUri).then((value) {
if (value) {
launchUrl(emailLaunchUri).then((value) {
print('launchUrl result: $value');
});
} else {
print('cannot call');
}
});
}
String? _encodeQueryParameters(Map<String, String> params) {
return params.entries
.map((MapEntry<String, String> e) =>
'${Uri.encodeComponent(e.key)}=${Uri.encodeComponent(e.value)}')
.join('&');
}
Future<bool?> _callNumber() {
const number = '117'; //set the number here
return FlutterPhoneDirectCaller.callNumber(number);
}
}