Flutter open_file.dart not opening pdf file - flutter

Im noob in flutter, i try to recreate this proses,create, save then launch pdf, this app has 2 dart file:
1. main.dart
import 'package:flutter/material.dart';
import 'package:syncfusion_flutter_pdf/pdf.dart';
import 'mobile.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {...}
class MyHomePage extends StatefulWidget {...}
class _MyHomePageState extends State<MyHomePage> {
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: ElevatedButton(
child: Text('Cliick Me'),
onPressed: _createPDF,
),
),
);
}
Future<void> _createPDF() async {
PdfDocument document = PdfDocument();
final page = document.pages.add();
page.graphics.drawString(
'welcome',
PdfStandardFont(PdfFontFamily.helvetica, 30)
);
List<int> bytes = document.save();
document.dispose();
//FileSaveHelper.saveAndLaunchFile(bytes, 'Outfile.pdf');
saveAndLaunchFile(bytes, 'Outfile.pdf');
}
2.mobile.dart
import 'dart:io' as io;
import 'dart:io';
import 'package:open_file/open_file.dart';
import 'package:path_provider/path_provider.dart';
Future<void> saveAndLaunchFile(List<int> bytes, String fileName) async {
try {
final path = (await getExternalStorageDirectory())!.path;
print('filepath : $path/$fileName');
String data='empty';
print('data pos1= $data');
data = (await io.File('$path/$fileName').exists()).toString();
final file = File('$path/$fileName');
await file.writeAsBytes(
bytes,
flush: true
);
print('data pos2= $data');
OpenFile.open('$path/$fileName');
print('done');
}
catch (e) {
print('error : $e');
}
}
Now when I press 'click me', it does nothing, it supposed to show 'welcome' String from main.dart
the output from mobile.dart are bellow:
Syncing files to device Android SDK built for x86...
Reloaded 1 of 955 libraries in 310ms.
I/flutter ( 3688): filepath : `/storage/emulated/0/Android/data/com.cg2.my_first_try/files/Outfile.pdf`
I/flutter ( 3688): data pos1= empty
I/flutter ( 3688): data pos2= true
I/flutter ( 3688): done
The funny things, the day before, when i first install android studio, flutter and run this program, it was working. Then I updated dependency on yaml file, then on this perticular line on mobile.dart, asking
final path = (await getExternalStorageDirectory()).path; generate error ....potentialy null.
so i change into :
final path = (await getExternalStorageDirectory())!.path;
lastly, iam using ubuntu 20.04, i just need to understand whats going on, is it androdi studio or emulator problem, or do linux need permision to getExternalStorageDirectory. Thanks.

Its seem ths java version that causing this. after googling, it turns out openJdk16 has campatible issues, messing up gradle creation. So i downgrade to 11, so far looks good.

To use jdk 16 you should upgrade to:
android/gradle/wrapper/gradle-wrapper.properties
distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.2-all.zip
android/build.gradle
classpath 'com.android.tools.build:gradle:7.0.1'
my jdk
java 16.0.1 2021-04-20
Java(TM) SE Runtime Environment (build 16.0.1+9-24)
Java HotSpot(TM) 64-Bit Server VM (build 16.0.1+9-24, mixed mode, sharing)

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

About PDF file opening and downloading flutter web in web hosting

I am trying to generate Pdf in flutter with pdf package in flutter Web.
while doing so I found a solution for flutter web with this code ..
Uint8List bytes = await pdf.save() ;
final blob = html.Blob([bytes], 'application/pdf');
final url = html.Url.createObjectUrlFromBlob(blob);
html.window.open(url, "_blank");
html.Url.revokeObjectUrl(url);
this code worked fine in local host but is not running in web hosting . please help
My first answer was deleted, so I'll repost it.
To download files look this one:
https://stackoverflow.com/a/60614367/18386517.
If you want to just open PDFs files inside your app try the pdfx package. Here is an example:
import 'dart:async';
import 'dart:typed_data';
import 'package:pdfx/pdfx.dart';
import 'package:flutter/material.dart';
class PdfLabPage extends StatefulWidget {
final String name;
final FutureOr<Uint8List> content;
const PdfLabPage({Key? key, required this.name, required this.content}) : super(key: key);
#override
State<PdfLabPage> createState() => _PdfLabPageState();
}
class _PdfLabPageState extends State<PdfLabPage> {
late PdfControllerPinch pdfController;
#override
void initState() {
pdfController = PdfControllerPinch(
document: PdfDocument.openData(widget.content)
);
super.initState();
}
#override
void dispose() {
pdfController.dispose();
super.dispose();
}
Widget pdfView() => PdfViewPinch(
controller: pdfController ,
onDocumentLoaded: (msg) {print(msg.toString());},
onDocumentError: (error) { print(error.toString());}
);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.name),
),
body:
Center(
child: pdfView(),
),
);
}
}
I got the content of the PDF file from the web using:
var url = "..."
final file = await http.get(Uri.parse(url));
final content = file.bodyBytes;
But you can load from assets (Android, Ios, MacOs, Web):
final document = await PdfDocument.openAsset('assets/sample.pdf')
From file (Android, Ios, MacOs):
final document = await PdfDocument.openFile('path/to/file/on/device')
From data (Android, Ios, MacOs, Web):
final document = await PdfDocument.openData((FutureOr<Uint8List>) data)

How can I download an image from the network and save it in a locally directory?

I'm trying to download an image from the network and save it locally in the Downloads folder of a computer. I need to achieve that for flutter web, I'm not sure how to do it.
I found some questions related to how to achieve download and save a file or an image for android and IOS, such as Flutter save a network image to local directory. I also took a look at How do I read and write image file locally for Flutter Web?. However, I don't see how those answers can help me.
I think that for IOS and Flutter I can use the following function without getting any error, but I don't know where the files are being saved in my emulator:
void _downloadAndSavePhoto() async {
var response = await http.get(Uri.parse(imageUrl));
try {
Directory tempDir = await getTemporaryDirectory();
String tempPath = tempDir.path;
File file = File('$tempPath/$name.jpeg');
file.writeAsBytesSync(response.bodyBytes);
} catch (e) {
print(e.toString());
}
}
However, when I try the above function for flutter web (using a chrome simulator) I get the following error:
MissingPluginException(No implementation found for method getTemporaryDirectory on channel plugins.flutter.io/path_provider)
I will be more than happy if someone knows a way to do it or have some suggestions to implement that functionality.
Thanks in advance!
To achieve this I would suggest you first to add the universal_html package to your pubspec.yaml because in the newer versions of Flutter you will get warnings for importing dart:html.
In pubspec.yaml:
dependencies:
flutter:
sdk: flutter
http: ^0.13.1 // add http
universal_html: ^2.0.8 // add universal_html
I created a fully working example Flutter web app, you can try it, but the only thing that interests you is the downloadImage function.
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
// if you don't add universal_html to your dependencies you should
// write import 'dart:html' as html; instead
import 'package:universal_html/html.dart' as html;
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final imageUrls = <String>[
'https://images.pexels.com/photos/208745/pexels-photo-208745.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940',
'https://images.pexels.com/photos/1470707/pexels-photo-1470707.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940',
'https://images.pexels.com/photos/2671089/pexels-photo-2671089.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940',
'https://images.pexels.com/photos/2670273/pexels-photo-2670273.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940',
];
#override
Widget build(BuildContext context) {
return Scaffold(
body: GridView.count(
crossAxisCount: 3,
children: imageUrls
.map(
(imageUrl) => ImageCard(imageUrl: imageUrl),
)
.toList(),
),
);
}
}
class ImageCard extends StatefulWidget {
#override
_ImageCardState createState() => _ImageCardState();
final String imageUrl;
ImageCard({
#required this.imageUrl,
});
}
class _ImageCardState extends State<ImageCard> {
Future<void> downloadImage(String imageUrl) async {
try {
// first we make a request to the url like you did
// in the android and ios version
final http.Response r = await http.get(
Uri.parse(imageUrl),
);
// we get the bytes from the body
final data = r.bodyBytes;
// and encode them to base64
final base64data = base64Encode(data);
// then we create and AnchorElement with the html package
final a = html.AnchorElement(href: 'data:image/jpeg;base64,$base64data');
// set the name of the file we want the image to get
// downloaded to
a.download = 'download.jpg';
// and we click the AnchorElement which downloads the image
a.click();
// finally we remove the AnchorElement
a.remove();
} catch (e) {
print(e);
}
}
#override
Widget build(BuildContext context) {
return InkWell(
onTap: () => downloadImage(widget.imageUrl),
child: Card(
child: Image.network(
widget.imageUrl,
fit: BoxFit.cover,
),
),
);
}
}

