Im getting the exception java.lang.RuntimeException:Fail to connect to camera service when reopening the same activity.
For the first time the code works fine without capturing video file(only camera preview).But after finishing MainActivity.If I again calls Mainactivity then for mCamera = Camera.open(0); it throws Exception
I checked questions on stackoverflow but non of the solution worked for it.
Code
public class MainActivity extends AppCompatActivity implements SurfaceHolder.Callback, View.OnClickListener {
private VideoView videoView = null;
private MediaController mc = null;
private SurfaceHolder surfaceHolder;
private SurfaceView surfaceView;
public MediaRecorder mediaRecorder = new MediaRecorder();
private Camera mCamera;
private Button btnStart;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
surfaceView = (SurfaceView) findViewById(R.id.surface_camera);
surfaceHolder = surfaceView.getHolder();
surfaceHolder.addCallback(this);
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
btnStart = (Button) findViewById(R.id.btnStart);
btnStart.setOnClickListener(this);
if (mCamera == null) {
mCamera = Camera.open(0);
Camera.Parameters params = mCamera.getParameters();
mCamera.setParameters(params);
mCamera.setDisplayOrientation(90);
}
}
#SuppressLint("NewApi")
protected void startRecording() throws IOException {
File sdCard = Environment.getExternalStorageDirectory();
File dir = new File(sdCard.getAbsolutePath() + "/myVideos");
if (!dir.exists()) {
dir.mkdirs();
}
Date date = new Date();
String fileName = "/rec" + date.toString().replace(" ", "_").replace(":", "_") + ".mp4";
File file = new File(dir, fileName);
mediaRecorder = new MediaRecorder();
mCamera.lock();
mCamera.unlock();
mediaRecorder.setCamera(mCamera);
mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.MPEG_4_SP);
mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
mediaRecorder.setPreviewDisplay(surfaceHolder.getSurface());
mediaRecorder.setOutputFile(dir + fileName);
mediaRecorder.setOrientationHint(90);
mediaRecorder.prepare();
mediaRecorder.start();
refreshGallery(file);
}
private void refreshGallery(File file) {
Intent mediaScanIntent = new Intent(
Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
mediaScanIntent.setData(Uri.fromFile(file));
sendBroadcast(mediaScanIntent);
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
if (mCamera != null) {
try {
if (mCamera != null) {
mCamera.setPreviewDisplay(surfaceHolder);
mCamera.startPreview();
mCamera.unlock();
}
}
catch(Exception ex)
{
ex.printStackTrace();
}
} else {
Toast.makeText(getApplicationContext(), "Camera not available!",
Toast.LENGTH_LONG).show();
finish();
}
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
mCamera.stopPreview();
mCamera.setPreviewCallback(null);
mCamera.release();
mCamera = null;
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btnStart:
if (btnStart.getText().toString().equalsIgnoreCase("Start")) {
btnStart.setText("Stop");
try {
startRecording();
} catch (IOException e) {
String message = e.getMessage();
Log.i(null, "Problem " + message);
mediaRecorder.release();
e.printStackTrace();
}
} else {
btnStart.setText("Start");
mediaRecorder.stop();
mediaRecorder.release();
mediaRecorder = null;
}
break;
default:
break;
}
}
#Override
public void onDestroy()
{
super.onDestroy();
if(mCamera!=null) {
mCamera.stopPreview();
mCamera.setPreviewCallback(null);
mCamera.release();
mCamera = null;
}
}
#Override
public void onBackPressed()
{
Intent intent=new Intent(MainActivity.this,FirstActivityActivity.class);
startActivity(intent);
super.onBackPressed();
}
}
can anyone tell me,whats wrong with the code?
here is the logcat
FATAL EXCEPTION: main
Process: com.example.surfaceviewrecord, PID: 11717
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.surfaceviewrecord/com.example.surfaceviewrecord.MainActivity}:
java.lang.RuntimeException: Fail to connect to camera service
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2585)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2667)
at android.app.ActivityThread.-wrap11(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1494)
at android.os.Handler.dispatchMessage(Handler.java:111)
at android.os.Looper.loop(Looper.java:207)
at android.app.ActivityThread.main(ActivityThread.java:5776)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:789)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:679)
Caused by: java.lang.RuntimeException: Fail to connect to camera service
at android.hardware.Camera.<init>(Camera.java:647)
at android.hardware.Camera.open(Camera.java:489)
at com.example.surfaceviewrecord.MainActivity.onCreate(MainActivity.java:47)
at android.app.Activity.performCreate(Activity.java:6582)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1113)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2532)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2667)
at android.app.ActivityThread.-wrap11(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1494)
at android.os.Handler.dispatchMessage(Handler.java:111)
at android.os.Looper.loop(Looper.java:207)
at android.app.ActivityThread.main(ActivityThread.java:5776)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:789)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:679)
Permissions in manifest file
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />
You need to apply Runtime Camera Permission from marshmallow and above. So here you haven't camera permission that's why this error occurred.
Please check this Link
#Override
protected void onDestroy() {
super.onDestroy();
releaseMediaRecorder();
if (camera != null) {
camera.stopPreview();
camera.setPreviewCallback(null);
camera.release();
camera = null;
}
}
private void releaseMediaRecorder() {
if (mediaRecorder != null) {
mediaRecorder.release(); // release the recorder object
mediaRecorder = null;
}
}
Please check above code and put in at onDestroy() method.
Related
I using this code to record from front camera, but when camera starting to record, Recorder changes to back camera (surface view shows front camera preview), that's my code:
public class MatchActivity extends Activity implements SurfaceHolder.Callback {
private static final String LOG_TAG = MainActivity.class.getCanonicalName();
View myButton;
MediaRecorder mediaRecorder;
SurfaceHolder surfaceHolder;
boolean recording;
private TextView mTimer;
private Camera mCamera;
TextView prepareid;
CountDownTimer countDownTimer;
String pathOfVideo;
TextView textmode;
ImageView imagemode;
boolean isRunning = false;
String PIC;
int ID;
operations op = new operations();
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_match);
SurfaceView myVideoView = (SurfaceView) findViewById(R.id.surface);
op.Localize();
recording = false;
mCamera = Camera.open(1);
mCamera.setDisplayOrientation(90);
mCamera.unlock();
mediaRecorder = new MediaRecorder();
mediaRecorder.setCamera(mCamera);
pathOfVideo=initMediaRecorder();
surfaceHolder = myVideoView.getHolder();
surfaceHolder.addCallback(this);
surfaceHolder = myVideoView.getHolder();
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
myButton = (View) findViewById(R.id.Prepare);
myButton.setOnClickListener(StartVideo);
ImageView CorecctAnswer = (ImageView) findViewById(R.id.correctanswer);
CorecctAnswer.setOnClickListener(CorrectAnswer);
prepareid = (TextView) findViewById(R.id.prepareid);
mTimer = (TextView) findViewById(R.id.timer);
if (ContextCompat.checkSelfPermission(getApplicationContext(), android.Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(MatchActivity.this, new String[]{android.Manifest.permission.CAMERA}, 50);
}
}
private Button.OnClickListener StartVideo
= new Button.OnClickListener() {
#Override
public void onClick(final View arg0) {
myButton.setVisibility(View.GONE);
prepareid.setVisibility(View.GONE);
countDownTimer = new CountDownTimer(60 * 1000, 1000) {
#Override
public void onTick(long millisUntilFinished) {
mTimer.setText(String.valueOf(millisUntilFinished / 1000)+ " ثانیه ");
isRunning = true;
}
#Override
public void onFinish() {
isRunning= false;
if(camerastate)
stopvideo();
Intent intent = new Intent(MatchActivity.this, ResultPage.class);
Bundle b = new Bundle();
b.putString("PIC",PIC);
b.putString("PATH", pathOfVideo);
b.putString("Word", textmode.getText().toString());
b.putInt("Answer",0);
b.putInt("ID",ID);
intent.putExtras(b);
startActivity(intent);
finish();
}
};
startvideo();
}
};
public void stopvideo()
{
recording=false;
try {
mediaRecorder.stop();
mediaRecorder.reset();
finish();
} catch (Exception e) {
Log.e(LOG_TAG, "Failed to stop recorder", e);
}
mediaRecorder.release();
mediaRecorder = null;
if (mCamera != null) {
mCamera.release();
mCamera = null;
}
}
public void startvideo()
{
mCamera.release();
countDownTimer.start();
mediaRecorder.start();
recording = true;
}
#Override
public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
if (mCamera != null) {
Camera.Parameters params = mCamera.getParameters();
mCamera.setParameters(params);
try {
mCamera.setPreviewDisplay(holder);
} catch (IOException e) {
e.printStackTrace();
}
mCamera.startPreview();
}
prepareMediaRecorder();
}
#Override
public void surfaceDestroyed(SurfaceHolder arg0) {
}
private String initMediaRecorder() {
mediaRecorder.setCamera(mCamera);
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.DEFAULT);
mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.MPEG_4_SP);
CamcorderProfile camcorderProfile = CamcorderProfile.get(CamcorderProfile.QUALITY_LOW); //get your own profile
Camera.Parameters parameters = null;
if (mCamera.getParameters()!=null) {
parameters = mCamera.getParameters();
}
parameters.setPreviewSize(camcorderProfile.videoFrameWidth,camcorderProfile.videoFrameHeight);
mCamera.setParameters(parameters);
File file = new File(getExternalFilesDir(Environment.DIRECTORY_MOVIES),"hadskalme" + System.currentTimeMillis()+ ".mp4");
if (file.exists()) {
file.delete();
}
mediaRecorder.setOutputFile(file.getAbsolutePath());
mediaRecorder.setMaxDuration(90000); // Set max duration 90 sec.
mediaRecorder.setMaxFileSize(15000000); // Set max file size 15M
return String.valueOf(file.getAbsolutePath());
}
private void prepareMediaRecorder() {
mediaRecorder.setPreviewDisplay(surfaceHolder.getSurface());
try {
mediaRecorder.prepare();
} catch (IllegalStateException | IOException e) {
Log.e(LOG_TAG, " to prepare recorder", e);
}
}
}
that's what error I receive:
W/AudioSystem: AudioFlinger server died!
W/IMediaDeathNotifier: media server died
E/MediaPlayer: error (100, 0)
W/MediaMetadataRetriever: MediaMetadataRetriever server died!
W/CameraBase: Camera service died!
public static Camera openFrontalCamera() {
Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
for (int i = 0; i < Camera.getNumberOfCameras(); i++) {
Camera.getCameraInfo(i, cameraInfo);
if (Camera.CameraInfo.CAMERA_FACING_FRONT == cameraInfo.facing) {
return Camera.open(i);
}
}
return null;
}
usage in your code
mCamera = openFrontalCamera();
if (mCamera != null) {
//continue flow
} else {
//no frontal camera available
}
I need a help. I'm trying to implement Custom camera using surface vie, but I'm stacked into this error:
Process: visionary.anselmo.camerademo, PID: 7464
java.lang.RuntimeException: Fail to connect to camera service
at android.hardware.Camera.<init>(Camera.java:496)
at android.hardware.Camera.open(Camera.java:360)
at visionary.anselmo.camerademo.CameraActivity.surfaceCreated(CameraActivity.java:149)
at android.view.SurfaceView.updateWindow(SurfaceView.java:608)
at android.view.SurfaceView$3.onPreDraw(SurfaceView.java:160)
at android.view.ViewTreeObserver.dispatchOnPreDraw(ViewTreeObserver.java:944)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2201)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1246)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6301)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:871)
at android.view.Choreographer.doCallbacks(Choreographer.java:683)
at android.view.Choreographer.doFrame(Choreographer.java:619)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:857)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6077)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)
And the here goes the activity that handles this:
public class CameraActivity extends AppCompatActivity implements SurfaceHolder.Callback {
#SuppressWarnings("deprecation")
private Camera camera;
#InjectView(R.id.surface_view)
SurfaceView surfaceView;
#InjectView(R.id.btn_take_picture)
ImageView take_picture;
SurfaceHolder surfaceHolder;
#SuppressWarnings("deprecation")
Camera.PictureCallback pictureCallback;
#SuppressWarnings("deprecation")
ShutterCallback shutterCallback;
#SuppressWarnings("deprecation")
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.camera_activity);
ButterKnife.inject(this);
surfaceHolder = surfaceView.getHolder();
// Install the surfaceHolder.Callback so we get notified when the underlying is created and destroyed
surfaceHolder.addCallback(this);
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
take_picture.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
cameraImage();
}
});
pictureCallback = new Camera.PictureCallback() {
#Override
public void onPictureTaken(byte[] data, Camera camera) {
FileOutputStream outputStream;
File imageFile = getDirectory();
if (!imageFile.exists() && !imageFile.mkdirs()) {
Toast.makeText(getApplicationContext(),
"Nao foi possivel criar o directorio para a imagem.",
Toast.LENGTH_SHORT)
.show();
return;
}
SimpleDateFormat format = new SimpleDateFormat("yyyymmddhhmmss", Locale.ENGLISH);
String date = format.format(new Date());
String photoFile = "Demo" + date + ".jpg";
String fileName = imageFile.getAbsolutePath() + "/" + photoFile;
File picFile = new File(fileName);
try {
outputStream = new FileOutputStream(picFile);
outputStream.write(data);
outputStream.close();
} catch (IOException ignored) {
}
Toast.makeText(getApplicationContext(), "Picture Saved", Toast.LENGTH_SHORT)
.show();
refreshCamera();
refreshGallery(picFile);
}
};
}
private void refreshGallery(File file) {
Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
intent.setData(Uri.fromFile(file));
sendBroadcast(intent);
}
private void refreshCamera() {
if (surfaceHolder.getSurface() == null) {
// Preview surfave does not exists
return;
}
// Stop the preview before making changes
try {
camera.stopPreview();
} catch (Exception ignored) {
}
// Set the preview size, and make any resize, rotate or any reformmating changes here
// Start preview with new Settings
try {
camera.setPreviewDisplay(surfaceHolder);
camera.startPreview();
} catch (Exception ignored) {
}
}
private File getDirectory() {
File dics = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM);
return new File(dics, "CameraActivity");
}
private void cameraImage() {
// Take the picture
camera.takePicture(null, null, pictureCallback);
}
#SuppressWarnings("deprecation")
#Override
public void surfaceCreated(SurfaceHolder holder) {
// Open the fuck'n Camera here
releaseCamera();
camera = Camera.open();
Camera.Parameters parameters;
parameters = camera.getParameters();
// Modify the parameters
parameters.setPreviewFrameRate(20);
parameters.setPreviewSize(352, 288);
camera.setParameters(parameters);
camera.setDisplayOrientation(90);
try {
// The surface has been created, now tell the camera where to draw the preview
camera.setPreviewDisplay(surfaceHolder);
} catch (Exception ignored) {
}
}
private void releaseCamera(){
if(camera != null){
camera.release();
camera = null;
}
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
refreshCamera();
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
// Stop the preview and release the camera
camera.stopPreview();
camera.release();
camera = null;
}
}
Help guys...
Thanks...
You might need to request the permission at runtime. See The Android Developers Homepage for more information on this topic.
Requesting runtime permissions is required when targeting Android 6.0 or later.
I know there are some similar subjects connecting to this but I couldn't solve mine. anyway,I am trying to make some front camera with "flash" where I am calling Camera.release only once in the whole activities, when surfaceDestroyed(). so here is my MainActivity:
#SuppressWarnings("deprecation")
public class MainActivity extends AppCompatActivity {
private Camera mCamera = null;
private CameraPreview mCameraView = null;
private int cameraId = 0;
private void addView() {
if (!getPackageManager()
.hasSystemFeature(PackageManager.FEATURE_CAMERA)) {
Toast.makeText(this, "No camera on this device", Toast.LENGTH_LONG)
.show();
} else {
cameraId = findFrontFacingCamera();
if (cameraId < 0) {
Toast.makeText(this, "No front facing camera found.",
Toast.LENGTH_LONG).show();
} else {
try {
mCamera = Camera.open(cameraId);
} catch (Exception e) {
Log.d("ERROR", "Failed to get camera: " + e.getMessage());
}
}
}
if (mCamera != null) {
mCameraView = new CameraPreview(this, mCamera);//create a SurfaceView to show camera data
FrameLayout camera_view = (FrameLayout) findViewById(R.id.camera_view);
camera_view.addView(mCameraView);//add the SurfaceView to the layout
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
addView();
ImageButton imgCapture = (ImageButton) findViewById(R.id.imgCapture);
imgCapture.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
WindowManager.LayoutParams layout = getWindow().getAttributes();
layout.screenBrightness = 1F;
getWindow().setAttributes(layout);
setContentView(R.layout.whitescreen);
new CountDownTimer(3000, 1000) {
public void onTick(long millisUntilFinished) {
}
public void onFinish() {
if (CameraPreview.safeToTakePicture) {
CameraPreview.safeToTakePicture = false;
mCamera.takePicture(null, null,
new PhotoHandler(getApplicationContext()));
}
setContentView(R.layout.activity_main);
addView();
}
}.start();
}
});
}
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) {
Log.d("Camera", "Camera found");
cameraId = i;
break;
}
}
return cameraId;
}
}
When pressing the capture button I switch the layout to an empty one(white layout), wait 3 seconds take a picture and then add the camera view again, here is my CameraPreview class:
#SuppressWarnings("deprecation")
public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
private SurfaceHolder mHolder;
private Camera mCamera;
public static boolean safeToTakePicture = false;
public CameraPreview(Context context, Camera camera) {
super(context);
mCamera = camera;
mCamera.setDisplayOrientation(90);
mHolder = getHolder();
mHolder.addCallback(this);
mHolder.setType(SurfaceHolder.SURFACE_TYPE_NORMAL);
}
#Override
public void surfaceCreated(SurfaceHolder surfaceHolder) {
try {
mCamera.setPreviewDisplay(surfaceHolder);
mCamera.startPreview();
} catch (IOException e) {
Log.d("ERROR", "Camera error on surfaceCreated " + e.getMessage());
}
}
#Override
public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i2, int i3) {
if (mHolder.getSurface() == null)
return;
try {
mCamera.stopPreview();
} catch (Exception e) {
Log.d("ERROR", "Trying the camera and it's not running");
}
try {
mCamera.setPreviewDisplay(mHolder);
mCamera.startPreview();
safeToTakePicture = true;
} catch (IOException e) {
Log.d("ERROR", "Camera error on surfaceChanged " + e.getMessage());
}
}
#Override
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
mCamera.stopPreview();
mCamera.release();
}
}
I get the error Camera is being used after Camera.release was called a lot of times, for example when taking a picture:
07-02 14:49:35.561 19017-19017/davidandguy.com.selfielightcamera E/AndroidRuntime: FATAL EXCEPTION: main
Process: davidandguy.com.selfielightcamera, PID: 19017
java.lang.RuntimeException: Camera is being used after Camera.release() was called
at android.hardware.Camera.native_takePicture(Native Method)
at android.hardware.Camera.takePicture(Camera.java:1523)
at android.hardware.Camera.takePicture(Camera.java:1468)
at davidandguy.com.selfielightcamera.MainActivity$1$1.onFinish(MainActivity.java:65)
at android.os.CountDownTimer$1.handleMessage(CountDownTimer.java:127)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:158)
at android.app.ActivityThread.main(ActivityThread.java:7224)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)
Or even when onResume() is called, for example, minimize the activity and then run again. I know I need to put somewhere onPause() and onResume() but I don't know where/how to implement it. thanks
This is really overdue but as I managed to solve a similar problem of mine a minute ago, I thought I'd contribute for the benefit of yourself and anyone else who might be desperately searching Stack.
I cant see your lifecycle code here , but heres what worked for me, surfaceDestroyed was empty in my case
Firstly, the cameraPreview
public void surfaceChanged(SurfaceHolder surfaceHolder, int format, int width, int height) {
try {
this.mCamera.setPreviewDisplay(surfaceHolder);
this.mCamera.startPreview();
} catch (Exception e) {
}
}
public void surfaceCreated(SurfaceHolder surfaceHolder) {
try {
//TODO we need this here too because on SurfaceCreated we always need to open the camera, in case its released
this.mCamera.setPreviewDisplay(surfaceHolder);
this.mCamera.setDisplayOrientation(90);
//this.mCamera.startPreview();
} catch (IOException e) {
}
}
Next, the CameraActivity
#Override
public void onResume() {
super.onResume();
try{
mCamera = openFrontFacingCameraGingerbread();
// Add to Framelayout
this.mCameraPreview = new CameraPreview(this, this.mCamera);
mImage.removeAllViews();
this.mImage.addView(this.mCameraPreview);
}catch (RuntimeException ex){
}
}
#Override
public void onPause() {
super.onPause();
captureButton.setText("Begin Capture");
if(CameraActivity.this.timer !=null) {
CameraActivity.this.timer.cancel();
CameraActivity.this.timer.purge();
CameraActivity.this.timer = null;
}
if (mCamera != null) {
mCamera.setPreviewCallback(null);
mCameraPreview.getHolder().removeCallback(mCameraPreview);
mCamera.release();
mCamera = null;
}
}
#Override
protected void onDestroy(){
super.onDestroy();
releaseCameraAndPreview();
}
private void releaseCameraAndPreview() {
if (mCamera != null) {
mCamera.stopPreview();
mCamera.release();
mCamera = null;
}
if(mCameraPreview != null){
mCameraPreview.destroyDrawingCache();
mCameraPreview.mCamera = null;
}
}
I am facing problems with android camera recording, the issue is whenever I record the video and go to videoPlayer activity to view the video and after I finish the videoPlayer activity and coming back to my videoRecrding activity if I start capturing the video again with back camera it gives me the exception mentioned in the title of this post, if the camera was in FRONT mode before going to videoPlayer activity it behaves normal and records again normally but the only problem is with BACK CAMERA.
here my videoRecorder activity
public class VideoRecorder extends Activity implements OnClickListener, OnErrorListener
{
public static final int MEDIA_TYPE_IMAGE = 1;
public static final int MEDIA_TYPE_VIDEO = 2;
private static int CURRENT_CAMERA_ID;
public static int VIDEO_QUALITY = CamcorderProfile.QUALITY_HIGH;
public static boolean CAMERA_FLASH_AVAILABLE = false;
public static boolean FRONT_CAMERA_AVAILABLE = false;
public static boolean EXTERNAL_STORAGE_AVAILABLE = false;
private CountDownTimer mCountDownTimer;
private int VIDEO_RECORDING_LIMIT = 60;
private boolean isRecording = false;
private String TAG = "CustmoizedCamera Application";
private Camera mCamera = null;
private Parameters cameraParams;
private CameraPreview mCameraPreview;
private MediaRecorder mMediaRecorder;
private TextView TextViewRecordingPercentage;
private ProgressBar ProgressBarVideoRecording;
private StorageHelper mStorageHelper;
public File VideoPath;
ImageButton ImageButtonVideoRecordingCapture, ImageButtonVideoRecordingFlash, ImageButtonVideoRecordingSwapCamera, ImageButtonVideoRecordingClose, ImageButtonVideoRecordingUpload, ImageButtonVideoRecordingThumbnail;
private PictureCallback mPicture = new PictureCallback()
{
#Override
public void onPictureTaken(byte[] data, Camera camera)
{
File pictureFile = getOutputMediaFile(MEDIA_TYPE_IMAGE);
if (pictureFile == null)
{
Log.d(TAG, "Error creating media file, check storage permissions: ");
return;
}
try
{
FileOutputStream fos = new FileOutputStream(pictureFile);
fos.write(data);
fos.close();
ImageButtonVideoRecordingThumbnail.setImageDrawable(Drawable.createFromPath(pictureFile.getAbsolutePath()));
}
catch (FileNotFoundException e)
{
Log.d(TAG, "File not found: " + e.getMessage());
}
catch (IOException e)
{
Log.d(TAG, "Error accessing file: " + e.getMessage());
}
}
};
#Override
protected void onCreate(Bundle savedInstanceState)
{
Log.d("inside onCreate", "of VideoRecorder");
super.onCreate(savedInstanceState);
setContentView(R.layout.video_recording_layout);
mStorageHelper = new StorageHelper();
CAMERA_FLASH_AVAILABLE = getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH);
FRONT_CAMERA_AVAILABLE = getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_FRONT);
EXTERNAL_STORAGE_AVAILABLE = mStorageHelper.isExternalStorageAvailable();
// mCamera = getCameraInstance();
ImageButtonVideoRecordingFlash = (ImageButton) findViewById(R.id.image_button_video_recording_flash);
ImageButtonVideoRecordingSwapCamera = (ImageButton) findViewById(R.id.image_button_video_recording_swap_camera);
ImageButtonVideoRecordingClose = (ImageButton) findViewById(R.id.image_button_video_recording_close);
ImageButtonVideoRecordingUpload = (ImageButton) findViewById(R.id.image_button_video_recording_upload);
ImageButtonVideoRecordingCapture = (ImageButton) findViewById(R.id.image_button_video_recording_capture);
ImageButtonVideoRecordingThumbnail = (ImageButton) findViewById(R.id.image_button_video_recording_thumbnail);
CURRENT_CAMERA_ID = getIntent().getExtras().getInt("cam_id");
if(CURRENT_CAMERA_ID == CameraInfo.CAMERA_FACING_FRONT)
{
ImageButtonVideoRecordingFlash.setClickable(false);
VIDEO_QUALITY = CamcorderProfile.QUALITY_LOW;
}
ProgressBarVideoRecording = (ProgressBar) findViewById(R.id.progress_bar_video_recording);
TextViewRecordingPercentage = (TextView) findViewById(R.id.text_view_video_recording_percentage);
// mCamera = getCameraInstance(CURRENT_CAMERA_ID);
//
// if(mCamera != null)
// {
// mCameraPreview = new CameraPreview(getApplicationContext(), mCamera);
// ImageButtonVideoRecordingThumbnail.setOnClickListener(null);
// ProgressBarVideoRecording.setProgress(0);
// TextViewRecordingPercentage.setText("60");
// FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);
// preview.addView(mCameraPreview);
// }
// else
// {
// Log.d("inside onCreate", "Camera = null");
// }
// mCameraPreview = new CameraPreview(getApplicationContext(), mCamera);
//
// FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);
// preview.addView(mCameraPreview);
ImageButtonVideoRecordingCapture.setOnClickListener(this);
ImageButtonVideoRecordingFlash.setOnClickListener(this);
ImageButtonVideoRecordingSwapCamera.setOnClickListener(this);
ImageButtonVideoRecordingClose.setOnClickListener(this);
ImageButtonVideoRecordingUpload.setOnClickListener(this);
// ImageButtonVideoRecordingThumbnail.setOnClickListener(this);
}
/** A safe way to get an instance of the Camera object. */
public Camera getCameraInstance(int camId)
{
Camera c = null;
CURRENT_CAMERA_ID = camId;
if(CURRENT_CAMERA_ID == CameraInfo.CAMERA_FACING_FRONT)
{
VIDEO_QUALITY = CamcorderProfile.QUALITY_LOW;
ImageButtonVideoRecordingFlash.setEnabled(false);
}
else
{
VIDEO_QUALITY = CamcorderProfile.QUALITY_HIGH;
ImageButtonVideoRecordingFlash.setEnabled(true);
}
try
{
c = Camera.open(camId); // attempt to get a Camera instance
// c = openFrontFacingCameraGingerbread();
}
catch (Exception e)
{
// Camera is not available (in use or does not exist)
}
return c; // returns null if camera is unavailable
}
private void releaseMediaRecorder()
{
if (mMediaRecorder != null)
{
mMediaRecorder.reset(); // clear recorder configuration
mMediaRecorder.release(); // release the recorder object
mMediaRecorder = null;
mCamera.lock(); // lock camera for later use
}
}
private void releaseCamera()
{
if (mCamera != null)
{
mCamera.release(); // release the camera for other applications
mCamera = null;
}
}
private static Camera openFrontFacingCameraGingerbread() {
int cameraCount = 0;
Camera cam = null;
Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
cameraCount = Camera.getNumberOfCameras();
for ( int camIdx = 0; camIdx < cameraCount; camIdx++ )
{
Camera.getCameraInfo( camIdx, cameraInfo );
if ( cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT )
{
try
{
cam = Camera.open( camIdx );
}
catch (RuntimeException e)
{
// Log.e(TAG, "Camera failed to open: " + e.getLocalizedMessage());
}
}
}
return cam;
}
private static 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())
{
Log.d("MyCameraApp", "failed to create directory");
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 if (type == MEDIA_TYPE_VIDEO)
{
mediaFile = new File(mediaStorageDir.getPath() + File.separator+ "VID_" + timeStamp + ".mp4");
}
else
{
return null;
}
return mediaFile;
}
private boolean prepareVideoRecorder()
{
mMediaRecorder = new MediaRecorder();
// Step 1: Unlock and set camera to MediaRecorder
mCamera.lock();
mCamera.unlock();
mMediaRecorder.setCamera(mCamera);
mMediaRecorder.setOnErrorListener(this);
// Step 2: Set sources
mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
// Step 3: Set a CamcorderProfile (requires API Level 8 or higher)
// mMediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH));
mMediaRecorder.setProfile(CamcorderProfile.get(VIDEO_QUALITY));
// Step 4: Set output file
VideoPath = getOutputMediaFile(MEDIA_TYPE_VIDEO);
mMediaRecorder.setOutputFile(VideoPath.toString());
// Step 5: Set the preview output
mMediaRecorder.setPreviewDisplay(mCameraPreview.getHolder().getSurface());
// Step 6: Prepare configured MediaRecorder
try
{
mMediaRecorder.prepare();
}
catch (IllegalStateException e)
{
Log.d(TAG,"IllegalStateException preparing MediaRecorder: "+ e.getMessage());
releaseMediaRecorder();
return false;
}
catch (IOException e)
{
Log.d(TAG, "IOException preparing MediaRecorder: " + e.getMessage());
releaseMediaRecorder();
return false;
}
return true;
}
#Override
public void onClick(View v)
{
switch (v.getId())
{
case R.id.image_button_video_recording_capture:
if(EXTERNAL_STORAGE_AVAILABLE)
{
if (isRecording)
{
// stop recording and release camera
try
{
mMediaRecorder.stop(); // stop the recording
releaseMediaRecorder(); // release the MediaRecorder object
mCamera.lock(); // take camera access back from
// MediaRecorder
}
catch(Exception ex)
{
ex.printStackTrace();
}
// inform the user that recording has stopped
isRecording = false;
mCountDownTimer.cancel();
ImageButtonVideoRecordingCapture.setImageResource(R.drawable.img_video_recording_unselected);
ImageButtonVideoRecordingSwapCamera.setClickable(true);
ImageButtonVideoRecordingThumbnail.setOnClickListener(VideoRecorder.this);
Toast.makeText(getApplicationContext(),"Video saved to SD Card\\Pictures\\MyCameraApp ",Toast.LENGTH_SHORT).show();
}
else
{
// initialize video camera
mCountDownTimer = new CountDownTimer(VIDEO_RECORDING_LIMIT * 1000, 1000)
{
#Override
public void onTick(long millisUntilFinished)
{
updateRecordingPercentage((int) millisUntilFinished/1000);
}
#Override
public void onFinish()
{
try
{
mMediaRecorder.stop(); // stop the recording
releaseMediaRecorder(); // release the MediaRecorder object
mCamera.lock(); // take camera access back from
// MediaRecorder
updateRecordingPercentage(0);
}
catch(Exception ex)
{
ex.printStackTrace();
}
// inform the user that recording has stopped
isRecording = false;
ImageButtonVideoRecordingCapture.setImageResource(R.drawable.img_video_recording_unselected);
ImageButtonVideoRecordingSwapCamera.setClickable(true);
Toast.makeText(getApplicationContext(),"Video saved to SD Card\\Pictures\\MyCameraApp ",Toast.LENGTH_SHORT).show();
}
};
// mCamera.takePicture(null, null, mPicture);
if (prepareVideoRecorder())
{
// Camera is available and unlocked, MediaRecorder is
// prepared,
// now you can start recording
mMediaRecorder.start();
// inform the user that recording has started
isRecording = true;
mCountDownTimer.start();
ImageButtonVideoRecordingSwapCamera.setClickable(false);
ImageButtonVideoRecordingCapture.setImageResource(R.drawable.img_video_recording_selected);
}
else
{
// prepare didn't work, release the camera
releaseMediaRecorder();
// inform user
}
}
}
else
{
Toast.makeText(getApplicationContext(), "SD card not available.....", Toast.LENGTH_SHORT).show();
}
break;
case R.id.image_button_video_recording_close:
releaseMediaRecorder();
releaseCamera();
setResult(RESULT_OK);
finish();
break;
case R.id.image_button_video_recording_flash:
if(!isRecording)
{
if (CAMERA_FLASH_AVAILABLE)
{
cameraParams = mCamera.getParameters();
if (cameraParams.getFlashMode().equalsIgnoreCase(Parameters.FLASH_MODE_OFF))
{
cameraParams.setFlashMode(Parameters.FLASH_MODE_TORCH);
mCamera.setParameters(cameraParams);
ImageButtonVideoRecordingFlash.setImageResource(R.drawable.img_video_recording_flash_selected);
}
else
{
cameraParams.setFlashMode(Parameters.FLASH_MODE_OFF);
mCamera.setParameters(cameraParams);
ImageButtonVideoRecordingFlash.setImageResource(R.drawable.img_video_recording_flash_unselected);
}
}
else
{
Toast.makeText(getApplicationContext(), "Camera flash not available.....", Toast.LENGTH_SHORT).show();
}
}
break;
case R.id.image_button_video_recording_swap_camera:
Intent intent = getIntent();
finish();
if(FRONT_CAMERA_AVAILABLE)
{
if(CURRENT_CAMERA_ID == CameraInfo.CAMERA_FACING_BACK)
{
startActivity(intent.putExtra("cam_id", CameraInfo.CAMERA_FACING_FRONT));
}
else
{
startActivity(intent.putExtra("cam_id", CameraInfo.CAMERA_FACING_BACK));
}
}
break;
case R.id.image_button_video_recording_upload:
break;
case R.id.image_button_video_recording_thumbnail:
startActivity(new Intent(this, VideoPlayer.class).putExtra("video_path", VideoPath.getAbsolutePath()));
break;
default:
break;
}
}
#Override
public void onBackPressed()
{
// super.onBackPressed();
releaseMediaRecorder();
releaseCamera();
setResult(RESULT_OK);
finish();
}
private void updateRecordingPercentage(int orgPerc)
{
TextViewRecordingPercentage.setText(orgPerc+"");
ProgressBarVideoRecording.setProgress(VIDEO_RECORDING_LIMIT- orgPerc);
}
#Override
protected void onPause()
{
Log.d("inside", "onPause() of Video recorder");
super.onPause();
if(mCamera != null)
{
mCamera.stopPreview();
mCameraPreview.getHolder().removeCallback(mCameraPreview);
releaseMediaRecorder(); // if you are using MediaRecorder, release it
// first
releaseCamera(); // release the camera immediately on pause event
}
}
// #Override
// protected void onActivityResult(int requestCode, int resultCode, Intent data)
// {
// super.onActivityResult(requestCode, resultCode, data);
// Log.d("inside", "onActivityResult of video recorder");
// Intent mIntent = getIntent();
// finish();
// startActivity(mIntent);
// }
#Override
public void onError(MediaRecorder mr, int what, int extra) {
Log.d("MediaRecorderError " + what, "" + extra);
}
/* (non-Javadoc)
* #see android.app.Activity#onResume()
*/
#Override
protected void onResume() {
super.onResume();
mCamera = getCameraInstance(CURRENT_CAMERA_ID);
if(mCamera != null)
{
mCameraPreview = new CameraPreview(getApplicationContext(), mCamera);
ImageButtonVideoRecordingThumbnail.setOnClickListener(null);
ProgressBarVideoRecording.setProgress(0);
TextViewRecordingPercentage.setText("60");
FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);
preview.addView(mCameraPreview);
}
else
{
Log.d("inside onCreate", "Camera = null");
}
}
}
and here is my CameraPreview class
public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback
{
private final String TAG = "Customized Camera Application";
private SurfaceHolder mHolder;
private Camera mCamera;
private Parameters mParameters;
public CameraPreview(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);
}
public void surfaceCreated(SurfaceHolder holder)
{
// The Surface has been created, now tell the camera where to draw the preview.
try
{
CamcorderProfile mProfile = CamcorderProfile.get(VideoRecorder.VIDEO_QUALITY);
mParameters = mCamera.getParameters();
mParameters.setPreviewSize(mProfile.videoFrameWidth, mProfile.videoFrameHeight);
mCamera.setParameters(mParameters);
mCamera.setPreviewDisplay(holder);
mCamera.startPreview();
}
catch (IOException e)
{
Log.d(TAG, "Error setting camera preview: " + e.getMessage());
mCamera.release();
}
}
public void surfaceDestroyed(SurfaceHolder holder)
{
// empty. Take care of releasing the Camera preview in your activity.
try
{
mCamera.stopPreview();
}
catch (Exception e)
{
// ignore: tried to stop a non-existent preview
}
}
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.
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)
{
Log.d(TAG, "Error starting camera preview: " + e.getMessage());
}
}
}
here is my stacktrace
01-22 15:01:52.328: I/MediaRecorderJNI(1045): prepare: surface=0x5e7736e0
01-22 15:01:52.383: E/MediaRecorder(1045): start failed: -2147483648
01-22 15:01:52.383: D/AndroidRuntime(1045): Shutting down VM
01-22 15:01:52.383: W/dalvikvm(1045): threadid=1: thread exiting with uncaught exception (group=0x4201a700)
01-22 15:01:52.406: E/AndroidRuntime(1045): FATAL EXCEPTION: main
01-22 15:01:52.406: E/AndroidRuntime(1045): java.lang.RuntimeException: start failed.
01-22 15:01:52.406: E/AndroidRuntime(1045): at android.media.MediaRecorder.start(Native Method)
01-22 15:01:52.406: E/AndroidRuntime(1045): at com.galaxonic.jmtv.VideoRecorder.onClick(VideoRecorder.java:385)
01-22 15:01:52.406: E/AndroidRuntime(1045): at android.view.View.performClick(View.java:4240)
01-22 15:01:52.406: E/AndroidRuntime(1045): at android.view.View$PerformClick.run(View.java:17721)
01-22 15:01:52.406: E/AndroidRuntime(1045): at android.os.Handler.handleCallback(Handler.java:730)
01-22 15:01:52.406: E/AndroidRuntime(1045): at android.os.Handler.dispatchMessage(Handler.java:92)
01-22 15:01:52.406: E/AndroidRuntime(1045): at android.os.Looper.loop(Looper.java:137)
01-22 15:01:52.406: E/AndroidRuntime(1045): at android.app.ActivityThread.main(ActivityThread.java:5103)
01-22 15:01:52.406: E/AndroidRuntime(1045): at java.lang.reflect.Method.invokeNative(Native Method)
01-22 15:01:52.406: E/AndroidRuntime(1045): at java.lang.reflect.Method.invoke(Method.java:525)
01-22 15:01:52.406: E/AndroidRuntime(1045): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
01-22 15:01:52.406: E/AndroidRuntime(1045): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
01-22 15:01:52.406: E/AndroidRuntime(1045): at dalvik.system.NativeStart.main(Native Method)
01-22 15:02:02.477: I/Process(1045): Sending signal. PID: 1045 SIG: 9
I am stuck here.
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.