In API 21, the original camera API was deprecated in favor of the new CAMERA2 API, which is a big move because the new API has changed the architecture, making it harder for developers to use.
Let's take a look at the CAMERA2 package architecture:
This refers to the concept of piping that connects the Android device to the camera, and the system sends the capture request to the camera, and the camera returns to Camerametadata. It's all based on a conversation called Cameracapturesession.
The following are the main classes in the CAMERA2 package:
One of the Cameramanager is the manager who is standing high in charge of all the camera equipment (cameradevice), and each cameradevice himself is responsible for establishing cameracapturesession and establishing capturerequest. Cameracharacteristics is the attribute description class of Cameradevice, so it is similar to the original Camerainfo if we want to make a comparison.
There are three important callback in the class diagram, although this increases the difficulty of reading the code, but you have to get used to it because it is the style of the new package. Where Cameracapturesession.capturecallback will work on previewing and taking pictures, it needs to be treated with emphasis.
How do these classes fit into each other? The following is a simple flowchart.
I use Surfaceview as the Display object (of course, can also be textureview to display, see the project in the reference)
The core code is as follows:
this.getSystemService(Context.CAMERA_SERVICE); mSurfaceView = (SurfaceView)findViewById(R.id.surfaceview); mSurfaceHolder = mSurfaceView.getHolder(); mSurfaceHolder.addCallback(new SurfaceHolder.Callback() { @Override publicvoidsurfaceCreated(SurfaceHolder holder) { initCameraAndPreview(); } });
private void Initcameraandpreview () {Log. D("Linc","Init camera and preview");Handlerthread handlerthread = new Handlerthread ("Camera2");Handlerthread. Start();Mhandler = new Handler (handlerthread. Getlooper());try {mcameraid =""+cameracharacteristics. LENS_facing_front;Mimagereader = ImageReader. newinstance(Msurfaceview. GetWidth(), Msurfaceview. GetHeight(), ImageFormat. JPEG,/*maximages*/7);Mimagereader. Setonimageavailablelistener(Monimageavailablelistener, Mhandler);Mcameramanager. Opencamera(Mcameraid, Devicestatecallback, Mhandler);} catch (Cameraaccessexception e) {Log. E("Linc","Open camera failed."+ E. GetMessage());} }
privatenew CameraDevice.StateCallback() { @Override publicvoidonOpened(CameraDevice camera) { Log.d("linc","DeviceStateCallback:camera was opend."); mCameraOpenCloseLock.release(); mCameraDevice = camera; try { createCameraCaptureSession(); catch (CameraAccessException e) { e.printStackTrace(); } } };
private void Createcameracapturesession () throws Cameraaccessexception {Log. D("Linc","Createcameracapturesession");Mpreviewbuilder = Mcameradevice. Createcapturerequest(Cameradevice. TEMPLATE_preview);Mpreviewbuilder. AddTarget(Msurfaceholder. Getsurface());Mstate = State_preview;Mcameradevice. Createcapturesession(Arrays. Aslist(Msurfaceholder. Getsurface(), Mimagereader. Getsurface()), Msessionpreviewstatecallback, Mhandler);}
Private Cameracapturesession. StatecallbackMsessionpreviewstatecallback = new Cameracapturesession. Statecallback() {@Override public void onconfigured (cameracapturesession session) {Log. D("Linc","Msessionpreviewstatecallback onconfigured");Msession = Session;try {Mpreviewbuilder. Set(Capturerequest. CONTROL_af_mode, Capturerequest. CONTROL_af_mode_continuous_picture);Mpreviewbuilder. Set(Capturerequest. CONTROL_ae_mode, Capturerequest. CONTROL_ae_mode_on_auto_flash);Session. Setrepeatingrequest(Mpreviewbuilder. Build(), Msessioncapturecallback, Mhandler);} catch (Cameraaccessexception e) {E. Printstacktrace();Log. E("Linc","Set preview builder failed."+e. GetMessage());} } };
PrivateCameracapturesession.capturecallback Msessioncapturecallback =NewCameracapturesession.capturecallback () {@Override Public void oncapturecompleted(cameracapturesession session, Capturerequest request, totalcaptureresult result) {//LOG.D ("Linc", "Msessioncapturecallback, oncapturecompleted");Msession = session; CheckState (result); }@Override Public void oncaptureprogressed(cameracapturesession session, Capturerequest request, Captureresult Partialresult) {LOG.D ("Linc","Msessioncapturecallback, oncaptureprogressed"); Msession = session; CheckState (Partialresult); }Private void CheckState(Captureresult result) {Switch(mstate) { CaseState_preview:// Nothing Break; CaseState_waiting_capture:intAfstate = Result.get (captureresult.control_af_state);if(captureresult.control_af_state_focused_locked = = Afstate | | captureresult.control_af_state_not_focused_locked = = Afstate | | captureresult.control_af_state_passive_focused = = Afstate | | captureresult.control_af_state_passive_unfocused = = afstate) {//do something like save picture} Break; } } };
Press the Capture button:
publicvoidonCapture(View view) { try { Log.i("linc""take picture"); mState = STATE_WAITING_CAPTURE; mSession.setRepeatingRequest(mPreviewBuilder.build(), mSessionCaptureCallback, mHandler); catch (CameraAccessException e) { e.printStackTrace(); } }
Test with the Genemotion simulator, directly call the notebook camera.
The configuration diagram is as follows:
Demo interface such as:
Source:
Please refer to the two demo projects in GitHub:
Https://github.com/pinguo-yuyidong/Camera2
Https://github.com/googlesamples/android-Camera2Basic
Android 33: Android.hardware.camera2 User Guide