My Android app successfully detects when the network disconnects and reconnects. The app successfully stops all appropriate services and moves the app to the background (but still in the application list) upon network disconnect as desired. By the way I am using sharedprefs to save my application data and onSavedInstance for rotation refresh.
When the network is reconnected my app detects the reconnect but where I am stuck is how to properly restart my app and and all related services. I tried the low hanging fruit such as just calling onCreate(bundle) or onResume() from my network detect routine. These do not appear to initialize and restart everything needed and the app does not come back to the foreground as desired.
What is the ideal way to restart my app and bring it back to the foreground upon network reconnect?
I recognize other posts contains bits/pieces of the above but I have yet find an answer to my second question, " What is the ideal way to restart my app and bring it back to the foreground upon network reconnect? "
Related
I am currently using a foreground service to check every 30 seconds if a specific bluetooth device is in range.
When it comes in range I connect to it and read data to display to the user.
I've been reading up on background services, and even though during the actual connection it should be a foreground service, while waiting to connect it should be a background one.
so I made a different service (yes I know I could just move it into foreground when it becomes connected, but I prefer to use a different service for it) which is in the background and will continuously scan for the specific mac address, when it finds it it will start the working service which will run in the background.
I don't mind the system killing my service if it is low on memory (it is not that important, plus if the user wishes to connect they can force the connection through the ui which will start the foreground service), but I would like to make sure that when there is enough memory the service is started again, is START_STICKY enough?
In case the system destroys my service, where do I put the clean up code? will onDestroy always fire?
Finally how can I test low memory conditions for android so as to make sure the restart goes correctly?
this has been answered here please ignore it
In my app, a Service is started in the background to handle BLE communication with a BLE device. I have an Activity (StartActivity) on start of the app which searches the BLE device and when it found it, it starts the Service (BleService), hands the found Device to it and then binds to it to receive Broadcasts from BleService.
BleService establishes the BLE connection, sets notifiers on different characteristics and reads them. As it got all the information it initially needs, a Broadcast is sent.
This Broadcast causes StartActivity to switch to another Activity (MainActivity), which then binds again to BleService and reacts to BleService's Broadcasts.
So far, so good.
When I press the back button while in MainActivity, the app 'closes'. Now, when I restart the app (either by clicking on its icon or in the recent app list), the app gets back into StartActivity and can't connect to the BLE device. As the LED on my BLE device is constantly signalling me, it's connected, I think the first BleService is still running and connected to the BLE device.
I checked this by adding a Log output to BleService's onDestroy() method and yes, onDestroy() isn't called. It is called, when I close my app through the recent app list.
What should I do when closing my app through the use of the back button?
EDIT: So I want to destillate my problem out of my question:
When I close my app on pressing the back button in MainActivity and then start it through the recent app list or via its icon again, I get stuck in StartActivity. This is, because StartActivity can't find the BLE device, as it is still connected to the still running BleService.
How can I avoid this?
I am not sure what you want to have happen when "back" is pressed, but you can take a look at this answer to help you determine if the service is running or not and take appropriate action.
If your client and server code is part of the same .apk and you are binding to the service with a concrete Intent (one that specifies the exact service class), then you can simply have your service set a global variable when it is running that your client can check.
We deliberately don't have an API to check whether a service is running because, nearly without fail, when you want to do something like that you end up with race conditions in your code.
An Android Service is meant to remain running even when its parent application terminates. This is an important function to be able to execute any critical operations even when the application crashes/closes/gets killed...
For you, this simply means that you have to close your service upon quitting your app, at least if this is what you intend to do. Doing this is very simple:
stopService(new Intent(ActivityName.this, ServiceClassName.class));
If you are starting your Service via Context.startService() then it must be stopped via Context.stopService() or the service itself calling stopSelf(). Binding/unbinding to the service will only stop it if the binding was how the Service was started in the first place (e.g. not using startService()).
It always seemed some sort of black magic the way other apps keeps their services always running, but mine gets killed by the system every time.
My app should keep a TCP socket open to the server and send/receive data when it becomes available, so it has to stay always on.
This is what I have tried so far:
1) Running the service in another process using this line (also with an additional line stopWithTask):
android:process="package.name.custom_process_name"
android:stopWithTask="false"
2) Restarting the service when these methods get called:
onTaskRemoved()
onDestroy()
3) Add return START_STICKY to onStartCommand() method
4) Check if the service is still running when these events happen:
android.net.wifi.WIFI_STATE_CHANGED
android.net.conn.CONNECTIVITY_CHANGE
- Here I am stopping the socket connection to the server if the device does not have internet connection anymore and reopening it when it gets a connection.
Yet, my service always gets randomly killed (sometimes after few hours, sometimes after few days) by the system and doesn't restart automatically until I reopen the app.
How does other apps, say chat apps for example, keep their services available all the time?
P.S.: Having a persistent notification would be the least of options.
Override onDestroy() in your service, whenever your service destroys create Alarm using AlarmManager. When alarm trigger start your service again.
Second way is not recommended or proper way but create a separate service AlwaysAliveService which will do nothing but will remain available in android system.
I stop getting onCharacteristicChanged after exiting the app and restarting it.
Here are the steps I did pairing to a ble device.
I have a service that contains the ble logic and persist the bluetoothGatth obj, I perform a blueToothGatt.connect here on app launch.
Once I get onConnectionStateChange with STATE_CONNECTED, I call blueToothGatt.discover
On the onServicesDiscovered callback, I will fetch and persist the services and characteristics that I care about. Then I will call blueToothGatt.setCharacteristicNotification and write to descriptor to enable notification.
Now I perform a write and then I will get callback for onCharacteristicChange just fine.
After this, say I exit the app (device is still paired). The onDestroy of the last activity, my ble device service gets unbind...in which I will perform close on unbind callback and call selfstop to stop the service. Now if I relaunch the app. I will do the same steps 1-4, however this time around onCharacteristicChange does not get call, also I tried disconnect before close...but that didn't help
(One thing that I do notice is that if the device is left unpaired/disconnected upon relaunch then the issue occurs, however if I power of the BLE device off and turn it back on before restarting the app, then I get the callback onCharacteristicChanged just fine. This seems like the device is holding onto some setting that prevents onCharacteristics to get call.)
Any insights to this will be greatly appreciated. Thanks!
I found the solution to this. Basically the bluettooth caching the last handle, so discover services is never triggered. You will need to clear the device cache after connect.
How to programmatically force bluetooth low energy service discovery on Android without using cache
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.