Главная
Блог разработчиков phpBB
 
+ 17 предустановленных модов
+ SEO-оптимизация форума
+ авторизация через соц. сети
+ защита от спама

Чак Норрис и Google Glass — что всеобщего, а вот…

Anna | 3.06.2014 | нет комментариев
Недавно мне (несказанно поперло) вывалился шанс приобрести Google Glass по Explorers Program. Стоило только заказать, как на следующее утро почтальон разбудил меня стуком в деверь — вам посылка. Не умываясь и не чистя зубы…

Под вечер появилась вероятность попрограммировать. Изучив пару-тройку примеров и настроив окружение — я взялся за дело. Появилась идея написать приложение которое будет вытягивать шутку про Чака Норриса из веб-обслуживания, парсить JSON, и читать вслух.


Выходит начнем.

Голосовая активизация:

Наша шутилка будет активироваться голосовой командой. Для этого определяем сервис в манифесте:

        <service
                android:name="com.chucknorris.JokeService"
                android:icon="@drawable/icon"
                android:label="@string/app_name"
                android:enabled="true"
                android:exported="true">
            <intent-filter>
                <action android:name="com.google.android.glass.action.VOICE_TRIGGER"/>
            </intent-filter>
            <meta-data
                    android:name="com.google.android.glass.VoiceTrigger"
                    android:resource="@xml/voice_trigger_start"/>
        </service>

Ключевым элементом тут, в различие от обыкновенных андроид приложений, является VoiceTrigger.

xml/voice_trigger_start выглядит легко:

<?xml version="1.0" encoding="utf-8"?>
<trigger keyword="@string/chuck_norris_joke" />

Ну и наконец, строка, которая задает фразу, по которой в свою очередь наш сервис запустится:

<string name="chuck_norris_joke">say Chuck Norris joke</string>

Примечание: согласно правилам, которые Google выдвигает по отношению к активационным фразам — они обязаны начинаться с глагола. Мне лично это правило не дюже нравится, но башмачник не вправе судить выше сапога. Легко уж больно много фраз будет начинаться с «show», «get», «say», «start»
Больше детально тут

Сейчас, когда мы определили VoiceTrigger, наш сервис будет стартовать, если мы скажем «ok glass, say Chuck Norris joke»
К слову, Activity тоже дозволено запустить с поддержкой голосовой команды. Ломтик манифеста будет таковым:

       <activity
         android:name="com.google.android.glass.sample.waveform.WaveformActivity" >
            <intent-filter>
                <action android:name="com.google.android.glass.action.VOICE_TRIGGER" />
            </intent-filter>
            <meta-data android:name="com.google.android.glass.VoiceTrigger"
                android:resource="@xml/voice_trigger_start" />
        </activity>
Начинка обслуживания

Дюже хочется рассказать о Card и LiveCard, но как-нибудь в иной раз. Наша шутилка не будет показывать ничего, легко будет шутить вслух.

Раз шутку необходимо вытянуть из интернет-источника, то не позабудем задекларировать сие намерение в AndroidManifest.xml:

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

В UI Thread лазить в интернет воспрещается, заведем для этой цели AsyncTask

doInBackground исполняет запрос на веб сервис:

        HttpClient client = new DefaultHttpClient();
        HttpGet getRequest = new HttpGet();

        try {
            // construct a URI object
            getRequest.setURI(new URI(urls[0]));
        } catch (URISyntaxException e) {
            Log.e("URISyntaxException", e.toString());
        }

        // buffer reader to read the response
        BufferedReader in = null;
        // the service response
        HttpResponse response = null;
        try {
            // execute the request
            response = client.execute(getRequest);
        } catch (ClientProtocolException e) {
            Log.e("ClientProtocolException", e.toString());
        } catch (IOException e) {
            Log.e("IO exception", e.toString());
        }

        try {
            in = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
        } catch (IllegalStateException e) {
            Log.e("IllegalStateException", e.toString());
        } catch (IOException e) {
            Log.e("IO exception", e.toString());
        }
        StringBuffer buff = new StringBuffer("");
        String line = "";
        try {
            while ((line = in.readLine()) != null) {
                buff.append(line);
            }
        } catch (IOException e) {
            Log.e("IO exception", e.toString());
            return e.getMessage();
        }

        try {
            in.close();
        } catch (IOException e) {
            Log.e("IO exception", e.toString());
        }

после этого парсит JSON:

        String joke = "";
        try {
            JSONObject jObject = new JSONObject(buff.toString());
            joke = jObject.getJSONObject("value").getString("joke");
        } catch (JSONException e) {
            Log.e("JSON exception", e.toString());
        }

ok glass скажи шось

AsyncTask предоставляет способ onPostExecute. Стало быть, когда запрос исполнен и шутка получена, вытянута из JSON оболочки — самое время произнести ее вслух. Android вежливо помогает нам не только распознать речь но и произнести текст с поддержкой TextToSpeech.

TextToSpeech инициализируем в сервисе и передаем в AsyncTask через параметр конструктора.

        tts = new TextToSpeech(this, new TextToSpeech.OnInitListener(){
            @Override
            public void onInit(int i) {
                  //TODO по-отменному нужно бы подождать инициализации
            }
        });

в onPostExecute вызываем новейший способ readOutLoud

    protected void onPostExecute(String joke) {
        if (exception != null) {
            return;
        }
        readOutLoud(joke);
    }

чтение шутки вслух:

    private void readOutLoud(String joke) {
        tts.speak(joke, TextToSpeech.QUEUE_FLUSH, null);
    }
Отладка и загладка

Сейчас осталось подключить очки через USB, собрать apk, align, sign, deploy (IDE все сделает за нас). Никакой Activity запускать не необходимо.

выходит, барабанная дробь
— «ok glass, say Chuck Norris Joke»
— «Chuck Norris can read from an input stream.»

Взамен послесловия

Пользуясь случаем, хочу поблагодарить www.icndb.com/. Я думаю нужно бы сделать схожий сервис с шутками про Штирлица. Если будет время — займусь.

Насчет голосового воспроизведения

наверно есть добавочные настройки скорости чтения и/или голоса. На OS X они есть.

Возвращаясь к пункту «а что показывать»

маленький фрагмент, тот, что разрешает сделать статическую карточку с картинкой слева и текстом шутки:

    private void publishJokeCard(String joke) {
        Card card = new Card(ctx);
        card.setText(joke);
        card.addImage(R.drawable.chuck);

        TimelineManager.from(ctx).insert(card);
    }

Немножко огромнее о карточках — в дальнейший раз, нужно немножко разобраться. Пока писал одно приложение — задеплоил на очки — а там теснее новая версия SDK. Благо кто-то на форуме поделился навыком, что вышло обновление день назад (на тот момент). Как выглядят карточки дозволено посмотреть тут

Картинки

Иконку подготовить не сложно — основное требование — белая, на прозрачном фоне и 50х50 пикселей.

Картинка для карточки — ну в тезисе любая, но отменнее — где-то треть размера ширины карточки и полный размер высоты карточки.
На последок, вероятно скажу, что не все шутки идентично порядочны. Чтоб не ввести пользователя в конфуз — отменнее добавить к URL “?type=nerdy”.

Код

Если кому увлекательно, код целиком
Формальные примеры тут

Источник: programmingmaster.ru

Оставить комментарий
Форум phpBB, русская поддержка форума phpBB
Рейтинг@Mail.ru 2008 - 2017 © BB3x.ru - русская поддержка форума phpBB