Reputation: 21062
In my previous question: How to keep and access data in BroadcastReceiver? I've got excellent answers, but here I focus on this.
There is BroadcastReceiver and there is Service. I would like to send some data from the receiver to service and get the data back. The party which initiates the transfer is receiver, not the service.
For the sake of the simplicity, let's say that receiver waits for SCREEN_ON and then asks service "is this a birthday of the user", and server returns true or false.
If I am not mistaken I should attach my data that goes to Service to the Intent, and call startService
, but how to get data back?
Upvotes: 0
Views: 3513
Reputation: 3441
Use a session! Save the data in a session:
@Override
public void onReceive(Context context, Intent intent)
{
SessionManager session = new SessionManager(context);
// get user data from session
HashMap<String, Object> user = session.getUserDetails();
// name
m_userId = (int)user.get(SessionManager.KEY_ID);
m_context = context;
PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "");
wl.acquire();
// Put here YOUR code.
//Toast.makeText(context, "Alarm !!!!!!!!!!", Toast.LENGTH_LONG).show(); // For example
wl.release();
}
Upvotes: 0
Reputation: 95578
You can't really do this the way you've described. @CommonsWare is correct, your chosen architecture is flawed.
BroadcastReceiver
s are short-lived. Therefore they cannot make any asynchronous calls and they cannot perform any tasks that take a "significant amount of time". Your BroadcastReceiver
gets triggered by a certain event and if you need to do any significant amount of work due to that event you will need to delegate that work to a Service
.
Normally (for example: within an Activity
), if you wanted to request information from a Service
you could either bind to the Service
and make a synchronous call to the service to request the data you want OR you could call the service asynchronously (ie: send an Intent
to it) and then listen for the returned result (using a BroadcastReceiver
). Neither of these methods works from a BroadcastReceiver
because a BroadcastReceiver
cannot bind to a Service
and it cannot make asynchronous calls.
EDIT: Copied relevant information from the Android documentation for reference here
Receiver Lifecycle
A
BroadcastReceiver
object is only valid for the duration of the call toonReceive(Context, Intent)
. Once your code returns from this function, the system considers the object to be finished and no longer active.This has important repercussions to what you can do in an
onReceive(Context, Intent)
implementation: anything that requires asynchronous operation is not available, because you will need to return from the function to handle the asynchronous operation, but at that point theBroadcastReceiver
is no longer active and thus the system is free to kill its process before the asynchronous operation completes.In particular, you may not show a dialog or bind to a service from within a
BroadcastReceiver
. For the former, you should instead use theNotificationManager
API. For the latter, you can useContext.startService()
to send a command to the service.
Upvotes: 5