I am using custom camera in my application this works fine in jelly bean. Now after this Samsung Galaxy Tab OS update the custom camera is broken. I got this report from one of my friend i didn't saw that tablet. And i got crash report form Carshylytics.
My log report:
java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.x.y/com.x.y.tools.EnregistrementVideoStackActivity}: java.lang.RuntimeException: Unable to initialize media recorder
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2053)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2154)
at android.app.ActivityThread.access$700(ActivityThread.java:146)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1260)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4949)
at java.lang.reflect.Method.invokeNative(Method.java)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1043)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:810)
at dalvik.system.NativeStart.main(NativeStart.java)
Caused by: java.lang.RuntimeException: Unable to initialize media recorder
at android.media.MediaRecorder.native_setup(MediaRecorder.java)
at android.media.MediaRecorder.<init>(MediaRecorder.java:121)
at com.x.y.tools.EnregistrementVideoStackActivity.<init>(EnregistrementVideoStackActivity.java:38)
at java.lang.Class.newInstanceImpl(Class.java)
at java.lang.Class.newInstance(Class.java:1319)
at android.app.Instrumentation.newActivity(Instrumentation.java:1068)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2044)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2154)
at android.app.ActivityThread.access$700(ActivityThread.java:146)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1260)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4949)
at java.lang.reflect.Method.invokeNative(Method.java)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1043)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:810)
at dalvik.system.NativeStart.main(NativeStart.java)
And this error line is
public MediaRecorder mrec = new MediaRecorder();
Why it is happen have any idea? How can i solve this issue. I hope the camera code is not needed. But anyone want to see the code i can post here.
EDIT:
My EnregistrementVideoStackActivity class:
public class EnregistrementVideoStackActivity extends Activity implements
SurfaceHolder.Callback {
private SurfaceHolder surfaceHolder;
private SurfaceView surfaceView;
public MediaRecorder mrec = new MediaRecorder();
private Button startRecording = null;
private Button stopRecording = null;
File video;
private Camera mCamera;
private String output_path;
boolean isActivityRestarting = false;
Chronometer myChronometer;
Boolean recording = false;
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
if (recording == false) {
finish();
} else {
stopRecording();
}
return true;
}
return super.onKeyDown(keyCode, event);
}
#Override
protected void onDestroy() {
super.onDestroy();
}
#Override
public void onRestart() {
super.onRestart();
isActivityRestarting = true;
finish();
}
#Override
public void onCreate(Bundle savedInstanceState) {
if (isActivityRestarting) {
return;
}
super.onCreate(savedInstanceState);
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
/*getWindow().setFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON,
WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);*/
setContentView(R.layout.camera_surface);
Intent intent = getIntent();
output_path = intent.getStringExtra("path");
startRecording = (Button) findViewById(R.id.buttonstart);
stopRecording = (Button) findViewById(R.id.buttonstop);
try {
// This case can actually happen if the user opens and closes the
// camera too frequently.
// The problem is that we cannot really prevent this from happening
// as the user can easily
// get into a chain of activites and tries to escape using the back
// button.
// The most sensible solution would be to quit the entire EPostcard
// flow once the picture is sent.
mCamera = Camera.open();
} catch (Exception e) {
Toast.makeText(getApplicationContext(),
"Please restart device, camera error", Toast.LENGTH_LONG)
.show();
finish();
return;
}
surfaceView = (SurfaceView) findViewById(R.id.surface_camera);
surfaceHolder = surfaceView.getHolder();
surfaceHolder.addCallback(this);
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
myChronometer = (Chronometer) findViewById(R.id.chronometer1);
startRecording.setOnClickListener(new OnClickListener() {
public void onClick(View arg0) {
try {
startRecording();
myChronometer.setBase(SystemClock.elapsedRealtime());
myChronometer.start();
startRecording.setClickable(false);
} catch (Exception e) {
e.getMessage();
e.printStackTrace();
mrec.release();
}
}
});
stopRecording.setOnClickListener(new OnClickListener() {
public void onClick(View arg0) {
try {
stopRecording();
myChronometer.stop();
Intent intent = getIntent();
intent.putExtra("gallery", "viewed");
setResult(RESULT_OK, intent);
} catch (Exception e) {
e.getMessage();
}
}
});
myChronometer
.setOnChronometerTickListener(new Chronometer.OnChronometerTickListener() {
public void onChronometerTick(Chronometer chronometer) {
long myElapsedMillis = SystemClock.elapsedRealtime()
- myChronometer.getBase();
if (myElapsedMillis >= 120000) {
Toast.makeText(getApplicationContext(),
"Maximum Video limit reached",
Toast.LENGTH_LONG).show();
stopRecording();
}
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
menu.add(0, 0, 0, "StartRecording");
menu.add(0, 1, 0, "StopRecording");
return super.onCreateOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case 0:
try {
startRecording();
} catch (Exception e) {
String message = e.getMessage();
Log.e(null, "Problem Start" + message);
mrec.release();
}
break;
case 1: // GoToAllNotes
mrec.stop();
mrec.release();
mrec = null;
break;
default:
break;
}
return super.onOptionsItemSelected(item);
}
protected void startRecording() throws IOException {
recording = true;
mrec = new MediaRecorder(); // Works well
mCamera.unlock();
mrec.setCamera(mCamera);
mrec.setVideoSource(MediaRecorder.VideoSource.CAMERA);
mrec.setAudioSource(MediaRecorder.AudioSource.MIC);
mrec.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
mrec.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
mrec.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
int width = 320;
int height = 240;
try {
// Check what resolutions are supported by your camera
List<Size> sizes = params.getSupportedPictureSizes();
for (Size size : sizes) {
Log.e("TAG", "Available resolution: " + size.width + " "
+ size.height);
width = size.width;
height = size.height;
}
} catch (Exception e) {
e.printStackTrace();
}
mrec.setVideoFrameRate(30);
mrec.setVideoSize(width, height);
mrec.setVideoEncodingBitRate(1700000);
mrec.setPreviewDisplay(surfaceHolder.getSurface());
mrec.setOutputFile(output_path);
mrec.prepare();
mrec.start();
}
protected void stopRecording() {
try {
Log.e("stop recording", "Stop recording");
recording = false;
mrec.stop();
mrec.release();
mCamera.release();
// go out
Toast.makeText(getApplicationContext(),
"New Video Observation Saved", Toast.LENGTH_LONG).show();
} catch (Exception npe) {
npe.printStackTrace();
}
Intent intent = getIntent();
setResult(RESULT_OK, intent);
finish();
}
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
//
}
Parameters params;
public void surfaceCreated(SurfaceHolder holder) {
if (!isActivityRestarting) {
if (mCamera != null) {
params = mCamera.getParameters();
mCamera.setParameters(params);
} else {
Toast.makeText(getApplicationContext(),
"Camera not available!", Toast.LENGTH_LONG).show();
finish();
}
}
}
public void surfaceDestroyed(SurfaceHolder holder) {
try {
if (mCamera != null) {
mCamera.stopPreview();
mCamera.release();
mCamera.setPreviewCallback(null);
mCamera = null;
}
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
protected void onPause() {
super.onPause();
if (recording == false) {
finish();
} else {
stopRecording();
}
}
}
I got the error Because of Video sizes are not set. I solve this
int width = 320;
int height = 240;
try {
//get the available sizes of the video
List<Size> tmpList = getSupportedVideoSizes();
final List<Size> sizeList = new Vector<Size>();
// compare the apsect ratio of the candidate sizes against the
// real ratio
Double aspectRatio = (Double.valueOf(getWindowManager()
.getDefaultDisplay().getHeight()) / getWindowManager()
.getDefaultDisplay().getWidth());
for (int i = tmpList.size() - 1; i > 0; i--) {
Double tmpRatio = Double.valueOf(tmpList.get(i).height)
/ tmpList.get(i).width;
if (Math.abs(aspectRatio - tmpRatio) < .15) {
width = tmpList.get(i).width;
height = tmpList.get(i).height;
sizeList.add(tmpList.get(i));
}
}
if (EnableLog.LOG_TAG) {
Log.e("tmpList", tmpList + "*");
}
} catch (Exception e) {
e.printStackTrace();
}
mrec.setVideoSize(width, height);
public List<Size> getSupportedVideoSizes() {
if (params.getSupportedVideoSizes() != null) {
return params.getSupportedVideoSizes();
} else {
// Video sizes may be null, which indicates that all the supported
// preview sizes are supported for video recording.
return params.getSupportedPreviewSizes();
}
}
Related
I want to capture image previewed in surfaceView.Capturing time is every 42 millisecond.While capturing I want to send these images to the server as byteArray at this moment.For security reason, photo cant is saved to sd.I must use this for making a video call.Can anyone help me?Pls
Button take;
Camera camera;
SurfaceView surfaceView;
SurfaceHolder surfaceHolder;
Camera.PictureCallback jpegCallback;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
checkPermission();
surfaceView = (SurfaceView) findViewById(R.id.surface);
surfaceHolder = surfaceView.getHolder();
take = (Button) findViewById(R.id.take);
take.setOnClickListener(this);
// Install a SurfaceHolder.Callback so we get notified when the
// underlying surface is created and destroyed.
surfaceHolder.addCallback(this);
// deprecated setting, but required on Android versions prior to 3.0
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
jpegCallback = new Camera.PictureCallback() {
public void onPictureTaken(byte[] data, Camera camera) {
FileOutputStream outStream = null;
try {
outStream = new FileOutputStream(String.format("/sdcard/%d.jpg", System.currentTimeMillis()));
outStream.write(data);
outStream.close();
Log.d("Log", "onPictureTaken - wrote bytes: " + data.length);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
}
Toast.makeText(getApplicationContext(), "Picture Saved", Toast.LENGTH_SHORT).show();
refreshCamera();
}
};
}
public void captureImage() throws IOException {
//take the picture
camera.takePicture(null, null, jpegCallback);
}
#Override
public void surfaceCreated(SurfaceHolder surfaceHolder) {
try {
// open the camera
camera = Camera.open();
} catch (RuntimeException e) {
// check for exceptions
System.err.println(e);
return;
}
Camera.Parameters param;
param = camera.getParameters();
// modify parameter
List<Camera.Size> sizes = param.getSupportedPreviewSizes();
Camera.Size selected = sizes.get(0);
param.setPreviewSize(selected.width,selected.height);
camera.setParameters(param);
try {
// The Surface has been created, now tell the camera where to draw
// the preview.
camera.setDisplayOrientation(90);
camera.setPreviewDisplay(surfaceHolder);
camera.startPreview();
} catch (Exception e) {
// check for exceptions
System.err.println(e);
return;
}
}
#Override
public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {
// Now that the size is known, set up the camera parameters and begin
// the preview.
refreshCamera();
}
#Override
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
// stop preview and release camera
camera.stopPreview();
camera.release();
camera = null;
}
public void refreshCamera() {
if (surfaceHolder.getSurface() == null) {
// preview surface does not exist
return;
}
// set preview size and make any resize, rotate or
// reformatting changes here
// start preview with new settings
try {
camera.setPreviewDisplay(surfaceHolder);
camera.startPreview();
} catch (Exception e) {
}
}
private void requestPermission() {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, 1);
}
private boolean checkPermission() {
int result = ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA);
if (result == PackageManager.PERMISSION_GRANTED) {
return true;
} else {
return false;
}
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
switch (requestCode) {
case 1:
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
} else {
}
break;
}
}
#Override
public void onPointerCaptureChanged(boolean hasCapture) {
}
#Override
public void onClick(View v) {
switch (v.getId()){
case R.id.take:{
try {
captureImage();
} catch (IOException e) {
e.printStackTrace();
}
break;
}
}
}
So while previewing in SurfaceView I must get every 42 millis photo as byteArray and send it
I found solution to my problem. I have fixed it through setPreviewCallbackWithBuffer an onPreviewFrame.There is no need neither handler nor timer...
private Camera camera;
private SurfaceView surfaceView;
private SurfaceHolder surfaceHolder;
private ImageView endCallBtn;
private ImageView micBtn;
private ImageView visibilityBtn;
private ImageView cameraBtn;
private Boolean clickedForMic = false;
private Boolean clickedForCamera = false;
private Boolean clickedForVisiblity = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_video_call);
surfaceView = (SurfaceView) findViewById(R.id.surfaceView);
surfaceHolder = surfaceView.getHolder();
surfaceHolder.addCallback(this);
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_NORMAL);
if (Build.VERSION.SDK_INT >= 23) {
if (checkPermission()) {
Log.e("permission", "Permission already granted.");
} else {
requestPermission();
}
}
endCallBtn = (ImageView) findViewById(R.id.endCallBtn);
endCallBtn.setOnClickListener(this);
micBtn = (ImageView) findViewById(R.id.micBtn);
micBtn.setImageResource(R.drawable.ic_mic_white_48px);
micBtn.setOnClickListener(this);
visibilityBtn = (ImageView) findViewById(R.id.visibilityBtn);
visibilityBtn.setImageResource(R.drawable.ic_visibility_white_48px);
visibilityBtn.setOnClickListener(this);
cameraBtn = (ImageView) findViewById(R.id.cameraBtn);
cameraBtn.setImageResource(R.drawable.ic_camera_rear_white_48px);
cameraBtn.setOnClickListener(this);
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.cameraBtn: {
if (clickedForCamera == false) {
if (clickedForVisiblity == true) {
Toast.makeText(VideoCallActivity.this, "Видимость камеры заблокирована", Toast.LENGTH_SHORT).show();
} else {
stopCamera();
startCameraBack();
cameraBtn.setImageResource(R.drawable.ic_camera_front_white_48px);
clickedForCamera = true;
}
} else {
if (clickedForVisiblity == true) {
Toast.makeText(VideoCallActivity.this, "Видимость камеры заблокирована", Toast.LENGTH_SHORT).show();
} else {
stopCamera();
startCameraFront();
cameraBtn.setImageResource(R.drawable.ic_camera_rear_white_48px);
clickedForCamera = false;
}
}
break;
}
case R.id.micBtn: {
if (clickedForMic == false) {
micBtn.setImageResource(R.drawable.ic_mic_off_white_48px);
micBtn.setColorFilter(Color.parseColor("#00897B"));
clickedForMic = true;
} else {
micBtn.setImageResource(R.drawable.ic_mic_white_48px);
micBtn.setColorFilter(Color.parseColor("#ffffff"));
clickedForMic = false;
}
break;
}
case R.id.endCallBtn: {
stopCamera();
finish();
overridePendingTransition(R.anim.window3, R.anim.window4);
break;
}
case R.id.visibilityBtn: {
if (clickedForVisiblity == false) {
camera.stopPreview();
visibilityBtn.setImageResource(R.drawable.ic_visibility_off_white_48px);
visibilityBtn.setColorFilter(Color.parseColor("#00897B"));
clickedForVisiblity = true;
} else {
camera.startPreview();
visibilityBtn.setImageResource(R.drawable.ic_visibility_white_48px);
visibilityBtn.setColorFilter(Color.parseColor("#ffffff"));
clickedForVisiblity = false;
}
break;
}
}
}
private void requestPermission() {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, 1);
}
private boolean checkPermission() {
int result = ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA);
if (result == PackageManager.PERMISSION_GRANTED) {
return true;
} else {
return false;
}
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
switch (requestCode) {
case 1:
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
} else {
}
break;
}
}
private void stopCamera() {
camera.stopPreview();
camera.release();
}
private void startCameraFront() {
if (checkPermission()) {
try {
camera = Camera.open(Camera.CameraInfo.CAMERA_FACING_FRONT);
} catch (Exception e) {
return;
}
Camera.Parameters param;
camera.setDisplayOrientation(90);
param = camera.getParameters();
param.setPreviewFrameRate(24);
param.setPreviewFpsRange(22000, 30000);
camera.setParameters(param);
try {
camera.setPreviewDisplay(surfaceHolder);
} catch (Exception e) {
return;
}
Log.v("CameraTest", "Camera PreviewFrameRate = " + camera.getParameters().getPreviewFrameRate());
Camera.Size previewSize = camera.getParameters().getPreviewSize();
int dataBufferSize = (int) (previewSize.height * previewSize.width *
(ImageFormat.getBitsPerPixel(camera.getParameters().getPreviewFormat()) / 8.0));
camera.addCallbackBuffer(new byte[dataBufferSize]);
camera.addCallbackBuffer(new byte[dataBufferSize]);
camera.addCallbackBuffer(new byte[dataBufferSize]);
camera.setPreviewCallbackWithBuffer(new Camera.PreviewCallback() {
private long timestamp = 0;
public synchronized void onPreviewFrame(byte[] data, Camera camera) {
//Log.v("CameraTest", "Time Gap = " + (System.currentTimeMillis() - timestamp));
Log.v("CameraTest", " data: " + String.valueOf(data.length));
timestamp = System.currentTimeMillis();
try {
camera.addCallbackBuffer(data);
} catch (Exception e) {
Log.e("CameraTest", "addCallbackBuffer error");
return;
}
return;
}
});
camera.startPreview();
}
}
private void startCameraBack() {
if (checkPermission()) {
try {
camera = Camera.open(Camera.CameraInfo.CAMERA_FACING_BACK);
} catch (Exception e) {
return;
}
Camera.Parameters param;
camera.setDisplayOrientation(90);
param = camera.getParameters();
//modify parameter
param.setPreviewFrameRate(30);
camera.setParameters(param);
try {
camera.setPreviewDisplay(surfaceHolder);
camera.startPreview();
} catch (Exception e) {
Log.d("Problema", e.toString());
return;
}
}
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
startCameraFront();
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
}
I am making Instagram like app in which there are different screens for capturing image and recording image. My problem is that when I run my app with both fragment then my app crashes leaving error :
FATAL EXCEPTION: main
java.lang.RuntimeException: Fail to connect to camera service
at android.hardware.Camera.native_setup(Native Method)
at android.hardware.Camera.<init>(Camera.java:428)
at android.hardware.Camera.open(Camera.java:389)
at textileapp.ebizz.com.myapplication.VideoFragment.onCreateView(VideoFragment.java:55)
But when I ran my app with only one fragment either camera screen ot video recorder screen, then it works fine. But with both fragment together app crashes. Ca any one help with this.
My code:
Camera Fragment
import android.hardware.Camera;
import android.os.Bundle;
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.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.Toast;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class CameraFragment extends Fragment implements View.OnClickListener, SurfaceHolder.Callback {
private View rootView;
private Camera camera;
SurfaceView surfaceView;
SurfaceHolder surfaceHolder;
Camera.PictureCallback rawCallback;
Camera.ShutterCallback shutterCallback;
Camera.PictureCallback jpegCallback;
LinearLayout capture;
private int mId = 0;
ImageView change_camera, flash_icon;
private String mFlashMode="Camera.Parameters.FLASH_MODE_ON";
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.fragment_camera, container, false);
defineIds(rootView);
handleClick();
change_camera.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (Camera.getNumberOfCameras() >= 2) {
releaseCamera();
chooseCamera();
}
}
});
flash_icon.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (mFlashMode.equalsIgnoreCase(Camera.Parameters.FLASH_MODE_AUTO)) {
mFlashMode = Camera.Parameters.FLASH_MODE_ON;
} else if (mFlashMode.equalsIgnoreCase(Camera.Parameters.FLASH_MODE_ON)) {
mFlashMode = Camera.Parameters.FLASH_MODE_OFF;
} else if (mFlashMode.equalsIgnoreCase(Camera.Parameters.FLASH_MODE_OFF)) {
mFlashMode = Camera.Parameters.FLASH_MODE_AUTO;
}
}
});
return rootView;
}
private void releaseCamera() {
// stop and release camera
if (camera != null) {
camera.release();
camera = null;
}
}
public void chooseCamera() {
//if the camera preview is the front
if (mId == 1) {
camera = Camera.open(0);
refreshCamera();
mId=0;
} else if (mId == 0) {
camera = Camera.open(1);
camera.setDisplayOrientation(90);
refreshCamera();
mId=1;
}
}
private void defineIds(View view) {
capture = (LinearLayout) view.findViewById(R.id.capture);
change_camera= (ImageView) view.findViewById(R.id.change_camera);
flash_icon= (ImageView) view.findViewById(R.id.flash_icon);
surfaceView = (SurfaceView) view.findViewById(R.id.surfaceView);
surfaceHolder = surfaceView.getHolder();
surfaceHolder.addCallback(this);
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
jpegCallback = new Camera.PictureCallback() {
public void onPictureTaken(byte[] data, Camera camera) {
FileOutputStream outStream = null;
try {
outStream = new FileOutputStream(String.format("/sdcard/%d.jpg", System.currentTimeMillis()));
outStream.write(data);
outStream.close();
Log.d("Log", "onPictureTaken - wrote bytes: " + data.length);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
}
Toast.makeText(getActivity(), "Picture Saved", Toast.LENGTH_LONG).show();
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;
}
// stop preview before making changes
try {
camera.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 {
camera.setPreviewDisplay(surfaceHolder);
camera.startPreview();
} catch (Exception e) {
}
}
private void handleClick() {
capture.setOnClickListener(this);
}
#Override
public void onClick(View v) {
switch (v.getId()){
case R.id.capture:
try {
captureImage(v);
} catch (IOException e) {
e.printStackTrace();
}
}
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
try {
// open the camera
camera = Camera.open(0);
} catch (RuntimeException e) {
// check for exceptions
System.err.println(e);
return;
}
Camera.Parameters param;
param = camera.getParameters();
// modify parameter
param.setPreviewSize(352, 288);
camera.setParameters(param);
try {
// The Surface has been created, now tell the camera where to draw
// the preview.
camera.setPreviewDisplay(surfaceHolder);
camera.startPreview();
} catch (Exception e) {
// check for exceptions
System.err.println(e);
return;
}
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
// Now that the size is known, set up the camera parameters and begin
// the preview.
refreshCamera();
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
// stop preview and release camera
camera.stopPreview();
camera.release();
camera = null;
}
public void onDestroy(){
super.onDestroy();
camera.release();
}
}
Video Fragment
public class VideoFragment extends Fragment {
private Camera mCamera;
private CameraPreview mPreview;
private MediaRecorder mediaRecorder;
private ImageView record_image_button, change_camera;
private Context myContext;
private LinearLayout cameraPreview;
private boolean cameraFront = false;
private View rootView;
/* #Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}*/
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.fragment_video, container, false);
// getActivity().getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
myContext = getActivity();
initialize();
if (!hasCamera(myContext)) {
Toast toast = Toast.makeText(myContext, "Sorry, your phone does not have a camera!", Toast.LENGTH_LONG);
toast.show();
}
if (mCamera == null) {
// if the front facing camera does not exist
if (findFrontFacingCamera() < 0) {
Toast.makeText(getActivity(), "No front facing camera found.", Toast.LENGTH_LONG).show();
change_camera.setVisibility(View.GONE);
}
mCamera = Camera.open(findBackFacingCamera());
mPreview.refreshCamera(mCamera);
}
return rootView;
}
private int findFrontFacingCamera() {
int cameraId = -1;
// Search for the front facing camera
int numberOfCameras = Camera.getNumberOfCameras();
for (int i = 0; i < numberOfCameras; i++) {
Camera.CameraInfo info = new Camera.CameraInfo();
Camera.getCameraInfo(i, info);
if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
cameraId = i;
cameraFront = true;
break;
}
}
return cameraId;
}
private int findBackFacingCamera() {
int cameraId = -1;
// Search for the back facing camera
// get the number of cameras
int numberOfCameras = Camera.getNumberOfCameras();
// for every camera check
for (int i = 0; i < numberOfCameras; i++) {
Camera.CameraInfo info = new Camera.CameraInfo();
Camera.getCameraInfo(i, info);
if (info.facing == Camera.CameraInfo.CAMERA_FACING_BACK) {
cameraId = i;
cameraFront = false;
break;
}
}
return cameraId;
}
public void initialize() {
cameraPreview = (LinearLayout)rootView. findViewById(R.id.camera_preview);
mPreview = new CameraPreview(myContext, mCamera);
cameraPreview.addView(mPreview);
record_image_button = (ImageView) rootView. findViewById(R.id.record_image_button);
record_image_button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(getActivity(), "Hold down the button to record video", Toast.LENGTH_LONG).show();
}
});
record_image_button.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN ) {
Log.e("CLCIKEVENT", String.valueOf(event));
if (!prepareMediaRecorder()) {
Toast.makeText(getActivity(), "Fail in prepareMediaRecorder()!\n - Ended -", Toast.LENGTH_LONG).show();
// finish();
}
// work on UiThread for better performance
getActivity().runOnUiThread(new Runnable() {
public void run() {
// If there are stories, add them to the table
try {
mediaRecorder.start();
} catch (final Exception ex) {
// Log.i("---","Exception in thread");
}
}
});
recording = true;
} else if (event.getAction() == MotionEvent.ACTION_UP||
event.getAction() == MotionEvent.ACTION_CANCEL) {
mediaRecorder.stop(); // stop the recording
releaseMediaRecorder(); // release the MediaRecorder object
Toast.makeText(getActivity(), "Video captured!", Toast.LENGTH_LONG).show();
recording = false;
}
return false;
}
});
change_camera = (ImageView) rootView. findViewById(R.id.change_camera);
change_camera.setOnClickListener(switchCameraListener);
}
View.OnClickListener switchCameraListener = new View.OnClickListener() {
#Override
public void onClick(View v) {
// get the number of cameras
if (!recording) {
int camerasNumber = Camera.getNumberOfCameras();
if (camerasNumber > 1) {
// release the old camera instance
// switch camera, from the front and the back and vice versa
releaseCamera();
chooseCamera();
} else {
Toast toast = Toast.makeText(myContext, "Sorry, your phone has only one camera!", Toast.LENGTH_LONG);
toast.show();
}
}
}
};
public void chooseCamera() {
// if the camera preview is the front
if (cameraFront) {
int cameraId = findBackFacingCamera();
if (cameraId >= 0) {
// open the backFacingCamera
// set a picture callback
// refresh the preview
mCamera = Camera.open(cameraId);
// mPicture = getPictureCallback();
mPreview.refreshCamera(mCamera);
}
} else {
int cameraId = findFrontFacingCamera();
if (cameraId >= 0) {
// open the backFacingCamera
// set a picture callback
// refresh the preview
mCamera = Camera.open(cameraId);
// mPicture = getPictureCallback();
mPreview.refreshCamera(mCamera);
}
}
}
#Override
public void onPause() {
super.onPause();
// when on Pause, release camera in order to be used from other
// applications
releaseCamera();
}
private boolean hasCamera(Context context) {
// check if the device has camera
if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)) {
return true;
} else {
return false;
}
}
boolean recording = false;
View.OnClickListener captrureListener = new View.OnClickListener() {
#Override
public void onClick(View v) {
if (recording) {
// stop recording and release camera
mediaRecorder.stop(); // stop the recording
releaseMediaRecorder(); // release the MediaRecorder object
Toast.makeText(getActivity(), "Video captured!", Toast.LENGTH_LONG).show();
recording = false;
} else {
if (!prepareMediaRecorder()) {
Toast.makeText(getActivity(), "Fail in prepareMediaRecorder()!\n - Ended -", Toast.LENGTH_LONG).show();
// finish();
}
// work on UiThread for better performance
getActivity().runOnUiThread(new Runnable() {
public void run() {
// If there are stories, add them to the table
try {
mediaRecorder.start();
} catch (final Exception ex) {
// Log.i("---","Exception in thread");
}
}
});
recording = true;
}
}
};
private void releaseMediaRecorder() {
if (mediaRecorder != null) {
mediaRecorder.reset(); // clear recorder configuration
mediaRecorder.release(); // release the recorder object
mediaRecorder = null;
mCamera.lock(); // lock camera for later use
}
}
private boolean prepareMediaRecorder() {
mediaRecorder = new MediaRecorder();
mCamera.unlock();
mediaRecorder.setCamera(mCamera);
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
mediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_LOW));
mediaRecorder.setOutputFile("/sdcard/myvideo.mp4");
mediaRecorder.setMaxDuration(600000); // Set max duration 60 sec.
mediaRecorder.setMaxFileSize(50000000); // Set max file size 50M
try {
mediaRecorder.prepare();
} catch (IllegalStateException e) {
releaseMediaRecorder();
return false;
} catch (IOException e) {
releaseMediaRecorder();
return false;
}
return true;
}
private void releaseCamera() {
// stop and release camera
if (mCamera != null) {
mCamera.release();
mCamera = null;
}}
Camera Preview for Video Record
public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
private SurfaceHolder mHolder;
private Camera mCamera;
public CameraPreview(Context context, Camera camera) {
super(context);
mCamera = camera;
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 surfaceCreated(SurfaceHolder holder) {
try {
// create the surface and start camera preview
if (mCamera == null) {
mCamera.setPreviewDisplay(holder);
mCamera.startPreview();
}
} catch (IOException e) {
Log.d(VIEW_LOG_TAG, "Error setting camera preview: " + e.getMessage());
}
}
public void refreshCamera(Camera camera) {
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
setCamera(camera);
try {
mCamera.setPreviewDisplay(mHolder);
mCamera.startPreview();
} catch (Exception e) {
Log.d(VIEW_LOG_TAG, "Error starting camera preview: " + e.getMessage());
}
}
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
// If your preview can change or rotate, take care of those events here.
// Make sure to stop the preview before resizing or reformatting it.
refreshCamera(mCamera);
}
public void setCamera(Camera camera) {
//method to set a camera instance
mCamera = camera;
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
// mCamera.release();
}
Any help will be appreciated.
If anyone get then please help me with this.
I want to make an app that record video, it seems like vine, hold to record, release it stop, hold to record and keep that to the end.
I have used MediaRecorder, but it just record once a time, if I start record again, app is crashed.
Please tell me there is any way to do this?
I edited my code:
public class VideoRecordingActivity extends AppCompatActivity implements View.OnTouchListener, View.OnLongClickListener {
private Context myContext;
private boolean hasCamera;
private boolean onRecording;
private Camera mCamera;
private CameraPreview mPreview;
private MediaRecorder mediaRecorder;
private boolean cameraFront = false;
private int cameraId;
private int videoNumer;
private boolean isActionDown = false;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_video_introduction_recording);
initUI();
initialize();
}
private LinearLayout lnCameraPreview;
private ImageButton btn_recording;
private void initUI() {
lnCameraPreview = (LinearLayout) findViewById(R.id.ln_body_recording);
btn_recording = (ImageButton) findViewById(R.id.btn_recording);
}
public void initialize() {
myContext = this;
mPreview = new CameraPreview(this, cameraId, mCamera);
lnCameraPreview.addView(mPreview);
btn_recording.setOnLongClickListener(this);
btn_recording.setOnTouchListener(this);
videoNumer = 0;
}
public boolean onLongClick(View v) {
isActionDown = true;
try {
boolean isPrepared = false;
if (isActionDown)
isPrepared = prepareMediaRecorder();
if (isPrepared && isActionDown) {
// work on UiThread for better performance
runOnUiThread(new Runnable() {
public void run() {
mediaRecorder.start();
onRecording = true;
}
});
}
} catch (Exception e) {
e.printStackTrace();
Log.e("onLongPress Error ", e.toString());
}
return true;
}
#Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_UP:
isActionDown = false;
try {
if (onRecording) {
if (mediaRecorder != null) {
mediaRecorder.stop();
}
onRecording = false;
videoNumer++;
}
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
break;
}
return false;
}
public void onResume() {
super.onResume();
if (!hasCamera(myContext)) {
Toast.makeText(myContext, "Sorry, your phone does not have a camera!", Toast.LENGTH_LONG).show();
return;
}
initCamera();
}
#Override
protected void onPause() {
super.onPause();
// when on Pause, release camera in order to be used from other
// applications
releaseCamera();
}
private final int cMaxRecordDurationInMs = 30000;
private final long cMaxFileSizeInBytes = 5000000;
private final int cFrameRate = 20;
private File prRecordedFile;
#SuppressLint("SdCardPath")
private boolean prepareMediaRecorder() {
mediaRecorder = new MediaRecorder();
try {
mCamera.unlock();
} catch (Exception ex) {
return false;
}
// adjust the camera the way you need
mediaRecorder.setCamera(mCamera);
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.DEFAULT);
mediaRecorder.setVideoSource(MediaRecorder.VideoSource.DEFAULT);
//
CamcorderProfile cpHigh = CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH);
mediaRecorder.setProfile(cpHigh);
mediaRecorder.setPreviewDisplay(mPreview.getHolder().getSurface());
mediaRecorder.setOutputFile("/sdcard/" + videoNumer + "videocapture_example.mp4");
//set max size
mediaRecorder.setMaxDuration(600000); // Set max duration 60 sec.
mediaRecorder.setMaxFileSize(50000000); // Set max file size 50M
try {
mediaRecorder.prepare();
} catch (Exception e) {
releaseMediaRecorder();
e.printStackTrace();
}
return true;
}
private void releaseMediaRecorder() {
if (mediaRecorder != null) {
mediaRecorder.reset(); // clear recorder configuration
mediaRecorder.release(); // release the recorder object
mediaRecorder = null;
if (mCamera != null) {
mCamera.lock(); // lock camera for later use
}
}
}
/**
* Camera
*/
private void initCamera() {
if (mCamera == null) {
// if the front facing camera does not exist
if (findFrontFacingCamera() < 0) {
Toast.makeText(this, "No front facing camera found.", Toast.LENGTH_LONG).show();
}
mCamera = Camera.open(findBackFacingCamera());
mPreview.refreshCamera(mCamera);
}
onRecording = false;
}
private boolean hasCamera(Context context) {
// check if the device has camera
if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)) {
hasCamera = true;
} else {
hasCamera = false;
}
return hasCamera;
}
private int findFrontFacingCamera() {
int cameraId = -1;
// Search for the front facing camera
int numberOfCameras = Camera.getNumberOfCameras();
for (int i = 0; i < numberOfCameras; i++) {
Camera.CameraInfo info = new Camera.CameraInfo();
Camera.getCameraInfo(i, info);
if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
cameraId = i;
cameraFront = true;
break;
}
}
this.cameraId = cameraId;
return cameraId;
}
private int findBackFacingCamera() {
int cameraId = -1;
// Search for the back facing camera
// get the number of cameras
int numberOfCameras = Camera.getNumberOfCameras();
// for every camera check
for (int i = 0; i < numberOfCameras; i++) {
Camera.CameraInfo info = new Camera.CameraInfo();
Camera.getCameraInfo(i, info);
if (info.facing == Camera.CameraInfo.CAMERA_FACING_BACK) {
cameraId = i;
cameraFront = false;
break;
}
}
this.cameraId = cameraId;
return cameraId;
}
public void switchCamera() {
// if the camera preview is the front
if (cameraFront) {
int cameraId = findBackFacingCamera();
if (cameraId >= 0) {
// open the backFacingCamera
mCamera = Camera.open(cameraId);
// refresh the preview
mPreview.refreshCamera(mCamera);
}
} else {
int cameraId = findFrontFacingCamera();
if (cameraId >= 0) {
// open the backFacingCamera
mCamera = Camera.open(cameraId);
// refresh the preview
mPreview.refreshCamera(mCamera);
}
}
}
private void releaseCamera() {
// stop and release camera
if (mCamera != null) {
mCamera.release();
mCamera = null;
}
}
}
You can do achieve this functionality by setting OnLongClickListener() and OnTouchListener() on your record button. Like this:
recordBtn.setOnLongClickListener(recordBtnLCListener);
recordBtn.setOnTouchListener(recordBtnTouchListener);
then :
#Override
public boolean onLongClick(View v) {
ivCancel.setVisibility(View.GONE);
ivDone.setVisibility(View.GONE);
isActionDown = true;
try {
if (isActionDown) {
initRecorder();
if (isActionDown)
prepareRecorder();
}
if (isPrepared && isActionDown) {
mMediaRecorder.start();
isRecording = true;
}
} catch (Exception e) {
e.printStackTrace();
Log.e("onLongPress Error ", e.toString());
}
return true;
}
and :
#Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_UP:
isActionDown = false;
try {
if (isRecording) {
if (mMediaRecorder != null) {
mMediaRecorder.stop();
}
isRecording = false;
}
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
break;
}
return false;
}
So, in this way you can record the parts of video.Means each time you LongPress your record button, the recording starts. And time you release the button, the recording stops and here you have to save this part of video in any temporary folder.
Once you done taking all parts of videos as many as you want, then you have to combine all that parts of videos to make a single video.
Here, is the code to merge all that video parts saved in temperory folder:
public void mergeVideos() {
try {
List<Movie> inMovies = new ArrayList<>();
for (int i = 0; i < videosPathList.size(); i++) {
String filePath = videosPathList.get(i);
try {
Movie movie = MovieCreator.build(filePath);
if (movie != null)
inMovies.add(movie);
} catch (Exception e) {
e.printStackTrace();
}
}
List<Track> videoTracks = new LinkedList<Track>();
List<Track> audioTracks = new LinkedList<Track>();
for (Movie m : inMovies) {
for (Track t : m.getTracks()) {
try {
if (t.getHandler().equals("soun")) {
audioTracks.add(t);
}
if (t.getHandler().equals("vide")) {
videoTracks.add(t);
}
} catch (Exception e) {
}
}
}
Movie result = new Movie();
if (audioTracks.size() > 0) {
result.addTrack(new AppendTrack(audioTracks
.toArray(new Track[audioTracks.size()])));
}
if (videoTracks.size() > 0) {
result.addTrack(new AppendTrack(videoTracks
.toArray(new Track[videoTracks.size()])));
}
BasicContainer out = (BasicContainer) new DefaultMp4Builder().build(result);
File f = null;
String finalVideoPath;
try {
f = setUpVideoFile(Environment
.getExternalStorageDirectory()+"/MyApp/videos/");
finalVideoPath = f.getAbsolutePath();
} catch (IOException e) {
e.printStackTrace();
f = null;
finalVideoPath = null;
}
WritableByteChannel fc = new RandomAccessFile(finalVideoPath, "rw").getChannel();
out.writeContainer(fc);
fc.close();
deleteFilesDir(); //In this method you have to delete all parts of video stored in temporary folder.
} catch (Exception e) {
e.printStackTrace();
progressDialog.dismiss();
finish();
}
}
File setUpVideoFile(String directory) throws IOException {
File videoFile = null;
if (Environment.MEDIA_MOUNTED.equals(Environment
.getExternalStorageState())) {
File storageDir = new File(directory);
if (storageDir != null) {
if (!storageDir.mkdirs()) {
if (!storageDir.exists()) {
Log.d("CameraSample", "failed to create directory");
return null;
}
}
}
videoFile = File.createTempFile("video_"
+ System.currentTimeMillis() + "_",
.mp4, storageDir);
}
return videoFile;
}
You can call mergeVideos() method after stopping mediaRecorder.
Hope this code helps you. :)
For merging the videos you have to use the isoparser library. So you have to add following dependendy in your gradle file :
compile 'com.googlecode.mp4parser:isoparser:1.0.5.4'
This is my code.
public class VideoRecordingActivity extends AppCompatActivity implements View.OnClickListener, SurfaceHolder.Callback {
MediaRecorder recorder;
SurfaceHolder holder;
boolean recording = false;
private boolean isPrepared = false;
int videoNumber = 0;
#Override
public void onCreate(Bundle savedInstanceState) {
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
super.onCreate(savedInstanceState);
recorder = new MediaRecorder();
initRecorder();
setContentView(R.layout.activity_video_introduction_recording);
SurfaceView cameraView = (SurfaceView) findViewById(R.id.ln_body_recording);
holder = cameraView.getHolder();
holder.addCallback(this);
holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
cameraView.setClickable(true);
cameraView.setOnClickListener(this);
}
private void initRecorder() {
File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES), "CameraSample");
recorder.setAudioSource(MediaRecorder.AudioSource.DEFAULT);
recorder.setVideoSource(MediaRecorder.VideoSource.DEFAULT);
CamcorderProfile cpHigh = CamcorderProfile
.get(CamcorderProfile.QUALITY_HIGH);
recorder.setProfile(cpHigh);
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(new Date());
//CGlobal.VIDEO_RECORD_PATH = CGlobal.VIDEO_HOME_PATH + "VID_" + timeStamp;
File mediaFile;
mediaFile = new File(mediaStorageDir.getPath() + File.separator +
"VID_"+ timeStamp + ".mp4");
recorder.setOutputFile(mediaFile+".mp4");
recorder.setMaxDuration(50000); // 50 seconds
recorder.setMaxFileSize(5000000); // Approximately 5 megabytes
}
private void prepareRecorder() {
recorder.setPreviewDisplay(holder.getSurface());
try {
recorder.prepare();
isPrepared = true;
} catch (IllegalStateException e) {
e.printStackTrace();
finish();
} catch (IOException e) {
e.printStackTrace();
finish();
}
}
public void onClick(View v) {
if (recording) {
recorder.stop();
recording = false;
isPrepared = false;
videoNumber++;
// Let's initRecorder so we can record again
} else {
if (!isPrepared){
initRecorder();
prepareRecorder();
}
recording = true;
recorder.start();
}
}
public void surfaceCreated(SurfaceHolder holder) {
prepareRecorder();
}
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
}
public void surfaceDestroyed(SurfaceHolder holder) {
if (recording) {
recorder.stop();
recording = false;
}
recorder.release();
finish();
}
}
This is the main activity where the XML file is launched: VideoCaptureActivity.java:
public class VideoCaptureActivity extends Activity
{
private static final String TAG = "VideoCaptureActivity";
Camera camera;
ImageButton recordButton;
ImageButton stopButton;enter code here
ImageButton back;
Button flash;
Button flashoff;
Button flip;
SeekBar sb;
FrameLayout cameraPreviewFrame;
CameraPreview cameraPreview;
MediaRecorder mediaRecorder;
private Spinner spinner1;
private Timer myTimer;
File file;
int currentZoomLevel = 0;
int maxZoomLevel = 0;
int MAX_ZOOM=15;
int fcamera =0;
Size temp;
#Override
public void onCreate(Bundle bundle) {
super.onCreate(bundle);
super.setContentView(R.layout.video_capture);
// this.mediaRecorder = new MediaRecorder();
// this.mediaRecorder.setVideoSource(MediaRecorder.VideoSource.DEFAULT);
// this.mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
// this.mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
// this.mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.MPEG_4_SP);
// this.mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
this.cameraPreviewFrame = (FrameLayout)super.findViewById(R.id.camera_preview);
this.recordButton = (ImageButton)super.findViewById(R.id.recordButton);
this.stopButton = (ImageButton)super.findViewById(R.id.stopButton);
spinner1 = (Spinner) findViewById(R.id.spinner1);
back =(ImageButton)findViewById(R.id.back);
this.flash=(Button)findViewById(R.id.flashon);
this.flashoff=(Button)findViewById(R.id.fashoff);
this.sb = (SeekBar) findViewById(R.id.seekBar1);
this.sb.setOnSeekBarChangeListener( new seekListener() );
this.toggleButtons(false);
// we'll enable this button once the camera is ready
this.recordButton.setEnabled(false);
// this.flash.setEnabled(false);
stopButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
stopRecording(v);
}
});
flash.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
flashLightOn(v );
}
});
flashoff.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
flashLightOff(v );
}
});
back.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
//DatePicker dp = (DatePicker)findViewById(R.id.datePicker1);
Intent intent = new Intent(VideoCaptureActivity.this ,MainGrid.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
}
});
}
void toggleButtons(boolean recording) {
this.recordButton.setEnabled(!recording);
this.recordButton.setVisibility(recording ? View.GONE : View.VISIBLE);
this.stopButton.setEnabled(recording);
this.stopButton.setVisibility(recording ? View.VISIBLE : View.GONE);
}
public void flashLightOn(View view) {
// this.flash.setVisibility(View.INVISIBLE);
this.flash.setVisibility(View.INVISIBLE);
try {
if (getPackageManager().hasSystemFeature(
PackageManager.FEATURE_CAMERA_FLASH)) {
// camera = Camera.open();
Parameters p = camera.getParameters();
p.setFlashMode(Parameters.FLASH_MODE_TORCH);
camera.setParameters(p);
// camera.startPreview();
}
} catch (Exception e) {
e.printStackTrace();
Toast.makeText(getBaseContext(), "Exception flashLightOn()",
Toast.LENGTH_SHORT).show();
}
}
public void flashLightOff(View view) {
// this.flash.setVisibility(View.VISIBLE);
this.flash.setVisibility(View.VISIBLE);
try {
if (getPackageManager().hasSystemFeature(
PackageManager.FEATURE_CAMERA_FLASH)) {
Parameters p = camera.getParameters();
p.setFlashMode(Parameters.FLASH_MODE_OFF);
camera.setParameters(p);
}
} catch (Exception e) {
e.printStackTrace();
Toast.makeText(getBaseContext(), "Exception flashLightOff",
Toast.LENGTH_SHORT).show();
}
}
#Override
protected void onResume() {
super.onResume();
// initialize the camera in background, as this may take a while
// try {
// Camera camera = Camera.open(Camera.CameraInfo.CAMERA_FACING_BACK);
// sb.setMax(camera.getParameters().getMaxZoom());
// sb.setProgress(0);
// // Camera camera = Camera.open(Camera.CameraInfo.CAMERA_FACING_FRONT);
//
// } catch (RuntimeException e) {
// Log.wtf(TAG, "Failed to get camera", e);
// }
// if (camera == null) {
// Toast.makeText(VideoCaptureActivity.this, R.string.cannot_record,
// Toast.LENGTH_SHORT).show();
// } else {
// VideoCaptureActivity.this.initCamera(camera);
// }
new AsyncTask<Void, Void, Camera>() {
#Override
protected Camera doInBackground(Void... params) {
try {
Camera camera = Camera.open(Camera.CameraInfo.CAMERA_FACING_BACK);
sb.setMax(camera.getParameters().getMaxZoom());
sb.setProgress(0);
// Camera camera = Camera.open(Camera.CameraInfo.CAMERA_FACING_FRONT);
return camera == null ? Camera.open(0) : camera;
} catch (RuntimeException e) {
Log.wtf(TAG, "Failed to get camera", e);
return null;
}
}
#Override
protected void onPostExecute(Camera camera) {
if (camera == null) {
Toast.makeText(VideoCaptureActivity.this, R.string.cannot_record,
Toast.LENGTH_SHORT).show();
} else {
initCamera(camera);
}
}
}.execute();
}
void initCamera(Camera camera) {
// we now have the camera
Camera.Parameters params = camera.getParameters();
List<Size> previewSize = params.getSupportedPreviewSizes();
temp = previewSize.get(0);
// for (int i =0; i<previewSize.size(); i++)
// {
//
// }
this.camera = camera;
// create a preview for our camera
this.cameraPreview = new CameraPreview( VideoCaptureActivity.this,camera);
// add the preview to our preview frame
this.cameraPreviewFrame.addView(this.cameraPreview);
// enable just the record button
this.recordButton.setEnabled(true);
}
void releaseCamera() {
if (this.camera != null) {
// this.camera.lock(); // unnecessary in API >= 14
// //this.camera.stopPreview();
this.camera.release();
this.camera = null;
this.cameraPreviewFrame.removeView(this.cameraPreview);
}
}
void releaseMediaRecorder() {
if (this.mediaRecorder != null) {
this.mediaRecorder.reset(); // clear configuration (optional here)
this.mediaRecorder.release();
this.mediaRecorder = null;
}
}
void releaseResources() {
this.releaseMediaRecorder();
this.releaseCamera();
}
#Override
public void onPause() {
super.onPause();
this.releaseResources();
}
#Override
public void onStop()
{
super.onStop();
this.releaseCamera();
}
#Override
public void onDestroy()
{
super.onDestroy();
this.releaseCamera();
}
// gets called by the button press
public void startRecording(final View v) {
Log.d(TAG, "startRecording()");
// we need to unlock the camera so that mediaRecorder can use it\\
// this.camera.unlock(); // unnecessary in API >= 14
// now we can initialize the media recorder and set it up with our
// camera
this.camera.stopPreview();
this.camera.release();
this.mediaRecorder = new MediaRecorder();
// this.mediaRecorder.setCamera(this.camera);
this.mediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
this.mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
//// this.mediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH));
this.mediaRecorder.setProfile(CamcorderProfile.get(Camera.CameraInfo.CAMERA_FACING_BACK,
CamcorderProfile.QUALITY_HIGH));
// this.mediaRecorder.setVideoSize(320, 240);
// this.mediaRecorder.setVideoFrameRate(15);
// this.mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
// this.mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.MPEG_4_SP);
// this.mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
// this.mediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH));
// if (CamcorderProfile.hasProfile(CamcorderProfile.QUALITY_1080P))
// this.mediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_1080P));
// else
// if (CamcorderProfile.hasProfile(CamcorderProfile.QUALITY_720P))
// this.mediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_720P));
// else
// if (CamcorderProfile.hasProfile(CamcorderProfile.QUALITY_480P))
// this.mediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_480P));
this.mediaRecorder.setOutputFile(this.initFile().getAbsolutePath());
this.mediaRecorder.setPreviewDisplay(this.cameraPreview.getHolder().getSurface());
// mediaRecorder.setMaxDuration((int) 1800);
try {
//this.toggleButtons(true);
String sec=String.valueOf(spinner1.getSelectedItem()) ;
//int seconds =Integer.parseInt(sec);
String toast =String.valueOf(spinner1.getSelectedItem()) +" Recording";
Toast.makeText(this, toast, Toast.LENGTH_SHORT).show();
if(sec.equals("1")){
this.recordButton.setVisibility(View.INVISIBLE);
this.mediaRecorder.setMaxDuration(1000);
this.mediaRecorder.prepare();
// start the actual recording
// throws IllegalStateException if not prepared
this.mediaRecorder.start();
// this.recordButton.setVisibility(View.VISIBLE);
this.recordButton.setVisibility(View.VISIBLE);
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
stopRecording(v);
}
},1000);
}
else if(sec.equals("2")){
this.recordButton.setVisibility(View.INVISIBLE);
this.mediaRecorder.setMaxDuration(2000);
this.mediaRecorder.prepare();
// start the actual recording
// throws IllegalStateException if not prepared
this.mediaRecorder.start();
// this.recordButton.setVisibility(View.VISIBLE);
this.recordButton.setVisibility(View.VISIBLE);
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
stopRecording(v);
}
},2000);
}
else{
//this.mediaRecorder.setMaxDuration(5000);
this.toggleButtons(true);
this.mediaRecorder.prepare();
//start the actual recording
// throws IllegalStateException if not prepared
this.mediaRecorder.start();
// stopRecording(v);
// enable the stop button by indicating that we are recording
}
} catch (Exception e) {
Log.wtf(TAG, "Failed to prepare MediaRecorder", e);
Toast.makeText(this, e.getMessage(), Toast.LENGTH_SHORT).show();
this.releaseResources();
}
}
// gets called by the button press
public void stopRecording(View v) {
Log.d(TAG, "stopRecording()");
assert this.mediaRecorder != null;
try {
this.mediaRecorder.stop();
Toast.makeText(this, R.string.saved, Toast.LENGTH_SHORT).show();
sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://" + Environment.getExternalStorageDirectory())));
// we are no longer recording
this.toggleButtons(false);
} catch (RuntimeException e) {
// the recording did not succeed
Log.w(TAG, "Failed to record", e);
if (this.file != null && this.file.exists() && this.file.delete()) {
Log.d(TAG, "Deleted " + this.file.getAbsolutePath());
}
return;
} finally {
this.releaseMediaRecorder();
}
if (this.file == null || !this.file.exists()) {
Log.w(TAG, "File does not exist after stop: " + this.file.getAbsolutePath());
} else {
Log.d(TAG, "Going to display the video: " + this.file.getAbsolutePath());
Intent intent = new Intent(this, VideoPlaybackActivity.class);
intent.setData(Uri.fromFile(file));
super.startActivity(intent);
}
}
private File initFile() {
File dir = new File(
Environment.getExternalStorageDirectory().toString() +
Utils.OUR_TEMP_FOLDER);
if (!dir.exists() && !dir.mkdirs()) {
Log.wtf(TAG, "Failed to create storage directory: " + dir.getAbsolutePath());
Toast.makeText(VideoCaptureActivity.this, R.string.cannot_record, Toast.LENGTH_SHORT).show();
this.file = null;
} else {
this.file = new File(dir.getAbsolutePath(), new SimpleDateFormat(
"yyyyMMddHHmmss'.mp4'").format(new Date()));
}
return this.file;
}
private class seekListener implements SeekBar.OnSeekBarChangeListener
{
#Override
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
if (fromUser == true)
{
Parameters p = camera.getParameters();
p.setZoom(progress);
camera.setParameters(p);
}
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
}
}
My camera prewiew is as follows
CameraPreview.java:
public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
private static final String TAG = "CameraPreview";
private final Camera camera;
#SuppressWarnings("deprecation")
public CameraPreview(Context context, Camera camera) {
super(context);
Camera.Parameters params = camera.getParameters();
List<String> focusModes = params.getSupportedFocusModes();
if (focusModes.contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO))
params.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);
else
if (focusModes.contains(Camera.Parameters.FOCUS_MODE_AUTO))
params.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
camera.setParameters(params);
this.camera = camera;
super.getHolder().addCallback(this);
// required for API <= 11
super.getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
public void surfaceCreated(SurfaceHolder holder) {
Log.d(TAG, "surfaceCreated()");
// now that we have the surface, we can start the preview
try {
this.camera.setPreviewDisplay(holder);
this.camera.startPreview();
} catch (IOException e) {
Log.wtf(TAG, "Failed to start camera preview", e);
}
}
public void surfaceDestroyed(SurfaceHolder holder) {
// we will release the camera preview in our activity before this
// happens
Log.d(TAG, "surfaceDestroyed()");
}
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
// our activity runs with screenOrientation="landscape" so we don't
// care about surface changes
Parameters params = camera.getParameters();
Log.d(TAG, "surfaceChanged()");
}
}
I dont know what went wrong camera is working fine but the UI is visible at start but invisible after some time but the preview remains and if ii clicked on to the button which is invisible it works .so the control works but cant see.
In my code i have camera preview and video recording on button click so my code works well for recording and preview.
but when i press back button then surfaceview create and surface view change method get called after that surfaceview destroy method called so i have to press back button again and at this time it directly call surface destroy ( second time surface create and surface change is not called)
Here is my code any body can help me?
public class VideoCapture extends Activity implements SurfaceHolder.Callback {
public static final String LOGTAG = "VIDEOCAPTURE";
private static final int SELECT_PHOTO = 100;
private MediaRecorder recorder;
private SurfaceHolder holder;
private CamcorderProfile camcorderProfile;
private Camera camera;
boolean recording = false;
boolean usecamera = true;
boolean previewRunning = false;
Button recorderButton,selectVideo;
long init,now,time;
Handler handler;
Runnable updater;
SimpleDateFormat df;
Camera.Parameters parameters;
String timeString, timeStamp,selectedVideoPath;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
setContentView(R.layout.main);
handler = new Handler();
df = new SimpleDateFormat("mm:ss");
camcorderProfile = CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH);
recorderButton = (Button)findViewById(R.id.button);
selectVideo = (Button)findViewById(R.id.videoselect);
final TextView timerText = (TextView)findViewById(R.id.time);
File dir = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_DCIM), "/Filme");
if (!dir.exists()) {
dir.mkdirs();
}
// Animation for blinking red dot while recording
SurfaceView cameraView = (SurfaceView) findViewById(R.id.CameraView);
holder = cameraView.getHolder();
holder.addCallback(this);
holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
cameraView.setClickable(true);
cameraView.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View v) {
camera.autoFocus(new AutoFocusCallback(){
#Override
public void onAutoFocus(boolean arg0, Camera arg1) {
//camera.takePicture(shutterCallback, rawCallback, jpegCallback);
}
});
}
});
selectVideo.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent photoPickerIntent = new Intent(Intent.ACTION_PICK);
photoPickerIntent.setType("video/*");
startActivityForResult(photoPickerIntent, SELECT_PHOTO);
}
});
recorderButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
if (recording) {
recorderButton.setBackgroundResource(R.drawable.recordbutton_background_selector);
recorder.stop();
handler.removeCallbacks(updater); // stop handler
// to refresh media scan on storage
sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse
("file://" + Environment.getExternalStorageDirectory())));
String filepath =Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM)+File.separator+"Filme"+File.separator+"Filme_"+timeStamp+".mp4";
Intent i = new Intent(getBaseContext(),VideoCutActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
i.putExtra("path", filepath);
getBaseContext().startActivity(i);
finish();
/*
if (usecamera) {
try {
camera.reconnect();
} catch (IOException e) {
e.printStackTrace();
}
}
*/
recording = false;
Log.v(LOGTAG, "Recording Stopped");
// Let's prepareRecorder so we can record again
// prepareRecorder();
} else {
recorderButton.setBackgroundResource(R.drawable.stopbutton_background_selector);
recording = true;
prepareRecorder();
// recorder.start();
Log.v(LOGTAG, "Recording Started");
}
}
});
// Recording timmer
updater = new Runnable() {
#Override
public void run() {
now=System.currentTimeMillis();
time=now-init;
timeString = df.format(new Date(time));
timerText.setText(timeString);
handler.postDelayed(this, 30);
}
};
}
#Override
protected void onResume() {
super.onResume();
Log.e("onresume", "on resume");
// Open the default i.e. the first rear facing camera.
}
#Override
protected void onPause() {
super.onPause();
// Because the Camera object is a shared resource, it's very
// important to release it when the activity is paused.
if (recording) {
recorder.stop();
recording = false;
recorder.release();
camera.stopPreview();
camera.setPreviewCallback(null);
camera.release();
camera = null;
}
else
{
if (camera != null) {
previewRunning = false;
camera.release();
camera = null;
}
}}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent imageReturnedIntent) {
super.onActivityResult(requestCode, resultCode, imageReturnedIntent);
switch(requestCode) {
case SELECT_PHOTO:
if(resultCode == RESULT_OK){
Uri selectedImage = imageReturnedIntent.getData();
selectedVideoPath = getPath(selectedImage);
Intent i = new Intent(getBaseContext(),VideoCutActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
i.putExtra("path", selectedVideoPath);
VideoCapture.this.startActivity(i);
finish();
}
}
}
public String getPath(Uri uri) {
String[] proj = { MediaStore.Images.Media.DATA };
CursorLoader loader = new CursorLoader(getBaseContext(), uri, proj, null, null, null);
Cursor cursor = loader.loadInBackground();
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
}
private void prepareRecorder() {
recorder = new MediaRecorder();
recorder.setPreviewDisplay(holder.getSurface());
if (usecamera) {
camera.unlock();
recorder.setCamera(camera);
}
recorder.setAudioSource(MediaRecorder.AudioSource.DEFAULT);
recorder.setVideoSource(MediaRecorder.VideoSource.DEFAULT);
recorder.setProfile(camcorderProfile);
timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
recorder.setOutputFile(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM)+File.separator+"Filme"+File.separator+"Filme_"+timeStamp+".mp4");
Log.v(LOGTAG, "camcorderProfile");
try {
recorder.prepare();
recorder.start();
init = System.currentTimeMillis();
handler.post(updater);
} catch (IllegalStateException e) {
e.printStackTrace();
finish();
} catch (IOException e) {
e.printStackTrace();
finish();
}
}
public void surfaceCreated(SurfaceHolder holder) {
Log.v(LOGTAG, "surfaceCreated");
if (usecamera) {
camera = Camera.open();
parameters = camera.getParameters();
try {
Log.i("Capture","surface created");
parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
camera.setParameters(parameters);
camera.setPreviewDisplay(holder);
camera.startPreview();
previewRunning = true;
}
catch (IOException e) {
Log.e(LOGTAG,e.getMessage());
e.printStackTrace();
}
}
}
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
Log.v(LOGTAG, "surfaceChanged");
if (!recording && usecamera) {
if (previewRunning){
Log.e("Capture","preview is running");
camera.stopPreview();
}
try {
Log.e("Capture","inside try of surface changed");
parameters = camera.getParameters();
parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
parameters.setPreviewSize(camcorderProfile.videoFrameWidth, camcorderProfile.videoFrameHeight);
parameters.setPreviewFrameRate(camcorderProfile.videoFrameRate);
camera.setParameters(parameters);
camera.setPreviewDisplay(holder);
camera.startPreview();
previewRunning = true;
}
catch (IOException e) {
Log.e(LOGTAG,e.getMessage());
e.printStackTrace();
}
// prepareRecorder();
}
}
public void surfaceDestroyed(SurfaceHolder holder) {
Log.v(LOGTAG, "surfaceDestroyed");
if (camera != null) {
camera.stopPreview();
}
if (recording) {
try{
Log.e("Capture","inside recording of surface destory");
recorder.stop();
recording = false;
recorder.release();
camera.stopPreview();
camera.setPreviewCallback(null);
camera.release();
camera = null;
}
catch (RuntimeException e) {
Log.d("surface destroyed", "Problem in surfaceDestroyed");
e.printStackTrace();
}
}
Based on debugging/discussion on chat:
the first time back is being hit, the existing Camera activity gets destroyed and another one is created. Used the following to follow the changes in the back stack:
adb shell dumpsys activity | grep -i run
No new task is required, so this is useless:
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
Apparently, using i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP) helps!
I'm not sure why exactly this is helping though. (Especially, because IIUC, with *CLEAR_TOP, the existing instance of the activity on the stack would be used (with onNewIntent), but here (based on the output from dumpsys, a new activity gets created :|). But it works on archos.