*Un BroadcastReceiver es un componente androide responsable de escuchar los eventos o intentos de difusión de todo el sistema.

En Android, la mayoría de los eventos del sistema se difunden a través de objetos Intent. Para ello estos objetos Intent se envían a los BroadcastReceivers utilizando los métodos Context.sendBroadcast().

Cuando se emite un evento de este tipo, el BroadcastReceiver recibirá el evento y reaccionará creando una notificación en la barra de estado o realizando una tarea determinada.

Un BroadcastReceiver es un componente androide como Activity y Service por lo que la mayoría de las veces necesita ser registrado en el archivo de manifiesto androide.

Sin embargo, a diferencia de la Activity, los BroadcastReceivers no tienen ninguna interfaz de usuario.

BroadcastReceiver como clase es abstracta, por lo que normalmente tiene un método llamado onReceive() que anulamos para hacer la tarea que queremos que ocurra cuando se reciba la tarea.

La mayoría de los eventos estándar del sistema se definen como cadenas de acción y se pueden encontrar en la documentación de la API para la clase Intent.

Supongamos, por ejemplo, que tu aplicación necesita ser notificada cada vez que el usuario conecta o desconecta el cargador al dispositivo, dos acciones de difusión definidas en la clase Intent hacen eso:

  1. ACTION_POWER_DISCONNECTED (ACCIÓN DE DESCONEXIÓN DE ENERGÍA)
  2. ACTION_POWER_CONNECTED.

Aquí hay un ejemplo.

public class PhoneChargerConnectedListener extends BroadcastReceiver {
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();
        if (Intent.ACTION_POWER_CONNECTED.equals(action)) {
            context.startService(
            new Intent(MyService.ACTION_POWER_CONNECTED));
        } else if (Intent.ACTION_POWER_DISCONNECTED.equals(action)) {
        context.startService(
        new Intent(MyService.ACTION_POWER_DISCONNECTED));
        }
    }
}

En este método, lo único que se hace es llamar a Context.startService() para delegar el evento a un service que realice el trabajo real.

¿Cómo registro el BroadcastReceiver?

Bueno, podemos registrar el BroadcastReceiver de dos maneras.

1. A través de AndroidManifest.xml

El método por defecto para implementar BroadcastReceivers es declararlos en el manifiesto de android.
Debido a esto, es posible que el BroadcastReceiver notifique a tu service aunque el usuario no haya iniciado tu aplicación.

Esto es especialmente útil para las aplicaciones que deben iniciarse en ciertos eventos del sistema sin la interacción del usuario.

<receiver android_name=".PhoneChargerConnectedListener">
    <intent-filter>
        <action android_name="android.intent.action.ACTION_POWER_CONNECTED"/>
        <action android_name="android.intent.action.ACTION_POWER_DISCONNECTED"/>
    </intent-filter>
</receiver>

Este método es también la forma más fácil.

Usando AndroidManifest.xml para registrar BroadcastReceiver, tu aplicación estará recibiendo los Broadcasts hasta que desinstales la aplicación. Esto significa que sacrificas un poco el control del ciclo de vida del BroadcastReceiver ya que no puedes registrarlo y desregistrarlo a tu antojo.

Para ello, comprueba la siguiente forma de registrar los receptores de difusión.

2. Programáticamente

Los BroadcastReceivers también se pueden registrar mediante programación dentro de Actividades y Servicios.

De hecho, algunos intentos de emisión sólo pueden registrarse mediante programación. Por otro lado, algunos sólo funcionan si los declaras en tu manifiesto.

Cuando registres un BroadcastReceiver de forma programática también tienes que acordarte de desregistrarlo en el callback correspondiente.

Aquí tienes un ejemplo:

