Skip to content

Instantly share code, notes, and snippets.

@jbendtsen
Last active January 23, 2021 11:56
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jbendtsen/a1c7fca87444621cb065fcb94a89d820 to your computer and use it in GitHub Desktop.
Save jbendtsen/a1c7fca87444621cb065fcb94a89d820 to your computer and use it in GitHub Desktop.
// Very simple preview-only Camera2 example.
import android.view.*;
import android.hardware.camera2.*;
import android.os.*;
import android.content.*;
import android.content.pm.*;
import java.util.Arrays;
import android.util.Range;
public class Preview extends CameraDevice.StateCallback {
Context ctx;
SurfaceView sv;
SurfaceHolder holder;
HandlerThread thread;
Handler handler;
CameraDevice device;
SessionCallback session_callback;
CameraCaptureSession session;
CaptureRequest.Builder builder;
Range refresh_range;
public Preview(Context ctx, SurfaceView sv) {
this.ctx = ctx;
this.sv = sv;
this.thread = null;
this.handler = null;
this.session_callback = new SessionCallback();
this.holder = sv.getHolder();
}
// Call inside your activity's onResume()
public void start_camera_thread() {
if (this.thread != null && this.handler != null)
return;
thread = new HandlerThread("Camera Background");
thread.start();
handler = new Handler(thread.getLooper());
}
// Call inside your activity's onPause()
public void stop_camera_thread() {
if (thread != null) {
thread.quitSafely();
try {
thread.join();
}
catch (InterruptedException ex) {
// Add error handling here
}
}
thread = null;
handler = null;
}
class SessionCallback extends CameraCaptureSession.StateCallback {
@Override
public void onConfigured(CameraCaptureSession ccs) {
if (device == null)
return;
session = ccs;
try {
update_preview();
}
catch (CameraAccessException ex) {
throw new RuntimeException(ex);
}
}
public void onConfigureFailed(CameraCaptureSession ccs) {
// Add error handling here
}
}
// from CameraDevice.StateCallback
@Override
public void onOpened(CameraDevice camera) {
device = camera;
try {
create_camera_preview();
}
catch (CameraAccessException ex) {
throw new RuntimeException(ex);
}
}
@Override
public void onDisconnected(CameraDevice camera) {
device.close();
}
@Override
public void onError(CameraDevice camera, int error) {
device.close();
device = null;
}
void create_camera_preview() throws CameraAccessException {
builder = device.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
var surface = holder.getSurface();
builder.addTarget(surface);
device.createCaptureSession(Arrays.asList(surface), this.session_callback, null);
}
void open_camera() throws CameraAccessException {
var manager = (CameraManager)ctx.getSystemService(Context.CAMERA_SERVICE);
var id = manager.getCameraIdList()[0];
var character = manager.getCameraCharacteristics(id);
// Get the list of acceptable frame rate ranges
Range<Integer>[] refresh_ranges = character.get(CameraCharacteristics.CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES);
// This is where you may want to not be lazy and actually find an appropriate range
this.refresh_range = refresh_ranges[0];
manager.openCamera(id, this, null);
}
void update_preview() throws CameraAccessException {
// Turn on automatic controls
builder.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO);
// Turn on automatic exposure
builder.set(CaptureRequest.CONTROL_AE_MODE, CameraMetadata.CONTROL_AE_MODE_ON);
// Set frame rate, and therefore shutter speed. Shutter speed affects brightness by increasing exposure time.
builder.set(CaptureRequest.CONTROL_AE_TARGET_FPS_RANGE, this.refresh_range);
session.setRepeatingRequest(builder.build(), null, handler);
}
void close_camera() {
if (device != null) {
device.close();
device = null;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment