2016-05-29 3 views
0

Мне нужна помощь с этим кодом. Это дает мне эту ошибкуВзятие изображений camera2api

java.lang.NullPointerException: попытка вызвать виртуальный метод Пустота android.hardware.camera2.CaptureRequest $ Builder.set (android.hardware.camera2.CaptureRequest $ Key, java.lang. Object)»на объектную ссылку нулевой

Мой код

private int mState = STATE_PREVIEW; 
private static final int REQUEST_CAMERA_PERMISSION_RESULT = 0; 
private static final int REQUEST_WRITE_EXTERNAL_STORAGE_PERMISSION_RESULT = 1; 
private static final int STATE_PREVIEW = 0; 
private static final int STATE_WAIT_LOCK = 1; 
private int mCaptureState = STATE_PREVIEW; 
private TextureView mTextureView; 
private TextureView.SurfaceTextureListener mSurfaceTextureListener = new TextureView.SurfaceTextureListener() { 
    @Override 
    public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) { 
     setupCamera(width, height); 
     connectCamera(); 
    } 

    @Override 
    public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) { 

    } 

    @Override 
    public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) { 
     return false; 
    } 

    @Override 
    public void onSurfaceTextureUpdated(SurfaceTexture surface) { 

    } 
}; 
private CameraDevice mCameraDevice; 
private CameraDevice.StateCallback mCameraDeviceStateCallback = new CameraDevice.StateCallback() { 
    @Override 
    public void onOpened(CameraDevice camera) { 
     mCameraDevice = camera; 
     startPreview(); 
    } 

    @Override 
    public void onDisconnected(CameraDevice camera) { 
     camera.close(); 
     mCameraDevice = null; 
    } 

    @Override 
    public void onError(CameraDevice camera, int error) { 
     camera.close(); 
     mCameraDevice = null; 
    } 
}; 
private HandlerThread mBackgroundHandlerThread; 
private Handler mBackgroundHandler; 
private String mCameraId; 
private Size mPreviewSize; 
private Size mImageSize; 
private ImageReader mImageReader; 
private final ImageReader.OnImageAvailableListener mOnImageAvailableListener = new 
     ImageReader.OnImageAvailableListener() { 
      @Override 
      public void onImageAvailable(ImageReader reader) { 
       mBackgroundHandler.post(new ImageSaver(reader.acquireLatestImage())); 
      } 
     }; 
private class ImageSaver implements Runnable { 

    private final Image mImage; 

    public ImageSaver(Image image) { 
     mImage = image; 
    } 

    @Override 
    public void run() { 
     ByteBuffer byteBuffer = mImage.getPlanes()[0].getBuffer(); 
     byte[] bytes = new byte[byteBuffer.remaining()]; 
     byteBuffer.get(bytes); 

     FileOutputStream fileOutputStream = null; 
     try { 
      fileOutputStream = new FileOutputStream(mImageFileName); 
      fileOutputStream.write(bytes); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } finally { 
      mImage.close(); 
      if(fileOutputStream != null) { 
       try { 
        fileOutputStream.close(); 
       } catch (IOException e) { 
        e.printStackTrace(); 
       } 
      } 
     } 

    } 
} 
private MediaRecorder mMediaRecorder; 

private int mTotalRotation; 
private CameraCaptureSession mPreviewCaptureSession; 
private CameraCaptureSession.CaptureCallback mPreviewCaptureCallback = new 
     CameraCaptureSession.CaptureCallback() { 

      private void process(CaptureResult captureResult) { 
       switch (mCaptureState) { 
        case STATE_PREVIEW: 
         // Do nothing 
         break; 
        case STATE_WAIT_LOCK: 
         mCaptureState = STATE_PREVIEW; 
         Integer afState = captureResult.get(CaptureResult.CONTROL_AF_STATE); 
         if(afState == CaptureResult.CONTROL_AF_STATE_FOCUSED_LOCKED || 
           afState == CaptureResult.CONTROL_AF_STATE_NOT_FOCUSED_LOCKED) { 
          Toast.makeText(getApplicationContext(), "AF Locked!", Toast.LENGTH_SHORT).show(); 
          startStillCaptureRequest(); 
         } 
         break; 
       } 
      } 

      @Override 
      public void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request, TotalCaptureResult result) { 
       super.onCaptureCompleted(session, request, result); 

       process(result); 
      } 
     }; 
