无法在 Android 中捕获图像
Could not capture image in Android
- Device: OnePlus 6
- Storage: 8GB RAM + 128GB ROM
- Android Version: 10
- Oxygen OS Version: OP6_02_BETA_31
我使用下面的代码捕获图像。除上述配置外,该代码几乎适用于所有设备。
应用程序正在打开相机,我无法拍摄图像。使用默认的相机应用程序,我没有遇到任何异常。拍摄照片后,会出现一个勾号按钮以确认图像。但是那个按钮是不可点击的。所以,我使用了不同的相机应用程序来捕捉图像。它在相机应用程序中返回 "Failed to save photo" 错误。没有抛出异常。
然后我在控制台中收到此消息 "E/ContentProviderNative: onTransact error from {P:7857;U:10456}"。请协助我解决这个问题。
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
try {
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state)) {
String appDirPath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/" + context.getString(R.string.app_name);
appDir = new File(appDirPath);
if (!appDir.exists()) {
appDir.mkdirs();
}
mFileCaptured = new File(appDir, tag + ".jpg");
mImageCaptureUri = FileProvider.getUriForFile(context,
context.getApplicationContext().getPackageName() + ".provider",
mFileCaptured);
}
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.LOLLIPOP) {
intent.setClipData(ClipData.newRawUri("", mImageCaptureUri));
intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
}
intent.putExtra(MediaStore.EXTRA_OUTPUT, mImageCaptureUri);
intent.putExtra("return-data", true);
context.startActivityForResult(intent, 10000);
} catch (Exception e) {
Crashlytics.logException(e);
Crashlytics.log(e.getLocalizedMessage());
}
您正在创建的文件 (mFileCaptured) 有问题。您刚刚创建了文件的路径,但文件系统中不存在该文件,因此该文件的 URI 为 NULL。
尝试这样做:-
if (!mFileCaptured.exists()) {
mFileCaptured.createNewFile();
}
如果上面的代码不起作用,那么试试这个
private static Uri getSharableImageUri(Context context) {
File outputDir = context.getCacheDir();
File imagePath = new File(outputDir, context.getString(R.string.app_name));
if (!imagePath.exists()) {
imagePath.mkdir();
}
File tempFile = new File(imagePath, "image.jpg");
Uri uri = null;
try {
if (!tempFile.exists()) {
tempFile.createNewFile();
}
uri = FileProvider.getUriForFile(context, context.getPackageName() + ".fileprovider", tempFile);
} catch (Exception e) {
e.printStackTrace();
}
return uri;
}
并使用此方法设置 URI
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
try {
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state)) {
mImageCaptureUri = getSharableImageUri(context);
}
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.LOLLIPOP) {
intent.setClipData(ClipData.newRawUri("", mImageCaptureUri));
}
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.putExtra(MediaStore.EXTRA_OUTPUT, mImageCaptureUri);
intent.putExtra("return-data", true);
context.startActivityForResult(intent, 10000);
} catch (Exception e) {
Crashlytics.logException(e);
Crashlytics.log(e.getLocalizedMessage());
}
在 Android10 下你不能再写入外部存储。
改用 getFilesDir()、getExternalFilesDir() 或 getExternalFilesDirs()。
或者向 Mediastore 请求一个有效的 uri,让相机应用程序将图片写入其中。
我遵循了 https://developer.android.com/training/camera/photobasics 的实现。
现在,它对我有用。
- Device: OnePlus 6
- Storage: 8GB RAM + 128GB ROM
- Android Version: 10
- Oxygen OS Version: OP6_02_BETA_31
我使用下面的代码捕获图像。除上述配置外,该代码几乎适用于所有设备。
应用程序正在打开相机,我无法拍摄图像。使用默认的相机应用程序,我没有遇到任何异常。拍摄照片后,会出现一个勾号按钮以确认图像。但是那个按钮是不可点击的。所以,我使用了不同的相机应用程序来捕捉图像。它在相机应用程序中返回 "Failed to save photo" 错误。没有抛出异常。
然后我在控制台中收到此消息 "E/ContentProviderNative: onTransact error from {P:7857;U:10456}"。请协助我解决这个问题。
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
try {
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state)) {
String appDirPath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/" + context.getString(R.string.app_name);
appDir = new File(appDirPath);
if (!appDir.exists()) {
appDir.mkdirs();
}
mFileCaptured = new File(appDir, tag + ".jpg");
mImageCaptureUri = FileProvider.getUriForFile(context,
context.getApplicationContext().getPackageName() + ".provider",
mFileCaptured);
}
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.LOLLIPOP) {
intent.setClipData(ClipData.newRawUri("", mImageCaptureUri));
intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
}
intent.putExtra(MediaStore.EXTRA_OUTPUT, mImageCaptureUri);
intent.putExtra("return-data", true);
context.startActivityForResult(intent, 10000);
} catch (Exception e) {
Crashlytics.logException(e);
Crashlytics.log(e.getLocalizedMessage());
}
您正在创建的文件 (mFileCaptured) 有问题。您刚刚创建了文件的路径,但文件系统中不存在该文件,因此该文件的 URI 为 NULL。
尝试这样做:-
if (!mFileCaptured.exists()) {
mFileCaptured.createNewFile();
}
如果上面的代码不起作用,那么试试这个
private static Uri getSharableImageUri(Context context) {
File outputDir = context.getCacheDir();
File imagePath = new File(outputDir, context.getString(R.string.app_name));
if (!imagePath.exists()) {
imagePath.mkdir();
}
File tempFile = new File(imagePath, "image.jpg");
Uri uri = null;
try {
if (!tempFile.exists()) {
tempFile.createNewFile();
}
uri = FileProvider.getUriForFile(context, context.getPackageName() + ".fileprovider", tempFile);
} catch (Exception e) {
e.printStackTrace();
}
return uri;
}
并使用此方法设置 URI
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
try {
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state)) {
mImageCaptureUri = getSharableImageUri(context);
}
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.LOLLIPOP) {
intent.setClipData(ClipData.newRawUri("", mImageCaptureUri));
}
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.putExtra(MediaStore.EXTRA_OUTPUT, mImageCaptureUri);
intent.putExtra("return-data", true);
context.startActivityForResult(intent, 10000);
} catch (Exception e) {
Crashlytics.logException(e);
Crashlytics.log(e.getLocalizedMessage());
}
在 Android10 下你不能再写入外部存储。
改用 getFilesDir()、getExternalFilesDir() 或 getExternalFilesDirs()。
或者向 Mediastore 请求一个有效的 uri,让相机应用程序将图片写入其中。
我遵循了 https://developer.android.com/training/camera/photobasics 的实现。
现在,它对我有用。