web-dev-qa-db-fra.com

changer de caméra avant/arrière

Si je n'utilise que CAMERA_FACING_BACK ou CAMERA_FACING_FRONT, tout va bien.

J'ai des problèmes avec le passage de CAMERA_FACING_BACK à CAMERA_FACING_FRONT.

Mon extrait de code:

public class PhotoCameraActivity extends Activity implements OnClickListener {
private SurfaceView cameraView;
private Button turnButton;
private Camera camera = null;
private Callback listener;
private static int camId = Camera.CameraInfo.CAMERA_FACING_BACK;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.photo_camera_main);
    prepareActivity();
}

private void prepareActivity() {
    cameraView = (SurfaceView) findViewById(R.id.photo_camera_surface_view);

    turnButton = (ImageButton) findViewById(R.id.turn_button);
    turnButton.setOnClickListener(this);
}

@Override
public void onClick(View v) {
    if (v.equals(turnButton)) {
        if (Camera.getNumberOfCameras() > 1 && camId < Camera.getNumberOfCameras() - 1) {
            startCamera(camId + 1);
        } else {
            startCamera(Camera.CameraInfo.CAMERA_FACING_BACK);
        }
    } 
}

@Override
protected void onResume() {
    startCamera(camId);
    super.onResume();
}

@Override
protected void onPause() {
    stopCamera();
    super.onPause();
}

private void startCamera(int cameraId) {
    if (camera != null) {
        stopCamera();
    }       
    holder = cameraView.getHolder();
    listener = new Callback() {

        @Override
        public void surfaceDestroyed(SurfaceHolder holder) {
        }

        @Override
        public void surfaceCreated(SurfaceHolder holder) {
            try {
                camera.setPreviewDisplay(holder);
                camera.startPreview();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void surfaceChanged(SurfaceHolder holder, int format, int           width, int height) {}
    };
    holder.addCallback(listener);


    camId = cameraId;
    camera = Camera.open(cameraId);
    Camera.Parameters params = camera.getParameters();
    if (cameraId == Camera.CameraInfo.CAMERA_FACING_BACK) {
        params.setPreviewSize(1280, 800);
    } else {
        params.setPreviewSize(640, 480);
    }
    camera.setParameters(params);

}

private void stopCamera(){
    System.out.println("stopCamera method");
    if (camera != null){
        camera.stopPreview();
        camera.setPreviewCallback(null);
        camera.release();
        camera = null;
        holder.removeCallback(listener);
        holder = null;
    }
}

}
25
Dmytro Boichenko

Je redémarre l'activité avec cameraId = 2 et cela fonctionne.

5
Dmytro Boichenko

Dans onCreate () de mon activité, j'ajoute l'écouteur onClick suivant à un bouton superposé à ma fenêtre Preview SurfaceView (il existe de nombreux exemples sur le Web pour la prévisualisation):

ImageButton useOtherCamera = (ImageButton) findViewById(R.id.useOtherCamera);
//if phone has only one camera, hide "switch camera" button
if(Camera.getNumberOfCameras() == 1){
    useOtherCamera.setVisibility(View.INVISIBLE);
}
else {
    useOtherCamera.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
    if (inPreview) {
        camera.stopPreview();
    }
    //NB: if you don't release the current camera before switching, you app will crash
    camera.release();

    //swap the id of the camera to be used
    if(currentCameraId == Camera.CameraInfo.CAMERA_FACING_BACK){
        currentCameraId = Camera.CameraInfo.CAMERA_FACING_FRONT;
    }
    else {
        currentCameraId = Camera.CameraInfo.CAMERA_FACING_BACK;
    }
    camera = Camera.open(currentCameraId);
    //Code snippet for this method from somewhere on Android developers, i forget where
    setCameraDisplayOrientation(CameraActivity.this, currentCameraId, camera);
    try {
        //this step is critical or preview on new camera will no know where to render to
        camera.setPreviewDisplay(previewHolder);
    } catch (IOException e) {
        e.printStackTrace();
    }
    camera.startPreview();
}

Sur mon périphérique de test, la caméra arrière a un ID de 0 et la face avant est un. Je suggère d'utiliser des variables statiques Camera.CameraInfo pour les ID de votre caméra plutôt que des valeurs codées en dur. Je suis sûr que cela ne causera que des problèmes sur d'autres appareils.

22
Derek

J'ai supprimé et rajouté SurfaceView dans ma mise en page et cela a donc fonctionné.

public void switchCamera(int cameraType)
{
    if(context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_FRONT))
    {
        if(Camera.getNumberOfCameras() > cameraType)
        {
            // Set selected camera
            this.cameraType = cameraType;
        }
        else
        {
            // Set default camera (Rear)
            this.cameraType = Camera.CameraInfo.CAMERA_FACING_BACK;
        }

        if(mCamera != null)
        {
            // Destroy previuos Holder
            surfaceDestroyed(holder);
            holder.removeCallback(this);

            // Remove and re-Add SurfaceView
            ViewGroup rootLayout = (ViewGroup) surface.getParent();
            rootLayout.removeView(surface);
            surface = new SurfaceView(context);
            holder = surface.getHolder();
            holder.addCallback(this);
            rootLayout.addView(surface, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
        }
    }
}
4
android_user_

Je dois supprimer l'aperçu de la surface avant d'en ajouter un nouveau:

if (mPreview != null) {
        mPreview.surfaceDestroyed(mPreview.getHolder());
        mPreview.getHolder().removeCallback(mPreview);
        mPreview.destroyDrawingCache();
        FrameLayout preview = (FrameLayout) view.findViewById(R.id.camera_frame);
        preview.removeView(mPreview);
        mPreview.mCamera = null;
        mPreview = null;

    }

//then add your preview
2
MobileMon

Utilisez ce code:

if (mCamera != null) {
      mCamera.stopPreview();                  
      mCamera.release();
      mCamera = null;
}

//swap the id of the camera to be used
if (currentCameraId == Camera.CameraInfo.CAMERA_FACING_BACK)
  currentCameraId = Camera.CameraInfo.CAMERA_FACING_FRONT;
else 
  currentCameraId = Camera.CameraInfo.CAMERA_FACING_BACK;         

try {                
       mCamera = Camera.open(currentCameraId);   

       mCamera.setDisplayOrientation(90);

       mCamera.setPreviewDisplay(surfaceHolder);               

       mCamera.startPreview();

     } 
catch (Exception e) { e.printStackTrace(); } 
0
Ingo