Mostrando entradas con la etiqueta desarrollo. Mostrar todas las entradas
Mostrando entradas con la etiqueta desarrollo. Mostrar todas las entradas

miércoles, 3 de septiembre de 2014

Crear Service en Android

Buenas tardes, en esta entrada y en las siguientes, vamos a enfocarnos sobre un aspecto importante de Android, los Services o Servicios.



Un Service es una aplicación en Android que se ejecuta en background sin tener que interactuar con el usuario. Por ejemplo, cuando usamos una aplicación, puede que queramos ejecutar algo de música en background a la vez. En este caso, el código que está ejecutando la música en background no necesita interactuar con el usuario, y por ello puede ejecutarse como un Service. Los Services son ideales tambien para situaciones en las cuales no tenemos que tener presente una UI para el usuario. Un buen ejemplo de este scenario es una aplicación que continuamente crea un log de coordenadas geográficas del dispositivo. En este caso podemos escribir un Service que haga algo en background.
Para comenzar, vamos a crear un Service, aunque lo único que haremos es crearlo y parar su ejecución, no hará ninguna función mas, pero aprenderemos a crearlo. En entradas posteriores veremos como podemos hacer que haga algo y ver mejor como funcionan.
Con esta pequeña introducción, vamos a ponernos manos a la obra:
  • Creación del Proyecto

    Para crear nuestro proyecto, vamos a pinchar en File -> New -> Android Application Project. En el caso de que la última opción no aparezca, podemos pinchar en “Other” con el cual nos aparecerá una ventana para elegir entre una lista. Para filtrar los resultados, podemos escribir “Android” en el cuadro de texto que encontraremos y así nos será mas fácil.
    Una vez se nos muestra la primera ventana del asistente, elegiremos un nombre para nuestro proyecto, yo en mi caso lo he llamado “EjemploService”, aunque no es importante y podeis poner el que querais. El resto de opciones podeis dejarlas como querais.
    A medida que avanzamos en el asistente vamos a encontrar una ventana donde se nos permitirá dar un nombre a nuestra Activity principal, yo en mi caso lo he llamado ServiceActivity, y su archivo layout se llama activity_service.xml. Este archivo layout se encuentra en la carpeta res/layoout, y en él definiremos la interfaz gráfica de nuestra Activity.
    Con esto, tendremos nuestro proyecto ya creado, y podemos continuar con la construcción de la aplicación.
  • ServiceActivity

    Una vez tenemos creado nuestro proyecto, tendremos nuestra clase Activity y su layout, ubicado como bien hemos especificado en la carpeta res/layout. Modificaremos su código para que quede como este:

    <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=".ServiceACtivity" >
     
        <Button
            android:id="@+id/btnStart"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:onClick="onClickComenzar"
            android:text="Comenzar Servicio" />
     
        <Button
            android:id="@+id/btnStop"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:onClick="onClickParar"
            android:text="Parar Servicio" />
     
    </LinearLayout>
    Podemos observar que tenemos 2 View del tipo Button, los cuales serán los encargados de comenzar el Service y de pararlo cuando deseemos. Hemos establecido valores en el atributo onClick, para luego crear métodos en la activity con el valor de estos atributos.
    Por otro lado, tenemos la clase ServiceActivity.java, cuya funcionalidad principal será comenzar el Service y pararlo cuando pulsemos el botón de detenerlo. Su código es el siguiente:

    package com.example.services;
     
    import android.app.Activity;
    import android.content.Intent;
    import android.os.Bundle;
    import android.view.View;
     
    public class ServiceActivity extends Activity {
     
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_service);
        }
         
        public void onClickComenzar(View v){
            startService(new Intent(getBaseContext(), MyService.class));
        }
         
        public void onClickParar(View v){
            stopService(new Intent(getBaseContext(), MyService.class));
        }
     
    }
    El código de nuestra Activity es bastante simple, lo único que hacemos es crear los 2 métodos para que los botones tengan funcionalidad
    • public void onClickComenzar(View v) En este método llamamos a otro método, llamado startService, y como argumento le pasamos un Intent el cual recibe el context de nuestra aplicación, y la clase MyService.class, que será la que contenga el servicio (Aún no la hemos creado).

      public void onClickComenzar(View v){
          startService(new Intent(getBaseContext(), MyService.class));
      }
    • public void onClickParar(View v) En este otro método invocaremos el método stopService el cual acepta como argumento un Intent el cual hemos creado nuevo con el context de nuestra Activity y el nombre de la clase de nuestro Service (MyService.class), que como he dicho anteriormente aún no hemos creado, pero será el siguiente paso.

      public void onClickParar(View v){
          stopService(new Intent(getBaseContext(), MyService.class));
      }
  • MyService

    Ahora vamos a crear nuestra clase para el Service, la cuál heredará de la clase Service. Para ello nos dirigimos a nuestro package (com.example.services en mi caso) y crearemos una nueva clase en su interior.
    Una vez nuestra clase esté creada, vamos a modificarla para que quede como la siguiente:

    package com.example.services;
     
    import android.app.Service;
    import android.content.Intent;
    import android.os.IBinder;
    import android.widget.Toast;
     
    public class MyService extends Service {
     
        @Override
        public IBinder onBind(Intent arg0) {
            // TODO Auto-generated method stub
            return null;
        }
     
        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
            // TODO Auto-generated method stub
            Toast.makeText(this, "Servicio en Ejecucion", Toast.LENGTH_SHORT).show();
            return START_STICKY;
        }
     
        @Override
        public void onDestroy() {
            // TODO Auto-generated method stub
            super.onDestroy();
            Toast.makeText(this, "Servicio destruido", Toast.LENGTH_SHORT).show();
        }
    }
    Vamos a explicar un poco los métodos que vemos:
    • onBind(Intent arg0) Vamos a ver su código:

      @Override
      public IBinder onBind(Intent arg0) {
          // TODO Auto-generated method stub
          return null;
      }
      Este método permite ligar una actividad a un servicio. Esto permite a la activity tener acceso a los miembros y métodos en el interior del Service. Por ahora, retornamos null para este método ya que en esta entrada solo veremos como crearlo.
    • onStartCommand(Intent intent, int flags, int startID) Vamos a ver su código:

      @Override
      public int onStartCommand(Intent intent, int flags, int startId) {
          // TODO Auto-generated method stub
          Toast.makeText(this, "Servicio en Ejecucion", Toast.LENGTH_SHORT).show();
          return START_STICKY;
      }
      Este método es llamado cuando hacemos que el servicio se ejecute explícitamente mediante un método startService(). Este método ejecutará todo el código que necesitemos que haga nuestro Service. Finalmente, retornamos la constante START_STICKY para que nuestro service siga ejecutandose hasta que lo detengamos explícitamente.
    • onDestroy() Vamos a ver su código:

      @Override
      public void onDestroy() {
          // TODO Auto-generated method stub
          super.onDestroy();
          Toast.makeText(this, "Servicio destruido", Toast.LENGTH_SHORT).show();
      }

      Este método es llamado cuando el servicio es detenido usando el método stopService(), aquí es donde limpiamos los recursos que hayan sido usados por nuestro service.
  • AndroidManifest.xml

    Finalmente, para que nuestro Service puede usarse, tenemos que declararlo en el AndroidManifest de nuestra aplicación. A continuación vemos como se hace:

    xml version="1.0" encoding="utf-8"?>
        package="com.example.services"
        android:versionCode="1"
        android:versionName="1.0" >
     
        <uses-sdk
            android:minSdkVersion="8"
            android:targetSdkVersion="17" />
     
        <application
            android:allowBackup="true"
            android:icon="@drawable/ic_launcher"
            android:label="@string/app_name"
            android:theme="@style/AppTheme" >
            <activity
                android:name="com.example.services.ServiceActivity"
                android:label="@string/app_name" >
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />
     
                    <category android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
            </activity>
            <service android:name=".MyService" />
        </application>
     
    </manifest>

    Vemos que hemos agregado la línea:


    <service android:name=".MyService" />
    Si quisieramos que nuestro service estuviera disponible para otras aplicaciones, podríamos añadir un action:

    <service android:name=".MyService">
        <intent-filter>
            <action android:name="sekth.droid.Services.MyService" /> 
        </intent-filter>
    </service>

