【WIP】Flutter speech_to_text 5.4.2 を Android エミュレータで動かしたい

実機では動く説あり。

概要

Flutter プラグイン speech_to_text を Andoroid で使いたい。

できてない。

環境

以下の環境で実行。

  • Flutter 2.8.1
  • speech_to_text 5.4.3
  • Pixel 5 API 30 シミュレータ

flutter doctor で調べられる範囲は以下。

  • Android SDK 30.0.3
  • Android Stuido 4.2
$ flutter doctor
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, 2.8.1, on macOS 11.4 20F71 darwin-x64, locale ja-JP)
[✓] Android toolchain - develop for Android devices (Android SDK version 30.0.3)
[✓] Xcode - develop for iOS and macOS (Xcode 13.2.1)
[✓] Chrome - develop for the web
[✓] Android Studio (version 4.2)
[✓] VS Code (version 1.63.2)
[✓] Connected device (3 available)

flutter create で作成される build.gradle に記載されている諸々のバージョン。

  • Gradle 4.1.0
  • JVM 1.8
  • Kotlin 1.3.50
  • build tools 4.1.0

SDK のバージョンは色々ある。

speech_to_text に必要なバージョン

  • minSdkVersion 21
  • targetSdkVersion 28
  • compileSdkVersion 28 (targetSdkVersionと合わせると吉らしい)

speech_to_text 公式のサンプルプログラム

  • minSdkVersion 21
  • targetSdkVersion 30
  • compileSdkVersion 31 (targetSdkVersionと合わせると吉らしい)

Android はバージョニングが大変らしく、本家サイトに組み合わせが載っている。

チュートリアル

準備

speech_to_text を動かすためのプロジェクト作成。

flutter create speech_android
cd speech_android

speech_to_text を追加。

flutter pub add speech_to_text

speech_to_text 動かす設定

公式 Example を記載する。長いので省略。

vi lib/main.dart

AndroidManifest.xml に音声録音のアクセス許可を追加する。

vi android/app/src/main/AndroidManifest.xml
  • <uses-permission ~> 部分
  • <queries> 部分
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.speech_android">

    <uses-permission android:name="android.permission.RECORD_AUDIO"/>
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.BLUETOOTH"/>
    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
    <uses-permission android:name="android.permission.BLUETOOTH_CONNECT"/>

    <queries>
        <intent>
            <action android:name="android.speech.RecognitionService" />
        </intent>
    </queries>  

   <application
        android:label="speech_android"
        android:name="${applicationName}"
        android:icon="@mipmap/ic_launcher">
        <activity
            android:name=".MainActivity"
            android:exported="true"
            android:launchMode="singleTop"
            android:theme="@style/LaunchTheme"
            android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
            android:hardwareAccelerated="true"
            android:windowSoftInputMode="adjustResize">
            <!-- Specifies an Android theme to apply to this Activity as soon as
                 the Android process has started. This theme is visible to the user
                 while the Flutter UI initializes. After that, this theme continues
                 to determine the Window background behind the Flutter UI. -->
            <meta-data
              android:name="io.flutter.embedding.android.NormalTheme"
              android:resource="@style/NormalTheme"
              />
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>
        <!-- Don't delete the meta-data below.
             This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
        <meta-data
            android:name="flutterEmbedding"
            android:value="2" />
    </application>
</manifest>

Android SDK バージョンを明示するため build.gradle を修正する。

vi android/app/build.gradle

speech_to_text 5.3.0 以上を利用する場合、compileSdkVersion は 31 にする必要がある。
Androidの音声機能の利用のための最低バージョン (minSdkVersion) は 21。
AndroidSDK 30 以降を利用する想定なので targetSdkVersion は30。

  • compileSdkVersion 31
  • minSdkVersion 21
  • targetSdkVersion 30
def localProperties = new Properties()
def localPropertiesFile = rootProject.file('local.properties')
if (localPropertiesFile.exists()) {
    localPropertiesFile.withReader('UTF-8') { reader ->
        localProperties.load(reader)
    }
}