public class MyActivity extends AppCompatActivity {
    private PhoneChargerConnectedListener myPhoneChargerConnectedListener;
    @Override
    protected void onResume() {
        super.onResume();
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(Intent.ACTION_POWER_CONNECTED);
        intentFilter.addAction(Intent.ACTION_POWER_DISCONNECTED);
        myPhoneChargerConnectedListener = new PhoneChargerConnectedListener();
        registerReceiver(myPhoneChargerConnectedListener, intentFilter);
    }
    @Override
    protected void onPause() {
        super.onPause();
        unregisterReceiver(myPhoneChargerConnectedListener);
    }
}

En este caso hemos registrado el BroadcastReceiver programáticamente usando el método registerReceiver() de la clase Context. Usando este método, podemos controlar el ciclo de vida de nuestro BroadcastReceiver registrándolo y desregistrándolo según nuestras necesidades.

Ejemplo de BroadcastReceiver con AlarmManager

Veamos un ejemplo sencillo de receptor de broadcast con gestor de alarmas.

Tendremos una actividad y una clase.

(a). MainActivity.java

Comienza creando una actividad en tu android studio.

Aquí tenemos nuestra clase MainActivity. Esta clase será derivada de AppCompatActivity que reside en la biblioteca de apoyo.

Tendremos tres métodos:

    1. onCreate(),
  1. initializeViews(),
    1. "go()`.

La interfaz de usuario de esta actividad se inflará desde content_main.xml utilizando el método setContentView().

Las vistas que utilizamos son EditTexts y Buttons.
Las referenciamos desde nuestra especificación de layout usando findViewById().

Inicializaremos y pondremos en marcha nuestra alarma en el método go().

package com.tutorials.hp.alarmmanagerstarter;

import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Intent;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    Button startBtn;
    EditText timeTxt;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

         initializeViews();

        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                        .setAction("Action", null).show();
            }
        });

    }

    /*
    INITIALIZE VIEWS
     */
    private void initializeViews()
    {
        timeTxt= (EditText) findViewById(R.id.timeTxt);
        startBtn= (Button) findViewById(R.id.startBtn);

        startBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
               go();
            }
        });
    }

    /*
    INITIALIZE AND START OUR ALARM
     */
    private void go()
    {
        //GET TIME IN SECONDS AND INITIALIZE INTENT
        int time=Integer.parseInt(timeTxt.getText().toString());
        Intent i=new Intent(this,MyReceiver.class);

        //PASS CONTEXT,YOUR PRIVATE REQUEST CODE,INTENT OBJECT AND FLAG
        PendingIntent pi=PendingIntent.getBroadcast(this,0,i,0);

        //INITIALIZE ALARM MANAGER
        AlarmManager alarmManager= (AlarmManager) getSystemService(ALARM_SERVICE);

        //SET THE ALARM
        alarmManager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis()+(time*1000),pi);
        Toast.makeText(MainActivity.this, "Alarm set in "+time+" seconds", Toast.LENGTH_SHORT).show();
    }

}

(b). MiRecibidor.java

  • Nuestra clase MyReciever.
  • Deriva de la clase android.content.BroadcastReceiver.
  • Métodos: onReceive().
  • Mostramos un mensaje de brindis en nuestro método onReceive() para simular el sonido de la alarma.

package com.tutorials.hp.alarmmanagerstarter;

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

public class MyReceiver extends BroadcastReceiver {
    /*
    RING ALARM WHEN IN WHEN WE RECEIVE OUR BROADCAST
     */
    @Override
    public void onReceive(Context context, Intent intent) {
        Toast.makeText(context, "Alarm Ringing...", Toast.LENGTH_SHORT).show();
    }
}

(c) activity_main.xml

  • Nuestro archivo de diseño de la actividad principal.
  • Se inflará a MainActivity.
  • La etiqueta raíz es relativeLayout.
  • Contiene un EditText y un botón.

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

