Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Motion permission isGranted sometimes return FALSE on iOS even though the permission is granted by the user #1294

Open
3 of 5 tasks
WUKS87 opened this issue Mar 25, 2024 · 11 comments
Assignees
Labels
platform: ios Issue is related to the iOS platform

Comments

@WUKS87
Copy link

WUKS87 commented Mar 25, 2024

Please check the following before submitting a new issue.

Please select affected platform(s)

  • Android
  • iOS
  • Windows

Steps to reproduce

  1. Request motion sensor on iOS
  2. Check if permission is granted

Expected results

await Permission.sensors.isGranted;

Should return correct bool value.

Actual results

await Permission.sensors.isGranted;

On rare occasions FALSE is returned even though user granted permission.

Code sample

Request sensor for iOS
if (Platform.isIOS) {
  await Permission.sensors.request();
}
Check granted status for iOS
bool checkDeviceMotion = await Permission.sensors.isGranted;

Screenshots or video

Screenshots or video demonstration

[Upload media here]

Version

11.3.0

Flutter Doctor output

Doctor output
[✓] Flutter (Channel stable, 3.19.3, on macOS 14.3.1 23D60 darwin-x64, locale en-RS)
    • Flutter version 3.19.3 on channel stable at /Users/admin/Flutter
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision ba39319843 (3 weeks ago), 2024-03-07 15:22:21 -0600
    • Engine revision 2e4ba9c6fb
    • Dart version 3.3.1
    • DevTools version 2.31.1

[✓] Android toolchain - develop for Android devices (Android SDK version 34.0.0)
    • Android SDK at /Users/admin/Library/Android/sdk
    • Platform android-34, build-tools 34.0.0
    • ANDROID_SDK_ROOT = /Users/admin/Library/Android/sdk
    • Java binary at: /Applications/Android Studio.app/Contents/jbr/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build 17.0.6+0-17.0.6b829.9-10027231)
    • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS (Xcode 15.2)
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Build 15C500b
    • CocoaPods version 1.15.2

[✓] Chrome - develop for the web
    • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[✓] Android Studio (version 2022.3)
    • Android Studio at /Applications/Android Studio.app/Contents
    • Flutter plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/9212-flutter
    • Dart plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/6351-dart
    • Java version OpenJDK Runtime Environment (build 17.0.6+0-17.0.6b829.9-10027231)

[✓] VS Code (version 1.87.2)
    • VS Code at /Applications/Visual Studio Code.app/Contents
    • Flutter extension version 3.84.0

[✓] Connected device (3 available)
    • iPhone 12 mini (mobile) • 1B3193E4-B683-4907-B557-B2B0F2F637BC • ios            • com.apple.CoreSimulator.SimRuntime.iOS-17-2 (simulator)
    • macOS (desktop)         • macos                                • darwin-x64     • macOS 14.3.1 23D60 darwin-x64
    • Chrome (web)            • chrome                               • web-javascript • Google Chrome 123.0.6312.58

[✓] Network resources
    • All expected network resources are available.

• No issues found!
@mvanbeusekom
Copy link
Member

Hi @WUKS87,

Does this problem occur on a real device or are you only experiencing it on the simulator. Can you provide more details about the devices on which the problem occurs (iPhone model, iOS version).

Internally the permission_handler uses the CMMotionActivityManager to check authorization status. Unfortunately Apple doesn't provide a explicit method to request permission, so our solution is to query the CMMotionActivityManager for a result, which triggers the permission dialog and immediately check the authorization status which is returned by the await Permission.sensor.request() call.

It is possible that if the user selects "Allow once" that the next time you check the permission status the result is "denied". Can you provide a more detailed use case or steps that we can use to try and reproduce the problem?

@mvanbeusekom mvanbeusekom added platform: ios Issue is related to the iOS platform status: needs more info We need more information before we can continue work on this issue. labels Apr 8, 2024
@mvanbeusekom mvanbeusekom self-assigned this Apr 8, 2024
@WUKS87
Copy link
Author

WUKS87 commented Apr 8, 2024

Hi @mvanbeusekom

It is happening on real devices, it's on our production.
Users who reported this had newer devices with OS 16 and 17.

We have few iOS devices for testing and we never saw this behaviour.

await Permission.sensor.request() is actually showing the permission dialog, user said they approved the Motion.

Our users have setup for the app, where they go through steps and they need to allow some permissions.
It starts with Location When In Use, after that we request Always permission, and finally Motion sensor.
After setup is done users is redirected to the app dashboard where we check if all steps in setup were good and if some permission is missing we show the error with explanation.

