拍照后裁剪图片失败:startActivityForResult返回错误结果码求助
Hey there, I’ve dealt with this exact startActivityForResult headache when working with camera capture and image cropping on Android—total pain, but let’s break down the fixes based on the most common causes of wonky result codes.
First, Fix the Camera Capture Setup
A super common culprit is mishandling the image output Uri, especially on Android 7.0+ where file:// Uris are blocked. Here’s the corrected capture method with proper FileProvider usage:
// Define these as class-level constants private static final int REQUEST_IMAGE_CAPTURE = 1; private File mCurrentPhotoFile; private void captureImage() { Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); // Always check if a camera app exists to handle the intent if (cameraIntent.resolveActivity(getPackageManager()) == null) { Toast.makeText(this, "No camera app found!", Toast.LENGTH_SHORT).show(); return; } try { mCurrentPhotoFile = createImageFile(); } catch (IOException ex) { ex.printStackTrace(); Toast.makeText(this, "Failed to create image file", Toast.LENGTH_SHORT).show(); return; } // Use FileProvider to get a safe Uri for Android 7.0+ Uri photoUri = FileProvider.getUriForFile(this, "com.your.package.name.fileprovider", // Replace with your package + .fileprovider mCurrentPhotoFile); cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoUri); // Grant temporary write permission to the camera app cameraIntent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION); startActivityForResult(cameraIntent, REQUEST_IMAGE_CAPTURE); } // Helper to create a temporary image file private File createImageFile() throws IOException { String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(new Date()); String imageFileName = "JPEG_" + timeStamp + "_"; File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES); return File.createTempFile(imageFileName, ".jpg", storageDir); }
Next, Fix the Cropping Intent
Bad crop intent parameters are another big reason for failed result codes. Avoid using return-data=true for large images (it can cause system crashes) and use an output Uri instead:
private static final int REQUEST_IMAGE_CROP = 2; private File mCurrentCropFile; private void cropImage(Uri imageUri) { Intent cropIntent = new Intent("com.android.camera.action.CROP"); cropIntent.setDataAndType(imageUri, "image/*"); cropIntent.putExtra("crop", "true"); // Set your desired aspect ratio/size cropIntent.putExtra("aspectX", 1); cropIntent.putExtra("aspectY", 1); cropIntent.putExtra("outputX", 300); cropIntent.putExtra("outputY", 300); // Disable return-data to avoid memory issues cropIntent.putExtra("return-data", false); try { mCurrentCropFile = createImageFile(); } catch (IOException e) { e.printStackTrace(); Toast.makeText(this, "Failed to create crop file", Toast.LENGTH_SHORT).show(); return; } Uri cropUri = FileProvider.getUriForFile(this, "com.your.package.name.fileprovider", mCurrentCropFile); cropIntent.putExtra(MediaStore.EXTRA_OUTPUT, cropUri); // Grant write permission to the cropping app cropIntent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION); startActivityForResult(cropIntent, REQUEST_IMAGE_CROP); }
Don’t Forget FileProvider Setup
If you haven’t configured FileProvider, this will almost certainly cause permission errors and bad result codes:
- Create
res/xml/file_paths.xml:
<?xml version="1.0" encoding="utf-8"?> <paths xmlns:android="http://schemas.android.com/apk/res/android"> <external-files-path name="camera_images" path="Pictures" /> </paths>
- Add the provider to your
AndroidManifest.xml:
<application> <!-- ... other app code ... --> <provider android:name="androidx.core.content.FileProvider" android:authorities="com.your.package.name.fileprovider" android:exported="false" android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths" /> </provider> </application>
Finally, Correct onActivityResult Handling
Make sure you’re checking the right result codes and handling both capture and crop results properly:
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (resultCode == RESULT_OK) { switch (requestCode) { case REQUEST_IMAGE_CAPTURE: // Photo captured successfully, start cropping cropImage(Uri.fromFile(mCurrentPhotoFile)); break; case REQUEST_IMAGE_CROP: // Crop done, display the image in your ImageView mImageView.setImageURI(Uri.fromFile(mCurrentCropFile)); break; } } else { // Debug what went wrong Log.d("CameraCropIssue", "Result code: " + resultCode + " | Request code: " + requestCode); // If resultCode is RESULT_CANCELED, it might be a permission or Uri issue } }
Key Pitfalls to Avoid
- Missing Permissions: For Android 6.0+, request
CAMERAandWRITE_EXTERNAL_STORAGE(or use scoped storage) dynamically before launching the camera. return-data=true: This causes crashes with large images, always use an output Uri instead.- Wrong Authority String: Make sure the authority in
FileProvider.getUriForFilematches what’s in your Manifest.
If you already pinpointed the root cause, adjust these steps to target that specific issue—for example, if it’s a permission problem, focus on dynamic permission requests; if it’s a Uri issue, double-check your FileProvider setup.
内容的提问来源于stack exchange,提问作者CodeRedDev

