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

Android WebView中无法调用摄像头/存储上传图片问题求助

Fixing Android WebView Camera/Storage Upload Issues for ASP.NET Web Apps

Hey there, let's tackle this WebView issue you're facing—super common when moving from regular mobile browsers to wrapped WebViews, so don't beat yourself up over it. The core problem here is that WebView doesn't inherit all the permissions and settings that a full-fledged browser like Chrome has out of the box. Let's break down the key fixes step by step:

1. First, Lock Down Permissions

WebView won't automatically request or use system permissions, so you need to explicitly configure them:

Manifest Permissions

Add these to your AndroidManifest.xml (adjust for your target Android version):

<!-- Camera access -->
<uses-permission android:name="android.permission.CAMERA" />
<!-- Storage access (Android <13) -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<!-- Storage access (Android 13+) -->
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
<!-- Optional: For saving camera photos -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="29" />

Runtime Permission Requests

Android 6.0+ requires you to ask users for permissions at runtime, not just in the manifest. Add code like this to your Activity/Fragment before loading the WebView:

// Check and request camera/storage permissions
String[] permissions = {Manifest.permission.CAMERA, Manifest.permission.READ_EXTERNAL_STORAGE};
if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED ||
    ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
    ActivityCompat.requestPermissions(this, permissions, PERMISSION_REQUEST_CODE);
}

2. Configure WebView Settings Correctly

This is where most people stumble. WebView needs specific settings enabled to handle file uploads:

WebView webView = findViewById(R.id.your_webview_id);
WebSettings webSettings = webView.getSettings();

// Enable JavaScript (critical for file upload controls)
webSettings.setJavaScriptEnabled(true);
// Allow file access and content loading
webSettings.setAllowFileAccess(true);
webSettings.setAllowContentAccess(true);
// Enable DOM storage (many modern upload widgets rely on this)
webSettings.setDomStorageEnabled(true);
// Match browser user-agent to avoid ASP.NET rendering issues
webSettings.setUserAgentString(webSettings.getUserAgentString() + " Chrome/118.0.0.0");

3. Override WebChromeClient for File Selection

The biggest gotcha: WebView won't show the file picker/camera prompt unless you override onShowFileChooser in WebChromeClient. This is how you bridge WebView's file request to Android's native system dialogs:

// Store the callback to handle results later
private ValueCallback<Uri[]> mFilePathCallback;
private static final int FILE_CHOOSER_REQUEST_CODE = 1001;

webView.setWebChromeClient(new WebChromeClient() {
    @Override
    public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback, FileChooserParams fileChooserParams) {
        // Save the callback to use in onActivityResult
        mFilePathCallback = filePathCallback;
        
        // Create intents for camera and gallery selection
        Intent takePhotoIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        Intent pickGalleryIntent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
        
        // Combine into a chooser dialog
        Intent chooserIntent = Intent.createChooser(pickGalleryIntent, "Select Image");
        chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, new Intent[]{takePhotoIntent});
        
        // Launch the dialog
        startActivityForResult(chooserIntent, FILE_CHOOSER_REQUEST_CODE);
        return true;
    }
});

4. Handle Activity Results

You need to pass the selected image/camera photo back to the WebView:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    
    if (requestCode == FILE_CHOOSER_REQUEST_CODE && mFilePathCallback != null) {
        Uri[] results = null;
        
        if (resultCode == RESULT_OK) {
            if (data != null) {
                // Handle gallery selection
                Uri selectedUri = data.getData();
                results = new Uri[]{selectedUri};
            } else {
                // Handle camera photo (you'll need to implement getCameraPhotoUri() to save the temp file)
                Uri cameraUri = getCameraPhotoUri();
                results = new Uri[]{cameraUri};
            }
        }
        
        // Pass results back to WebView
        mFilePathCallback.onReceiveValue(results);
        mFilePathCallback = null;
    }
}

Bonus: Fix Camera Photo Saving

For camera photos, you'll need to save the image to a temporary file using FileProvider to avoid FileUriExposedException:

  • Add a FileProvider entry to your manifest
  • Create a temp file and pass its content URI to the camera intent
  • Implement getCameraPhotoUri() to return that URI

5. Android Version-Specific Fixes

  • Android 10+ (Scoped Storage): Use MediaStore to access images instead of direct file paths
  • Android 13+: Use READ_MEDIA_IMAGES instead of READ_EXTERNAL_STORAGE for storage access
  • Android 7.0+: Always use FileProvider for file URIs to avoid security exceptions

Quick Troubleshooting Tips

  • Clear WebView cache: webView.clearCache(true) to rule out stale settings
  • Test with a simple HTML upload form first to isolate if the issue is in ASP.NET or WebView
  • Check logcat for specific errors (look for permission denied or file URI exceptions)

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

火山引擎 最新活动