I have built an application that listen to call state changes, and I want to notify a service when the call_state became IDLE.
All the components I have are functional, I just need to notify (not start) a service for this.
What's the correct practice, maybe using AIDL?
Because, in a PhoneStateListener, I can't bind to a service. Do I have to start an activity for that?
I'd think you'd be better off sending your service a broadcast intent than trying to bind to it.
When you want to notify your service you will need to call though to its process via AIDL.
Related
I am developing an application in android studio, and I have to save the location of the device, I did a "locationService" class that extends service, so the location is segmented on my server and the service would be in the background.
I have read the android documentation and there are two types of service (service and linked service), I use the linked service because I need to show the location data in an activity.
The problem is when I close the application, the service dies and does not record the change of location.
How can I prevent the linked service from dying. Thank you
I assume you mean a "bound" Service, not a "linked" Service. A bound Service will stop running when the last client disconnects from it. To prevent this, you need to call startService() and make sure that you return START_STICKY from onStartCommand() in your Service.
You don't need to use a "bound" Service in order to pass data from the Service to an Activity. Another way is to have your Service broadcast the data (by adding the data as an "extra" to an Intent and calling sendBroadcast() with the Intent). Your Activity can then set up a BroadcastReceiver to listen for any data braodcast by your Service.
Is it possible to make an activity and a service communicate, using the Observer design pattern?
I want to make them communicate both ways by giving them both the role as Observer and Notifier
The reason why I want to do this, is that I want low coupling between them. So if the activity crashes for some reason, the service will still be running and still trying to notify the GUI without crashing.
The reason I want the service to remain running, is that it acts like a server in a LAN and I still want the system and the clients to communicate even when the GUI of the server is gone.
If this can't be achieved using the Observer pattern or is too complex, is there another way to achieve what I described above?
Thanks in advance
You can run the service as foreground if your are using notification . so when the activity exit the service can update with the notification or remote views.
Also , When you start the activity you can bind the service from the activity to communicate using service connection.
bindService(new Intent(this,
YourService.class), mConnection, Context.BIND_AUTO_CREATE);
A started service can use the startForeground(int, Notification) API to put the service in a foreground state, where the system considers it to be something the user is actively aware of and thus not a candidate for killing when low on memory. (It is still theoretically possible for the service to be killed under extreme memory pressure from the current foreground application, but in practice this should not be a concern.)
check the link - http://developer.android.com/reference/android/app/Service.html
http://developer.android.com/guide/components/bound-services.html
You could have a communication from Activity to Service with a usual Binder. The Service can inform the Activity about changes with a Callback, which you can register in onServiceConnected() and unregister in the Activities onPause().
With this you have a two way communication between Service and Activity and the implementation isn't to complex.
So if the activity crashes for some reason, the service will still be running
The thing is, Activity doesn't crash. The whole app process does. So if you want to separate Activity and a Service, you need to run them in defferent processes. Note sure about if Service is restarted after process crash, though.
Take a look here https://stackoverflow.com/a/12022185/468311, that would be a good start for you.
If this can't be achieved using the Observer pattern or is too complex
As suggested, use Binder. Or you can communicate using Intents.
But keep in mind that Service wasn't intended to be used as a forever-running piece of your app. Try avoding this. Use Service for pereodic background operations.
I have a service that downloads some data from internet and periodically sends progress to the indicator activity. In the end of processing service sends a result.
I have a question what is the best way to achieve persistence of the communication.
Messenger or ResultReceiver, I need to parcel them into Intent and store list of listeners in the service. But on configuration change activity destroys, and it's hard to maintain this list.
LocalBroadcastManager, I need to migrate from Messages to Intents, and also there is no sticky send in this class. So if I get result while my progress activity is in background result will be lost.
BroadcastManager is good, but I don't need to broadcast my progress system wide, and security issues.
Any ideas?
You may want to give Otto (http://square.github.io/otto/) a try.
In your service, whenever you want to communicate with the activity, post a new event using a shared Bus. You should do that on main thread with a handler or main looper since you are probably using IntentService. The service may act as a producer as well. When your activity is recreated, current known value will be posted.
Your activity just needs to register with the Bus and subscribes to the right event. When it is paused, just unregister with the Bus.
I belive the best way to achieve that persistance is:
After the service downloads, you should save your data in a database or a file.
The service then sends broadcast to update.
If the activity is "alive" all goes well and it goes to the database/file to get the updated content.
If the activity was killed or something, you just have to make sure the data is in the database/file so that when you start/restart the activity you can get the latest content from database/file.
While downloading keep a state and progress saved in the db/file the same way.
Check this Google I/O Session, it explains this really good.
Use static variables inside your Application class (extends Application). Inside Service you set this variables. Inside Activity you read periodically this variables.
You should use massenger to send download progress, because it is more secure and less expensive method then broadcast receiver.
I have an android class that extends a service. I can start the service with startService(intent) and stop it with stopService(intent).
But what if I need send some information to the service after I've started it?
In my case for example I need to call some methods. How can I do it?
I thought is a simple thing but I looked for it on the web without find an easy way. Do I need to use a remote service or there is something easier?
Thank in advance
or just use startService() and send an Intent with some data along. No need to be complex.
Use Broadcasts and Broadcast Receivers.
To call methods in the Service from an Activity you need to bind the Service in an Activity. Check out Bound services from the official developers guide.
If you don't want to use an Activity then resort to Nieks suggestion with Broadcasts and Broadcast Receivers.
But then again if you need to call methods in you service on a regular basis, maybe it shouldn't be a service.
Convert your service over to an IntentService and it will handel the service life cycle for you.
Each startService(intent) will represent a new "job" for the service.
If you need notification of progress or completion Use Broadcasts and Broadcast Receivers.
Does android send any kind of broadcast when a new service is started/restarted.
underlying reason is i'd like to catch whenever a background service is starting without my knowledge.
any answer to how it's possible, if it is, are appreciated.
EDIT:
I want it to work with all services, not only my own services.
If the background service is in your control then you can use onBind() method to get to know that the service is started by bindService() and same time you can use onStartCommand() method if the service is started by startService()....
That mean you want to access system service or what? or service which you have written in your android application?
if you want to control your service which you have written in your application then as above told you can control it..or if you want to start or stop service when you want then you can create broadcast receiver and write onreceive() what you want to do.