Skip to content

Commit 7c0fee5

Browse files
Wenszelbehenate
andauthored
[media-library][next] Add docs (expo#39754)
Co-authored-by: Wojciech Dróżdż <[email protected]>
1 parent 843672d commit 7c0fee5

File tree

21 files changed

+418
-127
lines changed

21 files changed

+418
-127
lines changed
Lines changed: 240 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,240 @@
1+
---
2+
title: MediaLibrary (next)
3+
description: A library that provides access to the device's media library.
4+
sourceCodeUrl: 'https://github.com/expo/expo/tree/main/packages/expo-media-library/next'
5+
packageName: 'expo-media-library'
6+
iconUrl: '/static/images/packages/expo-media-library.png'
7+
platforms: ['android', 'ios', 'tvos']
8+
isNew: true
9+
---
10+
11+
import APISection from '~/components/plugins/APISection';
12+
import { APIInstallSection } from '~/components/plugins/InstallSection';
13+
import { Collapsible } from '~/ui/components/Collapsible';
14+
import { SnackInline } from '~/ui/components/Snippet';
15+
16+
`expo-media-library` provides access to the user's media library, allowing apps to read existing images and videos, as well as save new ones.
17+
18+
> **warning** On Android, full access to the media library (the main purpose of this package) is allowed only for apps that require broad access to photos. See [details on Google Play's Photo and Video Permissions policy](https://support.google.com/googleplay/android-developer/answer/14115180).
19+
20+
## Installation
21+
22+
<APIInstallSection />
23+
24+
## Usage
25+
26+
<Collapsible summary="Add a new asset from the web">
27+
<SnackInline label="Add a new asset from the web" dependencies={['expo-file-system', 'expo-image', 'expo-media-library']}>
28+
29+
```tsx
30+
import { View, Text } from 'react-native';
31+
import { Image } from 'expo-image';
32+
import { useEffect, useState } from 'react';
33+
import { File, Paths } from 'expo-file-system';
34+
import { Asset, requestPermissionsAsync } from 'expo-media-library/next';
35+
36+
export default function SaveToMediaLibraryExample() {
37+
const [asset, setAsset] = useState<Asset | null>(null);
38+
39+
const downloadFile = async () => {
40+
const url = 'https://picsum.photos/200/300';
41+
const destinationFile = new File(Paths.cache, 'test_image.jpg');
42+
if (destinationFile.exists) {
43+
return destinationFile;
44+
} else {
45+
return File.downloadFileAsync(url, destinationFile);
46+
}
47+
};
48+
49+
useEffect(() => {
50+
const downloadAndSaveAsset = async () => {
51+
const file = await downloadFile();
52+
const { status } = await requestPermissionsAsync();
53+
if (status !== 'granted') {
54+
return;
55+
}
56+
const asset = await Asset.create(file.uri);
57+
setAsset(asset);
58+
};
59+
60+
downloadAndSaveAsset();
61+
}, []);
62+
63+
return (
64+
<View>
65+
{asset ? (
66+
<>
67+
<Text>{asset.id}</Text>
68+
<Image source={{ uri: asset.id }} style={{ width: 200, height: 300 }} />
69+
</>
70+
) : (
71+
<Text>Downloading and creating asset...</Text>
72+
)}
73+
</View>
74+
);
75+
}
76+
```
77+
78+
</SnackInline>
79+
</Collapsible>
80+
81+
<Collapsible summary="Retrieve asset properties">
82+
<SnackInline label="Retrieve asset properties" dependencies={["expo-media-library"]}>
83+
84+
```tsx
85+
import { View, Text } from 'react-native';
86+
import { useEffect, useState } from 'react';
87+
import { AssetField, MediaType, Query, requestPermissionsAsync } from 'expo-media-library/next';
88+
89+
export default function RetrievingAssetPropertiesExample() {
90+
const [assetInfo, setAssetInfo] = useState<{
91+
id: string;
92+
filename: string;
93+
mediaType: string;
94+
width: number;
95+
height: number;
96+
creationTime: number | null;
97+
modificationTime: number | null;
98+
} | null>(null);
99+
100+
useEffect(() => {
101+
const querySomeAsset = async () => {
102+
const { status } = await requestPermissionsAsync();
103+
if (status !== 'granted') {
104+
return;
105+
}
106+
107+
const [asset] = await new Query().limit(1).eq(AssetField.MEDIA_TYPE, MediaType.IMAGE).exe();
108+
109+
if (asset) {
110+
const filename = await asset.getFilename();
111+
const mediaType = (await asset.getMediaType()).toString();
112+
const width = await asset.getWidth();
113+
const height = await asset.getHeight();
114+
const creationTime = await asset.getCreationTime();
115+
const modificationTime = await asset.getModificationTime();
116+
setAssetInfo({
117+
id: asset.id,
118+
filename,
119+
mediaType,
120+
width,
121+
height,
122+
creationTime,
123+
modificationTime,
124+
});
125+
} else {
126+
console.log('No assets found in the media library.');
127+
}
128+
};
129+
130+
querySomeAsset();
131+
}, []);
132+
133+
return (
134+
<View>
135+
{assetInfo ? (
136+
<View>
137+
<Text>Asset ID: {assetInfo.id}</Text>
138+
<Text>Filename: {assetInfo.filename}</Text>
139+
<Text>Media Type: {assetInfo.mediaType}</Text>
140+
<Text>
141+
Dimensions: {assetInfo.width} x {assetInfo.height}
142+
</Text>
143+
<Text>
144+
Creation Time:{' '}
145+
{assetInfo.creationTime
146+
? new Date(assetInfo.creationTime).toLocaleString()
147+
: 'Unavailable'}
148+
</Text>
149+
<Text>
150+
Modification Time:{' '}
151+
{assetInfo.modificationTime
152+
? new Date(assetInfo.modificationTime).toLocaleString()
153+
: 'Unavailable'}
154+
</Text>
155+
</View>
156+
) : (
157+
<Text>Fetching asset ...</Text>
158+
)}
159+
</View>
160+
);
161+
}
162+
```
163+
164+
</SnackInline>
165+
</Collapsible>
166+
167+
<Collapsible summary="Create a new album">
168+
<SnackInline label="Create a new album" dependencies={["expo-media-library"]}>
169+
170+
```tsx
171+
import { View, Text, FlatList, Image, Button } from 'react-native';
172+
import { useState } from 'react';
173+
import {
174+
Asset,
175+
AssetField,
176+
MediaType,
177+
Query,
178+
requestPermissionsAsync,
179+
Album,
180+
} from 'expo-media-library/next';
181+
182+
export default function CreateAlbumExample() {
183+
const [assets, setAssets] = useState<Asset[]>([]);
184+
const [album, setAlbum] = useState<Album | null>(null);
185+
const [albumTitle, setAlbumTitle] = useState<string>('');
186+
187+
const createAlbumWithAsset = async () => {
188+
await requestPermissionsAsync();
189+
190+
const [asset] = await new Query().limit(1).eq(AssetField.MEDIA_TYPE, MediaType.IMAGE).exe();
191+
192+
if (!asset) {
193+
console.log('No assets found in the media library.');
194+
return;
195+
}
196+
197+
const newAlbum = await Album.create('MyNewAlbum', [asset]);
198+
199+
setAlbum(newAlbum);
200+
setAlbumTitle(await newAlbum.getTitle());
201+
const albumAssets = await newAlbum.getAssets();
202+
setAssets(albumAssets);
203+
};
204+
205+
return (
206+
<View style={{ flex: 1, padding: 20 }}>
207+
<Button title="Create Album and Add Asset" onPress={createAlbumWithAsset} />
208+
209+
{assets.length > 0 ? (
210+
<>
211+
<Text style={{ marginTop: 20, fontSize: 18, fontWeight: 'bold' }}>
212+
Assets in {albumTitle}:
213+
</Text>
214+
<FlatList
215+
data={assets}
216+
keyExtractor={item => item.id}
217+
renderItem={({ item }) => (
218+
<View style={{ marginVertical: 10 }}>
219+
<Image
220+
source={{ uri: item.id }}
221+
style={{ width: 100, height: 100, borderRadius: 8 }}
222+
/>
223+
</View>
224+
)}
225+
/>
226+
</>
227+
) : (
228+
<Text style={{ marginTop: 20 }}>{album ? 'Album is empty.' : 'No album created yet.'}</Text>
229+
)}
230+
</View>
231+
);
232+
}
233+
```
234+
235+
</SnackInline>
236+
</Collapsible>
237+
238+
## API
239+
240+
<APISection packageName="expo-media-library-next" apiName="MediaLibrary (next)" />

docs/public/static/data/unversioned/expo-media-library-next.json

Lines changed: 1 addition & 0 deletions
Large diffs are not rendered by default.

packages/expo-media-library/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515

1616
### 💡 Others
1717

18+
- [next] Add documentation ([#39754](https://github.com/expo/expo/pull/39754) by [@Wenszel](https://github.com/Wenszel))
19+
1820
## 18.2.0 — 2025-09-16
1921

2022
### 🎉 New features

packages/expo-media-library/build/next/index.d.ts

Lines changed: 9 additions & 13 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/expo-media-library/build/next/index.d.ts.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/expo-media-library/build/next/index.js

Lines changed: 14 additions & 13 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)