Началось все с того, что я посмотрел неплохой обзор (сравнение) Siri и Google Now. Кто из них лучше, спорить не буду, однако у меня лично планшет на Андроиде. Я подумал, а что если написать калькулятор полностью на голосовом управлении (удобно ли будет?). Но для начала пришлось немного разобраться с самим голосовым управление, точнее говоря с голосовым вводом (управления еще добиться надо). Кроме того, я только что скачал Android Studio, и мне не терпелось скорей опробовать ее на практике (ну на минипроекте). Что ж, начнем.
Кидаем на активность ListView и Button. В ЛистВью будем сохранять сами команды, точнее варианты одной команды, а кнопка будет вежливо спрашивать, чего мы желаем. Да, программа логикой не будет обладать, с ее помощью просто посмотрим саму реализацию.
Добавим так же в Манифест одно разрешение
<uses-permission android:name="android.permission.INTERNET" />
И все, теперь можно переходить непосредственно к программированию. «Находим необходимые компоненты»:
private ListView mList;
private Button speakButton;
public static final int VOICE_RECOGNITION_REQUEST_CODE = 1234;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
speakButton = (Button) findViewById(R.id.button);
speakButton.setOnClickListener(this);
mList = (ListView) findViewById(R.id.listView);
}
Прописываем обработчик нажатия для кнопки, который вызовет метод startSpeak(), о котором мы поговорим далее:
public void onClick(View v) {
startSpeak();
}
Ну наконец закончилась «вода». Начинаем «говорить»:
public void startSpeak() {
Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH); // намерение для вызова формы обработки речи (ОР)
intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_FREE_FORM); // сюда он слушает и запоминает
intent.putExtra(RecognizerIntent.EXTRA_PROMPT, «What can you tell me?»);
startActivityForResult(intent, VOICE_RECOGNITION_REQUEST_CODE); // вызываем активность ОР
}
Пришло время дать волю фантазии и решить какие команды использовать. Сам я сначала хотел показать на примере тетрисного танчика: диктовали бы ему «up», «down», «left», «fire» и так далее, но это сложно оставляю вам. Я же отдавал команды по смене цвета кнопки, выходу из приложения, открытию страниц в браузере, запуску карт и перезагрузке устройства. Что касается последнего, reboot, это команда будет работать, как я понял, только на рутованных устройствах. На телефоне у меня есть права СП и все хорошо работает, а вот на планшете, он просто игнорирует эту команду. В записи команд нет ничего сложного, думаю комментариев будет достаточно:
public void onActivityResult(int requestCode, int resultCode, Intent data){
if (requestCode == VOICE_RECOGNITION_REQUEST_CODE && resultCode == RESULT_OK){
ArrayList commandList = data.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS);
mList.setAdapter(new ArrayAdapter(this, android.R.layout.simple_list_item_1, commandList));
// для лучшего распознавания английского языка, поставьте в настройках англ. яз как язык системы
// хотя все то же самое можно проделать и с русскими словами
if (commandList.contains("red")){
speakButton.setText("red");
speakButton.setBackgroundColor(Color.RED);
}
if (commandList.contains("blue")){
speakButton.setText("blue");
speakButton.setBackgroundColor(Color.BLUE);
}
if (commandList.contains("green")){
speakButton.setText("green");
speakButton.setBackgroundColor(Color.GREEN);
}
if (commandList.contains("yellow")){
speakButton.setText("yellow");
speakButton.setBackgroundColor(Color.YELLOW);
}
if (commandList.contains("white")){
speakButton.setText("white");
speakButton.setBackgroundColor(Color.WHITE);
}
if (commandList.contains("black")){
speakButton.setText("black");
speakButton.setBackgroundColor(Color.BLACK);
}
// выйти
if (commandList.contains("finish")){
finish();
}
// попробуем открыть гугловские карты
if (commandList.contains("maps")){
Intent i = new Intent();
PackageManager manager = getPackageManager();
i = manager.getLaunchIntentForPackage("com.google.android.apps.maps");
i.addCategory(Intent.CATEGORY_LAUNCHER);
startActivity(i);
}
//попросим открыть некоторые сайты
if (commandList.contains("google")){
finish();
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.google.com"));
startActivity(browserIntent);
}
if (commandList.contains("facebook")){
finish();
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.facebook.com"));
startActivity(browserIntent);
}
// если у Вас есть права суперпользователя
// Можно как-то и добавив "android.permission.REBOOT", но я не стал на этом заморачиваться (пока)
if (commandList.contains("reboot")){
try {
Process proc = Runtime.getRuntime()
.exec(new String[]{ "su", "-c", "reboot -p" });
proc.waitFor();
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
super.onActivityResult(requestCode, resultCode, data);
}
Так выглядит окно записи команд:
Скажем с красивым английским акцентом «maps». Вызвали Google Maps:
«Blue»:
Как видите, в списке выводятся все возможные (похожие) слова и из них уже выбирается необходимое нам.
Ну и на «finish», я закончил беседу с бездушной (или нет?) машиной.
Надеюсь моя небольшая статья побудит кого-нибудь на создание (не, не терминатора) какого-либо перспективного проекта, который упростит повседневную жизнь людям, а вам принесет миллионы, ну или хотя бы окажется полезной. Дерзайте!
P.S.: парочка полезных ссылок, на документацию и на исходники
Автор: McClay