In this part, We will make our own camera something like above. We have two activities, main activity and camera activity. Once you click on start button in main activity, it will launch the Camera activity. Camera preview will be automatically started and you only need to click the Take button to capture the image. After taking the picture, when you click the OK button it will take you back to the main activity and currently taken Image will be shown in the Image View of Main activity.
First we will create Main Activity java class.
package media.manager;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.Activity;
import android.view.View;
import android.widget.ImageView;
import sub_activities.MyCameraActivity;
public class FunActivity extends Activity
{
private static final String TAG=FunActivity.class.getSimpleName();
public static final int CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE = 101;
private Uri imageUri=null;
ImageView imageView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
imageView = (ImageView)findViewById(R.id.imageView);
}
public void buttonCameraClick(View v){
Intent takePicture = new Intent();
takePicture.setClass(this,MyCameraActivity.class);
startActivityForResult(takePicture, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if(requestCode==CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE) {
imageUri = data.getData();
imageView.setImageURI(imageUri);
}
}
}
|
Next we will create a helper class which we will use inside the Picture activity class. This class contains all the events related to camera activities.
BackCameraController.java
package media.manager;
import android.content.Context;
import android.content.pm.PackageManager;
import android.hardware.Camera;
import android.util.Log;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import java.io.File;
import java.io.FileOutputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
public class BackCameraController {
private static final String TAG = BackCameraController.class.getSimpleName();
private boolean hasBackCamera;
public Camera getCamera() {
return camera;
}
public interface BackCameraControllerListener{
public void afterTakePicture(File pictureFile, boolean finish);
}
private Camera camera;
private Camera.CameraInfo info;
private BackCameraControllerListener cameraListener;
private int backCameraId;
private int rotation;
public BackCameraController(Context context, int rotation) {
try {
cameraListener=(BackCameraControllerListener)context;
} catch (ClassCastException e) {
throw new ClassCastException(context.toString()
+ " must implement BackCameraControllerListener");
}
if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)) {
backCameraId=getBackCameraId();
hasBackCamera = backCameraId != -1;
}
info = new Camera.CameraInfo();
this.rotation=rotation;
}
public boolean hasBackCamera() {
return hasBackCamera;
}
public void getBackCameraInstance(SurfaceView surfaceView) {
Log.i(TAG, "hasBackCamera 1: " + hasBackCamera());
camera = null;
if (hasBackCamera) {
try {
camera = Camera.open(backCameraId);
Log.i(TAG, "Camera is open");
SurfaceHolder surfaceHolder = surfaceView.getHolder();
camera.setPreviewDisplay(surfaceHolder);
setCameraDisplayOrientation(backCameraId);
camera.startPreview();
Log.i(TAG, "Start Preview");
Camera.Parameters params = camera.getParameters();
params.setJpegQuality(100);
camera.setParameters(params);
} catch (Exception e) {
hasBackCamera = false;
Log.i(TAG, "Before take picture \n"+e.toString());
}
}
}
public void takeBackPicture() {
Log.i(TAG, "hasBackCamera 2: " + hasBackCamera);
if (hasBackCamera) {
camera.takePicture(null, null, mBackPicture);
}
}
private Camera.PictureCallback mBackPicture = new Camera.PictureCallback() {
@Override
public void onPictureTaken(byte[] data, Camera camera) {
File pictureFile = getBackMediaFile();
if (pictureFile == null) {
Log.i(TAG, "Error creating media file, check storage permissions");
return;
}
try {
Log.d(TAG, "File created");
FileOutputStream fos = new FileOutputStream(pictureFile);
fos.write(data);
fos.close();
} catch (Exception e) {
Log.i(TAG, "File not found: " + e.getMessage());
}
cameraListener.afterTakePicture(pictureFile, true);
releaseCamera();
Log.i(TAG,"Camera is released");
}
};
private File getBackMediaFile() {
File pictureDirectory = new File(Environment.getExternalStorageDirectory(),"MyCamera");
if(!ALF_HOME_DIRECTORY.exists()){
if(!ALF_HOME_DIRECTORY.mkdir()){
Log.i(TAG,"Home Directory does not Exists");
}
}
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
File picture = new File(pictureDirectory.getPath() + File.separator + "IMG_" + timeStamp + ".jpg");
Log.i(TAG, "mediaFile: " + picture);
return picture;
}
public void releaseCamera() {
if (camera != null) {
camera.stopPreview();
camera.release();
camera = null;
}
}
private int getBackCameraId() {
int camId = -1;
int numberOfCameras = Camera.getNumberOfCameras();
Camera.CameraInfo ci = new Camera.CameraInfo();
for (int i = 0; i < numberOfCameras; i++) {
Camera.getCameraInfo(i, ci);
if (ci.facing == Camera.CameraInfo.CAMERA_FACING_BACK) {
camId = i;
}
}
return camId;
}
private void setCameraDisplayOrientation(int camId) {
Camera.getCameraInfo(camId, info);
int degrees = 0;
switch (rotation) {
case Surface.ROTATION_0: degrees = 0; break;
case Surface.ROTATION_90: degrees = 90; break;
case Surface.ROTATION_180: degrees = 180; break;
case Surface.ROTATION_270: degrees = 270; break;
}
int result;
if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
result = (info.orientation + degrees) % 360;
result = (360 - result) % 360; // compensate the mirror
} else { // back-facing
result = (info.orientation - degrees + 360) % 360;
}
camera.setDisplayOrientation(result);
}
}
|
Next, we will create Camera Activity java class. This class has a layout which contain an three buttons Cancel, Take and OK. When you click the Take button it will take the photo and when you click OK it will be shown in first activity image view.
package media.manager;
import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.SurfaceView;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import java.io.File;
import media.manager.BackCameraController;
public class MyCameraActivity extends Activity implements
BackCameraController.BackCameraControllerListener
{
private static final String TAG = MyCameraActivity.class.getSimpleName();
BackCameraController cc;
SurfaceView surfaceView;
File picture;
Button take, ok, cancel;
boolean canFinish=false;
boolean canTake=false;
CameraTakeTask cameraTask;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my_camera);
cc = new BackCameraController(this,270);
surfaceView=(SurfaceView)findViewById(R.id.camera_surfaceView);
take=(Button)findViewById(R.id.camera_button_take);
ok=(Button)findViewById(R.id.camera_button_ok);
cancel=(Button)findViewById(R.id.camera_button_cancel);
ok.setEnabled(false);
take.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
canTake=true;
ok.setEnabled(true);
cancel.setVisibility(View.INVISIBLE);
}
});
ok.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(picture!=null){
Uri result = Uri.fromFile(picture);
Log.i(TAG, "Uri..... : "+result);
Intent data = new Intent(Intent.ACTION_PICK, result);
setResult(RESULT_OK, data);
}else {
Toast.makeText(MyCameraActivity.this,"Wait..",Toast.LENGTH_SHORT).show();
}
if(canFinish)
finish();
}
});
cancel.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
cc.releaseCamera();
finish();
}
});
}
@Override
protected void onResume() {
super.onResume();
cameraTask=new CameraTakeTask();
cameraTask.execute();
}
@Override
protected void onPause() {
super.onPause();
if(cc!=null){
if(cc.hasBackCamera()){
cc.releaseCamera();
}
cc=null;
}
}
@Override
public void afterTakePicture(File pictureFile, boolean finish) {
picture=pictureFile;
canFinish=finish;
ok.setEnabled(true);
}
class CameraTakeTask extends AsyncTask<Void,Void,Void>{
int count=1;
@Override
protected Void doInBackground(Void... params) {
if (cc!=null && cc.getCamera() == null) {
cc.getBackCameraInstance(surfaceView);
}else {
Log.i(TAG, "Camera is occupied");
}
for (int i = 0; i < 10; i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
if(canTake) {
cc.takeBackPicture();
count++;
}
if(count>1)
break;
}
return null;
}
}
}
|
activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical
android:background="#f0800082">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="New Text"
android:id="@+id/textView"
android:layout_gravity="center_horizontal" />
<ImageView
android:layout_width="match_parent"
android:layout_height="0dp"
android:id="@+id/imageView"
android:layout_gravity="center_horizontal"
android:layout_weight="1"
android:layout_margin="50dp"
android:src="@drawable/ic_launcher" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Start"
android:id="@+id/my_camera_button"
android:layout_gravity="center_horizontal"
andoid:onClick="buttonCameraClick"
android:layout_margin="20dp" />
</LinearLayout>
|
activity_my_camera.xml
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="2dp"
tools:context="sub_activities.MyCameraActivity">
<TextView
android:text="@string/hello_world"
android:layout_width="wrap_content"
android:visibility="gone"
android:layout_height="wrap_content" />
<SurfaceView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/camera_surfaceView"
/>
<Button
style="?android:attr/buttonStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/back_camera_ok"
android:id="@+id/camera_button_ok"
android:layout_gravity="end|bottom" />
<Button
style="?android:attr/buttonStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/back_camera_take"
android:id="@+id/camera_button_take"
android:layout_gravity="center_horizontal|bottom" />
<Button
style="?android:attr/buttonStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/back_camera_cancel"
android:id="@+id/camera_button_cancel"
android:layout_gravity="start|bottom" />
</FrameLayout>
|
Add following lines inside the your manifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="media.manager" >
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-feature android:name="android.hardware.camera.autofocus" />
<uses-feature android:name="android.hardware.camera" />
<uses-permission android:name="android.permission.camera" />
<uses-permission android:name="android.permission.CAMERA" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="MyCamera"
android:theme="@style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="MyCamera"
android:screenOrientation="portrait" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".MyCameraActivity"
android:label="Camera"
android:screenOrientation="portrait" >
</activity>
</manifest>
|
To store picture in the mobile you need the permission for read and write using uses-permission tag like below inside manifest.xml
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
Hope you will get some thought about creating your own camera in a Android device. Enjoy......
No comments:
Post a Comment