Android拍照完成后应用闪退且照片未保存问题求助
Hey there, let's break down why your camera intent is crashing the app after taking a photo, and why your callback code never runs—this is such a frustrating gotcha with Android camera integrations! Here are the most likely fixes to try out:
1. Double-Check Dynamic Permissions (Critical for Android 6.0+)
Even if the camera opens fine, missing permissions can trigger silent crashes when trying to save the photo or fire callbacks. Make sure you're requesting the right permissions, and doing it dynamically (not just adding them to the manifest):
- For Android 12 and below:
CAMERA+WRITE_EXTERNAL_STORAGE - For Android 13+:
CAMERA+READ_MEDIA_IMAGES/WRITE_MEDIA_IMAGES
Example code for requesting permissions with the modern Activity Result API:
private val requestPermissionsLauncher = registerForActivityResult( ActivityResultContracts.RequestMultiplePermissions() ) { permissions -> val allGranted = permissions.values.all { it } if (allGranted) { // Launch your camera intent here } else { // Show a message letting the user know permissions are required } } // Trigger permission request when the user taps the camera button requestPermissionsLauncher.launch( arrayOf( Manifest.permission.CAMERA, if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { Manifest.permission.WRITE_MEDIA_IMAGES } else { Manifest.permission.WRITE_EXTERNAL_STORAGE } ) )
2. Fix the Camera Intent's Output Uri (Avoid FileUriExposedException)
If you're using MediaStore.EXTRA_OUTPUT to specify where the photo saves, using a file:// Uri on Android 7.0+ will throw a FileUriExposedException—this is a top cause of crashes right after confirming a photo. Instead, use FileProvider to generate a secure content Uri:
- Add a FileProvider entry to your
AndroidManifest.xml:
<application> ... <provider android:name="androidx.core.content.FileProvider" android:authorities="${applicationId}.fileprovider" android:exported="false" android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths" /> </provider> </application>
- Create
res/xml/file_paths.xmlto define allowed save paths:
<?xml version="1.0" encoding="utf-8"?> <paths xmlns:android="http://schemas.android.com/apk/res/android"> <external-files-path name="camera_photos" path="Pictures/" /> </paths>
- Generate the Uri and launch the camera with the modern result API:
private fun createImageSaveUri(): Uri { val photoFile = File( getExternalFilesDir(Environment.DIRECTORY_PICTURES), "pic_${System.currentTimeMillis()}.jpg" ) return FileProvider.getUriForFile( this, "${packageName}.fileprovider", photoFile ) } // Register the camera result launcher private val takePictureLauncher = registerForActivityResult( ActivityResultContracts.TakePicture() ) { saveSuccess -> if (saveSuccess) { // Photo saved successfully—handle it here! } else { // Capture or save failed } } // Launch camera after permissions are granted takePictureLauncher.launch(createImageSaveUri())
3. Ditch Deprecated onActivityResult()
If you're still using the old startActivityForResult() and onActivityResult() methods, this can cause callbacks to fail on newer Android versions (API 30+). The modern ActivityResultContracts API ensures your callback stays registered even if the activity is recreated, so you won't miss the camera's response.
4. Use Logcat to Find the Exact Crash Cause
The most important step is to check Logcat for the crash stack trace. Filter by "Error" level to see the exact exception (like FileUriExposedException, SecurityException, or NullPointerException). This will point you straight to the root issue instead of guessing.
内容的提问来源于stack exchange,提问作者Schuey999

