Android 11创建文件夹和文件失败:No such file or directory

一、前言:

Manifest已经配置权限,代码中也动态获取权限,mkdirs一直返回false,
有的手机android11 或者android12 下载文本到本地文件没有任何问题,但是OPPO(Reno2 Z或者Reno4 Pro)手机创建本地文件夹或者文件一直失败。

android 11 第一次安装软件,File.mkdirs()方法创建文件夹失败

图片.png

二、解决:

1、动态申请读写权限

<!--SDCard写权限-->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> 
<!--SDCard读权限-->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> 
<!--在SDCard中创建与删除文件权限-->
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" /> 

Android XML 添加

2、在AndroidManifest.xml中添加如下配置:

如果你不想使用Android 10 的新特性来创建文件夹,那么你可以把targetSdkVersion 改为29之下,因为如果你的应用compileSdkVersion为29并且targetSdkVersion为29,就会使用29的最新源码编译和运行,如果降低targetSdkVersion在系统源码运行的时候就会找到相应的targetSdkVersion版本的源码,这样就相当于绕过了Android 10新特性。

你也可以在Androidmainfest 里面的application添加:
android:requestLegacyExternalStorage="true"

 <application
        android:name=".base.BWNApplication"
        android:allowBackup="true"
        android:appComponentFactory="beiwo"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:largeHeap="true"
        android:networkSecurityConfig="@xml/network_security_config"
        android:requestLegacyExternalStorage="true"
        android:resizeableActivity="true"
        android:theme="@style/AppTheme"
        android:usesCleartextTraffic="true"
        tools:ignore="GoogleAppIndexingWarning"
        tools:replace="android:appComponentFactory"
        android:supportsRtl="true"
        tools:targetApi="31">

3、android 11 第一次安装软件,File.mkdirs()方法创建文件夹失败

因为第一次安装软件后,File.mkdirs()方法创建文件夹失败,去网上找到了原因在这里
文件路径原本用的是Environment.getExternalStorageDirectory(),现在改为context.getFilesDir().getAbsolutePath()

import android.os.Environment;

import java.io.File;

public class SDCardUtil {
    /*public static String getInnerSDCardPath() {
        return Environment.getExternalStorageDirectory() + File.separator;
    }*/
    
    public static String getInnerSDCardPath() {
        if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
            File external = MainApplication.getContext().getExternalFilesDir(null);
            if (external != null) {
                return external.getAbsolutePath() + File.separator;
            }
        }
        return MainApplication.getContext().getFilesDir().getAbsolutePath() + File.separator;
    }
}

4、分析文件夹失败原因:

Manifest已经配置权限,代码中也动态获取权限,mkdirs一直返回false,最后找到原因是path的路径使用的是Environment.getExternalStorageDirectory().getPath(),在compileSdkVersion: 29版本中,该方法标注了@Deprecated,里面已经说明,对于Android Q的手机,应用程序不再可以直接访问此方法返回的路径,所以会一直报错open failed: ENOENT (No such file or directory)

图片.png

注意:替换path的路径方案,不使用Environment.getExternalStorageDirectory().getPath()即可

 private static String getFileRoot(Context context) {
        if (Environment.getExternalStorageState().equals(
                Environment.MEDIA_MOUNTED)) {
            File external = context.getExternalFilesDir(null);
            if (external != null) {
                return external.getAbsolutePath();
            }
        }
        return context.getFilesDir().getAbsolutePath();
    }

参考:https://blog.csdn.net/MoonAndroid/article/details/122824520

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容