What you said about "Allow once" could make sense.

I wrote something about "Allow once" problem in this thread:
How to handle situation if user chose "Allow Only Once"

@github-actions github-actions bot removed the status: needs more info We need more information before we can continue work on this issue. label Apr 8, 2024
@WUKS87
Copy link
Author

WUKS87 commented Apr 18, 2024

@mvanbeusekom I have some new updates on this.
We actually found one user willing to share the live process with us.

User allowed "Always Allow" through the app setup and in the Motion step user did NOT get Permission Modal to allow Motion Sensor.
After finishing the whole process and entering the app, user went to app settings and wasn't able to see Motion Sensor at all.

Motion Sensor is mandatory for using our app, these users become blocked for usage.

Please advise if there is a way for some workaround?

Thank you.

@mvanbeusekom
Copy link
Member

Hi @WUKS87,

Thank you for providing additional information. However the process is not really clear to me. In your previous comment you mention:

User allowed "Always Allow" through the app setup and in the Motion step user did NOT get Permission Modal to allow Motion Sensor.

I don't really understand how the user "Always Allow" the motion permission if the permission modal is not displayed? Can you explain this a bit more detailed?

You also mentioned that the application doesn't see motion sensor at all in the App Settings, this usually is the case when the permissions are not added to the ios/Runner/Info.plist file. Although this is a stretch I just want to make sure, does the ios/Runner/Info.plist file contain the NSMotionUsageDescription and optionally the NSFallDetectionUsageDescription keys (see iOS documentation for more details)?

I also had have experience where people have a damaged motion sensor (maybe because they dropped their phone or otherwise), this might also related to similar behavior and might explain why most user don't experience any problems.

@WUKS87
Copy link
Author

WUKS87 commented Apr 18, 2024

@mvanbeusekom

User is going through our app setup by steps.

  1. Allow location sharing While In Use (frontend)
  2. Allow location sharing Always (backend)
  3. Allow Motion Sensor. Here user don't get the modal window for permission. However, user can continue through the process and enter the app itself. But since this Motion permission is mandatory user is not able to use some features.

In ios/Runner/Info.plist I have NSMotionUsageDescription but I don't have NSFallDetectionUsageDescription, should I add it?

@mvanbeusekom
Copy link
Member

Reading up on the use of motion data in an iOS application, it seems that there is no need to explicitly request permissions (see iOS documentation).

Although the documentation isn't really clear about it, the CMMotionManager SDK doesn't expose an public methods to request permission or validate authorization status. This would also explain why a permission dialog is never displayed.

In the permission_handler we use the CMMotionActivityManager class which does have a authorizationStatus property, however according to the documentation this class is not used to access the live motion information but rather to access historical motion data.

An object that manages access to the motion data stored by the device.

So in other words:

  1. To access realtime motion data you don't need to request permission.
  2. We should probably rename the Permission.sensor for iOS to better reflect it's purpose.

@WUKS87
Copy link
Author

WUKS87 commented Apr 18, 2024

So, it means that users who don’t get the permission modal for Motion don't have any history of motion events, right?

As I can see here it can send notification for current motion changes as well as motion history data.
Using this class, you can ask for notifications when the current type of motion changes or you can gather past motion change data.

@mvanbeusekom
Copy link
Member

It really depends on the plugin you are using to acquire motion data and which iOS SDK they are using to fetch the information. If the plugin is only using CMMotionManager then there is no need for any permissions at all. If the plugin is using CMMotionActivityManager the permission dialog will pop up upon first usage of the CMMotionActivityManager (this is done by iOS it self, there is no specific API to force requesting permission).

To request permission the permission_handler also quickly instantiates the CMMotionActivityManager and query for today's motion data (see here). In most situations this should trigger the permission dialog.

Again if the application is only using the CMMotionManager SDK there is no need for permissions at all.

@WUKS87
Copy link
Author

WUKS87 commented Apr 18, 2024

Ok, I will check what my plugin is using.
Thank you very much for your help.

@mvanbeusekom
Copy link
Member

Did you create your own plugin or are you using an open source plugin.

The reason I am asking is that maybe I can also have a look.

@WUKS87
Copy link
Author

WUKS87 commented Apr 19, 2024

@mvanbeusekom This is what I'm using:
Geolocation

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
platform: ios Issue is related to the iOS platform
Projects
None yet
Development

No branches or pull requests

2 participants