【Ionic3】Androidで通知領域にプログレスバーを表示する

Androidアプリでよくみる、ダウンロード中に通知領域にプログレスバーを表示するという動作をIonic3で実現するには、プラグインが必要となります。

まずは、ファイルをダウンロードするプラグインである、File, File Transfer, Android Permissionsプラグインをインストールする必要があります。

上記プラグインのインストールについては、過去の記事を参考にしてください。

さて、通知領域はNativeの領分ですので、こちらもプラグインのインストールが必要です。

それと、ダウンロードした後にファイルを開くためのプラグインも必要となります。

プラグインのインストール

cordova-plugin-progress-notification

$ npm install cordova-plugin-progress-notification
$ cordova plugin add cordova-plugin-progress-notification --save --no-registry
引用元: cordova-plugin-progress-notification

File Openerプラグイン

$ ionic cordova plugin add cordova-plugin-file-opener2
$ npm install --save @ionic-native/file-opener
引用元: Ionic Docs File Opener

プラグインの使い方

下準備ができました。早速コードを書いてみます。

以下の流れを作成します。

「ダウンロード」ボタンタップ ダウンロード開始 通知領域にダウンロード進捗状況を表示 ダウンロード完了を通知領域に表示 ダウンロードしたファイルを開く

今回は横着して、ダウンロード元URL固定、保存時のファイル名も固定にしています。

Viewのコード

<!-- home.html -->
<ion-content padding>
  <div padding>
    <button ion-button primary (click)="download()" tappable>ダウンロード</button>
  </div>
</ion-content>

Componentのコード

// home.ts
import { Component } from '@angular/core';
import { NavController } from 'ionic-angular';
import { FileTransferObject } from '@ionic-native/file-transfer';
import { File } from '@ionic-native/file';
import { AndroidPermissions } from '@ionic-native/android-permissions';
import { FileOpener } from '@ionic-native/file-opener';
// cordova-plugin-progress-notificationを宣言
declare const progressNotification;

@Component({
  selector: 'page-home',
  templateUrl: 'home.html'
})
export class HomePage {

  constructor
  (
    public navCtrl: NavController,
    private transfer: FileTransferObject,
    private file: File,
    private androidPermissions: AndroidPermissions,
    private fileOpener: FileOpener,
  ) {}
  download() {
    // アクセス許可を求める
    this.androidPermissions.checkPermission(this.androidPermissions.PERMISSION.WRITE_EXTERNAL_STORAGE)
    .then(status => {
      // プログレスを表示
      progressNotification.show(
        0, // id
        'タイトル', // 任意のタイトル
        'メッセージ', // 任意のメッセージ
        false, // 進行状況をパーセンテージで渡せないときは true を指定
        () => { console.log('success Callback') }, // 成功コールバック
        () => { console.log('error Callback') } // エラーコールバック
      );
      // ダウンロード処理
      const url = 'https://www.example/sample.pdf';
      this.transfer.download(url, this.file.externalRootDirectory + 'Download/download_test.pdf')
      .then((entry) => {
        // 通知領域に完了を伝える
        progressNotification.finish(0, 'ダウンロード完了', 100); // id, message, value
        // ダウンロードしたファイルを開く
        this.fileOpener.open(this.file.externalRootDirectory + 'Download/download_test.pdf', 'application/pdf')
        .then(() => {
          console.log('File is opened');
          // 通知を削除
          progressNotification.dismiss(0);
        })
        .catch(e => console.log('Error opening file', e));
      })
      .catch((error) => {
        console.error('download error: ' + error);
      });
      // ダウンロード中、通知領域を更新する
      this.transfer.onProgress(((e) => {
        const percentage = Math.floor(e.loaded / e.total * 100);
        // パフォーマンスを考慮し、1桁目が0か5の時だけ更新する
        if (percentage % 5 === 0 || percentage % 5 === 5) {
          progressNotification.update(0, percentage); // id, value
        }
      }));
    })
    .catch(err => this.androidPermissions.requestPermission(this.androidPermissions.PERMISSION.WRITE_EXTERNAL_STORAGE));
  }
}

コード内にコメントを書いているので、あまり文章で説明することがありません。

実際に、端末でどのように表示されるかをスクリーンショットを載せておきます。

ダウンロード中の通知領域

ダウンロード完了時の通知領域

こうやってみてみると、実際に利用する時に、タイトルにはファイル名を表示して、message部分は空欄でも良いかもしれませんね。

余談ですが、以下のように第4引数のindeterminateをtrueに指定すると、進捗状況が不明な場合の見た目になります。

progressNotification.show(0, 'タイトル', 'メッセージ', true);

進捗状況が不明な見た目というのは、プログレスバーでパーセンテージを表示するのではなく、ローディング状態を表現するものです。

以下にスクリーンショットを載せます。

進捗状況不明の通知領域

プログレスバーが不要な時、もしくは、進捗状況が取得できない時には、第4引数のindeterminateにtrueに指定しておくとよいでしょう。

人気記事すべて表示

ハイブリッドアプリすべて表示