Kamera API'si

Android çerçevesi, cihazlarda bulunan çeşitli kameralar ve kamera özelliklerini destekler. Bu sayede uygulamalarınızda fotoğraf ve video çekebilirsiniz. Bu belgede, resim ve video çekmeye yönelik hızlı ve basit bir yaklaşım ele alınmakta, ayrıca kullanıcılarınız için özel kamera deneyimleri oluşturmaya yönelik gelişmiş bir yaklaşım özetlenmektedir.

Not: Bu sayfada, desteği sonlandırılan Camera sınıfı açıklanmaktadır. CameraX Jetpack kitaplığını veya belirli kullanım alanları için camera2 sınıfını kullanmanızı öneririz. Hem CameraX hem de Camera2, Android 5.0 (API düzeyi 21) ve sonraki sürümlerde çalışır.

Aşağıdaki ilgili kaynaklara göz atın:

Dikkat edilmesi gereken noktalar

Uygulamanızın Android cihazlardaki kameraları kullanmasını etkinleştirmeden önce, uygulamanızın bu donanım özelliğini nasıl kullanmayı planladığıyla ilgili birkaç soruyu göz önünde bulundurmanız gerekir.

  • Kamera Gereksinimi: Uygulamanız için kamera kullanımı o kadar önemli mi ki uygulamanızın kamerası olmayan bir cihaza yüklenmesini istemiyorsunuz? Bu durumda manifest dosyanızda kamera gereksinimini beyan etmeniz gerekir.
  • Hızlı Resim veya Özelleştirilmiş Kamera: Uygulamanız kamerayı nasıl kullanacak? Yalnızca hızlı bir fotoğraf veya video klip çekmek mi istiyorsunuz yoksa uygulamanız kameraları kullanmak için yeni bir yol mu sunacak? Hızlı bir fotoğraf veya klip çekmek için mevcut kamera uygulamalarını kullanabilirsiniz. Özel bir kamera özelliği geliştirmek için Kamera Uygulaması Oluşturma bölümüne göz atın.
  • Ön Plan Hizmetleri Şartı: Uygulamanız kamerayla ne zaman etkileşime giriyor? Android 9 (API düzeyi 28) ve sonraki sürümlerde, arka planda çalışan uygulamalar kameraya erişemez. Bu nedenle, kamerayı uygulamanız ön plandayken veya ön plan hizmetinin bir parçası olarak kullanmanız gerekir.
  • Depolama: Uygulamanızın oluşturduğu resimler veya videolar yalnızca uygulamanız tarafından mı görünür olmalı yoksa Galeri gibi diğer uygulamaların ya da diğer medya ve sosyal uygulamaların kullanabilmesi için paylaşılmalı mı? Uygulamanız kaldırılsa bile resim ve videoların kullanılabilir olmasını istiyor musunuz? Bu seçenekleri nasıl uygulayacağınızı öğrenmek için Medya Dosyalarını Kaydetme bölümüne göz atın.

Temel bilgiler

Android çerçevesi, android.hardware.camera2 API'si veya kamera Intent aracılığıyla resim ve video çekmeyi destekler. İlgili sınıflar şunlardır:

android.hardware.camera2
Bu paket, cihaz kameralarını kontrol etmek için kullanılan birincil API'dir. Kamera uygulaması oluştururken fotoğraf veya video çekmek için kullanılabilir.
Camera
Bu sınıf, cihaz kameralarını kontrol etmek için kullanılan eski ve desteği sonlandırılmış API'dir.
SurfaceView
Bu sınıf, kullanıcıya canlı kamera önizlemesi sunmak için kullanılır.
MediaRecorder
Bu sınıf, kameradan video kaydetmek için kullanılır.
Intent
MediaStore.ACTION_IMAGE_CAPTURE veya MediaStore.ACTION_VIDEO_CAPTURE niyet işlemi türü, Camera nesnesi doğrudan kullanılmadan resim veya video çekmek için kullanılabilir.

Manifest beyanları

Uygulamanızda Camera API ile geliştirme yapmaya başlamadan önce manifest dosyanızda kamera donanımının ve diğer ilgili özelliklerin kullanımına izin veren uygun bildirimlerin bulunduğundan emin olmanız gerekir.

  • Kamera İzni: Uygulamanız, cihaz kamerasını kullanmak için izin istemelidir.
    <uses-permission android:name="android.permission.CAMERA" />

    Not: Kamerayı mevcut bir kamera uygulamasını çağırarak kullanıyorsanız uygulamanızın bu izni istemesi gerekmez.

  • Kamera Özellikleri: Uygulamanız, kamera özelliklerinin kullanımını da bildirmelidir. Örneğin:
    <uses-feature android:name="android.hardware.camera" />

    Kamera özelliklerinin listesi için manifest Özellikler Referansı'na bakın.

    Manifestinize kamera özellikleri eklediğinizde Google Play, uygulamanızın kamera içermeyen veya belirttiğiniz kamera özelliklerini desteklemeyen cihazlara yüklenmesini engeller. Google Play ile özelliğe dayalı filtrelemeyi kullanma hakkında daha fazla bilgi için Google Play ve özelliğe dayalı filtreleme başlıklı makaleyi inceleyin.

    Uygulamanızın düzgün çalışması için kamera veya kamera özelliği kullanılabiliyorsa ancak gerekli değilse bunu android:required özelliğini ekleyip false olarak ayarlayarak manifest dosyasında belirtmeniz gerekir:

    <uses-feature android:name="android.hardware.camera" android:required="false" />
  • Depolama İzni: Uygulamanız Android 10'u (API düzeyi 29) veya daha eski bir sürümü hedefliyorsa ve manifest dosyasında aşağıdakileri belirtiyorsa resimleri ya da videoları cihazın harici depolama alanına (SD kart) kaydedebilir.
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
  • Ses Kaydı İzni: Video çekimiyle ses kaydı yapmak için uygulamanızın ses kaydı izni istemesi gerekir.
    <uses-permission android:name="android.permission.RECORD_AUDIO" />
  • Konum izni: Uygulamanız resimleri GPS konum bilgileriyle etiketliyorsa ACCESS_FINE_LOCATION izni istemeniz gerekir. Uygulamanızın Android 5.0'ı (API düzeyi 21) veya sonraki sürümleri hedeflediğini beyan ediyorsanız uygulamanızın cihazın GPS'ini kullandığını da beyan etmeniz gerektiğini unutmayın:

    <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" />

    Kullanıcı konumunu alma hakkında daha fazla bilgi için Konum Stratejileri başlıklı makaleyi inceleyin.

