Android BLE onCharacteristicChanged stop firing after restarting the app - android

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

Related

BluetoothGattCallback callback method onCharacteristicChanged keeps triggering even if I kill my app

I have a BLE android application and as usual I am using BluetoothGattCallback to receive data from BLE device periodically. However, even if I kill my application,onCharacteristicChanged method of BluetoothGattCallback keeps triggering and Android studio shows that app is still running.
I want that all app processes should be killed and onCharacteristicChanged should not be triggered after that.
If your app is still running then per definition it is not killed. Usually you never destroy an app process, but let the system do so when you have no running components anymore. To correctly shut down your Bluetooth connections when you are done, call close() on the BluetoothGatt objects you have. When you are "done" is up to you, but for example in an Activity's onDestroy if the connection is "bound" to an Activity.

Service doesn't stop when exiting app by press of the back button

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()).

Android - stop and restart app on network connection

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? "

How to keep android service always running?

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.

How can I resume an Android app that was running if any call came to that phone

I am working with bluetooth application. After running the app two bluetooth enabled devices are getting connected. But if in the mid time any call came then the bluetooth automatically disconnected. But it should not be like that. How can I resolve this problem?
You probably need to move your Bluetooth communication code into a Service: the only time this should happen is if your app's Activity is getting paused or destroyed when the call comes in. If you move the Bluetooth communication code into a Service then it will continue to run in the Background even when the Activity is paused or destroyed.
You can use PhoneStateListener in your Service to determine when the call ends and then relaunch your Activity.

Categories

Resources