A bit of a background here, I came from Ionic so I'm still a noob when it comes to java and android studio.
So I followed this article in medium and I stumbled a lot with declaring global variables specifically...
Here's my code
public class MainActivity extends AppCompatActivity {
private static final int CAMERA_REQUEST_CODE = 10001;
int cameraFacing;
CameraManager cameraManager;
TextureView textureView;
Size previewSize;
String cameraId;
Handler mHandler ;
HandlerThread mHandlerThread ;
CameraDevice.StateCallback stateCallback;
CameraDevice cameraDevice;
CameraCaptureSession cameraCaptureSession;
CaptureRequest captureRequest;
CaptureRequest.Builder captureRequestBuilder;
TextureView.SurfaceTextureListener surfaceTextureListener;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, CAMERA_REQUEST_CODE);
cameraManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
cameraFacing = CameraCharacteristics.LENS_FACING_BACK;
textureView = findViewById(R.id.texture_view);
surfaceTextureListener = new TextureView.SurfaceTextureListener() {
@Override
public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int i, int i1) {
setUpCamera();
openCamera();
}
@Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surfaceTexture, int i, int i1) {
}
@Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surfaceTexture) {
return false;
}
@Override
public void onSurfaceTextureUpdated(SurfaceTexture surfaceTexture) {
}
};
stateCallback = new CameraDevice.StateCallback() {
@Override
public void onOpened(CameraDevice cameraDevice) {
MainActivity.this.cameraDevice = cameraDevice;
createPreviewSession();
}
@Override
public void onDisconnected(CameraDevice cameraDevice) {
cameraDevice.close();
MainActivity.this.cameraDevice = null;
}
@Override
public void onError(CameraDevice cameraDevice, int error) {
cameraDevice.close();
MainActivity.this.cameraDevice = null;
}
};
}
private void createPreviewSession() {
try {
SurfaceTexture surfaceTexture = textureView.getSurfaceTexture();
surfaceTexture.setDefaultBufferSize(previewSize.getWidth(), previewSize.getHeight());
Surface previewSurface = new Surface(surfaceTexture);
captureRequestBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
captureRequestBuilder.addTarget(previewSurface);
cameraDevice.createCaptureSession(Collections.singletonList(previewSurface),
new CameraCaptureSession.StateCallback() {
@Override
public void onConfigured(CameraCaptureSession cameraCaptureSession) {
if (cameraDevice == null) {
return;
}
try {
captureRequest = captureRequestBuilder.build();
MainActivity.this.cameraCaptureSession = cameraCaptureSession;
MainActivity.this.cameraCaptureSession.setRepeatingRequest(captureRequest,
null, mHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
@Override
public void onConfigureFailed(CameraCaptureSession cameraCaptureSession) {
}
}, mHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
@Override
protected void onResume() {
super.onResume();
openBackgroundThread();
if (textureView.isAvailable()) {
setUpCamera();
openCamera();
} else {
textureView.setSurfaceTextureListener(surfaceTextureListener);
}
}
@Override
protected void onStop() {
super.onStop();
closeCamera();
closeBackgroundThread();
}
private void closeCamera() {
if (cameraCaptureSession != null) {
cameraCaptureSession.close();
cameraCaptureSession = null;
}
if (cameraDevice != null) {
cameraDevice.close();
cameraDevice = null;
}
}
private void closeBackgroundThread() {
if (mHandler != null) {
mHandlerThread.quitSafely();
mHandler = null;
mHandlerThread = null;
}
}
private void setUpCamera(){
try{
for(String cameraId: cameraManager.getCameraIdList()) {
CameraCharacteristics cameraCharacteristics = cameraManager.getCameraCharacteristics(cameraId);
if(cameraCharacteristics.get(CameraCharacteristics.LENS_FACING) == cameraFacing){
StreamConfigurationMap streamConfigurationMap = cameraCharacteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
previewSize = streamConfigurationMap.getOutputSizes(SurfaceTexture.class)[0];
this.cameraId = cameraId;
}
}
} catch (CameraAccessException e){
e.printStackTrace();
}
}
private void openCamera(){
try{
if(ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED){
cameraManager.openCamera(cameraId, stateCallback, mHandler );
}
} catch (CameraAccessException e){
e.printStackTrace();
}
}
private void openBackgroundThread(){
mHandlerThread = new HandlerThread("camera_background_thread");
mHandlerThread.start();
mHandler = new Handler(mHandler .getLooper());
}
}
And here's the error I got from the Logcat
10-24 18:47:10.269 5694-5694/adprog.reese.com.adprog E/AndroidRuntime: FATAL EXCEPTION: main
Process: adprog.reese.com.adprog, PID: 5694
java.lang.RuntimeException: Unable to resume activity {adprog.reese.com.adprog/adprog.reese.com.adprog.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'android.os.Looper android.os.Handler.getLooper()' on a null object reference
at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3031)
at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3062)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2396)
at android.app.ActivityThread.access$800(ActivityThread.java:151)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1309)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5354)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:908)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:703)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.os.Looper android.os.Handler.getLooper()' on a null object reference
at adprog.reese.com.adprog.MainActivity.openBackgroundThread(MainActivity.java:200)
at adprog.reese.com.adprog.MainActivity.onResume(MainActivity.java:139)
at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1241)
at android.app.Activity.performResume(Activity.java:6107)
at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3020)
at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3062)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2396)
at android.app.ActivityThread.access$800(ActivityThread.java:151)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1309)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5354)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:908)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:703)
And the problematic code
private void openBackgroundThread(){
mHandlerThread = new HandlerThread("camera_background_thread");
mHandlerThread.start();
mHandler = new Handler(mHandler.getLooper());
}
Any help would be greatly appreciated!
Maybe the line below is the issue...
mHandler = new Handler(mHandler .getLooper()); // this line
You might wanted this i suppose. Not sure but try it....
mHandler = new Handler(mHandlerThread.getLooper());