Professional Documents
Culture Documents
Android 1 0 CC
Android 1 0 CC
by Mark L. Murphy
The Busy Coder's Guide to Android Development by Mark L. Murphy Copyright 2008 CommonsWare, LLC. All Rights Reserve . !rinte in the "nite #tates o$ Ameri%a. CommonsWare books may be pur%hase in printe &bulk' or igital $orm $or e u%ational or business use. (or more in$ormation, %onta%t direct@commonsware.com. !rinting )istory* +ul 2008* ,ersion -.0 .#/0* 12830318-42803031 relate tra e ress are
5he CommonsWare name an logo, 6/usy Co er7s 8ui e9, an tra emarks o$ CommonsWare, LLC.
All other tra emarks re$eren%e in this book are tra emarks o$ their respe%tive $irms. 5he publisher an author&s' assume no responsibility $or errors or omissions or $or amages resulting $rom the use o$ the in$ormation %ontaine herein.
Table of Contents
Welcome to the Warescription!..................................................................................xiii Preface..........................................................................................................................xv Wel%ome to the /ook:...........................................................................................................;v !rere<uisites..........................................................................................................................;v Wares%ription.......................................................................................................................;vi /ook /ug /ounty.................................................................................................................;vii #our%e Co e Li%ense..........................................................................................................;viii Creative Commons an the (our3to3(ree &=2(' 8uarantee............................................;viii The Bi Picture................................................................................................................! What An roi s Are Ma e >$.................................................................................................? A%tivities...........................................................................................................................? Content !rovi ers...........................................................................................................= .ntents..............................................................................................................................= #ervi%es.............................................................................................................................= #tu$$ At @our Aisposal.............................................................................................................B #torage..............................................................................................................................B 0etCork............................................................................................................................B Multime ia.......................................................................................................................B 8!#...................................................................................................................................B !hone #ervi%es.................................................................................................................4 Pro"ect #tructure............................................................................................................$ Root Contents..........................................................................................................................2 5he #Ceat >$$ @our /roC.......................................................................................................8
iii
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
An 0oC, 5he Rest o$ the #tory.............................................................................................8 What @ou 8et >ut >$ .t.........................................................................................................1 %nside the &anifest........................................................................................................!! .n 5he /eginning, 5here Was the Root, An .t Was 8oo .................................................-!ermissions, .nstrumentations, an Appli%ations &>h, My:'.............................................-2 @our Appli%ation Aoes #omething, RightD..........................................................................-? Creatin a #'eleton Application...................................................................................!$ /egin at the /eginning...........................................................................................................-2 5he A%tivity............................................................................................................................-8 Aisse%ting the A%tivity...........................................................................................................-1 /uil ing an Running the A%tivity.......................................................................................2(sin )&*+Based *ayouts............................................................................................,What .s an EML3/ase LayoutD...........................................................................................2? Why "se EML3/ase LayoutsD............................................................................................2= >F, #o What Aoes .t Look LikeD..........................................................................................2B What7s With the G #ignsD....................................................................................................24 An We Atta%h 5hese to the +ava...)oCD...........................................................................24 5he Rest o$ the #tory.............................................................................................................22 .mployin Basic Wid ets.............................................................................................,/ Assigning Labels....................................................................................................................21 /utton, /utton, Who7s 8ot the /uttonD..............................................................................?0 (leeting .mages......................................................................................................................?(iel s o$ 8reen. >r >ther Colors..........................................................................................?+ust Another /o; to Che%k....................................................................................................?= 5urn the Ra io "p.................................................................................................................?2 .t7s Huite a ,ieC....................................................................................................................?1 "se$ul !roperties...........................................................................................................?1 "se$ul Metho s..............................................................................................................?1 Wor'in 0ith Containers.............................................................................................1! 5hinking Linearly..................................................................................................................=2 Con%epts an !roperties...............................................................................................=2 I;ample..........................................................................................................................=B All 5hings Are Relative.........................................................................................................B0
iv
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
Con%epts an !roperties...............................................................................................B0 I;ample..........................................................................................................................B? 5abula Rasa............................................................................................................................B4 Con%epts an !roperties...............................................................................................B4 I;ample..........................................................................................................................B1 #%rollCork..............................................................................................................................40 (sin #election Wid ets...............................................................................................23 A apting to the Cir%umstan%es............................................................................................4B "sing ArrayA apter......................................................................................................44 >ther Fey A apters.......................................................................................................42 Lists o$ 0aughty an 0i%e....................................................................................................48 #pin Control...........................................................................................................................20 8ri @our Lions &>r #omething Like 5hat...'.....................................................................2= (iel s* 0oC With ?BJ Less 5yping:.....................................................................................28 8alleries, 8ive >r 5ake 5he Art...........................................................................................82 .mployin 4ancy Wid ets and Containers..................................................................5!i%k an Choose....................................................................................................................8? 5ime Feeps (loCing Like a River.........................................................................................88 Making !rogress....................................................................................................................81 !utting .t >n My 5ab...........................................................................................................10 5he !ie%es.......................................................................................................................15he . iosyn%rasies..........................................................................................................1Wiring .t 5ogether........................................................................................................1? >ther Containers o$ 0ote.....................................................................................................14 Applyin &enus............................................................................................................/$ (lavors o$ Menu.....................................................................................................................12 Menus o$ >ptions.................................................................................................................18 Menus in Conte;t................................................................................................................-00 5aking a !eek.......................................................................................................................-02 .m6eddin the We67it Bro0ser................................................................................!8$ A /roCser, Writ #mall.........................................................................................................-02 Loa ing .t "p.......................................................................................................................-01 0avigating the Waters..........................................................................................................---
v
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
Intertaining the Client.........................................................................................................--#ettings, !re$eren%es, an >ptions &>h, My:'....................................................................--= #ho0in Pop+(p &essa es..........................................................................................!!$ Raising 5oasts........................................................................................................................--2 Alert: Alert:............................................................................................................................--8 Che%king 5hem >ut.............................................................................................................--1 Dealin 0ith Threads..................................................................................................!,8etting 5hrough the )an lers............................................................................................-2? Messages.......................................................................................................................-2= Runnables.....................................................................................................................-22 Running .n !la%e..................................................................................................................-22 "tilities &An . Aon7t Mean Water Works'.......................................................................-28 An 0oC, 5he Caveats........................................................................................................-28 9andlin Activity *ifecycle .vents..............................................................................!-! #%hroe inger7s A%tivity.........................................................................................................-?Li$e, Aeath, an @our A%tivity.............................................................................................-?2 onCreate&' an onComplete5haC&'............................................................................-?2 on#tart&', onRestart&', an onResume&'.....................................................................-?? on!ause&', on(reeKe&', on#top&', an onAestroy&'...................................................-?= (sin Preferences........................................................................................................!-$ 8etting What @ou Want......................................................................................................-?2 #tating @our !re$eren%e.......................................................................................................-?8 A !re$eren%e (or A%tion......................................................................................................-?8 Accessin 4iles.............................................................................................................!1@ou An 5he )orse @ou Ro e .n >n.................................................................................-=? Rea in7 7n Writin7.................................................................................................................-=2 Wor'in 0ith :esources..............................................................................................!3! 5he Resour%e Lineup............................................................................................................-B#tring 5heory........................................................................................................................-B2 !lain #trings..................................................................................................................-B2 #tring (ormats..............................................................................................................-B? #tyle 5e;t.....................................................................................................................-B? #tyle (ormats..............................................................................................................-B=
vi
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
8ot the !i%tureD...................................................................................................................-B8 EML* 5he Resour%e Way.....................................................................................................-40 Mis%ellaneous ,alues...........................................................................................................-4? Aimensions...................................................................................................................-4? Colors............................................................................................................................-4= Arrays............................................................................................................................-4B Ai$$erent #trokes $or Ai$$erent (olks..................................................................................-44 &ana in and Accessin *ocal Data6ases...................................................................!$! A Hui%k #HLite !rimer........................................................................................................-22 #tart at the /eginning..........................................................................................................-2? #etting the 5able..................................................................................................................-2= Makin7 Aata..........................................................................................................................-2= What 8oes Aroun , Comes Aroun ...................................................................................-24 RaC Hueries..................................................................................................................-24 Regular Hueries............................................................................................................-22 /uil ing Cith /uil ers.................................................................................................-22 "sing Cursors...............................................................................................................-21 Change $or the #ake o$ Change...................................................................................-21 Making @our >Cn Cursors..........................................................................................-80 Aata, Aata, IveryChere.......................................................................................................-80 *evera in ;ava *i6raries............................................................................................!55he >uter Limits..................................................................................................................-8? Ants an +ars........................................................................................................................-8= Communicatin via the %nternet................................................................................!5$ RI#5 an Rela;ation............................................................................................................-82 )55! >perations via Apa%he Commons...................................................................-88 !arsing Responses........................................................................................................-10 #tu$$ 5o Consi er.........................................................................................................-12 Imail over +ava.....................................................................................................................-1? Creatin %ntent 4ilters................................................................................................!// What7s @our .ntentD............................................................................................................200 !ie%es o$ .ntents..........................................................................................................200 #to%k >ptions...............................................................................................................20-
vii
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
.ntent Routing.............................................................................................................202 #tating @our .ntent&ions'....................................................................................................20? 0arroC Re%eivers.................................................................................................................20B *aunchin Activities and #u6+Activities.....................................................................,8$ !eers an #ubs.....................................................................................................................208 #tart 7Im "p........................................................................................................................208 Make an .ntent............................................................................................................201 Make the Call...............................................................................................................201 4indin Availa6le Actions via %ntrospection...............................................................,!3 !i%k 7Im................................................................................................................................2-4 A aptable A apters.............................................................................................................220 Woul @ou Like to #ee the MenuD.....................................................................................22? Asking Aroun .....................................................................................................................22B (sin a Content Provider...........................................................................................,,/ !ie%es o$ Me.........................................................................................................................221 8etting a )an le.................................................................................................................2?0 Makin7 Hueries.....................................................................................................................2?A apting to the Cir%umstan%es..........................................................................................2?? Aoing .t /y )an .................................................................................................................2?B !osition.........................................................................................................................2?B 8etting !roperties.......................................................................................................2?4 #etting !roperties........................................................................................................2?2 8ive an 5ake......................................................................................................................2?8 /eCare o$ the /L>/:...........................................................................................................2?1 Buildin a Content Provider.......................................................................................,1! (irst, #ome Aisse%tion.........................................................................................................2=0e;t, #ome 5yping..............................................................................................................2=2 #tep L-* Create a !rovi er Class..........................................................................................2=? Content!rovi er..........................................................................................................2=? AatabaseContent!rovi er...........................................................................................2B2 #tep L2* #upply a "ri...........................................................................................................2B2 #tep L?* Ae%lare the !roperties..........................................................................................2B2 #tep L=* "p ate the Mani$est.............................................................................................2B?
viii
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
0oti$y3>n3Change #upport................................................................................................2B= :e<uestin and :e<uirin Permissions.....................................................................,3$ Mother, May .D....................................................................................................................2B8 )alt: Who 8oes 5hereD.......................................................................................................2B1 In$or%ing !ermissions via the Mani$est....................................................................240 In$or%ing !ermissions IlseChere...............................................................................24May . #ee @our Ao%umentsD...............................................................................................242 Creatin a #ervice........................................................................................................,28etting /uKKe ....................................................................................................................24= #ervi%e Cith Class................................................................................................................24= When .!C Atta%ks:..............................................................................................................244 Write the A.AL............................................................................................................242 .mplement the .nter$a%e.............................................................................................248 Mani$est Aestiny.................................................................................................................220 Where7s the RemoteD...........................................................................................................22%nvo'in a #ervice.......................................................................................................,$/oun $or #u%%ess...............................................................................................................22= Re<uest $or #ervi%e..............................................................................................................224 !rometheus "nboun .........................................................................................................224 Manual 5ransmission..........................................................................................................224 Alertin (sers =ia >otifications.................................................................................,$/ 5ypes o$ !estering...............................................................................................................221 )ar Care 0oti$i%ations..............................................................................................280 .%ons..............................................................................................................................28Letting @our !resen%e /e (elt.............................................................................................28Accessin *ocation+Based #ervices.............................................................................,5$ Lo%ation !rovi ers* 5hey FnoC Where @ou7re )i ing....................................................288 (in ing @oursel$..................................................................................................................288 >n the Move........................................................................................................................212 Are We 5here @etD Are We 5here @etD Are We 5here @etD............................................212 5esting...5esting..................................................................................................................214 &appin 0ith &ap=ie0 and &apActivity..................................................................,// 5he /are /ones....................................................................................................................211
ix
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
I;er%ising @our Control.......................................................................................................?0Moom.............................................................................................................................?0Center...........................................................................................................................?02 Reti%le...........................................................................................................................?0? 5ra$$i% an 5errain...............................................................................................................?0? (olloC @ou, (olloC Me........................................................................................................?0B Layers "pon Layers.............................................................................................................?02 >verlay Classes............................................................................................................?08 AraCing the >verlay...................................................................................................?08 )an ling #%reen 5aps..................................................................................................?-0 Playin &edia..............................................................................................................-!8et @our Me ia >n..............................................................................................................?-= Making 0oise........................................................................................................................?-B Moving !i%tures....................................................................................................................?29andlin Telephone Calls..........................................................................................-,3 0o, 0o, 0o N 0ot 5hat .!hone...........................................................................................?24 What7s >ur #tatusD..............................................................................................................?24 @ou Make the Call:..............................................................................................................?24 #earchin 0ith #earch&ana er...................................................................................--)unting #eason....................................................................................................................??? #ear%h @oursel$.....................................................................................................................??B Cra$t the #ear%h A%tivity.............................................................................................??4 "p ate the Mani$est....................................................................................................?=0 5ry .t >ut.....................................................................................................................?=2 The Tour%t #ample Application..................................................................................-1$ .nstalling 5our.t..................................................................................................................?=2 Aemo Lo%ation !rovi er.............................................................................................?=2 #A Car .mage Cith #ample 5our..............................................................................?=8 Running 5our.t....................................................................................................................?=1 Main A%tivity................................................................................................................?B0 Con$iguration A%tivity.................................................................................................?B2 Cue #heet A%tivity.......................................................................................................?B= Map A%tivity.................................................................................................................?BB
x
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
5our "p ate A%tivity...................................................................................................?B2 )elp A%tivity................................................................................................................?B8 5our.t7s Mani$est.................................................................................................................?B1 5our.t7s Content..................................................................................................................?40 Aata #torage.................................................................................................................?4Content !rovi er..........................................................................................................?4Mo el Classes...............................................................................................................?45our.t7s A%tivities................................................................................................................?42 5ourListA%tivity...........................................................................................................?42 5our,ieCA%tivity.........................................................................................................?4? 5ourMapA%tivity..........................................................................................................?42 5ourI itA%tivity..........................................................................................................?42 )elpA%tivity.................................................................................................................?42 Con$igA%tivity..............................................................................................................?48
xi
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
We hope you enOoy this ebook an its up ates N keep tabs on the Wares%ription $ee o$$ the CommonsWare site to learn Chen neC e itions o$ this book, or other books in your Wares%ription, are available. All e itions o$ CommonsWare titles, print an ebook, $olloC a so$tCare3 style numbering system. MaOor releases &-.0, 2.0, et%.' are available in both print an ebookP minor releases &0.-, 0.1, et%.' are available in ebook $orm $or Wares%ription subs%ribers only. Releases en ing in .1 are Qrelease %an i atesQ $or the ne;t maOor release, la%king perhaps an in e; but otherCise being %omplete. Ia%h Wares%ription ebook is li%ense $or the e;%lusive use o$ its subs%riber an is tagge Cith the subs%ribers name. We ask that you not istribute these books. .$ you Cork $or a $irm an Cish to have several employees have a%%ess, enterprise Wares%riptions are available. +ust %onta%t us at enterpriseG%ommonsCare.%om. Also, bear in min that eventually this e ition o$ this title Cill be release un er a Creative Commons li%ense N more on this in the pre$a%e. Remember that the CommonsWare Web site has errata an resour%es &e.g., sour%e %o e' $or ea%h o$ our titles. +ust visit the Web page $or the book you are intereste in an $olloC the links. #ome notes $or Fin le users*
xiii
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
@ou may Cish to rop your $ont siKe to level 2 $or easier rea ing #our%e %o e listings are in%orporate as graphi%s so as to retain the monospa%e $ont, though this means the sour%e %o e listings o not honor %hanges in Fin le $ont siKe
xiv
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
Preface
Prerequisites
.$ you are intereste in programming $or An roi , you Cill nee at least basi% un erstan ing o$ hoC to program in +ava. An roi programming is one using +ava synta;, plus a %lass library that resembles a subset o$ the +ava #I library &plus An roi 3spe%i$i% e;tensions'. .$ you have not programme in +ava be$ore, you probably shoul <ui%k learn hoC that Corks be$ore attempting to ive into programming $or An roi .
xv
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
5he book oes not %over in any etail hoC to oCnloa or install the An roi evelopment tools, either the I%lipse .AI $lavor or the stan alone $lavor. 5he An roi Web site %overs this <uite ni%ely. 5he material in the book shoul be relevant Chether you use the .AI or not. @ou shoul oCnloa , install, an test out the An roi evelopment tools $rom the An roi Web site be$ore trying any o$ the e;amples liste in this book. #ome %hapters may re$eren%e material in previous %hapters, though usually Cith a link ba%k to the pre%e ing se%tion o$ relevan%e.
Warescription
5his book Cill be publishe both in print an in igital &ebook' $orm. 5he ebook versions o$ all CommonsWare titles are available via an annual subs%ription N the Wares%ription. 5he Wares%ription entitles you, $or the uration o$ your subs%ription, to ebook $orms o$ all CommonsWare titles, not Oust the one you are rea ing. !resently, CommonsWare o$$ers !A( an Fin leP other ebook $ormats Cill be a e base on interest an the openness o$ the $ormat. Ia%h subs%riber gets personaliKe e itions o$ all e itions o$ ea%h title* both those mirroring printe e itions an in3betCeen up ates that are only available in ebook $orm. 5hat Cay, your ebooks are never out o$ ate $or long, an you %an take a vantage o$ neC material as it is ma e available instea o$ having to Cait $or a Chole neC print e ition. (or e;ample, Chen neC releases o$ the An roi #AF are ma e available, this book Cill be <ui%kly up ate to be a%%urate Cith %hanges in the A!.s. (rom time to time, subs%ribers Cill also re%eive a%%ess to subs%riber3only online material, both short arti%les an not3yet3publishe neC titles. Also, i$ you oCn a print %opy o$ a CommonsWare book, an it is in goo %lean %on ition Cith no marks or sti%kers, you %an e;%hange that %opy $or a is%ount o$$ the Wares%ription pri%e. .$ you are intereste in a Wares%ription, visit the Wares%ription se%tion o$ the CommonsWare Web site.
xvi
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
5ypographi%al errors #ample appli%ations that o not Cork as a vertise , in the environment es%ribe in the book (a%tual errors that %annot be open to interpretation
/y Quni<ueQ, Ce mean ones not yet reporte . Ia%h book has an errata page on the CommonsWare Web siteP most knoCn problems Cill be liste there. We appre%iate hearing about Qso$terQ issues as Cell, su%h as*
!la%es Chere you think Ce are in error, but Chere Ce $eel our interpretation is reasonable !la%es Chere you think Ce %oul a upon the e;isting material sample appli%ations, or e;pan
#amples that o not Cork ue to Qshi$ting san sQ o$ the un erlying environment &e.g., %hange A!.s Cith neC releases o$ an #AF'
)oCever, those Qso$terQ issues o not <uali$y $or the $ormal bounty program. Huestions about the bug bounty, or problems you Cish to report $or bounty %onsi eration, shoul be sent to bountyG%ommonsCare.%om.
xvii
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
xviii
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
CHAPTER 1
An roi evi%es, by an large, Cill be mobile phones. While the An roi te%hnology is being is%usse $or use in other areas &e.g., %ar ashboar Q!CsQ', $or the most part, you %an think o$ An roi as being use on phones. (or evelopers, this has bene$its an raCba%ks.
>n the plus si e, %ir%a 2008, An roi 3style smartphones are se;y. >$$ering .nternet servi%es over mobile evi%es ates ba%k to the mi 3-1107s an the )an hel Aevi%e Markup Language &)AML'. )oCever, only in re%ent years have phones %apable o$ .nternet a%%ess taken o$$. 0oC, thanks to tren s like te;t messaging an to pro u%ts like Apple7s i!hone, phones that %an serve as .nternet a%%ess evi%es are rapi ly gaining popularity. #o, Corking on An roi appli%ations gives you e;perien%e Cith an interesting te%hnology &An roi ' in a $ast3moving market segment &.nternet3enable phones', Chi%h is alCays a goo thing. 5he problem %omes Chen you a%tually have to program the arn things. Anyone Cith e;perien%e in programming $or !AAs or phones has $elt the pain o$ phones simply being small in all sorts o$ imensions*
#%reens are small &you Con7t get %omments like, Qis that a 2=3in%h LCA in your po%ket, or...DQ' Feyboar s, i$ they e;ist, are small
(
!ointing evi%es, i$ they e;ist, are annoying &as anyone Cho has lost their stylus Cill tell you' or ine;a%t &large $ingers an Qmulti3tou%hQ LCAs are not a goo mi;' C!" spee an memory are tight %ompare to esktops an servers you may be use to @ou %an have any programming language an evelopment $rameCork you Cant, so long as it Cas Chat the evi%e manu$a%turer %hose an burne into the phone7s sili%on An so on
Moreover, appli%ations running on a phone have to eal Cith the $a%t that they7re on a phone. !eople Cith mobile phones ten to get very irritate Chen those phones on7t Cork, Chi%h is Chy the Q%an you hear me noCDQ a %ampaign $rom ,eriKon Wireless has been popular $or the past $eC years. #imilarly, those same people Cill get irritate at you i$ your program QbreaksQ their phone*
...by tying up the C!" su%h that %alls %an7t be re%eive ...by not Corking properly Cith the rest o$ the phone7s >#, su%h that your appli%ation oesn7t <uietly $a e to the ba%kgroun Chen a %all %omes in or nee s to be pla%e ...by %rashing the phone7s operating system, su%h as by leaking memory like a sieve
)en%e, eveloping programs $or a phone is a i$$erent e;perien%e than eveloping esktop appli%ations, Web sites, or ba%k3en server pro%esses. @ou Cin up Cith i$$erent3looking tools, i$$erent3behaving $rameCorks, an Q i$$erent than you7re use toQ limitations on Chat you %an o Cith your program. What An roi tries to o is meet you hal$Cay*
@ou get a %ommonly3use programming language &+ava' Cith some %ommonly use libraries &e.g., some Apa%he Commons A!.s', Cith support $or tools you may be use to &I%lipse'
%
@ou get a $airly rigi an un%ommon $rameCork in Chi%h your programs nee to run so they %an be Qgoo %itiKensQ on the phone an not inter$ere Cith other programs or the operation o$ the phone itsel$
As you might e;pe%t, mu%h o$ this book eals Cith that $rameCork an hoC you Crite programs that Cork Cithin its %on$ines an take a vantage o$ its %apabilities.
Activities
5he buil ing blo%k o$ the user inter$a%e is the activity. @ou %an think o$ an a%tivity as being the An roi analogue $or the Cin oC or ialog in a esktop appli%ation. While it is possible $or a%tivities to not have a user inter$a%e, most likely your Qhea lessQ %o e Cill be pa%kage in the $orm o$ %ontent provi ers or servi%es, es%ribe beloC.
,
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
Content Providers
Content provi ers provi e a level o$ abstra%tion $or any ata store on the evi%e that is a%%essible by multiple appli%ations. 5he An roi evelopment mo el en%ourages you to make your oCn ata available to other appli%ations, as Cell as your oCn N buil ing a %ontent provi er lets you o that, Chile maintaining %omplete %ontrol over hoC your ata gets a%%esse .
Intents
.ntents are system messages, running aroun the insi e o$ the evi%e, noti$ying appli%ations o$ various events, $rom har Care state %hanges &e.g., an #A %ar Cas inserte ', to in%oming ata &e.g., an #M# message arrive ', to appli%ation events &e.g., your a%tivity Cas laun%he $rom the evi%e7s main menu'. 0ot only %an you respon to intents, but you %an %reate your oCn, to laun%h other a%tivities, or to let you knoC Chen spe%i$i% situations arise &e.g., raise su%h3an 3so intent Chen the user gets Cithin -00 meters o$ this3an 3su%h lo%ation'.
Services
A%tivities, %ontent provi ers, an intent re%eivers are all short3live an %an be shut oCn at any time. #ervi%es, on the other han , are esigne to keep running, i$ nee e , in epen ent o$ any a%tivity. @ou might use a servi%e $or %he%king $or up ates to an R## $ee , or to play ba%k musi% even i$ the %ontrolling a%tivity is no longer operating.
$
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
"et#or$
An roi evi%es Cill generally be .nternet3rea y, through one %ommuni%ations me ium or another. @ou %an take a vantage o$ the .nternet a%%ess at any level you Cish, $rom raC +ava so%kets all the Cay up to a built3in WebFit3base Web broCser Ci get you %an embe in your appli%ation.
%ultimedi
An roi evi%es have the ability to play ba%k an re%or au io an vi eo. While the spe%i$i%s may vary $rom evi%e to evi%e, you %an <uery the evi%e to learn its %apabilities an then take a vantage o$ the multime ia %apabilities as you see $it, Chether that is to play ba%k musi%, take pi%tures Cith the %amera, or use the mi%rophone $or au io note3taking.
GPS
An roi evi%es Cill $re<uently have a%%ess to lo%ation provi ers, su%h as 8!#, that %an tell your appli%ations Chere the evi%e is on the $a%e o$ the Iarth. .n turn, you %an isplay maps or otherCise take a vantage o$ the lo%ation ata, su%h as tra%king a evi%e7s movements i$ the evi%e has been stolen.
/
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
Phone Services
An , o$ %ourse, An roi evi%es are typi%ally phones, alloCing your so$tCare to initiate %alls, sen an re%eive #M# messages, an everything else you e;pe%t $rom a mo ern bit o$ telephony te%hnology.
0
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
CHAPTER &
Pro1ect Structure
5he An roi buil system is organiKe aroun a spe%i$i% ire%tory tree stru%ture $or your An roi proOe%t, mu%h like any other +ava proOe%t. 5he spe%i$i%s, though, are $airly uni<ue to An roi an Chat it all oes to prepare the a%tual appli%ation that Cill run on the evi%e or emulator. )ere7s a <ui%k primer on the proOe%t stru%ture, to help you make sense o$ it all, parti%ularly $or the sample %o e re$eren%e in this book.
2oot Contents
When you %reate a neC An roi proOe%t &e.g., via activityCreator.py', you get $ive key items in the proOe%t7s root ire%tory*
AndroidManifest.xml,
Chi%h is an EML $ile es%ribing the appli%ation being built an Chat %omponents N a%tivities, servi%es, et%. N are being supplie by that appli%ation Chi%h is an Ant s%ript $or %ompiling the appli%ation an installing it on the evi%e
bin/, Chi%h hol src/, Chi%h hol res/, build.xml,
s the appli%ation on%e it is %ompile s the +ava sour%e %o e $or the appli%ation
Chi%h hol s Qresour%esQ, su%h as i%ons, 8". layouts, an the like, that get pa%kage Cith the %ompile +ava in the appli%ation
assets/,
Chi%h hol other stati% $iles you Cish pa%kage Cith the appli%ation $or eployment onto the evi%e
3
Pro1ect Structure
7
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
Pro1ect Structure
hol s the %ompile +ava %lasses hol s the e;e%utable %reate $rom those %ompile
bin/classes.dex
+ava %lasses
bin/yourapp.apk
is the a%tual An roi appli%ation &Chere yourapp is the name o$ your appli%ation'
5he .apk $ile is a M.! ar%hive %ontaining the .dex $ile, the %ompile e ition o$ your resour%es &resources.arsc', any un3%ompile resour%es &su%h as Chat you put in res/raw/' an the AndroidManifest.xml $ile.
9
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
CHAPTER '
5he $oun ation $or any An roi appli%ation is the mani$est $ile* AndroidManifest.xml in the root o$ your proOe%t. )ere is Chere you e%lare Chat all is insi e your appli%ation N the a%tivities, the servi%es, an so on. @ou also in i%ate hoC these pie%es atta%h themselves to the overall An roi systemP $or e;ample, you in i%ate Chi%h a%tivity &or a%tivities' shoul appear on the evi%e7s main menu &a.k.a., laun%her'. When you %reate your appli%ation, you Cill get a starter mani$est generate $or you. (or a simple appli%ation, o$$ering a single a%tivity an nothing else, the auto3generate mani$est Cill probably Cork out $ine, or perhaps re<uire a $eC minor mo i$i%ations. >n the other en o$ the spe%trum, the mani$est $ile $or the An roi A!. emo suite is over -,000 lines long. @our pro u%tion An roi appli%ations Cill probably $all someChere in the mi le. Most o$ the interesting bits o$ the mani$est Cill be es%ribe in greater etail in the %hapters on their asso%iate An roi $eatures. (or e;ample, the service element Cill be es%ribe in greater etail in the %hapter on %reating servi%es. (or noC, Ce Oust nee to un erstan Chat the role o$ the mani$est is an its general overall %onstru%tion.
0ote the namespa%e e%laration. Curiously, the generate mani$ests only apply it on the attributes, not the elements &e.g., it7s manifest, not android!manifest'. )oCever, that pattern Corks, so unless An roi %hanges, sti%k Cith their pattern. 5he biggest pie%e o$ in$ormation you nee to supply on the manifest element is the packa%e attribute &also %uriously not3namespa%e '. )ere, you %an provi e the name o$ the +ava pa%kage that Cill be %onsi ere the QbaseQ o$ your appli%ation. 5hen, everyChere else in the mani$est $ile that nee s a %lass name, you %an Oust substitute a lea ing ot as shorthan $or the pa%kage. (or e;ample, i$ you nee e to re$er to com.commonsware.android.Snicklefrit' in this mani$est shoCn above, you %oul Oust use .Snicklefrit', sin%e com.commonsware.android is e$ine as the appli%ation7s pa%kage.
elements, to in i%ate Chat permissions your appli%ation Cill nee in or er to $un%tion properly N see the %hapter on permissions $or more etails elements, to e%lare permissions that a%tivities or servi%es might re<uire other appli%ations hol in or er to use your appli%ation7s ata or logi% N again, more etails are $orth%oming in the %hapter on permissions
permission
elements, to in i%ate %o e that shoul be invoke on key system events, su%h as starting up a%tivities, $or the purposes o$ logging or monitoring
instrumentation
an application element, e$ining the guts o$ the appli%ation that the mani$est es%ribes
(%
<manifest xmlns!android"#$ttp!//sc$emas.android.com/apk/res/android# packa%e"#com.commonsware.android#& <uses(permission android!name"#android.permission.ACC)SS*+,CA-.,/# /& <uses(permission android!name"#android.permission.ACC)SS*01S# /& <uses(permission android!name"#android.permission.ACC)SS*ASS.S-)D*01S# /& <uses(permission android!name"#android.permission.ACC)SS*C)++*.D# /& <application& ... </application& </manifest&
.n the pre%e ing e;ample, the mani$est has uses(permission elements to in i%ate some evi%e %apabilities the appli%ation Cill nee N in this %ase, permissions to alloC the appli%ation to etermine its %urrent lo%ation. An , there is the application element, Chose %ontents Cill es%ribe the a%tivities, servi%es, an Chatnot that make up the bulk o$ the appli%ation itsel$.
5his element supplies android!name $or the %lass implementing the a%tivity, android!label $or the isplay name o$ the a%tivity, an &$re<uently' an intent(filter %hil element es%ribing un er Chat %on itions this a%tivity
(,
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
Cill be isplaye . 5he sto%k activity element sets up your a%tivity to appear in the laun%her, so users %an %hoose to run it. As Ce7ll see later in this book, you %an have several a%tivities in one proOe%t, i$ you so %hoose. @ou may also have one or more receiver elements, in i%ating non3a%tivities that shoul be triggere un er %ertain %on itions, su%h as Chen an #M# message %omes in. 5hese are %alle intent re%eivers an are es%ribe mi 3 Cay through the book. @ou may have one or more provider elements, in i%ating %ontent provi ers N %omponents that supply ata to your a%tivities an , Cith your permission, other a%tivities in other appli%ations on the evi%e. 5hese Crap up atabases or other ata stores into a single A!. that any appli%ation %an use. Later, Ce7ll see hoC to %reate %ontent provi ers an hoC to use %ontent provi ers that you or others %reate. (inally, you may have one or more service elements, es%ribing servi%es N long3running pie%es o$ %o e that %an operate in epen ent o$ any a%tivity. 5he <uintessential e;ample is the M!? player, Chere you Cant the musi% to keep playing even i$ the user pops open other a%tivities an the M!? player7s user inter$a%e is Qmispla%e Q. 5Co %hapters late in the book %over hoC to %reate an use servi%es.
($
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
PART II Activities
CHAPTER (
Ivery programming language or environment book starts o$$ Cith the ever3 popular Q)ello, Worl :Q emonstration* Oust enough o$ a program to prove you %an buil things, not so mu%h that you %annot un erstan Chat is going on. )oCever, the typi%al Q)ello, Worl :Q program has no intera%tivity &e.g., Oust umps the Cor s to a %onsole', an so is really boring. 5his %hapter emonstrates a simple proOe%t, but one using A van%e !ush3 /utton 5e%hnologyR an the %urrent time, to shoC you hoC a simple An roi a%tivity Corks.
you Cant to %reate an a ((out sCit%h in i%ating Chere the proOe%t $iles shoul be generate . (or e;ample*
./activityCreator.py ((out /pat$/to/my/project/dir 4 com.commonsware.android./ow
@ou Cill Cin up Cith a han $ul o$ pre3generate $iles, as es%ribe in a previous %hapter. (or the purposes o$ the samples shoCn in this book, you %an oCnloa their proOe%t ire%tories in a M.! $ile on the CommonsWare Web site. 5hese proOe%ts are rea y $or useP you o not nee to run activityCreator.py on those unpa%ke samples.
The )ctivity
@our proOe%t7s src/ ire%tory %ontains the stan ar +ava3style tree o$ ire%tories base upon the +ava pa%kage you %hose Chen you %reate the proOe%t &e.g., com.commonsware.android results in src/com/commonsware/android/'. .nsi e the innermost ire%tory you shoul $in a pre3generate sour%e $ile name /ow.java, Chi%h Chere your $irst a%tivity Cill go. >pen /ow.java in your e itor an paste in the $olloCing %o e*
packa%e com.commonsware.android.skeleton5 import import import import import android.app.Activity5 android.os.6undle5 android.view.7iew5 android.wid%et.6utton5 java.util.Date5
public class /ow extends Activity implements 7iew.,nClick+istener 8 6utton btn5 9,verride public void onCreate:6undle icicle; 8 super.onCreate:icicle;5 btn " new Button:t$is;5 btn.setOnClickListener:t$is;5
(7
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
<
updateTime:;5 setContentView:btn;5
public void onClick:7iew view; 8 updateTime:;5 < private void updateTime:; 8 btn.setText:new Date:;.toString:;;5 < <
>r, i$ you oCnloa the sour%e $iles o$$ the Web site, you %an Oust use the /ow proOe%t ire%tly.
5he pa%kage e%laration nee s to be the same as the one you use Chen %reating the proOe%t. An , like any other +ava proOe%t, you nee to import any %lasses you re$eren%e. Most o$ the An roi 3spe%i$i% %lasses are in the android pa%kage. Remember that not every +ava #I %lass is available to An roi programs: ,isit the An roi %lass re$eren%e to see Chat is an is not available.
public class /ow extends Activity implements 7iew.,nClick+istener 8 6utton btn5
A%tivities are publi% %lasses, inheriting $rom the android.Activity base %lass. .n this %ase, the a%tivity hol s a button &btn'. #in%e, $or simpli%ity, Ce Cant
(9
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
to trap all button %li%ks Oust Cithin the a%tivity itsel$, Ce also have the a%tivity %lass implement ,nClick+istener.
9,verride public void onCreate:6undle icicle; 8 super.onCreate:icicle;5 btn " new Button:t$is;5 btn.setOnClickListener:t$is;5 updateTime:;5 setContentView:btn;5 <
5he onCreate:; metho is invoke Chen the a%tivity is starte . 5he $irst thing you shoul o is %hain upCar to the super%lass, so the sto%k An roi a%tivity initialiKation %an be one. .n our implementation, Ce then %reate the button instan%e &new 6utton:t$is;', tell it to sen all button %li%ks to the a%tivity instan%e itsel$ &via set,nClick+istener:;', %all a private update-ime:; metho &see beloC', an then set the a%tivity7s %ontent vieC to be the button itsel$ &via setContent7iew:;'. We Cill is%uss that magi%al 6undle icicle in a later %hapter. (or the moment, %onsi er it an opa<ue han le that all a%tivities re%eive upon %reation.
public void onClick:7iew view; 8 updateTime:;5 <
.n #Cing, a =6utton %li%k raises an Action)vent, Chi%h is passe to the Action+istener %on$igure $or the button. .n An roi , a button %li%k %auses onClick:; to be invoke in the ,nClick+istener instan%e %on$igure $or the button. 5he listener is provi e the vieC that triggere the %li%k &in this %ase, the button'. All Ce o here is %all that private update-ime:; metho *
private void updateTime:; 8 btn.setText:new Date:;.toString:;;5 <
%;
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
When Ce open the a%tivity &onCreate:;' or Chen the button is %li%ke &onClick:;', Ce up ate the button7s label to be the %urrent time via set-ext:;, Chi%h $un%tions mu%h the same as the =6utton e<uivalent.
Laun%h the emulator &e.g., run tools/emulator $rom your An roi #AF installation' .nstall the pa%kage &e.g.,
/pat$/to/t$is/example/bin//ow.apk
run $rom
tools/adb
install
your
An roi
#AF
installation'
,ieC the list o$ installe appli%ations in the emulator an $in the Q0oCQ appli%ation
%(
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
Cli%king the button N in other Cor s, pretty mu%h anyChere on the phone7s s%reen N Cill up ate the time shoCn in the button7s label. 0ote that the label is %entere horiKontally an verti%ally, as those are the e$ault styles applie to button %aptions. We %an %ontrol that $ormatting, Chi%h Cill be %overe in a later %hapter. A$ter you are one gaKing at the aCesomeness o$ A van%e !ush3/utton 5e%hnologyR, you %an %li%k the ba%k button on the emulator to return to the laun%her.
%%
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
CHAPTER )
While it is te%hni%ally possible to %reate an atta%h Ci gets to our a%tivity purely through +ava %o e, the Cay Ce i in the pre%e ing %hapter, the more %ommon approa%h is to use an EML3base layout $ile. Aynami% instantiation o$ Ci gets is reserve $or more %ompli%ate s%enarios, Chere the Ci gets are not knoCn at %ompile3time &e.g., populating a %olumn o$ ra io buttons base on ata retrieve o$$ the .nternet'. With that in min , it7s time to break out the EML an learn out to lay out An roi a%tivity vieCs that Cay.
An roi 7s #AF ships Cith a tool &aapt' Chi%h uses the layouts. 5his tool shoul be automati%ally invoke by your An roi tool %hain &e.g., I%lipse, Ant7s build.xml'. >$ parti%ular importan%e to you as a eveloper is that aapt generates the R.java sour%e $ile Cithin your proOe%t, alloCing you to a%%ess layouts an Ci gets Cithin those layouts ire%tly $rom your +ava %o e, as Cill be emonstrate .
%$
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
5he %lass name o$ the Ci get N 6utton N $orms the name o$ the EML element. #in%e 6utton is an An roi 3supplie Ci get, Ce %an Oust use the bare %lass name. .$ you %reate your oCn Ci gets as sub%lasses o$ android.view.7iew, you Coul nee to provi e a $ull pa%kage e%laration as Cell &e.g., com.commonsware.android.MyCid%et'. 5he root element nee s to e%lare the An roi EML namespa%e*
xmlns!android"#$ttp!//sc$emas.android.com/apk/res/android#
All other elements Cill be %hil ren o$ the root an namespa%e e%laration.
/e%ause Ce Cant to re$eren%e this button $rom our +ava %o e, Ce nee to give it an i enti$ier via the android!id attribute. We Cill %over this %on%ept in greater etail . 5he remaining attributes are properties o$ this 6utton instan%e*
in i%ates the initial te;t to be isplaye on the button $a%e &in this %ase, an empty string'
android!text android!layout*widt$
an android!layout*$ei%$t tell An roi to have the button7s Ci th an height $ill the QparentQ, in this %ase the entire s%reen N these attributes Cill be %overe in greater etail in a later %hapter
%/
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
#in%e this single Ci get is the only %ontent in our a%tivity7s vieC, Ce only nee this single element. Comple; vieCs Cill re<uire a Chole tree o$ elements, representing the Ci gets an %ontainers that %ontrol their positioning. All the remaining %hapters o$ this book Cill use the EML layout $orm Chenever pra%ti%al, so there are oKens o$ other e;amples o$ more %omple; layouts $or you to peruse.
$rom our layout, is a%%esse $rom that %o e3generate R %lass. All o$ the layouts are a%%essible un er R.layout, keye by the base name o$ the layout $ile N snicklefrit'.xml results in R.layout.snicklefrit'. 5o a%%ess our i enti$ie Ci gets, use find7iew6y.d:;, passing it the numeri% i enti$ier o$ the Ci get in <uestion. 5hat numeri% i enti$ier Cas generate by An roi in the R %lass as R.id.somet$in% &Chere somet$in% is the spe%i$i% Ci get you are seeking'. 5hose Ci gets are simply sub%lasses o$ 7iew, Oust like the 6utton instan%e Ce %reate in the previous %hapter.
public class /owRedux extends Activity implements 7iew.,nClick+istener 8 6utton btn5 9,verride public void onCreate:6undle icicle; 8 super.onCreate:icicle;5 setContentView:R.layout.main;5 btn":6utton;findViewById:R.id.button;5 btn.setOnClickListener:t$is;5 updateTime:;5
<
<
5he $irst i$$eren%e is that rather than setting the %ontent vieC to be a vieC Ce %reate in +ava %o e, Ce set it to re$eren%e the EML layout &setContent7iew:R.layout.main;'. 5he R.java sour%e $ile Cill be up ate Chen Ce rebuil this proOe%t to in%lu e a re$eren%e to our layout $ile &store as main.xml in our proOe%t7s res/layout ire%tory'. 5he other i$$eren%e is that Ce nee to get our han s on our 6utton instan%e, $or Chi%h Ce use the find7iew6y.d:; %all. #in%e Ce i enti$ie our button as 9Bid/button, Ce %an re$eren%e the button7s i enti$ier as R.id.button. 0oC, Cith the 6utton instan%e in han , Ce %an set the %allba%k an set the label as nee e . 5he results look the same as Cith the original /ow emo*
%7
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
CHAPTER *
Ivery 8". toolkit has some basi% Ci gets* $iel s, labels, buttons, et%. An roi 7s toolkit is no i$$erent in s%ope, an the basi% Ci gets Cill provi e a goo intro u%tion as to hoC Ci gets Cork in An roi a%tivities.
)ssigning abels
5he simplest Ci get is the label, re$erre to in An roi as a -ext7iew. Like in most 8". toolkits, labels are bits o$ te;t not e itable ire%tly by users. 5ypi%ally, they are use to i enti$y a Oa%ent Ci gets &e.g., a Q0ame*Q label be$ore a $iel Chere one $ills in a name'. .n +ava, you %an %reate a label by %reating a -ext7iew instan%e. More %ommonly, though, you Cill %reate labels in EML layout $iles by a ing a -ext7iew element to the layout, Cith an android!text property to set the value o$ the label itsel$. .$ you nee to sCap labels base on %ertain %riteria, su%h as internationaliKation, you may Cish to use a resour%e re$eren%e in the EML instea , as Cill be es%ribe later in this book.
-ext7iew
has numerous other properties o$ relevan%e $or labels, su%h as* to set the type$a%e to use $or the label &e.g.,
android!typeface monospace'
android!textStyle to in i%ate that the type$a%e shoul be ma e bol &bold', itali% &italic', or bol an itali% &bold*italic'
%9
(or e;ample, in the +abel proOe%t, you Cill $in the $olloCing layout $ile*
<>xml version"#?.@# encodin%"#utf(A#>& <-ext7iew xmlns!android"#$ttp!//sc$emas.android.com/apk/res/android# android!layout*widt$"#fill*parent# android!layout*$ei%$t"#wrap*content# android!text"#Fou were expectin% somet$in% profound># /&
+ust that layout alone, Cith the stub +ava sour%e provi e proOe%t buil er &e.g., activityCreator', gives you*
by An roi 7s
!leeting 8mages
An roi
.ma%e7iew
has tCo Ci gets to help you embe images in your a%tivities* an .ma%e6utton. As the names suggest, they are image3base analogues to -ext7iew an 6utton, respe%tively.
Ia%h Ci get takes an android!src attribute &in an EML layout' to spe%i$y Chat pi%ture to use. 5hese usually re$eren%e a raCable resour%e, es%ribe in greater etail in the %hapter on resour%es. @ou %an also set the image %ontent base on a 2ri $rom a %ontent provi er via set.ma%e2R.:;.
.ma%e6utton, a sub%lass o$ .ma%e7iew,
mi;es in the stan ar /utton behaviors, $or respon ing to %li%ks an Chatnot.
shoul
provi e automati%
android!capitali'e, to %ontrol i$ the $iel shoul automati%ally %apitaliKe the $irst letter o$ entere te;t &e.g., $irst name, %ity' android!di%its, to %on$igure the $iel android!sin%le+ine,
to %ontrol i$ the $iel is $or single3line input or multiple3line input &e.g., oes SInterT move you to the ne;t Ci get or a a neClineD'
/eyon those, you %an %on$igure $iel s to use spe%ialiKe input metho s, su%h as android!numeric $or numeri%3only input, android!password $or
,(
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
shrou e passCor input, an android!p$one/umber $or entering in phone numbers. .$ you Cant to %reate your oCn input metho s%heme &e.g., postal %o es, #o%ial #e%urity numbers', you nee to %reate your oCn implementation o$ the .nputMet$od inter$a%e, then %on$igure the $iel to use it via android!inputMet$od. @ou %an see an e;ample o$ this in the appen i; is%ussing the 5our.t sample appli%ation. (or e;ample, $rom the Eield proOe%t, here is an EML layout $ile shoCing an )dit7iew*
<>xml version"#?.@# encodin%"#utf(A#>& <)dit-ext xmlns!android"#$ttp!//sc$emas.android.com/apk/res/android# android!id"#9Bid/field# android!layout*widt$"#fill*parent# android!layout*$ei%$t"#fill*parent# android!sin%le+ine"#false# /&
0ote that android!sin%le+ine is $alse, so users Cill be able to enter in several lines o$ te;t. (or this proOe%t, the EieldDemo.java $ile populates the input $iel Cith some prose*
packa%e com.commonsware.android.basic5 import android.app.Activity5 import android.os.6undle5 import android.wid%et.)dit-ext5 public class EieldDemo extends Activity 8 9,verride public void onCreate:6undle icicle; 8 super.onCreate:icicle;5 setContentView:R.layout.main;5 )dit-ext fld":)dit-ext;findViewById:R.id.field;5 fld.setText:#+icensed under t$e Apac$e +icenseG 7ersion H.@ # B #:t$e 4#+icense4#;5 you may not use t$is file # B #except in compliance wit$ t$e +icense. Fou may # B #obtain a copy of t$e +icense at # B #$ttp!//www.apac$e.or%/licenses/+.C)/S)(H.@#;5
< <
,%
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
>AT.* An roi 7s emulator only alloCs one appli%ation in the laun%her per uni<ue +ava pa%kage. #in%e all the emos in this %hapter share the com.commonsware.android.basic pa%kage, i$ you have the LabelAemo appli%ation installe , you Cill not see the (iel Aemo appli%ation in the laun%her. 5o remove the LabelAemo appli%ation N or any appli%ation N use adb s$ell #rm /data/app/...#, Chere ... is the name o$ the appli%ation7s A!F $ile &e.g., +abelDemo.apk'. 5hen, reinstall the $ormerly3hi en appli%ation, an it Cill shoC up in the laun%her. Another $lavor o$ $iel is one that o$$ers auto3%ompletion, to help users supply a value Cithout typing in the Chole te;t. 5hat is provi e in An roi as the AutoComplete-ext7iew Ci get, is%usse in greater etail later in this book.
,,
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
state
Also, you %an register a listener obOe%t &in this %ase, an instan%e o$ ,nC$eckedC$an%e+istener' to be noti$ie Chen the state o$ the %he%kbo; %hanges. (or e;ample, $rom the C$eck6ox proOe%t, here is a simple %he%kbo; layout*
<>xml version"#?.@# encodin%"#utf(A#>& <C$eck6ox xmlns!android"#$ttp!//sc$emas.android.com/apk/res/android# android!id"#9Bid/c$eck# android!layout*widt$"#wrap*content# android!layout*$ei%$t"#wrap*content# android!text"#-$is c$eckbox is! unc$ecked# /&
5he %orrespon ing C$eck6oxDemo.java retrieves an %on$igures the behavior o$ the %he%kbo;*
public class C$eck6oxDemo extends Activity implements Compound6utton.,nC$eckedC$an%e+istener 8 C$eck6ox cb5 9,verride public void onCreate:6undle icicle; 8 super.onCreate:icicle;5 ,$
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
<
public void onCheckedChanged:Compound6utton button7iewG boolean isC$ecked; 8 if :isC$ecked; 8 cb.setText:#-$is c$eckbox is! c$ecked#;5 < else 8 cb.setText:#-$is c$eckbox is! unc$ecked#;5 < < <
0ote that the a%tivity serves as its oCn listener $or %he%kbo; state %hanges sin%e it implements the ,nC$eckedC$an%e+istener inter$a%e &via cb.set,nC$eckedC$an%e+istener:t$is;'. 5he %allba%k $or the listener is onC$eckedC$an%ed:;, Chi%h re%eives the %he%kbo; Chose state has %hange an Chat the neC state is. .n this %ase, Ce up ate the te;t o$ the %he%kbo; to re$le%t Chat the a%tual bo; %ontains. 5he resultD Cli%king the %he%kbo; imme iately up ates its te;t, as shoCn beloC*
,/
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
!igure 0< The CheckBox.emo sample application6 4ith the checkbox unchecked
!igure 3< The same application6 no4 4ith the checkbox checked
,0
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
to %lear all ra io buttons, so none in the group are .A o$ the %urrently3%he%ke '
%he%ke
%etC$eckedRadio6utton.d:; to get the ra io button &or (? i$ none are %he%ke
(or e;ample, $rom the Radio6utton sample appli%ation, here is an EML layout shoCing a Radio0roup Crapping a set o$ Radio6utton Ci gets*
<>xml version"#?.@# encodin%"#utf(A#>& <Radio0roup xmlns!android"#$ttp!//sc$emas.android.com/apk/res/android# android!orientation"#vertical# android!layout*widt$"#fill*parent# android!layout*$ei%$t"#fill*parent# & <Radio6utton android!id"#9Bid/radio?# android!layout*widt$"#wrap*content# android!layout*$ei%$t"#wrap*content# android!text"#Rock# /&
,3
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
<Radio6utton android!id"#9Bid/radioH# android!layout*widt$"#wrap*content# android!layout*$ei%$t"#wrap*content# android!text"#Scissors# /& <Radio6utton android!id"#9Bid/radioI# android!layout*widt$"#wrap*content# android!layout*$ei%$t"#wrap*content# android!text"#1aper# /& </Radio0roup&
"sing the sto%k An roi 3generate +ava $or the proOe%t an this layout, you get*
0ote that the ra io button group is initially set to be %ompletely un%he%ke at the outset. 5o pre3set one o$ the ra io buttons to be %he%ke , use either setC$ecked:; on the Radio6utton or c$eck:; on the Radio0roup $rom Cithin your onCreate:; %allba%k in your a%tivity.
,7
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
+se,ul Properties
#ome o$ the properties on 7iew most likely to be use in%lu e*
android!visibility,
Chi%h %ontrols Chether the Ci get is initially R8/ %olor value $or the Ci get
visible
android!back%round, Chi%h typi%ally provi es an &e.g., D@@EE@@ $or green' to serve as the ba%kgroun
+se,ul %ethods
@ou %an toggle Chether or not a Ci get is enable via set)nabled:; an see i$ it is enable via is)nabled:;. >ne %ommon use pattern $or this is to isable some Ci gets base on a C$eck6ox or Radio6utton sele%tion. @ou %an give a Ci get $o%us via reJuestEocus:; an see i$ it is $o%use via isEocused:;. @ou might use this in %on%ert Cith isabling Ci gets as mentione above, to ensure the proper Ci get has the $o%us on%e your isabling operation is %omplete. 5o help navigate the tree o$ Ci gets an a%tivity7s overall vieC, you %an use*
%et1arent:; to $in
%et1arent,f-ype:; to sear%h upCar s in the tree to $in a %ontainer o$ a %ertain %lass &e.g., $in the Radio0roup $or a Radio6utton' find7iew6y.d:; to $in %etRoot7iew:;
to get the root o$ the tree &e.g., Chat you provi e to the a%tivity via setContent7iew:;'
$;
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
CHAPTER -
Containers pour a %olle%tion o$ Ci gets &an possibly %hil %ontainers' into spe%i$i% layouts you like. .$ you Cant a $orm Cith labels on the le$t an $iel s on the right, you Cill nee a %ontainer. .$ you Cant >F an Can%el buttons to be beneath the rest o$ the $orm, ne;t to one another, an $lush to right si e o$ the s%reen, you Cill nee a %ontainer. +ust $rom a pure EML perspe%tive, i$ you have multiple Ci gets &beyon Radio6utton Ci gets in a Radio0roup', you Cill nee a %ontainer Oust to have a root element to pla%e the Ci gets insi e. Most 8". toolkits have some notion o$ layout management, $re<uently organiKe into %ontainers. .n +avaU#Cing, $or e;ample, you have layout managers like 6ox+ayout an %ontainers that use them &e.g., 6ox'. #ome toolkits sti%k stri%tly to the bo; mo el, su%h as E"L an (le;, $iguring that any esire layout %an be a%hieve through the right %ombination o$ neste bo;es. An roi , through LinearLayout, also o$$ers a Qbo;Q mo el, but in a ition supports a range o$ %ontainers provi ing i$$erent layout rules. .n this %hapter, Ce Cill look at three %ommonly3use %ontainers* +inear+ayout &the bo; mo el', Relative+ayout &a rule3base mo el', an -able+ayout &the gri mo el', along Cith Scroll7iew, a %ontainer esigne to assist Cith implementing s%rolling %ontainers. .n the ne;t %hapter, Ce Cill e;amine some more esoteri% %ontainers.
$(
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
Thinking inearly
As note above, +inear+ayout is a bo; mo el N Ci gets or %hil %ontainers are line up in a %olumn or roC, one a$ter the ne;t. 5his Corks similar to Elow+ayout in +avaU#Cing, vbox an $box in (le; an E"L, et%. (le; an E"L use the bo; as their primary unit o$ layout. .$ you Cant, you %an use +inear+ayout in mu%h the same Cay, es%heCing some o$ the other %ontainers. 8etting the visual representation you Cant is mostly a matter o$ i enti$ying Chere bo;es shoul nest an Chat properties those bo;es shoul have, su%h as alignment vis a vis other bo;es.
Concepts nd Properties
5o %on$igure a +inear+ayout, you have $ive main areas o$ %ontrol besi es the %ontainer7s %ontents* the orientation, the $ill mo el, the Ceight, the gravity, an the pa ing.
Orientation
>rientation in i%ates Chether the +inear+ayout represents a roC or a %olumn. +ust a the android!orientation property to your +inear+ayout element in your EML layout, setting the value to be $ori'ontal $or a roC or vertical $or a %olumn. 5he orientation %an be mo i$ie at runtime by invoking set,rientation:; on the +inear+ayout, supplying it either 3,R.K,/-A+ or 7)R-.CA+.
Fill Model
Let7s imagine a roC o$ Ci gets, su%h as a pair o$ ra io buttons. 5hese Ci gets have a QnaturalQ siKe base on their te;t. 5heir %ombine siKes probably o not e;a%tly mat%h the Ci th o$ the An roi evi%e7s s%reen N parti%ularly sin%e s%reens %ome in various siKes. We then have the issue o$ Chat to o Cith the remaining spa%e.
$%
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
All Ci gets insi e a +inear+ayout must supply android!layout*widt$ an android!layout*$ei%$t properties to help a ress this issue. 5hese properties7 values have three $lavors*
@ou %an provi e a spe%i$i% imension, su%h as ?HLpx to in i%ate the Ci get shoul take up e;a%tly -2B pi;els @ou %an provi e wrap*content, Chi%h means the Ci get shoul $ill up its natural spa%e, unless that is too big, in Chi%h %ase An roi %an use Cor 3Crap as nee e to make it $it @ou %an provi e fill*parent, Chi%h means the Ci get shoul $ill up all available spa%e in its en%losing %ontainer, a$ter all other Ci gets are taken %are o$
5he latter tCo $lavors are the most %ommon, as they are in epen ent o$ s%reen siKe, alloCing An roi to a Oust your vieC to $it the available spa%e.
Weight
/ut, Chat happens i$ Ce have tCo Ci gets that shoul split the available $ree spa%eD (or e;ample, suppose Ce have tCo multi3line $iel s in a %olumn, an Ce Cant them to take up the remaining spa%e in the %olumn a$ter all other Ci gets have been allo%ate their spa%e. 5o make this Cork, in a ition to setting android!layout*widt$ &$or roCs' or android!layout*$ei%$t &$or %olumns' to fill*parent, you must also set android!layout*wei%$t. 5his property in i%ates Chat proportion o$ the $ree spa%e shoul go to that Ci get. .$ you set android!layout*wei%$t to be the same value $or a pair o$ Ci gets &e.g., ?', the $ree spa%e Cill be split evenly betCeen them. .$ you set it to be ? $or one Ci get an H $or another Ci get, the se%on Ci get Cill use up tCi%e the $ree spa%e that the $irst Ci get oes. An so on.
$,
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
Gravity
/y e$ault, everything is le$t3 an top3aligne . #o, i$ you %reate a roC o$ Ci gets via a horiKontal +inear+ayout, the roC Cill start $lush on the le$t si e o$ the s%reen. .$ that is not Chat you Cant, you nee to spe%i$y a gravity. "sing android!layout*%ravity on a Ci get &or %alling set0ravity:; at runtime on the Ci get7s +ava obOe%t', you %an tell the Ci get an its %ontainer hoC to align it vis a vis the s%reen. (or a %olumn o$ Ci gets, %ommon gravity values are left, center*$ori'ontal, an ri%$t $or le$t3aligne , %entere , an right3aligne Ci gets respe%tively. (or a roC o$ Ci gets, the e$ault is $or them to be aligne so their te;ts are aligne on the baseline &the invisible line that letters seem to Qsit onQ', though you may Cish to spe%i$y a gravity o$ center*vertical to %enter the Ci gets along the roC7s verti%al mi point.
Padding
/y e$ault, Ci gets are tightly pa%ke ne;t to ea%h other. .$ you Cant to in%rease the Chitespa%e betCeen Ci gets, you Cill Cant to use the android!paddin% property &or by %alling set1addin%:; at runtime on the Ci get7s +ava obOe%t'. 5he pa ing spe%i$ies hoC mu%h spa%e there is betCeen the boun aries o$ the Ci get7s Q%ellQ an the a%tual Ci get %ontents. !a ing is analogous to the margins on a Cor pro%essing o%ument N the page siKe might be 8.BQ;--Q, but -Q margins Coul leave the a%tual te;t to resi e Cithin a 4.BQ;1Q area.
$$
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
!igure 9< The relationship bet4een a 4idget6 its cell6 and the padding values
5he android!paddin% property alloCs you to set the same pa ing on all $our si es o$ the Ci get, Cith the Ci get7s %ontents itsel$ %entere Cithin that pa e 3out area. .$ you Cant the pa ing to i$$er on i$$erent si es, use android!paddin%+eft, android!paddin%Ri%$t, android!paddin%-op, an android!paddin%6ottom. 5he value o$ the pa pa ing. ing is a imension, su%h as Lpx $or B pi;els7 Corth o$
E. mple
Let7s look at an e;ample &+inear' that shoCs +inear+ayout properties set both in the EML layout $ile an at runtime. )ere is the layout*
$/
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
<>xml version"#?.@# encodin%"#utf(A#>& <+inear+ayout xmlns!android"#$ttp!//sc$emas.android.com/apk/res/android# android!orientation"#vertical# android!layout*widt$"#fill*parent# android!layout*$ei%$t"#fill*parent# & <Radio0roup android!id"#9Bid/orientation# android!orientation"#$ori'ontal# android!layout*widt$"#wrap*content# android!layout*$ei%$t"#wrap*content# android!paddin%"#Lpx#& <Radio6utton android!id"#9Bid/$ori'ontal# android!text"#$ori'ontal# /& <Radio6utton android!id"#9Bid/vertical# android!text"#vertical# /& </Radio0roup& <Radio0roup android!id"#9Bid/%ravity# android!orientation"#vertical# android!layout*widt$"#fill*parent# android!layout*$ei%$t"#wrap*content# android!paddin%"#Lpx#& <Radio6utton android!id"#9Bid/left# android!text"#left# /& <Radio6utton android!id"#9Bid/center# android!text"#center# /& <Radio6utton android!id"#9Bid/ri%$t# android!text"#ri%$t# /& </Radio0roup& </+inear+ayout&
0ote that Ce have a +inear+ayout Crapping tCo Radio0roup sets. Radio0roup is a sub%lass o$ +inear+ayout, so our e;ample emonstrates neste bo;es as i$ they Cere all +inear+ayout %ontainers. 5he top Radio0roup sets up a roC &android!orientation " #$ori'ontal#' o$ Radio6utton Ci gets. 5he Radio0roup has Lpx o$ pa ing on all si es, separating it $rom the other Radio0roup. 5he Ci th an height are both set to wrap*content, so the ra io buttons Cill only take up the spa%e that they nee . 5he bottom Radio0roup is a %olumn &android!orientation " #vertical#' o$ three Radio6utton Ci gets. Again, Ce have Lpx o$ pa ing on all si es an a QnaturalQ height &android!layout*$ei%$t " #wrap*content#'. )oCever, Ce
$0
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
have set android!layout*widt$ to be fill*parent, meaning the %olumn o$ ra io buttons Q%laimsQ the entire Ci th o$ the s%reen. 5o a Oust these settings at runtime base on user input, Ce nee some +ava %o e*
packa%e com.commonsware.android.containers5 import import import import import import android.app.Activity5 android.os.6undle5 android.text.-extCatc$er5 android.wid%et.+inear+ayout5 android.wid%et.Radio0roup5 android.wid%et.)dit-ext5 +inear+ayoutDemo extends Activity Radio0roup.,nC$eckedC$an%e+istener 8 orientation5 %ravity5
9,verride public void onCreate:6undle icicle; 8 super.onCreate:icicle;5 setContentView:R.layout.main;5 orientation":Radio0roup;findViewById:R.id.orientation;5 orientation.setOnCheckedChangeListener:t$is;5 %ravity":Radio0roup;findViewById:R.id.%ravity;5 %ravity.setOnCheckedChangeListener:t$is;5
<
public void onCheckedChanged:Radio0roup %roupG int c$ecked.d; 8 if :%roup""orientation; 8 if :c$ecked.d""R.id.$ori'ontal; 8 orientation.setOrientation:+inear+ayout.3,R.K,/-A+;5 < else 8 orientation.setOrientation:+inear+ayout.7)R-.CA+;5 < < else if :%roup""%ravity; 8 if :c$ecked.d""R.id.left; 8 %ravity.setGra ity:@x@I;5 // left < else if :c$ecked.d""R.id.center; 8 %ravity.setGra ity:@x@?;5 // center*$ori'ontal < else if :c$ecked.d""R.id.ri%$t; 8 %ravity.setGra ity:@x@L;5 // ri%$t < <
$3
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
< <
.n onCreate:;, Ce look up our tCo Radio0roup %ontainers an register a listener on ea%h, so Ce are noti$ie Chen the ra io buttons %hange state &set,nC$eckedC$an%e+istener:t$is;'. #in%e the a%tivity implements ,nC$eckedC$an%e+istener, the a%tivity itsel$ is the listener. .n onC$eckedC$an%ed:; &the %allba%k $or the listener', Ce see Chi%h Radio0roup ha a state %hange. .$ it Cas the orientation group, Ce a Oust the orientation base on the user7s sele%tion. .$ it Cas the gravity group, Ce a Oust the gravity base on the user7s sele%tion. )ere is the result Chen it is $irst laun%he insi e the emulator*
$7
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
!igure ((< The same application6 4ith the vertical radio button selected
.$ Ce toggle the Q%enterQ or QrightQ ra io buttons, the bottom Radio0roup a Ousts to mat%h*
!igure (%< The same application6 4ith the vertical and center radio buttons selected $9
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
!igure (,< The same application6 4ith the vertical and right radio buttons selected
as the name suggests, lays out Ci gets base upon their relationship to other Ci gets in the %ontainer an the parent %ontainer. @ou %an pla%e Wi get E beloC an to the le$t o$ Wi get @, or have Wi get M7s bottom e ge align Cith the bottom o$ the %ontainer, an so on. 5his is reminis%ent o$ +ames Illiot7s RelativeLayout $or use Cith +avaU#Cing.
Concepts nd Properties
5o make all this Cork, Ce nee Cays to re$eren%e other Ci gets Cithin an EML layout $ile, plus Cays to in i%ate the relative positions o$ those Ci gets.
/;
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
align
says the Ci get7s bottom shoul align Cith the bottom o$ the %ontainer
android!layout*ali%n1arent6ottom android!layout*ali%n1arent+eft
says the Ci get7s le$t si e shoul align Cith the le$t si e o$ the %ontainer says the Ci get7s right si e shoul align Cith the right si e o$ the %ontainer
android!layout*ali%n1arentRi%$t android!layout*center3ori'ontal android!layout*center7ertical android!layout*center.n1arent
shoul
be
says the Ci get shoul be positione verti%ally at the %enter o$ the %ontainer says the Ci get shoul be positione both horiKontally an verti%ally at the %enter o$ the %ontainer
All o$ these properties take a simple boolean value &true or false'. 0ote that the pa ing o$ the Ci get is taken into a%%ount Chen per$orming these various alignments. 5he alignments are base on the Ci get7s overall %ell &%ombination o$ its natural spa%e plus the pa ing'.
/(
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
2. Re$eren%e other Ci gets using the same i enti$ier value Cithout the plus sign &9id/...' (or e;ample, i$ Wi get A is i enti$ie as 9Bid/wid%et*a, Wi get / %an re$er to Wi get A in one o$ its oCn properties via the i enti$ier 9id/wid%et*a.
in i%ates that the Ci get shoul above the Ci get re$eren%e in the property
android!layout*above android!layout*below
be pla%e be pla%e
in i%ates that the Ci get shoul beloC the Ci get re$eren%e in the property
android!layout*to+eft
in i%ates that the Ci get shoul be pla%e to the le$t o$ the Ci get re$eren%e in the property in i%ates that the Ci get shoul be pla%e to the right o$ the Ci get re$eren%e in the property
android!layout*toRi%$t
/eyon those $our, there are $ive a itional properties that %an %ontrol one Ci get7s alignment relative to another*
in i%ates that the Ci get7s top shoul aligne Cith the top o$ the Ci get re$eren%e in the property
android!layout*ali%n-op android!layout*ali%n6ottom
be
in i%ates that the Ci get7s bottom shoul be aligne Cith the bottom o$ the Ci get re$eren%e in the property
android!layout*ali%n+eft
in i%ates that the Ci get7s le$t shoul be aligne Cith the le$t o$ the Ci get re$eren%e in the property in i%ates that the Ci get7s right shoul be aligne Cith the right o$ the Ci get re$eren%e in the property
android!layout*ali%nRi%$t android!layout*ali%n6aseline
/%
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
5he last one is use$ul $or aligning labels an $iel s so that the te;t appears QnaturalQ. #in%e $iel s have a bo; aroun them an labels o not, android!layout*ali%n-op Coul align the top o$ the $iel 7s bo; Cith the top o$ the label, Chi%h Cill %ause the te;t o$ the label to be higher on3s%reen than the te;t entere into the $iel . #o, i$ Ce Cant Wi get / to be positione to the right o$ Wi get A, in the EML element $or Wi get /, Ce nee to in%lu e android!layout*toRi%$t " #9id/wid%et*a# &assuming 9id/wid%et*a is the i entity o$ Wi get A'.
Order of Evaluation
What makes this even more %ompli%ate is the or er o$ evaluation. An roi makes a single pass through your EML layout an %omputes the siKe an position o$ ea%h Ci get in se<uen%e. 5his has a $eC rami$i%ations*
@ou %annot re$eren%e a Ci get that has not been e$ine in the $ile yet @ou %are$ul that any uses o$ fill*parent in android!layout*widt$ or android!layout*$ei%$t o not Qeat upQ all the spa%e be$ore subse<uent Ci gets have been e$ine must be
E. mple
With all that in min , let7s e;amine a typi%al Q$ormQ Cith a $iel , a label, plus a pair o$ buttons labele Q>FQ an QCan%elQ. )ere is the EML layout, pulle $rom the Relative sample proOe%t*
<>xml version"#?.@# encodin%"#utf(A#>& <Relative+ayout xmlns!android"#$ttp!//sc$emas.android.com/apk/res/android# android!layout*widt$"#fill*parent# android!layout*$ei%$t"#wrap*content# android!paddin%"#Lpx#& <-ext7iew android!id"#9Bid/label# android!layout*widt$"#wrap*content# android!layout*$ei%$t"#wrap*content# android!text"#2R+!#
/,
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
android!paddin%-op"#Lpx#/& <)dit-ext android!id"#9Bid/entry# android!layout*widt$"#fill*parent# android!layout*$ei%$t"#wrap*content# android!layout*toRi%$t"#9id/label# android!layout*ali%n6aseline"#9id/label#/& <6utton android!id"#9Bid/ok# android!layout*widt$"#wrap*content# android!layout*$ei%$t"#wrap*content# android!layout*below"#9id/entry# android!layout*ali%nRi%$t"#9id/entry# android!text"#,M# /& <6utton android!layout*widt$"#wrap*content# android!layout*$ei%$t"#wrap*content# android!layout*to+eft"#9id/ok# android!layout*ali%n-op"#9id/ok# android!text"#Cancel# /& </Relative+ayout&
(irst, Ce open up the Relative+ayout. .n this %ase, Ce Cant to use the $ull Ci th o$ the s%reen &android!layout*widt$ " #fill*parent#', only as mu%h height as Ce nee &android!layout*$ei%$t " #wrap*content#', an have a B3 pi;el pa betCeen the boun aries o$ the %ontainer an its %ontents &android!paddin% " #Lpx#'. 0e;t, Ce e$ine the label, Chi%h is $airly basi%, e;%ept $or its oCn B3pi;el pa ing &android!paddin% " #Lpx#'. More on that in a moment. A$ter that, Ce a in the $iel . We Cant the $iel to be to the right o$ the label, have their te;ts aligne along the baseline, an $or the $iel to take up the rest o$ this QroCQ in the layout. 5hose are han le by three properties*
android!layout*toRi%$t " #9id/label# android!layout*ali%n6aseline " #9id/label# android!layout*ali%n6aseline " #9id/label#
.$ Ce Cere to skip the B3pi;el pa ing on the label, Ce Coul $in that the top o$ the $iel is %lippe o$$. 5hat7s be%ause o$ the B3pi;el pa ing on the %ontainer itsel$. 5he android!layout*ali%n6aseline " #9id/label# simply aligns the baselines o$ the label an $iel . 5he label, by e$ault, has its top
/$
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
aligne Cith the top o$ the parent. /ut the label is shorter than the $iel be%ause o$ the $iel 7s bo;. #in%e the $iel is epen ent on the label7s position, an the label7s position is alrea y e$ine &be%ause it appeare $irst in the EML', the $iel Cin s up being too high an has the top o$ its bo; %lippe o$$ by the %ontainer7s pa ing. @ou may $in yoursel$ running into these sorts o$ problems as you try to get your Relative+ayout to behave the Cay you Cant it to. 5he solution to this %onun rum, use in the EML layout shoCn above, is to give the label B pi;els7 o$ pa ing on the top. 5his pushes the label oCn $ar enough that the $iel Cill not get %lippe . )ere are some QsolutionsQ that o not Cork*
@ou %annot use android!layout*ali%n1arent-op on the $iel , be%ause you %annot have tCo properties that both attempt to set the verti%al position o$ the $iel . .n this %ase, android!layout*ali%n1arent-op %on$li%ts Cith the later android!layout*ali%n6aseline " #9id/label# property, an the last one in Cins. #o, you either have the top aligne properly or the baselines aligne properly, but not both. @ou %annot e$ine the $iel $irst, then put the label to the le$t o$ the $iel , as the android!layout*widt$ " #fill*parent# Qeats upQ the Ci th o$ the QroCQ, leaving no room $or the label, so the label oes not appear
8oing ba%k to the e;ample, the >F button is set to be beloC the $iel &android!layout*below " #9id/entry#' an have its right si e align Cith the right si e o$ the $iel &android!layout*ali%nRi%$t " #9id/entry#'. 5he Can%el button is set to be to the le$t o$ the >F button &android!layout*to+eft " #9id/ok#' an have its top aligne Cith the >F button &android!layout*ali%n-op " #9id/ok#'. With no %hanges to the auto3generate +ava %o e, the emulator gives us*
//
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
Tabula 2asa
.$ you like )5ML tables, sprea sheet gri s, an the like, you Cill like An roi 7s -able+ayout N it alloCs you to position your Ci gets in a gri to your spe%i$i%ations. @ou %ontrol the number o$ roCs an %olumns, Chi%h %olumns might shrink or stret%h to a%%ommo ate their %ontents, an so on.
-able+ayout
Corks in %onOun%tion Cith -ableRow. -able+ayout %ontrols the overall behavior o$ the %ontainer, Cith the Ci gets themselves poure into one or more -ableRow %ontainers, one per roC in the gri .
Concepts nd Properties
(or all this to Cork, Ce nee to $igure out hoC Ci gets Cork Cith roCs an %olumns, plus hoC to han le Ci gets that live outsi e o$ roCs.
/0
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
(irst, there Cill be at least one %olumn per Ci get in your longest roC. #o i$ you have three roCs, one Cith tCo Ci gets, one Cith three Ci gets, an one Cith $our Ci gets, there Cill be at least $our %olumns. )oCever, a Ci get %an take up more than one %olumn by in%lu ing the android!layout*span property, in i%ating the number o$ %olumns the Ci get spans. 5his is akin to the colspan attribute one $in s in table %ells in )5ML*
<-ableRow& <-ext7iew android!text"#2R+!# /& <)dit-ext android!id"#9Bid/entry# android!layout*span"#I#/& </-ableRow&
.n the above EML layout $ragment, the $iel spans three %olumns. >r inarily, Ci gets are put into the $irst available %olumn. .n the above $ragment, the label Coul go in the $irst %olumn &%olumn @, as %olumns are %ounte starting $rom @', an the $iel Coul go into a spanne set o$ three %olumns &%olumns ? through I'. )oCever, you %an put a Ci get into a i$$erent %olumn via the android!layout*column property, spe%i$ying the @3 base %olumn the Ci get belongs to*
<-ableRow& <6utton android!id"#9Bid/cancel# android!layout*column"#H# android!text"#Cancel# /& <6utton android!id"#9Bid/ok# android!text"#,M# /& </-ableRow&
/3
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
.n the pre%e ing EML layout $ragment, the Can%el button goes in the thir %olumn &%olumn H'. 5he >F button then goes into the ne;t available %olumn, Chi%h is the $ourth %olumn.
@ou %an also leverage an android!collapseColumns property on the -able+ayout, again Cith a %olumn number or %omma3 elimite list o$ %olumn numbers. 5hese %olumns Cill start out Q%ollapse Q, meaning they Cill be part o$ the table in$ormation but Cill be invisible. !rogrammati%ally, you %an %ollapse an un3%ollapse %olumns by %alling setColumnCollapsed:; on the -able+ayout. @ou might use this to alloC users to %ontrol Chi%h %olumns are o$ importan%e to them an shoul be shoCn versus Chi%h ones are less important an %an be hi en. @ou also %ontrol stret%hing an shrinking setColumnStretc$able:; an setColumnS$rinkable:;. %an at runtime via
E. mple
5he EML layout $ragments shoCn above, Chen %ombine , give us a -able+ayout ren ition o$ the Q$ormQ Ce %reate $or Relative+ayout, Cith the a ition o$ a ivi er line betCeen the labelU$iel an the tCo buttons &$oun in the -able emo'*
<>xml version"#?.@# encodin%"#utf(A#>& <-able+ayout xmlns!android"#$ttp!//sc$emas.android.com/apk/res/android# android!layout*widt$"#fill*parent# android!layout*$ei%$t"#fill*parent# android!stretc$Columns"#?#& <-ableRow& <-ext7iew android!text"#2R+!# /& <)dit-ext android!id"#9Bid/entry# android!layout*span"#I#/& </-ableRow& <7iew android!layout*$ei%$t"#Hpx# android!back%round"#D@@@@EE# /& <-ableRow& <6utton android!id"#9Bid/cancel# android!layout*column"#H# android!text"#Cancel# /& <6utton android!id"#9Bid/ok# android!text"#,M# /& </-ableRow& </-able+ayout&
/9
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
When %ompile against the generate +ava %o e an run on the emulator, Ce get*
Scroll4ork
!hone s%reens ten to be small, Chi%h re<uires evelopers to use some tri%ks to present a lot o$ in$ormation in the limite available spa%e. >ne tri%k $or oing this is to use s%rolling, so only part o$ the in$ormation is visible at one time, the rest available via s%rolling up or oCn. is a %ontainer that provi es s%rolling $or its %ontents. @ou %an take a layout that might be too big $or some s%reens, Crap it in a Scroll7iew, an still use your e;isting layout logi%. .t Oust so happens that the user %an only see part o$ your layout at one time, the rest available via s%rolling.
Scroll7iew
(or e;ample, here is a Scroll7iew use in an EML layout $ile &$rom the Scroll emo'*
0;
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
<>xml version"#?.@# encodin%"#utf(A#>& <Scroll7iew xmlns!android"#$ttp!//sc$emas.android.com/apk/res/android# android!layout*widt$"#fill*parent# android!layout*$ei%$t"#wrap*content#& <-able+ayout android!layout*widt$"#fill*parent# android!layout*$ei%$t"#fill*parent# android!stretc$Columns"#@#& <-ableRow& <7iew android!layout*$ei%$t"#A@px# android!back%round"#D@@@@@@#/& <-ext7iew android!text"#D@@@@@@# android!paddin%+eft"#Npx# android!layout*%ravity"#center*vertical# /& </-ableRow& <-ableRow& <7iew android!layout*$ei%$t"#A@px# android!back%round"#DNN@@@@# /& <-ext7iew android!text"#DNN@@@@# android!paddin%+eft"#Npx# android!layout*%ravity"#center*vertical# /& </-ableRow& <-ableRow& <7iew android!layout*$ei%$t"#A@px# android!back%round"#DAANN@@# /& <-ext7iew android!text"#DAANN@@# android!paddin%+eft"#Npx# android!layout*%ravity"#center*vertical# /& </-ableRow& <-ableRow& <7iew android!layout*$ei%$t"#A@px# android!back%round"#DaaAANN# /& <-ext7iew android!text"#DaaAANN# android!paddin%+eft"#Npx# android!layout*%ravity"#center*vertical# /& </-ableRow& <-ableRow& <7iew android!layout*$ei%$t"#A@px# android!back%round"#DffaaAA# /& <-ext7iew android!text"#DffaaAA# android!paddin%+eft"#Npx# android!layout*%ravity"#center*vertical# /& </-ableRow& <-ableRow& <7iew android!layout*$ei%$t"#A@px# android!back%round"#Dffffaa# /& <-ext7iew android!text"#Dffffaa# android!paddin%+eft"#Npx# 0(
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
android!layout*%ravity"#center*vertical# /& </-ableRow& <-ableRow& <7iew android!layout*$ei%$t"#A@px# android!back%round"#Dffffff# /& <-ext7iew android!text"#Dffffff# android!paddin%+eft"#Npx# android!layout*%ravity"#center*vertical# /& </-ableRow& </-able+ayout& </Scroll7iew&
Without the Scroll7iew, the table Coul take up at least B40 pi;els &2 roCs at 80 pi;els ea%h, base on the 7iew e%larations'. 5here may be some evi%es Cith s%reens %apable o$ shoCing that mu%h in$ormation, but many Cill be smaller. 5he Scroll7iew lets us keep the table as3is, but only present part o$ it at a time. >n the sto%k An roi emulator, Chen the a%tivity is $irst vieCe , you see*
0%
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
0oti%e hoC only $our roCs an part o$ the $i$th are visible. /y pressing the upU oCn buttons on the ire%tional pa , you %an s%roll up an oCn to see the remaining roCs.
0,
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
CHAPTER /
/a%k in the %hapter on basi% Ci gets, you saC hoC $iel s %oul have %onstraints pla%e upon them to limit possible input, su%h as numeri%3only or phone3number3only. 5hese sorts o$ %onstraints help users Qget it rightQ Chen entering in$ormation, parti%ularly on a mobile evi%e Cith %rampe keyboar s. >$ %ourse, the ultimate in %onstraine input is to sele%t a %hoi%e $rom a set o$ items, su%h as the ra io buttons seen earlier. Classi% ". toolkits have listbo;es, %ombobo;es, rop3 oCn lists, an the like $or that very purpose. An roi has many o$ the same sorts o$ Ci gets, plus others o$ parti%ular interest $or mobile evi%es &e.g., the 0allery $or e;amining save photos'. Moreover, An roi o$$ers a $le;ible $rameCork $or etermining Chat %hoi%es are available in these Ci gets. #pe%i$i%ally, An roi o$$ers a $rameCork o$ ata a apters that provi e a %ommon inter$a%e to sele%tion lists ranging $rom stati% arrays to atabase %ontents. #ele%tion vieCs N Ci gets $or presenting lists o$ %hoi%es N are han e an a apter to supply the a%tual %hoi%es.
5his use o$ +ava inter$a%es is $airly %ommon &e.g., +avaU#Cing7s mo el a apters $or =-able', an +ava is $ar $rom the only environment o$$ering this sort o$ abstra%tion &e.g., (le;7s EML ata3bin ing $rameCork a%%epts EML inline as stati% ata or retrieve $rom the .nternet'. An roi 7s a apters are responsible $or provi ing the roster o$ ata $or a sele%tion Ci get plus %onverting in ivi ual elements o$ ata into spe%i$i% vieCs to be isplaye insi e the sele%tion Ci get. 5he latter $a%et o$ the a apter system may soun a little o , but in reality it is not that i$$erent $rom other 8". toolkits7 Cays o$ overri ing e$ault isplay behavior. (or e;ample, in +avaU#Cing, i$ you Cant a =+ist3ba%ke listbo; to a%tually be a %he%klist &Chere in ivi ual roCs are a %he%kbo; plus label, an %li%ks a Oust the state o$ the %he%kbo;', you inevitably Cin up %alling setCellRenderer:; to supply your oCn +istCellRenderer, Chi%h in turn %onverts strings $or the list into =C$eck6ox3plus3=+abel %omposite Ci gets.
5he Context to use &typi%ally this Cill be your a%tivity instan%e' 5he resour%e .A o$ a vieC to use &su%h as a built3in system resour%e .A, as shoCn above' 5he a%tual array or list o$ items to shoC
/y e$ault, the ArrayAdapter Cill invoke toStrin%:; on the obOe%ts in the list an Crap ea%h o$ those strings in the vieC esignate by the supplie resour%e. android.R.layout.simple*list*item*? simply turns those strings
00
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
into -ext7iew obOe%ts. 5hose -ext7iew Ci gets, in turn, Cill be shoCn the list or spinner or Chatever Ci get uses this ArrayAdapter. @ou %an sub%lass ArrayAdapter an vieCs* overri e %et7iew:; to Qroll your oCnQ
public 7iew getView:int positionG 7iew convert7iewG 7iew0roup parent; 8 if :convert7iew""null; 8 convert7iew"new TextView:t$is;5 < convert7iew.setText:!uildString"or:position;;5 < return:convert7iew;5
5he in e; o$ the item in the array to shoC in the vieC An e;isting vieC to up ate Cith the ata $or this position &i$ one alrea y e;iste , su%h as $rom s%rolling N i$ null, you nee to instantiate your oCn' 5he Ci get that Cill %ontain this vieC, i$ nee e $or instantiating the vieC
.n the e;ample shoCn above, the a apter still returns a -ext7iew, but uses a i$$erent behavior $or etermining the string that goes in the vieC. 5he 5our.t sample appli%ation emonstrates using a more %ompli%ate %ustom vieC $or a list a apter.
an Activity.conAdapter provi e you Cith the names or i%ons o$ a%tivities that %an be invoke upon a parti%ular intent
ActivityAdapter
07
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
5he +ava %o e to %on$igure the list an %onne%t the list Cith the label is*
public class +ist7iewDemo extends +istActivity 8 -ext7iew selection5 Strin%OP items"8#lorem#G #ipsum#G #dolor#G #sit#G #amet#G #consectetuer#G #adipiscin%#G #elit#G #morbi#G #vel#G #li%ula#G #vitae#G #arcu#G #aliJuet#G #mollis#G #etiam#G #vel#G #erat#G #placerat#G #ante#G #porttitor#G #sodales#G #pellentesJue#G #au%ue#G #purus#<5 /QQ Called wit$ t$e activity is first created. Q/ 9,verride public void onCreate:6undle icicle; 8 super.onCreate:icicle;5 setContentView:R.layout.main;5 setList#dapter:new ArrayAdapter<Strin%&:t$isG android.R.layout.simple*list*item*?G items;;5 selection":-ext7iew;findViewById:R.id.selection;5 < public void onListItemClick:+ist7iew parentG 7iew vG int positionG lon% id; 8 selection.setText:itemsOpositionP;5 < <
With +istActivity, you %an set the list a apter via set+istAdapter:; N in this %ase, provi ing an ArrayAdapter Crapping an array o$ nonsense strings. 5o $in out Chen the list sele%tion %hanges, overri e on+ist.temClick:; an take appropriate steps base on the supplie %hil vieC an position &in this %ase, up ating the label Cith the te;t $or that position'. 5he resultsD
09
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
Spin Control
.n An roi , the Spinner is the e<uivalent o$ the rop3 oCn sele%tor you might $in in other toolkits &e.g., =Combo6ox in +avaU#Cing'. !ressing the le$t an right buttons on the A3pa iterates over %hil ren. !ressing the %enter button on the A3pa isplays, by e$ault, a small list &akin to a +ist7iew' appears to shoC a $eC items at a time, instea o$ the one3item3at3a3time perspe%tive the une;pan e Spinner itsel$ provi es. As Cith +ist7iew, you provi e the a apter $or ata an %hil vieCs via setAdapter:; an hook in a listener obOe%t $or sele%tions via set,n.temSelected+istener:;. .$ you Cant to tailor the vieC use Chen isplaying the rop3 oCn perspe%tive, you nee to %on$igure the a apter, not the Spinner Ci get. "se the setDropDown7iewResource:; metho to supply the resour%e .A o$ the vieC to use.
3;
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
(or e;ample, %ulle $rom the Spinner sample proOe%t, here is an EML layout $or a simple vieC Cith a Spinner*
<>xml version"#?.@# encodin%"#utf(A#>& <+inear+ayout xmlns!android"#$ttp!//sc$emas.android.com/apk/res/android# android!orientation"#vertical# android!layout*widt$"#fill*parent# android!layout*$ei%$t"#fill*parent# & <-ext7iew android!id"#9Bid/selection# android!layout*widt$"#fill*parent# android!layout*$ei%$t"#wrap*content# /& <Spinner android!id"#9Bid/spinner# android!layout*widt$"#fill*parent# android!layout*$ei%$t"#wrap*content# android!drawSelector,n-op"#true# /& </+inear+ayout&
5his is the same vieC as shoCn in the previous se%tion, Oust Cith a Spinner instea o$ a +ist7iew. 5he Spinner property android!drawSelector,n-op %ontrols Chether the arroCs are raCn on the sele%tor button on the right si e o$ the Spinner ".. 5o populate an use the Spinner, Ce nee some +ava %o e*
public class SpinnerDemo extends Activity implements Adapter7iew.,n.temSelected+istener 8 -ext7iew selection5 Strin%OP items"8#lorem#G #ipsum#G #dolor#G #sit#G #amet#G #consectetuer#G #adipiscin%#G #elit#G #morbi#G #vel#G #li%ula#G #vitae#G #arcu#G #aliJuet#G #mollis#G #etiam#G #vel#G #erat#G #placerat#G #ante#G #porttitor#G #sodales#G #pellentesJue#G #au%ue#G #purus#<5 9,verride public void onCreate:6undle icicle; 8 super.onCreate:icicle;5 setContentView:R.layout.main;5 selection":-ext7iew;findViewById:R.id.selection;5 Spinner spin":Spinner;findViewById:R.id.spinner;5 spin.setOnItemSelectedListener:t$is;5 ArrayAdapter<Strin%& aa"new ArrayAdapter<Strin%&:t$isG android.R.layout.simple*list*item*?G
3(
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
items;5 aa.setDropDownView$esource: android.R.layout.simple*spinner*dropdown*item;5 spin.set#dapter:aa;5 < public void onItemSelected:Adapter7iew parentG 7iew vG int positionG lon% id; 8 selection.setText:itemsOpositionP;5 < public void on%othingSelected:Adapter7iew parent; 8 selection.setText:##;5 < <
)ere, Ce atta%h the a%tivity itsel$ as the sele%tion listener &spin.set,n.temSelected+istener:t$is;'. 5his Corks be%ause the a%tivity implements the ,n.temSelected+istener inter$a%e. We %on$igure the a apter not only Cith the list o$ $ake Cor s, but also Cith a spe%i$i% resour%e to use $or the rop3 oCn vieC &via aa.setDropDown7iewResource:;'. (inally, Ce implement the %allba%ks re<uire by ,n.temSelected+istener to a Oust the sele%tion label base on user input. What Ce get is*
3%
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
!igure (9< The same application6 4ith the spinner drop"do4n list displayed
3,
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
spells out hoC many %olumns there are, or, i$ you supply a value o$ auto*fit, An roi Cill %ompute the number o$ %olumns base on available spa%e an the properties liste beloC.
android!numColumns android!verticalSpacin% android!$ori'ontalSpacin% android!columnCidt$
an its %ounterpart in i%ate hoC many pi;els o$ Chitespa%e there shoul be betCeen items in the gri . in i%ates hoC many pi;els Ci e ea%h %olumn shoul be.
i%ates, $or gri s Cith auto*fit $or shoul happen $or any available spa%e not taken up by %olumns or spa%ing N this shoul be columnCidt$ to have the %olumns take up available spa%e or spacin%Cidt$ to have the Chitespa%e betCeen %olumns absorb e;tra spa%e. (or e;ample, suppose the s%reen is ?20 pi;els Ci e, an Ce have android!columnCidt$ set to ?@@ an android!$ori'ontalSpacin% set to L. 5hree %olumns Coul use ?-0 pi;els &three %olumns o$ -00 pi;els an tCo Chitespa%es o$ B pi;els'. With android!stretc$Mode set to columnCidt$, the three %olumns Cill ea%h e;pan by ?3= pi;els to use up the remaining -0 pi;els. With android!stretc$Mode set to spacin%Cidt$, the tCo Chitespa%es Cill ea%h groC by B pi;els to %onsume the remaining -0 pi;els. that
0ote
the properties android!verticalSpacin%, android!$ori'ontalSpacin%, an android!columnCidt$ all take a simple number pi;els, not a imension, at the time o$ this Criting.
3$
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
>therCise, the 0rid7iew Corks mu%h like any other sele%tion Ci get N use setAdapter:; to provi e the ata an %hil vieCs, invoke set,n.temSelected+istener:; to register a sele%tion listener, et%. (or e;ample, here is a EML layout $rom the 0rid sample proOe%t, shoCing a 0rid7iew %on$iguration*
<>xml version"#?.@# encodin%"#utf(A#>& <+inear+ayout xmlns!android"#$ttp!//sc$emas.android.com/apk/res/android# android!orientation"#vertical# android!layout*widt$"#fill*parent# android!layout*$ei%$t"#fill*parent# & <-ext7iew android!id"#9Bid/selection# android!layout*widt$"#fill*parent# android!layout*$ei%$t"#wrap*content# /& <0rid7iew android!id"#9Bid/%rid# android!layout*widt$"#fill*parent# android!layout*$ei%$t"#fill*parent# android!verticalSpacin%"#IL# android!$ori'ontalSpacin%"#L# android!numColumns"#auto*fit# android!columnCidt$"#?@@# android!stretc$Mode"#columnCidt$# android!%ravity"#center# /& </+inear+ayout&
(or this gri , Ce take up the entire s%reen e;%ept $or Chat our sele%tion label re<uires. 5he number o$ %olumns is %ompute by An roi &android!numColumns " #auto*fit#' base on B3pi;el horiKontal spa%ing &android!$ori'ontalSpacin% " #L#', -003pi;el %olumns &android!columnCidt$ " #?@@#', Cith the %olumns absorbing any QslopQ Ci th le$t over &android!stretc$Mode " #columnCidt$#'. 5he +ava %o e to %on$igure the 0rid7iew is*
public class 0ridDemo extends Activity implements Adapter7iew.,n.temSelected+istener 8 -ext7iew selection5 Strin%OP items"8#lorem#G #ipsum#G #dolor#G #sit#G #amet#G #consectetuer#G #adipiscin%#G #elit#G #morbi#G #vel#G
3/
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
#li%ula#G #vitae#G #arcu#G #aliJuet#G #mollis#G #etiam#G #vel#G #erat#G #placerat#G #ante#G #porttitor#G #sodales#G #pellentesJue#G #au%ue#G #purus#<5 9,verride public void onCreate:6undle icicle; 8 super.onCreate:icicle;5 setContentView:R.layout.main;5 selection":-ext7iew;findViewById:R.id.selection;5 0rid7iew %":0rid7iew; findViewById:R.id.%rid;5 %.set#dapter:new "unnyLooking#dapter:t$isG android.R.layout.simple*list*item*?G items;;5 %.setOnItemSelectedListener:t$is;5 < public void onItemSelected:Adapter7iew parentG 7iew vG int positionG lon% id; 8 selection.setText:itemsOpositionP;5 < public void on%othingSelected:Adapter7iew parent; 8 selection.setText:##;5 < private class Eunny+ookin%Adapter extends ArrayAdapter 8 Context ctxt5 "unnyLooking#dapter:Context ctxtG int resourceG Strin%OP items; 8 super:ctxtG resourceG items;5 < t$is.ctxt"ctxt5
public 7iew getView:int positionG 7iew convert7iewG 7iew0roup parent; 8 -ext7iew label":-ext7iew;convert7iew5 if :convert7iew""null; 8 convert7iew"new TextView:ctxt;5 label":-ext7iew;convert7iew5 < label.setText:itemsOpositionP;5 < < < return:convert7iew;5
30
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
(or the gri %ells, rather than using auto3generate -ext7iew Ci gets as in the previous se%tions, Ce %reate our oCn vieCs, by sub%lassing ArrayAdapter an overri ing %et7iew:;. .n this %ase, Ce Crap the $unny3looking strings in our oCn -ext7iew Ci gets, Oust to be i$$erent. .$ %et7iew:; re%eives a -ext7iew, Ce Oust reset its te;tP otherCise, Ce %reate a neC -ext7iew instan%e an populate it. With the ?B3pi;el verti%al spa%ing $rom the EML layout &android!verticalSpacin% " #IL#', the gri over$loCs the boun aries o$ the emulator7s s%reen*
33
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
!igure %(< The same application6 scrolled to the bottom of the grid
.n a ition, AutoComplete-ext7iew has a android!completion-$res$old property, to in i%ate the minimum number o$ %hara%ters a user must enter be$ore the list $iltering begins. @ou %an give AutoComplete-ext7iew an a apter %ontaining the list o$ %an i ate values via setAdapter:;. )oCever, sin%e the user %oul type
37
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
something not in the list, AutoComplete-ext7iew oes not support sele%tion listeners. .nstea , you %an register a -extCatc$er, like you %an Cith any )dit7iew, to be noti$ie Chen the te;t %hanges. 5hese events Cill o%%ur either be%ause o$ manual typing or $rom a sele%tion $rom the rop3 oCn list. /eloC Ce have a $amiliar3looking EML layout, this time %ontaining an AutoComplete-ext7iew &pulle $rom the AutoComplete sample appli%ation'*
<>xml version"#?.@# encodin%"#utf(A#>& <+inear+ayout xmlns!android"#$ttp!//sc$emas.android.com/apk/res/android# android!orientation"#vertical# android!layout*widt$"#fill*parent# android!layout*$ei%$t"#fill*parent# & <-ext7iew android!id"#9Bid/selection# android!layout*widt$"#fill*parent# android!layout*$ei%$t"#wrap*content# /& <AutoComplete-ext7iew android!id"#9Bid/edit# android!layout*widt$"#fill*parent# android!layout*$ei%$t"#wrap*content# android!completion-$res$old"#I#/& </+inear+ayout&
39
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
<
android.R.layout.simple*list*item*?G items;;5
public void onTextChanged:C$arSeJuence sG int startG int beforeG int count; 8 selection.setText:edit.getText:;;5 < public void !eforeTextChanged:C$arSeJuence sG int startG int countG int after; 8 // needed for interfaceG but not used < <
5his time, our a%tivity implements -extCatc$er, Chi%h means our %allba%ks are on-extC$an%ed:; an before-extC$an%ed:;. .n this %ase, Ce are only intereste in the $ormer, an Ce up ate the sele%tion label to mat%h the AutoComplete-ext7iew7s %urrent %ontents. )ere Ce have the results*
7;
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
!igure %,< The same application6 after a fe4 matching letters 4ere entered6 sho4ing the auto"complete drop"do4n
!igure %$< The same application6 after the auto"complete value 4as selected
7(
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
list
android!spinnerSelector
%ontrols Chat is use to in i%ate a sele%tion N this %an either be a re$eren%e to a Drawable &see the resour%es %hapter' or an R8/ value in DAARR0066 or similar notation
android!drawSelector,n-op in i%ates i$ the sele%tion bar &or Drawable' shoul be raCn be$ore &false' or a$ter &true' raCing the sele%te %hil N i$ you %hoose true, be sure that your sele%tor has su$$i%ient
transparen%y to shoC the %hil through the sele%tor, otherCise users Cill not be able to rea the sele%tion
7%
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
CHAPTER 2
5he Ci gets an %ontainers %overe to ate are not only $oun in many 8". toolkits &in one $orm or $ashion', but also are Ci ely use in buil ing 8". appli%ations, Chether Web3base , esktop, or mobile. 5he Ci gets an %ontainers in this %hapter are a little less Ci ely use , though you Cill likely $in many to be <uite use$ul.
also %hoose the ay on Chi%h a Ceek QbeginsQ N the tra itional "# %alen ar has Ceeks beginning on a #un ay &S2/DAF'. Most importantly, ea%h let you provi e a %allba%k obOe%t &,nDateSet+istener' Chere you are in$orme o$ a neC ate sele%te by the user. .t is up to you to store that ate somepla%e, parti%ularly i$ you are using the ialog, sin%e there is no other Cay $or you to get at the %hosen ate later on. #imilarly, -ime1icker an -ime1ickerDialo% let you*
set the initial time the user %an a Oust, in the $orm o$ an hour &@ through HI' an a minute &@ through LR' in i%ate i$ the sele%tion shoul be in -23hour mo e Cith an AMU!M toggle, or in 2=3hour mo e &Chat in the "# is thought o$ as Qmilitary timeQ an in the rest o$ the Corl is thought o$ as Qthe Cay times are suppose to beQ' provi e a %allba%k obOe%t &,n-imeSet+istener' to be noti$ie o$ Chen the user has %hosen a neC time, Chi%h is supplie to you in the $orm o$ an hour an minute
(or e;ample, $rom the C$rono sample proOe%t, here7s a trivial layout %ontaining a label an tCo buttons N the buttons Cill pop up the ialog $lavors o$ the ate an time pi%kers*
<>xml version"#?.@# encodin%"#utf(A#>& <+inear+ayout xmlns!android"#$ttp!//sc$emas.android.com/apk/res/android# android!orientation"#vertical# android!layout*widt$"#fill*parent# android!layout*$ei%$t"#fill*parent# & <-ext7iew android!id"#9Bid/dateAnd-ime# android!layout*widt$"#fill*parent# android!layout*$ei%$t"#wrap*content# /& <6utton android!id"#9Bid/date6tn# android!layout*widt$"#fill*parent# android!layout*$ei%$t"#wrap*content# android!text"#Set t$e Date# /& <6utton android!id"#9Bid/time6tn# android!layout*widt$"#fill*parent# android!layout*$ei%$t"#wrap*content# android!text"#Set t$e -ime#
7$
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
/& </+inear+ayout&
7/
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
true;.show:;5 < <;5 dateAnd-ime+abel":-ext7iew;findViewById:R.id.dateAnd-ime;5 updateLa!el:;5 < private void updateLa!el:; 8 dateAnd-ime+abel.setText:fmtDateAnd-ime .format:dateAnd-ime.getTime:;;;5 < <
5he Qmo elQ $or this a%tivity is Oust a Calendar instan%e, initially set to be the %urrent ate an time. We pour it into the vieC via a DateEormat $ormatter. .n the update+abel:; metho , Ce take the %urrent Calendar, $ormat it, an put it in the -ext7iew. Ia%h button is given a ,nClick+istener %allba%k obOe%t. When the button is %li%ke , either a Date1ickerDialo% or a -ime1ickerDialo% is shoCn. .n the %ase o$ the Date1ickerDialo%, Ce give it a ,nDateSet+istener %allba%k that up ates the Calendar Cith the neC ate &year, month, ay o$ month'. We also give the ialog the last3sele%te ate, getting the values out o$ the Calendar. .n the %ase o$ the -ime1ickerDialo%, it gets a ,n-imeSet+istener %allba%k to up ate the time portion o$ the Calendar, the last3sele%te time, an a true in i%ating Ce Cant 2=3hour mo e on the time sele%tor. With all this Cire together, the resulting a%tivity looks like this*
70
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
!igure %0< The same application6 sho4ing the date picker dialog
73
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
!igure %3< The same application6 sho4ing the time picker dialog
77
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
Without any +ava %o e other than the generate proOe%t an get the $olloCing a%tivity*
this
*aking Progress
.$ you nee to be oing something $or a long perio o$ time, you oCe it to your users to o tCo things*
"se a ba%kgroun threa , Chi%h Cill be %overe in a later %hapter Feep them apprise o$ your progress, lest they think your a%tivity has Can ere aCay an Cill never %ome ba%k
5he typi%al approa%h to keeping users in$orme o$ progress is some $orm o$ progress bar or QthrobberQ &think the animate graphi% toCar s the upper3
79
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
right %orner o$ many Web broCsers'. An roi supports this through the 1ro%ress6ar Ci get. A !rogress/ar keeps tra%k o$ progress, e$ine as an integer, Cith 0 in i%ating no progress has been ma e. @ou %an e$ine the ma;imum en o$ the range N Chat value in i%ates progress is %omplete N via the android!max property. /y e$ault, a 1ro%ress6ar starts Cith a progress o$ @, though you %an start $rom some other position via the android!pro%ress property. you pre$er your progress bar to be in eterminate, use the android!indeterminate property, setting it to true. @ou probably shoul also set the android!indeterminate6e$avior property to either repeat &to loop en lessly until stoppe in +ava %o e' or cycle to reverse %ourse an hea ba%k to @. .n your +ava %o e, you %an either positively set the amount o$ progress that has been ma e &via set1ro%ress:;' or in%rement the progress $rom its %urrent amount &via increment1ro%ress6y:;'. @ou %an $in out hoC mu%h progress has been ma e via %et1ro%ress:;. #in%e the 1ro%ress6ar is tie %losely to the use o$ threa s N a ba%kgroun threa oing Cork, up ating the ". threa Cith neC progress in$ormation N Ce Cill hol o$$ emonstrating the use o$ 1ro%ress6ar to a later %hapter. .$
Putting 8t +n *y Tab
5he general An roi philosophy is to keep a%tivities short an sCeet. .$ there is more in$ormation than %an reasonably $it on one s%reen, albeit perhaps Cith s%rolling, then it perhaps belongs in another a%tivity ki%ke o$$ via an .ntent, as Cill be es%ribe later in this book. )oCever, that %an be %ompli%ate to set up. Moreover, sometimes there legitimately is a lot o$ in$ormation that nee s to be %olle%te to be pro%esse as an atomi% operation. .n a tra itional "., you might use tabs to a%%omplish this en , su%h as a =-abbed1ane in +avaU#Cing. .n An roi , you noC have an option o$ using a
9;
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
%ontainer in mu%h the same Cay N a portion o$ your a%tivity7s s%reen is taken up Cith tabs Chi%h, Chen %li%ke , sCap out part o$ the vieC an repla%e it Cith something else. (or e;ample, you might have an a%tivity Cith a tab $or entering a lo%ation an a se%on tab $or shoCing a map o$ that lo%ation.
-ab3ost
#ome 8". toolkits re$er to QtabsQ as being Oust the things a user %li%ks on to toggle $rom one vieC to another. #ome toolkits re$er to QtabsQ as being the %ombination o$ the %li%kable button3ish element an the %ontent that appears Chen that tab is %hosen. An roi treats the tab buttons an %ontents as is%rete entities, so Ce Cill %all them Qtab buttonsQ an Qtab %ontentsQ in this se%tion.
The Pieces
5here are a $eC Ci gets an %ontainers you nee to use in or er to set up a tabbe portion o$ a vieC*
-ab3ost
tab
implements the roC o$ tab buttons, Chi%h %ontain te;t labels an optionally %ontain i%ons is the %ontainer $or the tab %ontentsP ea%h tab %ontent is a %hil o$ the Erame+ayout
Erame+ayout
5his is similar to the approa%h that MoKilla7s E"L takes. .n E"L7s %ase, the tabbox element %orrespon s to An roi 7s -ab3ost, the tabs element %orrespon s to -abCid%et, an tabpanels %orrespon s to the Erame+ayout.
9(
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
.$ you Cish to use the -abActivity, you must give the -ab3ost an android!id o$ 9android!id/tab$ost
-abActivity,
like +istActivity, Craps a %ommon ". pattern &a%tivity ma e up entirely o$ tabs' into a pattern3aCare a%tivity sub%lass. @ou o not ne%essarily have to use -abActivity N a plain a%tivity %an use tabs as Cell. With respe%t to the Erame+ayout pa ing issue, $or Chatever reason, the -abCid%et oes not seem to allo%ate its oCn spa%e insi e the -ab3ost %ontainer. .n other Cor s, no matter Chat you spe%i$y $or android!layout*$ei%$t $or the -abCid%et, the Erame+ayout ignores it an raCs at the top o$ the overall -ab3ost. @our tab %ontents obs%ure your tab buttons. )en%e, you nee to leave enough pa ing &via android!paddin%-op' in Erame+ayout to QshoveQ the a%tual tab %ontents oCn beneath the tab buttons. 5his is likely a bug, so this behavior may Cell %hange in $uture versions o$ the toolkit. .n a ition, the -abCid%et seems to alCays raC itsel$ Cith room $or i%ons, even i$ you o not supply i%ons. )en%e, $or this version o$ the toolkit, you nee to supply at least 42 pi;els o$ pa ing, perhaps more epen ing on the i%ons you supply. (or e;ample, here is a layout e$inition $or a tabbe a%tivity, $rom -ab*
<>xml version"#?.@# encodin%"#utf(A#>& <+inear+ayout xmlns!android"#$ttp!//sc$emas.android.com/apk/res/android# android!orientation"#vertical# android!layout*widt$"#fill*parent# android!layout*$ei%$t"#fill*parent#& <-ab3ost android!id"#9Bid/tab$ost# android!layout*widt$"#fill*parent# android!layout*$ei%$t"#fill*parent#& <-abCid%et android!id"#9android!id/tabs# android!layout*widt$"#fill*parent# android!layout*$ei%$t"#wrap*content# /& <Erame+ayout android!id"#9android!id/tabcontent# android!layout*widt$"#fill*parent# android!layout*$ei%$t"#fill*parent#
9%
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
android!paddin%-op"#SHpx#& <Analo%Clock android!id"#9Bid/tab?# android!layout*widt$"#fill*parent# android!layout*$ei%$t"#fill*parent# android!layout*center3ori'ontal"#true# /& <6utton android!id"#9Bid/tabH# android!layout*widt$"#fill*parent# android!layout*$ei%$t"#fill*parent# android!text"#A semi(random button# /& </Erame+ayout& </-ab3ost& </+inear+ayout&
0ote that the -abCid%et an Erame+ayout are imme iate %hil ren o$ the -ab3ost, an the Erame+ayout itsel$ has %hil ren representing the various tabs. .n this %ase, there are tCo tabs* a %lo%k an a button. .n a more %ompli%ate s%enario, the tabs are probably some $orm o$ %ontainer &e.g., +inear+ayout' Cith their oCn %ontents.
3irin! It To!ether
5he +ava %o e nee s to tell the -ab3ost Chat vieCs represent the tab %ontents an Chat the tab buttons shoul look like. 5his is all Crappe up in -abSpec obOe%ts. @ou get a -abSpec instan%e $rom the host via new-abSpec:;, $ill it out, then a it to the host in the proper se<uen%e. 5he tCo key metho s on -abSpec are*
setContent:;,
Chere you in i%ate Chat goes in the tab %ontent $or this tab, typi%ally the android!id o$ the vieC you Cant shoCn Chen this tab is sele%te
set.ndicator:;,
Chere you provi e the %aption $or the tab button an , in some $lavors o$ this metho , supply a Drawable to represent the i%on $or the tab
0ote that tab Qin i%atorsQ %an a%tually be vieCs in their oCn right, i$ you nee more %ontrol than a simple label an optional i%on.
9,
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
Also note that you must %all setup:; on the -ab3ost be$ore %on$iguring any o$ these -abSpec obOe%ts. 5he %all to setup:; is not nee e i$ you are using the -abActivity base %lass $or your a%tivity. (or e;ample, here is the +ava %o e to Cire together the tabs $rom the pre%e ing layout e;ample*
packa%e com.commonsware.android.fancy5 import android.app.Activity5 import android.os.6undle5 import android.wid%et.-ab3ost5 public class -abDemo extends Activity 8 9,verride public void onCreate:6undle icicle; 8 super.onCreate:icicle;5 setContentView:R.layout.main;5 -ab3ost tabs":-ab3ost;findViewById:R.id.tab$ost;5 tabs.setup:;5 -ab3ost.-abSpec spec"tabs.newTa!Spec:#ta%?#;5 spec.setContent:R.id.tab?;5 spec.setIndicator:#Clock#;5 tabs.addTa!:spec;5 spec"tabs.newTa!Spec:#ta%H#;5 spec.setContent:R.id.tabH;5 spec.setIndicator:#6utton#;5 tabs.addTa!:spec;5 < < tabs.setCurrentTa!:@;5
We $in our -ab3ost via the $amiliar find7iew6y.d:; metho , then have it setup:;. A$ter that, Ce get a -abSpec via new-abSpec:;, supplying a tag Chose purpose is unknoCn at this time. 8iven the spe%, you %all setContent:; an set.ndicator:;, then %all add-ab:; ba%k on the -ab3ost to register the tab as available $or use. (inally, you %an %hoose Chi%h tab is the one to shoC via setCurrent-ab:;, provi ing the @3base in e; o$ the tab. 5he resultD
9$
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
!igure %9< The Tab.emo sample application6 sho4ing the first tab
9/
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
90
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
CHAPTER 14
)pplying *enus
Like appli%ations $or the esktop an some mobile operating systems, su%h as !alm># an Win oCs Mobile, An roi supports a%tivities Cith Qappli%ationQ menus. #ome An roi phones Cill have a e i%ate menu key $or popping up the menuP others Cill o$$er alternate means $or triggering the menu to appear. Also, as Cith many 8". toolkits, you %an %reate Q%onte;t menusQ. >n a tra itional 8"., this might be triggere by the right3mouse button. >n mobile evi%es, %onte;t menus typi%ally appear Chen the user Qtaps3an 3 hol sQ over a parti%ular Ci get. (or e;ample, i$ a -ext7iew ha a %onte;t menu, an the evi%e Cas esigne $or $inger3base tou%h input, you %oul push the -ext7iew Cith your $inger, hol it $or a se%on or tCo, an a pop3up menu Cill appear $or the user to %hoose $rom. Where An roi i$$ers $rom most other 8". toolkits is in terms o$ menu %onstru%tion. While you %an a items to the menu, you o not have $ull %ontrol over the menu7s %ontents, nor the timing o$ Chen the menu is built. !art o$ the menu is system3 e$ine , an that portion is manage by the An roi $rameCork itsel$.
!lavors of *enu
An roi %onsi ers the tCo types o$ menu es%ribe above as being the Qoptions menuQ an Q%onte;t menuQ. 5he options menu is triggere by
93
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
)pplying *enus
pressing the har Care QMenuQ button on the evi%e, Chile the %onte;t menu is raise by a tap3an 3hol on the Ci get sporting the menu. .n a ition, the options menu operates in one o$ tCo mo es* i%on an e;pan e . When the user $irst presses the QMenuQ button, the i%on mo e Cill appear, shoCing up to the $irst $ive menu %hoi%es as large, $inger3 $rien ly buttons in a gri at the bottom o$ the s%reen. .$ the menu has more than $ive %hoi%es, a si;th button Cill appear, labele QMoreQ N %li%king that option Cill bring up the e;pan e mo e, shoCing all available %hoi%es. 0otably, the sele%tion bar Cill not be on the $irst menu %hoi%e, but rather the si;th, $iguring that the user probably Cants something loCer oCn on the menu, sin%e they passe on the $irst $ive %hoi%es alrea y. 5he menu is s%rollable, so the user %an get to any o$ the menu %hoi%es.
*enus of +ptions
Rather than buil ing your a%tivity7s options menu uring onCreate:;, the Cay you Cire up the rest o$ your "., you instea nee to implement onCreate,ptionsMenu:;. 5his %allba%k re%eives an instan%e o$ Menu. 5he $irst thing you shoul o is %hain upCar to the super%lass &super.onCreate,ptionsMenu:menu;', so the An roi $rameCork %an a in any menu %hoi%es it $eels are ne%essary. 5hen, you %an go about a ing your oCn options, es%ribe beloC. .$ you Cill nee to a Oust the menu uring your a%tivity7s use &e.g., isable a noC3invali menu %hoi%e', Oust hol onto the Menu instan%e you re%eive in onCreate,ptionsMenu:;. 8iven that you have re%eive a Menu obOe%t via onCreate,ptionsMenu:;, you a menu %hoi%es by %alling add:;. 5here are many $lavors o$ this metho , but all re<uire the $olloCing parameters*
A group i enti$ier &int', Chi%h shoul be @ unless you are %reating a spe%i$i% groupe set o$ menu %hoi%es $or use Cith set0roupC$eckable:; &see beloC'
97
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
)pplying *enus
A %hoi%e i enti$ier &also an int', $or use in i enti$ying this %hoi%e in the on,ptions.temSelected:; %allba%k Chen a menu %hoi%e is %hosen
@ou must also provi e an i%on &by its resour%e .A' or the te;t o$ the menu %hoi%e &as a Strin% or by its resour%e .A' N these provi e the Q$a%eQ o$ the menu %hoi%e. #ome $lavors o$ add:; also alloC you to supply a Runnable to be %alle Chen the menu %hoi%e is %hosen. .$ you provi e a Runnable, your %hoi%e i enti$ier &se%on parameter' %an be @. >therCise, you shoul make your %hoi%e i enti$iers be an in%rement over E.RS- &e.g., E.RS-B?', so you o not %olli e Cith any An roi system menu %hoi%es put on the same menu. 5he add:; $amily o$ metho s all return an instan%e o$ Menu..tem, Chere you %an a Oust any o$ the menu item settings you have alrea y set &e.g., the te;t o$ the menu %hoi%e'. @ou %an also set the short%uts $or the menu %hoi%e N single3%hara%ter mnemoni%s that %hoose that menu %hoi%e Chen the menu is visible. An roi supports both an alphabeti% &or Q<CertyQ' set o$ short%uts an a numeri% set o$ short%uts. 5hese are set in ivi ually by %alling setAlp$abeticS$ortcut:; an set/umericS$ortcut:; respe%tively. 5he menu is pla%e into alphabeti% short%ut mo e by %alling setTwertyMode:; on the menu Cith a true parameter. 5he %hoi%e an group i enti$iers are keys use to unlo%k a $eatures, su%h as*
itional menu
Calling set.temC$eckable:; Cith a %hoi%e i enti$ier, to %ontrol i$ the menu %hoi%e has a tCo3state %he%kbo; alongsi e the title, Chere the %he%kbo; value gets toggle Chen the user %hooses that menu %hoi%e Calling set0roupC$eckable:; Cith a group i enti$ier, to turn a set o$ menu %hoi%es into ones Cith a mutual3e;%lusion ra io button betCeen them, so one out o$ the group %an be in the Q%he%ke Q state at any time
99
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
)pplying *enus
to populate the menu Cith menu %hoi%es %orrespon ing to the available a%tivities $or an intent &see the %hapter on laun%hing a%tivities'
(inally, you %an %reate $ly3out sub3menus by %alling addSubMenu:;, supplying the same parameters as addMenu:; e;%ept the Runnable %allba%k. An roi Cill eventually %all onCreate1anelMenu:;, passing it the %hoi%e i enti$ier o$ your sub3menu, along Cith another Menu instan%e representing the sub3menu itsel$. As Cith onCreate,ptionsMenu:;, you shoul %hain upCar to the super%lass, then a menu %hoi%es to the sub3menu. >ne limitation is that you %annot in e$initely nest sub3menus N a menu %an have a sub3menu, but a sub3menu %annot itsel$ have a sub3sub3menu. >AT.* #eparators an sub3menus only Cork Chen the options menu is in Qe;pan e Q mo e, not Chen it is in Qi%onQ mo e. @ou shoul only use these $eatures i$ you have a really long menu, an then only starting Cith the si;th menu %hoi%e. .$ the user makes a menu %hoi%e, an that %hoi%e %ame Cith a Runnable instan%e atta%he , your Runnable Cill be invoke . >therCise, your a%tivity Cill be noti$ie via the on,ptions.temSelected:; %allba%k that a menu %hoi%e Cas sele%te . @ou are given the Menu..tem obOe%t %orrespon ing to the sele%te menu %hoi%e. A typi%al pattern is to switc$:; on the menu .A &item.%et.d:;' an take appropriate behavior. 0ote that on,ptions.temSelected:; is use regar less o$ Chether the %hosen menu item Cas in the base menu or in a submenu.
*enus in Context
/y an large, %onte;t menus use the same guts as option menus N the %lass e;ten s the regular Menu %lass, o$$ering only the means to set a Qhea erQ or %aption $or the popup menu via set3eader:;. 5he tCo main i$$eren%es are hoC you populate the menu an hoC you are in$orme o$ menu %hoi%es.
ContextMenu
(;;
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
)pplying *enus
#in%e %onte;t menus are per3Ci get, rather than per3a%tivity, there is no %allba%k in the Activity to populate the %onte;t menu the Cay there is onCreate,ptionsMenu:; to populate the options menu. .nstea , ea%h Ci get itsel$ is tol Chen to populate the %onte;t menu. 5o save you the total hea a%he o$ sub%lassing a bun%h o$ Ci gets Oust to set up your %onte;t menus, though, An roi o$$ers a set,n1opulateContextMenu+istener:; metho on all Ci gets. 5his takes an instan%e o$ the ,n1opulateContextMenu+istener %allba%k inter$a%e. @our implementation o$ that inter$a%e N spe%i$i%ally, your implementation o$ on1opulateContextMenu:; N is Chere you set up the %ontents o$ the %onte;t menu. 5he on1opulateContextMenu:; metho gets the ContextMenu itsel$, the 7iew the %onte;t menu is asso%iate Cith, an an opa<ue ,bject representing Qe;tra in$ormationQ about the menu being built. .$ the %onte;t menu is $or a sele%tion Ci get that inherits $rom Adapter7iew, this obOe%t is suppose to be an instan%e o$ ContextMenu.nfo, Chi%h tells you Chi%h item in the list the user i the tap3an 3hol over, in %ase you Cant to %ustomiKe the %onte;t menu base on that in$ormation. (or e;ample, you %oul toggle a %he%kable menu %hoi%e base upon the %urrent state o$ the item. 0ote that you only get this Qe;tra in$ormationQ Chen the menu is built, not Chen a %hoi%e is ma e. .t is also important to note that on1opulateContextMenu:; gets %alle $or ea%h time the %onte;t menu is re<ueste . "nlike the options menu &Chi%h is only built on%e per a%tivity', %onte;t menus are is%ar e on%e they are use or ismisse . )en%e, you o not Cant to hol onto the supplie ContextMenu obOe%tP Oust rely on getting the %han%e to rebuil the menu to suit your a%tivity7s nee s on an on3 eman basis base on user a%tions. 5o $in out Chen a %onte;t menu %hoi%e Cas %hosen, implement on the a%tivity. 0ote that you only get the Menu..tem instan%e that Cas %hosen in this %allba%k. As a result, i$ your a%tivity has tCo or more %onte;t menus, you may Cant to ensure they have uni<ue menu item i enti$iers $or all their %hoi%es, so you %an tell them apart in this %allba%k. >therCise, this %allba%k behaves the same as on,ptions.temSelected:; as is es%ribe above.
onContext.temSelected:;
(;(
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
)pplying *enus
Taking a Peek
.n the sample proOe%t Menus, you Cill $in an amen e version o$ the +ist7iew sample &+ist' Cith an asso%iate menu. #in%e the menus are e$ine in +ava %o e, the EML layout nee not %hange an is not reprinte here. )oCever, the +ava %o e has a $eC neC behaviors*
public class MenuDemo extends +istActivity 8 -ext7iew selection5 Strin%OP items"8#lorem#G #ipsum#G #dolor#G #sit#G #amet#G #consectetuer#G #adipiscin%#G #elit#G #morbi#G #vel#G #li%ula#G #vitae#G #arcu#G #aliJuet#G #mollis#G #etiam#G #vel#G #erat#G #placerat#G #ante#G #porttitor#G #sodales#G #pellentesJue#G #au%ue#G #purus#<5 public static final int ).03-*.D " Menu.E.RS-B?5 public static final int S.U-))/*.D " Menu.E.RS-BH5 public static final int -C)/-F*E,2R*.D " Menu.E.RS-BI5 public static final int -C,*.D " Menu.E.RS-BN5 9,verride public void onCreate:6undle icicle; 8 super.onCreate:icicle;5 setContentView:R.layout.main;5 setList#dapter:new ArrayAdapter<Strin%&:t$isG android.R.layout.simple*list*item*?G items;;5 selection":-ext7iew;findViewById:R.id.selection;5 getListView:; .setOn&opulateContext'enuListener:new 7iew.On&opulateContext'enuListener:; 8 public void on&opulateContext'enu:ContextMenu menuG 7iew vG ,bject menu.nfo; 8 populate'enu:menu;5 menu.set(eader:#Divider 3ei%$t#;5 < <;5 < public void onListItemClick:+ist7iew parentG 7iew vG int positionG lon% id; 8 selection.setText:itemsOpositionP;5 < 9,verride public boolean onCreateOptions'enu:Menu menu; 8 populate'enu:menu;5
(;%
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
)pplying *enus
return:super.onCreateOptions'enu:menu;;5 < 9,verride public boolean onOptionsItemSelected:Menu..tem item; 8 apply'enuChoice:item;5 return:apply'enuChoice:item; VV super.onOptionsItemSelected:item;;5 < 9,verride public boolean onContextItemSelected:Menu..tem item; 8 return:apply'enuChoice:item; VV super.onContextItemSelected:item;;5
<
private void populate'enu:Menu menu; 8 menu.add:@G -C,*.DG #H 1ixels#;5 menu.add:@G ).03-*.DG #A 1ixels#;5 menu.add:@G S.U-))/*.DG #?S 1ixels#;5 menu.add:@G -C)/-F*E,2R*.DG #HN 1ixels#;5 < private boolean apply'enuChoice:Menu..tem item; 8 switc$ :item.getId:;; 8 case ).03-*.D! getListView:;.setDi ider(eight:A;5 return:true;5 case S.U-))/*.D! getListView:;.setDi ider(eight:?S;5 return:true;5 case -C)/-F*E,2R*.D! getListView:;.setDi ider(eight:HN;5 return:true;5 case -C,*.D! getListView:;.setDi ider(eight:H;5 return:true;5
< <
return:false;5 <
.n onCreate:;, Ce register a ,n1opulateContextMenu+istener obOe%t Cith the list Ci get, so it Cill get a %onte;t menu, Chi%h Ce $ill in via our populateMenu:; private metho . We also set the hea er o$ the menu &menu.set3eader:#Divider 3ei%$t#;'.
(;,
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
)pplying *enus
We also implement the onCreate,ptionsMenu:; %allba%k, in i%ating that our a%tivity also has an options menu. >n%e again, Ce elegate to populateMenu:; to $ill in the menu. >ur implementations o$ on,ptions.temSelected:; &$or options menu sele%tions' an onContext.temSelected:; &$or %onte;t menu sele%tions' both elegate to a private applyMenuC$oice:; metho , plus %haining upCar s to the super%lass i$ none o$ our menu %hoi%es Cas the one sele%te by the user. .n populateMenu:;, Ce a $our menu %hoi%es, ea%h Cith a uni<ue i enti$ier. /eing laKy, Ce es%heC the i%ons. .n applyMenuC$oice:;, Ce see i$ any o$ our menu %hoi%es Cere %hosenP i$ so, Ce set the list7s ba%kgroun %olor to be the user3sele%te hue. .nitially, the a%tivity looks the same in the emulator as it i $or +istDemo*
/ut, i$ you press the Menu button, you Cill get our options menu*
(;$
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
)pplying *enus
Choosing a height &say, -4 pi;els' then %hanges the ivi er height o$ the list to something garish*
(;/
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
)pplying *enus
@ou %an trigger the %onte;t menu by oing a tap3an 3hol on any item in the list*
(;0
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
CHAPTER 11
>ther 8". toolkits let you use )5ML $or presenting in$ormation, $rom limite )5ML ren erers &e.g., +avaU#Cing, C;Wi gets' to embe ing .nternet I;plorer into .0I5 appli%ations. An roi is mu%h the same, in that you %an embe the built3in Web broCser as a Ci get in your oCn a%tivities, $or isplaying )5ML or $ull3$le ge broCsing. 5he An roi broCser is base on WebFit, the same engine that poCers Apple7s #a$ari Web broCser. 5he An roi broCser is su$$i%iently %omple; that it gets its oCn +ava pa%kage &android.webkit', though using the Ceb7iew Ci get itsel$ %an be simple or poCer$ul, base upon your re<uirements.
(;3
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
/& </+inear+ayout&
android!layout*widt$"#fill*parent# android!layout*$ei%$t"#fill*parent#
As Cith any other Ci get, you nee to tell it hoC it shoul $ill up the spa%e in the layout &in this %ase, it $ills all remaining spa%e'. 5he +ava %o e is e<ually simple*
packa%e com.commonsware.android.webkit5 import android.app.Activity5 import android.os.6undle5 import android.webkit.Ceb7iew5 public class 6rowserDemo? extends Activity 8 Ceb7iew browser5 9,verride public void onCreate:6undle icicle; 8 super.onCreate:icicle;5 setContentView:R.layout.main;5 browser":Ceb7iew;findViewById:R.id.webkit;5 browser.load)rl:#$ttp!//commonsware.com#;5 < <
5he only bit unusual Cith this e ition o$ onCreate:; is that Ce invoke load2rl:; on the Ceb7iew Ci get, to tell it to loa a Web page &in this %ase, the home page o$ some ran om $irm'. 5he resulting a%tivity looks like a Web broCser, Oust Cith hi en s%rollbars*
(;7
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
As Cith the regular An roi broCser, you %an pan aroun the page by ragging it, Chile the ire%tional pa moves you aroun all the $o%usable elements on the page. What is missing is all the e;tra a%%outerments that make up a Web broCser, su%h as a navigational toolbar.
oading 8t >p
5here are tCo main Cays to get %ontent into the Ceb7iew. >ne, shoCn above, is to provi e the broCser Cith a "RL an have the broCser isplay that page via load2rl:;. 5he broCser Cill a%%ess the .nternet through Chatever means are available to that spe%i$i% evi%e at the present time &Wi(i, %ellular netCork, /luetooth3tethere phone, Cell3traine tiny %arrier pigeons, et%.'. 5he alternative is to use loadData:;. )ere, you supply the )5ML $or the broCser to vieC. @ou might use this to*
(;9
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
isplay a manual that Cas installe as a $ile Cith your appli%ation pa%kage isplay snippets o$ )5ML you retrieve as part o$ other pro%essing, su%h as the es%ription o$ an entry in an Atom $ee generate a Chole user inter$a%e using )5ML, instea o$ using the An roi Ci get set
5here are tCo $lavors o$ loadData:;. 5he simpler one alloCs you to provi e the %ontent, the M.MI type, an the en%o ing, all as strings. 5ypi%ally, your M.MI type Cill be text/$tml an your en%o ing Cill be 2-E(A $or or inary )5ML. (or e;ample, i$ you repla%e the load2rl:; invo%ation in the previous e;ample Cith the $olloCing*
browser.loadData:#<$tml&<body&3elloG worldW</body&</$tml&#G #text/$tml#G #2-E(A#;5
@ou get*
((;
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
to go ba%k one step in the broCser history, an can0o6ack:; to etermine i$ there is any history to go ba%k to
%oEorward:; to go can0oEorward:; to %o6ack,rEorward:;
$orCar one step in the broCser history, an etermine i$ there is any history to go $orCar to
to go ba%kCar s or $orCar s in the broCser history, Chere negative numbers represent a %ount o$ steps to go ba%kCar s, an positive numbers represent hoC many steps to go $orCar s to see i$ the broCser %an go ba%kCar s or $orCar s the state number o$ steps &$olloCing the same positiveUnegative %onvention as %o6ack,rEorward:;'
can0o6ack,rEorward:; clearCac$e:;
to %lear the broCser resour%e %a%he an clear3istory:; to %lear the broCsing history
@our hook into Ceb7iew a%tivity is via setCeb7iewClient:;, Chi%h takes an instan%e o$ a Ceb7iewClient implementation as a parameter. 5he supplie %allba%k obOe%t Cill be noti$ie o$ a Ci e range o$ a%tivities, ranging $rom Chen parts o$ a page have been retrieve &on1a%eStarted:;, et%.' to Chen you, as the host appli%ation, nee to han le %ertain user3 or %ir%umstan%e3 initiate events, su%h as*
on-ooManyRedirects:; onReceived3ttpAut$ReJuest:;
et%.
A %ommon hook Cill be s$ould,verride2rl+oadin%:;, Chere your %allba%k is passe a "RL &plus the Ceb7iew itsel$' an you return true i$ you Cill han le the re<uest or false i$ you Cant e$ault han ling &e.g., a%tually $et%h the Web page re$eren%e by the "RL'. .n the %ase o$ a $ee rea er appli%ation, $or e;ample, you Cill probably not have a $ull broCser Cith navigation built into your rea er, so i$ the user %li%ks a "RL, you probably Cant to use an .ntent to ask An roi to loa that page in a $ull broCser. /ut, i$ you have inserte a Q$akeQ "RL into the )5ML, representing a link to some a%tivity3 provi e %ontent, you %an up ate the Ceb7iew yoursel$. (or e;ample, let7s amen the $irst broCser e;ample to be a broCser3base e<uivalent o$ our original e;ample* an appli%ation that, upon a %li%k, shoCs the %urrent time. (rom 6rowserI, here is the revise +ava*
packa%e com.commonsware.android.webkit5 import import import import import android.app.Activity5 android.os.6undle5 android.webkit.Ceb7iew5 android.webkit.Ceb7iewClient5 java.util.Date5
public class 6rowserDemoI extends Activity 8 Ceb7iew browser5 9,verride public void onCreate:6undle icicle; 8 super.onCreate:icicle;5 setContentView:R.layout.main;5 ((%
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
<
void loadTime:; 8 Strin% pa%e"#<$tml&<body&<a $ref"4#/clock4#&# Bnew Date:;.toString:; B#</a&</body&</$tml < browser.loadData:pa%eG #text/$tml#G #2-E(A#;5
private class Callback extends Ceb7iewClient 8 public boolean shouldO erride)rlLoading:Ceb7iew viewG Strin% url; 8 loadTime:;5 return:true;5 < < <
)ere, Ce loa a simple Web page into the broCser & load-ime:;' that %onsists o$ the %urrent time, ma e into a hyperlink to the /clock "RL. We also atta%h an instan%e o$ a Ceb7iewClient sub%lass, provi ing our implementation o$ s$ould,verride2rl+oadin%:;. .n this %ase, no matter Chat the "RL, Ce Cant to Oust reloa the Ceb7iew via load-ime:;. Running this a%tivity gives us*
((,
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
#ele%ting the link an %li%king the A3pa %enter button Cill Q%li%kQ the link, %ausing us to rebuil the page Cith the neC time.
(($
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
Control the $ont siKing via setDefaultEontSi'e:; &to use a point siKe' or set-extSi'e:; &to use %onstants in i%ating relative siKes like +AR0)R an SMA++)S-' Control +avas%ript via set=avaScript)nabled:; &to isable it outright' an set=avaScriptCan,penCindowsAutomatically:; &to merely stop it $rom opening pop3up Cin oCs' Control Web site ren ering via set2seDesktop2serA%ent:; N false means the Ceb7iew gives the Web site a user3agent string that in i%ates it is a mobile broCser, Chile true results in a user3agent string that suggests it is a esktop broCser
5he settings you %hange are not persistent, so you shoul store them someChere &su%h as via the An roi pre$eren%es engine' i$ you are alloCing your users to etermine the settings, versus har 3Ciring the settings in your appli%ation.
((/
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
CHAPTER 1&
#ometimes, your a%tivity &or other pie%e o$ An roi %o e' Cill nee to speak up. 0ot every intera%tion Cith An roi users Cill be neat, ti y, an %ontainable in a%tivities %ompose o$ vieCs. Irrors Cill %rop up. /a%kgroun tasks may take Cay longer than e;pe%te . #omething asyn%hronous may o%%ur, su%h as an in%oming message. .n these an other %ases, you may nee to %ommuni%ate Cith the user outsi e the boun s o$ the tra itional user inter$a%e. >$ %ourse, this is nothing neC. Irror messages in the $orm o$ ialog bo;es have been aroun $or a very long time. More subtle in i%ators also e;ist, $rom task tray i%ons to boun%ing o%k i%ons to a vibrating %ell phone. An roi has <uite a $eC systems $or letting you alert your users outsi e the boun s o$ an Activity3base ".. >ne, noti$i%ations, is tie heavily into intents an servi%es an , as su%h, is %overe in a later %hapter. .n this %hapter, you Cill see tCo means o$ raising pop3up messages* toasts an alerts.
2aising Toasts
A -oast is a transient message, meaning that it isplays an isappears on its oCn Cithout user intera%tion. Moreover, it oes not take $o%us aCay $rom
((3
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
the %urrently3a%tive Activity, so i$ the user is busy Criting the ne;t 8reat Ameri%an !rogramming 8ui e, they Cill not have keystrokes be QeatenQ by the message. #in%e a -oast is transient, you have no Cay o$ knoCing i$ the user even noti%es it. @ou get no a%knoCle gment $rom them, nor oes the message sti%k aroun $or a long time to pester the user. )en%e, the -oast is mostly $or a visory messages, su%h as in i%ating a long3running ba%kgroun task is %omplete , the battery has roppe to a loC3but3not3too3loC level, et%. Making a -oast is $airly easy. 5he -oast %lass o$$ers a stati% make-ext:; that a%%epts a Strin% &or string resour%e .A' an returns a -oast instan%e. 5he make-ext:; metho also nee s the Activity &or other Context' plus a uration. 5he uration is e;presse in the $orm o$ the +)/0-3*S3,R- or +)/0-3*+,/0 %onstants to in i%ate, on a relative basis, hoC long the message shoul remain visible. .$ you Coul pre$er your -oast be ma e out o$ some other 7iew, rather that be a boring ol pie%e o$ te;t, simply %reate a neC -oast instan%e via the %onstru%tor &Chi%h takes a Context', then %all set7iew:; to supply it Cith the vieC to use an setDuration:; to set the uration. >n%e your -oast is %on$igure , %all its s$ow:; metho , an the message Cill be isplaye .
)lert! )lert!
.$ you Coul pre$er something in the more %lassi% ialog bo; style, Chat you Cant is an AlertDialo%. As Cith any other mo al ialog bo;, an AlertDialo% pops up, grabs the $o%us, an stays there until %lose by the user. @ou might use this $or a %riti%al error, a vali ation message that %annot be e$$e%tively isplaye in the base a%tivity "., or something else Chere you are sure that the user nee s to see the message an nee s to see it noC. 5he simplest Cay to %onstru%t an AlertDialo% is to use the 6uilder %lass. (olloCing in true buil er style, 6uilder o$$ers a series o$ metho s to
((7
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
%on$igure an AlertDialo%, ea%h metho returning the 6uilder $or easy %haining. At the en , you %all s$ow:; on the buil er to isplay the ialog bo;. Commonly3use %on$iguration metho s on 6uilder in%lu e*
i$ you Cant the Qbo yQ o$ the ialog to be a simple te;tual message, $rom either a supplie Strin% or a supplie string resour%e .A
setMessa%e:; set-itle:; an
to %on$igure the te;t an Uor i%on to appear in the title bar o$ the ialog bo;
set1ositive6utton:;, set/eutral6utton:;, an set/e%ative6utton:;, to
set.con:;,
in i%ate Chi%h button&s' shoul appear a%ross the bottom o$ the ialog, Chere they shoul be positione &le$t, %enter, or right, respe%tively', Chat their %aptions shoul be, an Chat logi% shoul be invoke Chen the button is %li%ke &besi es ismissing the ialog'.
.$ you nee to %on$igure the AlertDialo% beyon Chat the buil er alloCs, instea o$ %alling s$ow:;, %all create:; to get the partially3built AlertDialo% instan%e, %on$igure it the rest o$ the Cay, then %all one o$ the $lavors o$ s$ow:; on the AlertDialo% itsel$. >n%e s$ow:; is %alle , the ialog bo; Cill appear an aCait user input.
((9
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
...an +ava %o e*
public class Messa%eDemo extends Activity implements 7iew.,nClick+istener 8 6utton alert5 6utton toast5 9,verride public void onCreate:6undle icicle; 8 super.onCreate:icicle;5 setContentView:R.layout.main;5 alert":6utton;findViewById:R.id.alert;5 alert.setOnClickListener:t$is;5 toast":6utton;findViewById:R.id.toast;5 toast.setOnClickListener:t$is;5 < public void onClick:7iew view; 8 if :view""alert; 8 new AlertDialo%.Builder:t$is; .setTitle:#Messa%eDemo#; .set'essage:#eekW#; .set%eutralButton:#Close#G new Dialo%.nterface.OnClickListener:; 8 public void onClick:Dialo%.nterface dl%G int sumt$in; 8 // do not$in% X it will close on its own < <; .show:;5 < else 8 -oast .makeText:t$isG #<clinkG clink&#G -oast.+)/0-3*S3,R-; .show:;5 < < <
5he layout is unremarkable N Oust a pair o$ buttons to trigger the alert an the toast. When you %li%k the alert button, Ce use a buil er &new 6uilder:t$is;' to set the title &set-itle:#Messa%eDemo#;', message &setMessa%e:#eekW#;', an
(%;
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
Qneutral buttonQ &set/eutral6utton:#Close#G new ,nClick+istener:; ...' be$ore shoCing the ialog. When the button is %li%ke , the ,nClick+istener %allba%k oes nothing N the mere $a%t the button Cas presse %auses the ialog to be ismisse . )oCever, you %oul up ate in$ormation in your a%tivity base upon the user a%tion, parti%ularly i$ you have multiple buttons $or the user to %hoose $rom. 5he result is a typi%al ialog bo;*
!igure ,7< The *essage.emo sample application6 after clicking the =2aise an alert= button
When you %li%k the toast button, the -oast %lass makes us a te;t3base toast &make-ext:t$isG #<clinkG clink&#G +)/0-3*S3,R-;', Chi%h Ce then s$ow:;. 5he result is a short3live , non3interrupting message*
(%(
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
!igure ,9< The same application6 after clicking the =*ake a toast= button
(%%
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
CHAPTER 1'
. eally, you Cant your a%tivities to be oCnright snappy, so your users on7t $eel that your appli%ation is sluggish. Respon ing to user input <ui%kly &e.g., 200ms' is a $ine goal. At minimum, though, you nee to make sure you respon Cithin B se%on s, lest the ActivityMana%er e%i e to play the role o$ the 8rim Reaper an kill o$$ your a%tivity as being non3responsive. >$ %ourse, your a%tivity might have real Cork to o, Chi%h takes non3 negligible amounts o$ time. 5here are tCo Cays o$ ealing Cith this* -. Ao e;pensive operations in a ba%kgroun servi%e, relying on noti$i%ations to prompt users to go ba%k to your a%tivity
2. Ao e;pensive Cork in a ba%kgroun threa An roi provi es a veritable %ornu%opia o$ means to set up ba%kgroun threa s yet alloC them to sa$ely intera%t Cith the ". on the ". threa . 5hese in%lu e 3andler obOe%ts, posting Runnable obOe%ts to the 7iew, an using 2.-$read2tilities.
(%,
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
merely %reating the instan%e is su$$i%ient to register it Cith the An roi threa ing subsystem. @our ba%kgroun threa %an %ommuni%ate Cith the 3andler, Chi%h Cill o all o$ its Cork on the a%tivity ". threa . 5his is important, as ". %hanges, su%h as up ating Ci gets, shoul only o%%ur on the a%tivity ". threa . @ou have tCo options $or %ommuni%ating Cith the 3andler* messages an Runnable obOe%ts.
%ess !es
5o sen a Messa%e to a 3andler, $irst invoke obtainMessa%e:; to get the Messa%e obOe%t out o$ the pool. 5here are a $eC $lavors o$ obtainMessa%e:;, alloCing you to Oust %reate empty Messa%e obOe%ts, or ones populate Cith message i enti$iers an arguments. 5he more %ompli%ate your 3andler pro%essing nee s to be, the more likely it is you Cill nee to put ata into the Messa%e to help the 3andler istinguish i$$erent events. 5hen, you sen the Messa%e to the 3andler via its message <ueue, using one o$ the sendMessa%e...:; $amily o$ metho s*
sendMessa%e:; puts the message on the <ueue imme sendMessa%eAtEront,fTueue:;
iately
puts the message on the <ueue imme iately, an moreover puts it at the $ront o$ the message <ueue &versus the ba%k, as is the e$ault', so your message takes priority over all others puts the message on the <ueue at the state time, e;presse in the $orm o$ millise%on s base on system uptime &SystemClock.uptimeMillis:;'
sendMessa%eAt-ime:;
5o
these messages, your 3andler nee s to implement $andleMessa%e:;, Chi%h Cill be %alle Cith ea%h message that appears on the
pro%ess
(%$
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
message <ueue. 5here, the han ler %an up ate the ". as nee e . )oCever, it shoul still o that Cork <ui%kly, as other ". Cork is suspen e until the 3andler is one. (or e;ample, let7s %reate a 1ro%ress6ar an up ate it via a 3andler. )ere is the layout $rom 3andler*
<>xml version"#?.@# encodin%"#utf(A#>& <+inear+ayout xmlns!android"#$ttp!//sc$emas.android.com/apk/res/android# android!orientation"#vertical# android!layout*widt$"#fill*parent# android!layout*$ei%$t"#fill*parent# & <1ro%ress6ar android!id"#9Bid/pro%ress# style"#>android!attr/pro%ress6arStyle3ori'ontal# android!layout*widt$"#fill*parent# android!layout*$ei%$t"#wrap*content# android!max"#?@@# /& </+inear+ayout&
5he 1ro%ress6ar, in a ition to setting the Ci th an height as normal, also employs tCo other properties o$ note*
Chi%h Cill be %overe in greater etail in some $uture e ition o$ this book. (or noC, su$$i%e it to say that it in i%ates this 1ro%ress6ar shoul be raCn as the tra itional horiKontal bar shoCing the amount o$ Cork that has been %omplete .
android!max,
style,
Chi%h in i%ates the ma;imum value $or the 1ro%ress6ar &i.e., at Chat value is the Cork Q oneQ an the progress bar %omplete '. A value o$ ?@@ means the 1ro%ress6ar Corks on a simple per%entage system.
(%/
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
3andler $andler"new (andler:; 8 9,verride public void handle'essage:Messa%e ms%; 8 bar.increment&rogressBy:L;5 < <5 boolean isRunnin%"false5 9,verride public void onCreate:6undle icicle; 8 super.onCreate:icicle;5 setContentView:R.layout.main;5 bar":1ro%ress6ar;findViewById:R.id.pro%ress;5 < public void onStart:; 8 super.onStart:;5 bar.set&rogress:@;5 -$read back%round"new Thread:new $unna!le:; 8 public void run:; 8 try 8 for :int i"@5i<H@ YY isRunnin%5iBB; 8 -$read.sleep:?@@@;5 $andler.send'essage:$andler.o!tain'essage:;;5 < < catc$ :-$rowable t; 8 // just end t$e back%round t$read < < <;5 isRunnin%"true5 back%round.start:;5 < public void onStop:; 8 super.onStop:;5 isRunnin%"false5 < <
As part o$ %onstru%ting the Activity, Ce %reate an instan%e o$ 3andler, Cith our implementation o$ $andleMessa%e:;. /asi%ally, $or any message re%eive , Ce up ate the 1ro%ress6ar by L points, then e;it the message han ler. .n onStart:;, Ce set up a ba%kgroun threa . .n a real system, this threa Coul o something meaning$ul. )ere, Ce Oust sleep one se%on , post a Messa%e to the 3andler, an repeat $or a total o$ H@ passes.
(%0
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
0ote that Ce then leave onStart:;. 5his is %ru%ial. 5he onStart:; metho is invoke on the a%tivity ". threa , so it %an up ate Ci gets an su%h. )oCever, that means Ce nee to get out o$ onStart:;, both to let the 3andler get its Cork one, an also so An roi oes not think our a%tivity is stu%k. 5he resulting a%tivity is simply a horiKontal progress bar*
Runn 5les
.$ you Coul rather not $uss Cith Messa%e obOe%ts, you %an also pass Runnable obOe%ts to the 3andler, Chi%h Cill run those Runnable obOe%ts on the a%tivity ". threa . 3andler o$$ers a set o$ post...:; metho s $or passing Runnable obOe%ts in $or eventual pro%essing.
2unning 8n Place
+ust as 3andler supports post:; an postDelayed:; to a Runnable obOe%ts to the event <ueue, you %an use those same metho s on 7iew. 5his lightly
(%3
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
simpli$ies your %o e, in that you %an then skip the 3andler obOe%t. )oCever, you lose a bit o$ $le;ibility, an the 3andler has been aroun longer in the An roi toolkit an may be more teste .
5he possibility that users Cill intera%t Cith your a%tivity7s ". Chile the ba%kgroun threa is %hugging along. .$ the Cork that the
(%7
ba%kgroun threa is oing is altere or invali ate by the user input, you Cill nee to %ommuni%ate this to the ba%kgroun threa . An roi in%lu es many %lasses in the java.util.concurrent pa%kage that Cill help you %ommuni%ate sa$ely Cith your ba%kgroun threa .
5he possibility that the a%tivity Cill be kille o$$ Chile ba%kgroun Cork is going on. (or e;ample, a$ter starting your a%tivity, the user might have a %all %ome in, $olloCe by a te;t message, $olloCe by a nee to look up a %onta%t...all o$ Chi%h might be su$$i%ient to ki%k your a%tivity out o$ memory. 5he ne;t %hapter Cill %over the various events An roi Cill take your a%tivity throughP hook the proper ones an be sure to shut oCn your ba%kgroun threa %leanly Chen you have the %han%e. 5he possibility that your user Cill get irritate i$ you %heC up a lot o$ C!" time an battery li$e Cithout giving any payba%k. 5a%ti%ally, this means using 1ro%ress6ar or other means o$ letting the user knoC that something is happening. #trategi%ally, this means you still nee to be e$$i%ient at Chat you o N ba%kgroun threa s are no pana%ea $or sluggish or pointless %o e. 5he possibility that you Cill en%ounter an error uring ba%kgroun pro%essing. (or e;ample, i$ you are gathering in$ormation o$$ the .nternet, the evi%e might lose %onne%tivity. Alerting the user o$ the problem via a 0oti$i%ation an shutting oCn the ba%kgroun threa may be your best option.
(%9
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
CHAPTER 1(
While this may soun like a broken re%or ...please remember that An roi evi%es, by an large, are phones. As su%h, some a%tivities are more important that others N taking a %all is probably more important to users than is playing #u oku. An , sin%e it is a phone, it probably has less RAM than oes your %urrent esktop or notebook. As a result, your a%tivity may $in itsel$ being kille o$$ be%ause other a%tivities are going on an the system nee s your a%tivity7s memory. 5hink o$ it as the An roi e<uivalent o$ the Q%ir%le o$ li$eQ N your a%tivity ies so others may live, an so on. @ou %annot assume that your a%tivity Cill run until you think it is %omplete, or even until the user thinks it is %omplete. 5his is one e;ample N perhaps the most important e;ample N o$ hoC an a%tivity7s li$e%y%le Cill a$$e%t your oCn appli%ation logi%. 5his %hapter %overs the various states an %allba%ks that make up an a%tivity7s li$e%y%le an hoC you %an hook into them appropriately.
SchroedingerAs )ctivity
An a%tivity, generally speaking, is in one o$ $our states at any point in time*
(,(
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
Active* the a%tivity Cas starte by the user, is running, an is in the $oregroun . 5his is Chat you7re use to thinking o$ in terms o$ your a%tivity7s operation. Paused* the a%tivity Cas starte by the user, is running, an is visible, but a noti$i%ation or something is overlaying part o$ the s%reen. Auring this time, the user %an see your a%tivity but may not be able to intera%t Cith it. (or e;ample, i$ a %all %omes in, the user Cill get the opportunity to take the %all or ignore it. #topped* the a%tivity Cas starte by the user, is running, but it is hi en by other a%tivities that have been laun%he or sCit%he to. @our appli%ation Cill not be able to present anything meaning$ul to the user ire%tly, only by Cay o$ a 0oti$i%ation. Dead* either the a%tivity Cas never starte &e.g., Oust a$ter a phone reset' or the a%tivity Cas terminate , perhaps ue to la%k o$ available memory.
2. .$ the a%tivity ha been running, ha onEree'e:; invoke , then sometime later Cas kille o$$, onCreate:; Cill be invoke Cith the 6undle $rom onEree'e:; as a parameter. Aealing Cith $reeKing an restoring state is %overe later in this %hapter. )ere is Chere you initialiKe your user inter$a%e an set up anything that nee s to be one on%e, regar less o$ hoC the a%tivity gets use . .$ the a%tivity is being restore $rom a $roKen state &se%on s%enario above', then onComplete-$aw:; is also %alle , an is passe the same 6undle as Cas the pre%e ing onCreate:;. .$ you Cant, you %an isolate your un3$reeKing logi% here.
Cill be %alle more %ommonly than the others, an shoul be %alle i$ the a%tivity Cas pause &on1ause:;' an then brought ba%k to the $oregroun relatively <ui%kly. .n $a%t, onResume:; shoul be %alle Oust be$ore the a%tivity is brought to the $oregroun in all %ir%umstan%es.
onResume:;
may be %alle i$ the a%tivity Cas stoppe &onStop:;' then starte up again Cithout the pro%ess being terminate
onStart:;
8enerally speaking, in these metho s you Cill Cish to o things that only make sense Chen a user is looking at your a%tivity, parti%ularly things that might have %hange sin%e the last time your a%tivity Cas looke at. (or e;ample, i$ you are polling a servi%e $or %hanges to some in$ormation &e.g., neC entries $or a $ee ', onResume:; is a $ine time to both re$resh the %urrent vieC an , i$ appli%able, ki%k o$$ a ba%kgroun threa to up ate the vieC &e.g., via a 3andler'.
(,,
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
(,$
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
CHAPTER 1)
>sing Preferences
An roi has many i$$erent Cays $or you to store ata $or long3term use by your a%tivity. 5he simplest to use is the pre$eren%es system. An roi alloCs a%tivities an appli%ations to keep pre$eren%es, in the $orm o$ keyUvalue pairs &akin to a Map', that Cill hang aroun betCeen invo%ations o$ an a%tivity. As the name suggests, the primary purpose is $or you to store user3spe%i$ie %on$iguration etails, su%h as the last $ee the user looke at in your $ee rea er, or Chat sort or er to use by e$ault on a list, or Chatever. >$ %ourse, you %an store in the pre$eren%es Chatever you like, so long as it is keye by a Strin% an has a primitive value &boolean, Strin%, et%.' !re$eren%es %an either be $or a single a%tivity or share among all a%tivities in an appli%ation. Iventually, pre$eren%es might be shareable a%ross appli%ations, but that is not supporte as o$ the time o$ this Criting.
2. %etS$ared1references:; $rom Cithin your Activity &or other appli%ation Context', to a%%ess appli%ation3level pre$eren%es
(,3
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
>sing Preferences
/oth take a se%urity mo e parameter N $or noC, pass in @. 5he %etS$ared1references:; metho also takes a name o$ a set o$ pre$eren%es N %et1references:; e$$e%tively %alls %etS$ared1references:; Cith the a%tivity7s %lass name as the pre$eren%e set name. /oth o$ those metho s return an instan%e o$ S$ared1references, Chi%h o$$ers a series o$ getters to a%%ess name pre$eren%es, returning a suitably3type result &e.g., %et6oolean:; to return a boolean pre$eren%e'. 5he getters also take a e$ault value, Chi%h is returne i$ there is no pre$eren%e set un er the spe%i$ie key.
5he last one is important N i$ you mo i$y pre$eren%es via the e itor an $ail to commit:; the %hanges, those %hanges Cill evaporate on%e the e itor goes out o$ s%ope. Conversely, sin%e the pre$eren%es obOe%t supports live %hanges, i$ one part o$ your appli%ation &say, an a%tivity' mo i$ies share pre$eren%es, another part o$ your appli%ation &say, a servi%e' Cill have a%%ess to the %hange value imme iately.
>sing Preferences
5he $irst %riterion is easy* Oust use a %he%kbo;. .n $a%t, this e;ample &1refs' is base o$$ o$ our earlier %he%kbo; emo*
<>xml version"#?.@# encodin%"#utf(A#>& <+inear+ayout xmlns!android"#$ttp!//sc$emas.android.com/apk/res/android# android!layout*widt$"#fill*parent# android!layout*$ei%$t"#fill*parent#& <C$eck6ox android!id"#9Bid/c$eck# android!layout*widt$"#wrap*content# android!layout*$ei%$t"#wrap*content# android!text"#-$is c$eckbox is! unc$ecked# /& <6utton android!id"#9Bid/close# android!layout*widt$"#wrap*content# android!layout*$ei%$t"#wrap*content# android!text"#Close# /& </+inear+ayout&
)ere, Ce have a roC o$ tCo Ci gets* our %he%kbo;, an a button labele QCloseQ. 5he +ava is a bit more involve *
packa%e com.commonsware.android.prefs5 import import import import import import import android.app.Activity5 android.content.S$ared1references5 android.os.6undle5 android.view.7iew5 android.wid%et.6utton5 android.wid%et.C$eck6ox5 android.wid%et.Compound6utton5
public class 1refsDemo extends Activity implements Compound6utton.,nC$eckedC$an%e+istener 8 C$eck6ox cb5 9,verride public void onCreate:6undle icicle; 8 super.onCreate:icicle;5 setContentView:R.layout.main;5 cb":C$eck6ox;findViewById:R.id.c$eck;5 cb.setOnCheckedChangeListener:t$is;5 6utton btn":6utton;findViewById:R.id.close;5 btn.setOnClickListener:new 6utton.OnClickListener:; 8 public void onClick:7iew v; 8 finish:;5 <
(,9
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
>sing Preferences
<;5 < public void onCheckedChanged:Compound6utton button7iewG boolean isC$ecked; 8 if :isC$ecked; 8 cb.setText:#-$is c$eckbox is! c$ecked#;5 < else 8 cb.setText:#-$is c$eckbox is! unc$ecked#;5 < < public void on$esume:; 8 super.on$esume:;5 S$ared1references settin%s"get&references:@;5 < cb.setChecked:settin%s.getBoolean:#cb*c$ecked#G false;;5
public void on&ause:; 8 super.on&ause:;5 S$ared1references settin%s"get&references:@;5 S$ared1references.)ditor editor"settin%s.edit:;5 editor.putBoolean:#cb*c$ecked#G cb.isChecked:;;5 editor.commit:;5
< <
.n onCreate:;, Ce o the same setup as be$ore, tying our a%tivity in as the ,nC$eckedC$an%e+istener $or the %he%kbo;. We also tie an anonymous ,nClick+istener to the button, Chi%h %alls finis$:; on the a%tivity. 5his proa%tively %loses the a%tivity, %ausing An roi to go through the $ull %hain o$ on1ause:;, onStop:;, an onDestroy:; as it %loses out the a%tivity. 5his Cay, Ce %an be sure that, $or our test, Ce get a likely spot to persist the pre$eren%es. "nlike in the original e;ample, Ce also hook into onResume:; an on1ause:;. .n onResume:;, Ce a%%ess the a%tivity7s pre$eren%es an retrieve a cb*c$ecked boolean pre$eren%e, an set the %he%kbo; to that value. /y e$ault, i$ the pre$eren%e is not $oun , it Cill be set to $alse. Conversely, in on1ause:;, Ce get the a%tivity7s pre$eren%es, store the cb*c$ecked pre$eren%e as the %he%kbo;7s %urrent state, an %ommit the %hange.
($;
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
>sing Preferences
.$ you %he%k the %he%kbo;, then %li%k the Close button, then re3open the a%tivity, you Cill see that it opens Cith the %he%kbo; alrea y %he%ke *
($(
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
>sing Preferences
0oti%e that the label $or the %he%kbo; is also %orre%t, in that it says the %he%kbo; is %he%ke . 5his means that our onC$eckedC$an%ed:; implementation is being %alle , even though Ce are manually setting the %he%kbo; state via setC$ecked:;.
($%
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
CHAPTER 1*
)ccessing !iles
While An roi o$$ers stru%ture storage, via pre$eren%es an atabases, sometimes a simple $ile Cill su$$i%e. An roi o$$ers tCo mo els $or a%%essing $iles* one $or $iles pre3pa%kage Cith your appli%ation, an one $or $iles %reate on3 evi%e by your appli%ation.
)ccessing !iles
or you Cill nee to provi e some means o$ up ating the ata. 5he simplest Cay to han le that is to use the re$eren%e ata to bootstrap some other mo i$iable $orm o$ storage &e.g., a atabase', but this makes $or tCo %opies o$ the ata in storage. An alternative is to keep the re$eren%e ata as3is but keep mo i$i%ations in a $ile or atabase, an merge them together Chen you nee a %omplete pi%ture o$ the in$ormation. (or e;ample, i$ your appli%ation ships a $ile o$ "RLs, you %oul have a se%on $ile that tra%ks "RLs a e by the user or re$eren%e "RLs that Cere elete by the user. .n the Static sample proOe%t, you Cill $in a reCorking o$ the listbo; e;ample $rom earlier, this time using a stati% EML $ile instea o$ a har Cire array in +ava. 5he layout is the same*
<>xml version"#?.@# encodin%"#utf(A#>& <+inear+ayout xmlns!android"#$ttp!//sc$emas.android.com/apk/res/android# android!orientation"#vertical# android!layout*widt$"#fill*parent# android!layout*$ei%$t"#fill*parent# & <-ext7iew android!id"#9Bid/selection# android!layout*widt$"#fill*parent# android!layout*$ei%$t"#wrap*content# /& <+ist7iew android!id"#9android!id/list# android!layout*widt$"#fill*parent# android!layout*$ei%$t"#fill*parent# android!drawSelector,n-op"#false# /& </+inear+ayout&
.n a ition to that EML $ile, you also nee an EML $ile Cith the Cor s to shoC in the list*
<words& <word <word <word <word <word <word <word <word <word <word <word value"#lorem# /& value"#ipsum# /& value"#dolor# /& value"#sit# /& value"#amet# /& value"#consectetuer# /& value"#adipiscin%# /& value"#elit# /& value"#morbi# /& value"#vel# /& value"#li%ula# /&
($$
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
)ccessing !iles
<word value"#vitae# /& <word value"#arcu# /& <word value"#aliJuet# /& <word value"#mollis# /& <word value"#etiam# /& <word value"#vel# /& <word value"#erat# /& <word value"#placerat# /& <word value"#ante# /& <word value"#porttitor# /& <word value"#sodales# /& <word value"#pellentesJue# /& <word value"#au%ue# /& <word value"#purus# /& </words&
While this EML stru%ture is not e;a%tly a mo el o$ spa%e e$$i%ien%y, it Cill su$$i%e $or a emo. 5he +ava %o e noC must rea in that EML $ile, parse out the Cor s, an put them somepla%e $or the list to pi%k up*
public class StaticEileDemo extends +istActivity 8 -ext7iew selection5 Array+ist items"new #rrayList:;5 9,verride public void onCreate:6undle icicle; 8 super.onCreate:icicle;5 setContentView:R.layout.main;5 selection":-ext7iew;findViewById:R.id.selection;5 try 8 .nputStream in"get$esources:;.open$aw$esource:R.raw.words;5 Document6uilder builder"Document6uilderEactory .newInstance:; .newDocumentBuilder:;5 Document doc"builder.parse:inG null;5 /ode+ist words"doc.get+lementsByTag%ame:#word#;5 for :int i"@5i<words.getLength:;5iBB; 8 items.add:::)lement;words.item:i;;.get#ttri!ute:#value#;;5 < in.close:;5 < catc$ :-$rowable t; 8 show#lert:#)xceptionW#G @G t.toString:;G #Cancel#G true;5 < setList#dapter:new ArrayAdapter<Strin%&:t$isG ($/
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
)ccessing !iles
<
android.R.layout.simple*list*item*?G items;;5
<
public void onListItemClick:+ist7iew parentG 7iew vG int positionG lon% id; 8 selection.setText:items.get:position;.toString:;;5 <
5he i$$eren%es mostly lie Cithin onCreate:;. We get an .nputStream $or the EML $ile &%etResources:;.openRawResource:R.raw.words;', then use the built3 in EML parsing logi% to parse the $ile into a A>M Document, pi%k out the Cor elements, then pour the value attributes into an Array+ist $or use by the ArrayAdapter. 5he resulting a%tivity looks the same as be$ore, sin%e the list o$ Cor s is the same, Oust relo%ate *
>$ %ourse, there are even easier Cays to have EML $iles available to you as pre3pa%kage $iles N using an EML resour%e. 5hat is %overe in the ne;t %hapter. )oCever, Chile this e;ample use EML, the $ile %oul Oust as easily
($0
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
)ccessing !iles
have been a simple one3Cor 3per3line list, or in some other $ormat not han le natively by the An roi resour%e system.
2eadinA An WritinA
Rea ing an Criting your oCn, appli%ation3spe%i$i% ata $iles is nearly i enti%al to Chat you might o in a esktop +ava appli%ation. 5he key is to use openEile.nput:; an openEile,utput:; on your Activity or other Context to get an .nputStream an ,utputStream, respe%tively. (rom that point $orCar , it is not mu%h i$$erent than regular +ava .U> logi%*
Wrap those streams as nee e , su%h as using an .nputStreamReader or ,utputStreamCriter $or te;t3base .U> Rea or Crite the ata "se close:; to release the stream Chen one
Relative paths &i.e., those Cithout lea ing slashes' are lo%al to the appli%ation. .$ tCo appli%ations both try rea ing a notes.txt $ile via openEile.nput:;, they Cill ea%h a%%ess their oCn e ition o$ the $ile. .$ you nee to have one $ile a%%essible $rom many pla%es, you probably Cant to %reate a %ontent provi er, as Cill be es%ribe an up%oming %hapter. /eloC you Cill see the layout $or the Corl 7s most trivial te;t e itor, pulle $rom the ReadCrite sample appli%ation*
<>xml version"#?.@# encodin%"#utf(A#>& <+inear+ayout xmlns!android"#$ttp!//sc$emas.android.com/apk/res/android# android!layout*widt$"#fill*parent# android!layout*$ei%$t"#fill*parent# android!orientation"#vertical#& <6utton android!id"#9Bid/close# android!layout*widt$"#wrap*content# android!layout*$ei%$t"#wrap*content# android!text"#Close# /& <)dit-ext android!id"#9Bid/editor# android!layout*widt$"#fill*parent# android!layout*$ei%$t"#fill*parent# android!sin%le+ine"#false# /& </+inear+ayout&
($3
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
)ccessing !iles
All Ce have here is a large te;t3e iting Ci get, Cith a QCloseQ button above it. 5he +ava is only slightly more %ompli%ate *
packa%e com.commonsware.android.files5 import import import import import import import import import import import android.app.Activity5 android.os.6undle5 android.view.7iew5 android.wid%et.6utton5 android.wid%et.)dit-ext5 java.io.6ufferedReader5 java.io..nputStream5 java.io..nputStreamReader5 java.io..nputStream5 java.io.,utputStream5 java.io.,utputStreamCriter5
public class ReadCriteEileDemo extends Activity 8 )dit-ext editor5 9,verride public void onCreate:6undle icicle; 8 super.onCreate:icicle;5 setContentView:R.layout.main;5 editor":)dit-ext;findViewById:R.id.editor;5 6utton btn":6utton;findViewById:R.id.close;5 btn.setOnClickListener:new 6utton.OnClickListener:; 8 public void onClick:7iew v; 8 finish:;5 < <;5 < public void on$esume:; 8 super.on$esume:;5 try 8 .nputStream in"open"ileInput:#notes.txt#;5 if :inW"null; 8 6ufferedReader reader"new Buffered$eader:new InputStream$eader:in;;5 Strin% str5 Strin%6uffer buf"new StringBuffer:;5 w$ile ::str " reader.readLine:;; W" null; 8 buf.append:strB#4n#;5 < in.close:;5
($7
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
)ccessing !iles
editor.setText:buf.toString:;;5 < catc$ :java.io.Eile/otEound)xception e; 8 // t$atZs ,MG we probably $avenZt created it yet < catc$ :-$rowable t; 8 show#lert:#)xceptionW#G @G t.toString:;G #Cancel#G true;5 < < public void on&ause:; 8 super.on&ause:;5 try 8 ,utputStreamCriter out"new OutputStream*riter:open"ileOutput:#notes.txt#G out.write:editor.getText:;.toString:;;5 out.close:;5 <
@;;5
< <
(irst, Ce Cire up the button to %lose out our a%tivity Chen %li%ke by using set,nClick+istener:; to invoke finis$:; on the a%tivity. 0e;t, Ce hook into onResume:;, so Ce get %ontrol Chen our e itor is %oming ba%k to li$e, $rom a $resh laun%h or a$ter having been $roKen. We use openEile.nput:; to rea in notes.txt an pour the %ontents into the te;t e itor. .$ the $ile is not $oun , Ce assume this is the $irst time the a%tivity Cas run &or the $ile Cas elete by other means', an Ce Oust leave the e itor empty. (inally, Ce hook into on1ause:;, so Ce get %ontrol as our a%tivity gets hi en by other user a%tivity or is %lose , su%h as via our QCloseQ button. )ere, Ce use openEile,utput:; to open notes.txt, into Chi%h Ce pour the %ontents o$ the te;t e itor. 5he net result is that Ce have a persistent notepa * Chatever is type in Cill remain until elete , surviving our a%tivity being %lose , the phone being turne o$$, or similar situations. >$ %ourse, it oesn7t look like mu%h*
($9
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
)ccessing !iles
(/;
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
CHAPTER 1-
Resour%es are stati% bits o$ in$ormation hel outsi e the +ava sour%e %o e. @ou have seen one type o$ resour%e N the layout N $re<uently in the e;amples in this book. 5here are many other types o$ resour%e, su%h as images an strings, that you %an take a vantage o$ in your An roi appli%ations.
Animations &res/anim/', esigne $or short %lips as part o$ a user inter$a%e, su%h as an animation suggesting the turning o$ a page Chen a button is %li%ke .mages &res/drawable', $or putting stati% i%ons or other pi%tures in a user inter$a%e
(/(
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
#trings, %olors, arrays, an imensions &res/values/', to both give these sorts o$ %onstants symboli% names an to keep them separate $rom the rest o$ the %o e &e.g., $or internationaliKation an lo%aliKation' EML &res/xml/', $or stati% EML $iles %ontaining your oCn ata an stru%ture
String Theory
Feeping your labels an other bits o$ te;t outsi e the main sour%e %o e o$ your appli%ation is generally %onsi ere to be a very goo i ea. .n parti%ular, it helps Cith internationaliKation &.-80' an lo%aliKation &L-00', %overe later in this %hapter. Iven i$ you are not going to translate your strings to other languages, it is easier to make %orre%tions i$ all the strings are in one spot instea o$ s%attere throughout your sour%e %o e. An roi supports regular e;ternaliKe strings, along Cith Qstring $ormatsQ, Chere the string has pla%ehol ers $or ynami%ally3inserte in$ormation. >n top o$ that, An roi supports simple te;t $ormatting, %alle Qstyle te;tQ, so you %an make your Cor s be bol or itali% intermingle Cith normal te;t.
Pl in Strin!s
8enerally speaking, all you nee to o is have an EML $ile in the res/values ire%tory &typi%ally name res/values/strin%s.xml', Cith a resources root element, an one %hil strin% element $or ea%h string you Cish to en%o e as a resour%e. 5he strin% element takes a name attribute, Chi%h is the uni<ue name $or this string, an a single te;t element %ontaining the te;t o$ the string*
<resources& <strin% name"#Juick#&-$e Juick brown fox...</strin%& <strin% name"#lau%$s#&3e w$o lau%$s last...</strin%& </resources&
5he only tri%ky part is i$ the string value %ontains a <uote &#' or an apostrophe &Z'. .n those %ases, you Cill Cant to es%ape those values, by
(/%
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
pre%e ing them Cith a ba%kslash &e.g., -$ese are t$e times t$at try men4Zs souls'. >r, i$ it is Oust an apostrophe, you %oul en%lose the value in <uotes &e.g., #-$ese are t$e times t$at try menZs souls.#'. @ou %an then re$eren%e this string $rom a layout $ile &as 9strin%/..., Chere the ellipsis is the uni<ue name N e.g., 9strin%/lau%$s'. >r you %an get the string $rom your +ava %o e by %alling %etStrin%:; Cith the resour%e .A o$ the string resour%e, that being the uni<ue name pre$i;e Cith R.strin%. &e.g., %etStrin%:R.strin%.Juick;'.
Strin! 9orm ts
As Cith other implementations o$ the +ava language, An roi 7s Aalvik ,M supports string $ormats. )ere, the string %ontains pla%ehol ers representing ata to be repla%e at runtime by variable in$ormation &e.g., My name is [?\s'. !lain strings store as resour%es %an be use as string $ormats*
Strin% strEormat"getString:R.strin%.my*name;5 Strin% strResult"Strin%.format:strEormatG #-im#;5 ::-ext7iew;findViewById:R.layout.some*label;; .setText:strResult;5
Styled Te.t
.$ you Cant really ri%h te;t, you shoul have raC resour%es %ontaining )5ML, then pour those into a WebFit Ci get. )oCever, $or light )5ML $ormatting, using <b&, <i&, an <u&, you %an Oust use a string resour%e*
<resources& <strin% name"#b#&-$is $as <b&bold</b& in it.</strin%& <strin% name"#i#&C$ereas t$is $as <i&italics</i&W</strin%& </resources&
@ou %an a%%ess these the same as Cith plain strings, Cith the e;%eption that the result o$ the %etStrin%:; %all is really a Spanned*
::-ext7iew;findViewById:R.layout.anot$er*label;; .setText:getString:R.strin%.lau%$s;;5
(/,
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
Styled 9orm ts
Where style te;t gets tri%ky is Cith style string $ormats, as Strin%.format:; Corks on Strin% obOe%ts, not Spanned obOe%ts Cith $ormatting instru%tions. .$ you really Cant to have style string $ormats, here is the Corkaroun * -. Intity3es%ape the angle bra%kets in the string resour%e &e.g., t$is is Ylt5bY%t5[?\sYlt5/bY%t5'
2. Retrieve the string resour%e as normal, though it Cill not be style at this point &e.g., %etStrin%:R.strin%.funky*format;' ?. 8enerate the $ormat results, being sure to es%ape any string values you substitute in, in %ase they %ontain angle bra%kets or ampersan s
Strin%.format:getString:R.strin%.funky*format;G -ext2tils.html+ncode:str/ame;;5
some-ext7iew.setText:3tml .from(tml:resultEromStrin%Eormat;;5
5o see this in a%tion, let7s look at the Strin%s emo. )ere is the layout $ile*
<>xml version"#?.@# encodin%"#utf(A#>& <+inear+ayout xmlns!android"#$ttp!//sc$emas.android.com/apk/res/android# android!orientation"#vertical# android!layout*widt$"#fill*parent# android!layout*$ei%$t"#fill*parent# & <+inear+ayout xmlns!android"#$ttp!//sc$emas.android.com/apk/res/android# android!orientation"#$ori'ontal# android!layout*widt$"#fill*parent# android!layout*$ei%$t"#wrap*content# & <6utton android!id"#9Bid/format# android!layout*widt$"#wrap*content# android!layout*$ei%$t"#wrap*content# android!text"#9strin%/btn*name# /& <)dit-ext android!id"#9Bid/name# android!layout*widt$"#fill*parent# android!layout*$ei%$t"#wrap*content# /& </+inear+ayout& <-ext7iew android!id"#9Bid/result# (/$
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
As you %an see, it is Oust a button, a $iel , an a label. 5he intent is $or somebo y to enter their name in the $iel , then %li%k the button to %ause the label to be up ate Cith a $ormatte message %ontaining their name. 5he 6utton in the layout $ile re$eren%es a string resour%e &9strin%/btn*name', so Ce nee a string resour%e $ile &res/values/strin%s.xml'*
<>xml version"#?.@# encodin%"#utf(A#>& <resources& <strin% name"#app*name#&Strin%sDemo</strin%& <strin% name"#btn*name#&/ame!</strin%& <strin% name"#funky*format#&My name is Ylt5bY%t5[?\sYlt5/bY%t5</strin%& </resources&
5he app*name resour%e is automati%ally %reate by the activityCreator s%ript. 5he btn*name string is the %aption o$ the 6utton, Chile our style string $ormat is in funky*format. (inally, to hook all this together, Ce nee a pin%h o$ +ava*
packa%e com.commonsware.android.resources5 import import import import import import import import android.app.Activity5 android.os.6undle5 android.text.-ext2tils5 android.text.3tml5 android.view.7iew5 android.wid%et.6utton5 android.wid%et.)dit-ext5 android.wid%et.-ext7iew5
public class Strin%sDemo extends Activity 8 )dit-ext name5 -ext7iew result5 9,verride public void onCreate:6undle icicle; 8 super.onCreate:icicle;5 setContentView:R.layout.main;5 name":)dit-ext;findViewById:R.id.name;5
(//
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
result":-ext7iew;findViewById:R.id.result;5 6utton btn":6utton;findViewById:R.id.format;5 btn.setOnClickListener:new 6utton.OnClickListener:; 8 public void onClick:7iew v; 8 apply"ormat:;5 < <;5 < private void apply"ormat:; 8 Strin% format"getString:R.strin%.funky*format;5 Strin% simpleResult"Strin%.format:formatG -ext2tils.html+ncode:name.getText:;.toString:;;;5 result.setText:3tml.from(tml:simpleResult;;5 < <
5he string resour%e manipulation %an be $oun in applyEormat:;, Chi%h is %alle Chen the button is %li%ke . (irst, Ce get our $ormat via %etStrin%:; N something Ce %oul have one at onCreate:; time $or e$$i%ien%y. 0e;t, Ce $ormat the value in the $iel using this $ormat, getting a Strin% ba%k, sin%e the string resour%e is in entity3en%o e )5ML. 0ote the use o$ -ext2tils.$tml)ncode:; to entity3en%o e the entere name, in %ase somebo y e%i es to use an ampersan or something. (inally, Ce %onvert the simple )5ML into a style te;t obOe%t via 3tml.from3tml:; an up ate our label. When the a%tivity is $irst laun%he , Ce have an empty label*
(/0
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
!igure $3< The same application6 after filling in some heroic figureAs name
(/3
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
2. android.resource!//com.example.app/raw/..., Chere com.example.app is the name o$ the +ava pa%kage use by your appli%ation in AndroidManifest.xml an ... is the te;tual name o$ the raC resour%e &e.g., foo $or res/drawable/foo.pn%' 0ote that An roi ships Cith some image resour%es built in. 5hose are a resse in +ava Cith an android.R.drawable pre$i; to istinguish them $rom appli%ation3spe%i$i% resour%es &e.g., android.R.drawable.picture*frame'. #o, let7s up ate the previous e;ample to use an i%on $or the button instea o$ the string resour%e. 5his %an be $oun as .ma%es. (irst, Ce slightly a Oust the layout $ile, using an .ma%e6utton an re$eren%ing a raCable name 9drawable/icon*
<>xml version"#?.@# encodin%"#utf(A#>& <+inear+ayout xmlns!android"#$ttp!//sc$emas.android.com/apk/res/android#
(/7
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
android!orientation"#vertical# android!layout*widt$"#fill*parent# android!layout*$ei%$t"#fill*parent# & <+inear+ayout xmlns!android"#$ttp!//sc$emas.android.com/apk/res/android# android!orientation"#$ori'ontal# android!layout*widt$"#fill*parent# android!layout*$ei%$t"#wrap*content# & <.ma%e6utton android!id"#9Bid/format# android!layout*widt$"#wrap*content# android!layout*$ei%$t"#wrap*content# android!src"#9drawable/icon# /& <)dit-ext android!id"#9Bid/name# android!layout*widt$"#fill*parent# android!layout*$ei%$t"#wrap*content# /& </+inear+ayout& <-ext7iew android!id"#9Bid/result# android!layout*widt$"#fill*parent# android!layout*$ei%$t"#wrap*content# /& </+inear+ayout&
0e;t, Ce nee to put an image $ile in res/drawable Cith a base name o$ i%on. .n this %ase, Ce use a ?2;?2 !08 $ile $rom the 0uvola i%on set. (inally, Ce tCi le the +ava sour%e, repla%ing our 6utton Cith an .ma%e6utton*
packa%e com.commonsware.android.resources5 import import import import import import import import import android.app.Activity5 android.os.6undle5 android.text.-ext2tils5 android.text.3tml5 android.view.7iew5 android.wid%et.6utton5 android.wid%et..ma%e6utton5 android.wid%et.)dit-ext5 android.wid%et.-ext7iew5
public class .ma%esDemo extends Activity 8 )dit-ext name5 -ext7iew result5 9,verride public void onCreate:6undle icicle; 8 super.onCreate:icicle;5 setContentView:R.layout.main;5 name":)dit-ext;findViewById:R.id.name;5 result":-ext7iew;findViewById:R.id.result;5
(/9
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
.ma%e6utton btn":.ma%e6utton;findViewById:R.id.format;5 btn.setOnClickListener:new 6utton.OnClickListener:; 8 public void onClick:7iew v; 8 apply"ormat:;5 < <;5
<
private void apply"ormat:; 8 Strin% format"getString:R.strin%.funky*format;5 Strin% simpleResult"Strin%.format:formatG -ext2tils.html+ncode:name.getText:;.toString:;;;5 result.setText:3tml.from(tml:simpleResult;;5 <
#imply put the EML $ile in res/xml/, an you %an a%%ess it by %etUml:; on a Resources obOe%t, supplying it a resour%e .A o$ R.xml. plus the base name o$ your EML $ile. #o, in an a%tivity, Cith an EML $ile o$ words.xml, you %oul %all %etResources:;.%etUml:R.xml.words;. 5his returns an instan%e o$ the presently3un o%umente Uml1ull1arser, $oun in the or%.xmlpull.v? +ava namespa%e. Ao%umentation $or this library %an be $oun at at the parser7s site as o$ this Criting. An EML pull parser is event3 riven* you keep %alling next:; on the parser to get the ne;t event, Chi%h %oul be S-AR-*-A0, )/D*-A0, )/D*D,C2M)/-, et%. >n a S-AR-*-A0 event, you %an a%%ess the tag7s name an attributesP a single -)Uevent represents the %on%atenation o$ all te;t no es that are ire%t %hil ren o$ this element. /y looping, testing, an invoking per3element logi%, you parse the $ile. 5o see this in a%tion, let7s reCrite the +ava %o e $or the Static sample proOe%t to use an EML resour%e. 5his neC proOe%t, UM+, re<uires that you pla%e the words.xml $ile $rom Static not in res/raw/, but in res/xml/. 5he layout stays the same, so all that nee s repla%ing is the +ava sour%e*
packa%e com.commonsware.android.resources5 import import import import import import import import import import import import android.app.Activity5 android.os.6undle5 android.app.+istActivity5 android.view.7iew5 android.wid%et.Adapter7iew5 android.wid%et.ArrayAdapter5 android.wid%et.+ist7iew5 android.wid%et.-ext7iew5 java.io..nputStream5 java.util.Array+ist5 or%.xmlpull.v?.Uml1ull1arser5 or%.xmlpull.v?.Uml1ull1arser)xception5
public class UM+ResourceDemo extends +istActivity 8 -ext7iew selection5 Array+ist items"new #rrayList:;5 9,verride public void onCreate:6undle icicle; 8 super.onCreate:icicle;5 setContentView:R.layout.main;5
(0(
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
selection":-ext7iew;findViewById:R.id.selection;5 try 8 Uml1ull1arser xpp"get$esources:;.get,ml:R.xml.words;5 w$ile :xpp.get+ entType:;W"Uml1ull1arser.)/D*D,C2M)/-; 8 if :xpp.get+ entType:;""Uml1ull1arser.S-AR-*-A0; 8 if :xpp.get%ame:;.e-uals:#word#;; 8 items.add:xpp.get#ttri!uteValue:@;;5 < < xpp.next:;5 < catc$ :-$rowable t; 8 show#lert:#)xceptionW#G @G t.toString:;G #Cancel#G true;5 < setList#dapter:new ArrayAdapter<Strin%&:t$isG android.R.layout.simple*list*item*?G items;;5 <
<
<
public void onListItemClick:+ist7iew parentG 7iew vG int positionG lon% id; 8 selection.setText:items.get:position;.toString:;;5 <
0oC, insi e our try...catc$ blo%k, Ce get our Uml1ull1arser an loop until the en o$ the o%ument. .$ the %urrent event is S-AR-*-A0 an the name o$ the element is word &xpp.%et/ame:;.eJuals:#word#;', then Ce get the one3 an 3only attribute an pop that into our list o$ items $or the sele%tion Ci get. #in%e Ce7re in %omplete %ontrol over the EML $ile, it is sa$e enough to assume there is e;a%tly one attribute. /ut, i$ you Cere not as %om$ortable that the EML is properly e$ine , you might %onsi er %he%king the attribute %ount &%etAttributeCount:;' an the name o$ the attribute &%etAttribute/ame:;' be$ore blin ly assuming the @3in e; attribute is Chat you think it is. 5he result looks the same as be$ore, albeit Cith a i$$erent name in the title bar*
(0%
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
*iscellaneous Galues
.n the res/values/ ire%tory, you %an pla%e one &or more' EML $iles es%ribing simple resour%es* imensions, %olors, an arrays. We have alrea y seen uses o$ imensions an %olors in previous e;amples, Chere they Cere passe as simple strings &e.g., #?@px#' as parameters to %alls. @ou %an, o$ %ourse, set these up as +ava stati% $inal obOe%ts an use their symboli% names...but this only Corks insi e +ava sour%e, not in layout EML $iles. /y putting these values in resour%e EML $iles, you %an re$eren%e them $rom both +ava an layouts, plus have them %entrally lo%ate $or easy e iting. Resour%e EML $iles have a root element o$ resourcesP everything else is a %hil o$ that root.
Dimensions
Aimensions are use in several pla%es in An roi to es%ribe istan%es, su%h a Ci get7s pa ing. While this book usually uses pi;els &e.g., ?@px $or ten pi;els', there are several i$$erent units o$ measurement available to you*
(0,
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
on the
$or points, Chi%h in publishing terms is -U22n o$ an in%h &again, base on the a%tual physi%al siKe o$ the s%reen' an sp $or evi%e3in epen ent pi;els an s%ale3in epen ent pi;els N one pi;el e<uals one p $or a -40 pi resolution s%reen, Cith the ratio s%aling base on the a%tual s%reen pi;el ensity &s%ale3 in epen ent pi;els also take into a%%ount the user7s pre$erre $ont siKe'
5o en%o e a imension as a resour%e, a a dimen element, Cith a name attribute $or your uni<ue name $or this resour%e, an a single %hil te;t element representing the value*
<resources& <dimen name"#t$in#&?@px</dimen& <dimen name"#fat#&?in</dimen& </resources&
.n a layout, you %an re$eren%e imensions as 9dimen/..., Chere the ellipsis is a pla%ehol er $or your uni<ue name $or the resour%e &e.g., t$in an fat $rom the sample above'. .n +ava, you re$eren%e imension resour%es by the uni<ue name pre$i;e Cith R.dimen. &e.g., Resources.%etDimen:R.dimen.t$in;'.
Colors
Colors in An roi are he;a e%imal R8/ values, also optionally spe%i$ying an alpha %hannel. @ou have your %hoi%e o$ single3%hara%ter he; values or ouble3%hara%ter he; values, leaving you Cith $our styles*
DR06 DAR06 DRR0066 DAARR0066
5hese Cork similarly to their %ounterparts in Cas%a ing #tyle #heets &C##'.
(0$
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
@ou %an, o$ %ourse, put these R8/ values as string literals in +ava sour%e or layout resour%es. .$ you Cish to turn them into resour%es, though, all you nee to o is a color elements to the resour%es $ile, Cith a name attribute $or your uni<ue name $or this %olor, an a single te;t element %ontaining the R8/ value itsel$*
<resources& <color name"#yellow*oran%e#&DEEDLLL</color& <color name"#forest*%reen#&D@@LL@@</color& <color name"#burnt*umber#&DAAIIHN</color& </resources&
.n a layout, you %an re$eren%e %olors as 9color/..., repla%ing the ellipsis Cith your uni<ue name $or the %olor &e.g., burnt*umber'. .n +ava, you re$eren%e %olor resour%es by the uni<ue name pre$i;e Cith R.color. &e.g., Resources.%etColor:R.dimen.forest*%reen;'.
Arr ys
Array resour%es are esigne to hol lists o$ simple strings, su%h as a list o$ honori$i%s &Mr., Mrs., Ms., Ar., et%.'. .n the resour%e $ile, you nee one array element per array, Cith a name attribute $or the uni<ue name you are giving the array. 5hen, a one or more %hil item elements, ea%h o$ Chi%h having a single te;t element Cith the value $or that entry in the array*
<resources& <array name"#$onorifics#& <item&Dr.</item& <item&Mr.</item& <item&Mrs.</item& <item&Ms.</item& </array& </resources&
(rom your +ava %o e, you %an then use Resources.%etStrin%Array:; to get a o$ the items in the list. 5he parameter to %etStrin%Array:; is your uni<ue name $or the array, pre$i;e Cith R.array. &e.g., Resources.%etStrin%Array:R.array.$onorifics;'.
Strin%OP
(0/
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
#creen orientation* is the s%reen in a portrait orientationD Lan s%apeD .s the s%reen s<uare an , there$ore, oes not really have an orientationD #creen siBe* hoC many pi;els oes the s%reen have, so you %an siKe your resour%es a%%or ingly &e.g., large versus small i%ons'D Touchscreen* oes the evi%e have a tou%hs%reenD .$ so, is the tou%hs%reen set up to be use Cith a stylus or a $ingerD 7ey6oard* Chat keyboar oes the user have &HWIR5@, numeri%, neither', either noC or as an optionD Ather input* oes the evi%e have some other $orm o$ input, like a ire%tional pa or %li%k3CheelD
5he Cay An roi presently han les this is by having multiple resour%e ire%tories, Cith the %riteria $or ea%h embe e in their names. #uppose, $or e;ample, you Cant to support strings in both Inglish an #panish. 0ormally, $or a single3language setup, you Coul put your strings in a $ile name res/values/strin%s.xml. 5o support both Inglish an #panish, you Coul %reate tCo $ol ers, res/values(en an res/values(es, Chere the value a$ter the hyphen is the .#> 4?13- tCo3letter %o e $or the language you Cant. @our Inglish3language strings Coul go in res/values( en/strin%s.xml an the #panish ones in res/values(es/strin%s.xml. An roi Cill %hoose the proper $ile base on the user7s evi%e settings.
(00
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
#eems easy, rightD Where things start to get %ompli%ate is Chen you nee to use multiple isparate %riteria $or your resour%es. 5his may %ome most $re<uently Cith layouts, as you might Cant one layout $or portrait an small s%reens, one layout $or larger s%reens in lan s%ape mo e, an variations o$ ea%h $or $inger3input versus other types o$ input &keyboar , stylus'. 5his Cill alloC you to make the best use o$ the available s%reen Qreal estateQ, Cithout any %o ing %hanges to your a%tivity using the layout. >n%e you get into these sorts o$ situations, though, all sorts o$ rules %ome into play, su%h as*
5he %on$iguration options &e.g., (en' have a parti%ular or er o$ pre%e en%e, an they must appear in the ire%tory name in that or er. 5he An roi o%umentation outlines the spe%i$i% or er in Chi%h these options %an appear. (or the purposes o$ this e;ample, s%reen orientation must pre%e e tou%hs%reen type, Chi%h must pre%e e s%reen siKe. 5here %an only be one value o$ ea%h %on$iguration option %ategory per ire%tory. @ou %annot, $or e;ample, %onsi er portrait an s<uare s%reens to be the same N ea%h Cill re<uire its oCn name res/layout... $ol er. >ptions are %ase sensitive
#o, $or the s%enario es%ribe above, in theory, Ce Coul nee the $olloCing ire%tories*
res/layout(port(fin%er res/layout(sJuare(fin%er res/layout(landscape(fin%er(SN@xNA@ res/layout(port(notouc$
res/layout(sJuare(notouc$
res/layout(landscape(notouc$(SN@xNA@ res/layout(port(stylus res/layout(sJuare(stylus
(03
res/layout(landscape(stylus(SN@xNA@
0ote that $or some o$ these, the a%tual layout $iles Cill be i enti%al. (or e;ample, Ce only %are about $inger layouts being i$$erent than the other tCo, but sin%e Ce %annot %ombine those tCo, Ce Coul theoreti%ally have to have separate ire%tories Cith i enti%al %ontents $or notouc$ an stylus. Also note that there is nothing preventing you $rom also having a ire%tory Cith the una orne base name &res/layout'. .n $a%t, this is probably a goo i ea, in %ase $uture e itions o$ the An roi runtime intro u%e other %on$iguration options you i not %onsi er N having a e$ault layout might make the i$$eren%e betCeen your appli%ation Corking or $ailing on that neC evi%e. 0oC, Ce %an Q%heatQ a bit, by e%o ing the rules An roi uses $or etermining Chi%h, among a set o$ %an i ates, is the QrightQ resour%e ire%tory to use* -. (irst up, An roi tosses out ones that are spe%i$i%ally invali . #o, $or e;ample, i$ the s%reen siKe o$ the evi%e is ?20;2=0, the SN@xNA@ ire%tories Coul be roppe as %an i ates, sin%e they spe%i$i%ally %all $or some other siKe.
2. 0e;t, An roi %ounts the number o$ mat%hes $or ea%h $ol er, an only pays attention to those Cith the most mat%hes. ?. (inally, An roi goes in the or er o$ pre%e en%e o$ the options N in other Cor s, it goes $rom le$t to right in the ire%tory name. #o Ce %oul skate by Cith only the $olloCing %on$igurations*
res/layout(landscape(fin%er(SN@xNA@ res/layout(landscape(SN@xNA@ res/layout(fin%er res/layout
.$ the evi%e is in portrait or s<uare mo e, or oes not have a 4=0;=80 s%reen siKe, the $irst tCo %an i ates Cill be skippe , an the layout Cill be %hosen base on Chether the evi%e supports $inger input or not.
(07
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
>therCise, one o$ the tCo lan s%ape 4=0;=80 layouts Cill be %hosen, as they Coul be a QstrongerQ mat%h than the others, Cith the $inal etermination being on Chether the evi%e supports $inger input or not.
(09
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
CHAPTER 1/
#HLite is a very popular embe e atabase, as it %ombines a %lean #HL inter$a%e Cith a very small memory $ootprint an e%ent spee . Moreover, it is publi% omain, so everyone %an use it. Lots o$ $irms &A obe, Apple, 8oogle, #un, #ymbian' an open sour%e proOe%ts &MoKilla, !)!, !ython' all ship pro u%ts Cith #HLite. (or An roi , #HLite is Qbake intoQ the An roi runtime, so every An roi appli%ation %an %reate #HLite atabases. #in%e #HLite uses a #HL inter$a%e, it is $airly straight$orCar to use $or people Cith e;perien%e in other #HL3 base atabases. )oCever, its native A!. is not +A/C, an +A/C might be too mu%h overhea $or a memory3limite evi%e like a phone, anyCay. )en%e, An roi programmers have a i$$erent A!. to learn N the goo neCs being is that it is not that i$$i%ult. 5his %hapter Cill %over the basi%s o$ #HLite use in the %onte;t o$ Corking on An roi . .t by no means is a thorough %overage o$ #HLite as a Chole. .$ you Cant to learn more about #HLite an hoC to use it in other environment than An roi , a $ine book is 5he Ae$initive 8ui e to #HLite by Mi%hael >Cens. A%tivities Cill typi%ally a%%ess a atabase via a %ontent provi er or servi%e. As su%h, this %hapter oes not have a $ull e;ample. @ou Cill $in a $ull e;ample
(3(
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
o$ a %ontent provi er that a%%esses a atabase in the /uil ing a Content !rovi er %hapter.
#HLite are meant to solve i$$erent problems, an that you Cill not be seeing a $ull %opy o$ >ra%le on a phone any time real soon, in all likelihoo .
5he name o$ the atabase N any %lass in your appli%ation %an a%%ess this atabase un er this name &though nothing outsi e your appli%ation %an a%%ess it' An integer version number $or the atabase &see beloC' 5he se%urity mo e $or a%%essing this atabase N $or noC, use @ An optional instan%e o$ a CursorEactory sub%lass that shoul be use in %onOun%tion Cith this atabase, %overe in greater etail in the se%tion on <uerying the atabase, later in this %hapter
5he version number is $or your oCn bookkeeping. When somebo y upgra es your appli%ation to a neC version, i$ your neC version uses a i$$erent atabase s%hema, you %an %ompare the version you Cant to use Cith the version o$ the atabase that is alrea y installe . 5hat Cill help your appli%ation $igure out Chat nee s to be %hange in the table stru%tures. 5his is %overe in greater etail in the %hapter on %reating a %ontent provi er. 5he result o$ the createDatabase:; %all is an instan%e o$ ST+iteDatabase, Chi%h you %an use $or %reating tables an the like, es%ribe later in this %hapter. @ou also get a ST+iteDatabase instan%e Chen you %all openDatabase:; to a%%ess a atabase you alrea y %reate . 5his takes the name o$ the atabase an , optionally, the CursorEactory use Chen <uerying the atabase.
(3,
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
When you are one Cith the atabase &e.g., your a%tivity is being %lose ', simply %all close:; on the #HLiteAatabase to release your %onne%tion. .$ you Cish to get ri o$ the atabase entirely, your Activity, Content1rovider, or other Context sub%lass %an %all deleteDatabase:; Cith the atabase7s name.
(or %reating your tables an in e;es, you Cill nee to %all execST+:; on your provi ing the AAL statement you Cish to apply against the atabase. /arring a atabase error, this metho returns nothing.
5his Cill %reate a table, name Ci gets, Cith a primary key %olumn name .D that is an auto3in%remente integer &i.e., #HLite Cill assign the value $or you Chen you insert roCs', plus tCo ata %olumns* name &te;t' an inventory &integer'. #HLite Cill automati%ally %reate an in e; $or you on your primary key %olumn, so the se%on statement a s another in e; on the table, by name. Most likely, you Cill %reate tables an in e;es Chen you $irst %reate the atabase, or possibly Chen the atabase nee s upgra ing to a%%ommo ate a neC release o$ your appli%ation. .$ you o not %hange your table s%hemas, you might never rop your tables or in e;es, but i$ you o, Oust use execST+:; to invoke DR,1 ./D)U an DR,1 -A6+) statements as nee e .
*akinA .ata
8iven that you have a atabase an one or more tables, you probably Cant to put some ata in them an su%h. @ou have tCo maOor approa%hes $or oing this.
(3$
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
@ou %an alCays use execST+:;, Oust like you i $or %reating the tables. 5he execST+:; metho Corks $or any #HL that oes not return results, so it %an han le ./S)R-, 21DA-), D)+)-), et%. Oust $ine. #o, $or e;ample*
db.execS.L:#./S)R- ./-, wid%ets :nameG inventory;#B #7A+2)S :ZSprocketZG L;#;5
@our alternative is to use the insert:;, update:;, an delete:; metho s on the ST+iteDatabase obOe%t. 5hese are Qbuil erQ sorts o$ metho s, in that the break oCn the #HL statements into is%rete %hunks, then take those %hunks as parameters. 5hese metho s make use o$ Content7alues obOe%ts, Chi%h implement a Map3 es<ue inter$a%e, albeit one that has a itional metho s $or Corking Cith #HLite types. (or e;ample, in a ition to %et:; to retrieve a value by its key, you have %etAs.nte%er:;, %etAsStrin%:;, an so $orth. 5he insert:; metho takes the name o$ the table, the name o$ one %olumn as the Qnull %olumn ha%kQ, an a Content7alues Cith the initial values you Cant put into this roC. 5he Qnull %olumn ha%kQ is $or the %ase Chere the Content7alues instan%e is empty N the %olumn name as the Qnull %olumn ha%kQ Cill be e;pli%itly assigne the value /2++ in the #HL ./S)R- statement generate by insert:;. 5he update:; metho takes the name o$ the table, a Content7alues representing the %olumns an repla%ement values to use, an optional C3)R) %lause, an an optional list o$ parameters to $ill into the C3)R) %lause, to repla%e any embe e <uestion marks &>'. #in%e update:; only repla%es %olumns Cith $i;e values, versus ones %ompute base on other in$ormation, you may nee to use execST+:; to a%%omplish some en s. 5he C3)R) %lause an parameter list Corks akin to the positional #HL parameters you may be use to $rom other #HL A!.s. (or e;ample*
// replacements is a Content7alues instance Strin%OP parms"new Strin%OP 8#snicklefrit'#<5 db.update:#wid%ets#G replacementsG #name">#G parms;5
(3/
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
5he delete:; metho Corks akin to update:;, taking the name o$ the table, the optional C3)R) %lause, an the %orrespon ing parameters to $ill into the C3)R) %lause.
2. @ou %an use Juery:; to buil up a <uery $rom its %omponent parts Con$oun ing matters $urther is the ST+iteTuery6uilder %lass an the issue o$ %ursors an %ursor $a%tories. Let7s take all o$ this one pie%e at a time.
R # ;ueries
5he simplest solution, at least in terms o$ the A!., is rawTuery:;. #imply %all it Cith your #HL S)+)C- statement. 5he S)+)C- statement %an in%lu e positional parametersP the array o$ these $orms your se%on parameter to rawTuery:;. #o, Ce Cin up Cith*
Strin%OP parms"8#snicklefrit'#<5 Cursor result" db.raw.uery:#S)+)C- .DGinventory ER,M wid%ets C3)R) name">#G parms;5
.$ your <ueries are pretty mu%h Qbake intoQ your appli%ation, this is a very straight$orCar Cay to use them. )oCever, it gets %ompli%ate i$ parts o$ the <uery are ynami%, beyon Chat positional parameters %an really han le. (or e;ample, i$ the set o$ %olumns you nee to retrieve is not knoCn at %ompile time, puttering aroun %on%atenating %olumn names into a %omma3 elimite list %an be annoying...Chi%h is Chere Juery:; %omes in.
(30
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
Re!ul r ;ueries
5he Juery:; metho takes the is%rete pie%es o$ a #ILIC5 statement an buil s the <uery $rom them. 5he pie%es, in or er that they appear as parameters to Juery:;, are*
5he name o$ the table to <uery against 5he list o$ %olumns to retrieve 5he C3)R) %lause, optionally in%lu ing positional parameters 5he list o$ values to substitute in $or those positional parameters 5he 0R,21 6F %lause, i$ any 5he ,RD)R 6F %lause, i$ any
5hese %an be null Chen they are not nee e &e;%ept the table name, o$ %ourse'. #o, our previous snippet %onverts into*
Strin%OP columns"8#.D#G #inventory#<5 Strin%OP parms"8#snicklefrit'#<5 Cursor result"db.-uery:#wid%ets#G columnsG #name">#G parmsG nullG nullG null;5
(33
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
ST+iteTuery6uilder Jb"new S.Lite.ueryBuilder:;5 Jb.setTa!les:getTa!le%ame:;;5 if :isCollection)ri:url;; 8 Jb.set&ro/ection'ap:getDefault&ro/ection:;;5 < else 8 Jb.append*here:getIdColumn%ame:;B#"# B url.get&athSegments:;.get:?;;5 < Strin% order6y5 if :-ext2tils.is+mpty:sort;; 8 order6y"getDefaultSortOrder:;5 < else 8 order6y"sort5 < Cursor c"Jb.-uery:dbG projectionG selectionG selectionAr%sG nullG nullG order6y;5 c.set%otification)ri:getContext:;.getContent$esol er:;G url;5
Content provi ers are e;plaine in greater etail later in the book, so some o$ this you Cill have to take on $aith until then. )ere, Ce see*
A ST+iteTuery6uilder is %onstru%te .t is tol the table to use $or the <uery &set-ables:%et-able/ame:;;' .t is either tol the e$ault set o$ %olumns to return &set1rojectionMap:;', or is given a pie%e o$ a C3)R) %lause to i enti$y a parti%ular roC in the table by an i enti$ier e;tra%te $rom the 2ri supplie to the Juery:; %all &appendC$ere:;' (inally, it is tol to e;e%ute the <uery, blen ing the pre3set values Cith those supplie on the %all to Juery:; &Jb.Juery:dbG projectionG selectionG selectionAr%sG nullG nullG order6y;'
.nstea o$ having the ST+iteTuery6uilder e;e%ute the <uery ire%tly, Ce %oul have %alle buildTuery:; to have it generate an return the #HL S)+)Cstatement Ce nee e , Chi%h Ce %oul then e;e%ute ourselves.
(37
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
+sin! Cursors
0o matter hoC you e;e%ute the <uery, you get a Cursor ba%k. 5his is the An roi U#HLite e ition o$ the atabase %ursor, a %on%ept use in many atabase systems. With the %ursor, you %an*
(in out hoC many roCs are in the result set via count:; .terate over the roCs via first:;, next:;, an isAfter+ast:; (in out the names o$ the %olumns via %etColumn/ames:;, %onvert those into %olumn numbers via %etColumn.ndex:;, an get values $or the %urrent roC $or a given %olumn via metho s like %etStrin%:;, %et.nt:;, et%. Re3e;e%ute the <uery that %reate the %ursor via reJuery:; Release the %ursor7s resour%es via close:;
(or e;ample, here Ce iterate over the Ci gets table entries $rom the previous snippets*
Cursor result" db.raw.uery:#S)+)C- .DG nameG inventory ER,M wid%ets#;5 w$ile :Wresult.is#fterLast:;; 8 int id"result.getInt:@;5 Strin% name"result.getString:?;5 int inventory"result.getInt:H;5 // do somet$in% useful wit$ t$ese result.next:;5 < result.close:;5
(39
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
"p ating values $or parti%ular %olumns in the %urrent roC via metho s like update.nt:; an updateStrin%:;, or eleting the %urrent roC via deleteRow:; Committing those %hanges ba%k to the atabase via commit2pdates:; .nvoking reJuery:; to re$resh the %ursor base on the results o$ your %hanges, i$ you Cant to %ontinue using the %ursor
(7;
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
)ere your.app.packa%e is the +ava pa%kage $or your appli%ation &e.g., com.commonsware.android' an your(db(name is the name o$ your atabase, as supplie to createDatabase:;. 5he sJliteI program Corks, an i$ you are use to poking aroun your tables using a %onsole inter$a%e, you are Cel%ome to use it. .$ you pre$er something a little bit $rien lier, you %an alCays %opy the #HLite atabase o$$ the evi%e onto your evelopment ma%hine, then use a #HLite3aCare %lient program to putter aroun . 0ote, though, that you are Corking o$$ a %opy o$ the atabaseP i$ you Cant your %hanges to go ba%k to the evi%e, you Cill nee to trans$er the atabase ba%k over. 5o get the atabase o$$ the evi%e, you %an use the adb pull %omman &or the e<uivalent in your .AI', Chi%h takes the path to the on3 evi%e atabase an the lo%al estination as parameters. 5o store a mo i$ie atabase on the evi%e, use adb pus$, Chi%h takes the lo%al path to the atabase an the on3 evi%e estination as parameters. >ne o$ the most3a%%essible #HLite %lients is the #HLite Manager e;tension $or (ire$o;, as it Corks a%ross all plat$orms.
(7(
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
(7%
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
CHAPTER 12
+ava has as many, i$ not more, thir 3party libraries than any other mo ern programming language. )ere, Qthir 3party librariesQ re$er to the innumerable +ARs that you %an in%lu e in a server or esktop +ava appli%ation N the things that the +ava #AFs themselves o not provi e. .n the %ase o$ An roi , the Aalvik ,M at its heart is not pre%isely +ava, an Chat it provi es in its #AF is not pre%isely the same as any tra itional +ava #AF. 5hat being sai , many +ava thir 3party libraries still provi e %apabilities that An roi la%ks natively an there$ore may be o$ use to you in your proOe%t, $or the ones you %an get Corking Cith An roi 7s $lavor o$ +ava. 5his %hapter e;plains Chat it Cill take $or you to leverage su%h libraries an the limitations on An roi 7s support $or arbitrary thir 3party %o e.
.xpected Platform AP%s* Aoes the %o e assume a neCer +,M than the one An roi is base onD >r, oes the %o e assume the e;isten%e o$ +ava A!.s that ship Cith +2#I but not Cith An roi , su%h as #CingD
(7,
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
#iBe* I;isting +ava %o e esigne $or use on esktops or servers nee not Corry too mu%h about on3 isk siKe, or, to some e;tent, even in3 RAM siKe. An roi , o$ %ourse, is short on both. "sing thir 3party +ava %o e, parti%ularly Chen pre3pa%kage as +ARs, may balloon the siKe o$ your appli%ation. Performance* Aoes the +ava %o e e$$e%tively assume a mu%h more poCer$ul C!" than Chat you may $in on many An roi evi%esD +ust be%ause a esktop %an run it Cithout issue oesn7t mean your average mobile phone Cill han le it Cell. %nterface* Aoes the +ava %o e assume a %onsole inter$a%eD >r is it a pure A!. that you %an Crap your oCn inter$a%e aroun D
>ne tri%k $or a ressing some o$ these %on%erns is to use open sour%e +ava %o e, an a%tually Cork Cith the %o e to make it more An roi 3$rien ly. (or e;ample, i$ you7re only using -0J o$ the thir 3party library, maybe it7s CorthChile to re%ompile the subset o$ the proOe%t to be only Chat you nee , or at least removing the unne%essary %lasses $rom the +AR. 5he $ormer approa%h is sa$er, in that you get %ompiler help to make sure you7re not is%ar ing some essential pie%e o$ %o e, though it may be more te ious to o.
-.
Copy the thir 3party +AR&s' into a lib/ ire%tory you a proOe%t, as a peer o$ src/, bin/, et%.
to your
2. A a classpat$ element to the javac task in the compile target o$ your build.xml s%ript, pointing it to your neC lib/ ire%tory ?. A neC ar% elements to your exec task in the dex target o$ the build.xml s%ript, pointing it to the spe%i$i% +ARs to translate to Aalvik instru%tions an pa%kage
(or e;ample, here are the tCo a$orementione Ant tasks $rom the build.xml $or Mail6u'', a proOe%t Ce Cill e;amine in greater etail in the %hapters on servi%es*
<W(( Compile t$is projectZs .java files into .class files. ((& <tar%et name"#compile# depends"#dirsG resource(srcG aidl#& <javac encodin%"#ascii# tar%et"#?.L# debu%"#true# extdirs"## srcdir"#.# destdir"#\8outdir(classes<# bootclasspat$"#\8android(jar<#& <classpat$& <fileset dir"#lib#& <include name"#QQ/Q.jar#/& </fileset& </classpat$& </javac& </tar%et& <W(( Convert t$is projectZs .class files into .dex files. ((& <tar%et name"#dex# depends"#compile#& <exec executable"#\8dx<# failonerror"#true#& <ar% value"#(=UmxIANM# /& <ar% value"#((dex# /& <ar% value"#((output"\8basedir</\8intermediate(dex<# /& <ar% value"#((locals"full# /& <ar% value"#((positions"lines# /& <ar% pat$"#\8basedir</\8outdir(classes<# /& <ar% pat$"#\8basedir</lib/activation(?.?.jar#/& <ar% pat$"#\8basedir</lib/mail(?.N.jar#/& </exec& </tar%et&
Mail/uKK, as the name suggests, eals Cith email. 5o a%%omplish that en , Mail/uKK leverages the +avaMail A!.s an nee s tCo +avaMail +ARs* mail(?.N.jar an activation(?.?.jar. With both o$ those in the lib/ ire%tory, the classpat$ tells javac to link against those +ARs, so any +avaMail re$eren%es in the Mail/uKK %o e %an be %orre%tly resolve . 5hen, those +ARs
(7/
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
are liste , along Cith the Mail/uKK %ompile %lasses, in the task that invokes the dex tool to %onvert the +ava %o e into Aalvik ,M instru%tions. Without this step, even though your %o e may %ompile, it Con7t $in the +avaMail %lasses at runtime an Cill $ail Cith an e;%eption. As note above, using +ARs %an make your proOe%t portly N Mail/uKK is about 2B0F/ thanks to the +avaMail %lasses. >$ %ourse, it is entirely possible that +avaMail Coul re<uire $eatures in +ava that the Aalvik ,M simply oesn7t o$$er. 5his Coul n7t ne%essarily be is%overe at %ompile time, though, so your testing Cill nee to ensure that you e;er%ise all relevant uses o$ the thir 3party A!., so you knoC that it Cill run Cithout in%i ent.
(70
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
CHAPTER &4
5he e;pe%tation is that most, i$ not all, An roi evi%es Cill have built3in .nternet a%%ess. 5hat %oul be Wi(i, %ellular ata servi%es &IA8I, ?8, et%.', or possibly something else entirely. Regar less, most people N or at least those Cith a ata plan or Wi(i a%%ess N Cill be able to get to the .nternet $rom their An roi phone. 0ot surprisingly, the An roi plat$orm gives evelopers a Ci e range o$ Cays to make use o$ this .nternet a%%ess. #ome o$$er high3level a%%ess, su%h as the integrate WebFit broCser %omponent Ce saC in an earlier %hapter. .$ you Cant, you %an rop all the Cay oCn to using raC so%kets. >r, in betCeen, you %an leverage A!.s N both on3 evi%e an $rom ?r 3party +ARs N that give you a%%ess to spe%i$i% proto%ols* )55!, EM!!, #M5!, an so on. 5he emphasis o$ this book is on the higher3level $orms o$ a%%ess* the WebFit %omponent an .nternet3a%%ess A!.s, as busy %o ers shoul be trying to reuse e;isting %omponents versus rolling one7s oCn on3the3Cire proto%ol Cherever possible.
style Web servi%esQ is e$ine as Qsimple )55! re<uests $or or inary "RLs over the $ull range o$ )55! verbs, Cith $ormatte payloa s &EML, +#>0, et%.' as responsesQ. More e;pansive tutorials, (AHs, an )>W5>s %an be $oun at the )ttpClient Web site. )ere, Ce7ll %over the basi%s, Chile %he%king the Ceather.
(77
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
relevant pie%es o$ the +ava %o e here in this %hapter, though you %an alCays oCnloa the $ull sour%e $rom the CommonsWare Web site. We retrieve the 0ational Weather #ervi%e ata every time the a%tivity pops ba%k to the $oregroun by implementing onResume:; in the a%tivity*
9,verride public void on$esume:; 8 super.on$esume:;5 +ocation loc"getLocation:;5 Strin% url"Strin%.format:formatG loc.getLatitude:;G loc.getLongitude:;;5 0etMet$od met$od"new Get'ethod:url;5 try 8 int statusCode"client.execute'ethod:met$od;5 if :statusCodeW"3ttpStatus.SC*,M; 8 -oast .makeText:t$isG #ReJuest failed! #Bmet$od.getStatusLine:;G H@@@; .show:;5 < else 8 !uild"orecasts:met$od.get$esponseBody#sStream:;;5 browser.loadData:generate&age:;G #text/$tml#G #2-E(A#;5 < < catc$ :-$rowable t; 8 -oast .makeText:t$isG #ReJuest failed! #Bt.toString:;G H@@@; .show:;5 < finally 8 met$od.releaseConnection:;5 <
<
(irst, Ce retrieve our lo%ation using a private %et+ocation:; metho , Chi%h uses An roi 7s built3in lo%ation servi%es N more on this in a later %hapter. (or noC, all you nee to knoC is that +ocation sports %et+atitude:; an %et+on%itude:; metho s that return the latitu e an longitu e o$ the evi%e7s position, respe%tively. We hol the "RL to the 0ational Weather #ervi%e EML in a string resour%e, an pour in the latitu e an longitu e at runtime. 8iven our 3ttpClient
(79
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
instan%e %reate in onCreate:;, Ce populate a 0etMet$od Cith that %ustomiKe "RL, then e;e%ute that metho . .$ Ce get H@@ as the result %o e, Ce buil the $ore%ast )5ML page &see beloC' an pour that into the CebMit Ci get. .$ Ce get some other response ba%k, or i$ the 3ttpClient bloCs up Cith an e;%eption, Ce provi e that error as a -oast, be$ore eventually releasing our )55! %onne%tion $or this re<uest.
P rsin! Responses
5he response you get Cill be $ormatte using some system N )5ML, EML, +#>0, Chatever. .t is up to you, o$ %ourse, to pi%k out Chat in$ormation you nee an o something use$ul Cith it. .n the %ase o$ the Ceat$erDemo, Ce nee to e;tra%t the $ore%ast time, temperature, an i%on &in i%ating sky %on itions an pre%ipitation' an generate an )5ML page $rom it. An roi in%lu es*
5hree EML parsers* the tra itional W?C A>M &or%.wIc.dom', a #AE parser &or%.xml.sax', an the EML pull parser is%usse in the %hapter on resour%es A +#>0 parser &or%.json'
@ou are also Cel%ome to use thir 3party +ava %o e, Chere possible, to han le other $ormats, su%h as a e i%ate R##UAtom parser $or a $ee rea er. 5he use o$ thir 3party +ava %o e is is%usse in a separate %hapter. (or Ceat$erDemo, Ce use the W?C A>M parser in our buildEorecasts:; metho *
void !uild"orecasts:.nputStream in; t$rows )xception 8 Document6uilder builder"Document6uilderEactory .newInstance:; .newDocumentBuilder:;5 Document doc"builder.parse:inG null;5 /ode+ist times"doc.get+lementsByTag%ame:#start(valid(time#;5 for :int i"@5i<times.getLength:;5iBB; 8 )lement time":)lement;times.item:i;5 Eorecast forecast"new "orecast:;5
(9;
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
<
forecasts.add:forecast;5 forecast.setTime:time.get"irstChild:;.get%odeValue:;;5
/ode+ist temps"doc.get+lementsByTag%ame:#value#;5 for :int i"@5i<temps.getLength:;5iBB; 8 )lement temp":)lement;temps.item:i;5 Eorecast forecast"forecasts.get:i;5 forecast.setTemp:new Integer:temp.get"irstChild:;.get%odeValue:;;;5 < /ode+ist icons"doc.get+lementsByTag%ame:#icon(link#;5 for :int i"@5i<icons.getLength:;5iBB; 8 )lement icon":)lement;icons.item:i;5 Eorecast forecast"forecasts.get:i;5 < < forecast.setIcon:icon.get"irstChild:;.get%odeValue:;;5
in.close:;5
5he 0ational Weather #ervi%e EML $ormat is...%uriously stru%ture , relying heavily on se<uential position in lists versus the more obOe%t3oriente style you $in in $ormats like R## or Atom. 5hat being sai , Ce %an take a $eC liberties an simpli$y the parsing someChat, taking a vantage o$ the $a%t that the elements Ce Cant &start(valid(time $or the $ore%ast time, value $or the temperature, an icon(link $or the i%on "RL' are all uni<ue Cithin the o%ument. 5he )5ML %omes in as an .nputStream an is $e into the A>M parser. (rom there, Ce s%an $or the start(valid(time elements an populate a set o$ Eorecast mo els using those start times. 5hen, Ce $in the temperature value elements an icon(link "RLs an $ill those in to the Eorecast obOe%ts. .n turn, the %enerate1a%e:; metho %reates a ru imentary )5ML table Cith the $ore%asts*
Strin% generate&age:; 8 Strin%6uffer bufResult"new StringBuffer:#<$tml&<body&<table&#;5 bufResult.append:#<tr&<t$ widt$"4#L@[4#&-ime</t$&#B #<t$&-emperature</t$&<t$&Eorecast</t$&</tr&#;5
(9(
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
for :Eorecast forecast ! forecasts; 8 bufResult.append:#<tr&<td ali%n"4#center4#&#;5 bufResult.append:forecast.getTime:;;5 bufResult.append:#</td&<td ali%n"4#center4#&#;5 bufResult.append:forecast.getTemp:;;5 bufResult.append:#</td&<td&<im% src"4##;5 bufResult.append:forecast.getIcon:;;5 bufResult.append:#4#&</td&</tr&#;5 < bufResult.append:#</table&</body&</$tml&#;5 < return:bufResult.toString:;;5
Stu,, To Consider
.$ you nee to use ##L, bear in min that the e$ault )ttpClient setup oes not in%lu e ##L support. Mostly, this is be%ause you nee to e%i e hoC to han le ##L %erti$i%ate presentation N o you blin ly a%%ept all %erti$i%ates, even sel$3signe or e;pire onesD >r o you Cant to ask the user i$ they
(9%
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
really Cant to use some strange %erti$i%atesD 5he )ttpClient Web site has instru%tions $or a ing ##L support Cith various %erti$i%ate poli%ies to your proOe%t. #imilarly, )ttpClient, by e$ault, is esigne $or single3threa e use. .$ you Cill be using )ttpClient $rom a servi%e or some other pla%e Chere multiple threa s might be an issue, you %an rea ily set up )ttpClient to support multiple threa s N again, the )ttpClient Web site has the instru%tions.
message an %an pop up a QneC mail:Q 0oti$i%ation. While Ce %oul use +avaMail7s Messa%eCount+istener to more ire%tly ete%t neC messages, that assumes a %onstant .nternet %onne%tion, an that7s $ar $rom assure Cith a mobile evi%e. While this implementation is e%i e ly more %lunky, it shoul han le a greater range o$ real3Corl situations. 5he .MA! an !>!? logi% is en%apsulate in the MailClient %lass*
packa%e com.commonsware.android.service5 import import import import import import java.security.Security5 javax.mail.Eolder5 javax.mail.Messa%e5 javax.mail.Messa%in%)xception5 javax.mail.Session5 javax.mail.Store5
public class MailClient 8 public static Strin%OP get&O&0'essageIds:Strin% serverG Strin% userG Strin% pw; t$rows Messa%in%)xception 8 return:get'essageIds:#popI#G serverG userG pw;;5 < public static Strin%OP getI'#&'essageIds:Strin% serverG Strin% userG Strin% pw; t$rows Messa%in%)xception 8 return:get'essageIds:#imap#G serverG userG pw;;5 < private static Strin%OP get'essageIds:Strin% typeG Strin% serverG Strin% userG Strin% pw; t$rows Messa%in%)xception 8 Strin%OP result"null5 Session session"Session.getDefaultInstance:System.get&roperties:;;5 Store store"session.getStore:type;5 store.connect:serverG userG pw;5 try 8 Eolder folder"store.get"older:#./6,U#;5 folder.open:Eolder.R)AD*,/+F;5 try 8 Messa%eOP ms%s"folder.get'essages:;5 result"new Strin%Oms%s.len%t$P5 for :int i"@5i<ms%s.len%t$5iBB; 8 (9$
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
< < finally 8 folder.close:false;5 < < finally 8 store.close:;5 < return:result;5 < <
+avaMail oes a ni%e Oob o$ abstra%ting out the i$$eren%es betCeen the proto%ols, so Chile the publi% A!.s are %et1,1IMessa%e.ds:; an %et.MA1Messa%e.ds:;, the guts are %ontaine in a %ommon %etMessa%e.ds:; stati% metho , Chi%h takes the type &!>!? or .MA!', server, user, an passCor as parameters. 5he +avaMail pattern is* -. 8et a Session
2. 8et a Store o$ the spe%i$i% type an %onne%t to the server ?. 8et a%%ess to the proper mail Eolder, typi%ally ./6,U $or neC messages =. >pen the Eolder $or rea operations B. 8et the messages in the $ol er 4. .terate over the messages an get the Messa%e(.d hea er, i$ any, pouring the results into a Strin%OP Chi%h is returne to the overall %aller 2. Close the $ol er an e;%eption is raise store on the Cay ba%k out, or in %ase an
(9/
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
5his %o e, %ombine Cith the hooks to the +avaMail +ARs es%ribe in the pre%e ing %hapter, gives Mail/uKK a%%ess to the message .As o$ the messages in the inbo; o$ the user3supplie mail a%%ount.
(90
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
PART IV Intents
CHAPTER &1
"p to noC, the $o%us o$ this book has been on a%tivities opene ire%tly by the user $rom the evi%e7s laun%her. 5his, o$ %ourse, is the most obvious %ase $or getting your a%tivity up an visible to the user. An , in many %ases it is the primary Cay the user Cill start using your appli%ation. )oCever, remember that the An roi system is base upon lots o$ loosely3 %ouple %omponents. What you might a%%omplish in a esktop 8". via ialog bo;es, %hil Cin oCs, an the like are mostly suppose to be in epen ent a%tivities. While one a%tivity Cill be Qspe%ialQ, in that it shoCs up in the laun%her, the other a%tivities all nee to be rea%he ...somehoC. 5he QhoCQ is via intents. An intent is basi%ally a message that you pass to An roi saying, Q@o: . Cant to o...er...something: @eah:Q )oC spe%i$i% the QsomethingQ is epen s on the situation N sometimes you knoC e;a%tly Chat you Cant to o &e.g., open up one o$ your other a%tivities', an sometimes you on7t. .n the abstra%t, An roi is all about intents an re%eivers o$ those intents. #o, noC that Ce are Cell3verse in %reating a%tivities, let7s ive into intents, so Ce %an %reate more %omple; appli%ations Chile simultaneously being Qgoo An roi %itiKensQ.
(99
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
Pieces o, Intents
5he tCo most important pie%es o$ an intent are the a%tion an Chat An roi re$ers to as the Q ataQ. 5hese are almost e;a%tly analogous to )55! verbs an "RLs N the a%tion is the verb, an the Q ataQ is a 2ri, su%h as content!//contacts/people/? representing a %onta%t in the %onta%ts atabase. A%tions are %onstants, su%h as 7.)C*AC-.,/ &to bring up a vieCer $or the resour%e', )D.-*AC-.,/ &to e it the resour%e', or 1.CM*AC-.,/ &to %hoose an available item given a 2ri representing a %olle%tion, su%h as content!//contacts/people'. .$ you Cere to %reate an intent %ombining 7.)C*AC-.,/ Cith a %ontent "ri o$ an pass that intent to An roi , An roi Coul knoC to $in an open an a%tivity %apable o$ vieCing that resour%e.
content!//contacts/people/?,
5here are other %riteria you %an pla%e insi e an intent &represente as an .ntent obOe%t', besi es the a%tion an Q ataQ 2ri, su%h as*
%;;
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
A %ategory. @our QmainQ a%tivity Cill be in the +A2/C3)R %ategory, in i%ating it shoul shoC up on the laun%her menu. >ther a%tivities Cill probably be in the D)EA2+- or A+-)R/A-.7) %ategories. A M.MI type, in i%ating the type o$ resour%e you Cant to operate on, i$ you on7t knoC a %olle%tion 2ri. A %omponent, Chi%h is to say, the %lass o$ the a%tivity that is suppose to re%eive this intent. "sing %omponents this Cay obviates the nee $or the other properties o$ the intent. )oCever, it oes make the intent more $ragile, as it assumes spe%i$i% implementations. QI;trasQ, Chi%h is a 6undle o$ other in$ormation you Cant to pass along to the re%eiver Cith the intent, that the re%eiver might Cant to take a vantage o$. What pie%es o$ in$ormation a given re%eiver %an use is up to the re%eiver an &hope$ully' is Cell3 o%umente .
Stoc$ 0ptions
#ome o$ the a%tions e$ine as part o$ An roi $or laun%hing a%tivities are*
A/SC)R*AC-.,/ CA++*AC-.,/ D)+)-)*AC-.,/ D.A+*AC-.,/ )D.-*AC-.,/ EAC-,RF*-)S-*AC-.,/ 0)-*C,/-)/-*AC-.,/ ./S)R-*AC-.,/ MA./*AC-.,/ 1.CM*AC-.,/ 1.CM*AC-.7.-F*AC-.,/ R2/*AC-.,/ S)ARC3*AC-.,/ S)/D-,*AC-.,/ S)/D*AC-.,/
%;(
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
5he main ones you Cill use are MA./*AC-.,/ $or the main entry point o$ your appli%ation, 7.)C*AC-.,/ an )D.-*AC-.,/ $or vieCing an e iting %ontent, an 1.CM*AC-.,/ to alloC other appli%ations to sele%t an item $rom your %ontent. 0ote that there are also some a%tions spe%i$i%ally $or Qbroa %astQ intents N intents that %an be pi%ke up by many a%tivities or listeners, not Oust one. #imilarly, there are many other intent a%tions not aime at starting a%tivities, su%h as M)D.A*M,2/-)D*AC-.,/, in i%ating that a me ia %ar has been mounte in the system. #imilarly, here are the stan ar available %ategories &Cith D)EA2+-*CA-)0,RF an +A2/C3)R*CA-)0,RF being the ones you Cill use most'*
A+-)R/A-.7)*CA-)0,RF 6R,CSA6+)*CA-)0,RF D)EA2+-*CA-)0,RF 0AD0)-*CA-)0,RF 3,M)*CA-)0,RF +A2/C3)R*CA-)0,RF 1R)E)R)/C)*CA-)0,RF S)+)C-)D*A+-)R/A-.7)*CA-)0,RF -A6*CA-)0,RF -)S-*CA-)0,RF
Intent Routin!
As note above, i$ you spe%i$y the target %omponent in your intent, An roi has no oubt Chere the intent is suppose to be route to N it Cill laun%h the name a%tivity. 5his might be >F i$ the target intent is in your appli%ation. .t e$initely is not re%ommen e $or sen ing intents to other
%;%
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
appli%ations. Component names, by an large, are %onsi ere private to the appli%ation an are subOe%t to %hange. Content 2ri templates an M.MI types are the pre$erre Cays o$ i enti$ying servi%es you Cish thir 3party %o e to supply. .$ you o not spe%i$y the target %omponent, then An roi has to $igure out Chat a%tivities &or other intent re%eivers' are eligible to re%eive the intent. 0ote the use o$ the plural Qa%tivitiesQ, as a broa ly3Critten intent might Cell resolve to several a%tivities. 5hat is the...ummm...intent &par on the pun', as you Cill see later in this %hapter. 5his routing approa%h is re$erre to as impli%it routing. /asi%ally, there are three rules, all o$ Chi%h must be true $or a given a%tivity to be eligible $or a given intent* -. 5he a%tivity must support the spe%i$ie a%tion
2. 5he a%tivity must support the state M.MI type &i$ supplie ' ?. 5he a%tivity must support all o$ the %ategories name in the intent 5he upshot is that you Cant to make your intents spe%i$i% enough to $in the right re%eiver&s', an no more spe%i$i% than that. 5his Cill be%ome %learer as Ce Cork through some e;amples later in this %hapter.
%;,
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
<manifest xmlns!android"#$ttp!//sc$emas.android.com/apk/res/android# packa%e"#com.commonsware.android.prefs#& <application& <activity android!name"#.1refsDemo# android!label"#1refsDemo#& <intent(filter& <action android!name"#android.intent.action.MA./# /& <cate%ory android!name"#android.intent.cate%ory.+A2/C3)R# /& </intent(filter& </activity& </application& </manifest&
0ote the intent(filter element un er the a%tivity element. )ere, Ce e%lare that this a%tivity*
.s the main a%tivity $or this appli%ation .t is in the +A2/C3)R %ategory, meaning it gets an i%on in the An roi main menu
/e%ause this a%tivity is the main one $or the appli%ation, An roi knoCs this is the %omponent it shoul laun%h Chen somebo y %hooses the appli%ation $rom the main menu. 5he intent $ilter also has a label &android!label " #1refsDemo#'. .n this %ase, this %ontrols the name asso%iate Cith the appli%ation7s i%on in the main menu. @ou are Cel%ome to have more than one a%tion or more than one %ategory in your intent $ilters. 5hat in i%ates that the asso%iate %omponent &e.g., a%tivity' han les multiple i$$erent sorts o$ intents. More than likely, you Cill also Cant to have your se%on ary &non3MA./' a%tivities spe%i$y the M.MI type o$ ata they Cork on. 5hen, i$ an intent is targete $or that M.MI type N either ire%tly, or in ire%tly by the 2ri re$eren%ing something o$ that type N An roi Cill knoC that the %omponent han les su%h ata. (or e;ample, you %oul have an a%tivity e%lare like this*
%;$
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
<activity android!name"#.-our7iewActivity#& <intent(filter& <action android!name"#android.intent.action.7.)C# /& <cate%ory android!name"#android.intent.cate%ory.D)EA2+-# /& <data android!mime-ype"#vnd.android.cursor.item/vnd.commonsware.tour# /& </intent(filter& </activity&
5his a%tivity Cill get laun%he by an intent re<uesting to vieC a 2ri representing a vnd.android.cursor.item/vnd.commonsware.tour pie%e o$ %ontent. 5hat intent %oul %ome $rom another a%tivity in the same appli%ation &e.g., the MA.0 a%tivity $or this appli%ation' or $rom another a%tivity in another An roi appli%ation that happens to knoC a 2ri that this a%tivity han les.
5arro4 2eceivers
.n the e;amples shoCn above, the intent $ilters Cere set up on a%tivities. #ometimes, tying intents to a%tivities is not e;a%tly Chat Ce Cant*
#ome system events might %ause us to Cant to trigger something in a servi%e rather than an a%tivity #ome events might nee to laun%h i$$erent a%tivities in i$$erent %ir%umstan%es, Chere the %riteria are not solely base on the intent itsel$, but some other state &e.g., i$ Ce get intent E an the atabase has a @, then laun%h a%tivity MP i$ the atabase oes not have a @, then laun%h a%tivity 0'
(or these %ases, An roi o$$ers the intent re%eiver, e$ine as a %lass implementing the .ntentReceiver inter$a%e. .ntent re%eivers are isposable obOe%ts esigne to re%eive intents N parti%ularly broa %ast intents N an take a%tion, typi%ally involving laun%hing other intents to trigger logi% in an a%tivity, servi%e, or other %omponent. 5he .ntentReceiver inter$a%e has only one metho * onReceive.ntent:;. .ntent re%eivers implement that metho , Chere they o Chatever it is they Cish to o upon an in%oming intent. 5o e%lare an intent re%eiver, a an re%eiver element to your AndroidManifest.xml $ile*
%;/
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
An intent re%eiver is only alive $or as long as it takes to pro%ess onReceive.ntent:; N as soon as that metho returns, the re%eiver instan%e is subOe%t to garbage %olle%tion an Cill not be reuse . 5his means intent re%eivers are someChat limite in Chat they %an o, mostly to avoi anything that involves any sort o$ %allba%k. (or e;ample, they %annot bin to a servi%e, an they %annot open a ialog bo;. 5he e;%eption is i$ the .ntentReceiver is implemente on some longer3live %omponent, su%h as an a%tivity or servi%e N in that %ase, the intent re%eiver lives as long as its QhostQ oes &e.g., until the a%tivity is $roKen'. )oCever, in this %ase, you %annot e%lare the intent re%eiver via AndroidManifest.xml. .nstea , you nee to %all re%ister.ntent:; on your Activity7s onResume:; %allba%k to e%lare interest in an intent, then %all unre%ister.ntent:; $rom your Activity7s on1ause:; Chen you no longer nee those intents. @ou %an see an e;ample o$ an intent re%eiver in a%tion in the 5our.t sample appli%ation.
%;0
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
CHAPTER &&
As is%usse previously, the theory behin the An roi ". ar%hite%ture is that evelopers shoul e%ompose their appli%ation into istin%t a%tivities, ea%h implemente as an Activity, ea%h rea%hable via intents, Cith one QmainQ a%tivity being the one laun%he by the An roi laun%her. (or e;ample, a %alen ar appli%ation %oul have a%tivities $or vieCing the %alen ar, vieCing a single event, e iting an event &in%lu ing a ing a neC one', an so $orth. 5his, o$ %ourse, implies that one o$ your a%tivities has the means to start up another a%tivity. (or e;ample, i$ somebo y %li%ks on an event $rom the vieC3 %alen ar a%tivity, you might Cant to shoC the vieC3event a%tivity $or that event. 5his means that, somehoC, you nee to be able to %ause the vieC3 event a%tivity to laun%h an shoC a spe%i$i% event &the one the user %li%ke upon'. 5his %an be $urther broken oCn into tCo s%enarios* -. @ou knoC Chat a%tivity you Cant to laun%h, probably be%ause it is another a%tivity in your oCn appli%ation
2. @ou have a %ontent 2ri to...something, an you Cant your users to be able to o...something Cith it, but you o not knoC up $ront Chat the options are
%;3
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
5his %hapter %overs the $irst s%enarioP the ne;t %hapter han les the se%on .
%;7
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
% $e n Intent
As is%usse in a previous %hapter, intents en%apsulate a re<uest, ma e to An roi , $or some a%tivity or other intent re%eiver to o something. .$ the a%tivity you inten to laun%h is one o$ your oCn, you may $in it simplest to %reate an e;pli%it intent, naming the %omponent you Cish to laun%h. (or e;ample, $rom Cithin your a%tivity, you %oul %reate an intent like this*
new Intent:t$isG 3elpActivity.class;5
5his Coul stipulate that you Cante to laun%h the 3elpActivity. 5his a%tivity Coul nee to be name in your AndroidManifest.xml $ile, though not ne%essarily Cith any intent $ilter, sin%e you are trying to re<uest it ire%tly. >r, you %oul put together an intent $or some 2ri, re<uesting a parti%ular a%tion*
2ri uri"2ri.parse:#%eo!#Blat.toString:;B #G#Blon.toString:;;5 .ntent i"new Intent:.ntent.7.)C*AC-.,/G uri;5
)ere, given that Ce have the latitu e an longitu e o$ some position &lat an lon, respe%tively' o$ type Double, Ce %onstru%t a %eo s%heme 2ri an %reate an intent re<uesting to vieC this 2ri &7.)C*AC-.,/'.
% $e the C ll
>n%e you have your intent, you nee to pass it to An roi an get the %hil a%tivity to laun%h. @ou have $our %hoi%es* -. 5he simplest option is to %all startActivity:; Cith the intent N this Cill %ause An roi to $in the best3mat%h a%tivity or intent re%eiver an pass the intent to it $or han ling. @our a%tivity Cill not be in$orme Chen the 6%hil 9 a%tivity is %omplete.
%;9
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
2. @ou %an %all startSubActivity:;, passing it the intent an a number &uni<ue to the %alling a%tivity'. An roi Cill $in the best3mat%h han ler an pass the intent over to it. )oCever, your a%tivity Cill be noti$ie Chen the %hil a%tivity is %omplete via the onActivityResult:; %allba%k &see beloC'. ?. @ou %an %all broadcast.ntent:;. .n this %ase, An roi Cill pass the intent to all registere a%tivities an intent re%eivers that %oul possibly Cant this intent, not Oust the best mat%h. =. @ou %an %all broadcast.ntentSeriali'ed:;. )ere, An roi Cill pass the intent to all %an i ate a%tivities an intent re%eivers one at a time N i$ any one 6%onsumes9 the intent, the rest o$ the the %an i ates are not noti$ie . Most o$ the time, you Cill Cin up using startActivity:; or startSubActivity:; N broa %ast intents are more typi%ally raise by the An roi system itsel$. With
startSubActivity:;, onActivityResult:; %allba%k
as note , you %an implement the to be noti$ie Chen the %hil a%tivity has %omplete its Cork. 5he %allba%k re%eives the uni<ue number supplie to startSubActivity:;, so you %an etermine Chi%h %hil a%tivity is the one that has %omplete . @ou also get*
A result %o e, $rom the %hil a%tivity %alling setResult:;. 5ypi%ally this is R)S2+-*,M or R)S2+-*CA/C)++)D, though you %an %reate your oCn return %o es &pi%k a number starting Cith R)S2+-*E.RS-*2S)R' An optional Strin% %ontaining some result ata, possibly a "RL to some internal or e;ternal resour%e N $or e;ample, a 1.CM*AC-.,/ intent typi%ally returns the sele%te bit o$ %ontent via this ata string An optional 6undle %ontaining a result %o e an ata string itional in$ormation beyon the
5o emonstrate laun%hing a peer a%tivity, take a peek at the +aunc$ sample appli%ation. 5he EML layout is $airly straight$orCar * tCo $iel s $or the latitu e an longitu e, plus a button*
%(;
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
<>xml version"#?.@# encodin%"#utf(A#>& <+inear+ayout xmlns!android"#$ttp!//sc$emas.android.com/apk/res/android# android!orientation"#vertical# android!layout*widt$"#fill*parent# android!layout*$ei%$t"#fill*parent# & <-able+ayout android!layout*widt$"#fill*parent# android!layout*$ei%$t"#wrap*content# android!stretc$Columns"#?GH# & <-ableRow& <-ext7iew android!layout*widt$"#wrap*content# android!layout*$ei%$t"#wrap*content# android!paddin%+eft"#Hdip# android!paddin%Ri%$t"#Ndip# android!text"#+ocation!# /& <)dit-ext android!id"#9Bid/lat# android!layout*widt$"#fill*parent# android!layout*$ei%$t"#wrap*content# android!cursor7isible"#true# android!editable"#true# android!sin%le+ine"#true# android!layout*wei%$t"#?# /& <)dit-ext android!id"#9Bid/lon# android!layout*widt$"#fill*parent# android!layout*$ei%$t"#wrap*content# android!cursor7isible"#true# android!editable"#true# android!sin%le+ine"#true# android!layout*wei%$t"#?# /& </-ableRow& </-able+ayout& <6utton android!id"#9Bid/map# android!layout*widt$"#fill*parent# android!layout*$ei%$t"#wrap*content# android!text"#S$ow MeW# /& </+inear+ayout&
5he button7s ,nClick+istener simply takes the latitu e an longitu e, pours them into a %eo s%heme 2ri, then starts the a%tivity.
packa%e com.commonsware.android.activities5 import android.app.Activity5 import android.content..ntent5 import android.net.2ri5
%((
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
public class +aunc$Demo extends Activity 8 private )dit-ext lat5 private )dit-ext lon5 9,verride public void onCreate:6undle icicle; 8 super.onCreate:icicle;5 setContentView:R.layout.main;5 6utton btn":6utton;findViewById:R.id.map;5 lat":)dit-ext;findViewById:R.id.lat;5 lon":)dit-ext;findViewById:R.id.lon;5 btn.setOnClickListener:new 7iew.OnClickListener:; 8 public void onClick:7iew view; 8 Strin% *lat"lat.getText:;.toString:;5 Strin% *lon"lon.getText:;.toString:;5 2ri uri"2ri.parse:#%eo!#B*latB#G#B*lon;5 start#cti ity:new Intent:.ntent.7.)C*AC-.,/G uri;;5 < <;5 < <
%(%
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
.$ you $ill in a lo%ation &e.g., =0.2--42 latitu e an 32=.0-??? longitu e' an %li%k the button, the resulting map is more interesting. 0ote that this is the built3in An roi map a%tivity N Ce i not %reate our oCn a%tivity to isplay this map.
%(,
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
!igure /,< The map launched by aunch .emo6 sho4ing the region kno4n as ='round Jero= in 5e4 -ork City
.n a later %hapter, you Cill see hoC you %an %reate maps in your oCn a%tivities, in %ase you nee greater %ontrol over hoC the map is isplaye .
%($
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
CHAPTER &'
#ometimes, you knoC Oust Chat you Cant to o, su%h as isplay one o$ your other a%tivities. #ometimes, you have a pretty goo i ea o$ Chat you Cant to o, su%h as vieC the %ontent represente by a 2ri, or have the user pi%k a pie%e o$ %ontent o$ some M.MI type. #ometimes, you7re lost. All you have is a %ontent 2ri, an you on7t really knoC Chat you %an o Cith it. (or e;ample, suppose you Cere %reating a %ommon tagging subsystem $or An roi , Chere users %oul tag pie%es o$ %ontent N %onta%ts, Web "RLs, geographi% lo%ations, et%. @our subsystem Coul hol onto the 2ri o$ the %ontent plus the asso%iate tags, so other subsystems %oul , say, ask $or all pie%es o$ %ontent re$eren%ing some tag. 5hat7s all Cell an goo . )oCever, you probably nee some sort o$ maintenan%e a%tivity, Chere users %oul vieC all their tags an the pie%es o$ %ontent so tagge . 5his might even serve as a <uasi3bookmark servi%e $or items on their phone. 5he problem is, the user is going to e;pe%t to be able to o use$ul things Cith the %ontent they $in in your subsystem, su%h as ial a %onta%t or shoC a map $or a lo%ation.
%(/
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
5he problem is, you have absolutely no i ea Chat is all possible Cith any given %ontent 2ri. @ou probably %an vieC any o$ them, but %an you e it themD Can you ial themD #in%e neC appli%ations Cith neC types o$ %ontent %oul be a e by any user at any time, you %an7t even assume you knoC all possible %ombinations Oust by looking at the sto%k appli%ations shippe on all An roi evi%es. (ortunately, the An roi evelopers thought o$ this.
An roi o$$ers various means by Chi%h you %an present to your users a set o$ likely a%tivities to spaCn $or a given %ontent 2ri...even i$ you have no i ea Chat that %ontent 2ri really represents. 5his %hapter e;plores some o$ these 2ri a%tion introspe%tion tools.
Pick AEm
#ometimes, you knoC your %ontent 2ri represents a %olle%tion o$ some type, su%h as content!//contacts/people representing the list o$ %onta%ts in the sto%k An roi %onta%ts list. .n this %ase, you %an let the user pi%k a %onta%t that your a%tivity %an then use &e.g., tag it, ial it'. 5o o this, you nee to %reate an intent $or the 1.CM*AC-.7.-F*AC-.,/ on the target 2ri, then start a sub a%tivity &via startSubActivity:;' to alloC the user to pi%k a pie%e o$ %ontent o$ the spe%i$ie type. .$ your onActivityResult:; %allba%k $or this re<uest gets a R)S2+-*,M result %o e, your ata string %an be parse into a 2ri representing the %hosen pie%e o$ %ontent. (or e;ample, take a look at 1ick in the sample appli%ations. 5his a%tivity gives you a $iel $or a %olle%tion 2ri &Cith content!//contacts/people pre3 $ille in $or your %onvenien%e', plus a really big 68imme:9 button*
<>xml version"#?.@# encodin%"#utf(A#>& <+inear+ayout xmlns!android"#$ttp!//sc$emas.android.com/apk/res/android# android!orientation"#vertical# android!layout*widt$"#fill*parent# android!layout*$ei%$t"#fill*parent# & <)dit-ext android!id"#9Bid/type#
%(0
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
"pon being %li%ke , the button %reates the 1.CM*AC-.7.-F*AC-.,/ on the user3supplie %olle%tion 2ri an starts the sub3a%tivity. When that sub3 a%tivity %ompletes Cith R)S2+-*,M, the 7.)C*AC-.,/ is invoke on the resulting %ontent 2ri.
packa%e com.commonsware.android.introspection5 import import import import import import import android.app.Activity5 android.content..ntent5 android.net.2ri5 android.os.6undle5 android.view.7iew5 android.wid%et.6utton5 android.wid%et.)dit-ext5
public class 1ickDemo extends Activity 8 static final int 1.CM*R)T2)S- " ?II]5 private )dit-ext type5 9,verride public void onCreate:6undle icicle; 8 super.onCreate:icicle;5 setContentView:R.layout.main;5 type":)dit-ext;findViewById:R.id.type;5 6utton btn":6utton;findViewById:R.id.pick;5 btn.setOnClickListener:new 7iew.OnClickListener:; 8 public void onClick:7iew view; 8 .ntent i"new Intent:.ntent.1.CM*AC-.,/G 2ri.parse:type.getText:;.toString:;;;5 < startSu!#cti ity:iG 1.CM*R)T2)S-;5
%(3
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
<;5 < protected void on#cti ity$esult:int reJuestCodeG int resultCodeG Strin% dataG 6undle extras; 8 if :reJuestCode""1.CM*R)T2)S-; 8 if :resultCode""R)S2+-*,M; 8 start#cti ity:new Intent:.ntent.7.)C*AC-.,/G 2ri.parse:data;;;5 < < <
<
5he result* the user %hooses a %olle%tion, pi%ks a pie%e o$ %ontent, an vieCs it.
%(7
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
!igure //< The same application6 after clicking the ='imme!= button6 sho4ing the list of available people
!igure /0< ) vie4 of a contact6 launched by Pick.emo after choosing one of the people from the pick list
%(9
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
>ne $laC in this appli%ation is that it may not have permission to vieC Chatever %ontent %olle%tion the user entere . (or the sample, Ce ha to spe%i$i%ally re<uest permission to rea the user7s %onta%ts, via a uses3 permission element in AndroidManifest.xml. We7ll %over more about re<uesting &an re<uiring' permissions later in this book.
)daptable )dapters
>ne Cay to present your users Cith available a%tions to take on a pie%e o$ %ontent is to use ActivityAdapter or Activity.conAdapter. 5hese are +istAdapter sub%lasses, meaning they supply %hil vieCs to sele%tion Ci gets like +ist7iew an Spinner. .n this %ase, they supply a list o$ available a%tions to take on the %ontent N an $or Activity.conAdapter, it in%lu es both a name &e.g., 6I it Conta%t9' an an i%on asso%iate Cith the a%tion. >n%e a user has %hosen an a%tion N $or e;ample, by %li%king on a list item N you %an get the intent that %ombines the %hosen a%tion Cith the %ontent 2ri o$ the pie%e o$ %ontent. 5hat intent %an be ire%tly passe to startActivity:; to take the user to the a%tivity they re<ueste . All Cithout you having to knoC anything about Chat the %ontent is. >ne %on$using $a%et o$ ActivityAdapter an Activity.conAdapter is that they take an .ntent, not a 2ri, on their %onstru%tor. 5his means you nee to Crap the 2ri $or the %ontent in an otherCise3empty .ntent in or er to satis$y the %onstru%tor7s re<uest*
.ntent i"new Intent:;5 i.setData:2ri.parse:data;;5 +istAdapter adapter"new #cti ity#dapter:t$isG i;5
#o, let7s embellish the previous e;ample N %opie into Adapter N to give the user some %hoi%es $or Chat to o Cith the pi%ke pie%e o$ %ontent, rather than alCays Oust vieCing it as be$ore. 5he layout noC a s a +ist7iew, to shoC the available a%tions*
%%;
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
<>xml version"#?.@# encodin%"#utf(A#>& <+inear+ayout xmlns!android"#$ttp!//sc$emas.android.com/apk/res/android# android!orientation"#vertical# android!layout*widt$"#fill*parent# android!layout*$ei%$t"#fill*parent# & <)dit-ext android!id"#9Bid/type# android!layout*widt$"#fill*parent# android!layout*$ei%$t"#wrap*content# android!cursor7isible"#true# android!editable"#true# android!sin%le+ine"#true# android!text"#content!//contacts/people# /& <6utton android!id"#9Bid/pick# android!layout*widt$"#fill*parent# android!layout*$ei%$t"#wrap*content# android!text"#0immeW# /& <+ist7iew android!id"#9android!id/list# android!layout*widt$"#fill*parent# android!layout*$ei%$t"#fill*parent# android!drawSelector,n-op"#false# android!layout*wei%$t"#?# /& </+inear+ayout&
%%(
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
!igure /7< The same application6 after clicking ='imme!= and choosing a person
0ote that, at the time o$ this Criting, An roi oes not $ilter the available a%tions to only be the ones that are possible $rom the a%tivity N it shoCs them all. )en%e, the user is given a%tion options that may not be alloCe
%%%
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
ue to insu$$i%ient permissions. .$ you run the supplie sample %o e Cithout mo i$i%ations, you Cill be able to vieC a %hosen %onta%t, but not e it them, $or e;ample.
%%,
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
.$ you Cant to Crite a%tivities that are aCare o$ possible a 3ons like tagging, you shoul use add.ntent,ptions:; to a those a 3ons7 a%tions to your options menu, su%h as the $olloCing*
.ntent intent " new Intent:nullG myContent2ri;5 intent.addCategory:.ntent.A+-)R/A-.7)*CA-)0,RF;5 menu.addIntentOptions:Menu.A+-)R/A-.7)G @G new Component%ame:t$isG MyActivity.class;G nullG intentG @G null;5
)ere, myContent2ri is the %ontent 2ri o$ Chatever is being vieCe by the user in this a%tivity, MyActivity is the name o$ the a%tivity %lass, an menu is the menu being mo i$ie . .n this %ase, the .ntent Ce are using to pi%k a%tions $rom re<uires that appropriate intent re%eivers support the A+-)R/A-.7)*CA-)0,RF. 5hen, Ce a the options to the menu Cith add.ntent,ptions:; an the $olloCing parameters*
5he sort position $or this set o$ menu %hoi%es, typi%ally set to @ &appear in the or er a e to the menu' or A+-)R/A-.7) &appear a$ter other menu %hoi%es' A uni<ue number $or this set o$ menu %hoi%es, or @ i$ you o not nee a number A Component/ame instan%e representing the a%tivity that is populating its menu N this is use to $ilter out the a%tivity7s oCn a%tions, so the a%tivity %an han le its oCn a%tions as it sees $it An array o$ .ntent instan%es that are the 6spe%i$i%9 mat%hes N any a%tions mat%hing those intents are shoCn $irst in the menu be$ore any other possible a%tions 5he .ntent $or Chi%h you Cant the available a%tions
%%$
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
A set o$ $lags. 5he only one o$ likely relevan%e is represente as MA-C3*D)EA2+-*,/+F, Chi%h means mat%hing a%tions must also implement the D)EA2+-*CA-)0,RF %ategory. .$ you o not nee this, use a value o$ @ $or the $lags. An array o$ Menu..tem, Chi%h Cill hol the menu items mat%hing the array o$ .ntent instan%es supplie as the 6spe%i$i%s9, or null i$ you o not nee those items &or are not using 6spe%i$i%s9'
)sking )round
/oth the ActivityAdapter $amily an add.ntent,ptions:; use Juery.ntentActivity,ptions:; $or the 6heavy li$ting9 o$ $in ing possible a%tions. 5he Juery.ntentActivity,ptions:; metho is implemente on 1acka%eMana%er, Chi%h is available to your a%tivity via %et1acka%eMana%er:;. 5he Juery.ntentActivity,ptions:; metho takes some o$ the same parameters as oes add.ntent,ptions:;, notably the %aller Component/ame, the 6spe%i$i%s9 array o$ .ntent instan%es, the overall .ntent representing the a%tions you are seeking, an the set o$ $lags. .t returns a +ist o$ .ntent instan%es mat%hing the state %riteria, Cith the 6spe%i$i%s9 ones $irst. .$ you Coul like to o$$er alternative a%tions to users, but by means other than the ActivityAdapter an add.ntent,ptions:; means, you %oul %all Juery.ntentActivity,ptions:;, get the .ntent instan%es, then use them to populate some other user inter$a%e &e.g., a toolbar'.
%%/
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
CHAPTER &(
Any 2ri in An roi that begins Cith the content!// s%heme represents a resour%e serve up by a %ontent provi er. Content provi ers o$$er ata en%apsulation using 2ri instan%es as han les N you neither knoC nor %are Chere the ata represente by the 2ri %omes $rom, so long as it is available to you Chen nee e . 5he ata %oul be store in a #HLite atabase, or in $lat $iles, or retrieve o$$ a evi%e, or be store on some $ar3o$$ server a%%esse over the .nternet. 8iven a 2ri, you %an per$orm basi% CR"A &%reate, rea , up ate, elete' operations using a %ontent provi er. 2ri instan%es %an represent either %olle%tions or in ivi ual pie%es o$ %ontent. 8iven a %olle%tion 2ri, you %an %reate neC pie%es o$ %ontent via insert operations. 8iven an instan%e 2ri, you %an rea ata represente by the 2ri, up ate that ata, or elete the instan%e outright. An roi lets you use e;isting %ontent provi ers, plus %reate your oCn. 5his %hapter %overs using %ontent provi ersP the ne;t %hapter Cill e;plain hoC you %an serve up your oCn ata using the %ontent provi er $rameCork.
Pieces of *e
5he simpli$ie mo el o$ the %onstru%tion o$ a %ontent 2ri is the s%heme, the namespa%e o$ ata, an , optionally, the instan%e i enti$ier, all separate by
%%9
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
slashes in "RL3style notation. 5he s%heme o$ a %ontent "ri is alCays content!//. #o, a %ontent 2ri o$ content!//tours/L represents the tours instan%e Cith an i enti$ier o$ L. 5he %ombination o$ the s%heme an the namespa%e is knoCn as the 6base "ri9 o$ a %ontent provi er, or a set o$ ata supporte by a %ontent provi er. .n the e;ample above, content!//tours is the base 2ri $or a %ontent provi er that serves up in$ormation about 6tours9 &in this %ase, bi%y%le tours $rom the 5our.t sample appli%ation'. 5he base 2ri %an be more %ompli%ate . (or e;ample, the base 2ri $or %onta%ts is content!//contacts/people, as the %onta%ts %ontent provi er may serve up other ata using other base 2ri values. 5he base 2ri represents a %olle%tion o$ instan%es. 5he base 2ri %ombine Cith an instan%e i enti$ier &e.g., B' represents a single instan%e. Most o$ the An roi A!.s e;pe%t these to be 2ri obOe%ts, though in %ommon is%ussion, it is simpler to think o$ them as strings. 5he 2ri.parse:; stati% metho %reates a 2ri out o$ the string representation.
'etting a Dandle
#o, Chere o these 2ri instan%es %ome $romD 5he most popular starting point, i$ you knoC the type o$ ata you Cant to Cork Cith, is to get the base 2ri $rom the %ontent provi er itsel$ in %o e. (or e;ample, android.provider.C,/-)/-*2R. is the base 2ri $or %onta%ts represente as people N this maps to content!//contacts/people. .$ you Oust nee the %olle%tion, this 2ri Corks as3isP i$ you nee an instan%e an knoC its i enti$ier, you %an %all add.d:; on the 2ri to inOe%t it, so you have a 2ri $or the instan%e.
%,;
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
@ou might also get 2ri instan%es han e to you $rom other sour%es. .n the pre%e ing %hapter, Ce saC hoC you got 2ri han les $or %onta%ts via sub3 a%tivities respon ing to 1.CM*AC-.,/ intents. .n this %ase, the 2ri is truly an opa<ue han le...unless you e%i e to pi%k it apart using the various getters on the 2ri %lass. @ou %an also har 3Cire literal Strin% obOe%ts an %onvert them into 2ri instan%es via 2ri.parse:;. (or e;ample, in the pre%e ing %hapter, the sample %o e use an )dit7iew Cith content!//contacts/people pre3$ille in. 5his isn7t an i eal solution, as the base 2ri values %oul %on%eivably %hange over time.
*akinA Fueries
8iven a base 2ri, you %an run a <uery to return ata out o$ the %ontent provi er relate to that 2ri. 5his has mu%h o$ the $eel o$ #HL* you spe%i$y the 6%olumns9 to return, the %onstraints to etermine Chi%h 6roCs9 to return, a sort or er, et%. 5he i$$eren%e is that this re<uest is being ma e o$ a %ontent provi er, not ire%tly o$ some atabase &e.g., #HLite'. 5he ne;us o$ this is the mana%edTuery:; metho available to your a%tivity. 5his metho takes $ive parameters* -. 5he base 2ri o$ the %ontent provi er to <uery, or the instan%e 2ri o$ a spe%i$i% obOe%t to <uery
2. An array o$ properties o$ instan%es $rom that %ontent provi er that you Cant returne by the <uery ?. A %onstraint statement, $un%tioning like a #HL C3)R) %lause =. An optional set o$ parameters to bin repla%ing any > that appear there into the %onstraint %lause,
B. An optional sort statement, $un%tioning like a #HL ,RD)R 6F %lause 5his metho returns a Cursor obOe%t, Chi%h you %an use to retrieve the ata returne by the <uery.
%,(
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
6!roperties9 is to %ontent provi ers as %olumns are to atabases. .n other Cor s, ea%h instan%e &roC' returne by a <uery %onsists o$ a set o$ properties &%olumns', ea%h representing some pie%e o$ ata. 5his Cill hope$ully make more sense given an e;ample. >ur %ontent provi er e;amples %ome $rom the 5our.t sample appli%ation, as es%ribe in Appen i; A. #pe%i$i%ally, the $olloCing %o e $ragment is $rom the -our7iewActivity, Chi%h shoCs the %ue sheet $or a sele%te bi%y%le tour*
try 8 if :c""null; 8 c"managed.uery:getIntent:;.getData:;G -our.1R,=)C-.,/G nullG nullG null;5 < else 8 c.re-uery:;5 < c.first:;5 tour"new Tour:getIntent:;.getData:;G c;5 int sel"getSelectedItem&osition:;5 setList#dapter:new $oute#dapter:tourG t$is;;5 setSelection:sel;5 setTitle:#-our.tW ( #Btour.getTitle:;;5
5he 2ri passe into the a%tivity by the %aller &%et.ntent:;.%etData:;', in this %ase representing a spe%i$i% bi%y%le tour, provi e to -our7iewActivity $rom the invoking a%tivity &-our+istActivity' A list o$ properties to retrieve, supplie to us by our -our mo el %lass &1R,=)C-.,/' 5hree null values, in i%ating that Ce o not nee a %onstraint %lause &the 2ri represents the instan%e Ce nee ', nor parameters $or the %onstraint, nor a sort or er &Ce shoul only get one entry ba%k'
%,%
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
5he biggest 6magi%9 here is the list o$ properties. 5he lineup o$ Chat properties are possible $or a given %ontent provi er shoul be provi e by the o%umentation &or sour%e %o e' $or the %ontent provi er itsel$. .n this %ase, Ce elegate to the -our mo el %lass the responsibility o$ telling us Chi%h properties it nee s to $ully represent the obOe%t*
class -our 8 public static final Strin%OP 1R,=)C-.,/ " new Strin%OP 8 1rovider.-ours..DG 1rovider.-ours.-.-+)G 1rovider.-ours.D)SCR.1-.,/G 1rovider.-ours.CR)A-)D*DA-)G 1rovider.-ours.M,D.E.)D*DA-)G 1rovider.-ours.R,2-)<5
5he proOe%tion is simply an array o$ strings, listing properties e;pose by the tour %ontent provi er &1rovider'. 5he tour %ontent provi er, in turn, simply provi es values $or these symboli% names*
public public public public public static static static static static final final final final final Strin% Strin% Strin% Strin% Strin% -.-+)"#title#5 D)SCR.1-.,/"#desc#5 CR)A-)D*DA-)"#created#5 M,D.E.)D*DA-)"#modified#5 R,2-)"#route#5
#o, Chen the -our7iewActivity invokes the <uery an gets the Cursor, it has the ata ne%essary to %reate the %orrespon ing -our mo el, via ata it is retrieving $rom the tour %ontent provi er.
SimpleCursorAdapter,
han the a apter o$$ to the Ci get, an you7re set N your Ci get Cill shoC the available options. (or e;ample, here is a $ragment o$ the onCreate:; metho -our+istActivity, Chi%h gives the user a list o$ tours to %hoose $rom* $rom
toursCursor " managed.uery:getIntent:;.getData:;G 1R,=)C-.,/G nullG nullG null;5 list":+ist7iew;findViewById:android.R.id.list;5 list.setOnItemClickListener:t$is;5 +istAdapter adapter " new SimpleCursor#dapter:t$isG R.layout.tourlist*itemG toursCursorG new Strin%OP 81rovider.-ours.-.-+)<G new intOP 8android.R.id.text?<;5 list.set#dapter:adapter;5
A$ter e;e%uting the mana%edTuery:; an getting the Cursor, -our+istActivity %reates a SimpleCursorAdapter Cith the $olloCing parameters*
5he a%tivity &or other Context' %reating the a apterP in this %ase, the -our+istActivity itsel$ 5he i enti$ier $or a layout to be use $or ren ering the list entries &R.layout.tourlist*item' 5he %ursor &toursCursor' 5he properties to pull out o$ the %ursor an use $or %on$iguring the list entry ,ieC instan%es &-.-+)' 5he %orrespon ing i enti$iers o$ -ext7iew Ci gets in the list entry layout that those properties shoul go into &android.R.id.text?'
%,$
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
.$ you nee more %ontrol over the vieCs than you %an reasonably a%hieve Cith the sto%k vieC %onstru%tion logi%, sub%lass SimpleCursorAdapter an overri e %et7iew:; to %reate your oCn Ci gets to go into the list, as emonstrate earlier in this book.
.oing 8t By Dand
>$ %ourse, you %an alCays o it the 6har Cay9 N pulling ata out o$ the Cursor by han . 5he Cursor inter$a%e is similar in %on%ept to other atabase a%%ess A!.s o$$ering %ursors as obOe%ts, though, as alCays, the evil is in the etails.
Position
instan%es have a built3in notion o$ position, akin to the +ava .terator inter$a%e. 5o get to the various roCs, you %an use*
Cursor first:; to move to the $irst roC in the result set or last:; to move to the last roC in the result set
%,/
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
to move to the ne;t roC an etermine i$ there is yet another roC to pro%ess &next:; returns true i$ it points to another roC a$ter moving, false otherCise'
next:; prev:; to move to the previous roC, as the opposite to next:; move-o:; to move to a spe%i$i% in e;, or move:; to move to a relative position plus or minus $rom your %urrent position position:; to return your %urrent in
e;
a Chole host o$ %on ition metho s, in%lu ing isEirst:;, is+ast:;, is6eforeEirst:;, an isAfter+ast:;
Gettin! Properties
>n%e you have the Cursor positione at a roC o$ interest, you have a variety o$ metho s to retrieve properties $rom that roC, Cith i$$erent metho s supporting i$$erent types &%etStrin%:;, %et.nt:;, %etEloat:;, et%.'. Ia%h metho takes the Kero3base in e; o$ the property you Cant to retrieve. .$ you Cant to see i$ a given property has a value, you %an use is/ull:; to test it $or null3ness. #o, as an e;ample, let7s e;amine hoC the -our mo el %lass a%%esses its Cursor. 5he un erlying assumption o$ the -our is that it is provi e a Cursor Cith only one roC, an that Cursor Cill remain pointe to that roC $or the li$espan o$ the -our instan%e. .$ this Cere a publi% inter$a%e, this approa%h Coul be s%ary, as Cursor obOe%ts are mutable. /ut, sin%e the -our mo el is use only Cithin a $airly small appli%ation, the assumptions regar ing the -our7s Cursor are probably sa$e. 5hat being sai , here are some %ursor3Crapping a%%essors $rom -our*
Strin% getTitle:; 8 return:c.getString:?;;5 < void setTitle:Strin% title; 8 c.updateString:?G title;5 <
%,0
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
Rather than %opying properties into lo%al $iel s, the -our simply hol s onto the Cursor. )en%e, %et-itle:; retrieves the property value at in e; ?, an so $orth. 5he e;%eption is the route &Caypoints an ire%tions', Chi%h is represente in the atabase as a path to a $ile in +#>0 $ormat N $or this, the -our parses the +#>0 an populates Caypoint an Direction mo el obOe%ts.
Settin! Properties
instan%es not only let you rea ata, but %hange it as Cell. #imply use the setters &e.g., putStrin%:;, put.nt:;', supplying the in e; o$ the property to alter an the neC value $or that property.
Cursor
.nitially, those %hanges are Oust in the Cursor itsel$. 5o %ommit those %hanges to the %ontent provi er, you nee to %all commit2pdates:;, Chi%h pa%kages up the %hange&s' to your roC&s'. At this point, though, your Cursor is stale N the %ontent provi er might alter the ata you supplie to $it some %ontent3spe%i$i% %onventions &e.g., roun ing o$ $loats, trun%ating strings'. .$ you are going to %ontinue using the Cursor, you shoul %all reJuery:; on the Cursor to re3e;e%ute the original <uery an thereby 6re$resh9 the Cursor7s ren ition o$ the ata. #o, to re%ap, the $loC is*
Call setters to make %hanges Call commit2pdates:; to persist the %hanges Call reJuery:; to re$resh the Cursor i$ you Cill %ontinue using it
@ou o not ne%essarily nee a Cursor to make %hanges, though. @ou %an also %all update:; on a ContentResolver &usually obtaine by an a%tivity via %etContentResolver:;'. 5his Corks akin to a #HL 21DA-) statement an takes $our parameters*
A 2ri representing the %olle%tion &or instan%e' you Cish to up ate A Content7alues &Map3like %olle%tion' instan%e representing the properties you Cish to %hange
%,3
A %onstraint statement, $un%tioning like a #HL C3)R) %lause, to etermine Chi%h roCs shoul be up ate An optional set o$ parameters to bin repla%ing any > that appear there into the %onstraint %lause,
As Cith a #HL 21DA-) statement, update:; %oul a$$e%t Kero to several roCs, as etermine by the %onstraint statement an parameters.
2. "se bulk.nsert:; Cith a %olle%tion 2ri an an array o$ Content7alues stru%tures to populate several roCs at on%e 5he insert:; metho returns a 2ri $or you to use $or $uture operations on that neC obOe%t. 5he bulk.nsert:; metho returns the number o$ %reate roCsP you Coul nee to o a <uery to get ba%k at the ata you Oust inserte . (or e;ample, here is a snippet o$ %o e $rom -our)ditActivity to insert a neC tour into the %ontent provi er*
if :tour""null; 8 Content7alues values"new ContentValues:;5 values.put:1rovider.-ours.-.-+)G tour.getTitle:;;5 2ri url"getContent$esol er:;.insert:1rovider.-ours.C,/-)/-*2R.G values;5 c"managed.uery:urlG -our.1R,=)C-.,/G nullG null;5
%,7
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
c.first:;5 try 8 tour"new Tour:urlG c;5 < catc$ :-$rowable t; 8 android.util.+o%.e:#-our.t#G #)xception creatin% tour#G t;5 -oast.makeText:t$isG R.strin%.save*failedG H@@@;.show:;5 return5 <
<
.n this %ase, all Ce o is populate the title. #in%e Ce get a 2ri ba%k, Ce %an turn aroun an get a Cursor on that 2ri &via mana%edTuery:uriG 1R,=)C-.,/G nullG null;' an reuse our e;isting up ate logi% to a in any a itional ata beyon the title itsel$. 5o elete one or more roCs $rom the %ontent provi er, use the delete:; metho on ContentResolver. 5his Corks akin to a #HL D)+)-) statement an takes three parameters* -. A 2ri representing the %olle%tion &or instan%e' you Cish to up ate
2. A %onstraint statement, $un%tioning like a #HL C3)R) %lause, to etermine Chi%h roCs shoul be up ate ?. An optional set o$ parameters to bin repla%ing any > that appear there into the %onstraint %lause,
5he .ma%e7iew Ci get %an o Oust that, via a %ontent 2ri to a +!I8. /y storing the photo in a manner that has its oCn 2ri, you o not nee to %opy ata out o$ the %ontent provi er into some temporary hol ing area Oust to be able to isplay it N Oust use the 2ri. 5he e;pe%tation, presumably, is that $eC An roi appli%ations Cill o mu%h more than uploa binary ata an use Ci gets or built3in a%tivities to isplay that ata.
%$;
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
CHAPTER &)
/uil ing a %ontent provi er is probably the most %ompli%ate an te ious task in all o$ An roi evelopment. 5here are many re<uirements o$ a %ontent provi er, in terms o$ metho s to implement an publi% ata members to supply. An , until you try using it, you have no great Cay o$ telling i$ you i any o$ it %orre%tly &versus, say, buil ing an a%tivity an getting vali ation errors $rom the resour%e %ompiler'. 5hat being sai , buil ing a %ontent provi er is o$ huge importan%e i$ your appli%ation Cishes to make ata available to other appli%ations. .$ your appli%ation is keeping its ata solely to itsel$, you may be able to avoi %reating a %ontent provi er, Oust a%%essing the ata ire%tly $rom your a%tivities. /ut, i$ you Cant your ata to possibly be use by others N $or e;ample, you are buil ing a $ee rea er an you Cant other programs to be able to a%%ess the $ee s you are oCnloa ing an %a%hing N then a %ontent provi er is right $or you.
%$(
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
When buil ing a %ontent provi er, though, you nee to knoC a bit more about the innar s o$ the %ontent 2ri. A %ontent 2ri has tCo to $our pie%es, epen ing on situation*
.t alCays has a s%heme &content!//', in i%ating it is a %ontent 2ri instea o$ a 2ri to a Web resour%e &$ttp!//'. .t alCays has an authority, Chi%h is the $irst path segment a$ter the s%heme. 5he authority is a uni<ue string i enti$ying the %ontent provi er that han les the %ontent asso%iate Cith this 2ri. .t may have a ata type path, Chi%h is the list o$ path segments a$ter the authority an be$ore the instan%e i enti$ier &i$ any'. 5he ata type path %an be empty, i$ the %ontent provi er only han les one type o$ %ontent. .t %an be a single path segment &foo' or a %hain o$ path segments &foo/bar/%oo' as nee e to han le Chatever ata a%%ess s%enarios the %ontent provi er re<uires. .t may have an instan%e i enti$ier, Chi%h is an integer i enti$ying a spe%i$i% pie%e o$ %ontent. A %ontent 2ri Cithout an instan%e i enti$ier re$ers to the %olle%tion o$ %ontent represente by the authority &an , Chere provi e , the ata path'.
(or e;ample, a %ontent 2ri %oul be as simple as content!//sekrits, Chi%h Coul re$er to the %olle%tion o$ %ontent hel by Chatever %ontent provi er Cas tie to the sekrits authority &e.g., Secrets1rovider'. >r, it %oul be as %omple; as content!//sekrits/card/pin/?], Chi%h Coul re$er to a pie%e o$ %ontent &i enti$ie as ?]' manage by the sekrits %ontent provi er that is o$ the ata type card/pin.
types. >ne M.MI type Cill represent the %olle%tionP the other Cill represent an instan%e. 5hese map to the 2ri patterns above $or no3i enti$ier an i enti$ier, respe%tively. As you saC earlier in this book, you %an $ill in a M.MI type into an .ntent to route the .ntent to the proper a%tivity &e.g., 1.CM*AC-.,/ on a %olle%tion M.MI type to %all up a sele%tion a%tivity to pi%k an instan%e out o$ that %olle%tion'. 5he %olle%tion M.MI type shoul be o$ the $orm vnd.U.cursor.dir/F, Chere U is the name o$ your $irm, organiKation, or proOe%t, an F is a ot3 elimite type name. #o, $or e;ample, you might use vnd.tla%ency.cursor.dir/sekrits.card.pin as the M.MI type $or your %olle%tion o$ se%rets. 5he instan%e M.MI type shoul be o$ the $orm vnd.U.cursor.item/F, usually $or the same values o$ U an F as you use $or the %olle%tion M.MI type &though that is not stri%tly re<uire '.
ContentProvider
.$ you implement a sub%lass o$ Content1rovider, you are responsible $or implementing si; metho s that, Chen %ombine , per$orm the servi%es that a %ontent provi er is suppose to o$$er to a%tivities Cishing to %reate, rea , up ate, or elete %ontent.
%$,
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
onCreate&'
As Cith an a%tivity, the main entry point to a %ontent provi er is onCreate:;. )ere, you %an o Chatever initialiKation you Cant. .n parti%ular, here is Chere you shoul laKy3initialiKe your ata store. (or e;ample, i$ you plan on storing your ata in su%h3an 3so ire%tory on an #A %ar , Cith an EML $ile serving as a Qtable o$ %ontentsQ, you shoul %he%k an see i$ that ire%tory an EML $ile are there an , i$ not, %reate them so the rest o$ your %ontent provi er knoCs they are out there an available $or use. #imilarly, i$ you have reCritten your %ontent provi er su$$i%iently to %ause the ata store to shi$t stru%ture, you shoul %he%k to see Chat stru%ture you have noC an a Oust it i$ Chat you have is out o$ ate. @ou on7t Crite your oCn QinstallerQ program an so have no great Cay o$ etermining i$, Chen onCreate:; is %alle , i$ this is the $irst time ever $or the %ontent provi er, the $irst time $or a neC release o$ a %ontent provi er that Cas upgra e in3pla%e, or i$ this is Oust a normal startup. .$ your %ontent provi er uses #HLite $or storage, an you are not using DatabaseContent1rovider, you %an ete%t to see i$ your tables e;ist by <uerying on the sJlite*master table. 5his is use$ul $or laKy3%reating a table your %ontent provi er Cill nee . (or e;ample, here is the onCreate:; metho $or 1rovider, $rom the 5our.t sample appli%ation*
9,verride public boolean onCreate:; 8 db":new Data!ase(elper:;;.openData!ase:getContext:;G getD!%ame:;G nullG getD!Version:;;5 < return :db "" null; > false ! true5
While that
Database3elper obOe%t*
private class Database3elper extends ST+ite,pen3elper 8 9,verride
%$$
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
public void onCreate:ST+iteDatabase db; 8 Cursor c"db.raw.uery:#S)+)C- name ER,M sJlite*master C3)R) type"ZtableZ A/D name"ZtoursZ#G null;5 try 8 if :c.count:;""@; 8 db.execS.L:#CR)A-) -A6+) tours :*id ./-)0)R 1R.MARF M)F A2-,./CR)M)/-G title -)U-G desc -)U- D)EA2+- ZZG created ./-)0)RG modified ./-)0)RG route -)UD)EA2+- Z8<Z;5#;5 Eile sdcard"new "ile:#/sdcard/tourit#;5 if :sdcard.exists:;; 8 for :Eile f ! sdcard.list"iles:;; 8 if :f.isDirectory:;; 8 Eile tour"new "ile:fG #tour.js#;5 if :tour.exists:;; 8 lon% now"System.currentTime'illis:;5 Content7alues map"new ContentValues:;5 map.put:#title#G f.get%ame:;;5 map.put:#created#G now;5 map.put:#modified#G now;5 map.put:#route#G tour.get&ath:;;5 db.insert:#tours#G nullG map;5 < < < < <
<
9,verride public void on)pgrade:ST+iteDatabase dbG int old7ersionG int new7ersion; 8 android.util.+o%.w:#-our.t#G #2p%radin% databaseG w$ic$ will destroy all old data#;5 db.execS.L:#DR,1 -A6+) .E )U.S-S tours#;5 onCreate:db;5 < <
(irst, Ce <uery sJlite*master to see i$ our table is there N i$ it is, Ce7re one. >therCise, Ce e;e%ute some #HL to %reate the table, then s%an the #A %ar to see i$ Ce %an $in any tours that nee to be loa e . 5hose are poure into the table via insert:; %alls.
%$/
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
5he metho behin this ma ness is %overe in greater etail in Appen i; A, Chere Ce %over 5our.t in more etail.
(uery&'
As one might e;pe%t, the Juery:; metho is Chere your %ontent provi er gets etails on a <uery some a%tivity Cants to per$orm. .t is up to you to a%tually pro%ess sai <uery. 5he <uery metho gets, as parameters*
A 2ri representing the %olle%tion or instan%e being <uerie A Strin%OP representing the list o$ properties that shoul returne be
A Strin% representing Chat amounts to a #HL C3)R) %lause, %onstraining Chi%h instan%es shoul be %onsi ere $or the <uery results A Strin%OP representing values to Qpour intoQ the C3)R) %lause, repla%ing any > $oun there A Strin% representing Chat amounts to a #HL ,RD)R 6F %lause
@ou are responsible $or interpreting these parameters hoCever they make sense an returning a Cursor that %an be use to iterate over an a%%ess the ata. As you %an imagine, these parameters are aime toCar s people using a #HLite atabase $or storage. @ou are Cel%ome to ignore some o$ these parameters &e.g., you ele%t not to try to roll your oCn #HL C3)R) %lause parser', but you nee to o%ument that $a%t so a%tivities only attempt to <uery you by instan%e 2ri an not using parameters you ele%t not to han le. (or #HLite3ba%ke storage provi ers, hoCever, the Juery:; metho implementation shoul be largely boilerplate. "se a ST+iteTuery6uilder to %onvert the various parameters into a single #HL statement, then use
%$0
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
Juery:;
on the buil er to a%tually invoke the <uery an give you a Cursor ba%k. 5he Cursor is Chat your Juery:; metho then returns.
We %reate a ST+iteTuery6uilder an pour the <uery etails into the buil er. 0ote that the <uery %oul be base aroun either a %olle%tion or an instan%e 2ri N in the latter %ase, Ce nee to a the instan%e .A to the <uery. When one, Ce use the Juery:; metho on the buil er to get a Cursor $or the results.
insert&'
@our insert&' metho Cill re%eive a 2ri representing the %olle%tion an a Content7alues stru%ture Cith the initial ata $or the neC instan%e. @ou are responsible $or %reating the neC instan%e, $illing in the supplie ata, an returning a 2ri to the neC instan%e.
%$3
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
.$ this is a #HLite3ba%ke %ontent provi er, on%e again, the implementation is mostly boilerplate* vali ate that all re<uire values Cere supplie by the a%tivity, merge your oCn notion o$ e$ault values Cith the supplie ata, an %all insert:; on the atabase to a%tually %reate the instan%e. (or e;ample, here is insert:; $rom 1rovider*
9,verride public 2ri insert:2ri urlG Content7alues initial7alues; 8 lon% row.D5 Content7alues values5 if :initial7aluesW"null; 8 values"new ContentValues:initial7alues;5 < else 8 values"new ContentValues:;5 < if :WisCollection)ri:url;; 8 t$row new Illegal#rgument+xception:#2nknown 2R+ # B url;5 < for :Strin% col/ame ! get$e-uiredColumns:;; 8 if :values.contains1ey:col/ame; "" false; 8 t$row new Illegal#rgument+xception:#Missin% column! #Bcol/ame;5 < < populateDefaultValues:values;5 row.D"db.insert:getTa!le%ame:;G get%ullColumn(ack:;G values;5 if :row.D & @; 8 2ri uri"Content2ris.with#ppendedId:getContent)ri:;G row.D;5 getContext:;.getContent$esol er:;.notifyChange:uriG null;5 return uri5 < t$row new S.L+xception:#Eailed to insert row into # B url;5 <
5he pattern is the same as be$ore* use the provi er parti%ulars plus the ata to be inserte to a%tually o the insertion. >$ note*
@ou %an only insert into a %olle%tion 2ri, so Ce vali ate that by %alling isCollection2ri:;
%$7
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
5he provi er also knoCs Chat %olumns are re<uire &%etReJuiredColumns:;', so Ce iterate over those an %on$irm our supplie values %over the re<uirements 5he provi er is also responsible $or $illing in any e$ault values &populateDefault7alues:;' $or %olumns not supplie in the insert:; %all an not automati%ally han le by the #HLite table e$inition
update&'
@our update:; metho gets the 2ri o$ the instan%e or %olle%tion to %hange, a Content7alues stru%ture Cith the neC values to apply, a #tring $or a #HL C3)R) %lause, an a Strin%OP Cith parameters to use to repla%e > $oun in the C3)R) %lause. @our responsibility is to i enti$y the instan%e&s' to be mo i$ie &base on the 2ri an C3)R) %lause', then repla%e those instan%es7 %urrent property values Cith the ones supplie . 5his Cill be annoying, unless you7re using #HLite $or storage. 5hen, you %an pretty mu%h pass all the parameters you re%eive to the update:; %all to the atabase, though the update:; %all Cill vary slightly epen ing on Chether you are up ating one instan%e or several. (or e;ample, here is update:; $rom 1rovider*
9,verride public int update:2ri urlG Content7alues valuesG Strin% w$ereG Strin%OP w$ereAr%s; 8 int count5 if :isCollection)ri:url;; 8 count"db.update:getTa!le%ame:;G valuesG w$ereG w$ereAr%s;5 < else 8 Strin% se%ment"url.get&athSegments:;.get:?;5 count"db .update:getTa!le%ame:;G valuesG getIdColumn%ame:;B#"# B se%ment B :W-ext2tils.is+mpty:w$ere; > # A/D :# B w$ere B Z;Z ! ##;G w$ereAr%s;5 < getContext:;.getContent$esol er:;.notifyChange:urlG null;5
%$9
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
.n this %ase, up ates %an either be to a spe%i$i% instan%e or applie a%ross the entire %olle%tion, so Ce %he%k the 2ri &isCollection2ri:;' an , i$ it is an up ate $or the %olle%tion, Oust per$orm the up ate. .$ Ce are up ating a single instan%e, Ce nee to a a %onstraint to the C3)R) %lause to only up ate $or the re<ueste roC.
delete&'
As Cith update:;, delete:; re%eives a 2ri representing the instan%e or %olle%tion to Cork Cith an a C3)R) %lause an parameters. .$ the a%tivity is eleting a single instan%e, the 2ri shoul represent that instan%e an the C3)R) %lause may be null. /ut, the a%tivity might be re<uesting to elete an open3en e set o$ instan%es, using the C3)R) %lause to %onstrain Chi%h ones to elete. As Cith update:;, though, this is simple i$ you are using #HLite $or atabase storage &sense a themeD'. @ou %an let it han le the i iosyn%rasies o$ parsing an applying the C3)R) %lause N all you have to o is %all delete:; on the atabase. (or e;ample, here is delete:; $rom 1rovider*
9,verride public int delete:2ri urlG Strin% w$ereG Strin%OP w$ereAr%s; 8 int count5 lon% row.d"@5 if :isCollection)ri:url;; 8 count"db.delete:getTa!le%ame:;G w$ereG w$ereAr%s;5 < else 8 Strin% se%ment"url.get&athSegments:;.get:?;5 row.d"+on%.parseLong:se%ment;5 count"db .delete:getTa!le%ame:;G getIdColumn%ame:;B#"# B se%ment B :W-ext2tils.is+mpty:w$ere; > # A/D :# B w$ere B Z;Z ! ##;G w$ereAr%s;5 <
%/;
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
5his is almost a %lone o$ the update:; implementation es%ribe above N either elete a subset o$ the entire %olle%tion or elete a single instan%e &i$ it also satis$ies the supplie C3)R) %lause'.
getType&'
5he last metho you nee returns the M.MI type %olle%tion or an instan%e an return the %orrespon to implement is %et-ype:;. 5his takes a 2ri an asso%iate Cith that 2ri. 5he 2ri %oul be a 2riP you nee to etermine Chi%h Cas provi e ing M.MI type.
As you %an see, most o$ the logi% elegates to private %etCollection-ype:; an %etSin%le-ype:; metho s*
private Strin% getCollectionType:; 8 return:#vnd.android.cursor.dir/vnd.commonsware.tour#;5 < private Strin% getSingleType:; 8 return:#vnd.android.cursor.item/vnd.commonsware.tour#;5 <
%/(
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
D t 5 seContentProvider
.$ you Cant to use DatabaseContent1rovider as a base %lass, here is Chat you nee to o*
@ou still nee %et-ype:; as es%ribe in the pre%e ing se%tion @ou may ele%t to overri e onCreate:; $or your oCn initialiKation, but be sure to %hain upCar to the super%lass &super.onCreate:;' @ou may ele%t to overri e up%radeDatabases:; to rebuil your tables i$ your atabase s%hema has %hange @ou nee to implement Juery.nternal:;, insert.nternal:;, update.nternal:;, an delete.nternal:; mu%h as es%ribe above $or Juery:;, insert:;, update:;, an delete:; respe%tively
@ou may Cish to use the same namespa%e $or the %ontent 2ri that you use $or your +ava %lasses, to re u%e the %han%e o$ %ollision Cith others.
%/%
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
public static final class -ours implements 6aseColumns 8 public static final 2ri C,/-)/-*2R. "2ri.parse:#content!//com.commonsware.android.tourit.1rovider/tours#;5 public static final Strin% D)EA2+-*S,R-*,RD)R"#title#5 public static final Strin% .D"#*id#5 public static final Strin% -.-+)"#title#5 public static final Strin% D)SCR.1-.,/"#desc#5 public static final Strin% CR)A-)D*DA-)"#created#5 public static final Strin% M,D.E.)D*DA-)"#modified#5 public static final Strin% R,2-)"#route#5 <
.$ you are using #HLite as a ata store, the values $or the property name %onstants shoul be the %orrespon ing %olumn name in the table, so you %an Oust pass the proOe%tion &array o$ properties' to #HLite on a Juery:;, or pass the Content7alues on an insert:; or update:;. 0ote that nothing in here stipulates the types o$ the properties. 5hey %oul be strings, integers, or Chatever. 5he biggest limitation is Chat a Cursor %an provi e a%%ess to via its property getters. 5he $a%t that there is nothing in %o e that en$or%es type sa$ety means you shoul o%ument the property types Cell, so people attempting to use your %ontent provi er knoC Chat they %an e;pe%t.
5he android!name property is the name o$ the %ontent provi er %lass, Cith a lea ing ot to in i%ate it is in the sto%k namespa%e $or this appli%ation7s %lasses &Oust like you use Cith a%tivities'. 5he android!aut$orities property shoul be a semi%olon3 elimite list o$ the authority values supporte by the %ontent provi er. Re%all, $rom earlier
%/,
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
in this %hapter, that ea%h %ontent 2ri is ma e up o$ a s%heme, authority, ata type path, an instan%e i enti$ier. Ia%h authority $rom ea%h C,/-)/-*2R. value shoul be in%lu e in the android!aut$orities list. 0oC, Chen An roi en%ounters a %ontent 2ri, it %an si$t through the provi ers registere through mani$ests to $in a mat%hing authority. 5hat tells An roi Chi%h appli%ation an %lass implements the %ontent provi er, an $rom there An roi %an bri ge betCeen the %alling a%tivity an the %ontent provi er being %alle .
5otify"+n"Change Support
An optional $eature your %ontent provi er to its %lients is noti$y3on3%hange support. 5his means that your %ontent provi er Cill let %lients knoC i$ the ata $or a given %ontent 2ri %hanges. (or e;ample, suppose you have %reate a %ontent provi er that retrieves R## an Atom $ee s $rom the .nternet base on the user7s $ee subs%riptions &via >!ML, perhaps'. 5he %ontent provi er o$$ers rea 3only a%%ess to the %ontents o$ the $ee s, Cith an eye toCar s several appli%ations on the phone using those $ee s versus everyone implementing their oCn $ee poll3$et%h3 an 3%a%he system. @ou have also implemente a servi%e that Cill get up ates to those $ee s asyn%hronously, up ating the un erlying ata store. @our %ontent provi er %oul alert appli%ations using the $ee s that su%h3an 3so $ee Cas up ate , so appli%ations using that spe%i$i% $ee %an re$resh an get the latest ata. >n the %ontent provi er si e, to o this, %all notifyC$an%e:; on your ContentResolver instan%e &available in your %ontent provi er via %etContext:;.%etContentResolver:;'. 5his takes tCo parameters* the 2ri o$ the pie%e o$ %ontent that %hange an the Content,bserver that initiate the %hange. .n many %ases, the latter Cill be nullP a non3null value simply means that observer Cill not be noti$ie o$ its oCn %hanges. >n the %ontent
5his ties a Content,bserver instan%e to a supplie 2ri N the observer Cill be noti$ie Chenever notifyC$an%e:; is %alle $or that spe%i$i% 2ri. When the %onsumer is one Cith the 2ri, unre%isterContent,bserver:; releases the %onne%tion.
%//
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
CHAPTER &*
.n the late -1107s, a Cave o$ viruses sprea through the .nternet, elivere via email, using %onta%t in$ormation %ulle $rom Mi%roso$t >utlook. A virus Coul simply email %opies o$ itsel$ to ea%h o$ the >utlook %onta%ts that ha an email a ress. 5his Cas possible be%ause, at the time, >utlook i not take any steps to prote%t ata $rom programs using the >utlook A!., sin%e that A!. Cas esigne $or or inary evelopers, not virus authors. 0oCa ays, many appli%ations that hol onto %onta%t ata se%ure that ata by re<uiring that a user e;pli%itly grant rights $or other programs to a%%ess the %onta%t in$ormation. 5hose rights %oul be grante on a %ase3by3%ase basis or a on%e at install time. An roi is no i$$erent, in that it re<uires permissions $or appli%ations to rea or Crite %onta%t ata. An roi 7s permission system is use$ul Cell beyon %onta%t ata, an $or %ontent provi ers an servi%es beyon those supplie by the An roi $rameCork. @ou, as an An roi eveloper, Cill $re<uently nee to ensure your appli%ations have the appropriate permissions to o Chat you Cant to o Cith other appli%ations7 ata. @ou may also ele%t to re<uire permissions $or other appli%ations to use your ata or servi%es, i$ you make those available to other An roi %omponents. 5his %hapter %overs hoC to a%%omplish both these en s.
%/3
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
*other6 *ay 8:
Re<uesting the use o$ other appli%ations7 ata or servi%es re<uires the uses( permission element to be a e to your AndroidManifest.xml $ile. @our mani$est may have Kero or more uses(permission elements, all as ire%t %hil ren o$ the root manifest element. 5he uses(permission element takes a single attribute, android!name, Chi%h is the name o$ the permission your appli%ation re<uires*
<uses(permission android!name"#android.permission.ACC)SS*+,CA-.,/# /&
5he sto%k system permissions all begin Cith android.permission an are liste in the o%umentation $or Manifest.permission in the online An roi o%umentation. 5hir 3party appli%ations may have their oCn permissions, Chi%h hope$ully they have o%umente $or you. !ermissions are %on$irme at the time the appli%ation is installe N the user Cill be prompte to %on$irm it is >F $or your appli%ation to o Chat the permission %alls $or. 5his prompt is not available in the %urrent emulator, hoCever. .$ you o not have the esire permission an try to o something that nee s it, you may get a Security)xception in$orming you o$ the missing permission, but this is not a guarantee N $ailures may %ome in other $orms, epen ing on i$ something else is %at%hing an trying to han le that e;%eption. 5o see the e$$e%ts o$ permissions, go ba%k to the 1ick e;ample proOe%t. .$ you look at the AndroidManifest.xml $ile, you Cill see it re<uests the R)AD*C,/-AC-S permission. 5his is Chat alloCs you to vieC the %onta%t in$ormation. Comment out the uses(permission element in the mani$est, re%ompile, an try out the neC version in the emulator. @ou shoul get a Security)xception. >AT.* you may nee to restart the emulator, i$ you Cere using the 1ickDemo be$ore uring this same emulator session.
%/7
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
%/9
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
5he $irst step to se%uring your oCn appli%ation using permissions is to e%lare sai permissions, on%e again in the AndroidManifest.xml $ile. .n this %ase, instea o$ uses(permission, you a permission elements. >n%e again, you %an have Kero or more permission elements, all as ire%t %hil ren o$ the root manifest element. Ae%laring a permission is slightly more %ompli%ate than using a permission. 5here are three pie%es o$ in$ormation you nee to supply* -. 5he symboli% name o$ the permission. 5o keep your permissions $rom %olli ing Cith those $rom other appli%ations, you shoul use your appli%ation7s +ava namespa%e as a pre$i; be
2. A label $or the permission* something short that Coul un erstan able by users
?. A es%ription $or the permission* something a Cee bit longer that is un erstan able by your users
<permission android!name"#vnd.tla%ency.sekrits.S))*S)MR.-S# android!label"#9strin%/see*sekrits*label# android!description"#9strin%/see*sekrits*description# /&
5his oes not en$or%e the permission. Rather, it in i%ates that it is a possible permissionP your appli%ation must still $lag se%urity violations as they o%%ur.
%0;
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
android!permission"#vnd.tla%ency.sekrits.S))*S)MR.-S#& <intent(filter& <action android!name"#android.intent.action.MA./# /& <cate%ory android!name"#android.intent.cate%ory.+A2/C3)R# /& </intent(filter& </activity&
>nly appli%ations that have re<ueste your in i%ate permission Cill be able to a%%ess the se%ure %omponent. .n this %ase, 6a%%ess9 means*
A%tivities %annot be starte Cithout the permission #ervi%es %annot be starte , stoppe , or boun to an a%tivity Cithout the permission .ntent re%eivers ignore messages sent via broadcast.ntent:; unless the sen er has the permission istin%t attributes* read1ermission an
.n this %ase, read1ermission %ontrols a%%ess to <uerying the %ontent provi er, Chile write1ermission %ontrols a%%ess to insert, up ate, or elete ata in the %ontent provi er.
permissions on a per3%all basis via 5his returns 1)RM.SS.,/*0RA/-)D or on Chether the %aller has the permission you spe%i$ie . (or e;ample, i$ your servi%e implements separate rea an Crite
c$eckCallin%1ermission:;. 1)RM.SS.,/*D)/.)D epen ing
%0(
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
metho s, you %oul get the e$$e%t o$ read1ermission an write1ermission in %o e by %he%king those metho s $or the permissions you nee $rom +ava. Also, you %an in%lu e a permission Chen you %all broadcast.ntent:;. 5his means that eligible re%eivers must hol that permissionP those Cithout the permission are ineligible to re%eive it. (or e;ample, the An roi subsystem presumably in%lu es the R)C).7)*SMS permission Chen it broa %asts that an #M# message has arrive N this Cill restri%t the re%eivers o$ that intent to be only those authoriKe to re%eive #M# messages.
%0%
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
CHAPTER &-
Creating a Service
As note previously, An roi servi%es are $or long3running pro%esses that may nee to keep running even Chen e%ouple $rom any a%tivity. I;amples in%lu e playing musi% even i$ the QplayerQ a%tivity gets garbage3%olle%te , polling the .nternet $or R##UAtom $ee up ates, an maintaining an online %hat %onne%tion even i$ the %hat %lient loses $o%us ue to an in%oming phone %all. #ervi%es are %reate Chen manually starte &via an A!. %all' or Chen some a%tivity tries %onne%ting to the servi%e via inter3pro%ess %ommuni%ation &.!C'. #ervi%es Cill live until no longer nee e an i$ RAM nee s to be re%laime . Running $or a long time isn7t Cithout its %osts, though, so servi%es nee to be %are$ul not to use too mu%h C!" or keep ra ios a%tive too mu%h o$ the time, lest the servi%e %ause the evi%e7s battery to get use up too <ui%kly. 5his %hapter %overs hoC you %an %reate your oCn servi%esP the ne;t %hapter %overs hoC you %an use su%h servi%es $rom your a%tivities or other %onte;ts. /oth %hapters Cill analyKe the Mail/uKK sample appli%ation &Mail6u''', Cith this %hapter $o%using mostly on the Mail6u''Service implementation. Mail6u''Service polls a supplie email a%%ount, either on3 eman or on a state interval, to see i$ neC messages have arrive , at Chi%h it Cill post a /otification &as es%ribe in the %hapter on noti$i%ations'.
%0,
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
Creating a Service
'etting BuLLed
5he Mail/uKK appli%ation is an email monitoring appli%ation, %ombining an a%tivity an a servi%e. 5he a%tivity alloCs you to spe%i$y an email a%%ount to monitorP the servi%e oes the a%tual monitoring. When neC messages arrive, the servi%e noti$ies the user. !rovi ing an appli%ation to a%tually rea e;er%ise $or the rea er. an Crite emails is le$t as an
2. onStart:;, Chi%h is %alle Chen a servi%e is manually starte by some other pro%ess, versus being impli%itly starte as the result o$ an .!C re<uest & is%usse more in the ne;t %hapter' ?. onDestroy:; Chi%h is %alle as the servi%e is being shut oCn Common startup an shut oCn logi% shoul go in onCreate:; an onDestroy:;P onStart:; is mostly i$ your servi%e nee s ata passe into it &via the supplie 6undle' $rom the starting pro%ess an you on7t Cish to use .!C. (or e;ample, here is the onCreate:; metho $or Mail6u''Service*
%0$
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
Creating a Service
9,verride public void onCreate:; 8 super.onCreate:;5 back%round"new Thread:new $unna!le:; 8 public void run:; 8 try 8 Strin% event"null5 w$ile :eventW"S32-D,C/; 8 event"Jueue.poll:;5 if :event""1,++; 8 check#ccountImpl:;5 < else if :eventW"S32-D,C/; 8 -$read.sleep:?@@@;5 <
< < catc$ :-$rowable t; 8 // just end t$e back%round t$read < < <;5 back%round.start:;5 setupTimer:;5
<
(irst, Ce %hain upCar to the super%lass, so An roi %an o any setup Cork it nee s to have one. 0e;t, Ce set up a ba%kgroun threa to monitor a Concurrent+inkedTueue on%e every se%on , looking $or neC events. As Ce7ll see, the <ueue alloCs us to o the a%tual polling $or neC messages in a separate threa than those use $or either the perio i% timer or the in%oming .!C metho %alls $rom the Mail6u'' a%tivity. 5he onCreate:; metho Craps up by %alling a private setup-imer:; metho *
private void setupTimer:; 8 if :get&ollState:;; 8 S$ared1references settin%s"get&refs:;5 int poll1eriod"settin%s.getInt:#poll1eriod#G L;QS@@@@5 task"new TimerTask:; 8 public void run:; 8 check#ccount:;5 < <5
%0/
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
Creating a Service
<
5his %he%ks to see i$ Ce7re suppose to be perio i%ally %he%king $or neC messages or not. .$ Ce are, Ce set up a -imer-ask to post a 1,++ message on our <ueue, an set up that task to be invoke base on an a%tivity3supplie perio , e;presse in minutes. .$ Ce are not suppose to be perio i%ally %he%king $or message, Ce shut oCn the timer i$ it Cas alrea y starte . 5his may seem super$luous, but setup-imer:; gets %alle not only $rom onCreate:;, but Chen the perio i%3%he%k status %hanges. 5he onDestroy:; metho is mu%h simpler*
9,verride public void onDestroy:; 8 super.onDestroy:;5 timer.cancel:;5 Jueue.add:S32-D,C/;5 <
)ere, Ce Oust shut oCn the timer an ba%kgroun threa , in a ition to %haining upCar to the super%lass $or any An roi internal bookkeeping that might be nee e . .n a ition to those li$e%y%le metho s, though, your servi%e also nee s to implement on6ind:;. 5his metho returns an .6inder, Chi%h is the lin%hpin behin the .!C me%hanism. .$ you7re %reating a servi%e %lass Chile rea ing this %hapter, Oust have this metho return null $or noC, an Ce7ll $ill in the $ull implementation in the ne;t se%tion.
Creating a Service
e%lares Chat metho s it is making available over .!CP those metho s are then available $or other %omponents to %all, Cith An roi han ling all the messy etails involve Cith making metho %alls a%ross %omponent or pro%ess boun aries. 5he guts o$ this, $rom the stan point o$ the eveloper, is e;presse in A.AL* the An roi .nter$a%e Aes%ription Language. .$ you have use .!C me%hanisms like C>M, C>R/A, or the like, you Cill re%ogniKe the notion o$ .AL. A.AL spells out the publi% .!C inter$a%e, an An roi supplies tools to buil the %lient an server si e o$ that inter$a%e. With that in min , let7s take a look at A.AL an .!C.
As Cith a +ava inter$a%e, you e%lare a pa%kage at the top. As Cith a +ava inter$a%e, the metho s are Crappe in an inter$a%e e%laration &interface .6u'' 8 ... <'. An , as Cith a +ava inter$a%e, you list the metho s you are making available. 5he i$$eren%es, though, are %riti%al. (irst, not every +ava type %an be use as a parameter. @our %hoi%es are*
%03
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
Creating a Service
&$rom java.util'
Any other A.AL3 e$ine inter$a%es Any +ava %lasses that implement the 1arcelable inter$a%e, Chi%h is An roi 7s $lavor o$ serialiKation &see beloC'
.n the %ase o$ the latter tCo %ategories, you nee to in%lu e import statements re$eren%ing the names o$ the %lasses or inter$a%es that you are using &e.g., import com.commonsware.android..Somet$in%'. 5his is true even i$ these %lasses are in your oCn pa%kage N you have to import them anyCay. 0e;t, parameters %an be %lassi$ie as in, out, or inout. ,alues that are out or inout %an be %hange by the servi%e an those %hanges Cill be propagate ba%k to the %lient. !rimitives &e.g., int' %an only be inP Ce in%lu e in $or the A.AL $or enable:; Oust $or illustration purposes. Also, you %annot throC any e;%eptions. @ou Cill nee to %at%h all e;%eptions in your %o e, eal Cith them, an return $ailure in i%ations some other Cay &e.g., error %o e return values'. 0ame your A.AL $iles Cith the .aidl e;tension an pla%e them in the proper ire%tory base on the pa%kage name. When you buil your proOe%t, either via an .AI or via Ant, the aidl utility $rom the An roi #AF Cill translate your A.AL into a server stub an a %lient pro;y.
%07
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
Creating a Service
.Stub
%lass &e.g.,
.mplement metho s mat%hing up Cith ea%h o$ the metho s you pla%e in the A.AL Return this private instan%e $rom your on6ind:; metho Service sub%lass in the
<5
.n this %ase, the stub %alls %orrespon ing metho s on the servi%e itsel$. 5hose metho s are shoCn beloC*
private void check#ccount:; 8 Jueue.add:1,++;5 < private void ena!le&oll:boolean enabled; 8 S$ared1references settin%s"get&refs:;5 S$ared1references.)ditor editor"settin%s.edit:;5 editor.putBoolean:#enabled#G enabled;5 editor.commit:;5 setupTimer:;5
<
pops a 1,++ message on our <ueue, so our ba%kgroun threa %an poll the mail server
c$eckAccount:;
%09
Creating a Service
up ates our pre$eren%es so Ce knoC to start or stop polling Chen the servi%e ne;t runs, then %alls setup-imer:; to start or stop the polling
enable1oll:; %et1ollState:; enable1oll:;
simply
returns
the
pre$eren%e
up ate
by
0ote that A.AL .!C %alls are syn%hronous, an so the %aller is blo%ke until the .!C metho returns. )en%e, your servi%es nee to be <ui%k about their Cork. .$ c$eckAccount:; Cere to ire%tly %he%k the mail server itsel$, instea o$ using the ba%kgroun <ueue, the a%tivity %alling c$eckAccount:; Coul be $roKen until the mail server respon e . #in%e that takes a noti%eable amount o$ time, putting the real c$eckAccount:; Cork &c$eckAccount.mpl:;' in a <ueue3base ba%kgroun threa provi es $or a %leaner user e;perien%e.
*anifest .estiny
(inally, you nee to a the servi%e to your AndroidManifest.xml $ile, $or it to be re%ogniKe as an available servi%e $or use. 5hat is simply a matter o$ a ing a service element as a %hil o$ the application element, provi ing android!name to re$eren%e your servi%e %lass. (or e;ample, here is the AndroidManifest.xml $ile $or Mail/uKK*
<manifest xmlns!android"#$ttp!//sc$emas.android.com/apk/res/android# packa%e"#com.commonsware.android.service#& <application& <activity android!name"#.Mail6u''# android!label"#Mail6u''#& <intent(filter& <action android!name"#android.intent.action.MA./# /& <cate%ory android!name"#android.intent.cate%ory.+A2/C3)R# /& </intent(filter& </activity& <service android!name"#.Mail6u''Service# /& </application& </manifest&
#in%e the servi%e %lass is in the same +ava namespa%e as everything else in this appli%ation, Ce %an use the shorthan ot3notation &#.Mail6u''Service#' to re$eren%e our %lass.
%3;
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
Creating a Service
.$ you Cish to re<uire some permission o$ those Cho Cish to start or bin to the servi%e, a an android!permission attribute naming the permission you are man ating N see the %hapter on permissions $or more etails.
%3(
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
CHAPTER &/
8nvoking a Service
#ervi%es %an be use by any appli%ation %omponent that Qhangs aroun Q $or a reasonable perio o$ time. 5his in%lu es a%tivities, %ontent provi ers, an other servi%es. 0otably, it oes not in%lu e pure intent re%eivers &i.e., intent re%eivers that are not part o$ an a%tivity', sin%e those Cill get garbage %olle%te imme iately a$ter ea%h instan%e pro%esses one in%oming .ntent. 5o use a servi%e, you nee to get an instan%e o$ the A.AL inter$a%e $or the servi%e, then %all metho s on that inter$a%e as i$ it Cere a lo%al obOe%t. When one, you %an release the inter$a%e, in i%ating you no longer nee the servi%e. .n this %hapter, Ce Cill look at the %lient si e o$ the Mail/uKK sample appli%ation &Mail6u'''. 5he Mail/uKK a%tivity provi es $iel s $or the a%%ount in$ormation &server type, server, et%.', a %he%kbo; to toggle Chether polling $or neC mail shoul go on, a button to push the a%%ount in$ormation to the servi%e, an another button to %he%k right noC $or neC messages. When run, the a%tivity looks like this*
%3,
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
8nvoking a Service
%3$
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
8nvoking a Service
<5
public void onSer iceDisconnected:Component/ame class/ame; 8 service"null5 c$eck/ow6utton.set+na!led:false;5 setAccount6utton.set+na!led:false;5 set)nabled.set+na!led:false;5 <
the servi%e 2. onServiceDisconnected:;, Chi%h is %alle i$ your %onne%tion en s normally, su%h as you unbin ing your a%tivity $rom the servi%e Ia%h o$ those metho s re%eives a Component/ame, Chi%h simply i enti$ies the servi%e you %onne%te to. More importantly, onServiceConnected:; re%eives an .6inder instan%e, Chi%h is your gateCay to the .!C inter$a%e. @ou Cill Cant to %onvert the .6inder into an instan%e o$ your A.AL inter$a%e %lass, so you %an use .!C as i$ you Cere %alling regular metho s on a regular +ava %lass &.6u''.Stub.as.nterface:binder;'. 5o a%tually hook your a%tivity to the servi%e, %all bindService:; on the a%tivity*
!indSer ice:service.ntentG svcConnG 6./D*A2-,*CR)A-);5
5he bindService:; metho takes three parameters* -. An .ntent representing the servi%e you Cish to invoke N $or your oCn servi%e, it7s easiest to use an intent re$eren%ing the servi%e %lass ire%tly &new .ntent:t$isG Mail6u''Service.class;'
2. @our ServiceConnection instan%e ?. A set o$ $lags N most times, you Cill Cant to pass in 6./D*A2-,*CR)A-), Chi%h Cill start up the servi%e i$ it is not alrea y running A$ter your bindService:; %all, your onServiceConnected:; %allba%k in the ServiceConnection Cill eventually be invoke , at Chi%h time your %onne%tion is rea y $or use.
%3/
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
8nvoking a Service
Prometheus >nbound
When you are one Cith the .!C inter$a%e, %all unbindService:;, passing in the ServiceConnection. Iventually, your %onne%tion7s onServiceDisconnected:; %allba%k Cill be invoke , at Chi%h point you shoul null out your inter$a%e obOe%t, isable relevant Ci gets, or otherCise $lag yoursel$ as no longer being able to use the servi%e. (or e;ample, in the Mail/uKK implementation o$ onServiceDisconnected:; shoCn above, Ce null out the .6u'' servi%e obOe%t an isable the tCo buttons an %he%kbo;. @ou %an alCays re%onne%t to the servi%e, via bindService:;, i$ you nee to use it again.
*anual Transmission
.n a ition to bin ing to the servi%e $or the purposes o$ .!C, you %an manually start an stop the servi%e. 5his is parti%ularly use$ul in %ases Chere
%30
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
8nvoking a Service
you Cant the servi%e to keep running in epen ently o$ your a%tivities N otherCise, on%e you unbin the servi%e, your servi%e %oul Cell be %lose oCn. 5o start a servi%e, simply %all startService:;, provi ing tCo parameters* -. 5he .ntent spe%i$ying the servi%e to start &again, the easiest Cay is probably to spe%i$y the servi%e %lass, i$ its your oCn servi%e'
2. A 6undle provi ing %on$iguration ata, Chi%h eventually gets passe to the servi%e7s onStart:; metho Conversely, to stop the servi%e, %all stopService:; Cith the .ntent you use in the %orrespon ing startService:; %all. (or e;ample, here is the Mail/uKK %o e behin %he%kbo;* the QInable pollingQ
set)nabled":C$eck6ox;findViewById:R.id.enabled;5 set)nabled.setOnCheckedChangeListener:new Compound6utton.OnCheckedChangeListener:; 8 public void onCheckedChanged:Compound6utton button7iewG boolean isC$ecked; 8 try 8 if :isC$ecked; 8 startSer ice:service.ntentG new Bundle:;;5 < else 8 stopSer ice:service.ntent;5 < service.ena!le:isC$ecked;5 < catc$ :Dead,bject)xception e; 8 svcConn.onSer iceDisconnected:null;5 <
< <;5
0ot only o Ce %all the servi%e7s enable:; .!C metho , but Ce also start an stop the servi%e, base on the %he%kbo; state. /y starting the servi%e, even i$ Ce later unbin $rom the servi%e, the servi%e Cill keep running an polling $or neC messages. >nly Chen Ce both unbin $rom the servi%e an stop the servi%e Cill the servi%e be $ully shut oCn.
%33
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
CHAPTER &2
!op3up messages. 5ray i%ons an their asso%iate QbubbleQ messages. /oun%ing o%k i%ons. @ou are no oubt use to programs trying to get your attention, sometimes $or goo reason. @our phone also probably %hirps at you $or more than Oust in%oming %alls* loC battery, alarm %lo%ks, appointment noti$i%ations, in%oming te;t message or email, et%. 0ot surprisingly, An roi has a Chole $rameCork $or ealing Cith these sorts o$ things, %olle%tively %alle Qnoti$i%ationsQ.
Types of Pestering
A servi%e, running in the ba%kgroun , nee s a Cay to users knoC something o$ interest has o%%urre , su%h as Chen email has been re%eive . Moreover, the servi%e may nee some Cay to steer the user to an a%tivity Chere they %an a%t upon the event N rea ing a re%eive message, $or e;ample. (or this, An roi supplies status bar i%ons, $lashing lights, an other in i%ators %olle%tively knoCn as Qnoti$i%ationsQ. @our %urrent phone may Cell have su%h i%ons, to in i%ate battery li$e, signal strength, Chether /luetooth is enable , an the like. With An roi , appli%ations %an a their oCn status bar i%ons, Cith an eye toCar s having them appear only Chen nee e &e.g., a message has arrive '.
%39
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
.n An roi , you %an raise noti$i%ations via the /otificationMana%er. 5he /otificationMana%er is a system servi%e. 5o use it, you nee to get the servi%e obOe%t via %etSystemService:/,-.E.CA-.,/*S)R7.C); $rom your a%tivity. 5he /otificationMana%er gives you tCo metho s* one to pester ¬ify:;' an one to stop pestering &cancel:;'. 5he notify:; metho takes a /otification, Chi%h is a ata stru%ture that spells out Chat $orm your pestering shoul take. )ere is Chat is at your isposal &bearing in min that not all evi%es Cill ne%essarily support all o$ these'*
%7;
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
Icons
While the $lashing lights, soun s, an vibrations are aime at getting somebo y to look at the evi%e, i%ons are esigne to take them the ne;t step an tell them Chat7s so important. 5o set up an i%on $or a /otification, you nee to set status6ar.con, Chere you provi e the i enti$ier o$ a Drawable resour%e representing the i%on, an status6arClick.ntent, Chere you supply an .ntent to be raise Chen the i%on is %li%ke . @ou shoul be sure the .ntent Cill be %aught by something, perhaps your oCn appli%ation %o e, to take appropriate steps to let the user eal Cith the event triggering the noti$i%ation. @ou %an also supply te;t blurbs to appear Chen the i%on is put on the status bar &status6ar-icker-ext' an Chen the i%on is sele%te but not yet %li%ke &status6ar6alloon-ext'.
%7(
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
5his metho *
sets up the noti$i%ation to shoC a Cheel i%on &-4p; high' an the message QWaypoint nearby:Q sets up a vibration pattern, i$ the user %hose &via the Confi%Activity' to be noti$ie by vibration sets up the QCaypoint3toneQ to play, i$ the user %hose to be noti$ie by a soun %on$igures the noti$i%ation to be insistent, so the vibration or soun Cill keep playing isplays the noti$i%ation
%7%
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
Later on, Chen the Caypoint is su$$i%iently istant, -our7iewActivity %an%els the noti$i%ation*
private 3andler $andler"new (andler:; 8 9,verride public void handle'essage:Messa%e ms%; 8 lon% tmp"lastAlertSeen.get:;5 if :tmp&(?+ YY System.currentTime'illis:;(tmp&H@@@; 8 /otificationMana%er nm":/otificationMana%er;getSystemSer ice:/,-.E.CA-.,/*S)R7.C);5 nm.cancel:R.strin%.%o*button;5 lastAlertSeen.set:(?+;5
%7,
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
CHAPTER '4
A popular $eature on %urrent3era mobile evi%es is 8!# %apability, so the evi%e %an tell you Chere you are at any point in time. While the most popular use o$ 8!# servi%e is mapping an ire%tions, there are other things you %an o i$ you knoC your lo%ation. (or e;ample, you might set up a ynami% %hat appli%ation Chere the people you %an %hat Cith are base on physi%al lo%ation, so you7re %hatting Cith those you are nearest. >r, you %oul automati%ally QgeotagQ posts to 5Citter or similar servi%es. 8!# is not the only Cay a mobile Alternatives in%lu e*
5he Iuropean e<uivalent to 8!#, %alle 8alileo, Chi%h is still un er evelopment at the time o$ this Criting Cell toCer triangulation, Chere your position is etermine base on signal strength to nearby %ell toCers !ro;imity to publi% Wi(i QhotspotsQ that have knoCn geographi% lo%ations
An roi evi%es may have one or more o$ these servi%es available to them. @ou, as a eveloper, %an ask the evi%e $or your lo%ation, plus etails on Chat provi ers are available. 5here are even Cays $or you to simulate your lo%ation in the emulator, $or use in testing your lo%ation3enable appli%ations.
%73
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
!inding -ourself
5he obvious thing to o Cith a lo%ation servi%e is to $igure out Chere you are right noC. get a +ocationMana%er N %all %etSystemService:+,CA-.,/*S)R7.C); $rom your a%tivity or servi%e an %ast it to be a +ocationMana%er. 5he ne;t step to $in out Chere you are is to get the name o$ the +ocation1rovider you Cant to use. )ere, you have tCo main options* -. Ask the user to pi%k a provi er
%77
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
5o
that,
you
nee
to
2. (in the best3mat%h provi er base on a set o$ %riteria .$ you Cant the user to pi%k a provi er, %alling %et1roviders:; on the +ocationMana%er Cill give you a +ist o$ provi ers, Chi%h you %an then Crap in an ArrayAdapter an use $or the sele%tion Ci get o$ your %hoi%e. 5he %at%h is that +ocation1rovider oes not have a use$ul toStrin%:; implementation, so you nee to o a little e;tra Cork, either overri ing ArrayAdapter to populate your vieCs by han , or Crapping ea%h +ocation1rovider in your oCn obOe%t that implements toStrin%:; by %alling the provi er7s %et/ame:; metho . 5our.t takes the latter approa%h in Confi%Activity*
9,verride public void onCreate:6undle icicle; 8 super.onCreate:icicle;5 setContentView:R.layout.confi%;5 +ocationMana%er m%r":+ocationMana%er;getSystemSer ice:Context.+,CA-.,/*S)R7.C);5 for :+ocation1rovider p ! m%r.get&ro iders:;; 8 listCrappers.add:new &ro ider*rapper:p;;5 < ArrayAdapter<Caypoint& aa"new ArrayAdapter<Caypoint&:t$isG R.layout.spinnerG :+ist;listCrappers;5 providers":Spinner;findViewById:R.id.providers;5 aa.setDropDownView$esource:android.R.layout.simple*spinner*dropdown*item;5 providers.set#dapter:aa;5 <
%79
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
>r, you %an %reate an populate a Criteria obOe%t, stating the parti%ulars o$ Chat you Cant out o$ a +ocation1rovider, su%h as*
setAltitudeReJuired:;
not
setAccuracy:;
position
setCostAllowed:; to %ontrol i$ the provi er must be $ree or i$ it %an in%ur a %ost on behal$ o$ the evi%e user
8iven a $ille 3in Critieria obOe%t, %all %et6est1rovider:; on your +ocationMana%er, an An roi Cill si$t through the %riteria an give you the best ansCer. 0ote that not all o$ your %riteria Cill be met N all but the monetary %ost %riterion might be rela;e i$ nothing mat%hes. >n%e you knoC the name o$ the +ocation1rovider, you %an %all to turn on the lo%ation provi er an get an up3to3 ate $i;, or you %an %all %et+astMnown1osition:; to $in out Chere you Cere re%ently. 0ote, hoCever, that Qre%entlyQ might be $airly out o$ ate &e.g., phone Cas turne o$$'. >n the other han , %et+astMnown1osition:; in%urs no monetary or poCer %ost, sin%e the provi er oes not nee to be a%tivate to get the value.
%etCurrent+ocation:;
5hese metho s return a +ocation obOe%t, Chi%h %an give you the latitu e an longitu e o$ the evi%e in egrees as a +ava double. .$ the parti%ular lo%ation provi er o$$ers other ata, you %an get at that as Cell*
(or altitu e, $asAltitude:; Cill tell you i$ there is an altitu e value, an %etAltitude:; Cill return the altitu e in meters. (or bearing &i.e., %ompass3style ire%tion', $as6earin%:; Cill tell you i$ there is a bearing available, an %et6earin%:; Cill return it as egrees east o$ true north. (or spee , $asSpeed:; Cill tell you i$ the spee is knoCn an %etSpeed:; Cill return the spee in meters per se%on .
%9;
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
(or e;ample, -our)ditActivity alloCs users to %li%k a button to $ill in the %urrent lo%ation Chen e iting Caypoint N the theory being that the user is ri ing the tour an taking lo%ations along the Cay to up ate the otherCise3 %omplete tour e$inition. 5he user7s pre$erre lo%ation provi er is store in a pre$eren%e, $ille in by the Confi%Activity an up ate in -our)ditActivity7s onResume:;*
9,verride public void on$esume:; 8 super.on$esume:;5 S$ared1references prefs"getShared&references:Confi%Activity.1R)ESG @;5 Strin% provider/ame"prefs.getString:Confi%Activity.+,CA-.,/*1R,7.D)RG null;5 if :provider/ameW"null; 8 for :+ocation1rovider p ! my+ocationMana%er.get&ro iders:;; 8 if :p.get%ame:;.e-uals:provider/ame;; 8 provider"p5 break5 < < < if :provider""null; 8 Criteria crit"new Criteria:;5 crit.setCost#llowed:true;5 crit.setSpeed$e-uired:false;5 crit.setBearing$e-uired:false;5 crit.set#ltitude$e-uired:false;5 provider"my+ocationMana%er.getBest&ro ider:crit;5 < <
5hen, Chen the button is %li%ke , it gets a %urrent $i; an $ills in the lo%ation in the appropriate $iel s*
6utton btn":6utton;findViewById:R.id.fillin;5 btn.setOnClickListener:new 7iew.OnClickListener:; 8 public void onClick:7iew view; 8 if :providerW"null; 8 +ocation loc"my+ocationMana%er.getCurrentLocation:provider.get%ame:;;5 pt*lat.setText:new Dou!le:loc.getLatitude:;;.toString:;;5 pt*lon%.setText:new Dou!le:loc.getLongitude:;;.toString:;;5 pt*ele.setText:new Dou!le:loc.get#ltitude:;;.toString:;;5
%9(
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
+n the *ove
0oC that you knoC Chere you are, you ne;t might Cant to knoC Chere you7re going. pair o$ reJuest2pdates:; metho s, Chere you %an $ire perio i%ally, to keep you in$orme o$ your %urrent position. /oth $lavors o$ reJuest2pdates:; take a time &in millise%on s' an istan%e &in meters' N only i$ the re<ueste time has elapse and the position has %hange by the re<ueste istan%e Cill the .ntent be ispat%he . >ne $lavor o$ reJuest2pdates:; takes a +ocation1rovider, an you Cill only get up ates base o$$ o$ that provi erP the other $lavor takes a Criteria an Cill use the best3mat%h provi er. .t is up to you to arrange $or an a%tivity or intent re%eiver to respon to the .ntent you register Cith reJuest2pdates:;. >therCise, the up ates Cill never be a%te upon. When you no longer nee the up ates, %all remove2pdates:; Cith the .ntent you registere .
+ocationMana%er sports a register an .ntent to be
%9%
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
5o a%%omplish this, +ocationMana%er o$$ers add1roximityAlert:;. 5his registers an .ntent, Chi%h Cill be $ire o$$ Chen the evi%e gets Cithin a %ertain istan%e o$ a %ertain lo%ation. 5he add1roximityAlert:; metho takes, as parameters*
5he latitu e an longitu e o$ the position that you are intereste in A ra ius, spe%i$ying hoC %lose you shoul be to that position $or the .ntent to be raise A uration $or the registration, in millise%on s N a$ter this perio , the registration automati%ally lapses. A value o$ (? means the registration lasts until you manually remove it via remove1roximityAlert:;. 5he .ntent to be raise Chen the evi%e is Cithin the Qtarget KoneQ e;presse by the position an ra ius
0ote that it is not guarantee that you Cill a%tually re%eive an .ntent, i$ there is an interruption in lo%ation servi%es, or i$ the evi%e is not in the target Kone uring the perio o$ time the pro;imity alert is a%tive. (or e;ample, i$ the position is o$$ by a bit, an the ra ius is a little too tight, the evi%e might only skirt the e ge o$ the target Kone, or go by so <ui%kly that the evi%e7s lo%ation isn7t sample Chile in the target Kone. .t is up to you to arrange $or an a%tivity or intent re%eiver to respon to the .ntent you register Cith the pro;imity alert. What you then o Chen the .ntent arrives is up to you* set up a noti$i%ation &e.g., vibrate the evi%e', log the in$ormation to a %ontent provi er, post a message to a Web site, et%. 0ote that you Cill re%eive the .ntent Chenever the position is sample an you are Cithin the target Kone N not Oust upon entering the Kone. )en%e, you Cill get the .ntent several times, perhaps <uite a $eC times epen ing on the siKe o$ the target Kone an the spee o$ the evi%e7s movement. .n 5our.t, Chen vieCing the %ue sheet $or a tour &-our7iewActivity', the user has a %he%kbo; to enable alerts. When %he%ke , -our7iewActivity sets up pro;imity alerts $or all o$ the Caypoints in the tour, plus sets up the a%tivity itsel$ as being an intent re%eiver $or the intent $or these alerts*
%9,
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
private void ena!le#lerts:; 8 if :providerW"null; 8 register$ecei er:receiverG proximitylocation.ntentEilter;5 for :Caypoint pt ! tour.get$oute:;; 8 .ntent i"new Intent:1R,U.M.-F*A+)R-;5 my+ocationMana%er.add&roximity#lert:pt.getLatitude:;G pt.getLongitude:;G ?@@.@fG NIH@@@@@G i;5 // ?H $ours max < < < proximity.ntents.add:i;5
o%umentation says*
!he intent will have an e"tra added with key #entering# and a boolean value. If the value is true, the device is entering the pro"imity region$ if false, it is e"iting. At the time o$ this Criting, that oes not seem to Cork properly. )en%e, ealing Cith the in%oming .ntent stream is a bit tri%ky. &or, more a%%urately, its private han les it is, Chen an alert .ntent is $irst re%eive , it sets up a noti$i%ation to alert the user that she is nearing a Caypoint*
private void show%otification:; 8 /otificationMana%er nm " :/otificationMana%er;getSystemSer ice:/,-.E.CA-.,/*S)R7.C);5 /otification notif " new %otification: -our7iewActivity.t$isG R.drawable.w$eel*?SG #Caypoint nearbyW#G System.currentTime'illis:;G nullG nullG nullG R.drawable.w$eel*?SG #-our.tW#G null;5
5he
%9$
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
// after a ?@@ms delayG vibrate for HL@msG pause for ?@@ ms and // t$en vibrate for L@@ms. if :alert7ibrate; 8 notif.vibrate " new lon%OP 8 ?@@G HL@G ?@@G L@@<5 < if :alertSound; 8 notif.sound"2ri.parse:#android.resource!//com.commonsware.tourit/#BR.raw.ale rt;5 < notif.insistent"alert.nsistent5 nm.notify:R.strin%.%o*buttonG notif;5 <
(or ea%h .ntent re%eive , 5our.t up ates a timestamp o$ Chen the last .ntent Cas re%eive . .t then uses a 3andler to monitor $or Chen the .ntent stream stops N i$ it is stoppe $or tCo se%on s or more, the noti$i%ation is isable an the me%hanism is reset to aCait the ne;t .ntent stream*
private 3andler $andler"new (andler:; 8 9,verride public void handle'essage:Messa%e ms%; 8 lon% tmp"lastAlertSeen.get:;5 if :tmp&(?+ YY System.currentTime'illis:;(tmp&H@@@; 8 /otificationMana%er nm":/otificationMana%er;getSystemSer ice:/,-.E.CA-.,/*S)R7.C);5 nm.cancel:R.strin%.%o*button;5 lastAlertSeen.set:(?+;5 < <5 <
(inally, i$ the user un3%he%ks the alert %he%kbo;, or i$ the a%tivity is positively %lose , all o$ the pro;imity alerts are unregistere *
private void disa!le#lerts:; 8 if :providerW"null YY proximity.ntents.si2e:;&@; 8 unregister$ecei er:receiver;5 for :.ntent i ! proximity.ntents; 8 my+ocationMana%er.remo e&roximity#lert:i;5 < proximity.ntents.clear:;5
%9/
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
< <
5his is not a per$e%t system by any means. . eally, the QenteringQ e;tra value Coul be set on the .ntent, negating the nee $or the 3andler. /etter smarts are probably nee e to han le other a%tivity li$e%y%le events, as it is un%lear Chat happens to registere pro;imity alerts i$ the a%tivity that registere them is kille o$$.
Testing<<<Testing<<<
5he An roi emulator oes not have the ability to get a $i; $rom 8!#, triangulate your position $rom %ell toCers, or i enti$y your lo%ation by some nearby Wi(i signal. .nstea , it has abuilt3in $ake 8!# provi er, set to simulate your movement aroun a loop o$ positions in the #ili%on ,alley area o$ Cali$ornia. 5his, o$ %ourse, is only nominally use$ul. "nless the other in$ormation you are tying lo%ation to happens to be in that area, you Cill nee to simulate lo%ations someChere else. 5he goo neCs is that the $ake 8!# provi er implemente by An roi is a%tually part o$ a larger system $or emulating lo%ation provi ers. @ou %an either implement a $ull +ocation1rovider an tie it into the system, or you %an %reate ata $iles %ontaining time o$$sets an positions, to simulate the movement o$ a evi%e. .t is mu%h simpler, though, to use 5ra%k/uil er. 5ra%k/uil er is a sample appli%ation, poste to the an ev.org site. .t uses An roi 7s oCn mapping logi% to present you Cith a map, upon Chi%h you %an %li%k to note lo%ations along a tra%k o$ movement. 5ra%k/uil er %an then save the tra%k, an you %an move the ata $ile into the proper spot $or use Cith An roi 7s $ake38!# provi er. 5he tra%k you re%or e is then available $or your testing use. #in%e the $ake38!# $iles re<uire latitu e an
%90
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
longitu e positions to several signi$i%ant igits, using 5ra%k/uil er beats han 3Criting those $iles in most situations. >n%e you have the $ake38!# ata $ile or %ustom +ocation1rovider in pla%e, though, you nee to have your appli%ation use that lo%ation sour%e versus any other. 5his is ma e more %ompli%ate i$ you have several $ake38!# ata $iles $or i$$erent test s%enarios. 5hat is Chy it is probably a goo i ea to alloC the user to %on$igure the +ocation1rovider that your appli%ation uses, rather than merely relying upon Critieria3base sele%tion N that Cay Chen you are testing, you %an %hoose the right provi er to mat%h the test you are running. .t %oul be you only o$$er a manually3%on$igure +ocation1rovider Chen your appli%ation is in some sort o$ test mo e, i$ you o not Cant to e;pose that %hoi%e to a%tual users o$ your appli%ation.
%93
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
CHAPTER '1
>ne o$ 8oogle7s most popular servi%es N a$ter sear%h, o$ %ourse N is 8oogle Maps, Chere you %an $in everything $rom the nearest piKKa parlor to ire%tions $rom 0eC @ork City to #an (ran%is%o &only 2,10B miles:' to street vieCs an satellite imagery. An roi , not surprisingly, integrates 8oogle Maps. 5here is a mapping a%tivity available to users straight o$$ the main An roi laun%her. More relevant to you, as a eveloper, are Map7iew an MapActivity, Chi%h alloC you to integrate maps into your oCn appli%ations. 0ot only %an you isplay maps, %ontrol the Koom level, an alloC people to pan aroun , but you %an tie in An roi 7s lo%ation3base servi%es to shoC Chere the evi%e is an Chere it is going. (ortunately, integrating basi% mapping $eatures into your An roi proOe%t is $airly easy. )oCever, there is a $air bit o$ poCer available to you, i$ you Cant to get $an%y.
MapActivity
.n your layout $or the MapActivity sub%lass, you nee to a an element name , at the time o$ this Criting, com.%oo%le.android.maps.Map7iew. 5his is the Qlonghan Q Cay to spell out the names o$ Ci get %lasses, by in%lu ing the $ull pa%kage name along Cith the %lass name. 5his is ne%essary be%ause Map7iew is not in the com.%oo%le.android.wid%et namespa%e. @ou %an give the Map7iew Ci get Chatever android!id attribute value you Cant, plus han le all the layout etails to have it ren er properly alongsi e your other Ci gets. (or e;ample, here is the layout $or -ourMapActivity, $rom the -our.t sample appli%ation*
<>xml version"#?.@# encodin%"#utf(A#>& <Relative+ayout xmlns!android"#$ttp!//sc$emas.android.com/apk/res/android# android!layout*widt$"#fill*parent# android!layout*$ei%$t"#fill*parent#& <com.%oo%le.android.maps.Map7iew android!id"#9Bid/map# android!layout*widt$"#fill*parent# android!layout*$ei%$t"#fill*parent#/& <+inear+ayout android!orientation"#$ori'ontal# android!layout*widt$"#fill*parent# android!layout*$ei%$t"#wrap*content# android!layout*ali%n1arent6ottom"#true#& <Spinner android!id"#9Bid/waypoints# android!layout*wei%$t"#?# android!layout*widt$"#wrap*content# android!layout*$ei%$t"#wrap*content# android!drawSelector,n-op"#true# android!paddin%-op"#?@dip# android!visibility"#invisible# android!paddin%6ottom"#?@dip# /& <.ma%e6utton android!id"#9Bid/%o# android!src"#9drawable/%o*to*point# android!layout*widt$"#wrap*content# android!layout*$ei%$t"#wrap*content# android!%ravity"#center*vertical# android!layout*%ravity"#center*vertical# android!visibility"#invisible# android!paddin%-op"#?@dip# android!paddin%6ottom"#?@dip# /& </+inear+ayout& </Relative+ayout&
,;;
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
5hat is pretty mu%h all you nee $or starters, plus to sub%lass your a%tivity $rom MapActivity. .$ you Cere to o nothing else, an built that proOe%t an tosse it in the emulator, you7 get a ni%e map o$ the Corl . .n theory, the user %oul pan aroun the map using the ire%tional pa . )oCever, that7s not terribly use$ul Chen the user has the Chole Corl in her han s. #in%e a map o$ the Corl is not mu%h goo by itsel$, Ce nee to a things... a $eC
>oom
5he map o$ the Corl you start Cith is rather broa . "sually, people looking at a map on a phone Cill be e;pe%ting something a bit narroCer in s%ope, su%h as a $eC %ity blo%ks. @ou %an %ontrol the Koom level ire%tly via the 'oom-o:; metho on the MapController. 5his takes an integer representing the level o$ Koom, Chere is the Corl vieC an 2- is the tightest Koom you %an get. Ia%h level is a oubling o$ the e$$e%tive resolution* - has the e<uator measuring 2B4 pi;els Ci e, Chile 2- has the e<uator measuring 248,=?B,=B4 pi;els Ci e. #in%e the phone7s isplay probably oesn7t have 248,=?B,=B4 pi;els in either imension, the user sees a small map $o%use on one tiny %orner o$ the globe. A level o$ -4 Cill shoC you several %ity blo%ks in ea%h imension an is probably a reasonable starting point $or you to e;periment Cith.
,;(
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
o$$ers a to%%le)d%eKoomin%:; metho , Chi%h takes a boolean parameter in i%ating i$ this $eature shoul be on or o$$. .$ it is enable , then the user %an rag her $inger oCn the right e ge o$ the map to %hange the Koom level manually. .n the emulator, use your mouse to simulate the ragging motion.
Map7iew
Center
5ypi%ally, you Cill nee to %ontrol Chat the map is shoCing, beyon the Koom level, su%h as the user7s %urrent lo%ation, or a lo%ation save Cith some ata in your a%tivity. 5o %hange the map7s position, %all centerMap-o:; on the MapController. 5his takes a 1oint as a parameter. A 1oint represents a lo%ation, via latitu e an longitu e. 5he %at%h is that the !oint stores latitu e an longitu e as integers representing the a%tual latitu e an longitu e multiplie by ?)S. 5his saves a bit o$ memory versus storing a float or double, an it probably spee s up some internal %al%ulations An roi nee s to o to %onvert the
,;%
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
into a map position. )oCever, it oes mean you have to remember to multiple the Qreal Corl Q latitu e an longitu e by ?)S.
1oint
Reticle
5he Qreti%leQ is the small %ir%le shoCing the %enter o$ the map. +ust as you %an set the map %enter, you %an retrieve it by %alling %etMapCenter:; on the Map7iew. 5his Cill return a 1oint re$le%ting the position o$ the reti%le. 5he user, in turn, %an use the reti%le to QpointQ at a spe%i$i% spot, perhaps using the option menu to signal to your a%tivity that it Cants some in$ormation about that point. !arti%ularly i$ you Cill be implementing overlays &see beloC', you Cill probably Cant to a the $olloCing statement to your onCreate:; metho , Chere map is your Map7iew*
map.set$eticleDraw'ode: Map7iew.ReticleDrawMode.DRAC*R)-.C+)*2/D)R ;5
5his Cill ensure anything you raC on the map Cill not be obs%ure by the reti%le itsel$.
,;,
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
o$$ers to%%leSatellite:; an to%%le-raffic:;, Chi%h, as the names suggest, toggle on an o$$ these perspe%tives on the area being vieCe . @ou %an have the user trigger these via an options menu or, in the %ase o$ -ourMapActivity, via keypresses*
Map7iew
9,verride public boolean on1eyDown:int keyCodeG Mey)vent event; 8 if :keyCode "" Mey)vent.M)FC,D)*S; 8 // Switc$ on t$e satellite ima%es map.toggleSatellite:;5 return:true;5 < else if :keyCode "" Mey)vent.M)FC,D)*-; 8 // Switc$ on traffic overlays map.toggleTraffic:;5 return:true;5 < < return:super.on1eyDown:keyCodeG event;;5
5he thir , e$ault perspe%tive is Qstreet vieCQ, Chi%h %an be turne on via to%%leStreet7iew:;. 5here is also isSatellite:;, is-raffic:;, an isStreet7iew:; to test to see Chi%h o$ these perspe%tives is visible.
,;$
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
At the time o$ this Criting, though, there7s one big problem Cith setEollowMy+ocation:; N it oesn7t let you %ontrol Chi%h lo%ation provi er to use. 5his is a serious limitation Chen Corking Cith the emulator, as you have no great means o$ %ontrolling Chi%h lo%ation provi er is use by the map, an so you might $in yoursel$ vieCing the map o$ Chere the lo%ation provi er thinks it is, rather than Chat you are trying to test. 5he goo i$$i%ult. neCs is that Qrolling your oCnQ $olloC3me logi% is not that
5he $irst step is $iguring out Chi%h lo%ation provi er you Cant to use, perhaps via an appli%ation pre$eren%e. 5our.t alloCs the user to %hoose a lo%ation provi er via the Confi%Activity, as es%ribe in the previous %hapter. 0e;t, you nee to re<uest up ates $rom that lo%ation provi er, via the metho on +ocationMana%er. 5his metho arranges $or an Chen the evi%e moves a %ertain istan%e over a %ertain minimum perio o$ time.
reJuest2pdates:; .ntent to be $ire
,;/
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
followMe"prefs.getBoolean:Confi%Activity.E,++,C*M)G true;5 Strin% provider/ame"prefs.getString:Confi%Activity.+,CA-.,/*1R,7.D)RG null;5 if :provider/ameW"null; 8 for :+ocation1rovider p ! my+ocationMana%er.get&ro iders:;; 8 if :p.get%ame:;.e-uals:provider/ame;; 8 provider"p5 break5 < < < if :provider""null; 8 Criteria crit"new Criteria:;5 crit.setCost#llowed:true;5 crit.setSpeed$e-uired:false;5 crit.setBearing$e-uired:false;5 crit.set#ltitude$e-uired:false;5 < provider"my+ocationMana%er.getBest&ro ider:crit;5
if :providerW"null; 8 register$ecei er:intentReceiverG my.ntentEilter;5 my+ocationMana%er.re-uest)pdates:providerG M./.M2M*-.M)*6)-C))/*21DA-)G M./.M2M*D.S-A/C)C3A/0)*E,R*21DA-)G my.ntent;5 < <
We $irst $in out Chat the %hosen lo%ation provi er is an Chether or not the $olloC3me $eature shoul be enable . .$ there is no spe%i$ie lo%ation provi er, Ce use a Criteria to $in one. 5hen, Ce register our intent re%eiver &an instan%e o$ the private +ocation.ntentReceiver %lass' using our intent $ilter*
new Intent"ilter:+,CA-.,/*C3A/0)D*AC-.,/;5
>ur +ocation.ntentReceiver %lass is trivial, simply telling the a%tivity to up ate its vieC*
class +ocation.ntentReceiver extends .ntentReceiver 8 9,verride public void on$ecei eIntent:Context contextG .ntent intent; 8 -ourMapActivity.t$is.updateView:;5
,;0
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
< <
5he update7iew:; metho on -ourMapActivity %he%ks to see i$ $olloC3me is enable , an , i$ true, re3%enters the map on the %urrent position*
private void updateView:; 8 if :providerW"null; 8 my+ocation"my+ocationMana%er.getCurrentLocation:provider.get%ame:;;5 if :followMe; 8 Double lat"-ourMapActivity.t$is.my+ocation.getLatitude:; Q ?)S5 Double ln%"-ourMapActivity.t$is.my+ocation.getLongitude:; Q ?)S5 1oint point"new &oint:lat.intValue:;G ln%.intValue:;;5 < < mc.center'apTo:pointG false;5
/y this me%hanism, you %an have your $olloC3me $eature Chile o$$ering more ire%t %ontrol over Chi%h lo%ation provi er to use. .t is eminently possible the An roi A!. Cill be up ate to Qbake inQ this type o$ %apability, at Chi%h point the %o e shoCn here may be%ome obsolete.
,;3
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
0verl y Cl sses
Any overlay you Cant to a to your map nee s to be implemente as a sub%lass o$ ,verlay. 5his oes not have to be a publi% %lassP -ourMapActivity has a private inner %lass %alle Route,verlay to shoC the Caypoints an %urrent evi%e position. 5o atta%h an overlay %lass to your map, you nee ,verlayController an a the overlay to it*
map.createO erlayController:;.add:new $outeO erlay:t$is;G true;5
5he $irst parameter is the ,verlay instan%e, in this %ase a neC Route,verlay, atta%he to the a%tivity. 5he se%on parameter is a boolean in i%ating i$ the overlay shoul be a%tivate . @ou %an e$ine overlays an a%tivate or ea%tivate them as nee e , Oust as you toggle betCeen regular an satellite vieCs. .n this %ase, sin%e Ce Cant the overlay to be visible at all times, Ce use true to a%tivate it imme iately.
-.
2. A 1ixelCalculator, to help you %onvert betCeen pi;els $or your raCing an real3Corl imensions on the map ?. A boolean in i%ating Chether this is the Qsha oCQ %all or not 5he draw:; metho is %alle tCi%e in su%%ession* on%e Cith s$adow " true, in i%ating that i$ your layer has any sort o$ ?A e$$e%t &e.g., sha oCs %ast by push3pins', you shoul raC those, an on%e Cith s$adow " false $or raCing the QregularQ part o$ the layer. While you shoul %hain upCar to the super%lass &via super.draw:canvasG calculatorG s$adow;', the e$ault
,;7
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
a%tion $or draw:; is to o nothing. )en%e, i$ you on7t have a sha oC, either ignore the parameter or only raC Chen s$adow " false. A Canvas o$$ers a range o$ raCing metho s, su%h as drawCircle:;, draw-ext:;, an so on. 5he %at%h is that the Canvas is e;pe%ting to be tol Chere to raC in terms o$ pi;els in %anvas3spa%e. @ou, on the other han , have your ata in terms o$ positions &latitu e an longitu e'. An , o$ %ourse, the user isn7t vieCing the Chole Corl at on%e, so there7s a <uestion o$ Chi%h subset o$ things you Cant to raC a%tually appear on the Canvas. (ortunately, An roi en%apsulates mu%h o$ those problems insi e the 1ixelCalculator. 5o raC things on the Canvas, you shoul * -. Convert your latitu e an longitu e into a 1oint...as note above, a 1oint uses a pair o$ integers $or the latitu e an longitu e, s%ale upCar s by a $a%tor o$ ?)S
2. Allo%ate an intOHP array to hol the pi;el %onversion o$ your 1oint ?. Call %et1ointUF:; on the 1ixelConverter, supplying your 1oint an intOHP array =. "se the intOHP array as ;Uy %oor inates $or your draw...:; metho s on the Canvas (or e;ample, here is the implementation o$ Route,verlay7s draw:; metho *
public void draw:Canvas canvasG 1ixelCalculator calculatorG boolean s$adow; 8 super.draw:canvasG calculatorG s$adow;5 if :show'yLocation:; YY -ourMapActivity.t$is.my+ocationW"null; 8 Double lat"-ourMapActivity.t$is.my+ocation.getLatitude:; Q ?)S5 Double ln%"-ourMapActivity.t$is.my+ocation.getLongitude:; Q ?)S5 1oint point"new &oint:lat.intValue:;G ln%.intValue:;;5 intOP myScreenCoords " new intOHP5 calculator.get&oint,3:pointG myScreenCoords;5 canvas.drawCircle:myScreenCoordsO@PG myScreenCoordsO?PG LG paintI;5 < int i"@5 for :Caypoint pt ! tour.get$oute:;; 8 ,;9
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
iBB5 1oint position"pt.get&osition:;5 if :positionW"null; 8 intOP screenCoords"new intOHP5 calculator.get&oint,3:positionG screenCoords;5 canvas.drawCircle:screenCoordsO@PG screenCoordsO?PG ?HG paint?;5 canvas.drawText:.nte%er.toString:i;G screenCoordsO@P ( NG screenCoordsO?P B NG paintH;5 < < <
A$ter %haining upCar to the super%lass, Ce $irst etermine i$ Ce7re suppose to be shoCing the evi%e7s position. .$ so, Ce buil a 1oint, %onvert it to ;Uy %oor inates, an raC a L3pi;el ra ius re %ir%le at those %oor inates &paintI is e$ine up in onCreate:; as being R8/ re '. 5hen, $or ea%h Caypoint in the tour, Ce o mu%h the same thing* buil a 1oint, %onvert it to ;Uy %oor inates, raC a ?H3pi;el ra ius bla%k %ir%le, an Crite in the %ir%le the Caypoint number in Chite.
H ndlin! Screen T ps
An ,verlay sub%lass %an also implement on-ap:;, to be noti$ie Chen the user taps on the map, so the overlay %an a Oust Chat it raCs. (or e;ample, in $ull3siKe 8oogle Maps, %li%king on a push3pin pops up a bubble Cith in$ormation about the business at that pin7s lo%ation. With on-ap:;, you %an o mu%h the same in An roi . 5he on-ap:; metho re%eives three parameters* -. A Q evi%e typeQ, in i%ating Chat generate tra%kball, et%.' the tap &tou%hs%reen,
.t is up to you to etermine i$ the supplie 1oint represents something o$ interest an , i$ so, Chat to isplay. .n the %ase o$ Route,verlay, on-ap:; looks like this*
9,verride public boolean onTap:com.%oo%le.android.maps.Map7iew.Device-ype device-ypeG 1oint pG 1ixelCalculator calculator; 8 for :Caypoint pt ! tour.get$oute:;; 8 1oint position"pt.get&osition:;5 if :positionW"null; 8 intOP screenCoords"new intOHP5 RectE rect"new $ect":;5 calculator.get&oint,3:positionG screenCoords;5 rect.set:(?HG(?HG?HG?H;5 rect.offset:screenCoordsO@PG screenCoordsO?P;5 calculator.get&oint,3:pG screenCoords;5 if :rect.contains:screenCoordsO@PG screenCoordsO?P;; 8 -oast.makeText:parentG pt.getTitle:;G H@@@;.show:;5 <
return:super.onTap:device-ypeG pG calculator;;5
We iterate over the Caypoints an use the RectE helper %lass to %onstru%t a 2=;2= pi;el s<uare aroun ea%h Caypoint7s on3s%reen representation. 5his s<uare isn7t raCn on s%reenP rather, it is use solely to etermine i$ the tap &represente by the supplie 1oint' o%%urre Cithin that s<uare. .$ so, Ce %onsi er the user to have tappe on that Caypoint, an Ce shoC a -oast Cith the name o$ the Caypoint &e.g., QMosser #t. G )amiltonQ'.
,((
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
CHAPTER '&
Playing *edia
!retty mu%h every phone %laiming to be a QsmartphoneQ has the ability to at least play ba%k musi%, i$ not vi eo. Iven many more or inary phones are $ull3$le ge M!? players, in a ition to o$$ering ringtones an Chatnot. 0ot surprisingly, An roi aims to mat%h the best o$ them. An roi has $ull %apability to play ba%k an re%or au io an vi eo. 5his in%lu es*
!layba%k o$ au io, su%h as oCnloa e M!? tra%ks #hoCing photos !laying ba%k vi eo %lips ,oi%e re%or ing through the mi%rophone Camera $or still pi%tures or vi eo %lips
I;a%tly hoC robust these %apabilities Cill be is heavily evi%e3 epen ent. Mobile evi%e %ameras range $rom e;%ellent to atro%ious. #%reen resolutions an siKes Cill vary, an vi eo playba%k Corks better on better s%reens. Whi%h %o e%s a evi%e manu$a%turer Cill li%ense &e.g., Chat types o$ vi eo %an it playD' an Chi%h /luetooth pro$iles a evi%e Cill support &e.g., A2A! $or stereoD' Cill also have an impa%t on Chat results any given person Cill have Cith their phone.
,(,
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
Playing *edia
@ou as a eveloper %an integrate me ia playba%k an re%or ing into your appli%ations. Re%or ing is outsi e the s%ope o$ this book, in large part be%ause the %urrent emulator has re%or ing limitations at this time. An , vieCing pi%tures is mostly a matter o$ putting an .ma%e7iew Ci get into an a%tivity. 5his %hapter, there$ore, $o%uses on playba%k o$ au io an vi eo. As Cith many a van%e An roi $eatures, e;pe%t %hanges in $uture releases o$ their toolkit. (or e;ample, at the time o$ this Criting, there is no built3in au io or vi eo playba%k a%tivity. )en%e, you %annot Oust %ra$t an .ntent to, say, an M!? "RL, an han it o$$ to An roi Cith 7.)C*AC-.,/ to initiate playba%k. Right noC, you nee to han le the playba%k yoursel$. .t is probably sa$e to assume, though, that stan ar a%tivities $or this Cill be $orth%oming, alloCing you to Qtake the easy Cay outQ i$ you Cant to play ba%k me ia but o not nee to %ontrol that playba%k mu%h yoursel$.
2. @ou %an pa%kage me ia %lips as assets &assets/ in your proOe%t' an re$eren%e them via file!///android*asset/ "RLs in a 2ri. 5he bene$it over raC resour%es is that this lo%ation Corks Cith A!.s that e;pe%t 2ri parameters instea o$ resour%e .As. 5he oCnsi e N assets are only repla%eable Chen the appli%ation is upgra e N remains. ?. @ou %an store me ia in an appli%ation3lo%al ire%tory, su%h as %ontent you oCnloa o$$ the .nternet. @our me ia may or may not be there, an your storage spa%e isn7t in$inite, but you %an repla%e the me ia as nee e . =. @ou %an store me ia N or re$eren%e me ia that the user has store hersel$ N that is on an #A %ar . 5here is likely more storage spa%e on
,($
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
Playing *edia
the %ar than there is on the evi%e, an you %an repla%e the me ia as nee e , but other appli%ations have a%%ess to the #A %ar as Cell. B. @ou %an, in some %ases, stream me ia o$$ the .nternet, bypassing any lo%al storage .nternet streaming seems to be someChat problemati% in this release o$ the An roi #AF.
*aking 5oise
5he %ru; o$ playing ba%k au io %omes in the $orm o$ the Media1layer %lass. With it, you %an $ee it an au io %lip, startUstopUpause playba%k, an get noti$ie on key events, su%h as Chen the %lip is rea y to be playe or is one playing. @ou have three Cays to set up a Media1layer an tell it Chat au io %lip to play* -. .$ the %lip is a raC resour%e, use Media1layer.create:; an provi e the resour%e .A o$ the %lip
Media1layer.create:;
version o$
?. .$ you have a string path to the %lip, Oust %reate a Media1layer using the e$ault %onstru%tor, then %all setDataSource:; Cith the path to the %lip 0e;t, you nee to %all prepare:; or prepareAsync:;. /oth Cill set up the %lip to be rea y to play, su%h as $et%hing the $irst $eC se%on s o$$ the $ile or stream. 5he prepare:; metho is syn%hronousP as soon as it returns, the %lip is rea y to play. 5he prepareAsync:; metho is asyn%hronous N more on hoC to use this version later. >n%e the %lip is prepare , start:; begins playba%k, pause:; pauses playba%k &Cith start:; pi%king up playba%k Chere pause:; pause ', an stop:; en s playba%k. >ne %aveat* you %annot simply %all start:; again on the Media1layer on%e you have %alle stop:; N that may be a bug or may be the
,(/
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
Playing *edia
inten e Media1layer behavior. We7ll %over a Corkaroun a bit later in this se%tion. 5o see this in a%tion, take a look at the AudioDemo sample proOe%t. 5he layout is pretty trivial, Cith three buttons an labels $or play, pause, an stop*
<>xml version"#?.@# encodin%"#utf(A#>& <+inear+ayout xmlns!android"#$ttp!//sc$emas.android.com/apk/res/android# android!orientation"#vertical# android!layout*widt$"#fill*parent# android!layout*$ei%$t"#fill*parent# & <+inear+ayout android!orientation"#$ori'ontal# android!layout*widt$"#fill*parent# android!layout*$ei%$t"#wrap*content# android!paddin%"#Npx# & <.ma%e6utton android!id"#9Bid/play# android!src"#9drawable/play# android!layout*$ei%$t"#wrap*content# android!layout*widt$"#wrap*content# android!paddin%Ri%$t"#Npx# android!enabled"#false# /& <-ext7iew android!text"#1lay# android!layout*widt$"#fill*parent# android!layout*$ei%$t"#fill*parent# android!%ravity"#center*vertical# android!layout*%ravity"#center*vertical# android!textAppearance"#>android!attr/textAppearance+ar%e# /& </+inear+ayout& <+inear+ayout android!orientation"#$ori'ontal# android!layout*widt$"#fill*parent# android!layout*$ei%$t"#wrap*content# android!paddin%"#Npx# & <.ma%e6utton android!id"#9Bid/pause# android!src"#9drawable/pause# android!layout*$ei%$t"#wrap*content# android!layout*widt$"#wrap*content# android!paddin%Ri%$t"#Npx# /& <-ext7iew android!text"#1ause# android!layout*widt$"#fill*parent# android!layout*$ei%$t"#fill*parent# android!%ravity"#center*vertical#
,(0
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
Playing *edia
/& </+inear+ayout& <+inear+ayout android!orientation"#$ori'ontal# android!layout*widt$"#fill*parent# android!layout*$ei%$t"#wrap*content# android!paddin%"#Npx# & <.ma%e6utton android!id"#9Bid/stop# android!src"#9drawable/stop# android!layout*$ei%$t"#wrap*content# android!layout*widt$"#wrap*content# android!paddin%Ri%$t"#Npx# /& <-ext7iew android!text"#Stop# android!layout*widt$"#fill*parent# android!layout*$ei%$t"#fill*parent# android!%ravity"#center*vertical# android!layout*%ravity"#center*vertical# android!textAppearance"#>android!attr/textAppearance+ar%e# /& </+inear+ayout& </+inear+ayout&
android!layout*%ravity"#center*vertical# android!textAppearance"#>android!attr/textAppearance+ar%e#
public class AudioDemo extends Activity 8 private static final int C+,S)*.D " Menu.E.RS-BH5 private private private private .ma%e6utton .ma%e6utton .ma%e6utton Media1layer play5 pause5 stop5 mp5
,(3
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
Playing *edia
play":.ma%e6utton;findViewById:R.id.play;5 pause":.ma%e6utton;findViewById:R.id.pause;5 stop":.ma%e6utton;findViewById:R.id.stop;5 play.setOnClickListener:new 7iew.OnClickListener:; 8 public void onClick:7iew view; 8 mp.start:;5 play.set+na!led:false;5 pause.set+na!led:true;5 stop.set+na!led:true;5 < <;5 pause.setOnClickListener:new 7iew.OnClickListener:; 8 public void onClick:7iew view; 8 mp.pause:;5 play.set+na!led:true;5 pause.set+na!led:false;5 stop.set+na!led:true;5 < <;5 stop.setOnClickListener:new 7iew.OnClickListener:; 8 public void onClick:7iew view; 8 stop:;5 < <;5 try 8 mp"new 'edia&layer:;5 mp.setOn&reparedListener:new Media1layer.On&reparedListener:; 8 public void on&repared:Media1layer mp; 8 play.set+na!led:true;5 < <;5 mp.setOnCompletionListener:new Media1layer.OnCompletionListener:; 8 public void onCompletion:Media1layer mp; 8 stop:;5 < <;5 setup:;5 < catc$ :-$rowable t; 8 android.util.+o%.e:#AudioDemo#G #)xception playin% audio#G t;5 -oast.makeText:t$isG #.ckW#G H@@@;.show:;5 < < 9,verride public boolean onCreateOptions'enu:Menu menu; 8 menu.add:@G C+,S)*.DG #Close#G R.drawable.eject; .set#lpha!eticShortcut:ZcZ;5
,(7
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
Playing *edia
<
return:super.onCreateOptions'enu:menu;;5
9,verride public boolean onOptionsItemSelected:Menu..tem item; 8 switc$ :item.getId:;; 8 case C+,S)*.D! finish:;5 return:true;5 < return:super.onOptionsItemSelected:item;;5 < private void stop:; 8 mp.reset:;5 setup:;5 < private void setup:; 8 play.set+na!led:false;5 pause.set+na!led:false;5 stop.set+na!led:false;5 try 8 mp.setDataSource:#/system/media/audio/rin%tones/rin%er.mpI#;5 < catc$ :-$rowable t; 8 android.util.+o%.e:#AudioDemo#G #)xception playin% audio#G t;5 -oast.makeText:t$isG #.ckW#G H@@@;.show:;5 < < < mp.prepare#sync:;5
Auring the preparation phase, Ce Cire up the three buttons to shi$t us betCeen the other states, plus prep the Media1layer &mp instan%e variable'. #pe%i$i%ally*
We use the empty %onstru%tor We hook it up to an ,n1repared+istener via set,n1repared+istener:; N this %allba%k gets invoke Chen prepareAsync:; is $inishe , an in our %ase it enables the play button We hook it up
set,nCompletion+istener:;
,(9
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
Playing *edia
rea%hes the en , at Chi%h point Ce %all stop:;, Oust as i$ the user ha %li%ke the #top button
>ur stop:; metho simply resets the Media1layer an %alls setup:;. 5he setup:; metho N %alle uring initial preparation an a$ter the %lip is stoppe N isables the buttons, sets the %lip to be a built3in ringtone M!?, an %alls prepareAsync:;. #o, the $loC is* -. We prep the Media1layer Cith the %lip
2. We enable the play button ?. 5he user %li%ks the play button an listens to the %lip =. 5he user possibly pauses playba%k, then %li%ks play again to resume B. 5he user possibly stops playba%k, at Chi%h time the me ia player is %ompletely reset to its post3prep state 4. 5he %lip possibly en s on its oCn, at Chi%h time the me ia player is also reset 5he Chole reset3an 3re%on$igure pro%ess is hoC you %an get a Media1layer ba%k to being able to play again a$ter you %all stop:;. 5he ". is nothing spe%ial, but Ce7re more intereste in the au io in this sample, anyCay*
,%;
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
Playing *edia
*oving Pictures
,i eo %lips get their oCn Ci get, the 7ideo7iew. !ut it in a layout, $ee it an M!= vi eo %lip, an you get playba%k: Right noC, playba%k seems a bit ro%ky in the emulator, but that Cill likely %lear itsel$ up in $uture releases N 7ideo7iew Cas only ma e available in the #AF release prior to publi%ation o$ this book. #in%e 7ideo7iew is a Ci get, you %an put it in a layout, su%h as this one $rom the ,i eoAemo sample proOe%t*
<>xml version"#?.@# encodin%"#utf(A#>& <+inear+ayout xmlns!android"#$ttp!//sc$emas.android.com/apk/res/android# android!orientation"#vertical# android!layout*widt$"#fill*parent# android!layout*$ei%$t"#fill*parent# & <7ideo7iew android!id"#9Bid/video# android!layout*widt$"#IH@px# android!layout*$ei%$t"#HN@px#
,%(
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
Playing *edia
/& <6utton android!id"#9Bid/s$ow# android!text"#S$ow ControllerW# android!layout*$ei%$t"#fill*parent# android!layout*widt$"#fill*parent# android!paddin%Ri%$t"#Npx# android!enabled"#false# /& </+inear+ayout&
.n a ition to the 7ideo7iew, Ce also put in a 6utton that, Chen pushe , Cill pop up the 7ideo7iew %ontrol panel, knoCn as the MediaController. 5his, by e$ault, overlays the bottom portion o$ the 7ideo7iew an shoCs your %urrent position in the vi eo %lip, plus o$$ers pause, reCin , an $ast3 $orCar buttons*
packa%e com.commonsware.android.video5 import import import import import import import android.app.Activity5 android.%rap$ics.1ixelEormat5 android.os.6undle5 android.view.7iew5 android.wid%et.6utton5 android.wid%et.MediaController5 android.wid%et.7ideo7iew5
public class 7ideoDemo extends Activity 8 private 7ideo7iew video5 private MediaController ctlr5 9,verride public void onCreate:6undle icicle; 8 super.onCreate:icicle;5 get*indow:;.set"ormat:1ixelEormat.-RA/S+2C)/-;5 setContentView:R.layout.main;5 6utton s$ow":6utton;findViewById:R.id.s$ow;5 s$ow.setOnClickListener:new 7iew.OnClickListener:; 8 public void onClick:7iew view; 8 ctlr.show:;5 < <;5 video":7ideo7iew;findViewById:R.id.video;5 video.setVideo&ath:#/tmp/test.mpN#;5 ctlr"new 'ediaController:t$is;5 ctlr.set'edia&layer:video;5 video.set'ediaController:ctlr;5 video.re-uest"ocus:;5
,%%
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
Playing *edia
< <
5he biggest tri%k Cith 7ideo7iew is getting a vi eo %lip onto the evi%e. While 7ideo7iew oes support some streaming vi eo, the re<uirements on the M!= $ile are $airly stringent. .$ you Cant to be able to play a Ci er array o$ vi eo %lips, you nee to have them on the evi%e, either in the lo%al $ilesystem or on an #A %ar . 5he %ru e 7ideoDemo %lass assumes there is an M!= $ile in /tmp/test.mpN on your emulator. 5o make this a reality* -. (in a %lip, su%h as Aaron Rosenberg7s %ocumentaries and &ou $rom Auke "niversity7s Center $or the #tu y o$ the !ubli% Aomain7s Moving .mage Contest, Chi%h Cas use in the %reation o$ this book
2. "se the adb pus$ %omman &or the e<uivalent in your .AI' to %opy the M!= $ile into /tmp/test.mpN >n%e there, the $olloCing +ava %o e Cill give you a Corking vi eo player*
!igure 0/< The Gideo.emo sample application6 sho4ing a Creative Commons" licensed video clip
,%,
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
Playing *edia
>AT.* the /tmp ire%tory is %leane out perio i%ally on the emulator, an so you may nee to re3push the $ile i$ you inten to run this sample over an e;ten e perio o$ time. 5he button is set up to %all s$ow:; on the MediaController, Chi%h isplays the %ontrol panel. 5he %lip Cill automati%ally start playing ba%k N you o not nee to %all play:; on the 7ideo7iew, though that metho is available &as is pause:; an stop1layback:;, in %ase you nee your oCn %ontrol over playba%k in a ition to the MediaController7s %ontrol panel'.
,%$
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
CHAPTER ''
Many, i$ not most, An roi evi%es Cill be phones. As su%h, not only Cill users be e;pe%ting to pla%e an re%eive %alls using An roi , but you Cill have the opportunity to help them pla%e %alls, i$ you Cish. Why might you Cant toD
Maybe you are Criting an An roi inter$a%e to a sales management appli%ation &a la #ales$or%e.%om' an you Cant to o$$er users the ability to %all prospe%ts Cith a single button %li%k, an Cithout them having to keep those %onta%ts both in your appli%ation an in the phone7s %onta%ts appli%ation Maybe you are Criting a so%ial netCorking appli%ation, an the roster o$ phone numbers that you %an a%%ess shi$ts %onstantly, so rather than try to Qsyn%Q the so%ial netCork %onta%ts Cith the phone7s %onta%t atabase, you let people pla%e %alls ire%tly $rom your appli%ation Maybe you are %reating an alternative inter$a%e to the e;isting %onta%ts system, perhaps $or users Cith re u%e motor %ontrol &e.g., the el erly', sporting big buttons an the like to make it easier $or them to pla%e %alls
Whatever the reason, An roi has A!.s to let you manipulate the phone Oust like any other pie%e o$ the An roi system.
,%/
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
2. call:;, Chi%h imme iately pla%es a %all, given a phone number ?. endCall:;, Chi%h terminates the %urrent %all
,%0
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
8enerally speaking, you probably shoul use dial:; over call:;, so the user gets %on$irmation that they7re a%tually pla%ing a %all, in %ase they mis3 %li%ke on something. >r, o$$er a %on$iguration option, alloCing users to %hoose Chether you Cin up using dial:; or call:;. .$ you $eel you Cant to use call:;, make sure the user has %on$irme they truly Cant a %all, or you may Cin up Cith a bun%h o$ unhappy users. (or e;ample, let7s look at the Dialer sample appli%ation. )ere7s the %ru e3 but3e$$e%tive layout*
<>xml version"#?.@# encodin%"#utf(A#>& <+inear+ayout xmlns!android"#$ttp!//sc$emas.android.com/apk/res/android# android!orientation"#vertical# android!layout*widt$"#fill*parent# android!layout*$ei%$t"#fill*parent# & <+inear+ayout android!orientation"#$ori'ontal# android!layout*widt$"#fill*parent# android!layout*$ei%$t"#wrap*content# & <-ext7iew android!layout*widt$"#wrap*content# android!layout*$ei%$t"#wrap*content# android!text"#/umber to dial!# /& <)dit-ext android!id"#9Bid/number# android!layout*widt$"#fill*parent# android!layout*$ei%$t"#wrap*content# android!cursor7isible"#true# android!editable"#true# android!sin%le+ine"#true# /& </+inear+ayout& <+inear+ayout android!orientation"#$ori'ontal# android!layout*widt$"#fill*parent# android!layout*$ei%$t"#wrap*content# & <6utton android!id"#9Bid/dial# android!layout*widt$"#fill*parent# android!layout*$ei%$t"#fill*parent# android!layout*wei%$t"#?# android!text"#Dial .tW# /& <6utton android!id"#9Bid/call# android!layout*widt$"#fill*parent# android!layout*$ei%$t"#fill*parent# android!layout*wei%$t"#?# android!text"#Call .tW#
,%3
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
We have a labele $iel $or typing in a phone number, plus buttons $or ialing an %alling sai number. 5he +ava %o e Cires up those buttons to dial:; an call:;, respe%tively, on the .1$one inter$a%e*
packa%e com.commonsware.android.dialer5 import import import import import import import import import import android.app.Activity5 android.os.6undle5 android.os.Dead,bject)xception5 android.os..ServiceMana%er5 android.os.ServiceMana%er/ative5 android.telep$ony..1$one5 android.view.7iew5 android.wid%et.6utton5 android.wid%et.)dit-ext5 android.wid%et.-oast5
public class DialerDemo extends Activity 8 .1$one p$one"null5 9,verride public void onCreate:6undle icicle; 8 super.onCreate:icicle;5 setContentView:R.layout.main;5 .ServiceMana%er svcM%r"ServiceMana%er/ative.getDefault:;5 try 8 p$one".1$one.Stub.asInterface:svcM%r.getSer ice:#p$one#;;5 < catc$ :Dead,bject)xception e; 8 android.util.+o%.e:#DialerDemo#G #)rror in dial:;#G e;5 -oast.makeText:DialerDemo.t$isG e.toString:;G H@@@;.show:;5 finish:;5 < final )dit-ext number":)dit-ext;findViewById:R.id.number;5 6utton dial":6utton;findViewById:R.id.dial;5 dial.setOnClickListener:new 6utton.OnClickListener:; 8 public void onClick:7iew v; 8 try 8 if :p$oneW"null; 8 p$one.dial:number.getText:;.toString:;;5 < ,%7
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
< catc$ :Dead,bject)xception e; 8 android.util.+o%.e:#DialerDemo#G #)rror in dial:;#G e;5 -oast.makeText:DialerDemo.t$isG e.toString:;G H@@@;.show:;5 < < <;5 6utton call":6utton;findViewById:R.id.call;5 call.setOnClickListener:new 6utton.OnClickListener:; 8 public void onClick:7iew v; 8 try 8 if :p$oneW"null; 8 p$one.call:number.getText:;.toString:;;5 < < catc$ :Dead,bject)xception e; 8 android.util.+o%.e:#DialerDemo#G #)rror in dial:;#G e;5 -oast.makeText:DialerDemo.t$isG e.toString:;G H@@@;.show:;5 < < <;5 < <
We keep the .1$one N %reate near the top o$ onCreate:; N aroun in an instan%e variable in the a%tivity, so Ce on7t keep having to %reate neC .1$one instan%es on every button push #in%e .1$one is, in e$$e%t, an inter$a%e to a servi%e, Ce have to eal Cith the possible Dead,bject)xception i$ the servi%e %onne%tion %ollapse P here, Ce Oust log an isplay an error message
,%9
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
)oCever, the ialer you get $rom %li%king the ial button is better, shoCing you the number you are about to ial*
,,;
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
>r, i$ you %li%k the %all button, you are taken straight to a %all*
,,(
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
CHAPTER '(
>ne o$ the $irms behin the >pen )an set Allian%e N 8oogle N has a teeny Ceeny Web sear%h servi%e, one you might have hear o$ in passing. 8iven that, it7s not surprising that An roi has some amount o$ built3in sear%h %apabilities. #pe%i$i%ally, An roi has Qbake inQ the notion o$ sear%hing not only on the evi%e $or ata, but over the air to .nternet sour%es o$ ata. @our appli%ations %an parti%ipate in the sear%h pro%ess, by triggering sear%hes or perhaps by alloCing your appli%ation7s ata to be sear%he . 0ote that this is $airly neC to the An roi plat$orm, an so some shi$ting in the A!.s is likely. #tay tune $or up ates to this %hapter.
Dunting Season
.$ your a%tivity has an options menu, then you automati%ally QinheritQ a hi en sear%h menu %hoi%e. .$ the user %li%ks the menu button $olloCe by the S key, it Cill isplay the sear%h popup*
,,,
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
!igure 09< The )ndroid search popup6 sho4ing a search for contacts
(rom here, you %an toggle betCeen appli%ations by %li%king the button on the le$t an enter in a sear%h string. .$ the appli%ation you are sear%hing supports a live $iltere sear%h, like the built3in Conta%ts a%tivity, you %an %hoose $rom an entry mat%hing your sear%h string as it appears beloC the sear%h $iel *
,,$
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
>r, you %an %li%k the 8o button an be taken to an a%tivity that Cill pro%ess your sear%h an shoC the results. .$ your a%tivity oes not have an options menu, you Cill nee to trigger this manually by some other user inter$a%e element, su%h as a button. 5hat is simply a matter o$ %alling onSearc$ReJuested:; in your a%tivity &e.g., $rom the button7s %allba%k metho '. .$ your a%tivity oes not nee keyboar entry, you %an have keystrokes pull up the sear%h popup by %alling setDefaultMeyMode:S)ARC3*D)EA2+-*M)FS; in your a%tivity &e.g., in onCreate:;'. 0ote that there are other options $or setDefaultMeyMode:;, su%h as D.A+)R*D)EA2+-*M)FS, Chi%h routes number keypresses to a neCly3laun%he Aialer a%tivity.
Search -ourself
>ver the long haul, there Cill be tCo $lavors o$ sear%h available via the An roi sear%h system*
,,/
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
-.
Huery3style sear%h, Chere the user7s sear%h string is passe to an a%tivity Chi%h is responsible $or %on u%ting the sear%h an isplaying the results
2. (ilter3style sear%h, Chere the user7s sear%h string is passe to an a%tivity on every keypress, an the a%tivity is responsible $or up ating a isplaye list o$ mat%hes #in%e the latter approa%h is un er heavy evelopment right noC by the An roi team, let7s $o%us on the $irst one.
,,0
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
<>xml version"#?.@# encodin%"#utf(A#>& <+inear+ayout xmlns!android"#$ttp!//sc$emas.android.com/apk/res/android# android!orientation"#vertical# android!layout*widt$"#fill*parent# android!layout*$ei%$t"#fill*parent# & <-ext7iew android!id"#9Bid/selection# android!layout*widt$"#fill*parent# android!layout*$ei%$t"#wrap*content# /& <+ist7iew android!id"#9android!id/list# android!layout*widt$"#fill*parent# android!layout*$ei%$t"#fill*parent# android!drawSelector,n-op"#false# /& </+inear+ayout&
.n terms o$ +ava %o e, most o$ the guts o$ the a%tivities are poure into an abstra%t +orem6ase %lass*
packa%e com.commonsware.android.searc$5 import import import import import import import import import import import import import import import import import android.app.Activity5 android.app.+istActivity5 android.app.Searc$Mana%er5 android.content..ntent5 android.os.6undle5 android.view.Menu5 android.view.7iew5 android.wid%et.Adapter7iew5 android.wid%et.ArrayAdapter5 android.wid%et.+istAdapter5 android.wid%et.+ist7iew5 android.wid%et.-ext7iew5 java.io..nputStream5 java.util.Array+ist5 java.util.+ist5 or%.xmlpull.v?.Uml1ull1arser5 or%.xmlpull.v?.Uml1ull1arser)xception5
abstract public class +orem6ase extends +istActivity 8 abstract +istAdapter make'e#n#dapter:.ntent intent;5 private static final int C+,S)*.D " Menu.E.RS-B?5 -ext7iew selection5 Array+ist<Strin%& items"new Array+ist<Strin%&:;5 9,verride public void onCreate:6undle icicle; 8 super.onCreate:icicle;5 setContentView:R.layout.main;5
,,3
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
selection":-ext7iew;findViewById:R.id.selection;5 try 8 Uml1ull1arser xpp"get$esources:;.get,ml:R.xml.words;5 w$ile :xpp.get+ entType:;W"Uml1ull1arser.)/D*D,C2M)/-; 8 if :xpp.get+ entType:;""Uml1ull1arser.S-AR-*-A0; 8 if :xpp.get%ame:;.e-uals:#word#;; 8 items.add:xpp.get#ttri!uteValue:@;;5 < < xpp.next:;5 < catc$ :-$rowable t; 8 show#lert:#)xceptionW#G @G t.toString:;G #Cancel#G true;5 < < on%ewIntent:getIntent:;;5 <
9,verride public void on%ewIntent:.ntent intent; 8 +istAdapter adapter"make'e#n#dapter:intent;5 if :adapter""null; 8 finish:;5 < else 8 setList#dapter:adapter;5 <
<
public void onListItemClick:+ist7iew parentG 7iew vG int positionG lon% id; 8 selection.setText:items.get:position;.toString:;;5 < 9,verride public boolean onCreateOptions'enu:Menu menu; 8 menu.add:@G C+,S)*.DG #Close#G R.drawable.eject; .set#lpha!eticShortcut:ZcZ;5 return:super.onCreateOptions'enu:menu;;5 < 9,verride public boolean onOptionsItemSelected:Menu..tem item; 8 switc$ :item.getId:;; 8 case C+,S)*.D! finish:;5 return:true;5 <
,,7
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
< <
return:super.onOptionsItemSelected:item;;5
5his a%tivity takes %are o$ everything relate to shoCing a list o$ Cor s, even loa ing the Cor s out o$ the EML resour%e. What it oes not o is %ome up Cith the +istAdapter to put into the +ist7iew N that is elegate to the sub%lasses. 5he main a%tivity N +oremDemo N Oust uses a +istAdapter $or the Chole Cor list*
packa%e com.commonsware.android.searc$5 import android.content..ntent5 import android.wid%et.ArrayAdapter5 import android.wid%et.+istAdapter5 public class +oremDemo extends +orem6ase 8 9,verride +istAdapter make'e#n#dapter:.ntent intent; 8 return:new ArrayAdapter<Strin%&:t$isG android.R.layout.simple*list*item*?G items;;5 < <
5he sear%h a%tivity, though, oes things a bit i$$erently. (irst, it inspe%ts the .ntent supplie to the abstra%t makeMeAnAdpater:; metho . 5hat .ntent %omes $rom either onCreate:; or on/ew.ntent:;. .$ the intent is a S)ARC3*AC-.,/, then Ce knoC this is a sear%h. We %an get the sear%h <uery an , in the %ase o$ this silly emo, spin through the loa e list o$ Cor s an $in only those %ontaining the sear%h string. 5hat list then gets Crappe in a +istAdapter an returne $or isplay*
packa%e com.commonsware.android.searc$5 import import import import import android.app.Searc$Mana%er5 android.content..ntent5 android.wid%et.ArrayAdapter5 android.wid%et.+istAdapter5 java.util.Array+ist5
,,9
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
import java.util.+ist5 public class +oremSearc$ extends +orem6ase 8 9,verride +istAdapter make'e#n#dapter:.ntent intent; 8 +istAdapter adapter"null5 if :intent.get#ction:;.e-uals:.ntent.S)ARC3*AC-.,/;; 8 Strin% Juery"intent.getString+xtra:Searc$Mana%er.T2)RF;5 +ist<Strin%& results"searchItems:Juery;5 adapter"new ArrayAdapter<Strin%&:t$isG android.R.layout.simple*list*item*?G results;5 setTitle:#+oremSearc$ for! #BJuery;5 < < return:adapter;5
private +ist<Strin%& searchItems:Strin% Juery; 8 +ist<Strin%& results"new Array+ist<Strin%&:;5 for :Strin% item ! items; 8 if :item.indexOf:Juery;&(?; 8 results.add:item;5 < < < < return:results;5
,$;
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
<activity android!name"#.+oremSearc$# android!label"#+oremSearc$# android!launc$Mode"#sin%le-op#& <intent(filter& <action android!name"#android.intent.action.S)ARC3# /& <cate%ory android!name"#android.intent.cate%ory.D)EA2+-# /& </intent(filter& <meta(data android!name"#android.app.searc$able# android!resource"#9xml/searc$able# /& </activity& </application& </manifest&
5he %hanges that are nee e are* -. 5he +oremDemo main a%tivity gets a meta(data element, Cith an android!name o$ android.app.default*searc$able an a android!value o$ the sear%h implementation %lass &.+oremSearc$'
+oremSearc$ a%tivity gets an intent $ilter android.intent.action.S)ARC3, so sear%h intents Cill be pi%ke up
2. 5he
$or
?. 5he +oremSearc$ a%tivity is set to have android!launc$Mode " #sin%le-op#, Chi%h means at most one instan%e o$ this a%tivity Cill be open at any time, so Ce on7t Cin up Cith a Chole bun%h o$ little sear%h a%tivities %luttering up the a%tivity sta%k =. 5he +oremSearc$ a%tivity gets a meta(data element, Cith an android!name o$ android.app.searc$able an a android!value o$ an EML resour%e %ontaining more in$ormation about the sear%h $a%ility o$$ere by this a%tivity &9xml/searc$able' 5hat EML resour%e provi es tCo bits o$ in$ormation to ay* -. What name shoul appear in the sear%h omain button to the le$t o$ the sear%h $iel , i enti$ying to the user Chere she is sear%hing
2. What hint te;t shoul appear in the sear%h $iel , to give the user a %lue as to Chat they shoul be typing in
,$(
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
Try It 0ut
8iven all that, sear%h is noC available N An roi knoCs your appli%ation is sear%hable, Chat sear%h omain to use Chen sear%hing $rom the main a%tivity, an the a%tivity knoCs hoC to o the sear%h. .$ you pop up the sear%h $rom the main a%tivity &MenuBS', you Cill see the Lorem .psum sear%h omain appear as your e$ault area to sear%h*
!igure 3(< The orem sample application6 sho4ing the search popup
5yping in a letter or tCo, then %li%king 8o, Cill bring up the sear%h a%tivity an the subset o$ Cor s %ontaining Chat you type , Cith your sear%h <uery in the a%tivity title bar*
,$%
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
!igure 3%< The results of searching for AcoA in the orem search sample
,$,
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
APPE"DI? A
.n several %hapters o$ this book, Ce use 5our.t as a sour%e o$ sample %o e $or $eatures ranging $rom %ontent provi ers to mapping an lo%ation servi%es. 5his appen i; is%usses the appli%ation as a Chole, so you %an see all $a%ets o$ it $rom $ront to ba%k.
8nstalling Tour8t
.nstalling the appli%ation itsel$ is straight$orCar * Cith the emulator running, $ire up ant install in the base o$ the 5our.t proOe%t ire%tory, an let Ant o the heavy li$ting. )oCever, 5our.t has tCo other re<uirements N a emo lo%ation provi er an an #A %ar image N that are someChat more %ompli%ate to install.
5his means, though, that you Cill probably Cant to install this emo lo%ation provi er yoursel$, so the 5our.t appli%ation7s tour lines up Cith a lo%ation provi er. .n the proOe%t7s location/velo/ ire%tory, you Cill $in three $iles*
location,
this tra%k
properties,
Chi%h es%ribes the %hara%teristi%s o$ this lo%ation provi er &e.g., oesn7t support altitu e, has a loC poCer re<uirement'
track,
Chi%h is the a%tual roster o$ time o$$sets $rom the starting time an the position the evi%e is in at that point, e$ine as latitu e an longitu e
5o install this lo%ation provi er in your emulator, o the $olloCing* -. "se adb s$ell to %reate a velo/ ire%tory un er /data/misc/location/ &e.g., adb s$ell #mkdir /data/misc/location/velo#'
2. "se adb pus$ to push ea%h o$ those three $iles into your neCly %reate ire%tory ?. Restart your emulator At this point, $or 5our.t an any other lo%ation3aCare appli%ation on your emulator, you Cill be able to use both the built3in $ake 8!# ata an this neC QveloQ set o$ $ake 8!# ata.
,$7
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
(or the purposes o$ this early in%arnation o$ 5our.t, you Cill nee an #A %ar image you %an use Cith the An roi emulator an uploa a tour there, be$ore the 5our.t appli%ation Cill be use$ul. 5o %reate an #A %ar image, use the mksdcard tool supplie by the An roi #AF. .n this %ase, though, a small #A %ar image is supplie as sdcard.im% in the 5our.t proOe%t ire%tory Cith the sample %o e $or this book. 5o use that %ar in the emulator, pass the (sdcard sCit%h Cith a path to the image $ile*
emulator (sdcard pat$/to/sdcard.im%
2unning Tour8t
Like most An roi laun%her* appli%ations, 5our.t is available $rom the An roi
!igure 3,< The )ndroid launcher6 sho4ing the Tour8t main activity ,$9
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
% in Activity
5he main a%tivity provi es tCo istin%t s%reens* -. A Qhome pageQ shoCing version in$ormation an some navigation buttons
5he three navigation buttons shoCn on the home page are upli%ate in the options menu, along Cith a Close menu %hoi%e to proa%tively e;it the a%tivity*
,/;
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
.$ you %li%k on the shoC3tours button, you Cill see a list o$ available tours. .$ your #A %ar image is mounte properly, 5our.t shoul automati%ally $in the sample tour Chen it laKy3%reates its atabase, so you shoul see*
,/(
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
,/%
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
As mentione , the most important setting to %hange is the lo%ation provi er, using the supplie spinner. .$ you uploa e the mo%k provi er es%ribe earlier in this appen i;, the QveloQ lo%ation provi er shoul be liste N %hoose it. /eyon that, you %an %on$igure*
Whether 5our.t starts Cith the Qhome pageQ or the list o$ tours Chen you %li%k the i%on $rom the laun%her Whether your %urrent lo%ation shoul be shoCn on the map, an i$ the map shoul s%roll to $olloC your lo%ation as you move What shoul happen Chen you near a Caypoint on a tour you are taking N play a soun , vibrate, or both, an Chether it shoul o that on%e or %ontinuously Chile you are near the Caypoint
,/,
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
5he starting point is the $irst entry, %alle a QCaypointQ. #ubse<uent Caypoints are given base on a ire%tion $rom the pre%e ing Caypoint N $or e;ample, $rom )amilton /lv . at Mosser, you Cill travel 0.2 miles an make a le$t at the stop sign to turn onto Weilers R . .$ you %hoose one o$ the Caypoints in the list, a panel Cill appear toCar s the bottom shoCing more etails about that Caypoint*
,/$
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
5here are several bits o$ in$ormation that %an appear in this panel. "se the le$t an right buttons on the A3pa to rotate betCeen them, or %he%k the QAnimate etailsQ %he%kbo; at the bottom to have them s%roll by automati%ally. 5he other %he%kbo; at the bottom, QAlert near CaypointQ, means you Cant the evi%e to beep or buKK Chen you are near the Caypoint. @ou Coul turn this on i$ you Cere a%tually taking the tour shoCn on this %ue sheet, to help let you knoC you are nearing a pla%e Chere you nee to turn or stop.
% p Activity
5he options menu $rom the %ue sheet a%tivity in%lu es one to spaCn a map shoCing your lo%ation an the lo%ation o$ the Caypoints on the tour*
,//
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
@our position is shoCn by the re ot &i$ you enable that in the %on$iguration'. 5he Caypoints are shoCn by numbere ots, starting Cith $or the $irst Caypoint. .$ you turne on the $olloC3me $eature in the %on$iguration, the map Cill shi$t to shoC your position no matter Chere you go on the map. 5he options menu $or this a%tivity has a $eC istin%tive %hoi%es*
,/0
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
!igure 7(< The Tour8t map vie46 4ith options menu displayed
5he Q#hoC !i%kerQ menu %hoi%e Cill bring up a spinner an button, alloCing you to %hoose a Caypoint an Oump to that lo%ation. 0ote, hoCever, i$ you are set Cith $olloC3me turne on, it Cill then pop the map ba%k to your %urrent lo%ation. 5he Q(ull MapQ menu %hoi%e Cill laun%h the built3in An roi map a%tivity on your %urrent lo%ation, to a%%ess mapping $eatures not available in 5our.t7s oCn simpli$ie map vieC.
the ability to up ate the lo%ation is provi e . @ou %an get to this via the "p ate menu %hoi%e $rom the %ue sheet*
,ia the spinner, you %an %hoose a Caypoint. 5hen, you %an up ate the istan%e travelle along the %ourse $rom the pre%e ing Caypoint to here, an %li%k Q(ill .n My Lo%ation:Q to up ate the latitu e, longitu e, an &in theory' elevation o$ your position. When one, %hoose #ave $rom the option menu to save your %hanges ba%k out to the tour $or later reuse.
Help Activity
5our.t also provi es a very limite amount o$ online help, to e;plain hoC to use the appli%ation. Choosing the )elp option menu %hoi%e $rom any a%tivity takes you to online help $or that a%tivity*
,/7
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
Tour8tAs *anifest
5our.t has a someChat more %ompli%ate AndroidManifest.xml $ile than the rest o$ the samples shoCn in this book*
<manifest xmlns!android"#$ttp!//sc$emas.android.com/apk/res/android# packa%e"#com.commonsware.tourit#& <uses(permission android!name"#android.permission.ACC)SS*+,CA-.,/# /& <uses(permission android!name"#android.permission.ACC)SS*01S# /& <uses(permission android!name"#android.permission.ACC)SS*ASS.S-)D*01S# /& <uses(permission android!name"#android.permission.ACC)SS*C)++*.D# /& <application android!icon"#9drawable/w$eel#& <provider android!name"#.1rovider# android!aut$orities"#com.commonsware.android.tourit.1rovider# /& <activity android!name"#.-our+istActivity# android!label"#-our.tW#& <intent(filter& <action android!name"#android.intent.action.MA./# /& <cate%ory android!name"#android.intent.cate%ory.+A2/C3)R# /& </intent(filter& </activity& <activity android!name"#.-our7iewActivity#& <intent(filter& <action android!name"#android.intent.action.7.)C# /& <cate%ory android!name"#android.intent.cate%ory.D)EA2+-# /& <data android!mime-ype"#vnd.android.cursor.item/vnd.commonsware.tour# /&
,/9
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
</intent(filter& </activity& <activity android!name"#.-our)ditActivity#& <intent(filter& <action android!name"#android.intent.action.)D.-# /& <cate%ory android!name"#android.intent.cate%ory.D)EA2+-# /& <data android!mime-ype"#vnd.android.cursor.item/vnd.commonsware.tour# /& </intent(filter& </activity& <activity android!name"#.-ourMapActivity#& </activity& <activity android!name"#.Confi%Activity# android!label"#-our.tW ( Confi%uration#& </activity& <activity android!name"#.3elpActivity# android!label"#-our.tW ( 3elp#& </activity& </application& </manifest&
0e;t, Ce Cire in the %ontent provi er, supplying ata about the available tours to our a%tivities. (inally, Ce es%ribe all the available a%tivities. >ne N -our+istActivity N is set to appear in the appli%ation7s laun%h menu. 5Co others N -our7iewActivity an -our)ditActivity N are available to be laun%he by intents looking to manipulate ata supplie by our %ontent provi er. 5he rest are simply liste Cithout an intent $ilter, so they %an only be a%%esse via their %lass names.
Tour8tAs Content
5our.t7s %ontent is %omprise o$ tours. 5ours are ma e up o$ Caypoints an ire%tions betCeen them. Waypoints an ire%tions ea%h have is%rete bits o$ ata, su%h as the %oor inates o$ Caypoint an the istan%e to travel $or a ire%tion. Later, tours an their Caypoints Cill also have multime ia %lips, either to shoC o$$ $eatures o$ a given lo%ation, or to help gui e travelers through tri%ky ire%tions.
,0;
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
D t Stor !e
8iven that 5our.t Cill eventually have multime ia %lips, an given that An roi 7s approa%h is to store su%h %lips in the $ile system, an sin%e %lips %oul be big, 5our.t assumes the e;isten%e o$ an #A %ar %ontaining the tours. Right noC, ea%h tour gets its oCn ire%tory on the %ar , %ontaining a +#>0 ata stru%ture &tour.js' Cith the tour etails &e.g., Caypoints'. Later, those ire%tories Cill also hol the me ia %lips asso%iate Cith that tour. 5here is also a #HLite atabase, Cith a tours table, to hol the master roster o$ available tours. 5his eliminates the nee to s%an the #A %ar Oust to populate the list o$ available tours. More importantly, it makes $or a better sample appli%ation $or this book.
Content Provider
5he #HLite atabase is manage by an An roi %ontent provi er, %unningly name 1rovider. Right noC, it only eals Cith a single table N tours N Chi%h %ontains the roster o$ all available tours, loa e o$$ the #A %ar . Iventually, the provi er might be e;pan e to en%ompass other tables, shoul that prove ne%essary.
%odel Cl sses
An roi appli%ations ten not to map all that %leanly to the mo el3vieC3 %ontroller &M,C' ar%hite%ture popular in 8". evelopment. An a%tivity ten s to blen both elements o$ the vieC &e.g., setting up an managing Ci gets' an %ontroller &han ling menu %hoi%es, button %li%ks, et%.'. An some An roi appli%ations use the Q umb mo elQ approa%h, putting business logi% in the a%tivity an using the %ontent provi er as Oust a ata store. 5our.t7s $irst step on the roa to a %leaner M,C implementation are the mo el %lasses* -our, Caypoint, an Direction. 5he -our %lass knoCs hoC to rea an Crite the +#>0 ata stru%ture an turn that into tour in$ormation, plus the Caypoints an Directions that make up the guts o$ the tour itsel$.
,0(
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
>ver time, more an more logi% Cill move into the mo els, leaving the %ontent provi er still as a umb store, but trying to make the a%tivity more o$ a thin %ontroller.
Tour8tAs )ctivities
5our.t breaks its user inter$a%e up into a series o$ a%tivities, ea%h %overing a i$$erent $a%et o$ Corking Cith tours*
-our+istActivity
your lo%ation
alloCs you to up ate lo%ation in$ormation $or a tour, base on An roi 7s reporte lo%ation
-our)ditActivity 3elpActivity
5our.t Corks $or you 5his se%tion isn7t going to go through these a%tivities line3by3line, but instea Cill highlight a $eC interesting bits that shoC o$$ various An roi $eatures.
Tour=istActivity
han les both the home page an the list o$ installe tours. 5o o this, it uses 7iewElipper N think o$ it as the guts o$ a -abActivity, minus the tabs. 8iven a 7iewElipper an the appropriate means to get $rom vieC to vieC, this shoCs hoC you %an buil an arbitrarily %omple; a%tivity instea o$ treating ea%h in ivi ual a%tivity as a separate %onstru%t.
-our+istActivity
.n the layout &res/layout/main.xml', Ce e%lare a 7iewElipper. Ia%h %hil element o$ the 7iewElipper represents a separate QpageQ to be $lippe
,0%
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
betCeen. @ou $lip betCeen them via the %hil 7s @3base in e;, as illustrate in s$ow+ist:;, Chi%h toggles the vieC to the list o$ available tours*
private void showList:; 8 flipper.setDisplayedChild:@;5 setTitle:#-our.tW ( -ours#;5 if :flipMenuW"null; 8 flipMenu.setTitle:#0o 3ome#;5 flipMenu.setIcon:R.drawable.$ome;5 < <
5he tour list itsel$ is a simple +ist7iew, ba%ke by a SimpleCursorAdapter, in turn ba%ke by the %ontent provi er. )oCever, Ce o tailor the look o$ the in ivi ual list entries, by re$eren%ing our oCn layout &res/layout/tourlist*item.xml'*
<>xml version"#?.@# encodin%"#utf(A#>& <-ext7iew xmlns!android"#$ttp!//sc$emas.android.com/apk/res/android# android!id"#9android!id/text?# android!layout*widt$"#fill*parent# android!layout*$ei%$t"#>android!attr/list1referred.tem3ei%$t# android!textAppearance"#>android!attr/textAppearance+ar%e.nverse# android!%ravity"#center*vertical# android!paddin%+eft"#Ldip# /&
Tour@ie#Activity
At B00V lines o$ %o e, -our7iewActivity is $ar an aCay the most %ompli%ate %lass in all o$ 5our.t. .t han les isplaying the %ue sheet plus noti$ying users Chen they approa%h a Caypoint. )ere are a $eC o$ the interesting $a%ets o$ this %lass, besi es the lo%ation servi%es o%umente in a previous %hapter*
,0,
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
5he problem is that there are several $lavors o$ vieC that goes into the list*
5he typi%al ire%tion plus Caypoint title 5he $irst entry, Chi%h is Oust the starting Caypoint Cith no ire%tion Intries Chere the Caypoint has a note &e.g., tra$$i% alert' that %alls $or a tCo3line isplay
5our.t makes a simpli$ying assumption* the $irst Caypoint has no note. 8iven that, Ce have the three s%enarios liste above &versus having a $ourth, Chere the $irst entry is a tCo3line variant'.
RouteAdapterD%etEirst7iew:; han &res/layout/tourview*std.xml' an
private 7iew get"irstView:7iew convert7iew; 8 7iew.nflate inflater"context.getViewInflate:;5 7iew view"inflater.inflate:R.layout.tourview*stdG nullG null;5 -ext7iew label":-ext7iew;view.findViewById:R.id.waypoint;5 label.setText:tour.get$oute:;.get:@;.getTitle:;;5 < return:view;5
han les the typi%al s%enario, in%lu ing %onverting %o es in the tour7s +#>0 into resour%es to isplay turn arroCs, signs, et%.*
RouteAdapterD%etStandard7iew:;
private 7iew getStandardView:Caypoint ptG boolean stripeG 7iew convert7iew; 8 7iew.nflate inflater"context.getViewInflate:;5 7iew view"inflater.inflate:R.layout.tourview*stdG nullG null;5 -ext7iew distance":-ext7iew;view.findViewById:R.id.distance;5 .ma%e7iew turn":.ma%e7iew;view.findViewById:R.id.turn;5 .ma%e7iew marker":.ma%e7iew;view.findViewById:R.id.marker;5 -ext7iew waypoint":-ext7iew;view.findViewById:R.id.waypoint;5 distance.setText:distanceEormat.format:pt.getCumulati eDistance:;;;5 turn.setImage$esource:get$esource"orTurn:pt.get"romDirection:;.getTurn:;;;5 if :pt.get"romDirection:;.get'arker:;W"null; 8
,0$
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
Clearly, some re$a%toring is %alle $or here to re u%e %o e upli%ation. 5his is le$t as an e;er%ise $or the rea er, or eventually $or the author.
*etails Panel
5he etails panel N the bla%k panel that is isplaye Chen you sele%t an entry in the %ue sheet N is a 7iewElipper. .n the layout &res/layout/view.xml', it is set to be invisible &android!visibility " #invisible#', Chi%h is Chy it oes not shoC up at $irst. 5hen, Chen you sele%t an item, it is ma e visible again &details1anel.set7isibility:7.S.6+);' an is $ille in Cith the etails $or that CaypointU ire%tion pair, in the on.temSelected:; metho .
,0/
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
5o
support
pages
o$
the
etails
panel,
public boolean on1ey)p:int keyCodeG Mey)vent event; 8 if :keyCode""Mey)vent.M)FC,D)*D1AD*+)E- VV keyCode""Mey)vent.M)FC,D)*D1AD*R.03-; 8 stop#nimation:;5 if :keyCode""Mey)vent.M)FC,D)*D1AD*+)E-; 8 details1anel.setIn#nimation:Animation2tils.load#nimation:t$isG R.anim.pus$*ri%$t*in;;5 details1anel.setOut#nimation:Animation2tils.load#nimation:t$isG R.anim.pus$*ri%$t*out;;5 if :details1anel.getDisplayedChild:;""@; 8 details1anel.setDisplayedChild:details1anel.getChildCount:;(?;5 < else 8 details1anel.setDisplayedChild:details1anel.getDisplayedChild:;(?;5 <
< <
return:super.on1ey)p:keyCodeG event;;5
>r, the %he%kbo; %an toggle automati% animation, %ourtesy o$ the $lipping $eatures built into 7iewElipper*
private void start#nimation:; 8 details1anel.start"lipping:;5 isElippin%"true5 < private void stop#nimation:; 8 details1anel.stop"lipping:;5 isElippin%"false5 <
,00
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
Tour% pActivity
5he guts o$ -ourMapActivity are %overe e;tensively in the %hapter on mapping servi%es an are not repeate here $or brevity.
TourEditActivity
/y an large, -our)ditActivity is Oust a $orm $or the user to $ill in Caypoint etails. 5Co things are interesting here. (irst, $or the istan%e travele $iel , Ce use a %ustom Eloat.nputMet$od %lass, that %onstrains input to be positive or negative $loating3point numbers*
class Eloat.nputMet$od extends /umber.nputMet$od 8 private static final Strin% C3ARS"#@?HINLS]AR(.#5 protected c$arOP get#cceptedChars:; 8 return:C3ARS.toChar#rray:;;5 <
<
Also, Chen the Q(ill .n My Lo%ation:Q button is %li%ke , Ce o Oust that N $in the %urrent lo%ation an $ill in the latitu e, longitu e, an elevation $iel s a%%or ingly, as is es%ribe in the %hapter on lo%ation servi%es.
HelpActivity
5he 3elpActivity is a thin shell aroun the WebFit broCser. .t loa s stati% )5ML out o$ the proOe%t7s assets/ ire%tory, Chi%h is re$eren%e in %o e as file!///android*assets, as shoCn beloC*
9,verride public void onCreate:6undle icicle; 8 super.onCreate:icicle;5 setContentView:R.layout.$elp;5 browser":Ceb7iew;findViewById:R.id.browser;5 browser.set*e!ViewClient:new Call!ack:;;5 browser.getSettings:;.setDefault"ontSi2e:browser.getSettings:;.getDefault"ontS i2e:;BN;5
,03
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
<
/y e$ault, it Cill loa the home page. .$, hoCever, the a%tivity Cas starte by another a%tivity that passe in a spe%i$i% page to vieC, it loa s that page instea . hooks into the WebFit broCser to ete%t %li%ks on links. #in%e the only links in the help are to other help pages, it simply loa s in the re<ueste page*
3elpActivity
private class Callback extends Ceb7iewClient 8 public boolean shouldO erride)rlLoading:Ceb7iew viewG Strin% url; 8 view.load)rl:url;5 < < return:true;5
Con,i!Activity
5he Confi%Activity %lass mostly loa s ata out o$ pre$eren%es, up ates the layout7s Ci gets to mat%h, then reverses the pro%ess Chen the a%tivity is pause &e.g., Chen the user %li%ks Close $rom the options menu'. 5he most interesting thing here is the spinner o$ lo%ation provi ers N this is %overe in etail in the %hapter on lo%ation servi%es.
,07
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
@ey4ord 8ndex
Class
AbsoluteLayout.......................................................14 A%tionIvent.............................................................20 A%tionListener.........................................................20 A%tivity. .8, 48, -0-, --2, --8, -24, -28, -?2, -?2, -=2, -2?, -2=, 204, 202 A%tivityA apter................................48, 220, 22?, 22B A%tivity.%onA apter........................................48, 220 A%tivityManager.....................................................-2? A apter..................................................................220 A apter,ieC...........................................................-0AlertAialog.......................................................--8, --1 AnalogClo%k............................................................88 ArrayA apter.................44, 42, 41, 22, -=4, 281, ?4= ArrayList.................................................................-=4 Au ioAemo............................................................?-4 AutoComplete.........................................................21 AutoComplete5e;t,ieC..............................??, 28380 /aseColumns.........................................................2B2 /o;............................................................................=-
/o;Layout.................................................................=/uil er..............................................................--8, --1 /un le................................-??, -?=, 20-, 2-0, 24=, 222 /utton...........................2?, 2B328, ?0, ?-, -BB, -B1, ?22 Calen ar..................................................................84 Canvas............................................................?08, ?01 Char#e<uen%e.......................................................248 Che%k/o;......................................................?=, ?2, ?1 Chrono.....................................................................8= Clo%ks......................................................................88 Component0ame...................................22=, 22B, 22B Compoun /utton...................................................?2 Con%urrentLinke Hueue......................................24B Con$igA%tivity.................282, 281, 21-, ?0B, ?42, ?48 ContentManager...................................................280 Content>bserver...........................................2B=, 2BB Content!rovi er................-2?, -2=, -22, 2?8, 2?1, 2=? ContentResolver.....................................2?2, 2?1, 2B= Content,alues..................-2B, 2?2, 2?8, 2=2, 2=1, 2B? Conte;t..........................44, --8, -?2, -=2, -2?, -2=, 2?=
,09
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
@ey4ord 8ndex
Conte;tMenu...................................................-00, -0Conte;tMenu.n$o...................................................-0Criteria...................................................210, 212, ?04 Critieria..........................................................210, 212 Cursor....42, -21, -80, 2?-, 2??32?2, 2?1, 2=4, 2=2, 2B? CursorA apter.........................................................42 Cursor(a%tory..................................................-2?, -80 AatabaseContent!rovi er.....................2=?, 2==, 2B2 Aatabase)elper.....................................................2== Aate(ormat.............................................................84 Aate!i%ker...............................................................8? Aate!i%kerAialog..............................................8?, 84 Aea >bOe%tI;%eption...................................224, ?21 Aialer......................................................................?22 Aialog.....................................................................-28 AigitalClo%k............................................................88 Aire%tion.........................................................2?2, ?4Ao%ument..............................................................-=4 Aouble...................................................................201 AraCable..............................................82, 1?, -B8, 28I it,ieC.....................................?-, ?2, 28, 21, 8?, 2?I;pan ableList,ieC...............................................14 (iel .........................................................................?2 (loat.nputMetho .................................................?42 (loCLayout..............................................................=2 (ol er......................................................................-1B (ore%ast...................................................................-1(rameLayout.......................................................1-31? 8allery................................................................4B, 82 8etMetho ......................................................-88, -10 8ri ..........................................................................2B 8ri ,ieC......................................................2=, 2B, 82 )an ler......................................-2?3-28, -??, 21B, 214 )elpA%tivity...................................201, ?42, ?42, ?48 )ttpClient.......................................................-883-10 )ttpMetho ...........................................................-88 ./in er...........................................................244, 22B .mage/utton..............................................?-, -B8, -B1 .mages.....................................................................-B8 .mage,ieC..........................................?-, -B8, 2=0, ?-= .nputMetho ...........................................................?2 .nput#tream...............................-=?, -=4, -=2, -88, -1.nput#treamRea er................................................-=2 .ntent......10, ---, --2, 220, 22?322B, 2=?, 22?, 22B, 222, 28-, 212321B, ?0B, ?-=, ??1 .ntentRe%eiver...............................................20B, 204 .!hone....................................................?24, ?28, ?21 .terator...................................................................2?B +/utton................................................................20, 2+Che%k/o;...............................................................44 +Combo/o;..............................................................20 +Label.......................................................................44 +List..........................................................................44 +5abbe !ane...........................................................10 +5able.......................................................................44 Label........................................................................?0 Laun%h....................................................................2-0 Linear.......................................................................=B LinearLayout...........................................=-3=4, B8, 1? List............................................48, -02, 22B, 248, 281 ListA%tivity..........................................48, 41, 12, 211
,3;
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
@ey4ord 8ndex
ListA apter..............................................14, 220, ??1 ListCellRen erer.....................................................44 ListAemo................................................................-0= List,ieC. . .48, 20, 2-, 82, -02, -88, 220, 2??, 2?=, 211, ??4, ??1, ?4? Lo%ation.........................................................-81, 210 Lo%ation.ntentRe%eiver........................................?04 Lo%ationManager...................2883210, 212, 21?, ?0B Lo%ation!rovi er...................2883210, 212, 214, 212 Lorem.....................................................................??4 Lorem/ase..............................................................??2 LoremAemo....................................................??1, ?=Lorem#ear%h..........................................................?=Mail/uKK...........................-8B, -1?, 24?, 24B, 22?, 22= Mail/uKK#ervi%e....................................24?, 24=, 242 MailClient..............................................................-1= Map............................................-?=, -?2, -2B, 2?2, 248 MapA%tivity....................................................2113?0MapController........................................?0-, ?02, ?0B Map,ieC........................................................2113?0= Me iaController............................................?22, ?2= Me ia!layer......................................?-B, ?-4, ?-1, ?20 Menu.........................................................18, -00, 22? Menu..tem.................................................113-0-, 22B Menus.....................................................................-02 Message..............................................--1, -2=, -24, -22 MessageCountListener..........................................-1= MyA%tivity.............................................................22= 0oti$i%ation............................................24?, 280, 280oti$i%ationManager.....................................280, 280oC...............................................................-1, 22, 28 0oCRe u;................................................................22 >bOe%t......................................................................-0>nChe%ke ChangeListener................?=, ?B, =8, -=0 >nCli%kListener............................20, 84, -2-, -=0, 2->nCompletionListener.........................................?-1 >nAate#etListener...........................................8=, 84 >n.tem#ele%te Listener.........................................22 >n!opulateConte;tMenuListener.................-0-, -0? >n!repare Listener..............................................?-1 >n5ime#etListener..........................................8=, 84 >utput#tream........................................................-=2 >utput#treamWriter.............................................-=2 >verlay...........................................................?08, ?-0 >verlayController.................................................?08 !a%kageManager....................................................22B !ar%elable..............................................................248 !i%k.................................................................2-4, 2B8 !i%kAemo..............................................................2B8 !i;elCal%ulator................................................?083?-0 !i;elConverter.......................................................?01 !oint..................................................?02, ?0?, ?013?-!ostMetho ............................................................-88 !re$s........................................................................-?1 !rogress/ar........................................10, -2B, -24, -21 !rovi er....................................2??, 2==, 2=232B2, ?4!rovi erWrapper..................................................281 !ro;imity.ntentRe%eiver.......................................21= Ra io/utton..................................................?23=-, =4 Ra io8roup..........................?2, ?8, =0, =-, =4, =8, =1 Rea Write...............................................................-=2
,3(
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
@ey4ord 8ndex
Re%t(........................................................................?-Relative.....................................................................B? RelativeLayout.............................=-, B0, B-, B=, BB, B1 Resour%es.........................................................-=?, -4RouteA apter........................................................?4= Route>verlay..........................................?08, ?01, ?-Runnable..............................11, -00, -2?, -2=, -22, -28 #%roll........................................................................40 #%roll,ieC....................................................=-, 40, 42 #e%rets!rovi er......................................................2=2 #e%urityI;%eption.................................................2B8 #ervi%e...........................................................24=, 241 #ervi%eConne%tion.........................................22=3224 #ession....................................................................-1B #hare !re$eren%es..................................................-?8 #impleA apter........................................................42 #impleCursorA apter.............................2??32?B, ?4? #panne ...........................................................-B?, -B= #pinner....................................20, 2-, 28, 82, 220, 2?? #HLiteAatabase...............................................-2?3-2B #HLiteHuery/uil er........................-243-28, 2=4, 2=2 #tati%................................................................-==, -4#tore........................................................................-1B #tring11, --8, --1, -?2, -B=, -B4, -88, 2-0, 2?-, 2=4, 248 #trings.....................................................................-B= 5ab...........................................................................12 5abA%tivity.................................................12, 1=, ?42 5ab)ost..............................................................1-31= 5able........................................................................B1 5ableLayout..................................................=-, B43B1 5ableRoC............................................................B43B8 5ab#pe%..............................................................1?, 1= 5abWi get..........................................................1-31? 5e;t,ieC.....24, 213?-, ?=, ?2, 42, 22, 84, 12, 2?=, ??4 5e;tWat%her......................................................21, 80 5ime!i%ker........................................................8?, 8= 5ime!i%kerAialog.......................................8?, 8=, 84 5imer5ask..............................................................244 5oast..............................................--2, --8, -2-, -10, ?-5our...........................................2?2, 2??, 2?4, 2?2, ?45ourI itA%tivity.....................2?8, 21-, ?40, ?42, ?42 5our.t.....................................................................?00 5ourListA%tivity..............................2?2, 2?=, ?40, ?42 5ourMapA%tivity.....?00, ?0=, ?0B, ?02, ?08, ?42, ?42 5our,ieCA%tivity. . .2?2, 2??, 282, 28?, 21?, 21=, ?40, ?42, ?4?, ?44 ".5hrea "tilities............................................-2?, -28 "ri..........?-, -B8, -28, 200, 20-, 20?320B, 202, 201, 2--, 2-B32-2, 220, 22=, 22132?2, 2?232=?, 2=432B2, 2B=, 2BB, 280, ?-=, ?-B ,i eoAemo............................................................?2? ,i eo,ieC.......................................................?2-3?2= ,ieC..........2?, 24, 22, ?1, B8, 42, -0-, --8, -2?, -22, -28 ,ieC(lipper............................................?42, ?4B, ?44 Waypoint.........................................................2?2, ?4Weather..................................................................-88 WeatherAemo.......................................................-10 WebFit............................................................-88, -10 Web#ettings............................................................--= Web,ieC..............................................-023-01, ---3--B Web,ieCClient.................................................--2, --? Eml!ull!arser..................................................-4-, -42
,3%
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
@ey4ord 8ndex
Command
a b pull...................................................................-8a b push..................................................-8-, ?2?, ?=8 a b shell.........................................................-80, ?=8 ant..........................................................................8, 1 ant install...............................................................?=2 e;...................................................................-8B, -84 s<lite?.....................................................................-80
Constant
ACCI##WA##.#5IAW8!#......................................288 ACCI##WCILLW.A.................................................288 ACCI##W8!#.........................................................288 ACCI##W!>#.5.>0.............................................288 AL5IR0A5IWCA5I8>R@....................................22? AL5IR0A5.,I...............................................20-, 22= AL5IR0A5.,IWCA5I8>R@........................202, 22= A0#WIRWAC5.>0...............................................20/.0AWA"5>WCRIA5I.........................................22B /R>W#A/LIWCA5I8>R@...................................202 CALLWAC5.>0......................................................20C>05I05W"R......................................................2B= AI(A"L5................................................................20AI(A"L5WCA5I8>R@..................................202, 22B AILI5I....................................................-2B, -24, 2?1 AILI5IWAC5.>0.................................................20A.ALWAC5.>0.......................................................20A.ALIRWAI(A"L5WFI@#.....................................??B IA.5WAC5.>0...............................................2003202 I0AWA>C"MI05................................................-4-
.0/>E....................................................................-1B .0#IR5.....................................................-22, -2B, -24 .0#IR5WAC5.>0..................................................20.05I8IR................................................................-22 LAR8IR...................................................................--B LA"0C)IR...................................................20-, 20= LA"0C)IRWCA5I8>R@.....................................202 LI085)WL>08.....................................................--8 LI085)W#)>R5...................................................--8 MA.0.....................................................................20= MA.0WAC5.>0.............................................20-, 202 MA5C)WAI(A"L5W>0L@...................................22B MIA.AWM>"05IAWAC5.>0............................202 0"LL.......................................................................-2B >RAIR /@..............................................................2?!IRM.##.>0WAI0.IA.........................................24!IRM.##.>0W8RA05IA.....................................24!.CFWAC5.>0.........................2003202, 2-0, 2?-, 2=? !.CFWAC5.,.5@WAC5.>0.....................20-, 2-4, 2-2 !>LL..............................................................244, 241 !>#5......................................................................-88
,3,
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
@ey4ord 8ndex
!RI(IRI0CIWCA5I8>R@..................................202 !R>+IC5.>0.........................................................2?2 R...............................................................................22 RIAAWC>05AC5#................................................2B8 RICI.,IW#M#.......................................................242 RI#"L5WCA0CILLIA..........................................2-0 RI#"L5W(.R#5W"#IR...........................................2-0 RI#"L5W>F.............................................2-0, 2-4, 2-2 R"0WAC5.>0.......................................................20#IARC)WAC5.>0.........................................20-, ??1 #ILIC5..............................................-22, -24, -28, -21 #ILIC5IAWAL5IR0A5.,IWCA5I8>R@............202 #I0AWAC5.>0......................................................20#I0A5>WAC5.>0................................................20#MALLI#5..............................................................--B #5AR5W5A8.....................................................-4-, -42 #"0AA@..................................................................8= #@0CWAC5.>0.....................................................202 5A/WCA5I8>R@...................................................202 5A8WAC5.>0........................................................22? 5I#5WCA5I8>R@.................................................202 5IE5.......................................................................-45.5LI.....................................................................2?= "!AA5I............................................-2B, -24, 2?2, 2?8 ,IR5.CAL...............................................................=2 ,.IWWAC5.>0.......................200, 202, 201, 2-2, ?-= WI/W#IARC)WAC5.>0......................................202 W)IRI................-2B3-28, 2?-, 2?8, 2?1, 2=4, 2=132Ba a a a a a a a &'..................................................................18, 11 . &'...................................................................2?0 .ntent>ptions&'................................-00, 22?322B Menu&'.............................................................-00 !ro;imityAlert&'..............................................21? #eparator&'.......................................................-00 #ubMenu&'.......................................................-00 5ab&'..................................................................1=
appen Where&'......................................................-28 apply(ormat&'........................................................-B4 applyMenuChoi%e&'...............................................-0= be$ore5e;tChange &'..............................................80 bin #ervi%e&'..................................................22B, 224 broa %ast.ntent&'....................................2-0, 24-, 242 broa %ast.ntent#erialiKe &'..................................2-0 buil (ore%asts&'.....................................................-10 buil Huery&'..........................................................-28 bulk.nsert&'............................................................2?8 %all&'................................................................?243?28 %an%el&'...........................................................280, 28%an8o/a%k&'............................................................--%an8o/a%k>r(orCar &'..........................................--%an8o(orCar &'......................................................--%enterMap5o&'.......................................................?02 %he%k&'...............................................................?2, ?8 %he%kA%%ount&'.............................................241, 220 %he%kA%%ount.mpl&'.............................................220 %he%kCalling!ermission&'.....................................24%lear&'.....................................................................-?8
ðod
%learCa%he&'.............................................................---
,3$
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
@ey4ord 8ndex
%learChe%k&'............................................................?2 %lear)istory&'..........................................................--%lose&'................................................-=2, -2=, -21, -80 %ommit&'.................................................................-?8 %ommit"p ates&'...........................................-80, 2?2 %ount&'....................................................................-21 %reate&'....................................................................--1 %reateAatabase&'..............................................-2?, -8elete&'.....................................-2B, -24, 2?1, 2B0, 2B2 eleteAatabase&'....................................................-2= elete.nternal&'.....................................................2B2 eleteRoC&'............................................................-80 ial&'...............................................................?243?28 raC&'............................................................?08, ?01 raCCir%le&'...........................................................?01 raC5e;t&'.............................................................?01 e it&'.......................................................................-?8 enable&'..........................................................248, 222 enable!oll&'...........................................................220 en Call&'................................................................?24 e<uery&'..................................................................-21 e;e%#HL&'........................................................-2=, -2B $in ,ieC/y. &'........................22, 28, =0, 1=, -=?, ?0$inish&'............................................................-=0, -=1 $irst&'...............................................................-21, 2?B generate!age&'........................................................-1get&'.........................................................................-2B getAltitu e&'..........................................................210 getAs.nteger&'.........................................................-2B getAs#tring&'..........................................................-2B getAttributeCount&'..............................................-42 getAttribute0ame&'...............................................-42 get/earing&'...........................................................210 get/est!rovi er&'..................................................210 get/oolean&'...........................................................-?8 getChe%ke Ra io/utton. &'...................................?2 getColle%tion5ype&'...............................................2BgetColumn.n e;&'.................................................-21 getColumn0ames&'...............................................-21 getContent!rovi er&'............................................2?8 getContentResolver&'.....................................2?2, 2B= getCurrentLo%ation&'............................................210 get(loat&'...............................................................2?4 get.MA!Message. s&'............................................-1B get.nput#tream&'...................................................2?1 get.nt&'............................................................-21, 2?4 get.ntent&'.............................................................??4 getLastFnoCn!osition&'.......................................210 getLatitu e&'..........................................................-81 getLo%ation&'.........................................................-81 getLongitu e&'.......................................................-81 getMapCenter&'.....................................................?0? getMapController&'................................................?0getMessage. s&'.....................................................-1B get0ame&'.............................................................281 get>utput#tream&'...............................................2?1 get!a%kageManager&'............................................22B get!arent&'...............................................................?1 get!arent>$5ype&'..................................................=0 get!ointE@&'..........................................................?01
,3/
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
@ey4ord 8ndex
get!oll#tate&'.........................................................220 get!>!?Message. s&'............................................-1B get!re$eren%es&'..............................................-?2, -?8 get!rogress&'...........................................................10 get!rovi ers&'........................................................281 getRe<uire Columns&'.........................................2=1 getResour%es&'........................................................-=? getRoot,ieC&'.........................................................=0 get#ettings&'............................................................--= get#hare !re$eren%es&'...................................-?2, -?8 get#ingle5ype&'......................................................2Bget#pee &'.............................................................210 get#tring&'.........................................-B?, -B4, -21, 2?4 get#tringArray&'.....................................................-4B get5itle&'................................................................2?2 get5ype&'.........................................................2B-, 2B2 get,ieC&'....................................................42, 22, 2?B getEml&'..................................................................-4go/a%k&'...................................................................--go/a%k>r(orCar &'................................................--go(orCar &'.............................................................--han leMessage&'.............................................-2=, -24 hasAltitu e&'.........................................................210 has/earing&'..........................................................210 has#pee &'.............................................................210 in%rement!rogress/y&'...........................................10 insert&'......................-2B, 2?8, 2=B, 2=8, 2=1, 2B2, 2B? insert.nternal&'......................................................2B2 isA$terLast&'....................................................-21, 2?4 is/e$ore(irst&'........................................................2?4 isChe%ke &'........................................................?=, ?2 isColle%tion"ri&'............................................2=8, 2B0 isInable &'.......................................................?1, 224 is(irst&'...................................................................2?4 is(o%use &'..............................................................?1 isLast&'...................................................................2?4 is0ull&'...................................................................2?4 is>$$hook&'............................................................?24 is#atellite&'.............................................................?0= is#treet,ieC&'........................................................?0= is5ra$$i%&'...............................................................?0= is".5hrea &'...........................................................-28 last&'.......................................................................2?B loa Aata&'.......................................................-01, --0 loa 5ime&'..............................................................--? loa "rl&'...........................................................-083--0 makeMeAnA pater&'............................................??1 make5e;t&'..............................................................--8 manage Huery&'.............................................2?-32?= move&'....................................................................2?4 move5o&'................................................................2?4 neCCursor&'...........................................................-80 neC5ab#pe%&'....................................................1?, 1= ne;t&'........................................................-4-, -21, 2?4 noti$y&'...........................................................280, 28noti$yChange&'...............................................2B=, 2BB obtainMessage&'.....................................................-2= onA%tivityResult&'..........................................2-0, 2-4 on/in &'........................................................244, 241 onChe%ke Change &'................................?B, =8, -=2
,30
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
@ey4ord 8ndex
onCli%k&'.............................................................20, 2onComplete5haC&'.........................................-??, -?= onConte;t.tem#ele%te &'...............................-0-, -0= onCreate&' 20, 2-, 24, 22, ?8, =8, 18, -0?, -08, -?23-?=, -=0, -=4, -B4, -10, 2?=, 2==, 2B2, 24=3244, ?0?, ?-0, ?21, ??B, ??4, ??1 onCreate>ptionsMenu&'...................18, -00, -0-, -0= onCreate!anelMenu&'...........................................-00 onAestroy&'.....................................-?=, -=0, 24=, 244 on(reeKe&'........................................................-??, -?= on.tem#ele%te &'...................................................?4B onFey"p&'.............................................................?44 onList.temCli%k&'...................................................41 on0eC.ntent&'...............................................??4, ??1 on>ptions.tem#ele%te &'.........................113-0-, -0= on!age#tarte &'......................................................--2 on!ause&'..........................-??, -?=, -=0, -=1, 204, 24= on!opulateConte;tMenu&'....................................-0onRe%eive )ttpAuthRe<uest&'.............................--2 onRe%eive.ntent&'.........................................20B, 204 onRestart&'.............................................................-?= onResume&' -??, -?=, -=0, -=1, -81, 204, 24=, 21-, ?0B on#ear%hRe<ueste &'............................................??B on#ervi%eConne%te &'...................................22B, 224 on#ervi%eAis%onne%te &'..............................22B, 224 on#tart&'....................................-24, -22, -??, 24=, 222 on#top&'....................................................-??, -?=, -=0 on5ap&'.............................................................?-0, ?-on5e;tChange &'....................................................80 on5ooManyRe ire%ts&'...........................................--2 openAatabase&'......................................................-2? open(ile.nput&'..............................................-=2, -=1 open(ile>utput&'...........................................-=2, -=1 openRaCResour%e&'...............................................-=? pause&'............................................................?-B, ?2= play&'......................................................................?2= populateAe$ault,alues&'......................................2=1 populateMenu&'..............................................-0?, -0= position&'...............................................................2?4 post&'...............................................................-22, -28 postAelaye &'.........................................................-22 prepare&'.................................................................?-B prepareAsyn%&'........................................?-B, ?-1, ?20 prev&'......................................................................2?4 put.nt&'..................................................................2?2 put#tring&'.............................................................2?2 <uery&'.......................-243-28, -80, 2=4, 2=2, 2B2, 2B? <uery.ntentA%tivity>ptions&'..............................22B <uery.nternal&'......................................................2B2 raCHuery&'.....................................................-24, -80 registerContent>bserver&'...................................2B= register.ntent&'......................................................204 releaseConne%tion&'..............................................-88 reloa &'....................................................................--remove&'.................................................................-?8 remove!ro;imityAlert&'........................................21? remove"p ates&'...................................................212 re<uery&'.........................................................-80, 2?2 re<uest(o%us&'.........................................................?1 re<uest"p ates&'...........................................212, ?0B run>n".5hrea &'..................................................-28
,33
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
@ey4ord 8ndex
sen Message&'........................................................-2= sen MessageAt(ront>$Hueue&'...........................-2= sen MessageAt5ime&'...........................................-2= sen MessageAelaye &'..........................................-2= setA%%ura%y&'........................................................210 setA apter&'...........................................48, 20, 2B, 28 setAlphabeti%#hort%ut&'.........................................11 setAltitu eRe<uire &'...........................................210 setCellRen erer&'....................................................44 setChe%ke &'.......................................?=, ?8, -=2, 224 setColumnCollapse &'............................................B1 setColumn#hrinkable&'..........................................B1 setColumn#tret%hable&'.........................................B1 setContent&'......................................................1?, 1= setContent,ieC&'..............................................20, =0 setCostAlloCe &'...................................................210 setCurrent5ab&'......................................................1= setAata#our%e&'......................................................?-B setAe$ault(ont#iKe&'...............................................--B setAe$aultFeyMo e&'............................................??B setAropAoCn,ieCResour%e&'................................20 setAuration&'..........................................................--8 setInable &'............................................................?1 set(antasy(ont(amily&'..........................................--= set(olloCMyLo%ation&'.........................................?0B set8ravity&'..............................................................== set8roupChe%kable&'.......................................18, 11 set)ea er&'............................................................-00 set.%on&'..................................................................--1 set.mage"R.&'..........................................................?set.n i%ator&'....................................................1?, 1= set.temChe%kable&'................................................11 set+ava#%riptCan>penWin oCsAutomati%ally&'. --B set+ava#%riptInable &'...........................................--B setLayout,ieC&'......................................................24 setListA apter&'......................................................41 setMessage&'...........................................................--1 set0egative/utton&'...............................................--1 set0eutral/utton&'.................................................--1 set0umeri%#hort%ut&'............................................11 set>nCli%kListener&'.......................................20, -=1 set>nCompletionListener&'..................................?-1 set>n.tem#ele%te Listener&'.....................48, 20, 2B set>n!opulateConte;tMenuListener&'................-0set>n!repare Listener&'.......................................?-1 set>rientation&'......................................................=2 set!a ing&'............................................................==
set!ositive/utton&'.................................................--1 set!rogress&'...........................................................10 set!roOe%tionMap&'................................................-28 setHCertyMo e&'...................................................11 setResult&'..............................................................2-0 set5e;t&'....................................................................2set5e;t#iKe&'............................................................--B set5itle&'.................................................................--1 set5ype$a%e&'...........................................................2= setup&'.............................................................1=, ?20 setup5imer&'..........................................24B, 244, 220 set"seAesktop"serAgent&'....................................--B set,ieC&'.................................................................--8
,37
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
@ey4ord 8ndex
setWeb,ieCClient&'...............................................--2 shoul >verri e"rlLoa ing&'...........................--2, --? shoC&'.................................................--8, --1, -2-, ?2= shoCList&'..............................................................?4? shoC0oti$i%ation&'................................................282 sRa io>n&'............................................................?24 start&'......................................................................?-B startA%tivity&'.........................................201, 2-0, 220 start#ervi%e&'.........................................................222 start#ubA%tivity&'...........................................2-0, 2-4 stop&'...............................................................?-B, ?20 stop!layba%k&'.......................................................?2= stop#ervi%e&'..........................................................222 support"p ates&'...................................................-21 sCit%h&'..................................................................-00 toggle&'...............................................................?=, ?2 toggleI geMooming&'...........................................?02 toggleRa io>n>$$&'..............................................?24 toggle#atellite&'.....................................................?0= toggle#treet,ieC&'................................................?0= toggle5ra$$i%&'........................................................?0= to#tring&'.........................................................44, 281 unbin #ervi%e&'.....................................................224 unregisterContent>bserver&'...............................2BB unregister.ntent&'.................................................204 up ate&'.............................-2B, -24, 2?2, 2?8, 2=132B? up ate.nt&'.............................................................-80 up ate.nternal&'....................................................2B2 up ateLabel&'..........................................................84 up ate#tring&'.......................................................-80 up ate5ime&'..........................................................20 up ate,ieC&'.........................................................?02 upgra eAatabases&'..............................................2B2 Koom5o&'................................................................?0-
Property
an roi *authorities........................................2B?, 2B= an roi *auto5e;t......................................................?an roi *ba%kgroun ...............................................?1 an roi *%apitaliKe....................................................?an roi *%ollapseColumns.......................................B1 an roi *%olumnWi th............................................2= an roi *%ompletion5hreshol ...............................28 an roi * igits...........................................................?an roi * raC#ele%tor>n5op.............................2-, 82 an roi *horiKontal#pa%ing.....................................2= an roi *i .....................................2B, 24, ?2, B-, 1-31? an roi *in eterminate...........................................10 an roi *in eterminate/ehavior............................10 an roi *inputMetho .............................................?2 an roi *label............................................................-? an roi *layoutWabove..............................................B2 an roi *layoutWalign/aseline.................................B2 an roi *layoutWalign/ottom..................................B2 an roi *layoutWalignLe$t........................................B2 an roi *layoutWalign!arent/ottom........................Ban roi *layoutWalign!arentLe$t..............................Ban roi *layoutWalign!arentRight...........................Ban roi *layoutWalign!arent5op.........................B-, BB an roi *layoutWalignRight......................................B2
,39
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition
@ey4ord 8ndex
an roi *layoutWalign5op...................................B2, B? an roi *layoutWbeloC.............................................B2 an roi *layoutW%enter)oriKontal...........................Ban roi *layoutW%enter.n!arent...............................Ban roi *layoutW%enter,erti%al................................Ban roi *layoutW%olumn...........................................B2 an roi *layoutWgravity............................................== an roi *layoutWheight...........................2B, =?, B?, 12 an roi *layoutWspan...............................................B2 an roi *layoutWtoLe$t.............................................B2 an roi *layoutWtoRight...........................................B2 an roi *layoutWCeight............................................=? an roi *layoutWCi th............................2B, =?, =2, B? an roi *mani$est......................................................-2 an roi *ma;.....................................................10, -2B an roi *name.............................-?, 2B?, 2B8, 220, ?=an roi *ne;t(o%usAoCn........................................?1 an roi *ne;t(o%usLe$t............................................?1 an roi *ne;t(o%usRight.........................................?1 an roi *ne;t(o%us"p.............................................?1 an roi *numColumns.............................................2= an roi *numeri%......................................................?an roi *orientation................................................=2 an roi *pa an roi *pa an roi *pa an roi *pa an roi *pa ing................................................==, =B ing/ottom.........................................=B ingLe$t...............................................=B ingRight.............................................=B ing5op.........................................=B, 12
an roi *passCor .....................................................?an roi *permission........................................240, 22an roi *phone0umber...........................................?2 an roi *progress.....................................................10 an roi *shrinkColumns..........................................B8 an roi *singleLine.............................................?-, ?2 an roi *spa%ing.......................................................82 an roi *spinner#ele%tor.........................................82 an roi *sr%...............................................................?an roi *stret%hColumns.........................................B8 an roi *stret%hMo e..............................................2= an roi *te;t.......................................................2B, 21 an roi *te;tColor..............................................?0, ?= an roi *te;t#tyle................................................21, ?an roi *type$a%e.....................................................21 an roi *value.........................................................?=an roi *verti%al#pa%ing..........................................2= an roi *visibility.....................................................?1
,7;
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition