Encodera

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.

Оглавление

Фото из галереи и камеры

Возможности телефона — камера, геолокация, контакты, вибрация — доступны через модули Expo. Каждый модуль — пакет с JavaScript-функциями, за которыми стоит родной код iOS и Android. Разберём на примере expo-image-picker: пользователь выберет аватар для профиля в блоге.

Установка

npx expo install expo-image-picker

Модуль уже есть внутри Expo Go, поэтому работает сразу после установки пакета.

Выбор из галереи

// app/(tabs)/profile.tsx
import { Image } from 'expo-image';
import * as ImagePicker from 'expo-image-picker';
import { useState } from 'react';
import { Button, View } from 'react-native';
 
export default function Profile() {
  const [avatar, setAvatar] = useState<string | null>(null);
 
  async function pickImage() {
    const result = await ImagePicker.launchImageLibraryAsync({
      mediaTypes: ['images'],
      allowsEditing: true,
      aspect: [1, 1],
      quality: 0.8,
    });
 
    if (!result.canceled) {
      setAvatar(result.assets[0].uri);
    }
  }
 
  return (
    <View style={{ flex: 1, alignItems: 'center', padding: 16, gap: 12 }}>
      {avatar && <Image source={avatar} style={{ width: 120, height: 120, borderRadius: 60 }} />}
      <Button title="Выбрать фото" onPress={pickImage} />
    </View>
  );
}

Нажмите «Выбрать фото» — откроется системная галерея. После выбора появится окно обрезки до квадрата (aspect: [1, 1]), а затем круглый аватар над кнопкой. uri — адрес файла на телефоне, его можно показать в Image или отправить на сервер.

Параметры

ПараметрЧто задаёт
mediaTypesЧто выбирать: ['images'], ['videos'] или оба
allowsEditingПоказать экран обрезки
aspectПропорции обрезки, например [4, 3]
qualityКачество сжатия от 0 до 1

Если пользователь закрыл галерею, result.canceled равен true, а assets нет.

Съёмка камерой

Для камеры нужно разрешение пользователя. Его запрашивают перед съёмкой:

// app/(tabs)/profile.tsx
async function takePhoto() {
  const permission = await ImagePicker.requestCameraPermissionsAsync();
  if (!permission.granted) {
    Alert.alert('Нет доступа к камере');
    return;
  }
 
  const result = await ImagePicker.launchCameraAsync({ allowsEditing: true, aspect: [1, 1] });
  if (!result.canceled) {
    setAvatar(result.assets[0].uri);
  }
}

Добавьте кнопку <Button title="Сделать фото" onPress={takePhoto} /> и Alert в импорт. При первом нажатии система спросит разрешение, затем откроется камера. В iOS-симуляторе камеры нет — проверяйте на телефоне.

Текст запроса разрешения

Текст системного окна задают в app.json через плагин модуля:

{
  "expo": {
    "plugins": [
      ["expo-image-picker", { "cameraPermission": "Камера нужна, чтобы сделать фото для профиля." }]
    ]
  }
}

Этот текст попадает в приложение при сборке через EAS; в Expo Go показывается стандартный текст Expo Go.

Частая ошибка

Не проверять result.canceled и сразу читать result.assets[0].uri. Если пользователь закрыл галерею без выбора, assets равен null, и приложение упадёт с ошибкой. Всегда проверяйте отмену перед использованием результата.

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.