2016-05-16 16 views
0

我在Nexus 5X上的Samsung Galaxy A3(2014)v23上測試SDK v21。我也測試了Camera2Basic示例,並且它在兩個設備上都能正常工作。我不知道我的小代碼調整(我用的活動,而不是一個片段)如何導致僅兩個設備的一個這樣的錯誤:使用SurfaceTexture進行camera2預覽完美適用於SDK v21,但在v23中保持黑色

// ... 

protected void onCreate() { 

    // setContentView ... 

    viewfinder = (AutoFitTextureView)findViewById(R.id.viewfinder); 

    // Choose back camera device, choose maxPictureSize (for JPEG), find out whether dimensions must be swapped 

    if (!swappedDimensions) 
     viewfinder.setAspectRatio(maxPictureSize.getWidth(), maxPictureSize.getHeight()); 
    else 
     viewfinder.setAspectRatio(maxPictureSize.getHeight(), maxPictureSize.getWidth()); 

    // initialize image reader 
} 

protected void onResume() { 

    if (viewfinder.isAvailable()) { 

     // Alternative to call in onSurfaceTextureAvailable() 
     init(); 
    } 
    else { 

     viewfinder.setSurfaceTextureListener(new TextureView.SurfaceTextureListener() { 

      public void onSurfaceTextureAvailable(SurfaceTexture texture, int width, int height) { 

       Log.d(tag(), "surfaceTexture available: " + width + " x " + height); 

       configureSurface(width, height); 

       init(); 
      } 

      public void onSurfaceTextureSizeChanged(SurfaceTexture texture, int width, int height) { 

       Log.d(tag(), "surfaceTexture size changed: " + width + " x " + height); 

       // Currently, don't react to changes. In opposite to the surface change listener, this method is not called after onSurfaceTextureAvailable and only needs to be implemented if the texture view size will change during the app is running 
      } 

      public boolean onSurfaceTextureDestroyed(SurfaceTexture texture) { 

       Log.d(tag(), "surfaceTexture destroyed"); 
       return true; 
      } 

      public void onSurfaceTextureUpdated(SurfaceTexture texture) { 

       Log.d(tag(), "surfaceTexture updated"); 
      } 

     }); 
    } 

    try { 
     if (!openCloseLock.tryAcquire(2500, TimeUnit.MILLISECONDS)) { 
      throw new RuntimeException("Time out waiting to lock camera opening."); 
     } 

     cameraManager.openCamera(deviceId, new CameraDevice.StateCallback() { 

      @Override 
      public void onOpened(CameraDevice camera) { 

       openCloseLock.release(); 
       device = camera; 
       init(); 
      } 

      // ... 
     }, null); 
    } 
    catch(InterruptedException e) { 
     // ... 
    } 
} 

protected void configureSurface(int view_width, int view_height) { 

    SurfaceTexture surfaceTexture = viewfinder.getSurfaceTexture(); 
    if (surfaceTexture == null) 
     return; 


    // Can this be changed after the session has been started?: 
    Size rotatedSurfaceSize = swappedDimensions 
      ? new Size(view_height, view_width) 
      : new Size(view_width, view_height); 
    Size previewSize = bestOutputSize(SurfaceTexture.class, rotatedSurfaceSize, Sizes.aspectRatio(maxPictureSize)); 
    Log.i(tag(), "Preview size for " + rotatedSurfaceSize + " (" + Sizes.aspectRatio(maxPictureSize) + ":1): "+previewSize); 
    surfaceTexture.setDefaultBufferSize(previewSize.getWidth(), previewSize.getHeight()); 
    // 

    // Copied from Camera2Basic, just changed var names: 
    int rotation = getWindowManager().getDefaultDisplay().getRotation(); 
    Matrix matrix = new Matrix(); 
    RectF viewRect = new RectF(0, 0, view_width, view_height); 
    RectF bufferRect = new RectF(0, 0, previewSize.getHeight(), previewSize.getWidth()); 
    float centerX = viewRect.centerX(); 
    float centerY = viewRect.centerY(); 
    if (Surface.ROTATION_90 == rotation || Surface.ROTATION_270 == rotation) { 
     bufferRect.offset(centerX - bufferRect.centerX(), centerY - bufferRect.centerY()); 
     matrix.setRectToRect(viewRect, bufferRect, Matrix.ScaleToFit.FILL); 
     float scale = Math.max(
       (float) view_height/previewSize.getHeight(), 
       (float) view_width/previewSize.getWidth()); 
     matrix.postScale(scale, scale, centerX, centerY); 
     matrix.postRotate(90 * (rotation - 2), centerX, centerY); 
    } else if (Surface.ROTATION_180 == rotation) { 
     matrix.postRotate(180, centerX, centerY); 
    } 
    viewfinder.setTransform(matrix); 
    // 
} 

/** 
* Prerequisites: 
* - The device must be opened. 
* - The surface texture must be available. 
*/ 
protected void init() { 

    // Executed only after second call, loadingState makes sure both prerequisites are true 
    if (++loadingState != 2) 
     return; 


    final CameraDevice d = device; 
    final Surface surface = new Surface(viewfinder.getSurfaceTexture()); 

    try { 
     previewRequestBuilder = d.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW); 
     previewRequestBuilder.addTarget(surface); 
    } catch (CameraAccessException e) { 
     e.printStackTrace(); 
    } 

    CameraCaptureSession.StateCallback cb = new CameraCaptureSession.StateCallback() { 

     @Override 
     public void onConfigured(CameraCaptureSession cameraCaptureSession) { 
      // The camera is already closed 
      if (d == null) { 
       return; 
      } 

      Log.d(tag(), "Configured!"); 

      // When the session is ready, we start displaying the preview. 
      captureSession = cameraCaptureSession; 
      try { 
       Log.d(tag(), "Surface: " + surface); 
       previewRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE); 
       previewRequestBuilder.set(CaptureRequest.CONTROL_AE_MODE, CameraMetadata.CONTROL_AE_MODE_OFF); 

       previewRequest = previewRequestBuilder.build(); 
       captureSession.setRepeatingRequest(previewRequest, previewCallback, null); 

       Log.d(tag(), "Preview started!"); 
      } catch (CameraAccessException e) { 
       e.printStackTrace(); 
      } 
     } 

     @Override 
     public void onConfigureFailed(CameraCaptureSession cameraCaptureSession) { 

      Log.e(tag(), "Configure failed!"); 
     } 
    }; 

    try { 

     d.createCaptureSession(Arrays.asList(surface, imageReader.getSurface()), cb, null); 

     Log.d(tag(), "Session started"); 
    } 
    catch (CameraAccessException e) { 

    } 
} 

// ... 

我自己的日誌輸出沒有拋出錯誤或異常兩臺設備上一樣,定期調用CameraCaptureSession.CaptureCallback.onCaptureCompletedTextureView.SurfaceTextureListener.onSurfaceTextureUpdated。 (可能有相機服務的條目會講述另一個故事,但這些錯誤應該反映在活動中引發的明顯錯誤中。) 預覽僅在我的三星設備上實時顯示,在我的Nexus上它具有合適的尺寸但保持黑色。

回答

2

我曾經有過同樣的問題。 我使用了你編碼的相同代碼。 如您所知,viewfinder.isavailable()返回false。 最後,我發現了AutoTextureView類不適用於API級別23. 因此,您應該創建新的TextureView級別,它在API級別23中可用。

相關問題