Bind Service to BroadcastReceiver - android

I have some Service class, which registers multiple alarms.
In my BroadcastReceiver class, I want the onReceive() method to call some method of the Service class.
However, I don't see how I can bind them together. I tried to make the BroadcastReceiver an inner class, but then I got more errors and couldn't fire the alarm at all.
Thanks

Look at http://developer.android.com/reference/android/content/BroadcastReceiver.html life cycle. BroadcastReceiver is created only for handling a message. It means that it's life is very short, ant it is also stateless. So you cannot bind anything to it.
Anyway you can try to start a service form onReceive(Context context, Intent intent) method of BroadcastReceiver,
like this:
public void onReceive(Context context, Intent intent) {
Intent intent2 = new Intent(context, GCMService.class);
intent2.putExtras(intent);
context.startService(intent2);
}
Then a=the service should handle a broadcast message.

From the http://developer.android.com/guide/components/bound-services.html
Note: Only activities, services, and content providers can bind to a service - you cannot bind to a service from a broadcast receiver.

Related

Boot completed broadcast receiver context parameter

I am working on a service that can start at device boot completion, i am setting a preference file to store service running state so i can retrieve it when i need it, in my broadcast receiver :
public class MyServiceBootReceiver extends BroadcastReceiver {
public MyServiceBootReceiver() {super();}
#Override
public void onReceive(Context context, Intent intent) {
if(intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) {
if(MyService.isRunning(context)) //static method to get shared preferences value
context.startService(new Intent(context, MyService.class));
}
}
}
Now i am confused about the "context" parameter in onReceive() method, since the application and all its components will be destroyed when device is shutdown, which context is passed in the receiver, and wich component of my application is actually receiving it ?
Before calling your BroadcastReceiver, Android will create your app's Application context. You can actually see this happenning if you have your own class that inherits Application and put up a Log on it's onCreate.
However, the context you receive in your Receiver is restricted: it cannot call registerReceiver() or bindService().
More information about different types of contexts can be found here.

Android Best-Way to communicate with a Foreground Service

I am bit new to android. I would like to know how to communicate with a foreground started service.
So, I got a Foreground service with a notification.
This notification has a (X) button to stop the service.
The service got a Static broadcastreceiver.
public static class NotificationStopButtonHandler extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context,"Close Clicked",Toast.LENGTH_SHORT).show();
Log.i(LOG_TAG, "In Closed");
// imposible to do context.stopForground(true) or
// to call any other private coded by me
}
}
So my question is :
Is BroadcastReceiver is the best way ?
If it is : How I can communicate with the service to call stopForeground in the broadcastReceiver ?
Thanks in advance for your responses.
Same question like mien... But I would like to know which are the other solution than broadcastReceiver. thx
In your notification you will have a PendingIntent for the X button. I presume you have built that PendingIntent with
PendingIntent.getBroadcast(/* ... */);
What you can do instead is to create a PendingIntent for your service
Intent intent = /* intent for starting your service */;
intent.putExtra("STOP_FOREGROUND", true);
PendingIntent.getService(context, requestCode, intent, flags);
and in the intent you pass to the PendingIntent you would add an extra (STOP_FOREGROUND). When this intent is fired, your service will get called in onStartCommand(). Here you check the intent and if it contains your extra, you know you're expected to call stopForeground.
Instead of broadcasts, you can use PendingIntent with an Intent to the Service and tell the Service to shut down. You assign the PendingIntent to the close button action and/or to the notifications onDelete call when you build the notification.
Assuming that you're starting the Service with the notification, you can put commands in the Intent to tell the service to stop itself. Service#onStartCommand will be called on the service with the new Intent. The service checks for the shutdown call and calls stopSelf() when done.
Basically, the reason this works is because there can only be one Service started. Every subsequent attempt to start the service will send the intent to Service#onStartCommand, but it will not restart the Service. Thus, this is a way you can send commands to the service through means outside of binding. Plus it's way cleaner than using broadcasts.

Activity Listen for broadcast receiver

