(なんちゃって)しゃべってコンシェル風な。音声でテキスト作成。からのDropboxに保存

ドコモのアプリで、しゃべってコンシェルってありますよね。
そんなような感じのアプリを作ってみました。

音声で指示出して、Dropboxにテキスト形式のファイルを保存するって機能です。

やらなければいけないのは、
・音声認識機能をつけること
・Dropboxにファイルを保存すること
の2つです。

まずは、音声認識機能からいきましょう。
このサイトを見れば簡単だったお。 音声認識(RecognizerIntent)を使用するには

RecogniserIntentクラスを使えば簡単に音声認識処理を組み込めちゃうぞ。
解説は主に下に書いたソースコードのコメントを参考にして下さい。

つぎは、Dropboxですが、 けっこう大変です。

まず、 Dropbox DeveloperここからDropboxのSDKをダウンロードしてきます。
スマフォ内のデータとDropboxのデータを簡単に連携出来るSyncAPIなるものを利用すれば、簡単にDropboxを操作出来るらしい。

そこで、App Consoleで作成するアプリを登録するらしい。
ここでApp keyとApp secretという認証キーを取得しなければいけないらしいです。
ちなみに、SDK同封のサンプルプロジェクトは何もしなくても動きました。
今回はそれを拡張しています。

/////////////////////////////////////////////////
事前準備
①libsフォルダの中身をコピペ
②マニュフェストにパーミッションを記入

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

③APP_KEYをマニュフェストに登録(今回はサンプルそのままのデフォルト値)

<activity android:name="com.dropbox.sync.android.DbxAuthActivity" />
<activity
    android:name="com.dropbox.client2.android.AuthActivity"
    android:launchMode="singleTask" >
    <intent-filter>
             <data android:scheme="xxxxxxxx" />
             <action android:name="android.intent.action.VIEW" />
             <category android:name="android.intent.category.BROWSABLE" />
             <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>
<service
    android:name="com.dropbox.sync.android.DbxSyncService"
    android:enabled="true"
    android:exported="false"
    android:label="Dropbox Sync" />

////////////////////////////////////////////////

そして、どう使うかについては公式のドキュメントがわかりやすいですかね。
Using the Sync API on Android

 

では、さっそくサンプルにいきましょかね。
音声で指示を出して、Dropboxにテキストファイルをつくります。

//////////////////////////////////////////
使い方
①クリエイトって言う
②テキストファイルのタイトルをいう
////////////////////////////////////////

 

MainActivity.java

import java.io.IOException;
import java.util.ArrayList;

import android.app.Activity;
import android.content.ActivityNotFoundException;
import android.content.Intent;
import android.os.Bundle;
import android.speech.RecognizerIntent;
import android.widget.Toast;

import com.dropbox.sync.android.DbxAccountManager;
import com.dropbox.sync.android.DbxFile;
import com.dropbox.sync.android.DbxFileSystem;
import com.dropbox.sync.android.DbxPath;

public class MainActivity extends Activity {

    private static final int REQUEST_CODE = 0;
    private static final int REQUEST_LINK_TO_DBX = 0;
    private static final String appKey = "xxxxxxxxx";
    private static final String appSecret = "XXXXXXXXX";

    private DbxAccountManager mDbxAcctMgr;
    private boolean createWasSaid = false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        // 起動と同時に音声認識開始
        voiceRecogenize("音声認識テスト");
        // DropboxにアクセスするためにDbxAccountManagerオブジェクトを生成する
        // appKeyとappSecretは登録した値。(今回はサンプルのままデフォルト値)
        mDbxAcctMgr = DbxAccountManager.getInstance(getApplicationContext(),
                appKey, appSecret);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {

        // 音声認識からの場合
        if (requestCode == REQUEST_CODE && resultCode == RESULT_OK) {
            // 候補になる文字列が大量に格納されている
            ArrayList results = data
                    .getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS);

            // results.get(0)でresults配列の中の1番目を取得
            // 「クリエイト」と言った場合
            if (results.get(0).equals("クリエイト")) {
                createWasSaid = true;
                voiceRecogenize("Textのタイトルは何ですか?");
            } else if (createWasSaid) {
                // 今まで、このアプリからDropboxにリンクしたことがあるか
                if (mDbxAcctMgr.hasLinkedAccount()) {
                    createTextToDropbox(results.get(0));
                } else {
                    // Dropboxとのリンクスタート。2回目以降は省略される
                    mDbxAcctMgr.startLink((Activity) this, REQUEST_LINK_TO_DBX);
                }
                createWasSaid = false;
            } else {
                voiceRecogenize("もう一度お願いします。");
            }

            // Dropboxからの場合
        } else if (requestCode == REQUEST_LINK_TO_DBX) {
            if (resultCode == Activity.RESULT_OK) {
                voiceRecogenize("音声認識テスト");
            }

        } else {
            super.onActivityResult(requestCode, resultCode, data);
        }
    }

    private void voiceRecogenize(String message) {
        try {
            // インテント作成
            // ACTION_RECOGNIZE_SPEECHは単語から認識結果とマッチするものをまとめてかえす
            // ACTION_WEB_SEARCH は認識結果からWEBサーチ
            Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
            intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,
                    RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
            intent.putExtra(RecognizerIntent.EXTRA_PROMPT, message);
            startActivityForResult(intent, REQUEST_CODE);
        } catch (ActivityNotFoundException e) {
            // このインテントに応答できるアクティビティがインストールされていない場合
            Toast.makeText(this, "ActivityNotFoundException", Toast.LENGTH_LONG)
                    .show();
        }
    }

    private void createTextToDropbox(String title) {
        try {
            final String TEXT_DATA = "Hello Dropbox";
            final String FILE_NAME = title + ".txt";

            DbxPath folderPath = new DbxPath(DbxPath.ROOT, title);
            // "/title/title.text" とうファイル階層になる
            DbxPath filePath = new DbxPath(folderPath, FILE_NAME);

            // DbxFileSystemでユーザーのDropboxにアクセスする
            DbxFileSystem dbxFs = DbxFileSystem.forAccount(mDbxAcctMgr
                    .getLinkedAccount());

            // ファイルがなかったらつくる
            if (!dbxFs.exists(filePath)) {
                DbxFile txtFile = dbxFs.create(filePath);
                try {
                    txtFile.writeString(TEXT_DATA);
                } finally {
                    txtFile.close();
                }
            }
        } catch (IOException e) {
            //
        }
    }

}

 

【追記】
実行してみればわかりますが、テキストファイルは”アプリ/Simple Example”とう階層構造の下に作られます。
本当は最上階層に作りたかったんですが、できなかったっす。
コード内で、”DbxPath.ROOT”ってかいてあるんですが、公式ドキュメントによると。

ROOT refers either to the root of a user’s Dropbox, or to the root of your app’s folder, depending on your app permissions.

ってなってます。最上階層に作れるっぽいですが、パーミッションによるって。。。
そのパーミッション教えて欲しいですね。

コメントを残す

メールアドレスが公開されることはありません。