I have a text file (.txt) that I'd like to be an asset that I can scan in later.
In the pubspec.yaml, I've made sure that:
flutter:
assets:
- res/my_file.txt
exists. The file resides in the res/ folder that I made, on the same level as lib/android/ and ios/
I'm trying to read the file from a custom class, not a widget.
According to the documentation, I'm to use this import:
import 'package:flutter/services.dart' show rootBundle;
and start reading like so:
/// Assumes the given path is a text-file-asset.
Future<String> getFileData(String path) async {
return await rootBundle.loadString(path);
}
And to get the actual data, do:
String data = await getFileData(fileName);
However, when I use a fileName like 'assets/res/my_file.txt', I get an error: Unable to load asset: assets/res/my_file.txt.
It's also worth noting that I'm trying to do this from a unit test. Any ideas on how to properly do this? Thanks!
Here is a fuller answer for future visitors.
Create an assets folder
Create an assets folder in your project's root folder. In Android Studio you can right click the Project outline and go to New > Directory.
You can create another subfolder for text files in assets if you like. But if you do, you have to include the relative path in pubspec.yaml. See below.
Add your text file to the new folder
You can just copy your text file into the assets directory. The relative path of my_file.txt, for example, would be assets/my_file.txt.
Register the assets folder in pubspec.yaml
Open the pubspec.yaml file that is in the root of your project.
Add an assets subsection to the flutter section like this:
flutter:
assets:
- assets/my_file.txt
If you have multiple files that you want to include, then you can leave off the file name and just use the directory name (include the final /):
flutter:
assets:
- assets/
Get the text in code
You can use the global rootBundle to get the text file asset:
import 'dart:async' show Future;
import 'package:flutter/services.dart' show rootBundle;
Future<String> loadAsset() async {
return await rootBundle.loadString('assets/my_text.txt');
}
Or if you have the BuildContext (inside a widget) you can use DefaultAssetBundle. This is recommended because it allows switching asset bundles at runtime, which is useful for multilingual assets.
Future<String> loadAsset(BuildContext context) async {
return await DefaultAssetBundle.of(context).loadString('assets/my_text.txt');
}
See also
Loading text assets
How to include images in your app
The folder name "assets" isn't magically added. Update your pubspec.yaml to include the full path to the asset.
flutter:
assets:
- assets/res/my_file.txt
In my opinion, in order to load a js file into a flutter, you should consider it as a text file and load it properly. So, you need to add the file to assets folder, add into a pubspec file, then load it. read the full answer here
Second, you used evalJavascript. this function can be used in many different situations. but it will work only if you have a view panel.
Check below example:
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_webview_plugin/flutter_webview_plugin.dart';
main() async {
String jsCode = await rootBundle.loadString('assets/javascript.js');
runApp(new MaterialApp(
home: LunchWebView(jsCode),
));
}
class LunchWebView extends StatelessWidget {
final String text;
LunchWebView(this.text);
#override
Widget build(BuildContext context) {
final FlutterWebviewPlugin flutterWebviewPlugin = FlutterWebviewPlugin();
flutterWebviewPlugin.launch('https://www.google.com');
flutterWebviewPlugin.evalJavascript(text);
return Container();
}
}
Related
How do you read text from a file and write text to a file?
I've been learning about how to read and write text to and from a file. I found another question about reading from assets, but that is not the same. I will add my answer below from what I learned from the documentation.
Setup
Add the following plugin in pubspec.yaml:
dependencies:
path_provider: ^1.6.27
Update the version number to whatever is current.
And import it in your code.
import 'package:path_provider/path_provider.dart';
You also have to import dart:io to use the File class.
import 'dart:io';
Writing to a text file
_write(String text) async {
final Directory directory = await getApplicationDocumentsDirectory();
final File file = File('${directory.path}/my_file.txt');
await file.writeAsString(text);
}
Reading from a text file
Future<String> _read() async {
String text;
try {
final Directory directory = await getApplicationDocumentsDirectory();
final File file = File('${directory.path}/my_file.txt');
text = await file.readAsString();
} catch (e) {
print("Couldn't read file");
}
return text;
}
Notes
You can also get the path string with join(directory.path, 'my_file.txt') but you need to import 'package:path/path.dart'.
Flutter's Official Documentation of Reading and Writing Files
This works for iOS, Android, Linux and MacOS but not for web.
As additional info to #Suragch's answer, if you want to find the file you created, you can do as the images show:
And then inside that data folder, go again to a folder named data and search for your package, and then go to:
If you happen to create new files, in order to be able to see them, just right click and click Synchronize.
An another way to pull the file from the device is by using adb pull command. You can find the file path by debugging the code and then use adb pull command. adb is located in Android SDK -> platform-tools directory.
./adb pull /storage/emulated/0/Android/data/com.innovate.storage.storage_sample/files/sample.txt ~/Downloads
#Suragch 's answer is right. Except the version of path_provider that you want to use now is:
path_provider: ^2.0.9
I am creating a Flutter project in which, I have a piece of data (JSON) that I want to Import from and Export to a location the user wants to. In order to achieve this, I require a File Picker plugin in Flutter. Now, I searched the Dart Packages repository for "file picker" but didn't find one.
Is there a way to get a File Picker that looks like this:
or even this...
The first screenshot is preferable for me as it allows file selection from different sources (like Drive).
Also, since I want to Export the data, I might want a Folder Picker too. ;)
But, if there is any other alternative to Folder Picker. I'd be happy to know...
I've created a file_picker plugin some time ago in order to make it possible to pick (both on iOS and Android) absolute paths and then loaded it with Flutter.
You can check it here: https://pub.dev/packages/file_picker
I used file_picker library to pick files. you can use this for pick images as well.
Future getPdfAndUpload(int position) async {
File file = await FilePicker.getFile(
type: FileType.custom,
allowedExtensions: ['pdf','docx'], //here you can add any of extention what you need to pick
);
if(file != null) {
setState(() {
file1 = file; //file1 is a global variable which i created
});
}
}
here file_picker flutter library.
I'm in the exact same boat as you, haha!
I noticed documents_picker 0.0.2. It allows the user to pick multiple files, and it seems to fit the need!
check it out: https://pub.dartlang.org/packages/documents_picker#-readme-tab-
Here's a better document picker. It looks like the native document picker from the Storage Access Framework, which is what you have in your picture.
flutter_document_picker
Just found the FileSelector plugin from flutter.dev. Compatible with MacOS, Windows and Web.
From its pub.dev page:
Open a single file
final typeGroup = XTypeGroup(label: 'images', extensions: ['jpg', 'png']);
final file = await openFile(acceptedTypeGroups: [typeGroup]);
Open multiple files at once
final typeGroup = XTypeGroup(label: 'images', extensions: ['jpg', 'png']);
final files = await openFiles(acceptedTypeGroups: [typeGroup]);
Saving a file
final path = await getSavePath();
final name = "hello_file_selector.txt";
final data = Uint8List.fromList("Hello World!".codeUnits);
final mimeType = "text/plain";
final file = XFile.fromData(data, name: name, mimeType: mimeType);
await file.saveTo(path);
MacOS: Provide file read or/and write privileges
On target MacOS please provide sufficient rights using Xcode:
In case you don't provide file read or/and write permissions, the call to
final XFile? file =
await openFile(acceptedTypeGroups: <XTypeGroup>[typeGroup]);
neither shows anything not returns.
Is there any way to access some of the attributes listed in a pubspec.yaml file in that files Dart application?
In particular, the version and description attributes may be quite useful to see in a version info dialog, or even a '--version' when using a console app. I haven't been able to find a way to access in the API. I'm not sure if Mirrors would have anything appropriate, but if a web app is compiled to JS, then I don't see the description anywhere in the output JS.
Thanks.
EDIT
feature request: https://code.google.com/p/dart/issues/detail?id=18769
FOR FLUTTER ONLY
Please use this new package package_info_plus from flutter community.
import 'package:package_info_plus/package_info_plus.dart';
PackageInfo packageInfo = await PackageInfo.fromPlatform();
String appName = packageInfo.appName;
String packageName = packageInfo.packageName;
String version = packageInfo.version;
String buildNumber = packageInfo.buildNumber;
BELOW SOLUTION IS DEPRICATED.
I know the OP wants to read YAML but for flutter dev's you guys can read the version and other info of the application using package_info.
This is the sample to fetch details from Android/iOS application.
import 'package:package_info/package_info.dart';
PackageInfo packageInfo = await PackageInfo.fromPlatform();
String appName = packageInfo.appName;
String packageName = packageInfo.packageName;
String version = packageInfo.version;
String buildNumber = packageInfo.buildNumber;
you can install the "dart_config" package and use this code to parse a pubspec.yaml file:
import 'package:dart_config/default_server.dart';
import 'dart:async';
void main() {
Future<Map> conf = loadConfig("../pubspec.yaml");
conf.then((Map config) {
print(config['name']);
print(config['description']);
print(config['version']);
print(config['author']);
print(config['homepage']);
print(config['dependencies']);
});
}
The output looks similar to this:
test_cli
A sample command-line application
0.0.1
Robert Hartung
URL
{dart_config: any}
EDIT
You can do it with the Yaml package itself:
*NOTE: this will not work on Flutter Web
import 'package:yaml/yaml.dart';
import 'dart:io'; // *** NOTE *** This will not work on Flutter Web
void main() {
File f = new File("../pubspec.yaml");
f.readAsString().then((String text) {
Map yaml = loadYaml(text);
print(yaml['name']);
print(yaml['description']);
print(yaml['version']);
print(yaml['author']);
print(yaml['homepage']);
print(yaml['dependencies']);
});
}
Regards Robert
None of the above answers worked for me, but here's a working solution for a Flutter app:
In your pubspec.yaml add the "pubspec.yaml" to assets:
assets:
- assets/
- pubspec.yaml
If you have a widget where you need to show the app version like this:
...
Container(
child: Text('Version: 1.0.0+1'),
),
...
Wrap your widget with a FutureBuilder like this:
import 'package:flutter/services.dart';
import 'package:yaml/yaml.dart';
...
FutureBuilder(
future: rootBundle.loadString("pubspec.yaml"),
builder: (context, snapshot) {
String version = "Unknown";
if (snapshot.hasData) {
var yaml = loadYaml(snapshot.data);
version = yaml["version"];
}
return Container(
child: Text(
'Version: $version'
),
);
}),
...
The services rootBundle property contains the resources that were packaged with the application when it was built.
If you want to show the version without the build number, you can split the string like so:
'Version: ${version.split("+")[0]}'
UPDATE: As mentioned by #wildsurfer, this approach has a potential security risk in web development because the pubspec.yaml is shared with the browser!
So assuming that this is for a dart cli application then the #Robert suggestion won't work.
dart_config isn't available for dart 2.x and your pubspec.yaml isn't going to be relative to your cwd except when you are in your development environment
So you need to get the pubspec.yaml relative to the libraries executable path.
This example uses the 'paths' package but it isn't required.
This can be obtained by:
import 'package:path/path.dart';
String pathToYaml = join(dirname(Platform.script.toFilePath()), '../pubspec.yaml');
You can now read the yaml:
import 'package:path/path.dart';
import 'package:yaml/yaml.dart';
String pathToYaml = join(dirname(Platform.script.toFilePath()), '../pubspec.yaml');
File f = new File(pathToYaml);
String yamlText = f.readAsStringSync();
Map yaml = loadYaml(yamlText);
print(yaml['name']);
print(yaml['description']);
print(yaml['version']);
print(yaml['author']);
print(yaml['homepage']);
print(yaml['dependencies']);
});
For Flutter only (Web, Android and IOS)... since October 2020
If you want your app working on Web, Android and IOS use "Package info_plus" instead.
How to Incorporate Automated Version Information into A Dart Command Line App
To update version information in your code without having to package a resource file to be parsed during run time, you can have the information hard coded into an automatically generated dart source file which gets compiled into your binary. The following example hard codes the version, name, and description information into the Map object "meta" in a meta.dart file. The meta.dart file is recreated and overwritten every time the test suite is run in development. To verify the source code has the correct version information, the app's code verifies the version and other meta information against the attributes in the pubspec.yaml file (but only when run as interpreted code in development). If there is a difference from pubspec.yaml, it throws an exception. Once compiled into a binary, it will skip that check as it won't find the pubspec.yaml file, so no error is thrown from the binary. Even if a pubspec.yaml file happens to be around and is found, it only throws an exception and does not create a "meta.dart" source file.
1. Create a MetaUpdate class and save it as "meta_update.dart":
import 'dart:io';
import 'package:yaml/yaml.dart';
import 'meta.dart';
class MetaUpdate {
String pathToYaml = "";
String metaDartFileContents = "";
MetaUpdate(this.pathToYaml);
void writeMetaDartFile(String metaDartFilePath) {
File metaDartFile = File(metaDartFilePath);
String metaDartFileContents = """
/// DO NOT EDIT THIS FILE EXCEPT TO ENTER INITIAL VERSION AND OTHER META INFO
/// THIS FILE IS AUTOMATICALLY OVER WRITTEN BY MetaUpdate
Map<String, String> meta = <String, String>{
"name": "${getPubSpec('name')}",
"description":
// ignore: lines_longer_than_80_chars
"${getPubSpec('description')}",
"version":"${getPubSpec('version')}",
};
""";
metaDartFile.writeAsStringSync(metaDartFileContents);
}
String getPubSpec(String pubSpecParam) {
File f = File(pathToYaml);
String yamlText = f.readAsStringSync();
// ignore: always_specify_types
Map yaml = loadYaml(yamlText);
return yaml[pubSpecParam];
}
void verifyLatestVersionFromPubSpec() {
try {
File f = File(pathToYaml);
//exit if no pubspec found so no warning in production
if (!f.existsSync()) return;
//compare meta.dart with pubspec meta and give warning if difference
if (meta.keys
.where((dynamic e) => (meta[e] != getPubSpec(e)))
.isNotEmpty) {
throw Exception(
"""Version number and other meta attributes in code are different from pubspec.yaml. Please check pubspec.yaml and then run test so that MetaUpdate can update meta information in code, then recompile""");
}
} on Exception {
rethrow;
}
}
}
2. Create a "meta.dart" file:
/// DO NOT EDIT THIS FILE EXCEPT TO ENTER INITIAL VERSION AND OTHER META INFO
/// THIS FILE IS AUTOMATICALLY OVER WRITTEN BY MetaUpdate
Map<String, String> meta = <String, String>{
"name": "Acme Transmogrifier",
"description":
"The best dart application ever.",
"version":"2021.09.001",
};
When you initially create the meta.dart file, copy your specific info from pubspec.yaml. This will later be overwritten each time your MetaUpdate.writeMetaDartFile() is run, changing the contents whenever the info in pubspec.yaml is changed.
3. Implement The Version Update In Your Test Code
Add the following in the first line of Main() in your test code (not the source of the main program, we don't want it to be compiled into the binary), changing the path to meta.dart as appropriate:
MetaUpdate("pubspec.yaml").writeMetaDartFile("lib/src/meta.dart");
4. Add A Meta Check To Your Main Code
Put this in your app's code so it is one of the first methods executed when your app is run - it will generate an exception if there is a difference between the attributes shown in the meta.dart and pubspec.yaml:
MetaUpdate("pubspec.yaml").verifyLatestVersionFromPubSpec();
5. Using
Make sure the Name, Version, and Description information in pubspec.yaml contains the latest information you want reflected in your code.
Import "meta.dart" and insert meta['name'], meta['version'], etc. where you need them to be shown (e.g., in --help or --version messages to be printed to the console).
As long as you run your tests before compiling your code the meta information will be accurately reflected in your code.
You can access pubspec.yaml properties with the official pubspec_parse package from the Dart team.
dart pub add pubspec_parse
import 'dart:io';
import 'package:pubspec_parse/pubspec_parse.dart';
final pubspec = File('pubspec.yaml').readAsStringSync();
final parsed = Pubspec.parse(pubspec);
You can then access typed properties on the parsed object.
You can find supported properties here: https://pub.dev/documentation/pubspec_parse/latest/pubspec_parse/Pubspec-class.html.
Dart's Web UI performs a compile step which puts the generated files into an "out" folder. I can't figure out how to get an image to be placed in that out folder, though. Does anyone know how?
I have the images in the web folder in a folder called img, although I've also tried putting them directly in web. Should I create a top level folder named resources and put them in there instead?
I had the same problem, and have almost solved it by updating my build.dart to include a copy of the img folder into the out folder.
import 'dart:io';
import 'dart:async';
import 'package:web_ui/component_build.dart';
// Ref: http://www.dartlang.org/articles/dart-web-components/tools.html
// Actually ... https://github.com/sethladd/dart-web-components-tests/blob/master/build.dart
main() {
var args = new List.from(new Options().arguments);
// args.addAll(['--', '--no-rewrite-urls']);
Future dwc = build(args, ['web/index.html']);
dwc
.then((_) => Process.run('cp', ['-fR', 'web/img', 'web/out']));
}
In the above I've added a command to run "cp" (I'm on a Mac) of web/img to web/out.
I say almost solved it because those image in the img folder also end up being copied directly into the out folder as well as out/img, which isn't ideal but doesn't harm anything for me just now. I believe these extra copies are from build.dart being triggered by the copy, haven't found a way to stop this yet.
I know you can use the library, import and even #import, but which is correct?
I have got two files, MainClass.dart and Library.Dart, and I want to add a reference to Library.dart in MainClass.dart. How can I do that?
Firstly let me just preface this by saying please do not use the hash symbol before import or library or anything else. This is an old syntax that is being deprecated. So we no longer want to use #import('...') The correct syntax is:
import 'some_file.dart';
That said, there are two different things we can do to access different dart source files within our current file. The first is to import the file. We use this such as in your case when you want to bring a different library into the current file (or more accurately current library).
Usually if your files are in the same directory, or a sub directory of the current one we would import them like this:
import 'lib/library.dart';
However If you are using the pub package layout you can also use some special short-cut references as well to import files (particularly from other packages you've imported). I highly suggest reading the documents on the pub site, as most applications and libraries are designed with this in mind. It also has suggestions on best naming conventions such as filenames in all lower case, and using underscore for spaces, and directory layouts.
The other important thing to know about bringing a dart file into another file, is that we can use the part and part of directives. This used to be called #source but was changed (with the removal of the hash sign) to reduce confusion. The part directive is used when we want to write a single library which spans multiple files. Say for instance you have an Awesome Library, which is starting to get a little large for a single file. We will create the main file of the library (not to be confused with the main method). This file will usually have the same name as the library itself.
// awesome_library.dart
library awesome_library;
import 'dart:math';
import '...';
// this injects all the content of secret_file.dart
// into this file right here almost as if it was
// here in the first place.
part 'src/secret_file.dart';
// The rest of our file here
// ...
The part directive basically takes everything from our src/secret_file.dart and inserts it into that part of the file. This allows us to split our huge Awesome Library into multiple smaller files that are easier to maintain. While not specifically required, it is helpful to use the part of directive in our secret_file.dart to help the editor know that it is "part of" the library.
// secret_file.dart
part of awesome_library;
// ... Rest of our secret_file code below.
Note that when using a part file like this, the part(s) (that is everything that is not the main file of the library) cannot import or use library declarations themselves. They import whatever is imported into the the main file, but they cannot add any additional imports.
For more information about library see this link.
Importing your own created libraries:
You will be importing the filename.dart and not the name of your library.
So if the name of your library is: myLib and it is saved in the file: someDartFile.dart you will have to
import 'someDartFile.dart';
If you have on Windows a library at: K:\SomeDir\someFile.dart you will need to write:
import '/K:/SomeDir/someFile.dart';
example:
import 'LibraryFile.dart'; //importing myLib
void main(){
//a class from myLib in the LibraryFile.dart file
var some = new SomeClassFromMyLibrary();
}
myLib in LibraryFile.dart:
library myLibrary;
import 'dart:math';
class SomeClassFromMyLibrary{
String _str = "this is some private String only to myLibrary";
String pubStr = "created instances of this class can access";
}
Here a full example.
//TestLib.dart
import 'LibFile.dart'; //SomeLibrary
void main() {
print("Hello, World!");
LibFile l = new LibFile();
print(l.publicString);//public
print(l.getPrivateString);//private
print(l.getMagicNumber); //42
}
//LibFile.dart
library SomeLibrary;
part 'LibFile2.dart';
class LibFile {
String _privateString = "private";
String publicString = "public";
String get getPrivateString => _privateString;
int get getMagicNumber => new LibFile2().number;
}
//LibFile2.dart
part of SomeLibrary;
class LibFile2 {
int number = 42;
}
Although i am answering very late, but the answer may help new developer.
Always use pubspec.yaml file in your dart package(application/library).
once you run pub get command it will add your local library in the dependencies list in .packages file.
Consider i have following project structure.
To refer to the content of greeting.dart in my main.dart file i should add the library as below
import 'package:my_project_name/greeting.dart'
Once imported we can use the content of greeting.dart file in our main.dart file.
Note: we have not used the actual path as you can see 'lib' directory is missing.
First make sure that's the name which you have mentioned in pubspec.yaml and the file you want to import are sharing the exact same name
example:
pubspec.yaml
name: flutter_wordpress_app
description: flutter wordpress app
...
....
// dirOne/dirTwo/greeting.dart
class FavArticleBloc {
// Your code goes here
}
import 'package:flutter_wordpress_app/dirOne/dirTwo/greeting.dart'
void main(){
var some = new FavArticleBloc();
}
But
in the main.dartyou don't need to specify
import 'package:flutter_wordpress_app
just do like below
import 'dirOne/dirTwo/greeting.dart