Éste blog es un agregador de posts de otros blogs que, por su temática, son de alto interés para los lectores de HijoDeBlog. Cada enlace redirige al autor original del post. Contacta con info _at_ hijodeblog _dot_ com para cualquier duda.

Creación de un Rest API con Google AppScript y uso de Volley Framework en Android – Parte 2  

En la primera parte de este tutorial aprendimos como hacer un pequeño Rest API con SpreadSheets de Google Drive. Ahora toca el turno de manejar dicha información en nuestra app, para ello no utilizaremos la manera tradicional  (Usando Threads con AsyncTask ver aqui ), en su remplazo usaremos un Framework HTTP client support llamado Volley, el uso de uno o de otro ya depende de gustos. Aqui el video del resultado que esperamos:

Volley:  ¿Android de verdad tenia un cliente HTTP?

Como se menciono en el Google I/O de 2013: “Volley is a library that makes networking for Android apps easier and most importantly, faster.” Por lo que ya no es tan doloroso el consumir web services. Anteriormente este tipo de aplicaciones se solucionaban a la manera HTTP client Java tradicional (con flujo de entrada, buffer, etc) pero con Volley, solo necesitamos saber que tipo de respuesta esperamos (JSONObject, JSONArray, String etc) y eso es todo. La siguiente imagen representa el diagrama de nuestra App:

Agregando la Libreria

Para trabajar con Volley necesitamos importar según sea el caso:

  • Android Studio: Solo agregamos la dirección de maven central (com.mcxiaoke.volley:library:1.0.+) en nuestro build.gradle
  •         dependencies {
                          compile 'com.android.support:appcompat-v7:19.1.0'
                          compile 'com.mcxiaoke.volley:library:1.0.+'
                          compile fileTree(dir: 'libs', include: ['*.jar'])
            }
           
  • Eclipse ADT: Clonamos directamente del repositorio master, importamos a eclipse la libreria como proyecto Android y después la asignamos como libreria a nuestro proyecto: click derecho en nuestro proyecto -> Android -> Library add -> “volley”
  • git clone https://android.googlesource.com/platform/frameworks/volley
    

Preparando Volley

Para empezar a trabajar con Volley creamos una instancia del mismo (RequestQueue), solo necesitamos crearla a partir del metodo newRequestQueue de Volley que recibe nuestro contexto:

RequestQueue queue = Volley.newRequestQueue(this);

Como mencione anteriormente, debemos saber que tipo de respuesta esperamos recibir, en nuestro caso es un JSONArray. Construiremos una instancia de ese tipo la cual podremos usarla en cualquier momento que lo necesitamos (es como un singleton, aqui preparamos el request, aun no es ejecutado).


Para construir el JsonArrayRequest su constructor recibe la URL a la que queremos acceder, la clase anonima Response.Listener que sobrecarga el metodo: onResponse(), ademas de la clase anonima Response.ErrorListener() que sobrecarga el metodo onErrorResponse(). Esto quiere decir que intuitivamente, dependiendo de si la respuesta fue exitosa o no, se mandan a llamar uno u el otro:

