Android WearでRemoteInputを使って通知から音声入力を受け取るとろこまで試してみる

本日は、先日の記事を見ながら、実際にプロジェクトを作成して実行してみましょう。
先日はEclipseを使用しましたが、今日はAndroid Studioを使ってみましょう。
http://developer.android.com/sdk/installing/studio.html
より、Android Studioをダウンロードします。

 
Macの場合、android-studio-bundle-133.1028713-mac.dmgがダウンロードされました。
ダウンロードしたdmgを開き、Android Studioをアプリケーションフォルダにドラッグ&ドロップします。

 
起動します。設定ファイルのインポート画面になるのでそのままOKをクリック。

 
起動中。

 
新しいバージョンがあることが示されています。More Infoを押すと更新内容をブラウザで表示します。
 

 
下部の「Check for updates now.」をクリックします。
 

Update and restartをクリックしてアップデートします。完了するとAndroidStudioが再起動します。

新しいプロジェクトを作成します。
適当な名称をつけてNext。

デフォルトのままNext。

デフォルトのままFinishするとプロジェクトが作成されます。

Tools > Android > SDK ManagerでSDKマネージャを開きます。
Android SDK Tools のバージョンがが22.6以上であることを確認します。

Android Wear ARM EABI v7a System Image」を選択します。

Android Support LibraryとAndroid Support Repositoryがインストールされているか確認します。インストールされていましたが最新版があるのでアップデートします。

インストールします。

ライセンスを承認してInstallをクリックするとインストールが開始されます。

Android Wearエミュレータを準備します。Tools > Android > AVD ManagerよりAVDマネージャを起動します。
Newをクリックして次のように設定します。

OKをクリック。作成結果が表示されますのでOKで閉じます。

作成したAVDを選択して、Startをクリックします。

Launch from snapshotのチェックを外し、Save to snapshotにチェックを付けてLaunchをクリックしてAVDを起動します。

起動中。起動にはそこそこ時間がかかります。

起動しました。起動したら一旦閉じることで、スナップショットを取ります。

もう一度起動します。今度はSave to snapshotのチェックを外し、Launch from snapshotだけにチェックを入れてLaunchで起動します。以後はこの方法で起動すれば起動時間をいくらか短縮できます。

携帯端末をMacにUSB接続します。
次のコマンドを入力します。
[shell]
* cd /Applications/Android\ Studio.app/sdk/platform-tools
* ./adb -d forward tcp:5601 tcp:5601
[/shell]
携帯デバイスAndroid Wear Preview起動します。青い部分をタップ。

通知へのアクセスが開くのでAndroid Wear Previewをタップ。
Android Wear Previewを有効にしますか?で「OK」をタップ。
これで準備は整いました。次はライブラリです。
libsディレクトリにwearable-preview-support.jar を追加します。ドラッグ&ドロップで追加できます。macの場合optionキーを押しながらドラッグ&ドロップでコピーになります。

追加されました。

build.gradleを開き次の依存ルールを追加します。
[text]
dependencies {
compile "com.android.support:support-v4:18.0.+"
compile files(‘../libs/wearable-preview-support.jar’)
}
[/text]
追加したら、ツールバーのボタンを押して反映します。

さてここからはコーディングです。
Android Wearで応答した時に開くActivityを新規作成します。パッケージを右クリックして New > Activity > Blank Activity を選択します。

Activityの新規作成画面になりますのでActivity Nameに「ReplyActivity」と入力してFinishをクリックして追加します。

まずは通知ボタンを追加します。activity_main.xmlを開きボタンを追加します。

MainActivity.javaにボタンを押したら通知を送信するようにコーディングします。
[java]
package com.example.androidweartestapplication.weartest;
import android.app.Activity;
import android.app.Notification;
import android.app.PendingIntent;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.preview.support.wearable.notifications.*;
import android.preview.support.v4.app.NotificationManagerCompat;
import android.support.v4.app.NotificationCompat;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.button).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
int notificationId = 001;
String EXTRA_VOICE_REPLY = "extra_voice_reply";
String replyLabel = "返信";
// 返信アクションのインテントを作成
Intent replyIntent = new Intent(getApplicationContext(), ReplyActivity.class);
PendingIntent replyPendingIntent =
PendingIntent.getActivity(getApplicationContext(), 0, replyIntent, 0);
// 通知の作成
NotificationCompat.Builder replyNotificationBuilder =
new NotificationCompat.Builder(MainActivity.this)
.setSmallIcon(android.R.drawable.ic_dialog_email)
.setContentTitle("embossさんからメッセージ")
.setContentText("I love KitKat!")
.setContentIntent(replyPendingIntent);
// リモート入力の作成
RemoteInput remoteInput = new RemoteInput.Builder(EXTRA_VOICE_REPLY)
.setLabel(replyLabel)
.build();
// ウェアラブル通知の作成とリモート入力の追加
Notification replyNotification =
new WearableNotifications.Builder(replyNotificationBuilder)
.addRemoteInputForContentIntent(remoteInput)
.build();
// NotificationManagerサービスのインスタンスを取得します
NotificationManagerCompat notificationManager =
NotificationManagerCompat.from(getApplicationContext());
// 通知マネージャーで通知を作成し発行します
notificationManager.notify(notificationId, replyNotification);
}
});
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
[/java]
実行してみましょう。携帯デバイスを選択してOKをクリックします。