def flutterRoot = localProperties.getProperty('flutter.sdk')
if (flutterRoot == null) {
    throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
}

def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
if (flutterVersionCode == null) {
    flutterVersionCode = '1'
}

def flutterVersionName = localProperties.getProperty('flutter.versionName')
if (flutterVersionName == null) {
    flutterVersionName = '1.0'
}

apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"

android {
    compileSdkVersion 31

    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }

    kotlinOptions {
        jvmTarget = '1.8'
    }

    sourceSets {
        main.java.srcDirs += 'src/main/kotlin'
    }

    defaultConfig {
        // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
        applicationId "com.example.speech_android"
        minSdkVersion 21
        targetSdkVersion 30
        versionCode flutterVersionCode.toInteger()
        versionName flutterVersionName
    }

    buildTypes {
        release {
            // TODO: Add your own signing config for the release build.
            // Signing with the debug keys for now, so `flutter run --release` works.
            signingConfig signingConfigs.debug
        }
    }
}

flutter {
    source '../..'
}

dependencies {
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
}

起動・使い方

Android エミュレータを指定し、起動。

flutter run

起動したら Initial を押す。その後 start を押したら認識開始。

しかしここでエラー中。

コードは下記。

GitHub - runble1/speech_to_text_android
Contribute to runble1/speech_to_text_android development by creating an account on GitHub.

遭遇したエラー

uses-sdk:minSdkVersion 16 cannot be smaller than version 21 declared in library

minSdkVersion を指定しなかった場合に起きたエラー。バージョンが低いとのこと。

以下を追加し、意図的にバージョンを指定。

android {
  defaultConfig {
    minSdkVersion 21
  }
}

エラーが変わる。

A problem occurred evaluating root project ‘android’. Could not find method defaultConfig() for arguments [] on root project ‘android’ of type org.gradle.api.Project.

修正する build.gradle を間違えていたために起きたエラー1。

以下全文。

FAILURE: Build failed with an exception.

* Where:
Build file '/Users/xxxx/private/flutter/TEST/Speach/test6/android/build.gradle' line: 1

* What went wrong:
A problem occurred evaluating root project 'android'.
> Could not find method android() for arguments [build_a0y21vkhlr302id1arv7i8khq$_run_closure1@30b51be4] on root project 'android' of type org.gradle.api.Project.

プラグインの宣言をする必要があったよう。Flutterさん、デフォルトで付けておいてくれてもいいのよ。

apply plugin: 'com.android.application'

エラーが変わる。

compileSdkVersion is not specified. Please add it to build.gradle

修正する build.gradle を間違えていたために起きたエラー2。

以下のエラーが発生。

2: Task failed with an exception.
-----------
* What went wrong:
A problem occurred configuring root project 'android'.
> compileSdkVersion is not specified. Please add it to build.gradle

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

compileSdkVersion が必要とのこと。以下を追加

android {
  defaultConfig {
    minSdkVersion 21
    compileSdkVersion 28
  }
}

Cannot add task ‘clean’ as a task with that name already exists.

修正する build.gradle を間違えていたために起きたエラー3。

clean というタスクが既に存在するとのこと。

とりあえずコメントアウトしておく

//task clean(type: Delete) {
//    delete rootProject.buildDir
//}

違うエラーが出た。

Execution failed for task ‘:generateDebugBuildConfig’.

修正する build.gradle を間違えていたために起きたエラー4。

タスク ‘generateDebugBuildConfig’ に失敗したとのこと。

ここでようやく違う build.gradle を修正していたと判明。

エラー内容を見ると AndroidManifest.xml のパスが違っているとのこと。 app がない。パスが違う。。

AILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':generateDebugBuildConfig'.
> Failed to calculate the value of task ':generateDebugBuildConfig' property 'buildConfigPackageName'.
   > Failed to query the value of property 'packageName'.
      > Manifest file does not exist: /Users/xxxx/private/flutter/TEST/Speach/test6/android/src/main/AndroidManifest.xml

