capacitor-community / background-geolocation

A Capacitor plugin that sends you geolocation updates, even while the app is in the background.
MIT License
187 stars 57 forks source link

Using Updated Version With @capacitor/geolocation Makes The App Crash #104

Open SumnimaS opened 1 year ago

SumnimaS commented 1 year ago

Describe the bug Hi, I'm using the official @capacitor/geolocation plugin to get the current location, and this @capacitor-community/background-geolocation plugin to get continuous location. The plugins were working completely fine side by side when using the 1.4.11 version. After updating this plugin and node modules of my project, app tends to crash the moment any function of @capacitor/geolocation is called. This only happens in Android 13+ devices.

To Reproduce Steps to reproduce the behavior:

  1. Update the plugin from 1.4.11.
  2. Delete package-lock.json and node modules in the local project.
  3. Install packages with 'npm install'.
  4. Build the android app.

Expected behavior The app to work smoothly like it did before updating the package.

Smartphone (please complete the following information):

Additional context I'm using an ionic 6.7.5 project with capacitor V4.

Any context on why this is happening would be nice. Thanks!

diachedelic commented 1 year ago

Can you provide a stack trace?

SumnimaS commented 1 year ago

Here's the stack trace: 1 2

diachedelic commented 1 year ago

I have no idea why this is happening, and unfortunately I don't have time to look into it. Please let me know if you find the problem. If all else fails, you can use this plugin for both foreground and background location updates (simply omit the backgroundMessage property to create a foreground watcher).

daniil777555 commented 8 months ago

I have no idea why this is happening, and unfortunately I don't have time to look into it. Please let me know if you find the problem. If all else fails, you can use this plugin for both foreground and background location updates (simply omit the backgroundMessage property to create a foreground watcher).

You should delete @capacitor/background-runner @capacitor/geolocation if you have them, I've had such problem, but my app couldn't build so I found out that those packeges are extra and I should get rid of them

LukasGrubis commented 2 months ago

Any update on this? We kind'a want to use @capacitor-community/background-geolocation along side with @capacitor/geolocation.

diachedelic commented 2 months ago

If you can locate the problem, I will release a fix.

LukasGrubis commented 2 months ago

When the app is moved to the background, the background geolocation watch often stops. Occasionally, it continues running, but it is unreliable. The issue appears to be associated with Android 14.

Steps to Reproduce:

Start the app and enable the background geolocation watch. Move the app to the background. Observe the behavior of the background geolocation watch. Expected Behavior:

The background geolocation watch should reliably continue to function when the app is moved to the background.

Actual Behavior:

Most of the time, the background geolocation watch stops when the app is moved to the background.

Log:

Attempted to start a foreground service (**********/com.equimaps.capacitor_background_geolocation.BackgroundGeolocationService) with a broken notification (no icon: Notification(channel=com.equimaps.capacitor_background_geolocation shortcut=null contentView=null vibrate=null sound=null defaults=0x0 flags=0x42 color=0x00000000 vis=PRIVATE))
2024-07-23 09:03:55.857 14472-14472 VRI[MainActivity] **********

Notes:

This issue seems to be more prominent on devices running Android 14. Additional testing on Android 14 devices may be required to determine reliability. Please investigate and provide any potential fixes or workarounds.

LukasGrubis commented 2 months ago

Also found this log:

2024-07-23 09:11:58.373 1691-4305 ActivityManager system_server W Foreground service started from background can not have location/camera/microphone access: service **/com.equimaps.capacitor_background_geolocation.BackgroundGeolocationService

diachedelic commented 2 months ago

Background geolocations never arrive if the notification icon is misconfigured. In your log, you have the line Attempted to start a foreground service ... with a broken notification, so make sure you have followed the instructions to the letter. Your other log line seems related to https://github.com/capacitor-community/background-geolocation/issues/117.

LukasGrubis commented 2 months ago

We've noticed that when we add the ACCESS_BACKGROUND_LOCATION permission into our AndroidManifest.xml, the app settings show the "Allow all the time" option for location permissions. Selecting this option enables the app to function correctly in the background, consistently collecting location data and sending it to our server via the Capacitor.Http plugin.

