0

I am currently using the Xamarin to build a cross-platform mobile application.
Basically my app only using the webview(The webview only opens a website that has a upload image function), for some extract features I have to use the webchromeclient for Android.
After adding setting up the webchromeclient, The webview can not open the file picker from the android device. (iphone works fine because the webchromeclient has noting to do with IOS path);

Here's the struct for my project

---test
     |_ CustomWebView.cs
     |_ MainPage.xaml
     |_ MainPage.cs
---test.Android
     |_ MainActivity.cs
     |_ AndroidCustomWebViewRenderer.cs
---test.IOS
     |_ IOS files

CustomWebView.cs

using Xamarin.Forms;

namespace test
{
    public class CustomWebView : WebView
    {
         
    }
}

AndroidCustomWebViewRenderer.cs

[assembly: ExportRenderer(typeof(CustomWebView), typeof(CustomWebViewRenderer))]
public class CustomWebViewRenderer : WebViewRenderer
{

    public CustomWebViewRenderer(Context context) : base(context)
    {
    }

    protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.WebView> e)
    {
        base.OnElementChanged(e);

        if (this.Control != null)
        {
            Android.Webkit.WebView webView = this.Control;
            webView.Settings.SetGeolocationEnabled(true);


            webView.Settings.JavaScriptEnabled = true;
            webView.Settings.AllowFileAccess = true;
            webView.Settings.AllowFileAccessFromFileURLs = true;
            webView.Settings.AllowUniversalAccessFromFileURLs = true;


            webView.SetWebChromeClient(new TestWebViewClient());
          
        }
    }

    public class TestWebViewClient : Android.Webkit.WebChromeClient
    {
        
        public override bool OnShowFileChooser(Android.Webkit.WebView webView, IValueCallback filePathCallback, FileChooserParams fileChooserParams)
        {
           
            return base.OnShowFileChooser(webView, filePathCallback, fileChooserParams);

        }



        public override bool OnConsoleMessage(Android.Webkit.ConsoleMessage consoleMessage)
        {
            Log.Debug("WebViewConsole", $"{consoleMessage.Message()}");
            return base.OnConsoleMessage(consoleMessage);
        }


    }
}

MainActivity.cs

namespace test.Droid
{
    [Activity(Label = "test", Icon = "@mipmap/icon", Theme = "@style/MainTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation | ConfigChanges.UiMode | ConfigChanges.ScreenLayout | ConfigChanges.SmallestScreenSize )]
    public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
    {
        protected override void OnCreate(Bundle savedInstanceState)
        {
            base.OnCreate(savedInstanceState);

            Xamarin.Essentials.Platform.Init(this, savedInstanceState);
            global::Xamarin.Forms.Forms.Init(this, savedInstanceState);
            LoadApplication(new App());
        }
        public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Android.Content.PM.Permission[] grantResults)
        {
            Xamarin.Essentials.Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults);

            base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
        }

    }
}

And the AndroidManifest.xml has all the permissions for accessing the Storage. So I assume that something wrong with the webchromeclient that missing something for opening the default file picker from android.

Tim
  • 33
  • 8

1 Answers1

0

You can try to add the following code into the TestWebViewClient:

public class TestWebViewClient : Android.Webkit.WebChromeClient
{
        public static int filechooser = 1;
        public static IValueCallback message;


        public override bool OnShowFileChooser(global::Android.Webkit.WebView webView, IValueCallback filePathCallback, FileChooserParams fileChooserParams)
        {
            message = filePathCallback;
            Intent chooserIntent = new Intent(Intent.ActionGetContent);
            chooserIntent.AddCategory(Intent.CategoryOpenable);
            chooserIntent.SetType("*/*");
            Xamarin.Essentials.Platform.Platform.CurrentActivity.StartActivityForResult(Intent.CreateChooser(chooserIntent, "File Chooser"), filechooser);
            return true;
        }
}

And in the MainActivity:

protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
    {
        base.OnActivityResult(requestCode, resultCode, data);
        if(data !=null)
        {
            if (requestCode == MyWebChromeClient.filechooser)
            {
                if(MyWebChromeClient.message !=null)
                {
                    TestWebViewClient.message.OnReceiveValue(WebChromeClient.FileChooserParams.ParseResult((int)resultCode, data));
                    TestWebViewClient.message = null;
                }
            }
        }
    }
Liyun Zhang - MSFT
  • 8,271
  • 1
  • 2
  • 14