cameraId为null(camera2)

时间:2018-01-31 11:40:36

标签: java android

所以我是编码和使用相机的新手。我不明白为什么cameraIdnull。如果有人可以帮助我,真的很感激。谢谢

代码:

public class CameraFragment extends Fragment {

    private TextureView textureView;
    private HandlerThread mBackgroundHandlerThread;
    private Handler mBackgroundHandler;

    private String mCameraId;

    private Size mPreviewSize;


    public static CameraFragment newInstance() {

        return new CameraFragment();
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

        View rootView = inflater.inflate(R.layout. fragment_camera, container, false);
        textureView = (TextureView) rootView.findViewById(R.id.textureView);

        return rootView;
    }



    private static final int REQUEST_CAMERA_PERMISSION_RESULT = 0;


     private TextureView.SurfaceTextureListener surfaceTextureListener = 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(@NonNull CameraDevice camera) {
            mCameraDevice = camera;
            startPreview();
            //Toast.makeText(getApplicationContext(), "Camera connected!", Toast.LENGTH_LONG).show();
        }

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

        @Override
        public void onError(@NonNull CameraDevice camera, int error) {
            camera.close();
            mCameraDevice = null;
        }
    };

    @Override
    public void onResume() {

        super.onResume();

        startBackgroundThread();

        if (textureView.isAvailable()) {
            //setupCamera(textureView.getWidth(), textureView.getHeight());
            connectCamera();
        } else {
            textureView.setSurfaceTextureListener(surfaceTextureListener);
        }
    }

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

        stopBackgroundThread();

        super.onPause();
    }

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

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


    private  void setupCamera(int width, int height) {
        if(mCameraDevice == null)
            return;

        CameraManager cameraManager = (CameraManager) getActivity().getSystemService(Context.CAMERA_SERVICE);
        try {

            if (cameraManager != null) {
                mCameraId = cameraManager.getCameraIdList()[0];
            }
            assert cameraManager != null;
            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 = getActivity().getWindowManager().getDefaultDisplay().getRotation();
                int totalRotation = sensorToDeviceRotation(cameraCharacteristics, deviceOrientation);
                boolean swapRotation = totalRotation == 90 || totalRotation == 270;
                int rotatedWidth = width;
                int rotatedHeight = height;
                if (swapRotation){
                    rotatedWidth = height;
                    rotatedHeight = width;
                }
                if (map != null) {
                    mPreviewSize = chooseOptimalSize(map.getOutputSizes(SurfaceTexture.class), rotatedWidth, rotatedHeight);
                }
                mCameraId = cameraId;
                return;
            }


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


    private void connectCamera() {
        CameraManager cameraManager = (CameraManager) getActivity().getSystemService(Context.CAMERA_SERVICE);
        try {
            if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.M) {
                if (ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.CAMERA) ==
                        PackageManager.PERMISSION_GRANTED) {
                    assert cameraManager != null;
                    cameraManager.openCamera(mCameraId, mCameraDeviceStateCallback, mBackgroundHandler);
                } else {
                    if (shouldShowRequestPermissionRationale(Manifest.permission.CAMERA)) {
                        Toast.makeText(getActivity(), "This app requires access to camera", Toast.LENGTH_LONG).show();
                    }
                    requestPermissions(new String[]{Manifest.permission.CAMERA}, REQUEST_CAMERA_PERMISSION_RESULT);
                }
            } else {
                assert cameraManager != null;
                cameraManager.openCamera(mCameraId, mCameraDeviceStateCallback, mBackgroundHandler);
            }
        }catch(CameraAccessException e){
            e.printStackTrace();
        }
    }


    private CaptureRequest.Builder mCaptureRequestBuilder;

    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());
        }
    }


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



    public void  onWindowFocusChanged (boolean hasFocus) {
        super.getActivity().onWindowFocusChanged(hasFocus);
        View decorView = getActivity().getWindow().getDecorView();
        if(hasFocus){
            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 startBackgroundThread() {
        mBackgroundHandlerThread = new HandlerThread("Camera Background");
        mBackgroundHandlerThread.start();
        mBackgroundHandler = new Handler(mBackgroundHandlerThread.getLooper());

    }

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

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

            mCameraDevice.createCaptureSession(Collections.singletonList(previewSurface),
                    new CameraCaptureSession.StateCallback() {
                        @Override
                        public void onConfigured(@NonNull CameraCaptureSession session) {
                            try {
                                session.setRepeatingRequest(mCaptureRequestBuilder.build(),
                                        null, mBackgroundHandler);
                            } catch (CameraAccessException e){
                                e.printStackTrace();
                            }
                        }

                        @Override
                        public void onConfigureFailed(@NonNull CameraCaptureSession session) {
                            Toast.makeText(getActivity(), "Unable to connect to camera", Toast.LENGTH_LONG).show();
                        }
                    }, null);
        } catch (CameraAccessException e){
            e.printStackTrace();
        }
    }






    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, (Comparator<? super Size>) new CompareSizeByArea());
        } else {
            return choices[0];
        }
    }
}

日志:

> FATAL EXCEPTION: main

    Process: com.example.patrick.wz, PID: 5246
    java.lang.IllegalArgumentException: cameraId was null
        at android.hardware.camera2.CameraManager.openCameraForUid(CameraManager.java:454)
        at android.hardware.camera2.CameraManager.openCamera(CameraManager.java:430)
        at com.example.patrick.wz.Fragments.CameraFragment.connectCamera(CameraFragment.java:214)
        at com.example.patrick.wz.Fragments.CameraFragment.access$100(CameraFragment.java:40)
        at com.example.patrick.wz.Fragments.CameraFragment$1.onSurfaceTextureAvailable(CameraFragment.java:74)
        at android.view.TextureView.getHardwareLayer(TextureView.java:390)
        at android.view.TextureView.draw(TextureView.java:339)
        at android.view.View.updateDisplayListIfDirty(View.java:18069)
        at android.view.View.draw(View.java:18847)
        at android.view.ViewGroup.drawChild(ViewGroup.java:4214)
        at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4000)
        at android.view.View.updateDisplayListIfDirty(View.java:18060)
        at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4198)
        at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4178)
        at android.view.View.updateDisplayListIfDirty(View.java:18028)
        at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4198)
        at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4178)
        at android.view.View.updateDisplayListIfDirty(View.java:18028)
        at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4198)
        at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4178)
        at android.view.View.updateDisplayListIfDirty(View.java:18028)
        at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4198)
        at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4178)
        at android.view.View.updateDisplayListIfDirty(View.java:18028)
        at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4198)
        at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4178)
        at android.view.View.updateDisplayListIfDirty(View.java:18028)
        at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4198)
        at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4178)
        at android.view.View.updateDisplayListIfDirty(View.java:18028)
        at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4198)
        at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4178)
        at android.view.View.updateDisplayListIfDirty(View.java:18028)
        at android.view.ThreadedRenderer.updateRootDisplayList(ThreadedRenderer.java:659)
        at android.view.ThreadedRenderer.draw(ThreadedRenderer.java:757)
        at android.view.ViewRootImpl.draw(ViewRootImpl.java:2980)
        at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:2794)
        at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2347)
        at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1386)
        at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6733)
        at android.view.Choreographer$CallbackRecord.run(Choreographer.java:911)
        at android.view.Choreographer.doCallbacks(Choreographer.java:723)
        at android.view.Choreographer.doFrame(Choreographer.java:658)
        at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:897)
        at android.os.Handler.handleCallback(Handler.java:789)
        at android.os.Handler.dispatchMessage(Handler.java:98)

1 个答案:

答案 0 :(得分:0)

在onResume中,你已经注释掉了对setupCamera的调用,这就是mCameraId的设置。所以当你进入connectCamera时它仍然是空的。