Con esto ya tendríamos nuestra aplicación funcional, podemos ejecutarla en el emulador y ver como funciona, aunque realmente no haga nada interesante.
Podemos ver unas capturas aunque tengan poco contenido:
Principal Service ejecucion Service Ajustes Service detenido

A continuación un video sobre la aplicación en tiempo real:




Con esta entrada, hemos visto la manera en la que podemos crear un Service en Android, aunque en este caso no haga naad mas que ocupar ram haciendo nada, pero en futuras entrada podemos ver un poco mas el enfoque que podemos darle para que haga diferentes tareas.
El código del ejemplo podeis descargarlo de aquí.

Sin más, cualquier aporte o corrección es bienvenido.

Saludos!!!

Fuente: http://sekthdroid.wordpress.com/2013/02/10/crear-service-en-android/

CONCATENAR USANDO FOR XML PATH Y STUFF

 En el foro de SQL SERVER se cuestiona mucho como concatenar varias filas en una sola, sobre todo esto se utiliza para evitar el uso de los cursores y es mucho más rápido, para comenzar es necesario la tabla AdventureWorks2012.
?
1
2
SELECT TOP 10 FirstName
FROM AdventureWorks2012.Person.Person

Hasta aquí no hay nada, digámoslo de cierta forma, nuevo, pero para poder hacer la concatenación requerimos de la función STUFF y la clausula FOR XML utilizando el modo PATH.
La función STUFF sirve para ingresar una cadena en otra a partir de los parámetros de posición y longitud. Siendo de esta manera, el siguiente ejemplo:
?
1
2
SELECT TOP 10 FirstName, STUFF( FirstName, 3,2,'CADENA') as resultado
FROM AdventureWorks2012.Person.Person
Lo que nos arroja como resultado:
Y para que funciona FOR XML PATH, para devolver una consulta en formato XML, este es el resultado de una consulta a la base de datos AdventureWorks2012:
?
1
2
3
SELECT TOP 3 FirstName, MiddleName, LastName LastName
FROM AdventureWorks2012.Person.Person
FOR XML PATH
Y si damos click al resultado, nos muestra esto:
Si agregamos el parámetro, reemplazara el atributo de fila:
?
1
2
3
SELECT TOP 3 FirstName, MiddleName, LastName LastName
FROM AdventureWorks2012.Person.Person
FOR XML PATH('FILA')
Y que pasa si establecemos un valor vacío?:
Combinando STUFF y FOR XML PATH, podemos lograr concatenar las filas.
?
1
2
3
4
5
SELECT STUFF((
       SELECT TOP 10 ','+FirstName
       FROM AdventureWorks2012.Person.Person
       FOR XML PATH('')
),1,1, '')
Y de esta manera es posible agrupar a un nivel superior:
?
1
2
3
4
5
6
7
8
9
SELECT
       PC.Name
       ,STUFF((
             SELECT ','+name
             FROM Production.ProductSubcategory PSC
             WHERE PSC.ProductCategoryID = PC.ProductCategoryID
             FOR XML PATH('')
       ),1,1,'')
