2016-02-29 3 views
-1

Я работаю с Camera2API есть мой кодПочему возникает ошибку IllegalArgumentException (Camera2API)

public class MainActivity extends AppCompatActivity { 

private static Context context; 
private CameraManager mCameraManager = null; 
public static final String LOG_TAG = "mistake"; 
private final int CAMERA1 = 0; 
private final int CAMERA2 = 1; 
private CameraHelper[] myCameras = null; 
private Button mButtonOpenCamera1 = null; 
private Button mButtonOpenCamera2 = null; 
private TextureView mImageView = null; 

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

    context = this; 

    //получаем обьект камера менеджер 
    mCameraManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE); 
    mImageView = (TextureView) findViewById(R.id.image_view); 

    // Получения списка камер в устрйстве 
    String[] cameraList = new String[0]; 
    try { 
     cameraList = mCameraManager.getCameraIdList(); 
    } catch (CameraAccessException e) { 
     e.printStackTrace(); 
    } 

    //нужно обязательно не забыть инициализировать массив 
    myCameras = new CameraHelper[cameraList.length]; 

    for (String cameraID : cameraList) { 
     System.out.println("cameraID: " + cameraID); 
     int id = Integer.parseInt(cameraID); 

     // создаем обработчик для камеры 
     myCameras[id] = new CameraHelper(mCameraManager, cameraID, getApplicationContext()); 

     // выводим инормацию по камере 
     myCameras[id].viewFormatSize(ImageFormat.YUV_420_888); 

     // устанавливаем текстуру для отображения 
     myCameras[id].setTextureView(mImageView); 
    } 

    mButtonOpenCamera1 = (Button) findViewById(R.id.btn_open_camera1); 
    mButtonOpenCamera2 = (Button) findViewById(R.id.btn_open_camera2); 

    mButtonOpenCamera1.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      if (myCameras[CAMERA2].isOpen()) myCameras[CAMERA2].closeCamera(); 
      if (myCameras[CAMERA1] != null) { 
       if (!myCameras[CAMERA1].isOpen()) myCameras[CAMERA1].openCamera(); 
      } 
     } 
    }); 

    mButtonOpenCamera2.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      if (myCameras[CAMERA1].isOpen()) myCameras[CAMERA1].closeCamera(); 
      if (myCameras[CAMERA2] != null) { 
       if (!myCameras[CAMERA2].isOpen()) myCameras[CAMERA2].openCamera(); 
      } 
     } 
    }); 
} 

public static void ToastPrint(String cameraId) { 
    Toast.makeText(context, "Open camera with id: " + cameraId, Toast.LENGTH_LONG).show(); 
} 
} 

theri является вспомогательным класс

public class CameraHelper { 
private CameraCaptureSession mSession = null; 
private CameraManager mCameraManager = null; 
private CameraDevice mCameraDevice = null; 
private String mCameraID = null; 
private Context context; 
private TextureView mTextureView; 
private ImageReader imageReader; 
private Handler handler; 
private Surface jpegCaptureSurface; 
private static ByteArrayOutputStream outputStream; 


public CameraHelper(@NonNull CameraManager cameraManager, @NonNull String cameraID, Context context) { 
    mCameraManager = cameraManager; 
    mCameraID = cameraID; 
    this.context = context; 

    //нужно разобраться с этой строчкой, она 650 в коде 
    handler = new Handler(); 
} 

public static ByteArrayOutputStream getOutputStream() { 
    return outputStream; 
} 

public void viewFormatSize(int formatSize) { 

//  Получения характеристик камеры, Для получения характеристик необходимо 
//  использовать метод getCameraCharacteristics(String cameraId). Этот метод возвращает объект 
//  класса CameraCharacteristics, в котором сконцентрированы параметры по камере. В данном классе 
//  сконцентрировано огромное количество параметров 
    CameraCharacteristics cc; 
    try { 
     cc = mCameraManager.getCameraCharacteristics(mCameraID); 

     // Получения списка выходного формата, который поддерживает камера 
     StreamConfigurationMap configurationMap = 
        cc.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP); 

     // Получения списка разрешений которые поддерживаются для формата jpeg 
     Size[] sizesJPEG = new Size[0]; 
     if (configurationMap != null) { 
      sizesJPEG = configurationMap.getOutputSizes(ImageFormat.JPEG); 
     } 

     if (sizesJPEG != null) { 
      for (Size item : sizesJPEG) { 
       System.out.println("w:" + item.getWidth() + " h:" + item.getHeight()); 
      } 
     } else { 
      Log.e(MainActivity.LOG_TAG, "camera with id: " + mCameraID + " don`t support format: " + 
        formatSize); 
     } 

    } catch (CameraAccessException e) { 
     Log.e(MainActivity.LOG_TAG, e.getMessage()); 
    } 
} 

public boolean isOpen() { 
    return mCameraDevice != null; 
} 


// В методе openCamera() с помощью нашего менеджера открываем камеры. В параметрах метода 
// указываем, какую камеру открывать, а также обработчик, который будет отслеживать состояния 
// открытия камеры. 
public void openCamera() { 
    try { 
//   я так понимаю что здесь мы проверяем прописан ли у нас доступ к камере в манифесте и 
//   если все в порядке то выполняется открытие камеры 
     if (ActivityCompat.checkSelfPermission(context, Manifest.permission.CAMERA) != 
       PackageManager.PERMISSION_GRANTED) { 
      return; 
     } 

     mCameraManager.openCamera(mCameraID, mCameraCallback, null); 

    } catch (CameraAccessException e) { 
     Log.e(MainActivity.LOG_TAG, e.getMessage()); 
    } 
} 

public void closeCamera() { 

    if (mCameraDevice != null) { 
     mCameraDevice.close(); 
     mCameraDevice = null; 
    } 
} 

private CameraDevice.StateCallback mCameraCallback = new CameraDevice.StateCallback() { 

    @Override 
    public void onOpened(@NonNull CameraDevice camera) { 
     mCameraDevice = camera; 
     createCameraPreviewSession(); 
     System.out.println("----------" + mCameraDevice.getId()); 
     MainActivity.ToastPrint(mCameraDevice.getId()); 
    } 

    @Override 
    public void onDisconnected(@NonNull CameraDevice camera) { 
     mCameraDevice.close(); 
     Log.i(MainActivity.LOG_TAG, "disconnect camera with id:" + mCameraDevice.getId()); 
     mCameraDevice = null; 
    } 

    @Override 
    public void onError(@NonNull CameraDevice camera, int error) { 
     Log.i(MainActivity.LOG_TAG, "error! camera id:" + camera.getId() + " error:" + error); 
    } 
}; 

private void createCameraPreviewSession() { 

//  для получения изображения нам необходимо использовать ImageReader. Для получения 
//  максимально возможной скорости передачи кадров нам необходимо использовать «сырой формат». То 
//  есть, jpeg нам не подойдет, поскольку он будет давать задержку на время конвертации кадра и 
//  таким образом у нас возникнет очень низкий fps. Для получения максимальной продуктивности 
//  следует использовать ImageFormat.YUV_420_888. 
    imageReader = ImageReader.newInstance(640, 480, ImageFormat.JPEG, 2); 
    imageReader.setOnImageAvailableListener(onImageAvailableListener, handler); 

    //эти 2 строчки пока не понятно зачем нужны 
    SurfaceTexture texture = mTextureView.getSurfaceTexture(); 
    texture.setDefaultBufferSize(640, 480); 

    try { 
     final CaptureRequest.Builder builder = 
       mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW); 

     builder.addTarget(jpegCaptu                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  reSurface); 
//   builder.addTarget(surface); 

     //это добавление возможных эффектов 
//   builder.set(CaptureRequest.CONTROL_AWB_MODE, CaptureRequest.CONTROL_AWB_MODE_INCANDESCENT); 
//   builder.set(CaptureRequest.CONTROL_EFFECT_MODE, CaptureRequest.CONTROL_EFFECT_MODE_SEPIA); 
//   builder.set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_SINGLE); 

     mCameraDevice.createCaptureSession(
       Collections.singletonList(imageReader.getSurface()), 
//     Collections.singletonList(surface), 
       new CameraCaptureSession.StateCallback() { 

        @Override 
        public void onConfigured(@NonNull CameraCaptureSession session) { 
         mSession = session; 
         try { 
          mSession.setRepeatingRequest(builder.build(), null, null); 
         } catch (CameraAccessException e) { 
          e.printStackTrace(); 
         } 
        } 

        @Override 
        public void onConfigureFailed(@NonNull CameraCaptureSession session) { 
        } 
       }, 
       null 
     ); 


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


private final ImageReader.OnImageAvailableListener onImageAvailableListener = 
     new ImageReader.OnImageAvailableListener() { 
      @Override 
      public void onImageAvailable(ImageReader reader) { 
       final Image image = reader.acquireLatestImage(); 

       jpegCaptureSurface = reader.getSurface(); 

       handler.post(new ImageSaver(context)); 
      } 
     }; 

private static class ImageSaver implements Runnable { 
    private BufferedOutputStream bos; 
    private Context context; 

    public ImageSaver(Context context) { 
     this.context = context; 
    } 

    @Override 
    public void run() { 

     final File pictureFile = getOutputMediaFile(); 
     if (pictureFile == null) { 
      return; 
     } 
     try { 
      bos = new BufferedOutputStream(
        new FileOutputStream(pictureFile)); 
      bos.write(convertOutputToByteArray(getOutputStream())); 
      bos.flush(); 

      Toast.makeText(context, "Picture saved: " + pictureFile.getName(), 
        Toast.LENGTH_SHORT).show(); 

     } catch (IOException e) { 
      e.printStackTrace(); 
     } finally { 
      try { 
       bos.close(); 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
     } 

    } 

    private byte[] convertOutputToByteArray(ByteArrayOutputStream stream) { 
     return stream.toByteArray(); 
    } 

    private static File getOutputMediaFile() { 
     File mediaStorageDir = new File("/sdcard/", "JCG Camera"); 

     if (!mediaStorageDir.exists()) { 
      if (!mediaStorageDir.mkdirs()) { 
       return null; 
      } 
     } 

     String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()); 
     File mediaFile = new File(mediaStorageDir.getPath() + File.separator + "IMG_" + 
       timeStamp + ".png"); 

     return mediaFile; 
    } 
} 

public void setTextureView(TextureView mImageView) { 
    mTextureView = mImageView; 
} 

есть ссылка мой github:

https://goo.gl/3yaTKo 

, когда я начинаю метод openCamera() который в CameraHelper классе, я вижу ошибку

java.lang.IllegalArgumentException: Null Surface targets are not allowed 
at android.hardware.camera2.impl.CameraDeviceImpl.submitCaptureRequest(CameraDeviceImpl.java:602) 
at android.hardware.camera2.impl.CameraDeviceImpl.setRepeatingRequest(CameraDeviceImpl.java:663) 
at android.hardware.camera2.impl.CameraCaptureSessionImpl.setRepeatingRequest(CameraCaptureSessionImpl.java:204) 
at  com.example.aleksey.camera2api.CameraHelper$2.onConfigured(CameraHelper.java:185) 
at java.lang.reflect.Method.invoke(Native Method) 
at java.lang.reflect.Method.invoke(Method.java:372) 

почему это происходит не так?

+2

потому что 'Null Surface target недопустимы' – njzk2

+0

да, я умею читать. Но что это значит? будет лучше, если вы попробуете помочь мне решить эту проблему ... –

+0

[строка 168] (https://github.com/alekseytimoshchenko/Camera2API/blob/master/app/src/main/java/com/example/aleksey/ camera2api/CameraHelper.java # L168) сломан –

ответ

0

Похоже, вы закомментировал строку, которая устанавливает поверхность в вашем строитель:

//   builder.addTarget(surface); 

Кроме того, убедитесь, что вы ждете, пока поверхность не будет готова до вызова все, что от него зависит.

+0

прокомментированная строка - это не случай ... я думаю, что поверхность не готова, прежде чем я ее вызову ... Можете ли вы попробовать меня решить? –

+0

Если поверхность не готова при подготовке запроса, вы не должны комментировать вызов 'addTarget()', но задерживаете эту подготовку. [Doc] (http://developer.android.com/reference/android/hardware/camera2/CaptureRequest.Builder.html#addTarget (android.view.Surface)) явно говорит, что ** поверхность ** для 'addTarget() 'должен быть включен в' createCaptureSession() ', то есть в вашем случае ** imageReader.getSurface() **. –

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