Mevcut kamera uygulamalarını kullanma

Uygulamanızda fotoğraf veya video çekmeyi etkinleştirmenin hızlı bir yolu, çok fazla ek kod yazmadan mevcut bir Android kamera uygulamasını çağırmak için Intent kullanmaktır. Ayrıntılar, Kolayca Fotoğraf Çekme ve Kolayca Video Kaydetme eğitim derslerinde açıklanmaktadır.

Kamera uygulaması oluşturma

Bazı geliştiriciler, uygulamalarının görünümüne göre özelleştirilmiş veya özel özellikler sunan bir kamera kullanıcı arayüzü isteyebilir. Kendi fotoğraf çekme kodunuzu yazmak, kullanıcılarınıza daha ilgi çekici bir deneyim sunabilir.

Not: Aşağıdaki kılavuz, eski ve kullanımdan kaldırılmış Camera API'si içindir. Yeni veya gelişmiş kamera uygulamaları için daha yeni olan android.hardware.camera2 API'nin kullanılması önerilir.

Uygulamanız için özel bir kamera arayüzü oluşturmaya ilişkin genel adımlar şunlardır:

  • Kamerayı Algılama ve Erişme: Kameraların varlığını kontrol etmek ve erişim isteğinde bulunmak için kod oluşturun.
  • Önizleme sınıfı oluşturma: SurfaceView sınıfını genişleten ve SurfaceHolder arayüzünü uygulayan bir kamera önizleme sınıfı oluşturun. Bu sınıf, kameradan alınan canlı görüntüleri önizler.
  • Önizleme düzeni oluşturma: Kamera önizleme sınıfına sahip olduğunuzda, önizlemeyi ve istediğiniz kullanıcı arayüzü kontrollerini içeren bir görünüm düzeni oluşturun.
  • Yakalamak İçin Dinleyicileri Ayarlama: Kullanıcı işlemlerine (ör. düğmeye basma) yanıt olarak resim veya video yakalamayı başlatmak için arayüz kontrolleriniz için dinleyicileri bağlayın.
  • Dosyaları Yakalama ve Kaydetme: Resim veya video yakalama ve çıkışı kaydetme kodunu ayarlayın.
  • Kamerayı serbest bırakma: Uygulamanız, kamerayı kullandıktan sonra diğer uygulamaların kullanabilmesi için kamerayı düzgün bir şekilde serbest bırakmalıdır.

Kamera donanımı, dikkatli bir şekilde yönetilmesi gereken paylaşılan bir kaynaktır. Bu sayede uygulamanız, kamerayı kullanmak isteyen diğer uygulamalarla çakışmaz. Aşağıdaki bölümlerde kamera donanımının nasıl algılanacağı, kameraya erişimin nasıl isteneceği, resim veya video çekmenin nasıl yapılacağı ve uygulamanız kamerayı kullanmayı bitirdiğinde kameranın nasıl serbest bırakılacağı açıklanmaktadır.

Dikkat: Uygulamanız nesneyi kullanmayı bitirdiğinde Camera Camera.release() çağırarak nesneyi serbest bırakmayı unutmayın. Uygulamanız kamerayı düzgün şekilde serbest bırakmazsa kendi uygulamanızın erişim denemeleri de dahil olmak üzere kameraya erişmeye yönelik tüm sonraki denemeler başarısız olur ve uygulamanızın veya diğer uygulamaların kapatılmasına neden olabilir.

Kamera donanımı algılanıyor

Uygulamanız, manifest beyanı kullanılarak kamerayı özellikle gerektirmiyorsa çalışma zamanında kameranın kullanılabilir olup olmadığını kontrol etmelisiniz. Bu kontrolü gerçekleştirmek için aşağıdaki örnek kodda gösterildiği gibi PackageManager.hasSystemFeature() yöntemini kullanın:

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;
    }
}

Android cihazlarda birden fazla kamera olabilir. Örneğin, fotoğraf çekmek için arkaya bakan bir kamera ve görüntülü görüşme yapmak için öne bakan bir kamera. Android 2.3 (API düzeyi 9) ve sonraki sürümlerde, Camera.getNumberOfCameras() yöntemini kullanarak bir cihazda bulunan kamera sayısını kontrol edebilirsiniz.

Kameralara erişme

Uygulamanızın çalıştığı cihazda kamera olduğunu belirlediyseniz Camera örneği alarak kameraya erişim isteğinde bulunmanız gerekir (kameraya erişmek için amaç kullanmıyorsanız).

Birincil kameraya erişmek için Camera.open() yöntemini kullanın ve aşağıdaki kodda gösterildiği gibi tüm istisnaları yakaladığınızdan emin olun:

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
}

Dikkat: Camera.open() kullanırken her zaman istisna olup olmadığını kontrol edin. Kamera kullanılıyorsa veya mevcut değilse istisnaları kontrol etmemek, uygulamanızın sistem tarafından kapatılmasına neden olur.