FROM Production.ProductCategory PC
Algo más complejo, observemos las tablas Sales.SpecialOffer, Sales.SpecialOfferProduct,Production.Product, la primera contiene las ofertas especiales( como su nombre lo indica), la segunda tabla contiene el detallado de los productos que por cada oferta especial y la tercera el detallado de los productos. Lo que queremos obtener es todos los productos de cada oferta especial:

Sales.SpecialOffer:
Sales.SpecialOfferProduct:
Production.Product
La consulta quedaría así:
?
1
2
3
4
5
6
7
8
9
10
SELECT SO.SpecialOfferID, SO.Description
, STUFF((
       SELECT ','+p.Name
       FROM sales.SpecialOfferProduct SOP
       INNER JOIN Production.Product P
       ON SOP.ProductID = p.ProductID
       AND SOP.SpecialOfferID = SO.SpecialOfferID
       FOR XML PATH('')
),1,1,'' ) as productos
FROM Sales.SpecialOffer SO
Una forma muy practica y mucho mejor para concatenar valores en comparación que si utilizaramos un cursor.

Espero que les sirva.

Fuente: http://chancrovsky.blogspot.com/2013/04/concatenar-usando-for-xml-path-y-stuff.html

viernes, 1 de agosto de 2014

JSSQL: Un motor de base de datos en javascript

ES un proyecto interesante llamado JSSQL. JSSQL es un motor de base de datos escrito en Javascript, el cual podemos ejecutar consutlas SQL desde nuestras páginas web. Sin necesidad de estar conectado a algún servidor.

JSSQL es un proyecto de Joaquín Becerra de la Universidad de Buenos Aires. Podéis encontrar más información en:

http://javascriptsql.sourceforge.net/ARCH/index.html

Pero vamos a ponernos manos a la obra...

Lo primero de todo es cargar la librería Javascript que implementa el motor de base de datos. Esta librería es JSSQL.js.




Una vez cargada la librería instanciaremos el objeto principal llamado JSSQL.


var myJSSQL= new JSSQL();


A partir del objeto JSSQL abriremos la base de datos a utilizar mediante el método open.


if (!myJSSQL.Open('mibasededatos')) {
  alert(myJSSQL.GetError()); //si falla que nos avise
}


Si falla la apertura de la base de datos, devolvemos el error del motor de la base de datos. Este error está accesible vía el método .GetError().

En el código vemos que abrimos una base de datos que se llama "mibasededatos". Pero ¿Dónde está la base de datos?

Las bases de datos están definidas en ficheros .jsdb bajo una estructura de directorios:

/bases/nombreBD/nombreBD.jsbd
El fichero JSDB tiene la siguiente estructura:


_bd={
  "paises":{
    "IdPais":"numeric",
    "Pais":"string",
  }
};
_bd_ind={
   'paises':[false,false]
};
_bd_pag={
   'paises':0
};


Vemos que contiene la definición mediante arrays de las bases de datos que contiene. A su vez, cada una de las tablas, tiene su fichero JSBD con el contenido. Por ejemplo la tabla de países tendría el siguiente contenido:


_aux['paises']=Array();
_aux['paises']=[
[1,"Noruega"],
[2,"Portugal"],
[3,"Francia"],
[4,"Italia"],
[5,"UK"]
];


