You are on page 1of 400

The Busy Coder's Guide to Android Development

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.

Subscribe to updates at http://commonsware.com

Special Creative Commons BY-SA 3.0 License Edition

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

Subscribe to updates at http://commonsware.com

Special Creative Commons BY-SA 3.0 License Edition

Welcome to the Warescription!

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

Welcome to the Book!


5hanks: 5hanks $or your interest in eveloping appli%ations $or An roi : .n%reasingly, people Cill a%%ess .nternet3base servi%es using so3%alle Qnon3tra itionalQ means, su%h as mobile evi%es. 5he more Ce o in that spa%e noC, the more that people Cill help invest in that spa%e to make it easier to buil more poCer$ul mobile appli%ations in the $uture. An roi is neC N at the time o$ this Criting, there are no shipping An roi 3poCere evi%es N but it likely Cill rapi ly groC in importan%e ue to the siKe an s%ope o$ the >pen )an set Allian%e. An , most o$ all, thanks $or your interest in this book: . sin%erely hope you $in it use$ul an at least o%%asionally entertaining.

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

Book Bug Bounty


(in a problem in one o$ our booksD Let us knoC: /e the $irst to report a uni<ue %on%rete problem, an Ce7ll give you a %oupon $or a si;3month Wares%ription as a bounty $or helping us eliver a better pro u%t. @ou %an use that %oupon to get a neC Wares%ription, reneC an e;isting Wares%ription, or give the %oupon to a $rien , %olleague, or some ran om person you meet on the subCay. /y Q%on%reteQ problem, Ce mean things like*

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

Source Code icense


5he sour%e %o e samples shoCn in this book are available $or oCnloa $rom the CommonsWare Web site. All o$ the An roi proOe%ts are li%ense un er the Apa%he 2.0 Li%ense, in %ase you have the esire to reuse any o$ it.

Creative Commons and the !our"to"!ree #$%!& 'uarantee


Ia%h CommonsWare book e ition Cill be available $or use un er the Creative Commons Attribution30on%ommer%ial3#hare Alike ?.0 li%ense as o$ the $ourth anniversary o$ its publi%ation ate, or Chen =,000 %opies o$ the e ition have been sol , Chi%hever %omes $irst. 5hat means that, on%e $our years have elapse &perhaps sooner:', you %an use this prose $or non3 %ommer%ial purposes. 5hat is our (our3to3(ree 8uarantee to our rea ers an the broa er %ommunity. (or the purposes o$ this guarantee, neC Wares%riptions an reneCals Cill be %ounte as sales o$ this e ition, starting $rom the time the e ition is publishe . 5his e ition o$ this book Cill be available un er the a$orementione Creative Commons li%ense on ;uly !? ,8!,. >$ %ourse, Cat%h the CommonsWare Web site, as this e ition might be reli%ense sooner base on sales. (or more etails on the Creative Commons Attribution30on%ommer%ial3 #hare Alike ?.0 li%ense, visit the Creative Commons Web site. 0ote that $uture e itions o$ this book Cill be%ome $ree on later ates, ea%h $our years $rom the publi%ation o$ that e ition or base on sales o$ that spe%i$i% e ition. Releasing one e ition un er the Creative Commons li%ense oes not automati%ally release all e itions un er that li%ense.

xviii
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition

PART I Core Concepts

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

The Big Picture

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
(

Subscribe to updates at http://commonsware.com

Special Creative Commons BY-SA 3.0 License Edition

The Big Picture

!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'
%

Subscribe to updates at http://commonsware.com

Special Creative Commons BY-SA 3.0 License Edition

The Big Picture

@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.

What )ndroids )re *ade +f


When you Crite a esktop appli%ation, you are Qmaster o$ your oCn omainQ. @ou laun%h your main Cin oC an any %hil Cin oCs N like ialog bo;es N that are nee e . (rom your stan point, you are your oCn Corl , leveraging $eatures supporte by the operating system, but largely ignorant o$ any other program that may be running on the %omputer at the same time. .$ you o intera%t Cith other programs, it is typi%ally through an A!., su%h as using +A/C &or $rameCorks atop it' to %ommuni%ate Cith My#HL or another atabase. An roi has similar %on%epts, but pa%kage make phones more %rash3resistant. i$$erently, an stru%ture to

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

The Big Picture

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

The Big Picture

Stuff )t -our .isposal


Stor !e
@ou %an pa%kage ata $iles Cith your appli%ation, $or things that o not %hange, su%h as i%ons or help $iles. @ou also %an %arve out a small bit o$ spa%e on the evi%e itsel$, $or atabases or $iles %ontaining user3entere or retrieve ata nee e by your appli%ation. An , i$ the user supplies bulk storage, like an #A %ar , you %an rea an Crite $iles on there as nee e .

"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

The Big Picture

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

Subscribe to updates at http://commonsware.com

Special Creative Commons BY-SA 3.0 License Edition

Pro1ect Structure

The S4eat +ff -our Bro4


When you %reate the proOe%t &e.g., via activityCreator.py', you supplie the $ully3<uali$ie %lass name o$ the QmainQ a%tivity $or the appli%ation &e.g., com.commonsware.android.SomeDemo'. @ou Cill then $in that your proOe%t7s src/ tree alrea y has the namespa%e ire%tory tree in pla%e, plus a stub Activity sub%lass representing your main a%tivity &e.g., src/com/commonsware/ android/SomeDemo.java'. @ou are Cel%ome to mo i$y this $ile an a others to the src/ tree as nee e to implement your appli%ation. 5he $irst time you %ompile the proOe%t &e.g., via ant', out in the QmainQ a%tivity7s namespa%e ire%tory, the An roi buil %hain Cill %reate R.java. 5his %ontains a number o$ %onstants tie to the various resour%es you pla%e out in the res/ ire%tory tree. @ou shoul not mo i$y R.java yoursel$, letting the An roi tools han le it $or you. @ou Cill see throughout many o$ the samples Chere Ce re$eren%e things in R.java &e.g., re$erring to a layout7s i enti$ier via R.layout.main'.

)nd 5o46 The 2est of the Story


@ou Cill also $in that your proOe%t has a res/ ire%tory tree. 5his hol s Qresour%esQ N stati% $iles that are pa%kage along Cith your appli%ation, either in their original $orm or, o%%asionally, in a prepro%esse $orm. #ome o$ the sub ire%tories you Cill $in or %reate un er res/ in%lu e*
res/drawable/ res/layout/ res/raw/

$or images &!08, +!I8, et%.'

$or EML3base ". layout spe%i$i%ations

$or general3purpose $iles &e.g,. a C#, $ile o$ a%%ount in$ormation'


res/values/

$or strings, imensions, an the like

res/xml/ $or other general3purpose EML $iles you Cish to ship

We Cill %over all o$ these, an more, in later %hapters o$ this book.

7
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition

Pro1ect Structure

What -ou 'et +ut +f 8t


When you %ompile your proOe%t &via ant or the .AI', the results go into the bin/ ire%tory un er your proOe%t root. #pe%i$i%ally*
bin/classes/

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

Subscribe to updates at http://commonsware.com

Special Creative Commons BY-SA 3.0 License Edition

CHAPTER '

8nside the *anifest

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.

8n The Beginning6 There Was the 2oot6 )nd 8t Was 'ood


5he root o$ all mani$est $iles is, not surprisingly, a manifest element*
((
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition

8nside the *anifest

<manifest xmlns!android"#$ttp!//sc$emas.android.com/apk/res/android# packa%e"#com.commonsware.android.searc$#& ... </manifest&

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.

Permissions6 8nstrumentations6 and )pplica" tions #+h6 *y!&


"n erneath the manifest element, you Cill $in *
uses(permission

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
(%

Subscribe to updates at http://commonsware.com

Special Creative Commons BY-SA 3.0 License Edition

8nside the *anifest

<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$.

-our )pplication .oes Something6 2ight:


5he real meat o$ the mani$est $ile are the %hil ren o$ the application element. /y e$ault, Chen you %reate a neC An roi proOe%t, you get a single activity element*
<manifest xmlns!android"#$ttp!//sc$emas.android.com/apk/res/android# packa%e"#com.commonsware.android.skeleton#& <application& <activity android!name"#./ow# android!label"#/ow#& <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&

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

8nside the *anifest

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

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 (

Creating a Skeleton )pplication

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.

Begin at the Beginning


5o Cork Cith anything in An roi , you nee a proOe%t. With or inary +ava, i$ you Cante , you %oul Oust Crite a program as a single $ile, %ompile it Cith javac, an run it Cith java, Cithout any other support stru%tures. An roi is more %omple;, but to help keep it manageable, 8oogle has supplie tools to help %reate the proOe%t. .$ you are using an An roi 3enable .AI, su%h as I%lipse Cith the An roi plugin, you %an %reate a proOe%t insi e o$ the .AI &e.g., sele%t 4ile @ >e0 @ Pro"ect, then %hoose Android @ Android Pro"ect'. .$ you are using tools that are not An roi 3enable , you %an use the activityCreator.py s%ript, $oun in the tools/ ire%tory in your #AF installation. +ust pass activityCreator.py the pa%kage name o$ the a%tivity
(3
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition

Creating a Skeleton )pplication

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

Creating a Skeleton )pplication

<

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.

.issecting the )ctivity


Let7s e;amine this pie%e by pie%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

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

Creating a Skeleton )pplication

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

Creating a Skeleton )pplication

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.

Building and 2unning the )ctivity


5o buil the a%tivity, either use your .AI7s built3in An roi pa%kaging tool, or run ant in the base ire%tory o$ your proOe%t. 5hen, to run the a%tivity*

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

!igure (< The )ndroid application =launcher=

>pen that appli%ation

%(
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition

Creating a Skeleton )pplication

@ou shoul see an a%tivity s%reen akin to*

!igure %< The 5o4 demonstration activity

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 )

>sing ?* "Based ayouts

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.

What 8s an ?* "Based ayout:


As the name suggests, an EML3base layout is a spe%i$i%ation o$ Ci gets7 relationships to ea%h other N an to %ontainers N en%o e in EML $ormat. #pe%i$i%ally, An roi %onsi ers EML3base layouts to be resour%es, an as su%h layout $iles are store in the res/layout ire%tory insi e your An roi proOe%t. Ia%h EML $ile %ontains a tree o$ elements spe%i$ying a layout o$ Ci gets an %ontainers that make up one 7iew. 5he attributes o$ the EML elements are properties, es%ribing hoC a Ci get shoul look or hoC a %ontainer shoul behave. (or e;ample, i$ a 6utton element has an attribute value o$ android!textStyle " #bold#, that means that the te;t appearing on the $a%e o$ the button shoul be ren ere in a bol $a%e $ont style.
%,
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition

>sing ?* "Based ayouts

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 .

Why >se ?* "Based ayouts:


Most everything you o using EML layout $iles %an be a%hieve through +ava %o e. (or e;ample, you %oul use set-ypeface:; to have a button ren er its te;t in bol , instea o$ using a property in an EML layout. #in%e EML layouts are yet another $ile $or you to keep tra%k o$, Ce nee goo reasons $or using su%h $iles. !erhaps the biggest reason is to assist in the %reation o$ tools $or vieC e$inition, su%h as a 8". buil er in an .AI like I%lipse or a e i%ate An roi 8". esigner like Aroi AraC. #u%h 8". buil ers %oul , in prin%iple, generate +ava %o e instea o$ EML. 5he %hallenge is re3rea ing the e$inition in to support e its N that is $ar simpler i$ the ata is in a stru%ture $ormat like EML than in a programming language. Moreover, keeping the generate bits separate out $rom han 3Critten %o e makes it less likely that somebo y7s %ustom3%ra$te sour%e Cill get %lobbere by a%%i ent Chen the generate bits get re3generate . EML $orms a ni%e mi le groun betCeen something that is easy $or tool3Criters to use an easy $or programmers to Cork Cith by han as nee e . Also, EML as a 8". e$inition $ormat is be%oming more %ommonpla%e. Mi%roso$t7s EAML, A obe7s (le;, an MoKilla7s E"L all take a similar approa%h to that o$ An roi * put layout etails in an EML $ile an put programming smarts in sour%e $iles &e.g., +avas%ript $or E"L'. Many less3 Cell3knoCn 8". $rameCorks, su%h as MF, also use EML $or vieC e$inition. While Q$olloCing the her Q is not ne%essarily the best poli%y, it oes have the a vantage o$ helping to ease the transition into An roi $rom any other EML3%entere vieC es%ription language.

%$
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition

>sing ?* "Based ayouts

+@6 So What .oes 8t ook ike:


)ere is the 6utton $rom the previous %hapter7s sample appli%ation, %onverte into an EML layout $ile*
<>xml version"#?.@# encodin%"#utf(A#>& <6utton xmlns!android"#$ttp!//sc$emas.android.com/apk/res/android# android!id"#9Bid/button# android!text"## android!layout*widt$"#fill*parent# android!layout*$ei%$t"#fill*parent#/&

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.

Cill inherit that

/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

>sing ?* "Based ayouts

#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.

WhatAs With the B Signs:


Many Ci gets an %ontainers only nee to appear in the EML layout $ile an o not nee to be re$eren%e in your +ava %o e. (or e;ample, a stati% label &-ext7iew' $re<uently only nee s to be in the layout $ile to in i%ate Chere it shoul appear. 5hese sorts o$ elements in the EML $ile o not nee to have the android!id attribute to give them a name. Anything you do Cant to use in your +ava sour%e, though, nee s an android!id. 5he %onvention is to use 9Bid/... as the id value, Chere the ... represents your lo%ally3uni<ue name $or the Ci get in <uestion. .n the EML layout e;ample in the pre%e ing se%tion, 9Bid/button is the i enti$ier $or the 6utton Ci get. provi es a $eC spe%ial android!id values, o$ the $orm 9android!id/... N Ce Cill see some o$ these in various %hapters o$ this book. An roi

)nd We )ttach These to the Cava<<<Do4:


