I have written BluetoothGattCallback in my activity. I also have a foreground service running to capture user location.
When I kill my app, I can see advertisement packets from Bluetooth Low Energy keeps receiving in onCharacteristicChanged.
But when I removed foreground service, as soon as I kill the app, advertisement packets from Bluetooth Low Energy stops receiving in onCharacteristicChanged (which is desired state).
How can I stop advertisement packets from Bluetooth Low Energy in onCharacteristicChanged when I kill app?
I think your definition of "kill app" really means "destroy the running activity", which is not the same thing as "killing the app process".
The Bluetooth API is completely separate from the Activity logic. Unless you actively do something to stop the notifications from arriving in your app process, and unless the Bluetooth connection geats teared down, they will keep coming until the app process is killed.
If you want the Bluetooth connection to stop when you destroy your Activity, you need to have some logic in the onDestroy method in your Activity (or in the onDestroy method of a service that your Activity is bound to) that for example makes sure the close method is called on your BluetoothGatt object.
Last thing, what you get in onCharacteristicChanged is notifications or indications. Not advertising packets. Advertising packets is what you get when you perform a scan.
Related
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.
I have an Android service which connects to a Bluetooth peripheral.
I don’t want Android to kill my service at its own discretion, as that would defeat the purpose of the app.
However, the app sometimes attempts to launch the service and connect when it just suspects the BT device might be in range—which may succeed or not. Unless the connection is successful, I don’t want to bother users with the notification which would be shown when the service becomes a foreground service. (The user can enable or disable this feature, thus it’s not about doing things behind the user’s back.)
I therefore considered delaying the call to startForeground() until the Bluetooth connection is complete. Brief description in prose (as code would be lengthy):
MyService#onStartCommand() creates an AsyncTask and launches it (it will run in a background thread, to keep the lengthy Bluetooth connection setup off the UI thread).
AsyncTask#run() sets up the Bluetooth connection.
AsyncTask#onPostExecute() (which runs on the UI thread after run() finishes) verifies we’re connected, and if so, calls startForeground(), creating the notification.
However, after onStartCommand() returns there is a short timeframe in which the service is still a background service.
Is there any risk of Android killing my service in that brief time to reclaim memory (when it would leave a foreground service alone)?
If so, does Android take the time elapsed since the service was started into account (killing the longest-running services first)?
Consider there is 1 service and 2 Activity.
Activity 1 is for connecting to the bluetooth device.
Activity 2 is for getting the data from the BLE Device
I have implemented both the connection and data read part Using Service because there is a need to collect data from BLE device even when the app is in background mode.
So how can I use the service to make connection during the Activity 1 and use the same service from Activity 2 for collecting the data with the same connection.
You need to make sure that your Service runs until you explicitly shut it down. Return START_STICKY from onStartCommand() and your Service will stay running even if the client Activity unbinds. Make sure that you have some way to shut the Service down (using stopService() or stopSelf() when you are done with it.
I haven't worked on a bluetooth service.But I guess you can create a bluetooth stream object in the first activity which can be shared with the second activity.Use the stream object in the second activity to do communications.
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
There is a state of my app in which it does nothing but scanning wifi (actually wifiP2pManager.discoverPeers). In that state it should use minimal energy but react quickly on broadcast intents.
1) Am I right that the receiver object is created before registering programmatically and keeps loaded until unregistered as long as the app's process is not killed?
2) How can I prevent the process from being killed without wakelocks which would also harm power consumption?
3) Can CPU be stopped while wifi scanning, i.e. while WifiLock is acquired?
4) How can a WifiLock can be held when a process is killed ->2?
5) Can I register a BroadcastReceiver class which will be created just when there is an intent to handle even when the app's process was killed?
Hope this is understandable. Maybe the following outline helps a bit:
Boot or app start
loop
initiate wifi scan
loop
sleep (stop CPU and release memory if possible)
process scan event (potentially calling services and activities)
until scan complete
forever
Currently I have the feeling that I need a service in parallel to the receiver to hold reference of the receiver and keep this service running all the time, but at least without wakelocks. Is this right? Or is there a better approach?
Thanks