<RelativeLayout

    android_layout_width="match_parent"
    android_layout_height="match_parent"
    tools_context="com.tutorials.hp.alarmmanagerstarter.MainActivity"
    >

    <EditText
        android_id="@+id/timeTxt"
        android_layout_width="wrap_content"
        android_layout_height="wrap_content"
        android_layout_alignParentLeft="true"
        android_layout_alignParentTop="true"
        android_layout_marginTop="28dp"
        android_ems="10"
        android_hint="Number of seconds"
        android_inputType="numberDecimal" />

    <Button
        android_id="@+id/startBtn"
        android_layout_width="wrap_content"
        android_layout_height="wrap_content"
        android_layout_alignRight="@+id/timeTxt"
        android_layout_below="@+id/timeTxt"
        android_layout_marginRight="60dp"
        android_layout_marginTop="120dp"
        android_text="Start" />
</RelativeLayout>

(d). AndroidManifest.xml

Tendremos que registrar nuestra clase BroadcastReceiver en nuestro manifiesto android.

Aquí está mi manifiesto al completo:

<?xml version="1.0" encoding="utf-8"?>
<manifest
    package="com.tutorials.hp.alarmmanagerstarter">
    <application
        android_allowBackup="true"
        android_icon="@mipmap/ic_launcher"
        android_label="@string/app_name"
        android_supportsRtl="true"
        android_theme="@style/AppTheme">
        <activity
            android_name=".MainActivity"
            android_label="@string/app_name"
            android_theme="@style/AppTheme.NoActionBar">
            <intent-filter>
                <action android_name="android.intent.action.MAIN" />

                <category android_name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <receiver android_name="MyReceiver" >
        </receiver>
    </application>

</manifest>

Ejemplos rápidos de BroadcastReceiver.

1. Escuchar los cambios de estado de la red con BroadcastReceiver.

Primero tenemos que crear una clase java, y luego hacer que derive de android.content.BroadcastReceiver.

Como campos de instancia tendremos un booleano isNetWorkConnected que nos mantendrá el verdadero o falso indicando si la red está conectada o no.

También tendremos un objeto Contexto.

Proporcionamos dos constructores, uno que inyectará en nuestra clase el objeto Context.
Luego sobrescribimos el método onReceive() de la clase BroadcastReceiver. Normalmente este método recibe dos objetos, uno Context y otro Intent.

Aquí inicializaremos un ConnectivityManager utilizando el método getSystemService() de la clase Context.

Usando la instancia del ConnectivityManager, invocamos el método getActiveNetworkInfo() para recibir la información de la red que tenemos en un objeto android.net.NetworkInfo.

Finalmente, establecemos el valor de isConnected() como booleano isNetWorkConnected.

También tenemos el método isNetWorkAvailable(), que básicamente comprobará por nosotros si la red está disponible.

Es sólo un método público que necesita la instancia de esta clase para ser invocada como veremos en breve.

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.widget.Toast;
import java.util.concurrent.CopyOnWriteArrayList;

public class NetWorkStateReceiver extends BroadcastReceiver {
    public boolean isNetWorkConnected;
    private Context mContext;

    public NetWorkStateReceiver() {
        super();
    }
    public NetWorkStateReceiver(Context context) {
        mContext = context;
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        ConnectivityManager connectivityManager = (ConnectivityManager)
                context.getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();

        if (networkInfo != null && networkInfo.isConnected()) {
            isNetWorkConnected = true;
        } else {
            isNetWorkConnected = false;
            Toast.makeText(context, "No network Connection", Toast.LENGTH_SHORT).show();
        }

    }

    /**
     * Check if network is available
     * @return boolean value
     */
    public boolean isNetWorkAvailable() {
        ConnectivityManager connectivityManager = (ConnectivityManager)
                mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
        if (networkInfo != null) {
            return networkInfo.isConnected();
        }
        return false;
    }
}

Entonces en tu MainActivity o donde sea, puedes venir y empezar instanciando la clase anterior:

    publi class MainActivity extends AppCompatActivity{
        NetWorkStateReceiver receiver;
        @Override
        public void onCreate(Bundle savedInstanceState){
            .....
           receiver = new NetWorkStateReceiver(this);
           if(receiver.isNetWorkAvailable())
           {
               //do something network is available
           }
        }
    }

