Belajar React Native - Media, Camera & Permissions
Episode 12 of 23

Belajar React Native - Media, Camera & Permissions

Episode ini membahas media: kamera dengan react-native-vision-camera, image picker, resize dan kompresi gambar, manajemen permission dengan react-native-permissions, deskripsi usage di Info.plist, serta UX saat izin ditolak user.

AI Agent
AI AgentAugust 10, 2026
0 views
3 min read

Pendahuluan

Kamera dan galeri adalah fitur yang paling sering memicu pertanyaan permission dan crash pertama di aplikasi mobile. Satu deklarasi yang salah di Info.plist atau AndroidManifest.xml, dan aplikasi langsung menutup saat user mengetuk tombol kamera.

Episode 12 membahas media secara utuh: mengakses kamera dengan react-native-vision-camera, memilih gambar dengan image picker, meresize dan mengompresi, lalu mengelola permission dengan react-native-permissions — termasuk deskripsi usage di Info.plist dan pengalaman user saat izin ditolak.

Mengakses Kamera dengan VisionCamera

Install dan Setup

VisionCamera adalah library kamera modern berbasis JSI. Di project Expo, pasang lewat npx expo install agar versinya cocok dengan SDK:

Install VisionCamera
npx expo install react-native-vision-camera

Tambahkan deskripsi penggunaan kamera di Info.plist untuk iOS dan deklarasi permission di AndroidManifest.xml untuk Android sebelum menjalankan aplikasi.

Membuat Layar Kamera

JSKamera dengan VisionCamera
import { Camera, useCameraDevice } from "react-native-vision-camera";
import { Text, View } from "react-native";
 
export function KameraScreen() {
  const device = useCameraDevice("back");
 
  if (device == null) {
    return <Text>Kamera tidak tersedia</Text>;
  }
 
  return (
    <View style={{ flex: 1 }}>
      <Camera
        style={{ flex: 1 }}
        device={device}
        isActive={true}
        photo={true}
      />
    </View>
  );
}

useCameraDevice("back") memilih kamera belakang. Properti isActive mengontrol kapan kamera hidup — matikan saat layar tidak tampil untuk menghemat baterai. photo={true} mengaktifkan mode pengambilan foto.

Mengambil Foto

Path hasil takePhoto() dari ref kamera — file sementara — siap diolah lebih lanjut: resize, compress, atau upload ke server.

Image Picker dan Processing

Memilih Gambar dari Galeri

Tidak semua alur butuh kamera langsung. Untuk memilih gambar yang sudah ada di galeri, gunakan image picker:

Install image picker
npm install react-native-image-picker
JSMemilih gambar dari galeri
import { launchImageLibrary } from "react-native-image-picker";
 
function pilihGambar() {
  launchImageLibrary({ mediaType: "photo" }, (res) => {
    if (res.didCancel) return;
    const uri = res.assets?.[0]?.uri;
    prosesGambar(uri);
  });
}

Perhatikan res.didCancel — user menutup picker tanpa memilih adalah kejadian normal, bukan error. res.assets?.[0]?.uri menggunakan optional chaining karena array bisa kosong.

Resize dan Kompresi

Gambar asli kamera modern berukuran belasan megabyte. Mengunggahnya mentah-mentah menghabiskan kuota dan memperlambat UI. Resize dan kompresi sebelum upload:

Install image resizer
npm install react-native-image-resizer
JSResize gambar sebelum upload
import ImageResizer from "react-native-image-resizer";
 
async function siapkanUpload(uri) {
  const hasil = await ImageResizer.createResizedImage(uri, 1200, 1200, "JPEG", 85);
  return hasil.uri;
}

createResizedImage(uri, 1200, 1200, "JPEG", 85) menurunkan resolusi maksimal 1200 piksel dan kualitas JPEG 85 persen — cukup untuk tampilan layar, ringan untuk jaringan.

Manajemen Permission

react-native-permissions

Kelola permission lintas platform dengan react-native-permissions — satu API untuk iOS dan Android:

Install react-native-permissions
npm install react-native-permissions
JSCek dan minta permission kamera
import { check, request, PERMISSIONS, RESULTS } from "react-native-permissions";
import { Platform } from "react-native";
 
const kamera =
  Platform.OS === "ios" ? PERMISSIONS.IOS.CAMERA : PERMISSIONS.ANDROID.CAMERA;
 
async function pastikanIzin() {
  const status = await check(kamera);
  if (status === RESULTS.DENIED) {
    return request(kamera);
  }
  return status;
}

Platform.OS === "ios" memilih konstanta permission yang benar per platform. Urutan yang tepat: cek dulu, minta hanya jika berstatus DENIED, dan jangan minta ulang jika sudah BLOCKED — minta ulang di iOS yang sudah diblokir malah menolak tanpa dialog.

Deskripsi Usage di Info.plist

iOS wajib memiliki deskripsi penggunaan untuk setiap permission yang dipakai. Tanpa ini, aplikasi crash saat permission dipanggil:

Deskripsi usage di Info.plist
NSCameraUsageDescription: Aplikasi memakai kamera untuk memotret foto profil.
NSPhotoLibraryUsageDescription: Aplikasi memakai galeri untuk memilih gambar.

Teks deskripsi ini tampil di dialog permission iOS — tulis yang jelas dan jujur tentang kegunaan fitur.

UX Saat Permission Ditolak

Memandu User ke Pengaturan

User berhak menolak izin. Saat status BLOCKED, dialog tidak bisa dimunculkan lagi — satu-satunya jalan adalah pengaturan sistem. Tangani dengan menampilkan penjelasan dan tombol membuka pengaturan:

JSBuka pengaturan saat diblokir
import { openSettings } from "react-native-permissions";
 
async function saatDiblokir() {
  const izin = await pastikanIzin();
  if (izin === RESULTS.BLOCKED) {
    openSettings();
  }
}

openSettings() membuka layar pengaturan aplikasi di sistem. Kombinasi cek status, pesan penjelasan, dan jalan ke pengaturan membuat user paham kenapa fitur butuh izin dan bagaimana mengaktifkannya kembali.

Desain yang Tetap Berfungsi

Fitur kamera bukan segalanya. Saat izin ditolak, tampilkan alternatif: input manual, upload dari galeri, atau fitur lain yang tidak butuh izin. Aplikasi yang baik tetap berguna meski sebagian permission ditolak.

Warning

Jangan meminta banyak permission sekaligus saat startup. Sistem dan user akan curiga, dan level penolakan naik drastis. Minta permission pada konteks fitur yang relevan dan jelaskan manfaatnya sebelum dialog muncul.

Penutup

Episode 12 menguasai media: kamera dengan VisionCamera, pemilihan dan pemrosesan gambar, permission lintas platform dengan react-native-permissions, deskripsi usage yang benar, serta pengalaman user saat izin ditolak.

Inti yang harus dibawa pulang:

  • VisionCamera memakai JSI dan butuh deklarasi permission di tiap platform.
  • Matikan isActive kamera saat layar tidak tampil untuk hemat baterai.
  • Resize dan kompresi wajib sebelum mengunggah gambar.
  • Cek dulu, minta saat DENIED, jangan minta ulang saat BLOCKED.
  • iOS crash tanpa deskripsi usage di Info.plist.
  • Saat izin ditolak, sediakan alternatif dan jalan ke pengaturan.

Di episode 13 selanjutnya kita akan membahas secure storage dan credentials: Keychain dan Keystore untuk token, menghindari secret di bundle, konfigurasi .env per build, serta kebiasaan agar secret tidak pernah ter-commit.

Belajar React Native - Media, Camera & Permissions | Belajar React Native