Моя цель - загрузить файл с сервера API (в данном случае файл PDF), а затем я хочу загрузить этот файл PDF и показать его в пользовательском интерфейсе. Я использую flutter_pdfview
и следую этому руководству , как его реализовать. Во-первых, разрешения: по моему android/app/build.gradle
targetSdkVersion
равно 29, а compileSdkVersion
. В android/app/main/AndroidManifest.xml
я написал ниже <application ... android:requestLegacyExternalStorage="true">
, и я добавил в эту папку эти разрешения.
<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"/>
Запрос на выборку:
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");
}
}
В варианте 1 я нашел pdf файл внутри моего внутреннего хранилища, но все равно выдает ошибку. С вариантом 2, как парень сделал это, я не мог найти его где-нибудь на моем устройстве. Кроме того, я предоставил доступ к хранилищу вручную в моем телефоне, но это также не помогло.
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(),
],
),
);
}
}