AndroidのオープンソースファイルダウンロードマネージャーFetch使ってみた

#今回の記事について
今回は、自分の開発しているアプリに実装します！
DownloadManagerを使おうかなーと思って調べていたところ、発見しよさそうだなと思ったので、使いたいと思います！
調べてみたら、日本語の情報が少なく、情報を共有出来たらと思い、書きます！
私も初めて使うので、間違えがあったら教えてください！
[GitHubのページはこちら](https://github.com/tonyofrancis/Fetch)

#今回の環境
今回の場合は、ファイルはFirebase CLoudStrageに保存されており、DownloadURLを取得し、そのURLを使用してダウンロードすることにします。
なお、FirebaseCloudStrageの使い方は、省略します。

#準備
まずは、applicationフォルダ内のbuild.gradleに依存関係を追加します。
今回は、AndroidXで使用するので、

```
implementation "androidx.tonyodev.fetch2:xfetch2:3.1.4"
```

を追加します。
追加したら、syncします。

#Acticvityの作成
今回は、DownloadActivityとして作成しました。
レイアウトは、ボタンとprogressbarだけの簡単なレイアウトです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167678/e01f4c2d-acb5-27ec-6427-314482b598ea.png)

#CloudStrageのDownloadURLの取得
Download用のURLを取得します。
今回のCloudStrageの場合は、セキュリティルールで認証済みの人のみに設定しているので、FirebaseAuthでログイン状態を確認します。
今回は、onCreateの中で実行し、ログインしている場合のみボタンを有効かするように設定します。
また、ユーザーがnullじゃない場合は、Strageの参照を取得するようにします。
実際の環境で使用する場合は、もう少し丁寧に行ってください。
onClickListnerも設定します。

```Java

Button downloadButton = findViewById(R.id.downloadbutton);
ProgressBar progressBar = findViewById(R.id.progressBar);

downloadButton.setOnClickListener(onClickListener);
if(FirebaseAuth.getInstance().getCurrentUser() == null) {
   downloadButton.setEnabled(false);
   }else {
    firebaseStorage = FirebaseStorage.getInstance();
    storageReference = firebaseStorage.getReference().child("FirebaseStrage上のパス");
   }

```

```Java
View.OnClickListener onClickListener = new View.OnClickListener() {
        @Override
        public void onClick(View v) {

        }
    };
```
onClickの中に処理を書いていきます。
まずは、ボタンが押されたら、ダウンロード用のURLを取得します。

```Java
storageReference.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
                @Override
                public void onSuccess(Uri uri) {
                }
            }).addOnFailureListener(new OnFailureListener() {
                @Override
                public void onFailure(@NonNull Exception exception) {
                }
            });
```
取得に成功すると、uriでダウンロード用URLが帰ってきます。

#ダウンロード処理

Fetchのインスタンスを生成します。
今回は、onCreateで生成しましたが、状況に合わせてください。
setDownloadCurrentLimitには、同時ダウンロード数を設定します。

```Java
 FetchConfiguration fetchConfiguration = new FetchConfiguration.Builder(this)
                    .setDownloadConcurrentLimit(2)
                    .build();
            fetch = Fetch.Impl.getInstance(fetchConfiguration);
```

次に、ダウンロードリクエストを生成します。
これは、onClickリスナーの中で処理します。
uriは先ほど取得したダウンロードurl
filePathには、端末の保存先をStringで指定します。

```Java
downloadRequest = new Request(uri.toString(),filePath );
```
リスナ－を生成します。
本番で使用する際は、もう少しちゃんと処理を書きましょう。

```Java

FetchListener fetchListener = new FetchListener() {
        @Override
        public void onWaitingNetwork(@NotNull Download download) {
        downloadStatusTextView.setText("ネットワーク接続待機中");
        }

        @Override
        public void onStarted(@NotNull Download download, @NotNull List<? extends DownloadBlock> list, int i) {
        downloadStatusTextView.setText("ダウンロード中");
        }

        @Override
        public void onError(@NotNull Download download, @NotNull Error error, @Nullable Throwable throwable) {
        downloadStatusTextView.setText("ダウンロードエラー");
        }

        @Override
        public void onDownloadBlockUpdated(@NotNull Download download, @NotNull DownloadBlock downloadBlock, int i) {
        }

        @Override
        public void onAdded(@NotNull Download download) {
        }

        @Override
        public void onQueued(@NotNull Download download, boolean waitingOnNetwork) {
        }

        @Override
        public void onCompleted(@NotNull Download download) {
        downloadStatusTextView.setText("ダウンロード完了");
        }

        @Override
        public void onProgress(@NotNull Download download, long etaInMilliSeconds, long downloadedBytesPerSecond) {
            int progress = download.getProgress();
            progressBar.setProgress(progress);
        }

        @Override
        public void onPaused(@NotNull Download download) {
        }

        @Override
        public void onResumed(@NotNull Download download) {
        }

        @Override
        public void onCancelled(@NotNull Download download) {
        }

        @Override
        public void onRemoved(@NotNull Download download) {
        }

        @Override
        public void onDeleted(@NotNull Download download) {
        }
    };

```
リスナーを設定します。

```Java

        fetch.addListener(fetchListener);
```


ダウンロードを開始します。


```Java
        fetch.enqueue(downloadRequest, updatedRequest -> {
        }, error -> {
        });
```
ダウンロードが完了すると、リスナーのonCompletedが呼び出されます。
複数のダウンロードをしている場合は、

```Java
download.getId()
```
でダウンロードIDが取得できます。

ダウンロードの中断等も簡単に出来ます。

```Java
//一時停止
fetch.pause(downloadrequest.getId());
//キャンセル
fetch.cancel(downloadrequest.getId());
```

また、Wifiの時のみダウンロードすることなども出来ます。

```Java
//すべてのタイプ
downloadRequest.setNetworkType(NetworkType.ALL);
//Wifiのみ
downloadRequest.setNetworkType(NetworkType.WIFI_ONLY);
```
ほかには、グループとしてダウンロードをまとめて管理したりすることができるようです。

#まとめ
少し雑な記事になってしまいましたが、これはとても便利ですね！
しかし、ダウンロード先にすでにファイルが存在する場合、ダウンロードされないけど、onCompleteになるようです。
私は、ダウンロードファイル名を変更することで対応しましたが、どうすれば良いのか、、
上書きオプションは無いようです。
もしご存じの方がいれば、教えてください！
ではではー