記載すべき build.gradle を間違えていた。app 配下の方を修正する必要あり。

✗ : project/android/build.gradle

● : project/android/app/build.gradle

該当の方を修正。

vi project/android/app/build.gradle

とりあえずベタ書き。

//minSdkVersion flutter.minSdkVersion
minSdkVersion 21

違うエラーが発生。

AndroidManifest.xml:55: AAPT: error: unexpected element <queries> found in <manifest><application>.

AndroidManifest の <manifest><application> 内で <queries> が見つかったとのこと

本家サイトでは compileSdkVersion と targetSdkVersion は 28 を指定していたが、29 にする。

android {
    compileSdkVersion 29
    ~ 省略 ~
    defaultConfig {
        targetSdkVersion 29

speech_to_text/SpeechToTextPlugin.kt: Unresolved reference

下記エラー。Unresolved reference は、コンパイラーが名前解決できなかったため。

e: /Users/xxxx/work/flutter/flutter/.pub-cache/hosted/pub.dartlang.org/speech_to_text-5.4.2/android/src/main/kotlin/com/csdcorp/speech_to_text/SpeechToTextPlugin.kt: (458, 87): Unresolved reference: BLUETOOTH_CONNECT
e: /Users/xxxx/work/flutter/flutter/.pub-cache/hosted/pub.dartlang.org/speech_to_text-5.4.2/android/src/main/kotlin/com/csdcorp/speech_to_text/SpeechToTextPlugin.kt: (651, 30): Unresolved reference: ERROR_LANGUAGE_NOT_SUPPORTED
e: /Users/xxxx/work/flutter/flutter/.pub-cache/hosted/pub.dartlang.org/speech_to_text-5.4.2/android/src/main/kotlin/com/csdcorp/speech_to_text/SpeechToTextPlugin.kt: (652, 30): Unresolved reference: ERROR_LANGUAGE_UNAVAILABLE
e: /Users/xxxx/work/flutter/flutter/.pub-cache/hosted/pub.dartlang.org/speech_to_text-5.4.2/android/src/main/kotlin/com/csdcorp/speech_to_text/SpeechToTextPlugin.kt: (653, 30): Unresolved reference: ERROR_SERVER_DISCONNECTED
e: /Users/xxxx/work/flutter/flutter/.pub-cache/hosted/pub.dartlang.org/speech_to_text-5.4.2/android/src/main/kotlin/com/csdcorp/speech_to_text/SpeechToTextPlugin.kt: (654, 30): Unresolved reference: ERROR_TOO_MANY_REQUESTS
2

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':speech_to_text:compileDebugKotlin'.
> Compilation error. See log for more details

Android を利用する場合の permission 許可を AndroidManifest.xml に追記。

vi /android/app/src/main/AndroidManifest.xml
    <uses-permission android:name="android.permission.RECORD_AUDIO"/>
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.BLUETOOTH"/>
    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
    <uses-permission android:name="android.permission.BLUETOOTH_CONNECT"/>

また AndroidSDK のバージョンを 30 以上で使う場合、以下も記載。

<queries>
    <intent>
        <action android:name="android.speech.RecognitionService" />
    </intent>
</queries>

指定されたの 28 だったからやらなくていいだろうと思ってたけど動かなったので、サンプルに合わせる。

vi android/app/build.gradle
compileSdkVersion 31
targetSdkVersion 30

これでようやく起動できた。起動したけど音声認識してくれない。。

参考

How to change Android minSdkVersion in flutter project

Android Studio の Gradle の備忘録

[Flutter/Android]【重要】2020/11/2までにAndroidアプリの「targetSdkVersion」を「29」に上げる必要あり!

compileSdk・minSdk・targetSdkの違い(Android)

僕たちはいつまでこんな楽しいAndroid Studio設定をし続けるのか? Android Studio 3.x時代の設定不足解消メモ

コメント

タイトルとURLをコピーしました