JSSQL nos ofrece una herramienta de conversión desde las bases de datos hacía JSDB. Puedes acceder a ella desde:

http://javascriptsql.sourceforge.net/ARCH/JSBD/ConversorBD.php

Una vez que hemos visto como se definen las bases de datos pasamos a ejecutar la consulta mediante el método .Query(). La consulta una SELECT sencilla de paises.


sql="select Pais from paises" ; 
res=myJSSQL.Query(sql);


El resultado nos lo deja en un array, el cual recorremos de forma sencilla:


for (x=0;x");


La verdad es que JSSQL realiza un enfoque muy interesante sobre la necesidad de tener una BD en local. Algo que ya no parece estar muy lejos gracias a HTML5.

Fuente: http://godmurdoc.diosdelared.com/?coment=12577

miércoles, 25 de junio de 2014

Componentes de una aplicación Android

En Java o .NET estamos acostumbrados a manejar conceptos como ventana, control, eventos o servicios como los elementos básicos en la construcción de una aplicación.

Pues bien, en Android vamos a disponer de esos mismos elementos básicos aunque con un pequeño cambio en la terminología y el enfoque. Repasemos los componentes principales que pueden formar parte de una aplicación Android [Por claridad, y para evitar confusiones al consultar documentación en inglés, intentaré traducir lo menos posible los nombres originales de los componentes].

Activity

Las actividades (activities) representan el componente principal de la interfaz gráfica de una aplicación Android. Se puede pensar en una actividad como el elemento análogo a una ventana o pantalla en cualquier otro lenguaje visual.

View
Las vistas (view) son los componentes básicos con los que se construye la interfaz gráfica de la aplicación, análogo por ejemplo a los controles de Java o .NET. De inicio, Android pone a nuestra disposición una gran cantidad de controles básicos, como cuadros de texto, botones, listas desplegables o imágenes, aunque también existe la posibilidad de extender la funcionalidad de estos controles básicos o crear nuestros propios controles personalizados.

Service
Los servicios (service) son componentes sin interfaz gráfica que se ejecutan en segundo plano. En concepto, son similares a los servicios presentes en cualquier otro sistema operativo. Los servicios pueden realizar cualquier tipo de acciones, por ejemplo actualizar datos, lanzar notificaciones, o incluso mostrar elementos visuales (p.ej. actividades) si se necesita en algún momento la interacción con del usuario.

Content Provider
Un proveedor de contenidos (content provider) es el mecanismo que se ha definido en Android para compartir datos entre aplicaciones. Mediante estos componentes es posible compartir determinados datos de nuestra aplicación sin mostrar detalles sobre su almacenamiento interno, su estructura, o su implementación. De la misma forma, nuestra aplicación podrá acceder a los datos de otra a través de los content provider que se hayan definido.

Broadcast Receiver
Un broadcast receiver es un componente destinado a detectar y reaccionar ante determinados mensajes o eventos globales generados por el sistema  (por ejemplo: “Batería baja”, “SMS recibido”, “Tarjeta SD insertada”, …) o por otras aplicaciones (cualquier aplicación puede generar mensajes (intents, en terminología Android) broadcast, es decir, no dirigidos a una aplicación concreta sino a cualquiera que quiera escucharlo).

Widget
Los widgets son elementos visuales, normalmente interactivos, que pueden mostrarse en la pantalla principal (home screen) del dispositivo Android y recibir actualizaciones periódicas. Permiten mostrar información de la aplicación al usuario directamente sobre la pantalla principal.

Intent

Un intent es el elemento básico de comunicación entre los distintos componentes Android que hemos descrito anteriormente. Se pueden entender como los mensajes o peticiones que son enviados entre los distintos componentes de una aplicación o entre distintas aplicaciones. Mediante un intent se puede mostrar una actividad desde cualquier otra, iniciar un servicio, enviar un mensaje broadcast, iniciar otra aplicación, etc.

Fuente: http://www.sgoliver.net/blog/?p=1295

Configurar Eclipse para Android en un solo paso

Eclipse es la herramienta por excelencia para desarrollar aplicaciones Android, el problema es que la instalación de Android es lenta y complicada. Pero eso era antes de que Google lanzara su propia version de Eclipse que ya viene con el SDK y todas las herramientas de desarrollo instaladas.
Screen Shot 2013-01-19 at 10.23.31 PM

Puedes descargalo en esta dirección:
http://developer.android.com/sdk/index.html
Aprende a instalar y utilizar la nueva versión de Eclipse para Android en este video tutorial

El paquete de desarrollo incluye:
  • Eclipse Juno, la mas reciente version de este IDE.
  • El SDK de Android todas las herramientas de desarrollo y emuladores.
  • La version de ADT (Android Developer tools) preinstalada en Eclipse
  • Los paquetes y la maquina virtual de Android 4.2 (Jelly Bean).

Solo tienes que instalar el paquete y en un solo paso podrás comenzar a trabajar en tus aplicaciones!

Fuente: http://revolucion.mobi/2013/01/22/configurar-eclipse-para-android-en-solo-paso/

Lanzar un segundo "Activity"

Problema:

Confeccionar un programa que muestre en la ventana principal un botón que al ser presionado muestre otra ventana (Activity) mostrando un TextView con el nombre del programador de la aplicación y un botón para cerrar la ventana o actividad.

1 - Primero creamos un nuevo proyecto que lo llamaremos proyecto008 y en la ventana principal creamos la siguiente interfaz:

lanzar segundo Activity


Es decir que nosotros queremos que cuando se presione el botón "Acerca De" nos abra otra ventana (Activity) y nos muestre el nombre del programador.

2 - Ahora tenemos que crear el segundo Activity. Crearemos primero el archivo XML. Presionamos el botón derecho sobre la carpeta layout y seleccionaremos la opción New -> Android XML File

lanzar segundo Activity


Aquí tenemos que definir el nombre del archivo XML (debe estar en minúsculas), lo llamaremos acercade:

lanzar segundo Activity

Implementamos ahora la interfaz visual de esta segunda ventana (Activity) disponiendo un objeto de la clase TextView donde mostramos el nombre del autor de este programa y un Button para cerrar la ventana.

lanzar segundo Activity


3 - Tenemos ahora que crear el archivo Java donde dispondremos la funcionalidad de la segunda ventana (Activity)

Creamos una nueva clase al proyecto desde el menú contextual(presionamos el botón derecho del mouse sobre el paquete com.androidya.proyecto008):

lanzar segundo Activity


Al nombre de la clase la llamamos AcercaDe y debemos especificar que hereda de la clase Activity (podemos presionar el botón Browse que está en la misma fila de SuperClass y buscamos la clase Activity para que disponga el nombre del paquete donde se encuentra):

lanzar segundo Activity

El código que nos genera es:

package com.javaya.proyecto008;

import android.app.Activity;

public class AcercaDe extends Activity {

}

Debemos sobreescribir el método onCreate donde enlazamos esta clase con el archivo XML que diseñamos.
Si no recordamos cual es la sintaxis exacta de este método podemos también generarlo automáticamente con la ayuda de nuestro editor, elegimos Source -> Override/Implement methods:
lanzar segundo Activity

Buscamos el método onCreate y presionamos el botón Ok, ahora ya tenemos la clase con el método onCreate:

package com.javaya.proyecto008;

import android.app.Activity;
import android.os.Bundle;

public class AcercaDe extends Activity {

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  // TODO Auto-generated method stub
  super.onCreate(savedInstanceState);
 }

}

