Amith Dissanayaka
Amith Dissanayaka

Reputation: 1059

Flutter - save file to download folder - downloads_path_provider

I'm developing a mobile app using flutter. For that I used downloads-path-provider to get the download directory of the mobile phone. The emulator returns /storage/emulated/0/Download. Also when I save a file in this directory the file can be visible in the Download folder.

But on a real devices it also returns the same directory path. /storage/emulated/0/Download Is this correct for the actual devices? Because on actual devices I cannot see the saved file in the Download folder.

Is there any solution to find the downloads directory on a real device?

Upvotes: 20

Views: 88761

Answers (5)

Siddy Hacks
Siddy Hacks

Reputation: 2330

just adding to @live-love answer

This code handles iOS normal way using path_provider package but for android it uses direct Downloads path, also taking the precaution that on some devices it may be Downloads with an s

bool dirDownloadExists = true;
var directory;
if (Platform.isIOS) {
  directory = await getDownloadsDirectory();
} else {

  directory = "/storage/emulated/0/Download/";

   dirDownloadExists = await Directory(directory).exists();
  if(dirDownloadExists){
    directory = "/storage/emulated/0/Download/";
  }else{
    directory = "/storage/emulated/0/Downloads/";
  }
}

Upvotes: 5

Yusuf GÜR
Yusuf GÜR

Reputation: 31

You can use "flutter_file_dialog" to handle the issue. After succesfully saving file into app you can provide the path of file to this package and save it in another folder of phone. You can use the function below; ** fromDest ** is the path of the saved file.

_saveFileToDest(String fromDest) async {
   final params =
            SaveFileDialogParams(sourceFilePath: fromDest);
        final filePath = await FlutterFileDialog.saveFile(params: params);
        if (kDebugMode) {
          print(filePath);
        }
  }

Upvotes: 0

amit.flutter
amit.flutter

Reputation: 1141

This question and answer is deprecated with flutter 3.0+ : try this one

Future<void> _prepareSaveDir() async {
    _localPath = (await _findLocalPath())!;

    print(_localPath);
    final savedDir = Directory(_localPath);
    bool hasExisted = await savedDir.exists();
    if (!hasExisted) {
      savedDir.create();
    }
  }

  Future<String?> _findLocalPath() async {
    if (platform == TargetPlatform.android) {
      return "/sdcard/download/";
    } else {
      var directory = await getApplicationDocumentsDirectory();
      return directory.path + Platform.pathSeparator + 'Download';
    }
  }

one method for create or find directory and other one will find path.

Upvotes: 3

Abdelrahman Tareq
Abdelrahman Tareq

Reputation: 2317

add this to manifest:

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

then use these 2 packages:

  1. permission_handler to request storage permission
  2. downloads_path_provider to save the file in downloads directory

in pubspec add:

permission_handler: ^5.0.1+1
downloads_path_provider: ^0.1.0

then

 Future<File> writeFile(Uint8List data, String name) async {
    // storage permission ask
    var status = await Permission.storage.status;
    if (!status.isGranted) {
      await Permission.storage.request();
    }
    // the downloads folder path
    Directory tempDir = await DownloadsPathProvider.downloadsDirectory;
    String tempPath = tempDir.path;
    var filePath = tempPath + '/$name';
    // 

    // the data
    var bytes = ByteData.view(data.buffer);
    final buffer = bytes.buffer;
    // save the data in the path
    return File(filePath).writeAsBytes(buffer.asUint8List(data.offsetInBytes, data.lengthInBytes));
  }

then use the method:

var file = await writeFile(uint8List, 'name');

Upvotes: 9

live-love
live-love

Reputation: 52494

path_provider will probably undergo some changes soon, there are some open issues:

https://github.com/flutter/flutter/issues/35783

As of right now, the best way to get the download path on an Android device is to use:

/storage/emulated/0/Download/

No (s) needed.

And to get the external dir path in Android:

/storage/emulated/0/

The "emulated" word does not mean it's the emulator path, it's just a naming convention.

Make sure you have permission to write to the file, add this to manifest.xml file, right under <manifest tag:

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

and also request permission at run time.

See https://pub.dev/packages/permission_handler

Upvotes: 33

Related Questions