I using android android.hardware.Camera class to capture image. For initialization I use following code.
Camera cam = null;
try {
cam = Camera.open();
} catch (Exception e) {
e.printStackTrace();
// camera unavailable
}
return cam;
I am interesting in catch block. For example, torch app is running at the moment of initialization. So Camera.open() throw RuntimeException with message Fail to connect to camera service.
Here is exception:
Is it possible to know the reason why camera is unavailable? I want to guide user how to fix this, for example show a dialog: "dude, turn off your torch".
If it's not possible, then in which cases camera could be blocked? I just will show user dialog with general instruction what he could do, for example: 1. turn off torch. 2. Close all camera app 3. Fed your cat etc.
Related
I am trying to develop an app that would take picture when you light the screen.
I created different method to do so, and different logs. When I call the method supposed to take the picture : this is in a Service
public void photo() {
try {
cam.setPreviewDisplay(new SurfaceView(this).getHolder());
cam.startPreview();
cam.takePicture(null,null,new PhotoHandler());
Log.i("photo","end");
}catch(IOException e) {e.printStackTrace();}
}
In the logs, the "photo","end" is displayed but the logs I put in PhotoHandler are not.
I also have the "Camera" "app passed NULL Surface" log.
So I am asking you guys why is the picture not taken ? The PhotoHandler works fine, I tested it in a basic app.
Hope you'll help me !
EDIT : The camera is selected in the onCreate method of the service and gives no error.
EDIT : The problem was that my PhotoHandler wasn't called so camera.release() too. My photo() method looks like this now
public void photo() {
Camera cam=null;
try {
cam=Camera.open(Camera.CameraInfo.CAMERA_FACING_FRONT);
cam.setPreviewTexture(new SurfaceTexture(0));
cam.startPreview();
cam.takePicture(null,null,new PhotoHandler());
cam.stopPreview();
cam.release();
Log.i("photo","end");
}catch(IOException e) {e.printStackTrace();stopSelf();}
catch(RuntimeException re {e.printStackTrace();stopSelf();}
Now, the problem is that the takePicture method is called when the service end, must be a thread problem I assume. But what is more bothering is that the takePicture method is not always called after the service end. And when the method is called, it's called once, whereas I light the screen more than one time during the life of the service.
Is there any way to check if the camera is open or not? I don't want to open the camera, I just want to check its status.
If your device API version is higher than 21, CameraManager.AvailabilityCallback might be a good choice.
You need to first obtain the camera manager of the system with the following code:
CameraManager manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
Then, you need to register the AvailabilityCallback:
CameraManager manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
manager.registerAvailabilityCallback(new CameraManager.AvailabilityCallback() {
#Override
public void onCameraAvailable(String cameraId) {
super.onCameraAvailable(cameraId);
//Do your work
}
#Override
public void onCameraUnavailable(String cameraId) {
super.onCameraUnavailable(cameraId);
//Do your work
}
}, yourHandler);
}
This works better if API version is higher than 21. You can refer to CameraManager, CameraManager.AvailabilityCallback, and the whole package
Trying to open the camera to check if exception is thrown works good if API level is lower than 23. In API level 23, camera service is different than before, from the official docs:
Access to camera subsystem resources, including opening and configuring a camera device, is awarded based on the “priority” of the client application process. Application processes with user-visible or foreground activities are generally given a higher-priority, making camera resource acquisition and use more dependable.
Active camera clients for lower priority apps may be “evicted” when a higher priority application attempts to use the camera. In the deprecated Camera API, this results in onError() being called for the evicted client. In the Camera2 API, it results in onDisconnected() being called for the evicted client.
We can see that in API 23 or higher, trying to open the camera used by other app/process will seize the camera from app/process which was using it, instead of getting RuntimeException.
You can check it using method Camera.open(cameraId).
Creates a new Camera object to access a particular hardware camera. If the same camera is opened by other applications, this will throw a RuntimeException.
Throws
RuntimeException
If opening the camera fails (For Example, if the camera is in use by another process or device policy manager has disabled the camera).
Update:
Example:
public boolean isCameraUsebyApp() {
Camera camera = null;
try {
camera = Camera.open();
} catch (RuntimeException e) {
return true;
} finally {
if (camera != null) camera.release();
}
return false;
}
You can use this method to use as Paul suggested but keep this thing in mind that this method first acquire the camera.
If its acquire successfully then its mean that no other application is using this camera and don't forgot to release it again otherwise you will not able to acquire it again.
Its its throws RuntimeException it means that camera is in use by another process or device policy manager has disabled the camera.
Looking into the source code of Camera, its JNI counterpart, and finally the native code for connecting a camera with the service, it appears that the only way of determining if the camera is in use is directly through the result of Camera::connect(jint).
The trouble is that this native code is only accessible through the JNI function android_hardware_Camera_native_setup(JNIEnv*, jobject, jobject, jint), which sets up the camera for use when creating the Camera instance from Java in new Camera(int).
In short, it doesn't seem possible. You'll have to attempt to open the camera, and if it fails, assume it is in use by another applicaiton. E.g.:
public boolean isCameraInUse() {
Camera c = null;
try {
c = Camera.open();
} catch (RuntimeException e) {
return true;
} finally {
if (c != null) c.release();
}
return false;
}
To better understand the underlying flow of camera's native code, see this thread.
I am trying to develop an Android app which interacts from Camera hardware to record video. It records the video for 10 seconds, saves it and sends it to server(in background thread) and starts another video for next 10 seconds.It is expected to take videos indefinitely unless user presses the "stop" button in the app. Even if user presses home button then the video recording should continue in background.
Currently, if user presses the home button then the camera preview generates an exception as
"Java: IO Exception: Invalid preview surface"
Here is the code snippet I have used
recorder.setOutputFile(outputFile+"_"+number+".mp4");
recorder.setPreviewDisplay( holder.getSurface());
if (recorder != null) {
try {
recorder.prepare();
recorder.start();
} catch (IllegalStateException e) {
Toast.makeText(context, e.toString(), Toast.LENGTH_LONG).show();
} catch (IOException e) {
Toast.makeText(context, e.toString(), Toast.LENGTH_LONG).show();
}
}
Can I continue recording in the background even when user presses the home key?
I don't have any link documenting to this behavior, but I guess it's not possible. Even though you use a Service, it keeps throwing exceptions saying that it has "lost the surface".
You can check this other question as well.
I am using pretty much the same code as the Camera app code from Google but am getting really weird results. Inside my application and the Camera app from Google the preview gets stuck or is overlid with weird lines. The preview is usually the last thing which I see in the phone's own Camera app.
The Samsung model is I9003. The same code ran fine on I9000 which Samsung just discontinued. The code also works fine on an HTC Wildfire.
Any resolution for this?
Just noticed that after taking a photo inside my application the camera preview becomes normal. Same thing is happening in the Google camera application.
Couldn't post the answer earlier. Wasn't sure if it was the right thing to do, but now with the app running properly on around 150 devices I guess this works.
So the Android camera app in its onCreate function had the following code:
/*
* To reduce startup time, we start the preview in another thread.
* We make sure the preview is started at the end of onCreate.
*/
Thread startPreviewThread = new Thread(new Runnable() {
public void run() {
try {
mStartPreviewFail = false;
startPreview();
} catch (CameraHardwareException e) {
// In eng build, we throw the exception so that test tool
// can detect it and report it
if ("eng".equals(Build.TYPE)) {
throw new RuntimeException(e);
}
mStartPreviewFail = true;
}
}
});
startPreviewThread.start();
For some reason this did not work on GT-I9003. What I noticed was that after taking a photo the preview would come properly so there was nothing wrong with the hardware as such. I tried to retrace what was happening after a photo was taken and then compare it with the code with which the camera was first initialized. I commented out this code from onCreate. The onResume from the camera app looked like this:
if (mSurfaceHolder != null) {
// If first time initialization is not finished, put it in the
// message queue.
if (!mFirstTimeInitialized) {
mHandler.sendEmptyMessage(FIRST_TIME_INIT);
} else {
initializeSecondTime();
}
}
I changed this to:
if (!mFirstTimeInitialized) {
initializeFirstTime();
} else {
initializeSecondTime();
}
There were some other changes too, will put it up on GitHub as a separate app soon.
Can anyone tell me how to check if the android phone has a front camera too? I'd tried to use some help form https://docs.google.com/View?id=dhtsnvs6_57d2hpqtgr but Camera camera = FrontFacingCamera.getFrontFacingCamera(); sometimes works sometimes not.
Any help please?
Can anyone tell me how to check if the android phone has a front camera too?
There is no API for this, at least through Android 2.2. Sorry!
I'd tried to use some help form https://docs.google.com/View?id=dhtsnvs6_57d2hpqtgr but Camera camera = FrontFacingCamera.getFrontFacingCamera(); sometimes works sometimes not.
That is for two specific models of phones, not for Android devices in general. With luck, the upcoming Gingerbread release will add built-in support for front-facing cameras.
In the meantime, you need to get the instructions (like the one you linked to) from each and every device manufacturer and attempt to follow them.
private boolean hasFlash() {
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.M) {
try {
if(camManager==null)
camManager=(CameraManager)getSystemService( CAMERA_SERVICE );
String cameraId = camManager.getCameraIdList()[1];
CameraCharacteristics cameraCharacteristics = camManager.getCameraCharacteristics( cameraId );
return cameraCharacteristics.get( CameraCharacteristics.FLASH_INFO_AVAILABLE );
} catch (Exception e) {
e.printStackTrace();
}
}
return false;
}