Adding default files to local storage in Flutter - flutter

TLDR: I understand how to create a new file via Dart and path provider, but I don't know how to get a pre-existing file into the Android/Apple file system.
I'm building this app which works a bit with string manipulation. Ideally, I want it reading strings from a pre-existing CSV file which I'm getting from a client, then manipulating the data to create more CSV files. I found packages for both CSV and Paths. What I don't know is how to get my CSV in there.
As of now I have this file called test.csv in my app's root directory. I tried to access it through my main.dart by using File f = File("$_localPath/test.csv"). The file was nowhere to be found. I then went into the phone's memory using Android Studio, and found the local storage path of the app. My test.csv file was nowhere to be seen. My guess right now is that at compilation, that CSV file becomes garbage machine code. So how can I get it intact into the device's local memory?
I don't want to get the file from the internet because I'm hoping the user can boot up the app for the first time in any setting and be able to have its full functionality.

I just tested this code example and it works on all platforms.
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:path_provider/path_provider.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({super.key});
#override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
String _fileContent = '';
final TextEditingController _controller = TextEditingController();
#override
initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) {
readFile();
});
}
Future<String> getFilePath() async {
Directory appDocumentsDirectory =
await getApplicationDocumentsDirectory(); // 1
String appDocumentsPath = appDocumentsDirectory.path;
String filePath = '$appDocumentsPath/file.csv';
return filePath;
}
void saveFile() async {
File file = File(await getFilePath());
if (mounted) {
file.writeAsString(_controller.text);
setState(() {
_fileContent = _controller.text;
});
_controller.text = '';
}
}
void readFile() async {
File file = File(await getFilePath());
final fileContent = await file.readAsString();
if (mounted) {
setState(() {
_fileContent = fileContent;
});
}
}
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: const Text('Saving CSV file')),
body: Padding(
padding: const EdgeInsets.all(16),
child: Column(
children: [
Text('Current content = $_fileContent'),
TextField(
controller: _controller,
),
TextButton(
onPressed: saveFile,
child: const Text('Press to save file'),
),
],
),
),
),
);
}
}
This code creates the file and sets a content into it. Then, after restarting the app, it tries to find the file and receive its content. After that it shows the content inside a Text widget.
I used this article for making this example. Hope it will help:)

Related

how to view pptx file inside my app in flutter

I list all pptx files from storage now I want to display these files inside my app using a file path. I used different packages like power file view, flutter file reader. but engine load failed all time so i need a material related opening pptx files inside my flutter app
Add this in your pubspec.yaml
pdftron_flutter:
git:
url: git://github.com/PDFTron/pdftron-flutter.git
main.dart
import 'package:flutter/material.dart';
import 'dart:async';
import 'package:flutter/services.dart';
import 'package:pdftron_flutter/pdftron_flutter.dart';
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
#override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
String _version = 'Unknown';
#override
void initState() {
super.initState();
initPlatformState();
PdftronFlutter.openDocument("https://pdftron.s3.amazonaws.com/downloads/pdfref.pdf");
}
// Platform messages are asynchronous, so we initialize via an async method.
Future<void> initPlatformState() async {
String version;
// Platform messages may fail, so we use a try/catch PlatformException.
try {
PdftronFlutter.initialize();
version = await PdftronFlutter.version;
} on PlatformException {
version = 'Failed to get platform version.';
}
// If the widget was removed from the tree while the asynchronous platform
// message was in flight, we want to discard the reply rather than calling
// setState to update our non-existent appearance.
if (!mounted) return;
setState(() {
_version = version;
});
}
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('PDFTron flutter app'),
),
body: Center(
child: Text('Running on: $_version\n'),
),
),
);
}
}
For more help read this blog

How do I create a "fake" dart:io File from MemoryFileSystem bytes?

