Using a Broadcast Intent/Broadcast Receiver to Send Messages from a Service to an Activity

Using a broadcast intent/broadcast receiver to send messages from a service to an activity

EDITED Corrected code examples for registering/unregistering the BroadcastReceiver and also removed manifest declaration.

Define ReceiveMessages as an inner class within the Activity which needs to listen for messages from the Service.

Then, declare class variables such as...

ReceiveMessages myReceiver = null;
Boolean myReceiverIsRegistered = false;

In onCreate() use myReceiver = new ReceiveMessages();

Then in onResume()...

if (!myReceiverIsRegistered) {
registerReceiver(myReceiver, new IntentFilter("com.mycompany.myapp.SOME_MESSAGE"));
myReceiverIsRegistered = true;
}

...and in onPause()...

if (myReceiverIsRegistered) {
unregisterReceiver(myReceiver);
myReceiverIsRegistered = false;
}

In the Service create and broadcast the Intent...

Intent i = new Intent("com.mycompany.myapp.SOME_MESSAGE");
sendBroadcast(i);

And that's about it. Make the 'action' unique to your package / app, i.e., com.mycompany... as in my example. This helps avoiding a situation where other apps or system components might attempt to process it.

Can a Broadcast Receiver send information to an Activity only if it is active without starting a new Activity?

There are several different ways to accomplish the same task. One is registering a listener like the following example:

MainActivity

public class MainActivity extends AppCompatActivity
{
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

Receiver.setOnReceiveListener(new Receiver.OnReceiveListener() {
public void onReceive(Context Context, Intent intent)
{
//Do something.
}
});
}

@Override
protected void onDestroy()
{
super.onDestroy();
Receiver.setOnReceiveListener(null);
}
}

Receiver

public class Receiver extends BroadcastReceiver
{
private static OnReceiveListener static_listener;

public static abstract interface OnReceiveListener
{
public void onReceive(Context context, Intent intent);
}

public static void setOnReceiveListener(OnReceiveListener listener)
{
static_listener = listener;
}

@Override
public final void onReceive(Context context, Intent intent)
{
if(static_listener != null) {
static_listener.onReceive(context, intent);
}
}
}

What is the proper way to send a broadcast from an activity to a service?

is there any way to also specify the sender's packageName for the receiver's IntentFilter so that it only listens to broadcasts from inside the app?

No, sorry. However, if this is all one app, then you do not need to use registerReceiver().

Presumably, right now, in your manifest, you have a <service> element that has android:process to have the service run in a separate process from the rest of the app. You can have a <receiver> element that has the same android:process attribute, to have it run in the same process as the service. If you have the <receiver> also be android:exported="false", then only your app can send broadcasts to it. Your sending code would use an explicit Intent, identifying the specific BroadcastReceiver class.

Once you have your broadcast over to the service's process via that BroadcastReceiver, it and the service can communicate via some common process-wide singleton.

Send string from service to activity

LocalBroadcastManager is the best solution for solving this type of problem. I have implemented LocalBroadcastManager to your existing. Its very easy. Hope it will work. You code will look something like this

private BroadcastReceiver statusReceiver;
private IntentFilter mIntent;
Sensor accelerometer;
SensorManager sm;
TextView acceleration;
SendValues sv;
int counter3 = 0;
int counter5 = 0;

private static final String TAG = "MainActivity";

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

//mIntent = new IntentFilter("NOW");

// this.registerReceiver(,new IntentFilter("status"));

sm = (SensorManager) getSystemService(SENSOR_SERVICE);
sm.registerListener(this,accelerometer, SensorManager.SENSOR_DELAY_NORMAL);
accelerometer = sm.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);

acceleration = (TextView) findViewById(R.id.sensorTxt);

}

private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String type = intent.getStringExtra("message"); //get the type of message from MyGcmListenerService 1 - lock or 0 -Unlock
sm = (SensorManager) getSystemService(SENSOR_SERVICE);
accelerometer = sm.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
Log.d(TAG, "Status: " + type);
if (type == "1") // 1 == lock
{
Toast.makeText(getApplication(), "Lock", Toast.LENGTH_LONG).show();
} else {
Toast.makeText(getApplication(), "UNLOCK", Toast.LENGTH_LONG).show();
}
}
};

@Override
protected void onResume()
{
super.onResume();
//registerReceiver(statusReceiver,mIntent);
LocalBroadcastManager.getInstance(MainActivity.this).registerReceiver(broadcastReceiver, new IntentFilter("NOW"));
}

@Override
protected void onPause() {
if(mIntent != null) {
unregisterReceiver(statusReceiver);
mIntent = null;
}
super.onPause();
}

And pass your value from push notification something like this

Intent in = new Intent();
in.putExtra("TYPE",typemessage);
in.setAction("NOW");
//sendBroadcast(in);
LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(in);

Android pass message from IntentService to Activity

When registering, this was what worked for me

IntentFilter filter = new IntentFilter(ResponseReceiver.ACTION_RESP);
filter.addCategory(Intent.CATEGORY_DEFAULT);
receiver = new ResponseReceiver();

LocalBroadcastManager.getInstance(this).registerReceiver(receiver, filter);

as opposed to

registerReceiver(receiver, filter);

@Override
public void onReceive(Context context, Intent intent) {
final String text = intent.getStringExtra(RegistrationIntentService.PARAM_OUT);

button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
//access the string text and send it to backend
}
});
}

I hope this will help someone. Sending the string like suggested in the comments didn't work for me. I was getting nullpointerexception at that specific line where I assigned ma.regid = text;

send intent from service to activity

For this, you can use a BroadcastReceiver in your Activity.

Here is a great example I use to communicate continuously between Service <> Activity using BroadcastReceivers.

Here is another great example of communication between Service <> Activity. It uses Messenger and IncomingHandler.

BroadcastReceiver

I will make a quick example for your case.

This is your BroadcastReceiver for your Activity. It is going to receive your String:

//Your activity will respond to this action String
public static final String RECEIVE_JSON = "com.your.package.RECEIVE_JSON";

private BroadcastReceiver bReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if(intent.getAction().equals(RECEIVE_JSON)) {
String serviceJsonString = intent.getStringExtra("json");
//Do something with the string
}
}
};
LocalBroadcastManager bManager;

In your onCreate() of the activity

bManager = LocalBroadcastManager.getInstance(this);
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(RECEIVE_JSON);
bManager.registerReceiver(bReceiver, intentFilter);

In your onDestroy() of the activity, make sure you unregister the broadcastReceiver.

bManager.unregisterReceiver(bReceiver);

And finally, in your Service onStart(), do this:

System.out.println("intent Received");
String jsonString = rottenTomatoesSearch(intent.getStringExtra("query"));
Intent RTReturn = new Intent(YourActivity.RECEIVE_JSON);
RTReturn.putExtra("json", jsonString);
LocalBroadcastManager.getInstance(this).sendBroadcast(RTReturn);

and your Activity will receive the intent with that json in it as an extra



Related Topics



Leave a reply



Submit