private CaptureRequest mPreviewCaptureRequest; 
private CaptureRequest.Builder mPreviewCaptureRequestBuilder; 
private CameraCaptureSession mCameraCaptureSession; 
private CameraCaptureSession.CaptureCallback mSessionCaptureCallback 
     = new CameraCaptureSession.CaptureCallback() { 

    private void process(CaptureResult result) { 
     switch(mState) { 
      case STATE_PREVIEW: 
       // Do nothing 
       break; 
      case STATE_WAIT_LOCK: 
       Integer afState = result.get(CaptureResult.CONTROL_AF_STATE); 
       if(afState == CaptureRequest.CONTROL_AF_STATE_FOCUSED_LOCKED) { 
        /* 
        unLockFocus(); 
        Toast.makeText(getApplicationContext(), "Focus Lock Successful", Toast.LENGTH_SHORT).show(); 
        */ 
        captureStillImage(); 
       } 
       break; 
     } 
    } 
    @Override 
    public void onCaptureStarted(CameraCaptureSession session, CaptureRequest request, long timestamp, long frameNumber) { 
     super.onCaptureStarted(session, request, timestamp, frameNumber); 
    } 

    @Override 
    public void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request, TotalCaptureResult result) { 
     super.onCaptureCompleted(session, request, result); 

     process(result); 
    } 

    @Override 
    public void onCaptureFailed(CameraCaptureSession session, CaptureRequest request, CaptureFailure failure) { 
     super.onCaptureFailed(session, request, failure); 

     Toast.makeText(getApplicationContext(), "Focus Lock Unsuccessful", Toast.LENGTH_SHORT).show(); 
    } 
}; 

private CaptureRequest.Builder mCaptureRequestBuilder; 

private File mImageFolder; 
private String mImageFileName; 

private static SparseIntArray ORIENTATIONS = new SparseIntArray(); 
static { 
    ORIENTATIONS.append(Surface.ROTATION_0, 0); 
    ORIENTATIONS.append(Surface.ROTATION_90, 90); 
    ORIENTATIONS.append(Surface.ROTATION_180, 180); 
    ORIENTATIONS.append(Surface.ROTATION_270, 270); 
} 

private static class CompareSizeByArea implements Comparator<Size> { 

    @Override 
    public int compare(Size lhs, Size rhs) { 
     return Long.signum((long) lhs.getWidth() * lhs.getHeight()/
       (long) rhs.getWidth() * rhs.getHeight()); 
    } 
} 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_camera); 

    createImageFolder(); 

    mTextureView = (TextureView) findViewById(R.id.textureView); 
    final Button button = (Button) findViewById(R.id.camera_button); 
    if (button != null) { 
     button.setOnClickListener(new View.OnClickListener() { 

      @Override 
      public void onClick(View v) { 
       takePicture(); 
      } 
     }); 
    } 

} 

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

    startBackgroundThread(); 

     if (mTextureView.isAvailable()) { 
     setupCamera(mTextureView.getWidth(), mTextureView.getHeight()); 
     connectCamera(); 
    } else { 
     mTextureView.setSurfaceTextureListener(mSurfaceTextureListener); 
    } 
} 

@Override 
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { 
    super.onRequestPermissionsResult(requestCode, permissions, grantResults); 
    if(requestCode == REQUEST_CAMERA_PERMISSION_RESULT) { 
     if(grantResults[0] != PackageManager.PERMISSION_GRANTED) { 
      Toast.makeText(getApplicationContext(), 
        "Application will not run without camera services", Toast.LENGTH_SHORT).show(); 
     } 
     if(grantResults[1] != PackageManager.PERMISSION_GRANTED) { 
      Toast.makeText(getApplicationContext(), 
        "Application will not have audio on record", Toast.LENGTH_SHORT).show(); 
     } 
    } 
    if(requestCode == REQUEST_WRITE_EXTERNAL_STORAGE_PERMISSION_RESULT) { 
     if(grantResults[0] == PackageManager.PERMISSION_GRANTED) { 

      Toast.makeText(this, 
        "Permission successfully granted!", Toast.LENGTH_SHORT).show(); 
     } else { 
      Toast.makeText(this, 
        "App needs to save image to run", Toast.LENGTH_SHORT).show(); 
     } 
    } 
} 

@Override 
protected void onPause() { 
    closeCamera(); 

    stopBackgroundThread(); 

    super.onPause(); 
} 

