插入媒体文件时应用程序在 Android 9 上崩溃

Posted

技术标签:

【中文标题】插入媒体文件时应用程序在 Android 9 上崩溃【英文标题】:App Crashing on Android 9 while inserting media file 【发布时间】:2021-12-28 11:39:46 【问题描述】:

媒体插入代码:

fun saveVideoToExternalStorage(
    contentResolver: ContentResolver,
    displayName: String,
    file: File
): Uri 
    val videoCollection = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q)
        MediaStore.Video.Media.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY)
    else MediaStore.Video.Media.EXTERNAL_CONTENT_URI

    val contentValues = ContentValues().apply 
        put(MediaStore.Video.Media.TITLE, displayName)
        put(MediaStore.Video.Media.MIME_TYPE, "video/mp4")
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) 
            put(MediaStore.Video.Media.DISPLAY_NAME, displayName)
            put(
                MediaStore.Video.Media.RELATIVE_PATH,
                "$Environment.DIRECTORY_MOVIES/Coutloot"
            )
         else 
            var videosDir =
                Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).path
            videosDir += "/Coutloot"

            with(File(videosDir, displayName)) 
                put(MediaStore.Video.Media.DATA, path)
                parentFile?.let 
                    if (!it.exists()) 
                        it.mkdir()
                    
                
            
        
    
    return try 
        val uri = contentResolver.insert(videoCollection, contentValues)?.also  uri ->
            contentResolver.openOutputStream(uri).use  outputStream ->
                outputStream?.write(file.readBytes())
            
         ?: throw IOException("Couldn't create MediaStore entry")
        uri
     catch (e: IOException) 
        e.printStackTrace()
        Uri.EMPTY
    

contentResolver.insert

上保存应用时崩溃

这是崩溃日志

2021-11-17 18:43:00.979 785-785/company.coutloot W/System.err: java.lang.SecurityException: Permission Denial: writing com.android.providers.media.MediaProvider uri content://media/external/images/media from pid=785, uid=10533 requires android.permission.WRITE_EXTERNAL_STORAGE, or grantUriPermission()

我也尝试添加运行时间权限,但没有奏效,而且这只发生在 Android 9 中。 谁能建议我如何解决这个问题?

【问题讨论】:

您是否允许该应用的存储权限? 【参考方案1】:

试试这个对我有用的代码

var fileOutputStream : OutputStream?

if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q)
    contentResolver.also  resolver ->
        val contentValues = ContentValues().apply 
            put(MediaStore.Video.Media.DISPLAY_NAME,displayName)
            put(MediaStore.Video.Media.MIME_TYPE,"video/mp4")
            put(MediaStore.Video.Media.RELATIVE_PATH,"$Environment.DIRECTORY_MOVIES/Coutloot")
        

        val videoUri = resolver.insert(
            MediaStore.Video.Media.EXTERNAL_CONTENT_URI,contentValues
        )
        fileOutputStream = videoUri?.let 
            resolver.openOutputStream(it)
        
    
else
    val absolutePath =
        Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).absolutePath

    val path = absolutePath.substring(0, absolutePath.length - 5) + "/Coutloot/"
    val filePath = File(path)
    if (!filePath.exists())
        filePath.mkdir()

    fileOutputStream = FileOutputStream(
        File(filePath, displayName)
    )


fileOutputStream?.write(file.readBytes())

【讨论】:

if (!filePath.exists()) if(! filePath.mkdir()) return

以上是关于插入媒体文件时应用程序在 Android 9 上崩溃的主要内容,如果未能解决你的问题,请参考以下文章

iOS - Swift - 插入电话时的回调

Android USB插入时弹出文件传输

Android 11.0 USB插入时自动进入文件传输界面

Android 9+ 上的媒体投影问题

CKQueryOperation iOS 9 只能在插入时工作

为啥 PhoneGap Android 应用程序在将一堆数据插入 SQL 时崩溃?