String URL="https://script.google.com/macros/s/AKfycbzzZbp4a8OdQ1YI_CBMDy17qDW-ouPZGwIbA3QfV_UsP7PAIxk/exec";

       JsonArrayRequest req = new JsonArrayRequest(URL, new Response.Listener<JSONArray> () {

            @Override
            public void onResponse(JSONArray response) {

            "Entraremos en este metodo si el llamado fue exitoso"
            "recibimos JSONArray response como respuesta"

            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {

            "Entraremos en este metodo si existió un error"

            }
        });

Ahora solo queda ejecutar nuestro request, recordamos que antes hemos creado una instancia RequestQueue llamada “queue”, “queue” tiene un metodo llamado “add” que recibe como parametro un request preparado de cualquier tipo (recordar el de nosotros es JsonArrayRequest llamado “req”), entonces lo pasamos como parametro para que se pueda ejecutar:

queue.add(req);

En nuestro caso solo es uno, pero “RequestQueue” puede ejecutar n llamados como instancias de respuesta hemos creado, ¿cool no es cierto?

Lo demás es cosa de diseño

Como un ListView no es suficiente para mostrar los datos de manera atractiva, hemos creado uno a la medida,con todas las buenas practicas que lo amerita, hemos creamos un modelo llamado “Persona” que es construido con los datos que obtenemos del API (Nombre, Sueldo, SalarioDiario, DiasLaborados).

Modelo Persona

package mx.gdgipn.nominandroid.app.models;

/**
 * Created by thespianartist on 4/12/14.
 */
public class Persona {

    private  String nombre;
    private  String salarioDiario;
    private  String diasLaborados;
    private  String sueldo;

    public String getNombre() {
        return nombre;
    }

    public void setNombre(String nombre) {
        this.nombre = nombre;
    }

    public String getSalarioDiario() {
        return salarioDiario;
    }

    public void setSalarioDiario(String salarioDiario) {
        this.salarioDiario = "$"+salarioDiario+" por dia";
    }

    public String getDiasLaborados() {
        return diasLaborados;
    }

    public void setDiasLaborados(String diasLaborados) {
        this.diasLaborados = diasLaborados+" dias trabajados";
    }

    public String getSueldo() {
        return sueldo;
    }

    public void setSueldo(String sueldo) {
        this.sueldo = "Sueldo Total $"+sueldo;
    }

}

CustomAdapter

public class CustomAdapter extends ArrayAdapter<Persona>{
    ArrayList<Persona> data;
    LayoutInflater inflater;

     public CustomAdapter(Context context, ArrayList<Persona> objects){
         super(context, -1, objects);
         this.data = objects;
         this.inflater = LayoutInflater.from(context);
     }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

        ViewHolder holder;
        Persona persona = data.get(position);
        int layout = R.layout.list_row;

        if (convertView == null) {

            convertView = inflater.inflate(layout, null);
            holder = new ViewHolder();
            holder.nombre = (TextView) convertView.findViewById(R.id.nombre);
            holder.salarioDiario = (TextView) convertView.findViewById(R.id.salario_diario);
            holder.diasLaborados = (TextView) convertView.findViewById(R.id.dias_laborados);
            holder.sueldo = (TextView) convertView.findViewById(R.id.sueldo);
            convertView.setTag(holder);

        }else {
            holder = (ViewHolder) convertView.getTag();
        }

        holder.nombre.setText(persona.getNombre());
        holder.sueldo.setText(persona.getSueldo());
        holder.salarioDiario.setText(persona.getSalarioDiario());
        holder.diasLaborados.setText(persona.getDiasLaborados());

       return convertView;

    }

    public static class ViewHolder{
        public TextView nombre;
        public TextView salarioDiario;
        public TextView diasLaborados;
        public TextView sueldo;
    }

Diseño de cada Row de la lista

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="#90000000"
    >

    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceLarge"
        android:text="Nombre"
        android:textColor="#FFFFFF"
        android:textStyle="bold"
        android:gravity="center_horizontal"
        android:paddingTop="15dp"
        android:paddingBottom="15dp"
        android:id="@+id/nombre" />

    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceLarge"
        android:text="Sueldo"
        android:textColor="#89d8fa"
        android:layout_marginLeft="10dp"
        android:layout_marginBottom="10dp"
        android:id="@+id/sueldo" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Salario diario"
        android:textStyle="italic"
        android:textColor="#ffb900"
        android:layout_marginLeft="10dp"
        android:id="@+id/salario_diario" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Dias"
        android:textStyle="italic"
        android:layout_marginRight="10dp"
        android:layout_marginBottom="15dp"
        android:layout_gravity="right"
        android:textColor="#00de72"
        android:id="@+id/dias_laborados" />

</LinearLayout>

Finalmente

Nuestro MainActivity contiene el llamado a nuestro API (hecho con Volley), el cual si es un éxito, construira nuestro adapter para el ListView con todos los objetos recibidos, no es tan directo ya que se necesita “parsear” la información, y de la cual creamos un metodo para dicho proposito, a continuacion el codigo completo de nuestro MainActivity:

public class MainActivity extends ActionBarActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //ActionBar de Color Negro, solo por estetica
        ColorDrawable colorDrawable = new ColorDrawable(Color.parseColor("#000000"));
        ActionBar actionbar = getSupportActionBar();
        actionbar.setBackgroundDrawable(colorDrawable);

        //Creamos una instancia de RequestQueue que solo recibe el contexto
        RequestQueue queue = Volley.newRequestQueue(this);

        //URL del SpreadSheet
        String URL = "https://script.google.com/macros/s/AKfycbzzZbp4a8OdQ1YI_CBMDy17qDW-ouPZGwIbA3QfV_UsP7PAIxk/exec";

        //Creamos una instancia de un ProgressDialog para que el usuario observe que los datos se estan obteniendo
        final ProgressDialog progressDialog = ProgressDialog.show(this, "Please wait ...", "Downloading Data ...", true);

        //Configuramos nuestro request, al intanciar JsonArrayRequest recibe la URL y un Listener de JSON Array, el cual
          //contiene una serie de metodos a implelentar, practicamente si resulto bien o existio un error, ademas
              // sirve como un singleton para mandarlo a llamar cuando sea necesario hacer de nuevo el request.
                // Recordar que este solo construye el llamado HTTP, se ejecuta mas adelante cuando lo agregamos como parametro del metodo add
                   //de RequestQueue

        JsonArrayRequest req = new JsonArrayRequest(URL, new Response.Listener<JSONArray> () {

            @Override
            public void onResponse(JSONArray response) {

                //Un textview antes de la vista nos permite ver los datos crudos dentro de la misma app
                TextView textView = (TextView) findViewById(R.id.datos_crudos);
                textView.setText(response.toString());
                //dejamos en el Log un pequeño mensaje con el response como string para ver un preview de lo que recibimos
                Log.e("respeusta", response.toString());

                //buscamos el listview de main_activity
                ListView list = (ListView) findViewById(R.id.list_view);

                //Si vemos el CustomAdapter debemos pasar un contexto y un ArrayList de objetos Personas
                  //dicho ArrayList es parseao de la respuesta por medio de la funcion parser

                CustomAdapter adapter = new CustomAdapter(getApplicationContext(), parser(response));

                //pasamos el adapter para que la lista se muestre en el UI
                list.setAdapter(adapter);

                progressDialog.dismiss();

            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                VolleyLog.e("Error: ", error.getMessage());
                progressDialog.dismiss();

            }
        });

        // Ejecutamos Volley, con el request preparado
        queue.add(req);
    }

    // La funcion de abajo se encarga de parsear toda la informacion

    public ArrayList<Persona> parser(JSONArray respuesta){
        ArrayList<Persona> personasAux = new ArrayList<Persona>();

        for(int i = 0; i < respuesta.length(); i++){
            JSONObject jsonObject;
            Persona persona = new Persona();

            try {
                jsonObject = (JSONObject) respuesta.get(i);
                persona.setNombre(jsonObject.getString("nombre"));
                persona.setSalarioDiario(jsonObject.getString("salarioDiario"));
                persona.setDiasLaborados(jsonObject.getString("diasLaborados"));
                persona.setSueldo(jsonObject.getString("sueldo"));
                personasAux.add(persona);

            } catch (JSONException e) { Log.e("peticion", "Error al parsear");}
        }

        return personasAux;
    }
}

Layout De MainActivity

