2016-05-16 1 views
0

SDK v21をSamsung Galaxy A3(2014)でテストし、v23をNexus 5Xでテストします。 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の両方が定期的に呼び出されます。 (おそらく別の物語を伝えるカメラサービスのエントリがあるかもしれませんが、そのエラーはアクティビティに明示されたエラーによって反映されるはずです) プレビューは自分のSamsungデバイスにのみ公開され、Nexusでは正しいサイズ黒いままです。

答えて

2

私は今まで同じ問題を抱えていました。 私はあなたがコード化した同じコードを使用しました。 ご存じのように、viewfinder.isavailable()はfalseを返します。 最後に私はAutoTextureViewクラスがAPIレベル23で利用できないことを発見しました。 したがって、APIレベル23で利用可能な新しいTextureViewクラスを作成する必要があります。

関連する問題