8iven that you have painstakingly set up the Ci gets an %ontainers $or your vieC in an EML layout $ile name snicklefrit'.xml store in res/layout, all you nee is one statement in your a%tivity7s onCreate:; %allba%k to use that layout* 5his is the same set+ayout7iew:; Ce use earlier, passing it an instan%e o$ a 7iew sub%lass &in that %ase, a 6utton'. 5he An roi 3built 7iew, %onstru%te
%0
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition

>sing ?* "Based ayouts

$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.

The 2est of the Story


.n the original /ow emo, the button7s $a%e Coul shoC the %urrent time, Chi%h Coul re$le%t Chen the button Cas last pushe &or Chen the a%tivity Cas $irst shoCn, i$ the button ha not yet been pushe '. Most o$ that logi% still Corks, even in this revise emo & /owRedux'. )oCever, rather than instantiating the 6utton in our a%tivity7s onCreate:; %allba%k, Ce %an re$eren%e the one $rom the EML layout*
packa%e com.commonsware.android.layouts5 import import import import import android.app.Activity5 android.os.6undle5 android.view.7iew5 android.wid%et.6utton5 java.util.Date5

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

<

public void onClick:7iew view; 8 %3


Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition

>sing ?* "Based ayouts

updateTime:;5 < private void updateTime:; 8 btn.setText:new Date:;.toString:;;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*

!igure ,< The 5o42edux sample activity

%7
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition

CHAPTER *

Employing Basic Widgets

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

Subscribe to updates at http://commonsware.com

Special Creative Commons BY-SA 3.0 License Edition

Employing Basic Widgets

android!textColor to set the $ormat &e.g., DEE@@@@ $or re '

%olor o$ the label7s te;t, in R8/ he;

(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

!igure $< The abel.emo sample application

Button6 Button6 WhoAs 'ot the Button:


We7ve alrea y seen the use o$ the 6utton Ci get in the previous tCo %hapters. As it turns out, 6utton is a sub%lass o$ -ext7iew, so everything is%usse in the pre%e ing se%tion in terms o$ $ormatting the $a%e o$ the button still hol s.
,;
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition

Employing Basic Widgets

!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.

!ields of 'reen< +r +ther Colors<


Along Cith buttons an labels, $iel s are the thir Qan%horQ o$ most 8". toolkits. .n An roi , they are implemente via the )dit7iew Ci get, Chi%h is a sub%lass o$ the -ext7iew use $or labels. Along Cith the stan ar -ext7iew properties &e.g., android!textStyle', has many others that Cill be use$ul $or you in %onstru%ting $iel s, in%lu ing*
)dit7iew android!auto-ext, to %ontrol i$ the $iel spelling assistan%e

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 a%%ept only %ertain igits

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

Employing Basic Widgets

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

Employing Basic Widgets

5he result, on%e built an installe into the emulator, is*

!igure /< The !ield.emo sample application

>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

Employing Basic Widgets

Cust )nother Box to Check


5he %lassi% %he%kbo; has tCo states* %he%ke an un%he%ke . Cli%king the %he%kbo; toggles betCeen those states to in i%ate a %hoi%e &e.g., QA rush elivery to my or erQ'. .n An roi , there is a C$eck6ox Ci get to meet this nee . .t has -ext7iew as an an%estor, so you %an use -ext7iew properties like android!textColor to $ormat the Ci get. Within +ava, you %an invoke*
isC$ecked:; to setC$ecked:;

etermine i$ the %he%kbo; has been %he%ke or un%he%ke

state

to $or%e the %he%kbo; into a %he%ke

to%%le:; to toggle the %he%kbo; as i$

the user %he%ke it

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

Employing Basic Widgets

setContentView:R.layout.main;5 cb":C$eck6ox;findViewById:R.id.c$eck;5 cb.setOnCheckedChangeListener:t$is;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 < < <

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

Employing Basic Widgets

!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

Employing Basic Widgets

Turn the 2adio >p


As Cith other implementations o$ ra io buttons in other toolkits, An roi 7s ra io buttons are tCo3state, like %he%kbo;es, but %an be groupe su%h that only one ra io button in the group %an be %he%ke at any time. Like C$eck6ox, Radio6utton inherits $rom Compound6utton, Chi%h in turn inherits $rom -ext7iew. )en%e, all the stan ar -ext7iew properties $or $ont $a%e, style, %olor, et%. are available $or %ontrolling the look o$ ra io buttons. #imilarly, you %an %all isC$ecked:; on a Radio6utton to see i$ it is sele%te , to%%le:; to sele%t it, an so on, like you %an Cith a C$eck6ox. Most times, you Cill Cant to put your Radio6utton Ci gets insi e o$ a 5he Radio0roup in i%ates a set o$ ra io buttons Chose state is tie , meaning only one button out o$ the group %an be sele%te at any time. .$ you assign an android!id to your Radio0roup in your EML layout, you %an a%%ess the group $rom your +ava %o e an invoke*
Radio0roup. c$eck:; to %he%k a %roup.c$eck:R.id.rb?;' clearC$eck:;

spe%i$i% ra io button via its .A &e.g.,

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

Employing Basic Widgets

<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*

!igure 7< The 2adioButton.emo sample application

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

Employing Basic Widgets

8tAs Fuite a Gie4


All Ci gets, in%lu ing the ones shoCn above, e;ten 7iew, an as su%h give all Ci gets an array o$ use$ul properties an metho s beyon those alrea y es%ribe .

+se,ul Properties
#ome o$ the properties on 7iew most likely to be use in%lu e*

Controls the $o%us se<uen%e*


android!nextEocusDown android!nextEocus+eft android!nextEocusRi%$t android!nextEocus2p

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

%ontainers that make up an

the parent Ci get or %ontainer


,9

Subscribe to updates at http://commonsware.com

Special Creative Commons BY-SA 3.0 License Edition

Employing Basic Widgets

%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:;

a %hil Ci get Cith a %ertain .A

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 -

Working 4ith Containers

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

Working 4ith Containers

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

Working 4ith Containers

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

Working 4ith Containers

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

Working 4ith Containers

!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

Working 4ith Containers

<>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

Working 4ith Containers

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

public class implements Radio0roup Radio0roup

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

Working 4ith Containers

< <

.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*

!igure (;< The inear ayout.emo sample application6 as initially launched

.$ Ce toggle on the Qverti%alQ ra io button, the top Radio0roup a Ousts to mat%h*

$7
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition

Working 4ith Containers

!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

Working 4ith Containers

!igure (,< The same application6 4ith the vertical and right radio buttons selected

)ll Things )re 2elative


Relative+ayout,

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

Working 4ith Containers

Positions Relative to Container


5he easiest relations to set up are tying a Ci get7s position to that o$ its %ontainer*
android!layout*ali%n1arent-op

says the Ci get7s top shoul

align

Cith the top o$ the %ontainer

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

says the Ci get positione horiKontally at the %enter o$ the %ontainer

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'.

Relative Notation in Properties


5he remaining properties o$ relevan%e to Relative+ayout take as a value the i entity o$ a Ci get in the %ontainer. 5o o this* -. !ut i enti$iers &android!id attributes' on all elements that you Cill nee to a ress, o$ the $orm 9Bid/...

