Search code examples
xamarinxamarin.android

WebView File Chooser stops to respond after cancelled selection


we have implement file chooser for web view. it works successfully when attachment is selected, but fails when cancelled without file specification. The file chooser just stops to react on click

any help is appreciated. Thanks

we use chrome client. it works fine if in all cases, file selection is listed. but even from the first file selection is cancelled, no longer file chooser will work. It is Xamarin.Android app based fully on webview

Our code is:

protected override void OnActivityResult(int requestCode, Result resultCode, Intent intent)
{
    if (requestCode == FILECHOOSER_RESULTCODE)
    {
        if (null == _mUploadMessage)
            return;

        // Check that the response is a good one
        if (resultCode == Result.Ok)
        {
            Android.Net.Uri[] results = null;
            if (intent == null)
            {
                // If there is not data, then we may have taken a photo
                if (mCameraPhotoPath != null)
                {
                    results = new Android.Net.Uri[] { Android.Net.Uri.Parse(mCameraPhotoPath) };
                }
            }
            else
            {
                if (intent.DataString != null)
                {
                    results = new Android.Net.Uri[] { Android.Net.Uri.Parse(intent.DataString) };
                }
            }

            _mUploadMessage.OnReceiveValue(results);
            _mUploadMessage = null;
        }
    }
}

Chrome client:

        var chrome = new FileChooserWebChromeClient((uploadMsg) =>
        {
            _mUploadMessage = uploadMsg;

            mCameraPhotoPath = null;

            Intent takePictureIntent = new Intent(Android.Provider.MediaStore.ActionImageCapture);

            //Create the File where the photo should go
            File photoFile = null;
            try
            {
                string folder = Android.OS.Environment.ExternalStorageDirectory.AbsolutePath;
                photoFile = new File(folder, "image" + DateTime.Now.Millisecond + ".png");
                takePictureIntent.PutExtra("PhotoPath", mCameraPhotoPath);
            }
            catch (IOException ex)
            {
                // Error occurred while creating the File
                System.Console.WriteLine("" + ex.ToString());
            }

            // Continue only if the File was successfully created
            if (photoFile != null)
            {
                mCameraPhotoPath = "file:" + photoFile.AbsolutePath;
                takePictureIntent.PutExtra(Android.Provider.MediaStore.ExtraOutput,
                        Android.Net.Uri.FromFile(photoFile));
            }
            else
            {
                takePictureIntent = null;
            }

            Intent contentSelectionIntent = new Intent(Intent.ActionGetContent);
            contentSelectionIntent.AddCategory(Intent.CategoryOpenable);
            contentSelectionIntent.SetType("image/*");

            Intent[] intentArray;
            if (takePictureIntent != null)
            {
                intentArray = new Intent[] { takePictureIntent };
            }
            else
            {
                intentArray = new Intent[0];
            }

            Intent chooserIntent = new Intent(Intent.ActionChooser);
            chooserIntent.PutExtra(Intent.ExtraIntent, contentSelectionIntent);
            chooserIntent.PutExtra(Intent.ExtraTitle, this.GetStringFromResource(Resource.String.chose_photo));
            chooserIntent.PutExtra(Intent.ExtraInitialIntents, intentArray);

            base.StartActivityForResult(chooserIntent, HarmonyAndroid.AndroidMainActivity.FILECHOOSER_RESULTCODE);
        });

        return chrome;

Part 2

class FileChooserWebChromeClient : WebChromeClient
{
    Action<IValueCallback> callback;

    public FileChooserWebChromeClient(Action<IValueCallback> callback)
    {
        this.callback = callback;
    }

    public override bool OnShowFileChooser(WebView webView, IValueCallback filePathCallback, FileChooserParams fileChooserParams)
    {
        callback(filePathCallback);
        return true;
    }

    public override void OnCloseWindow(WebView window)
    {
        base.OnCloseWindow(window);
    }
}

Part 3

   webView.ImprovePerformance();
   webView.SetWebViewClient(new HomeWebViewClient(customWebViewClientListener, clientId));
   webView.SetWebChromeClient(chrome);
   webView.Settings.JavaScriptEnabled = true;
   webView.Settings.DomStorageEnabled = true;
   webView.SetDownloadListener(new CustomDownloadListener(activity, customDownloadListener));
   webView.AddJavascriptInterface(new JavaScriptToCSharpCommunication(activity, javaScriptToCSharpCommunicationListener), Constants.JS_CSHARP_COMMUNICATOR_NAME);

Solution

  • Try to give a null object to the uri callback, when the resultCode is not RESULT_OK.

    add in your OnActivityResult method:

    if (resultCode != Result.Ok)
     {
        _mUploadMessage.OnReceiveValue(null);
        _mUploadMessage = null;
        return;
     }