Notify activity from service - android

I'm trying to start a Service from my Activity to look out for changes on a web page, it's a private app so I don't bother the battery life...
But I'd like to pass data from my Service to my Activity... I can't seem to find a way to call the Activity from my Service. How can I achieve this?

As Alex indicated, you can bind to the service and pass some sort of listener or callback to the service to use on events.
Or, you can use a broadcast Intent, perhaps using methods like setPackage() on the Intent to limit the scope of the broadcast.
Or, you can use createPendingResult() to create a PendingIntent that you pass as an Intent extra to the service -- the service can then use that PendingIntent to trigger onActivityResult() in your activity.
Or, you can use a ResultReceiver.
Or, you can use a Messenger.
(admittedly, I have not tried those latter two approaches, but I think they will work here)

One more alternative: if your service updates content provider, activity can be notified via ContentObserver. This would be enough if your service downloads some data from server and you simply want to display fresh contents in the activity.

Some ugly ways:
1.) If the activity has not started yet, then use intent and startActivity, but remember intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2.) Otherwise if the activity has started already, you can write your own callback method in the activity and register the method in the service, then direct call the method in the service.
Hope to find some smart way.
I think broadcast also work well, you can write a static inner class for receive broadcast and start activity. But it is also ugly in my opinion.

The ResultReceiver mechanism has been explained in another post :-
Restful API service
However it would not work in all cases. Please refer to my comment on that post. The limited scope broadcast or PendingIntent mechanism seem more suitable.

Related

What's the best way to make a request from an android service to an activity or service and wait for a response?

I've looked at all the IPC mechanisms in android and none seem to do what quite I'm looking for, perhaps there's a better way...
I have a service that's starting up, and it needs to get information from another service or activity in an entirely different 2nd application.
startActivityForResult is what I'm looking for, but that's not available from a service, only an activity.
I'd really prefer to get the information from the 2nd app's activity, but I'm happy to get it from the 2nd app's service.
But the part I'm really interested in, is making the synchronous call from the service and have it wait for a response.
I can send a broadcast intent from the service to the 2nd app's service, but then there's no tie back when the 2nd app's service sends a broadcast intent back with the answer I want.
Is there any way to do something like this from a service?
Is there any way to do something like this from a service?
The calls made to a Binder from a bound service are synchronous. The documentation discusses bound services, with a separate page on the AIDL you will need since the services are in different applications.
Personally, I would rewrite the first service to not need the synchronous call.

Android: pass data to a service

I'm actually working on an android app based on a background service sharing data with activities.
I was wondering If it's better to call bindService so that activities can call service's methods or if it's better to use sendBroadcast from the Activity and registerReceiver from the service.
Both work, but which one is recommended?
Furthermore, my service instanciates classes handling Localisation, sensors... Those classes also need to pass data with the service. Same question should I better use bindservice or sendBroadcast from these classes to communicate with my service?
Thanks.
If at all if you want to pass data then use BroadcastReciever because its OnRecieve method expects an Intent as arguemnt.. So you can pass your data through intent using intent.putxxxxx().. and again you will find this Advantageous when you want do some periodic checking or invoke some actions etc..

Communicate with Activity from Service (LocalService) - Android Best Practices

Common scenario - Activity with a background Service to poll server.
The Service will run periodically via AlarmManager and also perform tasks for the Activity (user hits a button, go fetch something from server).
I'd like to know the best practices here. I think the best design would be the Android LocalService example:
http://developer.android.com/reference/android/app/Service.html#LocalServiceSample
However in the example the Activity has a reference to the activity mBoundService but there is no reverse connection (the Service has no way to call the Activity).
What is the best way for the Service to call the Activity?
Do I use Intents, BroadcastReceivers, Messages? How?
I think the best design would be the Android LocalService example: http://developer.android.com/reference/android/app/Service.html#LocalServiceSample
I wouldn't. Use the loosest possible coupling you can stand. Hence, on average, aim for the command pattern with startService() instead of the binding pattern with bindService(). Notably, binding is a bit of a pain when it comes to dealing with configuration changes (e.g., screen rotations).
What is the best way for the Service to call the Activity? Do I use Intents, BroadcastReceivers, Messages? How?
See Notify activity from service
If you need tight coupling between your activity using bindService(), the way you communicate depends on who is originating the communication.
If the Service is originating (due to say an Alarm that has some new information to share), it would typically send a broadcast.
If the Activity is originating (due to say your example "go fetch something from server"), it could be handled asynchronously using AsyncTask or similar. That is, you could fetch from the server in the AsyncTask.doInBackground(), and post the results back to the activity in AsyncTask.onPostExecute. This scenario be a bit more complicated if the requested operation is expected to take a very long time - in which case I would de-couple it, and send a broadcast back from the Service instead.
As written here
When you want to communicate from service to an Activity or Fragment
which did NOT started the service or to communicate from service to multiple activities/fragments then you can use Event Bus or
Broadcast Intents since they can receive callback for an event in any
activity or fragment wherever they are implemented.If you want to
communicate from service to an activity/fragment which started the
service then you can use Pending Intent or Messenger as they can be
put into an Intent extra and passed to Service.
Pending Intent
We can use createPendingResult() which creates a new PendingIntent
object which you can hand to service to use and to send result data
back to your activity inside onActivityResult(int, int, Intent)
callback.
Event Bus
You can have the service raise events which activities or fragments
can listen for and respond to using Event Bus.
Messenger
Messenger is parcelable ,and can therefore be put into an Intent
extra,so your activity can pass this Messenger to the service.Service
will populate Message object with whatever data needs to be
send.
Broadcast Intents
Service can send a broadcast which can be responded by the activity.

How to communicate back to a service from a broadcast receiver?

Hope someone can help me out here. I will try to be concise!
I have a widget which starts a service. The service registers two broadcast receivers. I would like to send back intents from the receivers to the service, so that the service can react.
I believe I read somewhere that 'starting' the service multiple times works, e.g. do the following in the receivers:
serviceIntent.setAction("me.SERVICE");
intent.putExtra("me.SERVICE", somedata);
context.startService(serviceIntent);
I remember reading (on some blog) that this won't start a new service, but will simply pass the intent to the already running service. Is this correct? Is it a bad way of doing it? Is there a better way?
Thanks very much!
Jack
Yes, I've used that approach in a pre-2.0 app.
I accomplished this using a singleton. I set a private variable (pointing to 'this') in the service's onCreate, and then used a static method called getInstance() which would return it. So later on, I simply call MyService.getInstance() to get hold of the service.

updating an activity from an asynchronous service

I've implemented a service that does an asynchronous sync between my application and google docs. I want to update the top level activity of my application when the sync is complete. However because of the service it's possible that the app could be be in a unknown state. Is there a way to make the top level activity, whatever that may be, recreate itself from an asynchtask in a service.
In your Service, just call startActivity(new Intent(this, TopLevelActivity.class)). This will launch your TopLevelActivity if it's not already running, or call your TopLevelActivity's onNewIntent() method if it is already running, and bring it to the top. You can override onNewIntent() and capture the Intent if you want to be notified.
You should broadcast an Intent from the service and then have the Activity be a broadcast receiver.
Here is a write up on BroadcastReceiver.
Hope this helps.
The correct way to do this, I believe, is to use a Remote Interface using AIDL:
https://developer.android.com/guide/components/aidl.html
You make a simple *.aidl file with the interface in it, and the Android tools will generate the Interface class for you. It will allow you to register Callback methods. Much cleaner than tossing startActivity intents back and forth.

Categories

Resources