lunes, 4 de junio de 2012

Creando un servicio propio en Android


Continuando con esos tutoriales de Service en Android, que publicò la gente de Androideity (http://androideity.com/tag/servicios-en-android/ ) vamos a explicar los pasos que debemos llevar a cabo para crear un servicio para que desde una actividad podamos consumirlo. El objetivo del servicio será recuperar datos de forma periódica para que de esta forma la actividad pueda desplegarlos a través de una ListView, siempre pudiendo pedir los datos más actualizados de este servicio.
Teniendo el concepto claro, pasemos a codificarlo:
1. Creamos un nuevo proyecto llamado MiServicio con la versión Android 2.2. Como dato adicional, a la actividad principal del proyecto la he llamado Consumer:
2. Creamos una nueva clase llamada MiServicio que es en dónde vamos a escribir todo el código correspondiente a lo que hace el servicio. A continuación te proporciono el código que deberá tener esta clase:
import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;
 
public class MiServicio extends Service {
 private Timer timer = new Timer();
 private static final long UPDATE_INTERVAL = 5000;
 private final IBinder mBinder = new MyBinder();
 private ArrayList list = new ArrayList();
 private String[] fixedList = { "Cupcake", "Donut", "Eclair", "Froyo",
   "Gingerbread", "Honeycomb", "Ice Cream Sandwich" };
 private int index = 0;
 
 public void onCreate() {
  super.onCreate();
  pollForUpdates();
 }
 
 private void pollForUpdates() {
  timer.scheduleAtFixedRate(new TimerTask() {
   @Override
   public void run() {
    // Esta parte podría sustuirse por un web service que consultemos
    if (list.size() >= 6) {
     list.remove(0);
    }
    list.add(fixedList[index++]);
    if (index >= fixedList.length) {
     index = 0;
    }
   }
  }, 0, UPDATE_INTERVAL);
  Log.i(getClass().getSimpleName(), "Timer started.");
 
 }
 
 @Override
 public void onDestroy() {
  super.onDestroy();
  if (timer != null) {
   timer.cancel();
  }
  Log.i(getClass().getSimpleName(), "Timer stopped.");
 
 }
 
 @Override
 public IBinder onBind(Intent arg0) {
  return mBinder;
 }
 
 public class MyBinder extends Binder {
  MiServicio getService() {
   return MiServicio.this;
  }
 }
 
 public List getWordList() {
  return list;
 }
}
En primer lugar podemos observar que esta clase hereda de Service. Dentro de la claseMiServicio declaramos una variable Timer que nos ayudará a manipular las actualizaciones de la información que proveerá el servicio junto con la variable UPDATE_INTERVAL que fijamos con un valor de 5 segundos. Tenemos un ArrayList y un arreglo de cadenas que nos servirán para jugar con la información del servicio; y un IBinder, una interfaz que describe un protocolo abstracto para interactuar con un objeto utilizable de forma remota. Regularmente los servicios nos ayudan a trabajar con web services para así evitar la sobrecarga de procesos a la aplicación y que la batería del teléfono se vea altamente comprometida. En este caso, el servicio es interno y trabaja con datos estáticos, el tema de web services lo abarcaremos en posteriores tutoriales.
Dentro de los métodos que estamos creando en nuestro servicio se encuentrapollForUpdates() en el que definimos la tarea cuya ejecución se repetirá según el tiempo que nosotros mismo definamos y que es de 5 segundos gracias a la constanteUPDATE_INTERVAL.
Con respecto al uso de IBinder, la documentación de Android nos dice que no debemos implementarla de manera directa, y que para efectos práticos debemos utilizar una clase que extienda de Binder. Es por ello que creamos una clase interna llamada MyBinder. El resto es incluir los métodos sobreescritos onDestroy() y onBind().
3. Ahora pasemos a codificar la actividad que consumirá este servicio. Para la cuál definimos la siguiente interfaz gráfica que consta de un botón para refrescar la información del servicio y una ListView para desplegar los datos del mismo.
4. Después, escribimos el siguiente código que deberá contener la actividad Consumer:
import java.util.ArrayList;
import java.util.List;
 
import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Toast;
 
public class Consumer extends Activity {
 private MiServicio s;
 private ArrayList values;
 
/** Called when the activity is first created. */
 
 @Override
 public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.main);
  doBindService();
  values = new ArrayList();
  adapter = new ArrayAdapter(this,
    android.R.layout.simple_list_item_1, values);
  ListView list = (ListView) findViewById(R.id.list);
  list.setAdapter(adapter);
 }
 
 private ServiceConnection mConnection = new ServiceConnection() {
 
  public void onServiceConnected(ComponentName className, IBinder binder) {
   s = ((MiServicio.MyBinder) binder).getService();
   Toast.makeText(Consumer.this, "Connected",
     Toast.LENGTH_SHORT).show();
  }
 
  public void onServiceDisconnected(ComponentName className) {
   s = null;
  }
 };
 private ArrayAdapter adapter;
 
 void doBindService() {
  bindService(new Intent(this, MiServicio.class), mConnection,
    Context.BIND_AUTO_CREATE);
 }
 
 public void showServiceData(View view) {
  if (s != null) {
   List wordList = s.getWordList();
   values.clear();
   values.addAll(wordList);
   adapter.notifyDataSetChanged();
  }
 }
}
Declaramos un ArrayList y un objeto de tipo MiServicio. Para poder trabajar a gusto con el servicio propio, será indispensable crear un objeto de tipo ServiceConnection por medio del cuál realizaremos las funciones necesarias para que nuestra actividad pueda conectarse con el servicio creado y podamos así, accesar a la información que nos provee. Como vamos a llenar una ListView con estos datos, es importante crear un adaptador. 
Luego, a través del método showServiceData() manipulamos la forma en la que se llenará nuestra lista de información para desplegársela al usuario.
5. Una vez que hemos terminado la lógica de la aplicación nos faltará dar de alta el servicio creado en el archivo AndroidManifest.xml como te muestro a continuación:
6. Ejecutamos el ejemplo, para que puedas observar la manera en la que fluye la información en la pantalla y qué pasa cada vez que presionamos el botón Refresh.
Espero que este ejemplo te de una introducción al uso de servicios propios, que como mencioné líneas arriba en la mayoría de los casos se utilizan a través de web services cuando se manejan peticiones más complejas.

FUENTE: http://androideity.com/tag/servicios-en-android/

No hay comentarios:

Publicar un comentario