1. Camera
The Android framework includes support for various
cameras and camera features available on devices,
allowing you to capture pictures and videos in your
applications.
The BASICS
The Android framework supports capturing images
and video through
the android.hardware.camera2 API or
camera Intent. Here are the relevant classes:
android.hardware.camera2
This package is the primary API for controlling
device cameras. It can be used to take pictures or
videos when you are building a camera application.
Camera
This class is the older deprecated API for
controlling device cameras.
SurfaceView
This class is used to present a live camera preview
to the user
MediaRecorder
This class is used to record video from the camera.
Intent
An intent action type
of MediaStore.ACTION_IMAGE_CAPTURE or Med
iaStore.ACTION_VIDEO_CAPTURE can be used
to capture images or videos without directly using
the Camera object.
Creating a new project
Open your Android Studio and create a new blank
activity application.
The first step is to add the android permissions and
required features.
Add these lines to your AndroidManifest.xml:
<uses-permission
android:name="android.permission.CAMERA" />
<uses-feature
android:name="android.hardware.camera" />
Inside your style.xml, just edit the line to remove
the ActionBar, if you prefer(this is removed just to
have a full-screen camera):
<style name="AppTheme"
parent="Theme.AppCompat.Light.NoActionBar">
Create this basic activity_main.xml:
<FrameLayout
xmlns:android="http://schemas.android.com/apk/re
s/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<FrameLayout
android:id="@+id/camera_view"
android:layout_width="match_parent"
android:layout_height="match_parent">
</FrameLayout>
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/imgClose"
android:layout_gravity="right|top"
android:background="@android:drawable/ic_menu
_close_clear_cancel"
android:padding="20dp"/>
</FrameLayout>
Here we have a simple FrameLayout.
The camera_view will display the camera data,
that we’ll use later with OpenGL and some
algorithms to process it.
And the ImageButton will be used to close the
application.
III - Camera code
The first step is to create a SurfaceView. It’ll
receive camera data and display it inside the
FrameLayout.
Create a new file, CameraView.java in the same
folder that your MainActivity.java is.
2. First, just extend the SurfaceView and implements
the SurfaceHolder.Callback.
You’ll have something like this code:
public class CameraView extends SurfaceView
implements SurfaceHolder.Callback{
public CameraView(Context context, Camera
camera){
super(context);
}
@Override
public void surfaceCreated(SurfaceHolder
surfaceHolder) {
}
@Override
public void surfaceChanged(SurfaceHolder
surfaceHolder, int i, int i2, int i3) {
}
@Override
public void surfaceDestroyed(SurfaceHolder
surfaceHolder) {
}
}
Add these two private variables:
private SurfaceHolder mHolder;
private Camera mCamera;
And then just update your CameraView constructor
with:
public CameraView(Context context, Camera
camera){
super(context);
mCamera = camera;
mCamera.setDisplayOrientation(90);
//get the holder and set this class as the callback,
so we can get camera data here
mHolder = getHolder();
mHolder.addCallback(this);
mHolder.setType(SurfaceHolder.SURFACE_TYPE
_NORMAL);
}
Now, override these methods, I commented
everything to help you:
@Override
public void surfaceCreated(SurfaceHolder
surfaceHolder) {
try{
//when the surface is created, we can set the
camera to draw images in this surfaceholder
mCamera.setPreviewDisplay(surfaceHolder);
mCamera.startPreview();
} catch (IOException e) {
Log.d("ERROR", "Camera error on
surfaceCreated " + e.getMessage());
}
}
@Override
public void surfaceChanged(SurfaceHolder
surfaceHolder, int i, int i2, int i3) {
//before changing the application orientation, you
need to stop the preview, rotate and then start it
again
if(mHolder.getSurface() == null)//check if the
surface is ready to receive camera data
return;
try{
mCamera.stopPreview();
} catch (Exception e){
//this will happen when you are trying the camera
if it's not running
}
//now, recreate the camera preview
try{
mCamera.setPreviewDisplay(mHolder);
mCamera.startPreview();
} catch (IOException e) {
Log.d("ERROR", "Camera error on
surfaceChanged " + e.getMessage());
}
}
@Override
public void surfaceDestroyed(SurfaceHolder
surfaceHolder) {
//our app has only one screen, so we'll destroy the
camera in the surface
//if you are unsing with more screens, please
move this code your activity
mCamera.stopPreview();
mCamera.release();
}
III - Camera Activity
Now, inside you MainActivity.java, add these
variables:
3. private Camera mCamera = null;
private CameraView mCameraView = null;
No, override the method bellow, I commented to
help you to understand it:
protected void onCreate(Bundle
savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
try{
mCamera = Camera.open();//you can use
open(int) to use different cameras
} catch (Exception e){
Log.d("ERROR", "Failed to get camera: " +
e.getMessage());
}
if(mCamera != null) {
mCameraView = new CameraView(this,
mCamera);//create a SurfaceView to show camera
data
FrameLayout camera_view =
(FrameLayout)findViewById(R.id.camera_view);
camera_view.addView(mCameraView);//add the
SurfaceView to the layout
}
//btn to close the application
ImageButton imgClose =
(ImageButton)findViewById(R.id.imgClose);
imgClose.setOnClickListener(new
View.OnClickListener() {
@Override
public void onClick(View view) {
System.exit(0);
}
});
}
Now, you can run your app.