Kurs React Native · Moduł 6: Zdjęcia, kamera i dźwięk

expo-file-system i expo-sharing

2 min czytania ·
W tej lekcji3

Zarządzaj plikami i udostępniaj je!

expo-file-system

npx expo install expo-file-system
import * as FileSystem from 'expo-file-system';

// Ścieżki katalogów
const documentsDir = FileSystem.documentDirectory;
const cacheDir = FileSystem.cacheDirectory;

// Pobieranie pliku
async function downloadImage(url: string, filename: string) {
  const fileUri = `${FileSystem.documentDirectory}${filename}`;

  const downloadResumable = FileSystem.createDownloadResumable(
    url,
    fileUri,
    {},
    (progress) => {
      const percent = progress.totalBytesWritten / progress.totalBytesExpectedToWrite;
      console.log(`Pobrano: ${Math.round(percent * 100)}%`);
    }
  );

  const result = await downloadResumable.downloadAsync();
  return result?.uri;
}

// Odczyt pliku
async function readFile(filename: string) {
  const fileUri = `${FileSystem.documentDirectory}${filename}`;
  const content = await FileSystem.readAsStringAsync(fileUri);
  return content;
}

// Zapis pliku
async function writeFile(filename: string, content: string) {
  const fileUri = `${FileSystem.documentDirectory}${filename}`;
  await FileSystem.writeAsStringAsync(fileUri, content);
}

// Info o pliku
async function getFileInfo(uri: string) {
  const info = await FileSystem.getInfoAsync(uri);
  console.log('Exists:', info.exists);
  console.log('Size:', info.size);
  console.log('URI:', info.uri);
  return info;
}

// Usuwanie
async function deleteFile(uri: string) {
  await FileSystem.deleteAsync(uri);
}

// Lista plików
async function listDirectory(dir: string) {
  const files = await FileSystem.readDirectoryAsync(dir);
  return files;
}

expo-sharing

npx expo install expo-sharing
import * as Sharing from 'expo-sharing';
import * as FileSystem from 'expo-file-system';

async function shareImage(imageUri: string) {
  // Sprawdź czy sharing jest dostępny
  const isAvailable = await Sharing.isAvailableAsync();
  if (!isAvailable) {
    Alert.alert('Błąd', 'Udostępnianie niedostępne na tym urządzeniu');
    return;
  }

  // Udostępnij
  await Sharing.shareAsync(imageUri, {
    mimeType: 'image/jpeg',
    dialogTitle: 'Udostępnij zdjęcie',
  });
}

// Udostępnianie z pobranego URL
async function downloadAndShare(url: string) {
  const filename = url.split('/').pop() || 'file';
  const localUri = `${FileSystem.cacheDirectory}${filename}`;

  // Pobierz
  await FileSystem.downloadAsync(url, localUri);

  // Udostępnij
  await Sharing.shareAsync(localUri);
}

expo-media-library

npx expo install expo-media-library
import * as MediaLibrary from 'expo-media-library';

// Zapisz do galerii
async function saveToGallery(uri: string) {
  const { status } = await MediaLibrary.requestPermissionsAsync();
  if (status !== 'granted') return;

  const asset = await MediaLibrary.createAssetAsync(uri);

  // Opcjonalnie: dodaj do albumu
  const album = await MediaLibrary.getAlbumAsync('Atlantyda');
  if (album) {
    await MediaLibrary.addAssetsToAlbumAsync([asset], album, false);
  } else {
    await MediaLibrary.createAlbumAsync('Atlantyda', asset, false);
  }

  Alert.alert('Sukces', 'Zdjęcie zapisane w galerii!');
}

// Pobierz zdjęcia z galerii
async function getPhotos() {
  const { status } = await MediaLibrary.requestPermissionsAsync();
  if (status !== 'granted') return [];

  const media = await MediaLibrary.getAssetsAsync({
    mediaType: 'photo',
    first: 20,
    sortBy: MediaLibrary.SortBy.creationTime,
  });

  return media.assets;
}

Te biblioteki dają pełną kontrolę nad plikami i mediami!

Kod do tej lekcji: App.tsx
import React, { useState } from 'react';
import { View, Text, Pressable, StyleSheet, Alert } from 'react-native';
import * as FileSystem from 'expo-file-system';
import * as Sharing from 'expo-sharing';

export default function App() {
  const [busy, setBusy] = useState(false);

  const downloadAndShare = async () => {
    setBusy(true);
    const url = 'https://picsum.photos/600';
    const fileUri = `${FileSystem.cacheDirectory}atlantis.jpg`;

    // TODO: pobierz plik z URL do fileUri:
    //   await FileSystem.downloadAsync(url, fileUri);

    // TODO: sprawdź dostępność udostępniania:
    //   const isAvailable = await Sharing.isAvailableAsync();
    //   if (!isAvailable) { Alert.alert('Błąd', 'Udostępnianie niedostępne'); return; }

    // TODO: udostępnij pobrany plik:
    //   await Sharing.shareAsync(fileUri);

    setBusy(false);
  };

  return (
    <View style={styles.container}>
      <Pressable style={styles.button} onPress={downloadAndShare} disabled={busy}>
        <Text style={styles.buttonText}>{busy ? 'Pobieranie...' : 'Pobierz i udostępnij'}</Text>
      </Pressable>
    </View>
  );
}

const styles = StyleSheet.create({
  container: { flex: 1, justifyContent: 'center', alignItems: 'center', backgroundColor: '#1a5276' },
  button: { backgroundColor: '#2980b9', paddingVertical: 14, paddingHorizontal: 32, borderRadius: 8 },
  buttonText: { color: '#fff', fontSize: 16, fontWeight: '600' },
});

Hasła z dokumentacji w tej lekcji

Widzisz błąd w tej lekcji?

Sprawdź się

Odpowiedz na pytania z tej lekcji. Wybierz odpowiedź, a od razu zobaczysz, czy jest poprawna.

  1. 1. Gdzie przechowywać trwałe pliki aplikacji?

Zadania praktyczne w grze

  • Układanie w poziomie

    Ułóż udostępnianie pliku:

  • Edytor kodu

    Uzupełnij kod z FileSystem i Sharing.

Przydatne artykuły