WebView 相机问题:如何解决拍照前创建 0 字节图片?
2024-03-11 19:35:28
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;
}
其他提示
- 确保在清单文件中正确声明了所需的权限,例如
CAMERA
和WRITE_EXTERNAL_STORAGE
。 - 测试您的代码以确保它在不同的 Android 版本和设备上都能正常工作。
- 考虑使用第三方库(例如
RxJava
)来简化异步代码。
常见问题解答
- 为什么在拍照前会创建 0 字节的图片?
这个问题通常是由于在 FileChooserParams
中设置 EXTRA_OUTPUT
时未创建有效的 File 对象造成的。
- 如何解决此问题?
按照本文中提供的步骤操作,创建一个有效的 File 对象并将其 Uri 传递给 EXTRA_OUTPUT
。
- 是否还有其他解决方法?
可以尝试使用第三方库,例如 PhotoPicker
,它可以简化 WebView 中相机的使用。
- 如何避免此问题再次发生?
仔细检查代码并确保始终在相机意图中创建有效的 File 对象。
- 此问题只影响 Android WebView 吗?
不,它也可能影响其他使用相机意图的 Android 应用。
结论
在拍照前创建 0 字节的图片可能会导致 WebView 相机出现错误。通过仔细按照本文中的步骤操作,您可以解决此问题并确保相机正常运行。