I am using the camera flash for a Morse code application. I create a new camera object when the class is created. The user has a button which is used to reset and also release the camera when required (If they want to stop the light Morse sequence prematurely).
The problem is that when they hit the reset button because the activity is not created or loaded again the camera never get reinitialized - this is a problem because the method of the class that it is calling is used by another class and releases the camera when it is has completed it's function. I am not sure how to structure the code in a way that allows me to do this.
I am wondering if anyone has any advice/suggestions in how to achieve this?
//Camera object being declared
Light light;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity__morse);
//Camera object being initialized
light = new Light
}
//Reset user pressed a button
public void reset(View view)
{
light.release();
}
//Releasing the camera
public void release() {
if(camera != null)
{
camera.stopPreview();
camera.release();
camera = null;
}
}
Don't initialize the camera in onCreate. Do it in onStart, and release it in onStop.
I am using a Camera, and I call the open method on it in onCreate in an activity. When the activity is destroyed, I release the Camera. However, a fragment in the activity may be using the Camera (for example, making the flash blink repeatedly), so when the orientation changes from portrait to landscape, for example, the Camera is released (because the activity is destroyed) and the reference is set to null, causing a NPE to be thrown from the fragment. How do I keep the reference to the Camera during orientation change (so that the flash keeps blinking) and release the Camera when the activity is destroyed (for example, when the user clicks the Back button)?
public static Camera camera = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity);
if (camera == null) {
camera = Camera.open();
if (camera == null) {
Log.e(LOG_TAG, "Unable to get back-facing camera.");
finish();
}
}
// ..
}
#Override
protected void onDestroy() {
if (camera != null) {
camera.release();
camera = null;
}
super.onDestroy();
}
Try this android:configChanges="keyboardHidden|orientation"
For api 13 or higher android:configChanges="keyboardHidden|orientation|screenSize"
As of api 13 screen size also changes when a device switches between portrait and landscape mode
So this way your activity will not be destroyed during orientation change
I am making an android flashlight app. I it has two activities, a main activity and a settings activity where the camera led can be toggled on and off. It also has another class where all the camera changes are handled like opening it, releasing it, and turning the light on and off.
I kept getting errors when turning on the led based on shared preference settings because I was not opening and releasing the camera in the correct activity lifecycle stages. I fixed the issues by releasing the camera when onPause is called in either activity and turning the led on or off (based on shared preference settings) when onResume is called in either activity.
The problem I am having now is that if the led is on, it turns off briefly when switching from one activity to the other because I have to release the camera and then open again in the new activity. Can anyone help me figure out a way to eliminate this problem? Where should I open and release the camera? I have tried releasing it in on destroy but the led stays on when the app is minimized to the background, which is undesirable. Thanks for any suggestions.
In both main and settings activity I have:
#Override
protected void onResume() {
super.onResume();
if (sp.getBoolean("LED_TOGGLE_CB", false) == true) {
flash.turnFlashOn();
}
}
#Override
protected void onPause() {
super.onPause();
flash.killCamera();
}
In the Flash class I have:
void getCamera() {
if(camera == null) {
try {
camera = Camera.open();
params = camera.getParameters();
} catch(RuntimeException e) {
Log.e("Camera Error. Failed to Open. Error: ", e.getMessage());
}
}
}
void turnFlashOn() {
getCamera();
params.setFlashMode(Parameters.FLASH_MODE_TORCH);
camera.setParameters(params);
camera.startPreview();
isFlashOn = true;
}
public void killCamera() {
if (camera != null) {
camera.stopPreview();
camera.setPreviewCallback(null);
camera.release();
camera = null;
}
}
i have develped a camera app which uses camera API from this link
its working perfectly it shows preview takes picture but when i finish the app it never releases camera ...i can't use camera solely after installing this app ...even the app get crashed when i restart it.
here's how i am releasing the camera-->
#Override
protected void onPause() {
super.onPause();
if (camera != null) {
// preview.setCamera(null);
camera.stopPreview();
camera.setPreviewCallback(null);
camera.release();
camera = null;
}
}
onResume i put this code also but didn't work..s
#Override
protected void onResume() {
super.onResume();
camera = Camera.open();
preview.setCamera(camera);
}
I have same problems on HTC One X (4.1.2) and Nexus 4(4.3), but on Galaxy Nexus (4.3) same release method works great.
I temporary solved this issue with using camera.unlock() instead of camera.release() and keeping static reference to Camera object.
I'm using the Android APIDemo sample code.
When I run the CameraPreview example, at first it was giving me an error.
I traced that one down and the sample was working for a while.
Now, it no longer works. It says
ERROR/AndroidRuntime(2949): java.lang.RuntimeException: Fail to connect to camera service
What can be causing that? It happens when camera.open() is called.
Thanks,
Tee
Be sure to properly release all the aquired camera resources:
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
if (mCam != null) {
mCam.stopPreview();
mCam.setPreviewCallback(null);
mCam.release();
mCam = null;
}
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
if (mCam == null) {
mCam = Camera.open();
try {
mCam.setPreviewDisplay(holder);
// TODO test how much setPreviewCallbackWithBuffer is faster
mCam.setPreviewCallback(this);
} catch (IOException e) {
mCam.release();
mCam = null;
}
}
}
Make sure your <uses-permission> elements are in the proper positions in your AndroidManifest.xml file.
It happens if your activity does not close the camera properly in surfaceDestroyed or onConfigurationChanged etc...
Don't forget to do this everytime you go out of your activity:
if (camera!=null){
camera.stopPreview();
camera.release();
camera=null;
}
Another reason of this error is when you try to open camera but some other application or even your application is already using camera.
I also get this type of issue on a HTC device. To solve add this code:
#Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
if (camera!=null)
{
camera.stopPreview();
camera.release();
camera=null;
}
}
And yet you cannot start camera then restart device.
Also, if you are using the emulator, make sure you have selected to Emulate the Front Camera and/or the Back Camera.
Android Virtual Device Manager->Select Device->Edit->Front Camera->Emulated
As others mention, you have to call release() on your camera object when you're finished.
I wasn't doing this initially, so I changed my code but it still gave me the same error. I was deploying directly to a physical handset and had to restart the phone before it worked
I also received this error when I was testing and stopped execution before reaching the point in code when the:
if (camera!=null){
camera.stopPreview();
camera.release();
camera=null;
}
was called. This then blocked the camera because it hadn't een released properly. My solution was to turn the camera off and back on again. You can confirm this is the case by trying to use the inbuilt Camera app in your phone. It won't work either because it is still busy.
Second #matt-burns however you might want to check that you're only trying to get the camera once. I had forgotten to comment out a line and was trying to launch two activities that would both try to obtain the camera.