gpt4 book ai didi

android - 在 KitKat 4.4.4 API 19 上使用改造上传图像时应用程序崩溃

转载 作者:行者123 更新时间:2023-11-29 02:20:46 41 4
gpt4 key购买 nike

根据要求,应用程序的用户点击设备相机中的图像,然后将其上传到服务器。当我在 Lollipop 及更高版本上测试我的 APK 时一切正常,但当我在 Lollipop 以下(特别是在 KitKat 4.4.4 API 19 上)测试它时,应用程序崩溃并出现异常 java.io.FileNotFoundException:/: open failed : EISDIR(是一个目录).

在将 intent 传递给 Camera 之前,我正在创建一个 File 并将其传递给 Uri。此外文件 创建我将文件路径保存在某个变量中。

稍后在 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>

这就是我在 application 标签下的 AndroidManifest 中声明 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()
}

最后这是我改造的多部分接口(interface)方法,

@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)

最佳答案

经过大量的试验和错误,并在我的前辈和this的帮助下,我终于解决了相应的问题。

问题是,一旦我用后置摄像头拍摄照片,android 系统就会杀死我各自的 Activity类,以节约资源。当相机关闭并返回到我的Activity , Activity由于用于保存捕获图像的文件路径的实例变量为空,正在重新创建。结果,应用程序曾经崩溃。

所以为了保留实例变量我使用了onSaveInstanceState(outState: Bundle?)方法如下,在我的PrintActivity类(触发 ActivityCamera Intent),

override fun onSaveInstanceState(outState: Bundle?) {
super.onSaveInstanceState(outState)
outState?.putString(Constants.PRINT_IMAGE_FILE_PATH,printImageFilePath)
// printImageFilePath is the path of the image file ,
// Constants.PRINT_IMAGE_FILE_PATH is my key for the bundle

}

然后在我的 PrintActivityonCreate(savedInstanceState: Bundle?)里面我像这样重新分配实例变量,

override fun onCreate(savedInstanceState: Bundle?) {
if(savedInstanceState?.get(Constants.PRINT_IMAGE_FILE_PATH)!=null){
printImageFilePath =
savedInstanceState.get(Constants.PRINT_IMAGE_FILE_PATH)
}
}

关于android - 在 KitKat 4.4.4 API 19 上使用改造上传图像时应用程序崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55922590/

41 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com