<LinearLayout 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:orientation="vertical"
    tools:context="mx.gdgipn.nominandroid.app.MainActivity">

    <ScrollView
        android:layout_width="fill_parent"
        android:layout_height="match_parent"
        android:layout_weight="3" >

        <TextView
            android:layout_weight="1"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:id="@+id/datos_crudos"
            android:layout_gravity="center_horizontal" />
    </ScrollView>

    <ListView
        android:layout_weight="1"
        android:headerDividersEnabled="false"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:id="@+id/list_view"
        android:footerDividersEnabled="false" />

</LinearLayout>

Y eso es todo, no olviden hacer clone del repositorio que dejo a continuación con el ejemplo completo, no duden en dejar sus inquietudes, y si tienen alguna recomendacion de proximos temas con gusto lo trabajo. Saludos

Etiquetas:
Comentarios: Comentarios desactivados

Cargador de coche inalámbrico Nokia  

Hoy os presentamos uno de los soportes para coche que más nos ha llamado la atención en los últimos tiempos, hoy os presentamos el soporte de Nokia para choche con tecnología de carga inalámbrica y NFC, vamos un soporte que lo tiene todo. No os perdáis el vídeo que os hemos preparado para mostraros este …

Continuar leyendo »

The post Cargador de coche inalámbrico Nokia appeared first on DesAndrOId.


Comentarios: Comentarios desactivados

Creación de un Rest API con Google AppScript y uso de Volley Framework en Android – Parte 1  

No me imagino mejor manera de iniciar mi colaboración en esta comunidad que con un tema que puede describirse como: “Matando dos pájaros de un tiro”. Mi Nombre es Uriel (@thespianartist) actual Organizer de GDG IPN y en este ejemplo vamos a juntar dos tecnologías de Google: AppScript y Android.  

Nuestra aplicación será una especie de “hub” de recibos de Nomina, serán creados y llenados por medio de Google AppScript y nuestra App Android consumirá dichos datos con la ayuda de Volley Framework.

Google AppScript, las Google Apps vitaminadas.


Google AppScript es la propuesta de la empresa por hacer que las apps sean mas que una suite de oficina, es un conjunto de código que va por detrás de dichas apps escrito en Javascript (aunque la interpretación del mismo corre en los servidores de Google) que permite extender la funcionalidad de aplicaciones como Google Docs o Google Spreadsheets a la vez que permite comunicarse con servicios como Gmail o Google Calendar.


En este ejemplo vamos a realizar un rest API con Google Spreadsheets, si suena raro, pero nuestra “Base de datos”  por así decirlo, no séra mas que una hoja de SpreadSheet, véanlo como una posibilidad para aplicaciones ligeras donde cualquier persona puede modificar “La base de datos” como una hoja de Calculo normal y ver los cambios sin problemas en la aplicación Android.


La siguiente liga contiene la hoja con la que estaremos trabajando, debemos crear una copia a nuestra cuenta de Drive, eso se realiza de la siguiente manera:


Concentremonos en la hoja, podemos observar que se conforma de 3 partes: Header, Data y Footer. El motivo es resaltar los datos vamos a utilizar, como el app solo mostrara a cada persona en la nomina, el header y el footer no nos sirven, así mismo nuestro script estará preparado para solo obtener los datos importantes sin importar el tamaño de cualquiera de las secciones.


El siguiente paso es trabajar con el script, cuando ustedes crearon una copia de la liga anterior, no solo copiaron los datos de la hoja, si no que por detrás, copiamos el script que fue escrito previamente en ella, para crear o modificar un script ingresamos al menu “Tools” y debemos acceder a la opción Script Editor, antes de eso debemos guardar el ID de nuestro SpreadSheet que es facilmente identificable como el valor en la URL después de “Key=” y esa cadena de texto hasta llegar a “&”:


Nota: Si no pueden ver el valor Key en la URL, solo cambien la linea: var sheet = SpreadsheetApp.openById(SPREADSHEET_ID);
por: var sheet = SpreadsheetApp.getActiveSpreadsheet();


var SPREADSHEET_ID="Aqui va tu ID";   //ID de la hoja de Nomina.
var HEADER_SIZE=4;                                                   //Las 4 filas antes de los datos de los empleados
var FOOTER_SIZE=3;                                                   //Las 2 filas que siguen despues de los datos de las personas.

function myFunction() {

  var sheet = SpreadsheetApp.openById(SPREADSHEET_ID);               //Guardamos la SpreadSheet como variable
  var data  = sheet.getDataRange().getValues();                      //Obtenemos todos los datos de la SS
  var total =(data.length)-(HEADER_SIZE+FOOTER_SIZE);                //Aqui obtenemos el total de valores que nos importan(Usuarios)

  var sl =  HEADER_SIZE;                                             //Es el limite superior del SS, posicion donde termina el Header
  var il =  (total+HEADER_SIZE);                                     //Es el limite inferior del SS, posicion donde comienza el Header
  var users = [];                                                    //En cada posicion del arreglo, guardaremos un arreglo con el usurio

  for(i=sl; i<il; i++){
    users.push(data[i]);                                            //Los limites nos permiten solo obtener los valores deseados, vamos
  }                                                                 //e irlos agregando al arreglo users

  Logger.log(users);

  var usersData = [];

  for(i in users){

    var row           = users[i];
    var nombre        = row[0];
    var salarioDiario = row[1];
    var diasLaborados = row[2];
    var sueldo        = row[3];

    var userData= new toObject(nombre,salarioDiario, diasLaborados,sueldo); //creamos un objeto, con cada usuario
    Logger.log(userData);
    usersData[i] = userData;
  }

  return usersData;

 }

function toObject(nombre, salarioDiario, diasLaborados, sueldo){
  this.nombre = nombre;
  this.salarioDiario = salarioDiario;
  this.diasLaborados = diasLaborados;
  this.sueldo = sueldo;
}

