-
Notifications
You must be signed in to change notification settings - Fork 56
Description
Description:
The permission handling logic in JcaApp.kt does not correctly request all necessary permissions for certain capture scenarios.
Specifically:
- The
RECORD_AUDIOpermission is only requested when theExternalCaptureModeisStandard, but it is also required when capturing video in other modes. - The
WRITE_EXTERNAL_STORAGEpermission is only requested forStandardmode on Android P and below.
However, it is also needed inExternalCaptureMode.MultipleImageCapturemode when no output URIs are provided by the calling intent, forcing the app to save to the public gallery.
This can lead to crashes or unexpected behavior when the app attempts to record video or save multiple images without the required permissions.
Analysis:
The JetpackCameraNavHost composable in JcaApp.kt has the following logic for building the list of permissions to request:
val requestablePermissions = buildList {
add(android.Manifest.permission.CAMERA)
if (externalCaptureMode == ExternalCaptureMode.Standard) {
add(android.Manifest.permission.RECORD_AUDIO)
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.P) {
add(android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
}
}
}This code only considers the Standard capture mode.
- Audio Permission: When the app is in a video capture mode (e.g. launched via
MediaStore.INTENT_ACTION_VIDEO_CAMERA), it needs
RECORD_AUDIOpermission, but the current logic does not request it. - Storage Permission: As determined from the logic in
MainActivity.kt, when usingExternalCaptureMode.MultipleImageCapture, if theMediaStore.EXTRA_OUTPUTintent extra is missing, the app defaults to saving in the public gallery. This
action requiresWRITE_EXTERNAL_STORAGEon older API levels, but the permission is not requested in this case.
Suggested Fix:
The permission request logic in JcaApp.kt should be updated to account for all capture modes and their specific requirements. The set of required permissions should be determined based
on the capture mode and the provided intent extras.
Here is a suggested implementation:
val requestablePermissions = buildList {
add(android.Manifest.permission.CAMERA)
// Add audio permission if in a mode that can record video.
// Assuming a Video mode exists for ExternalCaptureMode
if (externalCaptureMode == ExternalCaptureMode.Standard || externalCaptureMode == ExternalCaptureMode.Video) {
add(android.Manifest.permission.RECORD_AUDIO)
}
// Add storage permission for specific legacy cases
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.P) {
if (externalCaptureMode == ExternalCaptureMode.Standard) {
add(android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
}
// Required for saving to public gallery in multi-image mode without URIs
if (externalCaptureMode is ExternalCaptureMode.MultipleImageCapture &&
captureUris.isEmpty()
) {
add(android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
}
}
}This change ensures that:
RECORD_AUDIOis requested whenever video capture is possible.WRITE_EXTERNAL_STORAGEis requested on Android P and below when inStandardmode OR when inMultipleImageCapturemode without pre-supplied output
URIs.