/(
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition

Working 4ith Containers

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.

Positions Relative to Other Widgets


5here are $our properties that %ontrol position o$ a Ci get vis a vis other Ci gets*

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

in i%ates that the baselines o$ the tCo

Ci gets shoul be aligne

/%
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition

Working 4ith Containers

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

Working 4ith Containers

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

Working 4ith Containers

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

Working 4ith Containers

!igure ($< The 2elative ayout.emo sample application

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

Working 4ith Containers

Putting Cells in Rows


RoCs are e%lare by you, the eveloper, by putting Ci gets as %hil ren o$ a -ableRow insi e the overall -able+ayout. @ou, there$ore, %ontrol ire%tly hoC many roCs appear in the table. 5he number o$ %olumns are etermine number o$ %olumns in an in ire%t $ashion. by An roi P you %ontrol the

(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

Working 4ith Containers

.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.

Non-Row Children of Ta le!ayout


0ormally, -able+ayout %ontains only -ableRow elements as imme iate %hil ren. )oCever, it is possible to put other Ci gets in betCeen roCs. (or those Ci gets, -able+ayout behaves a bit like +inear+ayout Cith verti%al orientation. 5he Ci gets automati%ally have their Ci th set to fill*parent, so they Cill $ill the same spa%e that the longest roC oes. >ne pattern $or this is to use a plain 7iew as a pi;el3high blue bar a%ross the Ci th o$ the table'. ivi er &e.g., <7iew as a tCo3

android!layout*$ei%$t " #Hpx# android!back%round " #D@@@@EE# /&

"tret#h$ "hrin%$ and Collapse


/y e$ault, ea%h %olumn Cill be siKe a%%or ing to the QnaturalQ siKe o$ the Ci est Ci get in that %olumn &taking spanne %olumns into a%%ount'. #ometimes, though, that oes not Cork out very Cell, an you nee more %ontrol over %olumn behavior. @ou %an pla%e an android!stretc$Columns property on the -able+ayout. 5he value shoul be a single %olumn number &again, @3base ' or a %omma3 elimite list o$ %olumn numbers. 5hose %olumns Cill be stret%he to take up any available spa%e yet on the roC. 5his helps i$ your %ontent is narroCer than the available spa%e. Conversely, you %an pla%e a android!s$rinkColumns property on the -able+ayout. Again, this shoul be a single %olumn number or a %omma3 elimite list o$ %olumn numbers. 5he %olumns liste in this property Cill try to Cor 3Crap their %ontents to re u%e the e$$e%tive Ci th o$ the %olumn N by e$ault, Ci gets are not Cor 3Crappe . 5his helps i$ you have %olumns Cith potentially Cor y %ontent that might %ause some %olumns to be pushe o$$ the right si e o$ the s%reen.
/7
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition

Working 4ith Containers

@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

Working 4ith Containers

When %ompile against the generate +ava %o e an run on the emulator, Ce get*

!igure (/< The Table ayout.emo sample application

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

Working 4ith Containers

<>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

Working 4ith Containers

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*

!igure (0< The ScrollGie4.emo sample application

0%
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition

Working 4ith Containers

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

Subscribe to updates at http://commonsware.com

Special Creative Commons BY-SA 3.0 License Edition

CHAPTER /

>sing Selection Widgets

/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.

)dapting to the Circumstances


.n the abstra%t, a apters provi e a %ommon inter$a%e to multiple isparate A!.s. More spe%i$i%ally, in An roi 7s %ase, a apters provi e a %ommon inter$a%e to the ata mo el behin a sele%tion3style Ci get, su%h as a listbo;.
0/
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition

>sing Selection Widgets

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.

+sin! Arr yAd pter


5he easiest a apter to use is ArrayAdapter N all you nee to o is Crap one o$ these aroun a +ava array or java.util.+ist instan%e, an you have a $ully3 $un%tioning a apter*
Strin%OP items"8#t$is#G #is#G #a#G #really#G #silly#G #list#<5 new ArrayAdapter<Strin%&:t$isG android.R.layout.simple*list*item*?G items;5

5he ArrayAdapter %onstru%tor takes three parameters*


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

>sing Selection Widgets

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

)ere, %et7iew:; re%eives three parameters*


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.

0ther 1ey Ad pters


)ere are some other a apters in An roi that you Cill likely use, ea%h o$ Chi%h Cill be %overe in greater etail later in this book*
CursorAdapter %onverts a Cursor, typi%ally $rom a %ontent provi er, into something that %an be isplaye in a sele%tion vieC SimpleAdapter %onverts

ata $oun in EML resour%es


03

Subscribe to updates at http://commonsware.com

Special Creative Commons BY-SA 3.0 License Edition

>sing Selection Widgets

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

ists of 5aughty and 5ice


5he %lassi% listbo; Ci get in An roi is knoCn as +ist7iew. .n%lu e one o$ these in your layout, invoke setAdapter:; to supply your ata an %hil vieCs, an atta%h a listener via set,n.temSelected+istener:; to $in out Chen the sele%tion has %hange . With that, you have a $ully3$un%tioning listbo;. )oCever, i$ your a%tivity is ominate by a single list, you might Cell %onsi er %reating your a%tivity as a sub%lass o$ +istActivity, rather than the regular Activity base %lass. .$ your main vieC is Oust the list, you o not even nee to supply a layout N +istActivity Cill %onstru%t a $ull3s%reen list $or you. .$ you o Cant to %ustomiKe the layout, you %an, so long as you i enti$y your +ist7iew as 9android!id/list, so +istActivity knoCs Chi%h Ci get is the main list $or the a%tivity. (or e;ample, here is a layout pulle $rom the +ist 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# & <-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&

.t is Oust a list Cith a label on top to shoC the %urrent sele%tion.

07
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition

>sing Selection Widgets

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

>sing Selection Widgets

!igure (3< The istGie4.emo sample application

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

>sing Selection Widgets

(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

>sing Selection Widgets

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

>sing Selection Widgets

!igure (7< The Spinner.emo sample application6 as initially launched

!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

>sing Selection Widgets

'rid -our ions #+r Something ike That<<<&


As the name suggests, 0rid7iew gives you a tCo3 imensional gri o$ items to %hoose $rom. @ou have mo erate %ontrol over the number an siKe o$ the %olumnsP the number o$ roCs is ynami%ally etermine base on the number o$ items the supplie a apter says are available $or vieCing. 5here are a $eC properties Chi%h, Chen %ombine , etermine the number o$ %olumns an their siKes*

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

android!stretc$Mode in android!numColumns, Chat

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

>sing Selection Widgets

>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

>sing Selection Widgets

#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

>sing Selection Widgets

(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*

!igure %;< The 'rid.emo sample application6 as initially launched

33
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition

>sing Selection Widgets

!igure %(< The same application6 scrolled to the bottom of the grid

!ieldsH 5o4 With ,/I ess Typing!


5he AutoComplete-ext7iew is sort o$ a hybri betCeen the )dit7iew &$iel ' an the Spinner. With auto3%ompletion, as the user types, the te;t is treate as a pre$i; $ilter, %omparing the entere te;t as a pre$i; against a list o$ %an i ates. Mat%hes are shoCn in a sele%tion list that, like Cith Spinner, $ol s oCn $rom the $iel . 5he user %an either type out an entry &e.g., something not in the list' or %hoose an entry $rom the list to be the value o$ the $iel . sub%lasses )dit7iew, so you %an %on$igure all the stan ar look3an 3$eel aspe%ts, su%h as $ont $a%e an %olor.
AutoComplete-ext7iew

.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

>sing Selection Widgets

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&

5he %orrespon ing +ava %o e is*


public class AutoCompleteDemo extends Activity implements -extCatc$er 8 -ext7iew selection5 AutoComplete-ext7iew edit5 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 edit":AutoComplete-ext7iew;findViewById:R.id.edit;5 edit.addTextChangedListener:t$is;5 edit.set#dapter:new ArrayAdapter<Strin%&:t$isG

39
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition

>sing Selection Widgets

<

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*

!igure %%< The )utoComplete.emo sample application6 as initially launched

7;
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition

>sing Selection Widgets

!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

>sing Selection Widgets

'alleries6 'ive +r Take The )rt


5he 0allery Ci get is not one or inarily $oun in 8". toolkits. .t is, in e$$e%t, a horiKontally3lai 3out listbo;. >ne %hoi%e $olloCs the ne;t a%ross the horiKontal plane, Cith the %urrently3sele%te item highlighte . >n an An roi evi%e, one rotates through the options through the le$t an right A3pa buttons. Compare to the +ist7iew, the 0allery takes up less s%reen spa%e Chile still shoCing multiple %hoi%es at one time &assuming they are short enough'. Compare to the Spinner, the 0allery alCays shoCs more than one %hoi%e at a time. 5he <uintessential e;ample use $or the 0allery is image previeC N given a %olle%tion o$ photos or i%ons, the 0allery lets people previeC the pi%tures in the pro%ess o$ %hoosing one. Co e3Cise, the 0allery Corks mu%h like a Spinner or 0rid7iew. .n your EML layout, you have a $eC properties at your isposal*
android!spacin% %ontrols the number o$

pi;els betCeen entries in the

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

Employing !ancy Widgets and Containers

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.

Pick and Choose


With limite 3input evi%es like phones, having Ci gets an ialogs that are aCare o$ the type o$ stu$$ somebo y is suppose to be entering is very help$ul. .t minimiKes keystrokes an s%reen taps, plus re u%es the %han%e o$ making some sort o$ error &e.g., entering a letter somepla%e Chere only numbers are e;pe%te '. As shoCn previously, )dit7iew has %ontent3aCare $lavors $or entering in numbers, phone numbers, et%. An roi also supports Ci gets &Date1icker, -ime1icker' an ialogs &Date1ickerDialo%, -ime1ickerDialo%' $or helping users enter ates an times. 5he Date1icker an Date1ickerDialo% alloC you to set the starting ate $or the sele%tion, in the $orm o$ a year, month, an ay o$ month value. 0ote that the month runs $rom @ $or +anuary through ?? $or Ae%ember. @ou %an
7,
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition

Employing !ancy Widgets and Containers

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

Employing !ancy Widgets and Containers

/& </+inear+ayout&

5he more interesting stu$$ %omes in the +ava sour%e*


public class C$ronoDemo extends Activity 8 DateEormat fmtDateAnd-ime"DateEormat.getDateTimeInstance:;5 -ext7iew dateAnd-ime+abel5 Calendar dateAnd-ime"Calendar.getInstance:;5 Date1icker.,nDateSet+istener d"new Date1icker.OnDateSetListener:; 8 public void dateSet:Date1icker viewG int yearG int mont$,fFearG int day,fMont$; 8 dateAnd-ime.set:Calendar.F)ARG year;5 dateAnd-ime.set:Calendar.M,/-3G mont$,fFear;5 dateAnd-ime.set:Calendar.DAF*,E*M,/-3G day,fMont$;5 updateLa!el:;5 < <5 -ime1icker.,n-imeSet+istener t"new -ime1icker.OnTimeSetListener:; 8 public void timeSet:-ime1icker viewG int $our,fDayG int minute; 8 dateAnd-ime.set:Calendar.3,2RG $our,fDay;5 dateAnd-ime.set:Calendar.M./2-)G minute;5 updateLa!el:;5 < <5 9,verride public void onCreate:6undle icicle; 8 super.onCreate:icicle;5 setContentView:R.layout.main;5 6utton btn":6utton;findViewById:R.id.date6tn;5 btn.setOnClickListener:new 7iew.OnClickListener:; 8 public void onClick:7iew v; 8 new Date&ickerDialog:C$ronoDemo.t$isG dG dateAnd-ime.get:Calendar.F)AR;G dateAnd-ime.get:Calendar.M,/-3;G dateAnd-ime.get:Calendar.DAF*,E*M,/-3;G Calendar.S2/DAF;.show:;5 < <;5 btn":6utton;findViewById:R.id.time6tn;5 btn.setOnClickListener:new 7iew.OnClickListener:; 8 public void onClick:7iew v; 8 new Time&ickerDialog:C$ronoDemo.t$isG tG #Set t$e time#G dateAnd-ime.get:Calendar.3,2R;G dateAnd-ime.get:Calendar.M./2-);G

7/
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition

Employing !ancy Widgets and Containers

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

Employing !ancy Widgets and Containers

!igure %/< The Chrono.emo sample application6 as initially launched

!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

Employing !ancy Widgets and Containers

!igure %3< The same application6 sho4ing the time picker dialog

Time @eeps !lo4ing ike a 2iver


.$ you Cant to isplay the time, rather than have users enter the time, you may Cish to use the Di%italClock or Analo%Clock Ci gets. 5hese are e;tremely easy to use, as they automati%ally up ate Cith the passage o$ time. All you nee to o it put them in your layout an let them o their thing. (or e;ample, $rom the Clocks sample appli%ation, here is an EML layout %ontaining both Di%italClock an Analo%Clock*
<>xml version"#?.@# encodin%"#utf(A#>& <Relative+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# & <Analo%Clock android!id"#9Bid/analo%# android!layout*widt$"#fill*parent# android!layout*$ei%$t"#wrap*content# android!layout*center3ori'ontal"#true# android!layout*ali%n1arent-op"#true# /& <Di%italClock android!id"#9Bid/di%ital#

77
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition

Employing !ancy Widgets and Containers

android!layout*widt$"#wrap*content# android!layout*$ei%$t"#wrap*content# android!layout*center3ori'ontal"#true# android!layout*below"#9id/analo%# /& </Relative+ayout&

Without any +ava %o e other than the generate proOe%t an get the $olloCing a%tivity*

stub, Ce %an buil

this

!igure %7< The Clocks.emo sample application

*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

Employing !ancy Widgets and Containers

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

Employing !ancy Widgets and Containers

%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

is the overar%hing %ontainer $or the tab buttons an %ontents


-abCid%et

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.

The Idiosyncr sies


5here are a $eC rules to $olloC, at least in this milestone e ition o$ the An roi toolkit, in or er to make these three Cork together*

@ou must give the -abCid%et an android!id o$ 9android!id/tabs

9(
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition

Employing !ancy Widgets and Containers

@ou must set asi e some pa buttons &more on this beloC'

ing in the Erame+ayout $or the tab

.$ 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

Employing !ancy Widgets and Containers

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

Employing !ancy Widgets and Containers

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

Employing !ancy Widgets and Containers

!igure %9< The Tab.emo sample application6 sho4ing the first tab

!igure ,;< The same application6 sho4ing the second tab

9/
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition

Employing !ancy Widgets and Containers

+ther Containers of 5ote


An roi o$$ers Absolute+ayout, Chere the %ontents are lai out base on spe%i$i% %oor inate positions. @ou tell Absolute+ayout Chere to pla%e a %hil in pre%ise E,@ %oor inates, an An roi puts it there, no <uestions aske . >n the plus si e, this gives you pre%ise positioning. >n the minus si e, it means your vieCs Cill only look QrightQ on s%reens o$ a %ertain imension, or it re<uires you to Crite a bun%h o$ %o e to a Oust the %oor inates base on s%reen siKe. #in%e An roi s%reens might run the gamut o$ siKes, plus have neC siKes %rop up perio i%ally, using Absolute+ayout %oul get <uite annoying. An roi also has a neC $lavor o$ list, the )xpandable+ist7iew. 5his provi es a simpli$ie tree representation, supporting tCo levels o$ epth* groups an %hil ren. 8roups %ontain %hil renP %hil ren are QleavesQ o$ the tree. 5his re<uires a neC set o$ a apters, sin%e the +istAdapter $amily oes not provi e any sort o$ group in$ormation $or the items in the list. 5his vieC $eels like it is a Cork3in3progress an so is not %overe here, but shoul appear in a $uture e ition o$ this book.

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

@ou %an also %all*

99
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition

)pplying *enus

to a a separator line betCeen alrea y3 e$ine an up%oming menu %hoi%es


addSeparator:; add.ntent,ptions:;

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*

!igure ,(< The *enu.emo sample application6 as initially launched

/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

!igure ,%< The same application6 sho4ing the options menu

Choosing a height &say, -4 pi;els' then %hanges the ivi er height o$ the list to something garish*

!igure ,,< The same application6 made ugly

(;/
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*

!igure ,$< The same application6 sho4ing a context menu

>n%e again, %hoosing an option sets the ivi er height.

(;0
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition

CHAPTER 11

Embedding the Web@it Bro4ser

>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.

) Bro4ser6 Writ Small


(or simple stu$$, Ceb7iew is not signi$i%antly i$$erent than any other Ci get in An roi N pop it into a layout, tell it Chat "RL to navigate to via +ava %o e, an you7re one. (or e;ample &6rowser?', here is a simple layout Cith a Ceb7iew*
<>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# & <Ceb7iew android!id"#9Bid/webkit#

(;3
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition

Embedding the Web@it Bro4ser

/& </+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

Embedding the Web@it Bro4ser

!igure ,/< The Bro4ser( sample application

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

Embedding the Web@it Bro4ser

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*

!igure ,0< The Bro4ser% sample application

((;
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition

Embedding the Web@it Bro4ser

5his is also available as a $ully3buil able sample, as 6rowserH.

5avigating the Waters


As Cas mentione above, there is no navigation toolbar Cith the Ceb7iew Ci get. 5his alloCs you to use it in pla%es Chere su%h a toolbar Coul be pointless an a Caste o$ s%reen real estate. 5hat being sai , i$ you Cant to o$$er navigational %apabilities, you %an, but you have to supply the "..
Ceb7iew o$$ers Cays to per$orm gar

en3variety broCser navigation, in%lu ing* Web page

reload:; to re$resh the %urrently3vieCe %o6ack:;

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

Entertaining the Client


!arti%ularly i$ you are going to use the Ceb7iew as a lo%al user inter$a%e &vs. broCsing the Web', you Cill Cant to be able to get %ontrol at key times, parti%ularly Chen users %li%k on links. @ou Cill Cant to make sure those links are han le properly, either by loa ing your oCn %ontent ba%k into the Ceb7iew, by submitting an .ntent to An roi to open the "RL in a $ull broCser, or by some other means &see the %hapter on laun%hing a%tivities'.
(((
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition

Embedding the Web@it Bro4ser

@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

Embedding the Web@it Bro4ser

browser":Ceb7iew;findViewById:R.id.webkit;5 loadTime:;5 browser.set*e!ViewClient:new Call!ack:;;5

<

void loadTime:; 8 Strin% pa%e"#<$tml&<body&<a $ref"4#/clock4#&# Bnew Date:;.toString:; B#</a&</body&</$tml&#5 < 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

Embedding the Web@it Bro4ser

!igure ,3< The Bro4ser, sample application

#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.

Settings6 Preferences6 and +ptions #+h6 *y!&


With your $avorite esktop Web broCser, you have some sort o$ QsettingsQ or Qpre$eren%esQ or QoptionsQ Cin oC. /etCeen that an the toolbar %ontrols, you %an tCeak an tCi le the behavior o$ your broCser, $rom pre$erre $onts to the behavior o$ +avas%ript. #imilarly, you %an a Oust the settings o$ your Ceb7iew Ci get as you see $it, via the CebSettin%s instan%e returne $rom %alling the Ci get7s %etSettin%s:; metho . 5here are lots o$ options on CebSettin%s to play Cith. Most appear $airly esoteri% &e.g., setEantasyEontEamily:;'. )oCever, here are some that you may $in more use$ul*

(($
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition

Embedding the Web@it Bro4ser

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

Subscribe to updates at http://commonsware.com

Special Creative Commons BY-SA 3.0 License Edition

CHAPTER 1&

Sho4ing Pop">p *essages

#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

Sho4ing Pop">p *essages

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

Sho4ing Pop">p *essages

%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.

Checking Them +ut


5o see hoC these Cork in pra%ti%e, take a peek at Messa%e, %ontaining the $olloCing 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# & <6utton android!id"#9Bid/alert# android!text"#Raise an alert# android!layout*widt$"#fill*parent# android!layout*$ei%$t"#wrap*content#/&

((9
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition

Sho4ing Pop">p *essages

<6utton android!id"#9Bid/toast# android!text"#Make a toast# android!layout*widt$"#fill*parent# android!layout*$ei%$t"#wrap*content#/& </+inear+ayout&

...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

Sho4ing Pop">p *essages

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

Sho4ing Pop">p *essages

!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'

.ealing 4ith Threads

. 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.

'etting Through the Dandlers


5he most $le;ible means o$ making an An roi 3$rien ly ba%kgroun threa is to %reate an instan%e o$ a 3andler sub%lass. @ou only nee one 3andler obOe%t per a%tivity, an you o not nee to manually register it or anything N

(%,
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition

.ealing 4ith Threads

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:;

puts the message on the <ueue a$ter a elay, e;presse in millise%on s


sendMessa%eDelayed:;

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

.ealing 4ith Threads

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.

An here is the +ava*


packa%e com.commonsware.android.t$reads5 import import import import import android.app.Activity5 android.os.6undle5 android.os.3andler5 android.os.Messa%e5 android.wid%et.1ro%ress6ar5

public class 3andlerDemo extends Activity 8 1ro%ress6ar bar5

(%/
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition

.ealing 4ith Threads

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

.ealing 4ith Threads

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*

!igure $;< The Dandler.emo sample application

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

.ealing 4ith Threads

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 .

>tilities #)nd 8 .onAt *ean Water Works&


@et another option is to use the 2.-$read2tilities helper %lass, Chi%h o$$ers a set o$ stati% metho s to assist in Corking Cith the ". threa . (irst, it o$$ers is2.-$read:;, Chi%h Cill tell you i$ you are presently e;e%uting on the ". threa o$ the supplie 7iew. .n the 3andler sample shoCn above, this metho Coul be super$luous N you pretty mu%h %an alCays tell by QeyeballingQ the %o e Chether it Cill be e;e%uting on the ". threa or not. /ut, i$ you pa%kage some o$ your %o e in a +AR $or others to reuse, you might not knoC Chether your %o e is being e;e%ute on the ". threa or $rom a ba%kgroun threa . 5here$ore, $or sa$ety, you %an invoke is2.-$read:; to $in out an take appropriate a%tion i$ you are not on the ". threa . #u%h Qappropriate a%tionQ might be to use run,n2.-$read:;. 5his Corks similar to the post:; metho s on 3andler an 7iew, in that it <ueues up a Runnable to run on the ". threa ...i$ you are not on the ". threa right noC. .$ you alrea y are on the ". threa , it invokes the Runnable imme iately. 5o i enti$y the proper ". threa , you must supply an Activity, Dialo%, or 7iew.

)nd 5o46 The Caveats


/a%kgroun threa s, Chile eminently possible using the An roi 3andler system, are not all happiness an Carm puppies. /a%kgroun threa s not only a %omple;ity, but they have real3Corl %osts in terms o$ available memory, C!", an battery li$e. 5o that en , there are a Ci e range o$ s%enarios you nee to a%%ount $or Cith your ba%kgroun threa , in%lu ing*

5he possibility that users Cill intera%t Cith your a%tivity7s ". Chile the ba%kgroun threa is %hugging along. .$ the Cork that the
(%7

Subscribe to updates at http://commonsware.com

Special Creative Commons BY-SA 3.0 License Edition

.ealing 4ith Threads

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

Subscribe to updates at http://commonsware.com

Special Creative Commons BY-SA 3.0 License Edition

CHAPTER 1(

Dandling )ctivity ifecycle Events

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

Dandling )ctivity ifecycle Events

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.

ife6 .eath6 and -our )ctivity


An roi Cill %all into your a%tivity as the a%tivity transitions betCeen the $our states liste above. #ome transitions may result in multiple %alls to your a%tivity, an sometimes An roi Cill kill your appli%ation Cithout %alling it. 5his Chole area is rather murky an probably subOe%t to %hange, so pay %lose attention to the o$$i%ial An roi o%umentation as Cell as this se%tion Chen e%i ing Chi%h events to pay attention to an Chi%h you %an sa$ely ignore. 0ote that $or all o$ these, you shoul %hain upCar an invoke the super%lass7 e ition o$ the metho , or An roi may raise an e;%eption.

onCre te67 nd onCompleteTh #67


We have been implementing onCreate:; in all o$ our Activity sub%lasses in all the e;amples. 5his Cill get %alle in tCo situations* -. When the a%tivity is $irst starte &e.g., sin%e a system restart', onCreate:; Cill be invoke Cith a null parameter.
(,%
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition

Dandling )ctivity ifecycle Events

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.

onSt rt678 onRest rt678 nd onResume67


5hese are invoke as your a%tivity is brought to the $oregroun an ma e available to the user. 5he An roi o%umentation is %ontra i%tory as to un er Chat %ir%umstan%es an in Chat or er these are %alle . .t is $airly sa$e to say that*

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

Dandling )ctivity ifecycle Events

onP use678 on9ree:e678 onStop678 nd onDestroy67


5he onEree'e:; event is triggere i$ An roi thinks that it may have to kill o$$ your a%tivity in the not3too3 istant $uture. @ou are passe a 6undle obOe%t, Chi%h Corks similar to a Map, Chere you %an persist the %urrent state o$ your ". &e.g., $iel values, %he%kbo; states'. 5hat 6undle Cill be re3supplie to you in onCreate:; an onComplete-$aw:; i$, in ee , your a%tivity Cas kille o$$. )oCever, it is possible that onEree'e:; Cill be %alle several times Cithout your a%tivity a%tually being kille o$$, so o not assume that Oust be%ause your onEree'e:; han ler is %alle that Qthe en is nearQ. Anything that steals your user aCay $rom your a%tivity N mostly, the a%tivation o$ another a%tivity N Cill result in your on1ause:; being %alle . )ere, you shoul un o anything you i in onResume:;, su%h as stopping ba%kgroun threa s, releasing any e;%lusive3a%%ess resour%es you may have a%<uire &e.g., %amera', an the like. >n%e on1ause:; is %alle , An roi reserves the right to kill o$$ your a%tivity7s pro%ess at any point. )en%e, you shoul not be relying upon re%eiving any $urther events. 5he onStop:; event is the %ounterpart to onRestart:;. )oCever, sin%e it might not get %alle , it is un%lear Chat spe%i$i%ally you might Cant to o in this metho . #imilarly, onDestroy:; may or may not be %alle be$ore your pro%ess en s. )oCever, there is no <uestion that, a$ter onDestroy:;, your pro%ess is en ing, an so the ne;t line o$ %o e o$ yours that Cill be invoke $or this a%tivity Cill be onCreate:;.

(,$
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition

PART III Data Stores, Network Services, and APIs

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.

'etting What -ou Want


5o get a%%ess to the pre$eren%es, you have tCo A!.s to %hoose $rom* -. $rom Cithin your Activity, to a%%ess a%tivity3 spe%i$i% pre$eren%es
%et1references:;

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.

Stating -our Preference


8iven the appropriate S$ared1references obOe%t, you %an use edit:; to get an Qe itorQ $or the pre$eren%es. 5his obOe%t has a set o$ setters that mirror the getters on the parent S$ared1references obOe%t. .t also has*
remove:; to get ri clear:; to get ri

o$ a single name pre$eren%e o$ all pre$eren%es e via the e itor

commit:; to persist your %hanges ma

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.

) Preference !or )ction


5o emonstrate pre$eren%es, Ce nee an a%tivity that gives the user something to input &so Ce %an persist it as a pre$eren%e'...an that Ce knoC Cill go through a likely a%tivity li$e%y%le event $or us to persist the %hange.
(,7
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition

>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

When Ce $irst laun%h the a%tivity, the %he%kbo; is un%he%ke *

!igure $(< The Prefs.emo sample application6 as initially launched

.$ 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

!igure $%< The same application6 after checking the checkbox

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.

-ou )nd The Dorse -ou 2ode 8n +n


Let7s suppose you have some stati% ata you Cant to ship Cith the appli%ation, su%h as a list o$ Cor s $or a spell3%he%ker. 5he easiest Cay to eploy that is to put the $ile in the res/raw ire%tory, so it gets put in the An roi appli%ation .apk $ile as part o$ the pa%kaging pro%ess. 5o a%%ess this $ile, you nee to get yoursel$ a Resources obOe%t. (rom an a%tivity, that is as simple as %alling %etResources:;. A Resources obOe%t o$$ers openRawResource:; to get an .nputStream on the $ile you spe%i$y. Rather than a path, openRawResource:; e;pe%ts an integer i enti$ier $or the $ile as pa%kage . 5his Corks Oust like a%%essing Ci gets via find7iew6y.d:; N i$ you put a $ile name words.xml in res/raw, the i enti$ier is a%%essible in +ava as R.raw.words. #in%e you %an only get an .nputStream, you have no means o$ mo i$ying this $ile. )en%e, it is really only use$ul $or stati% re$eren%e ata. Moreover, sin%e it is un%hanging until the user installs an up ate version o$ your appli%ation pa%kage, either the re$eren%e ata has to be vali $or the $oreseeable $uture,
($,
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition

)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 *

!igure $,< The Static!ile.emo sample application

>$ %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

< <

< catc$ :-$rowable t; 8 show#lert:#)xceptionW#G @G t.toString:;G #Cancel#G true;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

!igure $$< The 2eadWrite!ile.emo sample application6 as initially launched

!igure $/< The same application6 after entering some text

(/;
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition

CHAPTER 1-

Working 4ith 2esources

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.

The 2esource ineup


Resour%es are store as $iles un er the res/ ire%tory in your An roi proOe%t layout. With the e;%eption o$ raC resour%es &res/raw/', all the other types o$ resour%es are parse $or you, either by the An roi pa%kaging system or by the An roi system on the evi%e or emulator. #o, $or e;ample, Chen you lay out an a%tivity7s ". via a layout resour%e &res/layout/', you o not have to parse the layout EML yoursel$ N An roi han les that $or you. .n a ition to layout resour%es &$irst seen in an earlier %hapter' an raC resour%es &intro u%e in another earlier %hapter', there are several other types o$ resour%e available to you, in%lu ing*

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

Working 4ith 2esources

#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

Working 4ith 2esources

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

Working 4ith 2esources

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

=. Convert the entity3es%ape


3tml.from3tml:;

)5ML into a Spanned obOe%t via

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

Working 4ith 2esources

android!layout*widt$"#fill*parent# android!layout*$ei%$t"#wrap*content# /& </+inear+ayout&

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

Working 4ith 2esources

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

Working 4ith 2esources

!igure $0< The Strings.emo sample application6 as initially launched

but i$ Ce $ill in a name an %li%k the button, Ce get*

!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

Working 4ith 2esources

'ot the Picture:


An roi supports images in the !08, +!I8, an 8.( $ormats. 8.( is o$$i%ially is%ourage , hoCeverP !08 is the overall pre$erre $ormat. .mages %an be use anyChere that re<uires a Drawable, su%h as the image an ba%kgroun o$ an .ma%e7iew. "sing images is simply a matter o$ putting your image $iles in res/drawable/ an then re$eren%ing them as a resour%e. Within layout $iles, images are re$eren%e as 9drawable/... Chere the ellipsis is the base name o$ the $ile &e.g., $or res/drawable/foo.pn%, the resour%e name is 9drawable/foo'. .n +ava, Chere you nee an image resour%e .A, use R.drawable. plus the base name &e.g., R.drawable.foo'. .$ you nee a 2ri to an image resour%e, you %an use one o$ tCo i$$erent string $ormats $or the path* -. Chere com.example.app is the name o$ the +ava pa%kage use by your appli%ation in AndroidManifest.xml an ... is the numeri% resour%e .A $or the resour%e in <uestion &e.g., the value o$ R.drawable.foo'
android.resource!//com.example.app/...,

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

Working 4ith 2esources

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

Working 4ith 2esources

.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 <

0oC, our button has the esire i%on*

!igure $7< The 8mages.emo sample application

?* H The 2esource Way


.n a previous %hapter, Ce shoCe hoC you %an pa%kage EML $iles as raC resour%es an get a%%ess to them $or parsing an usage. 5here is another Cay o$ pa%kaging stati% EML Cith your appli%ation* the EML resour%e.
(0;
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition

Working 4ith 2esources

#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

Working 4ith 2esources

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

Working 4ith 2esources

!igure $9< The ?* 2esource.emo sample application

*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

Working 4ith 2esources

an mm $or in%hes an a%tual siKe o$ the s%reen


in pt dp

millimeters, respe%tively, base

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

Working 4ith 2esources

@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

Working 4ith 2esources

.ifferent Strokes for .ifferent !olks


>ne set o$ resour%es may not $it all situations Chere your appli%ation may be use . >ne obvious area %omes Cith string resour%es an ealing Cith internationaliKation &.-80' an lo%aliKation &L-00'. !utting strings all in one language Corks $ine N probably at least $or the eveloper N but only %overs one language. 5hat is not the only s%enario Chere resour%es might nee to i$$er, though. )ere are others*

#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

Working 4ith 2esources

#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

Subscribe to updates at http://commonsware.com

Special Creative Commons BY-SA 3.0 License Edition

Working 4ith 2esources

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

Working 4ith 2esources

>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

Subscribe to updates at http://commonsware.com

Special Creative Commons BY-SA 3.0 License Edition

CHAPTER 1/

*anaging and )ccessing ocal .atabases

#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

*anaging and )ccessing ocal .atabases

o$ a %ontent provi er that a%%esses a atabase in the /uil ing a Content !rovi er %hapter.

) Fuick SF ite Primer


#HLite, as the name suggests, uses a iale%t o$ #HL $or <ueries &S)+)C-', ata manipulation &./S)R-, et. al.', an ata e$inition &CR)A-) -A6+), et. al.'. #HLite has a $eC pla%es Chere it eviates $rom the #HL312 stan ar , no i$$erent than most #HL atabases. 5he goo neCs is that #HLite is so spa%e3e$$i%ient that the An roi runtime %an in%lu e all o$ #HLite, not some arbitrary subset to trim it oCn to siKe. 5he biggest i$$eren%e $rom other #HL atabases you Cill en%ounter is probably the ata typing. While you %an spe%i$y the ata types $or %olumns in a CR)A-) -A6+) statement, an Chile #HLite Cill use those as a hint, that is as $ar as it goes. @ou %an put Chatever ata you Cant in Chatever %olumn you Cant. !ut a string in an ./-)0)R %olumnD #ure: 0o problem: ,i%e versaD Works too: #HLite re$ers to this as Qmani$est typingQ, as es%ribe in the o%umentation* In manifest typing, the datatype is a property of the value itself, not of the column in which the value is stored. S Lite thus allows the user to store any value of any datatype into any column regardless of the declared type of that column. .n a ition, there are a han $ul o$ stan ar #HL $eatures not supporte in #HLite, notably E,R).0/ M)F %onstraints, neste transa%tions, R.03- ,2-)R =,./ an E2++ ,2-)R =,./, an some $lavors o$ A+-)R -A6+). /eyon that, though, you get a $ull #HL system, %omplete Cith triggers, transa%tions, an the like. #to%k #HL statements, like S)+)C-, Cork pretty mu%h as you might e;pe%t. .$ you are use to Corking Cith a maOor atabase, like >ra%le, you may look upon #HLite as being a QtoyQ atabase. !lease bear in min that >ra%le an
(3%
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition

*anaging and )ccessing ocal .atabases

#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 .

Start at the Beginning


0o atabases are automati%ally supplie to you by An roi . .$ you Cant to use #HLite, you have to %reate your oCn atabase, then populate it Cith your oCn tables, in e;es, an ata. 5o %reate a atabase, your Activity, Content1rovider, or other Context sub%lass %an %all createDatabase:;, provi ing $our parameters*

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

*anaging and )ccessing ocal .atabases

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.

Setting the Table


ST+iteDatabase,

(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.

#o, $or e;ample, you %an*


db.execS.L:#CR)A-) -A6+) wid%ets #B #:.D ./-)0)R 1R.MARF M)F A2-,./CR)M)/-G #B #name -)U-G inventory ./-)0)R;#;5 db.execS.L:#CR)A-) ./D)U wid%ets6y/ame.dx #B #,/ wid%ets :name;#;5

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

*anaging and )ccessing ocal .atabases

@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

*anaging and )ccessing ocal .atabases

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.

What 'oes )round6 Comes )round


As Cith ./S)R-, 21DA-), an D)+)-), you have tCo main options $or retrieving ata $rom a #HLite atabase using S)+)C-* -. @ou %an use rawTuery:; to invoke a S)+)C- statement ire%tly, or

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

*anaging and )ccessing ocal .atabases

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

Buildin! #ith Builders


@et another option is to use ST+iteTuery6uilder, Chi%h o$$ers mu%h ri%her <uery3buil ing options, parti%ularly $or nasty <ueries involving things like the union o$ multiple sub3<uery results. More importantly, the ST+iteTuery6uilder inter$a%e ovetails ni%ely Cith the Content1rovider inter$a%e $or e;e%uting <ueries. )en%e, a %ommon pattern $or your %ontent provi er7s Juery:; implementation is to %reate a ST+iteTuery6uilder, $ill in some e$aults, then alloC it to buil up &an optionally e;e%ute' the $ull <uery %ombining the e$aults Cith Chat is provi e to the %ontent provi er on the <uery re<uest. (or e;ample, here is a snippet o$ %o e $rom a %ontent provi er using ST+iteTuery6uilder*

(33
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition

*anaging and )ccessing ocal .atabases

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

*anaging and )ccessing ocal .atabases

+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

Ch n!e ,or the S $e o, Ch n!e


(or a simple S)+)C-, an in some other situations, the %ursor Cill support up ates &support2pdates:;'. 5his means not only %an you rea ata using the %ursor, but you %an mo i$y the ata an %ommit those %hanges ba%k to the atabase. @ou o this by*

(39
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition

*anaging and )ccessing ocal .atabases

"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

An , o$ %ourse, you shoul close:; the %ursor Chen one.

% $in! <our 0#n Cursors


5here may be %ir%umstan%es in Chi%h you Cant to use your oCn Cursor sub%lass, rather than the sto%k implementation provi e by An roi . .n those %ases, you %an use $lavors o$ Juery:; an rawTuery:; that take a CursorEactory instan%e as a parameter. 5he $a%tory, as one might e;pe%t, is responsible $or %reating neC %ursors via its newCursor:; implementation. (in ing an implementing a vali use $or this $a%ility is le$t as an e;er%ise $or the rea er. #u$$i%e it to say that you shoul not nee to %reate your oCn %ursor %lasses mu%h, i$ at all, in or inary An roi evelopment.

.ata6 .ata6 Every4here


.$ you are use to eveloping $or other atabases, you are also probably use to having tools to inspe%t an manipulate the %ontents o$ the atabase, beyon merely the atabase7s A!.. With An roi 7s emulator, you have tCo main options $or this. (irst, the emulator bun les in the sJliteI %onsole program an makes it available $rom the adb s$ell %omman . >n%e you are in the emulator7s shell, Oust e;e%ute sJliteI, provi ing it the path to your atabase $ile. @our atabase $ile %an be $oun at*
/data/data/your.app.packa%e/databases/your(db(name.db

(7;
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition

*anaging and )ccessing ocal .atabases

)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.

!igure /;< the SF ite *anager !irefox extension

(7(
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition

*anaging and )ccessing ocal .atabases

@ou %an $in

oKens o$ others on the #HLite Web site.

(7%
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition

CHAPTER 12

everaging Cava ibraries

+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.

The +uter imits


0ot all available +ava %o e, o$ %ourse, Cill Cork Cell Cith An roi . 5here are a number o$ $a%tors to %onsi er, in%lu ing*

.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

everaging Cava ibraries

#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.

)nts and Cars


@ou have tCo %hoi%es $or integrating thir 3party %o e into your proOe%t* use sour%e %o e, or use pre3pa%kage +ARs. .$ you %hoose to use their sour%e %o e, all you nee to o is %opy it into your oCn sour%e tree &un er src/ in your proOe%t', so it %an sit alongsi e your e;isting %o e, then let the %ompiler per$orm its magi%. .$ you %hoose to use an e;isting +AR, perhaps one $or Chi%h you o not have the sour%e %o e, you Cill nee to tea%h your buil %hain hoC to use the +AR. .$ you are using an .AI, that7s a matter o$ telling it to re$eren%e the +AR. .$, on the other han , you are not using an .AI an are relying upon the build.xml Ant s%ript, you Cill nee to make some %hanges. )ere7s a pattern that Corks*
(7$
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition

everaging Cava ibraries

-.

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

everaging Cava ibraries

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

Communicating via the 8nternet

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.

2EST and 2elaxation


An roi oes not have built3in #>A! or EML3R!C %lient A!.s. )oCever, it oes have the Apa%he +akarta Commons )ttpClient library bake in. @ou %an either layer a #>A!UEML3R!C layer atop this library, or use it QstraightQ $or a%%essing RI#53style Web servi%es. (or the purposes o$ this book, QRI#53
(73
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition

Communicating via the 8nternet

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.

HTTP 0per tions vi Ap che Commons


5he $irst step to using )ttpClient is, not surprisingly, to %reate an 3ttpClient obOe%t. 5he %lient obOe%t han les all )55! re<uests upon your behal$. 5hose re<uests are bun le up into 3ttpMet$od instan%es, Cith i$$erent 3ttpMet$od sub%lasses $or ea%h i$$erent )55! verb &e.g., 0etMet$od $or )55! 0)- re<uests'. @ou %reate an 3ttpMet$od sub%lass instan%e, $ill in the "RL to retrieve an other %on$iguration ata &e.g., $orm values i$ you are oing an )55! 1,S- via 1ostMet$od', then pass the metho to the %lient to a%tually make the )55! re<uest. 5he re<uest Cill, at minimum, give you an )55! response %o e &e.g., H@@ $or >F' an various )55! hea ers &e.g., Set(Cookie'. .n many %ases, you Cill also be given the bo y o$ the response, Chi%h you %an obtain as a byte array, a Strin%, or an .nputStream $or later pro%essing. When you are one Cith the re<uest, %lose the .nputStream &i$ that7s hoC you got the response bo y', then invoke releaseConnection:; on the metho obOe%t, to rop the )55! %onne%tion. (or e;ample, let7s take a look at the Ceat$er sample proOe%t. 5his implements an a%tivity that retrieves Ceather ata $or your %urrent lo%ation $rom the 0ational Weather #ervi%e &>AT.* this probably only Corks in the "#'. 5hat ata is %onverte into an )5ML page, Chi%h is poure into a CebMit Ci get $or isplay. Rebuil ing this emo using a +ist7iew is le$t as an e;er%ise $or the rea er. Also, sin%e this sample is relatively long, Ce Cill only shoC

(77
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition

Communicating via the 8nternet

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

Communicating via the 8nternet

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

Communicating via the 8nternet

<

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

Communicating via the 8nternet

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

5he result looks like this*

!igure /(< The Weather.emo sample application

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

Communicating via the 8nternet

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.

Email over Cava


An roi has no built3in $a%ility to sen ing or re%eiving emails. 5his oesn7t pre%lu e you $rom oing so yoursel$, but you Cill nee to either roll your oCn #M5!, !>!?, or .MA! %lient %o e, or use one $rom a thir 3party, like +avaMail. As es%ribe in the %hapter on integrating thir 3party +ava %o e, there are %aveats to going this route, su%h as bloating the siKe o$ your appli%ation. Iventually, Qlean an meanQ e itions o$ these libraries Cill spring up, $o%use on An roi 3style eployments. An , eventually, An roi 3style evi%es Cill e;pan their storage, memory, an C!" %apa%ities. .n the meantime, though, Ce %an still use A!.s like +avaMail, so long as Ce live Cith the limitations. Case in point is the Mail6u'' proOe%t, $irst mentione in the pre%e ing %hapter. 5his appli%ation %ombines an a%tivity an a servi%e, esigne to monitor an email a%%ount $or neC messages. 5his isn7t a $ull email %lient, but it is a $eature you might $in in $ull email %lient, an it shoCs o$$ integrating +avaMail ni%ely, plus the use o$ servi%es. .n this %hapter, though, Ce7ll $o%us on the +avaMail si e, $or a%%essing !>!? an .MA! on your An roi evi%e. 5his is not meant to be a thorough +avaMail tutorial, o$ %ourse. (or the purposes o$ Mail/uKK, Chat Ce Cant is to %onne%t to a mail server, grab the messages, e;tra%t the Messa%e(.d hea ers, an hol onto the .As. Ivery time Ce %he%k $or neC messages, Ce see i$ the last set o$ message .As is missing any $rom the Oust3retreive set o$ .As N i$ so, Ce have a neC
(9,
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition

Communicating via the 8nternet

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

Communicating via the 8nternet

Strin%OP $eaders"ms%sOiP.get(eader:#Messa%e(.d#;5 if :$eaders""null; 8 resultOiP"null5 < else 8 resultOiP"$eadersO@P5 <

< < 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

Communicating via the 8nternet

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

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

Creating 8ntent !ilters

"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

Creating 8ntent !ilters

WhatAs -our 8ntent:


When #ir 5im /erners3Lee %ooke up the )yperte;t 5rans$er !roto%ol N )55! N he set up a system o$ verbs plus a resses in the $orm o$ "RLs. 5he a ress in i%ate a resour%e, su%h as a Web page, graphi%, or server3si e program. 5he verb in i%ate Chat shoul be one* 8I5 to retrieve it, !>#5 to sen $orm ata to it $or pro%essing, et%. .ntents are similar, in that they represent an a%tion plus %onte;t. 5here are more a%tions an more %omponents to the %onte;t Cith An roi intents than there are Cith )55! verbs an resour%es, but the %on%ept is still the same. +ust as a Web broCser knoCs hoC to pro%ess a verbV"RL pair, An roi knoCs hoC to $in a%tivities or other appli%ation logi% that Cill han le a given intent.

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

Creating 8ntent !ilters

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

Creating 8ntent !ilters

SF/C*AC-.,/ 7.)C*AC-.,/ C)6*S)ARC3*AC-.,/

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

Creating 8ntent !ilters

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.

Stating -our 8ntent#ions&


All An roi %omponents that Cish to be noti$ie via intents must e%lare intent $ilters, so An roi knoCs Chi%h intents shoul go to that %omponent. 5o o this, you nee to a intent(filter elements to your AndroidManifest.xml $ile. All o$ the e;ample proOe%ts have intent $ilters e$ine , %ourtesy o$ the An roi appli%ation3buil ing s%ript &activityCreator.py or the .AI e<uivalent'. 5hey look something like this*

%;,
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition

Creating 8ntent !ilters

<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

Creating 8ntent !ilters

<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

Creating 8ntent !ilters

<receiver android!name"#.My.ntentReceiverClass/ame# /&

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 &&

aunching )ctivities and Sub" )ctivities

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

aunching )ctivities and Sub")ctivities