I have the in-memory bytes of a decrypt epub file, but the package that I want to open this epub file with only accepts dart:io File objects.
I don't want to create real local file => just for security
Is there a way to create a "fake" dart:io File, simply wrapping my in-memory bytes, so that I can pass this "fake" File to the package?
I'm using vocsy_epub_viewer package to open epub files
filePath should be a local file
import 'package:archive/archive.dart';
import 'package:flutter/material.dart';
import 'package:vocsy_epub_viewer/epub_viewer.dart';
import 'package:file_picker/file_picker.dart';
import 'package:path_provider/path_provider.dart';
import 'package:encrypt/encrypt.dart' as en;
import 'dart:io';
import 'package:cross_file/cross_file.dart';
import 'package:file/memory.dart';
import 'package:file/file.dart' as F;
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Ebook(),
);
}
}
class Ebook extends StatefulWidget {
#override
State<Ebook> createState() => _EbookState();
}
class _EbookState extends State<Ebook> {
Directory? _temp;
String? path;
#override
void initState() {
address();
super.initState();
}
Future decodeEpub(String path) async {
final bytes = await File(path).readAsBytes();
Archive archive =
await ZipDecoder().decodeBytes(bytes, password: '7web', verify: true);
final data = await archive.first.content;
final key = en.Key.fromUtf8('qwertyuiopasdfghjklmnbvcxzasdfgh');
final iv = en.IV.fromLength(16);
final decrypted = await en.AES(key).decrypt(en.Encrypted(data), iv: iv);
// XFile file = await XFile.fromData(decrypted,name:'2.epub',path:"${_appDocumentsDirectory!.path}/2.epub" );
// File file1= await File(file.path).create(recursive: true);
// File file = MemoryFileSystem().file('${temp!.path}/2.epub')..create(recursive: true)
// ..writeAsBytesSync(decrypted);
File file = await File('${_temp!.path}/2.epub').writeAsBytes(decrypted); // it must be change ******
print(file.path);
return file.path;
}
void address() async {
final temp = await getTemporaryDirectory();
setState(() {
_temp = temp;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(
onPressed: () async {
FilePickerResult? result =
await FilePicker.platform.pickFiles();
if (result != null) {
File file = File(result.files.single.path!);
path = await decodeEpub(file.path);
print('?= $path , ${file.path}');
} else {
print('cancel');
}
},
child: Text('add File')),
ElevatedButton(
onPressed: () {
EpubViewer.setConfig(
themeColor: Theme.of(context).primaryColor,
identifier: "iosBook",
scrollDirection: EpubScrollDirection.ALLDIRECTIONS,
allowSharing: true,
enableTts: true,
nightMode: false);
EpubViewer.open(path!, lastLocation: EpubLocator());
},
child: Text("open"),
),
],
),
),
);
}
}
I don't want to create real local file => just for security
This is not actually true because EPUBs are structured as a zip file and folioreader, the framework used behind the vocsy_epub_viewer, will "unzip" the file to a temp folder (or one predefined). So, in the end, it's not going to be secure anyway.
Just extract the EPUB to the temp folder from path_provider and remove it afterwards. Otherwise, you're going to need a new framework to read EPUBs that don't have this behaviour or even customize the vocsy_epub_viewer/folioreader sources yourself to make it secure.

Undefined name 'FlutterAbsolutePath'

