2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Flutter】任意の場所にファイルをダウンロードする

Last updated at Posted at 2023-12-23

はじめに

flutterでpdfファイルを端末内の任意の場所に保存するための方法を紹介します。
androidおよびiOSで動作することを確認しました。
この記事で紹介する内容を応用すればmp3,mp4,txt・・・など複数のファイル形式のダウンロードも可能になるかと思います。

結論

flutter_file_dialogを利用する

  final params = SaveFileDialogParams(
    data: data.bodyBytes,
    fileName: '$fileName.pdf',
  );
  final savedFiledPath = await FlutterFileDialog.saveFile(params: params);

実装

実際に実装してみました。今回はpdfのURLからそのファイルをダウンロードするというものを実装しています。

画面収録 2023-12-23 20.43.28.gif

パッケージのインストール

flutter_file_dialog, http, flutter_hooksの3つを使用しました。

flutter pub add flutter_file_dialog
flutter pub add http
flutter pub add flutter_hooks

UIの作成

テキストフィールド2つと送信ボタンだけのシンプルなものを作成しました。この記事の要旨ではないので↓のトグルに入れておきます。

main.dart(UI)のコード
main.dart
import 'package:download_to_optional_folder/save_file.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';

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

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Pdf download Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(title: 'File Dialog Demo'),
    );
  }
}

class MyHomePage extends HookWidget {
  const MyHomePage({Key? key, required this.title}) : super(key: key);

  final String title;

  @override
  Widget build(BuildContext context) {
    final urlController = useTextEditingController();
    final fileNameController = useTextEditingController(); // Add this line

    return Scaffold(
      appBar: AppBar(
        title: Text(title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            TextField(
              controller: urlController,
              decoration: const InputDecoration(
                labelText: 'Enter URL',
              ),
            ),
            TextField(
              // Add this block
              controller: fileNameController,
              decoration: const InputDecoration(
                labelText: 'Enter File Name',
              ),
            ),
            ElevatedButton(
              onPressed: () async {
                final url = urlController.text;
                final fileName = fileNameController.text;
                final isSuccessful = await savePdfFile(url, fileName);
                if (!isSuccessful && context.mounted) {
                  showDialog(
                    context: context,
                    builder: (BuildContext context) {
                      return AlertDialog(
                        title: const Text('Failed to Download'),
                        content: const Text('Failed to download the file.'),
                        actions: [
                          TextButton(
                            onPressed: () {
                              Navigator.of(context).pop();
                            },
                            child: const Text('OK'),
                          ),
                        ],
                      );
                    },
                  );
                }
              },
              child: const Text('Submit'),
            ),
          ],
        ),
      ),
    );
  }
}

ダウンロードを行う関数の作成

以下のような関数で実装しています。
処理の流れとしては以下の通りです。

  • httpパッケージでpdfファイルを取得
  • flutter_file_dialogで保存。
  • データの取得・保存に失敗すると例外を投げるようにする
  • 正常にダウンロードできればtrueが帰る
save_pdf_file.dart
import 'package:flutter/foundation.dart';
import 'package:flutter_file_dialog/flutter_file_dialog.dart';
import 'package:http/http.dart' as http;

Future<bool> savePdfFile(String url, String fileName) async {
  final data = await http.get(Uri.parse(url));
  try {
    if (data.statusCode == 200) {
      final params = SaveFileDialogParams(
        data: data.bodyBytes,
        fileName: '$fileName.pdf',
      );
      final savedFiledPath = await FlutterFileDialog.saveFile(params: params);
      if (savedFiledPath == null) {
        throw Exception('Failed to download pdf');
      }
    } else {
      throw Exception("Error while downloading file");
    }
  } catch (e) {
    if (kDebugMode) {
      print(e);
    }
    return false;
  }
  return true;
}

#最後に
参考になれば幸いです😀
もっと良い実装方法や補足等ありましたらコメント・もしくは編集リクエスト等で 優しく 指摘してください🥺

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?