Android platformunda "ön kamerayı" nasıl açarım?


83

Daha genel olarak, bir aygıtta birden fazla yerleşik kamera varsa, özellikle birini başlatmanın bir yolu var mı?

Android referans belgelerinde bulamadım:

Samsung SHW-M100S'de iki kamera bulunur. İki kamera kullanmakla ilgili bir referans yoksa, Samsung'un nasıl yaptığı hakkında bir fikriniz var mı?


Yanıtlar:


114
private Camera openFrontFacingCameraGingerbread() {
    int cameraCount = 0;
    Camera cam = null;
    Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
    cameraCount = Camera.getNumberOfCameras();
    for (int camIdx = 0; camIdx < cameraCount; camIdx++) {
        Camera.getCameraInfo(camIdx, cameraInfo);
        if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
            try {
                cam = Camera.open(camIdx);
            } catch (RuntimeException e) {
                Log.e(TAG, "Camera failed to open: " + e.getLocalizedMessage());
            }
        }
    }

    return cam;
}

AndroidManifest.xmlDosyaya aşağıdaki izinleri ekleyin :

<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" android:required="false" />
<uses-feature android:name="android.hardware.camera.front" android:required="false" />

Not: Bu özellik, Gingerbread (2.3) ve Yukarı Android Sürümlerinde mevcuttur.


Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);Mevcut kamera uygulamasını açmak için bunu bir şekilde teknikle kullanmak mümkün mü ?
loeschg

3
@loeschg Intentkamera hareketini kendi yöntemiyle ele alır. Bu teknik, SurfaceViewkamera işlevselliğinden yararlanmak için kullandığınızda kullanılır .

ben de öyle düşündüm. Teşekkürler!
loeschg

2
Çok güzel gönderi. Kameranın bakmasının kamera endeksiyle kesinlikle aynı olmadığını anlamam biraz zaman aldı. Örneğin, tabletimde yalnızca bir kamera var (dizin: 0), ancak öne dönük (bakan dizin: 1). Bu nedenle, Camera.open (CameraInfo.CAMERA_FACING_FRONT) gibi basit bir kod kullanmak anlamsızdır.
Matthias

@Matthias Seninle katılıyorum dostum. Farklı OEM'lere sahip olduğumuz için programlama tekniğimiz ihtiyaçlarımıza göre değişiyor. Vurguladığınız için teşekkürler.

14

Tüm eski yanıtların yöntemleri Google tarafından (sözde bunun gibi sorunlar nedeniyle) kullanımdan kaldırılmıştır, API 21'den beri Camera 2 API'sini kullanmanız gerekir :

Bu sınıf, API seviyesi 21'de kullanımdan kaldırılmıştır. Yeni uygulamalar için yeni android.hardware.camera2 API'sini kullanmanızı öneririz.

Gelen yeni API var neredeyse tam güç Android cihazı kamera ve belgelere açıkça tavsiye üzerine

String[] getCameraIdList()

ve ardından kamerayı açmak için elde edilen CameraId'yi kullanın:

void openCamera(String cameraId, CameraDevice.StateCallback callback, Handler handler)

Buna göre ön kameraların% 99'u id = "1" ve arka kamera kimliği = "0" değerine sahiptir:

Çıkarılamayan kameralar, tanımlayıcıları için 0'dan başlayan tamsayılar kullanırken, çıkarılabilir kameralar, aynı model olsalar bile her bir cihaz için benzersiz bir tanımlayıcıya sahiptir.

Bununla birlikte , bu, cihaz durumu sadece 1 ön kameralı tablet gibi nadirse, kaç tane gömülü kameranız olduğunu saymanız ve kameranın önem derecesine göre sırasını ("0") vermeniz gerektiği anlamına gelir . Dolayısıyla CAMERA_FACING_FRONT == 1 CAMERA_FACING_BACK == 0, bu da arka kameranın önden daha önemli olduğu anlamına gelir .

Tüm Android cihazlarda ön kamerayı tanımlamak için tek tip bir yöntem bilmiyorum . Basitçe söylemek gerekirse, cihazın içindeki Android işletim sistemi, bazı nedenlerden ötürü hangi kameranın tam olarak nerede olduğunu tam olarak bulamıyor: belki de kodlanmış tek kamera kimliği, önemini temsil eden bir tamsayıdır veya belki bazı cihazlarda hangi tarafa bakarsanız bakın .. " geri".

Belgeler : https://developer.android.com/reference/android/hardware/camera2/package-summary.html

Açık Örnekler : https://github.com/googlesamples/android-Camera2Basic


Eski API için (tavsiye edilmez, çünkü modern telefonlarda daha yeni Android sürümünde çalışmayacaktır ve aktarım bir acıdır). Bu cevapta olduğu gibi ön kamerayı açmak için aynı Tamsayı Kamera Kimliğini (1) kullanın :

cam = Camera.open(1);

OpenCV'nin kamera bölümünü yapması için güveniyorsanız :

İçeride

    <org.opencv.android.JavaCameraView
    ../>

ön kamera için aşağıdakileri kullanın:

        opencv:camera_id="1"

10

Android 2.1'den itibaren Android, SDK'sında yalnızca tek bir kamerayı destekler. Bunun gelecekteki bir Android sürümüne eklenmesi muhtemeldir.


1
bu ifade Android 2.2 için de geçerli mi?
ozmank

2
@ozmank: Evet, çoklu kamera desteği Android 2.3'e kadar eklenmedi.
CommonsWare

4
public void surfaceCreated(SurfaceHolder holder) {
    try {
        mCamera = Camera.open();
        mCamera.setDisplayOrientation(90);
        mCamera.setPreviewDisplay(holder);

        Camera.Parameters p = mCamera.getParameters();
        p.set("camera-id",2);
        mCamera.setParameters(p);   
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

3
Galaxy S'de iyi çalışma Önemli "kamera kimliği", "kamera_kimliği" değil
Mahesh

3
Asla 90 derecenin portre için doğru dönüşü sağlayacağını varsaymayın. Birçok cihazda farklıdır.
colintheshots

4

API 21 (5.0) ve sonrası için CameraManager API'lerini kullanabilirsiniz.

try {
    String desiredCameraId = null;
    for(String cameraId : mCameraIDsList) {
        CameraCharacteristics chars =  mCameraManager.getCameraCharacteristics(cameraId);
        List<CameraCharacteristics.Key<?>> keys = chars.getKeys();
        try {
            if(CameraCharacteristics.LENS_FACING_FRONT == chars.get(CameraCharacteristics.LENS_FACING)) {
               // This is the one we want.
               desiredCameraId = cameraId;
               break;
            }
        } catch(IllegalArgumentException e) {
            // This key not implemented, which is a bit of a pain. Either guess - assume the first one
            // is rear, second one is front, or give up.
        }
    }
}

4

Arka kamerayı açmak için : -

val cameraIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
startActivityForResult(cameraIntent, REQUEST_CODE_CAMERA)

Ön kamerayı açmak için : -

val cameraIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
when {
     Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1 && Build.VERSION.SDK_INT < Build.VERSION_CODES.O -> {
         cameraIntent.putExtra("android.intent.extras.CAMERA_FACING", CameraCharacteristics.LENS_FACING_FRONT)  // Tested on API 24 Android version 7.0(Samsung S6)
     }
     Build.VERSION.SDK_INT >= Build.VERSION_CODES.O -> {
         cameraIntent.putExtra("android.intent.extras.CAMERA_FACING", CameraCharacteristics.LENS_FACING_FRONT) // Tested on API 27 Android version 8.0(Nexus 6P)
         cameraIntent.putExtra("android.intent.extra.USE_FRONT_CAMERA", true)
     }
     else -> cameraIntent.putExtra("android.intent.extras.CAMERA_FACING", 1)  // Tested API 21 Android version 5.0.1(Samsung S4)
}
startActivityForResult(cameraIntent, REQUEST_CODE_CAMERA)

API 28 ve üzeri için çalışmasını sağlayamadım. Ayrıca, bazı cihazlarda ön kamerayı doğrudan açmak mümkün değildir (üreticiye bağlıdır).


API 28 ve üzeri için buna herhangi bir çözüm buldunuz mu?
Ankit Gupta

2

Android 2.3'ün (Gingerbread) sürümüyle birlikte, artık android.hardware.Camerakamera sayısını, belirli bir kamera hakkında bilgi almak ve belirli bir kamera ile ilgili bir referans almak için sınıfı kullanabilirsiniz Camera. Yeni CameraAPI'lere buradan göz atın .


1

build.gradle

 dependencies {
       compile 'com.google.android.gms:play-services-vision:9.4.0+'
    }

Görünümü Ayarla

CameraSourcePreview mPreview = (CameraSourcePreview) findViewById(R.id.preview);

GraphicOverlay mGraphicOverlay = (GraphicOverlay) findViewById(R.id.faceOverlay);

CameraSource mCameraSource = new CameraSource.Builder(context, detector)
                            .setRequestedPreviewSize(640, 480)
                            .setFacing(CameraSource.CAMERA_FACING_FRONT)
                            .setRequestedFps(30.0f)
                            .build();

           mPreview.start(mCameraSource, mGraphicOverlay);

0
Camera camera;   
if (Camera.getNumberOfCameras() >= 2) {

    //if you want to open front facing camera use this line   
    camera = Camera.open(CameraInfo.CAMERA_FACING_FRONT);

    //if you want to use the back facing camera
    camera = Camera.open(CameraInfo.CAMERA_FACING_BACK);                
}

try {
    camera.setPreviewDisplay("your surface holder here");
    camera.startPreview();      
} catch (Exception e) {  
    camera.release();
}

/ * Bu doğru bir yol değil, Android 4.0 veya daha eski sürümleri çalıştıran eski cihazlar için bir çözümdür. Bu, test amacıyla kullanılabilir, ancak ana geliştirme için önerilmez. Bu çözüm yalnızca geçici bir çözüm olarak düşünülebilir. Ancak bu çözüm birçok kişiye yardımcı oldu, bu yüzden bu yanıtı silmek niyetinde değilim * /


7
Bunun belgelenmiş kullanım olduğunu sanmıyorum. open (int id) kamera konumunu değil kimliği kabul eder
XY

13
lütfen bu yanıltıcı yanıtı kaldırın
Alex Cohn

13
@AmalanDhananjayan: Örneğin yukarıdaki @Matthias'ın yorumuna bakın : Kameranın yüzünün kamera indeksiyle aynı olmadığını anlamam biraz zaman aldı. Örneğin, tabletimde yalnızca bir kamera var (dizin: 0), ancak öne dönük (bakan dizin: 1). Bu nedenle, Camera.open (CameraInfo.CAMERA_FACING_FRONT) gibi basit bir kod kullanmak anlamsızdır.
Alex Cohn

6
Bu saçma. Bunu kullanmaya kalkma bile.
Adam

4
Bu korkunç. Bunu ASLA yapmayın. Bu cevap yasaklanmalıdır. Camera.open () bir kamera kimliğini kabul eder, bakan kameranın sıra değerini değil! Bu, cihazların önemli bir bölümünde başarısız olur ve yalnızca aptalca şansla işe yarar.
colintheshots
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.