狐好きぷろぐらまー

狐好きプログラマー見習いのブログです。

【Flutter】speech_recognition触ったら躓いた【Dangerous permission】

こんにちは。 pregum_foxです。

今回は、Androidのマイクを実機で触ってみたときに躓いたことがあったので、調査したことを備忘録として書き残しておきます。

私自身、Androidの中身を触ったことがないため手探りでの調査となっているため、多々間違ったことを書いているかもしれません。 またiOSでは動作させていません。

開発環境

開発環境は以下の通りです。

項目 バージョン
Dart 2.5.0
Flutter 1.9.1+hotfix.4
PS C:\XXX\XXX\Source\Repos\Flutter\second_challenge_api_sample> flutter --version
Flutter 1.9.1+hotfix.4 • channel stable • https://github.com/flutter/flutter.git
Framework • revision cc949a8e8b (2 weeks ago) • 2019-09-27 15:04:59 -0700
Engine • revision b863200c37
Tools • Dart 2.5.0

達成した機能

音声入力を使用して、しゃべった地名を地図上に表示する

概要

サンプルでは実機で音声入力が使用できたが、自作のアプリに組み込んで動かすと音声入力ができなかった。

躓いた内容と原因

  • マイクの機能が使用できない

speech_recognitionをcloneして、exampleフォルダ内のmain.dartを試しに動かしてみた所、こちらは実機で動作しました。
しかし、自作アプリに同じパッケージを追加してflutter runした所、マイクの機能が使用できませんでした。 Android上で使用する為には、どうやらAndroidManifest.xmlの中に使用する権限(マイクの場合はandroid.permission.RECORAD_AUDIOを記入し、権限を付与しないといけないみたいです。
私は、rootProject\app\main\AndroidManifest.xmlを編集しました。

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.second_challenge_api_sample">

    <!-- io.flutter.app.FlutterApplication is an android.app.Application that
         calls FlutterMain.startInitialization(this); in its onCreate method.
         In most cases you can leave this as-is, but you if you want to provide
         additional functionality it is fine to subclass or reimplement
         FlutterApplication and put your custom class here. -->
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.RECORD_AUDIO" />

    <application
        android:name="io.flutter.app.FlutterApplication"
        android:label="second_challenge_api_sample"
        android:icon="@mipmap/ic_launcher">
  • マイクの権限がインストール時に付与できない

どうやら、permissionにも2種類あって、ユーザーの確認が必要ないNormal permissionとユーザーの確認が必要なDangerous permissionがあり、マイクの権限android.permission.RECOARD_AUDIODangerous permissionなので、確認が必要なのですが自作アプリにはユーザーの確認処理を実装していなかったので、エラーが発生していました。
パーミッションについてはこちらをご覧ください。

解決方法としては、このプラグインを利用して、起動時に権限が付与されていない場合は、確認する処理を追加しました。

ちなみに、google_maps_flutterでmapを表示させていますが、端末から現在地を取得する場合はLOCATIONパーミッショングループの権限が必要になるそうです。
ただし、権限は付与させたい権限が含まれているパーミッショングループ内にあるパーミッションに対して既に権限が付与されている場合は、ユーザーへの確認をしないですぐ権限が付与されます。
パーミッショングループ内に権限が付与されているパーミッションがない場合は、ユーザーへの確認をする必要があります。
詳細は下記を参照してください。
システム パーミッション  |  Android デベロッパー  |  Android Developers

参考サイト