-
-
Save jbendtsen/a1c7fca87444621cb065fcb94a89d820 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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