使用 MediaStore 存储图像会导致特定三星设备上的应用程序崩溃 [英] Storing images using MediaStore crashes app on specific Samsung devices

查看:26
本文介绍了使用 MediaStore 存储图像会导致特定三星设备上的应用程序崩溃的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在为这个问题苦苦挣扎,不幸的是,其他答案没有给我任何线索.

I have been struggling with this issue for a while and other answers unfortunately didn't give me any clue.

我的应用允许用户拍照并将其存储在本地.对于大多数设备,一切正常,但是我在运行 Android 9 (API 28) 的特定三星设备上遇到崩溃.

My app allows users to take pictures and store them locally. Everything works fine for most devices, however I experience a crash on specific Samsung devices running Android 9 (API 28).

设备示例是:
三星 SM-G955F
三星 SM-G973F

Example of devices are:
Samsung SM-G955F
Samsung SM-G973F

这是我用来存储图像的方法:

Here is the method I use to store the images:

fun saveMedia(context: Context, uri: Uri) {

    val values = ContentValues().apply {
        put(MediaStore.Images.Media.DISPLAY_NAME, IMAGE_PREFIX + Date().toString(DATE_FORMAT) + ".$FILE_EXTENSION")
        put(MediaStore.Images.Media.MIME_TYPE, MIME_TYPE)
        put(MediaStore.Images.Media.DATE_ADDED, System.currentTimeMillis())

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            put(MediaStore.Images.Media.RELATIVE_PATH, Environment.DIRECTORY_PICTURES)
            put(MediaStore.Images.Media.IS_PENDING, 1)
        } else {
            @Suppress("deprecation")
            put(MediaStore.Images.Media.DATA, uri.toString())
        }
    }

    val imageCollection = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
        MediaStore.Images.Media.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY)
    } else {
        MediaStore.Images.Media.EXTERNAL_CONTENT_URI
    }
    //Crashes here
    val newImageUri = context.contentResolver.insert(imageCollection, values)

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {

        if (newImageUri == null) {
            Log.e(TAG, "unable to insert image: " + values.get(MediaStore.Images.Media.DISPLAY_NAME))
            throw IOException("Failed to create new MediaStore record: "
                    + values.get(MediaStore.Images.Media.DISPLAY_NAME))
        }

        val bitmapSource = ImageDecoder.createSource(context.applicationContext.contentResolver, uri)
        val bitmap = ImageDecoder.decodeBitmap(bitmapSource)

        context.contentResolver.openOutputStream(newImageUri).use { out ->
            bitmap.compress(BITMAP_COMPRESS_FORMAT, 90, out)
        }

        values.clear()
        values.put(MediaStore.Images.Media.IS_PENDING, 0)
        context.contentResolver.update(newImageUri, values, null, null)
    }

    load(context)
    cameraFile = null
}

在这些特定设备上,应用程序在 context.contentResolver.insert(imageCollection, values) 处崩溃作为附加信息,saveMedia 方法将其作为 uri 接收:content://media/external/images/media

On those specific devices the app crashes at context.contentResolver.insert(imageCollection, values) As additional info the saveMedia method receives this as uri: content://media/external/images/media

这是错误

02-07 00:48:05.666: E/AndroidRuntime(18495):FATAL EXCEPTION: main Process: 
02-07 00:48:05.666: E/AndroidRuntime(18495):com.myapp.myapp, PID: 3773 java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=196677, result=-1, data=Intent { (has extras) }} to activity {com.myapp.myapp/com.myapp.ui.MainActivity}: 
02-07 00:48:05.666: E/AndroidRuntime(18495):java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String java.lang.String.toLowerCase(java.util.Locale)' on a null object reference 
02-07 00:48:05.666: E/AndroidRuntime(18495): at android.app.ActivityThread.deliverResults(ActivityThread.java:4604) 
02-07 00:48:05.666: E/AndroidRuntime(18495): at android.app.ActivityThread.handleSendResult(ActivityThread.java:4646) 
02-07 00:48:05.666: E/AndroidRuntime(18495): at android.app.servertransaction.ActivityResultItem.execute(ActivityResultItem.java:49) 
02-07 00:48:05.666: E/AndroidRuntime(18495): at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108) 
02-07 00:48:05.666: E/AndroidRuntime(18495): at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68) 
02-07 00:48:05.666: E/AndroidRuntime(18495): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1947) 
02-07 00:48:05.666: E/AndroidRuntime(18495): at android.os.Handler.dispatchMessage(Handler.java:106) 
02-07 00:48:05.666: E/AndroidRuntime(18495): at android.os.Looper.loop(Looper.java:214) 
02-07 00:48:05.666: E/AndroidRuntime(18495): at android.app.ActivityThread.main(ActivityThread.java:7032) 
02-07 00:48:05.666: E/AndroidRuntime(18495): at java.lang.reflect.Method.invoke(Native Method) 
02-07 00:48:05.666: E/AndroidRuntime(18495): at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:494) 
02-07 00:48:05.666: E/AndroidRuntime(18495): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:965) 
02-07 00:48:05.666: E/AndroidRuntime(18495):Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String java.lang.String.toLowerCase(java.util.Locale)' on a null object reference 
02-07 00:48:05.666: E/AndroidRuntime(18495): at android.os.Parcel.createException(Parcel.java:1972) 
02-07 00:48:05.666: E/AndroidRuntime(18495): at android.os.Parcel.readException(Parcel.java:1934) 
02-07 00:48:05.666: E/AndroidRuntime(18495): at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:183) 
02-07 00:48:05.666: E/AndroidRuntime(18495): at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:135) 
02-07 00:48:05.666: E/AndroidRuntime(18495): at android.content.ContentProviderProxy.insert(ContentProviderNative.java:476) 
02-07 00:48:05.666: E/AndroidRuntime(18495): at android.content.ContentResolver.insert(ContentResolver.java:1594) 
02-07 00:48:05.666: E/AndroidRuntime(18495): at com.myapp.ui.tabs.progress.ProgressViewModel.saveMedia(ProgressViewModel.kt:97) 
02-07 00:48:05.666: E/AndroidRuntime(18495): at com.myapp.ui.tabs.progress.ProgressFragment.onActivityResult(ProgressFragment.kt:185) 
02-07 00:48:05.666: E/AndroidRuntime(18495): at androidx.fragment.app.FragmentActivity.onActivityResult(FragmentActivity.java:170) 
02-07 00:48:05.666: E/AndroidRuntime(18495): at android.app.Activity.dispatchActivityResult(Activity.java:7759)

我找不到它试图应用 toLowerCase() 的地方,也找不到什么对象为空.我错过了什么吗?

I cannot find where it tries to apply toLowerCase() nor what object is null. Am I missing something?

非常感谢任何提示谢谢

推荐答案

我最终通过更改此行来解决此问题

I ended up solving this by changing this line

 put(MediaStore.Images.Media.DATA, uri.toString())

到这里

 put(MediaStore.Images.Media.DATA, uri.path)

然后加载图片,区分具体安卓版本如下

And then load the image with the following differentiating between specific Android versions

fun loadPicture(uri: Uri, date: Date) {

  val request = Glide.with(this@ProgressFragment)

  val builder = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
      request.load(uri)
  } else {
      request.load(File(uri.path!!))
  }

  builder.centerCrop().into(picture)

  pictureDate.text = date.toString(getString(R.string.fragment_progress_date))
}

这篇关于使用 MediaStore 存储图像会导致特定三星设备上的应用程序崩溃的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