一、前言:
Manifest已经配置权限,代码中也动态获取权限,mkdirs一直返回false,
有的手机android11 或者android12 下载文本到本地文件没有任何问题,但是OPPO(Reno2 Z或者Reno4 Pro)手机创建本地文件夹或者文件一直失败。
android 11 第一次安装软件,File.mkdirs()方法创建文件夹失败
二、解决:
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)
注意:替换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