アプリケーション上で「通知」ボタンを押してみましょう。

するとAndroid Wearに通知が届きます。

左にスワイプします。通常「Open」アクションが表示されていたいましたが「Reply」アクションが表示されています。「Reply」をタップします。

音声入力の画面になります。

エミュレータでは音声認識は使用できませんので、かわりにキーボードで入力します。

入力後しばらくく待つと再入力または保存の画面になります。

Saveボタンのインジゲータが一周りし、Doneと表示されれば完了です。

端末ではReplyActivityが起動していることが確認できます。

では次に、定義済みテキストによる応答を試してみましょう。まずはXMLにreply_choicesを追加します。
strings.xml
[xml]
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="app_name">Android Wear Test Application</string>
    <string name="hello_world">Hello world!</string>
    <string name="action_settings">Settings</string>
    <string name="title_activity_reply">ReplyActivity</string>
    <string name="reply_label">返信</string>
    <string-array name="reply_choices">
        <item>Yes</item>
        <item>No</item>
        <item>Maybe</item>
    </string-array>
</resources>
[/xml]
ボタンを押した時の処理を次のように修正します。
[java]
findViewById(R.id.button).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
int notificationId = 001;
String EXTRA_VOICE_REPLY = "extra_voice_reply";
// 返信アクションのインテントを作成
Intent replyIntent = new Intent(getApplicationContext(), ReplyActivity.class);
PendingIntent replyPendingIntent =
PendingIntent.getActivity(getApplicationContext(), 0, replyIntent, 0);
// 通知の作成
NotificationCompat.Builder replyNotificationBuilder =
new NotificationCompat.Builder(MainActivity.this)
.setSmallIcon(android.R.drawable.ic_dialog_email)
.setContentTitle("embossさんからメッセージ")
.setContentText("I love KitKat!")
.setContentIntent(replyPendingIntent);
// 定義済みテキストよる返答を追加
String replyLabel = getResources().getString(R.string.reply_label);
String[] replyChoices = getResources().getStringArray(R.array.reply_choices);
// リモート入力の作成
RemoteInput remoteInput = new RemoteInput.Builder(EXTRA_VOICE_REPLY)
.setLabel(replyLabel)
.setChoices(replyChoices)
.build();
// ウェアラブル通知の作成とリモート入力の追加
Notification replyNotification =
new WearableNotifications.Builder(replyNotificationBuilder)
.addRemoteInputForContentIntent(remoteInput)
.build();
// NotificationManagerサービスのインスタンスを取得します
NotificationManagerCompat notificationManager =
NotificationManagerCompat.from(getApplicationContext());
// 通知マネージャーで通知を作成し発行します
notificationManager.notify(notificationId, replyNotification);
}
});
[/java]
実行してみましょう。左にスワイプしてReplyをタップします。すると選択肢が表示されています。タップして返信することが出来ます。

もちろんここで音声入力を開始すれば認識されます。

では最後に、Android Wearで返信した文字列を端末側で受け取るようにします。レイアウトに文字列を表示するためのTextViewを配置します。
activity_reply.xml
[xml]
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin"
    tools:context="com.example.androidweartestapplication.weartest.ReplyActivity">
    <TextView
        android:text="@string/title_activity_reply"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/reply_text" />
</RelativeLayout>
[/xml]
Android Wearから受け取った文字列をTextViewに表示します。ReplyActivityのonCreateに処理を追加します。
ReplyActivity.java
[java]
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_reply);
String EXTRA_VOICE_REPLY = "extra_voice_reply";
Intent i = getIntent();
String reply = i.getStringExtra(EXTRA_VOICE_REPLY);
TextView text = (TextView)findViewById(R.id.reply_text);
text.setText(reply);
}
[/java]
実行してみましょう。
音声入力を開始し、「I love key lime pie!」と入力します。

完了すると、端末側に「I love key lime pie!」と表示されます。あとは端末側でこのメッセージを投稿するなりすればアプリケーションとしては完成ですね。

上部へスクロール