Error direclty opening activity with Camera API SurfaceView from MainActivity - android

I have a MainActivity which is only used if phone number is not set in Shared Preference. After setting phone number once there is no need of MainActivity and everytime user opens app he should goto CameraActivity Activity which have Camera API working in SurfaceView in it.
There is no problem in opening CameraActivity using button on MainActivity but if I open CameraActivity from MainACtivity onCreate method then I am facing following Error:
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.hardware.Camera.setDisplayOrientation(int)' on a null object reference
at com.vivertechnologies.camera.ShowCamera.refreshCamera(ShowCamera.java:208)
at com.vivertechnologies.camera.ShowCamera.surfaceChanged(ShowCamera.java:281)
at android.view.SurfaceView.updateWindow(SurfaceView.java:590)
at android.view.SurfaceView$3.onPreDraw(SurfaceView.java:176)
at android.view.ViewTreeObserver.dispatchOnPreDraw(ViewTreeObserver.java:847)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1983)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1081)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5818)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:767)
at android.view.Choreographer.doCallbacks(Choreographer.java:580)
at android.view.Choreographer.doFrame(Choreographer.java:550)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:753)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5234)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:909)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:704)
My Code from Camera API is:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.camera_show);
Thread t = new Thread() {
#Override
public void run() {
try {
while (!isInterrupted()) {
Thread.sleep(1000);
runOnUiThread(new Runnable() {
#Override
public void run() {
// update TextView here!
Calendar c = Calendar.getInstance();
SimpleDateFormat df = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
String formattedDate = df.format(c.getTime());
TextView txtView = (TextView)findViewById(R.id.dateTime);
txtView.setText(formattedDate);
}
});
}
} catch (InterruptedException e) {
}
}
};
t.start();
surfaceView = (SurfaceView) findViewById(R.id.surfaceView);
surfaceHolder = surfaceView.getHolder();
surfaceHolder.addCallback(this);
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
jpegCallback = new PictureCallback() {
#Override
public void onPictureTaken(byte[] data, Camera camera) {
new Thread(new SavePicThread(data)).start();
//
// Intent i = new Intent(ShowCamera.this, UploadActivity.class);
// i.putExtra("isImage", data);
// startActivity(i);
refreshCamera();
}
};
}
Refresh Camera Method which is generating error:
public void refreshCamera() {
if (surfaceHolder.getSurface() == null) {
// preview surface does not exist
return;
}
// stop preview before making changes
try {
camera.stopPreview();
} catch (Exception e) {
// ignore: tried to stop a non-existent preview
}
int rotation = ((WindowManager)ShowCamera.this.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getRotation();
int degrees = 0;
// specifically for back facing camera
switch (rotation) {
case Surface.ROTATION_0:
degrees = 90;
break;
case Surface.ROTATION_90:
degrees = 0;
break;
case Surface.ROTATION_180:
degrees = 270;
break;
case Surface.ROTATION_270:
degrees = 180;
break;
}
camera.setDisplayOrientation(degrees);
setCamera(camera);
try {
camera.setPreviewDisplay(surfaceHolder);
camera.startPreview();
} catch (Exception e) {
Log.d("AAAAA", "Error starting camera preview: " + e.getMessage());
}
}
I am unable to identify how it can be solved.
Edit:
Complete Code:
package com.vivertechnologies.camera;
import android.content.Context;
import android.content.Intent;
import android.hardware.Camera;
import android.hardware.Camera.PictureCallback;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.Menu;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.WindowManager;
import android.widget.TextView;
import android.widget.Toast;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
/**
* Created by usman on 27/11/15.
*/
public class ShowCamera extends MainActivity implements SurfaceHolder.Callback {
Camera camera;
SurfaceView surfaceView;
SurfaceHolder surfaceHolder;
Camera.PictureCallback rawCallback;
Camera.ShutterCallback shutterCallback;
Camera.PictureCallback jpegCallback;
private Camera.Size mPreviewSize;
private List<Camera.Size> mSupportedPreviewSizes;
private Context mContext;
private SurfaceView mSurfaceView;
private SurfaceHolder mHolder;
private final String TAG = "CameraSurfaceView";
private Camera mCamera;
private List<String> mSupportedFlashModes;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.camera_show);
Thread t = new Thread() {
#Override
public void run() {
try {
while (!isInterrupted()) {
Thread.sleep(1000);
runOnUiThread(new Runnable() {
#Override
public void run() {
// update TextView here!
Calendar c = Calendar.getInstance();
SimpleDateFormat df = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
String formattedDate = df.format(c.getTime());
TextView txtView = (TextView)findViewById(R.id.dateTime);
txtView.setText(formattedDate);
}
});
}
} catch (InterruptedException e) {
}
}
};
t.start();
surfaceView = (SurfaceView) findViewById(R.id.surfaceView);
surfaceHolder = surfaceView.getHolder();
surfaceHolder.addCallback(this);
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
jpegCallback = new PictureCallback() {
#Override
public void onPictureTaken(byte[] data, Camera camera) {
new Thread(new SavePicThread(data)).start();
//
// Intent i = new Intent(ShowCamera.this, UploadActivity.class);
// i.putExtra("isImage", data);
// startActivity(i);
refreshCamera();
}
};
}
private void galleryAddPic(File file) {
Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
Uri contentUri = Uri.fromFile(file);
mediaScanIntent.setData(contentUri);
ShowCamera.this.sendBroadcast(mediaScanIntent);
}
public class SavePicThread implements Runnable {
byte[] data;
public SavePicThread(byte[] data) {
this.data = data;
}
public void run() {
// make a new picture file
File pictureFile = getOutputMediaFile();
if (pictureFile == null) {
return;
}
try {
// write to the file
FileOutputStream fos = new FileOutputStream(pictureFile);
fos.write(data);
fos.flush();
fos.close();
ShowCamera.this.runOnUiThread(new Runnable() {
#Override
public void run() {
// Toast toast = Toast.makeText(ShowCamera.this, "Picture saved", Toast.LENGTH_SHORT);
// toast.show();
}
});
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
// make the picture visible to the rest of the device
galleryAddPic(pictureFile);
Intent i = new Intent(ShowCamera.this, UploadActivity.class);
i.putExtra("filePath", pictureFile.getPath());
startActivity(i);
}
}
// make picture and save to a folder
private File getOutputMediaFile() {
// make a new file directory inside the "sdcard" folder
File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES), "imgCaptureApp");
// if the directory does not exist
if (!mediaStorageDir.exists()) {
// if you cannot make this directory return
if (!mediaStorageDir.mkdirs()) {
return null;
}
}
// take the current timeStamp
String timeStamp = new SimpleDateFormat("dd-MM-yyyy_HH:mm:ss").format(new Date());
File mediaFile;
// and make a media file:
mediaFile = new File(mediaStorageDir.getPath() + File.separator + "IMG_" + timeStamp + ".jpg");
return mediaFile;
}
public void captureImage(View v) throws IOException {
camera.takePicture(null, null, jpegCallback);
}
public void refreshCamera() {
if (surfaceHolder.getSurface() == null) {
// preview surface does not exist
return;
}
// stop preview before making changes
try {
camera.stopPreview();
} catch (Exception e) {
// ignore: tried to stop a non-existent preview
}
int rotation = ((WindowManager)ShowCamera.this.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getRotation();
int degrees = 0;
// specifically for back facing camera
switch (rotation) {
case Surface.ROTATION_0:
degrees = 90;
break;
case Surface.ROTATION_90:
degrees = 0;
break;
case Surface.ROTATION_180:
degrees = 270;
break;
case Surface.ROTATION_270:
degrees = 180;
break;
}
camera.setDisplayOrientation(degrees);
setCamera(camera);
try {
camera.setPreviewDisplay(surfaceHolder);
camera.startPreview();
} catch (Exception e) {
Log.d("AAAAA", "Error starting camera preview: " + e.getMessage());
}
}
public void setCamera(Camera camera)
{
Camera mCamera = camera;
if (mCamera != null)
{
mSupportedPreviewSizes = mCamera.getParameters().getSupportedPreviewSizes();
mSupportedFlashModes = mCamera.getParameters().getSupportedFlashModes();
// Set the camera to Auto Flash mode.
if (mSupportedFlashModes.contains(Camera.Parameters.FLASH_MODE_AUTO))
{
Camera.Parameters parameters = mCamera.getParameters();
parameters.setFlashMode(Camera.Parameters.FLASH_MODE_AUTO);
mCamera.setParameters(parameters);
}
}
surfaceView.requestLayout();
}
#Override
protected void onDestroy() {
super.onDestroy();
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
try {
camera = Camera.open();
}
catch (RuntimeException e) {
System.err.println(e);
return;
}
Camera.Parameters param;
param = camera.getParameters();
List<Camera.Size> sizes = param.getSupportedPictureSizes();
Camera.Size size = sizes.get(0);
for(int i=0;i<sizes.size();i++)
{
if(sizes.get(i).width > size.width)
size = sizes.get(i);
}
param.setPictureSize(size.width, size.height);
param.setRotation(90);
param.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
// param.setPreviewSize(352, 288);
camera.setParameters(param);
try {
camera.setPreviewDisplay(surfaceHolder);
camera.startPreview();
}
catch (Exception e) {
System.err.println(e);
return;
}
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
refreshCamera();
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
camera.stopPreview();
camera.release();
camera = null;
}
}

From your description, your problem appears to be that ShowCamera is a subclass of MainActivity. Presumably, you have something similar to the following in MainActivity's onCreate() method:
SharedPreferences prefs = ...
if(prefs.getBoolean("phone_number_set", false)) {
startActivity(new Intent(this, ShowCamera.class));
}
Since ShowCamera is a subclass of MainActivity, calling super.onCreate(savedInstanceState); in ShowCamera's onCreate() method is executing MainActivity's onCreate() method again. When you open ShowCamera with the Button, you've not yet set the phone number, so the if conditional shown above is false, and the startActivity() method doesn't get called again.
However, after you've set the phone number, the conditional is true, and it starts ShowCamera again, which is calling MainActivity's onCreate(), which executes the if block, which starts ShowCamera, which calls MainActivity's onCreate(), which executes the if block, which starts ShowCamera... This is easily verified by adding a static int to the ShowCamera class, printing it to the Log in onCreate(), and then immediately incrementing it.
Eventually, one of the ShowCamera instances will layout its SurfaceView and call refreshCamera() from the surfaceChanged() callback, but it will have a null Camera object, because a previous Activity already has the camera.open, and it will throw the NullPointerException you're getting.
The solution is simple. Change the ShowCamera class to be a direct subclass of Activity. That is:
public class ShowCamera extends Activity implements SurfaceHolder.Callback {

Related

Capture video in mp4 format using intent - Android

So I have been searching for the solution from past few days but it seems that I am unable to find any. At first it seems simple enough.
I have an app that uses default Android camera app to capture the video using intent. Video recording is working perfect but the file format is 3gp. I want to record the video in mp4 format but I do not want to implement my own mediarecorder etc to build my own video recording module.
I have also searched for available extra parameters I can pass into the intent for the file format but I couldn't.
Is there any extra parameter that I can use for selecting file format?
Thanks for all your help!
// Use this code to capture Mp4 video.
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.hardware.Camera;
import android.media.CamcorderProfile;
import android.media.MediaRecorder;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.Toast;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.Timer;
import java.util.TimerTask;
public class MainActivity extends Activity{
private static final String TAG = MainActivity.class.getSimpleName();
private Camera myCamera;
private CameraSurfaceView cameraSurfaceView;
private MediaRecorder mediaRecorder;
Button myButton;
boolean recording;
public Context context;
private Uri fileUri;
public static final int MEDIA_TYPE_VIDEO = 2;
final Handler handler = new Handler();
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
recording = false;
setContentView(R.layout.activity_main);
//Get Camera for preview
myCamera = getCameraInstance();
if(myCamera == null){
Log.w(TAG, "camera not found");
Toast.makeText(context,
"Fail to get Camera",
Toast.LENGTH_LONG).show();
}
cameraSurfaceView = new CameraSurfaceView(this, myCamera);
FrameLayout cameraPreview = (FrameLayout)findViewById(R.id.videoview);
cameraPreview.addView(cameraSurfaceView);
myButton = (Button)findViewById(R.id.mybutton);
myButton.setOnClickListener(myButtonOnClickListener);
}
Button.OnClickListener myButtonOnClickListener
= new Button.OnClickListener(){
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
try{
if(recording){
// stop recording and release camera
mediaRecorder.stop(); // stop the recording
releaseMediaRecorder(); // release the MediaRecorder object
//Exit after saved
//finish();
myButton.setText("REC");
recording = false;
Log.e("file path",fileUri.getPath());
}else{
//Release Camera before MediaRecorder start
releaseCamera();
if(!prepareMediaRecorder()){
Toast.makeText(context,
"Fail in prepareMediaRecorder()!\n - Ended -",
Toast.LENGTH_LONG).show();
finish();
}
mediaRecorder.start();
recording = true;
myButton.setText("STOP");
Runnable r = new Runnable() {
public void run() {
Timer timer = new Timer();
timer.schedule(doAsynchronousTask, 0, 10000);
}
};
handler.postDelayed(r, 10000);
}
}catch (Exception ex){
ex.printStackTrace();
}
}
};
private Camera getCameraInstance(){
Camera c = null;
try {
c = Camera.open(Camera.CameraInfo.CAMERA_FACING_FRONT); // attempt to get a Camera instance
c.setDisplayOrientation(90);
}
catch (Exception e){
// Camera is not available (in use or does not exist)
}
return c; // returns null if camera is unavailable
}
TimerTask doAsynchronousTask = new TimerTask() {
#Override
public void run() {
handler.post(new Runnable() {
#SuppressWarnings("unchecked")
public void run() {
try {
if(recording ==true) {
recording = false;
Log.e("file path",fileUri.getPath());
doAsynchronousTask.cancel();
} else{
doAsynchronousTask.cancel();
}
}
catch (Exception e) {
// TODO Auto-generated catch block
}
}
});
}
};
private boolean prepareMediaRecorder(){
myCamera = getCameraInstance();
mediaRecorder = new MediaRecorder();
myCamera.unlock();
mediaRecorder.setCamera(myCamera);
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
mediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH));
fileUri = getOutputMediaFileUri(MEDIA_TYPE_VIDEO);
mediaRecorder.setOutputFile(fileUri.getPath());
//mediaRecorder.setOutputFile("/sdcard/myvideo1.mp4");
mediaRecorder.setMaxDuration(10000); // Set max duration 60 sec.
mediaRecorder.setMaxFileSize(50000000); // Set max file size 50M
mediaRecorder.setPreviewDisplay(cameraSurfaceView.getHolder().getSurface());
try {
mediaRecorder.prepare();
} catch (IllegalStateException e) {
releaseMediaRecorder();
return false;
} catch (IOException e) {
releaseMediaRecorder();
return false;
}
return true;
}
#Override
protected void onPause() {
super.onPause();
releaseMediaRecorder(); // if you are using MediaRecorder, release it first
releaseCamera(); // release the camera immediately on pause event
}
private void releaseMediaRecorder(){
if (mediaRecorder != null) {
mediaRecorder.reset(); // clear recorder configuration
mediaRecorder.release(); // release the recorder object
mediaRecorder = new MediaRecorder();
myCamera.lock(); // lock camera for later use
}
}
private void releaseCamera(){
if (myCamera != null){
myCamera.release(); // release the camera for other applications
myCamera = null;
}
}
public class CameraSurfaceView extends SurfaceView implements SurfaceHolder.Callback{
private SurfaceHolder mHolder;
private Camera mCamera;
public CameraSurfaceView(Context context, Camera camera) {
super(context);
mCamera = camera;
// Install a SurfaceHolder.Callback so we get notified when the
// underlying surface is created and destroyed.
mHolder = getHolder();
mHolder.addCallback(this);
// deprecated setting, but required on Android versions prior to 3.0
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int weight,
int height) {
// If your preview can change or rotate, take care of those events here.
// Make sure to stop the preview before resizing or reformatting it.
if (mHolder.getSurface() == null){
// preview surface does not exist
return;
}
// stop preview before making changes
try {
mCamera.stopPreview();
} catch (Exception e){
// ignore: tried to stop a non-existent preview
}
// make any resize, rotate or reformatting changes here
// start preview with new settings
try {
mCamera.setPreviewDisplay(mHolder);
mCamera.startPreview();
} catch (Exception e){
}
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
// TODO Auto-generated method stub
// The Surface has been created, now tell the camera where to draw the preview.
try {
mCamera.setPreviewDisplay(holder);
mCamera.startPreview();
} catch (IOException e) {
}
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
}
}
public Uri getOutputMediaFileUri(int type) {
return Uri.fromFile(getOutputMediaFile(type));
}
/**
* returning image / video
*/
private static File getOutputMediaFile(int type) {
// External sdcard location
File mediaStorageDir = new File(
Environment
.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),
Config.IMAGE_DIRECTORY_NAME);
// Create the storage directory if it does not exist
if (!mediaStorageDir.exists()) {
if (!mediaStorageDir.mkdirs()) {
Log.d(TAG, "Oops! Failed create "
+ Config.IMAGE_DIRECTORY_NAME + " directory");
return null;
}
}
// Create a media file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss",
Locale.getDefault()).format(new Date());
File mediaFile;
if (type == MEDIA_TYPE_VIDEO) {
mediaFile = new File(mediaStorageDir.getPath() + File.separator
+ "VID_" + timeStamp + ".mp4");
} else {
return null;
}
return mediaFile;
}
}

surfaceview for camera is not working in android lollipop os

Today I had faced an issue in android surfaceview for camera customization.
I tried the below code.
The Issue occurred when I captured the image, it stops the camera
preview and doesn't return to the activity.
Following code will be implemented in the program. I took this code from an existing reference on stackoverflow
Supporting Class.
public class AndroidCameraSurfaceview extends Activity implements
SurfaceHolder.Callback {
TextView testView;
Camera camera;
SurfaceView surfaceView;
SurfaceHolder surfaceHolder;
boolean preview;
PictureCallback rawCallback;
ShutterCallback shutterCallback;
PictureCallback jpegCallback;
int displayheight, displaywidth;
Camera.PreviewCallback previewCallback;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.camerasurfaceview);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
surfaceView = (SurfaceView) findViewById(R.id.surfaceView);
surfaceHolder = surfaceView.getHolder();
surfaceHolder.addCallback(this);
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
jpegCallback = new PictureCallback() {
public void onPictureTaken(byte[] data, Camera camera) {
Bundle b = new Bundle();
b.putByteArray("Image", data);
Intent intent = new Intent();
intent.putExtras(b);
setResult(RESULT_OK, intent);
finish();
// refreshCamera();
}
};
}
public void captureImage(View v) throws IOException {
// take the picture
camera.takePicture(null, null, jpegCallback);
}
public void refreshCamera() {
if (surfaceHolder.getSurface() == null) {
// preview surface does not exist
return;
}
try {
camera.stopPreview();
} catch (Exception e) {
}
try {
camera.setDisplayOrientation(90);
camera.setPreviewDisplay(surfaceHolder);
camera.startPreview();
} catch (Exception e) {
}
}
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
if (preview) {
camera.stopPreview();
}
try{
Camera.Parameters parameters = camera.getParameters();
List<Size> sizes = parameters.getSupportedPreviewSizes();
Size optimalSize = getOptimalPreviewSize(sizes, width, height);
parameters.setPreviewSize(optimalSize.width, optimalSize.height);
camera.setParameters(parameters);
try {
camera.setDisplayOrientation(90);
camera.setPreviewDisplay(holder);
camera.startPreview();
preview = true;
} catch (IOException e) {
e.printStackTrace();
}
}catch(Exception e){
System.out.println("Surface Exception---=>"+e);
}
}
public void surfaceCreated(SurfaceHolder holder) {
camera = Camera.open();
if (camera != null) {
Camera.Parameters params = camera.getParameters();
camera.setDisplayOrientation(90);
camera.setParameters(params);
}
}
public void surfaceDestroyed(SurfaceHolder holder) {
// stop preview and release camera
camera.stopPreview();
camera.release();
camera = null;
}
private Size getOptimalPreviewSize(List<Size> sizes, int w, int h) {
final double ASPECT_TOLERANCE = 1;
double targetRatio = (double) w / h;
if (sizes == null)
return null;
Size optimalSize = null;
double minDiff = Double.MAX_VALUE;
int targetHeight = h;
for (Size size : sizes) {
double ratio = (double) size.width / size.height;
if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE)
continue;
if (Math.abs(size.height - targetHeight) < minDiff) {
optimalSize = size;
minDiff = Math.abs(size.height - targetHeight);
}
}
if (optimalSize == null) {
minDiff = Double.MAX_VALUE;
for (Size size : sizes) {
if (Math.abs(size.height - targetHeight) < minDiff) {
optimalSize = size;
minDiff = Math.abs(size.height - targetHeight);
}
}
}
return optimalSize;
}
}
2.Implemented in Activity
public void captureImage() {
Intent intentDriver = new Intent(AddNewDevice_Activity.this,
AndroidCameraSurfaceview.class);
startActivityForResult(intentDriver, 0);
//
// Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
//
// Uri fileUri = getOutputMediaFileUri(MEDIA_TYPE_IMAGE);
//
// intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
//
// // start the image capture Intent
// startActivityForResult(intent, CAMERA_CAPTURE_IMAGE_REQUEST_CODE);
// Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
//
// fileUri = getOutputMediaFileUri(MEDIA_TYPE_IMAGE);
//
// intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
//
// // start the image capture Intent
// startActivityForResult(intent, CAMERA_CAPTURE_IMAGE_REQUEST_CODE);
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 0) {
System.out.println("Result Code: " + resultCode);
if (resultCode == RESULT_OK && data != null) {
Bundle bundle = data.getExtras();
byte[] test = bundle.getByteArray("Image");
Bitmap bpCamera = BitmapFactory.decodeByteArray(test, 0,
test.length);
Matrix matrix = new Matrix();
matrix.postRotate(90);
bpCamera = Bitmap
.createBitmap(bpCamera, 0, 0, bpCamera.getWidth(),
bpCamera.getHeight(), matrix, true);
imageView_camera.setImageBitmap(bpCamera);
selectedImageStr = encodeTobase64(bpCamera);
}
} else {
finish();
}
}
You shold split activity and surface view.
public class AndroidCameraActivity extends Activity {
AndroidCameraSurfaceview surfaceView;
...
#Override
public void onCreate(Bundle savedInstanceState) {
...
surfaceView = (AndroidCameraSurfaceview) findViewById(R.id.surfaceView);
}
}
class AndroidCameraSurfaceview extends SurfaceView implements SurfaceHolder.Callback {
public AndroidCameraSurfaceview(Context context, AttributeSet attrs) {
super(context, attrs);
getHolder().addCallback(this);
...
}
public void surfaceCreated(SurfaceHolder holder) {
...
}
public void surfaceDestroyed(SurfaceHolder holder) {
...
}
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
...
}
}
Google had revised the camera API from in API version 21, henceforth we have to adopt new camera2 package and has to be adhered in cases where camera functionalities comes into picture. Here is the link to sample code published by google which uses surface view implementation and it works flawless in Android 5.0. I believe it solves a bit of mystery.
https://github.com/googlesamples/android-Camera2Basic
try this, I have made it from my self :
package com.fragments;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.sql.Date;
import java.text.SimpleDateFormat;
import com.jsonparsing.JsonMainActivity;
import com.jsonparsing.MailFragment;
import com.mobehc.R;
import com.sendmail.main;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.hardware.Camera;
import android.hardware.Camera.CameraInfo;
import android.hardware.Camera.PictureCallback;
import android.media.CamcorderProfile;
import android.media.MediaRecorder;
import android.net.Uri;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.os.Environment;
import android.os.Handler;
import android.os.SystemClock;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.ViewGroup;
import android.view.View.OnClickListener;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
public class CamImageCapture2 extends Fragment implements
MediaRecorder.OnInfoListener {
private Camera myCamera;
private MyCameraSurfaceView myCameraSurfaceView;
private MediaRecorder mediaRecorder;
Camera c = null;
ImageView myButton, myButton1, backcam;
SurfaceHolder surfaceHolder;
boolean recording;
private Button startButton;
private Button pauseButton;
private TextView timerValue;
private long startTime = 0L;
private Handler customHandler = new Handler();
long timeInMilliseconds = 0L;
long timeSwapBuff = 0L;
long updatedTime = 0L;
String path = Environment.getExternalStorageDirectory().toString()
+ "/00 MHC/VID.MP4";
/** Called when the activity is first created. */
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.activity_captureimage, container,
false);
recording = false;
getActivity().getWindow().addFlags(
WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
timerValue = (TextView) v.findViewById(R.id.timer);
// Get Camera for preview
myCamera = getCameraInstance();
if (myCamera == null) {
Toast.makeText(getActivity(), "Fail to get Camera",
Toast.LENGTH_LONG).show();
}
myCameraSurfaceView = new MyCameraSurfaceView(getActivity(), myCamera);
FrameLayout myCameraPreview = (FrameLayout) v
.findViewById(R.id.videoview);
myCameraPreview.addView(myCameraSurfaceView);
myButton = (ImageView) v.findViewById(R.id.rec);
myButton1 = (ImageView) v.findViewById(R.id.rec1);
backcam = (ImageView) v.findViewById(R.id.backcamera);
backcam.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Intent ik = new Intent(getActivity(), Camrec2.class);
startActivity(ik);
// getActivity().finish();
getActivity().getFragmentManager().popBackStack();
}
});
myButton1.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
myCamera.takePicture(null, null, mPicture);
}
});
myButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
File attachment1 = new File(Environment
.getExternalStorageDirectory(), "/00 MHC/image.jpg");
if (attachment1.exists()) {
attachment1.delete();
}
if (recording) {
mediaRecorder.stop(); // stop the recording
releaseMediaRecorder(); // release the MediaRecorder object
// Exit after saved
getActivity().finish();
} else {
// Release Camera before MediaRecorder start
releaseCamera();
if (!prepareMediaRecorder()) {
Toast.makeText(getActivity(),
"Fail in prepareMediaRecorder()!\n - Ended -",
Toast.LENGTH_LONG).show();
getActivity().finish();
}
mediaRecorder.start();
startTime = SystemClock.uptimeMillis();
customHandler.postDelayed(updateTimerThread, 0);
/*
* final TextView _tv = (TextView) findViewById(R.id.timer);
* _tv.setVisibility(View.VISIBLE); new
* CountDownTimer(60000, 1000) {
*
* public void onTick(long millisUntilFinished) {
* _tv.setText(new SimpleDateFormat("00:ss") .format(new
* Date(millisUntilFinished))); }
*
* public void onFinish() { _tv.setText("done!"); Intent ii
* = new Intent(Camrecord.this, Emailtry.class);
* startActivity(ii); finish(); } }.start();
*/recording = true;
// myButton.setText("STOP");
Drawable myDrawable = getResources().getDrawable(
R.drawable.stp);
myButton.setImageDrawable(myDrawable);
backcam.setVisibility(View.INVISIBLE);
}
}
});
return v;
}
PictureCallback mPicture = new PictureCallback() {
#Override
public void onPictureTaken(byte[] data, Camera camera) {
File externalStorage = Environment.getExternalStorageDirectory();
String sdcardPath = externalStorage.getAbsolutePath() + "/00 MHC/";
File pictureFile = new File(sdcardPath + "/image" + ".jpg");
try {
FileOutputStream fos = new FileOutputStream(pictureFile);
fos.write(data);
fos.close();
File attachment1 = new File(
Environment.getExternalStorageDirectory(),
"/00 MHC/VID.mp4");
if (attachment1.exists()) {
attachment1.delete();
}
Toast.makeText(getActivity(), "Captured Successfully...",
Toast.LENGTH_LONG).show();
Fragment fr = new main();
android.support.v4.app.FragmentTransaction fragmentTransaction = getFragmentManager()
.beginTransaction();
fragmentTransaction.replace(R.id.fragment_place, fr);
fragmentTransaction.commit();
// getActivity().finish();
} catch (FileNotFoundException e) {
} catch (IOException e) {
}
}
};
private Camera getCameraInstance() {
// TODO Auto-generated method stub
try {
// c = Camera.open(); // attempt to get a Camera instance
if (Camera.getNumberOfCameras() >= 2) {
// backcam.setVisibility(View.VISIBLE);
// if you want to open front facing camera use this line
c = Camera.open(CameraInfo.CAMERA_FACING_FRONT);
c = Camera.open(CameraInfo.CAMERA_FACING_BACK);
} else {
c = Camera.open(CameraInfo.CAMERA_FACING_BACK);
}
/*
* c.setDisplayOrientation(90); c.setPreviewDisplay(surfaceHolder);
*
* Camera.Parameters p = c.getParameters(); p.set("camera-id", 2);
* c.setParameters(p);
*/
} catch (Exception e) {
// Camera is not available (in use or does not exist)
}
return c; // returns null if camera is unavailable
}
private boolean prepareMediaRecorder() {
myCamera = getCameraInstance();
myCamera.setDisplayOrientation(90);
mediaRecorder = new MediaRecorder();
myCamera.unlock();
mediaRecorder.setCamera(myCamera);
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
mediaRecorder.setProfile(CamcorderProfile
.get(CamcorderProfile.QUALITY_LOW));
mediaRecorder.setOrientationHint(270);
mediaRecorder.setOutputFile(path);
mediaRecorder.setMaxDuration(60000); // Set max duration 60 sec.
mediaRecorder.setOnInfoListener(this);
mediaRecorder.setMaxFileSize(2500000); // Set max file size 5M
// mediaRecorder.setPreviewDisplay(surfaceHolder.getSurface());
mediaRecorder.setPreviewDisplay(myCameraSurfaceView.getHolder()
.getSurface());
try {
mediaRecorder.prepare();
} catch (IllegalStateException e) {
releaseMediaRecorder();
return false;
} catch (IOException e) {
releaseMediaRecorder();
return false;
}
return true;
}
#Override
public void onPause() {
super.onPause();
releaseMediaRecorder(); // if you are using MediaRecorder, release it
// first
releaseCamera(); // release the camera immediately on pause event
}
private void releaseMediaRecorder() {
if (mediaRecorder != null) {
mediaRecorder.reset(); // clear recorder configuration
mediaRecorder.release(); // release the recorder object
mediaRecorder = null;
myCamera.lock(); // lock camera for later use
}
}
private void releaseCamera() {
if (myCamera != null) {
myCamera.release(); // release the camera for other applications
myCamera = null;
}
}
public class MyCameraSurfaceView extends SurfaceView implements
SurfaceHolder.Callback {
private SurfaceHolder mHolder;
private Camera mCamera;
public MyCameraSurfaceView(Context context, Camera camera) {
super(context);
mCamera = camera;
// Install a SurfaceHolder.Callback so we get notified when the
// underlying surface is created and destroyed.
mHolder = getHolder();
mHolder.addCallback(this);
// deprecated setting, but required on Android versions prior to 3.0
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format,
int weight, int height) {
// If your preview can change or rotate, take care of those events
// here.
// Make sure to stop the preview before resizing or reformatting it.
if (mHolder.getSurface() == null) {
// preview surface does not exist
return;
}
// stop preview before making changes
try {
mCamera.stopPreview();
} catch (Exception e) {
// ignore: tried to stop a non-existent preview
}
// make any resize, rotate or reformatting changes here
// start preview with new settings
try {
mCamera.setPreviewDisplay(mHolder);
mCamera.startPreview();
} catch (Exception e) {
}
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
// TODO Auto-generated method stub
// The Surface has been created, now tell the camera where to draw
// the preview.
try {
mCamera.setDisplayOrientation(90);
mCamera.setPreviewDisplay(holder);
mCamera.startPreview();
} catch (IOException e) {
}
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
}
}
private Runnable updateTimerThread = new Runnable() {
public void run() {
timeInMilliseconds = SystemClock.uptimeMillis() - startTime;
updatedTime = timeSwapBuff + timeInMilliseconds;
int secs = (int) (updatedTime / 1000);
int mins = secs / 60;
secs = secs % 60;
int milliseconds = (int) (updatedTime % 1000);
timerValue.setText("" + mins + ":" + String.format("%02d", secs)
+ ":" + String.format("%03d", milliseconds));
customHandler.postDelayed(this, 0);
}
};
#Override
public void onInfo(MediaRecorder mr, int what, int extra) {
if (what == MediaRecorder.MEDIA_RECORDER_INFO_MAX_DURATION_REACHED) {
Log.v("VIDEOCAPTURE", "Maximum Duration Reached");
mediaRecorder.stop(); // stop the recording
releaseMediaRecorder(); // release the MediaRecorder object
// Exit after saved
// getActivity().finish();
getActivity().getFragmentManager().popBackStack();
}
}
}
I Tried the Camera API 2, but i don't have time fix the issue within
the time line. This is the way I found the solutions for the issue
using camera API 1. When the Multiple Views are Handle Single
Activity. Please try this code in case of the Camera Handling.
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == CAPTURE_IMAGE_CAPTURE_CODE) {
if (resultCode == RESULT_OK) {
Bitmap bp = (Bitmap) data.getExtras().get("data");
Bitmap resized = Bitmap.createScaledBitmap(bp,
(int) (bp.getWidth() * 0.8),
(int) (bp.getHeight() * 0.8), true);
imageView_camera.setImageBitmap(resized);
SharedPreferences value_1_Details = getSharedPreferences(
"Value_1_Key", MODE_PRIVATE);
Value_1_SelectedPosId = Integer.parseInt(value_1_Details.getString(
"Value_1_ID", ""));
String value_1_Name = value_1_Details.getString("Value_1_Data", "");
btn_popup_value_1_Name.setText(value_1_Name);
SharedPreferences value_2_Details = getSharedPreferences(
"Value_2_Key", MODE_PRIVATE);
value_2_SelectedPosId = Integer.parseInt(value_2_Details.getString(
"Value_2_ID", ""));
String value_2_Name = value_2_Details.getString("Value_2_Data", "");
btn_dropdown_value_2_Name.setText(value_2_Name);
SharedPreferences value_3_Details = getSharedPreferences(
"Value_3_Key", MODE_PRIVATE);
value_3_PosId = Integer.parseInt(value_3_Details
.getString("Value_3_ID", ""));
String value_3_Name = value_3_Details.getString("Value_3_Data",
"");
btn_dropdown_value_3_Name.setText(value_3_Name);
rL_include_ViewDetails.setVisibility(View.GONE);
rL_include_AddNew.setVisibility(View.VISIBLE);
rL_include_View.setVisibility(View.GONE);
selectedImageStr = encodeTobase64(resized);
} else if (resultCode == RESULT_CANCELED) {
Toast.makeText(this, "Cancelled", Toast.LENGTH_LONG).show();
}
}
}

How do I get back to the Viewfinder of the Camera after taking a picture?

I am making a Camera example on Android, currently it just takes a picture and saves it on the device's (internal) memory.
After taking a picture, the screen stays frozen on the last clicked picture and I have to exit the app and open it again to take another picture.
Here is my code:
MainActivity.java:
package com.example.camera;
import android.app.Activity;
import android.hardware.Camera;
import android.hardware.Camera.PictureCallback;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.Menu;
import android.view.Surface;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.Toast;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class MainActivity extends Activity
{
private Camera mCamera;
private ShowCamera showCamera;
public Camera isCameraAvailable()
{
Camera camera=null;
Log.d("isCameraAvailable","Camera object set to null.");
try
{
camera = Camera.open();
Log.d("isCameraAvailable","Camera opened.");
}
catch (Exception e)
{
Log.d("isCameraAvailable",e.toString());
}
return camera;
}
private static File getOutputMediaFile()
{
File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),"com.example.camera");
if (!mediaStorageDir.exists())
{
if (!mediaStorageDir.mkdirs())
{
Log.d("getOutputMediaFile","Failed to create directory.");
return null;
}
}
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
File mediaFile;
mediaFile = new File(mediaStorageDir.getPath() + File.separator+ "IMG_" + timeStamp + ".jpg");
Log.d("getOutputMediaFile","Filename created.");
return mediaFile;
}
private PictureCallback capturedIt = new PictureCallback()
{
#Override
public void onPictureTaken(byte[] data, Camera camera)
{
File pictureFile = getOutputMediaFile();
if (pictureFile == null)
{
Log.d("onPictureTaken","pictureFile=null");
return;
}
try
{
FileOutputStream fos = new FileOutputStream(pictureFile);
fos.write(data);
Log.d("onPictureTaken","File written.");
fos.close();
Log.d("onPictureTaken","File closed.");
Toast.makeText(MainActivity.this,pictureFile.toString()+" saved!", Toast.LENGTH_LONG).show();
return;
}
catch (FileNotFoundException e)
{
Log.e("onPictureTaken",e.toString());
}
catch (IOException e)
{
Log.d("onPictureTaken",e.toString());
}
}
};
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mCamera = isCameraAvailable();
setCameraDisplayOrientation(this,0,mCamera);
Log.d("onCreate","Camera instance taken.");
showCamera = new ShowCamera(this, mCamera);
FrameLayout preview = (FrameLayout) findViewById(R.id.flCameraPreview);
preview.addView(showCamera);
Log.d("onCreate","Camera view in initialized");
preview.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
mCamera.takePicture(null, null, capturedIt);
Log.d("onClick","Button Clicked.");
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu)
{
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
public static void setCameraDisplayOrientation(Activity activity,int cameraId, android.hardware.Camera camera)
{
android.hardware.Camera.CameraInfo info=new android.hardware.Camera.CameraInfo();
android.hardware.Camera.getCameraInfo(cameraId,info);
int rotation = activity.getWindowManager().getDefaultDisplay().getRotation();
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;
}
else
{
result = (info.orientation - degrees + 360) % 360;
}
camera.setDisplayOrientation(result);
}
}
ShowCamera.java:
package com.example.camera;
import android.content.Context;
import android.hardware.Camera;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import java.io.IOException;
public class ShowCamera extends SurfaceView implements SurfaceHolder.Callback
{
private SurfaceHolder holdMe;
private Camera mCamera;
public ShowCamera(Context context,Camera camera)
{
super(context);
this.mCamera = camera;
this.holdMe = getHolder();
this.holdMe.addCallback(this);
this.holdMe.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
#Override
public void surfaceChanged(SurfaceHolder surfaceHolder, int format,int width, int height)
{
try
{
mCamera.setPreviewDisplay(surfaceHolder);
mCamera.startPreview();
}
catch (Exception e)
{
Log.d("surfaceChanged",e.toString());
}
}
#Override
public void surfaceCreated(SurfaceHolder holder)
{
try
{
mCamera.setPreviewDisplay(holder);
mCamera.startPreview();
}
catch (IOException e)
{
Log.e("surfaceCreated",e.toString());
}
}
#Override
public void surfaceDestroyed(SurfaceHolder surfaceHolder)
{
mCamera.stopPreview();
mCamera.release();
}
}
After taking a picture and saving it to memory, if I click the screen once more, the app crashes.
You have stopPreview in surfaceDestroyed. but when it cames back. you have to restart the Camera in onResume . which is missing
public void onResume()
{
mCamera = getCameraInstance(); // i have created this i
// static method here
//mCamera.setPreviewCallback(previewCallback);//it depends on you need
try
{
mCamera.setPreviewDisplay(mHolder);
mCamera.startPreview();
}
catch (IOException ioexception)
{
Log.e("MyCamera",
(new StringBuilder()).append("PreviewDisplay Error => ")
.append(ioexception.getMessage()).toString());
}
}
And
public static Camera getCameraInstance()
{
Camera camera1;
try
{
if (android.os.Build.VERSION.SDK_INT >= 9)
{
return Camera.open(cameraId);
}
camera1 = Camera.open();
}
catch (Exception exception)
{
Log.e("NightVision",
(new StringBuilder()).append("ErrorCameraInit: ")
.append(exception.getMessage()).toString());
return null;
}
return camera1;
}

How to Get Image Path From SurfaceView android

How to get the Image path from SurfaceView till now i tried this code
public class CameraSwitch extends Activity implements SurfaceHolder.Callback, OnClickListener {
private static final String TAG = "MainActivity";
private Cursor mImageCursor;
private ImageThumbnailAdapter mAdapter;
private TwoWayGridView mImageGrid;
Camera camera;
SurfaceView surfaceView;
SurfaceHolder surfaceHolder;
boolean previewing = false;
LayoutInflater controlInflater = null;
int camId = Camera.CameraInfo.CAMERA_FACING_BACK;
int numberOfCamera;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.cameraswitch);
surfaceView = (SurfaceView)findViewById(R.id.surfaceView1);
surfaceHolder = surfaceView.getHolder();
surfaceHolder.addCallback(this);
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
controlInflater = LayoutInflater.from(getBaseContext());
View viewControl = controlInflater.inflate(R.layout.custom, null);
Button switchCam = (Button)findViewById(R.id.flip);
// Button toggleFlash = (Button)findViewById(R.id.toggleflash);
LayoutParams layoutParamsControl = new LayoutParams(LayoutParams.FILL_PARENT,
LayoutParams.FILL_PARENT);
this.addContentView(viewControl, layoutParamsControl);
switchCam.setOnClickListener(this);
initGrid();
Button picbtn = (Button) findViewById(R.id.button1);
picbtn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
camera.takePicture(null,null, new PhotoHandler(getApplicationContext()));
}
});
}
private void initGrid() {
// TODO Auto-generated method stub
Log.e("Bottom Grid View", "Grid view Bottom");
}
#SuppressLint("NewApi")
public void openFrontFacingCamera() {
numberOfCamera = Camera.getNumberOfCameras();
if(camId == Camera.CameraInfo.CAMERA_FACING_BACK){
camId = Camera.CameraInfo.CAMERA_FACING_FRONT;
Toast.makeText(getApplicationContext(), "BACK TO FRONT" ,1000).show();
try {
Toast.makeText(getApplicationContext(), "try block BACK TO FRONT" ,1000).show();
camera.release();
camera = Camera.open(camId);
camera.setDisplayOrientation(90);
//camera = Camera.open(Camera.CameraInfo.CAMERA_FACING_FRONT);
/* Comment this set previewDisplay*/
// camera.setPreviewDisplay(surfaceHolder);
camera.startPreview();
previewing = true;
}
catch (RuntimeException e)
{
e.printStackTrace();
}
catch (Exception e) {}
}
else if(camId == Camera.CameraInfo.CAMERA_FACING_FRONT){
camId = Camera.CameraInfo.CAMERA_FACING_BACK;
Toast.makeText(getApplicationContext(), "FRONT TO BACK" ,1000).show();
try {
camera.release();
camera = Camera.open(camId);
camera.setDisplayOrientation(90);
camera.setPreviewDisplay(surfaceHolder);
camera.startPreview();
} catch (RuntimeException e) {
e.printStackTrace();
} catch (IOException e) {}
}
}
#Override
public void onClick(View click) {
if(click.getId() == R.id.flip){
openFrontFacingCamera();
}else if(click.getId() == R.id.flip){
openFrontFacingCamera();
}
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
if(previewing)
{
camera.stopPreview();
previewing = false;
}
if (camera != null){
try {
camera.setPreviewDisplay(surfaceHolder);
camera.startPreview();
previewing = true;
} catch (IOException e)
{
e.printStackTrace();
}
}
}
#SuppressLint("NewApi")
#Override
public void surfaceCreated(SurfaceHolder holder) {
camera = Camera.open(camId);
camera.setDisplayOrientation(90);
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
camera.stopPreview();
camera.release();
camera = null;
previewing = false;
}
}
Picture Handler Class
import java.io.File;
import java.io.FileOutputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import android.content.Context;
import android.hardware.Camera;
import android.hardware.Camera.PictureCallback;
import android.os.Environment;
import android.util.Log;
import android.widget.Toast;
public class PhotoHandler implements PictureCallback {
private final Context context;
public PhotoHandler(Context context) {
this.context = context;
}
#Override
public void onPictureTaken(byte[] data, Camera camera) {
File pictureFileDir = getDir();
if (!pictureFileDir.exists() && !pictureFileDir.mkdirs()) {
// Log.d(MakePhotoActivity.DEBUG_TAG, "Can't create directory to save image.");
Toast.makeText(context, "Can't create directory to save image.",
Toast.LENGTH_LONG).show();
return;
}
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyymmddhhmmss");
String date = dateFormat.format(new Date());
String photoFile = "Picture_" + date + ".jpg";
String filename = pictureFileDir.getPath() + File.separator + photoFile;
Log.e("path", filename.toString());
File pictureFile = new File(filename);
try {
FileOutputStream fos = new FileOutputStream(pictureFile);
fos.write(data);
fos.close();
Toast.makeText(context, "New Image saved:" + photoFile,Toast.LENGTH_LONG).show();
} catch (Exception error) {
// Log.d(MakePhotoActivity.DEBUG_TAG, "File" + filename + "not saved: "
// + error.getMessage());
Toast.makeText(context, "Image could not be saved.",
Toast.LENGTH_LONG).show();
}
}
private File getDir() {
File sdDir = Environment
.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
return new File(sdDir, "Demo App");
}
}
till now i tried this
Thanks
In the takePicture() method one parameter is picture callback. You have to implement that callback and its method on picture taken. It will give you the image data in bytes. You can save the image from there and after that you can do whatever you want to do with that data. This link might help you
http://developer.android.com/reference/android/hardware/Camera.PictureCallback.html

Building my own camera application + Automatically capture the image

I have created my own camera application. And when I click the button it takes the picture and saves it in the galary. What I want to do is to take the picture without a preview and without clicking any button.
My main activity class.
package themiya.camera.android;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import android.app.Activity;
import android.content.Context;
import android.content.pm.PackageManager;
import android.hardware.Camera;
import android.hardware.Camera.PictureCallback;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.view.View;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.Toast;
public class CameraActivity extends Activity {
private Camera mCamera;
private CameraPreview mPreview;
public static final int MEDIA_TYPE_IMAGE = 1;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button captureButton = (Button) findViewById(R.id.button_capture);
System.out.println("Starting!");
// Create an instance of Camera
mCamera = getCameraInstance();
// Create our Preview view and set it as the content of our activity.
mPreview = new CameraPreview(this, mCamera);
FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);
preview.addView(mPreview);
final PictureCallback mPicture = new PictureCallback() {
public void onPictureTaken(byte[] data, Camera camera) {
File pictureFile = getOutputMediaFile(MEDIA_TYPE_IMAGE);
if (pictureFile == null){
return;
}
try {
FileOutputStream fos = new FileOutputStream(pictureFile);
fos.write(data);
fos.close();
MediaStore.Images.Media.insertImage(getContentResolver(), pictureFile.getAbsolutePath(), pictureFile.getName(), pictureFile.getName());
} catch (FileNotFoundException e) {
} catch (IOException e) {
}
}
};
// Add a listener to the Capture button
captureButton.setOnClickListener(
new View.OnClickListener() {
public void onClick(View v) {
// get an image from the camera
System.out.println("Photo Taking!");
mCamera.takePicture(null, null, mPicture);
}
}
);
}
/** A safe way to get an instance of the Camera object. */
public static Camera getCameraInstance(){
Camera c = null;
try {
c = Camera.open(); // attempt to get a Camera instance
}
catch (Exception e){
// Camera is not available (in use or does not exist)
}
return c; // returns null if camera is unavailable
}
#Override
protected void onPause() {
super.onPause();
releaseCamera(); // release the camera immediately on pause event
}
private void releaseCamera(){
if (mCamera != null){
mCamera.release(); // release the camera for other applications
mCamera = null;
}
}
/** Create a File for saving an image or video */
private File getOutputMediaFile(int type){
// To be safe, you should check that the SDCard is mounted
// using Environment.getExternalStorageState() before doing this.
File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES), "MyCameraApp");
// This location works best if you want the created images to be shared
// between applications and persist after your app has been uninstalled.
// Create the storage directory if it does not exist
if (! mediaStorageDir.exists()){
if (! mediaStorageDir.mkdirs()){
return null;
}
}
// Create a media file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
File mediaFile;
if (type == MEDIA_TYPE_IMAGE){
mediaFile = new File(mediaStorageDir.getPath() + File.separator +
"IMG_"+ timeStamp + ".jpg");
} else {
return null;
}
return mediaFile;
}
}
And the preview class.
package themiya.camera.android;
import android.content.Context;
import android.hardware.Camera;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback{
private SurfaceHolder mHolder;
private Camera mCamera;
public CameraPreview(Context context,Camera camera) {
super(context);
mCamera = camera;
/*SurfaceView view = new SurfaceView(this);
c.setPreviewDisplay(view.getHolder());
c.startPreview();
c.takePicture(shutterCallback, rawPictureCallback, jpegPictureCallback);
* */
// Install a SurfaceHolder.Callback so we get notified when the
// underlying surface is created and destroyed.
mHolder = getHolder();
mHolder.addCallback(this);
// deprecated setting, but required on Android versions prior to 3.0
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
// TODO Auto-generated method stub
if (mHolder.getSurface() == null){
// preview surface does not exist
return;
}
// stop preview before making changes
try {
mCamera.stopPreview();
} catch (Exception e){
// ignore: tried to stop a non-existent preview
}
// set preview size and make any resize, rotate or
// reformatting changes here
// start preview with new settings
try {
mCamera.setPreviewDisplay(mHolder);
mCamera.startPreview();
} catch (Exception e){
}
}
public void surfaceCreated(SurfaceHolder holder) {
// TODO Auto-generated method stub
}
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
}
}
In the activity class the on click method is like this.
captureButton.setOnClickListener(
new View.OnClickListener() {
public void onClick(View v) {
// get an image from the camera
System.out.println("Photo Taking!");
mCamera.takePicture(null, null, mPicture);
}
}
);
And when I remove that listener part and put only the
mCamera.takePicture(null, null, mPicture);
part application crashes. I think that may be due to the delay that the application takes to open the camera. So code try to get the photo before opening the camera. Also wait(10000); didn't work for me.
And also I want to take the picture without the preview. According to my knowledge I have to change the preview class to do that. But I don't know the correct way to do it.
Can anyone help me with this asp.
the trick is to give the Camera Class a SurfaceView which is not part of the view hierarchy. The following code is from one of my apps where i used this technique to display my own
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
#Override
protected void onPause() {
super.onPause();
if (mCamera != null) {
mCamera.stopPreview();
mCamera.release();
mCamera = null;
}
}
#Override
protected void onResume() {
super.onResume();
mCamera = Camera.open();
startPreview();
}
private void startPreview() {
if (mCamera != null) {
mCamera.stopPreview();
try {
mCamera.setPreviewDisplay(new SurfaceView(this).getHolder());
} catch (IOException e) {
e.printStackTrace();
}
mCamera.setPreviewCallbackWithBuffer(this);
Camera.Parameters parameters = mCamera.getParameters();
parameters.setPreviewSize(IMAGE_W, IMAGE_H);
mCamera.setParameters(parameters);
PixelFormat p = new PixelFormat();
PixelFormat.getPixelFormatInfo(parameters.getPreviewFormat(), p);
int bufSize = (IMAGE_W * IMAGE_H * p.bitsPerPixel) / 8;
mCamera.addCallbackBuffer(new byte[bufSize]);
mCamera.startPreview();
}
}
public void onPreviewFrame(final byte[] data, Camera camera) {
if (mCamera == null) {
return;
}
mCamera.addCallbackBuffer(data);
}
}
Ok I found a answer to take the picture automatically. Adding as a comment for the use of others.
final Timer t = new Timer();
t.schedule(new TimerTask() {
#Override
public void run() {
mCamera.takePicture(null, null, mPicture); t.cancel();
}
},5000);
its simple create another method with a timer variable with 10000 delay which finishes the activity of previewing then you will be done. The logic is that these method will run 5secs after timer 1 activity is done.

Categories

Resources