You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android WebView实现拍照或本地存储选图的方案咨询

Android WebView 实现拍照/本地存储选图功能

要让WebView的文件选择支持拍照和本地选图,你需要自定义Intent,将拍照动作和文件选择动作整合到选择器中,同时处理拍照后的Uri返回。以下是修改后的完整代码:

1. 修改onShowFileChooser方法

private ValueCallback<Uri[]> uploadMessage;
private static final int REQUEST_SELECT_FILE = 100;
private Uri cameraImageUri; // 保存拍照生成的图片Uri

public boolean onShowFileChooser(WebView mWebView, ValueCallback<Uri[]> filePathCallback, WebChromeClient.FileChooserParams fileChooserParams) {
    if (uploadMessage != null) {
        uploadMessage.onReceiveValue(null);
        uploadMessage = null;
    }
    uploadMessage = filePathCallback;

    // 1. 创建拍照Intent
    Intent takePhotoIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    if (takePhotoIntent.resolveActivity(getPackageManager()) != null) {
        // 创建拍照后保存的文件
        File photoFile = null;
        try {
            photoFile = createImageFile();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
        if (photoFile != null) {
            // Android 7.0及以上用FileProvider获取Uri
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                cameraImageUri = FileProvider.getUriForFile(this, 
                    getPackageName() + ".fileprovider", photoFile);
            } else {
                cameraImageUri = Uri.fromFile(photoFile);
            }
            takePhotoIntent.putExtra(MediaStore.EXTRA_OUTPUT, cameraImageUri);
        }
    }

    // 2. 创建本地文件选择Intent
    Intent pickFileIntent = new Intent(Intent.ACTION_GET_CONTENT);
    pickFileIntent.setType("image/*");
    pickFileIntent.addCategory(Intent.CATEGORY_OPENABLE);

    // 3. 整合两个Intent到选择器
    Intent[] intentArray;
    if (takePhotoIntent != null) {
        intentArray = new Intent[]{takePhotoIntent};
    } else {
        intentArray = new Intent[0];
    }

    Intent chooserIntent = new Intent(Intent.ACTION_CHOOSER);
    chooserIntent.putExtra(Intent.EXTRA_INTENT, pickFileIntent);
    chooserIntent.putExtra(Intent.EXTRA_TITLE, "选择图片来源");
    chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, intentArray);

    try {
        startActivityForResult(chooserIntent, REQUEST_SELECT_FILE);
    } catch (ActivityNotFoundException e) {
        uploadMessage = null;
        return false;
    }
    return true;
}

// 辅助方法:创建拍照保存的临时文件
private File createImageFile() throws IOException {
    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(new Date());
    String imageFileName = "JPEG_" + timeStamp + "_";
    File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
    return File.createTempFile(
        imageFileName,  /* 前缀 */
        ".jpg",         /* 后缀 */
        storageDir      /* 存储目录 */
    );
}

2. 实现onActivityResult方法处理返回结果

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == REQUEST_SELECT_FILE) {
        if (uploadMessage == null) return;

        Uri[] results = null;
        // 处理拍照结果
        if (resultCode == RESULT_OK && cameraImageUri != null) {
            results = new Uri[]{cameraImageUri};
        }
        // 处理本地选图结果
        else if (resultCode == RESULT_OK && data != null) {
            String dataString = data.getDataString();
            if (dataString != null) {
                results = new Uri[]{Uri.parse(dataString)};
            }
        }

        uploadMessage.onReceiveValue(results);
        uploadMessage = null;
        cameraImageUri = null; // 重置拍照Uri
    }
}

3. 必要配置(Android 7.0+)

  • 在AndroidManifest.xml中注册FileProvider:
<application>
    ...
    <provider
        android:name="androidx.core.content.FileProvider"
        android:authorities="${applicationId}.fileprovider"
        android:exported="false"
        android:grantUriPermissions="true">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/file_paths" />
    </provider>
</application>
  • 在res/xml目录下创建file_paths.xml文件:
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-files-path name="my_images" path="Pictures" />
</paths>

关键说明

  • 通过Intent.createChooser将拍照和文件选择的Intent合并,让用户选择来源。
  • 拍照时需要创建临时文件,并通过FileProvider(Android 7.0+)获取安全Uri,避免Uri暴露异常。
  • 在onActivityResult中区分拍照和选图的结果,将正确的Uri传递给WebView的uploadMessage。

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 12:10:23