为什么会出现错误IllegalArgumentException(Camera2API)

时间:2016-02-29 20:52:55

标签: java android camera android-camera

我正在使用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)

为什么会出错?

1 个答案:

答案 0 :(得分:0)

您似乎注释掉了在构建器中设置曲面的线:

//            builder.addTarget(surface);

另外,在调用任何依赖它的东西之前,请确保等待表面准备就绪。