2017-01-11 1 views
1

Normalerweise friert die Android Kamera API mit einem PreviewCallback die Kamera ein, nachdem ein Bild aufgenommen wurde, und dies kann als ein Genehmigungsbildschirm für das Bild verwendet werden. Mein Problem ist, das ist nicht das Verhalten auf Handys wie der Samsung S6 und S6 Rand. Diese beiden Telefone fahren mit der Live-Vorschau fort, nachdem das Bild aufgenommen wurde.Android Kamera Vorschau des Bildes aufgenommen nicht auf bestimmten Geräten

Die Bilder sind immer noch gut und können später verwendet werden, aber die Vorschau zeigt nicht, und die Art, wie meine App eingerichtet ist, habe ich ein Häkchen und ein X-Zeichen für den Benutzer zu genehmigen, was sie gerade genommen haben Foto von. Stattdessen haben sie dieses Overlay für check und "x" und eine Live-Vorschau im Hintergrund. Und das passiert nur an der Samsung s6/s6 Kante.

Eine Idee, was kann ein Problem wie dieses auf bestimmten Geräten verursachen?

-Code für die Vorschau und Bildaufnahme mit einiger Protokollierung überall dort zum Einsatz:

class CameraPreview extends SurfaceView implements SurfaceHolder.Callback { 

    // SurfaceHolder 
    private SurfaceHolder mHolder; 

    // Our Camera. 
    private Camera mCamera; 

    // Parent Context. 
    private Context mContext; 

    // Camera Sizing (For rotation, orientation changes) 
    private Camera.Size mPreviewSize; 

    // List of supported preview sizes 
    private List<Camera.Size> mSupportedPreviewSizes; 
    private List<Camera.Size> mSupportPictureSizes; 

    // Flash modes supported by this camera 
    private List<String> mSupportedFlashModes; 

    // View holding this camera. 
    private View mCameraView; 

    public CameraPreview(Context context, Camera camera, View cameraView) { 
     super(context); 

     Log.d(TAG, "CameraPreview: "); 

     // Capture the context 
     mCameraView = cameraView; 
     mContext = context; 
     setCamera(camera); 

     // Install a SurfaceHolder.Callback so we get notified when the 
     // underlying surface is created and destroyed. 
     mHolder = getHolder(); 
     mHolder.addCallback(this); 
//   mHolder.setKeepScreenOn(true); 
     // deprecated setting, but required on Android versions prior to 3.0 
//   mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); 
    } 

    /** 
    * Begin the preview of the camera input. 
    */ 
    public void startCameraPreview() 
    { 
     Log.d(TAG, "startCameraPreview: "); 
     try{ 
      mCamera.setPreviewDisplay(mHolder); 
      mCamera.startPreview(); 
     } 
     catch(Exception e){ 
      e.printStackTrace(); 
     } 
    } 

    /** 
    * Extract supported preview and flash modes from the camera. 
    * @param camera 
    */ 
    private void setCamera(Camera camera) 
    { 
     // Source: http://stackoverflow.com/questions/7942378/android-camera-will-not-work-startpreview-fails 
     mCamera = camera; 
     mSupportedPreviewSizes = mCamera.getParameters().getSupportedPreviewSizes(); 
     mSupportPictureSizes = mCamera.getParameters().getSupportedPictureSizes(); 

     for(Camera.Size size : mSupportedPreviewSizes){ 
      Log.d(TAG, "supportedPreviewSizes width: " + size.width + " x " + size.height); 
     } 
     for(Camera.Size size : mSupportPictureSizes){ 
      Log.d(TAG, "mSupportPictureSizes width: " + size.width + " x " + size.height); 
     } 
     mSupportedFlashModes = mCamera.getParameters().getSupportedFlashModes(); 
     Camera.Parameters parameters = mCamera.getParameters(); 

     parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE); 

     // Set the camera to Auto Flash mode. 
     if (mSupportedFlashModes != null && mSupportedFlashModes.contains(Camera.Parameters.FLASH_MODE_AUTO)){ 
      parameters.setFlashMode(Camera.Parameters.FLASH_MODE_AUTO); 

     } 