Ahora solo falta llamar al método setContentView para enlazar el archivo XML:

package com.javaya.proyecto008;

import android.app.Activity;
import android.os.Bundle;

public class AcercaDe extends Activity {

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  // TODO Auto-generated method stub
  super.onCreate(savedInstanceState);
  setContentView(R.layout.acercade);
 }

}

Como podemos ver la clase AcercaDe hereda de la clase Activity e implementa el método onCreate 
para enlazar el archivo XML que creamos anteriormente.

4 - Otro paso fundamental es registrar el Activity en el archivo "AndroidManifest.xml" que se encuentra en la raiz principal del proyecto.
Seleccionamos el archivo y activamos la pestaña : "Application", presionamos el botón "add" y seleccionamos "Activity":
lanzar segundo Activity

Por último seleccionamos en "Application Nodes" la actividad creada y definimos la propiedad Name con el nombre de la clase que la implementa (en nuestro caso se llama AcercaDe):
lanzar segundo Activity


5 - Ahora implementaremos la funcionalidad en la actividad (Activity) principal para que se active la segunda ventana.
Inicializamos la propiedad OnClick del objeto de la clase Button con el valor "lanzar", este es el método que se ejecutará cuando se presione.
El código fuente de la actividad principal queda:

package com.javaya.proyecto008;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.View;

public class MainActivity extends Activity {

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

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.activity_main, menu);
        return true;
    }
    
    public void lanzar(View view) {
        Intent i = new Intent(this, AcercaDe.class );
        startActivity(i);
  }    
    
}

En el método lanzar creamos un objeto de la clase Intent y le pasamos
 como parámetros la referencia del objeto de esta clase (this) y la 
