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)