Изображение камеры из FileProvider Uri отображается только в первый раз
Мое приложение камеры Jetpack Compose нацелено на уровень API 32 и тестируется на телефоне Android 11. Я создаю сFileProvider
сделать снимок с помощью стандартного приложения камеры. Logcat показывает каждый раз, когда я делаю снимок, но изображение отображается в пользовательском интерфейсе только в первый раз. Последующие снимки камеры не отображают изображение, хотяUri
отображается в Logcat. И выход из приложения нажатием кнопки «Назад», а затем открытие приложения для создания моментального снимка, опять же, работает только в первый раз. Как я могу решить эту проблему?
Файл манифеста
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.testsoft.camtest">
<uses-feature android:name="android.hardware.camera" />
<uses-permission android:name="android.permission.CAMERA" />
<application
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.Camtest"
tools:targetApi="31">
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.fileprovider"
android:grantUriPermissions="true"
android:exported="false">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
</provider>
<activity
android:name=".MainActivity"
android:exported="true"
android:label="@string/app_name"
android:theme="@style/Theme.Camtest">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Пути к файлам XML-файл
<?xml version="1.0" encoding="utf-8"?>
<paths>
<external-files-path
name="my_images"
path="Android/data/com.testsoft.camtest/files/Pictures"/>
<external-files-path
name="my_debug_images"
path="/storage/emulated/0/Android/data/com.testsoft.camtest/files/Pictures/"/>
<external-files-path
name="my_root_images"
path="/"/>
</paths>
Составной основной экран
@Composable
fun MainScreen() {
var hasImage by remember {
mutableStateOf(false)
}
var imageUri by remember {
mutableStateOf<Uri?>(null)
}
val context = LocalContext.current
var grantCameraState by remember {
mutableStateOf(
ContextCompat.checkSelfPermission(
context,
Manifest.permission.CAMERA
) == PackageManager.PERMISSION_GRANTED
)
}
val cameraPermissionlauncher: ManagedActivityResultLauncher<String, Boolean> =
rememberLauncherForActivityResult(contract = ActivityResultContracts.RequestPermission()) {
grantCameraState = it
}
val cameraLauncher = rememberLauncherForActivityResult(ActivityResultContracts.TakePicture()) { success ->
Log.i("UriContent@Snapshot", imageUri.toString())
hasImage = success
}
Column {
Button(
modifier = Modifier.align(alignment = Alignment.CenterHorizontally),
onClick = {
if (grantCameraState) {
val uri = getCamImageUri(context)
imageUri = uri
cameraLauncher.launch(uri)
} else {
cameraPermissionlauncher.launch(Manifest.permission.CAMERA)
}
}) {
Text(text = "Take photo")
}
Spacer(Modifier.width(10.dp))
if(hasImage && imageUri != null){
Log.i("UriContent@Render", imageUri.toString())
AsyncImage(
imageUri,
contentDescription = null,
modifier = Modifier.fillMaxWidth()
)
/*
//Also tried this but had the same issue:
Image(
painter = rememberAsyncImagePainter(imageUri),
contentDescription = null,
modifier = Modifier.fillMaxWidth()
)
*/
}
}
}
fun getCamImageUri(context: Context): Uri? {
var uri: Uri? = null
val file = createImageFile(context)
try {
uri = FileProvider.getUriForFile(context, "com.testsoft.camtest.fileprovider", file)
} catch (e: Exception) {
Log.e(ContentValues.TAG, "Error: ${e.message}")
}
return uri
}
private fun createImageFile(context: Context) : File {
val timestamp = SimpleDateFormat("yyyyMMdd_HHmmss").format(Date())
val imageDirectory = context.getExternalFilesDir(Environment.DIRECTORY_PICTURES)
return File.createTempFile(
"Camtest_Image_${timestamp}",
".jpg",
imageDirectory
)
}
Вывод логкэта
I/UriContent@Snapshot: content://com.testsoft.camtest.fileprovider/my_root_images/Pictures/Camtest_Image_20220702_1002472475660413794636578.jpg
I/UriContent@Render: content://com.testsoft.camtest.fileprovider/my_root_images/Pictures/Camtest_Image_20220702_1002472475660413794636578.jpg
Сообщение Logcat с последующим запуском камеры
D/skia: --- Failed to create image decoder with message 'unimplemented'