feat: Add support for Android 14 granular media permissions
๐ Android 14 (API 34) Granular Media Permissions Support
๐ Summary
This PR adds full support for Android 14's new granular media permissions, resolving runtime permission failures and providing an excellent user experience with the new permission model.
๐ Problem Solved
Issue: Users on Android 14 experience runtime permission failures where the image picker cannot access photos, even when permissions appear to be granted.
Root Cause: Android 14 introduced granular media permissions where users can choose between:
- "Select photos and videos" โ Grants
READ_MEDIA_VISUAL_USER_SELECTED(partial access) - "Allow access to all media" โ Grants
READ_MEDIA_IMAGES+READ_MEDIA_VIDEO(full access)
The library was only checking for full access permissions, causing failures when users chose partial access.
โจ What's New
๐ Smart Permission Handling
- Automatic Detection: Intelligently detects partial vs full media access
- Graceful Degradation: App works perfectly with limited access
- Permission Upgrade Flow: Non-intrusive prompts to upgrade from partial to full access
- Backward Compatibility: Zero breaking changes, works seamlessly on older Android versions
๐๏ธ Developer-Friendly Configuration
// Easy configuration options
val config = ImagePickerConfig()
.enableGranularPermissions() // Best UX (default)
.requireFullMediaAccess() // Legacy behavior
.minimalPermissionUI() // No upgrade prompts
.granularPermissions { // Custom configuration
showUpgradePrompt = true
allowPartialAccess = true
partialAccessMessage = "Custom message"
}
๐ฑ Enhanced User Experience
- Users can start with limited access and upgrade when needed
- Clear messaging about permission levels
- Smooth upgrade flow without app restart
- Respects user privacy choices
๐ง Technical Changes
New Files Added
-
MediaPermissionHelper.kt- Centralized permission logic and state detection -
GranularPermissionConfig.kt- Configuration class for permission behavior -
docs/android_14_migration.md- Comprehensive migration guide
Files Modified
-
AndroidManifest.xml- AddedREAD_MEDIA_VISUAL_USER_SELECTEDpermission -
ImagePickerFragment.kt- Enhanced with granular permission logic -
DefaultImageFileLoader.kt- Added partial access support -
ImagePickerConfig.kt- New configuration options and extension functions -
strings.xml- New permission-related messages -
MainActivity.kt(sample) - Updated with Android 14 examples -
README.md- Added Android 14 information -
CHANGELOG.md- Documented new features
Key Technical Features
-
Permission State Detection: Automatically detects
FULL_ACCESS,PARTIAL_ACCESS,NO_ACCESS, andLEGACY_ACCESSstates - Smart File Loading: Handles MediaStore queries for both full and partial access scenarios
- Security Exception Handling: Graceful handling when partial access limits queries
- Upgrade Flow: Seamless permission upgrade without app restart
๐งช Testing
Tested Scenarios
- โ Fresh install on Android 14 with both permission choices
- โ Permission upgrade flow from partial to full access
- โ Backward compatibility on Android 13 and below
- โ Permission revocation and re-granting
- โ App backgrounding during permission flows
Test Commands
# Grant partial access for testing
adb shell pm grant com.yourapp.package android.permission.READ_MEDIA_VISUAL_USER_SELECTED
# Grant full access for testing
adb shell pm grant com.yourapp.package android.permission.READ_MEDIA_IMAGES
adb shell pm grant com.yourapp.package android.permission.READ_MEDIA_VIDEO
# Revoke permissions for testing
adb shell pm revoke com.yourapp.package android.permission.READ_MEDIA_IMAGES
๐ Documentation
New Documentation
- Complete Migration Guide: Step-by-step guide for Android 14 support
- Configuration Examples: Multiple configuration patterns for different use cases
- Testing Guide: How to test both permission flows
- Troubleshooting: Common issues and solutions
Updated Documentation
- README: Added Android 14 support section
- CHANGELOG: Detailed feature documentation
- Sample App: Updated with granular permission examples
๐ Backward Compatibility
100% Backward Compatible - No breaking changes:
- โ Existing code continues to work without modifications
- โ Android 13 and below work exactly as before
- โ All existing APIs remain unchanged
- โ Graceful fallback for older Android versions
- โ No new required dependencies
๐ฏ Migration Path
For Existing Users (Zero Changes Required)
// This continues to work exactly as before
val launcher = registerImagePicker { images ->
// handle images
}
launcher.launch(ImagePickerConfig())
For New Android 14 Features (Optional)
// Enable the best Android 14 experience
val config = ImagePickerConfig()
.enableGranularPermissions()
launcher.launch(config)
๐ Impact
Before This PR
- โ Runtime failures on Android 14
- โ Poor user experience with permission errors
- โ No support for partial media access
After This PR
- โ Seamless Android 14 support
- โ Excellent user experience with granular permissions
- โ Smart permission upgrade flows
- โ Full backward compatibility
- โ Comprehensive documentation
๐ Benefits
- Fixes Critical Issue: Resolves runtime permission failures on Android 14
- Future-Proof: Ready for Android's privacy-first direction
- User-Friendly: Respects user privacy choices while providing upgrade paths
- Developer-Friendly: Easy configuration with sensible defaults
- Zero Migration Cost: Existing code works without changes
๐ Checklist
- [x] Added Android 14 permission support
- [x] Implemented permission upgrade flow
- [x] Added comprehensive configuration options
- [x] Updated documentation and examples
- [x] Maintained 100% backward compatibility
- [x] Added proper error handling
- [x] Updated sample app
- [x] Added migration guide
- [x] Updated CHANGELOG
๐ Related Issues
Fixes runtime permission failures on Android 14 devices where users experience image loading issues despite granting permissions.
This PR ensures your Android image picker library provides an excellent experience on Android 14 while maintaining full compatibility with existing implementations.