function doGet() {
  var datos = myFunction();
  return ContentService.createTextOutput(JSON.stringify(datos)).setMimeType(ContentService.MimeType.JSON); //convertimos la respuesta a JSON
}


Podemos observar que el Script contiene 3 funciones:

  • myFunction
  • toObject
  • doGet

Al inicio tenemos 2 variables con el tamaño del header y del footer, no olviden actualizar esos valores si es que modificaron el numero de rows. myFunction es el encargado de obtener todos los datos del SpreadSheet, toObject es una funcion que creamos para convertir los datos obtenidos como arreglo a objeto, esto sera de gran utilidad ya que la respuesta JSON sera mas agradable de manejar y por ultimo doGet es requerido para cuando publiquemos el script como WebApp, las partes mas importantes estan comentadas. Para ver funcionar nuestro Script, debemos publicarlo como WebApp, esto es muy facil, tan solo con acceder al menu “publish” -> Deploy as WebApp


Cuando publiquemos como web app, se nos otorgara una URL y eso es todo, ya tenemos un REST API hecho solamente con Google AppScript y los datos obtenidos desde una simple Hoja de Calculo, si ustedes ingresan a la URL generada les deberá crear una respuesta como la de la siguiente imagen, aun así te dejo una liga con el ejemplo ya generado


En la segunda parte de este tutorial, trabajaremos la parte de Android, la cual séra consumir ese JSON con ayuda de un Framework HTTP llamado “Volley”

Segunda parte ->

Etiquetas:
Comentarios: Comentarios desactivados

Desarrollo de aplicaciones para Android con características de reconocimiento de voz  

Android no puede reconocer el habla, de manera que un dispositivo Android típico tampoco puede reconocer el habla. O, ¿existe una manera de que lo haga?

La manera más fácil es pedir a otra aplicación que realice el reconocimiento. Pedir a otra aplicación que haga algo en Android se llama uso de intenciones.

Nuestro dispositivo de destino debe tener al menos una aplicación que pueda procesar la Intención para el reconocimiento del habla, la cual es llamada por la acción RecognizerIntent.ACTION_RECOGNIZE_SPEECH.

Una de esas aplicaciones es Google Voice Search. Es uno de los mejores reconocedores disponibles para Android y es compatible con varios idiomas. Este servicio requiere una conexión con Internet debido a que el reconocimiento de voz se lleva a cabo en los servidores de Google. Esta aplicación tiene una Actividad muy simple que informa a los usuarios que pueden hablar. El momento en que el usuario deja de hablar, se cierra el diálogo y nuestra aplicación (intent caller) recibe una gama de cadenas con el reconocimiento del habla.

Google Voice

Una muestra de reconocimiento de voz

Escribamos una pequeña aplicación de muestra que demuestre el uso de búsqueda de voz en aplicaciones.

Nuestra aplicación necesita hacer lo siguiente:

  • Recibir una solicitud de reconocimiento de voz
  • Consultar la disponibilidad de la aplicación para el reconocimiento del habla
  • Si el reconocimiento del habla está disponible, entonces debe llamar a la intención para éste y recibir los resultados
  • Si el reconocimiento del habla no está disponible, entonces debe mostrar el diálogo para instalar Google Voice Search y, si acepta, redirigir al usuario a Google Play

Primero, crearemos una clase que implementa la lógica para el reconocimiento del habla. Asigne a esta clase el nombre de SpeechRecognitionHelper donde declaramos una función run() pública y estática que recibirá una solicitud para iniciar un reconocimiento:

/**
 * A helper class for speech recognition
 */
public class SpeechRecognitionHelper {

/**
     * Running the recognition process. Checks availability of recognition Activity,
     * If Activity is absent, send user to Google Play to install Google Voice Search.
    * If Activity is available, send Intent for running.
     *
     * @param callingActivity = Activity, that initializing recognition process
     */
    public static void run(Activity callingActivity) {
        // check if there is recognition Activity
        if (isSpeechRecognitionActivityPresented(callingActivity) == true) {
            // if yes – running recognition
            startRecognition(callingActivity);
        } else {
            // if no, then showing notification to install Voice Search
            Toast.makeText(callingActivity, "In order to activate speech recognition you must install \"Google Voice Search\"", Toast.LENGTH_LONG).show();
            // start installing process
            installGoogleVoiceSearch(callingActivity);
        }
    }
}

Como puede ver, además de la función run() necesitamos implementar otras tres funciones:

  • isSpeechRecognitionActivityPresented: comprueba si la aplicación de reconocimiento del habla se encuentra en el sistema
  • installGoogleVoiceSearch: inicializa el proceso de instalación de Google Voice Search
  • startRecognition: prepara la Intención adecuada y ejecuta el reconocimiento

Para comprobar si el dispositivo tiene una aplicación para el reconocimiento del habla, podemos usar el método queryIntentActivities en la clasePackageManager. Este método ofrece una lista de actividades que pueden procesar la Intención especificada. Para recibir una instancia de PackageManager, podemos utilizar getPackageManager.

Nuestro código aparece a continuación:

isSpeechRecognitionActivityPresented

/**
     * Checks availability of speech recognizing Activity
     *
     * @param callerActivity – Activity that called the checking
     * @return true – if Activity there available, false – if Activity is absent
     */
    private static boolean isSpeechRecognitionActivityPresented(Activity callerActivity) {
        try {
            // getting an instance of package manager
            PackageManager pm = callerActivity.getPackageManager();
            // a list of activities, which can process speech recognition Intent
            List activities = pm.queryIntentActivities(new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH), 0);

            if (activities.size() != 0) {    // if list not empty
                return true;                // then we can recognize the speech
            }
        } catch (Exception e) {

        }

        return false; // we have no activities to recognize the speech
    }