@Override 
public void onWindowFocusChanged(boolean hasFocas) { 
    super.onWindowFocusChanged(hasFocas); 
    View decorView = getWindow().getDecorView(); 
    if(hasFocas) { 
     decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE 
       | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY 
       | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN 
       | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION 
       | View.SYSTEM_UI_FLAG_FULLSCREEN 
       | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION); 
    } 
} 

private void setupCamera(int width, int height) { 
    CameraManager cameraManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE); 
    try { 
     for(String cameraId : cameraManager.getCameraIdList()){ 
      CameraCharacteristics cameraCharacteristics = cameraManager.getCameraCharacteristics(cameraId); 
      if(cameraCharacteristics.get(CameraCharacteristics.LENS_FACING) == 
        CameraCharacteristics.LENS_FACING_FRONT){ 
       continue; 
      } 
      StreamConfigurationMap map = cameraCharacteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP); 
      int deviceOrientation = getWindowManager().getDefaultDisplay().getRotation(); 
      mTotalRotation = sensorToDeviceRotation(cameraCharacteristics, deviceOrientation); 
      boolean swapRotation = mTotalRotation == 90 || mTotalRotation == 270; 
      int rotatedWidth = width; 
      int rotatedHeight = height; 
      if(swapRotation) { 
       rotatedWidth = height; 
       rotatedHeight = width; 
      } 
      mPreviewSize = chooseOptimalSize(map.getOutputSizes(SurfaceTexture.class), rotatedWidth, rotatedHeight); 
      mImageSize = chooseOptimalSize(map.getOutputSizes(ImageFormat.JPEG), rotatedWidth, rotatedHeight); 
      mImageReader = ImageReader.newInstance(mImageSize.getWidth(), mImageSize.getHeight(), ImageFormat.JPEG, 1); 
      mImageReader.setOnImageAvailableListener(mOnImageAvailableListener, mBackgroundHandler); 
      mCameraId = cameraId; 
      return; 
     } 
    } catch (CameraAccessException e) { 
     e.printStackTrace(); 
    } 
} 

private void connectCamera() { 
    CameraManager cameraManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE); 
    try { 
     if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { 
      if(ContextCompat.checkSelfPermission(this, android.Manifest.permission.CAMERA) == 
        PackageManager.PERMISSION_GRANTED) { 
       cameraManager.openCamera(mCameraId, mCameraDeviceStateCallback, mBackgroundHandler); 
      } else { 
       if(shouldShowRequestPermissionRationale(android.Manifest.permission.CAMERA)) { 
        Toast.makeText(this, 
          "Video app required access to camera", Toast.LENGTH_SHORT).show(); 
       } 
       requestPermissions(new String[] {android.Manifest.permission.CAMERA, Manifest.permission.RECORD_AUDIO 
       }, REQUEST_CAMERA_PERMISSION_RESULT); 
      } 

     } else { 
      cameraManager.openCamera(mCameraId, mCameraDeviceStateCallback, mBackgroundHandler); 
     } 
    } catch (CameraAccessException e) { 
     e.printStackTrace(); 
    } 
} 



private void startPreview() { 
    SurfaceTexture surfaceTexture = mTextureView.getSurfaceTexture(); 
    surfaceTexture.setDefaultBufferSize(mPreviewSize.getWidth(), mPreviewSize.getHeight()); 
    Surface previewSurface = new Surface(surfaceTexture); 

    try { 
     mCaptureRequestBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW); 
     mCaptureRequestBuilder.addTarget(previewSurface); 

     mCameraDevice.createCaptureSession(Arrays.asList(previewSurface, mImageReader.getSurface()), 
       new CameraCaptureSession.StateCallback() { 
        @Override 
        public void onConfigured(CameraCaptureSession session) { 
         mPreviewCaptureSession = session; 
         try { 
          mPreviewCaptureSession.setRepeatingRequest(mCaptureRequestBuilder.build(), 
            null, mBackgroundHandler); 
         } catch (CameraAccessException e) { 
          e.printStackTrace(); 
         } 
        } 

        @Override 
        public void onConfigureFailed(CameraCaptureSession session) { 
         Toast.makeText(getApplicationContext(), 
           "Unable to setup camera preview", Toast.LENGTH_SHORT).show(); 

        } 
       }, null); 
    } catch (CameraAccessException e) { 
     e.printStackTrace(); 
    } 
} 

