ステップ 3:アラームと通知を追加する

このステップでは、次のことを学習します。

  • 指定した間隔でアプリを復帰させてバックグラウンド タスクを実行する方法
  • 画面上の通知を使用して重要なことに注意を引く方法。

このステップの推定所要時間: 20 分。このステップで完了する内容のプレビューを確認するには、このページの一番下までスクロールしてください ↓

リマインダーを使って Todo アプリを強化

Todo アプリが閉じている場合でも、完了していない作業があることを知らせる機能を追加することで、Todo アプリを強化します。

まず、アプリが未完了のタスクを定期的にチェックする方法を追加する必要があります。次に、Todo アプリのウィンドウを閉じた場合でも、ユーザーにメッセージを表示する必要があります。そのためには、Chrome アプリでのアラームと通知の仕組みを理解する必要があります。

アラームを追加する

chrome.alarms を使用して、起床間隔を設定します。Chrome が実行されている限り、設定された間隔でアラーム リスナーが呼び出されます。

アプリの権限の更新

manifest.json で、"alarms" 権限をリクエストします。

"permissions": ["storage", "alarms"],

バックグラウンド スクリプトを更新する

background.jsonAlarm リスナーを追加します。現時点で、コールバック関数は ToDo アイテムがあるたびにメッセージをコンソールにログするだけです。

chrome.app.runtime.onLaunched.addListener(function() {
  chrome.app.window.create('index.html', {
    id: 'main',
    bounds: { width: 620, height: 500 }
  });
});
chrome.alarms.onAlarm.addListener(function( alarm ) {
  console.log("Got an alarm!", alarm);
});

HTML ビューの更新

index.html に [アラームを有効にする] ボタンを追加します。

<footer id="info">
  <button id="toggleAlarm">Activate alarm</button>
  ...
</footer>

この新しいボタンの JavaScript イベント ハンドラを記述する必要があります。ステップ 2 で説明したように、CSP のコンプライアンス違反のうち、最も一般的なものの一つはインライン JavaScript にあります。index.html に次の行を追加して、新しい alarms.js ファイルをインポートします。このファイルは次の手順で作成します。

  </footer>
  ...
  <script src="js/app.js"></script>
  <script src="js/alarms.js"></script>
</body>

アラームのスクリプトを作成する

js フォルダに alarms.js という新しいファイルを作成します。

以下のコードを使用して、checkAlarm()createAlarm()cancelAlarm()toggleAlarm() の各メソッドを追加し、[アラームを有効にする] ボタンがクリックされたときにアラームを切り替えるクリック イベント ハンドラを追加します。

(function () {
  'use strict';
   var alarmName = 'remindme';
   function checkAlarm(callback) {
     chrome.alarms.getAll(function(alarms) {
       var hasAlarm = alarms.some(function(a) {
         return a.name == alarmName;
       });
       var newLabel;
       if (hasAlarm) {
         newLabel = 'Cancel alarm';
       } else {
         newLabel = 'Activate alarm';
       }
       document.getElementById('toggleAlarm').innerText = newLabel;
       if (callback) callback(hasAlarm);
     })
   }
   function createAlarm() {
     chrome.alarms.create(alarmName, {
       delayInMinutes: 0.1, periodInMinutes: 0.1});
   }
   function cancelAlarm() {
     chrome.alarms.clear(alarmName);
   }
   function doToggleAlarm() {
     checkAlarm( function(hasAlarm) {
       if (hasAlarm) {
         cancelAlarm();
       } else {
         createAlarm();
       }
       checkAlarm();
     });
   }
  $$('#toggleAlarm').addEventListener('click', doToggleAlarm);
  checkAlarm();
})();

アプリを再読み込みし、アラームの有効化(および無効化)を少しの間行います。

バックグラウンド ページのメッセージを調べる

アラームを有効にすると、アラームが「鳴る」たびに、コンソールにログメッセージが出力されます。

コンソールへのアラーム メッセージの印刷

次の点に注目してください。

  • ToDo アプリのウィンドウを閉じても、アラームは鳴り続けます。
  • ChromeOS 以外のプラットフォームでは、すべての Chrome ブラウザ インスタンスを完全に閉じると、アラームはトリガーされません。

chrome.alarms メソッドを使用する alarms.js の部分を 1 つずつ見ていきましょう。

アラームを作成する

createAlarm() で、chrome.alarms.create() API を使用して、[アラームを有効にする] が選択されたときにアラームを作成します。

chrome.alarms.create(alarmName, {delayInMinutes: 0.1, periodInMinutes: 0.1});

最初のパラメータはオプションの文字列で、アラームの一意の名前を識別します(例: remindme)。(注:アラームを名前でキャンセルするには、アラーム名を設定する必要があります。)

2 つ目のパラメータは alarmInfo オブジェクトです。alarmInfo の有効なプロパティには、when または delayInMinutesperiodInMinutes があります。ユーザーのパソコンの負荷を軽減するために、Chrome ではアラームを 1 分に 1 回に制限しています。ここでは、デモの目的にのみ小さな値(1 分に対して 0.1)を使用しています。

アラームをクリア

cancelAlarm() では、chrome.alarms.clear() API を使用して、[アラームをキャンセル] がオンになったときにアラームをキャンセルします。

chrome.alarms.clear(alarmName);

最初のパラメータは、chrome.alarms.create() でアラーム名として使用した識別文字列にする必要があります。

2 つ目のパラメータ(オプション)は、次の形式を受け取るコールバック関数です。

