Platforma Androida zapewnia obsługę różnych aparatów i funkcji aparatu dostępnych urządzeń, dzięki czemu możesz robić zdjęcia i nagrywać filmy w aplikacjach. W tym dokumencie omówiono szybkie i proste podejście do robienia zdjęć i nagrywania filmów. z aparatem dostosowanym do potrzeb użytkowników.
Uwaga:
Na tej stronie dowiesz się:
Camera
klasa, która została wycofana. Zalecamy użycie metody
CameraX; z biblioteki Jetpack lub, w określonych przypadkach,
camera2
,
zajęcia. Zarówno AparatX, jak i Aparat2 działają na Androidzie 5.0 (poziom interfejsu API 21) oraz
wyżej.
Zapoznaj się z tymi powiązanymi materiałami:
co należy wziąć pod uwagę
Zanim pozwolisz aplikacji na korzystanie z aparatów na urządzeniach z Androidem, rozważ kilka pytania na temat tego, w jaki sposób aplikacja będzie korzystać z tej funkcji sprzętowej.
- Wymagania dotyczące aparatu – czy korzystanie z kamery jest tak ważne Aplikacja, której nie chcesz instalować na urządzeniu bez aparat? Jeśli tak, musisz zadeklarować wymagania dotyczące aparatu na swoim pliku manifestu.
- Szybki obraz lub niestandardowy aparat – w jaki sposób aplikacja będzie korzystać z funkcji aparat? Chcesz zrobić krótkie zdjęcie lub klip wideo? A może Twoja aplikacja a my stworzyła nowy sposób korzystania z aparatów? Aby szybko zrobić zdjęcie lub klip, zastanów się: Korzystanie z istniejących aplikacji aparatu. Aby opracować niestandardową funkcję aparatu, zapoznaj się z artykułem zapoznaj się z sekcją Tworzenie aplikacji aparatu.
- Wymagania dotyczące usług działających na pierwszym planie – kiedy Twoja aplikacja wchodzi w interakcję z przez kamerę? Na Androidzie 9 (poziom interfejsu API 28) i nowszych aplikacje działające w Tło nie może uzyskać dostępu do aparatu. Dlatego należy używać aparatu gdy aplikacja działa na pierwszym planie lub usługę działającą na pierwszym planie.
- Pamięć wewnętrzna – czy obrazy lub filmy mają być generowane przez aplikację widoczne tylko dla aplikacji lub udostępniane, aby inne aplikacje, takie jak media i aplikacje społecznościowe mogą z nich korzystać? Czy chcesz, aby zdjęcia i filmy były dostępne, nawet jeśli aplikacja została odinstalowana? Zapoznaj się z sekcją Zapisywanie plików multimedialnych, aby zobacz, jak wdrożyć te opcje.
Podstawy
Platforma Androida obsługuje przechwytywanie obrazów i filmów za pomocą
android.hardware.camera2
API lub kamera Intent
. Oto istotne
zajęcia:
android.hardware.camera2
- Ten pakiet jest podstawowym interfejsem API do sterowania kamerami urządzenia. Może służyć do podejmowania zdjęć lub filmów wideo podczas tworzenia aplikacji aparatu.
Camera
- Ta klasa to starszy wycofany interfejs API do sterowania kamerami urządzenia.
SurfaceView
- Te zajęcia służą do prezentowania użytkownikowi podglądu z kamery na żywo.
MediaRecorder
- Te zajęcia służą do nagrywania obrazu z kamery.
Intent
- Działanie typu
MediaStore.ACTION_IMAGE_CAPTURE
lubMediaStore.ACTION_VIDEO_CAPTURE
może być używane do robienia zdjęć i filmów bez bezpośredniego przy użyciu obiektuCamera
.
Deklaracje w pliku manifestu
Zanim zaczniesz programować przy użyciu interfejsu Camera API, upewnij się, plik manifestu zawiera odpowiednie deklaracje pozwalające na korzystanie ze sprzętu kamery i innych powiązane funkcje.
- Uprawnienia dotyczące aparatu – aplikacja musi prosić o pozwolenie na korzystanie z urządzenia
aparat fotograficzny.
<uses-permission android:name="android.permission.CAMERA" />
Uwaga: jeśli używasz kamery przez wywołanie istniejącej aplikacji aparatu, Twoja aplikacja nie musi żądać tego uprawnienia.
- Funkcje aparatu – w aplikacji musisz też zadeklarować korzystanie z funkcji aparatu,
np.:
<uses-feature android:name="android.hardware.camera" />
Listę funkcji aparatu znajdziesz w pliku manifestu Funkcje Plik referencyjny.
Dodanie funkcji aparatu do pliku manifestu powoduje, że Google Play uniemożliwia aplikacji na urządzeniach, które nie mają kamery lub nie obsługują jej funkcji określić. Więcej informacji o używaniu filtrowania na podstawie cech w Google Play znajdziesz w sekcji Google Play Play i filtrowanie oparte na funkcjach.
jeśli aplikacja może używać jej funkcji do prawidłowego działania, ale nie nie są wymagane, określ to w pliku manifestu, dodając atrybut
android:required
i ustawiając dla niego wartośćfalse
:<uses-feature android:name="android.hardware.camera" android:required="false" />
- Uprawnienie do pamięci – aplikacja może zapisywać obrazy i filmy w
pamięci zewnętrznej urządzenia (karty SD), jeśli jest ona kierowana na Androida 10 (poziom interfejsu API 29) lub
i określa w pliku manifestu te elementy.
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
- Uprawnienia do nagrywania dźwięku – w przypadku nagrywania dźwięku z obrazem
aplikacja musi prosić o uprawnienia do przechwytywania dźwięku.
<uses-permission android:name="android.permission.RECORD_AUDIO" />
-
Pozwolenie na lokalizację – jeśli aplikacja taguje obrazy z informacjami o lokalizacji GPS, musisz wysłać prośbę o
ACCESS_FINE_LOCATION
uprawnienia. Pamiętaj, że jeśli aplikacja jest kierowana na Androida 5.0 (poziom interfejsu API 21) lub wyżej, musisz też zadeklarować, że aplikacja używa GPS-a urządzenia:<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" />
Więcej informacji o uzyskiwaniu lokalizacji użytkownika znajdziesz w sekcji Strategie lokalizacji.
Korzystanie z istniejących aplikacji aparatu
Szybki sposób na robienie zdjęć i nagrywanie filmów w aplikacji bez konieczności pisania dużych ilości kodu
to użycie Intent
do wywołania istniejącej aplikacji aparatu na Androida.
Szczegóły są opisane w wykładach szkoleniowych
Proste robienie zdjęć
Proste nagrywanie filmów.
Tworzę aplikację aparatu
Niektórzy deweloperzy mogą wymagać interfejsu użytkownika kamery dostosowanego do wyglądu aplikacji lub oferuje specjalne funkcje. Pisanie własnego kodu do robienia zdjęć może być atrakcyjniejsza dla użytkowników.
Uwaga: ten przewodnik dotyczy starszych, wycofanych wersji Camera
API. W przypadku nowych i zaawansowanych aplikacji aparatu nowszy interfejs API android.hardware.camera2
to
.
Ogólne kroki tworzenia interfejsu aparatu niestandardowego na potrzeby aplikacji są następujące:
- Wykryj kamerę i uzyskaj dostęp do niej – utwórz kod, aby sprawdzić, czy i poprosić o dostęp.
- Utwórz klasę podglądu – utwórz klasę podglądu kamery, która rozszerza język
SurfaceView
i implementuje interfejsSurfaceHolder
. Ten podczas lekcji wyświetli podgląd obrazów z kamery. - Utwórz układ podglądu – gdy masz już klasę podglądu aparatu, utwórz który obejmuje podgląd i wybrane elementy interfejsu.
- Skonfiguruj detektory przechwytywania – połącz detektory dla swojego interfejsu. elementów sterujących do rozpoczynania nagrywania obrazów i filmów w odpowiedzi na działania użytkownika, takie jak naciśnięcie Przycisk
- Przechwyć i zapisz pliki – skonfiguruj kod do robienia zdjęć lub filmy i zapisanie wyników.
- Zwalnianie aparatu – po użyciu aparatu aplikacja musi: i umożliwić jej używanie w innych aplikacjach.
Kamera to zasób współdzielony, którym trzeba odpowiednio zarządzać, aby aplikacja działała. w taki sposób, aby nie kolidowały z innymi aplikacjami, które również mogą zechcieć z niego korzystać. W poniższych sekcjach omówiono jak wykryć sprzęt z aparatu, jak poprosić o dostęp do aparatu, jak robić zdjęcia lub nagrywać filmy i jak ją zwolnić.
Uwaga: pamiętaj, by zwolnić Camera
przez wywołanie Camera.release()
, gdy
można za jej pomocą zakończyć korzystanie z aplikacji. Jeśli aplikacja nie uruchomi poprawnie aparatu,
kolejne próby dostępu do kamery, również te realizowane przez Twoją aplikację, zakończą się niepowodzeniem i mogą
może spowodować wyłączenie aplikacji lub innych aplikacji.
Wykrywam aparat
Jeśli Twoja aplikacja nie wymaga użycia aparatu przy użyciu deklaracji w pliku manifestu,
powinien sprawdzić, czy kamera jest dostępna w czasie działania. Aby to zrobić, użyj metody PackageManager.hasSystemFeature()
zgodnie z przykładowym kodem poniżej:
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; } }
Urządzenia z Androidem mogą mieć kilka aparatów, na przykład tylny aparat fotograficzny
przednim aparatem do rozmów wideo. Android 2.3 (poziom interfejsu API 9) i nowsze umożliwiają sprawdzenie
liczba kamer dostępnych na urządzeniu za pomocą metody Camera.getNumberOfCameras()
.
Dostęp do kamer
Jeśli okaże się, że urządzenie, na którym działa aplikacja, ma kamerę,
musi zażądać dostępu do niego przez pobranie instancji Camera
(chyba że
używają zamiaru dostępu do kamery).
Aby uzyskać dostęp do aparatu głównego, użyj metody Camera.open()
i pamiętaj o wykrywaniu wszelkich wyjątków, tak jak w poniższym kodzie:
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 }
Uwaga: jeśli używasz Camera.open()
, zawsze sprawdzaj wyjątki. Nie udało się sprawdzić wyjątków, jeśli kamera jest włączona
lub jeśli nie istnieje, spowoduje to wyłączenie aplikacji przez system.
Na urządzeniach z Androidem 2.3 (poziom interfejsu API 9) lub nowszym dostęp do określonych aparatów możesz uzyskać za pomocą
Camera.open(int)
Powyższy przykładowy kod umożliwia dostęp
pierwszy tylny aparat w urządzeniu z więcej niż 1 aparatem.
Sprawdzam funkcje aparatu
Gdy już uzyskasz dostęp do kamery, możesz dowiedzieć się więcej o jej możliwościach w
metody Camera.getParameters()
i sprawdź
zwrócił obiekt Camera.Parameters
, aby uzyskać obsługiwane funkcje. W przypadku użycia funkcji
Interfejs API na poziomie 9 lub wyższym: użyj interfejsu Camera.getCameraInfo()
, aby określić, czy kamera jest z przodu
lub tylnej części urządzenia oraz orientację zdjęcia.
Tworzenie zajęć w wersji testowej
Aby użytkownicy mogli wykonywać zdjęcia i nagrywać filmy, muszą mieć możliwość zobaczenia obrazu z aparatu urządzenia.
który widzi. Klasa podglądu aparatu to obiekt SurfaceView
, który może wyświetlać obraz na żywo
z aparatu, dzięki czemu użytkownicy mogą wykadrować i nagrać zdjęcie lub nagrać film.
Ten przykładowy kod pokazuje, jak utworzyć podstawową klasę podglądu aparatu, którą można
zawarte w układzie View
. Ta klasa implementuje funkcję SurfaceHolder.Callback
, aby przechwytywać zdarzenia wywołania zwrotnego
do tworzenia i niszczenia widoku, które są potrzebne do przypisywania danych wejściowych podglądu z kamery.
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()); } } }
Jeśli chcesz ustawić konkretny rozmiar podglądu z aparatu, ustaw go w metodzie surfaceChanged()
zgodnie z opisem w komentarzach powyżej. Ustawiając rozmiar podglądu,
musi używać wartości z getSupportedPreviewSizes()
.
Nie ustawiaj dowolnych wartości w metodzie setPreviewSize()
.
Uwaga:
Dzięki wprowadzeniu
funkcji wielu okien w Androidzie 7.0 (poziom interfejsu API 24) i nowszych,
Zakładamy, że format obrazu podglądu jest taki sam jak w przypadku aktywności
nawet po połączeniu telefonu z numerem setDisplayOrientation()
.
W zależności od rozmiaru okna i formatu obrazu konieczne może być dopasowanie
do podglądu z aparatu w układzie pionowym lub odwrotnie,
letterbox.
Umieszczanie podglądu w układzie
Klasa podglądu z aparatu, jak w przykładzie z poprzedniej sekcji, musi być umieszczona w polu układ aktywności wraz z innymi opcjami interfejsu do robienia zdjęcia lub nagrywania filmów. Ten pokazuje, jak utworzyć podstawowy układ i aktywność na potrzeby podglądu.
Poniższy kod układu zapewnia podstawowy widok, który można wykorzystać do wyświetlenia kamery
podgląd. W tym przykładzie element FrameLayout
ma być
dla klasy podglądu z użyciem aparatu. Ten typ układu jest używany, aby dodatkowe zdjęcie
informacje lub elementy sterujące można nałożyć na obrazy podglądu z kamery na żywo.
<?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>
Na większości urządzeń domyślna orientacja podglądu aparatu to pozioma. Ten przykładowy układ określa układ poziomy (poziomy), a poniższy kod ustawia orientację aplikacji w orientacji poziomej. Aby ułatwić renderowanie podglądu z aparatu, należy zmienić ustaw orientację działania podglądu aplikacji na poziomą. W tym celu dodaj ten fragment pliku manifestu.
<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>
Uwaga: podgląd z aparatu nie musi być w trybie poziomym.
Począwszy od Androida w wersji 2.2 (poziom interfejsu API 8) możesz używać metody setDisplayOrientation()
do konfigurowania
przez obrót obrazu podglądu. Aby zmienić orientację podglądu, gdy użytkownik zmieni orientację
w ramach metody surfaceChanged()
klasy podglądu najpierw zatrzymaj podgląd przy użyciu polecenia Camera.stopPreview()
, a następnie zmień orientację, a następnie
ponownie włącz podgląd, wybierając Camera.startPreview()
.
W aktywności związanej z widokiem z kamery dodaj klasę podglądu do elementu FrameLayout
widocznego w powyższym przykładzie. Aktywność kamery musi też obejmować
aby ją zwolnił, gdy jest wstrzymany lub wyłączony. Ten przykład pokazuje,
aby zmodyfikować aktywność kamery i dołączyć klasę podglądu widoczną w sekcji Tworzenie
podglądu.
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); } }
Uwaga: metoda getCameraInstance()
w przykładzie powyżej
odnosi się do przykładowej metody przedstawionej w sekcji Uzyskiwanie dostępu do aparatów.
Robię zdjęcia
Po utworzeniu klasy podglądu i układu widoku, w którym chcesz ją wyświetlać, możesz rozpocząć robienie obrazów za pomocą aplikacji. W kodzie aplikacji musisz skonfigurować detektory aby elementy sterujące interfejsu mogły reagować na działanie użytkownika poprzez zrobienie zdjęcia.
Aby pobrać zdjęcie, użyj metody Camera.takePicture()
. Ta metoda wykorzystuje 3 parametry, które odbierają dane z kamery.
Aby otrzymywać dane w formacie JPEG, musisz wdrożyć interfejs Camera.PictureCallback
do odbierania danych obrazu i
zapisać go w pliku. Poniższy kod przedstawia podstawową implementację interfejsu Camera.PictureCallback
w celu zapisywania obrazu otrzymanego z aparatu.
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()); } } };
Aby aktywować przechwytywanie obrazu, wywołaj metodę Camera.takePicture()
. Poniższy przykładowy kod pokazuje, jak wywołać tę metodę z poziomu
przycisk 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); } } );
Uwaga: do nazwy odnosi się użytkownik mPicture
z poniższego przykładu.
do powyższego przykładowego kodu.
Uwaga: pamiętaj, by zwolnić Camera
przez wywołanie Camera.release()
, gdy
można za jej pomocą zakończyć korzystanie z aplikacji. Informacje na temat zwalniania aparatu znajdziesz w sekcji Zwalnianie aparatu.
Nagrywanie filmów
Nagrywanie filmów przy użyciu platformy Androida wymaga starannego zarządzania obiektem Camera
i koordynacji z platformą MediaRecorder
zajęcia. Podczas nagrywania filmów za pomocą urządzenia Camera
musisz zarządzać połączeniami Camera.lock()
i Camera.unlock()
, aby zezwolić aplikacji MediaRecorder
na dostęp do kamery.
oprócz połączeń Camera.open()
i Camera.release()
.
Uwaga: od Androida 4.0 (poziom interfejsu API 14) wywołania Camera.lock()
i Camera.unlock()
są zarządzane automatycznie.
W przeciwieństwie do robienia zdjęć aparatem urządzenia, nagrywanie filmów wymaga konkretnego połączenia. zamówienie. Aby prawidłowo przygotować film i nagrać go, musisz postępować zgodnie z określoną kolejnością ich wykonania. zgodnie z poniższym opisem.
- Otwórz aparat – użyj
Camera.open()
aby pobrać instancję obiektu Camera. - Podłącz podgląd – przygotuj podgląd obrazu z kamery na żywo, podłączając
SurfaceView
do aparatu za pomocąCamera.setPreviewDisplay()
. - Rozpocznij podgląd – wywołaj
Camera.startPreview()
, by rozpocząć wyświetlanie obrazów na żywo z kamery. - Rozpocznij nagrywanie filmu – poniższe czynności należy wykonać w
zamówienie, aby nagrać film:
- Odblokuj aparat – odblokuj aparat i korzystaj z niego do
MediaRecorder
, dzwoniąc pod numerCamera.unlock()
. - Skonfiguruj MediaRecorder – wywołaj poniższe metody
MediaRecorder
w tej kolejności. Więcej informacji znajdziesz w dokumentacji referencyjnejMediaRecorder
.setCamera()
– ustaw kamerę, która będzie używana do nagrywania wideo. Użyj bieżącej instancji aplikacji. zCamera
.setAudioSource()
– ustaw wartość źródła dźwięku, użyj formatuMediaRecorder.AudioSource.CAMCORDER
.setVideoSource()
– ustaw źródła wideo, użyjMediaRecorder.VideoSource.CAMERA
.- Ustaw format i kodowanie wyjściowe wideo. Na Androida 2.2 (poziom interfejsu API 8)
użyj metody
MediaRecorder.setProfile
i pobierz wystąpienie profilu za pomocąCamcorderProfile.get()
. Wersje Androida starsze 2.2, należy ustawić format wyjściowy wideo i parametry kodowania:setOutputFormat()
– ustaw format wyjściowy, określ ustawienie domyślne lubMediaRecorder.OutputFormat.MPEG_4
.setAudioEncoder()
– ustaw typ kodowania dźwięku, określ ustawienie domyślne lubMediaRecorder.AudioEncoder.AMR_NB
.setVideoEncoder()
– ustaw typ kodowania wideo, określ ustawienie domyślne lubMediaRecorder.VideoEncoder.MPEG_4_SP
.
setOutputFile()
– Ustaw plik wyjściowy, użyj polagetOutputMediaFile(MEDIA_TYPE_VIDEO).toString()
z przykładu w sekcji Zapisywanie plików multimedialnych.setPreviewDisplay()
– określ element układu podgląduSurfaceView
dla Twojej aplikacji. Użyj tego samego obiektu, który został podany w podglądzie połączenia.
Uwaga: te metody konfiguracji
MediaRecorder
musisz wywoływać w tej kolejności. W przeciwnym razie aplikacja napotka błędy, a nagrywanie się nie uda. - Prepare MediaRecorder – przygotowywanie
MediaRecorder
z podanymi ustawieniami konfiguracji przez wywołanie metodyMediaRecorder.prepare()
. - Uruchom MediaRecorder – rozpocznij nagrywanie filmu, dzwoniąc pod numer
MediaRecorder.start()
.
- Odblokuj aparat – odblokuj aparat i korzystaj z niego do
- Zatrzymaj nagrywanie filmu – wywołaj poniższe metody w odpowiedniej kolejności, aby
Zakończył nagrywanie filmu:
- Zatrzymaj MediaRecorder – zatrzymaj nagrywanie filmu, wywołując
MediaRecorder.stop()
. - Resetuj MediaRecorder – opcjonalnie usuń ustawienia konfiguracji z
dyktafon, dzwoniąc pod numer
MediaRecorder.reset()
. - Release MediaRecorder – zwolnij
MediaRecorder
dzwoniąc pod numerMediaRecorder.release()
. - Zablokuj kamerę – zablokuj kamerę, aby kolejne sesje
MediaRecorder
mogły z niej korzystać, wywołując funkcjęCamera.lock()
. Od Androida 4.0 (poziom interfejsu API 14) to wywołanie nie jest wymagane, chyba że funkcjaMediaRecorder.prepare()
nieudane połączenie.
- Zatrzymaj MediaRecorder – zatrzymaj nagrywanie filmu, wywołując
- Zatrzymaj podgląd – gdy zakończysz aktywność z użyciem kamery, zatrzymaj
wyświetlić podgląd w elemencie
Camera.stopPreview()
. - Zwolnij aparat – puść aparat, by umożliwić korzystanie z innych aplikacji
go, dzwoniąc pod numer
Camera.release()
.
Uwaga: możesz użyć MediaRecorder
bez tworzenia podglądu z kamery i pomiń kilka pierwszych kroków tego procesu. Pamiętaj jednak:
użytkownicy zwykle wolą zobaczyć podgląd przed rozpoczęciem nagrywania, więc
które tu omawiamy.
Wskazówka: jeśli Twoja aplikacja zwykle służy do nagrywania filmów, ustaw
setRecordingHint(boolean)
do true
przed rozpoczęciem
podgląd. To ustawienie może skrócić czas potrzebny na rozpoczęcie nagrywania.
Konfigurowanie funkcji MediaRecorder
Jeśli używasz klasy MediaRecorder
do nagrywania filmu, musisz wykonać
w określonej kolejności, a potem wywołaj metodę MediaRecorder.prepare()
, aby sprawdzić i zaimplementować
konfiguracji. Poniższy przykładowy kod pokazuje, jak prawidłowo skonfigurować i przygotować
MediaRecorder
zajęcia do nagrywania wideo.
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; }
Przed Androidem 2.2 (poziom interfejsu API 8) trzeba ustawiać format wyjściowy i formaty kodowania
bezpośrednio, zamiast używać parametru CamcorderProfile
. To podejście
w tym kodzie:
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);
Podane są te parametry nagrywania wideo dla: MediaRecorder
domyślnych, ale możesz też dostosować do swojej aplikacji te ustawienia:
setVideoEncodingBitRate()
setVideoSize()
setVideoFrameRate()
setAudioEncodingBitRate()
setAudioChannels()
setAudioSamplingRate()
Uruchamianie i zatrzymywanie MediaRecorder
Gdy rozpoczynasz i zatrzymujesz nagrywanie filmu za pomocą klasy MediaRecorder
:
należy wykonać określoną kolejność, jak podano poniżej.
- Odblokuj aparat za pomocą aplikacji
Camera.unlock()
- Skonfiguruj
MediaRecorder
w sposób pokazany w powyższym przykładzie kodu - Zacznij nagrywać za pomocą urządzenia
MediaRecorder.start()
- Nagraj film
- Zatrzymaj nagrywanie za pomocą
MediaRecorder.stop()
- Zwolnij nagrywarkę multimediów za pomocą funkcji
MediaRecorder.release()
- Zablokuj aparat za pomocą funkcji
Camera.lock()
Ten przykładowy kod pokazuje, jak podłączyć przycisk, aby prawidłowo uruchamiał i zatrzymał się
nagrywanie filmów za pomocą kamery i klasy MediaRecorder
.
Uwaga: podczas nagrywania filmu nie puść kamery. W przeciwnym razie podgląd zostanie zatrzymany.
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 } } } } );
Uwaga: w tym przykładzie prepareVideoRecorder()
odnosi się do przykładowego kodu widocznego w sekcji Konfigurowanie MediaRecorder. Ta metoda umożliwia blokowanie
kamery oraz konfigurowania i przygotowywania instancji MediaRecorder
.
Zwalniam aparat
Kamery to zasób, z którego korzystają aplikacje zainstalowane na urządzeniu. Twoja aplikacja może
użycia kamery po uzyskaniu wystąpienia Camera
i musisz
szczególnie uważaj na zwolnienie obiektu aparatu, gdy aplikacja przestanie go używać.
po wstrzymaniu aplikacji (Activity.onPause()
). Jeśli
aplikacja nie zwalnia poprawnie kamery przy wszystkich kolejnych próbach jej uzyskania,
również tych, które zostały utworzone przez Ciebie, nie będą działać i mogą spowodować
wyłączyć.
Aby uruchomić wystąpienie obiektu Camera
, użyj metody Camera.release()
, jak pokazano w przykładowym kodzie poniżej.
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; } } }
Uwaga: jeśli aplikacja nie uruchomi poprawnie kodu kamery, wszystkie kolejne próby uzyskania dostępu do kamery, również te wykonywane przez Twoją aplikację, może dojść do wyłączenia aplikacji lub innych aplikacji.
Zapisuję pliki multimedialne
Pliki multimedialne utworzone przez użytkowników (np. zdjęcia i filmy) powinny być zapisywane na zewnętrznym urządzeniu katalog pamięci masowej (karta SD), aby oszczędzać miejsce w systemie i umożliwić użytkownikom dostęp do tych plików. bez urządzeń mobilnych. Jest wiele możliwych lokalizacji katalogów, w których można zapisać pliki multimedialne na urządzeniu, Pamiętaj jednak, że jako programista musisz wziąć pod uwagę tylko 2 standardowe lokalizacje:
Environment.getExternalStoragePublicDirectory
(Environment.DIRECTORY_PICTURES
) – ta metoda zwraca standardową, udostępnioną i zalecaną metodę. miejsca zapisywania zdjęć i filmów. Ten katalog jest udostępniony (publiczny), więc inne aplikacje mogą łatwo wykrywać, czytać, zmieniać i usuwać pliki zapisane w tej lokalizacji. Jeśli Twoja aplikacja to ale to użytkownik odinstaluje aplikację, pliki multimedialne zapisane w tej lokalizacji nie zostaną usunięte. Aby unikać ingerencji w istniejące zdjęcia i filmy użytkowników, należy utworzyć podkatalog dla pliki multimedialne aplikacji w tym katalogu, jak widać w poniższym przykładzie kodu. Ta metoda jest dostępne w Androidzie 2.2 (poziom interfejsu API 8). Informacje o równoważnych wywołaniach we wcześniejszych wersjach interfejsu API znajdziesz w sekcji Zapisywanie udostępnionych plików.Context.getExternalFilesDir
(Environment.DIRECTORY_PICTURES
) – ta metoda zwraca standardową lokalizację zapisu. zdjęcia i filmy powiązane z Twoją aplikacją. Jeśli aplikacja zostanie odinstalowana, wszystkie pliki zapisane w tej lokalizacji zostaną usunięte. Zabezpieczenia nie są wymuszane dla plików w tej lokalizacji i innych aplikacji mogą je odczytywać, zmieniać oraz usuwać.
Ten przykładowy kod pokazuje, jak utworzyć lokalizację File
lub Uri
dla pliku multimedialnego, której można użyć przy wywoływaniu aparatu urządzenia za pomocą
Intent
lub w ramach budowania kamery
Aplikacja.
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; }
Uwaga: usługa Environment.getExternalStoragePublicDirectory()
jest dostępna w Androidzie 2.2 (poziom API 8) oraz
wyżej. Jeśli kierujesz reklamy na urządzenia z wcześniejszymi wersjami Androida, użyj zasady Environment.getExternalStorageDirectory()
. Więcej informacji znajdziesz w artykule Zapisywanie udostępnionych plików.
Aby identyfikator URI obsługiwał profile służbowe, najpierw
skonwertują identyfikator URI pliku na identyfikator URI treści. Następnie dodaj identyfikator URI treści do
EXTRA_OUTPUT
Intent
.
Więcej informacji o zapisywaniu plików na urządzeniu z Androidem znajdziesz w artykule Przechowywanie danych.
Funkcje aparatu
Android obsługuje szeroką gamę funkcji aparatu, którymi możesz sterować za pomocą aplikacji.
takich jak format obrazu, tryb lampy błyskowej, ustawienia ostrości i wiele innych. W tej sekcji znajdziesz typowe
z aparatem i krótkim omówieniem tego, jak z nich korzystać. Można korzystać z większości funkcji aparatu i ustawić je
za pomocą obiektu do obsługi zdarzeń Camera.Parameters
. Dostępnych jest jednak kilka
ważnych funkcji, które wymagają czegoś więcej niż prostych ustawień w usłudze Camera.Parameters
. Funkcje te są opisane w tych sekcjach:
Ogólne informacje o korzystaniu z funkcji kontrolowanych za pomocą Camera.Parameters
znajdziesz w artykule Korzystanie z aparatu
funkcje. Więcej informacji o korzystaniu z funkcji kontrolowanych za pomocą
kamery parametrów kamery, skorzystaj z linków na liście funkcji poniżej, aby przejść do dokumentacji API
dokumentacji.
Tabela 1. Wspólne funkcje aparatu posortowane według poziomu interfejsu API Androida, na którym zostały wprowadzone.
Funkcja | Poziom API | Opis |
---|---|---|
Wykrywanie twarzy | 14 | Rozpoznawaj ludzkie twarze na zdjęciu i używaj ich do ustawiania ostrości, pomiaru oraz bieli saldo |
Obszary pomiaru | 14 | Określ co najmniej jeden obszar zdjęcia do obliczania balansu bieli |
Obszary specjalizacji | 14 | Ustaw co najmniej jeden obszar obrazu, który będzie używany do ostrości |
White Balance Lock |
14 | Zatrzymywanie i uruchamianie automatycznej korekty balansu bieli |
Exposure Lock |
14 | Zatrzymywanie i uruchamianie automatycznych korekt ekspozycji |
Video Snapshot |
14 | Robienie zdjęcia podczas nagrywania filmu (zrzut klatki) |
Film w trybie poklatkowym | 11 | Nagrywaj klatki z ustawionym opóźnieniem, aby nagrywać filmy w trybie poklatkowym |
Multiple Cameras |
9 | obsługa więcej niż 1 aparatu w urządzeniu, w tym przedniego i tylnego aparatu; kamery |
Focus Distance |
9 | Informuje o odległości między aparatem a obiektami, które są na pierwszym planie |
Zoom |
8 | Ustaw powiększenie obrazu |
Exposure
Compensation |
8 | Zwiększ lub zmniejsz poziom ekspozycji na światło |
GPS Data |
5 | Dołączaj lub pomijaj dane o lokalizacji geograficznej na zdjęciu |
White Balance |
5 | Ustaw tryb balansu bieli, który ma wpływ na wartości kolorów na robionym zdjęciu. |
Focus Mode |
5 | Ustawianie ostrości aparatu na obiekcie – na przykład automatyczne, stałe, makro lub nieskończoność |
Scene Mode |
5 | Zastosowanie trybu gotowych ustawień w określonych sytuacjach, na przykład w nocy, na plaży czy w śniegu. lub scenami przy świecach |
JPEG Quality |
5 | Ustaw poziom kompresji obrazu JPEG, który zwiększa lub zmniejsza wyjściowy plik graficzny jakość i rozmiar |
Flash Mode |
5 | Włączanie i wyłączanie lampy błyskowej oraz używanie ustawień automatycznych |
Color Effects |
5 | Zastosuj efekt kolorystyczny do zdjęcia, taki jak czarno-biały, w odcieniu sepii lub negatyw. |
Anti-Banding |
5 | Ogranicza efekt pasów w gradientach kolorów spowodowanych kompresją JPEG. |
Picture Format |
1 | Określ format pliku zdjęcia |
Picture Size |
1 | Określ wymiary zapisanego obrazu w pikselach. |
Uwaga: te funkcje nie są obsługiwane na wszystkich urządzeniach z powodu różnice dotyczące sprzętu i implementacji oprogramowania. Informacje o sprawdzaniu dostępności funkcji urządzenia, na którym działa aplikacja, patrz sekcja Sprawdzanie, czy dostępności funkcji.
Sprawdzam dostępność funkcji
Zanim zaczniesz korzystać z funkcji aparatu na urządzeniach z Androidem, warto wiedzieć, Nie wszystkie funkcje aparatu są obsługiwane na wszystkich urządzeniach. Ponadto urządzenia obsługujące określony mogą obsługiwać różne poziomy lub opcje. Dlatego też część procesu decyzyjnego przy opracowywaniu aplikacji do obsługi kamery jest wybór funkcji kamery, które chcesz i na jakim poziomie. Po podjęciu decyzji warto umieścić kod w swojej witrynie aplikacja aparatu, która sprawdza, czy sprzęt urządzenia obsługuje te funkcje, ale kończy się niepowodzeniem. jeśli jakaś funkcja nie jest dostępna.
Aby sprawdzić dostępność funkcji kamery, pobierz wystąpienie jej parametrów
i sprawdzanie odpowiednich metod. Poniższy przykładowy kod pokazuje, jak uzyskać
Camera.Parameters
obiekt i sprawdź, czy aparat obsługuje autofokus
cecha:
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 }
W przypadku większości funkcji aparatu możesz skorzystać z opisanej powyżej metody.
Obiekt Camera.Parameters
udostępnia metodę getSupported...()
, is...Supported()
lub getMax...()
do określenia, czy (i w jakim stopniu) cecha jest
obsługiwane.
Jeśli Twoja aplikacja do prawidłowego działania wymaga pewnych funkcji aparatu, ich wymagane jest dodanie ich do pliku manifestu aplikacji. Gdy zadeklarujesz użycie funkcji aparatu takich jak lampa błyskowa czy autofokus, Google Play ogranicza w aplikacji możliwość jest instalowana na urządzeniach, które nie obsługują tych funkcji. Listę funkcji aparatu, które można zadeklarować w manifeście aplikacji, zobacz plik manifestu Funkcje Plik referencyjny.
Korzystanie z funkcji aparatu
Większość funkcji kamery jest aktywowana i sterowana za pomocą obiektu Camera.Parameters
. Uzyskujesz ten obiekt przez pobranie instancji
obiekt Camera
, wywołując metodę getParameters()
i zmieniając zwracany parametr.
obiektu, a następnie ponownie umieścić go w obiekcie kamery, jak widać w przykładzie poniżej.
kod:
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);
Ta metoda działa w przypadku prawie wszystkich funkcji kamery, a większość parametrów można zmienić w dowolnym momencie
czasu po uzyskaniu instancji obiektu Camera
. Zmiany w
są zwykle widoczne dla użytkownika bezpośrednio na podglądzie w aplikacji.
Od strony oprogramowania zmiany parametrów mogą być widoczne dopiero po kilku klatkach, ponieważ
aparat przetwarza nowe instrukcje, a następnie wysyła zaktualizowane dane obrazu.
Ważne: niektórych funkcji aparatu nie można zmieniać. W zmiana rozmiaru lub orientacji podglądu aparatu wymaga wcześniejszego wyłączenia wyświetlić podgląd, zmienić jego rozmiar i ponownie uruchomić podgląd. Od Androida 4.0 (interfejs API) Poziom 14) można zmienić orientację podglądu bez jego ponownego uruchamiania.
Wdrożenie innych funkcji aparatu wymaga dodatkowego kodu, takich jak:
- Pomiar i obszary ostrości
- Wykrywanie twarzy
- Film poklatkowy
Poniżej znajdziesz krótki opis implementacji tych funkcji.
Pomiar i obszary ostrości
W niektórych sytuacjach związanych z fotografią automatyczne ustawianie ostrości i pomiar światła mogą nie powodować pożądanym efektom. Począwszy od Androida 4.0 (poziom interfejsu API 14) aplikacja aparatu może udostępniać dodatkowe opcje, które pozwalają aplikacji lub użytkownikom określić obszary na obrazie, które mają być używane ustawień ostrości i poziomu oświetlenia oraz przekazuj te wartości do sprzętu aparatu, aby wykorzystać je obrazów lub filmów.
Obszary do pomiaru i ustawiania ostrości działają bardzo podobnie do innych funkcji aparatu, ponieważ możesz kontrolować
je za pomocą metod w obiekcie Camera.Parameters
. Następujący kod:
pokazuje ustawienie dwóch obszarów pomiaru światła na potrzeby
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);
Obiekt Camera.Area
zawiera 2 parametry danych: obiekt Rect
do określenia obszaru w polu widzenia kamery oraz wagę.
która informuje kamerę, jak ważny jest ten obszar w pomiarze światła.
lub obliczeń skupienia.
Pole Rect
w obiekcie Camera.Area
opisuje prostokątny kształt zmapowany na siatce 2000 x 2000 jednostek. Współrzędne -1000, -1000
oznacza lewy górny róg zdjęcia z aparatu, a współrzędne 1000 i 1000 oznaczają
w prawym dolnym rogu zdjęcia z aparatu, tak jak na ilustracji poniżej.
Rysunek 1. Czerwone linie przedstawiają układ współrzędnych służący do określania
Camera.Area
w podglądzie z aparatu. Niebieskie pole pokazuje lokalizację
kształtu obszaru kamery o wartościach Rect
333 333 667 667.
Granice tego układu współrzędnych zawsze odpowiadają zewnętrznej krawędzi obrazu widocznego w
podglądu z aparatu i nie zmniejszaj ani nie powiększaj wraz z poziomem powiększenia. Podobnie jest z obracaniem obrazu.
zobacz podgląd w usłudze Camera.setDisplayOrientation()
nie powoduje zmiany mapowania układu współrzędnych.
Wykrywanie twarzy
W przypadku zdjęć przedstawiających osoby twarze są zwykle najważniejszym elementem. służy do określania ostrości i balansu bieli podczas robienia zdjęcia. Android 4.0 (poziom API 14) udostępnia interfejsy API do rozpoznawania twarzy i obliczania ustawień zdjęcia za pomocą technologii rozpoznawania twarzy.
Uwaga: gdy funkcja wykrywania twarzy jest włączona,
setWhiteBalance(String)
,
setFocusAreas(List<Camera.Area>)
i
setMeteringAreas(List<Camera.Area>)
nie ma żadnego efektu.
Aby zacząć korzystać z funkcji wykrywania twarzy w aplikacji aparatu, musisz wykonać kilka ogólnych czynności:
- Sprawdź, czy urządzenie obsługuje wykrywanie twarzy
- Utwórz detektor wykrywania twarzy
- Dodaj detektor wykrywania twarzy do obiektu kamery
- Uruchamiaj wykrywanie twarzy po wyświetleniu podglądu (i po każdym ponownym uruchomieniu podglądu)
Funkcja wykrywania twarzy nie jest obsługiwana na wszystkich urządzeniach. Możesz sprawdzić, czy ta funkcja
obsługiwane przez wywołanie getMaxNumDetectedFaces()
. An
tego przykładu można sprawdzić w metodzie startFaceDetection()
poniżej.
Aby otrzymywać powiadomienia i reagować na wykrycie twarzy, aplikacja aparatu musi być ustawiona
detektor zdarzeń związanych z wykrywaniem twarzy. Aby to zrobić, musisz utworzyć klasę detektora, która
implementuje interfejs Camera.FaceDetectionListener
zgodnie z tabelą
przykładowy kod poniżej.
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() ); } } }
Po utworzeniu tych zajęć możesz je ustawić w
Camera
– tak jak w przykładowym kodzie poniżej:
Kotlin
camera?.setFaceDetectionListener(MyFaceDetectionListener())
Java
camera.setFaceDetectionListener(new MyFaceDetectionListener());
Aplikacja musi uruchamiać funkcję wykrywania twarzy przy każdym uruchomieniu (lub ponownym uruchomieniu) funkcji podgląd z aparatu. Utwórz metodę uruchamiania wykrywania twarzy, aby móc do niej dzwonić w razie potrzeby, tak jak pokazano na ilustracji w przykładowym kodzie poniżej.
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(); } }
Wykrywanie twarzy musisz włączać za każdym razem, gdy uruchomisz (lub ponownie uruchomisz) podgląd aparatu. Jeśli
używasz klasy podglądu widocznej w artykule Tworzenie podglądu, dodaj
startFaceDetection()
do funkcji
surfaceCreated()
i surfaceChanged()
w zajęciach w wersji testowej,
jak widać w przykładowym kodzie poniżej.
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()); } }
Uwaga: pamiętaj, by wywołać tę metodę po wywołaniu
startPreview()
. Nie próbuj włączać wykrywania twarzy
w metodzie onCreate()
podczas głównej aktywności aparatu w aplikacji,
ponieważ podgląd nie jest dostępny do tego momentu wykonywania aplikacji.
Film poklatkowy
Funkcja filmów w trybie poklatkowym umożliwia tworzenie klipów wideo łączących zdjęcia wykonane kilka sekund lub
minut odstępu. Ta funkcja wykorzystuje MediaRecorder
do rejestrowania obrazów przez jakiś czas
sekwencja poklatkowa.
Aby nagrywać filmy w trybie poklatkowym za pomocą MediaRecorder
, musisz skonfigurować
obiektu nagrywarki tak jak przy normalnym filmie, ustaw liczbę przechwyconych klatek na sekundę na
przy użyciu jednego z ustawień jakości w trybie poklatkowym, jak widać w poniższym przykładzie kodu.
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
Te ustawienia należy wprowadzić w ramach większej procedury konfiguracji usługi MediaRecorder
. Pełny kod konfiguracji znajdziesz w artykule Konfigurowanie funkcji MediaRecorder. Po zakończeniu konfiguracji
zaczniesz nagrywać film tak, jakby był to zwykły klip wideo. Więcej informacji na temat konfiguracji
Informacje o konfigurowaniu i uruchamianiu usługi MediaRecorder
zawiera artykuł Nagrywanie filmów.
Camera2Video, oraz HdrViewfinder W przykładach szczegółowo opisano wykorzystanie interfejsów API opisanych na tej stronie.
Pola dotyczące aparatu, które wymagają uprawnień
Aplikacje na Androidzie 10 (poziom interfejsu API 29) lub nowszym muszą mieć
CAMERA
, aby:
uzyskać dostęp do wartości następujących pól,
getCameraCharacteristics()
metoda zwraca:
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
Dodatkowy przykładowy kod
Aby pobrać przykładowe aplikacje, zobacz Przykład z Aparatu2Podstawowy oraz Oficjalna przykładowa aplikacja CameraX.