根据需求,应用程序用户从设备相机中点击图像并将其上传到服务器。当我在Lollipop及以上版本上测试我的APK时,一切正常,但当我在Lollipop以下版本上测试(特别是KitKat 4.4.4 API 19)时,应用程序会崩溃并显示异常
在将
后来,在
这是我如何将
这是我提供的
这是方法
这是我的
这是我的
这是我收到的崩溃日志。
java.io.FileNotFoundException: /:open failed:EISDIR(是一个目录)
。在将
intent
传递给Camera
之前,我创建了一个File
并将其传递给Uri
。同时,在创建File
时,我还将文件路径保存在某个变量中。后来,在
onActivityResult()
中,我使用路径(保存在变量中)创建新文件,然后使用retrofit multipart将其传递给服务器。这是我如何将
Intent
传递给Camera
的方式。Intent(MediaStore.ACTION_IMAGE_CAPTURE).also { takePictureIntent ->
takePictureIntent.resolveActivity(packageManager)?.also {
val photoFile = try {
createImageFile()
} catch (e: Exception) {
null
}
Log.e("file tag", photoFile!!.absolutePath)
photoFile?.also {
val photoUri = FileProvider.getUriForFile(this@PrintActivity, "$packageName.fileprovider", it)
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoUri)
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.LOLLIPOP) {
takePictureIntent.clipData = ClipData.newRawUri("", photoUri)
takePictureIntent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
}
startActivityForResult(takePictureIntent, REQUEST_CAMERA)
}
}
}
createImageFile()
方法如下:
@Throws(IOException::class)
private fun createImageFile(): File {
val timeStamp = SimpleDateFormat("yyyyMMdd_HHmmss", Locale.ENGLISH).format(Date())
val storageDir = getExternalFilesDir("Allocation")
return File.createTempFile("JPEG_${timeStamp}_", ".jpg", storageDir).apply {
printImageFilePath = absolutePath
}
}
这是我提供的
file_paths
。<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="my_images" path="Android/data/$packageName/files/Allocation" />
</paths>
这是我在 AndroidManifest
文件中的 application
标签下声明 Provider
的方式。
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="$packageName.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
</provider>
这是方法
OnActivityResult()
。 override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == REQUEST_CAMERA && resultCode == Activity.RESULT_OK) {
try {
val printedImageFile = File(printImageFilePath)
doImageUpload(printedImageFile)
} catch (e: Throwable) {
e.stackTrace
}
}
}
这是我的
doImageUpload()
方法。private fun doImageUpload(printedImageFile: File?) {
if (networkUtil.isConnected()) {
try {
launch(UI) {
val response = dataManager.uploadImage(printedImageFile)
Log.v("ImageUploadSuccess", response.body())
}catch(e:Exception){
}
}
这是我的
dataManager.uploadImage(printedImageFile)
方法。suspend fun uploadImage(printImageFile: File?): Response<String> {
val printImageBody: RequestBody
val printImagePart: MultipartBody.Part
printImageBody =
RequestBody.create(MediaType.parse("multipart/formdata"),printImageFile)
printImagePart = MultipartBody.Part.createFormData("my_file1", printImageFile.name, printImageBody)
restService.uploadImage(printImagePart).await()
}
最后,这是我的retrofit多部分接口方法:
@Multipart
@POST
fun uploadImage(@Part myFile2: MultipartBody.Part?): Deferred<Response<String>>
这是我收到的崩溃日志。
E/AndroidRuntime: FATAL EXCEPTION: main
Process: $packageName, PID: 24339
java.io.FileNotFoundException: /: open failed: EISDIR (Is a directory)
at libcore.io.IoBridge.open(IoBridge.java:409)
at java.io.FileInputStream.<init>(FileInputStream.java:78)
at okio.Okio.source(Okio.java:168)
at okhttp3.RequestBody$3.writeTo(RequestBody.java:119)
at okhttp3.MultipartBody.writeOrCountBytes(MultipartBody.java:173)
at okhttp3.MultipartBody.writeTo(MultipartBody.java:114)
at com.readystatesoftware.chuck.ChuckInterceptor.intercept(ChuckInterceptor.java:154)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:254)
at okhttp3.RealCall$AsyncCall.execute(RealCall.java:200)
at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:841)
Caused by: libcore.io.ErrnoException: open failed: EISDIR (Is a directory)
at libcore.io.IoBridge.open(IoBridge.java:398)
at java.io.FileInputStream.<init>(FileInputStream.java:78)
at okio.Okio.source(Okio.java:168)
at okhttp3.RequestBody$3.writeTo(RequestBody.java:119)
at okhttp3.MultipartBody.writeOrCountBytes(MultipartBody.java:173)
at okhttp3.MultipartBody.writeTo(MultipartBody.java:114)
at com.readystatesoftware.chuck.ChuckInterceptor.intercept(ChuckInterceptor.java:154)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:254)
at okhttp3.RealCall$AsyncCall.execute(RealCall.java:200)
at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:841)