I trying to build storage app using firebase storage sample app, and when I take a picture I always get RESUL_CANCELED in onActivityResult(..). Here is the code:
@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();
}
}
}
logs: onActivityResult:101:0:Intent { }
So it depends from the version of the Android?
That depends on what you mean by that and what the bug is.
As I noted in my comment, ACTION_IMAGE_CAPTURE
implementations have a history of bugs. There is a wide range of such bugs, not necessarily tied to Android OS version.
However, your code takes an interesting approach to EXTRA_OUTPUT
: using FileProvider
with a location on external storage. Long-term, FileProvider
is a fine answer, as Android N is starting to ban file:
Uri
values. However, there are many camera apps that will have problems with content:
Uri
values, because the developers of those camera apps did not expect such values. For example, Google's own Camera app fails for ACTION_VIDEO_CAPTURE
on content:
Uri
values, at least as of a couple of months ago, though it is fine for ACTION_IMAGE_CAPTURE
.
Worse, there is no way for an app to advertise what schemes it supports for an extra. With the "data" facet of an Intent
, the <intent-filter>
can advertise supported schemes, but that does not work for extras. So, when you invoke ACTION_IMAGE_CAPTURE
with a content:
Uri
in EXTRA_OUTPUT
, you are not limited to camera apps that happen to support content:
Uri
values.
You might consider temporarily dropping your targetSdkVersion
below 24, then using Uri.fromFile(file)
instead of FileProvider.getUriForFile(...)
, and see what happens. If your original camera app works fine, then that app does not support content:
Uri
values correctly, and that was what caused your original problem.
Overall, I recommend that developers using ACTION_IMAGE_CAPTURE
keep their targetSdkVersion
below 24 and use file:
Uri
values for a few years, until such time as a higher percentage of users have a camera app installed that supports content:
Uri
values. Or, offer your users a choice between their existing camera apps (via ACTION_IMAGE_CAPTURE
) and some camera capability that you build into your own app (e.g., using my library), to increase the odds that something will work.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With