Programación y transmisión de datos a Arduino por aire usando el ESP8266. Tercera parte Hola ANDROID

Les ofrezco, queridos lectores de GeekTimes, otro artículo del ciclo sobre el uso del chip ESP8266 como puente inalámbrico para microcontroladores AVR, utilizando la plataforma de hardware Arduino Uno (Nano) como ejemplo. Esta vez, para el vuelo a la luna para controlar la plataforma, usamos un dispositivo basado en ANDROID en lugar de una computadora. Bueno, por ejemplo, un teléfono inteligente.



Detalles debajo del corte:

Para nuestro trabajo, utilizaremos las herramientas descritas en el artículo anterior: el programador inalámbrico BABUINO y el módulo MPDE (módulo para programa e intercambio de datos) para flashear en ESP8266.

Como resultó de los comentarios de los usuarios, el programador mismo, en general, acudió a la corte y algunas personas incluso lo usaron con éxito. Bueno, básicamente, la cosa es realmente conveniente; Lancé la aplicación en Windows, seleccioné el archivo hexadecimal de la carpeta deseada y eso es todo: en unos segundos, el programa en el dispositivo correcto sin cables. Otra cosa es que en vano, con ardor excesivo, ataqué a los usuarios del software ARDUINO que escriben en Wiring C y usan el IDE ARDUINO con sus bocetos y bibliotecas. Por supuesto, todos hacen lo que es conveniente para él, ya sea en Arduin Wiring C o C del estudio AVR. Pero al final, algunos usuarios, por alguna razón, decidieron de inmediato que el programador no es de ninguna manera compatible con el software ARDUINO.

De hecho, no hay problemas de compatibilidad, por supuesto. Absolutamente también compile su boceto donde sea conveniente para usted el estado de un archivo hexadecimal y envíelo fácilmente a través de un programador inalámbrico a su Arduino UNO o NANO.

El intercambio de datos bajo el software ARDUINO tampoco causa ningún problema. Escribe las líneas mágicas:

Serial.begin (9600);

y luego algo como:

recibirByte = Serial.read (); // lee el byte del búfer

o:

Serial.write (recibirByte); // registro de bytes

Y puede intercambiar secuencias de bytes a través de WI-FI con bastante calma. Para el microcontrolador AVR envía a ESP8266 y recibe bytes desde allí a través del puerto serie UART, que, como podemos ver, cualquier humanitario puede configurar el trabajo con el que se encuentra en Arduino.

Ahora volvamos al tema de este artículo. Para controlar el robot a través de un teléfono inteligente, por supuesto, debe escribir la aplicación adecuada para este teléfono inteligente.

Como persona que presentó este proceso hace un mes de manera extremadamente vaga, ahora puedo declarar con toda responsabilidad que el asunto no es esencialmente complicado. A menos, por supuesto, que tenga al menos algunos conocimientos básicos en el campo de Java.

Para cuando se escriben aplicaciones de Android, el código fuente se escribe en Java y luego se compila en código de bytes estándar de Java utilizando herramientas Java tradicionales. Luego, otras cosas interesantes suceden con el código, pero no necesitamos estos detalles aquí.

Parece que todavía hay oportunidades para escribir aplicaciones en C para trabajadores incondicionales notorios que obtienen puntajes por nanosegundos, y también en algún lugar hay algún tipo de paquete para traducir su código de Python, pero no puedo decir nada aquí, porque he tomado la decisión correcta durante mucho tiempo .

Entonces, Java y el paquete de software Android Studio: un entorno de desarrollo integrado (IDE) para trabajar con la plataforma Android basada en el software IntelliJ IDEA de JetBrains, la herramienta oficial de desarrollo para aplicaciones de Android.



Si ya está trabajando con el software IntelliJ IDEA, la interfaz familiar le sorprenderá gratamente.

Conocí los conceptos básicos de la creación de aplicaciones del libro de B. Phillips y C. Stewart - Programación "ANDROID" para profesionales ". Según tengo entendido, los profesionales consideran lectores que están al menos un poco familiarizados con Java SE. Algo archi-complejo en este libro No lo encontré, y para nuestros propósitos los primeros diez capítulos del libro serán suficientes, afortunadamente, todos los ejemplos de código se dan cuando se trabaja con el Android Studio anterior.