5his %hapter %overs the $irst s%enarioP the ne;t %hapter han les the se%on .

Peers and Subs


>ne key <uestion you nee to ansCer Chen you e%i e to laun%h an a%tivity is* oes your a%tivity nee to knoC Chen the laun%he a%tivity en sD (or e;ample, suppose you Cant to spaCn an a%tivity to %olle%t authenti%ation in$ormation $or some Web servi%e you are %onne%ting to N maybe you nee to authenti%ate Cith >pen.A in or er to use an >Auth servi%e. .n this %ase, your main a%tivity Cill nee to knoC Chen the authenti%ation is %omplete so it %an start to use the Web servi%e. >n the other han , imagine an email appli%ation in An roi . When the user ele%ts to vieC an atta%hment, neither you nor the user ne%essarily e;pe%t the main a%tivity to knoC Chen the user is one vieCing that atta%hment. .n the $irst s%enario, the laun%he a%tivity is %learly subor inate to the laun%hing a%tivity. .n that %ase, you probably Cant to laun%h the %hil as a sub3a%tivity, Chi%h means your a%tivity Cill be noti$ie Chen the %hil a%tivity is %omplete. .n the se%on s%enario, the laun%he a%tivity is more a peer o$ your a%tivity, so you probably Cant to laun%h the 6%hil 9 Oust as a regular a%tivity. @our a%tivity Cill not be in$orme Chen the 6%hil 9 is one, but, then again, your a%tivity really oesn7t nee to knoC.

Start AEm >p


5he tCo pie%es $or starting an a%tivity are an intent an your %hoi%e o$ hoC to start it up.

%;7
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition

aunching )ctivities and Sub")ctivities

% $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

aunching )ctivities and Sub")ctivities

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

aunching )ctivities and Sub")ctivities

<>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

aunching )ctivities and Sub")ctivities

import import import import

android.os.6undle5 android.view.7iew5 android.wid%et.6utton5 android.wid%et.)dit-ext5

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 < <

5he a%tivity is not mu%h to look at*

%(%
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition

aunching )ctivities and Sub")ctivities

!igure /%< The aunch.emo sample application6 as initially launched

.$ 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

aunching )ctivities and Sub")ctivities

!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 &'

!inding )vailable )ctions via 8ntrospection

#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

!inding )vailable )ctions via 8ntrospection

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

!inding )vailable )ctions via 8ntrospection

/& <6utton android!id"#9Bid/pick# android!layout*widt$"#fill*parent# android!layout*$ei%$t"#fill*parent# android!text"#0immeW# android!layout*wei%$t"#?# /& </+inear+ayout&

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#

"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

!inding )vailable )ctions via 8ntrospection

<;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.

!igure /$< The Pick.emo sample application6 as initially launched

%(7
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition

!inding )vailable )ctions via 8ntrospection

!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

!inding )vailable )ctions via 8ntrospection

>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

!inding )vailable )ctions via 8ntrospection

<>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&

5he resulting ". noC shoCs the available a%tions*

%%(
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition

!inding )vailable )ctions via 8ntrospection

!igure /3< The )ctivity)dapter.emo sample application6 as initially launched

!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

!inding )vailable )ctions via 8ntrospection

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.

Would -ou ike to See the *enu:


Another Cay to give the user Cays to take a%tions on a pie%e o$ %ontent, Cithout you knoCing Chat a%tions are possible, is to inOe%t a set o$ menu %hoi%es into the options menu via add.ntent,ptions:;. 5his metho , available on Menu, takes an .ntent an other parameters an $ills in a set o$ menu %hoi%es on the Menu instan%e, ea%h representing one possible a%tion. Choosing one o$ those menu %hoi%es spaCns the asso%iate a%tivity. 5he %anoni%al e;ample o$ using add.ntent,ptions:; illustrates another $lavor o$ having a pie%e o$ %ontent an not knoCing the a%tions that %an be taken. .n the previous e;ample, shoCing ActivityAdapter, the %ontent Cas $rom some other An roi appli%ation, an Ce knoC nothing about it. .t is also possible, though, that Ce knoC $ull Cell Chat the %ontent is N it7s ours. )oCever, An roi appli%ations are per$e%tly %apable o$ a ing neC a%tions to e;isting %ontent types, so even though you Crote your appli%ation an knoC Chat you e;pe%t to be one Cith your %ontent, there may be other options you are unaCare o$ that are available to users. (or e;ample, imagine the tagging subsystem mentione in the intro u%tion to this %hapter. .t Coul be very annoying to users i$, every time they Cante to tag a pie%e o$ %ontent, they ha to go to a separate tagging tool, then turn aroun an pi%k the %ontent they Oust ha been Corking on &i$ that is even te%hni%ally possible' be$ore asso%iating tags Cith it. .nstea , they Coul probably pre$er a menu %hoi%e in the %ontent7s oCn 6home9 a%tivity Chere they %an in i%ate they Cant to tag it, Chi%h lea s them to the set3a3tag a%tivity an tells that a%tivity Chat %ontent shoul get tagge . 5o a%%omplish this, the tagging subsystem shoul set up an intent $ilter, supporting any pie%e o$ %ontent, Cith their oCn a%tion &e.g., -A0*AC-.,/' an a %ategory o$ A+-)R/A-)*CA-)0,RF. 5he %ategory A+-)R/A-)*CA-)0,RF is the

%%,
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition

!inding )vailable )ctions via 8ntrospection

%onvention $or one appli%ation a %ontent.

ing a%tions to another appli%ation7s

.$ 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

!inding )vailable )ctions via 8ntrospection

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

Subscribe to updates at http://commonsware.com

Special Creative Commons BY-SA 3.0 License Edition

PART V Content Providers and Services

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 &(

>sing a Content Provider

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

>sing a Content Provider

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

>sing a Content Provider

@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

>sing a Content Provider

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

< catc$ :-$rowable t; 8 android.util.+o%.e:#-our.t#G #)xception creatin% tour#G t;5 <

.n the %all to mana%edTuery:;, Ce provi e*

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

>sing a Content Provider

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.

)dapting to the Circumstances


0oC that Ce have a Cursor via mana%edTuery:;, Ce have a%%ess to the <uery results an %an o Chatever Ce Cant Cith them. @ou might, $or e;ample, manually e;tra%t ata $rom the Cursor to populate Ci gets or other obOe%ts N -our7iewActivity oes this by populating a -our mo el obOe%t out o$ its Cursor. )oCever, i$ the goal o$ the <uery Cas to return a list $rom Chi%h the user shoul %hoose an item, you probably shoul %onsi er using SimpleCursorAdapter. 5his %lass bri ges betCeen the Cursor an a sele%tion Ci get, su%h as a +ist7iew or Spinner. !our the Cursor into a
%,,
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition

>sing a Content Provider

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?'

A$ter that, Ce put the a apter into the +ist7iew, an Ce get*

%,$
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition

>sing a Content Provider

!igure /9< Tour ist)ctivity6 sho4ing a list of tours

.$ 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

>sing a Content Provider

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

>sing a Content Provider

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

Subscribe to updates at http://commonsware.com

Special Creative Commons BY-SA 3.0 License Edition

>sing a Content Provider

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.

'ive and Take


>$ %ourse, %ontent provi ers Coul be astonishingly Ceak i$ you %oul n7t a or remove ata $rom them, only up ate Chat is there. (ortunately, %ontent provi ers o$$er these abilities as Cell. 5o insert ata into a %ontent provi er, you have tCo options available on the Content1rovider inter$a%e &available through %etContent1rovider:; to your a%tivity'* -. "se insert:; Cith a %olle%tion 2ri an a Content7alues stru%ture es%ribing the initial set o$ ata to put in the roC

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

>sing a Content Provider

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,

Be4are of the B +B!


/inary large obOe%ts N /L>/s N are supporte in many atabases, in%lu ing #HLite. )oCever, the An roi mo el is more aime at supporting su%h hunks o$ ata via their oCn separate %ontent 2ri values. A %ontent provi er, there$ore, oes not provi e ire%t a%%ess to binary ata, like photos, via a Cursor. Rather, a property in the %ontent provi er Cill give you the %ontent 2ri $or that parti%ular /L>/. @ou %an use %et.nputStream:; an %et,utputStream:; on your Content1rovider to rea an Crite the binary ata. Huite possibly, the rationale is to minimiKe unne%essary ata %opying. (or e;ample, the primary use o$ a photo in An roi is to isplay it to the user.
%,9
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition

>sing a Content Provider

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 &)

Building a Content Provider

/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.

!irst6 Some .issection


As Cas is%usse in the previous %hapter, the %ontent 2ri is the lin%hpin behin a%%essing ata insi e a %ontent provi er. When using a %ontent provi er, all you really nee to knoC is the provi er7s base 2riP $rom there you %an run <ueries as nee e , or %onstru%t a 2ri to a spe%i$i% instan%e i$ you knoC the instan%e i enti$ier.

%$(
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition

Building a Content Provider

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.

5ext6 Some Typing


0e;t, you nee to %ome up Cith some M.MI types %orrespon ing Cith the %ontent your %ontent provi er Cill provi e. An roi uses both the %ontent 2ri an the M.MI type as Cays to i enti$y %ontent on the evi%e. A %olle%tion %ontent 2ri N or, more a%%urately, the %ombination authority an ata type path N shoul map to a pair o$ M.MI
%$%
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition

Building a Content Provider

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 '.

Step K(H Create a Provider Class


+ust as an a%tivity an intent re%eiver are both +ava %lasses, so is a %ontent provi er. #o, the big step in %reating a %ontent provi er is %ra$ting its +ava %lass, %hoosing as a base %lass either Content1rovider or DatabaseContent1rovider. 0ot surprisingly, DatabaseContent1rovider o$$ers some e;tra hooks to help Cith %ontent provi ers using #HLite atabases $or storage, Chereas Content1rovider is more general3purpose. )ere7s hoC you e;ten these base %lasses to make up your %ontent provi er.

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

Building a Content Provider

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

oesn7t seem all that spe%ial, the Qmagi%Q is in the private

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

Building a Content Provider

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 < < < < <

<

< finally 8 c.close:;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

Building a Content Provider

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

Building a Content Provider

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.

(or e;ample, here is Juery:; $rom 1rovider*


9,verride public Cursor -uery:2ri urlG Strin%OP projectionG Strin% selectionG Strin%OP selectionAr%sG Strin% sort; 8 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 return c5 <

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

Building a Content Provider

.$ 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

Building a Content Provider

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

Building a Content Provider

return count5 <

.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

Building a Content Provider

getContext:;.getContent$esol er:;.notifyChange:urlG null;5 return count5 <

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.

(or e;ample, here is %et-ype:; $rom 1rovider*


9,verride public Strin% getType:2ri url; 8 if :isCollection)ri:url;; 8 return:getCollectionType:;;5 < return:getSingleType:;;5 <

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

Building a Content Provider

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

Step K%H Supply a >ri


@ou also nee to a a publi% stati% member...someChere, %ontaining the 2ri $or ea%h %olle%tion your %ontent provi er supports. 5ypi%ally, this is a publi% stati% $inal 2ri put on the %ontent provi er %lass itsel$*
public static final 2ri C,/-)/-*2R." 2ri.parse:#content!//com.commonsware.android.tourit.1rovider/tours#;5

@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.

Step K,H .eclare the Properties


Remember those properties you re$eren%e Chen you Cere using a %ontent provi er, in the previous %hapterD Well, you nee to have those too $or your oCn %ontent provi er. #pe%i$i%ally, you Cant a publi% stati% %lass implementing 6aseColumns that %ontains your property names, su%h as this e;ample $rom 1rovider*

%/%
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition

Building a Content Provider

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.

Step K$H >pdate the *anifest


5he glue tying the %ontent provi er implementation to the rest o$ your appli%ation resi es in your AndroidManifest.xml $ile. #imply a a <provider& element as a %hil o$ the <application& element*
<provider android!name"#.1rovider# android!aut$orities"#com.commonsware.android.tourit.1rovider# /&

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

Building a Content Provider

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

%onsumer si e, an a%tivity %an %all re%isterContent,bserver:; on its ContentResolver &via %etContentResolver:;'.


%/$
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition

Building a Content Provider

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

Subscribe to updates at http://commonsware.com

Special Creative Commons BY-SA 3.0 License Edition

CHAPTER &*

2equesting and 2equiring Permissions

.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

2equesting and 2equiring Permissions

*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

2equesting and 2equiring Permissions

!igure 0;< ) security exception

Dalt! Who 'oes There:


5he other si e o$ the %oin, o$ %ourse, is to se%ure your oCn appli%ation. .$ your appli%ation is merely a%tivities an intent re%eivers, se%urity may be Oust an 6outboun 9 thing, Chere you re<uest permission to use resour%es o$ other appli%ations. .$, on the other han , you put %ontent provi ers or servi%es in your appli%ation, you Cill Cant to implement 6inboun 9 se%urity to %ontrol Chi%h appli%ations %an o Chat Cith the ata. 0ote that the issue here is less about Chether other appli%ations might 6mess up9 your ata, but rather about priva%y o$ the user7s in$ormation or use o$ servi%es that might in%ur e;pense. 5hat is Chere the sto%k permissions $or built3in An roi appli%ations are $o%use N %an you rea or mo i$y %onta%ts, %an you sen #M#, et%. .$ your appli%ation oes not store in$ormation that might be %onsi ere private N su%h as 5our.t, Chi%h only stores bi%y%le tours N se%urity is less an issue. .$, on the other han , your appli%ation stores private ata, su%h as me i%al in$ormation, se%urity is mu%h more important.

%/9
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition

2equesting and 2equiring Permissions

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.

En,orcin! Permissions vi the % ni,est


5here are tCo Cays $or your appli%ation to en$or%e permissions, i%tating Chere an un er Chat %ir%umstan%es they are re<uire . 5he easier one is to in i%ate in the mani$est Chere permissions are re<uire . A%tivities, servi%es, an intent re%eivers %an all e%lare an attribute name android!permission, Chose value is the name o$ the permission that is re<uire to a%%ess those items*
<activity android!name"#.SekritApp# android!label"#-op Sekrit#

%0;
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition

2equesting and 2equiring Permissions

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

Content provi ers o$$er tCo write1ermission*

<provider android!name"#.Sekrit1rovider# android!aut$orities"#vnd.tla.sekrits.Sekrit1rovider# android!read1ermission"#vnd.tla.sekrits.S))*S)MR.-S# android!write1ermission"#vnd.tla.sekrits.M,D*S)MR.-S# /&

.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.

En,orcin! Permissions Else#here


.n your %o e, you have tCo a @our servi%es %an %he%k itional Cays to en$or%e permissions.

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

2equesting and 2equiring Permissions

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.

*ay 8 See -our .ocuments:


5here is no automati% is%overy o$ permissions at %ompile timeP all permission $ailures o%%ur at runtime. )en%e, it is important that you o%ument the permissions re<uire $or your publi% A!.s, in%lu ing %ontent provi ers, servi%es, an a%tivities inten e $or laun%hing $rom other a%tivities. >therCise, the programmers attempting to inter$a%e Cith your appli%ation Cill have to $in out the permission rules by trial an error. (urthermore, you shoul e;pe%t that users o$ your appli%ation Cill be prompte to %on$irm any permissions your appli%ation says it nee s. )en%e, you nee to o%ument $or your users Chat they shoul e;pe%t, lest they get %on$use by the <uestion pose by the phone an ele%t to not install or use your appli%ation.

