在此步骤中,您将学习以下内容:
- 如何按指定的时间间隔唤醒应用以执行后台任务。
- 如何使用屏幕通知吸引用户注意一些重要信息。
完成此步骤的预计用时:20 分钟。 如需预览您要在此步骤中完成的内容,请跳转到此页面的底部 ↓。
使用提醒功能增强 Todo 应用
添加相应功能,在用户有打开的待办事项时(即使应用已关闭)提醒用户,从而改进待办事项应用。
首先,您需要为应用添加一种方法来定期检查未完成的待办事项。接下来,应用需要向用户显示一条消息,即使 Todo 应用窗口已关闭。为此,您需要了解闹钟和通知在 Chrome 应用中的工作原理。
添加闹钟
使用 chrome.alarms
设置起床时间间隔。只要 Chrome 仍在运行,就会按照大致设定的时间间隔调用闹钟监听器。
更新应用权限
在 manifest.json 中,请求 "alarms"
权限:
"permissions": ["storage", "alarms"],
更新后台脚本
在 background.js 中,添加 onAlarm
监听器。目前,每当有待办事项时,回调函数只会向控制台记录一条消息:
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 步中提到,内嵌 JavaScript 导致了最常见的 CSP 违规行为之一。在 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();
})();
重新加载应用,然后花一点时间激活(和停用)闹钟。
:启用闹钟后,每次闹钟“响铃”时,您应该会看到控制台中输出了日志消息:
您会发现:
- 即使你关闭了待办事项应用窗口,闹钟仍会响起。
- 在 ChromeOS 以外的平台上,如果您完全关闭所有 Chrome 浏览器实例,将不会触发闹钟。
我们来逐一了解 alarms.js 中使用 chrome.alarms
方法的部分代码。
创建闹钟
在 createAlarm()
中,使用 chrome.alarms.create()
API 在启用闹钟切换开关时创建闹钟。
chrome.alarms.create(alarmName, {delayInMinutes: 0.1, periodInMinutes: 0.1});
第一个参数是一个可选字符串,用于标识闹钟的唯一名称,例如 remindme
。(注意:您需要设置闹钟名称,才能按名称取消闹钟。)
第二个参数是 alarmInfo
对象。alarmInfo
的有效属性包括 when
或 delayInMinutes
以及 periodInMinutes
。为了减少用户计算机的负载,Chrome 将闹钟限制为每分钟一次。我们在这里使用较小值(每分钟 0.1 分钟)仅用于演示目的。
清除闹钟
在 cancelAlarm()
中,使用 chrome.alarms.clear()
API,以便在取消闹钟切换开关时取消闹钟。
chrome.alarms.clear(alarmName);
第一个参数应该是您在 chrome.alarms.create()
中用作闹钟名称的标识字符串。
第二个(可选)参数是一个回调函数,其格式应为:
function(boolean wasCleared) {...};
设置闹钟
在 checkAlarm()
中,使用 chrome.alarms.getAll()
API 获取已创建的所有闹钟的数组,以便更新切换按钮的界面状态。
getAll()
接受传入 Alarm
对象数组的回调函数。如需查看 Alarm
中的内容,您可以在开发者工具控制台中检查正在运行的闹钟,如下所示:
chrome.alarms.getAll(function(alarms) {
console.log(alarms);
console.log(alarms[0]);
});
这将输出一个对象,例如 {name: "remindme", periodInMinutes: 0.1, scheduledTime: 1397587981166.858}
,如下所示:
为下一部分做好准备
现在,闹钟已设置好即可定期轮询应用,接下来可以以此为基础来添加视觉通知。
添加通知
我们将闹钟通知更改为用户能够轻松注意到的内容。使用 chrome.notifications
显示如下桌面通知:
当用户点击通知时,“待办事项”应用窗口应该会进入视图。
更新应用权限
在 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()
会检查是否有待处理(未完成)的待办事项。如果至少有一个待处理的待办事项,请通过 chrome.notifications.create()
创建弹出式通知。
第一个参数是唯一标识通知名称。您必须设置 ID,才能清除或处理与该特定通知的互动。如果该 ID 与现有通知匹配,create()
会先清除该通知,然后再发出新通知。
第二个参数是 NotificationOptions
对象。呈现通知弹出式窗口的选项有很多。这里我们使用的是“基本”通知,其中包含图标、标题和消息。其他通知类型包括图片、列表和进度指示器。完成第 3 步并尝试其他通知功能后,您可以随时返回本部分。
第三个(可选)参数是回调方法,其格式如下:
function(string notificationId) {...};
处理通知交互
在用户点击通知时打开待办事项应用。在 background.js 末尾,创建一个 chrome.notifications.onClicked
事件处理脚本:
chrome.notifications.onClicked.addListener(function() {
launch();
});
事件处理脚本回调只会调用 launch()
方法。chrome.app.window.create()
会创建一个新的 Chrome 应用窗口(如果尚无该窗口),或聚焦于当前打开且窗口 ID 为 main
的窗口。
启动已完成的待办事项应用
您已完成第 3 步!立即重新加载提醒应用。
检查以下行为是否符合预期:
- 如果没有任何未完成的待办事项,系统不会显示弹出式通知。
- 如果您在应用关闭时点击通知,Todo 应用会打开或获得焦点。
问题排查
最终的 background.js 文件应如下所示。如果未显示通知,请确认您的 Chrome 是版本 28 或更高版本。如果通知仍未显示,请在开发者工具控制台中检查主窗口(右键点击 > Inspect Element)和背景页面(点击右键点击 > Inspect Background Page)上的错误消息。
更多信息
如需详细了解此步骤中引入的一些 API,请参阅:
- 声明权限 ↑
- chrome.alarms ↑
- chrome.alarms.onAlarm ↑
- chrome.alarms.create() ↑
- chrome.alarms.clear() ↑
- chrome.alarms.getAll() ↑
- chrome.notifications ↑
- chrome.notifications.create() ↑
- NotificationOptions ↑
- chrome.notifications.onClicked ↑
准备好继续下一步了吗?转到第 4 步 - 使用 WebView 打开外部链接 »