Ahora implemente la función startRecognition. Esta función formará la Intención apropiada para iniciar la Actividad del reconocimiento del habla. Puede encontrar la información detallada sobre cómo hacerlo en la página de documentación.

Código fuente:

   /**
     * Send an Intent with request on speech
     * @param callerActivity  - Activity, that initiated a request
     */
    private static void startRecognitionActivity(Activity callerActivity) {

        // creating an Intent with “RecognizerIntent.ACTION_RECOGNIZE_SPEECH” action
        Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);

        // giving additional parameters:
        intent.putExtra(RecognizerIntent.EXTRA_PROMPT, "Select an application");    // user hint
        intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_WEB_SEARCH);    // setting recognition model, optimized for short phrases – search queries
        intent.putExtra(RecognizerIntent.EXTRA_MAX_RESULTS, 1);    // quantity of results we want to receive
//choosing only 1st -  the most relevant

        // start Activity ant waiting the result
        ownerActivity.startActivityForResult(intent, SystemData.VOICE_RECOGNITION_REQUEST_CODE);
    }

Y, por último, implementaremos installGoogleVoiceSearch. Esta función mostrará el diálogo que pregunta al usuario si desea instalar Google Voice Search y, si responde afirmativamente, abre Google Play.

/**
     * Asking the permission for installing Google Voice Search.
     * If permission granted – sent user to Google Play
     * @param callerActivity – Activity, that initialized installing
     */
    private static void installGoogleVoiceSearch(final Activity ownerActivity) {

        // creating a dialog asking user if he want
        // to install the Voice Search
        Dialog dialog = new AlertDialog.Builder(ownerActivity)
            .setMessage("For recognition it’s necessary to install \"Google Voice Search\"")    // dialog message
            .setTitle("Install Voice Search from Google Play?")    // dialog header
            .setPositiveButton("Install", new DialogInterface.OnClickListener() {    // confirm button

                // Install Button click handler
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    try {
                        // creating an Intent for opening applications page in Google Play
                        // Voice Search package name: com.google.android.voicesearch
                        Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=com.google.android.voicesearch"));
                        // setting flags to avoid going in application history (Activity call stack)
                        intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY | Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
                        // sending an Intent
                        ownerActivity.startActivity(intent);
                     } catch (Exception ex) {
                         // if something going wrong
                         // doing nothing
                     }
                }})

            .setNegativeButton("Cancel", null)    // cancel button
            .create();

        dialog.show();    // showing dialog
    }

Eso es todo. Ejecutamos la Actividad de reconocimiento del habla. Luego, solicitamos permiso del usuario para instalar Voice Search y, si nos da permiso, abrimos Google Play. Algo que todavía debemos hacer es recopilar los resultados del reconocimiento de voz.

Enviamos una solicitud con la función startActivityForResult para recopilar resultados de la Actividad iniciada. También necesitamos redefinir un método OnActivityResult en nuestro llamador de intenciones Actividad. Puede hacerlo de esta manera:

// Activity Results handler
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {

// if it’s speech recognition results
// and process finished ok
if (requestCode == SystemData.VOICE_RECOGNITION_REQUEST_CODE && resultCode == RESULT_OK) {

// receiving a result in string array
// there can be some strings because sometimes speech recognizing inaccurate
// more relevant results in the beginning of the list
ArrayList matches = data.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS);

// in “matches” array we holding a results... let’s show the most relevant
if (matches.size() > 0) Toast.makeText(this, matches.get(0), Toast.LENGTH_LONG).show();
}

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

Ahora estamos listos

La clase SpeechRecognitionHelper creada nos permite realizar una solicitud de reconocimiento del habla llamando a una sola función run().

Todo lo que se necesita para agregar una función de reconocimiento es agregar esta clase a nuestro proyecto y llamar a la función de ejecución en el lugar necesario. Y, después, implementar los resultados del procesamiento de texto al volver a definir el método onActivityResult para la Actividad que inició la llamada de reconocimiento.

Para obtener información adicional puede visitar el sitio web Desarrolladores para Android. Aquí encontrará buenos ejemplos que muestran la manera de implementar el reconocimiento de voz y, lo que es más importante, la manera de obtener la lista de idiomas disponibles. Necesitará esta lista si desea reconocer un idioma que no sea el de la región geográfica predeterminada del usuario.

Para obtener la rápida integración del reconocimiento de voz en su aplicación, puede descargar y utilizar este código para la clase SpeechRecognitionHelper.

Para conocer más sobre desarrollo de apps Android SDK, te recomendamos visitar la Zona de desarrolladores Intel.

Etiquetas:
Comentarios: Comentarios desactivados

SlimPort, haz de tu SmartPhone una Videoconsola  

Si en el post anterior os hablábamos del GamePad de Samsung, hoy os traemos el complemento ideal a este, hoy os presentamos SlimPort, un accesorio que convertirá tu Smartphone o Tablet en una auténtica video consola. Y es que con este adaptador podrás sacar la señal de vídeo y audio de tu terminal a pantallas …

Continuar leyendo »

The post SlimPort, haz de tu SmartPhone una Videoconsola appeared first on DesAndrOId.


Comentarios: Comentarios desactivados

Usar Android Studio tras un proxy  

¿Alguna vez habéis intentado utilizar Android Studio desde una ubicación donde el acceso a internet se realiza a través de un proxy?

Si habéis tenido que lidiar con esta situación ya sabréis que, a pesar de no ser complicada de resolver, conlleva más pasos de lo que sería deseable. Si por el contrario os acabáis de encontrar con este problema, en este artículo rápido os explico los pasos a seguir.

