如何使用新的 Activity Contracts API 将图像从相机上传到服务器?
How to upload Image to Server from camera Using new Activity Contracts APIs?
我正在尝试使用相机图像和新的 Activity 合同方法将图像上传到服务器,但出现异常,例如:我选择的路径没有这样的文件或目录。
这是我到目前为止所做的:
private fun takeImage() {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) {
lifecycleScope.launchWhenStarted {
getTmpFileUri().let { uri ->
latestTmpUri = uri
getImageResult.launch(uri)
}
}
} else {
requestCameraPermission.launch(Manifest.permission.CAMERA)
}
}
private fun getTmpFileUri(): Uri {
val timeStamp: String = SimpleDateFormat("ddMMyyyy", Locale.getDefault()).format(Date())
val tmpFile = File.createTempFile(timeStamp, ".png", cacheDir).apply {
createNewFile()
deleteOnExit()
}
return FileProvider.getUriForFile(applicationContext, "${BuildConfig.APPLICATION_ID}.provider", tmpFile)
}
private val getImageResult = registerForActivityResult(ActivityResultContracts.TakePicture()) { isSuccess ->
if (isSuccess) {
latestTmpUri?.let {
//loadImage(it, binding.imgProfile)
image = File(it.path.toString())
uploadImage()
}
}
}
if (image != null) {
profileImage = image.toMultipartBody("profile_image")
} // and than code for api calls which use profileImage to upload
fun File?.toMultipartBody(name: String): MultipartBody.Part? {
this ?: return null
return MultipartBody.Part.createFormData(
name,
this.name,
RequestBody.create(getMimeType().toMediaTypeOrNull(), this)
)
}
private fun File.getMimeType(): String {
var type: String? = null
val url = this.toURI().toURL().toString()
val extension = url.substringAfterLast(".")
return when (extension.lowercase(Locale.getDefault())) {
"jpg", "jpeg", "png" -> "image/$extension"
"mp4" -> "video/$extension"
"pdf" -> "application/$extension"
else -> "image/*"
}
}
感谢任何帮助!!
我是这样解决这个问题的:
首先在使用 private fun getTmpFileUri() 创建 tempFile 时:Uri 检索 tempFile 的绝对路径并将其存储在全局变量中,如下所示:
private fun getTmpFileUri(): Uri {
val timeStamp: String = SimpleDateFormat("ddMMyyyy", Locale.getDefault()).format(Date())
val tmpFile = File.createTempFile(timeStamp, ".png", cacheDir).apply {
createNewFile()
deleteOnExit()
}
imagePath = tmpFile.absolutePath // store file path in variable
return FileProvider.getUriForFile(applicationContext, "${BuildConfig.APPLICATION_ID}.provider", tmpFile)
}
现在使用该路径创建图像文件如下:
private val getImageResult = registerForActivityResult(ActivityResultContracts.TakePicture()) { isSuccess ->
if (isSuccess) {
latestTmpUri?.let {
image = File(imagePath)
uploadImage()
}
}
}
现在您可以使用可变图像在 uploadImage() 方法中上传您的图像文件。
我正在尝试使用相机图像和新的 Activity 合同方法将图像上传到服务器,但出现异常,例如:我选择的路径没有这样的文件或目录。
这是我到目前为止所做的:
private fun takeImage() {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) {
lifecycleScope.launchWhenStarted {
getTmpFileUri().let { uri ->
latestTmpUri = uri
getImageResult.launch(uri)
}
}
} else {
requestCameraPermission.launch(Manifest.permission.CAMERA)
}
}
private fun getTmpFileUri(): Uri {
val timeStamp: String = SimpleDateFormat("ddMMyyyy", Locale.getDefault()).format(Date())
val tmpFile = File.createTempFile(timeStamp, ".png", cacheDir).apply {
createNewFile()
deleteOnExit()
}
return FileProvider.getUriForFile(applicationContext, "${BuildConfig.APPLICATION_ID}.provider", tmpFile)
}
private val getImageResult = registerForActivityResult(ActivityResultContracts.TakePicture()) { isSuccess ->
if (isSuccess) {
latestTmpUri?.let {
//loadImage(it, binding.imgProfile)
image = File(it.path.toString())
uploadImage()
}
}
}
if (image != null) {
profileImage = image.toMultipartBody("profile_image")
} // and than code for api calls which use profileImage to upload
fun File?.toMultipartBody(name: String): MultipartBody.Part? {
this ?: return null
return MultipartBody.Part.createFormData(
name,
this.name,
RequestBody.create(getMimeType().toMediaTypeOrNull(), this)
)
}
private fun File.getMimeType(): String {
var type: String? = null
val url = this.toURI().toURL().toString()
val extension = url.substringAfterLast(".")
return when (extension.lowercase(Locale.getDefault())) {
"jpg", "jpeg", "png" -> "image/$extension"
"mp4" -> "video/$extension"
"pdf" -> "application/$extension"
else -> "image/*"
}
}
感谢任何帮助!!
我是这样解决这个问题的:
首先在使用 private fun getTmpFileUri() 创建 tempFile 时:Uri 检索 tempFile 的绝对路径并将其存储在全局变量中,如下所示:
private fun getTmpFileUri(): Uri {
val timeStamp: String = SimpleDateFormat("ddMMyyyy", Locale.getDefault()).format(Date())
val tmpFile = File.createTempFile(timeStamp, ".png", cacheDir).apply {
createNewFile()
deleteOnExit()
}
imagePath = tmpFile.absolutePath // store file path in variable
return FileProvider.getUriForFile(applicationContext, "${BuildConfig.APPLICATION_ID}.provider", tmpFile)
}
现在使用该路径创建图像文件如下:
private val getImageResult = registerForActivityResult(ActivityResultContracts.TakePicture()) { isSuccess ->
if (isSuccess) {
latestTmpUri?.let {
image = File(imagePath)
uploadImage()
}
}
}
现在您可以使用可变图像在 uploadImage() 方法中上传您的图像文件。