Skip to content
This repository has been archived by the owner on Apr 29, 2024. It is now read-only.

No clean way to stop the Android foreground service in background location demo #120

Open
tuukkapuranen opened this issue Sep 8, 2021 · 1 comment

Comments

@tuukkapuranen
Copy link

Sample

https://github.com/xamarin/mobile-samples/tree/main/BackgroundLocationDemo

Description

In the background location demo, when the app is swiped away, the OnDestroy is called as expected, and this method then proceeds to clean up the foreground service. Ostensibly the service is no longer running, as indicated by the running services in the developer section of the device. However, the visual Studio debugger stays attached indicating that the app is still running, and in list of apps on the device, the force close button is enabled for the app, also indicating running. Moreover, when the app is restarted on the device, the UI subscribes a second event handler to the foreground service, resulting in duplicate events in the UI after each location change. This suggests that the service instance has not been cleaned between the app executions.

The issue is that I have not been able to determine a clean way to stop the foreground service in the sample programmatically. All the documentation and related discussion would seem to suggest that this should be possible.

Now, in principle the described behavior would be fine, as the foreground service seems to stop providing the location updates when the app is closed, thus resulting in no wasted cycles when the app is not running. However, an existing and running foreground service should be handled in the main activity OnCreate when the application starts, or we risk creating duplicate resources, or at least setting unneeded event subscriptions.

This behavior happens both on device and emulator; and is not unique to the background location demo, the same behavior is present in a similar foreground service with no actual functionality.

I have attempted to clean up the foreground service with the following methods:

  • unsubscribed -= from all events
  • unbound the service with Application.Context.UnbindService
  • deleted the notification channel with DeleteNotificationChannel on notification manager
  • called RemoveUpdates on LocationManager
  • cancelled the Task used to start the location service
  • called StopService in OnDestroy
  • called StopSelf in OnDestroy
  • called StopForeground with StopForegroundFlags.Remove and StopSelf in OnTaskRemoved (OnTaskRemoved on LocationService is being executed as expected)
  • called Dispose on all disposable objects (binder, location manager, location service) - although disposing the location service results in a NotSupportedException (Unable to activate instance from native handle) soon after the disposal, crashing the application (and finally terminating the process, but arguably not the way it should).

I may have not gotten the order of operations right, but it seems that I have exhausted most of the avenues available. Perhaps someone with more detailed knowledge of Xamarin resource management could modify the sample project in a way that cleanly shutdowns the service.

I am opening the ticket here as the sample may just be missing something, and if we are not able to find a set of steps to cleanly shutdown the foreground service, we may want to open another on xamarin-android or Xamarin.Forms.

Alternatively, if not cleaning the foreground service is ok (it still seems strange to have to terminate the debugging session manually) we should at least have an example where the OnCreate cleanly handles an existing foreground service.

Steps to Reproduce

  1. Run the background location demo from Visual Studio with debugger attached, wait for a GPS update on UI
  2. Swipe the application away
  3. Run the background location demo from the device or emulator, wait for a GPS update on UI
  4. Swipe the application away

Expected Behavior

  • Debugger stops in VS
  • Settings - Developer options - Running Services - Location.Droid: changes from "1 process and 1 service" to "Not Active"
  • Settings - Apps - Location.Droid - Force stop: changes from enabled to disabled
  • The service is created such that the main activity receives an update request per location change. This can be seen in the logs as follows:
[LocationService] Speed is 0
[LocationService] Accuracy is 61.47781
[LocationService] Bearing is 0
[MainActivity] Foreground updating
[LocationService] Latitude is ...

Actual Behavior

  • Debugger does not stop in VS
  • Settings - Developer options - Running Services - Location.Droid: changes from "1 process and 1 service" to "Not Active"
  • Settings - Apps - Location.Droid - Force stop: stays enabled
  • The service is created such that the main activity receives a multiple update requests per location change. This can be seen in the logs as follows:
[LocationService] Speed is 0
[LocationService] Accuracy is 61.47781
[LocationService] Bearing is 0
[MainActivity] Foreground updating
[MainActivity] Foreground updating
[LocationService] Latitude is ...

Information

Microsoft Visual Studio Professional 2019 Version 16.11.2 VisualStudio.16.Release/16.11.2+31624.102
Microsoft .NET Framework Version 4.8.04084
Mono Debugging for Visual Studio 16.10.15 (552afdf)
Xamarin 16.11.000.174 (d16-11@e8f56f1)
Xamarin Designer 16.11.0.17 (remotes/origin/11e0001f0b17269345e80b58fb3adf1ba4efe2cd@11e0001f0)
Xamarin Templates 16.10.5 (355b57a)
Xamarin.Android SDK 11.4.0.5 (d16-11/7776c9f)
Xamarin.Android Reference Assemblies and MSBuild support. Mono: c633fe9 Java.Interop: xamarin/java.interop/d16-11@48766c0 ProGuard: Guardsquare/proguard@912d149 SQLite: xamarin/sqlite@85460d3 Xamarin.Android Tools: xamarin/xamarin-android-tools/d16-11@683f375
Android 11.0 (R) / API 30
Xamarin.Android.Support.x 28.0.0.3 -or- Xamarin.Forms 5.0.0.2083 and Xamarin.Essentials 1.7.0
Samsung SM-T725 (Android 11.0 - API 30)

Workaround

As a workaround, per https://stackoverflow.com/a/18450763, we may use Android.OS.Process.KillProcess(Android.OS.Process.MyPid()); which does not allow a controlled cleanup of resources, but may be fine if executed as the last step on the OnDestroy of the main activity.

@Netloc1
Copy link

Netloc1 commented Nov 28, 2022

you could

  1. add a stop comms on hidden function in your declarations to eliminate background resource usage when the app is not being used but still open

  2. call a time interval subroutine as a gps background process if you are doing push notifications rather than directly through the app and have it call up the app when the geo tag is within range

  3. if you want the page to close correctly and cleanup
    (. net )
    add the handle to your page form close~hidden subroutine to include
    environment.exit(0)
    that will close the application and cleanup the resources.

Hope this Helps,
☻☻☻☻☻NETLOC☻☻☻☻☻

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants