transistorsoft / flutter_background_geolocation

Sophisticated, battery-conscious background-geolocation & geofencing with motion-detection
https://www.transistorsoft.com/shop/products/flutter-background-geolocation
Other
645 stars 240 forks source link

Google Play declaration for FOREGROUND_SERVICE_HEALTH permission #1185

Closed mahdi-ninja closed 6 months ago

mahdi-ninja commented 10 months ago

Your Environment

Expected Behavior

Submit an app to Google Play

Actual Behavior

I need to fill a declaration form about Foreground service permissions and explain why I need FOREGROUND_SERVICE_HEALTH and FOREGROUND_SERVICE_LOCATION permissions.

Context

Google is asking me to fill the declaration and explain why I need FOREGROUND_SERVICE_HEALTH permission. This permission is added by this library and I'm not sure what the right answer is. It also asks for a video to demonstrate the functionality. Can you please help me understand what to do?

image

christocracy commented 10 months ago

The plug-in uses the motion api to automatically turn on location-tracking when the device is detected to be moving. The motion api comes under the umbrella of "Health API". Answer the questions truthfully

See my blog: https://transistorsoft.medium.com/new-google-play-console-guidelines-for-sensitive-app-permissions-d9d2f4911353

emaddoma commented 10 months ago

The blog post mentions nothing of FOREGROUND_SERVICE_HEALTH or FOREGROUND_SERVICE_LOCATION.

Though we understand the relationship to your plugin, Google does not and it would be nice if you provided some advice for explaining to Google why foreground services are necessary at all.

Furthermore, the prompt made by the plugin to allow Motion API is generic because the plugin doesn't allow a rationale to be made like it does for Location.

dumazy commented 10 months ago

I'm afraid our app is getting rejected by Google Play as well, with one of the reasons being the FOREGROUND_SERVICE_HEALTH, I assume:

Furthermore, we found that one or more of the declared use cases are not compliant with how FOREGROUND_SERVICE permission is allowed to be used. Specifically, the declared use case(s) can be interrupted or deferred by the system without creating a negative user experience.

Please remove the use of foreground services from the impacted use case(s) in your app and consider migration to alternative APIs such as WorkManager.

I've submitted an appeal, asking for a less abstract explanation to figure out what is the exact issue here, but still waiting for a response.

mahdi-ninja commented 10 months ago

@dumazy Do you have any updates?

dumazy commented 10 months ago

The issue was that I needed to provide a video showing a foreground notification. Now, on Android 14, there is no clear notification, just an indicator that the app is active.

I eventually just recorded a video on Android 12, showing the foreground service notification :-s

Is this another issue that it's not showing the notification on Android 14?

On Sat, 16 Dec 2023, 12:40 Mahdi, @.***> wrote:

@dumazy https://github.com/dumazy Do you have any updates?

— Reply to this email directly, view it on GitHub https://github.com/transistorsoft/flutter_background_geolocation/issues/1185#issuecomment-1858797214, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAQS4JG6STIWCJQZ5IUL45LYJWCD5AVCNFSM6AAAAABAJFQRO2VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTQNJYG44TOMRRGQ . You are receiving this because you were mentioned.Message ID: <transistorsoft/flutter_background_geolocation/issues/1185/1858797214@ github.com>

mwmcode commented 8 months ago

I have a similar issue but it also claims that the app uses FOREGROUND_SERVICE_HEALTHeven though I do not use it in my app. I've had questions from some users as to "why the permission settings for the app shows Motion Activity option" (even though it's off).

Any idea if/how I can remove the health tag?

christocracy commented 8 months ago

See the end of this blog post to learn how to remove permissions that this plugin automatically adds.

https://transistorsoft.medium.com/new-google-play-console-guidelines-for-sensitive-app-permissions-d9d2f4911353

christocracy commented 8 months ago

This plug-in uses the motion activity API (accelerometer + gyroscope + magnetometer) to determine when the device is in-motion to automatically trigger location tracking.

The motion api comes under the umbrella of the "health" api.

mwmcode commented 8 months ago

See the end of this blog post to learn how to remove permissions that this plugin automatically adds.

https://transistorsoft.medium.com/new-google-play-console-guidelines-for-sensitive-app-permissions-d9d2f4911353

Just started reading it. Thank you.

himsarevenus commented 8 months ago

@mwmcode have you find the solution ? is it ok to remove FOREGROUND_SERVICE_HEALTH ?

christocracy commented 8 months ago

Why don't you just follow Google's new directions and perform the declaration?

If you remove it, the plug-in will no longer be able to automatically trigger location tracking using the motion api,

mwmcode commented 8 months ago

@himsarevenus I only need simple (background) location tracking (significant changes only). My understanding is FOREGROUND_SERVICE_HEALTH is for motion tracking (i.e. steps, biking), which is not what I'm after. So I removed FOREGROUND_SERVICE_HEALTH and ACTIVITY_RECOGNITION as well. And, as Chris suggested, I followed Google's requirements, and provided a video showing usage of FOREGROUND_SERVICE_LOCATION

kieranmccwayleadr commented 6 months ago

@christocracy Could use your assistance on this please. Our app was rejected by the Play Store today now too. We gave a description 'truthfully' as you mentioned, but your blog post does not give enough information on FOREGROUND_SERVICE_HEALTH permissions or what to show to the user or where to add if any the permissions.

For instance, we get 3 rejected items since adding the library:

All in relation to the FOREGROUND_SERVICE_HEALTH service.

We do also show the Activity request permission when they enable the feature, but if we are to give more information here like the prominent location permission, that wasn't said anywhere:

Screenshot 2024-03-29 at 14 44 43

If I go to the example manifest, that too, doesn't have these permissions: https://github.com/transistorsoft/flutter_background_geolocation/blob/master/example/android/app/src/main/AndroidManifest.xml.

So how can we fix this. Also just an fyi, I checked the Example app on the play store and the last it's been updated was the 12th Oct 2023. I think you should put it through the reviews again to see if it passes now for the likes of Android 14 and update the docs to support users of the library.

Has anyone been able to get passed the Google Review stage using the Health service?

christocracy commented 6 months ago

For years, this plugin has used the ActivityTransistionApi from play-services to know when a device is moving (in_vehicle, on_bicycle, on_foot, running) or stationary (still). This allows the plugin to intelligently turn on location-services only when required and conserving energy when the device is stationary.

With Android 14, in order for ActivityTransition events to trigger in the background, this API now requires the permission FOREGROUND_SERVICE_HEALTH.

So, when providing a reason for usage of FOREGROUND_SERVICE_HEALTH, you should say something like:

We use the Activity Transition API to intelligently enable location-tracking when the app is in the background only when the device is determined to be moving ("on bicycle", "in vehicle", "walking", etc) and to save energy by turning off location-updates when the device is determined to be stationary.

If you do remove the FOREGROUND_SERVICE_HEALTH permission from your AndroidManifest, the plugin will still monitor a geofence around the last known position (what I call "the stationary geofence"), the exit of which will signal that the device is in-motion (this typically requires movement of about 200 meters from the last known location).

To remove FOREGROUND_SERVICE_HEALTH from you AndroidManifest, add the following element:

<manifest>
  <uses-permission
    android:name="android.permission.FOREGROUND_SERVICE_HEALTH"
    tools:node="remove" />
  .
  .
  . 
</manifest>

You should also configure disableMotionActivityUpdates: true.

Removing this permission will cause your app to have a longer delay initiating location-tracking. Where tracking might occur within a few meters of movement will now take at least 200 meters.

christocracy commented 6 months ago

If I go to the example manifest, that too, doesn't have these permissions:

The plugin's native library has its own AndroidManifest which is automatically merged into the App's manifest at compile-time.

kieranmccwayleadr commented 6 months ago

@christocracy that's helpful thank you.

I certainly really like the few meters of movement instead of 200 meters, that's incredibly sleek and I want to certainly push to keep it. Do we need to add these permissions to our own Manifest? Do we need to add something similar to the prominent disclosure to pass these? The fact Android 14 didn't crash trying to use this service shows that the services are used in the library as you mentioned but I wonder are Google expecting these on the app front?

ralon99 commented 5 months ago

To remove FOREGROUND_SERVICE_HEALTH from you AndroidManifest, add the following element:


<manifest>
  <uses-permission
    android:name="android.permission.FOREGROUND_SERVICE_HEALTH"
    tools:node="remove" />
  .
  .
  . 
</manifest>

You should also configure `disableMotionActivityUpdates: true`.

this one still left the activity recognition permission (without the request but the app was marked as requiring this permission on 'Health' section). i removed it the same way suggested above:

    <uses-permission
        android:name="android.permission.ACTIVITY_RECOGNITION"
        tools:node="remove" />

after this addition my problem of passing the health section on google play console disappeared

p.s is there any similar thread regarding apple store connect? i haven't got there yet, but i would like to remove any similar issues from there too

christocracy commented 4 months ago

Good news: I've found a way to enable motion updates in the background without requiring FOREGROUND_SERVICE_HEALTH. Will be released in the next version 4.15.5.

csarigumba commented 3 months ago

@christocracy

Do we need to do something in our side or just update the package to 4.15.5?

christocracy commented 3 months ago

Update to latest.

ralon99 commented 3 months ago

so can i remove these line from manifest.xml?

<manifest>
  <uses-permission
    android:name="android.permission.FOREGROUND_SERVICE_HEALTH"
    tools:node="remove" />
  .
  .
  . 