So I have broadcast receiver that is getting started on boot. I have an activity that using the information being collected by the broadcast receiver. I want the activity to be able to update its recycler view every time the broadcast receiver is called, the problem is the activity has no reference to the broadcast receiver. Is there a way that I can have my activity listen for the broadcasts and update itself?
The only thing I can think of is having the activity run a repeating task that will try to update itself with new information. This doesn't seem like a good solution to me.
the best approach is to register a BroadcastReceiver - see documentation on this. In your case you'd want to Programmatically register a broadcast receiver so that the onReceive(Context context, Intent intent) from inside the Activity class. In this way, you can then update the Recyclerview as you desire. Something like:
public void onCreate(Bundle savedInstanceState){
...
IntentFilter filter = new IntentFilter();
//you may want to set whatever filters here...
//define the broadcast receiver
receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
//here you can update the RecyclerView as you desire using intent's data
}
};
//register the broadcast receiver
registerReceiver(receiver, filter);
}
I strongly recommend that you go through this nice BroadcastReceiver tutorial.
Enjoy.
The broadcast receiver registered for BOOT_COMPLETED action has nothing to do with the activity, it's a separate component. So, yes, you don't have a reference to your activity and you should not run any periodical task.
What I would do is to write the collected data to the database or shared preferences and then read it when your activity is actually on the screen.
If you use an SQLite database you can use a ContentObserver to notify your activity about changes to the underlying data. This works great with loaders.
In case of shared preferences you can use a OnSharedPreferenceChangeListener registered in your activity.

How to send message/data from broadcast receiver (process1) to Service thread (process2) in android?

I am developing an android application. This application architecture is divided into 5 modules with 2 modules having multiple features. To develop this app, I am creating 2 process with multiple threads in them as required and 3 other threads. I have a some questions regarding this implementation:
Is this a good model? If not, why not? Right now I am considering only modularity.
I need to send a message from broadcast receiver in process1 to Service thread in process2, what is the best way to do it?
what is the best IPC mechanism in android? I tried to use this link, http://androidapps.org.ua/androidintro_ipc_intent.html which suggests startActivity and startActivityForResult, but these options are not available in broadcast receiver and service does not have startActivityForResult option.
Thank you.
Use Custom BroadcastReceiver
Write this in ActivityA.java
Intent intent = new Intent();
intent.putExtra("message","hi");
intent.setAction("com.android.activity.SEND_DATA");
sendBroadcast(intent);
Write this in ServiceA.java
private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
// Extract data included in the Intent
String message = intent.getStringExtra("message");
Log.d("receiver", "Got message: " + message);
}
};
Now register Receiver
LocalBroadcastManager.getInstance(mContext).registerReceiver(mMessageReceiver,
new IntentFilter("com.android.activity.SEND_DATA"));
Just create an Intent in the BroadcastReceiver, add your data as extras, can call startService() with the Intent:
Intent intent = new Intent(context, MyService.class);
intent.putExtra("message", "whatever data you need to pass to the service");
context.startService(intent);
The method onStartCommand() will be called in your service with the passed Intent.
To answer your other question "what is the best IPC method", the answer (as always) is "that depends". Using Intents is the easiest method, as it is supported for all components out-of-the-box. If you need more complicated interaction between components you can look at using AIDL which will allow you to do remote method calls in a Service. If that still isn't enough, then just implement your own socket protocol between the 2 components.
First of all, trying to understand your terminologies. By process, I presume you mean activity and "service thread", I presume you mean a service.
If you want to send a message from onReceive() broadcast receiver, running in context of Activity 1, to a service which is already active, you can try one of the below:
1) Create a new intent (service class name as the class) and call startService() with the intent. Add the additional parameters you need as intent extras. It does not matter if your service is already active, the onStartCommand() is still called, you can have special parameters as intent extras to differentiate a onStartCommand() from onReceive.
2) If your scenario allows this, consider registering to same broadcast event in both your activity and service and act appropriately (then no need to pass messages)
3) Write another broadcast receiver in your service and call sendBroadcast() from the Activity's broadcast receiver

send broadcast from Service to Activity?

I'm having a problem with sending a broadcast from a Service to an activity.
This is what I have in my Service class:
Intent intent = new Intent();
intent.setAction(BROADCAST_ACTION);
sendBroadcast(intent);
I have many Activities and in one of my activities I have this:
class MyBroadcast extends BroadcastReceiver {
#Override
public void onReceive(Context ctxt, Intent i) {
System.out.println("received");
}
};
The problem I have is that my broadcast receiver doesn't receive anything!!
Help!
EDIT:
If I have many activities how can send a broadcast message to all of them. In other words can I apply the same broadcast receiver to all the activities !?
Like others said, you need to register the activity first to receive those broadcasts (see Flo's answer)
For your other quesition (re: EDIT). If you are taking the same action, you should create an overall Activity, and have your other activities extend that activity..
Then in this super class, implement the broadcast receiver registers on onResume and un register onStop..
You have to register the broadcast receiver before it can receive anything.
Have a look at this question.

Categories

Resources