Expo MediaLibrary
提供对设备媒体库的访问的库。
expo-media-library
提供对用户媒体库的访问,允许他们从你的应用访问现有的图片和视频,以及保存新的图片和视频。你还可以订阅对用户媒体库所做的任何更新。
¥expo-media-library
provides access to the user's media library, allowing them to access their existing images and videos from your app, as well as save new ones. You can also subscribe to any updates made to the user's media library.
Android 仅允许需要广泛访问照片的应用完全访问媒体库(这是此包的目的)。参见 Google Play 照片和视频权限政策详情。
安装
¥Installation
-
npx expo install expo-media-library
If you are installing this in an existing React Native app, make sure to install expo
in your project.
应用配置中的配置
¥Configuration in app config
如果你在项目中使用配置插件(EAS 构建 或 npx expo run:[android|ios]
),则可以使用其内置的 配置插件 配置 expo-media-library
。该插件允许你配置无法在运行时设置的各种属性,并且需要构建新的应用二进制文件才能生效。
¥You can configure expo-media-library
using its built-in config plugin if you use config plugins in your project (EAS Build or npx expo run:[android|ios]
). The plugin allows you to configure various properties that cannot be set at runtime and require building a new app binary to take effect.
Example app.json with config plugin
{
"expo": {
"plugins": [
[
"expo-media-library",
{
"photosPermission": "Allow $(PRODUCT_NAME) to access your photos.",
"savePhotosPermission": "Allow $(PRODUCT_NAME) to save photos.",
"isAccessMediaLocationEnabled": true
}
]
]
}
}
Configurable properties
Name | Default | Description |
---|---|---|
photosPermission | "Allow $(PRODUCT_NAME) to access your photos." | Only for: iOS Sets the iOS |
savePhotosPermission | "Allow $(PRODUCT_NAME) to save photos." | Only for: iOS Sets the iOS |
preventAutomaticLimitedAccessAlert | false | Only for: iOS Prevents the automatic limited access alert from being shown when the user has limited access to the photo library. Useful for apps that want to access only the limited photo library without having iOS forcibly show the alert. |
isAccessMediaLocationEnabled | false | Only for: Android Sets whether or not to request the |
Are you using this library in an existing React Native app?
如果你未使用持续原生生成 (CNG) 或手动使用原生 Android/iOS 项目,则需要为原生项目添加以下权限和配置:
¥If you're not using Continuous Native Generation (CNG) or you're using native android ios projects manually, then you need to add following permissions and configuration to your native projects:
安卓
¥Android
-
要访问资源位置(经纬度 EXIF 标签),请在项目的 android/app/src/main/AndroidManifest.xml 中添加
ACCESS_MEDIA_LOCATION
权限:¥To access asset location (latitude and longitude EXIF tags), add
ACCESS_MEDIA_LOCATION
permission to your project's android/app/src/main/AndroidManifest.xml:
<uses-permission android:name="android.permission.ACCESS_MEDIA_LOCATION" />
-
分区存储 从 Android 10 开始可用。要使
expo-media-library
与分区存储配合使用,你需要在 android/app/src/main/AndroidManifest.xml 中添加以下配置:¥Scoped storage is available from Android 10. To make
expo-media-library
work with scoped storage, you need to add the following configuration to your android/app/src/main/AndroidManifest.xml:
<manifest ... >
<application android:requestLegacyExternalStorage="true" ...>
</manifest>
iOS 系统
¥iOS
-
将
NSPhotoLibraryUsageDescription
和NSPhotoLibraryAddUsageDescription
键添加到项目的 ios/[app]/Info.plist 中:¥Add
NSPhotoLibraryUsageDescription
, andNSPhotoLibraryAddUsageDescription
keys to your project's ios/[app]/Info.plist:
<key>NSPhotoLibraryUsageDescription</key>
<string>Give $(PRODUCT_NAME) permission to access your photos</string>
<key>NSPhotoLibraryAddUsageDescription</key>
<string>Give $(PRODUCT_NAME) permission to save photos</string>
用法
¥Usage
import { useState, useEffect } from 'react';
import { Button, Text, SafeAreaView, ScrollView, StyleSheet, Image, View, Platform } from 'react-native';
import * as MediaLibrary from 'expo-media-library';
export default function App() {
const [albums, setAlbums] = useState(null);
const [permissionResponse, requestPermission] = MediaLibrary.usePermissions();
async function getAlbums() {
if (permissionResponse.status !== 'granted') {
await requestPermission();
}
const fetchedAlbums = await MediaLibrary.getAlbumsAsync({
includeSmartAlbums: true,
});
setAlbums(fetchedAlbums);
}
return (
<SafeAreaView style={styles.container}>
<Button onPress={getAlbums} title="Get albums" />
<ScrollView>
{albums && albums.map((album) => <AlbumEntry album={album} />)}
</ScrollView>
</SafeAreaView>
);
}
function AlbumEntry({ album }) {
const [assets, setAssets] = useState([]);
useEffect(() => {
async function getAlbumAssets() {
const albumAssets = await MediaLibrary.getAssetsAsync({ album });
setAssets(albumAssets.assets);
}
getAlbumAssets();
}, [album]);
return (
<View key={album.id} style={styles.albumContainer}>
<Text>
{album.title} - {album.assetCount ?? 'no'} assets
</Text>
<View style={styles.albumAssetsContainer}>
{assets && assets.map((asset) => (
<Image source={{ uri: asset.uri }} width={50} height={50} />
))}
</View>
</View>
);
}
%%placeholder-start%%const styles = StyleSheet.create({ ... }); %%placeholder-end%%const styles = StyleSheet.create({
container: {
flex: 1,
gap: 8,
justifyContent: 'center',
...Platform.select({
android: {
paddingTop: 40,
},
}),
},
albumContainer: {
paddingHorizontal: 20,
marginBottom: 12,
gap: 4,
},
albumAssetsContainer: {
flexDirection: 'row',
flexWrap: 'wrap',
},
});
`
API
import * as MediaLibrary from 'expo-media-library';
Component
Constants
Type: SortByObject
Supported keys that can be used to sort getAssetsAsync
results.
Hooks
Parameter | Type |
---|---|
options(optional) | PermissionHookOptions<{
granularPermissions: GranularPermission[],
writeOnly: boolean
}> |
Check or request permissions to access the media library.
This uses both requestPermissionsAsync
and getPermissionsAsync
to interact with the permissions.
[null | PermissionResponse, RequestPermissionMethod<PermissionResponse>, GetPermissionMethod<PermissionResponse>]
Example
const [permissionResponse, requestPermission] = MediaLibrary.usePermissions();
Methods
Parameter | Type | Description |
---|---|---|
assets | AssetRef | AssetRef[] | An array of Asset or their IDs. |
album | AlbumRef | An Album or its ID. |
copy(optional) | boolean | Android only. Whether to copy assets to the new album instead of move them.
Defaults to Default: true |
Adds array of assets to the album.
On Android, by default it copies assets from the current album to provided one, however it's also
possible to move them by passing false
as copyAssets
argument. In case they're copied you
should keep in mind that getAssetsAsync
will return duplicated assets.
Promise<boolean>
Returns promise which fulfils with true
if the assets were successfully added to
the album.
Checks if the album should be migrated to a different location. In other words, it checks if the
application has the write permission to the album folder. If not, it returns true
, otherwise false
.
Note: For Android below R, web or iOS, this function always returns
false
.
Promise<boolean>
Returns a promise which fulfils with true
if the album should be migrated.
Parameter | Type | Description |
---|---|---|
albumName | string | Name of the album to create. |
asset(optional) | AssetRef | An Asset or its ID. On Android you either need to provide an asset or a localUri. |
copyAsset(optional) | boolean | Android Only. Whether to copy asset to the new album instead of move it. This parameter is ignored if Default: true |
initialAssetLocalUri(optional) | string | A URI to the local media file, which will be used to create the initial asset inside the album. It must contain an extension. On Android it
must be a local path, so it must start with |
Creates an album with given name and initial asset. The asset parameter is required on Android,
since it's not possible to create empty album on this platform. On Android, by default it copies
given asset from the current album to the new one, however it's also possible to move it by
passing false
as copyAsset
argument.
In case it's copied you should keep in mind that getAssetsAsync
will return duplicated asset.
On Android, it's not possible to create an empty album. You must provide an existing asset to copy or move into the album or an uri of a local file, which will be used to create an initial asset for the album.
Newly created Album
.
Parameter | Type | Description |
---|---|---|
localUri | string | A URI to the image or video file. It must contain an extension. On Android it
must be a local path, so it must start with |
album(optional) | AlbumRef | An Album or its ID. If provided, the asset will be added to this album upon creation, otherwise it will be added to the default album for the media type. The album has exist. |
Creates an asset from existing file. The most common use case is to save a picture taken by Camera.
This method requires CAMERA_ROLL
permission.
A promise which fulfils with an object representing an Asset
.
Example
const { uri } = await Camera.takePictureAsync();
const asset = await MediaLibrary.createAssetAsync(uri);
Parameter | Type | Description |
---|---|---|
albums | AlbumRef | AlbumRef[] | An array of |
assetRemove(optional) | boolean | iOS Only. Whether to also delete assets belonging to given albums.
Defaults to Default: false |
Deletes given albums from the library. On Android by default it deletes assets belonging to given
albums from the library. On iOS it doesn't delete these assets, however it's possible to do by
passing true
as deleteAssets
.
Promise<boolean>
Returns a promise which fulfils with true
if the albums were successfully deleted from
the library.
Parameter | Type | Description |
---|---|---|
assets | AssetRef | AssetRef[] | An array of Asset or their IDs. |
Deletes assets from the library. On iOS it deletes assets from all albums they belong to, while on Android it keeps all copies of them (album is strictly connected to the asset). Also, there is additional dialog on iOS that requires user to confirm this action.
Promise<boolean>
Returns promise which fulfils with true
if the assets were successfully deleted.
Parameter | Type | Description |
---|---|---|
title | string | Name of the album to look for. |
Parameter | Type | Description |
---|---|---|
asset | AssetRef | An Asset or its ID. |
options(optional) | MediaLibraryAssetInfoQueryOptions | - |
Parameter | Type |
---|---|
assetsOptions(optional) | AssetsOptions |
Parameter | Type | Description |
---|---|---|
writeOnly(optional) | boolean | - |
granularPermissions(optional) | GranularPermission[] | A list of |
Checks user's permissions for accessing media library.
Promise<PermissionResponse>
A promise that fulfils with PermissionResponse
object.
Returns whether the Media Library API is enabled on the current device.
Promise<boolean>
A promise which fulfils with a boolean
, indicating whether the Media Library API is
available on the current device.
Moves album content to the special media directories on Android R or above if needed.
Those new locations are in line with the Android scoped storage
- so your application won't
lose write permission to those directories in the future.
This method does nothing if:
- app is running on iOS, web or Android below R
- app has write permission to the album folder
The migration is possible when the album contains only compatible files types.
For instance, movies and pictures are compatible with each other, but music and pictures are not.
If automatic migration isn't possible, the function rejects.
In that case, you can use methods from the expo-file-system
to migrate all your files manually.
Why do you need to migrate files?
Android R introduced a lot of changes in the storage system. Now applications can't save
anything to the root directory. The only available locations are from the MediaStore
API.
Unfortunately, the media library stored albums in folders for which, because of those changes,
the application doesn't have permissions anymore. However, it doesn't mean you need to migrate
all your albums. If your application doesn't add assets to albums, you don't have to migrate.
Everything will work as it used to. You can read more about scoped storage in the Android documentation.
Promise<void>
A promise which fulfils to void
.
Parameter | Type | Description |
---|---|---|
mediaTypes(optional) | MediaTypeFilter[] | Limits the type(s) of media that the user will be granting access to. By default, a list that shows both photos and videos is presented. |
Allows the user to update the assets that your app has access to.
The system modal is only displayed if the user originally allowed only limited
access to their
media library, otherwise this method is a no-op.
Promise<void>
A promise that either rejects if the method is unavailable, or resolves to void
.
Note: This method doesn't inform you if the user changes which assets your app has access to. That information is only exposed by iOS, and to obtain it, you need to subscribe for updates to the user's media library using
addListener()
. IfhasIncrementalChanges
isfalse
, the user changed their permissions.
Parameter | Type | Description |
---|---|---|
assets | AssetRef | AssetRef[] | An array of Asset or their IDs. |
album | AlbumRef | An Album or its ID. |
Removes given assets from album.
On Android, album will be automatically deleted if there are no more assets inside.
Promise<boolean>
Returns promise which fulfils with true
if the assets were successfully removed from
the album.
Parameter | Type | Description |
---|---|---|
writeOnly(optional) | boolean | - |
granularPermissions(optional) | GranularPermission[] | A list of |
Asks the user to grant permissions for accessing media in user's media library.
Promise<PermissionResponse>
A promise that fulfils with PermissionResponse
object.
Parameter | Type | Description |
---|---|---|
localUri | string | A URI to the image or video file. It must contain an extension. On Android it
must be a local path, so it must start with |
Saves the file at given localUri
to the user's media library. Unlike createAssetAsync()
,
This method doesn't return created asset.
On iOS 11+, it's possible to use this method without asking for CAMERA_ROLL
permission,
however then yours Info.plist
should have NSPhotoLibraryAddUsageDescription
key.
Promise<void>
Event Subscriptions
Parameter | Type | Description |
---|---|---|
listener | (event: MediaLibraryAssetsChangeEvent) => void | A callback that is fired when any assets have been inserted or deleted from the
library. On Android it's invoked with an empty object. On iOS, it's invoked with Additionally, only on iOS, the listener is also invoked when the user changes access to individual assets in the media library
using |
Subscribes for updates in user's media library.
EventSubscription
An Subscription
object that you can call remove()
on when you would
like to unsubscribe the listener.
Interfaces
A subscription object that allows to conveniently remove an event listener from the emitter.
Types
Property | Type | Description |
---|---|---|
approximateLocation(optional) | Location | Only for: iOS Apply only to albums whose type is |
assetCount | number | Estimated number of assets in the album. |
endTime | number | Only for: iOS Apply only to albums whose type is |
id | string | Album ID. |
locationNames(optional) | string[] | Only for: iOS Apply only to albums whose type is |
startTime | number | Only for: iOS Apply only to albums whose type is |
title | string | Album title. |
type(optional) | AlbumType | Only for: iOS The type of the assets album. |
Property | Type | Description |
---|---|---|
albumId(optional) | string | Only for: Android Album ID that the asset belongs to. |
creationTime | number | File creation timestamp. |
duration | number | Duration of the video or audio asset in seconds. |
filename | string | Filename of the asset. |
height | number | Height of the image or video. |
id | string | Internal ID that represents an asset. |
mediaSubtypes(optional) | MediaSubtype[] | Only for: iOS An array of media subtypes. |
mediaType | MediaTypeValue | Media type. |
modificationTime | number | Last modification timestamp. |
uri | string | URI that points to the asset. |
width | number | Width of the image or video. |
Type: Asset
extended by:
Property | Type | Description |
---|---|---|
exif(optional) | object | EXIF metadata associated with the image. |
isFavorite(optional) | boolean | Only for: iOS Whether the asset is marked as favorite. |
isNetworkAsset(optional) | boolean | Only for: iOS This field is available only if flag |
localUri(optional) | string | Local URI for the asset. |
location(optional) | Location | GPS location if available. |
orientation(optional) | number | Only for: iOS Display orientation of the image. Orientation is available only for assets whose
|
pairedVideoAsset(optional) | Asset | null | Only for: iOS Contains information about the video paired with the image file.
This field is available if the |
Property | Type | Description |
---|---|---|
after(optional) | AssetRef | Asset ID of the last item returned on the previous page. To get the ID of the next page,
pass |
album(optional) | AlbumRef | Album or its ID to get assets from specific album. |
createdAfter(optional) | Date | number |
|
createdBefore(optional) | Date | number | Similarly as |
first(optional) | number | The maximum number of items on a single page. Default: 20 |
mediaType(optional) | MediaTypeValue[] | MediaTypeValue | An array of MediaTypeValues or a single Default: MediaType.photo |
sortBy(optional) | SortByValue[] | SortByValue | An array of |
An object obtained by permissions get and request functions.
Property | Type | Description |
---|---|---|
canAskAgain | boolean | Indicates if user can be asked again for specific permission. If not, one should be directed to the Settings app in order to enable/disable the permission. |
expires | PermissionExpiration | Determines time when the permission expires. |
granted | boolean | A convenience boolean that indicates if the permission is granted. |
status | PermissionStatus | Determines the status of the permission. |
Literal Type: string
Determines the type of media that the app will ask the OS to get access to.
Acceptable values are: 'audio'
| 'photo'
| 'video'
Property | Type | Description |
---|---|---|
shouldDownloadFromNetwork(optional) | boolean | Whether allow the asset to be downloaded from network. Only available in iOS with iCloud assets. Default: true |
Property | Type | Description |
---|---|---|
deletedAssets(optional) | Asset[] | Available only if |
hasIncrementalChanges | boolean | Whether the media library's changes could be described as "incremental changes".
|
insertedAssets(optional) | Asset[] | Available only if |
updatedAssets(optional) | Asset[] | Available only if |
Literal Type: string
Constants identifying specific variations of asset media, such as panorama or screenshot photos, and time-lapse or high-frame-rate video. Maps to these values.
Acceptable values are: 'depthEffect'
| 'hdr'
| 'highFrameRate'
| 'livePhoto'
| 'panorama'
| 'screenshot'
| 'stream'
| 'timelapse'
Literal Type: string
Represents the possible types of media that the app will ask the OS to get access to when calling presentPermissionsPickerAsync()
.
Acceptable values are: 'photo'
| 'video'
Literal Type: string
Acceptable values are: 'audio'
| 'photo'
| 'video'
| 'unknown'
| 'pairedVideo'
Property | Type | Description |
---|---|---|
assets | T[] | A page of |
endCursor | string | ID of the last fetched asset. It should be passed as |
hasNextPage | boolean | Whether there are more assets to fetch. |
totalCount | number | Estimated total number of assets that match the query. |
Literal Type: union
Permission expiration time. Currently, all permissions are granted permanently.
Acceptable values are: 'never'
| number
Type: EXPermissionResponse
extended by:
Property | Type | Description |
---|---|---|
accessPrivileges(optional) | 'all' | 'limited' | 'none' | Indicates if your app has access to the whole or only part of the photo library. Possible values are:
|
Literal Type: string
Acceptable values are: 'default'
| 'mediaType'
| 'width'
| 'height'
| 'creationTime'
| 'modificationTime'
| 'duration'
Property | Type | Description |
---|---|---|
creationTime | 'creationTime' | - |
default | 'default' | - |
duration | 'duration' | - |
height | 'height' | - |
mediaType | 'mediaType' | - |
modificationTime | 'modificationTime' | - |
width | 'width' | - |
Enums
权限
¥Permissions
安卓
¥Android
以下权限通过此库的 AndroidManifest.xml 自动添加:
¥The following permissions are added automatically through this library's AndroidManifest.xml:
Android Permission | Description |
---|---|
Allows an application to read from external storage. | |
Allows an application to write to external storage. | |
Allows an application to read image files from external storage. | |
Allows an application to read video files from external storage. | |
Allows an application to read audio files from external storage. | |
Allows an application to read image or video files from external storage that a user has selected via the permission prompt photo picker.
|
iOS 系统
¥iOS
该库使用以下用法描述键:
¥The following usage description keys are used by this library: