1

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?

EarlGrey
  • 531
  • 7
  • 29

3 Answers3

1

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));
PKlumpp
  • 4,913
  • 8
  • 36
  • 64
  • I know that Services are meant to keep running, even if the App ends. but this is my problem. The Service keeps running and is 'blocking' the BLE device, so I have no possibility to connecto to it again, as long as this service is running. Also, I seemingly can't bind back to the still living Service after restarting the app. – EarlGrey Jun 29 '17 at 12:05
  • @EarlGrey I see your problem. What you have to do is to terminate the service in the `onDestroy()` method of your application. So whenever your app shuts down, it releases the BLE – PKlumpp Jun 30 '17 at 06:50
1

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

Larry Schiefer
  • 15,687
  • 2
  • 27
  • 33
  • Where should I call Context.stopService()? I can't call it in an Activities onDestroy(), as I'm switching between them and don't want to stop my Service when I traverse between my App's Activities. – EarlGrey Jun 29 '17 at 12:06
  • You may want to consider having your `Service` be the only thing that detects/manages the BLE devices. Your activities can then interface with it to get the latest information, etc. If you do not need your app to maintain constant connection/details of the BLE devices or operate without your activities up, you may also want to just remove the `Service` all together as it's not necessarily providing you value. – Larry Schiefer Jun 29 '17 at 12:28
  • That is nearly exactly, what I'm doing. Just the initial Scan is done by StartActivity. When my BLE Device is found, I hand the BluetoothDevice Object via the Intent, that starts the Service. Reading, Writing, handling Notifications is all done by the Service. – EarlGrey Jun 29 '17 at 12:32
  • Oh!!! Of course I can't find the Device...And I don't have to search for it, as long as my Service is running. Thank you and thanks to @Cheticamp – EarlGrey Jun 29 '17 at 12:42
1

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.

Community
  • 1
  • 1
Cheticamp
  • 61,413
  • 10
  • 78
  • 131
  • I tried this approach. BleService got a static boolean which is set to 'true', when the service is created, and set to 'false', when it is destroyed. StartScreen now checks this. If the Service is running, it binds to it. If it is not running, it starts it first and then binds to it. But it isn't working )= – EarlGrey Jun 29 '17 at 11:45
  • @EarlGrey I think that you are getting some good advice from the answers to your question. It would help if you would post the relevant code to show how you are trying to work with the service and what your processing is when "back" is pressed. – Cheticamp Jun 29 '17 at 12:20