-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathlocation.html
More file actions
620 lines (582 loc) · 62.3 KB
/
location.html
File metadata and controls
620 lines (582 loc) · 62.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Android Development: Lecture Notes</title>
<meta name="description" content="Lecture Notes for INFO 448: Android Development.">
<meta name="generator" content="bookdown 0.5 and GitBook 2.6.7">
<meta property="og:title" content="Android Development: Lecture Notes" />
<meta property="og:type" content="book" />
<meta property="og:url" content="https://info448.github.io/" />
<meta property="og:image" content="https://info448.github.io/img/android_icon_transparent.png" />
<meta property="og:description" content="Lecture Notes for INFO 448: Android Development." />
<meta name="github-repo" content="info448/book" />
<meta name="twitter:card" content="summary" />
<meta name="twitter:title" content="Android Development: Lecture Notes" />
<meta name="twitter:description" content="Lecture Notes for INFO 448: Android Development." />
<meta name="twitter:image" content="https://info448.github.io/img/android_icon_transparent.png" />
<meta name="author" content="Joel Ross">
<meta name="date" content="2018-11-19">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<link rel="shortcut icon" href="img/android_icon_transparent.png" type="image/x-icon">
<link rel="prev" href="databases.html">
<link rel="next" href="services.html">
<script src="libs/jquery-2.2.3/jquery.min.js"></script>
<link href="libs/gitbook-2.6.7/css/style.css" rel="stylesheet" />
<link href="libs/gitbook-2.6.7/css/plugin-bookdown.css" rel="stylesheet" />
<link href="libs/gitbook-2.6.7/css/plugin-highlight.css" rel="stylesheet" />
<link href="libs/gitbook-2.6.7/css/plugin-search.css" rel="stylesheet" />
<link href="libs/gitbook-2.6.7/css/plugin-fontsettings.css" rel="stylesheet" />
<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-98444716-1', 'auto');
ga('send', 'pageview');
</script>
<style type="text/css">
div.sourceCode { overflow-x: auto; }
table.sourceCode, tr.sourceCode, td.lineNumbers, td.sourceCode {
margin: 0; padding: 0; vertical-align: baseline; border: none; }
table.sourceCode { width: 100%; line-height: 100%; }
td.lineNumbers { text-align: right; padding-right: 4px; padding-left: 4px; color: #aaaaaa; border-right: 1px solid #aaaaaa; }
td.sourceCode { padding-left: 5px; }
code > span.kw { color: #007020; font-weight: bold; } /* Keyword */
code > span.dt { color: #902000; } /* DataType */
code > span.dv { color: #40a070; } /* DecVal */
code > span.bn { color: #40a070; } /* BaseN */
code > span.fl { color: #40a070; } /* Float */
code > span.ch { color: #4070a0; } /* Char */
code > span.st { color: #4070a0; } /* String */
code > span.co { color: #60a0b0; font-style: italic; } /* Comment */
code > span.ot { color: #007020; } /* Other */
code > span.al { color: #ff0000; font-weight: bold; } /* Alert */
code > span.fu { color: #06287e; } /* Function */
code > span.er { color: #ff0000; font-weight: bold; } /* Error */
code > span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */
code > span.cn { color: #880000; } /* Constant */
code > span.sc { color: #4070a0; } /* SpecialChar */
code > span.vs { color: #4070a0; } /* VerbatimString */
code > span.ss { color: #bb6688; } /* SpecialString */
code > span.im { } /* Import */
code > span.va { color: #19177c; } /* Variable */
code > span.cf { color: #007020; font-weight: bold; } /* ControlFlow */
code > span.op { color: #666666; } /* Operator */
code > span.bu { } /* BuiltIn */
code > span.ex { } /* Extension */
code > span.pp { color: #bc7a00; } /* Preprocessor */
code > span.at { color: #7d9029; } /* Attribute */
code > span.do { color: #ba2121; font-style: italic; } /* Documentation */
code > span.an { color: #60a0b0; font-weight: bold; font-style: italic; } /* Annotation */
code > span.cv { color: #60a0b0; font-weight: bold; font-style: italic; } /* CommentVar */
code > span.in { color: #60a0b0; font-weight: bold; font-style: italic; } /* Information */
</style>
<link rel="stylesheet" href="css/style.css" type="text/css" />
</head>
<body>
<div class="book without-animation with-summary font-size-2 font-family-1" data-basepath=".">
<div class="book-summary">
<nav role="navigation">
<ul class="summary">
<li><a href="./" class="title">Android Development</a></li>
<li class="divider"></li>
<li class="chapter" data-level="" data-path="index.html"><a href="index.html"><i class="fa fa-check"></i>About this Book</a></li>
<li class="part"><span><b>I Lectures</b></span></li>
<li class="chapter" data-level="1" data-path="introduction.html"><a href="introduction.html"><i class="fa fa-check"></i><b>1</b> Introduction</a><ul>
<li class="chapter" data-level="1.1" data-path="introduction.html"><a href="introduction.html#android-history"><i class="fa fa-check"></i><b>1.1</b> Android History</a><ul>
<li class="chapter" data-level="" data-path="introduction.html"><a href="introduction.html#android-versions"><i class="fa fa-check"></i>Android Versions</a></li>
<li class="chapter" data-level="" data-path="introduction.html"><a href="introduction.html#legal-battles"><i class="fa fa-check"></i>Legal Battles</a></li>
</ul></li>
<li class="chapter" data-level="1.2" data-path="introduction.html"><a href="introduction.html#building-apps"><i class="fa fa-check"></i><b>1.2</b> Building Apps</a><ul>
<li class="chapter" data-level="" data-path="introduction.html"><a href="introduction.html#creating-a-project"><i class="fa fa-check"></i>Creating a Project</a></li>
<li class="chapter" data-level="" data-path="introduction.html"><a href="introduction.html#running-the-app"><i class="fa fa-check"></i>Running the App</a></li>
</ul></li>
<li class="chapter" data-level="1.3" data-path="introduction.html"><a href="introduction.html#app-source-code"><i class="fa fa-check"></i><b>1.3</b> App Source Code</a><ul>
<li class="chapter" data-level="" data-path="introduction.html"><a href="introduction.html#xml-resources"><i class="fa fa-check"></i>XML Resources</a></li>
<li class="chapter" data-level="" data-path="introduction.html"><a href="introduction.html#the-manifest"><i class="fa fa-check"></i>The Manifest</a></li>
<li class="chapter" data-level="" data-path="introduction.html"><a href="introduction.html#java-activities"><i class="fa fa-check"></i>Java Activities</a></li>
<li class="chapter" data-level="" data-path="introduction.html"><a href="introduction.html#gradle-scripts"><i class="fa fa-check"></i>Gradle Scripts</a></li>
</ul></li>
<li class="chapter" data-level="1.4" data-path="introduction.html"><a href="introduction.html#logging-adb"><i class="fa fa-check"></i><b>1.4</b> Logging & ADB</a><ul>
<li class="chapter" data-level="" data-path="introduction.html"><a href="introduction.html#log-methods"><i class="fa fa-check"></i>Log Methods</a></li>
<li class="chapter" data-level="" data-path="introduction.html"><a href="introduction.html#logcat"><i class="fa fa-check"></i>Logcat</a></li>
<li class="chapter" data-level="" data-path="introduction.html"><a href="introduction.html#toast"><i class="fa fa-check"></i>Toast</a></li>
</ul></li>
<li class="chapter" data-level="1.5" data-path="introduction.html"><a href="introduction.html#adding-interaction"><i class="fa fa-check"></i><b>1.5</b> Adding Interaction</a></li>
<li class="chapter" data-level="1.6" data-path="introduction.html"><a href="introduction.html#kotlin-setup"><i class="fa fa-check"></i><b>1.6</b> Kotlin</a></li>
</ul></li>
<li class="chapter" data-level="2" data-path="resources-and-layouts.html"><a href="resources-and-layouts.html"><i class="fa fa-check"></i><b>2</b> Resources and Layouts</a><ul>
<li class="chapter" data-level="2.1" data-path="resources-and-layouts.html"><a href="resources-and-layouts.html#resources"><i class="fa fa-check"></i><b>2.1</b> Resources</a><ul>
<li class="chapter" data-level="" data-path="resources-and-layouts.html"><a href="resources-and-layouts.html#r"><i class="fa fa-check"></i>R</a></li>
<li class="chapter" data-level="" data-path="resources-and-layouts.html"><a href="resources-and-layouts.html#alternative-resources"><i class="fa fa-check"></i>Alternative Resources</a></li>
</ul></li>
<li class="chapter" data-level="2.2" data-path="resources-and-layouts.html"><a href="resources-and-layouts.html#views"><i class="fa fa-check"></i><b>2.2</b> Views</a><ul>
<li class="chapter" data-level="" data-path="resources-and-layouts.html"><a href="resources-and-layouts.html#view-properties"><i class="fa fa-check"></i>View Properties</a></li>
<li class="chapter" data-level="" data-path="resources-and-layouts.html"><a href="resources-and-layouts.html#views-and-java"><i class="fa fa-check"></i>Views and Java</a></li>
<li class="chapter" data-level="" data-path="resources-and-layouts.html"><a href="resources-and-layouts.html#practice"><i class="fa fa-check"></i>Practice</a></li>
</ul></li>
<li class="chapter" data-level="2.3" data-path="resources-and-layouts.html"><a href="resources-and-layouts.html#layouts"><i class="fa fa-check"></i><b>2.3</b> Layouts</a><ul>
<li class="chapter" data-level="" data-path="resources-and-layouts.html"><a href="resources-and-layouts.html#linearlayout"><i class="fa fa-check"></i>LinearLayout</a></li>
<li class="chapter" data-level="" data-path="resources-and-layouts.html"><a href="resources-and-layouts.html#relativelayout"><i class="fa fa-check"></i>RelativeLayout</a></li>
<li class="chapter" data-level="" data-path="resources-and-layouts.html"><a href="resources-and-layouts.html#constraintlayout"><i class="fa fa-check"></i>ConstraintLayout</a></li>
<li class="chapter" data-level="" data-path="resources-and-layouts.html"><a href="resources-and-layouts.html#other-layouts"><i class="fa fa-check"></i>Other Layouts</a></li>
<li class="chapter" data-level="" data-path="resources-and-layouts.html"><a href="resources-and-layouts.html#combining-and-inflating-layouts"><i class="fa fa-check"></i>Combining and Inflating Layouts</a></li>
</ul></li>
<li class="chapter" data-level="2.4" data-path="resources-and-layouts.html"><a href="resources-and-layouts.html#inputs"><i class="fa fa-check"></i><b>2.4</b> Inputs</a></li>
</ul></li>
<li class="chapter" data-level="3" data-path="activities.html"><a href="activities.html"><i class="fa fa-check"></i><b>3</b> Activities</a><ul>
<li class="chapter" data-level="3.1" data-path="activities.html"><a href="activities.html#making-activities"><i class="fa fa-check"></i><b>3.1</b> Making Activities</a></li>
<li class="chapter" data-level="3.2" data-path="activities.html"><a href="activities.html#the-activity-lifecycle"><i class="fa fa-check"></i><b>3.2</b> The Activity Lifecycle</a><ul>
<li class="chapter" data-level="" data-path="activities.html"><a href="activities.html#overriding-the-callback-methods"><i class="fa fa-check"></i>Overriding the Callback Methods</a></li>
<li class="chapter" data-level="" data-path="activities.html"><a href="activities.html#saving-and-restoring-activity-state"><i class="fa fa-check"></i>Saving and Restoring Activity State</a></li>
</ul></li>
<li class="chapter" data-level="3.3" data-path="activities.html"><a href="activities.html#context"><i class="fa fa-check"></i><b>3.3</b> Context</a></li>
<li class="chapter" data-level="3.4" data-path="activities.html"><a href="activities.html#multiple-activities"><i class="fa fa-check"></i><b>3.4</b> Multiple Activities</a><ul>
<li class="chapter" data-level="" data-path="activities.html"><a href="activities.html#activity-intents"><i class="fa fa-check"></i>Intents</a></li>
<li class="chapter" data-level="" data-path="activities.html"><a href="activities.html#back-tasks"><i class="fa fa-check"></i>Back & Tasks</a></li>
<li class="chapter" data-level="" data-path="activities.html"><a href="activities.html#up-navigation"><i class="fa fa-check"></i>Up Navigation</a></li>
</ul></li>
</ul></li>
<li class="chapter" data-level="4" data-path="data-views.html"><a href="data-views.html"><i class="fa fa-check"></i><b>4</b> Data-Driven Views</a><ul>
<li class="chapter" data-level="4.1" data-path="data-views.html"><a href="data-views.html#listviews-and-adapters"><i class="fa fa-check"></i><b>4.1</b> ListViews and Adapters</a></li>
<li class="chapter" data-level="4.2" data-path="data-views.html"><a href="data-views.html#networking-with-volley"><i class="fa fa-check"></i><b>4.2</b> Networking with Volley</a><ul>
<li class="chapter" data-level="" data-path="data-views.html"><a href="data-views.html#using-volley"><i class="fa fa-check"></i>Using Volley</a></li>
<li class="chapter" data-level="" data-path="data-views.html"><a href="data-views.html#requestqueue-singletons"><i class="fa fa-check"></i>RequestQueue Singletons</a></li>
<li class="chapter" data-level="" data-path="data-views.html"><a href="data-views.html#downloading-images"><i class="fa fa-check"></i>Downloading Images</a></li>
</ul></li>
</ul></li>
<li class="chapter" data-level="5" data-path="material-design.html"><a href="material-design.html"><i class="fa fa-check"></i><b>5</b> Material Design</a><ul>
<li class="chapter" data-level="5.1" data-path="material-design.html"><a href="material-design.html#the-material-design-language"><i class="fa fa-check"></i><b>5.1</b> The Material Design Language</a></li>
<li class="chapter" data-level="5.2" data-path="material-design.html"><a href="material-design.html#material-styles-icons"><i class="fa fa-check"></i><b>5.2</b> Material Styles & Icons</a></li>
<li class="chapter" data-level="5.3" data-path="material-design.html"><a href="material-design.html#design-support-libraries"><i class="fa fa-check"></i><b>5.3</b> Design Support Libraries</a><ul>
<li class="chapter" data-level="" data-path="material-design.html"><a href="material-design.html#widgets"><i class="fa fa-check"></i>Widgets</a></li>
<li class="chapter" data-level="" data-path="material-design.html"><a href="material-design.html#coordinator-layout"><i class="fa fa-check"></i>Coordinator Layout</a></li>
</ul></li>
<li class="chapter" data-level="5.4" data-path="material-design.html"><a href="material-design.html#animations"><i class="fa fa-check"></i><b>5.4</b> Animations</a></li>
<li class="chapter" data-level="" data-path="material-design.html"><a href="material-design.html#resources-1"><i class="fa fa-check"></i>Resources</a></li>
</ul></li>
<li class="chapter" data-level="6" data-path="fragments.html"><a href="fragments.html"><i class="fa fa-check"></i><b>6</b> Fragments</a><ul>
<li class="chapter" data-level="6.1" data-path="fragments.html"><a href="fragments.html#creating-a-fragment"><i class="fa fa-check"></i><b>6.1</b> Creating a Fragment</a><ul>
<li class="chapter" data-level="" data-path="fragments.html"><a href="fragments.html#activity-to-fragment-communication"><i class="fa fa-check"></i>Activity-to-Fragment Communication</a></li>
</ul></li>
<li class="chapter" data-level="6.2" data-path="fragments.html"><a href="fragments.html#dynamic-fragments"><i class="fa fa-check"></i><b>6.2</b> Dynamic Fragments</a><ul>
<li class="chapter" data-level="" data-path="fragments.html"><a href="fragments.html#instantiating-fragments"><i class="fa fa-check"></i>Instantiating Fragments</a></li>
<li class="chapter" data-level="" data-path="fragments.html"><a href="fragments.html#transactions"><i class="fa fa-check"></i>Transactions</a></li>
<li class="chapter" data-level="" data-path="fragments.html"><a href="fragments.html#inter-fragment-communication"><i class="fa fa-check"></i>Inter-Fragment Communication</a></li>
<li class="chapter" data-level="" data-path="fragments.html"><a href="fragments.html#the-back-stack"><i class="fa fa-check"></i>The Back Stack</a></li>
</ul></li>
</ul></li>
<li class="chapter" data-level="7" data-path="intents.html"><a href="intents.html"><i class="fa fa-check"></i><b>7</b> Intents</a><ul>
<li class="chapter" data-level="7.1" data-path="intents.html"><a href="intents.html#intents-for-another-activity-explicit"><i class="fa fa-check"></i><b>7.1</b> Intents for Another Activity (Explicit)</a><ul>
<li class="chapter" data-level="" data-path="intents.html"><a href="intents.html#extras"><i class="fa fa-check"></i>Extras</a></li>
</ul></li>
<li class="chapter" data-level="7.2" data-path="intents.html"><a href="intents.html#intents-for-another-app-implicit"><i class="fa fa-check"></i><b>7.2</b> Intents for Another App (Implicit)</a></li>
<li class="chapter" data-level="7.3" data-path="intents.html"><a href="intents.html#intents-for-a-response"><i class="fa fa-check"></i><b>7.3</b> Intents for a Response</a></li>
<li class="chapter" data-level="7.4" data-path="intents.html"><a href="intents.html#listening-for-intents"><i class="fa fa-check"></i><b>7.4</b> Listening for Intents</a></li>
<li class="chapter" data-level="7.5" data-path="intents.html"><a href="intents.html#broadcasts-and-receivers"><i class="fa fa-check"></i><b>7.5</b> Broadcasts and Receivers</a></li>
<li class="chapter" data-level="7.6" data-path="intents.html"><a href="intents.html#menus"><i class="fa fa-check"></i><b>7.6</b> Menus</a><ul>
<li class="chapter" data-level="" data-path="intents.html"><a href="intents.html#action-views"><i class="fa fa-check"></i>Action Views</a></li>
<li class="chapter" data-level="" data-path="intents.html"><a href="intents.html#context-menus"><i class="fa fa-check"></i>Context Menus</a></li>
</ul></li>
<li class="chapter" data-level="7.7" data-path="intents.html"><a href="intents.html#an-intent-example-sms"><i class="fa fa-check"></i><b>7.7</b> An Intent Example: SMS</a></li>
</ul></li>
<li class="chapter" data-level="8" data-path="notifications-settings.html"><a href="notifications-settings.html"><i class="fa fa-check"></i><b>8</b> Notifications & Settings</a><ul>
<li class="chapter" data-level="8.1" data-path="notifications-settings.html"><a href="notifications-settings.html#dialogs"><i class="fa fa-check"></i><b>8.1</b> Dialogs</a><ul>
<li class="chapter" data-level="" data-path="notifications-settings.html"><a href="notifications-settings.html#dialogfragments"><i class="fa fa-check"></i>DialogFragments</a></li>
</ul></li>
<li class="chapter" data-level="8.2" data-path="notifications-settings.html"><a href="notifications-settings.html#notifications"><i class="fa fa-check"></i><b>8.2</b> Notifications</a><ul>
<li class="chapter" data-level="8.2.1" data-path="notifications-settings.html"><a href="notifications-settings.html#tap-actions"><i class="fa fa-check"></i><b>8.2.1</b> Tap Actions</a></li>
</ul></li>
<li class="chapter" data-level="8.3" data-path="notifications-settings.html"><a href="notifications-settings.html#settings"><i class="fa fa-check"></i><b>8.3</b> Settings</a><ul>
<li class="chapter" data-level="" data-path="notifications-settings.html"><a href="notifications-settings.html#sharedpreferences"><i class="fa fa-check"></i>SharedPreferences</a></li>
<li class="chapter" data-level="" data-path="notifications-settings.html"><a href="notifications-settings.html#preference-settings"><i class="fa fa-check"></i>Preference Settings</a></li>
</ul></li>
</ul></li>
<li class="chapter" data-level="9" data-path="loaders.html"><a href="loaders.html"><i class="fa fa-check"></i><b>9</b> Providers and Loaders</a><ul>
<li class="chapter" data-level="9.1" data-path="loaders.html"><a href="loaders.html#content-providers-intro"><i class="fa fa-check"></i><b>9.1</b> Content Providers</a></li>
<li class="chapter" data-level="9.2" data-path="loaders.html"><a href="loaders.html#cursors"><i class="fa fa-check"></i><b>9.2</b> Cursors</a></li>
<li class="chapter" data-level="9.3" data-path="loaders.html"><a href="loaders.html#loaders"><i class="fa fa-check"></i><b>9.3</b> Loaders</a></li>
<li class="chapter" data-level="9.4" data-path="loaders.html"><a href="loaders.html#other-provider-actions"><i class="fa fa-check"></i><b>9.4</b> Other Provider Actions</a></li>
</ul></li>
<li class="chapter" data-level="10" data-path="files-and-permissions.html"><a href="files-and-permissions.html"><i class="fa fa-check"></i><b>10</b> Files and Permissions</a><ul>
<li class="chapter" data-level="10.1" data-path="files-and-permissions.html"><a href="files-and-permissions.html#file-storage-locations"><i class="fa fa-check"></i><b>10.1</b> File Storage Locations</a></li>
<li class="chapter" data-level="10.2" data-path="files-and-permissions.html"><a href="files-and-permissions.html#permissions"><i class="fa fa-check"></i><b>10.2</b> Permissions</a></li>
<li class="chapter" data-level="10.3" data-path="files-and-permissions.html"><a href="files-and-permissions.html#external-storage"><i class="fa fa-check"></i><b>10.3</b> External Storage</a></li>
<li class="chapter" data-level="10.4" data-path="files-and-permissions.html"><a href="files-and-permissions.html#internal-storage-cache"><i class="fa fa-check"></i><b>10.4</b> Internal Storage & Cache</a></li>
<li class="chapter" data-level="10.5" data-path="files-and-permissions.html"><a href="files-and-permissions.html#example-saving-pictures"><i class="fa fa-check"></i><b>10.5</b> Example: Saving Pictures</a><ul>
<li class="chapter" data-level="10.5.1" data-path="files-and-permissions.html"><a href="files-and-permissions.html#fileproviders"><i class="fa fa-check"></i><b>10.5.1</b> FileProviders</a></li>
</ul></li>
<li class="chapter" data-level="10.6" data-path="files-and-permissions.html"><a href="files-and-permissions.html#sharing-files"><i class="fa fa-check"></i><b>10.6</b> Sharing Files</a></li>
</ul></li>
<li class="chapter" data-level="11" data-path="databases.html"><a href="databases.html"><i class="fa fa-check"></i><b>11</b> Providers and Databases</a><ul>
<li class="chapter" data-level="11.1" data-path="databases.html"><a href="databases.html#review-providers-and-loaders"><i class="fa fa-check"></i><b>11.1</b> Review: Providers and Loaders</a></li>
<li class="chapter" data-level="11.2" data-path="databases.html"><a href="databases.html#sqlite-databases"><i class="fa fa-check"></i><b>11.2</b> SQLite Databases</a></li>
<li class="chapter" data-level="11.3" data-path="databases.html"><a href="databases.html#implementing-a-contentprovider"><i class="fa fa-check"></i><b>11.3</b> Implementing a ContentProvider</a><ul>
<li class="chapter" data-level="" data-path="databases.html"><a href="databases.html#uris-and-types"><i class="fa fa-check"></i>URIs and Types</a></li>
<li class="chapter" data-level="" data-path="databases.html"><a href="databases.html#query-methods"><i class="fa fa-check"></i>Query Methods</a></li>
</ul></li>
</ul></li>
<li class="chapter" data-level="12" data-path="location.html"><a href="location.html"><i class="fa fa-check"></i><b>12</b> Location</a><ul>
<li class="chapter" data-level="12.1" data-path="location.html"><a href="location.html#localization-techniques"><i class="fa fa-check"></i><b>12.1</b> Localization Techniques</a><ul>
<li class="chapter" data-level="" data-path="location.html"><a href="location.html#gps"><i class="fa fa-check"></i>GPS</a></li>
<li class="chapter" data-level="" data-path="location.html"><a href="location.html#cell-tower-localization"><i class="fa fa-check"></i>Cell Tower Localization</a></li>
<li class="chapter" data-level="" data-path="location.html"><a href="location.html#wifi-localization"><i class="fa fa-check"></i>WiFi Localization</a></li>
<li class="chapter" data-level="" data-path="location.html"><a href="location.html#representing-location"><i class="fa fa-check"></i>Representing Location</a></li>
</ul></li>
<li class="chapter" data-level="12.2" data-path="location.html"><a href="location.html#android-location"><i class="fa fa-check"></i><b>12.2</b> Android Location</a><ul>
<li class="chapter" data-level="" data-path="location.html"><a href="location.html#google-play-services"><i class="fa fa-check"></i>Google Play Services</a></li>
<li class="chapter" data-level="" data-path="location.html"><a href="location.html#accessing-location"><i class="fa fa-check"></i>Accessing Location</a></li>
</ul></li>
</ul></li>
<li class="chapter" data-level="13" data-path="services.html"><a href="services.html"><i class="fa fa-check"></i><b>13</b> Threads and Services</a><ul>
<li class="chapter" data-level="13.1" data-path="services.html"><a href="services.html#threads-and-processes"><i class="fa fa-check"></i><b>13.1</b> Threads and Processes</a><ul>
<li class="chapter" data-level="" data-path="services.html"><a href="services.html#java-threads"><i class="fa fa-check"></i>Java Threads</a></li>
<li class="chapter" data-level="" data-path="services.html"><a href="services.html#android-threads"><i class="fa fa-check"></i>Android Threads</a></li>
</ul></li>
<li class="chapter" data-level="13.2" data-path="services.html"><a href="services.html#intentservices"><i class="fa fa-check"></i><b>13.2</b> IntentServices</a><ul>
<li class="chapter" data-level="" data-path="services.html"><a href="services.html#the-service-lifecycle"><i class="fa fa-check"></i>The Service Lifecycle</a></li>
</ul></li>
<li class="chapter" data-level="13.3" data-path="services.html"><a href="services.html#example-a-music-service"><i class="fa fa-check"></i><b>13.3</b> Example: A Music Service</a><ul>
<li class="chapter" data-level="" data-path="services.html"><a href="services.html#mediaplayer"><i class="fa fa-check"></i>MediaPlayer</a></li>
<li class="chapter" data-level="" data-path="services.html"><a href="services.html#creating-a-service"><i class="fa fa-check"></i>Creating a Service</a></li>
</ul></li>
<li class="chapter" data-level="13.4" data-path="services.html"><a href="services.html#foreground-services"><i class="fa fa-check"></i><b>13.4</b> Foreground Services</a></li>
<li class="chapter" data-level="13.5" data-path="services.html"><a href="services.html#bound-services"><i class="fa fa-check"></i><b>13.5</b> Bound Services</a></li>
</ul></li>
<li class="chapter" data-level="14" data-path="sensors.html"><a href="sensors.html"><i class="fa fa-check"></i><b>14</b> Sensors</a><ul>
<li class="chapter" data-level="14.1" data-path="sensors.html"><a href="sensors.html#motion-sensors"><i class="fa fa-check"></i><b>14.1</b> Motion Sensors</a><ul>
<li class="chapter" data-level="" data-path="sensors.html"><a href="sensors.html#accessing-sensors"><i class="fa fa-check"></i>Accessing Sensors</a></li>
<li class="chapter" data-level="" data-path="sensors.html"><a href="sensors.html#composite-sensors"><i class="fa fa-check"></i>Composite Sensors</a></li>
</ul></li>
<li class="chapter" data-level="14.2" data-path="sensors.html"><a href="sensors.html#rotation"><i class="fa fa-check"></i><b>14.2</b> Rotation</a><ul>
<li class="chapter" data-level="" data-path="sensors.html"><a href="sensors.html#coordinates"><i class="fa fa-check"></i>Coordinates</a></li>
</ul></li>
</ul></li>
<li class="chapter" data-level="15" data-path="graphics.html"><a href="graphics.html"><i class="fa fa-check"></i><b>15</b> Graphics and Touch</a><ul>
<li class="chapter" data-level="15.1" data-path="graphics.html"><a href="graphics.html#drawing-graphics"><i class="fa fa-check"></i><b>15.1</b> Drawing Graphics</a><ul>
<li class="chapter" data-level="" data-path="graphics.html"><a href="graphics.html#custom-views"><i class="fa fa-check"></i>Custom Views</a></li>
<li class="chapter" data-level="" data-path="graphics.html"><a href="graphics.html#surfaceviews"><i class="fa fa-check"></i>SurfaceViews</a></li>
</ul></li>
<li class="chapter" data-level="15.2" data-path="graphics.html"><a href="graphics.html#touch-and-gestures"><i class="fa fa-check"></i><b>15.2</b> Touch and Gestures</a><ul>
<li class="chapter" data-level="" data-path="graphics.html"><a href="graphics.html#advanced-gestures"><i class="fa fa-check"></i>Advanced Gestures</a></li>
</ul></li>
<li class="chapter" data-level="15.3" data-path="graphics.html"><a href="graphics.html#property-animation"><i class="fa fa-check"></i><b>15.3</b> Property Animation</a></li>
</ul></li>
<li class="part"><span><b>II Additional Topics (Labs)</b></span></li>
<li class="chapter" data-level="16" data-path="styles-themes.html"><a href="styles-themes.html"><i class="fa fa-check"></i><b>16</b> Styles & Themes</a><ul>
<li class="chapter" data-level="16.1" data-path="styles-themes.html"><a href="styles-themes.html#defining-styles"><i class="fa fa-check"></i><b>16.1</b> Defining Styles</a><ul>
<li class="chapter" data-level="" data-path="styles-themes.html"><a href="styles-themes.html#style-inheritance"><i class="fa fa-check"></i>Style Inheritance</a></li>
<li class="chapter" data-level="" data-path="styles-themes.html"><a href="styles-themes.html#built-in-styles"><i class="fa fa-check"></i>Built-in Styles</a></li>
<li class="chapter" data-level="" data-path="styles-themes.html"><a href="styles-themes.html#styles-for-text-views"><i class="fa fa-check"></i>Styles for Text Views</a></li>
</ul></li>
<li class="chapter" data-level="16.2" data-path="styles-themes.html"><a href="styles-themes.html#themes"><i class="fa fa-check"></i><b>16.2</b> Themes</a><ul>
<li class="chapter" data-level="" data-path="styles-themes.html"><a href="styles-themes.html#material-themes"><i class="fa fa-check"></i>Material Themes</a></li>
<li class="chapter" data-level="" data-path="styles-themes.html"><a href="styles-themes.html#theme-attributes"><i class="fa fa-check"></i>Theme Attributes</a></li>
</ul></li>
<li class="chapter" data-level="" data-path="styles-themes.html"><a href="styles-themes.html#resources-2"><i class="fa fa-check"></i>Resources</a></li>
</ul></li>
<li class="chapter" data-level="17" data-path="fragment-viewpager.html"><a href="fragment-viewpager.html"><i class="fa fa-check"></i><b>17</b> Fragments: ViewPager</a><ul>
<li class="chapter" data-level="17.1" data-path="fragment-viewpager.html"><a href="fragment-viewpager.html#define-a-searchfragment"><i class="fa fa-check"></i><b>17.1</b> Define a SearchFragment</a></li>
<li class="chapter" data-level="17.2" data-path="fragment-viewpager.html"><a href="fragment-viewpager.html#add-the-viewpager-and-adapter"><i class="fa fa-check"></i><b>17.2</b> Add the ViewPager and Adapter</a></li>
<li class="chapter" data-level="17.3" data-path="fragment-viewpager.html"><a href="fragment-viewpager.html#add-user-interaction"><i class="fa fa-check"></i><b>17.3</b> Add User Interaction</a></li>
</ul></li>
<li class="chapter" data-level="18" data-path="bluetooth.html"><a href="bluetooth.html"><i class="fa fa-check"></i><b>18</b> Bluetooth</a></li>
<li class="chapter" data-level="19" data-path="maps.html"><a href="maps.html"><i class="fa fa-check"></i><b>19</b> Maps</a><ul>
<li class="chapter" data-level="19.1" data-path="maps.html"><a href="maps.html#create-a-map-activity"><i class="fa fa-check"></i><b>19.1</b> Create a Map Activity</a><ul>
<li class="chapter" data-level="" data-path="maps.html"><a href="maps.html#getting-an-api-key"><i class="fa fa-check"></i>Getting an API Key</a></li>
<li><a href="maps.html#the-supportmapfragment">The <code>SupportMapFragment</code></a></li>
</ul></li>
<li class="chapter" data-level="19.2" data-path="maps.html"><a href="maps.html#specifying-the-user-interface"><i class="fa fa-check"></i><b>19.2</b> Specifying the User Interface</a></li>
<li class="chapter" data-level="19.3" data-path="maps.html"><a href="maps.html#markers-and-drawings"><i class="fa fa-check"></i><b>19.3</b> Markers and Drawings</a><ul>
<li class="chapter" data-level="" data-path="maps.html"><a href="maps.html#drawing-shapes"><i class="fa fa-check"></i>Drawing Shapes</a></li>
</ul></li>
</ul></li>
<li class="chapter" data-level="20" data-path="memory.html"><a href="memory.html"><i class="fa fa-check"></i><b>20</b> Memory Management</a><ul>
<li class="chapter" data-level="20.1" data-path="memory.html"><a href="memory.html#memory-allocation"><i class="fa fa-check"></i><b>20.1</b> Memory Allocation</a></li>
<li class="chapter" data-level="20.2" data-path="memory.html"><a href="memory.html#the-memory-monitor"><i class="fa fa-check"></i><b>20.2</b> The Memory Monitor</a><ul>
<li class="chapter" data-level="" data-path="memory.html"><a href="memory.html#garbage-collection"><i class="fa fa-check"></i>Garbage Collection</a></li>
</ul></li>
<li class="chapter" data-level="20.3" data-path="memory.html"><a href="memory.html#memory-leaks"><i class="fa fa-check"></i><b>20.3</b> Memory Leaks</a></li>
</ul></li>
<li class="chapter" data-level="21" data-path="multi-touch.html"><a href="multi-touch.html"><i class="fa fa-check"></i><b>21</b> Multi-Touch</a><ul>
<li class="chapter" data-level="21.1" data-path="multi-touch.html"><a href="multi-touch.html#identifying-fingers"><i class="fa fa-check"></i><b>21.1</b> Identifying Fingers</a></li>
<li class="chapter" data-level="21.2" data-path="multi-touch.html"><a href="multi-touch.html#drawing-touches"><i class="fa fa-check"></i><b>21.2</b> Drawing Touches</a></li>
<li class="chapter" data-level="21.3" data-path="multi-touch.html"><a href="multi-touch.html#moving-fingers"><i class="fa fa-check"></i><b>21.3</b> Moving Fingers</a></li>
<li class="chapter" data-level="21.4" data-path="multi-touch.html"><a href="multi-touch.html#other-multi-touch-gestures"><i class="fa fa-check"></i><b>21.4</b> Other Multi-Touch Gestures</a></li>
</ul></li>
<li class="appendix"><span><b>Appendix</b></span></li>
<li class="chapter" data-level="A" data-path="java-review.html"><a href="java-review.html"><i class="fa fa-check"></i><b>A</b> Java Review</a><ul>
<li class="chapter" data-level="A.1" data-path="java-review.html"><a href="java-review.html#building-apps-with-gradle"><i class="fa fa-check"></i><b>A.1</b> Building Apps with Gradle</a></li>
<li class="chapter" data-level="A.2" data-path="java-review.html"><a href="java-review.html#class-basics"><i class="fa fa-check"></i><b>A.2</b> Class Basics</a></li>
<li class="chapter" data-level="A.3" data-path="java-review.html"><a href="java-review.html#inheritance"><i class="fa fa-check"></i><b>A.3</b> Inheritance</a></li>
<li class="chapter" data-level="A.4" data-path="java-review.html"><a href="java-review.html#interfaces"><i class="fa fa-check"></i><b>A.4</b> Interfaces</a></li>
<li class="chapter" data-level="A.5" data-path="java-review.html"><a href="java-review.html#polymorphism"><i class="fa fa-check"></i><b>A.5</b> Polymorphism</a></li>
<li class="chapter" data-level="A.6" data-path="java-review.html"><a href="java-review.html#abstract-methods-and-classes"><i class="fa fa-check"></i><b>A.6</b> Abstract Methods and Classes</a></li>
<li class="chapter" data-level="A.7" data-path="java-review.html"><a href="java-review.html#generics"><i class="fa fa-check"></i><b>A.7</b> Generics</a></li>
<li class="chapter" data-level="A.8" data-path="java-review.html"><a href="java-review.html#nested-classes"><i class="fa fa-check"></i><b>A.8</b> Nested Classes</a></li>
</ul></li>
<li class="chapter" data-level="B" data-path="java-swing.html"><a href="java-swing.html"><i class="fa fa-check"></i><b>B</b> Java Swing Framework</a><ul>
<li class="chapter" data-level="B.1" data-path="java-swing.html"><a href="java-swing.html#events"><i class="fa fa-check"></i><b>B.1</b> Events</a></li>
<li class="chapter" data-level="B.2" data-path="java-swing.html"><a href="java-swing.html#layouts-and-composites"><i class="fa fa-check"></i><b>B.2</b> Layouts and Composites</a></li>
</ul></li>
<li class="chapter" data-level="C" data-path="publishing.html"><a href="publishing.html"><i class="fa fa-check"></i><b>C</b> Publishing</a><ul>
<li class="chapter" data-level="C.1" data-path="publishing.html"><a href="publishing.html#signing-an-app"><i class="fa fa-check"></i><b>C.1</b> Signing an App</a><ul>
<li><a href="publishing.html#release-.apk">Release <code>.apk</code></a></li>
</ul></li>
</ul></li>
<li class="divider"></li>
<li><a href="https://github.com/rstudio/bookdown" target="blank">Published with bookdown</a></li>
</ul>
</nav>
</div>
<div class="book-body">
<div class="body-inner">
<div class="book-header" role="navigation">
<h1>
<i class="fa fa-circle-o-notch fa-spin"></i><a href="./">Android Development: Lecture Notes</a>
</h1>
</div>
<div class="page-wrapper" tabindex="-1" role="main">
<div class="page-inner">
<section class="normal" id="section-">
<div id="location" class="section level1">
<h1><span class="header-section-number">Lecture 12</span> Location</h1>
<p>This lecture discusses <strong>localization</strong>: the process for determining <em>location</em>. This is particularly important for Android, which is primarily intended as an operating system for <em>mobile</em> devices. What makes phones and tablets special, and different from desktops, is that they can and do move around. And this mobility makes means that a device’s position and location can matter <em>significantly</em> for how they are used; it’s a major part of what separates the functionality of Android apps from any other computer application. Indeed: localization gives apps the ability to create new kinds of user experiences, and to adjust their functionality to fit the user’s <em>context</em>, supporting <a href="https://en.wikipedia.org/wiki/Context_awareness">context-aware</a> applications.</p>
<ul>
<li><p>The classic example of context-awareness is having software determine if you are at home, in the office, or on a bus, and change its usage accordingly.</p>
<ul>
<li>In fact, one of the winners of the <em>first</em> Android Developer Challenge (2008) was <a href="http://web.archive.org/web/20100209012355/http://www.ecorio.org/">Ecorio</a>, an app that figured out whether you were driving, walking, or busing and calculated your carbon footprint from that.</li>
</ul></li>
<li><p>Note that the emphasis on context-awareness comes out of <a href="https://en.wikipedia.org/wiki/Ubiquitous_computing">Ubiquitous Computing</a>, a discipline that considers technology that is <em>ubiquitous</em> or everywhere, to the point that it “blends into the surroundings.” That’s the author’s take on why phone development is important; so that you can compute without thinking about it.</p>
<p>I highly recommend you read Mark Weiser’s <a href="http://dx.doi.org/10.1145/329124.329126">original 1991 Scientific American article</a>. It’s a neat vision and is foundational for a lot of modern research into mobile systems. It marks the “official” start of the field of Ubicomp.</p></li>
</ul>
<p>In short: localization can let us know about the user’s situation (though mobile phone location is <a href="http://dx.doi.org/10.1007/11853565_8">not necessarily</a> a proxy for user location).</p>
<div id="localization-techniques" class="section level2">
<h2><span class="header-section-number">12.1</span> Localization Techniques</h2>
<p>Ubicomp researchers have been developing localization systems for <em>years</em>. A classical reference is a <a href="http://dx.doi.org/10.1109/2.940014">survey paper</a> by Jeff Hightower (who was getting his PhD in the CSE department at UW!)</p>
<ul>
<li>As an early example: the <em>Active Badge</em> (AT&T) system had a name-badge emit an infrared message, that was picked up by sensors in a room to determine where the wearer was! This is room-level precision, but improvements and <em>triangulation</em> (calculating angles to what you see) got it down to about <em>10cm</em> precision. However, this system required a lot of infrastructure to be built into a particular room.</li>
</ul>
<p>With Android, we’re usually interested in more general-purpose localization. Mobile devices use a couple of different kinds of localization (either independently or together).</p>
<div id="gps" class="section level3 unnumbered">
<h3>GPS</h3>
<p><strong>GPS</strong> is the most common general-purpose localization technology, and what most people think of when they think of localization. <a href="https://en.wikipedia.org/wiki/Global_Positioning_System">GPS</a> stands for “Global Position System”—and yes, it can work anywhere on the globe.</p>
<p>GPS’s functionality depends on satellites: 24 satellites in high orbit (not geo-synchronous) around the Earth. Satellites are distributed so that 4 to 12 are visible from any point on Earth at any time, and their locations are known with high precision. These satellites are each equipped with an atomic, synchronized clock that “ticks” every nanosecond. At every tick, the satellite broadcasts its current time and position. You can almost think of them as <em>really</em> loud alarm clocks.</p>
<p>The thing in your phone (or your car, or your watch) that you call a “GPS” or a “GPS device” is actually a <em>GPS</em> <strong><em>receiver</em></strong>. It is able to listen for the messages broadcast by these satellites, and determine its (the device’s) position based on that information.</p>
<p>First, the receiver calculates the <em>time of arrival</em> (TOA) based on its own clock and comparing time-codes from the satellites. It then uses the announced <em>time of transmission</em> (TOT; what the satellite was shouting) to calculate the <a href="https://en.wikipedia.org/wiki/Time_of_flight">time of flight</a>, or how long it took for the satellite’s message to reach the receiver. Because these messages are sent at (basically) the speed of light, the <em>time of flight</em> is equivalent to the distance from the satellite!</p>
<ul>
<li>There is some other synchronization work that is done to make sure clocks are all the same, but we won’t go into that here.</li>
</ul>
<p>And once it has distances from the satellites, the receiver can use <a href="https://en.wikipedia.org/wiki/Trilateration">trilateration</a> to determine its position based on the satellites it “sees”. (Trilateration is like Triangulation, but relies on measuring distances rather than measuring angles. Basically, you construct three spheres of given radii, and then look to see where they intersect).</p>
<p>GPS precision is generally about 5 meters (15 feet); however, by repeatedly calculating the receiver’s position (since the satellites tick every nanosecond), we can use <em>differential positioning</em> to extrapolate position with even higher precision, increasing precision to less than 1 meter! This is in part how Google can determine where you’re walking.</p>
<p>While GPS is ubiquitous, scalable, and sufficiently accurate, it does have some limitations. The biggest problem with GPS is that you need to be able to see the satellites! This means that GPS frequently doesn’t work indoors, as many building walls block the signals. Similarly, in highly urban areas (think downtown Seattle), the buildings can bounce the signal around and throw off the TOF calculations, making it harder to pinpoint position accurately.</p>
<ul>
<li>Additionally, receivers requires a lot of energy to constantly listen for the satellite messages. This means that utilizing the GPS can lead to a big hit on device battery life—which is of particular importance for mobile devices!</li>
</ul>
</div>
<div id="cell-tower-localization" class="section level3 unnumbered">
<h3>Cell Tower Localization</h3>
<p>But your phone can also give you a rough estimate of your location even <em>without</em> GPS. It does this through a couple of techniques, such as relying on the cell phone towers that provide the phone network service. This is also known as <a href="https://en.wikipedia.org/wiki/Mobile_phone_tracking#Network-based"><strong>GSM localization</strong></a> (Global System for Mobile Communications; the standard for cell phone communication used by many service providers). The location of these towers are known, so we can determine location based off them in a couple of ways:</p>
<ul>
<li><p>If you’re connected to a tower, you must be within range of it. So that gives you some measure of localization right off the bat. This would not be a very accurate measure though (you might be <em>anywhere</em> within that range).</p></li>
<li><p>If you can see multiple towers (which is important for “handoff” purposes, so your call doesn’t drop as you move), you can trilaterate the position between them (e.g., finding the possible overlapping area and picking a location in the middle of that). This can give accuracy within 50m in urban areas, with more towers producing better precision.</p></li>
</ul>
</div>
<div id="wifi-localization" class="section level3 unnumbered">
<h3>WiFi Localization</h3>
<p>But wait there’s more! What other kinds of communication antennas do you have in your phone? <strong>WiFi</strong>! As WiFi has became more popular, efforts have been made to identify the <em>location</em> of WiFi hotspots so that they too can be used for <a href="https://en.wikipedia.org/wiki/Wi-Fi_positioning_system">trilateration and localization</a>.</p>
<p>This is often done through crowdsourced databases, with information gathered via <a href="https://en.wikipedia.org/wiki/Wardriving">war driving</a>. War driving involves driving around with a GPS receiver and a laptop, and simply recording what WiFi routers you see at what locations. This then all gets compiled into a database that can be queried—given that you see <em>these</em> routers, where must you be?</p>
<ul>
<li>Google got in <a href="http://www.wired.com/2012/05/google-wifi-fcc-investigation/">hot water</a> for doing this as it was driving around to capture Street-View images.</li>
</ul>
<p>WiFi localization can then be combined with Cell Tower localization to produce a pretty good estimate of your location, even without GPS.</p>
<p>And in fact, Google provides the ability to automatically use all of these different techniques, abstracted into a single method call!</p>
<p class="alert alert-info">
I want to flag that just like the old <em>Active Badge</em> systems, all of these localizations systems rely on some kind of existing infrastructure: GPS requires satellites; GSM requires cell towers, and WiFi needs the database of routers. All these systems require and react to the world around them, making localization influenced by the actual location as well as both social and computational systems!
</p>
</div>
<div id="representing-location" class="section level3 unnumbered">
<h3>Representing Location</h3>
<p>So once we have a location, how do we represent it?</p>
<p>First, note that there is a philosophical difference between a “place” and a “space.” A <strong>space</strong> is a location, but without any social connotations. For example, GPS coordinates, or Cartesian xy-coordinates will all indicate a “space.” A <strong>place</strong> on the other hand is somewhere that has social meaning: Mary Gates Hall; the University of Washington; my kitchen. Space is a computational construct; place is a human construct. When we talk about localization with a mobile device, we’ll be mostly talking about <em>space</em>. But often <em>place</em> is what we’re really interested in, and we may have to convert between the two (Google does provide a few ways to convert between the two, such as with its <a href="https://developers.google.com/places/">Places API</a>).</p>
<p>Our space locations will generally be reported as two coordinates: <strong>Latitude</strong> and <strong>Longitude</strong>. (<strong>Altitude</strong> or height can also be reported, but that isn’t very relevant for us).</p>
<ul>
<li><p><strong>Latitude</strong> (“lat”) is the <strong><em>angle</em></strong> between the equatorial plane and a line that passes through a point and the center of the Earth—the angle you have to go up the earth’s surface from the equator. Effectively, it’s a measure of “north/south”. Latitude is usually measured in <em>degrees north</em>, so going south of the equator gives a negative latitude (though this can be expressed positively as “degrees south”).</p></li>
<li><p><strong>Longitude</strong> (“lng”) is the <strong><em>angle</em></strong> between the prime meridian plane and a line that passes through a point and the center of the Earth—the angle you have to go across the earth’s surface from the meridian. Effectively, it’s a measure of “east/west”. Latitude is measured in <em>degrees east</em>, so going east of the meridian. That mean that the western hemisphere has “negative longitude” (though this can be expressed as positive “degrees west”).</p></li>
</ul>
<p>As an example: <a href="https://www.google.com/search?q=uw+gps+coordinates">UW’s GPS Coordinates</a><a href="#fn38" class="footnoteRef" id="fnref38"><sup>38</sup></a> are N/W, so this would be expressed as N (positive) and E (negative).</p>
<p>The distance between degrees and miles depends on where you you are (particularly for longitude—the curvature of the earth means that each degree has less space between it as you get closer to their “joining” at the poles). However, for a very rough sense of scale, in the American Northwest, .01 degrees corresponds with a distance of <em>about</em> a mile (again: this is not an accurate conversion, and is intended only for a sense of the “units”).</p>
</div>
</div>
<div id="android-location" class="section level2">
<h2><span class="header-section-number">12.2</span> Android Location</h2>
<p>The remainder of the lecture will discuss how to implement an app that is able to access the device’s location. This location will simply be displayed for now; connecting the location to a visual display (e.g., a <a href="maps.html#maps">map</a>) is left as an exercise to the reader.</p>
<p class="alert alert-info">
This lecture references code found at <a href="https://github.com/info448/lecture12-location" class="uri">https://github.com/info448/lecture12-location</a>.
</p>
<div id="google-play-services" class="section level3 unnumbered">
<h3>Google Play Services</h3>
<p>In order to effectively access location, we first need to make sure we include the <a href="https://developers.google.com/android/guides/setup">Google Play Services</a>. These are a special set of libraries (similar to the support libraries) that provide additional functionality to Android. That functionality will include the location and mapping tools we’re interested in. (Much of this functionality was originally built into core Android, but Google has since been moving it into a separate app that can be more easily distributed and updated!)</p>
<p>There are a few steps to including the Play Services library:</p>
<ol style="list-style-type: decimal">
<li><p>Confirm that the <strong><em>project-level</em></strong> <code>build.gradle</code> file to include a reference to <a href="https://developer.android.com/studio/build/dependencies.html#google-maven">Google’s Maven Repository</a>:</p>
<pre><code>allprojects {
repositories {
google()
jcenter()
// If you're using a version of Gradle lower than 4.1, you must instead use:
maven {
url 'https://maven.google.com'
}
}
}</code></pre>
<p><em>Make sure you put this under <code>allprojects</code>, and not <code>buildscripts</code></em>!</p></li>
<li><p>Make sure the device supports these services (e.g., that it’s a Google device and not an Amazon device). For the emulator, go to the <code>AVD Manager</code>, and confirm the <em>target</em> platform includes the <code>Google APIs</code>.</p></li>
<li><p>Modify your <code>build.gradle</code> file so that you can get access to the Location classes. In the <strong><em>module-level</em></strong> <code>build.gradle</code> file, under <code>dependencies</code> add</p>
<pre><code>implementation 'com.google.android.gms:play-services-location:16.0.0'</code></pre>
<p>This will load in the location services (but not the other play services, which take up extra space and may require additional API keys). Note that you can specify a different version of the services, as long as it is greater than <code>11.6.0</code>.</p></li>
</ol>
<p>Additionally, you’ll need to request permission to access the device’s location. There are two permission levels we can ask for: <code>ACCESS_COARSE_LOCATION</code> (for GSM/WiFi level precision), and <code>ACCESS_FINE_LOCATION</code> (for GPS level precision). We’ll use the later because we want GPS-level precision.</p>
<p class="alert alert-warning">
This is a <strong>dangerous</strong> permission, so we need to make sure to ask for permission at run-time! See the <a href="files-and-permissions.html#permissions">lecture on permissions</a> for details.
</p>
<p>We’re going to use Google Play Services to access the device’s location. The Google APIs provide a nice set of methods for <a href="https://developer.android.com/training/location/retrieve-current.html">accessing location</a> (without us needing to specify the source of that localization, GPS or GSM), and is the recommended API to use.</p>
<ul>
<li>There is a built-in <code>android.location</code> API (e.g., for non-Google based Android devices), but it’s not recommended practice and is harder to use.</li>
</ul>
</div>
<div id="accessing-location" class="section level3 unnumbered">
<h3>Accessing Location</h3>
<p>Google provides location access through a <a href="https://developers.google.com/android/reference/com/google/android/gms/location/FusedLocationProviderClient"><code>FusedLocationProviderClient</code></a>. This is a “unified” interface for accessing location. It fuses together all of the different ways of getting location, providing whichever one best suits our specified needs. You can think of it as a “wrapper” around more detailed location services.</p>
<ul>
<li><p>It will let us specify at a high level whether we want to trade accuracy for power consumption, rather than us needing to be explicit about that. And it will make decisions about what how best to fetch location given our stated needs and other contextual information.</p></li>
<li><p>You can get access to the (singleton) client by calling a method on the <code>LocationServices</code> class:</p>
<div class="sourceCode"><pre class="sourceCode kotlin"><code class="sourceCode kotlin"><span class="kw">val</span> <span class="va">fusedLocationClient</span> = LocationServices.getFusedLocationProviderClient(<span class="kw">this</span>)</code></pre></div></li>
</ul>
<p>We’re going to specify this “high level” requirement using a <a href="https://developers.google.com/android/reference/com/google/android/gms/location/LocationRequest"><code>LocationRequest</code></a><a href="#fn39" class="footnoteRef" id="fnref39"><sup>39</sup></a> object, which represents the details of our request (e.g., how we want to have our phone search for it’s location).</p>
<div class="sourceCode"><pre class="sourceCode java"><code class="sourceCode java"><span class="co">//java</span>
LocationRequest request = <span class="kw">new</span> <span class="fu">LocationRequest</span>();
request.<span class="fu">setInterval</span>(<span class="dv">10000</span>);
request.<span class="fu">setFastestInterval</span>(<span class="dv">5000</span>);
request.<span class="fu">setPriority</span>(LocationRequest.<span class="fu">PRIORITY_HIGH_ACCURACY</span>);</code></pre></div>
<div class="sourceCode"><pre class="sourceCode kotlin"><code class="sourceCode kotlin"><span class="co">//kotlin</span>
<span class="kw">val</span> <span class="va">locationRequest</span> = LocationRequest().apply {
interval = <span class="dv">10000</span>
fastestInterval = <span class="dv">5000</span>
priority = LocationRequest.PRIORITY_HIGH_ACCURACY
}</code></pre></div>
<ul>
<li><p>We create the object, then specify the “interval” that we want to check for updates. We can also specify the “fastest” interval, which is the maximum rate we want updates (assuming they are available). It’s a bit like a minimum and maximum. 5 to 10 seconds is good for real-time navigation. See <a href="https://developer.android.com/training/location/change-location-settings#location-request">Set up a location request</a> for more details.</p>
<p>It is alternatively possible to only access the <a href="https://developer.android.com/training/location/retrieve-current">current location</a>, if you don’t need regularly updates</p></li>
<li><p>We also specify the <a href="https://developers.google.com/android/reference/com/google/android/gms/location/LocationRequest#constant-summary">priority</a>, which is the indicator to the FusedLocationApi about what kind of precision we want. <code>HIGH_ACCURACY</code> basically means GPS (trade power for accuracy!)</p></li>
</ul>
<p>We will also need to specify a <a href="https://developers.google.com/android/reference/com/google/android/gms/location/LocationCallback"><code>LocationCallback</code></a> object, which represents the “callback function” that will be executed when each location update is received. This is usually defined as an <em>anonymous object</em>:</p>
<div class="sourceCode"><pre class="sourceCode kotlin"><code class="sourceCode kotlin"><span class="co">//kotlin</span>
locationCallback = <span class="kw">object</span> : <span class="dt">LocationCallback</span>() {
<span class="kw">override</span> <span class="kw">fun</span> <span class="fu">onLocationResult</span>(<span class="va">locationResult</span>: <span class="dt">LocationResult?</span>) {
<span class="cf">if</span>(locationResult != <span class="kw">null</span>) {
<span class="co">//do something with result!</span>
}
}
}</code></pre></div>
<p>The <code>onLocationResult()</code> callback will be passed an object that is a <a href="https://developer.android.com/guide/topics/location/battery#batch">“batch collection”</a> of location updates (which can be useful to preserve battery); access the <code>location</code> property to get a <em>list</em> of <code>Location</code> objects. Each <code>Location</code> contains the latitude/longitude of the location. We can then use that location (such as display it). We can access the latitude and longitude with getters:</p>
<pre><code>```java
//java
textLat.setText("" + location.getLatitude());
textLng.setText("" + location.getLongitude());
```</code></pre>
<p>Finally, you can actually send the request for location updates using the <code>FusedLocationProviderClient</code>:</p>
<div class="sourceCode"><pre class="sourceCode kotlin"><code class="sourceCode kotlin">fusedLocationClient.requestLocationUpdates(locationRequest, locationCallback, <span class="kw">null</span>)</code></pre></div>
<p>(The third parameter is a <a href="https://developer.android.com/reference/android/os/Looper"><code>Looper</code></a>), which is used to perform asynchronous operations in a background thread.</p>
<p class="alert alert-warning">
Before actually sending the request, check for run-time permissions! Remember to implement <code>onRequestPermissionResult</code>
</p>
<p><strong>Importantly</strong>, in order to preserve battery life, you’ll want to make sure to <em>stop</em> requesting location updates when the app isn’t in use, such as when it is paused or stopped:</p>
<div class="sourceCode"><pre class="sourceCode kotlin"><code class="sourceCode kotlin"><span class="co">//kotlin</span>
<span class="kw">override</span> <span class="kw">fun</span> <span class="fu">onStop</span>() {
<span class="kw">super</span>.onStop()
fusedLocationClient.removeLocationUpdates(locationCallback) <span class="co">//stop the updates that go to this callback</span>
}</code></pre></div>
<p>It is possible to test this out (even when indoors) by using the emulator. Although the emulator doesn’t actually have a GPS receiver, it is possible to give it a “fake” location using the emulator’s options sidebar (where we previously sent SMS messages from). This allows us to “send” the phone a location, almost as if we as humans were the GPS receiver!</p>
<ul>
<li><p>You can test by giving the emulator UW’s coordinates (47.6550 N, -122.3080 E), and you can watch it update!</p>
<ul>
<li>Note that you may need to start up the <code>Maps</code> application to make sure the devices’s location settings are enabled and correct. See <a href="https://developer.android.com/training/location/change-location-settings.html">here</a> for how we can prompt for that ourselves (it’s a lot of repetitive code, so leaving it as exercise to the reader).</li>
</ul></li>
<li><p>The <code>FusedLocationApi</code> class also has a <code>setMockLocation()</code> method, which can allow you to programmatically define locations (e.g., you can make a button that changes your location). This can be useful for testing and debugging.</p></li>
</ul>
<p class="alert alert-info">
The <code>FusedLocationProviderApi</code> was added in Google Play Services v12, and simplifies the process of getting location <em>a lot</em>!
</p>
</div>
</div>
</div>
<div class="footnotes">
<hr />
<ol start="38">
<li id="fn38"><p><a href="https://www.google.com/search?q=uw+gps+coordinates" class="uri">https://www.google.com/search?q=uw+gps+coordinates</a><a href="location.html#fnref38">↩</a></p></li>
<li id="fn39"><p><a href="https://developers.google.com/android/reference/com/google/android/gms/location/LocationRequest" class="uri">https://developers.google.com/android/reference/com/google/android/gms/location/LocationRequest</a><a href="location.html#fnref39">↩</a></p></li>
</ol>
</div>
</section>
</div>
</div>
</div>
<a href="databases.html" class="navigation navigation-prev " aria-label="Previous page"><i class="fa fa-angle-left"></i></a>
<a href="services.html" class="navigation navigation-next " aria-label="Next page"><i class="fa fa-angle-right"></i></a>
</div>
</div>
<script src="libs/gitbook-2.6.7/js/app.min.js"></script>
<script src="libs/gitbook-2.6.7/js/lunr.js"></script>
<script src="libs/gitbook-2.6.7/js/plugin-search.js"></script>
<script src="libs/gitbook-2.6.7/js/plugin-sharing.js"></script>
<script src="libs/gitbook-2.6.7/js/plugin-fontsettings.js"></script>
<script src="libs/gitbook-2.6.7/js/plugin-bookdown.js"></script>
<script src="libs/gitbook-2.6.7/js/jquery.highlight.js"></script>
<script>
gitbook.require(["gitbook"], function(gitbook) {
gitbook.start({
"sharing": {
"github": true,
"facebook": false,
"twitter": false,
"google": false,
"weibo": false,
"instapper": false,
"vk": false,
"all": ["github", "facebook", "twitter", "google"]
},
"fontsettings": {
"theme": "white",
"family": "sans",
"size": 2
},
"edit": {
"link": "https://github.com/info448/book/edit/master/location.Rmd",
"text": "Edit"
},
"download": ["android-development.pdf", "android-development.epub"],
"toc": {
"collapse": "section",
"scroll_highlight": true
}
});
});
</script>
<!-- dynamically load mathjax for compatibility with self-contained -->
<script>
(function () {
var script = document.createElement("script");
script.type = "text/javascript";
script.src = "https://cdn.bootcss.com/mathjax/2.7.1/MathJax.js?config=TeX-MML-AM_CHTML";
if (location.protocol !== "file:" && /^https?:/.test(script.src))
script.src = script.src.replace(/^https?:/, '');
document.getElementsByTagName("head")[0].appendChild(script);
})();
</script>
</body>
</html>