I am developing a flutter mobile application where I need to upload multiple images through an API. Now I completed the part where pick images from the gallery. Next step is to upload the images. To do that I need the image path. I know that image path can be get by using the below code line but it keep saying that Undefined name 'FlutterAbsolutePath' what is the reason how to fix this issue. I am using multi-image-picker package.
final filePath =
await FlutterAbsolutePath.getAbsolutePath(image.identifier);
It would be really nice if you could provide us with some more information or even a code sample. In case you are using this package, I would strongly advice you to change it to one that is not discontinued (take a look into this one: image_picker; you can select multiple images at once with this one too).
Until further information is provided you can take a look over the following code that uses the image_picker:
After following the installation steps from the documentation you can get images using the next method:
Future<void> getImages() async {
ImagePicker imagePicker = ImagePicker();
List<XFile>? images = await imagePicker.pickMultiImage();
if ((images ?? []).isNotEmpty) {
//get the path of the first image from the select images
String imagePath = images?.first.path ?? '';
//get the content of the first image from the select images as bytes
Uint8List? imageAsBytes = await images?.first.readAsBytes();
//get the content of the first image from the select images as a String based on a given encoding
String? imageAsString = await images?.first.readAsString();
}
}
I hope that I helped you a little bit. Happy coding! :)
Later edit:
Here is a very basic Flutter app that picks an image with multi-picker, creates a temp file for which we know the path and displays the temp file in order to show that the temp file was correctly displayed.
For you, what's of most interest is getFile() method which takes care of creating the temp file that is 1:1 with picked image(s).
For creating the temp file I used: path_provider also take a look into the following: Read and write files
For permission handling: permission_handler
I still strongly suggest that you use other package for image picking as this one is discontinued :).
import 'dart:io';
import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:multi_image_picker/multi_image_picker.dart';
import 'package:path_provider/path_provider.dart';
import 'package:permission_handler/permission_handler.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const HomePage(),
);
}
}
Future<File?> getFile() async {
List<Asset> images = await MultiImagePicker.pickImages(maxImages: 100);
if (images.isNotEmpty) {
ByteData bytesData = await images.first.getByteData();
List<int> bytes = bytesData.buffer
.asUint8List(bytesData.offsetInBytes, bytesData.lengthInBytes)
.cast<int>();
//get the extension jpeg, png, jpg
String extension = (images.first.name ?? '').split('.').last;
//get path to the temporaryDirector
final Directory directory = await getTemporaryDirectory();
//get the path to the chosen directory
String directoryPath = directory.path;
//create a temporary file to the specified path
//you can use the path to this file for the API
File file = File('$directoryPath/myImage.$extension');
//write the bytes to the image
file.writeAsBytesSync(bytes, mode: FileMode.write);
//just for path: file.path -> will return a String with the path
return file;
}
return null;
}
class HomePage extends StatefulWidget {
const HomePage({Key? key}) : super(key: key);
#override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
File? file;
#override
Widget build(BuildContext context) {
return Container(
color: Colors.amber,
child: Column(
children: [
const SizedBox(
height: 50,
),
Center(
child: TextButton(
child: const Text('Pick an image'),
onPressed: () async {
await Permission.accessMediaLocation.request();
file = await getFile();
setState(() {});
},
),
),
const SizedBox(
height: 50,
),
file != null
? Image.file(
file!,
height: 200,
width: 200,
)
: Container(),
],
),
);
}
}

Is it possible to load PDF File From Google Drive using flutter_plugin_pdf_viewer?