En tu AndroidManifest.xml debes primero añadir los permisos adecuados así como registrar tu BroadcastReceiver:

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

    <uses-permission android_name="android.permission.INTERNET" />
    <uses-permission android_name="android.permission.ACCESS_NETWORK_STATE" />
    <application>
        ....
        <receiver
            android_name=".broadcasts.NetWorkStateReceiver"
            android_enabled="true"
            android_exported="true" />
        ....
    </application>

2. Cómo crear un BroadcastReceiver personalizado

Aquí tenemos una clase abstracta personalizada de BroadcastReciever. Obviamente deriva de la clase BroadcastReceiver. Procedemos a redefinir los métodos importantes de esta clase como los métodos registerReceiver(), unregisterReceiver() y sendBroadcast().


import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.support.v4.content.LocalBroadcastManager;

public abstract class LocalBroadcastCommunicator extends BroadcastReceiver {

    // The action name used to send and alsoe receive intents
    private static String sAction = null;

    private static <T> void registerReceiver(LocalBroadcastCommunicator receiver, Context context) {
        sAction = receiver.getClass().getName();
        LocalBroadcastManager.getInstance(context).registerReceiver(receiver, new IntentFilter(sAction));
    }

    private static <T> void unregisterReceiver(LocalBroadcastCommunicator receiver, Context context) {
        LocalBroadcastManager.getInstance(context).unregisterReceiver(receiver);
    }

    public static void sendBroadcast(Context context, Intent intent) {
        if(sAction == null) {
            /* If sAction is null at this point, no receiver has been registered yet and there's no
             * point in sending a broadcast. */
            return;
        }

        intent.setAction(sAction);
        LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
    }

    public void registerReceiver(Context context) {
        registerReceiver(this, context);
    }

    public void unregisterReceiver(Context context) {
        unregisterReceiver(this, context);
    }
}

Ejemplos completos

1. Cómo mostrar una notificación de batería baja usando BroadcastReceiver.

Estamos creando un simple BatteryManager usando la clase BroadcasteReceiver. Mostraremos el nivel de batería en un TextView y mostraremos el progreso en la barra de progreso.

Aquí están algunas de las API's que quizás no conozcas y que utilizamos:

(a). BroadcastReceiver

Esta es la clase base para el código que recibirá los intentos enviados por sendBroadcast().

(b). IntentFilter

IntentFilter es una descripción estructurada de los valores de Intent que deben ser comparados. Un IntentFilter puede coincidir con acciones, categorías y datos (ya sea a través de su tipo, esquema y/o ruta) en un Intent.

(c). Gestor de pilas

Esta clase contiene cadenas y constantes utilizadas para los valores de la ACTION_BATTERY_CHANGED Intent.

MainActivity.java

Esta es la actividad principal.

package com.example.ankitkumar.broadcastreceiver_batterymanager;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.BatteryManager;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.widget.ProgressBar;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {
    TextView batteryLevel;
    ProgressBar myProgressBar;

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        batteryLevel = (TextView)findViewById(R.id.textView);
        myProgressBar = (ProgressBar)findViewById(R.id.progressBar);
        IntentFilter intentFilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
        registerReceiver(myBroadcastReceiver, intentFilter);

    }

    BroadcastReceiver myBroadcastReceiver = new BroadcastReceiver() {
        public void onReceive(Context context, Intent intent) {
            context.unregisterReceiver(this);
            int currentLevel = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
            int scale = intent.getIntExtra(BatteryManager.EXTRA_SCALE, -1);
            int level = -1;
            if (currentLevel >= 0 && scale > 0) {
                level = (currentLevel * 100) / scale;
            }
            batteryLevel.setText("Battery Level remaining :"+  level +"%");
            myProgressBar.setProgress(level);
        }
    };
}

**Actividad_principal.xml

