Flutter: android 不允许应用程序在外部存储中创建一个新文件夹来保存文件?
Flutter: android doesn't lets the app create a new folder in the external storage to save file?
我有一个 flutter 应用程序,它下载视频并尝试通过特别是“/storage/emulated/0/”目录名视频来保存视频文件...所以路径将是“/storage/emulated/0/video” ....但是 android 不允许我创建这个文件夹...
我的 android manifest.xml 文件包含外部存储权限....
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.infinite_scroll">
<uses-permission android:name="android.permission.INTERNET"/>
<!-- <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<application
android:label="video"
android:icon="@mipmap/ic_launcher"
android:requestLegacyExternalStorage="true"
>
<activity
android:name=".MainActivity"
android:launchMode="singleTop"
android:theme="@style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize">
<!-- Specifies an Android theme to apply to this Activity as soon as
the Android process has started. This theme is visible to the user
while the Flutter UI initializes. After that, this theme continues
to determine the Window background behind the Flutter UI. -->
<meta-data
android:name="io.flutter.embedding.android.NormalTheme"
android:resource="@style/NormalTheme"
/>
<!-- Displays an Android View that continues showing the launch screen
Drawable until Flutter paints its first frame, then this splash
screen fades out. A splash screen is useful to avoid any visual
gap between the end of Android's launch screen and the painting of
Flutter's first frame. -->
<meta-data
android:name="io.flutter.embedding.android.SplashScreenDrawable"
android:resource="@drawable/launch_background"
/>
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<!-- Don't delete the meta-data below.
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
<meta-data
android:name="flutterEmbedding"
android:value="2" />
</application>
</manifest>
我有一个下载器功能,我在其中传递文件 url 和文件名,然后它创建目录并在特定目录中下载文件
Future<bool> downloadFile(String url, String fileName) async{
try {
// permission na dile direct failed
// Android
if (Platform.isAndroid){
if(await _requestPermission(Permission.storage)){
dir = await getExternalStorageDirectory();
print(dir!.path);
// var newPath = dir?.path.split("/data")[0];
var newPath = dir!.path;
newPath = newPath + "/video";
dir = Directory(newPath.toString());
print(dir?.path);
}
}else{
// IOS
print("in ios");
if(await _requestPermission(Permission.photos)){
dir = await getTemporaryDirectory();
print(dir);
}else{
print("rejected");
return false;
}
}
if(!await dir!.exists()){
await dir?.create(recursive: true); <<<----- this line gives error
}
if(await dir!.exists()){
File saveFile = File(dir!.path + "/$fileName");
await dio.download(
url,
saveFile.path,
onReceiveProgress: (downloaded, totalSize){
setState(() {
progress = downloaded / totalSize;
});
}
);
if(Platform.isIOS){
await ImageGallerySaver.saveFile(saveFile.path, isReturnPathOfIOS: true);
}
return true;
}
} catch (e) {
print(e);
}
return false;
}
请求权限是单独触发的函数...
Future<bool> _requestPermission(Permission permission) async{
if(await permission.isGranted){
return true;
}else{
PermissionStatus result = await permission.request();
if(result == PermissionStatus.granted){
return true;
}else{
return false;
}
}
}
但是当我触发这个函数时它给了我这个错误...
I/flutter ( 6252): /storage/emulated/0/Android/data/com.example.infinite_scroll/files
I/flutter ( 6252): /storage/emulated/0/Android/video
I/flutter ( 6252): FileSystemException: Cannot create file, path = '/storage/emulated/0/Android/video/logo1.png' (OS Error: Operation not permitted, errno = 1)
I/flutter ( 6252): failed downloading
我是 flutter 的新手...请提供描述性的答案并向我推荐一些博客....
从Android11开始,改变了写入外存的方式。
阅读有关分区存储的信息,您可能会找到 Android
的相同答案
我有一个 flutter 应用程序,它下载视频并尝试通过特别是“/storage/emulated/0/”目录名视频来保存视频文件...所以路径将是“/storage/emulated/0/video” ....但是 android 不允许我创建这个文件夹...
我的 android manifest.xml 文件包含外部存储权限....
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.infinite_scroll">
<uses-permission android:name="android.permission.INTERNET"/>
<!-- <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<application
android:label="video"
android:icon="@mipmap/ic_launcher"
android:requestLegacyExternalStorage="true"
>
<activity
android:name=".MainActivity"
android:launchMode="singleTop"
android:theme="@style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize">
<!-- Specifies an Android theme to apply to this Activity as soon as
the Android process has started. This theme is visible to the user
while the Flutter UI initializes. After that, this theme continues
to determine the Window background behind the Flutter UI. -->
<meta-data
android:name="io.flutter.embedding.android.NormalTheme"
android:resource="@style/NormalTheme"
/>
<!-- Displays an Android View that continues showing the launch screen
Drawable until Flutter paints its first frame, then this splash
screen fades out. A splash screen is useful to avoid any visual
gap between the end of Android's launch screen and the painting of
Flutter's first frame. -->
<meta-data
android:name="io.flutter.embedding.android.SplashScreenDrawable"
android:resource="@drawable/launch_background"
/>
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<!-- Don't delete the meta-data below.
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
<meta-data
android:name="flutterEmbedding"
android:value="2" />
</application>
</manifest>
我有一个下载器功能,我在其中传递文件 url 和文件名,然后它创建目录并在特定目录中下载文件
Future<bool> downloadFile(String url, String fileName) async{
try {
// permission na dile direct failed
// Android
if (Platform.isAndroid){
if(await _requestPermission(Permission.storage)){
dir = await getExternalStorageDirectory();
print(dir!.path);
// var newPath = dir?.path.split("/data")[0];
var newPath = dir!.path;
newPath = newPath + "/video";
dir = Directory(newPath.toString());
print(dir?.path);
}
}else{
// IOS
print("in ios");
if(await _requestPermission(Permission.photos)){
dir = await getTemporaryDirectory();
print(dir);
}else{
print("rejected");
return false;
}
}
if(!await dir!.exists()){
await dir?.create(recursive: true); <<<----- this line gives error
}
if(await dir!.exists()){
File saveFile = File(dir!.path + "/$fileName");
await dio.download(
url,
saveFile.path,
onReceiveProgress: (downloaded, totalSize){
setState(() {
progress = downloaded / totalSize;
});
}
);
if(Platform.isIOS){
await ImageGallerySaver.saveFile(saveFile.path, isReturnPathOfIOS: true);
}
return true;
}
} catch (e) {
print(e);
}
return false;
}
请求权限是单独触发的函数...
Future<bool> _requestPermission(Permission permission) async{
if(await permission.isGranted){
return true;
}else{
PermissionStatus result = await permission.request();
if(result == PermissionStatus.granted){
return true;
}else{
return false;
}
}
}
但是当我触发这个函数时它给了我这个错误...
I/flutter ( 6252): /storage/emulated/0/Android/data/com.example.infinite_scroll/files
I/flutter ( 6252): /storage/emulated/0/Android/video
I/flutter ( 6252): FileSystemException: Cannot create file, path = '/storage/emulated/0/Android/video/logo1.png' (OS Error: Operation not permitted, errno = 1)
I/flutter ( 6252): failed downloading
我是 flutter 的新手...请提供描述性的答案并向我推荐一些博客....
从Android11开始,改变了写入外存的方式。
阅读有关分区存储的信息,您可能会找到 Android
的相同答案