Given this setup, we are curious about the necessity of additional handling via local notifications or similar methods. Could you please provide some insights or clarification on why such additional handling might be required?

Additionally, we would like to be able to select the "Allow all the time" option right at the beginning when the plugin prompts for location permissions. Our main goal is to track users on the map while they are using our app, and we do not want to require every single user to manually go to the app settings and enable this option.

diachedelic commented 2 months ago

I've written a bit about the permissions model at https://github.com/capacitor-community/background-geolocation/issues/58#issuecomment-1101896976. Have a read and let me know if it doesn't answer your question.

LukasGrubis commented 2 months ago

Our application has a specific need for continuous background location tracking, and we have encountered some issues that we would like to clarify and seek your support on.

Our Use Case: Our users need to be tracked continuously while the app is running. We have implemented a handler within the addWatch callback that dynamically adjusts the distanceFilter to optimize battery usage. This handler cancels the previous watch and adds a new one with a recalculated distanceFilter based on user activity (e.g., walking, driving). This approach helps reduce battery drain when users keep the app open all day.

The Problem: We have observed that sometimes the location tracking works as expected in the background without the ACCESS_BACKGROUND_LOCATION permission, but sometimes it doesn't. We suspect this inconsistency is due to Android's strict rules on starting foreground services from the background. Specifically, our handler may be inadvertently killing the active watch and failing to start a new one because of these rules.

Why We Need ACCESS_BACKGROUND_LOCATION:

Dynamic Adjustment: We need to dynamically adjust the distanceFilter to handle different scenarios, such as precise locations when users are walking and broader distances when they are driving. This requires the ability to restart location watches in the background. Consistent Tracking: Without ACCESS_BACKGROUND_LOCATION, we face inconsistencies in background tracking, which undermines the reliability of our application. Battery Optimization: The dynamic adjustment is crucial for optimizing battery usage, and it relies on the ability to restart location watches based on user activity, even when the app is not in the foreground. We believe that obtaining ACCESS_BACKGROUND_LOCATION permission will resolve these issues and allow our application to function as intended, providing reliable and efficient background location tracking.

If this plugin is not built for such use cases, please let us know. We would greatly appreciate any guidance or suggestions you can provide to help us achieve consistent background location tracking. If there are alternative approaches we should consider, please let us know.

Thank you for your assistance.

diachedelic commented 2 months ago

I see. You could try starting the new watcher before stopping the previous one, that should prevent the foreground service from stopping.

The ACCESS_BACKGROUND_LOCATION permission seems too heavy handed for this plugin. Google are very stringent in their review of apps that list ACCESS_BACKGROUND_LOCATION in the manifest, because of the potential for abuse. I think you have already discovered that it is not possible to prompt the user for this permission. From what you are saying, however, the ACCESS_BACKGROUND_LOCATION makes it possible to start a foreground location service from the background.

I know of one alternative, https://github.com/transistorsoft/capacitor-background-geolocation. It is not free, but it seems to do everything you could ever want.

LukasGrubis commented 2 months ago

Thank you for your previous response. We have conducted further testing and have some additional observations and persistent issues to report:

Logs and Observations

App Foreground and Background Behavior:

When the app is in the foreground, we can start and utilize the foreground service without issues. This is confirmed by the consistent location updates received while the app is active. However, when the app transitions to the background, we experience mixed results. Initially, the foreground service is allowed to start from the background, as seen at 2024-07-24 08:54:37. But subsequently, when the app is backgrounded again, the system enforces restrictions. At 2024-07-24 08:54:49, we receive the log: Foreground service started from background can not have location/camera/microphone access.

Foreground Service Restriction:

This restriction prevents the foreground service from accessing location, camera, or microphone data, aligning with Android's privacy policies. This inconsistency is causing interruptions in our app’s functionality when it is not in the foreground.

Persistent Issues

Despite starting a new watcher before stopping the previous one, the foreground service still faces restrictions when the app is backgrounded. This approach has not resolved the issue.