Este es el layout de la actividad principal.
Aquí tendremos un TextView para mostrar el nivel de batería y una barra de progreso para mostrar el porcentaje de batería.

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

<RelativeLayout
        tools_context="com.example.ankitkumar.broadcastreceiver_batterymanager.MainActivity" android_paddingTop="@dimen/activity_vertical_margin" android_paddingRight="@dimen/activity_horizontal_margin" android_paddingLeft="@dimen/activity_horizontal_margin" android_paddingBottom="@dimen/activity_vertical_margin" android_layout_height="match_parent" android_layout_width="match_parent" android_id="@+id/activity_main"  >

<TextView
        android_layout_height="wrap_content" android_layout_width="wrap_content" android_id="@+id/textView" android_layout_centerHorizontal="true" android_layout_centerVertical="true" android_textSize="20sp" android_text="Hello World!"/>

<ProgressBar
        android_layout_height="20dp" android_layout_width="match_parent" android_id="@+id/progressBar" android_layout_alignParentRight="true" android_layout_alignParentEnd="true" android_layout_below="@+id/textView" android_layout_marginTop="25dp" android_max="100" style="?android:attr/progressBarStyleHorizontal"/>

</RelativeLayout>

Descarga

No. Localización Enlace
1. GitHub - Descarga

| 1. GitHub Creador original: @AnkitKumar111

2. Usar BroadcastReceiver para escuchar los SMS entrantes y mostrarlos

Escuchamos ese SMS entrante y luego lo leemos y lo mostramos en un mensaje Toast.

MainActivity.java

Esta es la actividad principal.

package com.example.ankitkumar.msgreceive;

import android.Manifest;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;

public class MainActivity extends AppCompatActivity {

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

        //checking wether the permission is already granted
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_SMS) != PackageManager.PERMISSION_GRANTED) {

            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_SMS}, 1);

        }

    }

}

IcomingSMS.java

Nuestro archivo IncomingSMS.java. Aquí están algunas de las APIs que utilizamos:

(a). SmsManager

Esta es una clase definida en el paquete android.telephony que es responsable de la gestión de las operaciones de SMS como el envío de datos, texto y mensajes SMS pdu.

(b). SmsMessage

Representa un mensaje del Servicio de Mensajes Cortos.

package com.example.ankitkumar.msgreceive;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.telephony.SmsManager;
import android.telephony.SmsMessage;
import android.util.Log;
import android.widget.Toast;
import static android.telephony.SmsMessage.createFromPdu;

public class IncomingSms extends BroadcastReceiver {

    // Get the object of SmsManager
    final SmsManager sms = SmsManager.getDefault();

    @Override
    public void onReceive(Context context, Intent intent) {

        // Retrieves a map of extended data from the intent.
        final Bundle bundle = intent.getExtras();

        try {

            if (bundle != null) {

                final Object[] pdusObj = (Object[]) bundle.get("pdus");

                for (int i = 0; i < pdusObj.length; i++) {

                    SmsMessage currentMessage = createFromPdu((byte[]) pdusObj[i]);
                    String phoneNumber = currentMessage.getDisplayOriginatingAddress();

                    String senderNum = phoneNumber;
                    String message = currentMessage.getDisplayMessageBody();

                    Log.i("SmsReceiver", "senderNum: " + senderNum + "; message: " + message);

                    int duration = Toast.LENGTH_LONG;
                    final Toast toast = Toast.makeText(context, "senderNum: " + senderNum + ", message: " + message, duration);
                    toast.show();

                    //Countdown Timer for extending normal time of toast notification
                    new CountDownTimer(9000, 1000) {

                        public void onTick(long millisUntilFinished) {
                            toast.show();
                        }

                        public void onFinish() {
                            toast.show();
                        }

                    }.start();
                } // end for loop
            } // bundle is null

        } catch (Exception e) {
            Log.e("SmsReceiver", "Exception smsReceiver" + e);

        }
    }

}

activity_main.xml

