Iniciar un servicio en android automaticamente

Hay ocasiones en las que podemos necesitar o querer que un servicio se inicie automáticamente por ejemplo para actualizar información de la aplicación. Para hacer esto en Android disponemos de los BroadcastReceivers que nos permiten llevar acabo alguna acción en respuesta a eventos del sistema como el arranque del sistema, cambio en el nivel de batería, recepción de un SMS, etc. y en este caso vamos a ver un ejemplo de como iniciar un servicio automáticamente tras el reinicio del sistema.

En el post anterior comenté como crear un servicio en Android y para ilustrarlo puse el ejemplo de un cronometro, como esa parte ya esta explicada (Como crear un Service (servicio) en Android) voy a reutilizar ese ejemplo y explicar que es lo que hay que añadir al proyecto anterior para que el servicio se inicie automáticamente cuando se encienda el móvil, tablet, o el dispositivo que sea.

Para conseguir nuestro objetivo únicamente se necesita añadir una clase más a nuestro proyecto (el BroadcastReceiver), añadir un par de líneas al AndroidManifest y un mínimo cambio en el servicio.

Vamos a empezar creando el BroadcastReceiver. Únicamente hay que sobrescribir el método onReceive y llamar desde aquí al servicio con el método startService del mismo modo que lo hacíamos en el post anterior desde el activity.


package com.poi.services;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;

public class AutoArranque extends BroadcastReceiver{

    @Override
    public void onReceive(Context context, Intent intent) {
        Intent service = new Intent(context,  Cronometro.class);
        context.startService(service);
    }

}

Con estas pocas líneas de código ya tenemos todo lo necesario para llamar al servicio cronometro.

El siguiente paso es añadir al AndroidManifest el permiso necesario para que la aplicación pueda «enterarse» de cuando arranca el sistema:


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

Y añadir el receiver que queremos que se ejecute cuando se produzca este evento:


<receiver android:name="AutoArranque" >
    <intent-filter>
        <action android:name="android.intent.action.BOOT_COMPLETED" />
    </intent-filter>
</receiver>

Con lo que el AndroidManifest resultante sería este:


<?xml version= "1.0" encoding= "utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.poi.services"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="19" />

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

    <application
        android:allowBackup="false"
        android:icon="@drawable/icon"
        android:label="@string/app_name" >
        <activity
            android:name="com.poi.services.PoiService"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <receiver android:name="AutoArranque" >
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED" />
            </intent-filter>
        </receiver>

        <service android:name="Cronometro" />
    </application>

</manifest>    

Y con esto ya esta todo listo para que cuando reiniciemos nuestro android el servicio se arranque solo automáticamente, pero si lo probamos va a fallar debido a que el servicio sincroniza sus datos con la activity para que podamos ver el cronometro y como no hemos iniciado la aplicación entonces dará un error que es tan sencillo de solucionar como comprobar si se ha iniciado el activity y sino actualizar el cronometro pero no intentar sincronizarlo con la IU. Para hacer esto simplemente añadimos la comprobación para ver si UPDATE_LISTENER (que se inicializa en el onCreate de el activity PoiService) es distinto de null y si lo es null no hacemos nada y sino llamamos al handler que hace la actualización.

Screenshot_2014-07-15-21-43-40


private void iniciarCronometro() {
    temporizador.scheduleAtFixedRate(new TimerTask() {
        public void run() {
            cronometro += 0.01;
            if(UPDATE_LISTENER != null) {
                handler.sendEmptyMessage(0);
            }
        }
    }, 0, INTERVALO_ACTUALIZACION);
}

Ahora ya si funciona con el ejemplo del cronometro, instálalo en tu móvil, reinicia y podrás comprobar que el servicio esta entre las aplicaciones que se están ejecutando y cuando habrás la aplicación «POI Service (Cronometro)» veras que el cronometro esta en marcha marcando el tiempo transcurrido desde que se inicio tu móvil.

Screenshot_2014-07-15-21-40-46

O al menos debería porque desde Android 3.1 para que la aplicación pueda iniciarse automáticamente el usuario tiene que haberla iniciado alguna vez, si no la aplicación no podrá recibir eventos android.intent.action.BOOT_COMPLETED, tampoco se iniciará automáticamente si el usuario ha forzado el cierre de la aplicación (la ha cerrado desde el administrador de aplicaciones) por lo tanto si no has iniciado nunca la aplicación o la has cerrado de «mala» manera no se iniciará automáticamente.

Como siempre puedes descargarte el proyecto completo del ejemplo haciendo click en este enlace.

3 Comments

  1. Nanoz Vera 13 abril, 2017 Reply
  2. Eduardo 15 noviembre, 2017 Reply
  3. Óscar 15 diciembre, 2017 Reply

Leave a Reply