美文网首页
Android11适配

Android11适配

作者: 主音King | 来源:发表于2020-11-06 10:00 被阅读0次

    适配targetSdkVersion 30或者以上(Android 11)

    分区存储强制执行

    对外部存储目录访问仅于应用专属目录,以及应用创建的特定类型媒体

    分区存储在Android10已经推行。对于文件读写只能在沙盒环境,属于自己应用的目录读写。其他媒体文件可以通过MediaStore进行访问。

    • 在targetSdkVersion = 29应用中,设置android:requestLegacyExternalStorage="true",就可以不启动分区存储。

    • 但是targetSdkVersion = 30中不行了,强制开启分区存储。
      targetSdkVersion = 30,如果是覆盖安装呢,可以增加android:preserveLegacyExternalStorage="true",暂时关闭分区存储。只要卸载重装,就会失效了;

    fun saveFile() {        
        if (checkPermission()) {            
            //getExternalStoragePublicDirectory被弃用,分区存储开启后就不允许访问了            
            val filePath = Environment.getExternalStoragePublicDirectory("").toString() + "/test3.txt"            
            val fw = FileWriter(filePath)            
            fw.write("hello world")            
            fw.close()            
            showToast("文件写入成功")        
        }    
    }
    
    • targetSdkVersion = 28,运行后正常读写。

    • targetSdkVersion = 29,不删除应用,targetSdkVersion 由 28 修改到 29,覆盖安装,运行后正常读写

    • targetSdkVersion = 29,删除应用,重新运行,读写报错,程序崩溃 (open failed: EACCES (Permission denied))

    • targetSdkVersion = 29,添加android:requestLegacyExternalStorage="true"(不启用分区存储),读写正常不报错

    • targetSdkVersion = 30,不删除应用,targetSdkVersion 由 29 修改到 30,读写报错,程序崩溃 (open failed: EACCES (Permission denied))

    • targetSdkVersion = 30,不删除应用,targetSdkVersion 由 29 修改到 30,增加 android:preserveLegacyExternalStorage="true",读写正常不报错

    • targetSdkVersion = 30,删除应用,重新运行,读写报错,程序崩溃 (open failed: EACCES (Permission denied))

    targetSdkVersion = 30 三种方法访问文件

    • 应用专属目录
    //分区存储空间
    val file = File(context.filesDir, filename) 
    //应用专属外部存储空间
    val appSpecificExternalDir = File(context.getExternalFilesDir(), filename) 
    
    • 访问公共媒体目录文件
    val cursor = contentResolver.query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, null, null, null, "${MediaStore.MediaColumns.DATE_ADDED} desc")
    if (cursor != null) {    
        while (cursor.moveToNext()) {        
            val id = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.MediaColumns._ID))        
            val uri = ContentUris.withAppendedId(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, id)        
            println("image uri is $uri")    
        }    
        cursor.close()
    } 
    
    • SAF (存储访问框架--Storage Access Framework)
    val intent = Intent(Intent.ACTION_OPEN_DOCUMENT)    
    intent.addCategory(Intent.CATEGORY_OPENABLE)    
    intent.type = "image/*"    
    startActivityForResult(intent, 100)     
    
    @RequiresApi(Build.VERSION_CODES.KITKAT)    
    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {        
        super.onActivityResult(requestCode, resultCode, data)        
        if (data == null || resultCode != Activity.RESULT_OK) 
            return        
        if (requestCode == 100) {            
            val uri = data.data            
            println("image uri is $uri")        
        }    
    } 
    

    参考:https://juejin.im/post/6890811621724618765

    相关文章

      网友评论

          本文标题:Android11适配

          本文链接:https://www.haomeiwen.com/subject/raozvktx.html