fix: add runtime camera permission request to prevent SecurityException crash

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Kohei 2026-02-18 21:35:36 +09:00
parent d77e9cec29
commit 86e7db965f

View file

@ -1,8 +1,11 @@
package io.picoclaw.android.feature.chat.screen package io.picoclaw.android.feature.chat.screen
import android.Manifest
import android.content.pm.PackageManager
import android.net.Uri import android.net.Uri
import androidx.activity.compose.rememberLauncherForActivityResult import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.contract.ActivityResultContracts import androidx.activity.result.contract.ActivityResultContracts
import androidx.core.content.ContextCompat
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
@ -55,6 +58,24 @@ fun ChatScreen(
} }
} }
val launchCamera = {
val imagesDir = File(context.cacheDir, "images").apply { mkdirs() }
val imageFile = File(imagesDir, "camera_${System.currentTimeMillis()}.jpg")
val uri = FileProvider.getUriForFile(
context,
"${context.packageName}.fileprovider",
imageFile
)
cameraImageUri = uri
cameraLauncher.launch(uri)
}
val cameraPermissionLauncher = rememberLauncherForActivityResult(
contract = ActivityResultContracts.RequestPermission()
) { granted ->
if (granted) launchCamera()
}
val galleryLauncher = rememberLauncherForActivityResult( val galleryLauncher = rememberLauncherForActivityResult(
contract = ActivityResultContracts.GetContent() contract = ActivityResultContracts.GetContent()
) { uri -> ) { uri ->
@ -107,15 +128,13 @@ fun ChatScreen(
onTextChanged = { viewModel.onEvent(ChatEvent.OnInputChanged(it)) }, onTextChanged = { viewModel.onEvent(ChatEvent.OnInputChanged(it)) },
onSendClick = { viewModel.onEvent(ChatEvent.OnSendClick) }, onSendClick = { viewModel.onEvent(ChatEvent.OnSendClick) },
onCameraClick = { onCameraClick = {
val imagesDir = File(context.cacheDir, "images").apply { mkdirs() } if (ContextCompat.checkSelfPermission(context, Manifest.permission.CAMERA)
val imageFile = File(imagesDir, "camera_${System.currentTimeMillis()}.jpg") == PackageManager.PERMISSION_GRANTED
val uri = FileProvider.getUriForFile( ) {
context, launchCamera()
"${context.packageName}.fileprovider", } else {
imageFile cameraPermissionLauncher.launch(Manifest.permission.CAMERA)
) }
cameraImageUri = uri
cameraLauncher.launch(uri)
}, },
onGalleryClick = { onGalleryClick = {
galleryLauncher.launch("image/*") galleryLauncher.launch("image/*")