返回

WebView 相机问题:如何解决拍照前创建 0 字节图片?

Android

WebView 相机问题:在拍照前创建 0 字节图片

作为一名经验丰富的程序员,我曾遇到过许多 Android WebView 中的相机问题。其中一个特别棘手的问题是,在拍照前会创建一个 0 字节的图片。这种情况下,相机图标会显示错误,并且无法创建实际图像。

问题原因

这个问题通常是由于相机意图配置不当造成的。具体来说,在 FileChooserParams 中设置 EXTRA_OUTPUT 时,必须为图片创建有效的 File 对象。如果没有创建 File 对象,相机意图将无法正确处理图片数据,从而导致错误。

解决方案

要解决此问题,需要按照以下步骤操作:

创建有效的 File 对象

createImageFile() 方法中,使用以下步骤创建有效的 File 对象:

  • 使用 SimpleDateFormat 创建一个唯一的文件名。
  • 获取公共图片目录的 File 对象。
  • 使用 createTempFile() 方法创建临时文件,该方法需要文件名、扩展名和目录。
  • 将创建的 File 对象的路径分配给 mCameraPhotoPath

FileChooserParams 中设置 EXTRA_OUTPUT

onShowFileChooser() 方法中,将创建的 File 对象的 Uri 传递给 EXTRA_OUTPUT

以下是更新后的 createImageFile() 方法和 onShowFileChooser() 方法的代码:

private File createImageFile() throws IOException {
    // Create an image file name
    Log.d(TAG, "createImageFile: creating Image");
    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
    String imageFileName = "JPEG_" + timeStamp + "_";
    File storageDir = Environment.getExternalStoragePublicDirectory(
            Environment.DIRECTORY_PICTURES);
    File image = File.createTempFile(
            imageFileName,  // prefix
            ".jpg",         // suffix
            storageDir      // directory
    );

    // Save a file: path for use with ACTION_VIEW intents
    mCameraPhotoPath = "file:" + image.getAbsolutePath();
    return image;
}

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

    Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
        File photoFile = null;
        try {
            photoFile = createImageFile();
            takePictureIntent.putExtra("PhotoPath", mCameraPhotoPath);
        } catch (IOException ex) {
            // Error occurred while creating the File
            Log.e(TAG, "Unable to create Image File", ex);
        }

        // continue only if the file was successfully created
        if (photoFile != null) {
            mCameraPhotoPath = "file:" + photoFile.getAbsolutePath();
            takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT,
                    Uri.fromFile(photoFile));
        } else {
            takePictureIntent = null;
        }
    }

    Intent contentSelectionIntent = new Intent(Intent.ACTION_GET_CONTENT);
    contentSelectionIntent.addCategory(Intent.CATEGORY_OPENABLE);
    contentSelectionIntent.setType("image/*");

    Intent[] intentArray;
    if (takePictureIntent != null) {
        intentArray = new Intent[]{takePictureIntent};
    } else {
        intentArray = new Intent[0];
    }

    Intent chooserIntent = new Intent(Intent.ACTION_CHOOSER);
    chooserIntent.putExtra(Intent.EXTRA_INTENT, contentSelectionIntent);
    chooserIntent.putExtra(Intent.EXTRA_TITLE, getString(R.STRING.image_chooser));
    chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, intentArray);

    startActivityForResult(chooserIntent, FILECHOOSER_RESULTCODE);

    return true;
}

其他提示

  • 确保在清单文件中正确声明了所需的权限,例如 CAMERAWRITE_EXTERNAL_STORAGE
  • 测试您的代码以确保它在不同的 Android 版本和设备上都能正常工作。
  • 考虑使用第三方库(例如 RxJava)来简化异步代码。

常见问题解答

  1. 为什么在拍照前会创建 0 字节的图片?

这个问题通常是由于在 FileChooserParams 中设置 EXTRA_OUTPUT 时未创建有效的 File 对象造成的。

  1. 如何解决此问题?

按照本文中提供的步骤操作,创建一个有效的 File 对象并将其 Uri 传递给 EXTRA_OUTPUT

  1. 是否还有其他解决方法?

可以尝试使用第三方库,例如 PhotoPicker,它可以简化 WebView 中相机的使用。

  1. 如何避免此问题再次发生?

仔细检查代码并确保始终在相机意图中创建有效的 File 对象。

  1. 此问题只影响 Android WebView 吗?

不,它也可能影响其他使用相机意图的 Android 应用。

结论

在拍照前创建 0 字节的图片可能会导致 WebView 相机出现错误。通过仔细按照本文中的步骤操作,您可以解决此问题并确保相机正常运行。