flutter-permission-handler
flutter-permission-handler copied to clipboard
[Bug]: Permission not granted in first time, We need to rebuild the app again to see ther permission change
Please check the following before submitting a new issue.
- [X] I have searched the existing issues.
- [X] I have carefully read the documentation and verified I have added the required platform specific configuration.
Please select affected platform(s)
- [ ] Android
- [X] iOS
- [ ] Windows
Steps to reproduce
First add the first 2 line before the runApp function in main()
then give permission and log the output, it says permissionStatus.granted
but when i call on
await Permission.calendarFullAccess.status
[ you can uncomment the commented part and check]
is says permissionStatus.denied
But when i close out the app and rebuild it on xcode or vscode again, then it says
permissionStatus.granted
it takes new rebuild to configure the permission, which is not good
Expected results
it should show the granted permission for all state after the permission is granted by the user. Not after the rebuild of the app again
Actual results
It says permission denied and
INVOKE_CHANNEL_METHOD_ERROR: PlatformException(401, The user has not allowed this application to modify their calendar(s), null, null)
for the first time and then it fixes itself after rebuilding the app again
Code sample
Code sample
await Permission.calendarWriteOnly.request();
await Permission.calendarFullAccess.request();
static Future<PermissionStatus> _calendarPermissions() async {
Map<Permission, PermissionStatus> permissionStatus = await [Permission.calendarWriteOnly].request();
log("--- : " + permissionStatus.toString());
return permissionStatus[Permission.calendarWriteOnly] ?? PermissionStatus.denied;
// PermissionStatus permission = await Permission.calendarWriteOnly.status;
// if (!permission.isGranted) {
// log(permission.toString());
// Map<Permission, PermissionStatus> permissionStatus = await [Permission.calendarWriteOnly].request();
// log("--- : " + permissionStatus.toString());
// return permissionStatus[Permission.calendarWriteOnly] ?? PermissionStatus.denied;
// } else {
// return permission;
// }
}
static Future<PermissionStatus> _calendarPermissions2() async {
Map<Permission, PermissionStatus> permissionStatus = await [Permission.calendarFullAccess].request();
log("--- : " + permissionStatus.toString());
return permissionStatus[Permission.calendarFullAccess] ?? PermissionStatus.denied;
// PermissionStatus permission = await Permission.calendarFullAccess.status;
// if (!permission.isGranted) {
// log(permission.toString());
// Map<Permission, PermissionStatus> permissionStatus = await [Permission.calendarFullAccess].request();
// log("--- : " + permissionStatus.toString());
// return permissionStatus[Permission.calendarFullAccess] ?? PermissionStatus.denied;
// } else {
// return permission;
// }
}
Future<bool> calendarPermissionsGranted() async {
PermissionStatus calendarPermissionsStatus = await _calendarPermissions();
log("break");
PermissionStatus calendarPermissionsStatus2 = await _calendarPermissions2();
// if (calendarPermissionsStatus2.isGranted) {
if (calendarPermissionsStatus.isGranted && calendarPermissionsStatus2.isGranted) {
log("yes");
return true;
} else {
log("no");
return false;
}
}
Screenshots or video
Screenshots or video demonstration
Version
11.1.0
Flutter Doctor output
Doctor output
flutter doctor -v
[✓] Flutter (Channel stable, 3.16.0, on macOS 14.0 23A344 darwin-x64, locale en-JP)
• Flutter version 3.16.0 on channel stable at /Users/emongenie/Downloads/Apps/flutter
• Upstream repository https://github.com/flutter/flutter.git
• Framework revision db7ef5bf9f (7 days ago), 2023-11-15 11:25:44 -0800
• Engine revision 74d16627b9
• Dart version 3.2.0
• DevTools version 2.28.2
[✓] Android toolchain - develop for Android devices (Android SDK version 34.0.0)
• Android SDK at /Users/emongenie/Library/Android/sdk
• Platform android-34, build-tools 34.0.0
• 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.0.1)
• Xcode at /Applications/Xcode.app/Contents/Developer
• Build 15A507
• CocoaPods version 1.14.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.84.2)
• VS Code at /Applications/Visual Studio Code.app/Contents
• Flutter extension version 3.76.0
[✓] Connected device (3 available)
• iPhone 15 Pro Max (mobile) • 744BEB5C-7838-4731-8C65-3FFF26E3F994 • ios • com.apple.CoreSimulator.SimRuntime.iOS-17-0 (simulator)
• macOS (desktop) • macos • darwin-x64 • macOS 14.0 23A344 darwin-x64
• Chrome (web) • chrome • web-javascript • Google Chrome 119.0.6045.159
! Error: Browsing on the local area network for iPhone. Ensure the device is unlocked and attached with a cable or associated with the same local area network as this Mac.
The device must be opted into Developer Mode to connect wirelessly. (code -27)
[✓] Network resources
• All expected network resources are available.
• No issues found!
I'm facing the same issue with Android 10.
Permission.storage.request();
The first request results in an error: W/permissions_handler(22142): onRequestPermissionsResult is called without results. This is probably caused by interfering request codes. If you see this error, please file an issue in flutter-permission-handler, including a list of plugins used by this application: https://github.com/Baseflow/flutter-permission-handler/issues
After restarting the app, it works with the permission granted.
Hi @Zahid046, thank you for bringing this to our attention!
Some initial questions that pop into my head:
- What iOS version are you using?
- What happens when you only request
Permission.calendarFullAccess
?
-
I am using ios 17 on iphone 15 pro max simulator and also in iphone SE3 and iphone 11 which all have ios 17 available to them
-
If permission.calendarFullAccess is called and the permission is given then
INVOKE_CHANNEL_METHOD_ERROR: PlatformException(401, The user has not allowed this application to modify their calendar(s), null, null) thiss error shows up
then after closing the app completely and rebuilding again it shows that permission is granted and it gives access to the calendar.
thats where i am stuck now. as it is not a very good approach to gain access on calendar in user level
@JeroenWeener
We faced a similar issue in iOS 17 after updating permission_hanlder
to 11.1.0
.
We added both NSCalendarsUsageDescription
& NSCalendarsFullAccessUsageDescription
in the Info.plist
, and PERMISSION_EVENTS_FULL_ACCESS=1
& PERMISSION_EVENTS=1
in the Podfile
.
Then we called permission.calendarFullAccess.request()
and it prompted the user to give full access (and it shows in the settings that a full access calendar permission had been given), but it would not work unless the user changed it manually (from the setting) to be "None/ Write Only" then to "Full Access".
@MrOsamah its actually same when you go to settings and change it manually you have to restart the app. Thats what i am also facing. But seems like it is not concerning the author of the package to fix it right now, But lets see
@mvanbeusekom @JeroenWeener Thanks for your hard work guys, would you consider making this issue a higher priority (or let us know what you think about it), I think it happens for all iOS 17 devices.
@JeroenWeener any update?
This is also a big problem for me. Because access is granted only after a complete restart of the program ( And this solution https://github.com/Baseflow/flutter-permission-handler/issues/1108#issuecomment-1826979829 does not help
Facing a similar issue as well @JeroenWeener
Using IOS 17.1.2 Iphone 13 Pro
But on my end await Permission.calendarFullAccess.request();
doesn't event request for calendar permission
Already added this in my Podfile
## dart: [PermissionGroup.calendarWriteOnly, PermissionGroup.calendar (until iOS 16)]
'PERMISSION_EVENTS=1',
## dart: [PermissionGroup.calendarFullAccess, PermissionGroup.calendar (from iOS 17)]
'PERMISSION_EVENTS_FULL_ACCESS=1',
## dart: PermissionGroup.reminders
'PERMISSION_REMINDERS=1',
And this on my Info.plist
<!-- Permission options for the `calendar` group -->
<key>NSCalendarsUsageDescription</key>
<string>Allow permission in order to process your loan application</string>
<key>NSCalendarsFullAccessUsageDescription</key>
<string>Calendar full access</string>
<key>NSRemindersFullAccessUsageDescription</key>
<string>Reminders full access</string>
Code
Future<void> _requestIOSPermissions() async {
try {
await Permission.calendarFullAccess.request();
final calendarStatus = await Permission.calendarFullAccess.status;
//log calendarStatus here is always denied
} catch (e) {
print(e);
}
}
Let me know if you need anything else would be glad to help
Thanks for the package! any news on this issue or a temporary workaround ?
It seems that device_calendar
has a fix on their develop branch (but needs full access unfortunately), check builttoroam/device_calendar/#490.
It seems that
device_calendar
has a fix on their develop branch (but needs full access unfortunately), check builttoroam/device_calendar/#490.
It doesn't change the problematic behavior. I still need to restart the app after asking for permissions before i can move on to the feature functionality.
It doesn't change the problematic behavior. I still need to restart the app after asking for permissions before i can move on to the feature functionality.
@einatguri @mulvad Sorry I didn't elaborate.
We used the device_dalendar
's methods DeviceCalendarPlugin.requestPermissions
and DeviceCalendarPlugin.hasPermission
, maybe it will help you in your case.
It doesn't change the problematic behavior. I still need to restart the app after asking for permissions before i can move on to the feature functionality.
@einatguri @mulvad Sorry I didn't elaborate.
We used the
device_dalendar
's methodsDeviceCalendarPlugin.requestPermissions
andDeviceCalendarPlugin.hasPermission
, maybe it will help you in your case.
it seems to be working for this specific scenario. Thanks!
Hello All,
Any updates?
Hello all,
Unfortunately we are unable to reproduce this issue. To reproduce the issue I have creates a quick test application taking the following steps:
- Create new Flutter application:
flutter create --platforms=ios issue_1235
. - Change into the project directory:
cd issue_1235
. - Add a dependency on the latest permission_handler plugin:
flutter pub add permission_handler
. - Add required configuration to the
ios/Podfile
(see code below). - Add required configuration to the
ios/Runner/Info.plist
(see code below). - Update the
lib/main.dart
to request full access to the Calendar (see code below). - Run the application and hit the floating action button to request permission, the method returns "granted" right away.
Code files I updated:
ios/Podfile
# Uncomment this line to define a global platform for your project
# platform :ios, '12.0'
# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
ENV['COCOAPODS_DISABLE_STATS'] = 'true'
project 'Runner', {
'Debug' => :debug,
'Profile' => :release,
'Release' => :release,
}
def flutter_root
generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__)
unless File.exist?(generated_xcode_build_settings_path)
raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first"
end
File.foreach(generated_xcode_build_settings_path) do |line|
matches = line.match(/FLUTTER_ROOT\=(.*)/)
return matches[1].strip if matches
end
raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get"
end
require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)
flutter_ios_podfile_setup
target 'Runner' do
use_frameworks!
use_modular_headers!
flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
target 'RunnerTests' do
inherit! :search_paths
end
end
post_install do |installer|
installer.pods_project.targets.each do |target|
flutter_additional_ios_build_settings(target)
target.build_configurations.each do |config|
# You can remove unused permissions here
# for more information: https://github.com/BaseflowIT/flutter-permission-handler/blob/master/permission_handler/ios/Classes/PermissionHandlerEnums.h
# e.g. when you don't need camera permission, just add 'PERMISSION_CAMERA=0'
config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= [
'$(inherited)',
## dart: PermissionGroup.calendar
'PERMISSION_EVENTS=1',
## dart: PermissionGroup.calendarFullAccess
'PERMISSION_EVENTS_FULL_ACCESS=1',
]
end
end
end
ios/Runner/Info.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleDisplayName</key>
<string>Issue 1235</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>issue_1235</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>$(FLUTTER_BUILD_NAME)</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>$(FLUTTER_BUILD_NUMBER)</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIMainStoryboardFile</key>
<string>Main</string>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>CADisableMinimumFrameDurationOnPhone</key>
<true/>
<key>UIApplicationSupportsIndirectInputEvents</key>
<true/>
<!-- Permission options for the `calendar` group -->
<key>NSCalendarsUsageDescription</key>
<string>Calendars</string>
<key>NSCalendarsFullAccessUsageDescription</key>
<string>Calendar full access</string>
</dict>
</plist>
pubspec.yaml
name: issue_1235
description: "A new Flutter project."
publish_to: 'none'
version: 1.0.0+1
environment:
sdk: '>=3.3.1 <4.0.0'
dependencies:
flutter:
sdk: flutter
cupertino_icons: ^1.0.6
permission_handler: ^11.3.0
dev_dependencies:
flutter_test:
sdk: flutter
flutter_lints: ^3.0.0
flutter:
uses-material-design: true
lib/main.dart
import 'package:flutter/material.dart';
import 'package:permission_handler/permission_handler.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.title});
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
String _permissionStatus = PermissionStatus.denied.name;
Future<void> _requestCalendarPermission() async {
final PermissionStatus permissionStatus =
await Permission.calendarFullAccess.request();
setState(() {
_permissionStatus = permissionStatus.name;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
const Text(
'Full access calendar status:',
),
Text(
'$_permissionStatus',
style: Theme.of(context).textTheme.headlineMedium,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _requestCalendarPermission,
tooltip: 'Request calendar permission',
child: const Icon(Icons.add),
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
}
Here is the output of flutter doctor -v
from my environment:
[✓] Flutter (Channel stable, 3.19.3, on macOS 14.3.1 23D60 darwin-arm64, locale en-US)
• Flutter version 3.19.3 on channel stable at /Users/maurits/development/flutter
• Upstream repository https://github.com/flutter/flutter.git
• Framework revision ba39319843 (12 days 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/maurits/Library/Android/sdk
• Platform android-34, build-tools 34.0.0
• Java binary at: /Applications/Android Studio.app/Contents/jbr/Contents/Home/bin/java
• Java version OpenJDK Runtime Environment (build 17.0.9+0-17.0.9b1087.7-11185874)
• 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.14.3
[✓] Chrome - develop for the web
• Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome
[✓] Android Studio (version 2023.2)
• 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.9+0-17.0.9b1087.7-11185874)
[✓] VS Code (version 1.87.2)
• VS Code at /Applications/Visual Studio Code.app/Contents
• Flutter extension version 3.84.0
[✓] Connected device (4 available)
• Pixel 7a (mobile) • 31071JEHN18081 • android-arm64 • Android 14 (API 34)
• Maurits van Beusekom’s iPhone (mobile) • 00008101-000D543E1A40001E • ios • iOS 17.3.1 21D61
• macOS (desktop) • macos • darwin-arm64 • macOS 14.3.1 23D60 darwin-arm64
• Chrome (web) • chrome • web-javascript • Google Chrome 122.0.6261.129
[✓] Network resources
• All expected network resources are available.
• No issues found!
Reading the original question carefully, I noticed the sentence "First add the first 2 line before the runApp function in main()". It is important to make sure that permissions are only requested when the Flutter engine is fully loaded. If you want to request permission before the runApp
call make sure that you first call WidgetsFlutterBinding.ensureInitialized();
before calling into the permission_hanlder. More information about this can be found here.
If anyone is still experiencing this issue, please provide an example similar to mine demonstrating the problem.
Without additional information, we are unfortunately not able to resolve this issue. Therefore, we reluctantly closed this issue for now. If you run into this issue later, feel free to file a new issue with a reference to this issue. Add a description of detailed steps to reproduce, expected and current behaviour, logs and the output of 'flutter doctor -v'. Thanks for your contribution.
I still encountered this issue yesterday where I got [(401, That account does not allow calendars to be added or removed., null, null)] after granting full access to calendars and then trying to retrieve calendars using:
await _deviceCalendarPlugin.retrieveCalendars()
I'm running iOS 17.2 on the stimulator.
Where I differ from the OP is instead of restarting my app, I noticed that if when I navigate to another screen that also uses this package and then navigate back to the screen where I encountered this issue, then my calendars would get retrieved without error.
After some trial and error, I realized that before await _deviceCalendarPlugin.retrieveCalendars() I need to first do a permission check by first running:
await _deviceCalendarPlugin.requestPermissions();
Before I would only run await _deviceCalendarPlugin.hasPermissions() before trying to retrieve calendars with await _deviceCalendarPlugin.retrieveCalendars().
Hope this helps.