Empezamos. Nos descargamos Android Studio desde la web oficial, lo instalamos en nuestra máquina, y tras iniciarlo por primera vez vemos que no es la última versión disponible. Para obtenerla, pulsamos el enlace de “Check for updates now” y… primera parada:

1-proxy-as-error

Android Studio no puede conectarse a internet. Parece razonable, debemos configurar el proxy. Para ello vamos a Configure -> Settings, buscamos las opciones de configuración de proxy, marcamos “Manual proxy configuration” (yo no he tenido suerte con la opción de “Auto-detect”) e introducimos los datos de nuestro proxy, incluidos el dominio, usuario y password si éste requiere identificación.

1-proxy-as

Una vez indicados los datos de conexión al proxy podemos hacer una prueba mediante el botón “Check connection”. Si todo va bien, ya podemos aceptar los cambios, y actualizar Android Studio a su última versión.

Una vez actualizado Android Studio, nos surge la necesidad de descargar o actualizar algún componente del SDK de Android. Entramos por tanto en Configure -> SDK Manager, y al intentar cargar la lista de componentes… segunda parada:

2-proxy-sdk-manager-error

El SDK Manager tampoco se puede conectar a internet. Si buscamos en las opciones, el SDK Manager tiene su propia configuración de proxy, a la que podemos acceder desde el menú Tools / Options.

2-proxy-sdk-manager

Una vez más introducimos la URL y puerto de nuestro proxy, pero… ¿dónde indicamos el dominio, usuario y password? No podemos hacerlo aquí, pero si aceptamos los cambios y refrescamos la lista de componentes (o volvemos a entrar en el SDK Manager) aparecerá un diálogo donde, esta vez sí, podremos indicar los datos de identificación del proxy.

2-proxy-sdk-manager-usuario

Perfecto, segundo problema solucionado. Actualizamos nuestro SDK y ya estamos preparados para crear nuestro primer proyecto. Usamos el asistente de nuevo proyecto, configuramos todas las opciones necesarias y tras aceptar el último paso Android Studio comienza a crear todos los elementos necesarios. Tras unos segundos ya tenemos nuestro nuevo proyecto creado. [O no, en este paso también puede aparecer el siguiente error que voy a comentar, dependiendo de lo actualizados que tengamos ciertos componentes de nuestro IDE]

Supongamos que ahora necesitamos añadir una nueva dependencia al proyecto. Abrimos nuestro fichero build.gralde y añadimos la referencia a una librería externa, por ejemplo:

dependencies {
    ...
    compile 'com.etsy.android.grid:library:1.0.4'
}

Pulsamos el botón de “Sync Project with Gradle files” para realizar la sincronización de este cambio y… nuevo error:

3-proxy-gradle-error

Esta vez es Gradle quien no puede descargar la nueva dependencia que acabamos de añadir, una vez más por no tener configurados los datos del proxy. Para esto, iremos al menú File -> Settings, y en la sección sobre Gradle veremos un campo llamado “Gradle VM options”:

3-proxy-gradle

Pues bien, podemos utilizar este campo para indicar opciones adicionales a Gradle con los datos de nuestro proxy. Por legibilidad indico las opciones necesarias una por línea, pero deben escribirse todas en una sola linea separadas por espacios:

-Dhttp.proxyHost=miproxy.miempresa.com
-Dhttp.proxyPort=8080
-Dhttp.proxyUser=midominio/miusuario
-Dhttp.proxyPassword=mipassword
-Dhttps.proxyHost=miproxy.miempresa.es
-Dhttps.proxyPort=8080
-Dhttps.proxyUser=midominio/miusuario
-Dhttps.proxyPassword=mipassword

Si aceptamos los cambios y volvemos a sincronizar el proyecto con gradle ahora debería ir todo bien.

Después de tres obstáculos salvados, ya tenemos todo actualizado y un proyecto creado y compilado.

Para terminar queremos probar nuestro proyecto en el emulador de Android. Ejecutamos el proyecto, seleccionamos el emulador donde queremos lanzarlo, la aplicación se inicia y en el momento en que necesita hacer un acceso a internet… nuevo error. El emulador tampoco tiene acceso a internet. Debemos volver a configurar las opciones del proxy. Esta vez tendremos que acceder a la configuración de ejecución del proyecto, en el menú Run -> Edit configurations, seleccionaremos nuestra aplicación, accederemos a la pestaña “Emulator” y nos aseguraremos de que el campo “Additional command line options” está marcado. Además, al igual que para el caso de Gradle, tendremos que especificar opciones adicionales.

4-proxy-run

En este caso las opciones a indicar seguirán el siguiente formato:

-http-proxy midominio/miusuario:mipassword@miproxy.miempresa.com:8080

Por supuesto, en todo este artículo donde indico “midominio”, “miusuario”, … tendréis que indicar vuestros datos reales de conexión al proxy.

Con esto también configurado, si cerramos nuestro emulador y volvemos a ejecutar la aplicación deberíamos tener ya acceso a internet y todos nuestros problemas de conexión se habrán terminado.

Resumiendo, para poder trabajar con cierta normalidad hemos tenido que configurar las mismas opciones de conexión al proxy en cuatro lugares diferentes (algo que en mi humilde opinión no tiene ningún sentido, es redundante, y sólo lleva a errores y pérdidas de tiempo innecesarias). Entiendo que se trata de 4 “piezas independientes” de nuestro entorno de desarrollo, que tienen opciones de configuración también independientes, pero aún así parece un tema bastante mejorable de cara al futuro. Mientras tanto, aquí tenéis una posible solución. Espero que os sirva.

¿Quieres más información sobre Programación en Android? ¿Conoces el curso online gratuito que ofrecemos en esta web? No esperes más, estás a sólo un click de aprender a crear tus propias aplicaciones: Curso de Programación Android
Etiquetas: , , , ,
Comentarios: Comentarios desactivados