%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

Service 4ith Class


Creating a servi%e implementation shares many %hara%teristi%s Cith buil ing an a%tivity. @ou inherit $rom an An roi 3supplie base %lass, overri e some li$e%y%le metho s, an hook the servi%e into the system via the mani$est. #o, the $irst step in %reating a servi%e is to e;ten the Service %lass, in our %ase Cith our oCn Mail6u''Service sub%lass. +ust as a%tivities have onCreate:;, onResume:;, on1ause:; an kin, Service implementations %an overri e three i$$erent li$e%y%le metho s* -.
onCreate:;,

Chi%h, as Cith servi%es, is %alle pro%ess is %reate

Chen the servi%e

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

<

timer.schedule#t"ixed$ate:taskG poll1eriodG poll1eriod;5 < else if :taskW"null; 8 task.cancel:;5 task"null5 <

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.

When 8PC )ttacks!


#ervi%es Cill ten to o$$er inter3pro%ess %ommuni%ation &.!C' as a means o$ intera%ting Cith a%tivities or other An roi %omponents. Ia%h servi%e
%00
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition

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.

3rite the AID=


.ALs are $re<uently Critten in a Qlanguage3neutralQ synta;. A.AL, on the other han , looks a lot like a +ava inter$a%e. (or e;ample, here is the A.AL $or the Mail6u''Service*
packa%e com.commonsware.android.service5 // Declare t$e interface. interface .6u'' 8 void check%ow:;5 void ena!le:in boolean enabled;5 boolean is+na!led:;5 <

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*

!rimitive values &int, float, double, boolean, et%.'

%03
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition

Creating a Service

Strin% an C$arSeJuence +ist an Map

&$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.

Implement the Inter, ce


8iven the A.AL3%reate server stub, noC you nee to implement the servi%e, either ire%tly in the stub, or by routing the stub implementation to other metho s you have alrea y Critten. 5he me%hani%s o$ this are $airly straight$orCar *

%07
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition

Creating a Service

Create a private instan%e o$ the A.AL3generate .6u''.Stub'

.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

(or e;ample, here is the .6u''.Stub instan%e*


private final .6u''.Stub binder"new .6u''.Stu!:; 8 public void check%ow:; 8 check#ccount:;5 < public void ena!le:boolean enabled; 8 ena!le&oll:enabled;5 < public boolean is+na!led:; 8 return:get&ollState:;;5 <

<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

<

private boolean get&ollState:; 8 S$ared1references settin%s"get&refs:;5 < return:settin%s.getBoolean:#enabled#G false;;5

pops a 1,++ message on our <ueue, so our ba%kgroun threa %an poll the mail server
c$eckAccount:;
%09

Subscribe to updates at http://commonsware.com

Special Creative Commons BY-SA 3.0 License Edition

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.

WhereAs the 2emote:


.n An roi , servi%es %an either be lo%al or remote. Lo%al servi%es run in the same pro%ess as the laun%hing a%tivityP remote servi%es run in their oCn pro%ess. A etaile is%ussion o$ remote servi%es Cill be a e to a $uture e ition o$ this book.

%3(
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 &/

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

!igure 0(< The *ailBuLL service client

Bound for Success


5o use a servi%e, you $irst nee to %reate an instan%e o$ your oCn ServiceConnection %lass. ServiceConnection, as the name suggests, represents your %onne%tion to the servi%e $or the purposes o$ making .!C %alls. (or e;ample, here is the ServiceConnection $rom the Mail6u'' %lass in the Mail6u'' proOe%t*
private ServiceConnection svcConn"new Ser iceConnection:; 8 public void onSer iceConnected:Component/ame class/ameG .6inder binder; 8 service".6u''.Stub.asInterface:binder;5 c$eck/ow6utton.set+na!led:true;5 setAccount6utton.set+na!led:true;5 set)nabled.set+na!led:true;5 try 8 set)nabled.setChecked:service.is+na!led:;;5 < catc$ :Dead,bject)xception e; 8 svcConn.onSer iceDisconnected:null;5 < <

%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 <

@our ServiceConnection sub%lass nee s to implement tCo metho s* -.


onServiceConnected:;,

Chi%h is %alle on%e your a%tivity is boun to

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

2equest for Service


>n%e your servi%e inter$a%e obOe%t is rea y &.6u''.Stub.as.nterface:binder;', you %an start %alling metho s on it as you nee to. .n $a%t, i$ you isable some Ci gets aCaiting the %onne%tion, noC is a $ine time to re3enable them &see the above ServiceConnection implementation'. (or e;ample, in onServiceConnected:;, on%e Ce have the servi%e inter$a%e obOe%t, Ce %all is)nabled:; to etermine i$ the QInable pollingQ %he%kbo; shoul be %he%ke or not &via setC$ecked:;'. )oCever, you Cill Cant to trap Dead,bject)xception N i$ this is raise , your servi%e %onne%tion terminate une;pe%te ly. .n this %ase, you shoul unCin your use o$ the servi%e, perhaps by %alling onServiceDisconnected:; manually, as shoCn above.

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

Subscribe to updates at http://commonsware.com

Special Creative Commons BY-SA 3.0 License Edition

CHAPTER &2

)lerting >sers Gia 5otifications

!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

)lerting >sers Gia 5otifications

.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 &notify:;' 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'*

H rd# re "oti,ic tions


@ou %an $lash LIAs on the evi%e by setting lights to true, also spe%i$ying the %olor &as an DAR06 value in ledAR06' an Chat pattern the light shoul blink in &by provi ing o$$Uon urations in millise%on s $or the light via led,nMS an led,ffMS'. @ou %an play a soun , using a 2ri to a pie%e o$ %ontent hel , perhaps, by a ContentMana%er &sound'. 5hink o$ this as a QringtoneQ $or your appli%ation. @ou %an vibrate the evi%e, %ontrolle via a lon%OP in i%ating the onUo$$ patterns &in millise%on s' $or the vibration &vibrate'. @ou might o this by e$ault, or you might make it an option the user %an %hoose Chen %ir%umstan%es re<uire a more subtle noti$i%ation than a ringtone. @ou might also Cant to set insistent to true, in i%ating that the har Care noti$i%ations &e.g., vibration' shoul not be playe Oust on%e, but rather shoul repeat until you %an%el the noti$i%ation.

%7;
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition

)lerting >sers Gia 5otifications

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'.

etting -our Presence Be !elt


5o raise a /otification, you %an use the notify:; metho on the /otificationMana%er servi%e obOe%t, Chere you spe%i$y the noti$i%ation i enti$ier an a /otification obOe%t. 5he i enti$ier is simply a number, uni<ue Cithin your appli%ation, that i enti$ies this spe%i$i% noti$i%ation &versus any others your appli%ation might be raising'. 5o %an%el a noti$i%ation, simply %all cancel:; on the /otificationMana%er servi%e obOe%t, provi ing your i enti$ier $or the noti$i%ation. @ou shoul o this Chen the noti$i%ation i%on is no longer nee e &e.g., the user rea the message an so there are no unrea messages to alert the user about'. (or e;ample, the 5our.t sample appli%ation uses noti$i%ations to alert ri ers that they are nearing Caypoints on their %hosen tour. )oC 5our.t knoCs they are nearing Caypoints is through the lo%ation servi%es o$$ere by An roi , is%usse later in this book. (or the moment, assume that 5our.t %an $in this out N here7s hoC it noti$ies the users.

%7(
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition

)lerting >sers Gia 5otifications

When a Caypoint is near, 5our.t invokes s$ow/otification:; on -our7iewActivity*


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 // 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 <

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

)lerting >sers Gia 5otifications

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

< <5 <

%7,
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

PART VI Other Android Capabilities

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 '4

)ccessing ocation"Based Services

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*

evi%e %an i enti$y your lo%ation.

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

)ccessing ocation"Based Services

ocation ProvidersH They @no4 Where -ouAre Diding


An roi evi%es %an have a%%ess to several i$$erent means o$ etermining your lo%ation. #ome Cill have better a%%ura%y than others. #ome may be $ree, Chile others may have a %ost asso%iate Cith them. #ome may be able to tell you more than Oust your %urrent position, su%h as your elevation over sea level, or your %urrent spee . An roi , there$ore, has abstra%te all this out into a set o$ +ocation1rovider obOe%ts. @our An roi environment Cill have Kero or more +ocation1rovider instan%es, one $or ea%h istin%t lo%ating servi%e that is available on the evi%e. !rovi ers knoC not only your lo%ation, but their oCn %hara%teristi%s, in terms o$ a%%ura%y, %ost, et%. @ou, as a eveloper, Cill use a +ocationMana%er, Chi%h hol s the set, to $igure out Chi%h +ocation1rovider is right $or your parti%ular %ir%umstan%e. @ou Cill also nee the ACC)SS*1,S.-.,/ permission in your appli%ation, or the various lo%ation A!.s Cill $ail ue to a se%urity violation. Aepen ing on Chi%h lo%ation provi ers you Cish to use, you may nee other permissions as Cell, su%h as ACC)SS*01S, ACC)SS*ASS.S-)D*01S, or ACC)SS*C)++*.D.
+ocation1rovider

!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

)ccessing ocation"Based Services

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 <

Chere 1roviderCrapper is*


class 1roviderCrapper 8 +ocation1rovider p5 &ro ider*rapper:+ocation1rovider p; 8 t$is.p"p5 < public Strin% toString:; 8 return:p.get%ame:;;5 < <

%79
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition

)ccessing ocation"Based Services

>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:;

to in i%ate i$ you nee the %urrent altitu e or

to set a minimum level o$ a%%ura%y, in meters, $or the

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

)ccessing ocation"Based Services

(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

)ccessing ocation"Based Services

< < <;5

+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

)re We There -et: )re We There -et: )re We There -et:


#ometimes, you Cant to knoC not Chere you are noC, or even Chen you move, but Chen you get to Chere you7re going. 5his %oul be an en estination, or it %oul be getting to the ne;t step on a set o$ ire%tions, so you %an give the user the ne;t turn. .n 5our.t, $or e;ample, it Coul be ni%e to knoC Chen a ri er gets to a Caypoint, so Ce %an prompt them $or the ire%tion to go to get to the ne;t Caypoint on the tour.

%9%
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition

)ccessing ocation"Based Services

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

)ccessing ocation"Based Services

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

5he o$$i%ial An roi

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

Cay -our7iewActivity 1roximity.ntentReceiver %lass'

%9$
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition

)ccessing ocation"Based Services

// 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

)ccessing ocation"Based Services

< <

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

)ccessing ocation"Based Services

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

Subscribe to updates at http://commonsware.com

Special Creative Commons BY-SA 3.0 License Edition

CHAPTER '1

*apping 4ith *apGie4 and *ap)ctivity

>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.

The Bare Bones


(ar an aCay the simplest Cay to get a map into your appli%ation is to %reate your oCn sub%lass o$ MapActivity. Like +istActivity, Chi%h Craps up some o$ the smarts behin having an a%tivity ominate by a +ist7iew,
%99
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition

*apping 4ith *apGie4 and *ap)ctivity

MapActivity

han les some o$ the nuan%es o$ setting up an a%tivity ominate by a Map7iew.

.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

*apping 4ith *apGie4 and *ap)ctivity

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

Exercising -our Control


@ou %an $in your Map7iew Ci get by find7iew6y.d:;, no i$$erent than any other Ci get. 5he Ci get itsel$ then o$$ers a %etMapController:; metho . /etCeen the Map7iew an MapController, you have a $air bit o$ %apability to etermine Chat the map shoCs an hoC it behaves. )ere are some likely $eatures you Cill Cant to use*

>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

*apping 4ith *apGie4 and *ap)ctivity

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

!igure 0%< *ap 4ith Loom indicator

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

*apping 4ith *apGie4 and *ap)ctivity

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$.

Traffic and Terrain


+ust as the 8oogle Maps you use on your $ull3siKe %omputer %an isplay satellite imagery an , $or some areas, tra$$i% in$ormation, so too %an An roi maps.

,;,
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition

*apping 4ith *apGie4 and *ap)ctivity

!igure 0,< *ap sho4ing satellite vie4

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

*apping 4ith *apGie4 and *ap)ctivity

!ollo4 -ou6 !ollo4 *e


When you use a 8!# navigation system, the Qnormal mo eQ is $or the map to $olloC your position. .t7s as i$ you are stan ing still an the Corl is moving un erneath your Cheels &or $eet, or $lippers, or...'. An roi o$$ers a similar $eature via setEollowMy+ocation:;, MapController. With this, the map shoul re3%enter itsel$ as you available on move.

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

(or e;ample, here is onResume:; $rom -ourMapActivity*


9,verride public void on$esume:; 8 super.on$esume:;5 S$ared1references prefs"getShared&references:Confi%Activity.1R)ESG @;5 s$owMy+ocation"prefs.getBoolean:Confi%Activity.S3,C*+,CA-.,/G true;5

,;/
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition

*apping 4ith *apGie4 and *ap)ctivity

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

*apping 4ith *apGie4 and *ap)ctivity

< <

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

map.in alidate:;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.

ayers >pon ayers


.$ you have ever use the $ull3siKe e ition o$ 8oogle Maps, you are probably use to seeing things overlai atop the map itsel$, su%h as Qpush3pinsQ in i%ating businesses near the lo%ation being sear%he . .n map parlan%e N an , $or that matter, in many serious graphi% e itors N the push3pins are on a separate layer than the map itsel$, an Chat you are seeing is the %omposition o$ the push3pin layer atop the map layer. An roi 7s mapping alloCs you to %reate layers as Cell, so you %an mark up the maps as you nee to base on user input an your appli%ation7s purpose. (or e;ample, 5our.t uses a layer to shoC Chere all the Caypoints o$ the tour are, in se<uen%e, plus your %urrent lo%ation relative to those Caypoints.

,;3
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition

*apping 4ith *apGie4 and *ap)ctivity

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

