Android Q文件适配

Android Q中无法直接对内部存储的公共空间操作File对象来实现读文件、写文件、删除文件、重命名文件等操作。只能通过Uri的形式读写。如果直接拿File对象操作,在使用File对象创建OutputStream或者InputStream的时候,就会报错。

操作公共空间时,会用到MediaStore。它是外部存储空间的公共媒体集合,存放的都是多媒体文件,在API >= 29后加入了Download集合:

为了以后的适配方便,在创建使用到文件的工具类的时候,最好不要再使用File对象传递了,而是替换成Uri对象。

创建Uri:

Uri fileUri = null;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
    //设置保存参数到ContentValues中
    ContentValues contentValues = new ContentValues();
    //设置文件名
    contentValues.put(MediaStore.Downloads.DISPLAY_NAME, fileName);
    contentValues.put(MediaStore.Downloads.RELATIVE_PATH, Environment.DIRECTORY_DOWNLOADS);
    //设置文件类型
    contentValues.put(MediaStore.Downloads.MIME_TYPE, mime);
    //执行insert操作,向系统文件夹中添加文件
    //EXTERNAL_CONTENT_URI代表外部存储器,该值不变
    fileUri = getContentResolver().insert(MediaStore.Downloads.EXTERNAL_CONTENT_URI, contentValues);
} else {
    File dir = new File(Environment.getExternalStorageDirectory().getPath() + File.separator + Environment.DIRECTORY_DOWNLOADS);
    if(!dir.exists()){
        dir.mkdirs();
    }
    File file = new File(dir, fileName);
    if (file.exists()) {
        file.delete();
    }
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
        fileUri = Uri.fromFile(file);
    } else {
        fileUri = FileProvider.getUriForFile(this, getApplicationContext().getPackageName() + ".file_provider", file);
    }
}

由Uri得到OutputStream或者InputStream:

OutputStream os = getContentResolver().openOutputStream(fileUri);
InputStream is = getContentResolver().openInputStream(fileUri);

创建Uri时,可以的话尽量设置正确的MIME_TYPE。因为如果文件已存在,系统会自动重命名,MIME_TYPE正确的话,重命名的时候才会自动的正确递增,比如1.jpeg, 1(1).jpeg。如果MIME_TYPE错误,则会错误的递增,比如1.jpg, 1.jpg(1)。注意jpg文件的mime为image/jpeg,而不能是image/jpg。

对同一个目录通过getContentResolver().insert创建Uri对象后,如果对该目录使用该方法创建一个新的Uri,会报错:UNIQUE constraint failed。经尝试对另一个目录创建没有问题。比如分别对Download和Picture目录创建,没有问题。还不知道为什么。

参考文献:

https://developer.android.com/training/data-storage#scoped-storage

https://stackoverflow.com/questions/8854359/exception-open-failed-eacces-permission-denied-on-android?page=1&tab=active#tab-top

https://www.jianshu.com/p/15520bc3f5c6

https://blog.csdn.net/yehui928186846/article/details/101706238

Share

You may also like...

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注