I am writing an application which needs a connected location client in all the activities. How do the manage the state of the client?
I want to call the mLocationClient.connect() only once to avoid hassle, and should be able to remove location updates / disconnect when the application stops.
How do I keep the location client connected across all activities, assuming I have connected to it in the splash screen Activity?
Another question that arises here is, when I resume the paused application (not recreation), the app won't start with the splash screen. How do I maintain the connection in this case?
Thanks in advance.
What you need is a bound service: these services only live while a client (like one of your activities) is connected to it. This allows you to have a shared state (a single connected location client) while still ensuring that you connect/disconnect appropriately.
In this situation, any location aware activity would bind to the service. When the first activity (say, your splash screen activity) binds to the service, the service would start and connect to Google Play Services. Your service's Binder would then give access to its LocationClient to any connected activities. As you move between activities, each would bind to the service in turn and be able to get the current location data and each would as they get destroyed.
When the user exits your application (i.e., the last activity is destroyed), then the service would automatically stop itself, allowing you to disconnect from Google Play Services.
As long as you bind to the service from every activity that needs location data, it doesn't matter which activity starts the service initially: the service would just connect if needed.
Related
I am developing an application in Android that connects to a Bluetooth device. On occasion, an alarm created by the alarm manager goes off and is supposed to send information to the connected Bluetooth device. My question is, what is the best way to make this connection so that I can communicate with the device when the activity has been stopped (app is closed). I have read about intent services, foreground services, remote messenger services, and have not found any source that says the best way to make a service that won't end when the application is closed to host Bluetooth.
create your service class extend service and bluetoothadapter init in yourservice oncreate()
Foreground Service
First of all I suggest using a foreground service.
The service runs indefinitely and the app will be recreated each time it is killed (by user or by system).
In addition foreground services are also excluded from Oreos background execution limits.
Check out this post for a detailed description and test of Android service's lifecycle. Please also be aware that testing the lifecycle of services can be quite a struggle. Debugging tools usually loose connection to a service once the app is swiped off of recent used apps list or killed otherwise.
Service lifecycle
Once you set up the foreground service you should make use of service's lifecycle hooks as pointed out by Yongho to keep a reference to peripherals.
For example you could create and assign BluetoothScannerCallback to an instance variable in OnCreate() like so:
OnCreate() {
_scannerCallback = CreateScannerCallback();
}
This way you'll be notified about connection losses. Also use Androids Bluetooth Default Adapter inside the service in order to keep connections to Bluetooth devices alive when the host application is moved to background or killed (and recreated).
You should also deinitialize all references in OnDestroy().
I'm in the middle of building an Android version of my iOS app and could use some guidance as to how to implement certain features.
The app has several responsibilities; monitoring location changes and adding them to a DB, advertising and discovering available peers via Bonjour, maintaining connections to discovered peers and to a server, and advertising and listening for nearby peers via Bluetooth LE.
To organize them, I created 'Manager' singleton classes for each responsibility (e.g. LocationManager, BonjourManager, etc..) I start them when the app starts and stop them when the app terminates.
Obviously, I don't want them running in the background when the user is not interacting with the app. In iOS this was simple enough; each manager registers itself for lifecycle notifications, pausing on appDidEnterBackground and resuming on appDidEnterForeground.
My question is: How can I 'manage' these managers in Android so that they stop running when the app in not visible to the user and resume when the app is opened again? As far as I know, there is no global onPause and onResume which get called when the app switches between background and foreground.
I looked into using BoundServices but then I would need a binding between every activity and every manager so that the managers aren't destroyed until all activities unbound?
Help! I have a feeling that managers maybe aren't the right way to keep these activities alive...
Maybe this can help http://www.stackoverflow.com/questions/20912229/…
Something with keeping track of the onStart etc. count.
Init your services in Application class.
Termination is handled "by the system"...
public void onTerminate ()
This method is for use in emulated process environments. It will never be called on a production Android device, where processes are removed by simply killing them; no user code (including this callback) is executed when doing so.
I read the Last Safe Method to be called before killing the application in Android is OnPause.
Suppose I have client running on Android that is a part of location based Client/Server application. I have some design issues:
When I create the main activity I though it is logicall to start a service that connects to the server (running on my computer) and updating it in with the user location.
Now, when the application is active I want to present the user some information. Even if the user paused the activity I want the service keep running in the background and update the server. I also want the server to know when user disconnected.
Now because OnPause is the last safe method guaranteed to be called by the system, I don't know where it's best to notify the server of user disconnection.
I am developing an application where I am streaming live sensor data via bluetooth, then have several Activities that can work on this live stream of data to display it in different ways (e.g. statistics, histogram, trend charts etc.)
I need to maintain the bluetooth link across Activities, and I also need to maintain receiving the data into a buffer across Activities (e.g. you can be viewing the data in the trend chart activity, then hop across into a statistics Activity without it clearing the data.)
How I've done it is to extend application and have it hold a custom class which holds all the relevant Bluetooth objects (bluetooth device, IOstreams.) Then when the user initiates the connection through the front page Activity, the bluetooth connection is opened and a service is started that reads the data from the input stream, converts it and stores it into a arraylist. Then any of the display Activities work on this ArrayList.
That works great. But I can't work out how to close the bluetooth connection and service when the application is either killed, or placed into the background. As it's important to ensure the bluetooth connection is closed properly, or else it can be difficult to re-establish a connection.
About the best I've come up with so far is to implement a task transition timer as described in this post https://stackoverflow.com/a/15573121/3015368, and have it close the connection and service if the timer completes.
I was hoping there might be a better way of doing this?
you can stop services by making an intent which points to ur service class and call this function if your service is running it kills it if its not running then it wont do anything
stopService(/* intent name*/)
u can do that in onPause() method which is automatically called when ur app goes to the background
then if you need to restart the service u can call onResume() which is also automatically called when ur app gains focus
hence: u need to override onPause() and onResume() methods.
I start an activity in my class Locator.java which starts a locacionListener Service. That activity writes positions to a database. I wonder if when i move to next screens(activities), positions will keep writing to the database, or I would need to go back to Locator.java to keep writting. The same when I minimize the application.
I have thouhgt about using a Service, but I want to be sure I need it.
As long as the service is started, and providing sufficient resources are available on the device, the service will continue to run in the background. Switching activities, minimizing or closing the app doesn't change that. It's up to you to formally stop the service.
The business logic for capturing location updates and storing them in the database should be implemented in the service however, and not in the activity. (The activity can be used to control the state of the service (stop-start), and to display data from the database, but the bulk of your location update / storing in database logic should be triggered from the service.
You can check the running services on your android device (Settings - Applications - Running Services). You should see your service, and the amount of time it has been running.
Depending on your requirements, a simple service will not cut it. If you for example you also want to capture location updates and store them in a database while the device is sleeping, you'll need to look at WakefullintentService