Android 在安卓系统中使用带MultipartBody的改型2发布图像时,EXIF详细信息丢失?
我们正在使用CameraX捕获多个图像并将其存储在设备上,并使用MultipartBody.Part和RequestBody发布这些图像和文本数据。我们发现服务器端没有收到EXIF详细信息。这是改装2多部件的问题吗?我们如何在服务器端获取图像而不丢失其EXIF详细信息 下面是我们正在使用的代码Android 在安卓系统中使用带MultipartBody的改型2发布图像时,EXIF详细信息丢失?,android,kotlin,retrofit2,android-camerax,Android,Kotlin,Retrofit2,Android Camerax,我们正在使用CameraX捕获多个图像并将其存储在设备上,并使用MultipartBody.Part和RequestBody发布这些图像和文本数据。我们发现服务器端没有收到EXIF详细信息。这是改装2多部件的问题吗?我们如何在服务器端获取图像而不丢失其EXIF详细信息 下面是我们正在使用的代码 private lateinit var activityCaptureImageBinding: ActivityCaptureImageBinding private var preview: Pr
private lateinit var activityCaptureImageBinding: ActivityCaptureImageBinding
private var preview: Preview? = null
private var imageCapture: ImageCapture? = null
private var camera: Camera? = null
private lateinit var outputDirectory: File
private lateinit var cameraExecutor: ExecutorService
private lateinit var fusedLocationClient: FusedLocationProviderClient
private var metadata = ImageCapture.Metadata()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
activityCaptureImageBinding = DataBindingUtil.setContentView(this@CaptureImageActivity, R.layout.activity_capture_image)
window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
fusedLocationClient = LocationServices.getFusedLocationProviderClient(this)
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return
}
fusedLocationClient.lastLocation
.addOnSuccessListener { location: Location? ->
metadata.apply {
setLocation(location)
}
}
activityCaptureImageBinding.btnCaptureImage.setOnClickListener {
takePhoto()
}
activityCaptureImageBinding.btnCancel.setOnClickListener {
val intent = Intent()
intent.putStringArrayListExtra(AppData.IMAGE_PATH, AppData.capturedCatsList)
setResult(Activity.RESULT_OK, intent)
finish()
}
outputDirectory = getOutputDirectory()
cameraExecutor = Executors.newSingleThreadExecutor()
}
private fun startCamera() {
val cameraProviderFuture = ProcessCameraProvider.getInstance(this)
cameraProviderFuture.addListener(Runnable {
val cameraProvider: ProcessCameraProvider = cameraProviderFuture.get()
preview = Preview.Builder()
.build()
imageCapture = ImageCapture.Builder()
.build()
val cameraSelector = CameraSelector.Builder().requireLensFacing(CameraSelector.LENS_FACING_BACK).build()
try {
cameraProvider.unbindAll()
camera = cameraProvider.bindToLifecycle(
this, cameraSelector, preview, imageCapture)
preview?.setSurfaceProvider(viewFinder.createSurfaceProvider())
} catch (exc: Exception) {
showLog(TAG, "Use case binding failed" + exc)
}
}, ContextCompat.getMainExecutor(this))
}
private fun takePhoto() {
val imageCapture = imageCapture ?: return
val photoFile = File(
outputDirectory,
SimpleDateFormat(FILENAME_FORMAT, Locale.getDefault()
).format(System.currentTimeMillis()) + ".jpg")
showLog(TAG, "created file")
val outputOptions = ImageCapture.OutputFileOptions.Builder(photoFile)
.setMetadata(metadata)
.build()
imageCapture.takePicture(
outputOptions, ContextCompat.getMainExecutor(this), object : ImageCapture.OnImageSavedCallback {
override fun onError(exc: ImageCaptureException) {
showLog(TAG, "Photo capture failed: ${exc.message}")
}
override fun onImageSaved(output: ImageCapture.OutputFileResults) {
showLog(TAG, "on image saved")
val savedUri = Uri.fromFile(photoFile)
AppData.capturedCatsList.add(savedUri.toString())
}
})
}
以下是改装代码
@Multipart
@POST("SimpleEncounterForm")
fun postCatImagesWithData(@Header("Cookie") cookie: String,
@Part catImages: List<MultipartBody.Part>,
@Part("datetime") dateTime: RequestBody,
@Part("lat") lat: RequestBody,
@Part("lon") lon: RequestBody,
@Part("locationID") locationId: RequestBody,
@Part("behavior") catBehaviour: RequestBody): Call<ResponseBody>
将Uri转换为文件
public static File getFile(Context context, Uri uri) {
if (uri != null) {
String path = getPath(context, uri);
if (path != null && isLocal(path)) {
return new File(path);
}
}
return null;
}
我们发现我们没有收到EXIF详细信息
仅收到详细信息还是根本没有收到EXIF头?比较文件大小。收到的字节是否较少?file=FileUtils.getFile(this@DashboardActivity,fileUri)
该语句的作用是什么?val savedUri=Uri.fromFile(photoFile)
您还可以保存photoFile.getAbsolutePath()并将其用于多部分,而不是转换为uri并返回。@blackapps在getFile中我们执行以下操作:公共静态文件getFile(上下文上下文,uri uri){if(uri!=null){String path=getPath(上下文,uri);if(path!=null&&isLocal(path)){return new File(path);}返回null;}
比较文件大小。接收的字节是否更少代码>我宁愿你告诉我尺寸。这就回答了您的问题。我们发现我们没有收到EXIF详细信息
仅收到详细信息,或者根本没有收到EXIF头?比较文件大小。收到的字节是否较少?file=FileUtils.getFile(this@DashboardActivity,fileUri)
该语句的作用是什么?val savedUri=Uri.fromFile(photoFile)
您还可以保存photoFile.getAbsolutePath()并将其用于多部分,而不是转换为uri并返回。@blackapps在getFile中我们执行以下操作:公共静态文件getFile(上下文上下文,uri uri){if(uri!=null){String path=getPath(上下文,uri);if(path!=null&&isLocal(path)){return new File(path);}返回null;}
比较文件大小。接收的字节是否更少代码>我宁愿你告诉我尺寸。这就回答了你的问题。
public static File getFile(Context context, Uri uri) {
if (uri != null) {
String path = getPath(context, uri);
if (path != null && isLocal(path)) {
return new File(path);
}
}
return null;
}