2012-06-28 12 views
5

Ciao ragazzi sto provando a passare dalla fotocamera anteriore e posteriore del dispositivo mentre mostro l'anteprima della fotocamera. Sto seguendo l'esempio fornito da ware comune. Di seguito è riportato il codice che sto usando e ogni volta che clicco sul pulsante Flip la vista della superficie diventa nera e non so dove sto andando male. Per favore aiutami a risolvere questo problema. Ho cercato su questo e non ho avuto risposte adeguate come alcuni hanno cercato di riavviare l'attività corrente, ma non voglio così. Sperando in una risposta migliore. Grazie in anticipo.Anteprima fotocamera Android Passa da una fotocamera all'altra

package com.commonsware.android.camera; 
import android.app.Activity; 
import android.hardware.Camera; 
import android.os.Bundle; 
import android.util.Log; 
import android.view.SurfaceHolder; 
import android.view.SurfaceView; 
import android.widget.CompoundButton; 
import android.widget.CompoundButton.OnCheckedChangeListener; 
import android.widget.Toast; 
import android.widget.ToggleButton; 
public class PreviewDemo extends Activity { 
    private SurfaceView preview = null; 
    private SurfaceHolder previewHolder = null; 
    private Camera camera = null; 
    private boolean inPreview = false; 
    private boolean cameraConfigured = false; 
    private ToggleButton flipCamera; 

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 

    setContentView(R.layout.main); 
    flipCamera = (ToggleButton) findViewById(R.id.flip); 
    preview = (SurfaceView) findViewById(R.id.preview); 
    previewHolder = preview.getHolder(); 
    previewHolder.addCallback(surfaceCallback); 
    previewHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); 
    flipCamera.setOnCheckedChangeListener(new OnCheckedChangeListener() { 

     @Override 
     public void onCheckedChanged(CompoundButton buttonView, 
       boolean isChecked) { 
      // TODO Auto-generated method stub 
      restartPreview(isChecked); 
     } 
    }); 

} 

@Override 
public void onResume() { 
    super.onResume(); 

    // camera=Camera.open(); 
    int camId = Camera.CameraInfo.CAMERA_FACING_BACK; 
    if (Camera.getNumberOfCameras() > 1 
      && camId < Camera.getNumberOfCameras() - 1) { 
     // startCamera(camId + 1); 
     camera = Camera.open(camId + 1); 
    } else { 
     // startCamera(Camera.CameraInfo.CAMERA_FACING_BACK); 
     camera = Camera.open(camId); 
    } 
    startPreview(); 
} 

void restartPreview(boolean isFront) { 
    if (inPreview) { 
     camera.stopPreview(); 
    } 
    // 
    camera.release(); 

    // camera=null; 
    // inPreview=false; 
    // /*int camId = Camera.CameraInfo.CAMERA_FACING_BACK; 
    // if (Camera.getNumberOfCameras() > 1 && camId < 
    // Camera.getNumberOfCameras() - 1) { 
    // //startCamera(camId + 1); 
    // camera = Camera.open(camId + 1); 
    // } else { 
    // //startCamera(Camera.CameraInfo.CAMERA_FACING_BACK); 
    // camera = Camera.open(camId); 
    // }*/ 
    int camId = Camera.CameraInfo.CAMERA_FACING_BACK; 
    if (isFront) { 
     camera = Camera.open(camId); 
     camera.startPreview(); 

    } else { 
     camera = Camera.open(camId + 1); 
     camera.startPreview(); 

    } 
    // startPreview(); 
} 

@Override 
public void onPause() { 
    if (inPreview) { 
     camera.stopPreview(); 
    } 

    camera.release(); 
    camera = null; 
    inPreview = false; 

    super.onPause(); 
} 

private Camera.Size getBestPreviewSize(int width, int height, 
     Camera.Parameters parameters) { 
    Camera.Size result = null; 

    for (Camera.Size size : parameters.getSupportedPreviewSizes()) { 
     if (size.width <= width && size.height <= height) { 
      if (result == null) { 
       result = size; 
      } else { 
       int resultArea = result.width * result.height; 
       int newArea = size.width * size.height; 

       if (newArea > resultArea) { 
        result = size; 
       } 
      } 
     } 
    } 

    return (result); 
} 

private void initPreview(int width, int height) { 
    if (camera != null && previewHolder.getSurface() != null) { 
     try { 
      camera.setPreviewDisplay(previewHolder); 
     } catch (Throwable t) { 
      Log.e("PreviewDemo-surfaceCallback", 
        "Exception in setPreviewDisplay()", t); 
      Toast.makeText(PreviewDemo.this, t.getMessage(), 
        Toast.LENGTH_LONG).show(); 
     } 

     if (!cameraConfigured) { 
      Camera.Parameters parameters = camera.getParameters(); 
      Camera.Size size = getBestPreviewSize(width, height, parameters); 

      if (size != null) { 
       parameters.setPreviewSize(size.width, size.height); 
       camera.setParameters(parameters); 
       cameraConfigured = true; 
      } 
     } 
    } 
} 

private void startPreview() { 
    if (cameraConfigured && camera != null) { 

     camera.startPreview(); 
     inPreview = true; 
    } 
} 

SurfaceHolder.Callback surfaceCallback = new SurfaceHolder.Callback() { 
    public void surfaceCreated(SurfaceHolder holder) { 
     // no-op -- wait until surfaceChanged() 
    } 

    public void surfaceChanged(SurfaceHolder holder, int format, int width, 
      int height) { 
     initPreview(width, height); 
     startPreview(); 
    } 

    public void surfaceDestroyed(SurfaceHolder holder) { 
     // no-op 
     if (camera != null) { 
      /* 
      * Call stopPreview() to stop updating the preview surface. 
      */ 
      camera.stopPreview(); 

      /* 
      * Important: Call release() to release the camera for use by 
      * other applications. Applications should release the camera 
      * immediately in onPause() (and re-open() it in onResume()). 
      */ 
      camera.release(); 

      camera = null; 
     } 
    } 
}; 
} 
+0

Rendi 'camId' un membro statico e ricomincia l'attività quando si controllano le modifiche .. come start stesso e call finish nella riga successiva ... Come un'attività' ricorsiva' .. – Ronnie

+0

@ userSeven7s Mentre questo risolverebbe il problema non è (secondo me) una scelta di design saggia. Un modello comune per le fotocamere è di farle restituire un percorso all'immagine catturata. Se avvio la mia videocamera dall'attività A e la fotocamera si avvia, ottenere il risultato dalla fotocamera diventa complicato. Inoltre, aggiungere la ricorsione al ciclo di vita "speciale" di Android sembra una pessima idea. – TheCrafter

risposta

12

Lei sembra aver dimenticato di chiamare setPreviewDisplay() (o, nel tuo caso, initPreview()) prima di chiamare startPreview() dal tuo metodo restartPreviev(). In effetti, stai tentando di avviare l'anteprima senza specificare una superficie per il rendering dell'anteprima.

Problemi correlati