Skip to content

Fix: location permission returns denied when user selects approximate - #1504

Open
HasanAlqaisi wants to merge 26 commits into
Baseflow:mainfrom
HasanAlqaisi:main
Open

HasanAlqaisi wants to merge 26 commits into
Baseflow:mainfrom
HasanAlqaisi:main

Conversation

@HasanAlqaisi

@HasanAlqaisi HasanAlqaisi commented Nov 19, 2025

Copy link
Copy Markdown

Issue: On Android 12 (API 31) and higher, users have the option to grant "Approximate" location (Coarse) instead of "Precise" location (Fine). When a user selects "Approximate", the system grants ACCESS_COARSE_LOCATION but denies ACCESS_FINE_LOCATION.

Currently, permission_handler incorrectly reports the status as PermissionStatus.denied in this scenario. This prevents apps from functioning that are capable of working with only approximate location.

It is also reported as an issue here

Expected Behavior: If the user grants "Approximate" location, the permission status should be reported as PermissionStatus.granted, as the app does have access to location data (with lower accuracy).

Pre-launch Checklist

  • I made sure the project builds.
  • I read the Contributor Guide and followed the process outlined there for submitting PRs.
  • I updated pubspec.yaml with an appropriate new version according to the pub versioning philosophy, or this PR is does not need version changes.
  • I updated CHANGELOG.md to add a description of the change.
  • I updated/added relevant documentation (doc comments with ///).
  • I rebased onto main.
  • I added new tests to check the change I am making, or this PR does not need tests.
  • I made sure all existing and new tests are passing.
  • I ran dart format . and committed any changes.
  • I ran flutter analyze and fixed any errors.

@KingkanB

Copy link
Copy Markdown

I want this fix too.

@quyenvsp

Copy link
Copy Markdown

I can't reproduce the bug. What device are you using? What uses-permission you declared in AndroidManifest.xml?

@HasanAlqaisi

Copy link
Copy Markdown
Author

I can't reproduce the bug. What device are you using? What uses-permission you declared in AndroidManifest.xml?

I tried both Android 14 emulator & Android 16 (S25 FE) and they have the same issue.

I made a simple repo for the bug reproduction

@anurag-ainxt

Copy link
Copy Markdown

need this fixed

TheoGermain and others added 24 commits September 15, 2026 13:54
* feat(apple): create SPM source directory structure

* feat(apple): move ObjC sources to SPM-compatible structure

* feat(apple): add public header for SPM plugin registration

* feat(apple): move PrivacyInfo.xcprivacy to SPM sources

* feat(apple): add Package.swift for Swift Package Manager support

* feat(apple): update podspec to reference SPM source structure

* chore(apple): ignore SPM build artifacts

* docs: add SPM setup instructions to README

* fix(apple): move Package.swift to correct SPM location (ios/permission_handler_apple/)

* fix(apple): add missing PERMISSION_PHOTOS_ADD_ONLY and PERMISSION_LOCATION_ALWAYS defines

* fix(apple): use forward declaration in public header to avoid missing internal import

* fix(example): bump compileSdk to 36, AGP to 8.9.1, Gradle to 8.11.1

* fix(apple): add explicit UIKit import to strategies that use UIApplication under SPM

* feat(apple): auto-detect permissions from Info.plist in Package.swift

Package.swift now walks up the directory tree from its own location to find
the app's Info.plist and enables each permission define when the corresponding
usage description key is present. This mirrors the CocoaPods workflow: adding
NSCameraUsageDescription to Info.plist is all that is needed to activate
PERMISSION_CAMERA, with no extra configuration files or terminal commands.

Environment variables remain supported as an explicit override (priority over
Info.plist), which covers PermissionGroup.notification and criticalAlerts that
have no required Info.plist key.

Users must clear DerivedData once after changing Info.plist so Xcode
re-evaluates the manifest: rm -rf ~/Library/Developer/Xcode/DerivedData

* docs: update SPM setup instructions to use Info.plist auto-detection

Replace the launchctl setenv / pre-action script approach with the new
Info.plist-based mechanism: permissions are now enabled automatically when
the corresponding usage description key is present in Info.plist, which is
already required for any permission to work at runtime.

Document the two permissions without an Info.plist key (notification,
criticalAlerts) as the only case still requiring an env var.

* chore(example): update iOS example app and remove plan artifact

- Add all permission usage description keys to Info.plist so the SPM
  Info.plist auto-detection covers all permissions out of the box
- Comment out the Siri entitlement (requires a paid Apple Developer
  account; uncomment to test PERMISSION_ASSISTANT)
- Update AppDelegate to modern FlutterImplicitEngineDelegate pattern
- Bump Podfile iOS platform to 13.0
- Remove docs/superpowers/plans/2026-05-05-spm-support.md (internal
  planning artifact not intended for the public repo)

* chore(apple): bump version to 9.4.8 and update CHANGELOG

* fix(apple): correct SPM permission flag mapping for photos and calendarWriteOnly

- PERMISSION_PHOTOS now triggers on NSPhotoLibraryAddUsageDescription alone,
  since PhotoPermissionStrategy (which handles photosAddOnly) compiles under
  PERMISSION_PHOTOS — without this, photosAddOnly silently fell back to
  UnknownPermissionStrategy when NSPhotoLibraryUsageDescription was absent
- PERMISSION_EVENTS_FULL_ACCESS now also triggers on
  NSCalendarsWriteOnlyAccessUsageDescription (iOS 17+), enabling calendarWriteOnly
  which requires PERMISSION_EVENTS || PERMISSION_EVENTS_FULL_ACCESS in native code
- Sync podspec version to 9.4.8
- Restore NSCameraUsageDescription in example Info.plist (lost during rewrite)
- Add NSCalendarsWriteOnlyAccessUsageDescription to example Info.plist

* docs: add calendarWriteOnly to SPM permission table in README

* fix(example): remove NSSiriUsageDescription and document permission constraints

Siri requires the com.apple.developer.siri entitlement; including
NSSiriUsageDescription without it crashes the app on launch under SPM.
Added a README section listing permissions that cannot be tested on
simulator or without special entitlements.

* fix(apple): enable notifications and criticalAlerts by default under SPM

These permissions have no required Info.plist key so the previous logic
always compiled them out (defaultValue "0"), causing permanentlyDenied
to be returned without ever showing a system dialog.

They are now enabled by default and can be opted out via env var set to "0".

* fix(apple): revert criticalAlerts to opt-in under SPM

criticalAlerts requires a special Apple entitlement; compiling it into
every app by default would add dead code for apps that don't use it.
Only PERMISSION_NOTIFICATIONS defaults to enabled (no entitlement needed).

* docs: clarify SPM special cases for notification and criticalAlerts

- Add both permissions to the Info.plist table with notes
- Distinguish export (terminal) vs launchctl setenv (Xcode GUI)
- Explain why criticalAlerts is opt-in (Apple entitlement required)

* chore(example): enable SPM in Xcode project for iOS example app

Flutter auto-generated FlutterGeneratedPluginSwiftPackage reference
when running with --enable-swift-package-manager.

* fix(example): align Java source/target compatibility to VERSION_17

AGP 8.x + Kotlin 1.9+ enforce JVM-target consistency; compileJava was
still on 1.8 while compileKotlin used 17, causing the build to fail.
Fix incorrect Android SDK parameter name in documentation.

"completeSdkVersion" is not a valid Android parameter. The correct name is "compileSdkVersion". This prevents developer confusion when following the troubleshooting guide.
…low#1488)

After version 8.0.0, permission handler no longer uses all permissions on iOS, but this was not explained clearly in the README.
This is my attempt to fix that small mistake.
>
> Co-authored-by: Novarest
* Changed Info.plist lookup

* Updated pubspec and changelog

* Refactored look up of infoplist in the Package.swift

* Reverting SPM changes in the example app.

* fixed changelog.
…flow#1541)

* Added ACCESS_LOCAL_NETWORK permission for android 17

* bump main package version

* bump compilesdk version for android

* Updated android pakcage version to 14 (breaking)

* Just a typo

* missing defs

* ...

* ...

* Added ACCESS_LOCAL_NETWORK permission for android 17

* bump main package version

* bump compilesdk version for android

* Updated android pakcage version to 14 (breaking)

* Just a typo

* missing defs

* ...

* ...

* dart formatting

* Update to use monorepo for managing development

* Linting, formatting, fix analysis issues

* Fix test for number of permissions

* Build after test (build is more time-costly)

* Fix permission_handler android build compileSdk

* Forgot to bump compilesdk version for android example app

* update code coverage for permission_handler_platform_interface, add android 37 sdk

* ...it is android 37.0, not android 37

* try to symlink the android-37.0 directory to android-37?

* ohhh...i think it is flutter.

* yes, flutter, but also outdated kotlin / gradle, etc

* feat(apple): add Swift Package Manager support (Baseflow#1523)

* feat(apple): create SPM source directory structure

* feat(apple): move ObjC sources to SPM-compatible structure

* feat(apple): add public header for SPM plugin registration

* feat(apple): move PrivacyInfo.xcprivacy to SPM sources

* feat(apple): add Package.swift for Swift Package Manager support

* feat(apple): update podspec to reference SPM source structure

* chore(apple): ignore SPM build artifacts

* docs: add SPM setup instructions to README

* fix(apple): move Package.swift to correct SPM location (ios/permission_handler_apple/)

* fix(apple): add missing PERMISSION_PHOTOS_ADD_ONLY and PERMISSION_LOCATION_ALWAYS defines

* fix(apple): use forward declaration in public header to avoid missing internal import

* fix(example): bump compileSdk to 36, AGP to 8.9.1, Gradle to 8.11.1

* fix(apple): add explicit UIKit import to strategies that use UIApplication under SPM

* feat(apple): auto-detect permissions from Info.plist in Package.swift

Package.swift now walks up the directory tree from its own location to find
the app's Info.plist and enables each permission define when the corresponding
usage description key is present. This mirrors the CocoaPods workflow: adding
NSCameraUsageDescription to Info.plist is all that is needed to activate
PERMISSION_CAMERA, with no extra configuration files or terminal commands.

Environment variables remain supported as an explicit override (priority over
Info.plist), which covers PermissionGroup.notification and criticalAlerts that
have no required Info.plist key.

Users must clear DerivedData once after changing Info.plist so Xcode
re-evaluates the manifest: rm -rf ~/Library/Developer/Xcode/DerivedData

* docs: update SPM setup instructions to use Info.plist auto-detection

Replace the launchctl setenv / pre-action script approach with the new
Info.plist-based mechanism: permissions are now enabled automatically when
the corresponding usage description key is present in Info.plist, which is
already required for any permission to work at runtime.

Document the two permissions without an Info.plist key (notification,
criticalAlerts) as the only case still requiring an env var.

* chore(example): update iOS example app and remove plan artifact

- Add all permission usage description keys to Info.plist so the SPM
  Info.plist auto-detection covers all permissions out of the box
- Comment out the Siri entitlement (requires a paid Apple Developer
  account; uncomment to test PERMISSION_ASSISTANT)
- Update AppDelegate to modern FlutterImplicitEngineDelegate pattern
- Bump Podfile iOS platform to 13.0
- Remove docs/superpowers/plans/2026-05-05-spm-support.md (internal
  planning artifact not intended for the public repo)

* chore(apple): bump version to 9.4.8 and update CHANGELOG

* fix(apple): correct SPM permission flag mapping for photos and calendarWriteOnly

- PERMISSION_PHOTOS now triggers on NSPhotoLibraryAddUsageDescription alone,
  since PhotoPermissionStrategy (which handles photosAddOnly) compiles under
  PERMISSION_PHOTOS — without this, photosAddOnly silently fell back to
  UnknownPermissionStrategy when NSPhotoLibraryUsageDescription was absent
- PERMISSION_EVENTS_FULL_ACCESS now also triggers on
  NSCalendarsWriteOnlyAccessUsageDescription (iOS 17+), enabling calendarWriteOnly
  which requires PERMISSION_EVENTS || PERMISSION_EVENTS_FULL_ACCESS in native code
- Sync podspec version to 9.4.8
- Restore NSCameraUsageDescription in example Info.plist (lost during rewrite)
- Add NSCalendarsWriteOnlyAccessUsageDescription to example Info.plist

* docs: add calendarWriteOnly to SPM permission table in README

* fix(example): remove NSSiriUsageDescription and document permission constraints

Siri requires the com.apple.developer.siri entitlement; including
NSSiriUsageDescription without it crashes the app on launch under SPM.
Added a README section listing permissions that cannot be tested on
simulator or without special entitlements.

* fix(apple): enable notifications and criticalAlerts by default under SPM

These permissions have no required Info.plist key so the previous logic
always compiled them out (defaultValue "0"), causing permanentlyDenied
to be returned without ever showing a system dialog.

They are now enabled by default and can be opted out via env var set to "0".

* fix(apple): revert criticalAlerts to opt-in under SPM

criticalAlerts requires a special Apple entitlement; compiling it into
every app by default would add dead code for apps that don't use it.
Only PERMISSION_NOTIFICATIONS defaults to enabled (no entitlement needed).

* docs: clarify SPM special cases for notification and criticalAlerts

- Add both permissions to the Info.plist table with notes
- Distinguish export (terminal) vs launchctl setenv (Xcode GUI)
- Explain why criticalAlerts is opt-in (Apple entitlement required)

* chore(example): enable SPM in Xcode project for iOS example app

Flutter auto-generated FlutterGeneratedPluginSwiftPackage reference
when running with --enable-swift-package-manager.

* fix(example): align Java source/target compatibility to VERSION_17

AGP 8.x + Kotlin 1.9+ enforce JVM-target consistency; compileJava was
still on 1.8 while compileKotlin used 17, causing the build to fail.

* Update version to 12.0.2

* fix typo in README about the compileSdkVersion (Baseflow#1472)

* docs: fix completeSdkVersion typo to compileSdkVersion (Baseflow#1494)

Fix incorrect Android SDK parameter name in documentation.

"completeSdkVersion" is not a valid Android parameter. The correct name is "compileSdkVersion". This prevents developer confusion when following the troubleshooting guide.

* Improved the iOS Setup section in permission_handler/README.md (Baseflow#1488)

After version 8.0.0, permission handler no longer uses all permissions on iOS, but this was not explained clearly in the README.
This is my attempt to fix that small mistake.

* Rewrite copyleft code from stackoverflow
>
> Co-authored-by: Novarest

* Bump permission_handler_apple to 9.4.9

* Bump permission_handler to 12.0.3

* Bump permission_handler_apple to 9.4.9

* Added ACCESS_LOCAL_NETWORK permission for android 17

* bump main package version

* missing defs

* dart formatting

* Update to use monorepo for managing development

* Linting, formatting, fix analysis issues

* Fix test for number of permissions

* Build after test (build is more time-costly)

* Fix permission_handler android build compileSdk

* Forgot to bump compilesdk version for android example app

* update code coverage for permission_handler_platform_interface, add android 37 sdk

* ...it is android 37.0, not android 37

* try to symlink the android-37.0 directory to android-37?

* ohhh...i think it is flutter.

* yes, flutter, but also outdated kotlin / gradle, etc

* accidental extra case during merge

* updated gitignore for ios

* Updated android plugin gradle / config

* remove ios ephemeral

* remove main permission_handler example ios ephemeral

---------

Co-authored-by: Gauhar <asanbayg@gmail.com>
Co-authored-by: harshit saini <harshitsaini666@gmail.com>
Co-authored-by: AlHomam Sultan <Hemobs24@gmail.com>
Co-authored-by: Maurits van Beusekom <maurits@vnbskm.nl>
Baseflow#1553)

The Package.swift manifest derives the PERMISSION_* macros from the host
app's Info.plist. Discovery failed in two independent ways:

- It only ever looked at `ios/Runner/Info.plist`, so apps using build
  configuration or flavor specific plists (`Info-Debug.plist`,
  `Runner/Info-$(CONFIGURATION).plist`, ...) were never matched.
- The app-root lookup required a pubspec.yaml and a loadable plist in the
  same condition, so a miss did not stop the walk-up at the app and could
  adopt an unrelated app's plist in a monorepo.

Info.plist locations are now resolved from INFOPLIST_FILE in the Xcode
project and any .xcconfig files, with a scan of `ios/` as a fallback, and
the usage description keys found across them are merged. The app root is
anchored on a pubspec.yaml next to an `ios/*.xcodeproj`, which is what
distinguishes a host app from a plugin package.

The INFOPLIST_FILE pattern is anchored so it cannot match inside
GENERATE_INFOPLIST_FILE, which Xcode writes into every target it creates
from a template, and candidates that are not files on disk no longer
count towards "the build settings produced something". Either one alone
was enough to suppress the fallback scan and compile out every
permission, for an app whose own target names its plist through a build
variable this manifest does not expand.

Adds PERMISSION_HANDLER_INFO_PLIST to point the manifest at specific
plists, which is the only mechanism available to builds started from
Xcode.app: those run with `/` as their working directory, and Xcode
passes none of its build settings to manifest evaluation.

Adds PERMISSION_HANDLER_VERBOSE to log the app root, the plists used and
the resolved macros, because Xcode discards manifest output entirely.

The example app's Debug configuration now uses a separate
`Info-Debug.plist` to cover the reported layout. It is identical to
Info.plist except that it declares no NSContactsUsageDescription, so
PERMISSION_CONTACTS can only resolve to 1 by merging the two, which is
what lets CI assert on the discovery rather than on the example's default
plist. A second CI step builds a project that forces the scan fallback.

Fixes Baseflow#1548
…/2) (Baseflow#1554)

* Add opt-in per-flavor permissions for Swift Package Manager builds

Permissions were merged across every Info.plist the manifest could find,
so an app whose dev flavor declares camera access compiled the camera
code into its prod binary too — the ITMS-90683 rejection the macros
exist to avoid.

An app can now declare a permission_handler.json next to its
pubspec.yaml, mapping each flavor to the single Info.plist that defines
it. Only the selected flavor's plist is read and nothing is merged, so a
flavor cannot inherit another flavor's permissions. Apps without the file
keep the previous behaviour.

This is a Swift Package Manager feature. CocoaPods builds take the
PERMISSION_* macros from the Podfile, where they can already be set per
configuration, so permission_handler.json does not apply to them and the
verification build phase exits early when the SPM package is not part of
the build. Without that the example, which builds under CocoaPods, would
require a flavor selection that changes nothing.

Selecting a flavor is a separate step rather than something the manifest
derives, because of three properties of Swift package manifests that were
measured rather than assumed:

- Xcode passes none of its build settings to manifest evaluation, so
  CONFIGURATION is not available and the manifest cannot know which
  flavor is building.
- Xcode does not re-evaluate a cached manifest when an environment
  variable or the selection changes. It keeps serving the previous
  answer until SourcePackages, XCBuildData and the shared SwiftPM
  manifest cache are gone.
- Scheme pre-actions run after package resolution, so they cannot
  prepare the selection for the build that follows.

`dart run permission_handler_apple:select <flavor>` therefore records the
choice and clears exactly those caches.

Since a cached manifest is never executed, nothing inside it can detect
that its own result went stale. tool/verify_flavor_selection.sh runs as a
build phase on the app target, where CONFIGURATION is available, and
fails the build when the selected flavor does not match the
configuration being built. It runs first in the phase list, so a mismatch
costs a second rather than a full compile, and it resolves the plugin
through either the SPM package or .symlinks so the same snippet works
whichever way a project consumes it.

A flavor whose infoPlist does not exist is an error rather than a
fallback to discovery: falling back would hand that flavor the union of
every other flavor's permissions, which is the leak this exists to stop.

The example declares two flavors over the two Info.plist files that
differ by a single key. CI asserts that neither flavor sees the other's
permission, that a missing selection compiles nothing in under
"strict": true, that a mismatched selection fails the build, and — with
the config switched off — that the merging path this replaces still
resolves both plists.

The repository .gitignore excluded every bin/ directory, which would have
dropped the new executable from the package; pub requires it to live
there.

* Use YAML for the per-flavor permission configuration

Flutter developers configure everything else in YAML, so the per-flavor
config moves from permission_handler.json to permission_handler.yaml, as
requested in review.

None of the build-time consumers can parse YAML natively: a Swift package
manifest cannot import libraries for its own evaluation and Foundation
has no YAML support, and the verification build phase runs on python3
whose standard library has none either. Rather than hand-rolling a YAML
parser in each of them, the `select` command becomes the single YAML
reader — it parses the config with package:yaml, the same parser pub
itself uses, and translates it into a generated
ios/Flutter/permission_handler.resolved.json that the manifest and the
build phase keep reading with the native JSON parsers they already had.

The generated file is an internal artifact: gitignored, never edited,
regenerated on every `select`. Two guards keep it from going stale.
The manifest and the build phase both refuse to build when the YAML is
newer than its translation or when the translation is missing, compiling
no permissions in and saying to re-run `select` — falling back to
discovery instead would hand the build the union of every flavor's
permissions, the exact leak the config exists to prevent.

`select` was already mandatory before any flavored build because Xcode
never re-evaluates a cached manifest, so the translation step adds no
new workflow.

CI gains a staleness assertion: touching permission_handler.yaml without
re-running `select` must compile everything out and name the guard in
the diagnostics.

* Reject ambiguous flavor configurations instead of guessing

Two flavors could list the same build configuration. Nothing rejected
that, and the verification build phase resolved it by taking whichever
came first, so selecting the flavor that configuration actually belongs
to failed the build with a message naming the other one — talking the
user into shipping the wrong flavor's permissions, which is the leak the
config exists to prevent.

A `configurations` written as a scalar rather than a list became an empty
list, silently removing every configuration of that flavor from the
verification phase's view. The build then reported that it could not
verify the permissions and continued.

`select` is the only reader of the YAML, so it is the only place where
either can be reported at all: everything downstream sees the generated
JSON, where a typo and a deliberate value are indistinguishable. It now
refuses a configuration claimed by more than one flavor, a
`configurations` that is not a list, a non-string flavor name, and a
`strict` that is not a boolean.

Three guards that failed open now fail closed. The manifest treated
unreadable modification times as "not stale" and built anyway; the
verification phase read a failing `find` as "not stale" for the same
reason; and PERMISSION_HANDLER_CONFIG was honoured only for locating the
YAML, while its generated translation and Info.plists were still resolved
against the automatically detected app — so the file that gated the
staleness check and the file that supplied the permissions could come
from two different apps.
…Baseflow#1555)

The "iOS - Swift Package Manager" section of permission_handler/README.md
is where most users will look, but it no longer covers what the package
does. This brings it up to date and points to the permission_handler_apple
README for the full detail, rather than duplicating documentation that
would drift.

Follow-up to Baseflow#1554, as discussed there.

The Info.plist key table was wrong in four places, checked against the
plistKeys of each macro in Package.swift: calendarWriteOnly and
calendarFullAccess were listed as two separate rows when both map to the
same macro (PERMISSION_EVENTS_FULL_ACCESS, either key enables both);
photos, location and bluetooth were each missing a second key they also
accept; and locationWhenInUse shared a row with location despite being a
narrower, separate macro. The section also claimed "no additional
configuration file is needed", which stopped being true with Baseflow#1554.

Separately, PERMISSION_HANDLER_VERBOSE was documented in both this README
and permission_handler_apple/README.md as always logging "the app root".
That only holds without a permission_handler.yaml; with one, it logs the
active flavor instead. Fixed in both places.

permission_handler_apple/README.md is the README this section now points
users to, so a few gaps found in the same pass are closed there too:
strict: false was never explained (only strict: true was), select's
validation added in Baseflow#1554 had one line covering one of its four rules,
and select --app / --derived-data were undocumented despite being what
makes the command usable in CI.

Adds to permission_handler/README.md: how Info.plist files are located
and merged across build configurations, a short flavors example pointing
to the full per-flavor documentation, the Xcode.app case, and a
troubleshooting block for the silent-denied failure mode behind Baseflow#1548.

No code changes, so no version bump and no CHANGELOG.md entry.
* Fix Android status reporting permanentlyDenied after "Ask every time"

On Android 11+, selecting "Ask every time" in the app settings revokes the
permission as a one-time permission, which clears FLAG_PERMISSION_USER_SET.
shouldShowRequestPermissionRationale() then returns false, exactly as for a
permission that was never requested or one that is permanently denied. The
plugin combined that with a "was denied before" flag in SharedPreferences
that was never cleared, so `status` kept reporting permanentlyDenied even
though the OS would show the request dialog again (Baseflow#1206).

- A status check now always reports `denied` for a denied runtime
  permission; Android offers no API to tell the three states apart.
- `request()` resolves permanentlyDenied from the change of the rationale
  flag across the request (true -> false means the second denial), falling
  back to the stored flag when the OS resolved the request without a dialog.
- The stored flag is cleared whenever the permission is observed granted.
- Docs, README and changelogs updated; versions bumped.

Verified on an Android 16 emulator with the example app: the old build
reports permanentlyDenied after "Ask every time", the fixed build reports
denied and shows the dialog on the next request.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* Add app adoption guide for the Android permanently-denied fix

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* Add app adoption guide for the Android permanently-denied fix

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
…w#1560)

The iOS CocoaPods setup mixed the calendar Podfile example with a camera
plist key, and "corresponding" was easy to read as pointing at step 2.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.