referencia del otro Activity (AcercaDe.class)
Llamamos posteriormente al método startActivity pasando el objeto de la clase Intent (con esto ya tenemos en pantalla la ventana del segundo Activity:

    public void lanzar(View view) {
          Intent i = new Intent(this, AcercaDe.class );
          startActivity(i);
    }

Si ejecutamos el programa podemos ver que cuando presionamos el botón
 "Acerca De" aparece la segunda ventana donde se muestra el TextView con
 el valor "Autor de este programa: Diego" y un botón con el texto 
"Finalizar" (si presionamos este botón no sucede nada, esto debido a que
 no hemos asociado ningún evento a dicho botón)

6 - Debemos codificar el evento OnClick de la segunda actividad. Seleccionemos el botón "Finalizar" y definamos en la propiedad OnClick el nombre de método que se ejecutará al presionarse el botón (en nuestro caso lo llamaremos cerrar") :

El código fuente de la actividad AcercaDe queda:

package com.javaya.proyecto008;


import android.app.Activity;
import android.os.Bundle;
import android.view.View;

public class AcercaDe extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.acercade);
    }
    
    public void cerrar(View view) {
     finish();
    }    
}

Cuando se presiona el botón finalizar llamando al método finish() que
 tiene por objetivo liberar el espacio de memoria de esta actividad y 
pedir que se active la actividad anterior.
Ahora nuestro programa está funcionando completamente:
Primer Activity:
lanzar segundo Activity

Segundo Activity:
lanzar segundo Activity

Ahora ya tenemos el programa funcionando en forma completa.
Este proyecto lo puede descargar en un zip desde este enlace: proyecto008.zip

Problema propuesto


  1. Realizar un programa que contenga dos Activity. En el primero que solicite el ingreso de una clave (control Password) Si ingresa la clave "abc123" activar el segundo Activity mostrando en un TextView un mensaje de bienvenida (mostrar en un TextView si se ingrese la clave incorrecta).
    Llamar al proyecto: proyecto009.
    En tiempo de ejecución los dos Activity deben mostrarse algo similar a esto:
    lanzar segundo Activity
    lanzar segundo Activity
    Este proyecto lo puede descargar en un zip desde este enlace: proyecto009.zip
Fuente: http://www.javaya.com.ar/androidya/detalleconcepto.php?codigo=140&inicio=

Integrando Google Drive en android

Cualquier dueño de un dispositivo Android con acceso a Google Play tiene forzosamente una cuenta de google activa. Toda cuenta de google activa tiene acceso a los servicios de Google Drive: almacenamiento, documentos, etc. Es por ello que me pareció particularmente interesante acceder desde una app a dichos recursos. Debido a la variedad de servicios que ofrece, haré de esto una serie de artículos. Investigué esta página (gracias @spcoder, porque yo había encontrado tropocientas diferentes pero no ésta) y di con un howto para crear una app sencillita con la que tomar fotos y guardarlas en el espacio de almacenamiento de Google Drive. Tras sufrir y corregir los errores que me encontré, pensé que sería una buena idea compilarlo todo en un post. Sin embargo, y para no arrollar con demasiadas cosas a la vez, dedicaremos este artículo principalmente a la preparación necesaria para que tu app pueda acceder a los servicios de Google Drive.

1. Preparar el entorno

Estos preparativos afectan al IDE (Eclipse, en nuestro caso) y a nuestro espacio de trabajo o Workspace.

Preparativos en Eclipse.

Necesitaremos que Eclipse disponga de lo siguiente:
  • El google plugin for eclipse.
  • La librería google_play_services
El plugin ‘google plugin for eclipse’ se puede instalar siguiendo las instrucciones de esta página. Este plugin sirve, principalmente, para facilitar la tarea de añadir las librerías cliente necesarias a nuestro proyecto con un par de clicks. Ya hemos visto en otra ocasión cómo instalar un plugin en Eclipse desde el propio Eclipse (el plugin ADT fue en ese caso), así que lo único que tenemos que hacer en la página de google es buscar nuestra versión de eclipse y tomar la url que debemos emplear, esperar a que cargue la lista y elegir el google plugin for eclipse. Una vez listo, instalamos (saldrá el aviso de “software no firmado” que tendremos que confirmar, estos de google…) y reiniciamos eclipse. Al volver a arrancar deberíamos tener un icono redondo azul con la g de google en nuestra barra de herramientas. A mí me salió a la izquierda del SDK Manager.
Y hablando del SDK Manager, tenemos que usarlo ahora. En la ventana que se abre, iremos al fondo hasta que veamos “extras” en el lado izquierdo. Ahí dentro tenemos que buscar Google Play Services e instalarlo.

Preparativos en el workspace

Cuando Google Play Services esté instalado, tocará importar el proyecto librería (la página de google decía que bastaba con el jar, pero no es cierto, en el próximo post os cuento), lo cual haremos con File > New > Import > Existing Android Code into Workspace > navegamos a dónde tengamos nuestra carpeta con el SDK (si no lo recordamos, en Window > Preferences > Android tenemos la SDK Location que es dónde tenemos que ir) buscar dentro de extras/google/google_play_services/libproject y aceptar. Se importará el proyecto, el cual está marcado como is Library, que tendremos que emplear en nuestras aplicaciones que quieran acceder a estos servicios.

