Sunday, July 17, 2016

Android LocalBroadcastManager Example

Using broadcasts in Android applications sometimes introduce problems as broadcasts can be received by the other applications too. To prevent these problems Android system has LocalBroadcastManager that can be used to implement secure communication mechanism within app components.

This example shows how to use LocalBroadcastManager to send and receive broadcasts. Though this application has only one activity it can LocalBroadcastManager is capable doing more than that. For example It can be used to send broadcasts from service to another activity, from One BroadcastReceiver to activity like use cases.

The app which is developed for demonstration has one EditText and Button. When user type something on EditText and click the Button typed content send to BroadcastReceiver that has been registered by using LocalBroadcastManager. After it received that Text it shows as a Toast.


Above image shows what this application does. Implementation of this application is on MainActivity class which is shown below.

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

public class MainActivity extends AppCompatActivity {

    private final String TEXT_SENT_ACTION =  
       "com.blogspot.nipunswritings.bcsender.action.TEXT_SENT";
    private final String TEXT_EXTRA 
       "com.blogspot.nipunswritings.bcsender.extra.TEXT";

    private BroadcastReceiver textSentReceier = new BroadcastReceiver() {
        @Override        public void onReceive(Context context, Intent intent) {
            String textExtra = intent.getStringExtra(TEXT_EXTRA);
            Toast.makeText(context, textExtra, Toast.LENGTH_LONG).show();
        }
    };

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

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

        IntentFilter textSentIntentFilter = new IntentFilter(TEXT_SENT_ACTION);
        LocalBroadcastManager
                .getInstance(MainActivity.this)
                .registerReceiver(textSentReceier, textSentIntentFilter);
    }

    @Override    protected void onPause() {
        LocalBroadcastManager.getInstance(MainActivity.this)
            .unregisterReceiver(textSentReceier);

        super.onPause();

    }

    public void sendLocalTestBc(View view) {
        EditText sendingTextEt = (EditText) findViewById(R.id.activity_main_sent_text_et);
        String sendingText = sendingTextEt.getText().toString();

        Intent textSentIntent = new Intent(TEXT_SENT_ACTION);
        textSentIntent.putExtra(TEXT_EXTRA, sendingText);
        LocalBroadcastManager.getInstance(MainActivity.this).sendBroadcast(textSentIntent);
    }
}


As Broadcasts and associated data are needed to be identified at the beginning of above class unique identifiers for above class has been defined like this.

    private final String TEXT_SENT_ACTION =  
       "com.blogspot.nipunswritings.bcsender.action.TEXT_SENT";
    private final String TEXT_EXTRA 
       "com.blogspot.nipunswritings.bcsender.extra.TEXT";

Receive Local Broadcasts 
To receive broadcasts this activity must have a BroadcastReceiver implementation, that is shown below.

    private BroadcastReceiver textSentReceier = new BroadcastReceiver() {
        @Override        public void onReceive(Context context, Intent intent) {
            String textExtra = intent.getStringExtra(TEXT_EXTRA);
            Toast.makeText(context, textExtra, Toast.LENGTH_LONG).show();
        }
    };

Register Receiver with LocalBroadcastManager
In the onResume() IntentFilter is created to register receiver for designated action. IntentFilter constructor take that action as the parameter so it can receive broadcasts with this action.  
Next line is about registering receiver for the IntentFilter by using LocalBroadcastManager and registerReceiver(). After that receiver has ability to get broadcasts with TEXT_SENT_ACTION.
    @Override    protected void onResume() {
        super.onResume();

        IntentFilter textSentIntentFilter = new IntentFilter(TEXT_SENT_ACTION);
        LocalBroadcastManager
                .getInstance(MainActivity.this)
                .registerReceiver(textSentReceier, textSentIntentFilter);
    }

Unregister Receiver with LocalBroadcastManager
    @Override    protected void onPause() {
        LocalBroadcastManager.getInstance(MainActivity.this)
            .unregisterReceiver(textSentReceier);

        super.onPause();

    }

All registered BroadcastReceivers must be unregistered so it has done in onPause() by using unregisterReceiver() and LocalBroadcastManager.

Sending LocalBroadCasts

    public void sendLocalTestBc(View view) {
        EditText sendingTextEt = (EditText) findViewById(R.id.activity_main_sent_text_et);
        String sendingText = sendingTextEt.getText().toString();

        Intent textSentIntent = new Intent(TEXT_SENT_ACTION);
        textSentIntent.putExtra(TEXT_EXTRA, sendingText);
        LocalBroadcastManager.getInstance(MainActivity.this).sendBroadcast(textSentIntent);
    }

Above method is onClick method of the button. When user touch that button a Intent is crated with previously defined action and data key. After that it is sent with sendBroadcast() and LocalBroadcastManager.

References:
  • https://developer.android.com/reference/android/support/v4/content/LocalBroadcastManager.html