Runtime Error: failed to connect to camera service in android - android

I wanted to make use of the zxing library to detect qrcodes in my app. But for the apps viewing purpose, i had to change the custom display orientation to portrait. Hence i had to integrate the whole zxing library into my app and addded camera.setDisplayOrientation(90) to the openDriver() method.
After doing this, the program works, but I get "Runtime exceptions : Fail to connect to camera service" randomly.
public void openDriver(SurfaceHolder holder) throws IOException {
if (camera == null) {
camera = Camera.open();
camera.setDisplayOrientation(90);
if (camera == null) {
throw new IOException();
}
}
camera.setPreviewDisplay(holder);
if (!initialized) {
initialized = true;
configManager.initFromCameraParameters(camera);
}
configManager.setDesiredCameraParameters(camera);
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
reverseImage = prefs.getBoolean(PreferencesActivity.KEY_REVERSE_IMAGE, false);
if (prefs.getBoolean(PreferencesActivity.KEY_FRONT_LIGHT, false)) {
FlashlightManager.enableFlashlight();
}
}
public void closeDriver() {
if (camera != null) {
FlashlightManager.disableFlashlight();
camera.release();
camera = null;
framingRect = null;
framingRectInPreview = null;
}
}
/**
* Asks the camera hardware to begin drawing preview frames to the screen.
*/
public void startPreview() {
if (camera != null && !previewing) {
camera.startPreview();
previewing = true;
}
}
/**
* Tells the camera to stop drawing preview frames.
*/
public void stopPreview() {
if (camera != null && previewing) {
if (!useOneShotPreviewCallback) {
camera.setPreviewCallback(null);
}
camera.stopPreview();
previewCallback.setHandler(null, 0);
autoFocusCallback.setHandler(null, 0);
previewing = false;
}
}

I doubt that the orientation change is causing that. I have found you will get that error whenever an activity stops but fails to call Camera.release in their onPause. The result is that the next time you try to do Camera.open you get that runtime error since the driver still considers it open regardless of the app/activity that opened it being gone.
You can easily get this to happen while debugging/testing stuff when something throws an exception and brings the activity down. You need to be very diligent about catching all exceptions and being sure to release the camera before finishing the activity.
BTW, are you finding you need to power cycle the device in order to be able to open the camera again?

Related

How to restart camera preview on Xamarin forms when using a custom renderer view for a camera preview

I am trying to resume my Camera preview with android after putting the app to sleep or changing between apps. Or even starting a different app which uses the camera feature but the Camera crashed with getParameters() being null.
Is there a way to retrieve the control other the camera preview when resuming using the Xamarin forms application.
I have tried to use Camera.Restart() and didn't work.
public void SurfaceCreated(ISurfaceHolder holder)
{
try
{
if (Preview != null)
{
Preview.StopPreview();
Preview.Reconnect();
Preview.SetPreviewDisplay(holder);
Preview.EnableShutterSound(true);
}
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(#" ERROR: ", ex.Message);
}
}
public void SurfaceDestroyed(ISurfaceHolder holder)
{
Preview.StopPreview();
Preview.Release();
}
public void SurfaceChanged(ISurfaceHolder holder, Android.Graphics.Format format, int width, int height)
{
Camera.Parameters parameters = Preview.GetParameters();
parameters.FocusMode = Camera.Parameters.FocusModeContinuousPicture;
IList<Camera.Size> previewSizes = parameters.SupportedPreviewSizes;
// You need to choose the most appropriate previewSize for your app
Camera.Size previewSize = previewSizes[0];
parameters.SetPreviewSize(previewSize.Width, previewSize.Height);
Preview.SetParameters(parameters);
Preview.StartPreview();
}
I was able to get it to work by reading more thoroughly about the behaviour of the Android camera(Camera1) hardware.
If you are working on Xamarin and trying to create camera view within the app the best way to do it is making a custom renderer and create a camera view in each platform. Like shown here:
https://learn.microsoft.com/en-ca/xamarin/xamarin-forms/app-fundamentals/custom-renderer/view
but this example only shows how to create the camera preview, there is no camera hardware lifecycle or taking a pictures included.
To solve the issue for the question above I had simply to do Camera.Open(0) to gain control over the camera again within the lifecycle of Xamarin forms pages.
Here is what I did(in CameraPreview class in Xamarin Forms):
Created Camera open event handler:
public event EventHandler CloseCameraRequest;
Created a method to invoke the event:
public void OpenCamera()
{
OpenCameraRequest?.Invoke(this, EventArgs.Empty);
}
Registered the handler in the android camera native class:
protected override void OnElementChanged(ElementChangedEventArgs<CameraPreview> e)
{
base.OnElementChanged(e);
if (Control == null)
{
_nativeCameraPreview = new NativeCameraPreview(Context);
_nativeCameraPreview.PhotoCaptured += OnPhotoCaptured;
SetNativeControl(_nativeCameraPreview);
}
Control.Preview = Camera.Open(0);
if (e.OldElement != null)
{
e.NewElement.OpenCameraRequest -= OnOpenCameraRequest;
}
if (e.NewElement != null)
{
e.NewElement.OpenCameraRequest += OnOpenCameraRequest;
}
}
private void OnOpenCameraRequest(object sender, EventArgs e)
{
Control.Preview = Camera.Open(0);
}
Invoked the request all the way from Xamarin forms page OnAppearing method:
protected override void OnAppearing()
{
base.OnAppearing();
CameraPreview.OpenCamera();
}
This fixed the issue of resuming camera preview after opening other application which uses the camera or putting the app to sleep where camera preview will timeout.

The camera is in use by another app

I am developing a webRTC app using opentok. The app was working fine. I converted the app to library and launching the library activity by adding it to another project. The app is connecting to server but camera not opening. I am getting camera error as follows
E/opentok-videocapturer: The camera is in use by another app
java.lang.RuntimeException: Fail to connect to camera service
at android.hardware.Camera.<init>(Camera.java:518)
at android.hardware.Camera.open(Camera.java:360)
at com.opentok.android.DefaultVideoCapturer.init(DefaultVideoCapturer.java:110)
at com.opentok.android.BaseVideoCapturer.initTrap(BaseVideoCapturer.java:223)
public boolean isCameraUsebyApp() {
Camera camera = null;
try {
camera = Camera.open();
}
catch (RuntimeException e)
{
return true;
}
finally
{
if (camera != null)
{
camera.release();
}
}
return false;
}

How to save camera instance?

How to save the state of the camera so when i close the screen and turn it on again the camera gets back to its previous state.Should i bundle it?
public void getCamera() {
if (camera == null) {
try {
camera = Camera.open();
params = camera.getParameters();
} catch (RuntimeException e) {
Log.e(e.getMessage(), "Camera Error. Failed to Open. Error:Application will close! ");
finish();
}
}
}
Generally you don't want to do this- you want to release the camera in onPause and recapture it in onResume so other apps can use it as well.

Managing the camera - Fail to access camera

I'm writing a program that accesses the camera. It worked for a while, but now it is the Camera API is throwing exceptions because the camera is still in use when I try to open it. I think this is because I am not handling it correctly in my onPause, onResume, and where I use it. Here is my code:
#Override
protected void onResume(){
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 {
if (camera != null) {
camera.release();
camera = null;
}
camera = Camera.open(cameraId);
try {
camera.setPreviewTexture(cameraTexture);
}
catch(IOException e){
Log.i("CameraHome", "could not set camera preview");
}
}
catch (Exception e){
}
}
}
super.onResume();}
Pause:
#Override
public void onPause(){
stopLocationUpdates();
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putLong("timeLeft", timeLeft);
editor.putBoolean("lockedOut", lockedOut);
editor.apply();
if (camera != null) {
camera.release();
camera = null;
}
super.onPause();
}
In use:
//Take picture
camera.startPreview();
camera.takePicture(null, null,
new PhotoHandler(getApplicationContext()));
camera.stopPreview();
camera.release();
Got any ideas what I'm doing wrong? Every time I relaunch the application, it throws an exception saying that the camera is in use, even if I launch the default camera app and close it.
EDIT: The camera is being accessed, but my callback (onPictureTaken in PhotoHandler) is never being called, as if the picture isn't being captured properly.
Turns out this code works. Had to uninstall, restart, and reinstall. Then my onPictureTaken callback wasn't being called. I believe this was because I was calling stopPreview too soon. I moved that to my onPause and took away the release call after the takePicture call. Works fine now

How to set the camera light on torch in Tokbox?

I am using TokBox for an android project. I need to add a button which would turn the flash light on torch mode.
Tokbox Publisher object already provides a swapCamera() method which switches between all the available cameras of the device. But I couldn't find any API to change the flash light mode for the currently selected camera.
I tried getting an instance of android.hardware.Camera myself to change it manually, but it didn't work because I got the "java.lang.RuntimeException: Fail to connect to camera service" exception. It is because the Camera object is being used by Tokbox and is not released.
I could find no way to access the Camera instance that Tokbox is using either. It is even deprecated since android API level 21.
Can anyone suggest a way to change the camera parameters? I have access to the View that the video is being previewed on it.
I needed to stop the stream to be able to start the camera app to take a picture. I've found code to release the camera and attach it. Maybe you can use this code to release the camera, turn on the light and then attach the camera again
The following code releases the camera:
public void ReleaseCamera()
{
if (_myPub != null) {
_myPub.PublishVideo = false;
BaseVideoCapturer bvc = _myPub.Capturer;
if (bvc != null) {
bvc.StopCapture ();
bvc.Destroy ();
}
}
}
And this code attaches the camera again:
public void AttachCamera()
{
if (_myPub != null) {
BaseVideoCapturer bvc = _myPub.Capturer;
if (bvc != null) {
if (bvc.IsCaptureStarted == false) {
bvc.Init ();
bvc.StartCapture ();
_myPub.PublishVideo = true;
}
}
}
}
torch light will work only with back camera, so if you are publishing video with front camera then it will freez tokbox video.
if(publisher.cameraPosition == .back){
if let device = AVCaptureDevice.defaultDevice(withMediaType: AVMediaTypeVideo), device.hasTorch {
do {
try device.lockForConfiguration()
let torchOn = !device.isTorchActive
try device.setTorchModeOnWithLevel(1.0)
device.torchMode = torchOn ? .on : .off
device.unlockForConfiguration()
} catch {
print("error")
}
}
}

Categories

Resources