Skip to content
This repository has been archived by the owner on May 1, 2024. It is now read-only.

CameraView restricts access to flash #1987

Open
mksdevelop opened this issue Sep 25, 2023 · 0 comments
Open

CameraView restricts access to flash #1987

mksdevelop opened this issue Sep 25, 2023 · 0 comments
Labels
bug Something isn't working. Breaky break.

Comments

@mksdevelop
Copy link

mksdevelop commented Sep 25, 2023

Description

Hello.
My application uses a flash to blink at a certain frequency. For example, I need to blink at a frequency of 1, 2, 10, 20, 30, 40 Hz in turn, and there may also be a pause between blinks.
In some cases, you also need to shoot a video.

If while recording a video, I try to use the flash, then I get an exception

Android.Hardware.Camera2.CameraAccessException CAMERA_IN_USE (4): setTorchMode:2125: Torch for camera "0" is not available due to an existing camera user

I can't use flash if I'm using a camera.
I understand that this may be a limitation of the system, but the CameraView component does not have the required functionality to enable flash.

Stack Trace

at Java.Interop.JniEnvironment+InstanceMethods.CallVoidMethod (Java.Interop.JniObjectReference instance, Java.Interop.JniMethodInfo method, Java.Interop.JniArgumentValue* args) [0x00068] in /Users/runner/work/1/s/xamarin-android/external/Java.Interop/src/Java.Interop/obj/Release/JniEnvironment.g.cs:11884
at Java.Interop.JniPeerMembers+JniInstanceMethods.InvokeAbstractVoidMethod (System.String encodedMember, Java.Interop.IJavaPeerable self, Java.Interop.JniArgumentValue* parameters) [0x0001a] in /Users/runner/work/1/s/xamarin-android/external/Java.Interop/src/Java.Interop/Java.Interop/JniPeerMembers.JniInstanceMethods_Invoke.cs:47
at Android.Hardware.Camera2.CameraManager.SetTorchMode (System.String cameraId, System.Boolean enabled) [0x00032] in /Users/runner/work/1/s/xamarin-android/src/Mono.Android/obj/Release/monoandroid10/android-33/mcw/Android.Hardware.Camera2.CameraManager.cs:689
at AppName.Droid.Services.FlashlightService.TurnOff () [0x00010] in /Users/dev/Develop/Projects/AppName/AppName.Android/Services/FlashlightService.cs:54
at AppName.Services.Flashlight.Stroboscope.Stop () [0x0003a] in /Users/dev/Develop/Projects/AppName/AppName/Services/Flashlight/Stroboscope.cs:46
at AppName.Services.Flashlight.Stroboscope.Start (System.Int32 frequency) [0x00001] in /Users/dev/Develop/Projects/AppName/AppName/Services/Flashlight/Stroboscope.cs:25
at AppName.Domain.Models.NeoRec.Stages.PhotoStimulationStage.Init (AppName.Domain.Models.NeoRec.Record record) [0x00070] in /Users/dev/Develop/Projects/AppName/AppName/Domain/Models/NeoRec/Stages/PhotoStimulationStage.cs:44
at AppName.Services.Exam.ExaminationService.GetNextStage () [0x00049] in /Users/dev/Develop/Projects/AppName/AppName/Services/Exam/ExaminationService.cs:124
at AppName.Services.Exam.ExaminationService.SkipStage () [0x00014] in /Users/dev/Develop/Projects/AppName/AppName/Services/Exam/ExaminationService.cs:106
at AppName.UI.ViewModels.NeoRecExaminationViewModel.<get_StageSkipCommand>b__74_0 () [0x00015] in /Users/dev/Develop/Projects/AppName/AppName/UI/ViewModels/NeoRecExaminationViewModel.cs:265
at Xamarin.CommunityToolkit.ObjectModel.Internals.BaseAsyncCommand2[TExecute,TCanExecute].ExecuteAsync (TExecute parameter) [0x00093] in <6243432aa10f4b63ae8efc1ac5c0cfbc>:0 at Xamarin.CommunityToolkit.Helpers.SafeFireAndForgetExtensions.HandleSafeFireAndForget[TException] (System.Threading.Tasks.Task task, System.Boolean continueOnCapturedContext, System.Action1[T] onException) [0x0006f] in <6243432aa10f4b63ae8efc1ac5c0cfbc>:0
at System.Runtime.CompilerServices.AsyncMethodBuilderCore+<>c.b__7_0 (System.Object state) [0x00000] in /Users/builder/jenkins/workspace/archive-mono/2020-02/android/release/company/class/referencesource/mscorlib/system/runtime/compilerservices/AsyncMethodBuilder.cs:1021
at Android.App.SyncContext+<>c__DisplayClass2_0.b__0 () [0x00000] in /Users/runner/work/1/s/xamarin-android/src/Mono.Android/Android.App/SyncContext.cs:36
at Java.Lang.Thread+RunnableImplementor.Run () [0x00008] in /Users/runner/work/1/s/xamarin-android/src/Mono.Android/Java.Lang/Thread.cs:36
at Java.Lang.IRunnableInvoker.n_Run (System.IntPtr jnienv, System.IntPtr native__this) [0x00008] in /Users/runner/work/1/s/xamarin-android/src/Mono.Android/obj/Release/monoandroid10/android-33/mcw/Java.Lang.IRunnable.cs:84
at Android.Runtime.JNINativeWrapper.Wrap_JniMarshal_PP_V (_JniMarshal_PP_V callback, System.IntPtr jnienv, System.IntPtr klazz) [0x00005] in /Users/runner/work/1/s/xamarin-android/src/Mono.Android/Android.Runtime/JNINativeWrapper.g.cs:22
at (wrapper native-to-managed) Android.Runtime.JNINativeWrapper.Wrap_JniMarshal_PP_V(intptr,intptr)
--- End of managed Android.Hardware.Camera2.CameraAccessException stack trace ---
android.hardware.camera2.CameraAccessException: CAMERA_IN_USE (4): setTorchMode:2125: Torch for camera "0" is not available due to an existing camera user
at android.hardware.camera2.CameraManager.throwAsPublicException(CameraManager.java:1209)
at android.hardware.camera2.CameraManager$CameraManagerGlobal.setTorchMode(CameraManager.java:1756)
at android.hardware.camera2.CameraManager.setTorchMode(CameraManager.java:942)
at crc64ee486da937c010f4.ButtonRenderer.n_onClick(Native Method)
at crc64ee486da937c010f4.ButtonRenderer.onClick(ButtonRenderer.java:107)
at android.view.View.performClick(View.java:7460)
at android.view.View.performClickInternal(View.java:7433)
at android.view.View.access$3700(View.java:840)
at android.view.View$PerformClick.run(View.java:28894)
at android.os.Handler.handleCallback(Handler.java:938)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.L

Steps to Reproduce

  1. Create page with CameraView
  2. Try turning on the flashlight from the service (see below FlashlightService.TurnOff())
  3. App crushing

Expected Behavior

App not crushing

Actual Behavior

App crushing

Basic Information

  • Version with issue: 8.2.1
  • Last known good version: -
  • IDE: Visual Studio for Mac
  • Platform Target Frameworks:
    • Android: 13
  • Android Support Library Version: 28.0.03
  • Nuget Packages:
  • Affected Devices:
[assembly: Dependency(typeof(FlashlightService))]
namespace AppName.Droid.Services
{
    internal class FlashlightService : IFlashlightService
    {
        private readonly CameraManager _cameraManager;
        private readonly string _flashCameraId;
        private int _maxTorchLevel;

        public bool IsFlashAvailable { get; }
        public bool IsTorchLevelAvailable { get; private set; }
        public float TorchLevel { get; set; } = 1f;

        public FlashlightService()
        {
            _cameraManager = (CameraManager)Platform.AppContext.GetSystemService(Context.CameraService);

            foreach (var id in _cameraManager.GetCameraIdList())
            {
                var hasFlash = _cameraManager.GetCameraCharacteristics(id).Get(CameraCharacteristics.FlashInfoAvailable);
                IsFlashAvailable = Java.Lang.Boolean.True.Equals(hasFlash);
                if (Java.Lang.Boolean.True.Equals(hasFlash))
                {
                    _flashCameraId = id;
                    FindMaxTorchLevel(_flashCameraId);
                    return;
                }
            }
        }

        public void TurnOn()
        {
            if (!IsFlashAvailable)
                return;

            if (IsTorchLevelAvailable)
                _cameraManager.TurnOnTorchWithStrengthLevel(_flashCameraId, GetCurrentTorchLevel());
            else
                _cameraManager.SetTorchMode(_flashCameraId, true);
        }

        public void TurnOff()
        {
            if (!IsFlashAvailable)
                return;

            _cameraManager.SetTorchMode(_flashCameraId, false);
        }

        private int GetCurrentTorchLevel()
        {
            var min = 1;
            var max = _maxTorchLevel;
            return (int)((max - min) * TorchLevel) + min;
        }

        private void FindMaxTorchLevel(string cameraId)
        {
            var characteristics = _cameraManager.GetCameraCharacteristics(cameraId);
            try
            {
                IsTorchLevelAvailable = characteristics.Keys.Contains(CameraCharacteristics.FlashInfoStrengthMaximumLevel);
            }
            catch { /*when no find characteristic*/ }

            if (!IsTorchLevelAvailable)
                return;

            _maxTorchLevel = (int)_cameraManager.GetCameraCharacteristics(_flashCameraId).Get(CameraCharacteristics.FlashInfoStrengthMaximumLevel);
        }
    }
}
@mksdevelop mksdevelop added the bug Something isn't working. Breaky break. label Sep 25, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug Something isn't working. Breaky break.
Projects
None yet
Development

No branches or pull requests

1 participant