So i have a class that listens to incoming calls, i want to make a service to all my app to receive calls even when i'm not in the application's UI.
How to trigger this class(broadcast receiver). I used "sendBroadcast" and have a FC.
sendBroadcast(new Intent(context, IncomingCallReceiver.class));
Thank you for your help.
In your case I would use the following approach:
Create Service and start it from your Activity (you mentioned that you have several applications, so starting first of them may also start the Service).
Make sure that Service does not work forever, so stop the service when you do not need it any more (last of your applications is finished). Service may terminate self even without Activity by calling stopSelf(). Please note that also System may terminate your Service and prevent it from working forever.
Make private class within Service that extends BroadcastReceiver and register it for the Intents you want to monitor using Service function registerReceiver().
Once you receive wanted Intent, you can call some Service function from within BroadcastReceiver onReceive(). For example, you may sendBroadcast() using some custom Intent that is recognized by your applications.
When Service is stopped make sure that you un-register the BroadcastReceiver extension using Service function unregisterReceiver().
UPDATE:
Service building guidelines
SDK example that illustrates BroadcastReceiver extension usage within Activity. All important related to register/unregister is the same if you do that within Service: android-sdk-windows\samples\android-8\Home\src\com\example\android\home\Home.java
Start Activity from Service
Handle the case of Activity already running in the background
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.
I have an application that makes async HTTP requests from various places (app activities and a background service). I'd like to catch response events inside my main activity and modify some views. This is achieved by using anonymous class BroadcastReceiver inside the main activity. The registering/unregistering of the broadcast receiver is inside onResume()/onPause().
The problem is that when screen is off and the activity is not in the foreground the events aren't caught, because the receiver is unregistered. How to catch all events even in background while preserving register/unregister coherency of BroadcastReceiver?
Your best bet here would be to start a persistent background service (with a local broadcast receiver).
Here are some starting points:
Your service's onStartCommand() should return START_STICKY, so
it's not killed by the OS.
You should create a local variable inside
the Service that holds your broadcast receiver and register this
receiver in onStart() and unregister it in onDestroy().
Start the
service whenever you find suitable (e.g. onCreate() of the
Application, since it's only called once per application life-cycle
and is not tied to a specific Activity).
This answer might help.
Your existing approach doesn't work because when the screen is turned off, the onPause signal is sent to all your activities and they automatically unregister the local broadcast receiver (and they should be).
There two alternatives
Have a service running and register the receiver there instead.
You can register the broadcast receiver in the manifest and handle it there. Please keep in mind that the receiver will run on the main thread, so you should signal to a running service perhaps a service that performs a single task.
A service that performs a single task can be implemented using IntentService. It is kind of like an async task wrapped in a service.
I solved the problem by adding EventBus lib. The handler is implemented inside the main activity, activity subscribes for events on onCreate() and unsubscribes on onDestroy(). Since EventBus lib is built on standard Java components I expect the garbage collector to automatically clean up everything even if onDestroy() is not called.
Futhermore I used WeakReference for my views which allows to check if an activity is already disposed to prevent unexpected errors.
This may be not the best solution, but it works for now and much easier to implement than other proposed answers.
I'm following this basic tutorial:
http://karanbalkar.com/2013/07/tutorial-41-using-alarmmanager-and-broadcastreceiver-in-android/
As you can see, it basically does the following (correct me if i'm wrong, please):
Once MainActivity is launched, sets an Alarm for a specific date and time.
As soon as this date and time is reached, it starts an intent to MyReceiver.class
First stop.: MyReceiver is extending BroadcastReceiver. Is it possible to start an Intent to a normal Activity?
BroadcastReceiver just triggers a new Intent to open a Service, which just shows a Notification.
Second stop.: Same as before: BroadcastReceiver, can only launch Intents which are Services? Or can it launch normal activities? Why do I even have to call any new intent? Why can't I just do the job in BroadcastReceiver (like downloading some content over internet)?
I'm a bit new about Services, so I'm sorry if I said something extremly weird.
Thank you so much.
Why can't I just do the job in BroadcastReceiver (like downloading
some content over internet)?
As per Android Documentation Broadcast receivers onReceive method is called on Main Thread so you can not perform downloading task in onReceive.Since it will freeze the UI and may throw exception in 3.0 and above version.
If you want to perform download,then the best bet would be to trigger IntentService inside onReceive ( IntentService by default runs on background thread.)
BroadcastReceiver is just a means to do anything you want upon receiving a broadcast.
A Service is something that won't easily be killed by the Android OS unlike an Activity. Service has no GUI though.
BroadcastReceivers can launch anything you want (Activities, Services) with an intent.
The reason you dont want to stuff in a BroadcastReceiver is because they only live so long where as a service runs until you tell it to stop.
If you are doing polling or something you really dont need a BroadcastReceiver and you can just use a service (IntentService specifically) with your alarm manager. An IntentService only runs a long as it has something to do meaning it will stop itself unlike a normal service where you have to stop it when its done.
I have a service which I know is already running, how does my activity communicate with it without restarting the service.
to elaborate, I have a widget which starts a service, upon click an activity gets loaded, in that scenario the service should still be running.
How do I do something along the lines of:
conditionally checking if the service is alive
accessing methods in the service
Basically, the main thing I do not want to do is run startService(new Intent(...)) within my activity. I don't want to run onStart again within my service.
Ideally I can just add some methods within my service class, and call those within my activity, like I would call any other public method in the project.
I want to start some new threads within my service, and I don't want to make a second service class if I don't have to.
Thanks for the insight
The documentation on startService() might help:
Request that a given application service be started. The Intent can either contain the complete class name of a specific service implementation to start, or an abstract definition through the action and other fields of the kind of service to start. If this service is not already running, it will be instantiated and started (creating a process for it if needed); if it is running then it remains running.
...
Returns
If the service is being started or is already running, the ComponentName of the actual service that was started is returned; else if the service does not exist null is returned.
So if your Service is already running, startService() won't start a new version.
I read some similar questions (for example at this link), but the problem I'm asking is a bit different. In fact, in my case the service is started manually by the startService method, then as a consequence it can not be started using the bindService method.
Suppose we have a package that contains the MainService service and MainServiceActivity activity. In the file "AndroidManifest.xml" this activity is declared with action MAIN and category LAUNCHER. This activity is used to configure the service via the SharedPreferences and start the service by invoking startService method. In other words, typically the user launches the MainServiceActivity and configures/starts the MainService.
Now consider another activity (Let's call it SecondActivity) that is part of another package. Depending on the configuration, the service starts this activity using the startActivity method, so this other activity is running on a separate process than the MainService. As soon as the activity is running, it should inform the service.
At this point, a communication request/reply begins between the MainService and the SecondActivity: the service sends a request and the activity sends a reply.
The communication via messaging might fit, but the MainService is started through startService method, so the bindService method can not be invoked by activities that want to bind to the service.
Then I had an idea that makes use of an additional service (Let's call it UtilityService), which is part of the same package of MainService: the UtilityService could be started using the bindService method. As a consequence:
as soon as the MainService is running, it might perform the bind to the UtilityService;
when the MainService launches an external activity (for example the above SecondActivity), this activity bind to the UtilityService.
In this way, both the MainService and the SecondActivity are connected to the UtilityService, where the latter acts as an intermediary for communication.
Are there alternatives to this idea?
In fact, in my case the service is started manually by the startService method, then as a consequence it can not be started using the bindService method.
You can both bind and start a service, if you wish. It's a bit unusual, but it can be done.
Are there alternatives to this idea?
Binding has nothing in particular to do with services being able to communicate with activities. Using some sort of callback or listener object via binding is a possibility, but it is far from the only one.
You can:
Have the service send a broadcast Intent, to be picked up by the activity
Have the activity send a PendingIntent (e.g., via createPendingResult()) to the service in an Intent extra on the command sent via startService(), to be used by the service to send information back to the activity (or wherever the activity wants it to go, such as a broadcast)
Have the activity pass a Messenger tied to its Handler to the service in an Intent extra on the command sent via startService(), to be used by the service to send information back to the activity
All of those work perfectly well between processes, as well as within a process.
You can use Android Interface Definition Language (AIDL).
You can find an easy to use guide here