Android 2.3 (API düzeyi 9) veya sonraki sürümleri çalıştıran cihazlarda Camera.open(int) simgesini kullanarak belirli kameralara erişebilirsiniz. Yukarıdaki örnek kod, birden fazla kamerası olan bir cihazda arkaya bakan ilk kameraya erişir.

Kamera özelliklerini kontrol etme

Bir kameraya erişim sağladıktan sonra Camera.getParameters() yöntemini kullanarak özellikleriyle ilgili daha fazla bilgi edinebilir ve desteklenen özellikler için döndürülen Camera.Parameters nesnesini kontrol edebilirsiniz. API düzeyi 9 veya daha yüksek bir sürümü kullanırken kameranın cihazın önünde mi yoksa arkasında mı olduğunu ve görüntünün yönünü belirlemek için Camera.getCameraInfo() kullanın.

Önizleme sınıfı oluşturma

Kullanıcıların etkili bir şekilde fotoğraf veya video çekebilmesi için cihaz kamerasının gördüklerini görmeleri gerekir. Kamera önizleme sınıfı, kameradan gelen canlı görüntü verilerini gösterebilen bir SurfaceView olduğundan kullanıcılar fotoğraf veya video çekmek için kadraj oluşturabilir.

Aşağıdaki örnek kod, View düzenine dahil edilebilecek temel bir kamera önizleme sınıfının nasıl oluşturulacağını gösterir. Bu sınıf, kamera önizleme girişini atamak için gereken görünümü oluşturma ve yok etme geri çağırma etkinliklerini yakalamak amacıyla SurfaceHolder.Callback öğesini uygular.

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());
        }
    }
}

Kamera önizlemeniz için belirli bir boyut ayarlamak istiyorsanız bunu yukarıdaki yorumlarda belirtildiği gibi surfaceChanged() yönteminde ayarlayın. Önizleme boyutu ayarlanırken getSupportedPreviewSizes() değerleri kullanılmalıdır. setPreviewSize() yönteminde rastgele değerler ayarlamayın.

Not: Android 7.0 (API düzeyi 24) ve sonraki sürümlerde Çoklu Pencere özelliğinin kullanıma sunulmasıyla birlikte, setDisplayOrientation() çağrısı yapıldıktan sonra bile önizlemenin en-boy oranının etkinliğinizle aynı olduğunu varsayamazsınız. Pencere boyutuna ve en boy oranına bağlı olarak, geniş bir kamera önizlemesini dikey yönlü bir düzene sığdırmanız veya tam tersi bir şekilde, mektup kutusu düzeni kullanarak dikey yönlü bir önizlemeyi yatay yönlü bir düzene sığdırmanız gerekebilir.

Düzenlere önizleme yerleştirme

Önceki bölümde gösterilen örnekteki gibi bir kamera önizleme sınıfı, fotoğraf veya video çekmeye yönelik diğer kullanıcı arayüzü kontrolleriyle birlikte bir etkinliğin düzenine yerleştirilmelidir. Bu bölümde, önizleme için temel bir düzen ve etkinlik oluşturma adımları açıklanmaktadır.

Aşağıdaki düzen kodu, kamera önizlemesini göstermek için kullanılabilecek çok temel bir görünüm sağlar. Bu örnekte, FrameLayout öğesi kamera önizleme sınıfının kapsayıcısı olarak tasarlanmıştır. Bu düzen türü, canlı kamera önizleme resimlerinin üzerine ek resim bilgileri veya kontrolleri yerleştirmek için kullanılır.

<?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>

Çoğu cihazda kamera önizlemesinin varsayılan yönü yataydır. Bu örnek düzen, yatay bir düzeni belirtir ve aşağıdaki kod, uygulamanın yönünü yatay olarak düzeltir. Kamera önizlemesini daha kolay oluşturmak için manifest dosyanıza aşağıdakileri ekleyerek uygulamanızın önizleme etkinliği yönünü yatay olarak değiştirmeniz gerekir.

<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>

Not: Kamera önizlemesinin yatay modda olması gerekmez. Android 2.2'den (API düzeyi 8) itibaren, önizleme resminin döndürülmesini ayarlamak için setDisplayOrientation() yöntemini kullanabilirsiniz. Kullanıcı telefonu yeniden yönlendirdikçe önizleme yönünü değiştirmek için önizleme sınıfınızın surfaceChanged() yönteminde önce Camera.stopPreview() ile önizlemeyi durdurun, yönü değiştirin ve ardından Camera.startPreview() ile önizlemeyi tekrar başlatın.

Kamera görünümünüzün etkinliğinde, önizleme sınıfınızı yukarıdaki örnekte gösterilen FrameLayout öğesine ekleyin. Kamera etkinliğiniz, duraklatıldığında veya kapatıldığında kamerayı serbest bırakmalıdır. Aşağıdaki örnekte, Önizleme sınıfı oluşturma bölümünde gösterilen önizleme sınıfını eklemek için kamera etkinliğinin nasıl değiştirileceği açıklanmaktadır.

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);
    }
}

Not: Yukarıdaki örnekte getCameraInstance() yöntemi, Kameralara erişme bölümünde gösterilen örnek yöntemi ifade eder.

Resim çekme

Bir önizleme sınıfı ve bunu görüntülemek için bir görünüm düzeni oluşturduktan sonra uygulamanızla görüntü yakalamaya başlayabilirsiniz. Uygulama kodunuzda, kullanıcı arayüzü kontrolleriniz için dinleyiciler ayarlamanız gerekir. Böylece, fotoğraf çekerek kullanıcı işlemine yanıt verebilirsiniz.

Bir resmi almak için Camera.takePicture() yöntemini kullanın. Bu yöntem, kameradan veri alan üç parametre kullanır. Verileri JPEG biçiminde almak için resim verilerini alacak ve bir dosyaya yazacak bir Camera.PictureCallback arayüzü uygulamanız gerekir. Aşağıdaki kod, kameradan alınan bir görüntüyü kaydetmek için Camera.PictureCallback arayüzünün temel bir uygulamasını göstermektedir.

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());
        }
    }
};

Camera.takePicture() yöntemini çağırarak görüntü yakalamayı tetikleyin. Aşağıdaki örnek kodda, bu yöntemin bir düğmeden View.OnClickListener nasıl çağrılacağı gösterilmektedir.

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);
        }
    }
);

Not: Aşağıdaki örnekteki mPicture üyesi, yukarıdaki örnek kodu ifade eder.

Dikkat: Uygulamanız nesneyi kullanmayı bitirdiğinde Camera Camera.release() çağırarak nesneyi serbest bırakmayı unutmayın. Kamerayı serbest bırakma hakkında bilgi için Kamerayı serbest bırakma başlıklı makaleyi inceleyin.

Video çekme

Android çerçevesini kullanarak video yakalamak için Camera nesnesinin dikkatli bir şekilde yönetilmesi ve MediaRecorder sınıfıyla koordinasyon gerekir. Camera ile video kaydederken MediaRecorder'ün kamera donanımına erişmesine izin vermek için Camera.lock() ve Camera.unlock() görüşmelerinin yanı sıra Camera.open() ve Camera.release() görüşmelerini de yönetmeniz gerekir.

Not: Android 4.0'dan (API düzeyi 14) itibaren Camera.lock() ve Camera.unlock() aramaları sizin için otomatik olarak yönetilir.

Cihaz kamerasıyla fotoğraf çekmekten farklı olarak, video çekmek için çok özel bir çağrı sırası gerekir. Uygulamanızla videoyu başarıyla hazırlayıp kaydetmek için aşağıda ayrıntılı olarak açıklanan belirli bir yürütme sırasını izlemeniz gerekir.

  1. Kamerayı açma: Kamera nesnesinin bir örneğini almak için Camera.open() kullanın.
  2. Connect Preview: Camera.setPreviewDisplay() kullanarak kameraya SurfaceView bağlayarak canlı kamera görüntüsü önizlemesi hazırlayın.
  3. Önizlemeyi Başlat: Canlı kamera görüntülerini göstermeye başlamak için Camera.startPreview()'ı arayın.
  4. Video Kaydetmeye Başlama: Videonun başarılı bir şekilde kaydedilmesi için aşağıdaki adımların sırayla tamamlanması gerekir:
    1. Kameranın kilidini açma: MediaRecorder tarafından kullanılabilmesi için Camera.unlock()'ı arayarak kameranın kilidini açın.
    2. MediaRecorder'ı yapılandırın: Aşağıdaki MediaRecorder yöntemleri bu sırayla çağırın. Daha fazla bilgi için MediaRecorder referans belgelerine bakın.
      1. setCamera() - Video çekimi için kullanılacak kamerayı ayarlayın, uygulamanızın mevcut Camera örneğini kullanın.
      2. setAudioSource() - Ses kaynağını ayarlamak için MediaRecorder.AudioSource.CAMCORDER simgesini kullanın.
      3. setVideoSource() - Video kaynağını ayarlamak için MediaRecorder.VideoSource.CAMERA simgesini kullanın.
      4. Video çıkış biçimini ve kodlamasını ayarlayın. Android 2.2 (API düzeyi 8) ve sonraki sürümlerde MediaRecorder.setProfile yöntemini kullanın ve CamcorderProfile.get() ile bir profil örneği alın. Android'in 2.2'den önceki sürümlerinde video çıkış biçimini ve kodlama parametrelerini ayarlamanız gerekir:
        1. setOutputFormat() - Çıkış biçimini ayarlayın, varsayılan ayarı belirtin veya MediaRecorder.OutputFormat.MPEG_4.
        2. setAudioEncoder() - Ses kodlama türünü ayarlayın, varsayılan ayarı veya MediaRecorder.AudioEncoder.AMR_NB'ı belirtin.
        3. setVideoEncoder() - Video kodlama türünü ayarlayın, varsayılan ayarı belirtin veya MediaRecorder.VideoEncoder.MPEG_4_SP.
      5. setOutputFile() - Çıkış dosyasını ayarlayın, Medya Dosyalarını Kaydetme bölümündeki örnek yöntemde getOutputMediaFile(MEDIA_TYPE_VIDEO).toString() öğesini kullanın.
      6. setPreviewDisplay() - Uygulamanız için SurfaceView önizleme düzeni öğesini belirtin. Bağlantı Önizlemesi için belirttiğiniz nesneyi kullanın.

      Dikkat: Bu MediaRecorder yapılandırma yöntemlerini bu sırayla çağırmanız gerekir. Aksi takdirde uygulamanız hatalarla karşılaşır ve kayıt başarısız olur.

    3. MediaRecorder'ı hazırlayın: MediaRecorder with provided configuration settings by calling MediaRecorder.prepare().
    4. MediaRecorder'ı başlatma: MediaRecorder.start() işlevini çağırarak video kaydetmeye başlayın.
  5. Video Kaydını Durdurma: Video kaydını başarıyla tamamlamak için aşağıdaki yöntemleri sırayla çağırın:
    1. MediaRecorder'ı durdurma: MediaRecorder.stop() çağrısı yaparak video kaydını durdurun.
    2. MediaRecorder'ı sıfırlama: İsteğe bağlı olarak, MediaRecorder.reset() işlevini çağırarak yapılandırma ayarlarını kaydediciden kaldırın.
    3. Release MediaRecorder: MediaRecorder öğesini MediaRecorder.release() çağırarak serbest bırakın.
    4. Kamerayı kilitleme: Gelecekteki MediaRecorder oturumlarında Camera.lock() çağrılarak kullanılabilmesi için kamerayı kilitleyin. Android 4.0'dan (API düzeyi 14) itibaren, MediaRecorder.prepare() çağrısı başarısız olmadıkça bu çağrı gerekli değildir.
  6. Önizlemeyi Durdurma: Kamerayı kullanma etkinliğiniz bittiğinde Camera.stopPreview() simgesini kullanarak önizlemeyi durdurun.
  7. Release Camera: Kamerayı serbest bırakır. Böylece diğer uygulamalar Camera.release() işlevini çağırarak kamerayı kullanabilir.

Not: Önce kamera önizlemesi oluşturmadan MediaRecorder kullanmak ve bu işlemin ilk birkaç adımını atlamak mümkündür. Ancak kullanıcılar genellikle kayda başlamadan önce önizleme görmeyi tercih ettiğinden bu işlem burada ele alınmamıştır.

İpucu: Uygulamanız genellikle video kaydetmek için kullanılıyorsa önizlemeyi başlatmadan önce setRecordingHint(boolean) değerini true olarak ayarlayın. Bu ayar, kaydın başlatılması için gereken süreyi kısaltmaya yardımcı olabilir.

MediaRecorder'ı yapılandırma

Video kaydetmek için MediaRecorder sınıfını kullanırken yapılandırma adımlarını belirli bir sırayla uygulamanız, ardından yapılandırmayı kontrol edip uygulamak için MediaRecorder.prepare() yöntemini çağırmanız gerekir. Aşağıdaki örnek kodda, MediaRecorder sınıfının video kaydı için nasıl doğru şekilde yapılandırılacağı ve hazırlanacağı gösterilmektedir.

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;
}

Android 2.2'den (API düzeyi 8) önce, CamcorderProfile kullanmak yerine çıkış biçimi ve kodlama biçimleri parametrelerini doğrudan ayarlamanız gerekir. Bu yaklaşım aşağıdaki kodda gösterilmektedir:

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);

MediaRecorder için aşağıdaki video kaydı parametrelerine varsayılan ayarlar verilir. Ancak bu ayarları uygulamanıza göre düzenlemek isteyebilirsiniz:

MediaRecorder'ı başlatma ve durdurma

Video kaydını MediaRecorder sınıfını kullanarak başlatıp durdururken aşağıdaki listede belirtilen sırayı izlemeniz gerekir.

  1. Kameranın kilidini Camera.unlock() ile açma
  2. MediaRecorder öğesini yukarıdaki kod örneğinde gösterildiği gibi yapılandırın.
  3. MediaRecorder.start() ile kayıt yapmaya başlama
  4. Videoyu kaydetme
  5. MediaRecorder.stop() kullanarak kaydı durdurma
  6. MediaRecorder.release() ile medya kaydediciyi serbest bırakın.
  7. Camera.lock() kullanarak kamerayı kilitleme

Aşağıdaki örnek kod, kamerayı ve MediaRecorder sınıfını kullanarak video kaydını düzgün şekilde başlatmak ve durdurmak için bir düğmeyi nasıl bağlayacağınızı gösterir.

Not: Video kaydını tamamlarken kamerayı bırakmayın. Aksi takdirde önizlemeniz durdurulur.

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
                }
            }
        }
    }
);

Not: Yukarıdaki örnekte prepareVideoRecorder() yöntemi, MediaRecorder'ı yapılandırma bölümünde gösterilen örnek kodu ifade eder. Bu yöntem, kamerayı kilitleme, MediaRecorder örneğini yapılandırma ve hazırlama işlemlerini gerçekleştirir.

Kamerayı serbest bırakma

Kameralar, bir cihazdaki uygulamalar tarafından paylaşılan bir kaynaktır. Uygulamanız, Camera örneğini aldıktan sonra kamerayı kullanabilir. Uygulamanız kamerayı kullanmayı bıraktığında ve uygulama duraklatılır duraklatılmaz (Activity.onPause()) kamera nesnesini serbest bırakmaya özellikle dikkat etmeniz gerekir. Uygulamanız kamerayı düzgün şekilde serbest bırakmazsa kendi uygulamanızın da dahil olduğu, kameraya erişmeye yönelik tüm sonraki girişimler başarısız olur ve uygulamanızın veya diğer uygulamaların kapatılmasına neden olabilir.

Camera nesnesinin bir örneğini serbest bırakmak için aşağıdaki örnek kodda gösterildiği gibi Camera.release() yöntemini kullanın.

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;
        }
    }
}

Dikkat: Uygulamanız kamerayı düzgün şekilde serbest bırakmazsa kendi uygulamanızın erişim denemeleri de dahil olmak üzere kameraya erişmeye yönelik tüm sonraki denemeler başarısız olur ve uygulamanızın veya diğer uygulamaların kapatılmasına neden olabilir.

Medya dosyalarını kaydetme

Kullanıcılar tarafından oluşturulan resim ve video gibi medya dosyaları, sistem alanını korumak ve kullanıcıların bu dosyalara cihazları olmadan erişebilmesini sağlamak için cihazın harici depolama dizinine (SD kart) kaydedilmelidir. Cihazda medya dosyalarını kaydetmek için birçok olası dizin konumu vardır ancak geliştirici olarak dikkate almanız gereken yalnızca iki standart konum vardır:

  • Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES): Bu yöntem, resim ve videoları kaydetmek için standart, paylaşılan ve önerilen konumu döndürür. Bu dizin paylaşıldığı (herkese açık) için diğer uygulamalar bu konuma kaydedilen dosyaları kolayca bulabilir, okuyabilir, değiştirebilir ve silebilir. Uygulamanız kullanıcı tarafından kaldırılırsa bu konuma kaydedilen medya dosyaları kaldırılmaz. Kullanıcıların mevcut resim ve videolarına müdahale etmemek için uygulamanızın medya dosyaları için bu dizinde bir alt dizin oluşturmanız gerekir. Aşağıdaki kod örneğinde bu durum gösterilmektedir. Bu yöntem Android 2.2'de (API düzeyi 8) kullanılabilir. Daha önceki API sürümlerindeki eşdeğer çağrılar için Paylaşılan Dosyaları Kaydetme bölümüne bakın.
  • Context.getExternalFilesDir(Environment.DIRECTORY_PICTURES): Bu yöntem, uygulamanızla ilişkili resim ve videoların kaydedileceği standart bir konum döndürür. Uygulamanız kaldırılırsa bu konuma kaydedilen tüm dosyalar kaldırılır. Bu konumdaki dosyalar için güvenlik uygulanmaz ve diğer uygulamalar bu dosyaları okuyabilir, değiştirebilir ve silebilir.

Aşağıdaki örnek kod, bir cihazın kamerasını Intent ile çağırırken veya Kamera Uygulaması Oluşturma sürecinde kullanılabilecek bir medya dosyası için File veya Uri konumu oluşturmayı gösterir.

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;
}

Not: Environment.getExternalStoragePublicDirectory(), Android 2.2 (API düzeyi 8) veya sonraki sürümlerde kullanılabilir. Android'in eski sürümlerini çalıştıran cihazları hedefliyorsanız bunun yerine Environment.getExternalStorageDirectory() kullanın. Daha fazla bilgi için Paylaşılan Dosyaları Kaydetme başlıklı makaleyi inceleyin.

URI'nin iş profillerini desteklemesi için önce dosya URI'sini içerik URI'sine dönüştürün. Ardından, içerik URI'sini Intent öğesinin EXTRA_OUTPUT bölümüne ekleyin.

Android cihazda dosya kaydetme hakkında daha fazla bilgi için Veri Depolama başlıklı makaleyi inceleyin.

Kamera özellikleri

Android, kamera uygulamanızla kontrol edebileceğiniz çok çeşitli kamera özelliklerini (ör. resim biçimi, flaş modu, odak ayarları) destekler. Bu bölümde, yaygın kamera özellikleri listelenmekte ve bunların nasıl kullanılacağı kısaca açıklanmaktadır. Çoğu kamera özelliğine Camera.Parameters nesnesi kullanılarak erişilebilir ve bu özellikler ayarlanabilir. Ancak, Camera.Parameters'da basit ayarlardan daha fazlasını gerektiren birkaç önemli özellik vardır. Bu özellikler aşağıdaki bölümlerde ele alınmaktadır:

Camera.Parameters üzerinden kontrol edilen özellikleri kullanma hakkında genel bilgi için Kamera özelliklerini kullanma bölümünü inceleyin. Kamera parametreleri nesnesi aracılığıyla kontrol edilen özellikleri kullanma hakkında daha ayrıntılı bilgi için aşağıdaki özellik listesindeki bağlantıları kullanarak API referans belgelerine gidin.

Tablo 1. Yaygın kamera özellikleri, kullanıma sunuldukları Android API düzeyine göre sıralanır.

Özellik API düzeyi Açıklama
Yüz Algılama 14 Resimdeki insan yüzlerini tanımlama ve bunları odak, ölçüm ve beyaz dengesi için kullanma
Ölçüm Alanları 14 Beyaz dengesini hesaplamak için resim içinde bir veya daha fazla alan belirtin
Odaklanılan Alanlar 14 Odak için kullanılacak bir veya daha fazla alan belirleyin.
White Balance Lock 14 Otomatik beyaz dengesi ayarlamalarını durdurma veya başlatma
Exposure Lock 14 Otomatik pozlama ayarlamalarını durdurma veya başlatma
Video Snapshot 14 Video çekerken fotoğraf çekme (kare yakalama)
Zaman atlamalı video 11 Zaman atlamalı video kaydetmek için belirli aralıklarla kareler kaydedin
Multiple Cameras 9 Ön ve arka kameralar da dahil olmak üzere bir cihazda birden fazla kamera desteği
Focus Distance 9 Kamera ile odaklanmış gibi görünen nesneler arasındaki mesafeleri bildirir.
Zoom 8 Resim büyütmesini ayarlama
Exposure Compensation 8 Işık pozlama düzeyini artırma veya azaltma
GPS Data 5 Resimle birlikte coğrafi konum verilerini ekleme veya çıkarma
White Balance 5 Çekilen resimdeki renk değerlerini etkileyen beyaz dengesi modunu ayarlayın.
Focus Mode 5 Otomatik, sabit, makro veya sonsuz gibi seçeneklerle kameranın bir özneye nasıl odaklanacağını ayarlama
Scene Mode 5 Gece, plaj, kar veya mum ışığı gibi belirli fotoğrafçılık durumları için önceden ayarlanmış bir mod uygulayın.
JPEG Quality 5 JPEG resimler için sıkıştırma seviyesini ayarlayın. Bu seviye, resim çıkışı dosyasının kalitesini ve boyutunu artırır veya azaltır.
Flash Mode 5 Flaşın açık, kapalı veya otomatik ayarını kullanma
Color Effects 5 Çekilen resme siyah beyaz, sepya tonu veya negatif gibi bir renk efekti uygulayın.
Anti-Banding 5 JPEG sıkıştırması nedeniyle renk geçişlerinde bantlanma etkisini azaltır.
Picture Format 1 Resmin dosya biçimini belirtin.
Picture Size 1 Kayıtlı resmin piksel boyutlarını belirtin

Not: Bu özellikler, donanım farklılıkları ve yazılım uygulaması nedeniyle tüm cihazlarda desteklenmez. Uygulamanızın çalıştığı cihazda özelliklerin kullanılabilirliğini kontrol etme hakkında bilgi edinmek için Özelliklerin kullanılabilirliğini kontrol etme başlıklı makaleyi inceleyin.

Özelliklerin kullanılabilirlik durumunu kontrol etme

Android cihazlarda kamera özelliklerini kullanmaya başlarken bilinmesi gereken ilk şey, tüm kamera özelliklerinin tüm cihazlarda desteklenmediğidir. Ayrıca, belirli bir özelliği destekleyen cihazlar bu özelliği farklı düzeylerde veya farklı seçeneklerle destekleyebilir. Bu nedenle, kamera uygulaması geliştirirken karar verme sürecinizin bir parçası olarak hangi kamera özelliklerini hangi düzeyde desteklemek istediğinize karar vermeniz gerekir. Bu kararı verdikten sonra, kamera uygulamanıza cihaz donanımının bu özellikleri destekleyip desteklemediğini kontrol eden ve bir özellik kullanılamıyorsa sorunsuz bir şekilde başarısız olan kodu eklemeyi planlamalısınız.

Kameranın parametreler nesnesinin bir örneğini alıp ilgili yöntemleri kontrol ederek kamera özelliklerinin kullanılabilirliğini kontrol edebilirsiniz. Aşağıdaki kod örneğinde, Camera.Parameters nesnesinin nasıl alınacağı ve kameranın otomatik odaklama özelliğini destekleyip desteklemediğinin nasıl kontrol edileceği gösterilmektedir:

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
}

Çoğu kamera özelliği için yukarıda gösterilen tekniği kullanabilirsiniz. Camera.Parameters nesnesi, bir özelliğin desteklenip desteklenmediğini (ve ne ölçüde desteklendiğini) belirlemek için getSupported...(), is...Supported() veya getMax...() yöntemini sağlar.

Uygulamanızın düzgün çalışması için belirli kamera özellikleri gerekiyorsa uygulama manifestinize eklemeler yaparak bu özellikleri zorunlu kılabilirsiniz. Flaş ve otomatik odaklama gibi belirli kamera özelliklerinin kullanımını beyan ettiğinizde Google Play, uygulamanızın bu özellikleri desteklemeyen cihazlara yüklenmesini kısıtlar. Uygulama manifestinizde beyan edilebilecek kamera özelliklerinin listesi için manifest Özellikleri Referansı'na bakın.

Kamera özelliklerini kullanma

Çoğu kamera özelliği, Camera.Parameters nesnesi kullanılarak etkinleştirilir ve kontrol edilir. Bu nesneyi elde etmek için önce Camera nesnesinin bir örneğini alıp getParameters() yöntemini çağırarak, döndürülen parametre nesnesini değiştirerek ve ardından aşağıdaki örnek kodda gösterildiği gibi kamera nesnesine geri ayarlayarak elde edersiniz:

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);

Bu teknik, neredeyse tüm kamera özelliklerinde çalışır ve Camera nesnesinin bir örneğini aldıktan sonra çoğu parametre istediğiniz zaman değiştirilebilir. Parametrelerde yapılan değişiklikler genellikle uygulamadaki kamera önizlemesinde kullanıcıya anında gösterilir. Yazılım tarafında, kamera donanımı yeni talimatları işleyip güncellenmiş görüntü verilerini gönderdiğinden parametre değişikliklerinin geçerlilik kazanması birkaç kare sürebilir.

Önemli: Bazı kamera özellikleri istenildiği zaman değiştirilemez. Özellikle kamera önizlemesinin boyutunu veya yönünü değiştirmek için önce önizlemeyi durdurmanız, önizleme boyutunu değiştirmeniz ve ardından önizlemeyi yeniden başlatmanız gerekir. Android 4.0 (API düzeyi 14) sürümünden itibaren, önizleme yönü önizlemeyi yeniden başlatmadan değiştirilebilir.

Aşağıdakiler de dahil olmak üzere diğer kamera özelliklerinin uygulanması için daha fazla kod gerekir:

  • Ölçüm ve odaklanılacak noktalar
  • Yüz algılama
  • Zaman atlamalı video

Bu özelliklerin nasıl uygulanacağına dair kısa bir özet aşağıdaki bölümlerde verilmiştir.

Ölçüm ve odaklanılacak noktalar

Bazı fotoğrafçılık senaryolarında otomatik odaklama ve ışık ölçümü istenen sonuçları vermeyebilir. Android 4.0'dan (API düzeyi 14) itibaren kamera uygulamanız, uygulamanızın veya kullanıcıların odak ya da ışık seviyesi ayarlarını belirlemek için kullanılacak alanları belirtmesine ve bu değerleri görüntü ya da video çekiminde kullanılmak üzere kamera donanımına iletmesine olanak tanıyan ek kontroller sağlayabilir.

Ölçme ve odaklama alanları, diğer kamera özelliklerine çok benzer şekilde çalışır. Bu alanları Camera.Parameters nesnesindeki yöntemlerle kontrol edersiniz. Aşağıdaki kod, Camera örneği için iki ışık ölçüm alanı ayarlamayı gösterir:

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);

Camera.Area nesnesi iki veri parametresi içerir: Kameranın görüş alanı içinde bir alanı belirtmek için kullanılan bir Rect nesnesi ve kameraya, ışık ölçümü veya odak hesaplamalarında bu alana hangi önem düzeyinin verilmesi gerektiğini söyleyen bir ağırlık değeri.

Camera.Area nesnesindeki Rect alanı, 2000 x 2000 birimlik bir ızgaraya eşlenmiş dikdörtgen bir şekli tanımlar. -1000, -1000 koordinatları, aşağıdaki resimde gösterildiği gibi kamera görüntüsünün sol üst köşesini, 1000, 1000 koordinatları ise kamera görüntüsünün sağ alt köşesini temsil eder.

1.şekil Kırmızı çizgiler, kamera önizlemesinde Camera.Area belirtmek için kullanılan koordinat sistemini gösterir. Mavi kutu, Rect değerleri 333,333,667,667 olan bir kamera alanının konumunu ve şeklini gösterir.

Bu koordinat sisteminin sınırları her zaman kamera önizlemesinde görünen görüntünün dış kenarına karşılık gelir ve yakınlaştırma düzeyine göre küçülmez veya büyümez. Benzer şekilde, Camera.setDisplayOrientation() kullanılarak yapılan resim önizlemesinin döndürülmesi de koordinat sistemini yeniden eşlemez.

Yüz algılama

İnsanların yer aldığı resimlerde yüzler genellikle resmin en önemli bölümüdür ve resim çekilirken hem odak hem de beyaz dengesini belirlemek için kullanılmalıdır. Android 4.0 (API düzeyi 14) çerçevesi, yüzleri tanımlamak ve yüz tanıma teknolojisini kullanarak resim ayarlarını hesaplamak için API'ler sağlar.

Not: Yüz algılama özelliği çalışırken setWhiteBalance(String), setFocusAreas(List<Camera.Area>) ve setMeteringAreas(List<Camera.Area>) etkili olmaz.

Kamera uygulamanızdaki yüz algılama özelliğini kullanmak için birkaç genel adım gerekir:

  • Cihazda yüz algılama özelliğinin desteklendiğinden emin olun.
  • Yüz algılama dinleyicisi oluşturma
  • Yüz algılama dinleyicisini kamera nesnenize ekleyin
  • Önizlemeden sonra (ve her önizleme yeniden başlatıldıktan sonra) yüz algılamayı başlatma

Yüz algılama özelliği tüm cihazlarda desteklenmez. Bu özelliğin desteklenip desteklenmediğini getMaxNumDetectedFaces() numarasını arayarak kontrol edebilirsiniz. Bu kontrolün bir örneği aşağıdaki startFaceDetection() örnek yönteminde gösterilmektedir.

Yüz algılamayla ilgili bildirim almak ve yanıt vermek için kamera uygulamanızın yüz algılama etkinlikleri için bir dinleyici ayarlaması gerekir. Bunu yapmak için aşağıdaki örnek kodda gösterildiği gibi Camera.FaceDetectionListener arayüzünü uygulayan bir dinleyici sınıfı oluşturmanız gerekir.

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() );
        }
    }
}

Bu sınıfı oluşturduktan sonra, aşağıdaki örnek kodda gösterildiği gibi uygulamanızın Camera nesnesine ayarlarsınız:

Kotlin

camera?.setFaceDetectionListener(MyFaceDetectionListener())

Java

camera.setFaceDetectionListener(new MyFaceDetectionListener());

Uygulamanız, kamera önizlemesini her başlattığınızda (veya yeniden başlattığınızda) yüz algılama işlevini başlatmalıdır. Aşağıdaki örnek kodda gösterildiği gibi, gerektiğinde çağırabilmeniz için yüz algılamayı başlatma yöntemi oluşturun.

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();
    }
}

Kamera önizlemesini her başlattığınızda (veya yeniden başlattığınızda) yüz algılamayı başlatmanız gerekir. Önizleme sınıfı oluşturma bölümünde gösterilen önizleme sınıfını kullanıyorsanız startFaceDetection() yönteminizi, aşağıdaki örnek kodda gösterildiği gibi önizleme sınıfınızdaki hem surfaceCreated() hem de surfaceChanged() yöntemlerine ekleyin.

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());
    }
}

Not: Bu yöntemi startPreview() yöntemini çağırdıktan sonra çağırmayı unutmayın. Uygulamanızın yürütülmesinde bu noktada önizleme kullanılamadığından, kamera uygulamanızın ana etkinliğinin onCreate() yönteminde yüz algılamayı başlatmaya çalışmayın.

Zaman atlamalı video

Hızlandırılmış video özelliği, kullanıcıların birkaç saniye veya dakika arayla çekilen fotoğrafları birleştirerek video klipler oluşturmasına olanak tanır. Bu özellik, hızlandırılmış çekim dizisi için görüntüleri kaydetmek üzere MediaRecorder kullanır.

MediaRecorder ile zaman atlamalı video kaydetmek için kaydedici nesnesini normal bir video kaydediyormuş gibi yapılandırmanız, yakalanan kare sayısını düşük bir değere ayarlamanız ve aşağıdaki kod örneğinde gösterildiği gibi zaman atlamalı kalite ayarlarından birini kullanmanız gerekir.

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

Bu ayarlar, MediaRecorder için daha büyük bir yapılandırma prosedürünün parçası olarak yapılmalıdır. Tam yapılandırma kodu örneği için MediaRecorder'ı yapılandırma başlıklı makaleye bakın. Yapılandırma tamamlandıktan sonra, normal bir video klip kaydeder gibi video kaydını başlatırsınız. MediaRecorder yapılandırma ve çalıştırma hakkında daha fazla bilgi için Video çekme başlıklı makaleyi inceleyin.

Camera2Video ve HdrViewfinder örnekleri, bu sayfada ele alınan API'lerin kullanımını daha ayrıntılı bir şekilde gösterir.

İzin gerektiren kamera alanları

Android 10 (API düzeyi 29) veya sonraki sürümleri çalıştıran uygulamaların, getCameraCharacteristics() yönteminin döndürdüğü aşağıdaki alanların değerlerine erişebilmesi için CAMERA iznine sahip olması gerekir:

  • 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

Ek örnek kod

Örnek uygulamaları indirmek için Camera2Basic örneği ve Resmi CameraX örnek uygulaması sayfalarına bakın.