Flutter PDF Viewer shows only white pages - flutter

I'm trying to display a PDF file in Flutter which I have previously downloaded from a server.
I have tried both flutter_full_pdf_viewer and advance_pdf_viewer. Both libs show me the correct number of pages, but the pages are all white.
Does anybody have an idea why? makes no difference if I run it on iOS or Android or in emulator or real device.
class _PdfPageState extends State<PdfPage> {
String pathPDF = "";
File file;
PDFDocument doc = null;
#override
void initState() {
super.initState();
WeeklyReportsRepository( userRepository: UserRepository()).loadWeeklyReport(widget.weeklyReport.filename).then((file) {
setDoc(file);
});
}
Future<void> setDoc(File file) async {
var doc1 = await PDFDocument.fromFile(file);
setState(() {
doc = doc1;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
iconTheme: IconThemeData(color: Colors.white),
title: Text(
"Wochenbericht",
style: TextStyle(
color: Colors.white,
),
),
),
body: Container(
color: Theme
.of(context)
.backgroundColor,
child: (doc == null) ? Center(child: CircularProgressIndicator()) :
PDFViewer(document: doc,
scrollDirection: Axis.vertical,),
),
);
}
}

Everything seems right but can you try to view a pdf from your computer or a link and also try to view specific page of the pdf. Package document try load from assets, URL, or file as shown in the link if these ways work you have a problem from server side.

In my case, it is the file name which was in UTF-8 characters. Once I changed the pdf file name to english letters, advance_pdf_viewer can read it with or without .pdf extension.

Make sure the Pdf File is alphabet file, not a pic converted to a pdf.

Related

The Enter/Return key is not being read on a flutter webview using the webview_flutter package

I'm using the Plaid Link Web View for a flutter project i'm working on. I have installed the latest Webview Flutter package. The web view has a text box to search for an institution (see Image 1.0).
Here's where i'm building the webview.
import 'package:ditch/settings.dart';
import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';
class PlaidWebView extends StatefulWidget {
final String linkToken;
const PlaidWebView({
super.key,
required this.linkToken,
});
#override
State<PlaidWebView> createState() => _PlaidWebViewState();
}
class _PlaidWebViewState extends State<PlaidWebView> {
bool isAuthenticated = false;
late String publicToken;
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
body: Container(
margin: const EdgeInsets.fromLTRB(15, 50, 15, 50),
child: WebView(
initialUrl:
'https://cdn.plaid.com/link/v2/stable/link.html?isWebview=true&token=${widget.linkToken}',
javascriptMode: JavascriptMode.unrestricted,
navigationDelegate: (request) {
if (request.url.contains('plaidlink://connected')) {
isAuthenticated = true;
return NavigationDecision.navigate;
} else if (request.url.contains('plaidlink://exit')) {
Navigator.pushReplacement(
context,
MaterialPageRoute(builder: (context) => const Settings()),
);
return NavigationDecision.prevent;
} else {
print(request);
return NavigationDecision.navigate;
}
},
),
),
);
}
}
The Web View registers key inputs and updates the search query succesfully, this is the HTTP redirect when I type let's say "First Platypus Bank"]
flutter: NavigationRequest(url: plaidlink://event?error_code=&error_message=&error_type=&event_name=SEARCH_INSTITUTION&exit_status=&institution_id=&institution_name=&institution_search_query=**first%20platypus%20bank**&...)
However, it does not register when I press the "Enter/Return" key on either a physical keyboard or on the I/O on the iOS simulator, or the keyboard on the phone when I run it from xcode directly on to my device. The results will not update unless I press the enter/return key.
Image 1.0
I have visited the same web view on my browser and the results don't update automatically either but it does update when I press enter on the keyboard.
When I run this to my physical device using flutter this is the console output on the text input (may be unrelated)
2022-11-28 07:49:42.430862-0500 Runner[7222:1919659] Could not signal service com.apple.WebKit.WebContent: 113: Could not find specified service
I've scraped the web for some time and I don't see other with the same issue, anyone have any thoughts?
I resolved this issue by using the the Plaid Flutter plugin it does a really great job at natively integrating with both android and iOS and has a bunch of useful methods. Would highly advise you go this route.

Populate data Map before opening screen

I am trying to get data from an API to populate a Map and then display the screen to show the data from the Map
My getter is as follows:
Map data = {};
Future getData(symbol) async {
final response = await http.get(Uri.parse(
"https://financialmodelingprep.com/api/v3/quote/" +
symbol +
"?apikey=${api_key}"));
if (response.statusCode == 200) {
final jsonResponse = json.decode(response.body);
// print(jsonResponse);
data = jsonResponse[0];
print(data);
}
}
For starters, I am trying to display the symbol and name from the data in the API:
void initState() {
getData(data['symbol']);
super.initState();
}
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
toolbarHeight: 80,
centerTitle: true,
backgroundColor: Colors.white,
automaticallyImplyLeading: true,
title: Column(
children: [
Text("Symbol", style: TextStyle(color: Colors.black)),
Text("Name", style: TextStyle(color: Colors.black))
],
),
),
);
}
After opening one screen successfully, on opening the next screen, I get the error:
type 'Null' is not a subtype of type 'String'
Can anyone suggest steps to deal with the issue? Any help would be appreciated.
Thanks
So there are a few things that could have gone wrong in the code that you've provided. The getData function is an asynchronous function marked as async and needs to be inside an asynchronous context to actually work properly. What is probably happening in this case is that the data doesn't even have enough time to get downloaded before your widget gets loaded on the screen.
What you need to do is to use FutureBuilder by having a look at the documentation and the introduction video which is in the link I've provided for you.
The FutureBuilder will be able to execute a Future<T> and inside its builder you will be able to retrieve an AsyncSnapshot of either your Future's data or an error.