     mCamera.setParameters(parameters); 
     requestLayout(); 
    } 

    /** 
    * The Surface has been created, now tell the camera where to draw the preview. 
    * @param holder 
    */ 
    public void surfaceCreated(SurfaceHolder holder) { 
     Log.d(TAG, "surfaceCreated: "); 
     try { 
      mCamera.setPreviewDisplay(holder); 
      mCamera.startPreview(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 

    /** 
    * Dispose of the camera preview. 
    * @param holder 
    */ 
    public void surfaceDestroyed(SurfaceHolder holder) { 
     Log.d(TAG, "surfaceDestroyed: "); 
     if (mCamera != null){ 
      mCamera.stopPreview(); 
     } 
    } 

    /** 
    * React to surface changed events 
    * @param holder 
    * @param format 
    * @param w 
    * @param h 
    */ 
    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 
      Log.d(TAG, "surfaceChanged: preview surface does not exist"); 
      return; 
     } 
     Log.d(TAG, "surfaceChanged: start & stop preview"); 
     // 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 

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

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

    } 

    @Override 
    public SurfaceHolder getHolder() { 
     return super.getHolder(); 
    } 

    /** 
    * Calculate the measurements of the layout 
    * @param widthMeasureSpec 
    * @param heightMeasureSpec 
    */ 
    @Override 
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) 
    { 

     // Source: http://stackoverflow.com/questions/7942378/android-camera-will-not-work-startpreview-fails 
     final int width = resolveSize(getSuggestedMinimumWidth(), widthMeasureSpec); 
     final int height = resolveSize(getSuggestedMinimumHeight(), heightMeasureSpec); 
     setMeasuredDimension(width, height); 

     if (mSupportedPreviewSizes != null){ 
      Log.d(TAG, "onMeasure: w x h: " + width + " x " + height); 
      mPreviewSize = getOptimalPreviewSize(mSupportedPreviewSizes, width, height); 
     } 
    } 

    /** 
    * Update the layout based on rotation and orientation changes. 
    * @param changed 
    * @param left 
    * @param top 
    * @param right 
    * @param bottom 
    */ 
    @Override 
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) 
    { 
     Log.d(TAG, "onLayout: "); 
     // Source: http://stackoverflow.com/questions/7942378/android-camera-will-not-work-startpreview-fails 
     if (changed) { 
      final int width = right - left; 
      final int height = bottom - top; 

      int previewWidth = width; 
      int previewHeight = height; 

      if (mPreviewSize != null){ 
       Display display = ((WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay(); 

       switch (display.getRotation()) 
       { 
        case Surface.ROTATION_0: 
         previewWidth = mPreviewSize.height; 
         previewHeight = mPreviewSize.width; 
         mCamera.setDisplayOrientation(90); 
         Log.d(TAG, "onLayout: rotation0"); 
         break; 
        case Surface.ROTATION_90: 
         previewWidth = mPreviewSize.width; 
         previewHeight = mPreviewSize.height; 
         Log.d(TAG, "onLayout: rotation90"); 
         break; 
        case Surface.ROTATION_180: 
         previewWidth = mPreviewSize.height; 
         previewHeight = mPreviewSize.width; 
         Log.d(TAG, "onLayout: rotation180"); 
         break; 
        case Surface.ROTATION_270: 
         previewWidth = mPreviewSize.width; 
         previewHeight = mPreviewSize.height; 
         mCamera.setDisplayOrientation(180); 
         Log.d(TAG, "onLayout: rotation270"); 
         break; 
       } 
      } 

      final int scaledChildHeight = previewHeight * width/previewWidth; 
      mCameraView.layout(0, height - scaledChildHeight, width, height); 
     } 
    } 

    private Camera.Size getOptimalPreviewSize(List<Camera.Size> sizes, int w, int h) { 
     Log.d(TAG, "getOptimalPreviewSize: "); 
     final double ASPECT_TOLERANCE = 0.05; 
     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) { 
       Log.d(TAG, "getOptimalPreviewSize: found a match"); 
       optimalSize = size; 
       minDiff = Math.abs(size.height - targetHeight); 
      } 
     } 

     // Cannot find the one match the aspect ratio, ignore the requirement 
     if (optimalSize == null) { 
      Log.d(TAG, "getOptimalPreviewSize: couldn't find match"); 
      minDiff = Double.MAX_VALUE; 
      for (Camera.Size size : sizes) { 
       if (Math.abs(size.height - targetHeight) < minDiff) { 
        optimalSize = size; 
        minDiff = Math.abs(size.height - targetHeight); 
       } 
      } 
     } 
     Log.d(TAG, "getOptimalPreviewSize: " + optimalSize.width + " x HEIGHT: " + optimalSize.height); 
     return optimalSize; 

    } 

} 


/** 
* Picture Callback for handling a picture capture and saving it out to a file. 
*/ 
private Camera.PictureCallback mPicture = new Camera.PictureCallback() { 

    @Override 
    public void onPictureTaken(byte[] data, Camera camera) { 
     Camera.Parameters parameters = camera.getParameters(); 
     Camera.Size mPictureTakenSize = parameters.getPictureSize(); 
     System.out.println("picture taken size: " + mPictureTakenSize.width + " x " + mPictureTakenSize.height); 
     if(data!=null){ 
      Log.d(TAG, "onPictureTaken: data not null, setting data to currentData"); 
//    currentData = data; 
      setPictureTakenData(data); 
      cameraViewModel.setPreview(true); 
     } 
     else{ 
      onProgress = false; 
      Log.d(TAG, "onPictureTaken: data is null"); 
     } 

    } 
}; 

Antwort

0

Ich lief in das gleiche Problem. Es sieht so aus, als könnten Sie es beheben, indem Sie camera.stopPreview() manuell in der onPictureTaken-Methode von PictureCallback aufrufen.

0

Die Kamera Vorschau nicht automatisch nach Aufnahme stoppen, so müssen Sie manuell mCamera.stopPreview() aufrufen:

if (mCamera != null) { 
    try { 
     mCamera.stopPreview(); 
     pauseFlash(); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
} 

// if current camera flash mode is TORCH, you need pause it. 
private void pauseFlash() { 
    if (currentFlashMode.equals(Camera.Parameters.FLASH_MODE_TORCH)) { 
     params = mCamera.getParameters(); 
     params.setFlashMode(Camera.Parameters.FLASH_MODE_OFF); 
     mCamera.setParameters(params); 
    } 
} 

Und dann, nach etwas tun, und navigieren Sie zurück zur Kamera Vorschau:

@Override 
public void startCameraPreview() { 
    if (mCamera != null) { 
     try { 
      mCamera.startPreview(); 
      resumeFlash(); 
     } catch (Exception e) { 
      e.printStackTrace(); 
      // TAKE CARE IF YOUR CAMERA HAS BEEN RELEASED 
     } 
    } 
} 

void resumeFlash() { 
    flashChange(currentFlashMode); 
} 

Und ich habe einige Tipps zur Leistung: Sie sollten die beste Bildgröße und Vorschau Größe beim ersten Mal Benutzer Ihre App verwenden, speichern Sie diese in SharedPreferences und Sie können nach ohne Neuberechnung verwenden.

Hoffe diese Hilfe.

Verwandte Themen