Las aplicaciones de depuración se pueden llevar a cabo en un emulador de software o directamente en un teléfono inteligente cambiándolo al "modo desarrollador".

En un artículo anterior, se describió el control de trolley a través de una aplicación de Windows en Windows. Es decir, todo el código para crear conexiones HTTP y UDP, así como la lógica de control, ya está presente en teoría. Por lo tanto, habiendo adoptado el eslogan de Oracle "Está escrito en un lugar, funciona en todas partes", simplemente transferimos estas clases a un nuevo programa para aplicaciones de Android. Pero la GUI es una interfaz gráfica de usuario, por razones obvias, debe dejarla donde estaba. Pero, por otro lado, en Android todo se hace de manera muy similar y bastante rápida, por lo que no nos quedaremos en el perdedor.

Meter un dedo en la pantalla



Por lo tanto, creamos un nuevo proyecto "FourWheelRobotControl" en Android Studio.
Esta es una aplicación simple y consistirá en actividad

Clase MainActivity.java
import android.content.Context; import android.hardware.Sensor; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.MotionEvent; import android.view.View; import android.widget.ImageButton; import android.widget.TextView; import android.widget.Toast; public class MainActivity extends AppCompatActivity { private ImageButton mButtonUP; private ImageButton mButtonDOWN; private ImageButton mButtonLEFT; private ImageButton mButtonRIGHT; public static byte direction = 100; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); new HTTP_client(40000); new Udp_client(); mButtonUP = (ImageButton) findViewById(R.id.imageButtonUP); mButtonUP.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN) { direction = 3; } } if (event.getAction() == MotionEvent.ACTION_UP) { direction = 100; } return false; } }); mButtonDOWN = (ImageButton) findViewById(R.id.imageButtonDown); mButtonDOWN.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN) { direction = 4; Toast.makeText(MainActivity.this, " " + direction, Toast.LENGTH_SHORT).show(); } if (event.getAction() == MotionEvent.ACTION_UP) { direction = 100; } return false; } }); mButtonLEFT = (ImageButton) findViewById(R.id.imageButtonLeft); mButtonLEFT.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN) { direction = 1; Toast.makeText(MainActivity.this, " " + direction, Toast.LENGTH_SHORT).show(); } if (event.getAction() == MotionEvent.ACTION_UP) { direction = 100; } return false; } }); mButtonRIGHT = (ImageButton) findViewById(R.id.imageButtonRight); mButtonRIGHT.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN) { direction = 2; Toast.makeText(MainActivity.this, " " + direction, Toast.LENGTH_SHORT).show(); } if (event.getAction() == MotionEvent.ACTION_UP) { direction = 100; } return false; } }); } 

y diseño:

maquetacion
  /spoiler/ activity_main.xml <?xml version="1.0" encoding="utf-8"?> <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="mikhail_akhmetov.fourweelsrobotcontrol.MainActivity"> <ImageButton android:id="@+id/imageButtonRight" style="@android:style/Widget.Holo.ImageButton" android:layout_width="52dp" android:layout_height="52dp" android:layout_marginEnd="8dp" android:layout_marginLeft="8dp" android:layout_marginRight="8dp" android:layout_marginStart="8dp" android:background="@android:color/holo_orange_dark" app:layout_constraintBottom_toTopOf="@+id/linearLayout" app:layout_constraintHorizontal_bias="0.417" app:layout_constraintLeft_toRightOf="@+id/imageButtonLeft" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintVertical_bias="0.513" app:srcCompat="@android:drawable/ic_media_ff"/> <ImageButton android:id="@+id/imageButtonUP" style="@android:style/Widget.ImageButton" android:layout_width="52dp" android:layout_height="52dp" android:layout_marginBottom="8dp" android:layout_marginTop="8dp" android:background="@android:color/holo_orange_dark" app:layout_constraintBottom_toTopOf="@+id/imageButtonDown" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintVertical_bias="0.486" app:srcCompat="@android:drawable/arrow_up_float"/> <ImageButton android:id="@+id/imageButtonDown" style="@android:style/Widget.ImageButton" android:layout_width="52dp" android:layout_height="52dp" android:layout_marginBottom="57dp" android:layout_marginLeft="8dp" android:background="@android:color/holo_orange_dark" android:fadingEdge="horizontal" app:layout_constraintBottom_toTopOf="@+id/linearLayout" app:layout_constraintHorizontal_bias="0.487" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:srcCompat="@android:drawable/arrow_down_float" android:layout_marginStart="8dp"/> <ImageButton android:id="@+id/imageButtonLeft" style="@android:style/Widget.ImageButton" android:layout_width="52dp" android:layout_height="52dp" android:layout_marginLeft="94dp" android:layout_marginStart="94dp" android:background="@android:color/holo_orange_dark" app:layout_constraintBottom_toTopOf="@+id/linearLayout" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintVertical_bias="0.513" app:srcCompat="@android:drawable/ic_media_rew" /> <LinearLayout android:id="@+id/linearLayout" android:layout_width="368dp" android:layout_height="227dp" android:layout_marginBottom="11dp" android:layout_marginEnd="8dp" android:layout_marginLeft="8dp" android:layout_marginRight="8dp" android:layout_marginStart="8dp" android:orientation="vertical" android:weightSum="1" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintHorizontal_bias="1.0" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent"> <TextView android:id="@+id/textViewX" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="0.28" /> <TextView android:id="@+id/textViewY" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="0.28" /> <TextView android:id="@+id/textViewZ" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="0.23" /> </LinearLayout> </android.support.constraint.ConstraintLayout> 


