We are trying to make it possible for users to select entire folders to upload them to our back end. This is no problem on Android and iOS, where I can use getDirectoryPath() from FilePicker, and then get all the files using Directory(path).listSync(recursive: true).
The issue is that this isn't available on web, and while i can exchange dart:io for universal_io, that doesn't help with getDirectoryPath().
Is there any other approach that I can use here? The end goal is to upload the selected folder to Google Cloud Storage, so one Idea that I have is to bypass Flutter entirely, but I haven't figured out a way to do that yet. Any ideas?
There is File System Access API and showDirectoryPicker, which would be the way to go, but it is not supported by all browsers.
One option would be to allow a user to pick multiple files and upload bytes. Not the same thing, but in some cases would be sufficient. Something like this:
final result = await FilePicker.platform.pickFiles(allowMultiple: false);
if (result != null && result.files.isNotEmpty) {
final fileBytes = result.files.first.bytes;
final fileName = result.files.first.name;
// TODO upload file
}
Use a JavaScript library: You can use a JavaScript library such as file-uploader or dropzone.js to handle file uploads in your web application. These libraries provide a file explorer interface for the user to select and upload files, and can be integrated with Flutter using dart:js and package:js
Related
I have started a development of a music player. I made some additional kotlin logic to retrieve all audio files meta data on device from the Android as a list of meta data. I'm trying to understand how a native path should look like for just_audio to understand. My current implementation uses a deprecated key - MediaStore.Audio.Media.DATA for contentResolver which returns a path like this /storage/emulated/0/Download/scifri20181123-episode.mp3. Can this path be used by the plugin or I need to find another way to retrieve the path in different format?
The same question is valid for the album art.
Yes, if it's a valid file path, then just_audio will be able to open it. You could pass this into setFilePath:
var filePath = '/storage/emulated/....../foo.mp3';
await player.setFilePath(filePath);
This is a convenience method for:
setAudioSource(AudioSource.uri(Uri.file(filePath)));
where Uri.file(filePath) will create a Uri instance containing something like file:///storage/emulated/..... under the hood.
Note that if your app tries to access any file outside of its own app data/cache directories, it also requires permission to do so, and there are other Flutter packages available to help you with this.
Note also that there is also an existing flutter package using the content resolver API called flutter_audio_query, so if it contains what you need, you might not need to write your own Kotlin code.
I'm a beginner at flutter and dart and had some issues with file handling using flutter.
I'm trying to store data locally in text files for my flutter application, and came across the standard tutorial on flutter's website which used path_provider and dart:io. It had instructions on getting the path and reading and writing to a file, however this didn't seem to work for files I added to the project. The only way to store to files was to first write using the inbuilt functions, then reading this newly created file. I can't add my own file and read it using flutter.
I also can't open the file created by flutter as I don't know where its stored. The path given by getApplicationDocumentsDirectory() returns the path /data/user/0/com.example.daily_challenges/app_flutter, and I don't know where to find this in my project.
In summary: How do I read a pre-existing file and how do I view the file created automatically by flutter.
Thanks :)
You can access the files from a physical device or simulator through Device File Explorer in Android Studio. Follow this guide
You won't be able to access getApplicationDocumentsDirectory().
If you are using android device, you can try to store it in getExternalStorageDirectory(). There's no equivalent in IOS though.
If you are running in a physical device. Open Device File Explorer in Android Studio and you can find the file under
data/data/your app package/app_flutter/fileName.txt
For example,
data/data/com.example.file_example/app_flutter/example.txt
And if you want to read the pre-existing file, you not need to anything specific, if you give the same file name, if not exist, it will create one, otherwise it will return the old one.
final File file = File(filePath);
file.writeAsStringSync('${text}', mode: FileMode.append);
For write, you consider using FileMode if you want to append text to the existing file. Or else by default overwrite will happen.
For read, you can consider this
final File file = File(filePath);
String text = await file.readAsString();
Just use Device File Explorer from Android Studio.
But the weird thing, path_provider gives you path like /data/user/0/your_app_id/..., but in fact all files are located in /data/data/your_app_id/..., as mentioned in previous answer.
We have a flutter application where we want to use map functionality in offline mode.
Mapbox provides functionality in the flutter to use offline maps but .db file which contains offline data needs to be saved in the project at build time.
How to achieve the same at runtime?
also open to suggestions to use any other map service providers that works in both online and offline mode.
If you want to store a file on the device please read the official Flutter documentation about Reading and Writing Files
Essentially you need to add path_provider package to your project in order to retrieve the standard cache folder for every device and then simply save you file in it.
This is a my application similar behaviour code
//Get an available temporary dir on device using path_provider package
final Directory tempDir = await getTemporaryDirectory();
//Create a path with file name
final String tempPath = tempDir.path + '/' + 'yourFileName.db';
//Write file on device disk
final File file = File(tempPath);
await writeAsBytesSync(fileContent); //If it is a string use writeAsStringAsync
print('File written on disk');
Then using the file path you can simply read it from disk using readAsByteAsync method.
Remember that in the sample we are using getTemporaryDirectory() and as the documentation tell us
Path to the temporary directory on the device that is not backed up and is suitable for storing caches of downloaded files.
Files in this directory may be cleared at any time.
I would recommend to check out this issue on the github page of the flutter-mapbox-gl repository:
https://github.com/tobrun/flutter-mapbox-gl/issues/88
See the comment of vinceKruger:
https://github.com/tobrun/flutter-mapbox-gl/issues/88#issuecomment-559380534
It is not an official way, but seems to work!
I want to make a Flutter Web App like Blog System,but when I use the library 'dart:io', I found it doesn't supported in Flutter for Web.
So,how can I read content from a local markdown file with Flutter for web? Thx!
And apology for My poor English.
I see an example here on the flutter web samples repo.
https://github.com/flutter/samples/blob/master/web/github_dataviz/lib/main.dart
Check the Future loadGitHubData() async function.
They have used HttpRequest.getString() method. This is ideally a client side request as per the docs here.
https://api.dartlang.org/stable/2.4.0/dart-html/HttpRequest-class.html
I am not sure if this is what you want. If you want to just access the contents of the MD file this should help. But if you want to process it into an html or something you probably have to do it in your server.
I had the same issue. I needed to read a .svg file as text. This was my solution:
import 'dart:html';
readFile(String path) async {
var request = await HttpRequest.request(path);
var response = request.response;
return response;
}
Note:
Path used: "assets/someImage.svg"
Returns: File contents as a String
I included this note for context.
I have created a flutter app with video assets which are about 450mb in size. I have published the app successfully in the Apple appstore. But Google Play does not accept my APK as it is over the limit of 200mb. I tried to go with the approach of creating APK expansion files as the recommended workflow. I have read all available Android documention about expansion files but I still can not figure out how to implement them with flutter.
How do you implement and access assets within APK expansion files in a flutter app?
You're going to have a little bit of fun with this. Basically, until someone implements a plugin to access APK expansion files, you're going to have to write the java code to connect up to Flutter.
It's not prohibitively difficult, it just means that you're going to have to learn about Platform Channels and write a bit of native android code. The documentation probably does a better job of explaining platform channels than I do, but basically the easiest way is to use a MethodChannel to pass data from dart to native and vice-versa.
What you'd do to start is set up a method channel to initiate this process and call it with something like getObbFolder.
On the android side the first thing you need to do is make sure your app actually has the files downloaded. According to the android documentation, you can't guarantee that they will have been so you need to write the logic to download them. I'd recommend using the Download Library they provide as there's all sorts of things to worry about like the device running out of storage, network connectivity, showing progress, etc. I think the documentation for that is moderately straight forward (and if you have issues I'd recommend asking a new question specific to it.
Once you've done that, you need to get the path to the file, and request permission to read it if needed. Some android versions and some devices in other versions (it sounds like it's a bit of a crapshoot to be honest), you need permissions to read the file, while in others you don't. So it's best to just try and ask for permission if trying fails.
To get the directory it's saved in use context.getObbDir()
Then this one way to do it from the android docs:
File obb = new File(obb_filename);
boolean open_failed = false;
try {
BufferedReader br = new BufferedReader(new FileReader(obb));
open_failed = false;
ReadObbFile(br);
} catch (IOException e) {
open_failed = true;
}
if (open_failed) {
// request READ_EXTERNAL_STORAGE permission before reading OBB file
ReadObbFileWithPermission();
}
And for the versions that don't do runtime permission checking add this to your application manifest:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
Android doesn't recommend always asking for the permission since sometimes the Obb folder is exempted from needing the READ_EXTERNAL_STORAGE permission.
Now you have two options. One is that you could pass that path back to flutter, and then use flutter's file reading to do something with the data, if the file is something you can directly read. If it's not, you could unpack it either using flutter or using java/kotlin, and then pass back the path to the unpacked files.
If you do choose to unpack the file from android you should do it to one of the directories flutter knows about (with the path_provider plugin for example), or write to wherever you want (and have permission to) and then simply pass the path back to flutter.
Hope that helps!