i used the google simple code to "Creating and Monitoring Geofences" and every thing works fine but i have one problem that when the device lost gps signal for second the trigger event will count this as exit , and when signal back will count as enter
even it's still inside Geofence ,i guess i can't avoid this situation
so did any one know if this behavior can be suppressed?
also An additional questions, i read alot in stackoverflow geofence problems that using a BroadcastReceiver better than Service to receive the transitions
right now i use service to receive and it's work fine , Is it necessary change it to BroadcastReceiver ?
This is an issue with Google Geofence relying on bad network location points at times. I have a potential solution for this here. It's not 100%, but it does help suppress the geofence jumps.
As for the second part of your question, I don't know if you mean the IntentService or just a Service. If it is a Service, I would recommend using an IntentService or BroadcastReceiver. IntentServices are mostly used for performing tasks on a background thread, where BroadcastReceivers are meant to restart the process (if it wasn't force killed by the user), and perform a quick task to handle the intent. Both of those are self contained, and destroy themselves right after the task is done. But to answer your question, no, you don't have to use a BroadcastReceiver, but it is better practice to do so.
Related
I would like to know, I have an Activity that receives broadcasts from an IntentService that needs to save data and then export it to a CSV file. However, this can take longer than 10 seconds, and I know there are certain problems with starting AsyncTasks and Threads using BroadcastReceivers that they might get killed after 10 seconds. I would like to know, how would I overcome this?
EDIT: Note that what I am actually doing is saving data from sensors, calculating data, and then exporting. Apparently when the app is in the stopped state when receiving the save command from the other app, the app gets stuck in the calculation state. The save and export use AsyncTasks, but the calculation uses a Thread where I send a message back to the Activity using a Handler. Does anyone know how I would get around this? I used PendingResult in the saving portion, but now it gets stuck in the calculation portion.
Have it launch a Service to do the work, rather than doing it in the Receiver itself.
Here are different approaches to save data in background.
Android background processing
It really depends upon your requirements. If exporting to csv can tolerate a little bit delay, use WorkManager as its battery friendly and automatically uses best approach depending upon API level.
Use foreground service, if you want immediate high priority background execution and you also wanna notify user because foreground services are visible to users via a non-dismissible notification in the notification tray. For example, WhatsApp attachment uploading.
If it is not a very long running background task and you don't expect user to close the app during this, you can use any background execution approach like ASyncTask, Rxjava, kotlin Coroutines.
background execution evolution. A very interesting article to read and compare these different approaches.
I figured out a solution. As suggested, I used a foreground service, however, there was an issue with my callback to my activity in my background thread that was started by the service that the callback interface was null when the app was paused. I was able to fix that.
Thank you for your help.
Hello all i want location updates when my app is triggered first and after even it is killed i want my service to run i tried broadcast receiver for this purpose but it run on phone reboot Can anybody guide me to the right direction? Thanks
depending on the layout of your code, I believe it might be as easy as making the app perform the location update request on onResume while leaving onPause blank to test if it works for what you want. At least if I understood you correctly, that's what worked for me but it might drain your battery if you are using some power demanding location provider like GPS. And about your service to survive reboot I'm not really acquainted on that topic but from a quick read, indeed using broadcast receiver and listening for BOOT_COMPLETED to set off an intent.setAction declared after onCreate on your MainActivity should do it, but haven't tested that myself yet. Anyhow, it would be best if you can post the code you're working with so that others can see exactly what you have so far and be more helpful.
Hope it helps
my knowledge of services in any operating system, is that they usually run in the background and perform whatever work they have to do.
but the first time I got familiarized with android services, I got confused.
it appears they only run when the application is working, and that for me, makes them no more then sophisticated threads.
do I have this all wrong? how do I make a service that runs when the application doesn't? (so that I can check for updates and create notifications for the user that will then lead him to the application if he chooses to open them).
does push notifications have anything to do with it?
Edit:
thank you guys for your answers so far.
my problem seems to be the fact that the service is only started officialy when the device is booted up. I do call startService when the app starts, but that doesn't seem to help. the service still dies when the app is turned off (unless it was booted)
also I never call stopService
If you are trying to implement a long running task that is performed in a (background) service, you have to start one or more threads within your service. So the service just gives you the opportunity to have an application context without having to have a user interface ;) you can consider it as a kind of container.
This page give you a nice overview about different thread approaches in Android. As you can see a service has not its own thread.
Anyway, in your case it seems that an AlarmManager is probably the better option. Running services for polling information all the time can be quite CPU and battery consuming (see this post for instance). So try to avoid having threads that run all the time.
If you can push information about updates from a server it's just fine. Check out Googles Cloud Messaging in this case.
Michael who commented on my question first was right in his comment about startService()
so it goes like this:
my receiver is only activated on boot, and uses an AlarmManager to
time the service to certain intervals.
what I did was to bind the activities to the service. if the service
was off and I binded it and unbinded it, then by the time the app was
terminated, there was nothing keeping it alive.
by simply making sure that the service was started properly with
startService if it is not already on, I managed to keep the service
alive at all times
also thanks to Trinimon who gave a very nice explanation on what
services are, and the importance of not overloading the CPU with
excessive polling. (which is kind of a trade off situation)
good luck to all :)
this scenario is very common according to the Android documentation but still I don't find a straight solution neither there nor anywhere on the net.
So I have a service that should do something like this:
Register a LocationListener to receive the user location
Once the LocationListener is called - stop listening for a 5 minutes
After 5 minutes start listening again and loop from 1
This is the recommended way to save battery power while listening for the user location.
As a service I have a major problem with step 3.
The only way I found to "wait" for 5 minutes is to schedule a java.util.Timer to execute a TimerTask in 5 minutes and this TimerTask should register the LocationListneres again.
However this does not work because of:
java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
Which is also expected because requestLocationUpdates should be called from a "main" thread.
Ok .. nice... but I don't have a Main thread. I don't have an activity. From the TimerTask I can't send an intent to the service to register my listeners back.
How can I ask my own service to register my listeners again?
This is the recommended way to save battery power while listening for the user location.
Really? The only way that's a good pattern is if you are using AlarmManager for the five-minute delay, so the device falls asleep in between location checks.
The only way I found to "wait" for 5 minutes is to schedule a java.util.Timer to execute a TimerTask in 5 minutes and this TimerTask should register the LocationListneres again.
And that would be a horrible use of battery, because it would mean you would need to keep the device powered on constantly, not allowing it to go to sleep.
I don't have a Main thread
Yes, you do. All processes have a main application thread. onCreate(), onStartCommand(), etc. of a service are called on the main application thread.
I don't have an activity.
Then you better write one, as your app will not work on Android 3.1+ without it. Your app will not run until a user launches one of your activities on Android 3.1+.
How can I ask my own service to register my listeners again?
What you are trying to accomplish is a rather complex problem. Not only do you need to arrange for the device to fall asleep and wake back up again, but you also need to deal with lots of edge cases (e.g., what if no location is available, because the device is in airplane mode or is underground or something?).
I wrote LocationPoller to handle your use case, and another developer forked it to create a more feature-rich implementation.
Whether you use one of these directly or simply examine their implementation, they should be useful to help you understand how to solve this problem. All of the details, though, are well beyond the scope of a StackOverflow answer -- it would take several pages in a book to explain it all.
You can specify the parameter in requeestLocationUpdates() to make it run after a certain time.
I want to update the location every 5 mins till the lifecycle of the application. I know how to update the location. What I want to know is whether the requestForLocation is a blocking call or not.
I can do this in Service class but Service is run on main thread only and also Service can be stopped by the system anytime. I do not want this to happen. The location update should work till the application is in memory. If the application itself is killed then obviously the Service also gets killed.
What should be the approach for implementing this?
What I want to know is whether the requestForLocation is a blocking call or not.
There is no method named requestForLocation() or requestForLocationUpdates() in Android. If you mean requestLocationUpdates(), this is not a blocking call.
I do not want this to happen.
Users and the OS have the right to terminate your service whenever they wish. In this case, it's a good thing, because your proposed plan wastes RAM for no benefit.
What should be the approach for implementing this?
Use AlarmManager and a service akin to my LocationPoller, so you can get your location data, do something with it, and shut down until the next period comes around.
Also, please allow your users to configure the polling period, including an option for "do not poll".
For some reason this requestLocationUpdates() call is really blocking, at least in the phone brands that I tested. The way to fix it is to use one of its overloads. Please see this answer in another post.