to get your map7s

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.

Dr #in! the 0verl y


sub%lasses nee to implement a draw:; metho to a%tually put their material onto their layer $or superposition over the map sur$a%e. 5he draw:; metho takes three parameters*
,verlay

-.

A Canvas, use as the raCing sur$a%e

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

*apping 4ith *apGie4 and *ap)ctivity

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

*apping 4ith *apGie4 and *ap)ctivity

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,

2. 5he 1oint representing the real3Corl tappe the map

lo%ation Chere the user ;Uy

?. A 1ixelCalculator to help you %onvert betCeen 1oint an %oor inates, i$ nee e


,(;
Subscribe to updates at http://commonsware.com

Special Creative Commons BY-SA 3.0 License Edition

*apping 4ith *apGie4 and *ap)ctivity

.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

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$.

'et -our *edia +n


.n An roi , you have $ive i$$erent pla%es you %an pull me ia %lips $rom N one o$ these Cill hope$ully $it your nee s* -. @ou %an pa%kage me ia %lips as raC resour%es &res/raw in your proOe%t', so they are bun le Cith your appli%ation. 5he bene$it is that you7re guarantee the %lips Cill be thereP the oCnsi e is that they %annot be repla%e Cithout upgra ing the appli%ation.

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:;

2. .$ you have a 2ri to the %lip, use the 2ri3$lavore

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#

5he +ava, o$ %ourse, is Chere things get interesting*


packa%e com.commonsware.android.audio5 import import import import import import import import import android.app.Activity5 android.content.Context5 android.content.S$ared1references5 android.media.Media1layer5 android.os.6undle5 android.view.Menu5 android.view.7iew5 android.wid%et..ma%e6utton5 android.wid%et.-oast5

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

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

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:;

to an ,nCompletion+istener via N this %allba%k gets invoke Chen the %lip

,(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

We %all a setup:; metho

>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

!igure 0$< The )udio.emo sample application

*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 ''

Dandling Telephone Calls

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

Dandling Telephone Calls

5o6 5o6 5o M 5ot That 8Phone<<<


5o get at the phone A!., you nee to get an obOe%t implementing the .1$one inter$a%e $rom An roi . 5o ay, that Corks mu%h like hoC you Coul a%%ess any other servi%e7s .!C inter$a%e, by %alling .1$one.Stub.as.nterface:; Cith a suitable bin er. 5he i$$eren%e is in hoC you get that bin er*
p$one".1$one.Stub.asInterface:svcM%r.getSer ice:#p$one#;;5

WhatAs +ur Status:


/ear in min that the phone %apability might not alCays be on, even i$ An roi is running. 5he phone might have the phone ra io turne o$$ in pla%es Chere either it isn7t alloCe &airplanes, hospitals, et%.' or as a means o$ silen%ing the phone uring meetings. @ou %an etermine i$ the phone is rea y $or use by %alling isRadio,n:; on the .1$one inter$a%e. @ou %an even %all to%%leRadio,n,ff:; to %hange the ra io7s status N though you really shoul make sure this is Chat the user Cants, lest they a%%i entally toggle the phone on Chen they really shoul n7t. >$ %ourse, there7s a more prosai% reason Chy you might not be able to use the phone N the user might alrea y be on a %all. 5he is,ff$ook:; metho N espite using the ar%hai% QhookQ terminology $rom a byegone era o$ phones N Cill tell i$ you i$ a %all is in progress. )ere, Qo$$ hookQ means the phone is in use, so i$ is,ff$ook:; returns true, you %annot pla%e a %all.

-ou *ake the Call!


.!hone also o$$ers three A!.s relate to %all han ling* -. Chi%h takes a phone number an puts it on the An roi Aialer s%reen, aCaiting user %on$irmation to ial that number
dial:;,

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

Dandling Telephone Calls

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

Dandling Telephone Calls

/& </+inear+ayout& </+inear+ayout&

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

Dandling Telephone Calls

< 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 < <

#ome notes about the %o e*

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

5he a%tivity7s oCn ". is not that impressive*

,%9
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition

Dandling Telephone Calls

!igure 00< The .ialer.emo sample application6 as initially launched

)oCever, the ialer you get $rom %li%king the ial button is better, shoCing you the number you are about to ial*

!igure 03< The )ndroid .ialer activity6 as launched from .ialer.emo

,,;
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition

Dandling Telephone Calls

>r, i$ you %li%k the %all button, you are taken straight to a %all*

!igure 07< The )ndroid call activity6 as launched from .ialer.emo

,,(
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 '(

Searching 4ith Search*anager

>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

Searching 4ith Search*anager

!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

Searching 4ith Search*anager

!igure 3;< ) filtered search for contacts

>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

Searching 4ith Search*anager

-.

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.

Cr ,t the Se rch Activity


5he $irst thing you are going to Cant to o i$ you Cant to support <uery3style sear%h in your appli%ation is to %reate a sear%h a%tivity. While it might be possible to have a single a%tivity be both opene $rom the laun%her an opene $rom a sear%h, that might prove someChat %on$using to users. Certainly, $or the purposes o$ learning the te%hni<ues, having a separate a%tivity is %leaner. 5he sear%h a%tivity %an have any look you Cant. .n $a%t, other than Cat%hing $or <ueries, a sear%h a%tivity looks, Calks, an talks like any other a%tivity in your system. All the sear%h a%tivity nee s to o i$$erently is %he%k the intents supplie to onCreate:; &via %et.ntent:;' an on/ew.ntent:; to see i$ one is a sear%h, an , i$ so, to o the sear%h an isplay the results. (or e;ample, let7s look at the +orem sample appli%ation. 5his starts o$$ as a %lone o$ the list3o$3lorem3ipsum3Cor s appli%ation that Ce $irst built ba%k Chen shoCing o$$ the +ist7iew %ontainer, then later Cith EML resour%es. 0oC, Ce up ate it to support sear%hing the list o$ Cor s $or ones %ontaining the sear%h string. 5he main a%tivity an the sear%h a%tivity both share a %ommon layout* a +ist7iew plus a -ext7iew shoCing the sele%te entry*

,,0
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition

Searching 4ith Search*anager

<>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

Searching 4ith Search*anager

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

Searching 4ith Search*anager

< <

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

Searching 4ith Search*anager

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

+pd te the % ni,est


While this implements sear%h, it oesn7t tie it into the An roi sear%h system. 5hat re<uires a $eC %hanges to the auto3generate AndroidManifest.xml $ile*
<manifest xmlns!android"#$ttp!//sc$emas.android.com/apk/res/android# packa%e"#com.commonsware.android.searc$#& <application& <activity android!name"#.+oremDemo# android!label"#+oremDemo#& <intent(filter& <action android!name"#android.intent.action.MA./# /& <cate%ory android!name"#android.intent.cate%ory.+A2/C3)R# /& </intent(filter& <meta(data android!name"#android.app.default*searc$able# android!value"#.+oremSearc$# /& </activity&

,$;
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition

Searching 4ith Search*anager

<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

Searching 4ith Search*anager

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

Searching 4ith Search*anager

!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

Subscribe to updates at http://commonsware.com

Special Creative Commons BY-SA 3.0 License Edition

PART VII Appendices

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

APPE"DI? A

The Tour8t Sample )pplication

.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.

Demo =oc tion Provider


As mentione in the %hapter on lo%ations, An roi has a built3in $ake, or emo, lo%ation provi er, that has the evi%e moving through a loop aroun the 8oogle %ampus in Cali$ornia. 5he author o$ this book oes not live in #ili%on ,alley. As su%h, he ha no goo Cay o$ eveloping a bi%y%le tour mat%hing that loop. .t Cas more e;pe ient to evelop another emo lo%ation provi er, this one han ling a loop aroun the author7s home base in eastern !ennsylvania, Cith the tour starting at the Lehigh ,alley ,elo rome.
,$3
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition

The Tour8t Sample )pplication

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

Chi%h hol s the most3re%ent position o$ the evi%e along

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.

SD C rd Im !e #ith S mple Tour


(uture e itions o$ 5our.t Cill support multime ia %lips, on%e some stan ar players start shipping Cith the An roi #AF &versus the player %omponents es%ribe in an earlier %hapter'. )en%e, the long3term vision is $or a tour an its asso%iate me ia %lips to resi e on an #A %ar , either oCnloa e there o$$ the .nternet, or trans$erre there via "#/ %ables, /luetooth, or similar means.

,$7
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition

The Tour8t Sample )pplication

(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%

5hat Cill mount the %ar un er /sdcard/ in the emulator7s $ilesystem.

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

The Tour8t Sample )pplication

Cli%king on that i%on brings up the main 5our.t a%tivity.

% in Activity
5he main a%tivity provi es tCo istin%t s%reens* -. A Qhome pageQ shoCing version in$ormation an some navigation buttons

2. A list o$ available tours loa e into the appli%ation

!igure 3$< The Tour8t =home page=

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

The Tour8t Sample )pplication

!igure 3/< The Tour8t =home page= 4ith option menu

.$ 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

The Tour8t Sample )pplication

!igure 30< The Tour8t list of tours

Con,i!ur tion Activity


)oCever, be$ore looking at a tour, it is a goo i ea to visit the %on$iguration a%tivity, so Ce %an use the right sample lo%ation provi er Chen raCing the map. .$ you %hoose the Q%on$igureQ button or option menu %hoi%e, you Cill bring up that %on$iguration a%tivity*

,/%
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition

The Tour8t Sample )pplication

!igure 33< The Tour8t configuration activity

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

The Tour8t Sample )pplication

Cue Sheet Activity


>$ %ourse, the interesting part o$ 5our.t are the tours themselves. >n the tours list, i$ you %hoose the QL, ,elo romeQ tour, it Cill bring up the %ue sheet*

!igure 37< ) tourAs cue sheet in Tour8t

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

The Tour8t Sample )pplication

!igure 39< The Tour8t cue sheet 4ith 4aypoint details

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

The Tour8t Sample )pplication

!igure 7;< The Tour8t map vie4

@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

The Tour8t Sample )pplication

!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.

Tour +pd te Activity


5our.t oes not alloC you to e$ine neC tours $rom s%rat%h insi e the appli%ation, mostly be%ause there Coul be a $air amount o$ typing involve , an that Coul be te ious on a phone. )oCever, it oes alloC you to up ate the position in$ormation asso%iate Cith Caypoints. .n theory, you Coul use some e;ternal program to e$ine a tour, uploa it to 5our.t, then take the tour an up ate the Caypoints as you go, then publish the resulting up ate tour. 5here are a $eC pie%es missing in this version o$ 5our.t to make this a reality &e.g., easily a ing an publishing tours', but
,/3
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition

The Tour8t Sample )pplication

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*

!igure 7%< >pdating a cue sheet 4ithin Tour8t

,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

The Tour8t Sample )pplication

!igure 7,< ) Tour8t help page

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

The Tour8t Sample )pplication

</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

The Tour8t Sample )pplication

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

The Tour8t Sample )pplication

>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

is the home page plus the list o$ installe tours tour

-our7iewActivity shoCs the %ue sheet $or a sele%te -ourMapActivity

shoCs the Caypoints $or the tour, plus &optionally'

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

is the gateCay to online help $or using 5our.t hoC

Confi%Activity alloCs you to set various options $or %ustomiKing

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

The Tour8t Sample )pplication

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*

Custo) !ist Contents


5he in ivi ual items in the %ue sheet N the Caypoint title plus the ire%tion o$ hoC to get there N is a tri$le more %ompli%ate than the sto%k list $ormats supplie by An roi . .t7s su$$i%iently %ompli%ate that even Oust provi ing a %ustom layout Coul not han le the nee . #o, -our7iewActivity has a private

,0,
Subscribe to updates at http://commonsware.com Special Creative Commons BY-SA 3.0 License Edition

The Tour8t Sample )pplication

%lass, RouteAdapter, that sub%lasses ArrayAdapter an vieCs as nee e .

buil s the list item

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

les the $irst entry, in$lating a layout populating it*

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

The Tour8t Sample )pplication

marker.setImage$esource:get$esource"or'arker:pt.get"romDirection:;.get'arker :;;;5 < waypoint.setText:pt.getTitle:;;5 return:view;5 <

(inally, RouteAdapterD%et-wo+ine7iew:; in$lates a tCo3line layout an populates it as Cell*


private 7iew getTwoLineView:Caypoint ptG boolean stripeG 7iew convert7iew; 8 7iew.nflate inflater"context.getViewInflate:;5 7iew view"inflater.inflate:R.layout.tourview*HlineG 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 -ext7iew $int":-ext7iew;view.findViewById:R.id.$int;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 marker.setImage$esource:get$esource"or'arker:pt.get"romDirection:;.get'arker :;;;5 < waypoint.setText:pt.getTitle:;;5 $int.setText:pt.get"romDirection:;.get(int:;;5 return:view;5 <

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

The Tour8t Sample )pplication

5o

manually $lipping the -our7iewActivity implements onMey2p:;*

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 <

< <

< else 8 details1anel.setIn#nimation:Animation2tils.load#nimation:t$isG R.anim.pus$*left*in;;5 details1anel.setOut#nimation:Animation2tils.load#nimation:t$isG R.anim.pus$*left*out;;5 details1anel.show%ext:;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

The Tour8t Sample )pplication

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

The Tour8t Sample )pplication

Strin% pa%e"getIntent:;.getString+xtra:1A0);5 if :pa%e""null; 8 browser.load)rl:#file!///android*asset/index.$tml#;5 < else 8 browser.load)rl:#file!///android*asset/#Bpa%eB#.$tml#;5 <

<

/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

I0AW5A8................................................................-4(AC5>R@W5I#5WAC5.>0....................................20(.R#5.......................................................................11 8AA8I5WCA5I8>R@..........................................202 8I5.........................................................................-88 8I5WC>05I05WAC5.>0....................................20)>MIWCA5I8>R@..............................................202 )>R.M>05AL........................................................=2 .A............................................................................-2=

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

&ethod

%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