Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(4)

Side by Side Diff: chrome/common/extensions/docs/templates/articles/app_codelab_alarms.html

Issue 609433003: Updated Chrome Apps codelab from I/O 2013 Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Upload the rest of the images Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 <h1 id="add-alarms-notifications">
2 <span class="h1-step">Step 3:</span>
3 Add Alarms and Notifications
4 </h1>
5
6 <p class="note">
7 <strong>Want to start fresh from here?</strong>
8 Find the previous step's code in the <a href="https://github.com/mangini/io13- codelab/archive/master.zip">reference code zip</a> under <strong><em>cheat_code > solution_for_step2</strong></em>.
9 </p>
10
11 <p>In this step, you will learn:</p>
12
13 <ul>
14 <li>How to wake your app at specified intervals to execute background tasks.</ li>
15 <li>How to use on-screen notifications to draw attention to something importan t.</li>
16 </ul>
17
18 <p>
19 <em>Estimated time to complete this step: 20 minutes.</em>
20 <br>
21 To preview what you will complete in this step, <a href="#launch">jump down to the bottom of this page &#8595;</a>.
22 </p>
23
24 <h2 id="overview">Enhance your Todo app with reminders</h2>
25
26 <p>Let's enhance our Todo app by adding functionality to remind the user if they have open todos &mdash; even when the
27 app is closed.</p>
28
29 <p>First, we must add a way for our app to regularly check for uncompleted todos . Next, we need to display a message to the user, even if the Todo app window is closed. To accomplish this, we will learn about implementing alarms and notific ations in Chrome Apps.</p>
30
31 <h2 id="alarms">Add alarms</h2>
32
33 <p>Use <a href="/apps/alarms.html"><code>chrome.alarms</code></a>
34 to set a wake up interval. As long as Chrome is running, the alarm listener will be called at
35 approximately the interval set.</p>
36
37 <h3 id="update-permissions-alarms">Update app permissions</h3>
38
39 <p>In <strong><em>manifest.json</em></strong>, request the <code>"alarms"</code> permission:</p>
40
41 <pre data-filename="manifest.json">
42 "permissions": ["storage"<b>, "alarms"</b>],
43 </pre>
44
45 <h3 id="update-background-script-alarms">Update background scripts</h3>
46
47 <p>In <strong><em>background.js</em></strong>, add an <a href="/apps/alarms#even t-onAlarm"><code>onAlarm</code></a> listener.
48 For now, the callback function will just log a message to the Console whenever t here is a todo item:</p>
49
50 <pre data-filename="background.js">
51 chrome.app.runtime.onLaunched.addListener(function() {
52 chrome.app.window.create('index.html', {
53 id: 'main',
54 bounds: { width: 620, height: 500 }
55 });
56 });
57 <b>chrome.alarms.onAlarm.addListener(function( alarm ) {
58 console.log("Got an alarm!", alarm);
59 });</b>
60 </pre>
61
62 <h3 id="update-html-view-alarms">Update HTML view</h3>
63
64 <p>In <strong><em>index.html</em></strong>, add an <strong>Activate alarm</stron g> button:</p>
65
66 <pre data-filename="index.html">
67 &lt;footer id="info"&gt;
68 <b>&lt;button id="toggleAlarm"&gt;Activate alarm&lt;/button&gt;</b>
69 ...
70 &lt;/footer&gt;
71 </pre>
72
73 <p>We now need to write the JavaScript event handler for this new button but rec all from <a href="/apps/app_codelab_import_todomvc#csp-compliance">Step 2</a> th at one of the most common CSP non-compliances is caused by inline JavaScript. St ill in <em>index.html</em>, add this line to import a new <em>alarms.js</em>
74 file we will create in the following step:</p>
75
76 <pre data-filename="index.html">
77 &lt;/footer&gt;
78 ...
79 &lt;script src="js/app.js"&gt;&lt;/script&gt;
80 <b>&lt;script src="js/alarms.js"&gt;&lt;/script&gt;</b>
81 &lt;/body&gt;
82 </pre>
83
84 <h3 id="add-alarms-script">Create alarms script</h3>
85
86 <p>Create a new file in your <strong><em>js</em></strong> folder called <strong> <em>alarms.js</em></strong>.</p>
87
88 <p>Use the code below to add <code>checkAlarm()</code>, <code>createAlarm()</cod e>,
89 <code>cancelAlarm()</code> and <code>toggleAlarm()</code> methods, along with a
90 click event handler to toggle the
91 alarm when the <strong>Activate alarm</strong> button is clicked.</p>
92
93 <pre data-filename="alarms.js">
94 (function () {
95 'use strict';
96 var alarmName = 'remindme';
97 function checkAlarm(callback) {
98 chrome.alarms.getAll(function(alarms) {
99 var hasAlarm = alarms.some(function(a) {
100 return a.name == alarmName;
101 });
102 var newLabel;
103 if (hasAlarm) {
104 newLabel = 'Cancel alarm';
105 } else {
106 newLabel = 'Activate alarm';
107 }
108 document.getElementById('toggleAlarm').innerText = newLabel;
109 if (callback) callback(hasAlarm);
110 })
111 }
112 function createAlarm() {
113 chrome.alarms.create(alarmName, {
114 delayInMinutes: 0.1, periodInMinutes: 0.1});
115 }
116 function cancelAlarm() {
117 chrome.alarms.clear(alarmName);
118 }
119 function doToggleAlarm() {
120 checkAlarm( function(hasAlarm) {
121 if (hasAlarm) {
122 cancelAlarm();
123 } else {
124 createAlarm();
125 }
126 checkAlarm();
127 });
128 }
129 $$('#toggleAlarm').addEventListener('click', doToggleAlarm);
130 checkAlarm();
131 })();
132 </pre>
133
134 <p>Reload your app and spend a few moments activating (and deactivating) the ala rm.</p>
135
136 <p class="note">Since the log messages are being sent to the Console via the eve nt page (aka background script),
137 you need to <strong>right-click > Inspect Background Page</strong> to see the lo g messages:</p>
138
139 <figure>
140 <img src="{{static}}/images/app_codelab/inspect-background-page.png" alt="Insp ect background page messages"/>
141 </figure>
142
143 <p class="note">It's also worthwhile to continue to use <strong>right-click > In spect Element</strong>
144 to make sure you do not have errors in other JavaScript files.</p>
145
146 <p>Whenever you have the alarm activated, you should see log messages being prin ted
147 in the Console every time the alarm "rings":</p>
148
149 <figure>
150 <img src="{{static}}/images/app_codelab/alarm-console-logs.png" alt="Alarm mes sages printing to the Console"/>
151 </figure>
152
153 <p>You should notice that:</p>
154
155 <ul>
156 <li>Even when you close the Todo app window, the alarms will keep coming.</li>
157 <li>On platforms other than ChromeOS, if you completely close all Chrome brows er instances, alarms won't trigger.</li>
158 </ul>
159
160 <p>Let's go over some of the pieces in <em>alarms.js</em> that use <code>chrome. alarms</code> methods one by one.</p>
161
162 <h3 id="create-alarms">Create alarms</h3>
163
164 <p>In <code>createAlarm()</code>, we use the <a href="/apps/alarms#method-create "><code>chrome.alarms.create()</code></a> API to create an alarm when <strong>Ac tivate alarm</strong> is toggled.</p>
165
166 <pre data-filename="alarms.js">
167 chrome.alarms.create(alarmName, {delayInMinutes: 0.1, periodInMinutes: 0.1});
168 </pre>
169
170 <p>The first parameter is an optional string identifying an unique name for your alarm. In our case, the alarm name is <code>remindme</code>. (Note: You need to set an alarm name in order to cancel it by name.)</p>
171
172 <p>The second parameter is an <code>alarmInfo</code> object. Valid properties fo r <code>alarmInfo</code> include <code>when</code> or <code>delayInMinutes</code >, and <code>periodInMinutes</code>. In order to reduce the load on the user's m achine, Chrome limits alarms to once every minute.
173 We are using small values (0.1 of a minute) here for demo purposes only.</p>
174
175 <h3 id="clear-alarms">Clear alarms</h3>
176
177 <p>In <code>cancelAlarm()</code>, we use the <a href="/apps/alarms#method-clear" ><code>chrome.alarms.clear()</code></a> API to cancel an alarm when <strong>Canc el alarm</strong> is toggled.</p>
178
179 <pre data-filename="alarms.js">
180 chrome.alarms.clear(alarmName);
181 </pre>
182
183 <p>The first parameter should be the identifying string you used as an alarm nam e in <code>chrome.alarms.create()</code>.</p>
184
185 <p>The second (optional) parameter is a callback function that should take on th e format:</p>
186
187 <pre>function(boolean wasCleared) {...};</pre>
188
189 <h3 id="get-alarms">Get alarms</h3>
190
191 <p>In <code>checkAlarm()</code>, we use the <a href="/apps/alarms#method-getAll" ><code>chrome.alarms.getAll()</code></a> API to get an array of all created alar ms in order to update the UI state of the toggle button.</p>
192
193 <p><code>getAll()</code> accepts a callback function that passes in an array of <code>Alarm</code> objects. To see what's in an <code>Alarm</code>, you can insp ect running alarms in the DevTools Console like so:</p>
194
195 <pre>
196 chrome.alarms.getAll(function(alarms) {
197 console.log(alarms);
198 console.log(alarms[0]);
199 });
200 </pre>
201
202 <p>This will output an object such as <code>{name: "remindme", periodInMinutes: 0.1, scheduledTime: 1397587981166.858}</code> as seen below:</p>
203
204 <figure>
205 <img src="{{static}}/images/app_codelab/alarms-getAll-console.png" alt="Use ge tAll() to inspect running alarms."/>
206 </figure>
207
208 <h3 id="next-section">Get ready for the next section</h3>
209
210 <p>Now that we have alarms in place to poll our app at regular intervals, we can use it as a base for adding visual notifications &mdash; which is exactly what we'll do in the next section.</p>
211
212 <h2 id="notifications">Add notifications</h2>
213
214 <p>Let's change the alarm notification to something the user can easily notice.
215 For that purpose, we will use <a href="/apps/notifications"><code>chrome.notific ations</code></a>
216 to show a desktop notification like the one below:</p>
217
218 <figure>
219 <img src="{{static}}/images/app_codelab/notification-example.png" alt="Our Tod o app notification"/>
220 </figure>
221
222 <p>When the user clicks on the notification, we will bring the Todo app window i nto view.</p>
223
224 <h3 id="update-permissions-notifications">Update app permissions</h3>
225
226 <p>In <strong><em>manifest.json</em></strong>, request the <code>"notifications" </code> permission:</p>
227
228 <pre data-filename="manifest.json">
229 "permissions": ["storage", "alarms"<b>, "notifications"</b>],
230 </pre>
231
232 <h3 id="update-background-script-notifications">Update background scripts</h3>
233
234 <p>In <strong><em>background.js</em></strong>, refactor the <code>chrome.app.win dow.create()</code> callback into a standalone method so we can reuse it:</p>
235
236 <pre data-filename="background.js">
237 <strike>chrome.app.runtime.onLaunched.addListener(function() {</strike>
238 <b>function launch() {</b>
239 chrome.app.window.create('index.html', {
240 id: 'main',
241 bounds: { width: 620, height: 500 }
242 });
243 <b>}</b>
244 <strike>});</strike>
245 <b>chrome.app.runtime.onLaunched.addListener(launch);</b>
246 ...
247 </pre>
248
249 <h3 id="update-alarm-listener">Update alarm listener</h3>
250
251 <p>At the top of the <em>background.js</em>, add a variable for a database name that we'll use in our alarm listener:</p>
252
253 <pre data-filename="background.js">
254 <b>var dbName = 'todos-vanillajs';</b>
255 </pre>
256
257 <p>The value of <code>dbName</code> is the same database name we set in line 17 of <em>js/app.js</em>:</p>
258
259 <pre data-filename="app.js">
260 var todo = new Todo('todos-vanillajs');
261 </pre>
262
263 <h3 id="create-notification">Create a notification</h3>
264
265 <p>Instead of simply logging a new alarm to the Console, update the <code>onAlar m</code> listener
266 to get stored data via <code>chrome.storage.local.get()</code> and call a <code> showNotification()</code>
267 method that we'll make in the following step:</p>
268
269 <pre data-filename="background.js">
270 chrome.alarms.onAlarm.addListener(function( alarm ) {
271 <strike>console.log("Got an alarm!", alarm);</strike>
272 <b>chrome.storage.local.get(dbName, showNotification);</b>
273 });
274 </pre>
275
276 <p>Add this <code>showNotification()</code> method to <em>background.js</em>:</p >
277
278 <pre data-filename="background.js">
279 function launch(){
280 ...
281 }
282
283 <b>function showNotification(storedData) {
284 var openTodos = 0;
285 if ( storedData[dbName].todos ) {
286 storedData[dbName].todos.forEach(function(todo) {
287 if ( !todo.completed ) {
288 openTodos++;
289 }
290 });
291 }
292 if (openTodos>0) {
293 // Now create the notification
294 chrome.notifications.create('reminder', {
295 type: 'basic',
296 iconUrl: 'icon_128.png',
297 title: 'Don\'t forget!',
298 message: 'You have '+openTodos+' things to do. Wake up, dude!'
299 }, function(notificationId) {});
300 }
301 }</b>
302
303 chrome.app.runtime.onLaunched.addListener(launch);
304 ...
305 </pre>
306
307 <p><code>showNotification()</code> will check for open (uncompleted) todo items. If there is at least one open todo item, create a notification popup via <a hre f="/apps/notifications#method-create"><code>chrome.notifications.create()</code> </a>.</p>
308
309 <p>The first parameter is an uniquely identifying notification name. You must ha ve an id set in order to clear or handle interactions with that particular notif ication. If the id matches an existing notification, <code>create()</code> first clears that notification before making a new notification.</p>
310
311 <p>The second parameter is a <a href="/apps/notifications#type-NotificationOptio ns"><code>NotificationOptions</code></a> object. There are many options for rend ering the notification popup. Here we are using a "basic" notification with an i con, title, and message. Other notification types include images, lists, and pro gress indicators. Feel free to return to this section when you are done Step 3 a nd experiment with other notification features.</p>
312
313 <p>The third (optional) parameter is a callback method that should take on the f ormat:</p>
314
315 <pre>
316 function(string notificationId) {...};
317 </pre>
318
319 <h3 id="interact-with-notification">Handle notification interactions</h3>
320
321 <p>Open the Todo app when the user clicks on the notification. At the end of <em >background.js</em>, create a <a href="/apps/notifications#event-onClicked"><cod e>chrome.notifications.onClicked</code></a> event handler:</p>
322
323 <pre data-filename="background.js">
324 <b>chrome.notifications.onClicked.addListener(function() {
325 launch();
326 });</b>
327 </pre>
328
329 <p>The event handler callback simply calls the <code>launch()</code> method that we refactored earlier. <code>chrome.app.window.create()</code> will either crea te a new Chrome App window if one doesn't already exist, or bring into focus the currently open window that has the window id of <code>main</code>.</p>
330
331 <!-- <h3 id="clear-notification">Clear the notification</h3>
332
333 <p style="color: red;">You might notice that the notification popup does not go away after we click on it. The <code>onClicked</code> event handler callback pas ses along the id name of the popup that was interacted with. Use that, in combin ation with <a href=""><code>chrome.notifications.clear()</code></a>, to dismiss the notification:</p>
334
335 <pre data-filename="background.js">
336 chrome.notifications.onClicked.addListener(
337 function(<b> notificationId </b>) {
338 launch();
339 <b>chrome.notifications.clear(notificationId, function() {});</b>
340 }
341 );
342 </pre> -->
343
344 <!-- <h3 id="rich-notifications">Learn more about rich notifications</h3>
345
346 <p>For additional information about notifications, refer to <a href="/apps/deskt op_notifications">Rich Notifications</a> in the docs.</p> -->
347
348 <h2 id="launch">Launch your finished Todo app</h2>
349
350 <p>You are done Step 3! Reload your app and you should now have a Todo app with reminders.</p>
351
352 <figure>
353 <img src="{{static}}/images/app_codelab/step3-completed.gif" alt="The Todo app with notifications"/>
354 </figure>
355
356 <p>You should notice that:</p>
357
358 <ul>
359 <li>If you don't have any uncompleted todo items, there are no popup notificat ions.</li>
360 <li>If you click on the notification when your app is closed, the Todo app wil l
361 open or come into focus.</li>
362 </ul>
363
364 <h3 id="troubleshooting">Troubleshooting</h3>
365
366 <p>Your final <em>background.js</em> file should look like
367 <a href="https://github.com/mangini/io13-codelab/blob/master/cheat_code/solution _for_step3/background.js">this</a>. If notifications are not showing up, confirm that your Chrome is version 28 or
368 higher. If notifications still don't show up, check for error messages in the
369 DevTools Console on both the main window (<strong>right click > Inspect Element< /strong>) and the
370 background page (<strong>right click > Inspect Background Page</strong>).</p>
371
372 <h2 id="recap">Recap APIs referenced in this step</h2>
373
374 <p>For more detailed information about some of the APIs introduced in this step, refer to:</p>
375
376 <ul>
377 <li>
378 <a href="/apps/declare_permissions" title="Read 'Declare Permissions' in the Chrome developer docs">Declare Permissions</a>
379 <a href="#update-permissions-alarms" class="anchor-link-icon" title="This fe ature mentioned in 'Update app permissions for alarms'">&#8593;</a> <a href="#up date-permissions-notifications" class="anchor-link-icon" title="This feature men tioned in 'Update app permissions for notifications'">&#8593;</a>
380 </li>
381 <li>
382 <a href="/apps/alarms.html" title="Read 'chrome.alarms' in the Chrome develo per docs">chrome.alarms</a>
383 <a href="#alarms" class="anchor-link-icon" title="This feature mentioned in 'Add alarm reminders'">&#8593;</a>
384 </li>
385 <li>
386 <a href="/apps/alarms#event-onAlarm" title="Read 'chrome.alarms.onAlarm' in the Chrome developer docs">chrome.alarms.onAlarm</a>
387 <a href="#update-background-script-alarms" class="anchor-link-icon" title="T his feature mentioned in ''">&#8593;</a>
388 </li>
389 <li>
390 <a href="/apps/alarms#method-create" title="Read 'chrome.alarms.create()' in the Chrome developer docs">chrome.alarms.create()</a>
391 <a href="#create-alarms" class="anchor-link-icon" title="This feature mentio ned in 'Create alarms'">&#8593;</a>
392 </li>
393 <li>
394 <a href="/apps/alarms#method-clear" title="Read 'chrome.alarms.clear()' in t he Chrome developer docs">chrome.alarms.clear()</a>
395 <a href="#clear-alarms" class="anchor-link-icon" title="This feature mention ed in 'Clear alarms'">&#8593;</a>
396 </li>
397 <li>
398 <a href="/apps/alarms#method-getAll" title="Read 'chrome.alarms.getAll()' in the Chrome developer docs">chrome.alarms.getAll()</a>
399 <a href="#get-alarms" class="anchor-link-icon" title="This feature mentioned in 'Get alarms'">&#8593;</a>
400 </li>
401 <li>
402 <a href="/apps/notifications" title="Read 'chrome.notifications' in the Chro me developer docs">chrome.notifications</a>
403 <a href="#notifications" class="anchor-link-icon" title="This feature mentio ned in 'Add notifications'">&#8593;</a>
404 </li>
405 <li>
406 <a href="/apps/notifications#method-create" title="Read 'chrome.notification s.create()' in the Chrome developer docs">chrome.notifications.create()</a>
407 <a href="#create-notification" class="anchor-link-icon" title="This feature mentioned in 'Create a notification'">&#8593;</a>
408 </li>
409 <li>
410 <a href="/apps/notifications#type-NotificationOptions" title="Read 'Notifica tionOptions' in the Chrome developer docs">NotificationOptions</a>
411 <a href="#create-notification" class="anchor-link-icon" title="This feature mentioned in 'Create a notification'">&#8593;</a>
412 </li>
413 <li>
414 <a href="/apps/notifications#event-onClicked" title="Read 'chrome.notificati ons.onClicked' in the Chrome developer docs">chrome.notifications.onClicked</a>
415 <a href="#interact-with-notification" class="anchor-link-icon" title="This f eature mentioned in 'Handle notification interactions'">&#8593;</a>
416 </li>
417 <!-- <li>
418 <a href="/apps/notifications" title="Read 'chrome.notifications.clear()' in the Chrome developer docs">chrome.notifications.clear()</a>
419 <a href="#clear-notification" class="anchor-link-icon" title="This feature m entioned in 'Clear the notification'">&#8593;</a>
420 </li> -->
421 <!-- <li>
422 <a href="/apps/desktop_notifications" title="Read 'Rich Notifications' in th e Chrome developer docs">Rich Notifications</a>
423 <a href="#rich-notifications" class="anchor-link-icon" title="This feature m entioned in 'Learn more about rich notifications'">&#8593;</a>
424 </li> -->
425 </ul>
426
427 <p>Ready to continue onto the next step? Go to <a href="app_codelab_webview.html ">Step 4 - Open external links with a webview &raquo;</a></p>
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698