Jazzel Mehmood
Jazzel Mehmood

Reputation: 5

Dual Camera (front + back simultaneously) support in Android phones for applications ended or what?

So I have a requirement of recording both front and back camera at once. I even have this feature in my phone's camera application. So i thought maybe I can develop and application too to achieve this functionality.

First I tried using react-native, it failed to create 2 views for 2 separate cameras by showing a message "Camera already in use". Then after a little bit research, I got to know react-native cannot do that and we have to write native code for CameraX or Camera2 libraries. Attached code for reference.

import {
  useCameraDevices,
  Camera,
  useCameraDevice,
  useCameraPermission,
} from "react-native-vision-camera";
import { View, Button, Text } from "react-native";
import { useEffect, useState } from "react";

const DualCameraScreen = () => {
  const device1 = useCameraDevice("front");
  const device2 = useCameraDevice("back");
  const { hasPermission, requestPermission } = useCameraPermission();
  const [isRecording, setIsRecording] = useState(false);

  if (!hasPermission) {
    requestPermission();
  }

  const startRecording = async () => {
    setIsRecording(true);
  };

  return (
    <View style={{ flex: 1 }}>
      {device1 && device2 && (
        <View
          style={{ flex: 1, flexDirection: "column", backgroundColor: "green" }}
        >
          <Camera
            style={{ flex: 1 / 3, width: "100%" }}
            device={device1}
            isActive={true}
            video={true}
          />
          <Camera
            style={{ flex: 1 / 3, width: "100%" }}
            device={device2}
            isActive={true}
          />
        </View>
      )}
    </View>
  );
};

export default DualCameraScreen;

Coming back to android studio (kotlin), started developing the same thing and again stuck on the same thing, This time since I was on native mode, I had access to more logs, which showed me that phone's maximum allowed cameras is 1. Code attached below:

implementation "androidx.camera:camera-core:1.4.1"
implementation "androidx.camera:camera-camera2:1.4.1"
implementation "androidx.camera:camera-lifecycle:1.4.1"
implementation "androidx.camera:camera-view:1.4.1"
class DualCameraActivity : AppCompatActivity() {
    private lateinit var backCameraPreview: PreviewView
    private lateinit var frontCameraPreview: PreviewView
    private var cameraProvider: ProcessCameraProvider? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_dual_camera)

        backCameraPreview = findViewById(R.id.backCameraPreview)
        frontCameraPreview = findViewById(R.id.frontCameraPreview)

        val cameraProviderFuture = ProcessCameraProvider.getInstance(this)
        cameraProviderFuture.addListener({
            cameraProvider = cameraProviderFuture.get()
            bindDualCameras()
        }, ContextCompat.getMainExecutor(this))
    }

    private fun bindDualCameras() {
        val cameraProvider = cameraProvider ?: return
        val cameraSelectorBack = CameraSelector.Builder()
            .requireLensFacing(CameraSelector.LENS_FACING_BACK)
            .build()

        val cameraSelectorFront = CameraSelector.Builder()
            .requireLensFacing(CameraSelector.LENS_FACING_FRONT)
            .build()

        val previewBack = Preview.Builder().build().also {
            it.setSurfaceProvider(backCameraPreview.surfaceProvider)
        }

        val previewFront = Preview.Builder().build().also {
            it.setSurfaceProvider(frontCameraPreview.surfaceProvider)
        }

        // Unbind any previously bound use cases
        cameraProvider.unbindAll()

        try {
            // Bind both cameras
            cameraProvider.bindToLifecycle(this, cameraSelectorBack, previewBack)
            cameraProvider.bindToLifecycle(this, cameraSelectorFront, previewFront)
        } catch (exc: Exception) {
            Log.e("DualCameraActivity", "Use case binding failed", exc)
        }
    }
}

<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <androidx.camera.view.PreviewView
        android:id="@+id/backCameraPreview"
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toTopOf="@id/frontCameraPreview"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent" />

    <androidx.camera.view.PreviewView
        android:id="@+id/frontCameraPreview"
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:layout_constraintTop_toBottomOf="@id/backCameraPreview"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

Now after a bit of more research, I got the following code:

val cameraManager = getSystemService(Context.CAMERA_SERVICE) as CameraManager
val cameraIdList = cameraManager.cameraIdList

for (id in cameraIdList) {
    val characteristics = cameraManager.getCameraCharacteristics(id)
    val capabilities = characteristics.get(CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES)

    if (capabilities != null && capabilities.contains(CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_LOGICAL_MULTI_CAMERA)) {
        Log.d("CameraInfo", "Device supports concurrent camera: $id")
    }
}

this code REQUEST_AVAILABLE_CAPABILITIES_LOGICAL_MULTI_CAMERA tells if phone can handle multiple cameras or not and the above code failed to print anything which shows my phone cannot allow custom made applications to do this. I researched more and got to know that only Snapdragon chipsets can handle this. I checked on a phone with Snapdragon 730 and it failed but with Snapdragon 860 it worked.

So I want to know what kind of issue is this, is this only allowed on Snapdragons 800+ because it fails on latest MediaTeks (which actually has access to dual mode in camera app).

Upvotes: 0

Views: 63

Answers (1)

Eddy Talvala
Eddy Talvala

Reputation: 18137

REQUEST_AVAILABLE_CAPABILITIES_LOGICAL_MULTI_CAMERA is not about using the front and back cameras at the same time; it's about camera clusters such as telephoto + wide + ultrawide combinations that are often used on back cameras especially. Devices that support this capability allow access to these individual cameras, instead of either hiding them or only allowing access to a composite logical camera.

What you want to use is either ConcurrentCamera from CameraX, or if using camera2 directly, you'd need to follow the information at PackageManager.FEATURE_CAMERA_CONCURRENT.

In any case, the presence of FEATURE_CAMERA_CONCURRENT will tell you if the device officially supports simultaneous access to the back and front cameras for regular Android apps.

Upvotes: 0

Related Questions