Este es el diseño de la actividad principal.

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

<RelativeLayout
        tools_context="com.example.ankitkumar.msgreceive.MainActivity" android_background="#f2f2f2" android_layout_height="match_parent" android_layout_width="match_parent"  >

<ImageView
        android_background="@drawable/ic_sms" android_layout_height="200sp" android_layout_width="200sp" android_contentDescription="@string/app_name" android_layout_centerInParent="true" android_alpha="0.4"/>

</RelativeLayout>

Descarga

No. Ubicación Enlace
1. GitHub 2. [Descarga] (https://github.com/AnkitKumar111/Android_Assignment18.2/tree/master/sample/archive/master.zip)
1. GitHub: Navegar 2. GitHub: Navegar
2. GitHub Creador original: @AnkitKumar111

Android LocalBroadcastManager

Android LocalBroadcastManager con IntentService Tutorial y Ejemplo.

Este es un tutorial y ejemplo de android LocalBroadcastManager. Queremos ver qué es el LocalBroadcastManager y cómo utilizarlo con un IntentService.

Video Tutorial

Algunas personas siempre prefieren los tutoriales en vídeo. En ese caso aquí está la versión en video de este tutorial.

Lo que se aprende en este tutorial

Estos son algunos de los concpetos que aprenderás en este tutorial.

  1. Qué es un LocalBroadcastManager y su definición del API.
    1. Ventajas del LocalBroadcastManager.
  2. Cómo utilizar LocalBroadcastManager con IntentService.

¿Qué es LocalBroadcastManager?

Bueno, LocalBroadcastManager es una clase de ayuda que nos permite registrar y enviar transmisiones de Intents a objetos locales dentro de nuestro proceso.

Esta es su definición del API:

public final class LocalBroadcastManager
extends Object

java.lang.Object
   ↳    android.support.v4.content.LocalBroadcastManager

Ventajas de LocalBroadcastManager

Estas son algunas de las ventajas del LocalBroadcastManager sobre el envío de emisiones globales con el método sendBroadcast(Intent):

  1. Los datos de tu aplicación se mantienen privados ya que esta clase trabaja sólo con objetos loales dentro de tu proceso de aplicación.
    1. Es más seguro debido al hecho de que funciona sólo dentro de su proceso de aplicación.
  2. También es más eficiente que enviar un broadcast global a través del sistema.

(a). BroadcastSenderIntentService

Esta es nuestra clase IntentService. Derivaremos de android.app.IntentService y anularemos el método onHandleIntent(). Dentro de este método simularemos una tarea pesada invocando el método sleep() de nuestra clase thread.

package info.camposha.localbroadcastandintentservice;

import android.app.IntentService;
import android.content.Intent;
import android.support.v4.content.LocalBroadcastManager;

public class BroadcastSenderIntentService extends IntentService {

    public BroadcastSenderIntentService() {
        super("BroadcastSenderIntentService");
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        String message = getString(R.string.running);
        Intent broadcastIntent = new Intent();
        broadcastIntent.setAction(MainActivity.MESSAGE_SENT_ACTION);
        broadcastIntent.putExtra(MainActivity.MESSAGE_EXTRA, message);
        LocalBroadcastManager.getInstance(this).sendBroadcast(broadcastIntent);

        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
        }

        message = getString(R.string.finished);
        broadcastIntent = new Intent();
        broadcastIntent.setAction(MainActivity.MESSAGE_SENT_ACTION);
        broadcastIntent.putExtra(MainActivity.MESSAGE_EXTRA, message);
        LocalBroadcastManager.getInstance(this).sendBroadcast(broadcastIntent);
    }

}

(b). MainActivity.java

Aquí está nuestra actividad principal. Comenzamos definiendo varias constantes de cadena que serán útiles a la hora de enviar y recibir nuestros intents ya que actúan como identificadores.