</manifest>
christocracy commented 3 months ago

See the CHANGELOG. It’s already removed in the latest version,

jonasfeld commented 1 month ago

@christocracy a) we use the newest (4.16.0) version of flutter_background_geolocation and still have to submit health feature compliance for our app because the app uses android.permissions.ACTIVITY_RECOGNITION

Quote:

Your app uses the following health permissions and must meet Health apps policy requirements. If you don't have any health features in your app, remove these permissions from your app's manifest. android.permission.ACTIVITY_RECOGNITION

b) do we have to have a service with android:foregroundServiceType="location" in our AndroidManifest.xml for the background tracking to work properly or does the library background_geolocation library not need that permission/service declared?

thanks in advance

christocracy commented 1 month ago

a) we use the newest (4.16.0) version of flutter_background_geolocation and still have to submit health feature compliance for our app because the app uses android.permissions.ACTIVITY_RECOGNITION

See my blog: https://medium.com/@transistorsoft/google-play-store-required-declarations-for-foreground-services-and-health-97da6e2abd5a

b) do we have to have a service with android:foregroundServiceType="location" in our AndroidManifest.xml for the background tracking to work properly

No. The plugin contains its own AndroidManifest containing all the plugin's required elements. You do not need to add any manual elements to your AndroidManifest.

Here's is the plugin's AndroidManifest, which is automatically merged into your app:

<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.transistorsoft.tslocationmanager">
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.ACTIVITY_RECOGNITION" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
    <uses-permission android:name="com.google.android.gms.permission.ACTIVITY_RECOGNITION" />
    <uses-permission android:name="com.huawei.hms.permission.ACTIVITY_RECOGNITION" />
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
    <uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" />
    <uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
    <uses-permission android:name="android.permission.FOREGROUND_SERVICE_LOCATION" />

    <!-- ENABLE FOR CrashDetector testing:  <uses-permission android:name="android.permission.HIGH_SAMPLING_RATE_SENSORS" /> -->

    <!--
    This permission overrids Android 12 restriction on starting foreground-serivces in background
    but the permission is available only to "priveliged" apps (EMERGENCY apps)

    <uses-permission android:name="android.permission.START_FOREGROUND_SERVICES_FROM_BACKGROUND" />
    -->

    <!-- device-specific permissions for DeviceSettings methods -->
    <uses-permission android:name="oppo.permission.OPPO_COMPONENT_SAFE"/>
    <uses-permission android:name="com.huawei.permission.external_app_settings.USE_COMPONENT"/>

    <uses-feature android:name="android.hardware.location.gps" android:required="false" />

    <application>
        <!-- TODO For disabling SharedPreferences backup on Android 12+ android:dataExtractionRules="@xml/backup_rules" -->
        <activity
            android:name="com.transistorsoft.locationmanager.activity.TSLocationManagerActivity"
            android:exported="true"
            android:excludeFromRecents="true"
            android:launchMode="singleInstance"
            android:theme="@style/TSLocationManagerActivity" />

        <service
            android:name="com.transistorsoft.locationmanager.service.TrackingService"
            android:foregroundServiceType="location" />
        <service
            android:name="com.transistorsoft.locationmanager.service.LocationRequestService"
            android:foregroundServiceType="@integer/foregroundServiceTypeShortService" />
        <service
            android:name="com.transistorsoft.locationmanager.service.ActivityRecognitionService"
            android:foregroundServiceType="@integer/foregroundServiceTypeShortService" />
        <service
            android:name="com.transistorsoft.locationmanager.service.GeofencingService"
            android:foregroundServiceType="location" />
        <service
            android:name="com.transistorsoft.locationmanager.service.PolygonGeofencingService"
            android:foregroundServiceType="location" />
        <service
            android:name="com.transistorsoft.locationmanager.scheduler.ScheduleService"
            android:foregroundServiceType="@integer/foregroundServiceTypeShortService" />

        <receiver
            android:name="com.transistorsoft.locationmanager.scheduler.ScheduleAlarmReceiver"
            android:exported="false" />

        <service
            android:name="com.transistorsoft.locationmanager.scheduler.ScheduleJobService"
            android:permission="android.permission.BIND_JOB_SERVICE" />
        <receiver
            android:name="com.transistorsoft.locationmanager.BootReceiver"
            android:enabled="true"
            android:exported="false"
            android:permission="android.permission.RECEIVE_BOOT_COMPLETED">
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED" />
                <action android:name="android.intent.action.MY_PACKAGE_REPLACED" />
            </intent-filter>
        </receiver>

        <provider
            android:name="com.transistorsoft.locationmanager.util.LogFileProvider"
            android:authorities="${applicationId}.tslocationmanager.fileprovider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/tslocationmanager_file_provider_path" />
        </provider>

    </application>
</manifest>