private void startStillCaptureRequest() { 

     mCaptureRequestBuilder.addTarget(mImageReader.getSurface()); 
     mCaptureRequestBuilder.set(CaptureRequest.JPEG_ORIENTATION, mTotalRotation); 

     CameraCaptureSession.CaptureCallback stillCaptureCallback = new 
       CameraCaptureSession.CaptureCallback() { 
        @Override 
        public void onCaptureStarted(CameraCaptureSession session, CaptureRequest request, long timestamp, long frameNumber) { 
         super.onCaptureStarted(session, request, timestamp, frameNumber); 

         try { 
          createImageFileName(); 
         } catch (IOException e) { 
          e.printStackTrace(); 
         } 
        } 
       }; 



} 

private void closeCamera() { 
    if(mCameraDevice != null) { 
     mCameraDevice.close(); 
     mCameraDevice = null; 
    } 
    if(mMediaRecorder != null) { 
     mMediaRecorder.release(); 
     mMediaRecorder = null; 
    } 
} 

private void startBackgroundThread() { 
    mBackgroundHandlerThread = new HandlerThread("CameraImage"); 
    mBackgroundHandlerThread.start(); 
    mBackgroundHandler = new Handler(mBackgroundHandlerThread.getLooper()); 
} 

private void stopBackgroundThread() { 
    mBackgroundHandlerThread.quitSafely(); 
    try { 
     mBackgroundHandlerThread.join(); 
     mBackgroundHandlerThread = null; 
     mBackgroundHandler = null; 
    } catch (InterruptedException e) { 
     e.printStackTrace(); 
    } 
} 

private static int sensorToDeviceRotation(CameraCharacteristics cameraCharacteristics, int deviceOrientation) { 
    int sensorOrienatation = cameraCharacteristics.get(CameraCharacteristics.SENSOR_ORIENTATION); 
    deviceOrientation = ORIENTATIONS.get(deviceOrientation); 
    return (sensorOrienatation + deviceOrientation + 360) % 360; 
} 

private static Size chooseOptimalSize(Size[] choices, int width, int height) { 
    List<Size> bigEnough = new ArrayList<Size>(); 
    for(Size option : choices) { 
     if(option.getHeight() == option.getWidth() * height/width && 
       option.getWidth() >= width && option.getHeight() >= height) { 
      bigEnough.add(option); 
     } 
    } 
    if(bigEnough.size() > 0) { 
     return Collections.min(bigEnough, new CompareSizeByArea()); 
    } else { 
     return choices[0]; 
    } 
} 



private void createImageFolder() { 
    File imageFile = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES); 
    mImageFolder = new File(imageFile, "camera2VideoImage"); 
    if(!mImageFolder.exists()) { 
     mImageFolder.mkdirs(); 
    } 
} 

private File createImageFileName() throws IOException { 
    String timestamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()); 
    String prepend = "IMAGE_" + timestamp + "_"; 
    File imageFile = File.createTempFile(prepend, ".jpg", mImageFolder); 
    mImageFileName = imageFile.getAbsolutePath(); 
    return imageFile; 
} 


private void captureStillImage() { 
    try { 
     CaptureRequest.Builder captureStillBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE); 
     captureStillBuilder.addTarget(mImageReader.getSurface()); 

     int rotation = getWindowManager().getDefaultDisplay().getRotation(); 
     captureStillBuilder.set(CaptureRequest.JPEG_ORIENTATION, 
       ORIENTATIONS.get(rotation)); 

     CameraCaptureSession.CaptureCallback captureCallback = 
       new CameraCaptureSession.CaptureCallback() { 
        @Override 
        public void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request, TotalCaptureResult result) { 
         super.onCaptureCompleted(session, request, result); 

         Toast.makeText(getApplicationContext(), 
           "Image Captured!", Toast.LENGTH_SHORT).show(); 
         unLockFocus(); 
        } 
       }; 

     mCameraCaptureSession.capture(
       captureStillBuilder.build(), captureCallback, null 
     ); 

    } catch (CameraAccessException e) { 
     e.printStackTrace(); 
    } 
} 

private void takePicture() { 
    lockFocus(); 
} 


private void lockFocus() { 
    try { 

     mPreviewCaptureRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER, 
       CaptureRequest.CONTROL_AF_TRIGGER_START); 
     mState = STATE_WAIT_LOCK; 
     mCameraCaptureSession.capture(mPreviewCaptureRequestBuilder.build(), 
       mSessionCaptureCallback, mBackgroundHandler); 
    } catch (CameraAccessException e) { 
     e.printStackTrace(); 
    } 
} 

