android - kotlin - 如何在 Room 中保存拍摄的图像?

问题描述 投票:0回答:1

我正在使用 android studio、lenguage kotlin 来制作我的应用程序,我想在其中处理用户及其烹饪食谱。我需要使用用户想要分享的菜肴的图像。我正在努力保存图像。 现在我的代码是:

                val context = LocalContext.current
                val file = context.createImageFile()
                val uri = FileProvider.getUriForFile(
                    Objects.requireNonNull(context),
                    context.packageName + ".provider", file
                )

                var capturedImageUri by remember {
                    mutableStateOf<Uri>(Uri.EMPTY)
                }

                val cameraLauncher =
                    rememberLauncherForActivityResult(ActivityResultContracts.TakePicture()) { isSuccess ->
                        if (isSuccess) {
                            capturedImageUri = uri
                        }
                    }

                val permissionLauncher = rememberLauncherForActivityResult(
                    ActivityResultContracts.RequestPermission()
                ) {
                    if (it) {
                        cameraLauncher.launch(uri)
                    } else {
                        Toast.makeText(context, "Permission Denied", Toast.LENGTH_SHORT).show()
                    }
                }

                Button(
                    onClick = {
                        val permissionCheckResult = ContextCompat.checkSelfPermission(
                            context,
                            Manifest.permission.CAMERA
                        )
                        if (permissionCheckResult == PackageManager.PERMISSION_GRANTED) {
                            cameraLauncher.launch(uri)
                        } else {
                            permissionLauncher.launch(Manifest.permission.CAMERA)
                        }
                    },
                    contentPadding = ButtonDefaults.TextButtonContentPadding,
                ) {
                    Icon(
                        Icons.Filled.PhotoCamera,
                        contentDescription = "Camera icon",
                        modifier = Modifier.size(ButtonDefaults.IconSize)
                    )
                    Spacer(Modifier.size(ButtonDefaults.IconSpacing))
                    Text("Scatta foto")
                }

                if (capturedImageUri.path?.isNotEmpty() == true) {
                    AsyncImage(
                        model = ImageRequest.Builder(context)
                            .data(capturedImageUri)
                            .crossfade(true)
                            .build(),
                        contentDescription = "image taken"
                    )

                    photoURI = saveImage(context.applicationContext.contentResolver, capturedImageUri)
                }

我也有这些功能:

fun saveImage(contentResolver: ContentResolver, capturedImageUri: Uri): String {
    val bitmap = getBitmap(capturedImageUri, contentResolver)

    val values = ContentValues()
    values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg")
    values.put(MediaStore.Images.Media.DISPLAY_NAME, "IMG_${SystemClock.uptimeMillis()}")

    val imageUri =
        contentResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values)

    val outputStream = imageUri?.let { contentResolver.openOutputStream(it) }
    bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outputStream)
    outputStream?.close()

    return imageUri.toString()
}

fun Context.createImageFile(): File {
    val timeStamp = SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(Date())
    val imageFileName = "JPEG_" + timeStamp + "_"
    return File.createTempFile(
        imageFileName,
        ".jpg",
        externalCacheDir
    )
}

private fun getBitmap(selectedPhotoUri: Uri, contentResolver: ContentResolver): Bitmap {
    val bitmap = when {
        Build.VERSION.SDK_INT < 28 -> MediaStore.Images.Media.getBitmap(
            contentResolver,
            selectedPhotoUri
        )
        else -> {
            val source = ImageDecoder.createSource(contentResolver, selectedPhotoUri)
            ImageDecoder.decodeBitmap(source)
        }
    }
    return bitmap
}

问题是,当我尝试使用

photoURI = saveImage(context.applicationContext.contentResolver, capturedImageUri)
保存图像时,应用程序停止(“MyApp 已停止”)。有人可以帮助我吗?

android image kotlin android-room uri
1个回答
0
投票
suspend fun saveImage(contentResolver: ContentResolver, capturedImageUri: Uri): String =
    withContext(Dispatchers.IO) {
        val bitmap = getBitmap(capturedImageUri, contentResolver)

        val values = ContentValues()
        values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg")
        values.put(MediaStore.Images.Media.DISPLAY_NAME, "IMG_${SystemClock.uptimeMillis()}")

        val imageUri =
            contentResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values)

        val outputStream = imageUri?.let { contentResolver.openOutputStream(it) }
        bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outputStream)
        outputStream?.close()

        return@withContext imageUri.toString()
    }

此外,

saveImage
必须在协程范围内调用。举个例子:

viewModelScope.launch {
    photoURI = saveImage(context.applicationContext.contentResolver, capturedImageUri)
}

此外,请验证您的 AndroidManifest.xml 文件中是否列出了以下权限:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

从 Android 10(API 级别 29)开始,不推荐使用

MediaStore.Images.Media.insertImage
,您应该改用 ContentValues,就像在代码中一样。

© www.soinside.com 2019 - 2024. All rights reserved.