I had tried but it doesn't load pdf file. This is My Code
import 'package:flutter/material.dart';
import 'package:flutter_plugin_pdf_viewer/flutter_plugin_pdf_viewer.dart';
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
#override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
bool _isLoading = true;
PDFDocument document;
#override
void initState() {
super.initState();
loadDocument();
}
loadDocument() async {
document = await PDFDocument.fromUrl('https://drive.google.com/drive/u/0/folders/1ei6916qmZ34LZECNf5e0DlvB7EJqxqz8');
setState(() => _isLoading = false);
}
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('PDF FILE'),
),
body: Center(`enter code here`
child: _isLoading
? Center(child: CircularProgressIndicator())
: PDFViewer(document: document)),
),
);
}
}
It seems like the id in your link (https://drive.google.com/drive/u/0/folders/1ei6916qmZ34LZECNf5e0DlvB7EJqxqz8) is a folder id.
To get your link, open the file
in a new window and copy the Url into your code.
If the link doesn't work, try the following link format in which you insert the file Id from the Url you got previously.
https://drive.google.com/file/d/fileId/
For this you need to be autenticated user of Google.
And after successfully login
Use these api to ge the drive data:
https://www.googleapis.com/drive/v2/files
and also you need to pass the token over the header with Authorization key:
"Authorization" = "Bearer " + token
or simply you can create a public link of your file, than copy url and use it.

flutter download an Image from url

I'm trying to load image from server using networkimage() and I want to download the same once it is loaded.. can anyone suggest me some ideas.
CircleAvatar(
backgroundImage: NetworkImage(url),
maxRadius: 15.0,
);
Here I'm loading image from my server. I want to save to the image to particular path after the image is loaded.
I recently battled this, and decided to solve it without plugins. I hope it helps someone.
The below program downloads a picture from the web, stores it in the device's local path, and then displays it when run. (note, it does not work for flutter web because you don't have access to the local file storage on that platform. Instead you would have to save the image to a local database using a plugin like sqflite, or hive from pub.dev.) Here's the code:
import 'package:flutter/material.dart';
import 'package:http/http.dart' show get;
import 'dart:io';
import 'package:path_provider/path_provider.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Test Image',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Test Image'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
#override
initState() {
_asyncMethod();
super.initState();
}
_asyncMethod() async {
//comment out the next two lines to prevent the device from getting
// the image from the web in order to prove that the picture is
// coming from the device instead of the web.
var url = "https://www.tottus.cl/static/img/productos/20104355_2.jpg"; // <-- 1
var response = await get(url); // <--2
var documentDirectory = await getApplicationDocumentsDirectory();
var firstPath = documentDirectory.path + "/images";
var filePathAndName = documentDirectory.path + '/images/pic.jpg';
//comment out the next three lines to prevent the image from being saved
//to the device to show that it's coming from the internet
await Directory(firstPath).create(recursive: true); // <-- 1
File file2 = new File(filePathAndName); // <-- 2
file2.writeAsBytesSync(response.bodyBytes); // <-- 3
setState(() {
imageData = filePathAndName;
dataLoaded = true;
});
}
String imageData;
bool dataLoaded = false;
#override
Widget build(BuildContext context) {
if (dataLoaded) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Image.file(File(imageData), width: 600.0, height: 290.0)
],
),
),
);
} else {
return CircularProgressIndicator(
backgroundColor: Colors.cyan,
strokeWidth: 5,
);
}
}
}
pubspec.yaml file:
http: ^0.12.1
path_provider: ^1.6.5
flutter version: 1.20.0-3.0.pre.112
dart version 2.9.0-19.0.dev
I recommend image_downloader.
For ios, image is saved in Photo Library.
For Android, image is saved in Environment.DIRECTORY_DOWNLOADS or specified location. By calling inExternalFilesDir(), specification of permission becomes unnecessary.
By callback(), you can get progress status.
The following is the simplest example. It will be saved.
await ImageDownloader.downloadImage(url);
I used image_downloader.
Use await ImageDownloader.downloadImage("url") of image_downloader package's method to download image using it's url.
Note : above method will return value as follows :-
imageId of the saved image if saving succeeded.
null if not been granted permission.
for this you have to ask for storage permission, just add following line into android manifest file :
uses-permission
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
Otherwise it is a PlatformException.
I tried many solution, but this is simplest solution for my... Just try it
STEP - 1
Add this package in your pubspec.yaml file
dependencies:
image_downloader: ^0.20.1
STEP - 2
Add this in your dart file
import 'package:image_downloader/image_downloader.dart';
STEP - 3
Write this code on press download button
ColButton(
title: 'Download',
icon: Icons.file_download,
onTap: () async {
try {
showLoadingDialog(context);
// Saved with this method.
var imageId =
await ImageDownloader.downloadImage("https://raw.githubusercontent.com/wiki/ko2ic/image_downloader/images/bigsize.jpg");
if (imageId == null) {
return;
}
// Below is a method of obtaining saved image information.
var fileName = await ImageDownloader.findName(imageId);
var path = await ImageDownloader.findPath(imageId);
var size = await ImageDownloader.findByteSize(imageId);
var mimeType = await ImageDownloader.findMimeType(imageId);
Navigator.pop(context);
showToast('Image downloaded.');
} on PlatformException catch (error) {
print(error);
}
},
),
I use this plugin to save image in the phone using an URL
https://pub.dartlang.org/packages/image_picker_saver
For more advanced handling of Image/File downloads, you can consider the flutter_downloader package.
Some of the features that I like are :
Shows OS level download progress
can track all downloads
Has notification