Anotar la Huellas del Certificado de Firmas

Por último, tenemos que encontrar y anotar las Huellas del Certificado de Firmas, que necesitaremos para acceder a las API de Google. Para ello haremos lo siguiente en sistemas Linix (es el sistema que manejo, pero seguramente habrá un equivalente para otros sistemas a un vistazo en Google =3):
En un Terminal ejecutaremos el siguiente comando keytool:
keytool -exportcert -alias androiddebugkey -keystore ~/.android/debug.keystore -list -v
La keystore o almacén de claves de android está normalmente en /home/usuario/.android/debug-keystore. Esto nos dará una lista de Huellas que tiene la firma que el sistema da automáticamente a todas nuestras aplicaciones, la firma de debug. Cuando queramos publicar la app, tendremos que firmarla con una firma privada, pero eso es otro tema.
En lo que nos devuelve ese comando tenemos que buscar la línea que comienza por “SHA-1″ y dejarla apuntada, ya que la necesitaremos mas adelante.

2. Preparar el proyecto

Los siguientes preparativos se refieren al proyecto o aplicación que tengamos entre manos y ha de repetirse para cada aplicación en la que queramos integrar los servicios de Google Drive.

Obtener el permiso para que nuestra app pueda acceder a los servicios de la API de Google Drive.

Crear el API Project en la consola de APIs de google. Le daremos el nombre de la app a la que queramos que Google de paso cuando usemos las llamadas de sus APIs. Una vez creado, seguimos los siguientes pasos dentro de la misma consola:
  1. En el desplegable, elegimos Services. Saldrá un listado con las API de Google a las que querremos que tenga acceso nuestra app, así que buscaremos Drive API y la activaremos.
  2. En el desplegable, elegimos API Access. Accedemos a Create an OAuth 2.0 client ID y lo cumplimentamos con la siguiente información:
    • En Branding Information ponemos el nombre de nuestra aplicación. El resto de campos son opcionales, por lo que pulsaremos Next.
    • En Client ID Settings:
      • En Application type: Installed application
      • En Installed Application Type: Android
      • En Package Name: el package name de nuestro proyecto (ejemplo: com.alberovalley.gdrivetutorial)
      • En Signing Certificate fingerprint: la cadena de texto que copiamos de nuestra clave de debug (sin el SHA-1).
      • Clickamos en Create Client ID.

Librerías y dependencias del proyecto

Usando el plugin de google para Eclipse, elegimos del desplegable Add Google APIs. En la nueva ventana, buscaremos Drive API v2. Con esto habremos añadido la librería cliente de Google Drive.
En el proyecto Properties > Android añadimos el proyecto librería google_play_services que dejamos preparado en el punto 1. El quickstart de Google sólo habla de añadir el jar que viene ahí, pero si se hace como dice, al ejecutar la app te dará un NoClassDefFoundError porque necesita el código y los recursos que están definidos en el proyecto, no sólo el jar.

3. Empezar a programar


Cuando hemos llegado a este punto, ya sólo queda empezar a programar nuestra app. haremos una app muy sencilla (una única Activity y sin usar siquiera su layout) que nos pedirá que nos loguemos con nuestra cuenta de Google, nos permitirá tomar fotografías y las subirá a nuestro Google Drive, tal como dije en la introducción.

Vamos ahora con la app de subir fotos. Proviene de un quickstar de google developers y, como ellos mismos dicen, se trata de una aplicación rápida y sencilla para que vayamos aprendiendo cómo se hace, por lo que puede no estar todo lo bien hecha que cabría, pero funciona y hace lo que debe.

Partimos de la base que todos los preparativos nombrados en el primer artículo de esta serie han sido tomados correctamente. Una vez todo ello listo, vamos al turrón.

Permisos

En el Manifest tenemos que añadir los permisos convenientes para poder acceder a los servicios de Google Drive. Estos son
  • INTERNET, obviamente, para tener acceso a los servidores de Google.
  • GET_ACCOUNTS, que es el que nos permite trastear con las cuentas ID (Google, Twitter, Facebook, etc).
El código a añadir al xml (por si os da pereza meteros en el desplegable interminable de la interfaz en Eclipse) es el siguiente


El código

Sólo necesitaremos una clase, la MainActivity (o el nombre que le hayamos dado) que genera Eclipse cuando creamos el proyecto Android. Ni siquiera usaremos el layout, ya que todo se hará a través de Intents del sistema (el de gestión de cuentas, el de la cámara…).
El código de la actividad es este. Procederemos a despiezarlo para intentar entenderlo.
1
2
3
4
5
6
7
@Override
 public void onCreate(Bundle savedInstanceState) {
   super.onCreate(savedInstanceState);
   credential = GoogleAccountCredential.usingOAuth2(this, DriveScopes.DRIVE);
   startActivityForResult(credential.newChooseAccountIntent(), REQUEST_ACCOUNT_PICKER);
 }
