Flutter

【Flutter】Android11以降のお問い合わせ実装 【コピペでイケル】

僕のFlutterアプリのお問い合わせは、url_launcherパッケージを使ってメーラーを起動させ、そこからお問い合わせしてもらうようにしています。

自アプリから他のアプリ(gmailなど)を起動させるには、Androidでは
「QUERY_ALL_PACKAGES」
パーミッションをAndroidManifestに追加する必要がありますが、年々セキュリティが厳しくなってきて、QUERY_ALL_PACKAGESパーミッションを追加したアプリの審査は余程の理由が無い限り通らなくなりました。

iOSは何もしなくても普通に動きます。

という訳で、この記事では、その辺の対処方法と、僕のお問い合わせの実装を共有します。
コピペしてボタンに割り当てれば、 一瞬でお問い合わせ機能が完成です!🔥

 

1.ひとまず権限の対応を

ちょっとググってみると、次のような実装をすると良い、という記事を見かけます。

<queries>
  <intent>
    <action android:name="android.intent.action.SENDTO" />
    <data android:scheme="mailto" />
  </intent>
</queries>

 

が、これはAndroidネイティブに対する正解で、url_launcher、を使ったFlutterでの実装の場合、動きませんでした。

答えはコレです。

<queries>
  <intent>
    <action android:name="android.intent.action.SEND" />
    <data android:mimeType="*/*" />
  </intent>
</queries>

この表記を、android/app/src/main/AndroidManifest.mxlの タグの外に追加して解決!

 

2.メーラー起動の実装

こんな感じのお問い合わせメールがユーザーから届いて欲しいので、各情報の取得方法とメーラーを起動させる実装方法を解説していきます。

最高の使い心地なので、期待を込めて、⭐3です。

※ 以下の情報は調査に必要なので消さないでください。
device: iPhone13,3
iOS: 16.1.2
appName: 100ChouyenMaker(4.6.1)
uuid: 62417d35-926c-4cd3-ae96-f67ea10bf3f6

 

  • 端末依存? -> 端末の種類が欲しい
  • OSのバグ? -> OSのバージョンが欲しい
  • アプリアップデートしてない? -> アプリのバージョンが欲しい
  • クラッシュ調査必要? -> UUIDで個人を特定したい

UUIDは何で?

UUIDは、firebaseのcrashlyticsに

FirebaseCrashlytics.instance
.setUserIdentifier( UUID )

こんな感じにUUIDを入れておくと、crashlyticsの 「ユーザーIDで検索」 欄からピンポイントで調査ができるので、活用してくださいね。

 

2.1 OSのバージョンと端末の種類の取得方法

device_infoパッケージを使ってこんな感じで取得できます。

String device;
String os;
String osVersion;

if (Platform.isIOS) {
  IosDeviceInfo iosInfo = await deviceInfo.iosInfo;
  os = "iOS";
  osVersion = iosInfo.systemVersion;
  device = Config.getiOSDeviceName(iosInfo.utsname.machine);

} else {
  AndroidDeviceInfo androidInfo = await deviceInfo.androidInfo;
  os = "Android";
  osVersion = androidInfo.version.release;
  device = androidInfo.model;
}

 

 

2.2 アプリのバージョンの取得方法

package_info_plusパッケージを使ってこんな感じで取得できます。

String appVersion;
PackageInfo packageInfo = await PackageInfo.fromPlatform();
appVersion = packageInfo.version;

 

 

2.3 UUIDは

uuidパッケージ、を使ってこんな感じで取得できます。
僕はSharedPreferencesも使って初めてuuidを発行する場合はローカルに保存し、2回目以降はローカルのデータを渡すようにする関数を作っています。

String uuid = Uuid().v4();

 

 

2.4 メーラーの起動は

こんな感じでメーラーを起動できます。

String? encodeQueryParameters(Map<String, String> params) {
  return params.entries
    .map((e) =>
    '${Uri.encodeComponent(e.key)}=${Uri.encodeComponent(e.value)}')
    .join('&');
}

String body = "メールの本文テンプレートですよ〜";

final Uri emailLaunchUri = Uri(
  scheme: 'mailto',
  path: "hoshi5igai@sikei.rip", // お問い合わせ先
  query: encodeQueryParameters(<String, String>{
    'subject': "あぷり名(" + appVersion + ")",
    'body': "$body"
  }),
);

canLaunchUrl(emailLaunchUri).then((enabled) {
  if (enabled) {
    launchUrl(emailLaunchUri);
  } else {
       // エラーメッセージを表示する
  }
});

 

 

2.5 まとめるとこんな感じです

String? encodeQueryParameters(Map<String, String> params) {
  return params.entries
    .map((e) =>
    '${Uri.encodeComponent(e.key)}=${Uri.encodeComponent(e.value)}')
    .join('&');
}

String format =
"%s\r\n\r\n\r\n\r\n\r\n%s\r\n---------------\r\ndevice: %s\r\n%s: %s\r\nappName: 100ChouyenMaker(%s)\r\nuuid: %s";
String device;
String os;
String osVersion;
String appVersion;
String uuid;

PackageInfo packageInfo = await PackageInfo.fromPlatform();
appVersion = packageInfo.version;

DeviceInfoPlugin deviceInfo = DeviceInfoPlugin();
if (Platform.isIOS) {
  IosDeviceInfo iosInfo = await deviceInfo.iosInfo;
  os = "iOS";
  osVersion = iosInfo.systemVersion;
  device = Config.getiOSDeviceName(iosInfo.utsname.machine);
} else {
  AndroidDeviceInfo androidInfo = await deviceInfo.androidInfo;
  os = "Android";
  osVersion = androidInfo.version.release;
  device = androidInfo.model;
}

uuid = await ZisakunoUtilityDayo().getUUID();
String body = sprintf(format, [
  "こちらにお問い合わせ内容をご記入ください",
  "※ 以下の情報は調査に必要なので消さないでください。",
  device,
  os,
  osVersion,
  appVersion,
  uuid,
]);

final Uri emailLaunchUri = Uri(
  scheme: 'mailto',
  path: "hoshi5igai@sikei.rip",
  query: encodeQueryParameters(<String, String>{
    'subject': "100ChouyenMaker(" + appVersion + ")",
    'body': "$body"
  }),
);

canLaunchUrl(emailLaunchUri).then((enabled) {
  if (enabled) {
    launchUrl(emailLaunchUri);
  } else {
    // エラーメッセージを出す
  }
});

 

おしまい