Just AIのソリューションアーキテクトであるVitalyaGorbachevは、Habitica(習慣を修正して目標を達成するためのオープンソースアプリ、Kotlinで作成)の例を使用して、音声インターフェイスを任意のアプリケーションの機能にすばやくシームレスに統合する方法を示します。

しかし、最初に、モバイルアプリケーションの音声制御が便利な理由について説明しましょう。明白なことから始めましょう。
- 調理、運転、スーツケースの持ち運び、機械的な作業など、手が忙しいときにアプリケーションを使用する必要があることがよくあります。
- 音声は、視覚障害を持つ人々にとって不可欠なツールです。
ケースはすでに透過的ですが、実際にはすべてがさらに単純です。場合によっては、音声ダイヤルの方が高速です。想像してみてください。長いフォームに記入する代わりに、「明日のチケットを2人でサマラに購入してください」という1つのフレーズで航空券を注文します。同時に、ユーザーに明確な質問をする機能を備えています:夕方または午後?荷物の有無は?
音声は、「フォーム入力」シナリオを実行するときに役立ち、ユーザーからの一定量の情報を必要とするほとんどすべての長いフォームに入力するのに便利です。そして、そのようなフォームはほとんどのモバイルアプリケーションに存在します。
左から右へ:Prigorod RZDアプリ、FatSecret食品日記(ユーザーは数百の製品から選択して、1日に数回フォームに記入する必要があります)、Korzhovベーカリーアプリ。
今日、音声アシスタントはサポートチャットに導入されることが多く、そこから開発されるため、ほとんどの企業はアプリケーションの機能をチャットにプッシュしようとしています。バランスを取り、製品やサービスについて何かを見つけてください...これは必ずしも便利に実装されているわけではなく、音声入力の場合、音声認識が完全に機能しないことが多いという理由だけで、完全に逆効果になります。
正しいアプローチは、アシスタントをアプリケーションの既存の機能にシームレスに統合し、そのインターフェイスでフォームに入力することです。これにより、ユーザーはすべてを正しく言ったことを確認して、[OK]をクリックするだけで済みます。Habiticaの例を使用してこれを行う方法を示すことにしました。これはほぼ純粋なKotlinで記述されたオープンソースアプリケーションです。 「ハビティカ」は音声アシスタントの場合に最適です。ここでも、新しいタスクを開始するには、かなり膨大なフォームに記入する必要があります。この退屈なプロセスを、主要な質問を含む1つのフレーズに置き換えてみましょう。
チュートリアルを2つの部分に分けました。この記事では、モバイルアプリケーションに音声アシスタントを追加し、基本的なシナリオを実装する方法を理解します(この場合、これは天気と時間の予測を明確にするための既成のシナリオです。これは、世界で最も人気のある音声アシスタントのリクエストの1つです)。 2番目の記事(まもなくリリースされる予定です)では、特定の画面を音声で呼び出し、アプリケーション内に複雑なクエリを実装する方法を学習します。
あなたが働く必要があるもの
SDK。我々はかかったAimyboxをダイアログインターフェースを構築するためのSDKとして。箱から出して、AimyboxはアシスタントSDKと簡潔でカスタマイズ可能なUI(必要に応じて変更可能)を提供します。同時に、既存のモジュールから選択するか、認識、合成、およびNLPのエンジンとして独自のモジュールを作成できます。
基本的に、Aimyboxは音声アシスタントアーキテクチャを実装し、これらすべてのモジュールのインターフェイスを標準化し、それらの相互作用を正しい方法で整理します。したがって、このソリューションを実装することにより、アプリケーション内で音声インターフェイスを開発する時間を大幅に短縮できます。Aimyboxの詳細については、こちらまたはここ。
スクリプト作成ツール。スクリプトはJAICF(Just AIから音声アプリケーションを開発するためのオープンソースで完全に無料のフレームワーク)で記述し、JAICP(Just AI Conversational Platform)でCaila(NLUサービス)を使用してインテントを認識します。チュートリアルの次のパートで、それらの使用方法について詳しく説明します。スマートフォン。テストには、Habitikaを実行してテストするAndroidスマートフォンが必要です。
手順
まず、「Habitika」(リリースブランチ)をフォークして、私たちにとって最も重要なファイルを検索します。Android Studio IDEを使用しました:MainActivity.kt
を検索します-そこにロジックを埋め込みます。HabiticaBaseApplication.kt-そこでAimyboxを初期化します。Activity_main.xml-そこにインターフェイス要素を埋め込みます。AndroidManifest.xml-アプリケーションの構造全体とそのアクセス許可がそこに保存されます。 Habitikiカブの指示に従って、habitica.properties.exampleとhabitica.resources.exampleの名前を変更し、それらから例を削除して、アプリケーションのfirebaseでプロジェクトを開始し、google-services.jsonファイルをルートにコピーします。 アプリケーションを起動して、アセンブリが機能していることを確認します。出来上がり!
まず、Aimyboxの依存関係を追加しましょう。
implementation 'com.justai.aimybox:core:0.11.0'
implementation("com.justai.aimybox:components:0.1.8")
依存関係と
maven { url 'https://dl.bintray.com/aimybox/aimybox-android-sdk/' }
maven { url "https://dl.bintray.com/aimybox/aimybox-android-assistant/" }
リポジトリ内。
そして、compileOptionsの直後に次の行を追加して、すべてが正しく機能するようにします。
kotlinOptions {
jvmTarget = JavaVersion.VERSION_1_8.toString()
}
今度は権限。
フラグを削除しRECORD_AUDIOとMODIFY_AUDIO_SETTINGS権限でAndroidManifestオプションは次のようになりようの.xml。
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="com.android.vending.BILLING" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>
それでは、BaseApplicationでAimyboxを初期化しましょう。クラスを初期化するとき
にAimyboxProviderを追加します。
そして、実際の初期化を行います。
private fun createAimybox (context: Context): Aimybox {
val unitId = UUID.randomUUID().toString()
val textToSpeech = GooglePlatformTextToSpeech(context, Locale("Ru"))
val speechToText = GooglePlatformSpeechToText(context, Locale("Ru"))
val dialogApi = AimyboxDialogApi(
"YOUR KEY", unitId)
return Aimybox(Config.create(speechToText, textToSpeech, dialogApi))
}
YOUR_KEYの代わりに、Aimyboxコンソールからのコードはその後になります。
次に、スニペットをmainActivity.ktに埋め込みます。frameLayoutをactivity_main.xmlの、idbottom_navigationのframeLayoutのすぐ下に事前に挿入します
<FrameLayout
android:id="@+id/assistant_container"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
MainActivity自体で、最初に明示的なアクセス許可要求をOnCreateに追加します
ActivityCompat.requestPermissions(this, arrayOf(android.Manifest.permission.RECORD_AUDIO), 1)
そして、それらを受け取ったら、上のフレームにフラグメントを追加します。
@SuppressLint("MissingPermission")
override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<out String>,
grantResults: IntArray
) {
val fragmentManager = supportFragmentManager
val fragmentTransaction = fragmentManager.beginTransaction()
fragmentTransaction.add(R.id.assistant_container, AimyboxAssistantFragment())
fragmentTransaction.commit()
}
アシスタントに入った後にアシスタントを終了する機能をOnBackPressedに追加することを忘れないでください。
val assistantFragment = (supportFragmentManager.findFragmentById(R.id.assistant_container)
as? AimyboxAssistantFragment)
if (assistantFragment?.onBackPressed() != true) {
return
}
さらに、AppThemeのスタイル(styles.xml)に追加します
<item name="aimybox_assistantButtonTheme">@style/CustomAssistantButtonTheme</item>
<item name="aimybox_recognitionTheme">@style/CustomRecognitionWidgetTheme</item>
<item name="aimybox_responseTheme">@style/CustomResponseWidgetTheme</item>
<item name="aimybox_imageReplyTheme">@style/CustomImageReplyWidgetTheme</item>
<item name="aimybox_buttonReplyTheme">@style/CustomButtonReplyWidgetTheme</item>
そして、個々のスタイルはすぐ下にあります:
<style name="CustomAssistantButtonTheme" parent="DefaultAssistantTheme.AssistantButton">
</style>
<style name="CustomRecognitionWidgetTheme" parent="DefaultAssistantTheme.Widget.Recognition">
</style>
<style name="CustomResponseWidgetTheme" parent="DefaultAssistantTheme.Widget.Response">
</style>
<style name="CustomButtonReplyWidgetTheme" parent="DefaultAssistantTheme.Widget.ButtonReply">
</style>
<style name="CustomImageReplyWidgetTheme" parent="DefaultAssistantTheme.Widget.ImageReply">
</style>
マイクが追加されているか確認してみましょう。アプリケーションを起動します。
誤った構文について多くのエラーが発生しました。IDEのアドバイスに従ってすべてを修正します。
ワーキング!
しかし、マイクは下部のナビゲーションに忍び寄っています。少し上げましょう。CustomAssistantButtonThemeで上記のスタイルに追加します。
<item name="aimybox_buttonMarginBottom">72dp</item>
より良い!
そこでアシスタントを接続して、彼が正常に応答するかどうかを確認しましょう。このためには、Aimyboxコンソールが必要です。
まず、githubアカウントでapp.aimybox.comにアクセスし、新しいプロジェクトを作成し、いくつかのスキルを接続して(テストのためにDateTimeを接続しました)、アシスタントで適切な質問をしてみましょう。ここの設定では、右上隅にあるapiKeyを使用します。これは、KEYの代わりにcreateAimyboxに挿入します。
private fun createAimybox (context: Context): Aimybox {
val unitId = UUID.randomUUID().toString()
val textToSpeech = GooglePlatformTextToSpeech(context)
val speechToText = GooglePlatformSpeechToText(context)
val dialogApi = AimyboxDialogApi(
"YOUR KEY", unitId)
return Aimybox(Config.create(speechToText, textToSpeech, dialogApi))
}
ワーキング!
英語のテキストのみ、strings.constants.xmlのウェルカムメッセージを変更しましょう。
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Prefs -->
<string name="SP_userID" translatable="false">UserID</string>
<string name="SP_APIToken" translatable="false">APIToken</string>
<string name="base_url" translatable="false">https://habitica.com</string>
<string name="initial_phrase">"! ?</string>
やったー!
ここにあるリンクコードリポジトリには。
「ハビティカ」のアシスタントに関する次の記事では、あなたの声を使って天気を知るだけでなく、アプリケーションを直接制御する方法を説明します。ページをナビゲートして、習慣やタスクを追加します。