Mirror: La mejor herramienta para probar diseños en vivo  

androcode_mirror

Mi proceso para diseñar interfaces en Android suele ser el siguiente: primero hago bocetos en papel para definir la estructura y la navegabilidad (viene genial POP); luego, si no lo tengo muy claro aún, hago algún boceto de mejor definición en Photoshop o Illustrator, cuidando los colores, tamaños de letra y demás detalles; y por último abro Android Studio y empiezo a crear los XML, estáticos, de cómo quiero que se vea la interfaz para probarlo en el teléfono. En este último paso puedo tirarme horas y horas simplemente ajustando y cambiando valores como tamaños de letra, niveles de opacidad, padding, márgenes, ejecutando la aplicación una y otra vez hasta dar con una combinación con la que esté satisfecho. Si sois como yo, hoy os voy a presentar la herramienta que os cambiará la vida.

Hay muchas formas de previsualizar un diseño de interfaz. Si éste está hecho en una imagen hay muchas herramientas como Android Design Preview de Roman Nurik para mostrar una porción de la pantalla del PC en el móvil. Si la interfaz está hecha en código hay dos posibilidades: la vista previa del IDE, o ejecutar la aplicación y probar la interfaz en vivo. Lo primero dista de ser una experiencia real, y lo segundo es muy lento (compilar, instalar, ejecutar).

Desde hace pocos meses tenemos una nueva posibilidad, que cae entre medio de las anteriores. Se trata de Mirror, una herramienta para previsualizar de forma instantánea los layouts en un dispositivo real. Pero tiene una particularidad: los layouts se muestran de forma nativa. Es decir, la aplicación Mirror lee todos los archivos de recursos de tu proyecto, los procesa y te muestra la interfaz generada por el dispositivo.

mirror

El resultado es muy cercano al de ejecutar la aplicación, pero como digo es instantáneo. La aplicación en el PC monitoriza el proyecto y cada vez que detecte cambios actualizará los recursos en el dispositivo y en un pestañeo aparecerá la interfaz actualizada. Es francamente impresionante lo bien que funciona, os recomiendo que lo probéis por vosotros mismos. De todos modos, os quedará mucho más claro viendo el vídeo de demostración que ellos mismos han preparado:

Como veis, Mirror está compuesto por una aplicación de escritorio (Windows, Mac y Linux) y una app móvil que se conectan a través de ADB. No importa con qué IDE desarrolles, Mirror monitoriza el sistema de archivos directamente. La aplicación es gratuita con las funciones básicas, y tiene una versión premium (pago in-app) que permite previsualizar vistas propias, Action Bar personalizado y usar datos de prueba.

Personalmente la empecé a usar recientemente, y me tiene enamorado. Me va a ahorrar muchas horas de ejecutar-cambiar-ejecutar-cambiar. Y a vosotros, ¿qué os parece?

Más información y descarga: http://jimulabs.com/

Etiquetas:
Comentarios: Comentarios desactivados

Android Navigation Drawer – Parte 2  

 

Hola el día de  hoy les traigo la segunda parte del tutorial de navigation drawer, antes de seguir si todavia no vieron la 1er parte hagan click aqui.  En esta parte lo que aprenderemos es como incorporar el botón para abrir y cerrar el menú de navegación y como asignarle una acción a la pulsación sobre un item del menu.

Abrir y Cerrar Menu desde un Icono

Les mostrare como implementar el clasico boton para abrir y cerrar el menu,

el boton se mostrara en el angulo superior izquierdo junto al titulo.

 

Para poder realizar esto utilizaremos una clase llamada ActionBarDrawerToggle, su  uso es muy simple como veremos a continuación,

Como ven dentro del onCreate declaramos el  mDrawerToggle al cual hay que especificar

El contexto, el drawerLayout,el icono que se mostrara en el boton (disponible en el pack de iconos que comente en la 1er paerte.), y 2 string de descripcion (yo no los he usado).

Tambien podemos especificar una acción al abrir y cerrar el menú en onDrawerClosed() y  onDrawerOpened(), dar un vistazo al Logcat durante el funcionamiento de la aplicación.

Mediante NavDrawerLayout.setDrawerListener(mDrawerToggle);  asignamos cual sera el DrawerListener que utilizara en este caso

sera nuestro mDrawerToggle .

Luego en getActionBar().setDisplayHomeAsUpEnabled(true); Establecemos que el ActionBar muestre el Boton Home.

Si corremos la app en esta parte podemos ver como al presionar el icono el menu se cierra y abre también podrán observar que este se desplaza segun este el menú abierto o no.

 

Asignar accion a la pulsacion de un Item del menu de navegación:

Esto es igual que en cualquier listiew que ya hallan visto antes, basicamente hay que asignar cual sera el ItemClickListener que usaremos para especificar cada opción, en este caso lo que haremos es segun la opción del menu que pulse mostrara un fragment especifico, si no saben lo que es un fragment hagan un parate aqui y vean estos links:

http://developer.android.com/training/basics/fragments/creating.html

https://developer.android.com/training/basics/fragments/index.html

Por lo que para cada pantalla habra que definir un fragment y un layout para esa opcion.

Al codigo de la primer parte del tutorial le he agregado en el menu una opcion “home” que antes no estaba.

 

He creado las pantallas solo para  ”Home” y para “Perfil”

Opcion Home:

Este fragment tiene asociado home.xml (no mostrare el codigo del layout ya que es basico puden verlo haciendo click en el nombre del layout.)

la pantalla tendra la siguiente apariencia.

 

Opcion Perfil:

Utilizara el framgent ProfileFragment.java y el layout profile.xml

Como ven es igual al anterior solo que con diferente layout, aquí sera donde tendrán que incluir todo el código para darle funcionamiento a los widgets que coloquen dentro.