The suggested use of ACCESS_BACKGROUND_LOCATION permission seems to address part of the problem. However, as you noted, Google’s stringent review process and potential for abuse make this permission less ideal for our use case.

Logs:

[app] - [2024-07-24 08:54:34] appStateChange true [geoLocation] - [2024-07-24 08:54:34] Speed in mps: 0.20945321 Speed in km/h: 0.754031556 [geoLocation] - [2024-07-24 08:54:34] Watcher update from 21525298 to 21525311 [geoLocation] - [2024-07-24 08:54:34] Speed in mps: 0.20945321 Speed in km/h: 0.754031556 [geoLocation] - [2024-07-24 08:54:34] Speed in mps: 0 Speed in km/h: 0 [geoLocation] - [2024-07-24 08:54:34] Watcher update from 21525311 to 21525337 [geoLocation] - [2024-07-24 08:54:34] Speed in mps: 0.20945321 Speed in km/h: 0.754031556 [geoLocation] - [2024-07-24 08:54:35] Watcher update from 21525337 to 21525349 [geoLocation] - [2024-07-24 08:54:35] Speed in mps: 0.23577248 Speed in km/h: 0.848780928 [geoLocation] - [2024-07-24 08:54:36] Speed in mps: 0.17713715 Speed in km/h: 0.63769374 [geoLocation] - [2024-07-24 08:54:36] Speed in mps: 0.124507606 Speed in km/h: 0.44822738160000003 [geoLocation] - [2024-07-24 08:54:36] Watcher update from 21525349 to 21525366 [geoLocation] - [2024-07-24 08:54:37] Speed in mps: 0.124507606 Speed in km/h: 0.44822738160000003 [app] - [2024-07-24 08:54:37] appStateChange false [geoLocation] - [2024-07-24 08:54:37] Speed in mps: 0.10348552 Speed in km/h: 0.372547872 [geoLocation] - [2024-07-24 08:54:38] Speed in mps: 0.12884517 Speed in km/h: 0.46384261200000004 [geoLocation] - [2024-07-24 08:54:39] Speed in mps: 0.13284412 Speed in km/h: 0.47823883200000006 [geoLocation] - [2024-07-24 08:54:40] Speed in mps: 0.12111354 Speed in km/h: 0.436008744 [geoLocation] - [2024-07-24 08:54:40] Speed in mps: 0.031016504 Speed in km/h: 0.1116594144 [geoLocation] - [2024-07-24 08:54:40] Speed in mps: 0.076406844 Speed in km/h: 0.2750646384 [geoLocation] - [2024-07-24 08:54:41] Speed in mps: 0.07869838 Speed in km/h: 0.283314168 [geoLocation] - [2024-07-24 08:54:41] Speed in mps: 0.0759485 Speed in km/h: 0.2734146 [geoLocation] - [2024-07-24 08:54:42] Speed in mps: 0.029365502 Speed in km/h: 0.10571580720000001 [geoLocation] - [2024-07-24 08:54:43] Speed in mps: 0.0821686 Speed in km/h: 0.29580696 [geoLocation] - [2024-07-24 08:54:43] Speed in mps: 0.04148306 Speed in km/h: 0.14933901600000002 [geoLocation] - [2024-07-24 08:54:44] Speed in mps: 0.08566267 Speed in km/h: 0.308385612 [geoLocation] - [2024-07-24 08:54:44] Speed in mps: 0.12446294 Speed in km/h: 0.448066584 [geoLocation] - [2024-07-24 08:54:45] Speed in mps: 0.16775437 Speed in km/h: 0.603915732 [geoLocation] - [2024-07-24 08:54:45] Watcher update from 21525366 to 21525421 [geoLocation] - [2024-07-24 08:54:45] Speed in mps: 0.16775437 Speed in km/h: 0.603915732 [geoLocation] - [2024-07-24 08:54:46] Speed in mps: 0.1857523 Speed in km/h: 0.66870828 [app] - [2024-07-24 08:54:46] appStateChange true [geoLocation] - [2024-07-24 08:54:46] Speed in mps: 0 Speed in km/h: 0 [geoLocation] - [2024-07-24 08:54:46] Watcher update from 21525421 to 21525453 [geoLocation] - [2024-07-24 08:54:47] Speed in mps: 0.17506139 Speed in km/h: 0.630221004 [geoLocation] - [2024-07-24 08:54:47] Watcher update from 21525453 to 21525465 [geoLocation] - [2024-07-24 08:54:47] Speed in mps: 0.17479034 Speed in km/h: 0.6292452239999999 [geoLocation] - [2024-07-24 08:54:48] Speed in mps: 0.124514595 Speed in km/h: 0.44825254200000003 [geoLocation] - [2024-07-24 08:54:48] Watcher update from 21525465 to 21525475 [geoLocation] - [2024-07-24 08:54:48] Speed in mps: 0.14376326 Speed in km/h: 0.517547736 [geoLocation] - [2024-07-24 08:54:48] Speed in mps: 0.1068989 Speed in km/h: 0.38483604000000005 [geoLocation] - [2024-07-24 08:54:49] Speed in mps: 0.10202237 Speed in km/h: 0.367280532 [app] - [2024-07-24 08:54:49] appStateChange false

