Skip to content
This repository was archived by the owner on Apr 29, 2024. It is now read-only.
This repository was 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

@tuukkapuranen

Description

@tuukkapuranen

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions