i have app for video call, in app i am using webview for video call between two users. 2 users can aslo share file with each other via from gallery or camera.
Now the issue i am facing when both users are in between call and one user send image from camera, the camera that is already running for video get stopped. These are errors i am getting
07-02 14:47:06.115 I/CameraManagerGlobal( 3656): Camera 1 facing CAMERA_FACING_FRONT state now CAMERA_STATE_IDLE for client com.kihmobile.kih API Level 2 07-02 14:47:06.175 I/CameraManagerGlobal( 3656): Camera 1 facing CAMERA_FACING_FRONT state now CAMERA_STATE_CLOSED for client com.kihmobile.kih API Level 2 07-02 14:47:06.182 E/CameraCaptureSession( 3656): Session 0: Exception while stopping repeating: 07-02 14:47:06.182 E/CameraCaptureSession( 3656): android.hardware.camera2.CameraAccessException: CAMERA_DISCONNECTED (2): cancelRequest:473: Camera device no longer alive 07-02 14:47:06.182 E/CameraCaptureSession( 3656): at android.hardware.camera2.CameraManager.throwAsPublicException(CameraManager.java:1127) 07-02 14:47:06.182 E/CameraCaptureSession( 3656): at android.hardware.camera2.impl.ICameraDeviceUserWrapper.cancelRequest(ICameraDeviceUserWrapper.java:97) 07-02 14:47:06.182 E/CameraCaptureSession( 3656): at android.hardware.camera2.impl.CameraDeviceImpl.stopRepeating(CameraDeviceImpl.java:1151) 07-02 14:47:06.182 E/CameraCaptureSession( 3656): at android.hardware.camera2.impl.CameraCaptureSessionImpl.close(CameraCaptureSessionImpl.java:526) 07-02 14:47:06.182 E/CameraCaptureSession( 3656): at
android.hardware.camera2.impl.CameraCaptureSessionImpl$2.onDisconnected(CameraCaptureSessionImpl.java:737)
this is my webview code in xamarin
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; using Android.Annotation; using Android.App; using Android.Content; using Android.OS; using Android.Provider; using Android.Runtime; using Android.Support.V4.Content; using Android.Views; using Android.Webkit; using Android.Widget; using Java.Interop; using Java.IO; using OnlineKIHStore.Droid; using Xamarin.Forms; using Xamarin.Forms.Platform.Android; [assembly: ExportRenderer(typeof(OnlineKIHStore.MyWebView), typeof(MyWebViewRenderer))] namespace OnlineKIHStore.Droid { public class MyWebViewRenderer : WebViewRenderer { MainActivity mContext; public MyWebViewRenderer(Context context) : base(context) { this.mContext = context as MainActivity; } protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.WebView> e) { base.OnElementChanged(e); var oldWebView = e.OldElement as MyWebView; if (oldWebView != null) oldWebView.EvaluateJavascript = null; var newWebView = e.NewElement as MyWebView; if (newWebView != null) newWebView.EvaluateJavascript = async (js) => { ManualResetEvent reset = new ManualResetEvent(false); var response = ""; Device.BeginInvokeOnMainThread(() => { // System.Diagnostics.Debug.WriteLine("Javascript Send: " + js); Control?.EvaluateJavascript(js, new JavascriptCallback((r) => { response = r; reset.Set(); })); }); await Task.Run(() => { reset.WaitOne(); }); if (response == "null") response = string.Empty; return response; }; if (Control != null && e.NewElement != null) { InitializeCommands((MyWebView)e.NewElement); //SetupControl(); } Control.Settings.JavaScriptEnabled = true; Control.Settings.MediaPlaybackRequiresUserGesture = false; Control.ClearCache(true); Control.SetWebViewClient(new WebViewClientAuthentication()); Control.SetWebChromeClient(new MyWebClient(mContext)); Control.Settings.DomStorageEnabled = true; Control.Settings.AllowUniversalAccessFromFileURLs = true; Control.Settings.AllowFileAccess = true; global::Android.Webkit.WebView.SetWebContentsDebuggingEnabled(true); } private void InitializeCommands(MyWebView element) { element.RefreshCommand = new Command(() => { Control?.Reload(); }); element.GoBackCommand = new Command(() => { var ctrl = Control; if (ctrl == null) return; if (ctrl.CanGoBack()) ctrl.GoBack(); }); element.CanGoBackFunction = () => { var ctrl = Control; if (ctrl == null) return false; return ctrl.CanGoBack(); }; // This allows you to show a file chooser dialog from the WebView } public class WebViewClientAuthentication : WebViewClient { public override void OnReceivedSslError(Android.Webkit.WebView view, SslErrorHandler handler, Android.Net.Http.SslError error) { handler.Proceed(); } } public class MyWebClient : WebChromeClient { private static int filechooser = 1; private IValueCallback message; MainActivity mContext; private static int cameraCode=11; public static Android.Net.Uri myImageUri { get; private set; } public MyWebClient(MainActivity context) { this.mContext = context; } private Android.Net.Uri getFileUri() { Android.Net.Uri imageUri = null; string path = getFilePath(); File file = new File(path); if (Build.VERSION.SdkInt >= BuildVersionCodes.N) { try { imageUri = FileProvider.GetUriForFile(this.mContext, $"{mContext.ApplicationInfo.PackageName}.fileprovider", file); } catch (Exception e) { } } else { imageUri = Android.Net.Uri.FromFile(file); } return imageUri; } private string getFilePath() { File externalDataDir = Android.OS.Environment .GetExternalStoragePublicDirectory(Android.OS.Environment.DirectoryDcim); File cameraDataDir = new File(externalDataDir.AbsolutePath + File.Separator + "Images"); cameraDataDir.Mkdirs(); string mCameraFilePath = cameraDataDir.AbsolutePath + File.Separator + "send_new_image.jpg"; return mCameraFilePath; } [Export] [JavascriptInterface] private Intent createCameraIntent() { Intent cameraIntent = new Intent(MediaStore.ActionImageCapture); //Intent cameraIntent = new Intent(MediaStore.ActionImageCapture); myImageUri = getFileUri(); //cameraIntent.PutExtra(MediaStore.Images.Media.InterfaceConsts.Orientation, 0); //cameraIntent.PutExtra(MediaStore.ExtraOutput, myImageUri); return cameraIntent; } public override bool OnShowFileChooser(Android.Webkit.WebView webView, IValueCallback filePathCallback, WebChromeClient.FileChooserParams fileChooserParams) { // AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(this.mContext); // using (dialogBuilder = new AlertDialog.Builder(this.mContext)) // { // dialogBuilder.SetTitle("Upload Image"); // dialogBuilder.SetPositiveButton("Choose from Library", delegate // { // Intent chooserIntent = fileChooserParams.CreateIntent(); // chooserIntent.SetType("image/*"); // this.mContext.StartActivity(Intent.CreateChooser(chooserIntent, "Select Picture"), 1, OnActivityResult); // } // dialogBuilder.SetNegativeButton("Cancel", delegate // { // dialogBuilder.Dispose(); // }); // } AlertDialog.Builder alertDiag = new AlertDialog.Builder(this.mContext); alertDiag.SetTitle("Confirm delete"); alertDiag.SetCancelable(false); alertDiag.SetMessage("Once deleted the move cannot be undone"); alertDiag.SetPositiveButton("Gallery", (senderAlert, args) => { this.message = filePathCallback; Intent chooserIntent = fileChooserParams.CreateIntent(); chooserIntent.AddCategory(Intent.CategoryOpenable); this.mContext.StartActivity(Intent.CreateChooser(chooserIntent, "File Chooser"), filechooser, this.OnActivityResult); }); alertDiag.SetNegativeButton("Camera", (senderAlert, args) => { this.message = filePathCallback; mContext.StartActivity(createCameraIntent(), cameraCode, this.OnActivityResult); }); Dialog diag = alertDiag.Create(); diag.Show(); //this.message = filePathCallback; //Intent chooserIntent = fileChooserParams.CreateIntent(); //chooserIntent.AddCategory(Intent.CategoryOpenable); //this.mContext.StartActivity(Intent.CreateChooser(chooserIntent, "File Chooser"), filechooser, this.OnActivityResult); return true; } private void OnActivityResult(int requestCode, Result resultCode, Intent data) { if (resultCode != Android.App.Result.Ok) { this.message.OnReceiveValue(null); return; } //if (data != null) //{ if (requestCode == MyWebClient.cameraCode) { if (null == this.message) { return; } try { Android.Net.Uri[] uris = new Android.Net.Uri[1]; uris[0] = MyWebClient.myImageUri; this.message.OnReceiveValue(uris); } catch (Exception ex) { throw ex; } this.message = null; } else if (requestCode == filechooser) { if (null == this.message) { return; } try { this.message.OnReceiveValue(WebChromeClient.FileChooserParams.ParseResult((int)resultCode, data)); } catch (Exception) { throw; } this.message = null; } //} } [TargetApi(Value = 21)] public override void OnPermissionRequest(PermissionRequest request) { mContext.RunOnUiThread(() => { request.Grant(request.GetResources()); }); } } internal class JavascriptCallback : Java.Lang.Object, IValueCallback { public JavascriptCallback(Action<string> callback) { _callback = callback; } private Action<string> _callback; public void OnReceiveValue(Java.Lang.Object value) { //System.Diagnostics.Debug.WriteLine("Javascript Return: " + Convert.ToString(value)); _callback?.Invoke(Convert.ToString(value)); } } } }
i just want to know how i can resume camera in video call after user send image from camera using input file...?
here are some picture how app looks like
this is running video call between two users and both users camera are open
android user where he can chat and send file via gallery or camera
now here when android user click on camera, camera does open to capture image, but camera that is already running for video call get stop