5

My goal is to download a file from an API server (pdf file in this case) and then I want to load that pdf and show it on the UI. I am using flutter_pdfview and I am following this tutorial how to implement it . Firstly, permissions: In my android/app/build.gradle targetSdkVersion is 29 as well as compileSdkVersion. In android/app/main/AndroidManifest.xml i wrote bellow <application ... android:requestLegacyExternalStorage="true"> and I have added in the same folder these permissions.

<uses-permission android:name="android.permission.INTERNET"/> 
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

Fetch request:

Future<File> getFile(String id) async {
    _isLoading = true;
    notifyListeners();
    var headers = {
      'Authorization': 'JWT ${_authenticatedUser.token}',
      'Content-Type': 'application/x-www-form-urlencoded',
      'Accept': 'application/json',
    };
    try {
      final http.Response response = await http.get(
          'api-host/pdf',
          headers: headers);
      var bytes = response.bodyBytes;
      var dir = await getExternalStorageDirectory();// Option 1
      //var dir = awiat getApplicationDocumentsDirectory(); //Option 2
      File file = File("${dir.path}/mypdfonline.pdf");
      File urlFile = await file.writeAsBytes(bytes);
      if (response.statusCode != 200) {
        _isLoading = false;
        notifyListeners();
        throw Exception('get error: statusCode= ${response.headers}');
      }
      _isLoading = false;
      notifyListeners();
      return urlFile;
    } catch (e) {
      _isLoading = false;
      notifyListeners();
      throw Exception("Error opening url file");
    }
  }

With option 1, I have found pdf file inside my internal storage, but it still gives me an error. With Option 2 like the guy did it, i couldn't find it anywhere on my device. Also, I have granted storage access manually in my phone but that also didn't help.


class ImagePreview extends StatefulWidget {
  final MainModel model;
  final String id;
  ImagePreview(this.model, this.id);
  @override
  State<StatefulWidget> createState() {
    return _ImagePreviewState();
  }
}

class _ImagePreviewState extends State<ImagePreview> {
  String urlPDFPath = "";
  int _totalPages = 0;
  int _currentPage = 0;
  bool pdfReady = false;
  PDFViewController _pdfViewController;
  @override
  void initState() {
    super.initState();
    widget.model.getFile(widget.id).then((value) {
      setState(() {
        urlPDFPath = value.path;
        print(urlPDFPath);
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('PDF Preview'),
      ),
      body: Stack(
        children: <Widget>[
          PDFView(
            filePath: urlPDFPath,
            autoSpacing: true,
            enableSwipe: true,
            pageSnap: true,
            swipeHorizontal: true,
            nightMode: false,
            onError: (e) {
              print(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(),
        ],
      ),
      floatingActionButton: Row(
        mainAxisAlignment: MainAxisAlignment.end,
        children: <Widget>[
          _currentPage > 0
              ? FloatingActionButton.extended(
                  backgroundColor: Colors.red,
                  label: Text("Go to ${_currentPage - 1}"),
                  onPressed: () {
                    _currentPage -= 1;
                    _pdfViewController.setPage(_currentPage);
                  },
                )
              : Offstage(),
          _currentPage + 1 < _totalPages
              ? FloatingActionButton.extended(
                  backgroundColor: Colors.green,
                  label: Text("Go to ${_currentPage + 1}"),
                  onPressed: () {
                    _currentPage += 1;
                    _pdfViewController.setPage(_currentPage);
                  },
                )
              : Offstage(),
        ],
      ),
    );
  }
}
halfer
  • 19,824
  • 17
  • 99
  • 186
kmtz
  • 484
  • 4
  • 14

1 Answers1

0

You need storage permission access to write data on the device storage. You can use permission_handler plugin to manage storage permission.

// Check for existing storage permission
if (await Permission. storage.request().isGranted) {
  // Run after verifying storage permission
}
Omatt
  • 8,564
  • 2
  • 42
  • 144