package info.camposha.localbroadcastandintentservice;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.support.v4.content.LocalBroadcastManager;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {

    public static final String MESSAGE_SENT_ACTION = "info.camposha.MESSAGE_RECEIVED_ACTION";
    public static final String MESSAGE_EXTRA = "info.camposha.MESSAGE_EXTRA";

    private static final String MESSAGE_FROM_SERVICE_KEY = "info.camposha.MESSAGE_FROM_SERVICE_KEY";

    private BroadcastReceiver receiver;
    private TextView serviceMessageView;

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

        serviceMessageView = findViewById(R.id.service_message_textview);

        if (savedInstanceState != null) {
            serviceMessageView.setText(savedInstanceState.getString(MESSAGE_FROM_SERVICE_KEY));
        }else{
            serviceMessageView.setText("Null");
        }
    }

    @Override
    protected void onResume() {
        super.onResume();

        receiver = new BroadcastReceiver() {

            @Override
            public void onReceive(Context context, Intent intent) {
                Bundle bundle = intent.getExtras();
                String message = bundle.getString(MESSAGE_EXTRA);

                serviceMessageView.setText(message);
            }
        };

        LocalBroadcastManager.getInstance(this).registerReceiver(receiver, new IntentFilter(MESSAGE_SENT_ACTION));
    }

    @Override
    protected void onPause() {
        super.onPause();

        if (receiver != null) {
            LocalBroadcastManager.getInstance(this).unregisterReceiver(receiver);
            receiver = null;
        }
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putString(MESSAGE_FROM_SERVICE_KEY, serviceMessageView.getText().toString());
    }

    public void onStartServiceClicked(View view) {
        startService(new Intent(this, BroadcastSenderIntentService.class));
    }

}

activity_main.xml

Aquí está el diseño de nuestra actividad principal. Aquí tenemos textview y botón.

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

        android_layout_width="match_parent"
        android_layout_height="match_parent"
        tools_context=".MainActivity">

        <TextView
            android_id="@+id/headerLabel"
            android_layout_width="wrap_content"
            android_layout_height="wrap_content"
            android_layout_alignParentTop="true"
            android_layout_centerHorizontal="true"
            android_fontFamily="casual"
            android_text="LocalBroadcastReceiver"
            android_textAllCaps="true"
            android_textSize="24sp"
            android_textStyle="bold" />

        <LinearLayout
            android_layout_width="wrap_content"
            android_layout_height="wrap_content"
            android_layout_centerHorizontal="true"
            android_layout_centerVertical="true"
            android_gravity="center"
            android_orientation="vertical" >

            <TextView
                android_id="@+id/textView1"
                android_layout_width="wrap_content"
                android_layout_height="wrap_content"
                android_text="@string/service_status"
                android_textSize="16dp" />

            <TextView
                android_id="@+id/service_message_textview"
                android_layout_width="wrap_content"
                android_layout_height="wrap_content"
                android_text="@string/not_running"
                android_textSize="16dp" />
        </LinearLayout>

        <Button
            android_id="@+id/button1"
            android_onClick="onStartServiceClicked"
            android_text="@string/start_service"
            android_layout_width="wrap_content"
            android_layout_height="wrap_content"
            android_layout_alignParentBottom="true"
            android_layout_centerHorizontal="true"
            android_layout_marginBottom="12dp"
            android_fontFamily="serif-monospace" />

</RelativeLayout>

AndroidManifest.xml

En nuestro android manifes hay que asegurarse de que registramos el service. Aquí está el mío:

<?xml version="1.0" encoding="utf-8"?>
<manifest
    package="info.camposha.localbroadcastandintentservice">

    <application
        android_allowBackup="true"
        android_icon="@mipmap/ic_launcher"
        android_label="@string/app_name"
        android_roundIcon="@mipmap/ic_launcher_round"
        android_supportsRtl="true"
        android_theme="@style/AppTheme">
        <activity android_name=".MainActivity">
            <intent-filter>
                <action android_name="android.intent.action.MAIN" />

                <category android_name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <service
            android_name=".BroadcastSenderIntentService" />
    </application>