La pantalla tendrá la sig. apariencia.

 

Una vez que ya tenemos listo los fragments el código que utilizaremos sera el siguiente:

 

Dentro de OnCreate() al Navlist le asignamos el OnItemClickListener y dentro coloque que llame al metodo

MostrarFragment(position) al cual le paso como parametro la posicion de la opcion seleccionada en el menu, en base a esto mostrara el fragment especifico.

Luego fuera de esto  indico que cuando la aplicacion cargue muestre la opcion “home”  por defecto, para eso le paso el numero 1 el cual equivale a la primer opcion del menú.

MostrarFragment(1)

Ver los comentarios en cada linea par entender como funciona.

Con esto básicamente ya podemos dotar a nuestra aplicación de la lógica necesaria para poder mostrar cada opción del menú, luego depende de cada uno lo que  quiera poner dentro. Recuerden que esto solamente funciona con versiones de android >= 4.0 para poder utilizarla en 2.3 hay que incluir la Support Library

pueden dar un vistazo a los sig. links

https://developer.android.com/tools/support-library/setup.html

http://stackoverflow.com/questions/16605005/adding-supported-libraries-in-android-application

En el sig. video pueden ver como es el funcionamiento de la aplicación.

Pueden descargarse el código desde nuestro repositorio haciendo click en la imagen debajo.

 

Cualquier consulta o sugerencia siéntanse libres de hacerlas utilizando el cuadro de comentarios.

Esto fue todo por hoy, espero que les halla gustado, hasta la próxima.!

Saludos

Sebastian

 

Fuentes:

http://developer.android.com/training/implementing-navigation/nav-drawer.html

¿Te gustó este artículo? ¡Compártelo!

 

Etiquetas:
Comentarios: Comentarios desactivados

Otra forma de acelerar el emulador de Android  

Por muchos es sabido que el emulador de android que viene con el SDK deja mucho que desear. Afortunadamente existen alternativas como usar android-x86 y virtualbox para virtualizar un dispositivo android como vimos anteriormente. Pero hoy voy a contaros otra forma, disponible desde hace un tiempo, que también está basado en virtualización pero está mejor integrado con el entorno de desarrollo como puede ser Eclipse. En este caso vamos a usar la virtualización existente en los procesadores Intel, y una imagen de disco de android para x86, también provista por intel a través del SDK Manager de Android, de forma que convierte este proceso en algo fácil y rápido.

Requisitos:

  • Procesador con Intel que soporte Intel VT-x, EM64T y Execute Disable(XD) Bit habilitado en la BIOS.
  • Tener instalado el SDK de Android.

Instalación en Windows

Una vez instalado el SDK de Android, abrimos el SDK Manager que usamos para descargarnos las diferentes versiones de Android y marcamos para descargar el Intel HAXM dentro de la pestaña de “extras”. Aunque lo instalemos desde el SDK Manager en realidad sólo nos copia un instalador a la carpeta “extras” donde está instalado el SDK de Android, así que vamos a ésa carpeta de nuestro disco duro e instalamos IntelHaxm.exe. Otra cosa que debemos marcar para instalar es la Intel x86 Atom System Image de la versión de Android que deseemos, de esta manera podremos crear AVDs con esta imagen del sistema.intel_haxm_1Intel HAXM.exeEjecutamos el instalador y seguimos los pasos. En caso de que nuestra BIOS no tenga configurada la opción de VT-x deberemos arrancar la BIOS, para activarla más o menos así, y luego volver a instalar el Intel HAXM:

Crear el AVD

Una vez instalado el SDK y el Intel HAXM, procederemos a crear un dispositivo android virtual, para ello abrimos el AVD Manager y creamos un AVD nuevo.

Deberemos elegir un target del que nos hayamos bajado su imagen Intel x86 como hemos hecho en el paso anterior con el SDK Manager, así podremos elegir, en CPU/ABI, la opción Intel Atom (x86).

Ponemos un nombre y elegimos un dispositivo cualquiera.

Importante seleccionar “Use Host GPU” para que utilice OpenGL para el renderizado, de esta manera la parte gráfica irá más rápida. Una vez hecho todo esto, hacemos click en OK, para generar el AVD y luego una vez creado, pulsamos en Start y arrancamos el emulador. Debería tardar sólo 15 segundos y debemos ver un mensaje de que está arrancando en “fast virtual mode”

intel_haxm_3

Una vez hecho esto, podemos instalar y probar nuestra aplicación en el emulador e incluso controlar algunos aspectos como la ubicación GPS, simular recibir llamadas o mensajes, etc. desde la pestaña “Emulator control” de la perspectiva “DDMS” (En Eclipse: Window > Open perspective > DDMS).

Para más información, resolución de problemas y cómo instalarlo en Linux, podéis leer este artículo de la página de Intel que lo explica con más detalle.


Comentarios: Comentarios desactivados

Energy Soundbar SB5 Bluetooth  

Hoy os presentamos un artículo que se sale de lo habitual en este blog y es que hoy os traemos una barra de sonido que hará las delicias de los amantes del cine en casa. Se trata de la Energy Soundbar SB5 Bluetooth, un sistema de sonido completo para vuestro salón. 120W de sonido estéreo …

Continuar leyendo »

The post Energy Soundbar SB5 Bluetooth appeared first on DesAndrOId.


Comentarios: Comentarios desactivados

Disclaimer: Las imágenes mostradas en ésta página web se utilizan sólamente con propósitos ilustrativos, y son propiedad de sus respectivos autores (cuando es aplicable).
Hijo de Blog es un producto del Dr. SeROne

Los contenidos se ofrecen bajo una licencia de Creative Commons
Attribution-NonCommercial-NoDerivs 3.0 Unported

salvo que se indique lo contrario

Licencia de Creative Commons

Switch to our mobile site