private void unLockFocus() { 
    try { 
     mState = STATE_PREVIEW; 
     mPreviewCaptureRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER, 
       CaptureRequest.CONTROL_AF_TRIGGER_CANCEL); 
     mCameraCaptureSession.capture(mPreviewCaptureRequestBuilder.build(), 
       mSessionCaptureCallback, mBackgroundHandler); 
    } catch (CameraAccessException e) { 
     e.printStackTrace(); 
    } 
} 

трассировки стека:

05-29 13: 23: 15.601 511-511/com.example.pc.snadfinal E/AndroidRuntime: FATAL> EXCEPTION: main Процесс:> com.example.pc.snadfinal, PID: 511 Тема:> темы: {}

java.lang.NullPointerException: Попытка вызвать виртуальный метод 'аннулируются android.hardware.camera2.CaptureRequest $ Builder.set (android.hardware.camera2.CaptureRequest $ Key, java.lang.Object)' на нулевой ссылке объекта на com.example.pc.snadfinal.CameraActivity.lockFocus (CameraActivity.java:548) на com.example.pc.snadfinal.CameraActivity.takePicture (CameraActivity.java:541) at com.example .pc.snadfinal .CameraActivity.access $ 1100 (CameraActivity.java:48) на com.example.pc.snadfinal.CameraActivity $ 6.onClick (CameraActivity.java:259) на android.view.View.performClick (View.java:5204) на android.view.View $ PerformClick.run (View.java:21158) на android.os.Handler.handleCallback (Handler.java:739) на android.os.Handler.dispatchMessage (Handler.java:95) на android.os.Looper.loop (Looper.java:148) на android.app.ActivityThread.main (ActivityThread.java:5461) на java.lang.reflect.Method.invoke (собственный метод) at com. android.internal.os.ZygoteInit $ Мет odAndArgsCaller.run (ZygoteInit.java:726) в com.android.internal.os.ZygoteInit.main (ZygoteInit.java:616)

Я думаю, что ошибка вызвана чем-то в методе lockFocus() или takePicture(), и я не знаю, что.

Я добавил это к lockFocus() и unlockFocus() mPreviewCaptureRequestBuilder = mCameraDevice.createCaptureRequest (CameraDevice.TEMPLATE_STILL_CAPTURE);

и теперь она дает мне эту StackTrace:

java.lang.NullPointerException: попытка вызвать виртуальный метод «INT android.hardware.camera2.CameraCaptureSession.capture (android.hardware.camera2.CaptureRequest, Android .hardware.camera2.CameraCaptureSession $ CaptureCallback, android.os.Handler) 'на нулевой ссылке объекта на com.example.pc.snadfinal.CameraActivity.lockFocus (CameraActivity.java:548) на com.example.pc.snadfinal .CameraActivity.takePicture (CameraActivity.java:538) at com.example.pc.snadfinal.CameraActivity.access $ 1000 (CameraActivity.java: 48) at com.example.pc.snadfinal.CameraActivity $ 6.onClick (CameraActivity.java:256) на android.view.View.performClick (View.java:5204) на android.view.View $ PerformClick .run (View.java:21158) на android.os.Handler.handleCallback (Handler.java:739) на android.os.Handler.dispatchMessage (Handler.java:95) на android.os.Looper.loop (Looper.java:148) на android.app.ActivityThread.main (ActivityThread.java:5461) на java.lang.reflect.Method.invoke (собственный метод) на com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run (ZygoteInit.jav а: 726) на com.android.internal.os.ZygoteInit.main (ZygoteInit.java:616)

+0

Не могли бы вы также добавить трассировку стека? – Sulthan

+0

Пожалуйста, отредактируйте ваш вопрос, не добавляйте информацию к комментариям. – Sulthan

+0

Sulthan Я начинаю, как можно его восстановить? –

ответ

0

Я просто решил такую ​​же проблему. Это связано с тем, что камера не готова к захвату изображения. Просто поддерживайте короткий интервал (достаточно 1 сек) между start() и takePicture().

Это работает для меня, надеюсь, что это поможет ... :-)

+1

Привет @Neo у меня такая же проблема, вы используете новый Handler.postDelayed в takePicture()? – Ashky

0

После некоторого испытания и @Neo ответа я решил установить щелчок слушатель takePictureButton после предварительного просмотра камеры составляет

Смежные вопросы