function(boolean wasCleared) {...};

アラームを設定する

checkAlarm() で、chrome.alarms.getAll() API を使用して、作成されたすべてのアラームの配列を取得し、切り替えボタンの UI 状態を更新します。

getAll() は、Alarm オブジェクトの配列を渡すコールバック関数を受け入れます。Alarm の内容を確認するには、DevTools コンソールで実行中のアラームを次のように検査します。

chrome.alarms.getAll(function(alarms) {
  console.log(alarms);
  console.log(alarms[0]);
});

これにより、以下に示すように {name: "remindme", periodInMinutes: 0.1, scheduledTime: 1397587981166.858} などのオブジェクトが出力されます。

getAll() を使用して、実行中のアラームを検査します。

次のセクションに備えましょう

これで、定期的にアプリをポーリングするアラームが設定されました。これを、ビジュアル通知を追加するためのベースとして使用します。

通知を追加する

アラームの通知を、ユーザーがすぐにわかるものに変更しましょう。chrome.notifications を使用して、次のようなデスクトップ通知を表示します。

Todo アプリの通知

ユーザーが通知をクリックすると、Todo アプリのウィンドウが表示されます。

アプリの権限の更新

manifest.json で、"notifications" 権限をリクエストします。

"permissions": ["storage", "alarms", "notifications"],

バックグラウンド スクリプトを更新する

background.js で、chrome.app.window.create() コールバックをスタンドアロン メソッドにリファクタリングして再利用できるようにします。

chrome.app.runtime.onLaunched.addListener(function() {
function launch() {
  chrome.app.window.create('index.html', {
    id: 'main',
    bounds: { width: 620, height: 500 }
  });
}
});
chrome.app.runtime.onLaunched.addListener(launch);
...

アラーム リスナーを更新する

background.js の先頭に、アラーム リスナーで使用するデータベース名の変数を追加します。

var dbName = 'todos-vanillajs';

dbName の値は js/app.js の 17 行目で設定したデータベース名と同じです。

var todo = new Todo('todos-vanillajs');

通知を作成する

新しいアラームを単にコンソールにロギングするのではなく、onAlarm リスナーを更新して、chrome.storage.local.get() を介して保存されたデータを取得し、showNotification() メソッドを呼び出します。

chrome.alarms.onAlarm.addListener(function( alarm ) {
  console.log("Got an alarm!", alarm);
  chrome.storage.local.get(dbName, showNotification);
});

この showNotification() メソッドを background.js に追加します。

function launch(){
  ...
}

function showNotification(storedData) {
  var openTodos = 0;
  if ( storedData[dbName].todos ) {
    storedData[dbName].todos.forEach(function(todo) {
      if ( !todo.completed ) {
        openTodos++;
      }
    });
  }
  if (openTodos>0) {
    // Now create the notification
    chrome.notifications.create('reminder', {
        type: 'basic',
        iconUrl: 'icon_128.png',
        title: 'Don\'t forget!',
        message: 'You have '+openTodos+' things to do. Wake up, dude!'
     }, function(notificationId) {});
  }
}

chrome.app.runtime.onLaunched.addListener(launch);
...

showNotification() は、未完了の(未完了の)ToDo アイテムを確認します。開いている ToDo アイテムが 1 つ以上ある場合は、chrome.notifications.create() で通知のポップアップを作成します。

最初のパラメータは、一意に識別する通知名です。その通知に対する操作を消去または処理するには、ID を設定する必要があります。ID が既存の通知と一致する場合、create() はまずその通知を消去してから、新しい通知を作成します。

2 つ目のパラメータは NotificationOptions オブジェクトです。通知のポップアップをレンダリングする方法は多数あります。ここでは、アイコン、タイトル、メッセージからなる「基本的な」通知を使用しています。その他の通知タイプには、画像、リスト、進行状況インジケーターなどがあります。ステップ 3 が完了したら、このセクションに戻って他の通知機能を試してください。

3 つ目のパラメータ(省略可)は、次の形式を受け取るコールバック メソッドです。

function(string notificationId) {...};

通知インタラクションを処理する

ユーザーが通知をクリックすると、Todo アプリを開きます。background.js の最後に chrome.notifications.onClicked イベント ハンドラを作成します。

chrome.notifications.onClicked.addListener(function() {
  launch();
});

イベント ハンドラのコールバックは、単に launch() メソッドを呼び出すだけです。chrome.app.window.create() は、新しい Chrome アプリ ウィンドウを作成する(まだ存在しない場合)か、ウィンドウ ID が main の現在開いているウィンドウをフォーカスします。

完成した ToDo アプリを起動する

ステップ 3 は完了です。リマインダーを使って Todo アプリを再読み込みしてください。

以下の動作が想定どおりに動作することを確認します。

  • 未完了の ToDo アイテムがない場合、ポップアップ通知は表示されません。
  • アプリを閉じているときに通知をクリックすると、Todo アプリが開くか、フォーカスされます。

トラブルシューティング

最終的な background.js ファイルはこちらのようになります。通知が表示されない場合は Chrome バージョンが 28 以降であることを確認しますそれでも通知が表示されない場合は、DevTools コンソールのメイン ウィンドウ([右クリック] > [要素を検証])とバックグラウンド ページ([右クリック] > [バックグラウンド ページを検証])の両方でエラー メッセージを確認してください。

自然言語処理についてや、

この手順で導入する API の詳細については、以下をご覧ください。

次のステップに進む準備はできましたか?ステップ 4 - WebView で外部リンクを開く »