Framework Android mencakup dukungan untuk berbagai kamera dan fitur kamera yang tersedia di perangkat, yang memungkinkan Anda untuk mengambil gambar dan video di aplikasi. Dokumen ini membahas pendekatan cepat dan sederhana untuk pengambilan gambar dan video, serta menguraikan pendekatan lanjutan untuk menciptakan pengalaman kamera kustom bagi pengguna Anda.
Catatan:
Halaman ini menjelaskan class
Camera
,
yang sudah tidak digunakan lagi. Sebaiknya gunakan library Jetpack
CameraX atau, untuk kasus penggunaan tertentu,
class
camera2
. CameraX dan Camera2 berfungsi di Android 5.0 (API level 21) dan
yang lebih tinggi.
Lihat referensi terkait berikut ini:
Pertimbangan
Sebelum mengaktifkan aplikasi untuk menggunakan kamera pada perangkat Android, Anda harus mempertimbangkan beberapa pertanyaan tentang bagaimana cara aplikasi Anda menggunakan fitur hardware ini.
- Persyaratan Kamera - Apakah penggunaan kamera begitu penting untuk aplikasi sehingga Anda tidak ingin aplikasi diinstal pada perangkat yang tidak memiliki kamera? Jika demikian, Anda harus mendeklarasikan persyaratan kamera dalam manifes Anda.
- Gambar Cepat atau Kamera Kustom - Bagaimana aplikasi Anda menggunakan kamera? Apakah Anda hanya tertarik untuk mengambil gambar cepat atau klip video, atau apakah aplikasi Anda akan menyediakan cara baru untuk menggunakan kamera? Untuk mendapatkan klip atau jepretan cepat, pertimbangkan Menggunakan Aplikasi Kamera yang Ada. Untuk mengembangkan fitur kamera kustom, lihat bagian Membuat Aplikasi Kamera.
- Persyaratan Layanan Latar Depan - Kapan aplikasi Anda berinteraksi dengan kamera? Di Android 9 (API level 28) dan yang lebih baru, aplikasi yang berjalan di latar belakang tidak dapat mengakses kamera. Karena itu, Anda harus menggunakan kamera baik saat aplikasi berada di latar depan maupun sebagai bagian dari layanan latar depan.
- Penyimpanan - Apakah gambar atau video yang dihasilkan aplikasi Anda ditujukan hanya untuk dapat dilihat oleh aplikasi Anda, atau dibagikan agar aplikasi lain seperti Galeri atau media dan aplikasi sosial lainnya dapat menggunakannya? Apakah Anda ingin gambar dan video tersedia bahkan jika aplikasi Anda di-uninstal? Lihat bagian Menyimpan File Media untuk mengetahui cara menerapkan opsi ini.
Dasar-dasarnya
Framework Android mendukung pengambilan gambar dan video melalui
API android.hardware.camera2
atau kamera Intent
. Berikut adalah class yang
relevan:
android.hardware.camera2
- Paket ini adalah API utama untuk mengontrol kamera perangkat. Paket ini dapat digunakan untuk mengambil gambar atau video saat Anda membuat aplikasi kamera.
Camera
- Class ini adalah API lebih lama yang tidak digunakan lagi untuk mengontrol kamera perangkat.
SurfaceView
- Class ini digunakan untuk menyajikan pratinjau kamera langsung kepada pengguna.
MediaRecorder
- Class ini digunakan untuk merekam video dari kamera.
Intent
- Jenis tindakan intent
MediaStore.ACTION_IMAGE_CAPTURE
atauMediaStore.ACTION_VIDEO_CAPTURE
dapat digunakan untuk mengambil gambar atau video tanpa langsung menggunakan objekCamera
.
Deklarasi manifes
Sebelum memulai pengembangan pada aplikasi dengan Camera API, pastikan manifes Anda memiliki deklarasi yang sesuai untuk mengizinkan penggunaan hardware kamera dan fitur terkait lainnya.
- Izin Kamera - Aplikasi Anda harus meminta izin untuk menggunakan perangkat
kamera.
<uses-permission android:name="android.permission.CAMERA" />
Catatan: Jika Anda menggunakan kamera dengan mengaktifkan aplikasi kamera yang ada, aplikasi Anda tidak perlu meminta izin ini.
- Fitur Kamera - Aplikasi Anda juga harus mendeklarasikan penggunaan fitur kamera,
misalnya:
<uses-feature android:name="android.hardware.camera" />
Untuk daftar fitur kamera, lihat manifes Referensi Fitur.
Menambahkan fitur kamera ke manifes Anda menyebabkan Google Play mencegah aplikasi Anda diinstal ke perangkat yang tidak menyertakan kamera atau tidak mendukung fitur kamera yang Anda tentukan. Untuk informasi selengkapnya tentang penggunaan pemfilteran berbasis fitur dengan Google Play, lihat Pemfilteran Berbasis Fitur dan Google Play.
Jika aplikasi Anda dapat menggunakan kamera atau fitur kamera untuk pengoperasian yang benar, tetapi tidak mengharuskannya, Anda harus menentukan hal ini dalam manifes dengan memasukkan atribut
android:required
, lalu menetapkannya kefalse
:<uses-feature android:name="android.hardware.camera" android:required="false" />
- Izin Penyimpanan - Aplikasi Anda dapat menyimpan gambar atau video ke
penyimpanan eksternal perangkat (Kartu SD) jika menargetkan Android 10 (API level 29) atau
lebih rendah dan menentukan hal berikut dalam manifes.
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
- Izin Perekaman Audio - Untuk merekam audio dengan perekaman video,
harus meminta izin perekaman audio.
<uses-permission android:name="android.permission.RECORD_AUDIO" />
-
Izin Lokasi - Jika aplikasi Anda menandai gambar dengan informasi lokasi GPS, Anda harus meminta izin
ACCESS_FINE_LOCATION
. Ingat bahwa, jika aplikasi Anda menargetkan Android 5.0 (API level 21) atau lebih tinggi, Anda juga perlu mendeklarasikan bahwa aplikasi tersebut menggunakan GPS perangkat:<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> ... <!-- Needed only if your app targets Android 5.0 (API level 21) or higher. --> <uses-feature android:name="android.hardware.location.gps" />
Untuk informasi selengkapnya tentang cara mendapatkan lokasi pengguna, lihat Strategi Lokasi.
Menggunakan aplikasi kamera yang ada
Cara cepat untuk mengaktifkan pengambilan gambar atau video di aplikasi Anda tanpa banyak kode tambahan
adalah dengan menggunakan Intent
untuk menjalankan aplikasi kamera Android yang ada.
Detailnya dijelaskan dalam tutorial pelatihan
Mengambil Foto Secara Sederhana dan
Merekam Video Secara Sederhana.
Membuat aplikasi kamera
Beberapa developer mungkin memerlukan antarmuka pengguna kamera yang disesuaikan dengan tampilan aplikasi mereka atau menyediakan fitur khusus. Menulis kode pengambilan gambar sendiri dapat memberikan pengalaman yang lebih menarik bagi pengguna.
Catatan: Panduan berikut ini untuk Camera
API lebih lama yang tidak digunakan lagi. Untuk aplikasi kamera baru atau lanjutan, android.hardware.camera2
API yang lebih baru
direkomendasikan.
Langkah umum untuk membuat antarmuka kamera kustom bagi aplikasi Anda adalah sebagai berikut:
- Mendeteksi dan Mengakses Kamera - Buat kode untuk meminta akses dan memeriksa keberadaan kamera.
- Membuat Class Pratinjau - Buat class pratinjau kamera yang memperluas
SurfaceView
dan mengimplementasikan antarmukaSurfaceHolder
. Class ini mempratinjau gambar langsung dari kamera. - Membuat Tata Letak Pratinjau - Setelah memiliki class pratinjau kamera, buat tata letak tampilan yang menggabungkan pratinjau dan kontrol antarmuka pengguna yang Anda inginkan.
- Menyiapkan Pemroses untuk Pengambilan - Hubungkan pemroses untuk kontrol antarmuka guna memulai pengambilan gambar atau video sebagai respons terhadap tindakan pengguna, seperti menekan tombol.
- Mengambil dan Menyimpan File - Siapkan kode untuk mengambil gambar atau video dan menyimpan hasilnya.
- Merilis Kamera - Setelah menggunakan kamera, aplikasi Anda harus merilisnya dengan benar untuk digunakan oleh aplikasi lain.
Hardware kamera adalah sumber daya bersama yang harus dikelola dengan hati-hati agar aplikasi Anda tidak bertabrakan dengan aplikasi lain yang mungkin juga ingin menggunakannya. Bagian berikut membahas cara mendeteksi hardware kamera, cara meminta akses ke kamera, cara mengambil gambar atau video, dan cara merilis kamera setelah aplikasi Anda selesai menggunakannya.
Perhatian: Ingatlah untuk merilis objek Camera
dengan memanggil Camera.release()
setelah aplikasi
Anda selesai menggunakannya. Jika aplikasi Anda tidak merilis kamera dengan benar, semua
upaya berikutnya untuk mengakses kamera, termasuk yang dilakukan oleh aplikasi Anda sendiri, akan gagal dan dapat
menyebabkan aplikasi Anda atau lainnya dinonaktifkan.
Mendeteksi hardware kamera
Jika aplikasi Anda secara khusus tidak membutuhkan kamera menggunakan deklarasi manifes, Anda
harus memeriksa untuk melihat apakah kamera tersedia saat runtime. Untuk melakukan pemeriksaan ini, gunakan metode PackageManager.hasSystemFeature()
, seperti yang ditunjukkan pada contoh kode di bawah ini:
Kotlin
/** Check if this device has a camera */ private fun checkCameraHardware(context: Context): Boolean { if (context.packageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA)) { // this device has a camera return true } else { // no camera on this device return false } }
Java
/** Check if this device has a camera */ private boolean checkCameraHardware(Context context) { if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)){ // this device has a camera return true; } else { // no camera on this device return false; } }
Perangkat Android dapat memiliki beberapa kamera, misalnya kamera belakang untuk fotografi dan
kamera depan untuk panggilan video. Android 2.3 (API Level 9) dan yang lebih baru memungkinkan Anda memeriksa
jumlah kamera yang tersedia di perangkat menggunakan metode Camera.getNumberOfCameras()
.
Mengakses kamera
Setelah mengetahui bahwa perangkat yang menjalankan aplikasi Anda memiliki kamera, Anda
harus meminta untuk mengaksesnya dengan mendapatkan instance Camera
(kecuali jika
Anda menggunakan intent untuk mengakses kamera).
Untuk mengakses kamera utama, gunakan metode Camera.open()
dan pastikan untuk menangkap pengecualian apa pun, seperti yang ditunjukkan pada kode di bawah ini:
Kotlin
/** A safe way to get an instance of the Camera object. */ fun getCameraInstance(): Camera? { return try { Camera.open() // attempt to get a Camera instance } catch (e: Exception) { // Camera is not available (in use or does not exist) null // returns null if camera is unavailable } }
Java
/** A safe way to get an instance of the Camera object. */ public static Camera getCameraInstance(){ Camera c = null; try { c = Camera.open(); // attempt to get a Camera instance } catch (Exception e){ // Camera is not available (in use or does not exist) } return c; // returns null if camera is unavailable }
Perhatian: Selalu periksa pengecualian saat menggunakan Camera.open()
. Gagal memeriksa pengecualian jika kamera sedang
digunakan atau tidak ada akan menyebabkan aplikasi Anda dinonaktifkan oleh sistem.
Pada perangkat yang menjalankan Android 2.3 (API Level 9) atau lebih tinggi, Anda dapat mengakses kamera tertentu menggunakan
Camera.open(int)
. Contoh kode di atas akan mengakses
kamera belakang terlebih dahulu pada perangkat dengan lebih dari satu kamera.
Memeriksa fitur kamera
Setelah mendapatkan akses ke kamera, Anda dapat memperoleh informasi selengkapnya tentang kemampuannya menggunakan
metode Camera.getParameters()
dan memeriksa objek
Camera.Parameters
yang ditampilkan untuk kemampuan yang didukung. Saat menggunakan
API Level 9 atau yang lebih tinggi, gunakan Camera.getCameraInfo()
untuk menentukan apakah kamera ada di bagian depan
atau belakang perangkat, dan orientasi gambarnya.
Membuat class pratinjau
Agar pengguna dapat mengambil gambar atau video secara efektif, mereka harus dapat melihat apa yang dilihat kamera
perangkat. Class pratinjau kamera adalah SurfaceView
yang dapat menampilkan data gambar langsung
yang berasal dari kamera, sehingga pengguna dapat membingkai dan mengambil gambar atau video.
Contoh kode berikut menunjukkan cara membuat class pratinjau kamera dasar yang dapat
dimasukkan dalam tata letak View
. Class ini mengimplementasikan SurfaceHolder.Callback
untuk mengambil peristiwa callback
guna membuat dan menutup tampilan, yang diperlukan untuk menetapkan input pratinjau kamera.
Kotlin
/** A basic Camera preview class */ class CameraPreview( context: Context, private val mCamera: Camera ) : SurfaceView(context), SurfaceHolder.Callback { private val mHolder: SurfaceHolder = holder.apply { // Install a SurfaceHolder.Callback so we get notified when the // underlying surface is created and destroyed. addCallback(this@CameraPreview) // deprecated setting, but required on Android versions prior to 3.0 setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS) } override fun surfaceCreated(holder: SurfaceHolder) { // The Surface has been created, now tell the camera where to draw the preview. mCamera.apply { try { setPreviewDisplay(holder) startPreview() } catch (e: IOException) { Log.d(TAG, "Error setting camera preview: ${e.message}") } } } override fun surfaceDestroyed(holder: SurfaceHolder) { // empty. Take care of releasing the Camera preview in your activity. } override fun surfaceChanged(holder: SurfaceHolder, format: Int, w: Int, h: Int) { // If your preview can change or rotate, take care of those events here. // Make sure to stop the preview before resizing or reformatting it. if (mHolder.surface == null) { // preview surface does not exist return } // stop preview before making changes try { mCamera.stopPreview() } catch (e: Exception) { // ignore: tried to stop a non-existent preview } // set preview size and make any resize, rotate or // reformatting changes here // start preview with new settings mCamera.apply { try { setPreviewDisplay(mHolder) startPreview() } catch (e: Exception) { Log.d(TAG, "Error starting camera preview: ${e.message}") } } } }
Java
/** A basic Camera preview class */ public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback { private SurfaceHolder mHolder; private Camera mCamera; public CameraPreview(Context context, Camera camera) { super(context); mCamera = camera; // Install a SurfaceHolder.Callback so we get notified when the // underlying surface is created and destroyed. mHolder = getHolder(); mHolder.addCallback(this); // deprecated setting, but required on Android versions prior to 3.0 mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); } public void surfaceCreated(SurfaceHolder holder) { // The Surface has been created, now tell the camera where to draw the preview. try { mCamera.setPreviewDisplay(holder); mCamera.startPreview(); } catch (IOException e) { Log.d(TAG, "Error setting camera preview: " + e.getMessage()); } } public void surfaceDestroyed(SurfaceHolder holder) { // empty. Take care of releasing the Camera preview in your activity. } public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { // If your preview can change or rotate, take care of those events here. // Make sure to stop the preview before resizing or reformatting it. if (mHolder.getSurface() == null){ // preview surface does not exist return; } // stop preview before making changes try { mCamera.stopPreview(); } catch (Exception e){ // ignore: tried to stop a non-existent preview } // set preview size and make any resize, rotate or // reformatting changes here // start preview with new settings try { mCamera.setPreviewDisplay(mHolder); mCamera.startPreview(); } catch (Exception e){ Log.d(TAG, "Error starting camera preview: " + e.getMessage()); } } }
Jika ingin menyetel ukuran tertentu untuk pratinjau kamera Anda, setel ini dalam metode surfaceChanged()
seperti yang disebutkan dalam komentar di atas. Saat menyetel ukuran pratinjau, Anda
harus menggunakan nilai dari getSupportedPreviewSizes()
.
Jangan setel nilai arbitrer dalam metode setPreviewSize()
.
Catatan:
Dengan diperkenalkannya fitur
Multi-Aplikasi di Android 7.0 (API level 24) dan yang lebih tinggi, Anda tidak dapat
lagi mengasumsikan rasio lebar tinggi pratinjau sama seperti aktivitas Anda
bahkan setelah memanggil setDisplayOrientation()
.
Bergantung pada ukuran jendela dan rasio lebar tinggi, Anda mungkin harus memasukkan pratinjau kamera
lebar ke dalam tata letak berorientasi potret, atau sebaliknya, menggunakan
tata letak tampilan lebar.
Menempatkan pratinjau dalam tata letak
Class pratinjau kamera, seperti contoh yang ditunjukkan pada bagian sebelumnya, harus ditempatkan dalam tata letak suatu aktivitas bersama dengan kontrol antarmuka pengguna lain untuk mengambil gambar atau video. Bagian ini menunjukkan kepada Anda cara membuat tata letak dan aktivitas dasar untuk pratinjau.
Kode tata letak berikut memberikan tampilan yang sangat mendasar yang dapat digunakan untuk menampilkan pratinjau
kamera. Dalam contoh ini, elemen FrameLayout
dimaksudkan sebagai
container untuk class pratinjau kamera. Jenis tata letak ini digunakan sehingga informasi gambar
tambahan atau kontrol dapat ditempatkan pada gambar pratinjau kamera langsung.
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="fill_parent" > <FrameLayout android:id="@+id/camera_preview" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_weight="1" /> <Button android:id="@+id/button_capture" android:text="Capture" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" /> </LinearLayout>
Pada sebagian besar perangkat, orientasi default pratinjau kamera adalah lanskap. Tata letak contoh ini menentukan tata letak horizontal (lanskap), dan kode di bawah ini memperbaiki orientasi aplikasi ke lanskap. Untuk mempermudah dalam merender pratinjau kamera, Anda harus mengubah orientasi aktivitas pratinjau aplikasi Anda menjadi lanskap dengan menambahkan berikut ini ke manifes Anda.
<activity android:name=".CameraActivity" android:label="@string/app_name" android:screenOrientation="landscape"> <!-- configure this activity to use landscape orientation --> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity>
Catatan: Pratinjau kamera tidak harus dalam mode lanskap.
Mulai di Android 2.2 (API Level 8), Anda dapat menggunakan metode setDisplayOrientation()
untuk menyetel
rotasi gambar pratinjau. Untuk mengubah orientasi pratinjau saat pengguna mengorientasikan ulang
ponsel, dalam metode surfaceChanged()
dari class pratinjau Anda, pertama-tama hentikan pratinjau dengan Camera.stopPreview()
, ubah orientasi,
lalu mulai pratinjau lagi dengan Camera.startPreview()
.
Pada aktivitas untuk tampilan kamera, tambahkan class pratinjau Anda ke elemen FrameLayout
yang ditunjukkan pada contoh di atas. Aktivitas kamera Anda juga
harus memastikan bahwa ia merilis kamera ketika dijeda atau dimatikan. Contoh berikut menunjukkan cara
memodifikasi aktivitas kamera untuk melampirkan class pratinjau yang ditunjukkan dalam Membuat
class pratinjau.
Kotlin
class CameraActivity : Activity() { private var mCamera: Camera? = null private var mPreview: CameraPreview? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) // Create an instance of Camera mCamera = getCameraInstance() mPreview = mCamera?.let { // Create our Preview view CameraPreview(this, it) } // Set the Preview view as the content of our activity. mPreview?.also { val preview: FrameLayout = findViewById(R.id.camera_preview) preview.addView(it) } } }
Java
public class CameraActivity extends Activity { private Camera mCamera; private CameraPreview mPreview; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); // Create an instance of Camera mCamera = getCameraInstance(); // Create our Preview view and set it as the content of our activity. mPreview = new CameraPreview(this, mCamera); FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview); preview.addView(mPreview); } }
Catatan: Metode getCameraInstance()
pada contoh di atas
merujuk pada metode contoh yang ditampilkan di Mengakses kamera.
Mengambil foto
Setelah membuat class pratinjau dan tata letak tampilan untuk menampilkannya, Anda siap untuk mulai mengambil gambar dengan aplikasi Anda. Dalam kode aplikasi Anda, Anda harus menyiapkan pemroses untuk kontrol antarmuka pengguna demi merespons tindakan pengguna dengan mengambil gambar.
Untuk mengambil gambar, gunakan metode Camera.takePicture()
. Metode ini mengambil tiga parameter yang menerima data dari kamera.
Untuk menerima data dalam format JPEG, Anda harus mengimplementasikan antarmuka Camera.PictureCallback
untuk menerima data gambar dan
menulisnya ke file. Kode berikut menunjukkan implementasi dasar antarmuka Camera.PictureCallback
untuk menyimpan gambar yang diterima dari kamera.
Kotlin
private val mPicture = Camera.PictureCallback { data, _ -> val pictureFile: File = getOutputMediaFile(MEDIA_TYPE_IMAGE) ?: run { Log.d(TAG, ("Error creating media file, check storage permissions")) return@PictureCallback } try { val fos = FileOutputStream(pictureFile) fos.write(data) fos.close() } catch (e: FileNotFoundException) { Log.d(TAG, "File not found: ${e.message}") } catch (e: IOException) { Log.d(TAG, "Error accessing file: ${e.message}") } }
Java
private PictureCallback mPicture = new PictureCallback() { @Override public void onPictureTaken(byte[] data, Camera camera) { File pictureFile = getOutputMediaFile(MEDIA_TYPE_IMAGE); if (pictureFile == null){ Log.d(TAG, "Error creating media file, check storage permissions"); return; } try { FileOutputStream fos = new FileOutputStream(pictureFile); fos.write(data); fos.close(); } catch (FileNotFoundException e) { Log.d(TAG, "File not found: " + e.getMessage()); } catch (IOException e) { Log.d(TAG, "Error accessing file: " + e.getMessage()); } } };
Pemicu mengambil gambar dengan memanggil metode Camera.takePicture()
. Kode contoh berikut menunjukkan cara memanggil metode ini dari
tombol View.OnClickListener
.
Kotlin
val captureButton: Button = findViewById(R.id.button_capture) captureButton.setOnClickListener { // get an image from the camera mCamera?.takePicture(null, null, picture) }
Java
// Add a listener to the Capture button Button captureButton = (Button) findViewById(R.id.button_capture); captureButton.setOnClickListener( new View.OnClickListener() { @Override public void onClick(View v) { // get an image from the camera mCamera.takePicture(null, null, picture); } } );
Catatan: Anggota mPicture
pada contoh berikut merujuk
pada contoh kode di atas.
Perhatian: Ingatlah untuk merilis objek Camera
dengan memanggil Camera.release()
setelah aplikasi
Anda selesai menggunakannya. Untuk informasi tentang cara merilis kamera, lihat Merilis kamera.
Mengambil video
Pengambilan video menggunakan framework Android membutuhkan pengelolaan objek Camera
yang cermat dan koordinasi dengan class MediaRecorder
.
Saat merekam video dengan Camera
, Anda harus mengatur panggilan Camera.lock()
dan Camera.unlock()
untuk mengizinkan akses MediaRecorder
ke hardware kamera,
selain panggilan Camera.open()
dan Camera.release()
.
Catatan: Mulai dari Android 4.0 (API level 14), panggilan Camera.lock()
dan Camera.unlock()
dikelola untuk Anda secara otomatis.
Tidak seperti mengambil gambar dengan kamera perangkat, merekam video membutuhkan urutan panggilan yang sangat khusus. Anda harus mengikuti urutan eksekusi tertentu agar berhasil mempersiapkan dan mengambil video dengan aplikasi Anda, seperti yang dijelaskan di bawah ini.
- Membuka Kamera - Gunakan
Camera.open()
untuk mendapatkan instance objek kamera. - Menghubungkan Pratinjau - Siapkan pratinjau gambar kamera langsung dengan menghubungkan
SurfaceView
ke kamera menggunakanCamera.setPreviewDisplay()
. - Memulai Pratinjau - Panggil
Camera.startPreview()
untuk mulai menampilkan gambar kamera langsung. - Memulai Rekaman Video - Langkah-langkah berikut harus diselesaikan
agar berhasil merekam video:
- Membuka Kunci Kamera - Buka kunci kamera untuk digunakan oleh
MediaRecorder
dengan memanggilCamera.unlock()
. - Mengonfigurasi MediaRecorder - Panggil metode
MediaRecorder
berikut dalam urutan ini. Untuk informasi selengkapnya, lihat dokumentasi referensiMediaRecorder
.setCamera()
- Setel kamera yang akan digunakan untuk pengambilan video, gunakan instanceCamera
aplikasi Anda saat ini.setAudioSource()
- Setel sumber audio, gunakanMediaRecorder.AudioSource.CAMCORDER
.setVideoSource()
- Setel sumber video, gunakanMediaRecorder.VideoSource.CAMERA
.- Setel encoding dan format output video. Untuk Android 2.2 (API Level 8) dan
lebih tinggi, gunakan metode
MediaRecorder.setProfile
, dan dapatkan instance profil menggunakanCamcorderProfile.get()
. Untuk versi Android sebelum 2.2, Anda harus menyetel format output video dan parameter encoding:setOutputFormat()
- Setel format output, tentukan setelan default atauMediaRecorder.OutputFormat.MPEG_4
.setAudioEncoder()
- Setel jenis encoding suara, tentukan setelan default atauMediaRecorder.AudioEncoder.AMR_NB
.setVideoEncoder()
- Setel jenis encoding video, tentukan setelan default atauMediaRecorder.VideoEncoder.MPEG_4_SP
.
setOutputFile()
- Setel file output, gunakangetOutputMediaFile(MEDIA_TYPE_VIDEO).toString()
dari metode contoh di bagian Menyimpan File Media.setPreviewDisplay()
- Tentukan elemen tata letak pratinjauSurfaceView
untuk aplikasi Anda. Gunakan objek yang sama yang Anda tentukan untuk Menghubungkan Pratinjau.
Perhatian: Anda harus memanggil metode konfigurasi
MediaRecorder
dalam urutan ini, jika tidak, aplikasi Anda akan mengalami error dan perekaman akan gagal. - Menyiapkan MediaRecorder - Siapkan
MediaRecorder
dengan setelan konfigurasi yang disediakan dengan memanggilMediaRecorder.prepare()
. - Memulai MediaRecorder - Mulai merekam video dengan memanggil
MediaRecorder.start()
.
- Membuka Kunci Kamera - Buka kunci kamera untuk digunakan oleh
- Menghentikan Rekaman Video - Panggil metode berikut agar
berhasil menyelesaikan rekaman video:
- Menghentikan MediaRecorder - Hentikan merekam video dengan memanggil
MediaRecorder.stop()
. - Mereset MediaRecorder - Secara opsional, hapus setelan konfigurasi dari
perekam dengan memanggil
MediaRecorder.reset()
. - Merilis MediaRecorder - Rilis
MediaRecorder
dengan memanggilMediaRecorder.release()
. - Mengunci Kamera - Kunci kamera sehingga sesi
MediaRecorder
berikutnya dapat menggunakannya dengan memanggilCamera.lock()
. Mulai Android 4.0 (API level 14), panggilan ini tidak diperlukan kecuali jika panggilanMediaRecorder.prepare()
gagal.
- Menghentikan MediaRecorder - Hentikan merekam video dengan memanggil
- Menghentikan Pratinjau - Saat aktivitas Anda selesai menggunakan kamera, hentikan
pratinjau menggunakan
Camera.stopPreview()
. - Merilis Kamera - Rilis kamera sehingga aplikasi lain dapat menggunakannya
dengan memanggil
Camera.release()
.
Catatan: Dimungkinkan untuk menggunakan MediaRecorder
tanpa membuat pratinjau kamera terlebih dahulu dan melewati beberapa langkah pertama proses ini. Namun,
karena pengguna biasanya lebih suka melihat pratinjau sebelum memulai rekaman, proses itu tidak dibahas di sini.
Tips: Jika aplikasi Anda biasanya digunakan untuk merekam video, setel setRecordingHint(boolean)
ke true
sebelum memulai pratinjau. Setelan ini dapat membantu mengurangi waktu yang diperlukan untuk memulai rekaman.
Mengonfigurasi MediaRecorder
Saat menggunakan class MediaRecorder
untuk merekam video, Anda harus melakukan
langkah-langkah konfigurasi dalam urutan spesifik, lalu memanggil metode MediaRecorder.prepare()
untuk memeriksa dan mengimplementasikan konfigurasi. Contoh kode berikut menunjukkan cara mengonfigurasi dan mempersiapkan class
MediaRecorder
untuk perekaman video dengan benar.
Kotlin
private fun prepareVideoRecorder(): Boolean { mediaRecorder = MediaRecorder() mCamera?.let { camera -> // Step 1: Unlock and set camera to MediaRecorder camera?.unlock() mediaRecorder?.run { setCamera(camera) // Step 2: Set sources setAudioSource(MediaRecorder.AudioSource.CAMCORDER) setVideoSource(MediaRecorder.VideoSource.CAMERA) // Step 3: Set a CamcorderProfile (requires API Level 8 or higher) setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH)) // Step 4: Set output file setOutputFile(getOutputMediaFile(MEDIA_TYPE_VIDEO).toString()) // Step 5: Set the preview output setPreviewDisplay(mPreview?.holder?.surface) setOutputFormat(MediaRecorder.OutputFormat.MPEG_4) setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT) setVideoEncoder(MediaRecorder.VideoEncoder.DEFAULT) // Step 6: Prepare configured MediaRecorder return try { prepare() true } catch (e: IllegalStateException) { Log.d(TAG, "IllegalStateException preparing MediaRecorder: ${e.message}") releaseMediaRecorder() false } catch (e: IOException) { Log.d(TAG, "IOException preparing MediaRecorder: ${e.message}") releaseMediaRecorder() false } } } return false }
Java
private boolean prepareVideoRecorder(){ mCamera = getCameraInstance(); mediaRecorder = new MediaRecorder(); // Step 1: Unlock and set camera to MediaRecorder mCamera.unlock(); mediaRecorder.setCamera(mCamera); // Step 2: Set sources mediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER); mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA); // Step 3: Set a CamcorderProfile (requires API Level 8 or higher) mediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH)); // Step 4: Set output file mediaRecorder.setOutputFile(getOutputMediaFile(MEDIA_TYPE_VIDEO).toString()); // Step 5: Set the preview output mediaRecorder.setPreviewDisplay(mPreview.getHolder().getSurface()); // Step 6: Prepare configured MediaRecorder try { mediaRecorder.prepare(); } catch (IllegalStateException e) { Log.d(TAG, "IllegalStateException preparing MediaRecorder: " + e.getMessage()); releaseMediaRecorder(); return false; } catch (IOException e) { Log.d(TAG, "IOException preparing MediaRecorder: " + e.getMessage()); releaseMediaRecorder(); return false; } return true; }
Sebelum Android 2.2 (API Level 8), Anda harus menyetel parameter
format output dan format encoding secara langsung, daripada menggunakan CamcorderProfile
. Pendekatan ini
ditunjukkan dalam kode berikut:
Kotlin
// Step 3: Set output format and encoding (for versions prior to API Level 8) mediaRecorder?.apply { setOutputFormat(MediaRecorder.OutputFormat.MPEG_4) setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT) setVideoEncoder(MediaRecorder.VideoEncoder.DEFAULT) }
Java
// Step 3: Set output format and encoding (for versions prior to API Level 8) mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT); mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.DEFAULT);
Parameter perekaman video berikut untuk MediaRecorder
diberi setelan default, tetapi Anda mungkin ingin menyesuaikan setelan ini untuk aplikasi Anda:
setVideoEncodingBitRate()
setVideoSize()
setVideoFrameRate()
setAudioEncodingBitRate()
setAudioChannels()
setAudioSamplingRate()
Memulai dan menghentikan MediaRecorder
Saat memulai dan menghentikan perekaman video menggunakan class MediaRecorder
,
Anda harus mengikuti urutan tertentu, seperti yang tercantum di bawah ini.
- Buka kunci kamera dengan
Camera.unlock()
- Konfigurasi
MediaRecorder
seperti yang ditunjukkan pada contoh kode di atas - Mulai perekaman menggunakan
MediaRecorder.start()
- Rekam videonya
- Hentikan perekaman menggunakan
MediaRecorder.stop()
- Rilis perekam media dengan
MediaRecorder.release()
- Kunci kamera menggunakan
Camera.lock()
Kode contoh berikut menunjukkan cara memasang tombol untuk memulai dan menghentikan
perekaman video dengan benar menggunakan kamera dan class MediaRecorder
.
Catatan: Saat menyelesaikan rekaman video, jangan rilis kamera atau pratinjau Anda akan dihentikan.
Kotlin
var isRecording = false val captureButton: Button = findViewById(R.id.button_capture) captureButton.setOnClickListener { if (isRecording) { // stop recording and release camera mediaRecorder?.stop() // stop the recording releaseMediaRecorder() // release the MediaRecorder object mCamera?.lock() // take camera access back from MediaRecorder // inform the user that recording has stopped setCaptureButtonText("Capture") isRecording = false } else { // initialize video camera if (prepareVideoRecorder()) { // Camera is available and unlocked, MediaRecorder is prepared, // now you can start recording mediaRecorder?.start() // inform the user that recording has started setCaptureButtonText("Stop") isRecording = true } else { // prepare didn't work, release the camera releaseMediaRecorder() // inform user } } }
Java
private boolean isRecording = false; // Add a listener to the Capture button Button captureButton = (Button) findViewById(id.button_capture); captureButton.setOnClickListener( new View.OnClickListener() { @Override public void onClick(View v) { if (isRecording) { // stop recording and release camera mediaRecorder.stop(); // stop the recording releaseMediaRecorder(); // release the MediaRecorder object mCamera.lock(); // take camera access back from MediaRecorder // inform the user that recording has stopped setCaptureButtonText("Capture"); isRecording = false; } else { // initialize video camera if (prepareVideoRecorder()) { // Camera is available and unlocked, MediaRecorder is prepared, // now you can start recording mediaRecorder.start(); // inform the user that recording has started setCaptureButtonText("Stop"); isRecording = true; } else { // prepare didn't work, release the camera releaseMediaRecorder(); // inform user } } } } );
Catatan: Dalam contoh di atas, metode prepareVideoRecorder()
merujuk pada kode contoh yang ditunjukkan pada Mengonfigurasi MediaRecorder. Metode ini menangani penguncian kamera,
konfigurasi, dan penyiapan instance MediaRecorder
.
Merilis kamera
Kamera adalah sumber daya yang digunakan bersama oleh aplikasi pada perangkat. Aplikasi Anda dapat menggunakan
kamera setelah mendapatkan instance Camera
, dan Anda harus sangat
berhati-hati untuk merilis objek kamera saat aplikasi berhenti menggunakannya, dan
segera setelah aplikasi dijeda (Activity.onPause()
). Jika
aplikasi Anda tidak merilis kamera dengan benar, semua upaya berikutnya untuk mengakses kamera,
termasuk yang dilakukan oleh aplikasi Anda sendiri, akan gagal dan dapat menyebabkan aplikasi Anda atau aplikasi lainnya
dinonaktifkan.
Untuk merilis instance objek Camera
, gunakan metode Camera.release()
seperti yang ditunjukkan pada contoh kode di bawah ini.
Kotlin
class CameraActivity : Activity() { private var mCamera: Camera? private var preview: SurfaceView? private var mediaRecorder: MediaRecorder? override fun onPause() { super.onPause() releaseMediaRecorder() // if you are using MediaRecorder, release it first releaseCamera() // release the camera immediately on pause event } private fun releaseMediaRecorder() { mediaRecorder?.reset() // clear recorder configuration mediaRecorder?.release() // release the recorder object mediaRecorder = null mCamera?.lock() // lock camera for later use } private fun releaseCamera() { mCamera?.release() // release the camera for other applications mCamera = null } }
Java
public class CameraActivity extends Activity { private Camera mCamera; private SurfaceView preview; private MediaRecorder mediaRecorder; ... @Override protected void onPause() { super.onPause(); releaseMediaRecorder(); // if you are using MediaRecorder, release it first releaseCamera(); // release the camera immediately on pause event } private void releaseMediaRecorder(){ if (mediaRecorder != null) { mediaRecorder.reset(); // clear recorder configuration mediaRecorder.release(); // release the recorder object mediaRecorder = null; mCamera.lock(); // lock camera for later use } } private void releaseCamera(){ if (mCamera != null){ mCamera.release(); // release the camera for other applications mCamera = null; } } }
Perhatian: Jika aplikasi Anda tidak merilis kamera dengan benar, semua upaya berikutnya untuk mengakses kamera, termasuk yang dilakukan oleh aplikasi Anda sendiri, akan gagal dan dapat menyebabkan aplikasi Anda atau lainnya dinonaktifkan.
Menyimpan file media
File media yang dibuat oleh pengguna seperti gambar dan video harus disimpan ke direktori penyimpanan eksternal perangkat (Kartu SD) untuk menghemat ruang sistem dan memungkinkan pengguna untuk mengakses file-file ini tanpa perangkat mereka. Ada banyak kemungkinan lokasi direktori untuk menyimpan file media pada perangkat, tetapi hanya ada dua lokasi standar yang harus Anda pertimbangkan sebagai developer:
Environment.getExternalStoragePublicDirectory
(Environment.DIRECTORY_PICTURES
) - Metode ini menampilkan lokasi standar, bersama, dan yang disarankan untuk menyimpan gambar dan video. Direktori ini dibagikan (publik), sehingga aplikasi lain dapat dengan mudah menemukan, membaca, mengubah, dan menghapus file yang disimpan di lokasi ini. Jika aplikasi Anda dihapus oleh pengguna, file media yang disimpan di lokasi ini tidak akan dihapus. Untuk menghindari gangguan pada pengguna yang ada gambar dan video, Anda harus membuat sub-direktori untuk file media aplikasi Anda dalam direktori ini, seperti yang ditunjukkan dalam contoh kode di bawah ini. Metode ini tersedia di Android 2.2 (API Level 8), untuk panggilan setara di versi API sebelumnya, lihat Menyimpan File Bersama.Context.getExternalFilesDir
(Environment.DIRECTORY_PICTURES
) - Metode ini menampilkan lokasi standar untuk menyimpan gambar dan video yang terkait dengan aplikasi Anda. Jika aplikasi Anda dihapus, file apa pun yang disimpan di lokasi ini akan terhapus. Keamanan tidak diberlakukan untuk file di lokasi ini dan aplikasi lain dapat membaca, mengubah, dan menghapusnya.
Kode contoh berikut menunjukkan cara membuat lokasi File
atau Uri
untuk file media yang dapat digunakan saat mengaktifkan kamera perangkat dengan
Intent
atau sebagai bagian dari Membuat Aplikasi
Kamera.
Kotlin
val MEDIA_TYPE_IMAGE = 1 val MEDIA_TYPE_VIDEO = 2 /** Create a file Uri for saving an image or video */ private fun getOutputMediaFileUri(type: Int): Uri { return Uri.fromFile(getOutputMediaFile(type)) } /** Create a File for saving an image or video */ private fun getOutputMediaFile(type: Int): File? { // To be safe, you should check that the SDCard is mounted // using Environment.getExternalStorageState() before doing this. val mediaStorageDir = File( Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "MyCameraApp" ) // This location works best if you want the created images to be shared // between applications and persist after your app has been uninstalled. // Create the storage directory if it does not exist mediaStorageDir.apply { if (!exists()) { if (!mkdirs()) { Log.d("MyCameraApp", "failed to create directory") return null } } } // Create a media file name val timeStamp = SimpleDateFormat("yyyyMMdd_HHmmss").format(Date()) return when (type) { MEDIA_TYPE_IMAGE -> { File("${mediaStorageDir.path}${File.separator}IMG_$timeStamp.jpg") } MEDIA_TYPE_VIDEO -> { File("${mediaStorageDir.path}${File.separator}VID_$timeStamp.mp4") } else -> null } }
Java
public static final int MEDIA_TYPE_IMAGE = 1; public static final int MEDIA_TYPE_VIDEO = 2; /** Create a file Uri for saving an image or video */ private static Uri getOutputMediaFileUri(int type){ return Uri.fromFile(getOutputMediaFile(type)); } /** Create a File for saving an image or video */ private static File getOutputMediaFile(int type){ // To be safe, you should check that the SDCard is mounted // using Environment.getExternalStorageState() before doing this. File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory( Environment.DIRECTORY_PICTURES), "MyCameraApp"); // This location works best if you want the created images to be shared // between applications and persist after your app has been uninstalled. // Create the storage directory if it does not exist if (! mediaStorageDir.exists()){ if (! mediaStorageDir.mkdirs()){ Log.d("MyCameraApp", "failed to create directory"); return null; } } // Create a media file name String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()); File mediaFile; if (type == MEDIA_TYPE_IMAGE){ mediaFile = new File(mediaStorageDir.getPath() + File.separator + "IMG_"+ timeStamp + ".jpg"); } else if(type == MEDIA_TYPE_VIDEO) { mediaFile = new File(mediaStorageDir.getPath() + File.separator + "VID_"+ timeStamp + ".mp4"); } else { return null; } return mediaFile; }
Catatan: Environment.getExternalStoragePublicDirectory()
tersedia di Android 2.2 (API Level 8)
atau lebih tinggi. Jika Anda menargetkan perangkat dengan versi Android yang lebih lama, gunakan Environment.getExternalStorageDirectory()
sebagai gantinya. Untuk informasi selengkapnya, lihat Menyimpan File Bersama.
Untuk membuat URI mendukung profil kerja, pertama
konversikan URI file ke URI konten. Kemudian, tambahkan URI konten untuk
EXTRA_OUTPUT
dari Intent
.
Untuk informasi selengkapnya tentang menyimpan file di perangkat Android, lihat Penyimpanan Data.
Fitur kamera
Android mendukung beragam fitur kamera yang dapat Anda kontrol dengan aplikasi kamera,
seperti format gambar, mode lampu flash, setelan fokus, dan banyak lagi. Bagian ini mencantumkan fitur-fitur
kamera yang umum, dan secara singkat membahas cara menggunakannya. Sebagian besar fitur kamera dapat diakses dan disetel
menggunakan objek Camera.Parameters
. Namun, ada beberapa
fitur penting yang memerlukan lebih dari sekadar setelan sederhana dalam Camera.Parameters
. Fitur-fitur ini tercakup di bagian berikut:
Untuk informasi umum tentang cara menggunakan fitur yang dikontrol melalui Camera.Parameters
, tinjau bagian Menggunakan fitur
kamera. Untuk informasi lebih detail tentang cara menggunakan fitur yang dikontrol melalui
objek parameter kamera, ikuti link dalam daftar fitur di bawah ini ke dokumentasi
referensi API.
Tabel 1. Fitur kamera umum yang diurutkan berdasarkan Android API Level tempat fitur tersebut diperkenalkan.
Fitur | API Level | Deskripsi |
---|---|---|
Deteksi Wajah | 14 | Mengidentifikasi wajah manusia dalam gambar dan menggunakannya untuk fokus, pengukuran, dan keseimbangan putih |
Area Pengukuran | 14 | Menentukan satu atau beberapa area dalam gambar untuk menghitung keseimbangan putih |
Area Fokus | 14 | Menyetel satu atau beberapa area dalam gambar untuk digunakan untuk fokus |
White Balance Lock |
14 | Menghentikan atau memulai penyesuaian keseimbangan putih otomatis |
Exposure Lock |
14 | Menghentikan atau memulai penyesuaian eksposur otomatis |
Video Snapshot |
14 | Mengambil foto saat merekam video (pengambilan bingkai) |
Video Time Lapse | 11 | Merekam bingkai dengan penundaan yang disetel untuk merekam video time lapse |
Multiple Cameras |
9 | Dukungan untuk lebih dari satu kamera pada perangkat, termasuk kamera depan dan belakang |
Focus Distance |
9 | Melaporkan jarak antara kamera dan objek yang tampak dalam fokus |
Zoom |
8 | Menyetel pembesaran gambar |
Exposure
Compensation |
8 | Menambah atau mengurangi level eksposur cahaya |
GPS Data |
5 | Menyertakan atau menghapus data lokasi geografis dengan gambar |
White Balance |
5 | Menyetel mode keseimbangan putih, yang memengaruhi nilai warna pada gambar yang diambil |
Focus Mode |
5 | Menyetel cara kamera fokus pada objek, misalnya otomatis, tetap, makro, atau tak terbatas |
Scene Mode |
5 | Menerapkan mode preset untuk jenis situasi fotografi tertentu seperti pemandangan malam, pantai, salju, atau cahaya lilin |
JPEG Quality |
5 | Menyetel level kompresi untuk gambar JPEG, yang menambah atau mengurangi kualitas dan ukuran file output gambar |
Flash Mode |
5 | Menyalakan atau mematikan flash, atau menggunakan setelan otomatis |
Color Effects |
5 | Menerapkan efek warna pada gambar yang diambil seperti hitam dan putih, warna sepia atau negatif. |
Anti-Banding |
5 | Mengurangi efek garis melintang pada gradien warna karena kompresi JPEG |
Picture Format |
1 | Menentukan format file untuk gambar |
Picture Size |
1 | Menentukan dimensi piksel dari gambar yang disimpan |
Catatan: Fitur ini tidak didukung di semua perangkat karena perbedaan hardware dan penerapan software. Untuk informasi tentang cara memeriksa ketersediaan fitur pada perangkat tempat aplikasi Anda berjalan, lihat Memeriksa ketersediaan fitur.
Memeriksa ketersediaan fitur
Hal pertama yang harus dipahami saat menetapkan untuk menggunakan fitur kamera pada perangkat Android adalah tidak semua fitur kamera didukung pada semua perangkat. Selain itu, perangkat yang mendukung fitur tertentu dapat mendukungnya ke level yang berbeda atau dengan opsi yang berbeda. Oleh karena itu, bagian dari proses pengambilan keputusan saat Anda mengembangkan aplikasi kamera adalah memutuskan fitur kamera apa yang ingin Anda dukung dan pada level apa. Setelah membuat keputusan itu, Anda harus merencanakan untuk memasukkan kode dalam aplikasi kamera yang memeriksa apakah hardware perangkat mendukung fitur-fitur tersebut dan gagal dengan baik jika fitur tidak tersedia.
Anda dapat memeriksa ketersediaan fitur kamera dengan mendapatkan instance objek parameter
kamera, dan memeriksa metode yang relevan. Contoh kode berikut menunjukkan cara mendapatkan objek
Camera.Parameters
dan memeriksa apakah kamera mendukung fitur fokus otomatis:
Kotlin
val params: Camera.Parameters? = camera?.parameters val focusModes: List<String>? = params?.supportedFocusModes if (focusModes?.contains(Camera.Parameters.FOCUS_MODE_AUTO) == true) { // Autofocus mode is supported }
Java
// get Camera parameters Camera.Parameters params = camera.getParameters(); List<String> focusModes = params.getSupportedFocusModes(); if (focusModes.contains(Camera.Parameters.FOCUS_MODE_AUTO)) { // Autofocus mode is supported }
Anda dapat menggunakan teknik yang ditunjukkan di atas untuk sebagian besar fitur kamera. Objek
Camera.Parameters
menyediakan metode getSupported...()
, is...Supported()
, atau getMax...()
untuk mengetahui apakah (dan sejauh mana) fitur
didukung.
Jika aplikasi memerlukan fitur kamera tertentu agar berfungsi dengan benar, Anda dapat memintanya melalui penambahan pada manifes aplikasi Anda. Saat Anda mendeklarasikan penggunaan fitur kamera tertentu, seperti flash dan autofocus, Google Play membatasi aplikasi Anda agar tidak diinstal pada perangkat yang tidak mendukung fitur ini. Untuk daftar fitur kamera yang dapat dideklarasikan dalam manifes aplikasi Anda, lihat manifes Referensi Fitur.
Menggunakan fitur kamera
Sebagian besar fitur kamera diaktifkan dan dikontrol menggunakan objek Camera.Parameters
. Anda mendapatkan objek ini dengan terlebih dahulu membuat instance objek
Camera
, memanggil metode getParameters()
, mengubah objek parameter yang
ditampilkan, lalu menyetelnya kembali ke objek kamera, seperti yang ditunjukkan dalam kode
contoh berikut:
Kotlin
val params: Camera.Parameters? = camera?.parameters params?.focusMode = Camera.Parameters.FOCUS_MODE_AUTO camera?.parameters = params
Java
// get Camera parameters Camera.Parameters params = camera.getParameters(); // set the focus mode params.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO); // set Camera parameters camera.setParameters(params);
Teknik ini berfungsi untuk hampir semua fitur kamera, dan sebagian besar parameter dapat diubah
kapan saja setelah Anda mendapatkan instance objek Camera
. Perubahan
pada parameter biasanya langsung terlihat oleh pengguna di pratinjau kamera aplikasi.
Di sisi software, perubahan parameter mungkin memerlukan beberapa bingkai agar benar-benar berfungsi saat
hardware kamera memproses instruksi baru dan kemudian mengirim data gambar yang diperbarui.
Penting: Beberapa fitur kamera tidak dapat diubah sesuai keinginan. Secara khusus, mengubah ukuran atau orientasi pratinjau kamera mengharuskan Anda terlebih dahulu menghentikan pratinjau, mengubah ukuran pratinjau, lalu memulai ulang pratinjau. Memulai dengan orientasi pratinjau Android 4.0 (API Level 14) dapat diubah tanpa memulai ulang pratinjau.
Fitur kamera lainnya memerlukan lebih banyak kode untuk diimplementasikan, termasuk:
- Pengukuran dan area fokus
- Deteksi wajah
- Video time lapse
Garis besar singkat cara mengimplementasikan fitur-fitur ini disediakan di bagian berikut.
Pengukuran dan area fokus
Dalam beberapa skenario fotografi, pemfokusan otomatis dan pengukuran cahaya mungkin tidak menghasilkan hasil yang diinginkan. Mulai Android 4.0 (API Level 14), aplikasi kamera Anda dapat memberikan kontrol tambahan untuk memungkinkan aplikasi atau pengguna Anda menentukan area dalam gambar yang akan digunakan untuk menentukan fokus atau setelan level cahaya dan meneruskan nilai-nilai ini ke hardware kamera untuk digunakan dalam mengambil gambar atau video.
Area untuk pengukuran dan fokus berfungsi sangat mirip dengan fitur kamera lainnya, karena Anda
mengontrolnya melalui metode pada objek Camera.Parameters
. Kode berikut
menunjukkan setelan dua area pengukuran cahaya untuk instance
Camera
:
Kotlin
// Create an instance of Camera camera = getCameraInstance() // set Camera parameters val params: Camera.Parameters? = camera?.parameters params?.apply { if (maxNumMeteringAreas > 0) { // check that metering areas are supported meteringAreas = ArrayList<Camera.Area>().apply { val areaRect1 = Rect(-100, -100, 100, 100) // specify an area in center of image add(Camera.Area(areaRect1, 600)) // set weight to 60% val areaRect2 = Rect(800, -1000, 1000, -800) // specify an area in upper right of image add(Camera.Area(areaRect2, 400)) // set weight to 40% } } camera?.parameters = this }
Java
// Create an instance of Camera camera = getCameraInstance(); // set Camera parameters Camera.Parameters params = camera.getParameters(); if (params.getMaxNumMeteringAreas() > 0){ // check that metering areas are supported List<Camera.Area> meteringAreas = new ArrayList<Camera.Area>(); Rect areaRect1 = new Rect(-100, -100, 100, 100); // specify an area in center of image meteringAreas.add(new Camera.Area(areaRect1, 600)); // set weight to 60% Rect areaRect2 = new Rect(800, -1000, 1000, -800); // specify an area in upper right of image meteringAreas.add(new Camera.Area(areaRect2, 400)); // set weight to 40% params.setMeteringAreas(meteringAreas); } camera.setParameters(params);
Objek Camera.Area
berisi dua parameter data: Objek Rect
untuk menentukan area dalam ruang pandang kamera dan nilai
bobot, yang memberi tahu kamera berapa level nilai penting yang harus diberikan pada area ini dalam pengukuran cahaya atau perhitungan fokus.
Bidang Rect
dalam objek Camera.Area
menjelaskan bentuk persegi panjang yang dipetakan pada petak unit 2000 x 2000. Koordinat -1000, -1000
merepresentasikan sudut kiri atas gambar kamera, dan koordinat 1000, 1000 merepresentasikan
sudut kanan bawah gambar kamera, seperti yang ditunjukkan pada ilustrasi di bawah ini.
Gambar 1. Garis merah menggambarkan sistem koordinat untuk menentukan
Camera.Area
dalam pratinjau kamera. Kotak biru menunjukkan lokasi dan
bentuk area kamera dengan nilai Rect
333,333,667,667.
Batas-batas sistem koordinat ini selalu sesuai dengan tepi luar gambar yang terlihat
di pratinjau kamera dan tidak menyusut atau melebar dengan level zoom. Demikian pula, rotasi pratinjau gambar menggunakan Camera.setDisplayOrientation()
tidak memetakan ulang sistem koordinat.
Deteksi wajah
Untuk gambar yang menyertakan orang, wajah biasanya merupakan bagian terpenting dari gambar, dan harus digunakan untuk menentukan fokus dan keseimbangan putih saat mengambil foto. Framework Android 4.0 (API Level 14) menyediakan API untuk mengidentifikasi wajah dan menghitung setelan gambar menggunakan teknologi pengenalan wajah.
Catatan: Saat fitur deteksi wajah berjalan,
setWhiteBalance(String)
,
setFocusAreas(List<Camera.Area>)
, dan
setMeteringAreas(List<Camera.Area>)
tidak memiliki efek.
Menggunakan fitur deteksi wajah dalam aplikasi kamera Anda memerlukan beberapa langkah umum:
- Periksa apakah deteksi wajah didukung pada perangkat
- Buat pemroses deteksi wajah
- Tambahkan pemroses deteksi wajah ke objek kamera
- Mulai deteksi wajah setelah pratinjau (dan setelah setiap pratinjau dimulai ulang)
Fitur deteksi wajah tidak didukung di semua perangkat. Anda dapat memeriksa apakah fitur ini
didukung dengan memanggil getMaxNumDetectedFaces()
. Contoh
pemeriksaan ini ditunjukkan dalam metode contoh startFaceDetection()
di bawah ini.
Agar diberi tahu dan merespons deteksi wajah, aplikasi kamera Anda harus mengatur
pemroses untuk peristiwa deteksi wajah. Untuk melakukannya, Anda harus membuat class pemroses
yang mengimplementasikan antarmuka Camera.FaceDetectionListener
seperti yang ditunjukkan pada
contoh kode di bawah ini.
Kotlin
internal class MyFaceDetectionListener : Camera.FaceDetectionListener { override fun onFaceDetection(faces: Array<Camera.Face>, camera: Camera) { if (faces.isNotEmpty()) { Log.d("FaceDetection", ("face detected: ${faces.size}" + " Face 1 Location X: ${faces[0].rect.centerX()}" + "Y: ${faces[0].rect.centerY()}")) } } }
Java
class MyFaceDetectionListener implements Camera.FaceDetectionListener { @Override public void onFaceDetection(Face[] faces, Camera camera) { if (faces.length > 0){ Log.d("FaceDetection", "face detected: "+ faces.length + " Face 1 Location X: " + faces[0].rect.centerX() + "Y: " + faces[0].rect.centerY() ); } } }
Setelah membuat class ini, Anda dapat menyetelnya ke dalam objek
Camera
aplikasi Anda, seperti yang ditunjukkan pada contoh kode di bawah ini:
Kotlin
camera?.setFaceDetectionListener(MyFaceDetectionListener())
Java
camera.setFaceDetectionListener(new MyFaceDetectionListener());
Aplikasi Anda harus memulai fungsi deteksi wajah setiap kali memulai (atau memulai ulang) pratinjau kamera. Buat metode untuk memulai deteksi wajah sehingga Anda dapat memanggilnya sesuai kebutuhan, seperti yang ditunjukkan pada kode contoh di bawah ini.
Kotlin
fun startFaceDetection() { // Try starting Face Detection val params = mCamera?.parameters // start face detection only *after* preview has started params?.apply { if (maxNumDetectedFaces > 0) { // camera supports face detection, so can start it: mCamera?.startFaceDetection() } } }
Java
public void startFaceDetection(){ // Try starting Face Detection Camera.Parameters params = mCamera.getParameters(); // start face detection only *after* preview has started if (params.getMaxNumDetectedFaces() > 0){ // camera supports face detection, so can start it: mCamera.startFaceDetection(); } }
Anda harus memulai deteksi wajah setiap kali Anda memulai (atau memulai ulang) pratinjau kamera. Jika
Anda menggunakan class pratinjau yang ditunjukkan dalam Membuat class pratinjau, tambahkan metode
startFaceDetection()
ke metode
surfaceCreated()
dan surfaceChanged()
di class pratinjau Anda,
seperti yang ditunjukkan pada kode contoh di bawah ini.
Kotlin
override fun surfaceCreated(holder: SurfaceHolder) { try { mCamera.setPreviewDisplay(holder) mCamera.startPreview() startFaceDetection() // start face detection feature } catch (e: IOException) { Log.d(TAG, "Error setting camera preview: ${e.message}") } } override fun surfaceChanged(holder: SurfaceHolder, format: Int, w: Int, h: Int) { if (holder.surface == null) { // preview surface does not exist Log.d(TAG, "holder.getSurface() == null") return } try { mCamera.stopPreview() } catch (e: Exception) { // ignore: tried to stop a non-existent preview Log.d(TAG, "Error stopping camera preview: ${e.message}") } try { mCamera.setPreviewDisplay(holder) mCamera.startPreview() startFaceDetection() // re-start face detection feature } catch (e: Exception) { // ignore: tried to stop a non-existent preview Log.d(TAG, "Error starting camera preview: ${e.message}") } }
Java
public void surfaceCreated(SurfaceHolder holder) { try { mCamera.setPreviewDisplay(holder); mCamera.startPreview(); startFaceDetection(); // start face detection feature } catch (IOException e) { Log.d(TAG, "Error setting camera preview: " + e.getMessage()); } } public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { if (holder.getSurface() == null){ // preview surface does not exist Log.d(TAG, "holder.getSurface() == null"); return; } try { mCamera.stopPreview(); } catch (Exception e){ // ignore: tried to stop a non-existent preview Log.d(TAG, "Error stopping camera preview: " + e.getMessage()); } try { mCamera.setPreviewDisplay(holder); mCamera.startPreview(); startFaceDetection(); // re-start face detection feature } catch (Exception e){ // ignore: tried to stop a non-existent preview Log.d(TAG, "Error starting camera preview: " + e.getMessage()); } }
Catatan: Ingat untuk memanggil metode ini setelah memanggil
startPreview()
. Jangan coba memulai deteksi wajah dalam metode
onCreate()
dari aktivitas utama aplikasi kamera Anda,
karena pratinjau tidak tersedia pada titik ini dalam eksekusi aplikasi Anda.
Video time lapse
Video time lapse memungkinkan pengguna untuk membuat klip video yang menggabungkan gambar yang diambil terpisah selang beberapa detik
atau menit. Fitur ini menggunakan MediaRecorder
untuk merekam gambar untuk
urutan time lapse.
Untuk merekam video time lapse dengan MediaRecorder
, Anda harus mengonfigurasi
objek perekam seolah-olah Anda merekam video normal, menyetel frame yang diambil per detik
ke angka rendah, dan menggunakan salah satu setelan kualitas time lapse, seperti yang ditunjukkan pada contoh kode di bawah ini.
Kotlin
mediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_TIME_LAPSE_HIGH)) mediaRecorder.setCaptureRate(0.1) // capture a frame every 10 seconds
Java
// Step 3: Set a CamcorderProfile (requires API Level 8 or higher) mediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_TIME_LAPSE_HIGH)); ... // Step 5.5: Set the video capture rate to a low number mediaRecorder.setCaptureRate(0.1); // capture a frame every 10 seconds
Setelan ini harus dilakukan sebagai bagian dari prosedur konfigurasi yang lebih besar untuk MediaRecorder
. Untuk contoh kode konfigurasi lengkap, lihat Mengonfigurasi MediaRecorder. Setelah konfigurasi selesai,
mulai merekam video seolah-olah Anda sedang merekam klip video normal. Untuk informasi selengkapnya
tentang cara mengonfigurasi dan menjalankan MediaRecorder
, lihat Merekam video.
Contoh Camera2Video dan HdrViewfinder lebih lanjut menunjukkan penggunaan API yang dibahas di halaman ini.
Bidang kamera yang memerlukan izin
Aplikasi yang menjalankan Android 10 (API level 29) atau yang lebih tinggi harus memiliki izin
CAMERA
untuk
mengakses nilai dari kolom berikut yang dihasilkan oleh metode
getCameraCharacteristics()
:
LENS_POSE_ROTATION
LENS_POSE_TRANSLATION
LENS_INTRINSIC_CALIBRATION
LENS_RADIAL_DISTORTION
LENS_POSE_REFERENCE
LENS_DISTORTION
LENS_INFO_HYPERFOCAL_DISTANCE
LENS_INFO_MINIMUM_FOCUS_DISTANCE
SENSOR_REFERENCE_ILLUMINANT1
SENSOR_REFERENCE_ILLUMINANT2
SENSOR_CALIBRATION_TRANSFORM1
SENSOR_CALIBRATION_TRANSFORM2
SENSOR_COLOR_TRANSFORM1
SENSOR_COLOR_TRANSFORM2
SENSOR_FORWARD_MATRIX1
SENSOR_FORWARD_MATRIX2
Kode contoh tambahan
Untuk mendownload aplikasi sampel, lihat sampel Camera2Basic sample dan aplikasi sampel CameraX resmi.