如何从Flutter / dart中将文件从Internet下载并保存到内部存储(android)?

时间:2018-11-05 16:19:17

标签: android dart flutter storage

我需要将eg.jpg文件保存到“ internalstorage / appname / files /” 并显示通知,如果它确实已经存在于文件夹中。当按下按钮/启动活动时,应使用飞镖代码将文件下载到Andorid设备的本地存储中。 帮我找到解决方法。

**code:**
   import 'dart:io';
  import 'dart:async';
  import 'package:flutter/material.dart';
 import 'package:flutter_downloader/flutter_downloader.dart';
 import './landing_page.dart';
 import 'package:dio/dio.dart';
 import 'package:path_provider/path_provider.dart';
 import 'package:simple_permissions/simple_permissions.dart';
 import 'package:flutter/services.dart';


 class MoviesPage extends StatefulWidget {

  @override
 State createState() => new MoviesPageState();
 }

 class MoviesPageState extends State<MoviesPage> {
  final dUrl ="https://cdn.putlockers.es/download/0BBCA7584749D4E741747E32E6EB588AEA03E40F";
 bool downloading = false;
 var progressString = "";
static const MethodChannel _channel =
     const MethodChannel('flutter_downloader');

 @override
  void initState() {
    super.initState();
   downloadFile();

   }


  Future<void> downloadFile() async {
    Dio dio = Dio();

    try {
     var dir = await getApplicationDocumentsDirectory();

     await dio.download(dUrl, "${dir.path}/file.torrent",
          onProgress: (rec, total) {
          print("Rec: $rec , Total: $total");

       setState(() {
        downloading = true;
        progressString = ((rec / total) * 100).toStringAsFixed(0) + "%";
      });
     });
      } catch (e) {
      print(e);
      }

    setState(() {
     downloading = false;
     progressString = "Completed";
     });
     print("Download completed");
     }
    @override
     Widget build(BuildContext context) {
     return Scaffold(
          appBar: AppBar(
         title: Text("AppBar"),
        ),
     body: Center(
       child: downloading
           ? Container(
               height: 120.0,
              width: 200.0,
               child: Card(
                 color: Colors.black,
                 child: Column(
                     mainAxisAlignment: MainAxisAlignment.center,
                     children: <Widget>[
                       CircularProgressIndicator(),
                      SizedBox(
                    height: 20.0,
                  ),
                  Text(
                    "Downloading File: $progressString",
                    style: TextStyle(
                      color: Colors.white,
                    ),
                  )
                ],
              ),
            ),
          )
        : Text("No Data"),
  ),
);
 }
}

提前感谢。以完全错误的方式发布您的解决方案。

1 个答案:

答案 0 :(得分:0)

我已经检查了您发布的最小复制,看来您正在使用Flutter插件dio下载文件。我已经重用了您代码中的Future<void> downloadFile()并对其进行了一些修改,以检查插件是否按预期工作。从dio插件的3.0.10版本开始,onProgress上的dio.download()现在为onReceiveProgress,但实际上仍然具有相同的功能。

这是从您的代码进行一些修改后下载图像文件的方法。

Future downloadFile() async {
  Dio dio = Dio();
  var dir = await getApplicationDocumentsDirectory();
  var imageDownloadPath = '${dir.path}/image.jpg';
  await dio.download(imageSrc, imageDownloadPath,
      onReceiveProgress: (received, total) {
    var progress = (received / total) * 100;
    debugPrint('Rec: $received , Total: $total, $progress%');
    setState(() {
      downloadProgress = received.toDouble() / total.toDouble();
    });
  });
  // downloadFile function returns path where image has been downloaded
  return imageDownloadPath;
}

该插件可以正常工作,并成功下载了图像文件。尽管我无法验证您如何确定要下载的图像在repro上失败。在我的示例应用程序中,Future downloadFile()返回一个字符串,用于存储图像路径。然后,我使用它来更新Image Widget以显示下载的图像-这确定下载已成功。

这是完整的示例应用程序。

import 'dart:io';

import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:path_provider/path_provider.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  final imageSrc = 'https://picsum.photos/250?image=9';
  var downloadPath = '';
  var downloadProgress = 0.0;
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Expanded(flex: 5, child: Image.network(imageSrc)),
            Expanded(
              flex: 2,
              child: Row(
                children: [
                  ElevatedButton(
                    // Download displayed image from imageSrc
                    onPressed: () {
                      downloadFile().catchError((onError) {
                        debugPrint('Error downloading: $onError');
                      }).then((imagePath) {
                        debugPrint('Download successful, path: $imagePath');
                        displayDownloadImage(imagePath);
                      });
                    },
                    child: Text('Download'),
                  ),
                  ElevatedButton(
                    // Delete downloaded image
                    onPressed: () {
                      deleteFile().catchError((onError) {
                        debugPrint('Error deleting: $onError');
                      }).then((value) {
                        debugPrint('Delete successful');
                      });
                    },
                    child: Text('Clear'),
                  )
                ],
              ),
            ),
            LinearProgressIndicator(
              value: downloadProgress,
            ),
            Expanded(
                flex: 5,
                child: downloadPath == ''
                // Display a different image while downloadPath is empty
                // downloadPath will contain an image file path on successful image download
                    ? Icon(Icons.image)
                    : Image.file(File(downloadPath))),
          ],
        ),
      ),
    );
  }

  displayDownloadImage(String path) {
    setState(() {
      downloadPath = path;
    });
  }

  Future deleteFile() async {
    final dir = await getApplicationDocumentsDirectory();
    var file = File('${dir.path}/image.jpg');
    await file.delete();
    setState(() {
      // Clear downloadPath on file deletion
      downloadPath = '';
    });
  }

  Future downloadFile() async {
    Dio dio = Dio();
    var dir = await getApplicationDocumentsDirectory();
    var imageDownloadPath = '${dir.path}/image.jpg';
    await dio.download(imageSrc, imageDownloadPath,
        onReceiveProgress: (received, total) {
      var progress = (received / total) * 100;
      debugPrint('Rec: $received , Total: $total, $progress%');
      setState(() {
        downloadProgress = received.toDouble() / total.toDouble();
      });
    });
    // downloadFile function returns path where image has been downloaded
    return imageDownloadPath;
  }
}

在示例应用程序中,单击“下载”按钮将下载显示在屏幕顶部的网络图像。下载成功后,将使用Image.file()在屏幕下方显示下载的图像。

enter image description here