2024-07-24 08:54:37.158 1691-4028 ActivityManager system_server I Background started FGS: Allowed [callingPackage: [APP ID]; callingUid: 10449; uidState: TOP ; uidBFSL: [BFSL]; intent: Intent { cmp=[APP ID]/com.equimaps.capacitor_background_geolocation.BackgroundGeolocationService }; code:PROC_STATE_TOP; tempAllowListReason:; targetSdkVersion:34; callerTargetSdkVersion:34; startForegroundCount:0; bindFromPackage:null: isBindService:false]; startForegroundDelayMs:102021

2024-07-24 08:54:49.210 1691-6066 ActivityManager system_server W Foreground service started from background can not have location/camera/microphone access: service [APP ID]/com.equimaps.capacitor_background_geolocation.BackgroundGeolocationService 2024-07-24 08:54:49.210 1691-6066 ActivityManager system_server I Background started FGS: Allowed [callingPackage: [APP ID]; callingUid: 10449; uidState: LAST; uidBFSL: n/a; intent: Intent { cmp=[APP ID]/com.equimaps.capacitor_background_geolocation.BackgroundGeolocationService }; code:ACTIVITY_VISIBILITY_GRACE_PERIOD; tempAllowListReason:; targetSdkVersion:34; callerTargetSdkVersion:34; startForegroundCount:1; bindFromPackage:null: isBindService:false]

LukasGrubis commented 2 months ago

We tested the app without the dynamic distanceFilter setup. We created the foreground service once and then toggled the app between foreground and background. However, the foreground service randomly stops.

