首页指南参考教程

Expo MediaLibrary iconExpo MediaLibrary

提供对设备媒体库的访问的库。

Android
iOS

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.

安装

¥Installation

Terminal
npx expo install expo-media-library

If you are installing this in an existing React Native app (bare workflow), start by installing expo in your project. Then, follow the additional instructions as mentioned by library's README under "Installation in bare React Native projects" section.

app.json/app.config.js 中的配置

¥Configuration in app.json/app.config.js

如果你在项目中使用配置插件(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.

Are you using this library in a bare React Native app?

了解如何在 expo-media-library 存储库中的安装说明 文件中配置原生项目。

¥Learn how to configure the native projects in the installation instructions in the expo-media-library repository.

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

NameDefaultDescription
photosPermission"Allow $(PRODUCT_NAME) to access your photos."
Only for:
iOS

Sets the iOS NSPhotoLibraryUsageDescription permission message in Info.plist.

savePhotosPermission"Allow $(PRODUCT_NAME) to save photos."
Only for:
iOS

Sets the iOS NSPhotoLibraryAddUsageDescription permission message in Info.plist.

isAccessMediaLocationEnabledfalse
Only for:
Android

Sets whether or not to request the ACCESS_MEDIA_LOCATION permission on Android.

用法

¥Usage

Fetching albums and displaying assets
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';

Constants

MediaLibrary.MediaType

Type: MediaTypeObject


Possible media types.

MediaLibrary.SortBy

Type: SortByObject


Supported keys that can be used to sort getAssetsAsync results.

Hooks

usePermissions(options)

NameType
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.

Returns:

[null | PermissionResponse, RequestPermissionMethod<PermissionResponse>, GetPermissionMethod<PermissionResponse>]

Example

const [permissionResponse, requestPermission] = MediaLibrary.usePermissions();

Methods

MediaLibrary.addAssetsToAlbumAsync(assets, album, copy)

NameTypeDescription
assetsAssetRef | AssetRef[]

An array of Asset or their IDs.

albumAlbumRef

An Album or its ID.

copy
(optional)
boolean

Android only. Whether to copy assets to the new album instead of move them. Defaults to true.

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.

Returns:

Promise<boolean>

Returns promise which fulfils with true if the assets were successfully added to the album.

MediaLibrary.albumNeedsMigrationAsync(album)

NameTypeDescription
albumAlbumRef

An Album or its ID.


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.

Returns:

Promise<boolean>

Returns a promise which fulfils with true if the album should be migrated.

MediaLibrary.createAlbumAsync(albumName, asset, copyAsset)

NameTypeDescription
albumNamestring

Name of the album to create.

asset
(optional)
AssetRef

An Asset or its ID (required on Android).

copyAsset
(optional)
boolean

Android Only. Whether to copy asset to the new album instead of move it. Defaults to true.

Default: true

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.

Returns:

Promise<Album>

Newly created Album.

MediaLibrary.createAssetAsync(localUri)

NameTypeDescription
localUristring

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 file:///


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.

Returns:

Promise<Asset>

A promise which fulfils with an object representing an Asset.

Example

const { uri } = await Camera.takePictureAsync();
const asset = await MediaLibrary.createAssetAsync(uri);

MediaLibrary.deleteAlbumsAsync(albums, assetRemove)

NameTypeDescription
albumsAlbumRef | AlbumRef[]

An array of Albums or their IDs.

assetRemove
(optional)
boolean

iOS Only. Whether to also delete assets belonging to given albums. Defaults to false.

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.

Returns:

Promise<boolean>

Returns a promise which fulfils with true if the albums were successfully deleted from the library.

MediaLibrary.deleteAssetsAsync(assets)

NameTypeDescription
assetsAssetRef | 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.

Returns:

Promise<boolean>

Returns promise which fulfils with true if the assets were successfully deleted.

MediaLibrary.getAlbumAsync(title)

NameTypeDescription
titlestring

Name of the album to look for.


Queries for an album with a specific name.

Returns:

Promise<Album>

MediaLibrary.getAlbumsAsync(namedParameters)

NameType
namedParameters
(optional)
AlbumsOptions

Queries for user-created albums in media gallery.

Returns:

Promise<Album[]>

MediaLibrary.getAssetInfoAsync(asset, options)

NameTypeDescription
assetAssetRef

An Asset or its ID.

options
(optional)
MediaLibraryAssetInfoQueryOptions-

Provides more information about an asset, including GPS location, local URI and EXIF metadata.

Returns:

Promise<AssetInfo>

An AssetInfo object, which is an Asset extended by an additional fields.

MediaLibrary.getAssetsAsync(assetsOptions)

NameType
assetsOptions
(optional)
AssetsOptions

Fetches a page of assets matching the provided criteria.

Returns:

Promise<PagedInfo<Asset>>

Only for:
iOS

MediaLibrary.getMomentsAsync()

Fetches a list of moments, which is a group of assets taken around the same place and time.

Returns:

Promise<any>

An array of albums whose type is moment.

MediaLibrary.getPermissionsAsync(writeOnly, granularPermissions)

NameTypeDescription
writeOnly
(optional)
boolean-
granularPermissions
(optional)
GranularPermission[]

A list of GranularPermission values. This parameter will have an effect only on Android API 33 and newer. By default, expo-media-library will ask for all possible permissions.


Checks user's permissions for accessing media library.

Returns:

Promise<PermissionResponse>

A promise that fulfils with PermissionResponse object.

MediaLibrary.isAvailableAsync()

Returns whether the Media Library API is enabled on the current device.

Returns:

Promise<boolean>

A promise which fulfils with a boolean, indicating whether the Media Library API is available on the current device.

MediaLibrary.migrateAlbumIfNeededAsync(album)

NameTypeDescription
albumAlbumRef

An Album or its ID.


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 will be rejected. 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.

Returns:

Promise<void>

A promise which fulfils to void.

MediaLibrary.presentPermissionsPickerAsync()

Available only on iOS >= 14. 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.

Returns:

Promise<void>

A promise that either rejects if the method is unavailable (meaning the device is not running iOS >= 14), or resolves to void.

Note: This method doesn't inform you if the user changes which assets your app has access to. For that information, you need to subscribe for updates to the user's media library using addListener(listener). If hasIncrementalChanges is false, the user changed their permissions.

MediaLibrary.removeAssetsFromAlbumAsync(assets, album)

NameTypeDescription
assetsAssetRef | AssetRef[]

An array of Asset or their IDs.

albumAlbumRef

An Album or its ID.


Removes given assets from album.

On Android, album will be automatically deleted if there are no more assets inside.

Returns:

Promise<boolean>

Returns promise which fulfils with true if the assets were successfully removed from the album.

MediaLibrary.removeSubscription(subscription)

NameType
subscriptionSubscription

Returns:

void

MediaLibrary.requestPermissionsAsync(writeOnly, granularPermissions)

NameTypeDescription
writeOnly
(optional)
boolean-
granularPermissions
(optional)
GranularPermission[]

A list of GranularPermission values. This parameter will have an effect only on Android API 33 and newer. By default, expo-media-library will ask for all possible permissions.


Asks the user to grant permissions for accessing media in user's media library.

Returns:

Promise<PermissionResponse>

A promise that fulfils with PermissionResponse object.

MediaLibrary.saveToLibraryAsync(localUri)

NameTypeDescription
localUristring

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 file:///.


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.

Returns:

Promise<void>

Event Subscriptions

MediaLibrary.addListener(listener)

NameTypeDescription
listener(event: MediaLibraryAssetsChangeEvent) => void

A callback that is fired when any assets have been inserted or deleted from the library, or when the user changes which assets they're allowing access to. On Android it's invoked with an empty object. On iOS it's invoked with MediaLibraryAssetsChangeEvent object.


Subscribes for updates in user's media library.

Returns:

Subscription

An Subscription object that you can call remove() on when you would like to unsubscribe the listener.

MediaLibrary.removeAllListeners()

Removes all listeners.

Returns:

void

Interfaces

EXPermissionResponse

An object obtained by permissions get and request functions.

EXPermissionResponse Properties

NameTypeDescription
canAskAgainboolean

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.

expiresPermissionExpiration

Determines time when the permission expires.

grantedboolean

A convenience boolean that indicates if the permission is granted.

statusPermissionStatus

Determines the status of the permission.


Types

Album

NameTypeDescription
approximateLocation
(optional)
Location
Only for:
iOS

Apply only to albums whose type is 'moment'. Approximated location of all assets in the moment.

assetCountnumber

Estimated number of assets in the album.

endTimenumber
Only for:
iOS

Apply only to albums whose type is 'moment'. Latest creation timestamp of all assets in the moment.

idstring

Album ID.

locationNames
(optional)
string[]
Only for:
iOS

Apply only to albums whose type is 'moment'. Names of locations grouped in the moment.

startTimenumber
Only for:
iOS

Apply only to albums whose type is 'moment'. Earliest creation timestamp of all assets in the moment.

titlestring

Album title.

type
(optional)
AlbumType
Only for:
iOS

The type of the assets album.

AlbumRef

Literal Type: multiple types

Acceptable values are: Album | string

AlbumType

Literal Type: string

Acceptable values are: 'album' | 'moment' | 'smartAlbum'

AlbumsOptions

NameTypeDescription
includeSmartAlbums
(optional)
boolean-

Asset

NameTypeDescription
albumId
(optional)
string
Only for:
Android

Album ID that the asset belongs to.

creationTimenumber

File creation timestamp.

durationnumber

Duration of the video or audio asset in seconds.

filenamestring

Filename of the asset.

heightnumber

Height of the image or video.

idstring

Internal ID that represents an asset.

mediaSubtypes
(optional)
MediaSubtype[]
Only for:
iOS

An array of media subtypes.

mediaTypeMediaTypeValue

Media type.

modificationTimenumber

Last modification timestamp.

uristring

URI that points to the asset. assets://* (iOS), file://* (Android)

widthnumber

Width of the image or video.

AssetInfo

Type: Asset extended by:


NameTypeDescription
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 shouldDownloadFromNetwork is set to false. Whether the asset is stored on the network (iCloud on iOS).

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 mediaType is MediaType.photo. Value will range from 1 to 8, see EXIF orientation specification for more details.

AssetRef

Literal Type: multiple types

Acceptable values are: Asset | string

AssetsOptions

NameTypeDescription
after
(optional)
AssetRef

Asset ID of the last item returned on the previous page. To get the ID of the next page, pass endCursor as its value.

album
(optional)
AlbumRef

Album or its ID to get assets from specific album.

createdAfter
(optional)
Date | number

Date object or Unix timestamp in milliseconds limiting returned assets only to those that were created after this date.

createdBefore
(optional)
Date | number

Similarly as createdAfter, but limits assets only to those that were created before specified date.

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 MediaTypeValue.

Default: MediaType.photo
sortBy
(optional)
SortByValue[] | SortByValue

An array of SortByValues or a single SortByValue value. By default, all keys are sorted in descending order, however you can also pass a pair [key, ascending] where the second item is a boolean value that means whether to use ascending order. Note that if the SortBy.default key is used, then ascending argument will not matter. Earlier items have higher priority when sorting out the results. If empty, this method will use the default sorting that is provided by the platform.

Only for:
Android API 33+

GranularPermission

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'

Location

NameTypeDescription
latitudenumber-
longitudenumber-

MediaLibraryAssetInfoQueryOptions

NameTypeDescription
shouldDownloadFromNetwork
(optional)
boolean

Whether allow the asset to be downloaded from network. Only available in iOS with iCloud assets.

Default: true

MediaLibraryAssetsChangeEvent

NameTypeDescription
deletedAssets
(optional)
Asset[]

Available only if hasIncrementalChanges is true. Array of Assets that have been deleted from the library.

hasIncrementalChangesboolean

Whether the media library's changes could be described as "incremental changes". true indicates the changes are described by the insertedAssets, deletedAssets and updatedAssets values. false indicates that the scope of changes is too large and you should perform a full assets reload (eg. a user has changed access to individual assets in the media library).

insertedAssets
(optional)
Asset[]

Available only if hasIncrementalChanges is true. Array of Assets that have been inserted to the library.

updatedAssets
(optional)
Asset[]

Available only if hasIncrementalChanges is true. Array of Assets that have been updated or completed downloading from network storage (iCloud on iOS).

MediaSubtype

Literal Type: string

Acceptable values are: 'depthEffect' | 'hdr' | 'highFrameRate' | 'livePhoto' | 'panorama' | 'screenshot' | 'stream' | 'timelapse'

MediaTypeObject

NameTypeDescription
audio'audio'-
photo'photo'-
unknown'unknown'-
video'video'-

MediaTypeValue

Literal Type: string

Acceptable values are: 'audio' | 'photo' | 'video' | 'unknown'

PagedInfo

NameTypeDescription
assetsT[]

A page of Assets fetched by the query.

endCursorstring

ID of the last fetched asset. It should be passed as after option in order to get the next page.

hasNextPageboolean

Whether there are more assets to fetch.

totalCountnumber

Estimated total number of assets that match the query.

PermissionExpiration

Literal Type: multiple types

Permission expiration time. Currently, all permissions are granted permanently.

Acceptable values are: 'never' | number

PermissionHookOptions

Literal Type: multiple types

Acceptable values are: PermissionHookBehavior | Options

PermissionResponse

Type: EXPermissionResponse extended by:


NameTypeDescription
accessPrivileges
(optional)
'all' | 'limited' | 'none'

Indicates if your app has access to the whole or only part of the photo library. Possible values are:

  • 'all' if the user granted your app access to the whole photo library
  • 'limited' if the user granted your app access only to selected photos (only available on Android API 34+ and iOS 14.0+)
  • 'none' if user denied or hasn't yet granted the permission

SortByKey

Literal Type: string

Acceptable values are: 'default' | 'mediaType' | 'width' | 'height' | 'creationTime' | 'modificationTime' | 'duration'

SortByObject

NameTypeDescription
creationTime'creationTime'-
default'default'-
duration'duration'-
height'height'-
mediaType'mediaType'-
modificationTime'modificationTime'-
width'width'-

SortByValue

Literal Type: multiple types

Acceptable values are: [SortByKey, boolean] | SortByKey

Subscription

NameTypeDescription
remove() => void

A method to unsubscribe the listener.

Enums

PermissionStatus

PermissionStatus Values

DENIED

PermissionStatus.DENIED = "denied"

User has denied the permission.

GRANTED

PermissionStatus.GRANTED = "granted"

User has granted the permission.

UNDETERMINED

PermissionStatus.UNDETERMINED = "undetermined"

User hasn't granted or denied the permission yet.

权限

¥Permissions

安卓

¥Android

以下权限是通过该库的 AndroidManifest.xml 自动添加的。

¥The following permissions are added automatically through this library's AndroidManifest.xml.

Android PermissionDescription

READ_EXTERNAL_STORAGE

Allows an application to read from external storage.

WRITE_EXTERNAL_STORAGE

Allows an application to write to external storage.

iOS 系统

¥iOS

该库使用以下用法描述键:

¥The following usage description keys are used by this library:

Info.plist KeyDescription

NSPhotoLibraryUsageDescription

A message that tells the user why the app is requesting access to the user’s photo library.

NSPhotoLibraryAddUsageDescription

A message that tells the user why the app is requesting add-only access to the user’s photo library.
Expo 中文网 - 粤ICP备13048890号