capacitor-community / background-geolocation

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

Missing permissions to Android 14 (specific to Samsung phones in particular) #112

Closed nesnejretep closed 4 months ago

nesnejretep commented 4 months ago

After quite a bit of troubleshooting on Android 14, I ended up with a solution which might be of use to others with similar problems. On Android 14 either emulating or on real device, no notifications appear, when app is sent to the background. Solved by requesting Notifications with:

npm install @capacitor/push-notifications

and calling a function at app startup like:

async function registerNotifications(){
  let permStatus = await Capacitor.Plugins.PushNotifications.checkPermissions();
 if (permStatus.receive === 'prompt') {
    permStatus = await Capacitor.Plugins.PushNotifications.requestPermissions();
 }
  if (permStatus.receive !== 'granted') {
    throw new Error('User denied permissions!');
  }
}

Furthermore - and perhaps more critical to the operation of this plugin - background locations would stop completely when app is sent into background or screen is turned of on Samsung Android 14 devices (Galaxy S23 etc.).

Solved by adding: <uses-permission android:name="android.permission.FOREGROUND_SERVICE_LOCATION"/>

to AndroidMainfest.xml

diachedelic commented 4 months ago

The permissions requirement is documented in the README:

On Android 13+, the app needs the POST_NOTIFICATIONS runtime permission to show the persistent notification informing the user that their location is being used in the background. You may need to request this permission from the user.

It should not be necessary to add <uses-permission android:name="android.permission.FOREGROUND_SERVICE_LOCATION"/> to the app's manifest, because it is already included in the plugin's manifest. Seeing as the app and plugins' manifests are merged to produce the final manifest, I suspect this is unnecessary. Can you please check?

nesnejretep commented 4 months ago

The permissions requirement is documented in the README:

On Android 13+, the app needs the POST_NOTIFICATIONS runtime permission to show the persistent notification informing the user that their location is being used in the background. You may need to request this permission from the user.

You are absolutely right. It just wasn't clear to me, that it wasn't enough to add POST_NOTIFICATIONS to AndroidManifest.xml, or to provide Notification permissions during run-time, which was the case. My app had to actively request Notification Permissions - in this case using another plugin.

It should not be necessary to add <uses-permission android:name="android.permission.FOREGROUND_SERVICE_LOCATION"/> to the app's manifest, because it is already included in the plugin's manifest. Seeing as the app and plugins' manifests are merged to produce the final manifest, I suspect this is unnecessary. Can you please check?

Sorry. Perhaps I just know too little about how Capacitor merges and packages the app and permissions. But I have checked. Removing <uses-permission android:name="android.permission.FOREGROUND_SERVICE_LOCATION"/> makes background-geolocation stop while in the background; tested on several separate Samsung Galaxy models running Android 14. It does not appear to be a problem on earlier versions of Android (11-12). Also, on submitting for internal test on Google Play, the Foreground Service Location permission was not identified before I added it manually (which meant I had to then upload a YouTube video etc. explaining how the app makes use of foreground services). I am not sure if this is a Capacitor manifest merging issue. I tried looking through various manifest-merger log files present in my build folder hierarchy, but lost track of what it was doing.

This is what I see in the plugin's manifest - the FOREGROUND_SERVICE_LOCATION is not explicitly mentioned, using <uses-permission android:name="android.permission.FOREGROUND_SERVICE_LOCATION"/> as far as I can tell.

<manifest xmlns:android="http://schemas.android.com/apk/res/android">
    <application>
        <service
            android:name="com.equimaps.capacitor_background_geolocation.BackgroundGeolocationService"
            android:enabled="true"
            android:exported="true"
            android:foregroundServiceType="location" />
    </application>

    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
    <!-- Android SDK 33+ requires the POST_NOTIFICATIONS runtime permission to
    display the foreground service notification. -->
    <uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
    <uses-feature android:name="android.hardware.location.gps" />
</manifest>

It is, however, mentioned as a requirement here: https://developer.android.com/develop/background-work/services/fg-service-types

diachedelic commented 4 months ago

Whoa! I did not notice that FOREGROUND_SERVICE_LOCATION was different from FOREGROUND_SERVICE. I will add that to the plugin's manifest so there will be no need to add it to the app's manifest.

You are right that it's not at all obvious how to request notification permissions. I will link to this issue from the README.

diachedelic commented 4 months ago

Fixed in v1.2.16, please test.