Load pdf file from url

I have this url from server
https://xxxx.pdf20200529". How can I load it as pdf in my flutter app?
I use this plugin, but nothing happened.
Code
OpenFile.open(value); // value is https://xxxx.pdf20200529
Edit
generatePDF(dynamic value) async {
final filename = value.substring(value.lastIndexOf("/") + 1);
var request = await HttpClient().getUrl(Uri.parse(value));
var response = await request.close();
var bytes = await consolidateHttpClientResponseBytes(response);
String dir = (await getApplicationDocumentsDirectory()).path;
File file = new File('$dir/$filename');
await file.writeAsBytes(bytes);
OpenFile.open(file.path);
}
Opening PDF's in Flutter is pretty fiddly. So I suggest you use a package. flutter_full_pdf_viewer works pretty well and is easy to use, but there are others out there.
https://pub.dev/packages/flutter_full_pdf_viewer
This will be your PDF Screen:
class PDFScreen extends StatelessWidget {
String pathPDF = "";
PDFScreen(this.pathPDF);
#override
Widget build(BuildContext context) {
return PDFViewerScaffold(
appBar: AppBar(
title: Text("Document"),
actions: <Widget>[
IconButton(
icon: Icon(Icons.share),
onPressed: () {},
),
],
),
path: pathPDF);
}
}
Navigate to it like this. Make sure to pass the local path to the screen.:
Navigator.push(context, MaterialPageRoute(builder: (context) => PDFScreen(pathPDF)),
Have you tried url_launcher 5.4.10
As far as I know it opens pdfs as well.
I miss .pdf in this line
File file = new File('$dir/$filename.pdf');
After add .pdf, all PDF viewer able to open.

Flutter app crash on release mode reading PDF

I have a pdf reader in my app, with this function I get de pdf from URL and save the file in local path
Future<File> getFileFromUrl(String url) async {
try {
var data = await http.get(url);
var bytes = data.bodyBytes;
var dir = await getApplicationSupportDirectory();
File file = File("${dir.path}/some.pdf");
File urlFile = await file.writeAsBytes(bytes);
return urlFile;
} catch (e) {
throw Exception("Error opening url file");
}
}
After this process, I call a class to show this PDF in a new route
import 'package:flutter/material.dart';
import 'package:flutter_pdfview/flutter_pdfview.dart';
class CustomPdfView extends StatefulWidget {
final String title;
final String urlPdf;
CustomPdfView(
this.title,
this.urlPdf
);
#override
_CustomPdfViewState createState() => _CustomPdfViewState();
}
class _CustomPdfViewState extends State<CustomPdfView> {
//int _totalPages = 0;
//int _currentPage = 0;
bool pdfReady = false;
//PDFViewController _pdfViewController;
#override
Widget build(BuildContext context) {
print('Aqui entra antes: ${widget.urlPdf}');
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Stack(
children: <Widget>[
PDFView(
filePath: widget.urlPdf,
autoSpacing: true,
enableSwipe: true,
pageSnap: true,
swipeHorizontal: true,
nightMode: false,
onError: (e) {
print("error $e");
},
onRender: (_pages) {
setState(() {
//_totalPages = _pages;
pdfReady = true;
});
},
onViewCreated: (PDFViewController vc) {
//_pdfViewController = vc;
},
onPageChanged: (int page, int total) {
setState(() {});
},
onPageError: (page, e) {},
),
!pdfReady
? Center(
child: CircularProgressIndicator(),
)
: Offstage()
],
),
);
}
}
All works fine in debug mode, but when I run my app on release, the app crashes in CustomPdfView.
I don't know what is the error, I already added, STORAGE permissions in my /app/src/main/AndroidManifest.xml
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
And I don't know how can I get error line in the console, because the app is running on release.
same issue.....
i fixed that one
clean your project after build your apk
if still problem persist
than try these commands
flutter build apk --no-shrink
flutter build apk --release --split-per-abi --no-shrink
your way of reading pdf is very nice, here you try to launch pdf in your app,
i almost did the same way.
where i was getting Uint8List from url of pdf, and reading it in my app using printing 5.9.3
but when size of pdf or number of pages more then my app keep getting crash, and also before launching pdf in my app i need to save it locally as you did.
so, to solve this i just need to use flutter_cached_pdfview: ^0.4.1
using this flutter_cached_pdfview i don't need to save pdf locally, just pass the url of pdf and you can launch it in your app without worrying about size of pdf or number of pages in pdf.
i just launch using a button and i pass url of pdf
// navigate in another screen
onPressed: () => nextScreen(
PDFViewerPage(
url: widget.magazineModel.fileUrl,
title: widget.magazineModel.name,
),
),
and MyPdfViewerPage is below
class PDFViewerPage extends StatelessWidget {
final String url;
final String title;
const PDFViewerPage({
Key? key,
required this.title,
required this.url,
}) : super(key: key);
#override
Widget build(BuildContext context) {
debugPrint('url : $url');
return Scaffold(
appBar: AppBar(
leading: const LeadingIconComponent(), // for popScreen()
title: Text(title),
),
body: const PDF().cachedFromUrl(
Uri.parse(url).toString(),
placeholder: (progress) => const LoadingComponent(),
errorWidget: (error) {
debugPrint('errorInOprnPDF : $error');
return const ErrorPageComponent(
title: 'File Not Exist',
content: "This file is either removed or not valid",
image: "assets/images/empty_data_component/new data not found.svg",
);
},
),
);
}
}

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