Flutter : Create directory on external storage path - path provider getExternalStorageDirectory()

17,781

Solution 1

The below code is working fine in my application to download an image using the url to the external storage

Future<bool> downloadImage(String url) async {
  await new Future.delayed(new Duration(seconds: 1));
  bool checkResult =
      await SimplePermissions.checkPermission(Permission.WriteExternalStorage);
  if (!checkResult) {
    var status = await SimplePermissions.requestPermission(
        Permission.WriteExternalStorage);
    if (status == PermissionStatus.authorized) {
      var res = await saveImage(url);
      return res != null;
    }
  } else {
    var res = await saveImage(url);
    return res != null;
  }
  return false;
}

Future<Io.File> saveImage(String url) async {
  try {
    final file = await getImageFromNetwork(url);
    var dir = await getExternalStorageDirectory();
    var testdir =
        await new Io.Directory('${dir.path}/iLearn').create(recursive: true);
    IM.Image image = IM.decodeImage(file.readAsBytesSync());
    return new Io.File(
        '${testdir.path}/${DateTime.now().toUtc().toIso8601String()}.png')
      ..writeAsBytesSync(IM.encodePng(image));
  } catch (e) {
    print(e);
    return null;
  }
}

  Future<Io.File> getImageFromNetwork(String url) async {
  var cacheManager = await CacheManager.getInstance();
  Io.File file = await cacheManager.getFile(url);
  return file;
}

Namespaces

import 'dart:io' as Io;
import 'package:image/image.dart' as IM;
import 'package:flutter_cache_manager/flutter_cache_manager.dart';
import 'package:path_provider/path_provider.dart';
import 'package:simple_permissions/simple_permissions.dart';

Hope it helps

Solution 2

You need to request permissions before saving a file using getExternalStorageDirectory.

Add this to Androidmanifest.xml:

 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

Then use the permission_handler package to get Storage permission:

https://pub.dev/packages/permission_handler

If you are running in the Emulator, getExternalStorageDirectory returns:

/storage/emulated/0/Android/data/com.example.myapp/files/

If you just need the external dir to create a directory under it, then just use:

/storage/emulated/0/

You can create a directory under this folder, so they user will be able to open the files.

Share:
17,781
Gaurav Pingale
Author by

Gaurav Pingale

Updated on December 09, 2022

Comments

  • Gaurav Pingale
    Gaurav Pingale over 1 year

    I'm creating a flutter app where I want to download and store an image to the external storage (not documents directory) so it can be viewed by any photo gallery app. I'm using the following code to create a directory

    var dir = await getExternalStorageDirectory();
      if(!Directory("${dir.path}/myapp").existsSync()){
        Directory("${dir.path}/myapp").createSync(recursive: true);
      }
    

    It's giving me following error:

    FileSystemException: Creation failed, path = '/storage/emulated/0/myapp' (OS Error: Permission denied, errno = 13)
    

    I have set up permissions in the manifest file and using the following code for runtime permissions

    List<Permissions> permissions = await Permission.getPermissionStatus([PermissionName.Storage]);
    permissions.forEach((p) async {
      if(p.permissionStatus != PermissionStatus.allow){
        final res = await Permission.requestSinglePermission(PermissionName.Storage);
        print(res);
      }
    });
    

    I have verified in settings that app has got the permission, also as suggested on some answers here I've also tried giving permission from settings app manually which did not work.

  • nivla360
    nivla360 over 4 years
    how about video?
  • Nithin Sai
    Nithin Sai over 3 years
    Hey, this is throwing an error for android 10 devices
  • mohammad
    mohammad about 3 years
    Unhandled Exception: FileSystemException: Creation failed, path = '/storage/emulated/0/app_name' (OS Error: Operation not permitted, errno = 1)