Search code examples
androidiodartflutterstorage

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


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.


Solution

  • 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