</manifest>

Kotlin LocalBroadcastManager Ejemplo

Un ejemplo de kotlin AndroidX localbroadcastmanager con IntentService y BroadcastReceiver.

Ver video tutorial aquí:

Paso 1: Añadir Dependencias

Añade AndroiX localbroadcastmanager como dependencia en tu archivo gradle:

    implementation 'androidx.localbroadcastmanager:localbroadcastmanager:1.0.0'

Paso 2: Diseñar el diseño

Diseñe un layout con un textvew y un botón:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:gravity="center"
    android:orientation="vertical">

    <TextView
        android:id="@+id/dateText"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Initial value"
        android:textSize="20dp"
        android:textStyle="bold"/>

    <Button
        android:id="@+id/startButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:text="Start Service"/>

</LinearLayout>

Paso 3: Crear `IntentService

Creamos una clase intentservice y luego sobrescribimos el método onHandleIntent:

package info.camposha.ms_localbroadcastmanager

import android.app.IntentService
import android.content.Intent
import android.util.Log
import androidx.localbroadcastmanager.content.LocalBroadcastManager
import java.util.*

//IntentService is a ntentService is a base class for Services that handle asynchronous
// requests (expressed as Intents) on demand.
class MyIntentService : IntentService("MyIntentService") {
    override fun onHandleIntent(arg0: Intent?) {
        val intent = Intent(CUSTOM_ACTION)
        //get date to send
        intent.putExtra("DATE", Date().toString())
        Log.d(MyIntentService::class.java.simpleName, "sending broadcast")

        // send local broadcast
        //LocalBroadcastManager is a Helper to register for and send broadcasts of Intents
        // to local objects within your process.
        LocalBroadcastManager.getInstance(this).sendBroadcast(intent)
    }

    companion object {
        const val CUSTOM_ACTION = "YOUR_CUSTOM_ACTION"
    }
}

Paso 4: Crear MainActivity

Creamos nuestro lanzador activity:

package info.camposha.ms_localbroadcastmanager

import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.os.Bundle
import android.view.View
import androidx.appcompat.app.AppCompatActivity
import androidx.localbroadcastmanager.content.LocalBroadcastManager
import kotlinx.android.synthetic.main.activity_main.*

//Our main activity
class MainActivity : AppCompatActivity(), View.OnClickListener {
    //override onCreate
    public override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        startButton.setOnClickListener(this)
    }

    //when activity is paused
    override fun onPause() {
        super.onPause()
        // unregister local broadcast
        LocalBroadcastManager.getInstance(this).unregisterReceiver(mReceiver)
    }

    //when activity is resumed
    override fun onResume() {
        super.onResume()

        // register local broadcast
        val filter = IntentFilter(MyIntentService.CUSTOM_ACTION)
        LocalBroadcastManager.getInstance(this).registerReceiver(mReceiver, filter)
    }

    /**
    Create a BroadcastReceiver

     * BroadcastReceiver is a Base class for code that will receive intents sent by sendBroadcast().
     * Broadcast receiver to receive the data
     */
    private val mReceiver: BroadcastReceiver = object : BroadcastReceiver() {
        override fun onReceive(context: Context, intent: Intent) {
            val date = intent.getStringExtra("DATE")
            dateText.text = date
        }
    }

    //when user clicks the start button, start our intent service
    override fun onClick(view: View) {
        if (view.id == R.id.startButton) {
            // start intent service
            val intent = Intent(this, MyIntentService::class.java)
            startService(intent)
        }
    }
}

Paso 5: Registrar componentes

Registramos dos componentes en el archivo manifext de android:

  1. MainActivity
  2. IntentService

 <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

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

Paso 6: Ejecutar

Ejecuta el proyecto y obtendrás lo siguiente:

Android <code>LocalBroadcastManager</code> Ejemplo

Descargar código

Descarga el código aquí.

Categorizado en:

Etiquetado en: