dotnet / MobileBlazorBindings

Experimental Mobile Blazor Bindings - Build native and hybrid mobile apps with Blazor
MIT License
1.2k stars 172 forks source link

File Input not working #203

Open sake402 opened 3 years ago

sake402 commented 3 years ago

I have an existing Blazor app that I have successfully ported into MBB. However file select inputs doesnt work.

<input class="fileupload-input" type="file" name="@Id" id="@Id" @onchange="OnSelected" />

The first time I tap a file input, the filechooser get opened and when a file is selected, nothing happens and the onchange event is not fired either. Subsequent tapping of the file input does nothing, filechooser not opening anymore.

So, I started snooping around in the WebKitWebChromeClient.cs file of the WebView.Android project. I observed

  1. The OnShowFileChooser get called when I tapped the file input the first time
  2. It calls ChooseFile which register an internal callback with a request code obtained from
    var newRequestCode = ActivityResultCallbackRegistryHelper.RegisterActivityResultCallback(callback);

    which is used for the _activity.StartActivityForResult(Intent.CreateChooser(intent, title), newRequestCode);

  3. This callback can only be invoked from ActivityResultCallbackRegistryHelper.InvokeCallback function which is internal and needs to be called from MainActivity.OnActivityResult

Simply changing the access modifier on ActivityResultCallbackRegistryHelper to public and adding

protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
        {
            ActivityResultCallbackRegistryHelper.InvokeCallback(requestCode, resultCode, data);
            base.OnActivityResult(requestCode, resultCode, data);
        }

to my MainActivity solve the problem..

sake402 commented 3 years ago

Hi @Eilon Please confirm if this problem is resolve in the 0.5 preview.

ktaze1 commented 3 years ago

For files, why don't you use Xamarin Essentials? It's way easier. Here is a link to my repo on how I used it. I've a button which has an OnClick event handler to call Select Files method. Method looks like this:

@code {
FileResult pickResult;

async void SelectFiles()
    {
        pickResult = await FilePicker.PickAsync(new PickOptions
        {
            FileTypes = FilePickerFileType.Images
        });
    }
}

https://github.com/ktaze1/CugemderMobileApp/blob/d776a3f49a6b30e9f3eb44133b44961fca2f7f5e/CugemderApp/WebUI/Pages/Authentication/Register.razor#L44

sake402 commented 3 years ago

@ktaze1 Thanks for your response. As I mentioned earlier, it is an existing project in a razor class library that is entirely unaware of xamarin and I do not want it to be dependent on xamarin as it is also being used in server and web assembly.

I fixed the issue by modifying the source code of MBB as iterated in my question. I would love the fix applied to MBB

Eilon commented 3 years ago

Hi @sake402 we didn't do any specific fix for this in Preview 5 so it's probably still not working.

sake402 commented 3 years ago

Since this issue is not fixed, if someone else is experiencing this issue. Use reflection to call the internal function from MainActivity

protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
        {
            //ActivityResultCallbackRegistryHelper.InvokeCallback(requestCode, resultCode, data);
            var assembly = typeof(BlazorHybridAndroid).Assembly;
            Type type = assembly.GetType("Microsoft.MobileBlazorBindings.WebView.Android.ActivityResultCallbackRegistryHelper");
            var method = type.GetMethod("InvokeCallback");
            method.Invoke(null, new object[] { requestCode, resultCode, data });
            base.OnActivityResult(requestCode, resultCode, data);
        }