bellotas
bellotas

Reputation: 2461

How to get the absolute path of a file in flutter

I am working on a Flutter project to syntehsise an string to an audio file. For this reason, I have added flutter_tts as a dependency and implemented the following method with different approaches in order to check the existence of the generated file:

/// Synthesises the current audio cue into an audio file
  static Future<void> synthesiseStringToAudioFile() async {
    Future<String> finalPath;
    Future<File> finalFile;
    Uri uriToFile;
    String absolutePath;
    bool existsPath;
    bool existsManually;
    bool exists3;
    await flutterTts
        .synthesizeToFile("This is my first audio synthesizer in Flutter",
            audioFileName)
        .then((value) => {
              // File has been successfully created
              if (value == 1)
                {
                  // Gets the path to the generated audio file
                  finalPath =  pathToFile,
                  finalPath.then((path) async => { 
                        print('AFile :Path to audio file: $path'),
                        // Check if exists
                        existsPath = FileSystemEntity.typeSync(path) != FileSystemEntityType.notFound,
                        print("AFile : Exists? $existsPath"),
                        existsManually = await File('/storage/emulated/0/Android/data/mypath/files/temp_audio_cue.wav').exists(), // Requieres async function
                        print("AFile : Exists2? $existsManually"), // RETURNS TRUE
                        exists3 = await File(path).exists(),
                        print("AFile : Exists3? $exists3")

                  }),

                  // Gets the generated file
                  finalFile = localFile,
                  finalFile.then((file) => {
                    // Absolute path
                    absolutePath = file.absolute.path,
                    print('AFile : AbsolutePath: $absolutePath'),
                    // Check the URI
                    uriToFile = file.uri,
                    print('AFile : URI to audio file: $uriToFile'),
                  }),
                  

                  
                }
              else
                {print('There was an error during the synthezisation')}
            });
  }

  static void setAudioFileName() {
    audioFileName = Platform.isAndroid ? "temp_audio_cue.wav" : "temp_audio_cue.caf";
  }

  /// Gets the path to the file to be accessed
  static Future<String> get pathToFile async {
    final path = await localPath;
    return '$path/$audioFileName';
  }

  /// Gets the path to the local directory
  static Future<String> get localPath async {
    final dir = await getApplicationDocumentsDirectory();
    return dir.path;
  }

Once the synthesisation is completed, flutterTts.synthesizeToFile() logs in console the following message:

D/TTS (10335): Successfully created file : /storage/emulated/0/Android/data/mypath/files/temp_audio_cue.wav

so if I check the existence of the file manually (as I do with existManually) will get a true value, but I am not able to do it trying to get dynamically the path as in the other examples I am trying but the ones I am getting are:

/data/user/0/mypath/app_flutter/temp_audio_cue.wav

so it is missing the beginning

/storage/emulated/0/Android/

I was wondering what is the correct way to get the path to the file (missing)?

Upvotes: 0

Views: 16368

Answers (5)

BadTanMan
BadTanMan

Reputation: 21

I am using filesystem_picker to return absolute paths from storage and then using File('path_string') or Directory('path_string') to get the actual file. Using manageExternalStorage permissions allows this work, but keep in mind:
"The Google Play store has a policy that limits usage of MANAGE_EXTERNAL_STORAGE".

This also may not work depending on the SDK you are using and/or conflicts from other packages.

import 'package:filesystem_picker/filesystem_picker.dart';
import 'package:permission_handler/permission_handler.dart';

Directory? rootDir;
late String tempDir;

_getFile(){
  await _pickFile();
  String path = tempDir;
  var file = File(path);
  // Do stuff with file
}

// Call this before _pickFile(), ideally inside initState() 
Future<void> _prepareStorage() async {
  rootDir = Directory('/storage/emulated/0/');

  var storageExternal = await Permission.manageExternalStorage.status;
  if (storageExternal != PermissionStatus.granted) {
    await Permission.manageExternalStorage.request();
  }

  bool b = storageExternal == PermissionStatus.granted;
  //mPrint("STORAGE ACCESS IS : $b");
}

Future<void> _pickFile(BuildContext context) async {
  await FilesystemPicker.open(
    title: 'Select file',
    context: context,
    rootDirectory: rootDir!,
    fsType: FilesystemType.file,
    pickText: 'Select file to add',
    folderIconColor: Colors.teal,
    requestPermission: () async => await Permission.manageExternalStorage.request().isGranted,
  ).then((value){
    if (value != null){
      tempDir = value.toString();
    }
    else{
      tempDir = "";
    }

    //mPrint(tempDir);
  });
}

Add the following to AndroidManifest.xml:

<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" android:minSdkVersion="30" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>    
<application
     android:label="test_flutter"
     android:name="${applicationName}"
     android:icon="@mipmap/ic_launcher"
     android:requestLegacyExternalStorage="true"
     >

Upvotes: 1

Abdul Samad
Abdul Samad

Reputation: 59

you can use path_provider package of flutter

Directory appDocDir = await getApplicationDocumentsDirectory();
String appDocPath = appDocDir.path;

https://pub.dev/packages/path_provider

Upvotes: 0

ki bo
ki bo

Reputation: 11

I tried and it worked

import 'package:path_provider/path_provider.dart';


Future<File> getImageFileFromAssets(Asset asset) async {
    final byteData = await asset.getByteData();

    final tempFile =
        File("${(await getTemporaryDirectory()).path}/${asset.name}");
    final file = await tempFile.writeAsBytes(
      byteData.buffer
          .asUint8List(byteData.offsetInBytes, byteData.lengthInBytes),
    );
    return file;
    }

Upvotes: 0

Fernando Lozada
Fernando Lozada

Reputation: 347

With path_provider in Android save in getExternalStorageDirectory and in iOS save in getApplicationDocumentsDirectory..

Upvotes: 2

Aakash kondhalkar
Aakash kondhalkar

Reputation: 680

If you want to get this path : /storage/emulated/0

Use path_provider_ex package, which provides root and app files directory for both "external storage" (internal flash) and SD card (if present), as well as available space for each storage.

Upvotes: 2

Related Questions