2

I can't seem to figure out what I am doing wrong here. Can anyone please help? I have altered the code a few times but unless I completely remove the OnResume, which I need, the code always terminates the program.

Code:

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


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

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

        @Override
        public void onError( 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 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 setupCamera(int width, int height) {
        CameraManager cameraManager = (CameraManager) getActivity().getSystemService(Context.CAMERA_SERVICE);
        try {
            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 void startBackgroundThread() {
        mBackgroundHandlerThread = new HandlerThread("Camera Background");
        mBackgroundHandlerThread.start();
        mBackgroundHandler = new Handler(mBackgroundHandlerThread.getLooper());

    }

    private void startPreview() {
        SurfaceTexture surfaceTexture = textureView.getSurfaceTexture();
        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];
        }
    }
}

Terminal:

01-30 16:04:10.295 23701-23701/com.example.patrick.wz E/AndroidRuntime: FATAL EXCEPTION: main Process: com.example.patrick.wz, PID: 23701 java.lang.NullPointerException: Attempt to invoke virtual method 'void android.view.TextureView.setSurfaceTextureListener(android.view.TextureView$SurfaceTextureListener)' on a null object reference at com.example.patrick.wz.Fragments.CameraFragment.onResume(CameraFragment.java:124) at android.support.v4.app.Fragment.performResume(Fragment.java:2401) at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1465) at android.support.v4.app.FragmentManagerImpl.performPendingDeferredStart(FragmentManager.java:1228) at android.support.v4.app.FragmentManagerImpl.startPendingDeferredFragments(FragmentManager.java:1845) at android.support.v4.app.FragmentManagerImpl.doPendingDeferredStart(FragmentManager.java:2689) at android.support.v4.app.FragmentManagerImpl.execSingleAction(FragmentManager.java:2205) at android.support.v4.app.BackStackRecord.commitNowAllowingStateLoss(BackStackRecord.java:651) at android.support.v4.app.FragmentPagerAdapter.finishUpdate(FragmentPagerAdapter.java:145) at android.support.v4.view.ViewPager.populate(ViewPager.java:1236) at android.support.v4.view.ViewPager.populate(ViewPager.java:1084) at android.support.v4.view.ViewPager.onMeasure(ViewPager.java:1614) at android.view.View.measure(View.java:21045) at android.support.constraint.ConstraintLayout.internalMeasureChildren(ConstraintLayout.java:934) at android.support.constraint.ConstraintLayout.onMeasure(ConstraintLayout.java:973) at android.view.View.measure(View.java:21045) at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6459) at android.widget.FrameLayout.onMeasure(FrameLayout.java:185) at android.support.v7.widget.ContentFrameLayout.onMeasure(ContentFrameLayout.java:139) at android.view.View.measure(View.java:21045) at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6459) at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1464) at android.widget.LinearLayout.measureVertical(LinearLayout.java:758) at android.widget.LinearLayout.onMeasure(LinearLayout.java:640) at android.view.View.measure(View.java:21045) at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6459) at android.widget.FrameLayout.onMeasure(FrameLayout.java:185) at android.view.View.measure(View.java:21045) at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6459) at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1464) at android.widget.LinearLayout.measureVertical(LinearLayout.java:758) at android.widget.LinearLayout.onMeasure(LinearLayout.java:640) at android.view.View.measure(View.java:21045) at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6459) at android.widget.FrameLayout.onMeasure(FrameLayout.java:185) at com.android.internal.policy.DecorView.onMeasure(DecorView.java:849) at android.view.View.measure(View.java:21045) at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:2576) at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1635) at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1886) at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1515) at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:7091) at android.view.Choreographer$CallbackRecord.run(Choreographer.java:927) at android.view.Choreographer.doCallbacks(Choreographer.java:702) at android.view.Choreographer.doFrame(Choreographer.java:638) at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:913) at android.os.Handler.handleCallback(Handler.java:751) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:154) at android.app.ActivityThread.main(ActivityThread.java:6682) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1520) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1410)

TofferJ
  • 4,678
  • 1
  • 37
  • 49
PadN
  • 41
  • 1
  • 5

1 Answers1

4

onResume method

textureView doesn't seem to be initialized, you have to do something like this

textureView = new TextureView(this);

if (textureView.isAvailable()) {
            setupCamera(textureView.getWidth(), textureView.getHeight());
            connectCamera();
        } else {
            textureView.setSurfaceTextureListener(surfaceTextureListener);
        }
lib4backer
  • 3,337
  • 3
  • 18
  • 16