2016-05-03 7 views
0

die Android-Kamera-Framework fand ich ein Problem: Wenn ich versuche, die Kamera von hinten nach vorne mit dem folgenden Code zu wechselnSchalt android Kamera hinten nach vorne: App übergeben NULL Oberfläche

   releaseMediaRecorder(); 
       releaseCamera(); 
       if(currentCameraId == Camera.CameraInfo.CAMERA_FACING_BACK){ 
        currentCameraId = Camera.CameraInfo.CAMERA_FACING_FRONT; 
       } 
       else { 
        currentCameraId = Camera.CameraInfo.CAMERA_FACING_BACK; 
       } 
       mCamera = Camera.open(currentCameraId); 
       mCamera.setPreviewCallback(null); 
       try { 
        mCamera.setPreviewDisplay(mPreview.getHolder()); 
       } catch (IOException e) { 
        e.printStackTrace(); 
       } 
       mCamera.startPreview(); 

alles funktioniert gut, außer den Vorschaugrößen. Tatsächlich habe ich in meiner Preview-Klasse eine Funktion implementiert, die die besten Vorschaugrößen liefert, aber in diesem Code gibt es diesen Aufruf nicht, weil ich eine neue Instanz der Vorschau bekommen soll, wie ich es in der onResume-Methode mache:

Alles funktioniert, wenn ich die OnResume-Methode ausführen, aber wenn ich und preview.addView(mPreview); in den Umschalt-Kamera-Code kopieren, sagt Log mir "D/Kamera: App bestanden NULL-Oberfläche". Warum?

--EDIT--

Ich habe die SurfaceHolder.Callback in CameraPreview Klasse

public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback { 
private SurfaceHolder mHolder; 
private Camera mCamera; 
private static final String TAG = CameraPreview.class.getName(); 
Camera.Parameters params; 
private float mDist; 

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(); 
    // deprecated setting, but required on Android versions prior to 3.0 
    mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); 
    mHolder.addCallback(this); 
} 
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 
    params = mCamera.getParameters(); 

    params.setWhiteBalance(Camera.Parameters.WHITE_BALANCE_AUTO); 
    params.setExposureCompensation(0); 

    mCamera.setParameters(params); 

    // start preview with new settings 
    try { 
     mCamera.setPreviewDisplay(mHolder); 
     mCamera.startPreview(); 

    } catch (Exception e){ 
     Log.d(TAG, "Error starting camera preview: " + e.getMessage()); 
    } 
} 

// When the surface is ready then we can build the camera and attach 
// the camera preview output to the UI holder 
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. 
    if (mCamera != null) { 
     this.getHolder().removeCallback(this); 
     mCamera.stopPreview(); 
     mCamera.setPreviewCallback(null); 
     mCamera.release(); 
     mCamera = null; 
    } 
} 

private Camera.Size getOptimalPreviewSize(List<Camera.Size> sizes, int w, int h) { 
    final double ASPECT_TOLERANCE = 0.1; 
    double targetRatio = (double) w/h; 
    if (sizes == null) 
     return null; 

    Camera.Size optimalSize = null; 
    double minDiff = Double.MAX_VALUE; 

    int targetHeight = h; 

    // Try to find an size match aspect ratio and size 
    for (Camera.Size size : sizes) { 
     double ratio = (double) size.width/size.height; 
     if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) 
      continue; 
     if (Math.abs(size.height - targetHeight) < minDiff) { 
      optimalSize = size; 
      minDiff = Math.abs(size.height - targetHeight); 
     } 
    } 
    // Cannot find the one match the aspect ratio, ignore the requirement 
    if (optimalSize == null) { 
     minDiff = Double.MAX_VALUE; 
     for (Camera.Size size : sizes) { 
      if (Math.abs(size.height - targetHeight) < minDiff) { 
       optimalSize = size; 
       minDiff = Math.abs(size.height - targetHeight); 
      } 
     } 
    } 

    return optimalSize; 
} 
+0

Ihre Oberfläche ist null, wo erstellen Sie SurfaceHolder? Sie müssen SurfaceHolder.Callback implementieren – manolodewiner

+0

Schauen Sie sich die Bearbeitung an: Ich habe das schon getan..wenn ich eine neue Instanz von CameraPreview erstellen, sollte die Oberfläche neu erstellt werden, oder? – sbomb

Antwort

0

ich die Sache umgesetzt gelöst Code diese Zeilen von

Zugabe
mPreview = new CameraPreview(context, mCamera); 
preview.addView(mPreview); 

vor

try { 
     mCamera.setPreviewDisplay(mPreview.getHolder()); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 

und preview.removeView(mPreview); in die releaseCamera() -Methode hinzufügen