You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Xamarin WebView相机上传两张图片异常:仅第一张成功的原因与解决

Troubleshooting Second Image Upload Failure in WebView Camera Flow

Hey there! Let's figure out why only your first image upload works and the second one fails in your WebView-based camera upload setup. This is a super common issue with Android WebView file uploads, so let's break down the most likely causes and how to fix them.

Common Causes & Fixes

1. Missing Callback Reset After First Upload

The biggest culprit here is usually forgetting to reset the WebView's file upload callback after the first successful upload. Android WebView requires that once you've handled a file selection result, you clear the ValueCallback<Uri[]> reference—if you don't, subsequent file upload requests will be ignored because the WebView thinks the previous callback is still pending.

Fix:
After you pass the image Uri to the callback in your renderer, immediately set the callback to null. Here's how that might look in your MyCustomwebviewRenderer.cs:

// Inside your method that handles the Activity result
public void OnActivityResult(int resultCode, Intent data)
{
    if (_filePathCallback == null) return;

    Uri[] results = null;
    if (resultCode == Result.Ok && _activity.CameraImageUri != null)
    {
        results = new Uri[] { _activity.CameraImageUri };
    }

    // Send results to WebView
    _filePathCallback.OnReceiveValue(results);
    // Critical: Reset callback to null for next upload
    _filePathCallback = null;
}

2. Stale Callback Reference in WebChromeClient

If your WebChromeClient isn't updating the callback reference every time a new file upload is requested, the second upload will try to use the already-completed first callback.

Fix:
In your OnShowFileChooser override, always save the latest callback (overwriting any old one) before launching the camera:

public override bool OnShowFileChooser(Android.Webkit.WebView webView, ValueCallback<Uri[]> filePathCallback, FileChooserParams fileChooserParams)
{
    // Save the new callback, replacing any existing one
    _renderer._filePathCallback = filePathCallback;
    // Launch your camera flow
    _renderer._activity.LaunchCameraForUpload();
    return true;
}

3. Activity Result Handling Issues

If your MainActivity isn't properly passing results back to the WebView renderer, or isn't generating a unique image Uri for each upload, the second image might be overwritten or never reach the WebView.

Fix:

  • Generate a unique file name for each camera capture to avoid overwriting the first image:
public void LaunchCameraForUpload()
{
    // Use a timestamp to ensure unique file names
    var fileName = $"upload_{DateTime.Now.Ticks}.jpg";
    var storageDir = GetExternalFilesDir(Android.OS.Environment.DirectoryPictures);
    var imageFile = new File(storageDir, fileName);
    CameraImageUri = FileProvider.GetUriForFile(this, $"{PackageName}.fileprovider", imageFile);

    // Launch camera intent with proper permissions
    var takePictureIntent = new Intent(MediaStore.ActionImageCapture);
    takePictureIntent.PutExtra(MediaStore.ExtraOutput, CameraImageUri);
    takePictureIntent.AddFlags(ActivityFlags.GrantReadUriPermission);
    StartActivityForResult(takePictureIntent, 100);
}
  • Make sure your MainActivity passes the result directly to the renderer:
protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
{
    base.OnActivityResult(requestCode, resultCode, data);
    if (requestCode == 100)
    {
        _webViewRenderer?.OnActivityResult((int)resultCode, data);
    }
}

4. Permission or Uri Permission Issues

Sometimes the second upload fails because you're not rechecking permissions, or the Uri from the first upload doesn't have the right permissions for the second request.

Fix:

  • Ensure you request camera and storage permissions (for Android 13+, use READ_MEDIA_IMAGES instead of WRITE_EXTERNAL_STORAGE) every time before launching the camera, or check if permissions are still granted.
  • When creating the camera intent, add the GrantReadUriPermission flag to ensure the camera app can write to the Uri, and the WebView can read it later.

Quick Checklist to Verify

  • After each upload, the ValueCallback<Uri[]> is set to null
  • OnShowFileChooser always updates the callback reference with the latest request
  • Each camera capture uses a unique file Uri
  • Permissions are valid and granted for each upload attempt
  • Activity results are correctly passed from MainActivity to the WebView renderer

If you're still hitting issues after trying these fixes, feel free to share more snippets of your MyCustomwebviewRenderer.cs and Mainactivity.cs—I can help dig deeper into specific code paths!

内容的提问来源于stack exchange,提问作者Ufuk Zimmerman

火山引擎 最新活动