No es necesario escribir con bolígrafos, se genera automáticamente después de sus creaciones en el editor.

Ahora solo transferimos dos clases del programa dado en el artículo anterior:

HTTP_client.java
 import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.net.InetAddress; import java.net.Socket; public class HTTP_client extends Thread{ int port; String s; public static String host_address="192.168.1.138";//    public String Greetings_from_S; HTTP_client(int port) { this.port = port; start(); } public void run() { try (Socket socket = new Socket(host_address,port)){ PrintWriter pw = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()), true); BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream())); pw.println("stop data\r");//  ,    pw.println("data\r");// Greetings with SERVER Greetings_from_S = br.readLine(); if (Greetings_from_S.equals("ready")) { new Udp_client(); } } catch (Exception e) { e.printStackTrace(); } } } 


Udp_clent.java
 import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; public class Udp_client extends Thread { int i =0; byte [] data = {0}; int udp_port=50000; InetAddress addr; DatagramSocket ds; public Udp_client() { try { ds = new DatagramSocket(); addr = InetAddress.getByName(HTTP_client.host_address); } catch (Exception e) { } start(); } public void run() { while (true) { byte temp = MainActivity.direction; String s = "" + MainActivity.direction; data = s.getBytes(); if(temp!=100 ) { DatagramPacket pack = new DatagramPacket(data, data.length, addr, udp_port); try { ds.send(pack); i=0; Thread.sleep(200); } catch (Exception e) { } } else { if(i==0) { s = "" + 0; data = s.getBytes(); DatagramPacket pack = new DatagramPacket(data, data.length, addr, udp_port); try { ds.send(pack); Thread.sleep(200); } catch (Exception e) { } } i=1;//     } } } } 

La esencia del programa sigue siendo la misma. MainActivity primero lanza clientes HTTP y UDP, y luego captura las pulsaciones y depresiones de los botones, enviando un código de dirección para formar un paquete UDP. Y a partir de ahí, todo ya está: "adelante", "atrás", "izquierda", "derecha" y cuando presiona "detener" se van a través de WI-FI en un carrito.

Además de todo esto, necesitamos modificar ligeramente el archivo del llamado manifiesto, que, una vez más, se genera principalmente por sí mismo.

Un manifiesto es un archivo XML con metadatos que describe su aplicación de Android. El archivo de manifiesto siempre se llama AndroidManifest.xml y se encuentra en el directorio de la aplicación / manifiesto de su proyecto.

Es cierto, hay muy poco trabajo para nosotros.

prohibir la rotación de la pantalla:

 android:screenOrientation="portrait" 

Permitimos trabajar en Internet:

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

Y aquí está todo por completo.

AndroidManifest.xml
 <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="mikhail_akhmetov.fourweelsrobotcontrol"> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme" > <activity android:name=".MainActivity" android:screenOrientation="portrait" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> <uses-permission android:name="android.permission.INTERNET"/> </manifest> 


Al inicio, deberíamos ver algo como:



Eso es esencialmente todo. Ahora el carro se puede controlar desde un teléfono móvil. La aplicación es extremadamente simple, porque es una aplicación de demostración sin "silbatos y falsificaciones", como buscar un carrito en una red doméstica, conectarse, desconectarse y otras características útiles que hacen la vida más fácil, pero hacen que el código sea difícil de entender.

Por otro lado, operar con los botones en pantalla es lo mismo
"Cómo beber solo vodka, incluso del cuello: no hay nada en él más que languidecer de espíritu y alboroto".
Y Venya Erofeev tenía razón en esto, por supuesto.

Es mucho más interesante, por ejemplo, dirigir un carro con la ayuda de acelerómetros estándar del mismo teléfono inteligente.

Además, esta característica también se implementa de manera muy simple, a través de las llamadas intenciones. Es cierto que crear tus propias intenciones es más difícil que usar las listas. Afortunadamente, nadie prohíbe usar los ya hechos.

ACELERÓMETRO EN MASAS



Por lo tanto, nuestro código en MainActivity (y solo en él) cambiará mínimamente.

Agregue variables para el acelerómetro:

 private SensorManager mSensorManager; private Sensor mOrientation; private float xy_angle; private float xz_angle; 

Obtenemos el sensor del sistema y lo registramos como oyente.

 mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); //    mOrientation = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); //    mSensorManager.registerListener(this, mOrientation, SensorManager.SENSOR_DELAY_NORMAL); 

Implementamos la interfaz de escucha en sí:

 public class MainActivity implements SensorEventListener 

Y escribiremos cuatro métodos obligatorios de los cuales usaremos solo el último. Un método que funciona al cambiar las lecturas del acelerómetro. En realidad, quería interrogar al acelerómetro yo mismo, como periféricos normales con un período de aproximadamente 100 ms, porque había una sospecha (debido al nombre enCambiado) de que el método funcionaba con demasiada frecuencia. Pero allí todo es privado e higos para las interfaces que pasará.

 @Override public void onAccuracyChanged(Sensor sensor, int accuracy) { //    } @Override protected void onResume() { super.onResume(); } @Override protected void onPause() { super.onPause(); } @Override public void onSensorChanged(SensorEvent event) {} //   

Como resultado, MainActivity.java tomará la siguiente forma
 import android.hardware.SensorEvent; import android.hardware.SensorEventListener; import android.hardware.SensorManager; import android.content.Context; import android.hardware.Sensor; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.widget.ImageButton; import android.widget.TextView; public class MainActivity extends AppCompatActivity implements SensorEventListener { private ImageButton mButtonUP; private ImageButton mButtonDOWN; private ImageButton mButtonLEFT; private ImageButton mButtonRIGHT; public static byte direction = 100; private SensorManager mSensorManager; private Sensor mOrientation; private float xy_angle; private float xz_angle; private int x; private int y; private TextView xyView; private TextView xzView; private TextView zyView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); new HTTP_client(40000); new Udp_client(); mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); //    mOrientation = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); //    mSensorManager.registerListener(this, mOrientation, SensorManager.SENSOR_DELAY_NORMAL); xyView = (TextView) findViewById(R.id.textViewX); // xzView = (TextView) findViewById(R.id.textViewY); //       zyView = (TextView) findViewById(R.id.textViewZ);//   "direction" mButtonUP = (ImageButton) findViewById(R.id.imageButtonUP); mButtonDOWN = (ImageButton) findViewById(R.id.imageButtonDown); mButtonLEFT = (ImageButton) findViewById(R.id.imageButtonLeft); mButtonRIGHT = (ImageButton) findViewById(R.id.imageButtonRight); //    } @Override public void onAccuracyChanged(Sensor sensor, int accuracy) { //    } @Override protected void onResume() { super.onResume(); } @Override protected void onPause() { super.onPause(); } @Override public void onSensorChanged(SensorEvent event) { //   xy_angle = event.values[0]*10; // XY xz_angle = event.values[1]*10; // XZ x=-(int) xy_angle*1; y=-(int) xz_angle*1; xyView.setText(" x = "+ String.valueOf(x)); xzView.setText(" y = "+String.valueOf(y)); zyView.setText(" direction "+String.valueOf(direction)); if(y>-40&&y<-20){ direction=100;//   ,   ,     if (x>10){//   10  30  20  direction=(byte)(x+30); if (direction>60){direction=60;} } if(x<-10){ direction=(byte)(-x+50); if (direction>80){direction=80;} } } else { if (y > -20) {//  ,  -20: 20  40  direction = (byte) (y / 2 + 10); if (direction > 20) { direction = 20; } ; } if (y < -40) {//  ,  -40: -80  40  direction = (byte) (-y - 20); if (direction > 40) { direction = 40; } ; } } } } //   direction 100  // 1-20  ,   -20 // 21-40  ,   -40 // 41-60 ,  10 // 61-80 ,   -10 


El programa muestra los sensores en dos ejes en la pantalla del teléfono inteligente. En lugar del tercer eje, que no se utiliza, se muestra la variable de dirección "dirección". Y los mismos datos se ejecutan en forma de una secuencia de bytes en el carrito. Sin embargo, debido al hecho de que la secuencia es puramente byte, sería difícil determinar dónde estaría el comando "adelante" o "detener". Por lo tanto, actué simplemente: cada dirección y ángulo de inclinación tiene su propio rango de números. En términos generales, 1-20 es "hacia adelante" con la velocidad correspondiente, 21-40 es "hacia atrás" y así sucesivamente. Por supuesto, sería posible transmitir puramente datos a través de UDP, y los comandos de control deberían configurarse a través del protocolo TCP, y esto sería ciertamente más correcto. Pero para esto necesitas editar el programa en el ESP8266, que todavía no quiero.

Entonces, el carrito está rodando por el apartamento, reaccionando con sensibilidad a las pendientes de mi GalaxyS7, pero incluso esto, como solía decir el famoso Venya, todavía no es eso.

“Ahora te ofrezco lo último y lo mejor. "La corona del trabajo, sobre todo recompensas", como dijo el poeta. En resumen, te ofrezco el cóctel "Offal Off", una bebida que eclipsa todo. Esto ya no es una bebida, es la música de las esferas. „

En esta era de Siri y Alexa, ¿hay algo para hacer girar tus manos? ¡Que el control de voz obedezca!

Y ahora escúchame!



Cito:

En realidad, trabajar con reconocimiento de voz y síntesis de voz en Android es muy simple. Todos los cálculos complejos están ocultos para nosotros en una biblioteca bastante elegante con una API simple. Puede dominar esta lección incluso si tiene un conocimiento muy superficial de la programación para Android.

De hecho, todo resultó bastante torpe para mí, pero probablemente porque utilicé la opción más simple y no profundicé en esta API correctamente. Todo también se hace a través de intentos, con la ayuda de los cuales recurrimos al motor de voz de Google, es decir, a su función de reconocimiento de voz. Por lo tanto, necesita un Internet que funcione.

Nuevamente, solo MainActivity.java cambia, aunque cambié el diseño un poco más (cuatro botones ahora son completamente inútiles, uno es suficiente).

Se ha agregado lo siguiente a MainActivity.java:

La misma intención:

 Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH); intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_FREE_FORM); intent.putExtra(RecognizerIntent.EXTRA_PROMPT, ", ,  -??? "); startActivityForResult(intent, Print_Words); 

Y lo que devuelve:

 @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { //    : if (requestCode==Print_Words && resultCode==RESULT_OK) { //     ,   : ArrayList<String>result=data.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS); //     TextView: stroka_otveta = result.toString(); } 

Y devuelve una serie de palabras similares, y en una "forma basura", con todo tipo de corchetes y comas. Y solo tienes que elegir una palabra similar a la que dijiste. Bueno, y en consecuencia, si se atrapa la palabra "adelante", entonces avanzamos, si es "correcto", luego a la derecha y así sucesivamente. Por supuesto, debemos tener en cuenta dónde a través de "E", donde se adjunta la coma extra (corté los corchetes, pero no tenía suficiente fuerza para las comas).

En total, el texto de MainActivity.java se hizo tan
 import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.MotionEvent; import android.view.View; import android.widget.ImageButton; import android.widget.TextView; import java.util.ArrayList; import android.content.Intent; import android.speech.RecognizerIntent; public class MainActivity extends AppCompatActivity { private ImageButton mButtonUP; public static byte direction = 100; public String stroka_otveta; private static final int Print_Words = 100; private TextView EnteredText1; private TextView EnteredText2; public static TextView EnteredText3; private boolean slovo_raspoznano =false; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); new Udp_client(); new HTTP_client(40000); EnteredText1 = (TextView) findViewById(R.id.textViewX); // EnteredText2 = (TextView) findViewById(R.id.textViewY); // EnteredText3 = (TextView) findViewById(R.id.textViewZ); // mButtonUP = (ImageButton) findViewById(R.id.imageButtonUP); mButtonUP.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN){ if(HTTP_client.ok){ // RecognizerIntent        : EnteredText3.setText(" http  "); Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH); intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_FREE_FORM); intent.putExtra(RecognizerIntent.EXTRA_PROMPT, ", ,  -??? "); startActivityForResult(intent, Print_Words); } else { EnteredText3.setText("  "); } } if (event.getAction() == MotionEvent.ACTION_UP ){ } return false; } }); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { //    : if (requestCode==Print_Words && resultCode==RESULT_OK) { //     ,   : ArrayList<String>result=data.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS); //     TextView: stroka_otveta = result.toString(); } StringBuffer sb = new StringBuffer(stroka_otveta); sb.deleteCharAt(stroka_otveta.length()-1); sb.deleteCharAt(0); stroka_otveta=sb.toString(); String[] words = stroka_otveta.split("\\s"); //        () //    for(int i = 0; i< words.length;i++) { if(words[i].equals(",")||words[i].equals("")) { direction = 1; slovo_raspoznano=true; stroka_otveta=words[i]; } if(words[i].equals(",")||words[i].equals("")){ direction=2; slovo_raspoznano=true; stroka_otveta=words[i]; } if(words[i].equals(",")|| words[i].equals("")){ direction=4; slovo_raspoznano=true; stroka_otveta=words[i]; } if(words[i].equals(",")|| words[i].equals(",")|| words[i].equals("") || words[i].equals("")){ direction=3; slovo_raspoznano=true; stroka_otveta=words[i]; } if(words[i].equals(",")|| words[i].equals(",")|| words[i].equals("") || words[i].equals("")){ direction=100; slovo_raspoznano=true; stroka_otveta=words[i]; } } if(!slovo_raspoznano){ direction=100; stroka_otveta=" ,   ... "; } EnteredText1.setText(" "+direction+" " +stroka_otveta); slovo_raspoznano=false; super.onActivityResult(requestCode, resultCode, data); } } 

Bueno, hasta el diseño del montón con un botón

actividad_principal.xml.
  <?xml version="1.0" encoding="utf-8"?> <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="mikhail_akhmetov.fourwheelsrobotandroidvoice.MainActivity"> <ImageButton android:id="@+id/imageButtonUP" style="@android:style/Widget.ImageButton" android:layout_width="160dp" android:layout_height="146dp" android:layout_marginTop="8dp" android:background="@android:color/holo_orange_dark" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" app:srcCompat="@android:drawable/arrow_up_float" android:layout_marginBottom="8dp" app:layout_constraintBottom_toTopOf="@+id/linearLayout"/> <LinearLayout android:id="@+id/linearLayout" android:layout_width="368dp" android:layout_height="227dp" android:layout_marginBottom="11dp" android:layout_marginEnd="8dp" android:layout_marginLeft="8dp" android:layout_marginRight="8dp" android:layout_marginStart="8dp" android:orientation="vertical" android:weightSum="1" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintHorizontal_bias="1.0" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent"> <TextView android:id="@+id/textViewTitle" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="   " android:textColor="@android:color/holo_red_dark"/> <TextView android:id="@+id/textViewX" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="0.28" /> <TextView android:id="@+id/textViewY" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="0.28" /> <TextView android:id="@+id/textViewZ" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="0.23" /> </LinearLayout> </android.support.constraint.ConstraintLayout> 

Lo más sorprendente es que realmente monta y escucha la voz (como regla). Pero, por supuesto, la interfaz de freno; mientras dices, hasta que sea reconocido y vuelva; En resumen, elija una velocidad pequeña por adelantado o la sala es viceversa.

Eso es todo por hoy, me alegrará si me ha gustado.

Source: https://habr.com/ru/post/es409107/


All Articles