1import { 2 ConfigPlugin, 3 withPlugins, 4 withAndroidManifest, 5 AndroidConfig, 6 createRunOncePlugin, 7} from 'expo/config-plugins'; 8 9const pkg = require('expo-media-library/package.json'); 10 11const READ_PHOTOS_USAGE = 'Allow $(PRODUCT_NAME) to access your photos'; 12const WRITE_PHOTOS_USAGE = 'Allow $(PRODUCT_NAME) to save photos'; 13 14export function modifyAndroidManifest( 15 manifest: AndroidConfig.Manifest.AndroidManifest 16): AndroidConfig.Manifest.AndroidManifest { 17 // Starting with Android 10, the concept of scoped storage is introduced. 18 // Currently, to make expo-media-library working with that change, you have to add 19 // android:requestLegacyExternalStorage="true" to AndroidManifest.xml: 20 const app = AndroidConfig.Manifest.getMainApplicationOrThrow(manifest); 21 app.$['android:requestLegacyExternalStorage'] = 'true'; 22 return manifest; 23} 24 25const withMediaLibraryExternalStorage: ConfigPlugin = (config) => { 26 return withAndroidManifest(config, async (config) => { 27 config.modResults = modifyAndroidManifest(config.modResults); 28 return config; 29 }); 30}; 31 32const withMediaLibrary: ConfigPlugin< 33 { 34 photosPermission?: string; 35 savePhotosPermission?: string; 36 isAccessMediaLocationEnabled?: boolean; 37 } | void 38> = (config, { photosPermission, savePhotosPermission, isAccessMediaLocationEnabled } = {}) => { 39 if (!config.ios) config.ios = {}; 40 if (!config.ios.infoPlist) config.ios.infoPlist = {}; 41 config.ios.infoPlist.NSPhotoLibraryUsageDescription = 42 photosPermission || config.ios.infoPlist.NSPhotoLibraryUsageDescription || READ_PHOTOS_USAGE; 43 config.ios.infoPlist.NSPhotoLibraryAddUsageDescription = 44 savePhotosPermission || 45 config.ios.infoPlist.NSPhotoLibraryAddUsageDescription || 46 WRITE_PHOTOS_USAGE; 47 48 return withPlugins(config, [ 49 [ 50 AndroidConfig.Permissions.withPermissions, 51 [ 52 'android.permission.READ_EXTERNAL_STORAGE', 53 'android.permission.WRITE_EXTERNAL_STORAGE', 54 isAccessMediaLocationEnabled && 'android.permission.ACCESS_MEDIA_LOCATION', 55 ].filter(Boolean), 56 ], 57 withMediaLibraryExternalStorage, 58 ]); 59}; 60 61export default createRunOncePlugin(withMediaLibrary, pkg.name, pkg.version); 62