Flutter String Problem in equality comparison

Problem
This is my code in Flutter. As you can see, on line 33 the value of type is 'ngo' as is printed on line 34 using print statement. But, in the if block, the correct block does not get executed. I can't understand what's the issue. Please help.
main.dart
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/services.dart';
import 'package:xyz/homescreen.dart';
import 'package:xyz/ngo_details.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
Future main() async {
WidgetsFlutterBinding.ensureInitialized();
await SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitUp,
]);
await SystemChrome.setEnabledSystemUIOverlays([]);
var _homeWidget = await checkUserLogin();
//Timer(Duration(seconds: 3), () {runApp(MyApp(rootWidget: _homeWidget));});
runApp(MyApp(rootWidget: _homeWidget));
}
Future<Widget> checkUserLogin() async {
final firestoreInstance = Firestore.instance;
final curUser = await FirebaseAuth.instance.currentUser();
if (curUser != null) {
firestoreInstance
.collection('users')
.document(curUser.uid)
.get()
.then((value) {
if (!value.exists) {
FirebaseAuth.instance.signOut();
return HomeScreen();
} else {
String type = value.data['type'];
print(type);
if (type == 'ngo') {
return NGODetailsScreen(user: curUser);
}
else if (type =='user') {
return NGODetailsScreen(user: curUser);
}
}
print('no cases selected');
return Container(color: Colors.yellow,);
});
} else {
return HomeScreen();
}
print('return outer');
return Container(color: Colors.red,);
}
class MyApp extends StatelessWidget {
final firestoreInstance = Firestore.instance;
final rootWidget;
MyApp({this.rootWidget});
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Charity for Everyone',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: rootWidget,
);
}
}
Output :
Expected results: NGODetailsScreen should be called after outputting 'ngo' on line 34
Actual results: Container with red background is executed even when line 34 outputs 'ngo'
Logs
PS D:\flutter\xyz> flutter run
Launching lib\main.dart on Redmi Note 4 in debug mode...
Running Gradle task 'assembleDebug'...
Running Gradle task 'assembleDebug'... Done 16.1s
√ Built build\app\outputs\apk\debug\app-debug.apk.
I/flutter (18833): return outer
W/DynamiteModule(18833): Local module descriptor class for providerinstaller not found.
I/DynamiteModule(18833): Considering local module providerinstaller:0 and remote module providerinstaller:0
W/ProviderInstaller(18833): Failed to load providerinstaller module: No acceptable module found. Local version is 0 and remote version is 0.
W/ResourceType(18833): No package identifier when getting name for resource number 0x00000000
V/NativeCrypto(18833): Registering com/google/android/gms/org/conscrypt/NativeCrypto's 286 native methods...
D/NetworkSecurityConfig(18833): No Network Security Config specified, using platform default
I/ProviderInstaller(18833): Installed default security provider GmsCore_OpenSSL
W/art (18833): Before Android 4.1, method double java.util.concurrent.ThreadLocalRandom.internalNextDouble(double, double) would have incorrectly overridden the package-private method
in java.util.Random
W/art (18833): Before Android 4.1, method int java.util.concurrent.ThreadLocalRandom.internalNextInt(int, int) would have incorrectly overridden the package-private method in java.util.Random
W/art (18833): Before Android 4.1, method long java.util.concurrent.ThreadLocalRandom.internalNextLong(long, long) would have incorrectly overridden the package-private method in java.util.Random
Syncing files to device Redmi Note 4... 1,216ms
Flutter run key commands.
r Hot reload.
R Hot restart.
h Repeat this help message.
d Detach (terminate "flutter run" but leave application running).
c Clear the screen
q Quit (terminate the application on the device).
An Observatory debugger and profiler on Redmi Note 4 is available at: http://127.0.0.1:65500/s-e-dD_DnYk=/
I/flutter (18833): ngo
Application finished.
D:\flutter\xyz>flutter analyze
Analyzing xyz...
No issues found! (ran in 22.5s)
Thanks #jamesdlin for pointing out the solution.
Basically I changed
firestoreInstance
.collection('users')
.document(curUser.uid)
.get()
.then((value)
to
var value = await firestoreInstance
.collection('users')
.document(curUser.uid)
.get();
and it worked.

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