2024-07-24 11:03:54.645 1691-6579 ActivityManager system_server W Foreground service started from background can not have location/camera/microphone access: service [APP_ID]/com.equimaps.capacitor_background_geolocation.BackgroundGeolocationService 2024-07-24 11:03:54.645 1691-6579 ActivityManager system_server I Background started FGS: Allowed [callingPackage: [APP_ID]; callingUid: 10449; uidState: LAST; uidBFSL: n/a; intent: Intent { cmp=[APP_ID]/com.equimaps.capacitor_background_geolocation.BackgroundGeolocationService }; code:ACTIVITY_VISIBILITY_GRACE_PERIOD; tempAllowListReason:; targetSdkVersion:34; callerTargetSdkVersion:34; startForegroundCount:0; bindFromPackage:null: isBindService:false]; startForegroundDelayMs:40614 2024-07-24 11:04:05.781 1691-4866 ActivityManager system_server W Foreground service started from background can not have location/camera/microphone access: service [APP_ID]/com.equimaps.capacitor_background_geolocation.BackgroundGeolocationService 2024-07-24 11:04:05.781 1691-4866 ActivityManager system_server I Background started FGS: Allowed [callingPackage: [APP_ID]; callingUid: 10449; uidState: LAST; uidBFSL: n/a; intent: Intent { cmp=[APP_ID]/com.equimaps.capacitor_background_geolocation.BackgroundGeolocationService }; code:ACTIVITY_VISIBILITY_GRACE_PERIOD; tempAllowListReason:; targetSdkVersion:34; callerTargetSdkVersion:34; startForegroundCount:0; bindFromPackage:null: isBindService:false]; startForegroundDelayMs:51750 2024-07-24 11:05:16.071 1691-6217 ActivityManager system_server I Background started FGS: Allowed [callingPackage: [APP_ID]; callingUid: 10449; uidState: TOP ; uidBFSL: [BFSL]; intent: Intent { cmp=[APP_ID]/com.equimaps.capacitor_background_geolocation.BackgroundGeolocationService }; code:PROC_STATE_TOP; tempAllowListReason:; targetSdkVersion:34; callerTargetSdkVersion:34; startForegroundCount:0; bindFromPackage:null: isBindService:false]; startForegroundDelayMs:122040 2024-07-24 11:05:31.466 1691-3794 ActivityManager system_server I Background started FGS: Allowed [callingPackage: [APP_ID]; callingUid: 10449; uidState: TOP ; uidBFSL: [BFSL]; intent: Intent { cmp=[APP_ID]/com.equimaps.capacitor_background_geolocation.BackgroundGeolocationService }; code:PROC_STATE_TOP; tempAllowListReason:; targetSdkVersion:34; callerTargetSdkVersion:34; startForegroundCount:1; bindFromPackage:null: isBindService:false] 2024-07-24 11:05:35.767 1691-1713 ActivityManager system_server I Background started FGS: Allowed [callingPackage: [APP_ID]; callingUid: 10449; uidState: TOP ; uidBFSL: [BFSL]; intent: Intent { cmp=[APP_ID]/com.equimaps.capacitor_background_geolocation.BackgroundGeolocationService }; code:PROC_STATE_TOP; tempAllowListReason:; targetSdkVersion:34; callerTargetSdkVersion:34; startForegroundCount:2; bindFromPackage:null: isBindService:false] 2024-07-24 11:05:39.314 1691-6093 ActivityManager system_server W Foreground service started from background can not have location/camera/microphone access: service [APP_ID]/com.equimaps.capacitor_background_geolocation.BackgroundGeolocationService 2024-07-24 11:05:39.314 1691-6093 ActivityManager system_server I Background started FGS: Allowed [callingPackage: [APP_ID]; callingUid: 10449; uidState: LAST; uidBFSL: n/a; intent: Intent { cmp=[APP_ID]/com.equimaps.capacitor_background_geolocation.BackgroundGeolocationService }; code:ACTIVITY_VISIBILITY_GRACE_PERIOD; tempAllowListReason:; targetSdkVersion:34; callerTargetSdkVersion:34; startForegroundCount:3; bindFromPackage:null: isBindService:false]

We toggled multiple times between foreground and background. Sometimes it worked, and we received tracking notifications when the foreground service was running in the background. However, other times, it did not work. The location icon disappeared from the phone's status bar, no notification was provided, and this log appeared: "Foreground service started from background cannot have location/camera/microphone access: service."

The app is functioning correctly without any other errors or crashes.

When you developed the plugin, did you test the notification delivery in scenarios where the app is toggled multiple times to ensure that the foreground service runs continuously without any issues?

We are confused of this inconsistency.

LukasGrubis commented 2 months ago

We've added a method to check the ACCESS_BACKGROUND_LOCATION permission in the BackgroundGeolocation plugin. This helps apps ensure they have the necessary permissions before accessing location services in the background, which is crucial for avoiding issues on Android 14.

Could you please review and merge this pull request? It would greatly help us and other users of the plugin.

diachedelic commented 2 months ago

Continuing this discussion in https://github.com/capacitor-community/background-geolocation/issues/119.

Gjagadish123 commented 1 month ago

I am using this plugin in my ionic angular application but, If I remove the lapp from my background it was not working.