在 onActivityResult(..) 中拍照总是 returns RESULT_CANCELED (0)
Taking photo always returns RESULT_CANCELED (0) in onActivityResult(..)
我尝试使用 firebase 存储示例应用构建 storage app,当我拍照时,我总是在 onActivityResult(..) 中得到 RESUL_CANCELED。
这是代码:
@AfterPermissionGranted(RC_STORAGE_PERMS)
private void launchCamera() {
Log.d(LOG_TAG, "launchCamera");
// Check that we have permission to read images from external storage.
String perm = Manifest.permission.WRITE_EXTERNAL_STORAGE;
if (!EasyPermissions.hasPermissions(this, perm)) {
EasyPermissions.requestPermissions(this, getString(R.string.rationale_storage),
RC_STORAGE_PERMS, perm);
return;
}
// Choose file storage location, must be listed in res/xml/file_paths.xml
File externalDir = Environment.getExternalStorageDirectory();
File file = new File(externalDir, "photos/" + UUID.randomUUID().toString() + ".jpg");
// Create content:// URI for file, required since Android N
// See: https://developer.android.com/reference/android/support/v4/content/FileProvider.html
mFileUri = FileProvider.getUriForFile(this,
"com.google.firebase.quickstart.firebasestorage.fileprovider", file);
// Create and launch the intent
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, mFileUri);
startActivityForResult(takePictureIntent, RC_TAKE_PICTURE);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
Log.d(LOG_TAG, "onActivityResult:" + requestCode + ":" + resultCode + ":" + data);
if (requestCode == RC_TAKE_PICTURE) {
if (resultCode == RESULT_OK) {
if (mFileUri != null) {
uploadFromUri(mFileUri);
} else {
Log.w(LOG_TAG, "File URI is null");
}
} else {
Toast.makeText(this, "Taking picture failed.", Toast.LENGTH_SHORT).show();
}
}
}
日志:onActivityResult:101:0:Intent { }
So it depends from the version of the Android?
这取决于你的意思和错误是什么。
正如我在评论中指出的那样,ACTION_IMAGE_CAPTURE
实现有 a history of bugs。此类错误的范围很广,不一定与 Android OS 版本相关。
但是,您的代码采用了一种有趣的方法 EXTRA_OUTPUT
:将 FileProvider
与外部存储上的位置一起使用。从长远来看,FileProvider
是一个很好的答案,因为 Android N is starting to ban file:
Uri
values。但是,有很多相机应用程序会出现 content:
Uri
值的问题,因为那些相机应用程序的开发人员没有想到这样的值。例如,Google 自己的相机应用程序在 content:
Uri
值上因 ACTION_VIDEO_CAPTURE
失败,至少在几个月前是这样,尽管 ACTION_IMAGE_CAPTURE
.
更糟糕的是,应用程序无法宣传它支持的额外方案。使用 Intent
的 "data" 方面,<intent-filter>
可以通告支持的方案,但这不适用于额外的方案。因此,当您在 EXTRA_OUTPUT
中使用 content:
Uri
调用 ACTION_IMAGE_CAPTURE
时,您不限于碰巧支持 content:
Uri
的相机应用程序值。
您可以考虑暂时将 targetSdkVersion
降低到 24 以下,然后使用 Uri.fromFile(file)
而不是 FileProvider.getUriForFile(...)
,看看会发生什么。如果您原来的相机应用程序工作正常,那么该应用程序不正确支持 content:
Uri
值,这就是导致您最初出现问题的原因。
总的来说,我建议使用 ACTION_IMAGE_CAPTURE
的开发人员将他们的 targetSdkVersion
保持在 24 以下,并使用 file:
Uri
值几年,直到更高的时间百分比的用户安装了支持 content:
Uri
值的相机应用程序。或者,让您的用户在他们现有的相机应用程序(通过 ACTION_IMAGE_CAPTURE
)和您在自己的应用程序中构建的某些相机功能(例如,使用 my library)之间进行选择,以增加 有些东西会起作用。
只需添加一些代码即可调用添加到@CommonsWare 的平滑解决方法。
检查 API 并适当处理效果很好。
private void startCamera() {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
File photoFile = null;
try {
photoFile = ImgUtils.createTempImageFile(this);
} catch (IOException ex) {
ex.printStackTrace();
}
if (photoFile != null) {
mTempPhotoPath = photoFile.getAbsolutePath();
if(Build.VERSION.SDK_INT < 24) {
//create Uri with 'file://' prefix
tempImgUri = Uri.fromFile(photoFile);
}else{
//create Uri with 'content://' prefix
tempImgUri = FileProvider.getUriForFile(this,
FILE_PROVIDER_AUTHORITY,
photoFile);
}
mImgUriString = tempImgUri.toString();
// Add the URI so the camera can store the image
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, tempImgUri);
startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
}
}
我尝试使用 firebase 存储示例应用构建 storage app,当我拍照时,我总是在 onActivityResult(..) 中得到 RESUL_CANCELED。 这是代码:
@AfterPermissionGranted(RC_STORAGE_PERMS)
private void launchCamera() {
Log.d(LOG_TAG, "launchCamera");
// Check that we have permission to read images from external storage.
String perm = Manifest.permission.WRITE_EXTERNAL_STORAGE;
if (!EasyPermissions.hasPermissions(this, perm)) {
EasyPermissions.requestPermissions(this, getString(R.string.rationale_storage),
RC_STORAGE_PERMS, perm);
return;
}
// Choose file storage location, must be listed in res/xml/file_paths.xml
File externalDir = Environment.getExternalStorageDirectory();
File file = new File(externalDir, "photos/" + UUID.randomUUID().toString() + ".jpg");
// Create content:// URI for file, required since Android N
// See: https://developer.android.com/reference/android/support/v4/content/FileProvider.html
mFileUri = FileProvider.getUriForFile(this,
"com.google.firebase.quickstart.firebasestorage.fileprovider", file);
// Create and launch the intent
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, mFileUri);
startActivityForResult(takePictureIntent, RC_TAKE_PICTURE);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
Log.d(LOG_TAG, "onActivityResult:" + requestCode + ":" + resultCode + ":" + data);
if (requestCode == RC_TAKE_PICTURE) {
if (resultCode == RESULT_OK) {
if (mFileUri != null) {
uploadFromUri(mFileUri);
} else {
Log.w(LOG_TAG, "File URI is null");
}
} else {
Toast.makeText(this, "Taking picture failed.", Toast.LENGTH_SHORT).show();
}
}
}
日志:onActivityResult:101:0:Intent { }
So it depends from the version of the Android?
这取决于你的意思和错误是什么。
正如我在评论中指出的那样,ACTION_IMAGE_CAPTURE
实现有 a history of bugs。此类错误的范围很广,不一定与 Android OS 版本相关。
但是,您的代码采用了一种有趣的方法 EXTRA_OUTPUT
:将 FileProvider
与外部存储上的位置一起使用。从长远来看,FileProvider
是一个很好的答案,因为 Android N is starting to ban file:
Uri
values。但是,有很多相机应用程序会出现 content:
Uri
值的问题,因为那些相机应用程序的开发人员没有想到这样的值。例如,Google 自己的相机应用程序在 content:
Uri
值上因 ACTION_VIDEO_CAPTURE
失败,至少在几个月前是这样,尽管 ACTION_IMAGE_CAPTURE
.
更糟糕的是,应用程序无法宣传它支持的额外方案。使用 Intent
的 "data" 方面,<intent-filter>
可以通告支持的方案,但这不适用于额外的方案。因此,当您在 EXTRA_OUTPUT
中使用 content:
Uri
调用 ACTION_IMAGE_CAPTURE
时,您不限于碰巧支持 content:
Uri
的相机应用程序值。
您可以考虑暂时将 targetSdkVersion
降低到 24 以下,然后使用 Uri.fromFile(file)
而不是 FileProvider.getUriForFile(...)
,看看会发生什么。如果您原来的相机应用程序工作正常,那么该应用程序不正确支持 content:
Uri
值,这就是导致您最初出现问题的原因。
总的来说,我建议使用 ACTION_IMAGE_CAPTURE
的开发人员将他们的 targetSdkVersion
保持在 24 以下,并使用 file:
Uri
值几年,直到更高的时间百分比的用户安装了支持 content:
Uri
值的相机应用程序。或者,让您的用户在他们现有的相机应用程序(通过 ACTION_IMAGE_CAPTURE
)和您在自己的应用程序中构建的某些相机功能(例如,使用 my library)之间进行选择,以增加 有些东西会起作用。
只需添加一些代码即可调用添加到@CommonsWare 的平滑解决方法。 检查 API 并适当处理效果很好。
private void startCamera() {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
File photoFile = null;
try {
photoFile = ImgUtils.createTempImageFile(this);
} catch (IOException ex) {
ex.printStackTrace();
}
if (photoFile != null) {
mTempPhotoPath = photoFile.getAbsolutePath();
if(Build.VERSION.SDK_INT < 24) {
//create Uri with 'file://' prefix
tempImgUri = Uri.fromFile(photoFile);
}else{
//create Uri with 'content://' prefix
tempImgUri = FileProvider.getUriForFile(this,
FILE_PROVIDER_AUTHORITY,
photoFile);
}
mImgUriString = tempImgUri.toString();
// Add the URI so the camera can store the image
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, tempImgUri);
startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
}
}