El familiar método onCreate. Aquí ya se empiezan a usar las clases de Google, Credential en este caso. Se inicializa la misma y se arranca la Actividad del gestor de cuentas ForResult, vaya, devolviéndonos información que recibiremos en el onActivityResult.
Veamos ahora los casos del onActivityResult
1
2
3
4
5
6
7
8
9
10
case REQUEST_ACCOUNT_PICKER:
     if (resultCode == RESULT_OK && data != null && data.getExtras() != null) {
       String accountName = data.getStringExtra(AccountManager.KEY_ACCOUNT_NAME);
       if (accountName != null) {
         credential.setSelectedAccountName(accountName);
         service = getDriveService(credential);
         startCameraIntent();
       }
     }
     break;
Por aquí pasa cuando, la primera vez que se ejecuta, sale el gestor de cuentas y nosotros le hemos dicho que sí, que hacemos login con la cuenta X de la lista que tenemos. Actualiza el campo SelectedAccountName de credential con el valor adecuado que devolvió el gestor de cuentas, inicializa el servicio Drive con los credenciales ahora cumplimentados y arranca el Intent de la cámara.
1
2
3
4
5
6
7
case REQUEST_AUTHORIZATION:
      if (resultCode == Activity.RESULT_OK) {
        saveFileToDrive();
      } else {
        startActivityForResult(credential.newChooseAccountIntent(), REQUEST_ACCOUNT_PICKER);
      }
      break
Por aquí pasa tras hacer la primera foto, cuando tiene que pedir permiso la app para gestionar (en este caso, guardar las fotos allí) el Google Drive del usuario. Si se obtienen, guarda la foto; si no, a pedirlo tocan.
1
2
3
4
case CAPTURE_IMAGE:
      if (resultCode == Activity.RESULT_OK) {
        saveFileToDrive();
      }
Y por aquí cuando ha hecho una foto y hemos pulsado en guardarla. Llama al método con el que guardamos la foto en Google Drive y listos.
1
2
3
4
5
6
7
8
9
10
11
private void startCameraIntent() {
    String mediaStorageDir = Environment.getExternalStoragePublicDirectory(
        Environment.DIRECTORY_PICTURES).getPath();
    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(new Date());
    fileUri = Uri.fromFile(new java.io.File(mediaStorageDir + java.io.File.separator + "IMG_"
        + timeStamp + ".jpg"));
    Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
    startActivityForResult(cameraIntent, CAPTURE_IMAGE);
  }
Con este método llama al Intent de la cámara. Así se ahorra tener que escribir una actividad que lleve el tema de las cámaras y, además, tener que pedir permiso CAMERA en el Manifest. Muestra algo de lo que comenté de ser una app “no todo lo bien hecha que cabría”: El Locale para el formato de tiempo lo pone a pelo de Estados Unidos, en vez de usar el default para que tome el que tenga configurado el móvil. Habrá mas cosas “no del todo bien hechas” en toda la app, pero esta es una bastante llamativa.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
private void saveFileToDrive() {
    Thread t = new Thread(new Runnable() {
      @Override
      public void run() {
        try {
          // File's binary content
          java.io.File fileContent = new java.io.File(fileUri.getPath());
          FileContent mediaContent = new FileContent("image/jpeg", fileContent);
          // File's metadata.
          File body = new File();
          body.setTitle(fileContent.getName());
          body.setMimeType("image/jpeg");
          File file = service.files().insert(body, mediaContent).execute();
          if (file != null) {
            showToast("Photo uploaded: " + file.getTitle());
            startCameraIntent();
          }
        } catch (UserRecoverableAuthIOException e) {
          startActivityForResult(e.getIntent(), REQUEST_AUTHORIZATION);
        } catch (IOException e) {
          e.printStackTrace();
        }
      }
    });
    t.start();
  }


Y con esto, por último, guarda la foto en Google Drive. Si no estuviera autorizada la app para ello (como ocurre en el caso de la primera foto) se producirá la excepción UserRecoverableAuthIOException y solicitará permisos lanzando el Intent adecuado. Y esto es todo. Con tan solo los permisos y esta actividad ya se puede probar la app en el móvil o tablet. La pantalla del gestor de cuentas y la de petición de permiso sólo aparecerán en la primera ejecución y el primer guardado de foto (salvo que se diga “no” al permiso, claro). A partir de ahí sólo tomará fotos, las subirá y volverá a sacar la actividad de la cámara. Tomad un par de fotos de ejemplo y luego mirad en vuestro Google Drive, en Recientes, para ver que se han subido correctamente. Y ya está. Como siempre, tenéis disponible el código de este tutorial en el repositorio de github.

Fuente: http://alberovalley.wordpress.com/2013/01/21/integrando-google-drive-en-nuestras-apps-ii-primera-app-integrada-con-drive/