Android video recording - IllegalStateException on mediaRecorder.start - android

I am following the tutorial on https://developer.android.com/guide/topics/media/camera.html#capture-video
As such I follow the below order when trying to start the camera:
Camera.open
camera.unlock
mediaRecorder.setCamera
mediaRecorder.setAudioSource
mediaRecorder.setVideoSource
mediaRecorder.setProfile
mediaRecorder.setOutputFile
mediaRecorder.prepare
mediaRecorder.start <- this is where I get the IllegalStateException
I can figure out what could be going wrong since I'm following the guide, running 5.0.2
private Camera mCamera;
private MediaRecorder mMediaRecorder;
public CameraActivity() {
mCamera = getCameraInstance();
mMediaRecorder = new MediaRecorder();
}
public static Camera getCameraInstance(){
Camera c = null;
try {
c = Camera.open();
}
catch (Exception e) { ... }
return c;
}
public void startRecording() {
mCamera.unlock();
mMediaRecorder.setCamera(mCamera);
mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
mMediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_LOW));
mMediaRecorder.setOutputFile(getOutputMediaFile(MEDIA_TYPE_VIDEO).toString());
try {
mMediaRecorder.prepare();
}
catch (IOException e) { ... }
catch (IllegalStateException e) { ... }
try {
mMediaRecorder.start();
}
catch (Exception e) {
Log.d(TAG, "exception on mediaRecorder.start" + e.toString()); // This is the exception that gets thrown on .start
}
}
My manifest includes all necessary permissions
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.RECORD_VIDEO" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.microphone" />
I have also tried manually setting format instead of using .setProfile, same results
mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.DEFAULT);
Update
The file is indeed created, though it's unplayable of course, so I know it's working up to that point. The call to prepare does not throw an exception, and occurs before start. Same exception thrown on start()

Comparing agains my code, it seems you're missing two calls:
mediaRecorder.setVideoSize(int width, int height)
mediaRecorder.setPreviewDisplay(SurfaceHolder surfaceHolder)
The latter is most likely to be causing the crash as Android requires a valid preview surface to start recording. This is done so to prevent hidden cameras apps.
There are dozens of questions related to recording without a preview surface, but this one seems to sum up what you need to do to bypass this restriction.
The basic idea is to resize your surface to be 1x1 and pass it to your mediaRecorder instance. Keep in mind that this may not work in all devices though.

If you are accessing mic hardware multiple times, like, using MediaRecorder and AudioRecord classes at a time will also make this exception.

Related

Capture image in service without preview android

Problem statement:
When someone tries to open the device with the wrong pattern / PIN, my application should trigger an alarm, send an alert SMS to the registered mobile number. AND it should capture the image of the person trying to unlock the device, and send this image to registered Email ID.
What I have achieved:
I am getting notification of wrong Pattern / PIN in my DeviceAdmin class.
I start the service for background tasks. This service plays alarm successfully.
I send an alert SMS to the registered mobile number.
I sent an alert Email to the registered email ID successfully. (BUT without image.)
I am confused about how can I capture image in background IntentService when the device is locked, and that, too without preview.
I cannot use the Camera intent obviously. Because startActivityForResult can't be called from Service. PLUS, I don't want user to capture the image after opening the Camera app.
My research led me to these posts already.
Can I use Android Camera in service without preview?
How to Capture Image When Device is Locked
Issue is:
Camera API is deprecate`. Camera2 API requires Minimum sdk version 21,
but my client's requirement is minSdkVersion 15, which I can't change. I am unable to figure out what should I do now. Any reference or help please?
I solved my issue with help of this blog
So I capture the image within background service using this code:
#Override
public void onStart(Intent intent, int startId) {
mCamera = getAvailableFrontCamera(); // globally declared instance of camera
if (mCamera == null){
mCamera = Camera.open(); //Take rear facing camera only if no front camera available
}
SurfaceView sv = new SurfaceView(getApplicationContext());
SurfaceTexture surfaceTexture = new SurfaceTexture(10);
try {
mCamera.setPreviewTexture(surfaceTexture);
//mCamera.setPreviewDisplay(sv.getHolder());
parameters = mCamera.getParameters();
//set camera parameters
mCamera.setParameters(parameters);
//This boolean is used as app crashes while writing images to file if simultaneous calls are made to takePicture
if(safeToCapture) {
mCamera.startPreview();
mCamera.takePicture(null, null, mCall);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//Get a surface
sHolder = sv.getHolder();
//tells Android that this surface will have its data constantly replaced
sHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
Camera.PictureCallback mCall = new Camera.PictureCallback()
{
public void onPictureTaken(byte[] data, Camera camera)
{
safeToCapture = false;
//decode the data obtained by the camera into a Bitmap
FileOutputStream outStream = null;
try{
// create a File object for the parent directory
File myDirectory = new File(Environment.getExternalStorageDirectory()+"/Test");
// have the object build the directory structure, if needed.
myDirectory.mkdirs();
//SDF for getting current time for unique image name
SimpleDateFormat curTimeFormat = new SimpleDateFormat("ddMMyyyyhhmmss");
String curTime = curTimeFormat.format(new java.util.Date());
// create a File object for the output file
outStream = new FileOutputStream(myDirectory+"/user"+curTime+".jpg");
outStream.write(data);
outStream.close();
mCamera.release();
mCamera = null;
String strImagePath = Environment.getExternalStorageDirectory()+"/"+myDirectory.getName()+"/user"+curTime+".jpg";
sendEmailWithImage(strImagePath);
Log.d("CAMERA", "picture clicked - "+strImagePath);
} catch (FileNotFoundException e){
Log.d("CAMERA", e.getMessage());
} catch (IOException e){
Log.d("CAMERA", e.getMessage());
}
safeToCapture = true; //Set a boolean to true again after saving file.
}
};
private Camera getAvailableFrontCamera (){
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("CAMERA", "Camera failed to open: " + e.getLocalizedMessage());
}
}
}
return cam;
}
//Send Email using javamail API as user will not be allowed to choose available
// application using a Chooser dialog for intent.
public void sendEmailWithImage(String imageFile){
.
.
.
}
Following uses-features and permissions will be needed for this in manifest file:
<uses-feature
android:name="android.hardware.camera"
android:required="false" />
<uses-feature
android:name="android.hardware.camera.front"
android:required="false" />
<uses-permission android:name="android.permission.SEND_MAIL" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CAMERA" />
I have set property required to false, so that user will be able to install my app even without any of the Camera available. May be this can help someone in future.

my camera do not work on my new device (nullpointerexcepetion) [duplicate]

This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 5 years ago.
after i changed my device my camera suddently stopped working and throwing out a
java.lang.NullPointerException: Attempt to invoke virtual method 'android.hardware.Camera$Parameters android.hardware.Camera.getParameters()' on a null object reference
i had tryed to change out my catch (RuntimeException ex) to finaly
but that instead gaved me a
Fail to connect to camera service” exception
public void surfaceCreated(SurfaceHolder surfaceHolder) {
String PreviewFPS;
String Previewsize;
String Displayor;
PreviewFPS = setingPreferences.getString("previewfps", "");
Previewsize = setingPreferences.getString("screensize", "");
Displayor = setingPreferences.getString("orientation", "");
String[] size = Previewsize.split(",");
try {
camera = Camera.open();
} catch (RuntimeException ex) {
}
Camera.Parameters parameters;
parameters = camera.getParameters();
//modificer parameterene
parameters.setPreviewFrameRate(Integer.parseInt(PreviewFPS));
parameters.setPreviewSize(Integer.parseInt(size[0]),Integer.parseInt(size[1]));
camera.setParameters(parameters);
parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
camera.setDisplayOrientation(Integer.parseInt(Displayor));
try {
camera.setPreviewDisplay(surfaceHolder);
camera.startPreview();
} catch (Exception ex) {
}
}
manifest
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />
the manufactor of the device had investigated the code and told me that the reason was due to it couldn't run the scanner and camera at once
Hi Kewin
 
Would you please share the source code to me? as we haven't tested if it can run both the camera and scanner
 
We checked, the scanner and camera can not be opened in same time.
 
Best Regards,
so my fix for this was by having my camera and scanner activity running in 2 separate activites and layouts hopefully this would help someone else
You need all the camera code in the try and you should read the stacktraces if you actually printed them
try {
camera = Camera.open();
Camera.Parameters parameters = camera.getParameters();
...
} catch (RuntimeException ex) {
ex.printStackTrace();
}
// camera remains null if an exception is caught...

MediaRecorder fails on start on some devices (start failed: -2147483648 and -19)

I have read everything about MediaRecorder and followed the GUIDES on Android.
Well, it supose to work fine at least on API 8 and higher, but my minimum SDK is 14, so I it should be better.
On my device, Samsung Galaxy S3 Mini it works fine. Some other devices with Ice Cream Sandwitch as well, but some others not. They crash on:
mediaRecorder.start()
I create a service for recording video and this is my code (guide for what I do on every stage):
#Override
public void surfaceCreated(SurfaceHolder surfaceHolder) {
//OPEN CAMERA
int ncamara=0;
qcamara=0;
if(android.os.Build.VERSION.SDK_INT<9)
camera = Camera.open();
else{
try {
ncamara = Camera.getNumberOfCameras();
if (f.leer("camara", context).equals("frontal"))
qcamara=10;
else qcamara=20;
} catch (Exception e) {}
if (ncamara>=2 && qcamara == 10)
camera = Camera.open(Camera.CameraInfo.CAMERA_FACING_FRONT);
else if (ncamara>=2 && qcamara == 20)
camera = Camera.open(Camera.CameraInfo.CAMERA_FACING_BACK);
else
camera = Camera.open();
}
//
try {
camera.setPreviewDisplay(surfaceHolder);
camera.startPreview();
} catch (IOException e1) {
e1.printStackTrace();
}
//UNLOCK CAMERA
camera.unlock();
mediaRecorder = new MediaRecorder();
mediaRecorder.setCamera(camera); //setCamera
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
//setProfile
if (f.leer("calidad", context).equals("alta") && qcamara !=10)
mediaRecorder.setProfile(CamcorderProfile.get(0, CamcorderProfile.QUALITY_HIGH));
else if (f.leer("calidad", context).equals("alta") && qcamara == 10)
mediaRecorder.setProfile(CamcorderProfile.get(1, CamcorderProfile.QUALITY_LOW));
else if (f.leer("calidad", context).equals("baja") && qcamara != 10)
mediaRecorder.setProfile(CamcorderProfile.get(0, CamcorderProfile.QUALITY_LOW));
else
mediaRecorder.setProfile(CamcorderProfile.get(1, CamcorderProfile.QUALITY_LOW));
mediaRecorder.setVideoSize(320, 240);
if (CameraRecorder.duracion>0) // -- duration
mediaRecorder.setMaxDuration(CameraRecorder.duracion * 1000);
File dataDirectory = Environment.getExternalStorageDirectory();
File fileDir = new File(dataDirectory, "/weddingR/");
fileDir.mkdirs();
mediaRecorder.setOutputFile( //setOutputFile
Environment.getExternalStorageDirectory()+"/weddingR/"+
DateFormat.format("yyyy-MM-dd---kk-mm-ss", new Date().getTime())+
".mp4"
);
mediaRecorder.setPreviewDisplay(surfaceHolder.getSurface());
if (qcamara==10){ // FRONT CAMERA
try { mediaRecorder.setOrientationHint(270); } catch (Exception e) {}
} else { // BACK CAMERA
try { mediaRecorder.setOrientationHint(90); } catch (Exception e) {}
}
try {
mediaRecorder.prepare();
} catch (Exception e) {}
mediaRecorder.setOnInfoListener(new OnInfoListener(){
#Override
public void onInfo(MediaRecorder mr, int what, int extra) {
Log.d("INFO_ON", what + " " + extra + " ");
nascosto=true;
stopSelf();
}
});
mediaRecorder.start();
}
If I set mediaRecorder.setVideoFrameRate(20) for example, it crashes on every device.
I'm most asking before in some devices works fine, but not others (for example, EMULATOR with API 17 or 18 works... devices with API 15 works but EMULATOR API 15 doesn't work...)
What am I doing wrong ??
Thanks in advance.
ANDROID MANIFEST PERMISSIONS
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />
EDIT
After #Melquiades answer, I edited my code now catching exceptions and no exception is caught.
Also, I'd like to point some interesting thing: I'm trying with API15 emulator and this happens:
When I set mediaRecorder.setPreviewDisplay(surfaceHolder.getSurface()); (after mediaRecorder.setOutputFile()), I get START FAILED -19
When I don't set it, I get START FAILED -2147483648
But in my Samsung it still works fine...
NEW EDIT (01/01/2014) HAPPY NEW YEAR!!
I tried on Samsung Galaxy S2 Plus (Android 4.1.2) and it doesn't work, but on mine, Samsung Galaxy S3 Mini it works (also Android 4.1.2)... I'm becoming crazy.
When calling mediaRecorder.prepare(), you're not doing anything with caught exception:
try {
mediaRecorder.prepare();
} catch (Exception e) { //empty??? }
DON'T DO IT. It's a bad practice. If there are any exceptions, you won't know it.
Place a Log.d() inside {} and see what's going on during prepare(). Do it with all your exceptions that you're catching.
From that guide:
// 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;
}

Why does the start() method of MediaRecorder throw an IllegalStateException?

I am trying to record audio but the start() method of MediaRecorder class throws an IllegalStateException.
I use the following code:
MediaRecorder recorder = new MediaRecorder();
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
recorder.setOutputFile("/sdcard/");
try {
recorder.prepare();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Log.i("Try","Exception");
recorder.start();
And following permission
<uses-permission android:name="android.permission.RECORD_AUDIO" />
Vijay, recorder.setOutputFile("/sdcard/"); is setting a directory, not a file.
Replace that with:
mFileName = Environment.getExternalStorageDirectory().getAbsolutePath();
mFileName += "/youraudiofile.3gp";
Using "/sdcard" hard codes a path which is fragile, so use the above
Also, for this to work you must add
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
to your AndroidManifext.xml
It may be helpful for some one in future. IllegalstateException is thrown when the MediaRecorder. Prepare method is not called or called after Mediarecorder.start or before configuring audio/video sources,format and encoders.
The correct order of configuration mentioned in camera developer guide on android documentation
camera unlock
control of camera to media recorder -> setCamera
set audio/video source, format,encoder
prepare
start

Problems with MediaRecorder class to record audio - prepare() gives an exception - Permission denied

I'm new in Android development and I have the next question/problem.
I'm playing around with the MediaRecorder class to record just audio from the microphone. I'm following the steps indicated in the official site: http://developer.android.com/reference/android/media/MediaRecorder.html
So I have a method that initializes and configure the MediaRecorder object in order to start recording. Here you have the code:
//initializes audio recorder
MediaRecorder mrecorder = new MediaRecorder();
//configure the input sources
mrecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
//set the output format
mrecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
//set the audio encoding
mrecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
//specify the output file
mrecorder.setOutputFile("/sdcard/test.3gp");
//prepare for recording
try {
mrecorder.prepare();
} catch (IllegalStateException e) {
e.printStackTrace();
Log.d("Syso". e.toString());
} catch (IOException e) {
e.printStackTrace();
Log.d("Syso". e.toString());
}
When I execute this code in the simulator, thanks to logcat, I can see that the method prepare() gives an exception when is called:
java.io.FileNotFoundException: /sdcard/test.3gp (Permission denied)
And I have no idea why this is happening. Due to the message of the exception, I've given permissions in the manifest to access to storage by adding the following line to the xml:
<uses-permission android:name="android.permission.STORAGE" />
But this doesn't fix anything and I still get the same exception all the time. The SDCard is mounted according to the emulator, so I have no clue.
Add the WRITE_EXTERNAL_STORAGE permission to AndroidManifest.xml.

Categories

Resources