I currently have a foreground service fetching GPS co-ordinates and sending them to an activity which calculates distance, time and speed. I want to constantly be getting this data and sending it until the user presses a stop button.
However, whilst I am using a foreground service to get the information, I'm worried my activity won't receive it, if it's been minimised and executed onPause or onStop methods.
Therefore is there a way to stop the activity from pausing or stopping. Or perhaps a better alternative would be, how to store the data in the service and send it/update once the activity has resumed?
You may push them into a Queue or something similar (maybe SQLite) and when your Activity is not paused/stopped you can just pop entries from your Queue.
You can't stop the Activity from getting paused/stopped since this is controlled by the Android framework.
So generally in cases like yours a FIFO data structure usually solves the problem.
Related
I am looking for a bit of app design advice.
I have an app that connects to the Google Location Services and tracks location coordinates it receives. These are displayed as a path on the UI.
When the screen times out and goes blank then this Activity will, of course, shut down as per the normal Activity life cycle.
However - I atill want to record the co-ordinates coming back in each onLocationChanged event from Location Services, but, of course, the Activity has paused so it cannot do that.
I don't particularly want to prevent the screen from blanking in the Manifest (and thus the Activity would never pause). Though I believe it would still pause if, say, a phone call is received etc.
My solution would be to start an IntentService in one of the Activity pausing events (either onPause, onStop or onSaveInstanceState) to receive Location updates, and then when the Activity restarts, collect the data from the Service and close the Service down.
Would this be an efficient and correct way of achieving this, or is there some Android black art that I don't know about? If so, is IntentService the correct way to go about it (or should I use Service)?
Proberly a normal service that gets restarted by an alarmmanager is an better idea.
In order to tie up loose ends, I'll add my own answer to this now I have implemented something.
My solution in the end was not an IntentService. This was because I thought that the IntentService would consider its work to be the actual setting up of the LocationService and once that work had been completed then it would shut itself down rather than hang about waiting for LocationService 'pings'.
Therefore, I implemented a normal Service, but I bound it to the calling Activity. I also set up a callback to the Activity. This way when a 'ping' was received I could process it and pass back the data directly to the Activity. Also, the Service would remain alive as long as the binding was in place. I clear the binder when the Activity is destroyed.
This worked perfectly....HOWEVER
I then discovered that the reason that the LocationService 'pings' were not being handled in the Activity was bacause I was disconnecting the GoogleAPIClient when the Activity onStop was called. Having removed this, the Activity processed the 'pings'even in its stopped state, so no Service was required anyway.
Therefore the correct answer to this question is... Activity should continue processing in the background (unless it's destroyed for memory management purposes), so check you're not stopping stuff in your 'shutdown' handlers onPause onStop etc. Then you won't waste time writing services like I did!
Let's say we have an Android app that consists of a MainActivity, and also a bound intent service (or any other background service that continues to run while MainActivity is paused).
Lets say we have some variables belonging to MainActivity, MainAcitivity.variable1, and MainActivity.variable2.
Is it safe/normal to update these variables from the background service while MainActivity is paused? I know that it works without errors, but it seems strange to me that it is possible to interact with a class/thread that is "asleep." If you send multiple updates while Main is paused, do they all end up in a buffer that gets dealt with when Main is resumed? or do the updates happen immediately?
What technical subject to these questions have to do with?
Thankyou!!
You shouldn't get used to this. simply because your Service will not be able to see your Activity's variable when the app is closed.
A very good solution is to cache the changes made by the Service in local storage, and use BroadcastReciever to update the Activity if it is running. In addition to that, the Activity should get data from the storage in the onResume() method and update the UI accordingly.
First sorry for my english.
I have a problem, and i can't find a solution, it sounds like:
i'm developping an app that's getting my location from gps and send it to a tcp server on pc , and store the data into a listview (for example). I have set a timer that send the location every 2 seconds. Everything works fine even if i connect two clients to server, until the phones gets locked .. then my server receive ugly string ..it seems like the sent-strings it straddles (the string contains parts of data from bought clients, parts are concatenated) .. but when i unlock the phones the server receive normal strings again..
I want to know how to make my app run in the same parameters when lock screen occurs .. Any ideas?
If you are doing this inside an activity or a fragment you are probably having an issue with the lifecycle of your app. If you want to understand the lifecycle, read this documentation article: http://developer.android.com/training/basics/activity-lifecycle/index.html
Doing nothing on your onPause method won't prevent your activity from sleeping, Android can kill your activity anytime.
The proper way to do this would be inside a Service, a service is a special component on Android that is executed independently of what the user is doing or not doing, and in this case, you could create a service that holds a wake lock in order to prevent it from sleeping for the couple of seconds you need to send your data.
An easier solution would be to use something like this Location polling library and suit it to your needs.
When the screen locks your activity is either paused on stopped and it is important you handle these methods so that any interuptions are handled elegantly and without error. Or so the app will continue to run in the background.
If you read up about the activity lifecycle.
During normal app use, the foreground activity is sometimes obstructed by other visual components that cause the activity to pause. For example, when a semi-transparent activity opens (such as one in the style of a dialog), the previous activity pauses. As long as the activity is still partially visible but currently not the activity in focus, it remains paused.
However, once the activity is fully-obstructed and not visible, it stops (which is discussed in the next lesson).
Activity Lifecycle from android.com
Say I have an Activity A which is running a sockets connection to server, the server will keep sending some message and A should process these message and update UI to display them. The sockets connection is running on another thread.
On A I have a button, I wish to press the button and start another activity B.
The requirement is that when user go to activity B, activity A should keep connection with the server and updating its UI. When User back from B, activity A should show up to date info as user never leave.
I did some research, one of the post suggest that using Tabhost Cheat, that put both A and B into an invisible tab host. However I check tab host, when switching tabs the activity will go to onPause state, which disconnect the socket in that activity.
Is solution to work around this? Thank you!
It might be worth taking a look at using an intentservice to do the work with the web socket and have it broadcast messages. In whatever activity you want to read/process the messages you can register a broadcast receiver to get the messages sent from the intentservice thereby ensuring that whenever for example Activity A has it;s onResume method called you could update the ui with the latest messages from the broadcast receiver or just interrogate the intentservice for the latest messages.
The advantage here is that the IntentService will run in the background without needing to any activity hanging around, you might also want to think about introducing something to cut down on the amount of web traffic by having the intentservice only poll for data when it is needing to be shown thereby reducing battery drain and potential cost to the user with using up data allowances, especially if user is on PAYG
An excellent simple example of how this might work can be found here
http://code.tutsplus.com/tutorials/android-fundamentals-intentservice-basics--mobile-6183
I'm just reading up on the use of services to keep an app alive in the background.
A few things are not quite clear to me.
1: Once a service has started, does it stay alive when the main app gets destroyed by Android? (I know it does with OnPause() and OnStop() )
2: If anything is declared in memory for the service, is there a way to access this as well from my app?? (EG service just records the GPS to see if you're moving or standing still. from the main app I want to see how much of each is recorded while the main app was inactive)
I know these are fairly general questions, I'm just reading up on this part of Android programming, and would like to modify a program in the near future. So I have no code to go with the question yet
Thanks,
BBBwex
Once a service has started, does it stay alive when the main app gets destroyed by Android?
An app does not get destroyed. Activities get destroyed. Apps have their process terminated.
A service will run in the process until:
there are no more bound connections (i.e., via bindService()) and
if the service was started with startService(), it was stopped with stopService() or stopSelf()
Of course, once the process is terminated, the service (and everything else) is gone.
If anything is declared in memory for the service, is there a way to access this as well from my app?
Your service is part of your app. I am going to assume here that by "app" you mean "activity".
Your service has any number of ways of publishing information in ways that an activity can monitor and use, including:
Service writes the data to a ContentProvider, which updates the activity via a Loader or ContentObserver
Service sends messages to the activity, via LocalBroadcastManager, a third-party message bus like Otto, a Messenger tied to a Handler, etc.
Service stores a cache of data in a static data member, which the activity reads (or perhaps polls)
The activity simply reads the data out of whatever persistent data store the service uses (e.g., SharedPreferences) as needed
Etc.