Documente Academic
Documente Profesional
Documente Cultură
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* #ep 2008* +ersion ,.2 -#./* 01820208,31802020 relate tra e ress are
4he CommonsWare name an logo, 5.usy Co er6s 7ui e8, an tra emarks o$ CommonsWare, LLC.
All other tra emarks re$eren%e in this book are tra emarks o$ their respe%tive $irms. 4he publisher an author&s' assume no responsibility $or errors or omissions or $or amages resulting $rom the use o$ the in$ormation %ontaine herein.
Table of Contents
Welcome to the Warescription!..................................................................................xiii Preface..........................................................................................................................xv Wel%ome to the .ook9...........................................................................................................:v !rere;uisites..........................................................................................................................:v Wares%ription.......................................................................................................................:vi .ook .ug .ounty.................................................................................................................:vii #our%e Co e Li%ense..........................................................................................................:viii Creative Commons an the (our2to2(ree &<2(' 7uarantee............................................:viii A%kno=le gements............................................................................................................: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 /et=ork............................................................................................................................B Multime ia.......................................................................................................................B 7!#...................................................................................................................................B !hone #ervi%es.................................................................................................................3 Pro"ect #tructure............................................................................................................$ Root Contents..........................................................................................................................1
iii
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
4he #=eat >$$ @our .ro=.......................................................................................................8 An /o=, 4he Rest o$ the #tory.............................................................................................8 What @ou 7et >ut >$ -t.........................................................................................................0 %nside the &anifest........................................................................................................!! -n 4he .eginning, 4here Was the Root, An -t Was 7oo .................................................,, !ermissions, -nstrumentations, an Appli%ations &>h, My9'.............................................,2 @our Appli%ation Aoes #omething, RightC..........................................................................,? Creatin a #'eleton Application...................................................................................!$ .egin at the .eginning...........................................................................................................,1 4he A%tivity............................................................................................................................,8 Aisse%ting the A%tivity...........................................................................................................,0 .uil ing an Running the A%tivity.......................................................................................2, (sin )&*+Based *ayouts............................................................................................,What -s an DML2.ase LayoutC...........................................................................................2B Why "se DML2.ase LayoutsC............................................................................................23 >E, #o What Aoes -t Look LikeC..........................................................................................21 What6s With the F #ignsC....................................................................................................28 An We Atta%h 4hese to the Gava...)o=C...........................................................................28 4he Rest o$ the #tory.............................................................................................................20 .mployin Basic Wid ets..............................................................................................// Assigning Labels....................................................................................................................?? .utton, .utton, Who6s 7ot the .uttonC..............................................................................?< (leeting -mages......................................................................................................................?B (iel s o$ 7reen. >r >ther Colors.........................................................................................?3 Gust Another .o: to Che%k...................................................................................................?0 4urn the Ra io "p................................................................................................................<2 -t6s Huite a +ie=....................................................................................................................<< "se$ul !roperties...........................................................................................................<< "se$ul Metho s.............................................................................................................<< Wor'in 0ith Containers.............................................................................................1$ 4hinking Linearly..................................................................................................................<8 Con%epts an !roperties...............................................................................................<8 I:ample...........................................................................................................................B,
iv
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
All 4hings Are Relative.........................................................................................................B3 Con%epts an !roperties...............................................................................................B3 I:ample..........................................................................................................................B0 4abula Rasa............................................................................................................................32 Con%epts an !roperties...............................................................................................32 I:ample..........................................................................................................................3B #%roll=ork..............................................................................................................................33 (sin #election Wid ets...............................................................................................$! A apting to the Cir%umstan%es............................................................................................1, "sing ArrayA apter.......................................................................................................12 >ther Eey A apters.......................................................................................................1? Lists o$ /aughty an /i%e....................................................................................................1< #pin Control...........................................................................................................................13 7ri @our Lions &>r #omething Like 4hat...'.....................................................................80 (iel s* /o= With ?BJ Less 4yping9....................................................................................8< 7alleries, 7ive >r 4ake 4he Art...........................................................................................88 Gettin 2ancy With *ists..............................................................................................34 7etting 4o (irst .ase............................................................................................................80 A Aynami% !resentation.......................................................................................................02 A #i ebar About -n$lation.............................................................................................0< An /o=, .a%k 4o >ur #tory.......................................................................................0< .etter. #tronger. (aster.........................................................................................................0B "sing %onvert+ie=........................................................................................................03 "sing the )ol er !attern.............................................................................................08 Making a List.........................................................................................................................,0, ...An Che%king -t 4=i%e.....................................................................................................,01 .mployin 2ancy Wid ets and Containers..................................................................!!!i%k an Choose....................................................................................................................,,B 4ime Eeeps (lo=ing Like a River........................................................................................,20 Making !rogress....................................................................................................................,2, !utting -t >n My 4ab...........................................................................................................,22 4he !ie%es.....................................................................................................................,2? 4he - iosyn%rasies........................................................................................................,2?
v
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
Wiring -t 4ogether.......................................................................................................,2B >ther Containers o$ /ote....................................................................................................,28 Applyin &enus...........................................................................................................!,4 (lavors o$ Menu....................................................................................................................,20 Menus o$ >ptions................................................................................................................,?0 Menus in Conte:t.................................................................................................................,?2 4aking a !eek........................................................................................................................,?? .m5eddin the We56it Bro0ser.................................................................................!1! A .ro=ser, Writ #mall..........................................................................................................,<, Loa ing -t "p........................................................................................................................,<? /avigating the Waters.........................................................................................................,<B Intertaining the Client........................................................................................................,<3 #ettings, !re$eren%es, an >ptions &>h, My9'...................................................................,<8 #ho0in Pop+(p &essa es..........................................................................................!-! Raising 4oasts........................................................................................................................,B, Alert9 Alert9...........................................................................................................................,B2 Che%king 4hem >ut.............................................................................................................,B? Dealin 0ith Threads..................................................................................................!-$ 7etting 4hrough the )an lers............................................................................................,B1 Messages.......................................................................................................................,B8 Runnables......................................................................................................................,3, Running -n !la%e...................................................................................................................,3, Where, >h Where )as My "- 4hrea 7oneC....................................................................,32 An /o=, 4he Caveats........................................................................................................,32 7andlin Activity *ifecycle .vents.............................................................................!8#%hroe inger6s A%tivity........................................................................................................,3B Li$e, Aeath, an @our A%tivity............................................................................................,33 onCreate&' an onAestroy&'........................................................................................,33 on#tart&', onRestart&', an on#top&'..........................................................................,31 on!ause&' an onResume&'.........................................................................................,31 4he 7ra%e o$ #tate................................................................................................................,38 (sin Preferences........................................................................................................!$/ 7etting What @ou Want......................................................................................................,1?
vi
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
#tating @our !re$eren%e.......................................................................................................,1< An /o=, a Wor (rom >ur (rame=ork..........................................................................,1B Letting "sers )ave 4heir #ay..............................................................................................,13 A ing a Wee .it >6 #tru%ture............................................................................................,8, 4he Ein >$ !op2"ps @ou Like..........................................................................................,8< Accessin 2iles.............................................................................................................!34 @ou An 4he )orse @ou Ro e -n >n.................................................................................,80 Rea in6 6n Writin6.................................................................................................................,0? Wor'in 0ith 9esources.............................................................................................!4$ 4he Resour%e Lineup...........................................................................................................,01 #tring 4heory.......................................................................................................................,08 !lain #trings.................................................................................................................,08 #tring (ormats..............................................................................................................,00 #tyle 4e:t....................................................................................................................,00 #tyle (ormats.............................................................................................................200 7ot the !i%tureC...................................................................................................................20< DML* 4he Resour%e Way....................................................................................................201 Mis%ellaneous +alues..........................................................................................................200 Aimensions...................................................................................................................2,0 Colors............................................................................................................................2,0 Arrays.............................................................................................................................2,, Ai$$erent #trokes $or Ai$$erent (olks..................................................................................2,2 &ana in and Accessin *ocal Data5ases..................................................................,!$ A Hui%k #HLite !rimer........................................................................................................2,8 #tart at the .eginning..........................................................................................................2,0 #etting the 4able.................................................................................................................220 Makin6 Aata..........................................................................................................................22, What 7oes Aroun , Comes Aroun ..................................................................................222 Ra= Hueries.................................................................................................................222 Regular Hueries...........................................................................................................22? .uil ing =ith .uil ers.................................................................................................22< "sing Cursors...............................................................................................................22B Making @our >=n Cursors.........................................................................................223
vii
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
Aata, Aata, Ivery=here......................................................................................................223 *evera in :ava *i5raries............................................................................................,,4 4he >uter Limits.................................................................................................................220 Ants an Gars........................................................................................................................2?0 (ollo=ing the #%ript.............................................................................................................2?, Communicatin via the %nternet................................................................................,/$ RI#4 an Rela:ation...........................................................................................................2?1 )44! >perations via Apa%he )ttpComponents......................................................2?8 !arsing Responses.......................................................................................................2<0 #tu$$ 4o Consi er.........................................................................................................2<2 Creatin %ntent 2ilters................................................................................................,1$ What6s @our -ntentC............................................................................................................2<8 !ie%es o$ -ntents..........................................................................................................2<8 -ntent Routing.............................................................................................................2<0 #tating @our -ntent&ions'....................................................................................................2B0 /arro= Re%eivers.................................................................................................................2B2 4he !ause Caveat.................................................................................................................2B? *aunchin Activities and #u5+Activities.....................................................................,-!eers an #ubs.....................................................................................................................2B3 #tart 6Im "p.........................................................................................................................2B3 Make an -ntent.............................................................................................................2B1 Make the Call...............................................................................................................2B1 2indin Availa5le Actions via %ntrospection..............................................................,8/ !i%k 6Im...............................................................................................................................23< Woul @ou Like to #ee the MenuC....................................................................................238 Asking Aroun .....................................................................................................................210 (sin a Content Provider............................................................................................,$/ !ie%es o$ Me.........................................................................................................................21? 7etting a )an le.................................................................................................................21< Makin6 Hueries.....................................................................................................................21B A apting to the Cir%umstan%es..........................................................................................211 Aoing -t .y )an .................................................................................................................218 !osition........................................................................................................................210
viii
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
7etting !roperties.......................................................................................................210 7ive an 4ake......................................................................................................................210 .e=are o$ the .L>.9............................................................................................................28, Buildin a Content Provider.......................................................................................,3/ (irst, #ome Aisse%tion.........................................................................................................28? /e:t, #ome 4yping..............................................................................................................28< #tep K,* Create a !rovi er Class..........................................................................................28B onCreate&'....................................................................................................................28B ;uery&'..........................................................................................................................283 insert&'..........................................................................................................................288 up ate&'........................................................................................................................280 elete&'.........................................................................................................................200 get4ype&'.......................................................................................................................20, #tep K2* #upply a "ri...........................................................................................................202 #tep K?* Ae%lare the !roperties..........................................................................................202 #tep K<* "p ate the Mani$est.............................................................................................20? /oti$y2>n2Change #upport................................................................................................20< 9e;uestin and 9e;uirin Permissions.....................................................................,4$ Mother, May -C....................................................................................................................208 )alt9 Who 7oes 4hereC......................................................................................................200 In$or%ing !ermissions via the Mani$est....................................................................?00 In$or%ing !ermissions Ilse=here...............................................................................?0, May - #ee @our Ao%umentsC...............................................................................................?02 Creatin a #ervice......................................................................................................../</ #ervi%e =ith Class................................................................................................................?0< When -!C Atta%ks9..............................................................................................................?03 Write the A-AL............................................................................................................?03 -mplement the -nter$a%e.............................................................................................?08 Mani$est Aestiny.................................................................................................................?00 Lobbing >ne >ver the (en%e.............................................................................................?00 Where6s the RemoteC An the Rest o$ the Co eC...............................................................?,, %nvo'in a #ervice......................................................................................................../!/ .oun $or #u%%ess................................................................................................................?,<
ix
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
Re;uest $or #ervi%e...............................................................................................................?,3 !rometheus "nboun .........................................................................................................?,3 Manual 4ransmission..........................................................................................................?,3 Cat%hing the Lob..................................................................................................................?,1 Alertin (sers =ia >otifications................................................................................../,! 4ypes o$ !estering................................................................................................................?2, )ar =are /oti$i%ations...............................................................................................?22 -%ons..............................................................................................................................?22 #eeing !estering in A%tion..................................................................................................?2? Accessin *ocation+Based #ervices............................................................................./,4 Lo%ation !rovi ers* 4hey Eno= Where @ou6re )i ing....................................................??0 (in ing @oursel$...................................................................................................................??0 >n the Move........................................................................................................................??2 Are We 4here @etC Are We 4here @etC Are We 4here @etC.............................................??? 4esting...4esting...................................................................................................................??B (ee Me9 #ee More9......................................................................................................??B Making a Mo%kery o$ the #ituation............................................................................??1 Changing Weather !atterns........................................................................................??8 &appin 0ith &ap=ie0 and &apActivity.................................................................../1! 4he .are .ones.....................................................................................................................?<, I:er%ising @our Control......................................................................................................?<? Loom.............................................................................................................................?<< Center...........................................................................................................................?<B Rugge 4errain....................................................................................................................?<3 Layers "pon Layers.............................................................................................................?<3 >verlay Classes............................................................................................................?<1 Ara=ing the -temiMe >verlay....................................................................................?<1 )an ling #%reen 4aps.................................................................................................?<0 7andlin Telephone Calls.........................................................................................../-! Report 4o 4he Manager......................................................................................................?B2 @ou Make the Call9..............................................................................................................?B2 #earchin 0ith #earch&ana er.................................................................................../-$ )unting #eason....................................................................................................................?B1
x
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
#ear%h @oursel$....................................................................................................................?B0 Cra$t the #ear%h A%tivity.............................................................................................?30 "p ate the Mani$est....................................................................................................?3< #ear%hing $or Meaning -n Ran omness.............................................................................?3B
xi
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
We hope you enNoy this ebook an its up ates O subs%ribe to the Wares%ription ne=sletter on the Wares%ription site to learn =hen ne= e itions o$ this book, or other books, are available. All e itions o$ CommonsWare titles, print an ebook, $ollo= a so$t=are2 style numbering system. MaNor releases &,.0, 2.0, et%.' are available in both print an ebookP minor releases &0.,, 0.0, et%.' are available in ebook $orm $or Wares%ription subs%ribers only. Releases en ing in .0 are Qrelease %an i atesQ $or the ne:t maNor release, la%king perhaps an in e: but other=ise being %omplete. Ia%h Wares%ription ebook is li%ense $or the e:%lusive use o$ its subs%riber an is tagge =ith the subs%ribers name. We ask that you not istribute these books. -$ you =ork $or a $irm an =ish to have several employees have a%%ess, enterprise Wares%riptions are available. Gust %onta%t us at enterpriseF%ommons=are.%om. Also, bear in min that eventually this e ition o$ this title =ill be release un er a Creative Commons li%ense O 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. Gust visit the Web page $or the book you are intereste in an $ollo= the links. #ome notes $or Ein le users*
xiii
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
@ou may =ish to rop your $ont siMe 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 Ein le $ont siMe
xiv
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
Preface
Prerequisites
-$ you are intereste in programming $or An roi , you =ill nee at least basi% un erstan ing o$ ho= to program in Gava. An roi programming is one using Gava synta:, plus a %lass library that resembles a subset o$ the Gava #I library &plus An roi 2spe%i$i% e:tensions'. -$ you have not programme in Gava be$ore, you probably shoul ;ui%k learn ho= that =orks be$ore attempting to ive into programming $or An roi .
xv
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
4he book oes not %over in any etail ho= to o=nloa or install the An roi evelopment tools, either the I%lipse -AI $lavor or the stan alone $lavor. 4he An roi Web site %overs this ;uite ni%ely. 4he material in the book shoul be relevant =hether you use the -AI or not. @ou shoul o=nloa , 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 =ith a link ba%k to the pre%e ing se%tion o$ relevan%e.
Warescription
4his book =ill be publishe both in print an in igital &ebook' $orm. 4he ebook versions o$ all CommonsWare titles are available via an annual subs%ription O the Wares%ription. 4he Wares%ription entitles you, $or the uration o$ your subs%ription, to ebook $orms o$ all CommonsWare titles, not Nust the one you are rea ing. !resently, CommonsWare o$$ers !A( an Ein leP other ebook $ormats =ill be a e base on interest an the openness o$ the $ormat. Ia%h subs%riber gets personaliMe e itions o$ all e itions o$ ea%h title* both those mirroring printe e itions an in2bet=een up ates that are only available in ebook $orm. 4hat =ay, your ebooks are never out o$ ate $or long, an you %an take a vantage o$ ne= material as it is ma e available instea o$ having to =ait $or a =hole ne= print e ition. (or e:ample, =hen ne= releases o$ the An roi #AE are ma e available, this book =ill be ;ui%kly up ate to be a%%urate =ith %hanges in the A!-s. (rom time to time, subs%ribers =ill also re%eive a%%ess to subs%riber2only online material, both short arti%les an not2yet2publishe ne= titles. Also, i$ you o=n a print %opy o$ a CommonsWare book, an it is in goo %lean %on ition =ith 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-NC-SA 3.0 License Edition
4ypographi%al errors #ample appli%ations that o not =ork as a vertise , in the environment es%ribe in the book (a%tual errors that %annot be open to interpretation
.y Quni;ueQ, =e mean ones not yet reporte . Ia%h book has an errata page on the CommonsWare Web siteP most kno=n problems =ill be liste there. We appre%iate hearing about Qso$terQ issues as =ell, su%h as*
!la%es =here you think =e are in error, but =here =e $eel our interpretation is reasonable !la%es =here you think =e %oul a upon the e:isting material sample appli%ations, or e:pan
#amples that o not =ork ue to Qshi$ting san sQ o$ the un erlying environment &e.g., %hange A!-s =ith ne= releases o$ an #AE'
)o=ever, those Qso$terQ issues o not ;uali$y $or the $ormal bounty program. Huestions about the bug bounty, or problems you =ish to report $or bounty %onsi eration, shoul be sent to bountyF%ommons=are.%om.
xvii
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
(ckno)ledgments
- =oul like to thank the An roi team, not only $or putting out a goo pro u%t, but $or invaluable assistan%e on the An roi 7oogle 7roups. -n parti%ular, - =oul like to thank Romain 7uy an ha%kbo .
xviii
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
-%ons use in the sample %o e =ere provi e by the /uvola i%on set.
xix
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
CHAPTER 1
An roi evi%es, by an large, =ill 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 ra=ba%ks.
>n the plus si e, %ir%a 2008, An roi 2style smartphones are se:y. >$$ering -nternet servi%es over mobile evi%es ates ba%k to the mi 2,0006s an the )an hel Aevi%e Markup Language &)AML'. )o=ever, only in re%ent years have phones %apable o$ -nternet a%%ess taken o$$. /o=, thanks to tren s like te:t messaging an to pro u%ts like Apple6s i!hone, phones that %an serve as -nternet a%%ess evi%es are rapi ly gaining popularity. #o, =orking on An roi appli%ations gives you e:perien%e =ith an interesting te%hnology &An roi ' in a $ast2moving market segment &-nternet2enable phones', =hi%h is al=ays a goo thing. 4he problem %omes =hen you a%tually have to program the arn things. Anyone =ith 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 =on6t get %omments like, Qis that a 2<2in%h LCA in your po%ket, or...CQ' Eeyboar s, i$ they e:ist, are small
*
!ointing evi%es, i$ they e:ist, are annoying &as anyone =ho has lost their stylus =ill tell you' or ine:a%t &large $ingers an Qmulti2tou%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 $rame=ork you =ant, so long as it =as =hat the evi%e manu$a%turer %hose an burne into the phone6s sili%on An so on
Moreover, appli%ations running on a phone have to eal =ith the $a%t that they6re on a phone. !eople =ith mobile phones ten to get very irritate =hen those phones on6t =ork, =hi%h is =hy the Q%an you hear me no=CQ a %ampaign $rom +eriMon Wireless has been popular $or the past $e= years. #imilarly, those same people =ill get irritate at you i$ your program QbreaksQ their phone*
...by tying up the C!" su%h that %alls %an6t be re%eive ...by not =orking properly =ith the rest o$ the phone6s >#, su%h that your appli%ation oesn6t ;uietly $a e to the ba%kgroun =hen a %all %omes in or nee s to be pla%e ...by %rashing the phone6s 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%k2en server pro%esses. @ou =in up =ith i$$erent2looking tools, i$$erent2behaving $rame=orks, an Q i$$erent than you6re use toQ limitations on =hat you %an o =ith your program. What An roi tries to o is meet you hal$=ay*
@ou get a %ommonly2use programming language &Gava' =ith some %ommonly use libraries &e.g., some Apa%he Commons A!-s', =ith support $or tools you may be use to &I%lipse'
%
@ou get a $airly rigi an un%ommon $rame=ork in =hi%h your programs nee to run so they %an be Qgoo %itiMensQ on the phone an not inter$ere =ith other programs or the operation o$ the phone itsel$
As you might e:pe%t, mu%h o$ this book eals =ith that $rame=ork an ho= you =rite programs that =ork =ithin its %on$ines an take a vantage o$ its %apabilities.
Activities
4he 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 =in o= 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 =ill be pa%kage in the $orm o$ %ontent provi ers or servi%es, es%ribe belo=.
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
Content Providers
Content provi ers provi e a level o$ abstra%tion $or any ata store on the evi%e that is a%%essible by multiple appli%ations. 4he An roi evelopment mo el en%ourages you to make your o=n ata available to other appli%ations, as =ell as your o=n O buil ing a %ontent provi er lets you o that, =hile maintaining %omplete %ontrol over ho= 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 =are state %hanges &e.g., an #A %ar =as inserte ', to in%oming ata &e.g., an #M# message arrive ', to appli%ation events &e.g., your a%tivity =as laun%he $rom the evi%e6s main menu'. /ot only %an you respon to intents, but you %an %reate your o=n, to laun%h other a%tivities, or to let you kno= =hen spe%i$i% situations arise &e.g., raise su%h2an 2so intent =hen the user gets =ithin ,00 meters o$ this2an 2su%h lo%ation'.
Services
A%tivities, %ontent provi ers, an intent re%eivers are all short2live an %an be shut o=n 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-NC-SA 3.0 License Edition
"et#or$
An roi evi%es =ill generally be -nternet2rea y, through one %ommuni%ations me ium or another. @ou %an take a vantage o$ the -nternet a%%ess at any level you =ish, $rom ra= Gava so%kets all the =ay up to a built2in WebEit2base Web bro=ser =i 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, =hether that is to play ba%k musi%, take pi%tures =ith the %amera, or use the mi%rophone $or au io note2taking.
GPS
An roi evi%es =ill $re;uently have a%%ess to lo%ation provi ers, su%h as 7!#, that %an tell your appli%ations =here the evi%e is on the $a%e o$ the Iarth. -n turn, you %an isplay maps or other=ise take a vantage o$ the lo%ation ata, su%h as tra%king a evi%e6s movements i$ the evi%e has been stolen.
0
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
Phone Services
An , o$ %ourse, An roi evi%es are typi%ally phones, allo=ing your so$t=are 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.
1
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
CHAPTER &
Pro2ect Structure
4he An roi buil system is organiMe aroun a spe%i$i% ire%tory tree stru%ture $or your An roi proNe%t, mu%h like any other Gava proNe%t. 4he spe%i$i%s, though, are $airly uni;ue to An roi an =hat it all oes to prepare the a%tual appli%ation that =ill run on the evi%e or emulator. )ere6s a ;ui%k primer on the proNe%t stru%ture, to help you make sense o$ it all, parti%ularly $or the sample %o e re$eren%e in this book.
3oot Contents
When you %reate a ne= An roi proNe%t &e.g., via activitycreator', you get $ive key items in the proNe%t6s root ire%tory*
AndroidManifest.xml,
=hi%h is an DML $ile es%ribing the appli%ation being built an =hat %omponents O a%tivities, servi%es, et%. O are being supplie by that appli%ation =hi%h is an Ant s%ript $or %ompiling the appli%ation an installing it on the evi%e
bin/, =hi%h hol libs/, build.xml,
=hi%h hol s any thir 2party Gava GARs your appli%ation re;uires
src/, =hi%h hol res/,
=hi%h hol s Qresour%esQ, su%h as i%ons, 7"- layouts, an the like, that get pa%kage =ith the %ompile Gava in the appli%ation
4
Pro2ect Structure
=hi%h hol other stati% $iles you =ish pa%kage =ith the appli%ation $or eployment onto the evi%e
assets/,
res/raw/ $or general2purpose $iles &e.g,. a C#+ $ile o$ a%%ount in$ormation' res/values/
7
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
Pro2ect Structure
When you %ompile your proNe%t &via ant or the -AI', the results go into the ire%tory un er your proNe%t root. #pe%i$i%ally*
bin/classes/
hol s the %ompile Gava %lasses hol s the e:e%utable %reate $rom those %ompile your appli%ation6s resour%es, pa%kage is the name o$ your appli%ation' as a
bin/classes.dex
Gava %lasses
bin/yourapp.ap_ hol s L-! $ile &=here yourapp
bin/yourapp-debug.ap or bin/yourapp-unsigned.ap is the a%tual An roi appli%ation &=here yourapp is the name o$ your appli%ation'
4he .ap $ile is a L-! ar%hive %ontaining the .dex $ile, the %ompile e ition o$ your resour%es &resources.arsc', any un2%ompile resour%es &su%h as =hat you put in res/raw/' an the AndroidManifest.xml $ile. -t is also igitally signe , =ith the -debug portion o$ the $ilename in i%ating it has been signe using a ebug key that =orks =ith the emulator, or -unsigned in i%ating that you built your appli%ation $or release &ant!release', but the A!E still nee s to be signe using jarsigner an an o$$i%ial key.
9
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
CHAPTER '
4he $oun ation $or any An roi appli%ation is the mani$est $ile* AndroidManifest.xml in the root o$ your proNe%t. )ere is =here you e%lare =hat all is insi e your appli%ation O the a%tivities, the servi%es, an so on. @ou also in i%ate ho= these pie%es atta%h themselves to the overall An roi systemP $or e:ample, you in i%ate =hi%h a%tivity &or a%tivities' shoul appear on the evi%e6s main menu &a.k.a., laun%her'. When you %reate your appli%ation, you =ill get a starter mani$est generate $or you. (or a simple appli%ation, o$$ering a single a%tivity an nothing else, the auto2generate mani$est =ill probably =ork out $ine, or perhaps re;uire a $e= 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 =ill probably $all some=here in the mi le. Most o$ the interesting bits o$ the mani$est =ill be es%ribe in greater etail in the %hapters on their asso%iate An roi $eatures. (or e:ample, the service element =ill be es%ribe in greater etail in the %hapter on %reating servi%es. (or no=, =e Nust nee to un erstan =hat the role o$ the mani$est is an its general overall %onstru%tion.
/ote the namespa%e e%laration. Curiously, the generate mani$ests only apply it on the attributes, not the elements &e.g., it6s manifest, not android#manifest'. )o=ever, that pattern =orks, so unless An roi %hanges, sti%k =ith their pattern. 4he biggest pie%e o$ in$ormation you nee to supply on the manifest! element is the pac age attribute &also %uriously not2namespa%e '. )ere, you %an provi e the name o$ the Gava pa%kage that =ill be %onsi ere the QbaseQ o$ your appli%ation. 4hen, every=here else in the mani$est $ile that nee s a %lass name, you %an Nust 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.Snic lefrit( in this mani$est sho=n above, you %oul Nust use .Snic lefrit(, sin%e com.commonsware.android is e$ine as the appli%ation6s pa%kage.
elements, to in i%ate =hat permissions your appli%ation =ill nee in or er to $un%tion properly O see the %hapter on permissions $or more etails
uses-permission permission
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%ation6s ata or logi% O again, more etails are $orth%oming in the %hapter on permissions
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 uses-library
%omponents,
an application element, e$ining the guts o$ the appli%ation that the mani$est es%ribes
"manifest!xmlns#android$%&ttp#//sc&emas.android.com/ap /res/android% !!pac age$%com.commonsware.android%' !!"uses-permission !!!!android#name$%android.permission.A))*SS_+,)A-.,/%!/' !!"uses-permission !!!!android#name$%android.permission.A))*SS_01S%!/'! !!"uses-permission !!!!android#name$%android.permission.A))*SS_ASS.S-*D_01S%!/'! !!"uses-permission !!!!android#name$%android.permission.A))*SS_)*++_.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 =ill nee O in this %ase, permissions to allo= the appli%ation to etermine its %urrent lo%ation. An , there is the application element, =hose %ontents =ill es%ribe the a%tivities, servi%es, an =hatnot that make up the bulk o$ the appli%ation itsel$.
*Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
4his 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 =hat %on itions this a%tivity =ill be isplaye . 4he sto%k activity element sets up your a%tivity to appear in the laun%her, so users %an %hoose to run it. As =e6ll see later in this book, you %an have several a%tivities in one proNe%t, i$ you so %hoose. @ou may also have one or more receiver elements, in i%ating non2a%tivities that shoul be triggere un er %ertain %on itions, su%h as =hen an #M# message %omes in. 4hese are %alle intent re%eivers an are es%ribe mi 2 =ay through the book. @ou may have one or more provider elements, in i%ating %ontent provi ers O %omponents that supply ata to your a%tivities an , =ith your permission, other a%tivities in other appli%ations on the evi%e. 4hese =rap up atabases or other ata stores into a single A!- that any appli%ation %an use. Later, =e6ll see ho= to %reate %ontent provi ers an ho= to use %ontent provi ers that you or others %reate. (inally, you may have one or more service elements, es%ribing servi%es O long2running pie%es o$ %o e that %an operate in epen ent o$ any a%tivity. 4he ;uintessential e:ample is the M!? player, =here you =ant the musi% to keep playing even i$ the user pops open other a%tivities an the M!? player6s user inter$a%e is Qmispla%e Q. 4=o %hapters late in the book %over ho= to %reate an use servi%es.
*$
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
PART II Activities
CHAPTER (
Ivery programming language or environment book starts o$$ =ith the ever2 popular Q)ello, Worl 9Q emonstration* Nust enough o$ a program to prove you %an buil things, not so mu%h that you %annot un erstan =hat is going on. )o=ever, the typi%al Q)ello, Worl 9Q program has no intera%tivity &e.g., Nust umps the =or s to a %onsole', an so is really boring. 4his %hapter emonstrates a simple proNe%t, but one using A van%e !ush2 .utton 4e%hnologyR an the %urrent time, to sho= you ho= a simple An roi a%tivity =orks.
=ant to %reate an a --out s=it%h in i%ating =here the proNe%t $iles shoul be generate . (or e:ample*
activitycreator!--out!/pat&/to/my/project/dir!4 com.commonsware.android./ow
@ou =ill =in up =ith a han $ul o$ pre2generate $iles, as es%ribe in a previous %hapter. (or the purposes o$ the samples sho=n in this book, you %an o=nloa their proNe%t ire%tories in a L-! $ile on the CommonsWare Web site. 4hese proNe%ts are rea y $or useP you o not nee to run activitycreator on those unpa%ke samples.
The (ctivity
@our proNe%t6s src/ ire%tory %ontains the stan ar Gava2style tree o$ ire%tories base upon the Gava pa%kage you %hose =hen you %reate the proNe%t &e.g., com.commonsware.android results in src/com/commonsware/android/'. -nsi e the innermost ire%tory you shoul $in a pre2generate sour%e $ile name /ow.java, =hi%h =here your $irst a%tivity =ill go. >pen /ow.java in your e itor an paste in the $ollo=ing %o e*
pac age!com.commonsware.android.s eleton5 import!android.app.Activity5 import!android.os.6undle5 import!android.view.7iew5 import!android.widget.6utton5 import!java.util.Date5 public!class!/ow!extends!Activity!implements!7iew.,n)lic +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-NC-SA 3.0 License Edition
!!!!updateTime:;5 !!!!setContentView:btn;5 !!< !!public!void!onClick:7iew!view;!8 !!!!updateTime:;5 !!< !!private!void!updateTime:;!8 !!!!btn.setText:new!Date:;.toString:;;5 !!< <
>r, i$ you o=nloa the sour%e $iles o$$ the Web site, you %an Nust use the /ow! proNe%t ire%tly.
4he pa%kage e%laration nee s to be the same as the one you use =hen %reating the proNe%t. An , like any other Gava proNe%t, you nee to import any %lasses you re$eren%e. Most o$ the An roi 2spe%i$i% %lasses are in the android! pa%kage. Remember that not every Gava #I %lass is available to An roi programs9 +isit the An roi %lass re$eren%e to see =hat is an is not available.
public!class!/ow!extends!Activity!implements!7iew.,n)lic +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, =e =ant
*9
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
to trap all button %li%ks Nust =ithin the a%tivity itsel$, =e also have the a%tivity %lass implement ,n)lic +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 <
4he on)reate:; metho is invoke =hen the a%tivity is starte . 4he $irst thing you shoul o is %hain up=ar to the super%lass, so the sto%k An roi a%tivity initialiMation %an be one. -n our implementation, =e 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,n)lic +istener:;', %all a private update-ime:; metho &see belo=', an then set the a%tivity6s %ontent vie= to be the button itsel$ &via set)ontent7iew:;'. We =ill 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 #=ing, a =6utton %li%k raises an Action*vent, =hi%h is passe to the Action+istener %on$igure $or the button. -n An roi , a button %li%k %auses on)lic :; to be invoke in the ,n)lic +istener instan%e %on$igure $or the button. 4he listener is provi e the vie= that triggere the %li%k &in this %ase, the button'. All =e 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-NC-SA 3.0 License Edition
When =e open the a%tivity &on)reate:;' or =hen the button is %li%ke &on)lic :;', =e up ate the button6s label to be the %urrent time via set-ext:;, =hi%h $un%tions mu%h the same as the =6utton e;uivalent.
Laun%h the emulator &e.g., run tools/emulator $rom your An roi #AE installation'
-nstall
the
pa%kage
&e.g.,
/pat&/to/t&is/example/bin//ow.ap
run $rom
tools/adb ! install!
your
An roi
#AE
installation'
+ie= the list o$ installe appli%ations in the emulator an $in the Q/o=Q appli%ation
%*
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
%%
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
Cli%king the button O in other =or s, pretty mu%h any=here on the phone6s s%reen O =ill up ate the time sho=n in the button6s label. /ote that the label is %entere horiMontally an verti%ally, as those are the e$ault styles applie to button %aptions. We %an %ontrol that $ormatting, =hi%h =ill be %overe in a later %hapter. A$ter you are one gaMing at the a=esomeness o$ A van%e !ush2.utton 4e%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-NC-SA 3.0 License Edition
CHAPTER )
While it is te%hni%ally possible to %reate an atta%h =i gets to our a%tivity purely through Gava %o e, the =ay =e i in the pre%e ing %hapter, the more %ommon approa%h is to use an DML2base layout $ile. Aynami% instantiation o$ =i gets is reserve $or more %ompli%ate s%enarios, =here the =i gets are not kno=n at %ompile2time &e.g., populating a %olumn o$ ra io buttons base on ata retrieve o$$ the -nternet'. With that in min , it6s time to break out the DML an learn out to lay out An roi a%tivity vie=s that =ay.
An roi 6s #AE ships =ith a tool &aapt' =hi%h uses the layouts. 4his tool shoul be automati%ally invoke by your An roi tool %hain &e.g., I%lipse, Ant6s build.xml'. >$ parti%ular importan%e to you as a eveloper is that aapt! generates the R.java sour%e $ile =ithin your proNe%t, allo=ing you to a%%ess layouts an =i gets =ithin those layouts ire%tly $rom your Gava %o e, as =ill be emonstrate .
%1
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
4he %lass name o$ the =i get O 6utton O $orms the name o$ the DML element. #in%e 6utton is an An roi 2supplie =i get, =e %an Nust use the bare %lass name. -$ you %reate your o=n =i gets as sub%lasses o$ android.view.7iew, you =oul nee to provi e a $ull pa%kage e%laration as =ell &e.g., com.commonsware.android.MyCidget'. 4he root element nee s to e%lare the An roi DML namespa%e*
xmlns#android$%&ttp#//sc&emas.android.com/ap /res/android%
All other elements =ill be %hil ren o$ the root an namespa%e e%laration.
.e%ause =e =ant to re$eren%e this button $rom our Gava %o e, =e nee to give it an i enti$ier via the android#id attribute. We =ill %over this %on%ept in greater etail . 4he remaining attributes are properties o$ this 6utton instan%e*
android#text in i%ates the initial te:t to be isplaye on the button $a%e &in this %ase, an empty string'
an android#layout_&eig&t tell An roi to have the button6s =i th an height $ill the QparentQ, in this %ase the entire s%reen O these attributes =ill be %overe in greater etail in a later %hapter
android#layout_widt&
%4
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
#in%e this single =i get is the only %ontent in our a%tivity6s vie=, =e only nee this single element. Comple: vie=s =ill re;uire a =hole tree o$ elements, representing the =i gets an %ontainers that %ontrol their positioning. All the remaining %hapters o$ this book =ill use the DML layout $orm =henever pra%ti%al, so there are oMens o$ other e:amples o$ more %omple: layouts $or you to peruse.
%7
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
4his is the same set)ontent7iew:; =e use earlier, passing it an instan%e o$ a 7iew sub%lass &in that %ase, a 6utton'. 4he An roi 2built 7iew, %onstru%te $rom our layout, is a%%esse $rom that %o e2generate R %lass. All o$ the layouts are a%%essible un er R.layout, keye by the base name o$ the layout $ile O main.xml results in R.layout.main. 4o a%%ess our i enti$ie =i gets, use find7iew6y.d:;, passing it the numeri% i enti$ier o$ the =i get in ;uestion. 4hat numeri% i enti$ier =as generate by An roi in the R %lass as R.id.somet&ing &=here somet&ing is the spe%i$i% =i get you are seeking'. 4hose =i gets are simply sub%lasses o$ 7iew, Nust like the 6utton instan%e =e %reate in the previous %hapter.
%9
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
4he $irst i$$eren%e is that rather than setting the %ontent vie= to be a vie= =e %reate in Gava %o e, =e set it to re$eren%e the DML layout &set)ontent7iew:R.layout.main;'. 4he R.java sour%e $ile =ill be up ate =hen =e rebuil this proNe%t to in%lu e a re$eren%e to our layout $ile &store as main.xml in our proNe%t6s res/layout ire%tory'. 4he other i$$eren%e is that =e nee to get our han s on our 6utton instan%e, $or =hi%h =e use the find7iew6y.d:; %all. #in%e =e i enti$ie our button as 9Bid/button, =e %an re$eren%e the button6s i enti$ier as R.id.button. /o=, =ith the 6utton instan%e in han , =e %an set the %allba%k an set the label as nee e . 4he results look the same as =ith the original /ow emo*
-;
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
-*
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
CHAPTER *
Ivery 7"- toolkit has some basi% =i gets* $iel s, labels, buttons, et%. An roi 6s toolkit is no i$$erent in s%ope, an the basi% =i gets =ill provi e a goo intro u%tion as to ho= =i gets =ork in An roi a%tivities.
(ssigning abels
4he simplest =i get is the label, re$erre to in An roi as a -ext7iew. Like in most 7"- toolkits, labels are bits o$ te:t not e itable ire%tly by users. 4ypi%ally, they are use to i enti$y a Na%ent =i gets &e.g., a Q/ame*Q label be$ore a $iel =here one $ills in a name'. -n Gava, you %an %reate a label by %reating a -ext7iew instan%e. More %ommonly, though, you =ill %reate labels in DML layout $iles by a ing a -ext7iew element to the layout, =ith an android#text property to set the value o$ the label itsel$. -$ you nee to s=ap labels base on %ertain %riteria, su%h as internationaliMation, you may =ish to use a resour%e re$eren%e in the DML instea , as =ill 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., be ma e bol
android#typeface monospace'
android#textStyle to in i%ate that the type$a%e shoul &bold', itali% &italic', or bol an itali% &bold_italic'
--
(or e:ample, in the +abel proNe%t, you =ill $in the $ollo=ing layout $ile*
">xml!version$%?.@%!encoding$%utf-A%>' "-ext7iew!xmlns#android$%&ttp#//sc&emas.android.com/ap /res/android% !!android#layout_widt&$%fill_parent%! !!android#layout_&eig&t$%wrap_content%! !!android#text$%Fou!were!expecting!somet&ing!profound>% !!/'
Gust that layout alone, =ith the stub Gava sour%e provi e proNe%t buil er &e.g., activity)reator', gives you*
by An roi 6s
!leeting 8mages
An roi has t=o =i gets to help you embe images in your a%tivities* an .mage6utton. As the names suggest, they are image2base analogues to -ext7iew an 6utton, respe%tively.
.mage7iew
Ia%h =i get takes an android#src attribute &in an DML layout' to spe%i$y =hat pi%ture to use. 4hese usually re$eren%e a ra=able 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.mage2R.:;.
.mage6utton,
a sub%lass o$ .mage7iew, mi:es in the stan ar 6utton behaviors, $or respon ing to %li%ks an =hatnot. (or e:ample, take a peek at the main.xml layout $rom the .mage7iew sample proNe%t*
">xml!version$%?.@%!encoding$%utf-A%>' ".mage7iew!xmlns#android$%&ttp#//sc&emas.android.com/ap /res/android% !!!!android#id$%9Bid/icon% !!!!android#layout_widt&$%fill_parent%! !!!!android#layout_&eig&t$%fill_parent% !!!!android#adjust7iew6ounds$%true% !!!!android#src$%9drawable/molecule% !!!!/'
4he result, Nust using the %o e2generate a%tivity, is simply the image*
-0
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
shoul
provi e automati%
to %ontrol i$ the $iel shoul automati%ally %apitaliMe the $irst letter o$ entere te:t &e.g., $irst name, %ity'
android#digits, to %on$igure the $iel
android#single+ine, to %ontrol i$ the $iel is $or single2line input or multiple2line input &e.g., oes SInterT move you to the ne:t =i get or a a ne=lineC'
-1
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
.eyon those, you %an %on$igure $iel s to use spe%ialiMe input metho s, su%h as android#numeric $or numeri%2only input, android#password $or shrou e pass=or input, an android#p&one/umber $or entering in phone numbers. -$ you =ant to %reate your o=n input metho s%heme &e.g., postal %o es, #o%ial #e%urity numbers', you nee to %reate your o=n implementation o$ the .nputMet&od inter$a%e, then %on$igure the $iel to use it via android#inputMet&od. (or e:ample, $rom the Eield proNe%t, here is an DML layout $ile sho=ing an *dit7iew*
">xml!version$%?.@%!encoding$%utf-A%>' "*dit-ext!xmlns#android$%&ttp#//sc&emas.android.com/ap /res/android% !!android#id$%9Bid/field% !!android#layout_widt&$%fill_parent%! !!android#layout_&eig&t$%fill_parent% !!android#single+ine$%false% !!/'
/ote that android#single+ine is $alse, so users =ill be able to enter in several lines o$ te:t. (or this proNe%t, the EieldDemo.java $ile populates the input $iel =ith some prose*
pac age!com.commonsware.android.basic5 import!android.app.Activity5 import!android.os.6undle5 import!android.widget.*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.org/licenses/+.)*/S*-H.@%;5 !!< <
-4
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
>AT.* An roi 6s emulator only allo=s one appli%ation in the laun%her per uni;ue Gava 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 =ill not see the (iel Aemo appli%ation in the laun%her. 4o remove the LabelAemo appli%ation O or any appli%ation O use adb !s&ell !%rm !/data/app/...%, =here ... is the name o$ the appli%ation6s A!E $ile &e.g., +abelDemo.ap '. 4hen, reinstall the $ormerly2hi en appli%ation, an it =ill sho= up in the laun%her. Another $lavor o$ $iel is one that o$$ers auto2%ompletion, to help users supply a value =ithout typing in the =hole te:t. 4hat is provi e in An roi as the Auto)omplete-ext7iew =i get, is%usse in greater etail later in this book.
-7
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
state
Also, you %an register a listener obNe%t &in this %ase, an instan%e o$ ,n)&ec ed)&ange+istener' to be noti$ie =hen the state o$ the %he%kbo: %hanges. (or e:ample, $rom the )&ec 6ox proNe%t, here is a simple %he%kbo: layout*
">xml!version$%?.@%!encoding$%utf-A%>' ")&ec 6ox!xmlns#android$%&ttp#//sc&emas.android.com/ap /res/android% !!!!android#id$%9Bid/c&ec % !!!!android#layout_widt&$%wrap_content% !!!!android#layout_&eig&t$%wrap_content% !!!!android#text$%-&is!c&ec box!is#!unc&ec ed%!/'
4he %orrespon ing )&ec 6oxDemo.java retrieves an %on$igures the behavior o$ the %he%kbo:*
public!class!)&ec 6oxDemo!extends!Activity !!implements!)ompound6utton.,n)&ec ed)&ange+istener!8 !!)&ec 6ox!cb5 !! !!9,verride !!public!void!onCreate:6undle!icicle;!8 !!!!super.onCreate:icicle;5 -9
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
!!!!setContentView:R.layout.main;5 !!!! !!!!cb$:)&ec 6ox;findViewById:R.id.c&ec ;5 !!!!cb.setOnCheckedChangeListener:t&is;5 !!< !! !!public!void!onCheckedChanged:)ompound6utton!button7iewG !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!boolean!is)&ec ed;!8 !!!!if!:is)&ec ed;!8 !!!!!!cb.setText:%-&is!c&ec box!is#!c&ec ed%;5 !!!!< !!!!else!8 !!!!!!cb.setText:%-&is!c&ec box!is#!unc&ec ed%;5 !!!!< !!< <
/ote that the a%tivity serves as its o=n listener $or %he%kbo: state %hanges sin%e it implements the ,n)&ec ed)&ange+istener inter$a%e &via cb.set,n)&ec ed)&ange+istener:t&is;'. 4he %allba%k $or the listener is on)&ec ed)&anged:;, =hi%h re%eives the %he%kbo: =hose state has %hange an =hat the ne= state is. -n this %ase, =e up ate the te:t o$ the %he%kbo: to re$le%t =hat the a%tual bo: %ontains. 4he resultC Cli%king the %he%kbo: imme iately up ates its te:t, as sho=n belo=*
$;
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
!igure 7< The CheckBox/emo sample application6 )ith the checkbox unchecked
!igure 9< The same application6 no) )ith the checkbox checked
$*
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
to %lear all ra io buttons, so none in the group are -A o$ the %urrently2%he%ke '
%he%ke
get)&ec edRadio6utton.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 DML layout sho=ing a Radio0roup =rapping a set o$ Radio6utton =i gets*
">xml!version$%?.@%!encoding$%utf-A%>' "Radio0roup !!xmlns#android$%&ttp#//sc&emas.android.com/ap /res/android% !!android#orientation$%vertical% !!android#layout_widt&$%fill_parent% !!android#layout_&eig&t$%fill_parent% !!' !!!!"Radio6utton!android#id$%9Bid/radio?% !!!!!!android#layout_widt&$%wrap_content% !!!!!!android#layout_&eig&t$%wrap_content% !!!!!!android#text$%Roc %!/'
$%
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
"sing the sto%k An roi 2generate Gava $or the proNe%t an this layout, you get*
/ote that the ra io button group is initially set to be %ompletely un%he%ke at the outset. 4o preset one o$ the ra io buttons to be %he%ke , use either set)&ec ed:; on the Radio6utton or c&ec :; on the Radio0roup $rom =ithin your on)reate:; %allba%k in your a%tivity.
$Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
+se,ul Properties
#ome o$ the properties on 7iew most likely to be use in%lu e*
android#visibility,
=hi%h %ontrols =hether the =i get is initially R7. %olor value $or the =i get
visible
android#bac ground, =hi%h typi%ally provi es an &e.g., D@@EE@@ $or green' to serve as the ba%kgroun
+se,ul %ethods
@ou %an toggle =hether or not a =i 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 =i gets base on a )&ec 6ox or Radio6utton sele%tion. @ou %an give a =i get $o%us via reJuestEocus:; an see i$ it is $o%use via isEocused:;. @ou might use this in %on%ert =ith isabling =i gets as mentione above, to ensure the proper =i get has the $o%us on%e your isabling operation is %omplete. 4o help navigate the tree o$ =i gets an a%tivity6s overall vie=, you %an use* %ontainers that make up an
$$
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
get1arent:; to $in
to get the root o$ the tree &e.g., =hat you provi e to the a%tivity via set)ontent7iew:;'
$0
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
CHAPTER -
Containers pour a %olle%tion o$ =i gets &an possibly %hil %ontainers' into spe%i$i% layouts you like. -$ you =ant a $orm =ith labels on the le$t an $iel s on the right, you =ill nee a %ontainer. -$ you =ant >E 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 =ill nee a %ontainer. Gust $rom a pure DML perspe%tive, i$ you have multiple =i gets &beyon Radio6utton =i gets in a Radio0roup', you =ill nee a %ontainer Nust to have a root element to pla%e the =i gets insi e. Most 7"- toolkits have some notion o$ layout management, $re;uently organiMe into %ontainers. -n GavaU#=ing, $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 D"L an (le:, $iguring that any esire layout %an be a%hieve through the right %ombination o$ neste bo:es. An roi , through +inear+ayout, 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, =e =ill look at three %ommonly2use %ontainers* +inear+ayout &the bo: mo el', Relative+ayout &a rule2base mo el', an -able+ayout &the gri mo el', along =ith Scroll7iew, a %ontainer esigne to assist =ith implementing s%rolling %ontainers. -n the ne:t %hapter, =e =ill e:amine some more esoteri% %ontainers.
$4
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
Thinking inearly
As note above, +inear+ayout is a bo: mo el O =i gets or %hil %ontainers are line up in a %olumn or ro=, one a$ter the ne:t. 4his =orks similar to Elow+ayout in GavaU#=ing, vbox an &box in (le: an D"L, et%. (le: an D"L use the bo: as their primary unit o$ layout. -$ you =ant, you %an use +inear+ayout in mu%h the same =ay, es%he=ing some o$ the other %ontainers. 7etting the visual representation you =ant is mostly a matter o$ i enti$ying =here bo:es shoul nest an =hat properties those bo:es shoul have, su%h as alignment vis a vis other bo:es.
Concepts nd Properties
4o %on$igure a +inear+ayout, you have $ive main areas o$ %ontrol besi es the %ontainer6s %ontents* the orientation, the $ill mo el, the =eight, the gravity, an the pa ing.
Orientation
>rientation in i%ates =hether the +inear+ayout represents a ro= or a %olumn. Gust a the android#orientation property to your +inear+ayout! element in your DML layout, setting the value to be &ori(ontal $or a ro= or vertical $or a %olumn. 4he 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-.)A+.
Fill Model
Let6s imagine a ro= o$ =i gets, su%h as a pair o$ ra io buttons. 4hese =i gets have a QnaturalQ siMe base on their te:t. 4heir %ombine siMes probably o not e:a%tly mat%h the =i th o$ the An roi evi%e6s s%reen O parti%ularly sin%e s%reens %ome in various siMes. We then have the issue o$ =hat to o =ith the remaining spa%e.
$7
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
All =i gets insi e a +inear+ayout must supply android#layout_widt& an android#layout_&eig&t properties to help a ress this issue. 4hese properties6 values have three $lavors*
@ou %an provi e a spe%i$i% imension, su%h as ?HLpx to in i%ate the =i get shoul take up e:a%tly ,2B pi:els @ou %an provi e wrap_content, =hi%h means the =i get shoul $ill up its natural spa%e, unless that is too big, in =hi%h %ase An roi %an use =or 2=rap as nee e to make it $it @ou %an provi e fill_parent, =hi%h means the =i get shoul $ill up all available spa%e in its en%losing %ontainer, a$ter all other =i gets are taken %are o$
4he latter t=o $lavors are the most %ommon, as they are in epen ent o$ s%reen siMe, allo=ing An roi to a Nust your vie= to $it the available spa%e.
Weight
.ut, =hat happens i$ =e have t=o =i gets that shoul split the available $ree spa%eC (or e:ample, suppose =e have t=o multi2line $iel s in a %olumn, an =e =ant them to take up the remaining spa%e in the %olumn a$ter all other =i gets have been allo%ate their spa%e. 4o make this =ork, in a ition to setting android#layout_widt& &$or ro=s' or &$or %olumns' to fill_parent, you must also set 4his property in i%ates =hat proportion o$ the $ree spa%e shoul go to that =i get. -$ you set android#layout_weig&t to be the same value $or a pair o$ =i gets &e.g., ?', the $ree spa%e =ill be split evenly bet=een them. -$ you set it to be ? $or one =i get an H $or another =i get, the se%on =i get =ill use up t=i%e the $ree spa%e that the $irst =i get oes. An so on.
android#layout_&eig&t android#layout_weig&t.
$9
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
Gravity
.y e$ault, everything is le$t2 an top2aligne . #o, i$ you %reate a ro= o$ =i gets via a horiMontal +inear+ayout, the ro= =ill start $lush on the le$t si e o$ the s%reen. -$ that is not =hat you =ant, you nee to spe%i$y a gravity. "sing android#layout_gravity on a =i get &or %alling set0ravity:; at runtime on the =i get6s Gava obNe%t', you %an tell the =i get an its %ontainer ho= to align it vis a vis the s%reen. (or a %olumn o$ =i gets, %ommon gravity values are left, center_&ori(ontal, an rig&t $or le$t2aligne , %entere , an right2aligne =i gets respe%tively. (or a ro= o$ =i 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 =ish to spe%i$y a gravity o$ center_vertical to %enter the =i gets along the ro=6s verti%al mi point.
Padding
.y e$ault, =i gets are tightly pa%ke ne:t to ea%h other. -$ you =ant to in%rease the =hitespa%e bet=een =i gets, you =ill =ant to use the android#padding property &or by %alling set1adding:; at runtime on the =i get6s Gava obNe%t'. 4he pa ing spe%i$ies ho= mu%h spa%e there is bet=een the boun aries o$ the =i get6s Q%ellQ an the a%tual =i get %ontents. !a ing is analogous to the margins on a =or pro%essing o%ument O the page siMe might be 8.BQ:,,Q, but ,Q margins =oul leave the a%tual te:t to resi e =ithin a 3.BQ:0Q area.
0;
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
!igure **< The relationship bet)een a )idget6 its cell6 and the padding values
4he android#padding property allo=s you to set the same pa ing on all $our si es o$ the =i get, =ith the =i get6s %ontents itsel$ %entere =ithin that pa e 2out area. -$ you =ant the pa ing to i$$er on i$$erent si es, use android#padding+eft, android#paddingRig&t, android#padding-op, an android#padding6ottom. 4he value o$ the pa pa ing. ing is a imension, su%h as Lpx $or B pi:els6 =orth o$
E. mple
Let6s look at an e:ample &+inear' that sho=s +inear+ayout properties set both in the DML layout $ile an at runtime. )ere is the layout*
0*
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
">xml!version$%?.@%!encoding$%utf-A%>' "+inear+ayout !!xmlns#android$%&ttp#//sc&emas.android.com/ap /res/android% !!android#orientation$%vertical% !!android#layout_widt&$%fill_parent% !!android#layout_&eig&t$%fill_parent% !!' !!"Radio0roup!android#id$%9Bid/orientation% !!!!android#orientation$%&ori(ontal% !!!!android#layout_widt&$%wrap_content% !!!!android#layout_&eig&t$%wrap_content% !!!!android#padding$%Lpx%' !!!!"Radio6utton !!!!!!android#id$%9Bid/&ori(ontal% !!!!!!android#text$%&ori(ontal%!/' !!!!"Radio6utton !!!!!!android#id$%9Bid/vertical% !!!!!!android#text$%vertical%!/' !!"/Radio0roup' !!"Radio0roup!android#id$%9Bid/gravity% !!!!android#orientation$%vertical% !!!!android#layout_widt&$%fill_parent% !!!!android#layout_&eig&t$%wrap_content% !!!!android#padding$%Lpx%' !!!!"Radio6utton !!!!!!android#id$%9Bid/left% !!!!!!android#text$%left%!/' !!!!"Radio6utton !!!!!!android#id$%9Bid/center% !!!!!!android#text$%center%!/' !!!!"Radio6utton !!!!!!android#id$%9Bid/rig&t% !!!!!!android#text$%rig&t%!/' !!"/Radio0roup' "/+inear+ayout'
/ote that =e have a +inear+ayout =rapping t=o Radio0roup sets. Radio0roup is a sub%lass o$ +inear+ayout, so our e:ample emonstrates neste bo:es as i$ they =ere all +inear+ayout %ontainers. 4he top Radio0roup sets up a ro= &android#orientation!$! %&ori(ontal%' o$ Radio6utton =i gets. 4he Radio0roup has Lpx o$ pa ing on all si es, separating it $rom the other Radio0roup. 4he =i th an height are both set to wrap_content, so the ra io buttons =ill only take up the spa%e that they nee . 4he bottom Radio0roup is a %olumn &android#orientation!$!%vertical%' o$ three Radio6utton =i gets. Again, =e have Lpx o$ pa ing on all si es an a QnaturalQ height &android#layout_&eig&t ! $ ! %wrap_content%'. )o=ever, =e
0%
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
have set android#layout_widt& to be fill_parent, meaning the %olumn o$ ra io buttons Q%laimsQ the entire =i th o$ the s%reen. 4o a Nust these settings at runtime base on user input, =e nee some Gava %o e*
pac age!com.commonsware.android.containers5 import!android.app.Activity5 import!android.os.6undle5 import!android.text.-extCatc&er5 import!android.widget.+inear+ayout5 import!android.widget.Radio0roup5 import!android.widget.*dit-ext5 public!class!+inear+ayoutDemo!extends!Activity !!implements!Radio0roup.,n)&ec ed)&ange+istener!8 !!Radio0roup!orientation5 !!Radio0roup!gravity5 !! !!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 !!!!gravity$:Radio0roup;findViewById:R.id.gravity;5 !!!!gravity.setOnCheckedChangeListener:t&is;5 !!< !! !!public!void!onCheckedChanged:Radio0roup!groupG!int!c&ec ed.d;!8 !!!!if!:group$$orientation;!8 !!!!!!if!:c&ec ed.d$$R.id.&ori(ontal;!8 !!!!!!!!orientation.setOrientation:+inear+ayout.3,R.K,/-A+;5 !!!!!!< !!!!!!else!8 !!!!!!!!orientation.setOrientation:+inear+ayout.7*R-.)A+;5 !!!!!!< !!!!< !!!!else!if!:group$$gravity;!8 !!!!!!if!:c&ec ed.d$$R.id.left;!8 !!!!!!!!gravity.setGra ity:@x@I;5!!!!//!left !!!!!!< !!!!!!else!if!:c&ec ed.d$$R.id.center;!8 !!!!!!!!gravity.setGra ity:@x@?;5!!!!//!center_&ori(ontal !!!!!!< !!!!!!else!if!:c&ec ed.d$$R.id.rig&t;!8 !!!!!!!!gravity.setGra ity:@x@L;5!!!!//!rig&t !!!!!!< !!!!<
0Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
!!< <
-n on)reate:;, =e look up our t=o Radio0roup %ontainers an register a listener on ea%h, so =e are noti$ie =hen the ra io buttons %hange state &set,n)&ec ed)&ange+istener:t&is;'. #in%e the a%tivity implements ,n)&ec ed)&ange+istener, the a%tivity itsel$ is the listener. -n on)&ec ed)&anged:; &the %allba%k $or the listener', =e see =hi%h Radio0roup ha a state %hange. -$ it =as the orientation group, =e a Nust the orientation base on the user6s sele%tion. -$ it =as the gravity group, =e a Nust the gravity base on the user6s sele%tion. )ere is the result =hen it is $irst laun%he insi e the emulator*
0$
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
!igure *-< The same application6 )ith the vertical radio button selected
-$ =e toggle the Q%enterQ or QrightQ ra io buttons, the bottom Radio0roup! a Nusts to mat%h*
!igure *$< The same application6 )ith the vertical and center radio buttons selected 00
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
!igure *0< The same application6 )ith the vertical and right radio buttons selected
Concepts nd Properties
4o make all this =ork, =e nee =ays to re$eren%e other =i gets =ithin an DML layout $ile, plus =ays to in i%ate the relative positions o$ those =i gets.
01
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
align
says the =i get6s le$t si e shoul align =ith the le$t si e o$ the %ontainer
android#layout_align1arent+eft
says the =i get6s right si e shoul align =ith the right si e o$ the %ontainer
android#layout_align1arentRig&t android#layout_center3ori(ontal
shoul
be
says the =i get shoul be positione verti%ally at the %enter o$ the %ontainer says the =i get shoul be positione both horiMontally an verti%ally at the %enter o$ the %ontainer
All o$ these properties take a simple boolean value &true or false'. /ote that the pa ing o$ the =i get is taken into a%%ount =hen per$orming these various alignments. 4he alignments are base on the =i get6s overall %ell &%ombination o$ its natural spa%e plus the pa ing'.
04
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
2. Re$eren%e other =i gets using the same i enti$ier value =ithout the plus sign &9id/...' (or e:ample, i$ Wi get A is i enti$ie as 9Bid/widget_a, Wi get . %an re$er to Wi get A in one o$ its o=n properties via the i enti$ier 9id/widget_a.
in i%ates that the =i get shoul above the =i get re$eren%e in the property
android#layout_above android#layout_below
be pla%e be pla%e
in i%ates that the =i get shoul belo= the =i get re$eren%e in the property
android#layout_to+eft,f
in i%ates that the =i get shoul be pla%e to the le$t o$ the =i get re$eren%e in the property in i%ates that the =i get shoul be pla%e to the right o$ the =i get re$eren%e in the property
android#layout_toRig&t,f
.eyon those $our, there are $ive a itional properties that %an %ontrol one =i get6s alignment relative to another*
in i%ates that the =i get6s top shoul aligne =ith the top o$ the =i get re$eren%e in the property
android#layout_align-op
be
android#layout_align6ottom in i%ates that the =i get6s bottom shoul be aligne =ith the bottom o$ the =i get re$eren%e in the property
in i%ates that the =i get6s le$t shoul be aligne =ith the le$t o$ the =i get re$eren%e in the property
android#layout_align+eft android#layout_alignRig&t
in i%ates that the =i get6s right shoul be aligne =ith the right o$ the =i get re$eren%e in the property
android#layout_align6aseline
07
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
4he 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_align-op =oul align the top o$ the $iel 6s bo: =ith the top o$ the label, =hi%h =ill %ause the te:t o$ the label to be higher on2s%reen than the te:t entere into the $iel . #o, i$ =e =ant Wi get . to be positione to the right o$ Wi get A, in the DML element $or Wi get ., =e nee to in%lu e android#layout_toRig&t! $! %9id/widget_a% &assuming 9id/widget_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 DML layout an %omputes the siMe an position o$ ea%h =i get in se;uen%e. 4his has a $e= rami$i%ations*
@ou %annot re$eren%e a =i 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_&eig&t o not Qeat upQ all the spa%e be$ore subse;uent =i gets have been e$ine must be
E. mple
With all that in min , let6s e:amine a typi%al Q$ormQ =ith a $iel , a label, plus a pair o$ buttons labele Q>EQ an QCan%elQ. )ere is the DML layout, pulle $rom the Relative sample proNe%t*
">xml!version$%?.@%!encoding$%utf-A%>' "Relative+ayout !!xmlns#android$%&ttp#//sc&emas.android.com/ap /res/android% !!android#layout_widt&$%fill_parent% !!android#layout_&eig&t$%wrap_content% !!android#padding$%Lpx%' !!"-ext7iew!android#id$%9Bid/label% !!!!android#layout_widt&$%wrap_content% !!!!android#layout_&eig&t$%wrap_content% !!!!android#text$%2R+#%
09
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
!!!!android#padding-op$%?Lpx%/' !!"*dit-ext !!!!android#id$%9Bid/entry% !!!!android#layout_widt&$%fill_parent% !!!!android#layout_&eig&t$%wrap_content% !!!!android#layout_toRig&t,f$%9id/label% !!!!android#layout_align6aseline$%9id/label%/' !!"6utton !!!!android#id$%9Bid/o % !!!!android#layout_widt&$%wrap_content% !!!!android#layout_&eig&t$%wrap_content% !!!!android#layout_below$%9id/entry% !!!!android#layout_alignRig&t$%9id/entry% !!!!android#text$%,M%!/' !!"6utton !!!!android#layout_widt&$%wrap_content% !!!!android#layout_&eig&t$%wrap_content% !!!!android#layout_to+eft,f$%9id/o % !!!!android#layout_align-op$%9id/o % !!!!android#text$%)ancel%!/' "/Relative+ayout'
(irst, =e open up the Relative+ayout. -n this %ase, =e =ant to use the $ull =i th o$ the s%reen &android#layout_widt&!$!%fill_parent%', only as mu%h height as =e nee &android#layout_&eig&t!$!%wrap_content%', an have a B2 pi:el pa bet=een the boun aries o$ the %ontainer an its %ontents &android#padding!$!%Lpx%'. /e:t, =e e$ine the label, =hi%h is $airly basi%, e:%ept $or its o=n ,32pi:el pa ing &android#padding!$!%?Npx%'. More on that in a moment. A$ter that, =e a in the $iel . We =ant 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 Qro=Q in the layout. 4hose are han le by three properties*
android#layout_toRig&t!$!%9id/label% android#layout_align6aseline!$!%9id/label% android#layout_align6aseline!$!%9id/label%
-$ =e =ere to skip the ,32pi:el pa ing on the label, =e =oul $in that the top o$ the $iel is %lippe o$$. 4hat6s be%ause o$ the ,32pi:el pa ing on the %ontainer itsel$. 4he android#layout_align6aseline ! $ ! %9id/label% simply aligns the baselines o$ the label an $iel . 4he label, by e$ault, has its top
1;
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
aligne =ith the top o$ the parent. .ut the label is shorter than the $iel be%ause o$ the $iel 6s bo:. #in%e the $iel is epen ent on the label6s position, an the label6s position is alrea y e$ine &be%ause it appeare $irst in the DML', the $iel =in s up being too high an has the top o$ its bo: %lippe o$$ by the %ontainer6s pa ing. @ou may $in yoursel$ running into these sorts o$ problems as you try to get your Relative+ayout to behave the =ay you =ant it to. 4he solution to this %onun rum, use in the DML layout sho=n above, is to give the label ,3 pi:els6 =orth o$ pa ing on the top. 4his pushes the label o=n $ar enough that the $iel =ill not get %lippe . )ere are some QsolutionsQ that o not =ork*
@ou %annot use android#layout_align1arent-op on the $iel , be%ause you %annot have t=o properties that both attempt to set the verti%al position o$ the $iel . -n this %ase, android#layout_align1arent-op! %on$li%ts =ith the later android#layout_align6aseline!$!%9id/label%! property, an the last one in =ins. #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 , be%ause you %annot Q$or=ar re$eren%eQ labele =i gets O you must e$ine the =i get be$ore you %an re$eren%e it by its -A.
7oing ba%k to the e:ample, the >E button is set to be belo= the $iel &android#layout_below!$!%9id/entry%' an have its right si e align =ith the right si e o$ the $iel &android#layout_alignRig&t ! $ ! %9id/entry%'. 4he Can%el button is set to be to the le$t o$ the >E button &android#layout_to+eft! $ ! %9id/o %' an have its top aligne =ith the >E button &android#layout_align-op!$!%9id/o %'. With no %hanges to the auto2generate Gava %o e, the emulator gives us*
1*
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
Tabula 3asa
-$ you like )4ML tables, sprea sheet gri s, an the like, you =ill like An roi 6s -able+ayout O it allo=s you to position your =i gets in a gri to your spe%i$i%ations. @ou %ontrol the number o$ ro=s an %olumns, =hi%h %olumns might shrink or stret%h to a%%ommo ate their %ontents, an so on.
-able+ayout
=orks in %onNun%tion =ith -ableRow. -able+ayout %ontrols the overall behavior o$ the %ontainer, =ith the =i gets themselves poure into one or more -ableRow %ontainers, one per ro= in the gri .
Concepts nd Properties
(or all this to =ork, =e nee to $igure out ho= =i gets =ork =ith ro=s an %olumns, plus ho= to han le =i gets that live outsi e o$ ro=s.
1%
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
(irst, there =ill be at least one %olumn per =i get in your longest ro=. #o i$ you have three ro=s, one =ith t=o =i gets, one =ith three =i gets, an one =ith $our =i gets, there =ill be at least $our %olumns. )o=ever, a =i 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 =i get spans. 4his is akin to the colspan attribute one $in s in table %ells in )4ML*
"-ableRow' !!"-ext7iew!android#text$%2R+#%!/' !!"*dit-ext !!!!android#id$%9Bid/entry% !!!!android#layout_span$%I%/' "/-ableRow'
-n the above DML layout $ragment, the $iel spans three %olumns. >r inarily, =i gets are put into the $irst available %olumn. -n the above $ragment, the label =oul go in the $irst %olumn &%olumn @, as %olumns are %ounte starting $rom @', an the $iel =oul go into a spanne set o$ three %olumns &%olumns ? through I'. )o=ever, you %an put a =i get into a i$$erent %olumn via the android#layout_column property, spe%i$ying the @2 base %olumn the =i get belongs to*
"-ableRow' !!"6utton !!!!android#id$%9Bid/cancel% !!!!android#layout_column$%H% !!!!android#text$%)ancel%!/' !!"6utton!android#id$%9Bid/o %!android#text$%,M%!/' "/-ableRow'
1Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
-n the pre%e ing DML layout $ragment, the Can%el button goes in the thir %olumn &%olumn H'. 4he >E button then goes into the ne:t available %olumn, =hi%h is the $ourth %olumn.
android#layout_&eig&t!$!%Hpx%!android#bac ground!$!%D@@@@EE%!/'
@ou %an also leverage an android#collapse)olumns property on the -able+ayout, again =ith a %olumn number or %omma2 elimite list o$ %olumn numbers. 4hese %olumns =ill start out Q%ollapse Q, meaning they =ill be part o$ the table in$ormation but =ill be invisible. !rogrammati%ally, you %an %ollapse an un2%ollapse %olumns by %alling set)olumn)ollapsed:;! on the -able+ayout. @ou might use this to allo= users to %ontrol =hi%h %olumns are o$ importan%e to them an shoul be sho=n versus =hi%h ones are less important an %an be hi en. @ou also %ontrol stret%hing an shrinking set)olumnStretc&able:; an set)olumnS&rin able:;. %an at runtime via
E. mple
-able+ayout
4he DML layout $ragments sho=n above, =hen %ombine , give us a ren ition o$ the Q$ormQ =e %reate $or Relative+ayout, =ith the a ition o$ a ivi er line bet=een the labelU$iel an the t=o buttons &$oun in the -able emo'*
">xml!version$%?.@%!encoding$%utf-A%>' "-able+ayout !!xmlns#android$%&ttp#//sc&emas.android.com/ap /res/android% !!android#layout_widt&$%fill_parent% !!android#layout_&eig&t$%fill_parent% !!android#stretc&)olumns$%?%' !!"-ableRow' !!!!"-ext7iew !!!!!!!!android#text$%2R+#%!/' !!!!"*dit-ext!android#id$%9Bid/entry% !!!!!!android#layout_span$%I%/' !!"/-ableRow' !!"7iew !!!!android#layout_&eig&t$%Hpx% !!!!android#bac ground$%D@@@@EE%!/' !!"-ableRow' !!!!"6utton!android#id$%9Bid/cancel% !!!!!!android#layout_column$%H% !!!!!!android#text$%)ancel%!/' !!!!"6utton!android#id$%9Bid/o % !!!!!!android#text$%,M%!/' !!"/-ableRow' "/-able+ayout'
10
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
When %ompile against the generate Gava %o e an run on the emulator, =e get*
Scroll)ork
!hone s%reens ten to be small, =hi%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 o=n. 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, =rap it in a Scroll7iew, an still use your e:isting layout logi%. -t Nust 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 DML layout $ile &$rom the Scroll! emo'*
11
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
">xml!version$%?.@%!encoding$%utf-A%>' "Scroll7iew !!xmlns#android$%&ttp#//sc&emas.android.com/ap /res/android% !!android#layout_widt&$%fill_parent% !!android#layout_&eig&t$%wrap_content%' !!"-able+ayout !!!!android#layout_widt&$%fill_parent% !!!!android#layout_&eig&t$%fill_parent% !!!!android#stretc&)olumns$%@%' !!!!"-ableRow' !!!!!!"7iew !!!!!!!!android#layout_&eig&t$%A@px% !!!!!!!!android#bac ground$%D@@@@@@%/' !!!!!!"-ext7iew!android#text$%D@@@@@@% !!!!!!!!android#padding+eft$%Opx% !!!!!!!!android#layout_gravity$%center_vertical%!/' !!!!"/-ableRow' !!!!"-ableRow' !!!!!!"7iew !!!!!!!!android#layout_&eig&t$%A@px% !!!!!!!!android#bac ground$%DOO@@@@%!/' !!!!!!"-ext7iew!android#text$%DOO@@@@% !!!!!!!!android#padding+eft$%Opx% !!!!!!!!android#layout_gravity$%center_vertical%!/' !!!!"/-ableRow' !!!!"-ableRow' !!!!!!"7iew !!!!!!!!android#layout_&eig&t$%A@px% !!!!!!!!android#bac ground$%DAAOO@@%!/' !!!!!!"-ext7iew!android#text$%DAAOO@@% !!!!!!!!android#padding+eft$%Opx% !!!!!!!!android#layout_gravity$%center_vertical%!/' !!!!"/-ableRow' !!!!"-ableRow' !!!!!!"7iew !!!!!!!!android#layout_&eig&t$%A@px% !!!!!!!!android#bac ground$%DaaAAOO%!/' !!!!!!"-ext7iew!android#text$%DaaAAOO% !!!!!!!!android#padding+eft$%Opx% !!!!!!!!android#layout_gravity$%center_vertical%!/' !!!!"/-ableRow' !!!!"-ableRow' !!!!!!"7iew !!!!!!!!android#layout_&eig&t$%A@px% !!!!!!!!android#bac ground$%DffaaAA%!/' !!!!!!"-ext7iew!android#text$%DffaaAA% !!!!!!!!android#padding+eft$%Opx% !!!!!!!!android#layout_gravity$%center_vertical%!/' !!!!"/-ableRow' !!!!"-ableRow' !!!!!!"7iew !!!!!!!!android#layout_&eig&t$%A@px% !!!!!!!!android#bac ground$%Dffffaa%!/' !!!!!!"-ext7iew!android#text$%Dffffaa% !!!!!!!!android#padding+eft$%Opx% 14
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
!!!!!!!!android#layout_gravity$%center_vertical%!/' !!!!"/-ableRow' !!!!"-ableRow' !!!!!!"7iew !!!!!!!!android#layout_&eig&t$%A@px% !!!!!!!!android#bac ground$%Dffffff%!/' !!!!!!"-ext7iew!android#text$%Dffffff% !!!!!!!!android#padding+eft$%Opx% !!!!!!!!android#layout_gravity$%center_vertical%!/' !!!!"/-ableRow' !!"/-able+ayout' "/Scroll7iew'
Without the Scroll7iew, the table =oul take up at least B30 pi:els &1 ro=s at 80 pi:els ea%h, base on the 7iew e%larations'. 4here may be some evi%es =ith s%reens %apable o$ sho=ing that mu%h in$ormation, but many =ill be smaller. 4he Scroll7iew lets us keep the table as2is, but only present part o$ it at a time. >n the sto%k An roi emulator, =hen the a%tivity is $irst vie=e , you see*
/oti%e ho= only $ive ro=s an part o$ the si:th are visible. .y pressing the upU o=n buttons on the ire%tional pa , you %an s%roll up an o=n to see
17
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
the remaining ro=s. Also note ho= the right si e o$ the %ontent gets %lippe by the s%rollbar O be sure to put some pa ing on that si e or other=ise ensure your o=n %ontent oes not get %lippe in that $ashion.
19
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
CHAPTER /
.a%k in the %hapter on basi% =i gets, you sa= ho= $iel s %oul have %onstraints pla%e upon them to limit possible input, su%h as numeri%2only or phone2number2only. 4hese sorts o$ %onstraints help users Qget it rightQ =hen entering in$ormation, parti%ularly on a mobile evi%e =ith %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, rop2 o=n lists, an the like $or that very purpose. An roi has many o$ the same sorts o$ =i 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 $rame=ork $or etermining =hat %hoi%es are available in these =i gets. #pe%i$i%ally, An roi o$$ers a $rame=ork 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 vie=s O =i gets $or presenting lists o$ %hoi%es O are han e an a apter to supply the a%tual %hoi%es.
4his use o$ Gava inter$a%es is $airly %ommon &e.g., GavaU#=ing6s mo el a apters $or =-able', an Gava is $ar $rom the only environment o$$ering this sort o$ abstra%tion &e.g., (le:6s DML ata2bin ing $rame=ork a%%epts DML inline as stati% ata or retrieve $rom the -nternet'. An roi 6s a apters are responsible $or provi ing the roster o$ ata $or a sele%tion =i get plus %onverting in ivi ual elements o$ ata into spe%i$i% vie=s to be isplaye insi e the sele%tion =i get. 4he latter $a%et o$ the a apter system may soun a little o , but in reality it is not that i$$erent $rom other 7"- toolkits6 =ays o$ overri ing e$ault isplay behavior. (or e:ample, in GavaU#=ing, i$ you =ant a =+ist2ba%ke listbo: to a%tually be a %he%klist &=here in ivi ual ro=s are a %he%kbo: plus label, an %li%ks a Nust the state o$ the %he%kbo:', you inevitably =in up %alling set)ellRenderer:;! to supply your o=n +ist)ellRenderer, =hi%h in turn %onverts strings $or the list into =)&ec 6ox2plus2=+abel %omposite =i gets.
4he )ontext to use &typi%ally this =ill be your a%tivity instan%e' 4he resour%e -A o$ a vie= to use &su%h as a built2in system resour%e -A, as sho=n above' 4he a%tual array or list o$ items to sho=
.y e$ault, the ArrayAdapter =ill invoke toString:; on the obNe%ts in the list an =rap ea%h o$ those strings in the vie= esignate by the supplie resour%e. android.R.layout.simple_list_item_? simply turns those strings
4%
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
into -ext7iew obNe%ts. 4hose -ext7iew =i gets, in turn, =ill be sho=n the list or spinner or =hatever =i get uses this ArrayAdapter. @ou %an sub%lass ArrayAdapter an vie=s* overri e get7iew:; to Qroll your o=nQ
4he in e: o$ the item in the array to sho= in the vie= An e:isting vie= to up ate =ith the ata $or this position &i$ one alrea y e:iste , su%h as $rom s%rolling O i$ null, you nee to instantiate your o=n' 4he =i get that =ill %ontain this vie=, i$ nee e $or instantiating the vie=
-n the e:ample sho=n above, the a apter still returns a -ext7iew, but uses a i$$erent behavior $or etermining the string that goes in the vie=. A later %hapter =ill %over $an%ier +ist7iews.
%onverts a )ursor, typi%ally $rom a %ontent provi er, into something that %an be isplaye in a sele%tion vie=
)ursorAdapter SimpleAdapter %onverts
4Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
ActivityAdapter
an Activity.conAdapter provi e you =ith the names or i%ons o$ a%tivities that %an be invoke upon a parti%ular intent
4$
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
4he Gava %o e to %on$igure the list an %onne%t the list =ith the label is*
public!class!+ist7iewDemo!extends!+istActivity!8 !!-ext7iew!selection5 !!StringPQ!items$8%lorem%G!%ipsum%G!%dolor%G!%sit%G!%amet%G !!!!!!!!!!%consectetuer%G!%adipiscing%G!%elit%G!%morbi%G!%vel%G !!!!!!!!!!%ligula%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!%augue%G!%purus%<5 !! !!/RR!)alled!wit&!t&e!activity!is!first!created.!R/ !!9,verride !!public!void!onCreate:6undle!icicle;!8 !!!!super.onCreate:icicle;5 !!!!setContentView:R.layout.main;5 !!!!setList#dapter:new!ArrayAdapter"String':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 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!long!id;!8 !!!selection.setText:itemsPpositionQ;5 !!< <
With +istActivity, you %an set the list a apter via set+istAdapter:; O in this %ase, provi ing an ArrayAdapter =rapping an array o$ nonsense strings. 4o $in out =hen the list sele%tion %hanges, overri e on+ist.tem)lic :; an take appropriate steps base on the supplie %hil vie= an position &in this %ase, up ating the label =ith the te:t $or that position'. 4he resultsC
40
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
Spin Control
-n An roi , the Spinner is the e;uivalent o$ the rop2 o=n sele%tor you might $in in other toolkits &e.g., =)ombo6ox in GavaU#=ing'. !ressing the le$t an right buttons on the A2pa iterates over %hil ren. !ressing the %enter button on the A2pa isplays, by e$ault, a small list &akin to a +ist7iew' appears to sho= a $e= items at a time, instea o$ the one2item2at2a2time perspe%tive the une:pan e Spinner itsel$ provi es. As =ith +ist7iew, you provi e the a apter $or ata an %hil vie=s via setAdapter:; an hook in a listener obNe%t $or sele%tions via set,n.temSelected+istener:;. -$ you =ant to tailor the vie= use =hen isplaying the rop2 o=n perspe%tive, you nee to %on$igure the a apter, not the Spinner =i get. "se the setDropDown7iewResource:; metho to supply the resour%e -A o$ the vie= to use.
41
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
(or e:ample, %ulle $rom the Spinner sample proNe%t, here is an DML layout $or a simple vie= =ith a Spinner*
">xml!version$%?.@%!encoding$%utf-A%>' "+inear+ayout !!xmlns#android$%&ttp#//sc&emas.android.com/ap /res/android% !!android#orientation$%vertical% !!android#layout_widt&$%fill_parent% !!android#layout_&eig&t$%fill_parent% !!' !!"-ext7iew !!!!android#id$%9Bid/selection% !!!!android#layout_widt&$%fill_parent% !!!!android#layout_&eig&t$%wrap_content% !!!!/' !!"Spinner!android#id$%9Bid/spinner% !!!!android#layout_widt&$%fill_parent% !!!!android#layout_&eig&t$%wrap_content% !!!!android#drawSelector,n-op$%true% !!/' "/+inear+ayout'
4his is the same vie= as sho=n in the previous se%tion, Nust =ith a Spinner! instea o$ a +ist7iew. 4he Spinner property android#drawSelector,n-op! %ontrols =hether the arro=s are ra=n on the sele%tor button on the right si e o$ the Spinner "-. 4o populate an use the Spinner, =e nee some Gava %o e*
public!class!SpinnerDemo!extends!Activity !!implements!Adapter7iew.,n.temSelected+istener!8 !!-ext7iew!selection5 !!StringPQ!items$8%lorem%G!%ipsum%G!%dolor%G!%sit%G!%amet%G !!!!!!!!!!%consectetuer%G!%adipiscing%G!%elit%G!%morbi%G!%vel%G !!!!!!!!!!%ligula%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!%augue%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"String'!aa$new!ArrayAdapter"String':t&isG !!!!!!!!!!!!!!!!!!!!!!!!!!!!!android.R.layout.simple_spinner_itemG
44
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!items;5 !!!! !!!!aa.setDropDownView$esource: !!!!!!android.R.layout.simple_spinner_dropdown_item;5 !!!!spin.set#dapter:aa;5 !!< !! !!public!void!onItemSelected:Adapter7iew!parentG!7iew!vG !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!int!positionG!long!id;!8 !!!!selection.setText:itemsPpositionQ;5 !!< !! !!public!void!on%othingSelected:Adapter7iew!parent;!8 !!!!selection.setText:%%;5 !!< <
)ere, =e atta%h the a%tivity itsel$ as the sele%tion listener &spin.set,n.temSelected+istener:t&is;'. 4his =orks be%ause the a%tivity implements the ,n.temSelected+istener inter$a%e. We %on$igure the a apter not only =ith the list o$ $ake =or s, but also =ith a spe%i$i% resour%e to use $or the rop2 o=n vie= &via aa.setDropDown7iewResource:;'. Also note the use o$ android.R.layout.simple_spinner_item as the built2in 7iew $or sho=ing items in the spinner itsel$. (inally, =e implement the %allba%ks re;uire by ,n.temSelected+istener to a Nust the sele%tion label base on user input. What =e get is*
47
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
!igure %*< The same application6 )ith the spinner drop"do)n list displayed
49
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
spells out ho= many %olumns there are, or, i$ you supply a value o$ auto_fit, An roi =ill %ompute the number o$ %olumns base on available spa%e an the properties liste belo=.
android#num)olumns
an its %ounterpart in i%ate ho= mu%h =hitespa%e there shoul be bet=een items in the gri .
android#verticalSpacing android#&ori(ontalSpacing android#columnCidt&
shoul be.
i%ates, $or gri s =ith auto_fit $or shoul happen $or any available spa%e not taken up by %olumns or spa%ing O this shoul be columnCidt& to have the %olumns take up available spa%e or spacingCidt& to have the =hitespa%e bet=een %olumns absorb e:tra spa%e. (or e:ample, suppose the s%reen is ?20 pi:els =i e, an =e have android#columnCidt& set to ?@@ an android#&ori(ontalSpacing set to L. 4hree %olumns =oul use ?,0 pi:els &three %olumns o$ ,00 pi:els an t=o =hitespa%es o$ B pi:els'. With android#stretc&Mode set to columnCidt&, the three %olumns =ill ea%h e:pan by ?2< pi:els to use up the remaining ,0 pi:els. With android#stretc&Mode set to spacingCidt&, the t=o =hitespa%es =ill ea%h gro= by B pi:els to %onsume the remaining ,0 pi:els.
>ther=ise, the 0rid7iew =orks mu%h like any other sele%tion =i get O use setAdapter:; to provi e the ata an %hil vie=s, invoke set,n.temSelected+istener:; to register a sele%tion listener, et%.
7;
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
(or e:ample, here is a DML layout $rom the 0rid sample proNe%t, sho=ing a 0rid7iew %on$iguration*
">xml!version$%?.@%!encoding$%utf-A%>' "+inear+ayout !!xmlns#android$%&ttp#//sc&emas.android.com/ap /res/android% !!android#orientation$%vertical% !!android#layout_widt&$%fill_parent% !!android#layout_&eig&t$%fill_parent% !!' !!"-ext7iew !!!!android#id$%9Bid/selection% !!!!android#layout_widt&$%fill_parent% !!!!android#layout_&eig&t$%wrap_content% !!!!/' !!"0rid7iew !!!!android#id$%9Bid/grid% !!!!android#layout_widt&$%fill_parent%! !!!!android#layout_&eig&t$%fill_parent% !!!!android#verticalSpacing$%ILpx% !!!!android#&ori(ontalSpacing$%Lpx% !!!!android#num)olumns$%auto_fit% !!!!android#columnCidt&$%?@@px% !!!!android#stretc&Mode$%columnCidt&% !!!!android#gravity$%center% !!!!/' "/+inear+ayout'
(or this gri , =e take up the entire s%reen e:%ept $or =hat our sele%tion label re;uires. 4he number o$ %olumns is %ompute by An roi &android#num)olumns ! $ ! %auto_fit%' base on B2pi:el horiMontal spa%ing &android#&ori(ontalSpacing!$!%L%', ,002pi:el %olumns &android#columnCidt&! $ ! %?@@%', =ith the %olumns absorbing any QslopQ =i th le$t over &android#stretc&Mode!$!%columnCidt&%'. 4he Gava %o e to %on$igure the 0rid7iew is*
public!class!0ridDemo!extends!Activity !!implements!Adapter7iew.,n.temSelected+istener!8 !!-ext7iew!selection5 !!StringPQ!items$8%lorem%G!%ipsum%G!%dolor%G!%sit%G!%amet%G !!!!!!!!!!%consectetuer%G!%adipiscing%G!%elit%G!%morbi%G!%vel%G !!!!!!!!!!%ligula%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!%augue%G!%purus%<5 !! !!9,verride !!public!void!onCreate:6undle!icicle;!8
7*
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
!!!!super.onCreate:icicle;5 !!!!setContentView:R.layout.main;5 !!!!selection$:-ext7iew;findViewById:R.id.selection;5 !!!! !!!!0rid7iew!g$:0rid7iew;!findViewById:R.id.grid;5 !!!!g.set#dapter:new!"unnyLooking#dapter:t&isG !!!!!!!!!!!!!!!!!!!!!!!android.R.layout.simple_list_item_?G !!!!!!!!!!!!!!!!!!!!!!!items;;5 !!!!g.setOnItemSelectedListener:t&is;5 !!< !! !!public!void!onItemSelected:Adapter7iew!parentG!7iew!vG !!!!!!!!!!!!!!!!!!!!!!!!!!!!!int!positionG!long!id;!8 !!!!selection.setText:itemsPpositionQ;5 !!< !! !!public!void!on%othingSelected:Adapter7iew!parent;!8 !!!!selection.setText:%%;5 !!< !! !!private!class!Eunny+oo ingAdapter!extends!ArrayAdapter!8 !!!!)ontext!ctxt5 !!!! !!!!"unnyLooking#dapter:)ontext!ctxtG!int!resourceG !!!!!!!!!!!!!!!!!!!!!!!StringPQ!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:itemsPpositionQ;5 !!!!!! !!!!!!return:convert7iew;5 !!!!< !!< <
(or the gri %ells, rather than using auto2generate -ext7iew =i gets as in the previous se%tions, =e %reate our o=n vie=s, by sub%lassing ArrayAdapter! an overri ing get7iew:;. -n this %ase, =e =rap the $unny2looking strings in our o=n -ext7iew =i gets, Nust to be i$$erent. -$ get7iew:; re%eives a
7%
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
-ext7iew,
=e Nust reset its te:tP other=ise, =e %reate a ne= -ext7iew instan%e an populate it. With the ?B2pi:el verti%al spa%ing $rom the DML layout &android#verticalSpacing!$!%IL%', the gri over$lo=s the boun aries o$ the emulator6s s%reen*
7Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
!igure %-< The same application6 scrolled to the bottom of the grid
-n a ition, Auto)omplete-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 Auto)omplete-ext7iew an a apter %ontaining the list o$ %an i ate values via setAdapter:;. )o=ever, sin%e the user %oul type
7$
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
something not in the list, Auto)omplete-ext7iew oes not support sele%tion listeners. -nstea , you %an register a -extCatc&er, like you %an =ith any *dit7iew, to be noti$ie =hen the te:t %hanges. 4hese events =ill o%%ur either be%ause o$ manual typing or $rom a sele%tion $rom the rop2 o=n list. .elo= =e have a $amiliar2looking DML layout, this time %ontaining an Auto)omplete-ext7iew &pulle $rom the Auto)omplete sample appli%ation'*
">xml!version$%?.@%!encoding$%utf-A%>' "+inear+ayout !!xmlns#android$%&ttp#//sc&emas.android.com/ap /res/android% !!android#orientation$%vertical% !!android#layout_widt&$%fill_parent% !!android#layout_&eig&t$%fill_parent% !!' !!"-ext7iew !!!!android#id$%9Bid/selection% !!!!android#layout_widt&$%fill_parent% !!!!android#layout_&eig&t$%wrap_content% !!!!/' !!"Auto)omplete-ext7iew!android#id$%9Bid/edit% !!!!!!android#layout_widt&$%fill_parent% !!!!!!android#layout_&eig&t$%wrap_content% !!!!!!android#completion-&res&old$%I%/' "/+inear+ayout'
70
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
!!!!!!!!!!!!!!!!!!!!!!!!!android.R.layout.simple_list_item_?G !!!!!!!!!!!!!!!!!!!!!!!!!items;;5 !!< !! !!public!void!onTextChanged:)&arSeJuence!sG!int!startG!int!beforeG !!!!!!!!!!!!!!!!!!!!!!!!!!!!!int!count;!8 !!!!selection.setText:edit.getText:;;5 !!< !! !!public!void!!eforeTextChanged:)&arSeJuence!sG!int!startG !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!int!countG!int!after;!8 !!!!//!needed!for!interfaceG!but!not!used !!< !! !!public!void!afterTextChanged:*ditable!s;!8 !!!!//!needed!for!interfaceG!but!not!used !!< <
4his time, our a%tivity implements -extCatc&er, =hi%h means our %allba%ks are on-ext)&anged:; an before-ext)&anged:;. -n this %ase, =e are only intereste in the $ormer, an =e up ate the sele%tion label to mat%h the Auto)omplete-ext7iew6s %urrent %ontents. )ere =e have the results*
71
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
!igure %0< The same application6 after a fe) matching letters )ere entered6 sho)ing the auto"complete drop"do)n
!igure %1< The same application6 after the auto"complete value )as selected
74
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
list
android#spinnerSelector %ontrols =hat is use to in i%ate a sele%tion O this %an either be a re$eren%e to a Drawable &see the resour%es %hapter' or an R7. value in DAARR0066 or similar notation android#drawSelector,n-op in i%ates i$ the sele%tion bar &or Drawable' shoul be ra=n be$ore &false' or a$ter &true' ra=ing the sele%te %hil O i$ you %hoose true, be sure that your sele%tor has su$$i%ient
transparen%y to sho= the %hil through the sele%tor, other=ise users =ill not be able to rea the sele%tion
77
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
CHAPTER 2
4he humble +ist7iew is one o$ the most important =i gets in all o$ An roi , simply be%ause it is use so $re;uently. Whether %hoosing a %onta%t to %all or an email message to $or=ar or an ebook to rea , +ist7iew =i gets are employe in a =i e range o$ a%tivities. >$ %ourse, it =oul be ni%e i$ they =ere more than Nust plain te:t. 4he goo ne=s is that they %an be as $an%y as you =ant, =ithin the limitations o$ a mobile evi%e6s s%reen, o$ %ourse. )o=ever, making them $an%y takes some =ork an some $eatures o$ An roi that =e =ill %over in this %hapter. 4he material in this %hapter is base on the author6s posts to the .uil ing 6Aroi s %olumn on An roi 7uys.%om.
79
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
)o=ever, you %an have a list =hose ro=s are ma e up o$ i%ons, or i%ons an te:t, or %he%kbo:es an te:t, or =hatever you =ant. -t is merely a matter o$ supplying enough ata to the a apter an helping the a apter to %reate a ri%her set o$ 7iew obNe%ts $or ea%h ro=. (or e:ample, suppose you =ant a +ist7iew =hose entries are ma e up o$ an i%on, $ollo=e by some te:t. @ou %oul %onstru%t a layout $or the ro= that looks like this, $oun in the Static sample proNe%t*
">xml!version$%?.@%!encoding$%utf-A%>' "+inear+ayout!xmlns#android$%&ttp#//sc&emas.android.com/ap /res/android% !!android#layout_widt&$%fill_parent% !!android#layout_&eig&t$%wrap_content% !!android#orientation$%&ori(ontal% ' !!".mage7iew !!!!android#id$%9Bid/icon% !!!!android#layout_widt&$%HHpx% !!!!android#padding+eft$%Hpx% !!!!android#paddingRig&t$%Hpx% !!!!android#padding-op$%Hpx% !!!!android#layout_&eig&t$%wrap_content% !!!!android#src$%9drawable/o % !!/' !!"-ext7iew !!!!android#id$%9Bid/label% !!!!android#layout_widt&$%wrap_content% !!!!android#layout_&eig&t$%wrap_content% !!!!android#textSi(e$%OOsp% !!/' "/+inear+ayout'
4his layout uses a +inear+ayout to set up a ro=, =ith the i%on on the le$t an the te:t &in a ni%e big $ont' on the right. .y e$ault, though, An roi has no i ea that you =ant to use this layout =ith your +ist7iew. 4o make the %onne%tion, you nee to supply your Adapter =ith the resour%e -A o$ the %ustom layout sho=n above*
public!class!StaticDemo!extends!+istActivity!8 !!-ext7iew!selection5 !!StringPQ!items$8%lorem%G!%ipsum%G!%dolor%G!%sit%G!%amet%G !!!!!!!!!!%consectetuer%G!%adipiscing%G!%elit%G!%morbi%G!%vel%G !!!!!!!!!!%ligula%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!%augue%G
9;
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
!!!!!!!!!!%purus%<5 !! !!9,verride !!public!void!onCreate:6undle!icicle;!8 !!!!super.onCreate:icicle;5 !!!!setContentView:R.layout.main;5 !!!!setList#dapter:new!ArrayAdapter"String':t&isG !!!!!!!!!!!!!!!!!!!!!!!R.layout.rowG!R.id.labelG !!!!!!!!!!!!!!!!!!!!!!!items;;5 !!!!selection$:-ext7iew;findViewById:R.id.selection;5 !!< !! !!public!void!onListItemClick:+ist7iew!parentG!7iew!vG !!!!!!!!!!!!!!!!!!!!!!!!!!!!!int!positionG!!long!id;!8 !!!selection.setText:itemsPpositionQ;5 !!< <
4his $ollo=s the general stru%ture $or the previous List+ie= sample. 4he key in this e:ample is that you have tol ArrayAdapter that you =ant to use your %ustom layout &R.layout.row' an that the -ext7iew =here the =or shoul go is kno=n as R.id.label =ithin that %ustom layout. 4he result is a +ist7iew =ith i%ons o=n the le$t si e. -n parti%ular, all the i%ons are the same*
9*
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
( /ynamic Presentation
4his te%hni;ue O supplying an alternate layout to use $or ro=s O han les simple %ases very ni%ely. )o=ever, it $alls o=n =hen you have more %ompli%ate s%enarios $or your ro=s, su%h as*
/ot every ro= uses the same layout &e.g., some have one line o$ te:t, others have t=o' @ou nee to %on$igure the =i gets in the ro=s &e.g., i$$erent i%ons $or i$$erent %ases'
-n those %ases, the better option is to %reate your o=n sub%lass o$ your esire Adapter, overri e get7iew:;, an %onstru%t your ro=s yoursel$. 4he get7iew:; metho is responsible $or returning a 7iew, representing the ro= $or the supplie position in the a apter ata. (or e:ample, letWs re=ork the above %o e to use get7iew:;, so =e %an have i$$erent i%ons $or i$$erent ro=s O in this %ase, one i%on $or short =or s an one $or long =or s &$rom the Dynamic sample proNe%t'*
9%
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
public!class!DynamicDemo!extends!+istActivity!8 !!-ext7iew!selection5 !!StringPQ!items$8%lorem%G!%ipsum%G!%dolor%G!%sit%G!%amet%G !!!!!!!!!!%consectetuer%G!%adipiscing%G!%elit%G!%morbi%G!%vel%G !!!!!!!!!!%ligula%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!%augue%G !!!!!!!!!!%purus%<5 !! !!9,verride !!public!void!onCreate:6undle!icicle;!8 !!!!super.onCreate:icicle;5 !!!!setContentView:R.layout.main;5 !!!!setList#dapter:new!Iconic#dapter:t&is;;5 !!!!selection$:-ext7iew;findViewById:R.id.selection;5 !!< !! !!public!void!onListItemClick:+ist7iew!parentG!7iew!vG !!!!!!!!!!!!!!!!!!!!!!!!!!!!!int!positionG!long!id;!8 !!!selection.setText:itemsPpositionQ;5 !!< !! !!class!.conicAdapter!extends!ArrayAdapter!8 !!!!Activity!context5 !!!! !!!!Iconic#dapter:Activity!context;!8 !!!!!!super:contextG!R.layout.rowG!items;5 !!!!!! !!!!!!t&is.context$context5 !!!!< !!!! !!!!public!7iew!getView:int!positionG!7iew!convert7iewG !!!!!!!!!!!!!!!!!!!!!!!7iew0roup!parent;!8 !!!!!!+ayout.nflater!inflater$context.getLayoutInflater:;5 !!!!!!7iew!row$inflater.inflate:R.layout.rowG!null;5 !!!!!!-ext7iew!label$:-ext7iew;row.findViewById:R.id.label;5 !!!!!! !!!!!!label.setText:itemsPpositionQ;5 !!!!!! !!!!!!if!:itemsPpositionQ.length:;'O;!8 !!!!!!!!.mage7iew!icon$:.mage7iew;row.findViewById:R.id.icon;5 !!!!!!!! !!!!!!!!icon.setImage$esource:R.drawable.delete;5 !!!!!!<!! !!!!!! !!!!!!return:row;5 !!!!< !!< <
4he theory is that =e overri e get7iew:; an return ro=s base on =hi%h obNe%t is being isplaye , =here the obNe%t is in i%ate by a position in e: into the Adapter. )o=ever, i$ you look at the implementation sho=n above,
9Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
you =ill see a re$eren%e to a 7iew.nflate %lass...an that %on%ept takes a little bit o$ an e:planation.
(ill in the te:t label into our label =i get, using the =or at the supplie position #ee i$ the =or is longer than $our %hara%ters an , i$ so, =e $in our .mage7iew i%on =i get an repla%e the sto%k resour%e =ith a i$$erent one
9$
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
/o=, =e have a +ist7iew =ith i$$erent i%ons base upon %onte:t o$ that spe%i$i% entry in the list*
>bviously, this =as a $airly %ontrive e:ample, but you %an see =here this te%hni;ue %oul be use to %ustomiMe ro=s base on any sort o$ %riteria, su%h as other %olumns in a returne )ursor.
o$ C!" that is use eats up the battery. 4his is %ompoun e by the e:tra =ork the garbage %olle%tor nee s to o to get ri o$ all those e:tra obNe%ts you %reate. #o the less e$$i%ient your %o e, the more ;ui%kly the phone6s battery =ill be raine , an the less happy the user =ill be. An you =ant happy users, rightC #o, let us take a look at a $e= tri%ks to make your $an%y +ist7iew =i gets more e$$i%ient.
+sin! convert5ie#
4he get7iew:; metho re%eives, as one o$ its parameters, a 7iew name , by %onvention, convert7iew. #ometimes, convert7iew =ill be null. -n those %ases, you have to %reate a ne= ro= 7iew $rom s%rat%h &e.g., via in$lation', Nust as =e i be$ore. )o=ever, i$ convert7iew is not null, then it is a%tually one o$ your previously2 %reate 7iews9 4his =ill happen primarily =hen the user s%rolls the +ist7iew! O as ne= ro=s appear, An roi =ill attempt to re%y%le the vie=s o$ the ro=s that s%rolle o$$ the other en o$ the list, to save you having to rebuil them $rom s%rat%h. Assuming that ea%h o$ your ro=s has the same basi% stru%ture, you %an use find7iew6y.d:; to get at the in ivi ual =i gets that make up your ro= an %hange their %ontents, then return content7iew $rom get7iew:;, rather than %reate a =hole ne= ro=. (or e:ample, here is the get7iew:; implementation $rom last time, no= optimiMe via content7iew &$rom the Re%y%ling proNe%t'*
public!class!RecyclingDemo!extends!+istActivity!8 !!-ext7iew!selection5 !!StringPQ!items$8%lorem%G!%ipsum%G!%dolor%G!%sit%G!%amet%G !!!!!!!!!!%consectetuer%G!%adipiscing%G!%elit%G!%morbi%G!%vel%G !!!!!!!!!!%ligula%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!%augue%G
91
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
!!!!!!!!!!%purus%<5 !! !!9,verride !!public!void!onCreate:6undle!icicle;!8 !!!!super.onCreate:icicle;5 !!!!setContentView:R.layout.main;5 !!!!setList#dapter:new!Iconic#dapter:t&is;;5 !!!!selection$:-ext7iew;findViewById:R.id.selection;5 !!< !! !!public!void!onListItemClick:+ist7iew!parentG!7iew!vG !!!!!!!!!!!!!!!!!!!!!!!!!!!!!int!positionG!long!id;!8 !!!selection.setText:itemsPpositionQ;5 !!< !! !!class!.conicAdapter!extends!ArrayAdapter!8 !!!!Activity!context5 !!!! !!!!Iconic#dapter:Activity!context;!8 !!!!!!super:contextG!R.layout.rowG!items;5 !!!!!! !!!!!!t&is.context$context5 !!!!< !!!! !!!!public!7iew!getView:int!positionG!7iew!convert7iewG !!!!!!!!!!!!!!!!!!!!!!!7iew0roup!parent;!8 !!!!!!7iew!row$convert7iew5 !!!!!! !!!!!!if!:row$$null;!8!!!!!!!!!!!!!!!!!!!!!!!!! !!!!!!!!+ayout.nflater!inflater$context.getLayoutInflater:;5 !!!!!!!! !!!!!!!!row$inflater.inflate:R.layout.rowG!null;5 !!!!!!< !!!!!! !!!!!!-ext7iew!label$:-ext7iew;row.findViewById:R.id.label;5 !!!!!! !!!!!!label.setText:itemsPpositionQ;5 !!!!!! !!!!!!if!:itemsPpositionQ.length:;'O;!8 !!!!!!!!.mage7iew!icon$:.mage7iew;row.findViewById:R.id.icon;5 !!!!!!!! !!!!!!!!icon.setImage$esource:R.drawable.delete;5 !!!!!!<!! !!!!!! !!!!!!return:row;5 !!!!< !!< <
)ere, =e %he%k to see i$ the content7iew is null an , i$ so, =e then in$late our ro= O but i$ it is not2null, =e Nust reuse it. 4he =ork to $ill in the %ontents
94
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
&i%on image, te:t' is the same in either %ase. 4he a vantage is that =e avoi the potentially2e:pensive in$lation step. 4his approa%h =ill not =ork in every %ase, though. (or e:ample, it may be that you have a List+ie= $or =hi%h some ro=s =ill have one line o$ te:t an others have t=o. -n this %ase, re%y%ling e:isting ro=s be%omes tri%ky, as the layouts may signi$i%antly i$$er. (or e:ample, i$ the ro= =e nee to %reate a +ie= $or re;uires t=o lines o$ te:t, =e %annot Nust use a 7iew =ith one line o$ te:t as2is. We either nee to tinker =ith the innar s o$ that 7iew, or ignore it an in$late a ne= 7iew. >$ %ourse, there are =ays to eal =ith this, su%h as making the se%on line o$ te:t visible or invisible epen ing on =hether it is nee e . An , on a phone, every millise%on o$ C!" time is pre%ious, possibly $or the user e:perien%e, but al=ays $or battery li$e O more C!" utiliMation means a more ;ui%kly2 raine battery. 4hat being sai , parti%ularly i$ you are a rookie to An roi , $o%us on getting the $un%tionality right $irst, then looking to optimiMe per$orman%e on a se%on pass through your %o e, rather than get lost in a sea o$ 7iews trying to ta%kle it all in one shot.
gets rather verbose. What =oul be ni%e is a =ay =here =e %an still use the layout DML yet %a%he our ro=Ws key %hil =i gets so =e only have to $in them on%e. 4hat6s =here the hol er pattern %omes into play, in a %lass =e6ll %all 7iewCrapper. All +ie= obNe%ts have get-ag:; an set-ag:; metho s. 4hese allo= you to asso%iate an arbitrary obNe%t =ith the =i get. What the hol er pattern oes is use that QtagQ to hol an obNe%t that, in turn, hol s ea%h o$ the %hil =i gets o$ interest. .y atta%hing that hol er to the ro= +ie=, every time =e use the ro=, =e alrea y have a%%ess to the %hil =i gets =e %are about, =ithout having to %all find7iew6y.d:; again. #o, letWs take a look at one o$ these hol er %lasses &taken $rom the 7iewCrapper sample proNe%t'*
class!7iewCrapper!8 !!7iew!base5 !!-ext7iew!label$null5 !!.mage7iew!icon$null5 !! !!View&rapper:7iew!base;!8 !!!!t&is.base$base5 !!< !! !!-ext7iew!getLa!el:;!8 !!!!if!:label$$null;!8 !!!!!!label$:-ext7iew;base.findViewById:R.id.label;5 !!!!< !!!! !!!!return:label;5 !!< !! !!.mage7iew!getIcon:;!8 !!!!if!:icon$$null;!8 !!!!!!icon$:.mage7iew;base.findViewById:R.id.icon;5 !!!!< !!!! !!!!return:icon;5 !!< <
7iewCrapper
not only hol s onto the %hil =i gets, it laMy2$in s the %hil =i gets. -$ you %reate a =rapper an never nee a spe%i$i% %hil , you never go
99
through the find7iew6y.d:; operation $or it an never have to pay $or those C!" %y%les. 4he hol er pattern also*
Allo=s us to %onsoli ate all our per2=i get type %asting in one pla%e, rather than having to %ast it every=here =e %all find7iew6y.d:; !erhaps tra%k other in$ormation about the ro=, su%h as state in$ormation =e are not yet rea y to 5$lush8 to the un erlying mo el
"sing 7iewCrapper is a matter o$ %reating an instan%e =henever =e in$late a ro= an atta%hing sai instan%e to the ro= 7iew via set-ag:;, as sho=n in this re=rite o$ get7iew:;*
public!class!7iewCrapperDemo!extends!+istActivity!8 !!-ext7iew!selection5 !!StringPQ!items$8%lorem%G!%ipsum%G!%dolor%G!%sit%G!%amet%G !!!!!!!!!!%consectetuer%G!%adipiscing%G!%elit%G!%morbi%G!%vel%G !!!!!!!!!!%ligula%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!%augue%G !!!!!!!!!!%purus%<5 !! !!9,verride !!public!void!onCreate:6undle!icicle;!8 !!!!super.onCreate:icicle;5 !!!!setContentView:R.layout.main;5 !!!!setList#dapter:new!Iconic#dapter:t&is;;5 !!!!selection$:-ext7iew;findViewById:R.id.selection;5 !!< !! !!private!String!get'odel:int!position;!8 !!!!return:::.conicAdapter;getList#dapter:;;.getItem:position;;5 !!< !! !!public!void!onListItemClick:+ist7iew!parentG!7iew!vG !!!!!!!!!!!!!!!!!!!!!!!!!!!!!int!positionG!long!id;!8 !!!selection.setText:get'odel:position;;5 !!< !! !!class!.conicAdapter!extends!ArrayAdapter"String'!8 !!!!Activity!context5 !!!! !!!!Iconic#dapter:Activity!context;!8 !!!!!!super:contextG!R.layout.rowG!items;5 !!!!!! !!!!!!t&is.context$context5 !!!!<
*;;
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
!!!! !!!!public!7iew!getView:int!positionG!7iew!convert7iewG !!!!!!!!!!!!!!!!!!!!!!!7iew0roup!parent;!8 !!!!!!7iew!row$convert7iew5 !!!!!!7iewCrapper!wrapper$null5 !!!!!! !!!!!!if!:row$$null;!8!!!!!!!!!!!!!!!!!!!!!!!!! !!!!!!!!+ayout.nflater!inflater$context.getLayoutInflater:;5 !!!!!!!! !!!!!!!!row$inflater.inflate:R.layout.rowG!null;5 !!!!!!!!wrapper$new!View&rapper:row;5 !!!!!!!!row.setTag:wrapper;5 !!!!!!< !!!!!!else!8 !!!!!!!!wrapper$:7iewCrapper;row.getTag:;5 !!!!!!< !!!!!! !!!!!!wrapper.getLa!el:;.setText:get'odel:position;;5 !!!!!! !!!!!!if!:get'odel:position;.length:;'O;!8 !!!!!!!!wrapper.getIcon:;.setImage$esource:R.drawable.delete;5 !!!!!!<!! !!!!!! !!!!!!return:row;5 !!!!< !!< <
Gust as =e %he%k convert7iew to see i$ it is null in or er to %reate the ro= 7iews as nee e , =e also pull out &or %reate' the %orrespon ing ro=Ws 7iewCrapper. 4hen, a%%essing the %hil =i gets is merely a matter o$ %alling their asso%iate metho s on the =rapper.
+aking a ist<<<
Lists =ith pretty i%ons ne:t to them are all $ine an =ell. .ut, %an =e %reate +ist7iew =i gets =hose ro=s %ontain intera%tive %hil =i gets instea o$ Nust passive =i gets like -ext7iew an .mage7iewC (or e:ample, %oul =e %ombine the Rating6ar =ith te:t in or er to allo= people to s%roll a list o$, say, songs an rate them right insi e the listC 4here is goo ne=s an ba ne=s. 4he goo ne=s is that intera%tive =i gets in ro=s =ork Nust $ine. 4he ba ne=s is that it is a little tri%ky, spe%i$i%ally =hen it %omes to taking a%tion
*;*
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
=hen the intera%tive =i get6s state %hanges &e.g., a value is type into a $iel '. We nee to store that state some=here, sin%e our Rating6ar =i get =ill be re%y%le =hen the +ist7iew is s%rolle . We nee to be able to set the Rating6ar state base upon the a%tual =or =e are vie=ing as the Rating6ar! is re%y%le , an =e nee to save the state =hen it %hanges so it %an be restore =hen this parti%ular ro= is s%rolle ba%k into vie=. What makes this interesting is that, by e$ault, the Rating6ar has absolutely no i ea =hat mo el in the ArrayAdapter it is looking at. A$ter all, the Rating6ar is Nust a =i get, use in a ro= o$ a +ist7iew. We nee to tea%h the ro=s =hi%h mo el they are presently isplaying, so =hen their %he%kbo: is %he%ke , they kno= =hi%h mo elWs state to mo i$y. #o, let6s see ho= this is one, using the a%tivity in the Rate+ist sample proNe%t. WeWll use the same basi% %lasses as our previous emo O =eWre sho=ing a list o$ nonsense =or s, =hi%h you %an then rate. -n a ition, =or s given a top rating are put in all %aps*
public!class!Rate+istDemo!extends!+istActivity!8 !!-ext7iew!selection5 !!StringPQ!items$8%lorem%G!%ipsum%G!%dolor%G!%sit%G!%amet%G !!!!!!!!!!%consectetuer%G!%adipiscing%G!%elit%G!%morbi%G!%vel%G !!!!!!!!!!%ligula%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!%augue%G !!!!!!!!!!%purus%<5 !! !!9,verride !!public!void!onCreate:6undle!icicle;!8 !!!!super.onCreate:icicle;5 !!!!setContentView:R.layout.main;5 !!!! !!!!Array+ist"RowModel'!list$new!Array+ist"RowModel':;5 !!!! !!!!for!:String!s!#!items;!8 !!!!!!list.add:new!$ow'odel:s;;5 !!!!< !!!! !!!!setList#dapter:new!Check#dapter:t&isG!list;;5 !!!!selection$:-ext7iew;findViewById:R.id.selection;5 !!< !! !!private!RowModel!get'odel:int!position;!8 !!!!return:::)&ec Adapter;getList#dapter:;;.getItem:position;;5 !!< !!
*;%
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
!!public!void!onListItemClick:+ist7iew!parentG!7iew!vG !!!!!!!!!!!!!!!!!!!!!!!!!!!!!int!positionG!long!id;!8 !!!selection.setText:get'odel:position;.toString:;;5 !!< !! !!class!)&ec Adapter!extends!ArrayAdapter"RowModel'!8 !!!!Activity!context5 !!!! !!!!Check#dapter:Activity!contextG!Array+ist"RowModel'!list;!8 !!!!!!super:contextG!R.layout.rowG!list;5 !!!!!! !!!!!!t&is.context$context5 !!!!< !!!! !!!!public!7iew!getView:int!positionG!7iew!convert7iewG !!!!!!!!!!!!!!!!!!!!!!!7iew0roup!parent;!8 !!!!!!7iew!row$convert7iew5 !!!!!!7iewCrapper!wrapper5 !!!!!!Rating6ar!rate5!!!!!!!!!!!!!!!!!! !!!!!!!!!!!!!!!!!!!!!!!!! !!!!!!if!:row$$null;!8!!!! !!!!!!!!+ayout.nflater!inflater$context.getLayoutInflater:;5 !!!!!!!! !!!!!!!!row$inflater.inflate:R.layout.rowG!null;5 !!!!!!!!wrapper$new!View&rapper:row;5 !!!!!!!!row.setTag:wrapper;5 !!!!!!!!rate$wrapper.get$atingBar:;5 !!!!!!!! !!!!!!!!Rating6ar.,nRating6ar)&ange+istener!l$ !!!!!!!!!!!!!!!!!!!!new!Rating6ar.On$atingBarChangeListener:;!8 !!!!!!!!!!public!void!on$atingChanged:Rating6ar!rating6arG !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!float!ratingG !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!boolean!from-ouc&;!!8 !!!!!!!!!!!!.nteger!my1osition$:.nteger;rating6ar.getTag:;5 !!!!!!!!!!!!RowModel!model$get'odel:my1osition;5 !!!!!!!!!!!! !!!!!!!!!!!!model.rating$rating5 !!!!!!!!!! !!!!!!!!!!!!+inear+ayout!parent$:+inear+ayout;rating6ar.get(arent:;5 !!!!!!!!!!!!-ext7iew!label$:-ext7iew;parent.findViewById:R.id.label;5 !!!!!!!! !!!!!!!!!!!!label.setText:model.toString:;;5 !!!!!!!!!!< !!!!!!!!<5 !!!!!!!! !!!!!!!!rate.setOn$atingBarChangeListener:l;5 !!!!!!< !!!!!!else!8 !!!!!!!!wrapper$:7iewCrapper;row.getTag:;5 !!!!!!!!rate$wrapper.get$atingBar:;5 !!!!!!< !!!!!!RowModel!model$get'odel:position;5 !!!!!!
*;Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
!!!!!!wrapper.getLa!el:;.setText:model.toString:;;5 !!!!!!rate.setTag:new!Integer:position;;5 !!!!!!rate.set$ating:model.rating;5 !!!!!! !!!!!!return:row;5 !!!!< !!< !! !!class!RowModel!8 !!!!String!label5 !!!!float!rating$H.@f5 !!!! !!!!$ow'odel:String!label;!8 !!!!!!t&is.label$label5 !!!!< !!!! !!!!public!String!toString:;!8 !!!!!!if!:rating'$I.@;!8 !!!!!!!!return:label.to)pperCase:;;5 !!!!!!< !!!!!! !!!!!!return:label;5 !!!!< !!< <
)ere is =hat is i$$erent in this a%tivity an get7iew:; implementation than be$ore* ,. While =e are still using StringXY items as the list o$ nonsense =or s, rather than pour that String array straight into an ArrayAdapter, =e turn it into a list o$ RowModel obNe%ts. RowModel is this emoWs poor e:%use $or a mutable mo el* it hol s the nonsense =or plus the %urrent %he%ke state. -n a real system, these might be obNe%ts populate $rom a )ursor, an the properties =oul have more business meaning.
2. "tility metho s like on+ist.tem)lic :; ha to be up ate to re$le%t the %hange $rom a pure2String mo el to use a RowModel. ?. 4he ArrayAdapter sub%lass &)&ec Adapter', in get7iew:;, looks to see i$ convert7iew is null. -$ so, =e %reate a ne= ro= by in$lating a simple layout &see belo=' an also atta%h a 7iewCrapper &also belo='. (or the ro=Ws Rating6ar, =e a an anonymous onRating)&anged:; listener that looks at the ro=Ws tag &get-ag:;' an %onverts that into an .nteger, representing the position =ithin the ArrayAdapter that this ro= is isplaying. "sing that, the %he%kbo: %an get the a%tual
*;$
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
RowModel
$or the ro= an up ate the mo el base upon the ne= state o$ the rating bar. -t also up ates the te:t a Na%ent to the Rating6ar! =hen %he%ke to mat%h the rating bar state.
<. We al=ays make sure that the Rating6ar has the proper %ontents an has a tag &via set-ag:;' pointing to the position in the a apter the ro= is isplaying. 4he ro= layout is very simple* Nust a Rating6ar an +inear+ayout* a -ext7iew insi e a
">xml!version$%?.@%!encoding$%utf-A%>' "+inear+ayout!xmlns#android$%&ttp#//sc&emas.android.com/ap /res/android% !!android#layout_widt&$%fill_parent% !!android#layout_&eig&t$%wrap_content% !!android#orientation$%&ori(ontal% ' !!"Rating6ar !!!!android#id$%9Bid/rate% !!!!android#layout_widt&$%wrap_content% !!!!android#layout_&eig&t$%wrap_content% !!!!android#numStars$%I% !!!!android#stepSi(e$%?% !!!!android#rating$%H%!/' !!"-ext7iew !!!!android#id$%9Bid/label% !!!!android#padding+eft$%Hpx% !!!!android#paddingRig&t$%Hpx% !!!!android#padding-op$%Hpx% !!!!android#textSi(e$%O@sp% !!!!android#layout_widt&$%fill_parent% !!!!android#layout_&eig&t$%wrap_content%/' "/+inear+ayout'
4he 7iewCrapper is similarly simple, Nust e:tra%ting the Rating6ar an the -ext7iew out o$ the ro= 7iew*
class!7iewCrapper!8 !!7iew!base5 !!Rating6ar!rate$null5 !!-ext7iew!label$null5 !! !!View&rapper:7iew!base;!8 !!!!t&is.base$base5 !!< !! !!Rating6ar!get$atingBar:;!8 !!!!if!:rate$$null;!8
*;0
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
!!!!!!rate$:Rating6ar;base.findViewById:R.id.rate;5 !!!!< !!!! !!!!return:rate;5 !!< !! !!-ext7iew!getLa!el:;!8 !!!!if!:label$$null;!8 !!!!!!label$:-ext7iew;base.findViewById:R.id.label;5 !!!!< !!!! !!!!return:label;5 !!< <
4his in%lu es the toggle %he%kbo:es turning their =or s into all %aps*
*;1
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
*;4
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
=here, in our %o e, almost all o$ the logi% that might have re$erre to a +ist7iew be$ore 5Nust =orks8 =ith the Rate+ist7iew =e put in the layout*
public!class!Rate+ist7iewDemo!extends!+istActivity!8 !!-ext7iew!selection5 !!StringPQ!items$8%lorem%G!%ipsum%G!%dolor%G!%sit%G!%amet%G !!!!!!!!!!%consectetuer%G!%adipiscing%G!%elit%G!%morbi%G!%vel%G !!!!!!!!!!%ligula%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!%augue%G !!!!!!!!!!%purus%<5 !! !!9,verride !!public!void!onCreate:6undle!icicle;!8 !!!!super.onCreate:icicle;5 !!!!setContentView:R.layout.main;5 !!!! !!!!setList#dapter:new!ArrayAdapter"String':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!long!id;!8 !!!selection.setText:itemsPpositionQ;5 !!< <
Where things get a =ee bit %hallenging is =hen you stop an realiMe that, in everything up to this point in this %hapter, never =ere =e a%tually %hanging the +ist7iew itsel$. All our =ork =as =ith the a apters, overri ing get7iew:;! an in$lating our o=n ro=s, an =hatnot. #o i$ =e =ant Rate+ist7iew to take in any or inary +istAdapter an 5Nust =ork8, putting %he%kbo:es on the ro=s as nee e , =e are going to nee to o some $an%y $oot=ork. #pe%i$i%ally, =e are going to nee to =rap the 5ra=8 +istAdapter in some other +istAdapter that kno=s ho= to put the %he%kbo:es on the ro=s an tra%k the state o$ those %he%kbo:es.
*;7
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
(irst, =e nee to establish the pattern o$ one +istAdapter augmenting another. )ere is the %o e $or AdapterCrapper, =hi%h takes a +istAdapter an elegates all o$ the inter$a%eWs metho s to the elegate &$rom the )&ec +ist7iew sample proNe%t'*
public!class!AdapterCrapper!implements!+istAdapter!8 !!+istAdapter!delegate$null5 !! !!public!#dapter&rapper:+istAdapter!delegate;!8 !!!!t&is.delegate$delegate5 !!< !! !!public!int!getCount:;!8 !!!!return:delegate.getCount:;;5 !!< !! !!public!,bject!getItem:int!position;!8 !!!!return:delegate.getItem:position;;5 !!< !! !!public!long!getItemId:int!position;!8 !!!!return:delegate.getItemId:position;;5 !!< !! !!public!7iew!getView:int!positionG!7iew!convert7iewG !!!!!!!!!!!!!!!!!!!!!7iew0roup!parent;!8 !!!!return:delegate.getView:positionG!convert7iewG!parent;;5 !!< !! !!public!void!registerDataSetO!ser er:DataSet,bserver!observer;!8 !!!!delegate.registerDataSetO!ser er:observer;5 !!< !! !!public!boolean!hasSta!leIds:;!8 !!!!return:delegate.hasSta!leIds:;;5 !!< !! !!public!boolean!is*mpty:;!8 !!!!return:delegate.is*mpty:;;5 !!< !! !!public!int!getViewTypeCount:;!8 !!!!return:delegate.getViewTypeCount:;;5 !!< !! !!public!int!getItemViewType:int!position;!8 !!!!return:delegate.getItemViewType:position;;5 !!< !! !!public!void!unregisterDataSetO!ser er:DataSet,bserver!observer;!8 !!!!delegate.unregisterDataSetO!ser er:observer;5 !!<
*;9
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
We %an then sub%lass AdapterCrapper to %reate RateableCrapper, overri ing the e$ault get7iew:; but other=ise allo=ing the elegate +istAdapter to o the 5real =ork8*
public!class!RateableCrapper!extends!AdapterCrapper!8 !!)ontext!ctxt$null5 !!floatPQ!rates$null5 !! !!public!$atea!le&rapper:)ontext!ctxtG!+istAdapter!delegate;!8 !!!!super:delegate;5 !!!! !!!!t&is.ctxt$ctxt5 !!!!t&is.rates$new!floatPdelegate.getCount:;Q5 !!!! !!!!for!:int!i$@5i"delegate.getCount:;5iBB;!8 !!!!!!t&is.ratesPiQ$H.@f5 !!!!< !!< !! !!public!7iew!getView:int!positionG!7iew!convert7iewG !!!!!!!!!!!!!!!!!!!!!7iew0roup!parent;!8 !!!!7iewCrapper!wrap$null5 !!!!7iew!row$convert7iew5 !!!!!!!!!!!!!!!!!!!!!!!!!!! !!!!if!:convert7iew$$null;!8 !!!!!!+inear+ayout!layout$new!LinearLayout:ctxt;5 !!!!!!Rating6ar!rate$new!$atingBar:ctxt;5 !!!!!! !!!!!!rate.set%umStars:I;5 !!!!!!rate.setStepSi+e:?.@f;5 !!!!!! !!!!!!7iew!guts$delegate.getView:positionG!nullG!parent;5 !!!! !!!!!!layout.setOrientation:+inear+ayout.3,R.K,/-A+;5! !!!!!!!!!! !!!!!!rate.setLayout(arams:new!+inear+ayout.Layout(arams: !!!!!!!!!!!!+inear+ayout.+ayout1arams.CRA1_),/-*/-G !!!!!!!!!!!!+inear+ayout.+ayout1arams.E.++_1AR*/-;;5 !!!!!!guts.setLayout(arams:new!+inear+ayout.Layout(arams: !!!!!!!!!!!!+inear+ayout.+ayout1arams.E.++_1AR*/-G !!!!!!!!!!!!+inear+ayout.+ayout1arams.E.++_1AR*/-;;5 !!!!!!
**;
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
!!!!!!Rating6ar.,nRating6ar)&ange+istener!l$ !!!!!!!!!!!!!!!!!!!!new!Rating6ar.On$atingBarChangeListener:;!8 !!!!!!!!public!void!on$atingChanged:Rating6ar!rating6arG !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!float!ratingG !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!boolean!from-ouc&;!!8 !!!!!!!!!!ratesP:.nteger;rating6ar.getTag:;Q$rating5 !!!!!!!!< !!!!!!<5 !!!!!! !!!!!!rate.setOn$atingBarChangeListener:l;5 !!!!!!!!!! !!!!!!layout.addView:rate;5!!!!!!!!!! !!!!!!layout.addView:guts;5 !!!!!! !!!!!!wrap$new!View&rapper:layout;5 !!!!!!wrap.setGuts:guts;5 !!!!!!layout.setTag:wrap;5 !!!!!! !!!!!!rate.setTag:new!Integer:position;;5 !!!!!!rate.set$ating:ratesPpositionQ;5 !!!!!!!! !!!!!!row$layout5!!!!!!!! !!!!< !!!!else!8 !!!!!!wrap$:7iewCrapper;convert7iew.getTag:;5 !!!!!!wrap.setGuts:delegate.getView:positionG!wrap.getGuts:;G !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!parent;;5 !!!!!!wrap.get$atingBar:;.setTag:new!Integer:position;;5 !!!!!!wrap.get$atingBar:;.set$ating:ratesPpositionQ;5 !!!!< !!!! !!!!return:row;5 !!<!!!! <
4he i ea is that RateableCrapper is =here most o$ our rate2list logi% resi es. -t puts the rating bars on the ro=s an it tra%ks the rating barsW states as they are a Nuste by the user. (or the states, it has a floatPQ siMe to $it the number o$ ro=s that the elegate says are in the list.
RateableCrapperWs
implementation o$ get7iew:; is reminis%ent o$ the one $rom RateListAemo, e:%ept that rather than use +ayout.nflater, =e nee to manually %onstru%t a +inear+ayout to hol our Rating6ar an the 5guts8 &a.k.a., =hatever vie= the elegate %reate that =e are e%orating =ith the %he%kbo:'. +ayout.nflater is esigne to %onstru%t a 7iew $rom ra= =i getsP in our %ase, =e onWt kno= in a van%e =hat the ro=s =ill look like, other than that =e nee to a a %he%kbo: to them. )o=ever, the rest is similar to
***
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
the one $rom Rate+istDemo, in%lu ing using a 7iewCrapper &belo=', hooking onRating6ar)&anged:; to have the rating bar up ate the state, an so $orth*
class!7iewCrapper!8 !!7iew0roup!base5 !!7iew!guts$null5 !!Rating6ar!rate$null5 !! !!View&rapper:7iew0roup!base;!8 !!!!t&is.base$base5 !!< !! !!Rating6ar!get$atingBar:;!8 !!!!if!:rate$$null;!8 !!!!!!rate$:Rating6ar;base.getChild#t:@;5 !!!!< !!!! !!!!return:rate;5 !!< !! !!void!set$atingBar:Rating6ar!rate;!8 !!!!t&is.rate$rate5 !!< !! !!7iew!getGuts:;!8 !!!!if!:guts$$null;!8 !!!!!!guts$base.getChild#t:?;5 !!!!< !!!! !!!!return:guts;5 !!< !! !!void!setGuts:7iew!guts;!8 !!!!t&is.guts$guts5 !!< <
**%
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
We simply sub%lass +ist7iew an overri e setAdapter:; so =e %an =rap the supplie +istAdapter in our o=n RateableCrapper. +isually, the results are similar to the Rate+istDemo, albeit =ithout top2rate =or s appearing in all %aps*
4he i$$eren%e is in reusability. We %oul pa%kage Rate+ist7iew in its o=n GAR an plop it into any An roi proNe%t =here =e nee it. #o =hile Rate+ist7iew is some=hat %ompli%ate to =rite, =e only have to =rite it on%e, an the rest o$ the appli%ation %o e is bliss$ully simple. >$ %ourse, this Rate+ist7iew %oul use some more $eatures, su%h as programmati%ally %hanging states &up ating both the floatPQ an the a%tual Rating6ar itsel$', allo=ing other appli%ation logi% to be invoke =hen a
**Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
Rating6ar
state is toggle &via some sort o$ %allba%k', et%. 4hese are le$t as e:er%ises $or the rea er.
**$
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
CHAPTER 16
4he =i gets an %ontainers %overe to ate are not only $oun in many 7"toolkits &in one $orm or $ashion', but also are =i ely use in buil ing 7"appli%ations, =hether Web2base , esktop, or mobile. 4he =i gets an %ontainers in this %hapter are a little less =i ely use , though you =ill likely $in many to be ;uite use$ul.
importantly, ea%h let you provi e a %allba%k obNe%t &,nDate)&anged+istener or ,nDateSet+istener' =here you are in$orme o$ a ne= 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 =ay $or you to get at the %hosen ate later on. #imilarly, -ime1ic er an -ime1ic erDialog let you*
set the initial time the user %an a Nust, in the $orm o$ an hour &@! through HI' an a minute &@ through LS' in i%ate i$ the sele%tion shoul be in ,22hour mo e =ith an AMU!M toggle, or in 2<2hour mo e &=hat in the "# is thought o$ as Qmilitary timeQ an in the rest o$ the =orl is thought o$ as Qthe =ay times are suppose to beQ' provi e %allba%k obNe%t &,n-ime)&anged+istener or to be noti$ie o$ =hen the user has %hosen a ne= time, =hi%h is supplie to you in the $orm o$ an hour an minute
,n-imeSet+istener'
(or e:ample, $rom the )&rono sample proNe%t, here6s a trivial layout %ontaining a label an t=o buttons O the buttons =ill pop up the ialog $lavors o$ the ate an time pi%kers*
">xml!version$%?.@%!encoding$%utf-A%>' "+inear+ayout !!xmlns#android$%&ttp#//sc&emas.android.com/ap /res/android% !!android#orientation$%vertical% !!android#layout_widt&$%fill_parent% !!android#layout_&eig&t$%fill_parent% !!' !!"-ext7iew!android#id$%9Bid/dateAnd-ime%!! !!!!android#layout_widt&$%fill_parent%! !!!!android#layout_&eig&t$%wrap_content% !!!!/' !!"6utton!android#id$%9Bid/date6tn%!! !!!!android#layout_widt&$%fill_parent%! !!!!android#layout_&eig&t$%wrap_content%! !!!!android#text$%Set!t&e!Date% !!!!/' !!"6utton!android#id$%9Bid/time6tn%!! !!!!android#layout_widt&$%fill_parent%! !!!!android#layout_&eig&t$%wrap_content%! !!!!android#text$%Set!t&e!-ime% !!!!/' "/+inear+ayout' **1
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
!!!! !!!!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 !!< <
4he Qmo elQ $or this a%tivity is Nust a )alendar instan%e, initially set to be the %urrent ate an time. We pour it into the vie= via a DateEormat $ormatter. -n the update+abel:; metho , =e take the %urrent )alendar, $ormat it, an put it in the -ext7iew. Ia%h button is given a ,n)lic +istener %allba%k obNe%t. When the button is %li%ke , either a Date1ic erDialog or a -ime1ic erDialog is sho=n. -n the %ase o$ the Date1ic erDialog, =e give it a ,nDateSet+istener %allba%k that up ates the )alendar =ith the ne= ate &year, month, ay o$ month'. We also give the ialog the last2sele%te ate, getting the values out o$ the )alendar. -n the %ase o$ the -ime1ic erDialog, it gets a ,n-imeSet+istener %allba%k to up ate the time portion o$ the )alendar, the last2sele%te time, an a true in i%ating =e =ant 2<2hour mo e on the time sele%tor. With all this =ire together, the resulting a%tivity looks like this*
**7
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
!igure --< The same application6 sho)ing the date picker dialog
**9
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
!igure -$< The same application6 sho)ing the time picker dialog
*%;
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
Without any Gava %o e other than the generate proNe%t an get the $ollo=ing a%tivity*
this
+aking Progress
-$ you nee to be oing something $or a long perio o$ time, you o=e it to your users to o t=o things*
"se a ba%kgroun threa , =hi%h =ill be %overe in a later %hapter Eeep them apprise o$ your progress, lest they think your a%tivity has =an ere a=ay an =ill never %ome ba%k
4he typi%al approa%h to keeping users in$orme o$ progress is some $orm o$ progress bar or QthrobberQ &think the animate graphi% to=ar s the upper2
*%*
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
right %orner o$ many Web bro=sers'. An roi supports this through the 1rogress6ar =i get. A 1rogress6ar keeps tra%k o$ progress, e$ine as an integer, =ith 0 in i%ating no progress has been ma e. @ou %an e$ine the ma:imum en o$ the range O =hat value in i%ates progress is %omplete O via setMax:;. .y e$ault, a 1rogress6ar starts =ith a progress o$ @, though you %an start $rom some other position via set1rogress:;. -$ you pre$er your progress bar to be in eterminate, use set.ndeterminate:;, setting it to true. -n your Gava %o e, you %an either positively set the amount o$ progress that has been ma e &via set1rogress:;' or in%rement the progress $rom its %urrent amount &via increment1rogress6y:;'. @ou %an $in out ho= mu%h progress has been ma e via get1rogress:;. #in%e the 1rogress6ar is tie %losely to the use o$ threa s O a ba%kgroun threa oing =ork, up ating the "- threa =ith ne= progress in$ormation O =e =ill hol o$$ emonstrating the use o$ 1rogress6ar to a later %hapter.
Putting 8t ,n +y Tab
4he general An roi philosophy is to keep a%tivities short an s=eet. -$ there is more in$ormation than %an reasonably $it on one s%reen, albeit perhaps =ith s%rolling, then it perhaps belongs in another a%tivity ki%ke o$$ via an .ntent, as =ill be es%ribe later in this book. )o=ever, 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 GavaU#=ing. -n An roi , you no= have an option o$ using a -ab3ost %ontainer in mu%h the same =ay O a portion o$ your a%tivity6s s%reen is taken up =ith tabs =hi%h, =hen %li%ke , s=ap out part o$ the vie= an repla%e it =ith something else. (or e:ample, you might have an a%tivity =ith
*%%
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
a tab $or entering a lo%ation an a se%on tab $or sho=ing a map o$ that lo%ation. #ome 7"- toolkits re$er to QtabsQ as being Nust the things a user %li%ks on to toggle $rom one vie= to another. #ome toolkits re$er to QtabsQ as being the %ombination o$ the %li%kable button2ish element an the %ontent that appears =hen that tab is %hosen. An roi treats the tab buttons an %ontents as is%rete entities, so =e =ill %all them Qtab buttonsQ an Qtab %ontentsQ in this se%tion.
The Pieces
4here are a $e= =i gets an %ontainers you nee to use in or er to set up a tabbe portion o$ a vie=*
-ab3ost is the overar%hing %ontainer $or the tab buttons an %ontents -abCidget
tab
implements the ro= o$ tab buttons, =hi%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
4his is similar to the approa%h that MoMilla6s D"L takes. -n D"L6s %ase, the tabbox element %orrespon s to An roi 6s -ab3ost, the tabs element %orrespon s to -abCidget, an tabpanels %orrespon s to the Erame+ayout.
@ou must give the -abCidget an android#id o$ 9android#id/tabs @ou must set asi e some pa buttons &more on this belo=' ing in the Erame+ayout $or the tab
*%Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
-$ you =ish to use the -abActivity, you must give the -ab3ost an android#id o$ 9android#id/tab&ost
-abActivity, like +istActivity, =raps a %ommon "- pattern &a%tivity ma e up entirely o$ tabs' into a pattern2a=are a%tivity sub%lass. @ou o not ne%essarily have to use -abActivity O a plain a%tivity %an use tabs as =ell.
With respe%t to the Erame+ayout pa ing issue, $or =hatever reason, the -abCidget oes not seem to allo%ate its o=n spa%e insi e the -ab3ost! %ontainer. -n other =or s, no matter =hat you spe%i$y $or android#layout_&eig&t $or the -abCidget, the Erame+ayout ignores it an ra=s 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#padding-op' in Erame+ayout to QshoveQ the a%tual tab %ontents o=n beneath the tab buttons. 4his is likely a bug, so this behavior may =ell %hange in $uture versions o$ the toolkit. -n a ition, the -abCidget seems to al=ays ra= itsel$ =ith 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 32 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$%?.@%!encoding$%utf-A%>' "+inear+ayout!xmlns#android$%&ttp#//sc&emas.android.com/ap /res/android% !!android#orientation$%vertical% !!android#layout_widt&$%fill_parent% !!android#layout_&eig&t$%fill_parent%' !!"-ab3ost!android#id$%9Bid/tab&ost% !!!!android#layout_widt&$%fill_parent% !!!!android#layout_&eig&t$%fill_parent%' !!!!"-abCidget!android#id$%9android#id/tabs% !!!!!!android#layout_widt&$%fill_parent% !!!!!!android#layout_&eig&t$%wrap_content% !!!!/' !!!!"Erame+ayout!android#id$%9android#id/tabcontent% !!!!!!android#layout_widt&$%fill_parent% !!!!!!android#layout_&eig&t$%fill_parent% !!!!!!android#padding-op$%NHpx%' !!!!!!"Analog)loc !android#id$%9Bid/tab?% !!!!!!!!android#layout_widt&$%fill_parent%! !!!!!!!!android#layout_&eig&t$%fill_parent% *%$
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
!!!!!!!!android#layout_center3ori(ontal$%true% !!!!!!/' !!!!!!"6utton!android#id$%9Bid/tabH% !!!!!!!!android#layout_widt&$%fill_parent% !!!!!!!!android#layout_&eig&t$%fill_parent% !!!!!!!!android#text$%A!semi-random!button% !!!!!!/' !!!!"/Erame+ayout' !!"/-ab3ost' "/+inear+ayout'
/ote that the -abCidget 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 t=o 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' =ith their o=n %ontents.
7irin! It To!ether
4he Gava %o e nee s to tell the -ab3ost =hat vie=s represent the tab %ontents an =hat the tab buttons shoul look like. 4his is all =rappe up in -abSpec! obNe%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. 4he t=o key metho s on -abSpec are*
set)ontent:;, =here you in i%ate =hat goes in the tab %ontent $or this tab, typi%ally the android#id o$ the vie= you =ant sho=n =hen this tab is sele%te set.ndicator:;,
=here 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
/ote that tab Qin i%atorsQ %an a%tually be vie=s in their o=n right, i$ you nee more %ontrol than a simple label an optional i%on. Also note that you must %all setup:; on the -ab3ost be$ore %on$iguring any o$ these -abSpec obNe%ts. 4he %all to setup:; is not nee e i$ you are using the -abActivity base %lass $or your a%tivity.
*%0
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
(or e:ample, here is the Gava %o e to =ire together the tabs $rom the pre%e ing layout e:ample*
pac age!com.commonsware.android.fancy5 import!android.app.Activity5 import!android.os.6undle5 import!android.widget.-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:%tag?%;5 !!!! !!!!spec.setContent:R.id.tab?;5 !!!!spec.setIndicator:%)loc %;5 !!!!tabs.addTa!:spec;5 !!!! !!!!spec$tabs.newTa!Spec:%tagH%;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, =e get a -abSpec via new-abSpec:;, supplying a tag =hose purpose is unkno=n at this time. 7iven the spe%, you %all set)ontent:; an set.ndicator:;, then %all add-ab:; ba%k on the -ab3ost to register the tab as available $or use. (inally, you %an %hoose =hi%h tab is the one to sho= via set)urrent-ab:;, provi ing the @2base in e: o$ the tab. 4he resultC
*%1
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
!igure -1< The Tab/emo sample application6 sho)ing the first tab
*%4
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
*%7
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
CHAPTER 11
(pplying +enus
Like appli%ations $or the esktop an some mobile operating systems, su%h as !alm># an Win o=s Mobile, An roi supports a%tivities =ith Qappli%ationQ menus. #ome An roi phones =ill have a e i%ate menu key $or popping up the menuP others =ill o$$er alternate means $or triggering the menu to appear. Also, as =ith many 7"- toolkits, you %an %reate Q%onte:t menusQ. >n a tra itional 7"-, this might be triggere by the right2mouse button. >n mobile evi%es, %onte:t menus typi%ally appear =hen the user Qtaps2an 2 hol sQ over a parti%ular =i get. (or e:ample, i$ a -ext7iew ha a %onte:t menu, an the evi%e =as esigne $or $inger2base tou%h input, you %oul push the -ext7iew =ith your $inger, hol it $or a se%on or t=o, an a pop2up menu =ill appear $or the user to %hoose $rom. Where An roi i$$ers $rom most other 7"- toolkits is in terms o$ menu %onstru%tion. While you %an a items to the menu, you o not have $ull %ontrol over the menu6s %ontents, nor the timing o$ =hen the menu is built. !art o$ the menu is system2 e$ine , an that portion is manage by the An roi $rame=ork itsel$.
!lavors of +enu
An roi %onsi ers the t=o types o$ menu es%ribe above as being the Qoptions menuQ an Q%onte:t menuQ. 4he options menu is triggere by
*%9
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
(pplying +enus
pressing the har =are QMenuQ button on the evi%e, =hile the %onte:t menu is raise by a tap2an 2hol on the =i get sporting the menu. -n a ition, the options menu operates in one o$ t=o mo es* i%on an e:pan e . When the user $irst presses the QMenuQ button, the i%on mo e =ill appear, sho=ing up to the $irst si: menu %hoi%es as large, $inger2$rien ly buttons in a gri at the bottom o$ the s%reen. -$ the menu has more than si: %hoi%es, the si:th button =ill be%ome QMoreQ O %li%king that option =ill bring up the e:pan e mo e, sho=ing the remaining %hoi%es not visible in the regular menu. 4he 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%tivity6s options menu uring on)reate:;, the =ay you =ire up the rest o$ your "-, you instea nee to implement on)reate,ptionsMenu:;. 4his %allba%k re%eives an instan%e o$ Menu. 4he $irst thing you shoul o is %hain up=ar to the super%lass &super.on)reate,ptionsMenu:menu;', so the An roi $rame=ork %an a in any menu %hoi%es it $eels are ne%essary. 4hen, you %an go about a ing your o=n options, es%ribe belo=. -$ you =ill nee to a Nust the menu uring your a%tivity6s use &e.g., isable a no=2invali menu %hoi%e', Nust hol onto the Menu instan%e you re%eive in on)reate,ptionsMenu:;. /ote, ho=ever, that on)reate,ptionsMenu:; =ill be %alle ea%h an every time the user presses the Menu button. 7iven that you have re%eive a Menu obNe%t via on)reate,ptionsMenu:;, you a menu %hoi%es by %alling add:;. 4here are many $lavors o$ this metho , =hi%h re;uire some %ombination o$ the $ollo=ing parameters*
A group i enti$ier &int', =hi%h shoul be /,/* unless you are %reating a spe%i$i% groupe set o$ menu %hoi%es $or use =ith set0roup)&ec able:; &see belo='
*-;
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-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 =hen a menu %hoi%e is %hosen An or er i enti$ier &yet another int', $or in i%ating =here this menu %hoi%e shoul be slotte i$ the menu has An roi 2supplie %hoi%es alongsi e your o=n O $or no=, Nust use /,/* 4he te:t o$ the menu %hoi%e, as a #tring or a resour%e -A
4he add:; $amily o$ metho s all return an instan%e o$ Menu.tem, =here you %an a Nust 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 O single2%hara%ter mnemoni%s that %hoose that menu %hoi%e =hen the menu is visible. An roi supports both an alphabeti% &or Q;=ertyQ' set o$ short%uts an a numeri% set o$ short%uts. 4hese are set in ivi ually by %alling setAlp&abeticS&ortcut:; an set/umericS&ortcut:; respe%tively. 4he menu is pla%e into alphabeti% short%ut mo e by %alling setTwertyMode:; on the menu =ith a true parameter. 4he %hoi%e an group i enti$iers are keys use to unlo%k a $eatures, su%h as*
itional menu
Calling Menu.temDset)&ec able:; =ith a %hoi%e i enti$ier, to %ontrol i$ the menu %hoi%e has a t=o2state %he%kbo: alongsi e the title, =here the %he%kbo: value gets toggle =hen the user %hooses that menu %hoi%e Calling MenuDset0roup)&ec able:; =ith a group i enti$ier, to turn a set o$ menu %hoi%es into ones =ith a mutual2e:%lusion ra io button bet=een them, so one out o$ the group %an be in the Q%he%ke Q state at any time
@ou %an also %all add.ntent,ptions:; to populate the menu =ith 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 $ly2out sub2menus by %alling addSubMenu:;, supplying the same parameters as addMenu:;. An roi =ill eventually %all on)reate1anelMenu:;, passing it the %hoi%e i enti$ier o$ your sub2menu,
*-*
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
(pplying +enus
along =ith another Menu instan%e representing the sub2menu itsel$. As =ith on)reate,ptionsMenu:;, you shoul %hain up=ar to the super%lass, then a menu %hoi%es to the sub2menu. >ne limitation is that you %annot in e$initely nest sub2menus O a menu %an have a sub2menu, but a sub2menu %annot itsel$ have a sub2sub2menu. -$ the user makes a menu %hoi%e, your a%tivity =ill be noti$ie via the on,ptions.temSelected:; %allba%k that a menu %hoi%e =as sele%te . @ou are given the Menu.tem obNe%t %orrespon ing to the sele%te menu %hoi%e. A typi%al pattern is to switc&:; on the menu -A &item.get.tem.d:;' an take appropriate behavior. /ote that on,ptions.temSelected:; is use regar less o$ =hether the %hosen menu item =as in the base menu or in a submenu.
+enus in Context
.y an large, %onte:t menus use the same guts as option menus. 4he t=o main i$$eren%es are ho= you populate the menu an ho= you are in$orme o$ menu %hoi%es. (irst, you nee to in i%ate =hi%h =i get&s' on your a%tivity have %onte:t menus. 4o o this, %all registerEor)ontextMenu:; $rom your a%tivity, supplying the 7iew that is the =i get nee ing a %onte:t menu. /e:t, you nee to implement on)reate)ontextMenu:;, =hi%h, among other things, is passe the 7iew you supplie in registerEor)ontextMenu:;. @ou %an use that to etermine =hi%h menu to buil , assuming your a%tivity has more than one. 4he on)reate)ontextMenu:; metho gets the )ontextMenu itsel$, the 7iew the %onte:t menu is asso%iate =ith, an a )ontextMenu.)ontextMenu.nfo, =hi%h tells you =hi%h item in the list the user i the tap2an 2hol over, in %ase you =ant to %ustomiMe 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. /ote that you only get this Qe:tra in$ormationQ =hen the menu is built, not =hen a %hoi%e is ma e.
*-%
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
(pplying +enus
-t is also important to note that on)reate)ontextMenu:; gets %alle $or ea%h time the %onte:t menu is re;ueste . "nlike the options menu &=hi%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 =ant to hol onto the supplie )ontextMenu! obNe%tP Nust rely on getting the %han%e to rebuil the menu to suit your a%tivity6s nee s on an on2 eman basis base on user a%tions. 4o $in out =hen a %onte:t menu %hoi%e =as %hosen, implement on the a%tivity. /ote that you only get the Menu.tem! instan%e that =as %hosen in this %allba%k. As a result, i$ your a%tivity has t=o or more %onte:t menus, you may =ant 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. >ther=ise, this %allba%k behaves the same as on,ptions.temSelected:; as is es%ribe above.
on)ontext.temSelected:;
Taking a Peek
-n the sample proNe%t Menus, you =ill $in an amen e version o$ the +ist7iew sample &+ist' =ith an asso%iate menu. #in%e the menus are e$ine in Gava %o e, the DML layout nee not %hange an is not reprinte here. )o=ever, the Gava %o e has a $e= ne= behaviors*
public!class!MenuDemo!extends!+istActivity!8 !!-ext7iew!selection5 !!StringPQ!items$8%lorem%G!%ipsum%G!%dolor%G!%sit%G!%amet%G !!!!!!!!!!%consectetuer%G!%adipiscing%G!%elit%G!%morbi%G!%vel%G !!!!!!!!!!%ligula%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!%augue%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-BO5 !!public!static!final!int!-3.R-F_-C,_.D!$!Menu.E.RS-BL5 !!public!static!final!int!E,R-F_.D!$!Menu.E.RS-BN5 !!public!static!final!int!E,R-F_*.03-_.D!$!Menu.E.RS-BV5 !!9,verride !!public!void!onCreate:6undle!icicle;!8 !!super.onCreate:icicle;5
*-Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
(pplying +enus
!!setContentView:R.layout.main;5 !!!!setList#dapter:new!ArrayAdapter"String':t&isG !!!!!!!!!!!!!!!!android.R.layout.simple_list_item_?G!items;;5 !!!!selection$:-ext7iew;findViewById:R.id.selection;5 !!!! !!!!register"orContext'enu:getListView:;;5 !!< !! !!public!void!onListItemClick:+ist7iew!parentG!7iew!vG !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!int!positionG!long!id;!8 !!!selection.setText:itemsPpositionQ;5 !!< !! !!9,verride !!public!void!onCreateContext'enu:)ontextMenu!menuG!7iew!vG !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!)ontextMenu.)ontextMenu.nfo!menu.nfo;!8 !!!!populate'enu:menu;5 !!< !! !!9,verride !!public!boolean!onCreateOptions'enu:Menu!menu;!8 !!!!populate'enu:menu;5 !!!!return:super.onCreateOptions'enu:menu;;5 !!< !!9,verride !!public!boolean!onOptionsItemSelected:Menu.tem!item;!8 !!!!apply'enuChoice:item;5 !!!!return:apply'enuChoice:item;!WW !!!!!!!!!!!!super.onOptionsItemSelected:item;;5 !!< !!9,verride !!public!boolean!onContextItemSelected:Menu.tem!item;!8 !!!!return:apply'enuChoice:item;!WW !!!!!!!!!!!!super.onContextItemSelected:item;;5 !!< !! !!private!void!populate'enu:Menu!menu;!8 !!!!menu.add:Menu./,/*G!-C,_.DG!Menu./,/*G!%H!1ixels%;5 !!!!menu.add:Menu./,/*G!*.03-_.DG!Menu./,/*G!%A!1ixels%;5 !!!!menu.add:Menu./,/*G!S.U-**/_.DG!Menu./,/*G!%?N!1ixels%;5 !!!!menu.add:Menu./,/*G!-C*/-F_E,2R_.DG!Menu./,/*G!%HO!1ixels%;5 !!!!menu.add:Menu./,/*G!-3.R-F_-C,_.DG!Menu./,/*G!%IH!1ixels%;5 !!!!menu.add:Menu./,/*G!E,R-F_.DG!Menu./,/*G!%O@!1ixels%;5 !!!!menu.add:Menu./,/*G!E,R-F_*.03-_.DG!Menu./,/*G!%OA!1ixels%;5 !!< !! !!private!boolean!apply'enuChoice:Menu.tem!item;!8 !!!!switc&!:item.getItemId:;;!8 !!!!!!case!*.03-_.D#
*-$
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
(pplying +enus
!!!!!!!!getListView:;.setDi !!!!!!!!return:true;5 !!!! !!!!!!case!S.U-**/_.D# !!!!!!!!getListView:;.setDi !!!!!!!!return:true;5 !!!! !!!!!!case!-C*/-F_E,2R_.D# !!!!!!!!getListView:;.setDi !!!!!!!!return:true;5 !!!! !!!!!!case!-C,_.D# !!!!!!!!getListView:;.setDi !!!!!!!!return:true;5 !!!! !!!!!!case!-3.R-F_-C,_.D# !!!!!!!!getListView:;.setDi !!!!!!!!return:true;5 !!!! !!!!!!case!E,R-F_.D# !!!!!!!!getListView:;.setDi !!!!!!!!return:true;5 !!!! !!!!!!case!E,R-F_*.03-_.D# !!!!!!!!getListView:;.setDi !!!!!!!!return:true;5 !!!!< !!!!return:false;5 !!< <
ider,eight:A;5
ider,eight:?N;5
ider,eight:HO;5
ider,eight:H;5
ider,eight:IH;5
ider,eight:O@;5
ider,eight:OA;5
-n on)reate:;, =e register our list =i get as having a %onte:t menu, =hi%h =e $ill in via our populateMenu:; private metho , by =ay o$ on)reate)ontextMenu:;. We also implement the on)reate,ptionsMenu:; %allba%k, in i%ating that our a%tivity also has an options menu. >n%e again, =e elegate to populateMenu:;! to $ill in the menu. >ur implementations o$ on,ptions.temSelected:; &$or options menu sele%tions' an on)ontext.temSelected:; &$or %onte:t menu sele%tions' both elegate to a private applyMenu)&oice:; metho , plus %haining up=ar s to the super%lass i$ none o$ our menu %hoi%es =as the one sele%te by the user.
*-0
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
(pplying +enus
-n populateMenu:;, =e a $our menu %hoi%es, ea%h =ith a uni;ue i enti$ier. .eing laMy, =e es%he= the i%ons. -n applyMenu)&oice:;, =e see i$ any o$ our menu %hoi%es =ere %hosenP i$ so, =e set the list6s ivi er siMe to be the user2sele%te =i th. -nitially, the a%tivity looks the same in the emulator as it i $or +istDemo*
.ut, i$ you press the Menu button, you =ill get our options menu*
*-1
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
(pplying +enus
Cli%king the More button sho=s the remaining t=o menu %hoi%es*
*-4
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
(pplying +enus
Choosing a height &say, ,3 pi:els' then %hanges the ivi er height o$ the list to something garish*
@ou %an trigger the %onte:t menu by oing a tap2an 2hol on any item in the list*
*-7
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
(pplying +enus
*-9
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
CHAPTER 1&
>ther 7"- toolkits let you use )4ML $or presenting in$ormation, $rom limite )4ML ren erers &e.g., GavaU#=ing, =:Wi gets' to embe ing -nternet I:plorer into ./I4 appli%ations. An roi is mu%h the same, in that you %an embe the built2in Web bro=ser as a =i get in your o=n a%tivities, $or isplaying )4ML or $ull2$le ge bro=sing. 4he An roi bro=ser is base on WebEit, the same engine that po=ers Apple6s #a$ari Web bro=ser. 4he An roi bro=ser is su$$i%iently %omple: that it gets its o=n Gava pa%kage &android.web it', though using the Ceb7iew =i get itsel$ %an be simple or po=er$ul, base upon your re;uirements.
*$*
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
As =ith any other =i get, you nee to tell it ho= it shoul $ill up the spa%e in the layout &in this %ase, it $ills all remaining spa%e'. 4he Gava %o e is e;ually simple*
pac age!com.commonsware.android.web it5 import!android.app.Activity5 import!android.os.6undle5 import!android.web it.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.web it;5 !!!! !!!!browser.load)rl:%&ttp#//commonsware.com%;5 !!< <
4he only bit unusual =ith this e ition o$ on)reate:; is that =e invoke load2rl:; on the Ceb7iew =i get, to tell it to loa a Web page &in this %ase, the home page o$ some ran om $irm'. )o=ever, =e also have to make one %hange to AndroidManifest.xml, re;uesting permission to a%%ess the -nternet*
"manifest!xmlns#android$%&ttp#//sc&emas.android.com/ap /res/android% !!pac age$%com.commonsware.android.web it%' !!"uses-permission!android#name$%android.permission../-*R/*-%!/' !!"application' !!!!"activity!android#name$%.6rowserDemo?%!android#label$%6rowserDemo?%' !!!!!!"intent-filter' !!!!!!!!"action!android#name$%android.intent.action.MA./%!/' !!!!!!!!"category!android#name$%android.intent.category.+A2/)3*R%!/' !!!!!!"/intent-filter' !!!!"/activity'
*$%
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
!!"/application' "/manifest'
-$ =e $ail to a
As =ith the regular An roi bro=ser, you %an pan aroun the page by ragging it, =hile 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 bro=ser, su%h as a navigational toolbar.
oading 8t >p
4here are t=o main =ays to get %ontent into the Ceb7iew. >ne, sho=n above, is to provi e the bro=ser =ith a "RL an have the bro=ser isplay that page via load2rl:;. 4he bro=ser =ill a%%ess the -nternet through =hatever means
*$Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
are available to that spe%i$i% evi%e at the present time &Wi(i, %ellular net=ork, .luetooth2tethere phone, =ell2traine tiny %arrier pigeons, et%.'. 4he alternative is to use loadData:;. )ere, you supply the )4ML $or the bro=ser to vie=. @ou might use this to*
isplay a manual that =as installe as a $ile =ith your appli%ation pa%kage isplay snippets o$ )4ML you retrieve as part o$ other pro%essing, su%h as the es%ription o$ an entry in an Atom $ee generate a =hole user inter$a%e using )4ML, instea o$ using the An roi =i get set
4here are t=o $lavors o$ loadData:;. 4he simpler one allo=s you to provi e the %ontent, the M-MI type, an the en%o ing, all as strings. 4ypi%ally, your M-MI type =ill be text/&tml an your en%o ing =ill be 2-E-A $or or inary )4ML. (or e:ample, i$ you repla%e the load2rl:; invo%ation in the previous e:ample =ith the $ollo=ing*
browser.loadData:%"&tml'"body'3elloG!worldX"/body'"/&tml'%G !!!!!!!!!!!!!!!!!!%text/&tml%G!%2-E-A%;5
@ou get*
*$$
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
to go ba%k one step in the bro=ser history, an can0o6ac :;! to etermine i$ there is any history to go ba%k to
goEorward:; to go can0oEorward:; to go6ac ,rEorward:;
$or=ar one step in the bro=ser history, an etermine i$ there is any history to go $or=ar to
to go ba%k=ar s or $or=ar s in the bro=ser history, =here negative numbers represent a %ount o$ steps to go
*$0
to see i$ the bro=ser %an go ba%k=ar s or $or=ar s the state number o$ steps &$ollo=ing the same positiveUnegative %onvention as go6ac ,rEorward:;'
can0o6ac ,rEorward:; clear)ac&e:;
to %lear the bro=ser resour%e %a%he an clear3istory:;! to %lear the bro=sing history
et%.
A %ommon hook =ill be s&ould,verride2rl+oading:;, =here your %allba%k is passe a "RL &plus the Ceb7iew itsel$' an you return true i$ you =ill han le the re;uest or false i$ you =ant 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 =ill probably not have a $ull bro=ser =ith navigation built into your rea er, so i$ the user %li%ks a "RL, you probably =ant to use an .ntent to ask An roi to loa that page in a $ull bro=ser. .ut, i$ you have
*$1
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
inserte a Q$akeQ "RL into the )4ML, representing a link to some a%tivity2 provi e %ontent, you %an up ate the Ceb7iew yoursel$. (or e:ample, let6s amen the $irst bro=ser e:ample to be a bro=ser2base e;uivalent o$ our original e:ample* an appli%ation that, upon a %li%k, sho=s the %urrent time. (rom 6rowserI, here is the revise Gava*
pac age!com.commonsware.android.web it5 import!android.app.Activity5 import!android.os.6undle5 import!android.web it.Ceb7iew5 import!android.web it.Ceb7iew)lient5 import!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 !!!!browser$:Ceb7iew;findViewById:R.id.web it;5 !!!!browser.set&e!ViewClient:new!Call!ack:;;5 !!!! !!!!loadTime:;5 !!< !! !!void!loadTime:;!8 !!!!String!page$%"&tml'"body'"a!&ref$4%cloc 4%'% !!!!!!!!!!!!Bnew!Date:;.toString:; !!!!!!!!!!!!B%"/a'"/body'"/&tml'%5 !!!!!!!!!!!! !!!!!!!!!!!!browser.loadData&ithBase)$L:%x-data#//base%G!pageG !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!%text/&tml%G!%2-E-A%G !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!null;5 !!< !!private!class!)allbac !extends!Ceb7iew)lient!8 !!!!public!boolean!shouldO erride)rlLoading:Ceb7iew!viewG!String!url;!8 !!!!!!loadTime:;5 !!!!!! !!!!!!return:true;5 !!!!<
*$4
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
)ere, =e loa a simple Web page into the bro=ser & load-ime:;' that %onsists o$ the %urrent time, ma e into a hyperlink to the /cloc "RL. We also atta%h an instan%e o$ a Ceb7iew)lient sub%lass, provi ing our implementation o$ s&ould,verride2rl+oading:;. -n this %ase, no matter =hat the "RL, =e =ant to Nust reloa the Ceb7iew via load-ime:;. Running this a%tivity gives us*
#ele%ting the link an %li%king the A2pa %enter button =ill Q%li%kQ the link, %ausing us to rebuil the page =ith the ne= time.
*$7
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
#imilarly, you %an a Nust the settings o$ your Ceb7iew =i get as you see $it, via the CebSettings instan%e returne $rom %alling the =i get6s getSettings:;! metho . 4here are lots o$ options on CebSettings to play =ith. Most appear $airly esoteri% &e.g., setEantasyEontEamily:;'. )o=ever, here are some that you may $in more use$ul*
Control the $ont siMing via setDefaultEontSi(e:; &to use a point siMe' or set-extSi(e:; &to use %onstants in i%ating relative siMes like +AR0*R an SMA++*S-' Control Gavas%ript via set=avaScript*nabled:; &to isable it outright' an set=avaScript)an,penCindowsAutomatically:; &to merely stop it $rom opening pop2up =in o=s' Control Web site ren ering via set2serAgent:; O @ means the Ceb7iew! gives the Web site a user2agent string that in i%ates it is a mobile bro=ser, =hile ? results in a user2agent string that suggests it is a esktop bro=ser
4he settings you %hange are not persistent, so you shoul store them some=here &su%h as via the An roi pre$eren%es engine' i$ you are allo=ing your users to etermine the settings, versus har 2=iring the settings in your appli%ation.
*$9
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
CHAPTER 1'
#ometimes, your a%tivity &or other pie%e o$ An roi %o e' =ill nee to speak up. /ot every intera%tion =ith An roi users =ill be neat, ti y, an %ontainable in a%tivities %ompose o$ vie=s. Irrors =ill %rop up. .a%kgroun tasks may take =ay 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 =ith the user outsi e the boun s o$ the tra itional user inter$a%e. >$ %ourse, this is nothing ne=. 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 $e= systems $or letting you alert your users outsi e the boun s o$ an Activity2base "-. >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 =ill see t=o means o$ raising pop2up messages* toasts an alerts.
3aising Toasts
A -oast is a transient message, meaning that it isplays an isappears on its o=n =ithout user intera%tion. Moreover, it oes not take $o%us a=ay $rom
*0*
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
the %urrently2a%tive Activity, so i$ the user is busy =riting the ne:t 7reat Ameri%an !rogramming 7ui e, they =ill not have keystrokes be QeatenQ by the message. #in%e a -oast is transient, you have no =ay o$ kno=ing i$ the user even noti%es it. @ou get no a%kno=le 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 long2running ba%kgroun task is %omplete , the battery has roppe to a lo=2but2not2too2lo= level, et%. Making a -oast is $airly easy. 4he -oast %lass o$$ers a stati% ma e-ext:; that a%%epts a String &or string resour%e -A' an returns a -oast instan%e. 4he ma e-ext:; metho also nee s the Activity &or other )ontext' plus a uration. 4he 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, ho= long the message shoul remain visible. -$ you =oul 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 ne= -oast instan%e via the %onstru%tor &=hi%h takes a )ontext', then %all set7iew:; to supply it =ith the vie= to use an setDuration:; to set the uration. >n%e your -oast is %on$igure , %all its s&ow:; metho , an the message =ill be isplaye .
(lert! (lert!
-$ you =oul pre$er something in the more %lassi% ialog bo: style, =hat you =ant is an AlertDialog. As =ith any other mo al ialog bo:, an AlertDialog! 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 =here you are sure that the user nee s to see the message an nee s to see it no=. 4he simplest =ay to %onstru%t an AlertDialog is to use the 6uilder %lass. (ollo=ing in true buil er style, 6uilder o$$ers a series o$ metho s to
*0%
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
%on$igure an AlertDialog, 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:. Commonly2use %on$iguration metho s on 6uilder in%lu e*
setMessage:; i$ you =ant the Qbo yQ o$ the ialog to be a simple te:tual message, $rom either a supplie String or a supplie string resour%e -A 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/egative6utton:;, to
set.con:;,
in i%ate =hi%h button&s' shoul appear a%ross the bottom o$ the ialog, =here they shoul be positione &le$t, %enter, or right, respe%tively', =hat their %aptions shoul be, an =hat logi% shoul be invoke =hen the button is %li%ke &besi es ismissing the ialog'.
-$ you nee to %on$igure the AlertDialog beyon =hat the buil er allo=s, instea o$ %alling s&ow:;, %all create:; to get the partially2built AlertDialog! instan%e, %on$igure it the rest o$ the =ay, then %all one o$ the $lavors o$ s&ow:; on the AlertDialog itsel$. >n%e s&ow:; is %alle , the ialog bo: =ill appear an a=ait user input.
*0Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
...an Gava %o e*
public!class!MessageDemo!extends!Activity!implements!7iew.,n)lic +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!AlertDialog.Builder:t&is; !!!!!!!!.setTitle:%MessageDemo%; !!!!!!!!.set'essage:%ee X%; !!!!!!!!.set%eutralButton:%)lose%G!new!Dialog.nterface.OnClickListener:;!8 !!!!!!!!!!public!void!onClick:Dialog.nterface!dlgG!int!sumt∈!8 !!!!!!!!!!!!//!do!not&ing!Y!it!will!close!on!its!own !!!!!!!!!!< !!!!!!!!<; !!!!!!!!.show:;5 !!!!< !!!!else!8 !!!!!!-oast !!!!!!!!.makeText:t&isG!%"clin G!clin '%G!-oast.+*/0-3_S3,R-; !!!!!!!!.show:;5 !!!!< !!< <
4he layout is unremarkable O Nust a pair o$ buttons to trigger the alert an the toast. When you %li%k the alert button, =e use a buil er &new!6uilder:t&is;' to set the title &set-itle:%MessageDemo%;', message &setMessage:%ee X%;', an
*0$
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
Qneutral buttonQ &set/eutral6utton:%)lose%G ! new ! ,n)lic +istener:; ! ...' be$ore sho=ing the ialog. When the button is %li%ke , the ,n)lic +istener! %allba%k oes nothing O the mere $a%t the button =as presse %auses the ialog to be ismisse . )o=ever, 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. 4he result is a typi%al ialog bo:*
!igure $1< The +essage/emo sample application6 after clicking the =3aise an alert= button
When you %li%k the toast button, the -oast %lass makes us a te:t2base toast &ma e-ext:t&isG ! %"clin G ! clin '%G ! +*/0-3_S3,R-;', =hi%h =e then s&ow:;. 4he result is a short2live , non2interrupting message*
*00
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
!igure $4< The same application6 after clicking the =+ake a toast= button
*01
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
CHAPTER 1(
- eally, you =ant your a%tivities to be o=nright snappy, so your users on6t $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 =ithin B se%on s, lest the ActivityManager e%i e to play the role o$ the 7rim Reaper an kill o$$ your a%tivity as being non2responsive. >$ %ourse, your a%tivity might have real =ork to o, =hi%h takes non2 negligible amounts o$ time. 4here are t=o =ays o$ ealing =ith 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 =ork in a ba%kgroun threa An roi provi es a veritable %ornu%opia o$ means to set up ba%kgroun threa s yet allo= them to sa$ely intera%t =ith the "- on the "- threa . 4hese in%lu e 3andler obNe%ts, posting Runnable! obNe%ts to the 7iew, an using 2.-&read2tilities.
*04
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
merely %reating the instan%e is su$$i%ient to register it =ith the An roi threa ing subsystem. @our ba%kgroun threa %an %ommuni%ate =ith the 3andler, =hi%h =ill o all o$ its =ork on the a%tivity "- threa . 4his is important, as "- %hanges, su%h as up ating =i gets, shoul only o%%ur on the a%tivity "- threa . @ou have t=o options $or %ommuni%ating =ith the 3andler* messages an Runnable obNe%ts.
%ess !es
4o sen a Message to a 3andler, $irst invoke obtainMessage:; to get the Message! obNe%t out o$ the pool. 4here are a $e= $lavors o$ obtainMessage:;, allo=ing you to Nust %reate empty Message obNe%ts, or ones populate =ith message i enti$iers an arguments. 4he more %ompli%ate your 3andler pro%essing nee s to be, the more likely it is you =ill nee to put ata into the Message to help the 3andler istinguish i$$erent events. 4hen, you sen the Message to the 3andler via its message ;ueue, using one o$ the sendMessage...:; $amily o$ metho s, su%h as*
sendMessage:; puts the message on the ;ueue imme sendMessageAtEront,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 &System)loc .uptimeMillis:;'
sendMessageAt-ime:; sendMessageDelayed:;
4o
these messages, your 3andler nee s to implement &andleMessage:;, =hi%h =ill be %alle =ith ea%h message that appears on the
pro%ess
*07
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
message ;ueue. 4here, the han ler %an up ate the "- as nee e . )o=ever, it shoul still o that =ork ;ui%kly, as other "- =ork is suspen e until the 3andler is one. (or e:ample, let6s %reate a 1rogress6ar an up ate it via a 3andler. )ere is the layout $rom 3andler*
">xml!version$%?.@%!encoding$%utf-A%>' "+inear+ayout!xmlns#android$%&ttp#//sc&emas.android.com/ap /res/android% !!android#orientation$%vertical% !!android#layout_widt&$%fill_parent% !!android#layout_&eig&t$%fill_parent% !!' !!"1rogress6ar!android#id$%9Bid/progress% !!!!style$%>android#attr/progress6arStyle3ori(ontal% !!!!android#layout_widt&$%fill_parent% !!!!android#layout_&eig&t$%wrap_content%!/' "/+inear+ayout'
4he 1rogress6ar, in a ition to setting the =i th an height as normal, also employs t=o other properties o$ note*
style,
=hi%h =ill be %overe in greater etail in some $uture e ition o$ this book. (or no=, su$$i%e it to say that it in i%ates this 1rogress6ar shoul be ra=n as the tra itional horiMontal bar sho=ing the amount o$ =ork that has been %omplete .
android#max,
=hi%h in i%ates the ma:imum value $or the 1rogress6ar! &i.e., at =hat value is the =ork Q oneQ an the progress bar %omplete '. A value o$ ?@@ means the 1rogress6ar =orks on a simple per%entage system.
*09
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
!!!!9,verride !!!!public!void!handle'essage:Message!msg;!8 !!!!!!bar.increment(rogressBy:L;5 !!!!< !!<5 !!boolean!isRunning$false5 !! !!9,verride !!public!void!onCreate:6undle!icicle;!8 !!!!super.onCreate:icicle;5 !!!!setContentView:R.layout.main;5 !!!!bar$:1rogress6ar;findViewById:R.id.progress;5 !!< !! !!public!void!onStart:;!8 !!!!super.onStart:;5 !!!!bar.set(rogress:@;5 !!!! !!!!-&read!bac ground$new!Thread:new!$unna!le:;!8 !!!!!!public!void!run:;!8 !!!!!!!!try!8 !!!!!!!!!!for!:int!i$@5i"H@!ZZ!isRunning5iBB;!8 !!!!!!!!!!!!-&read.sleep:?@@@;5 !!!!!!!!!!!!&andler.send'essage:&andler.o!tain'essage:;;5 !!!!!!!!!!< !!!!!!!!< !!!!!!!!catc&!:-&rowable!t;!8 !!!!!!!!!!//!just!end!t&e!bac ground!t&read !!!!!!!!< !!!!!!< !!!!<;5 !!!! !!!!isRunning$true5 !!!!bac ground.start:;5 !!< !! !!public!void!onStop:;!8 !!!!super.onStop:;5 !!!!isRunning$false5 !!< <
As part o$ %onstru%ting the Activity, =e %reate an instan%e o$ 3andler, =ith our implementation o$ &andleMessage:;. .asi%ally, $or any message re%eive , =e up ate the 1rogress6ar by L points, then e:it the message han ler. -n onStart:;, =e set up a ba%kgroun threa . -n a real system, this threa =oul o something meaning$ul. )ere, =e Nust sleep one se%on , post a Message to the 3andler, an repeat $or a total o$ H@ passes.
*1;
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
/ote that =e then leave onStart:;. 4his is %ru%ial. 4he onStart:; metho is invoke on the a%tivity "- threa , so it %an up ate =i gets an su%h. )o=ever, that means =e nee to get out o$ onStart:;, both to let the 3andler! get its =ork one, an also so An roi oes not think our a%tivity is stu%k. 4he resulting a%tivity is simply a horiMontal progress bar*
Runn 3les
-$ you =oul rather not $uss =ith Message obNe%ts, you %an also pass Runnable! obNe%ts to the 3andler, =hi%h =ill run those Runnable obNe%ts on the a%tivity "- threa . 3andler o$$ers a set o$ post...:; metho s $or passing Runnable! obNe%ts in $or eventual pro%essing.
3unning 8n Place
Gust as 3andler supports post:; an postDelayed:; to a Runnable obNe%ts to the event ;ueue, you %an use those same metho s on 7iew. 4his lightly
*1*
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
simpli$ies your %o e, in that you %an then skip the 3andler obNe%t. )o=ever, you lose a bit o$ $le:ibility, an the 3andler has been aroun longer in the An roi toolkit an may be more teste .
4he possibility that users =ill intera%t =ith your a%tivity6s "- =hile the ba%kgroun threa is %hugging along. -$ the =ork that the ba%kgroun threa is oing is altere or invali ate by the user input, you =ill 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 =ill help you %ommuni%ate sa$ely =ith your ba%kgroun threa . 4he possibility that the a%tivity =ill be kille o$$ =hile ba%kgroun =ork is going on. (or e:ample, a$ter starting your a%tivity, the user
*1%
might have a %all %ome in, $ollo=e by a te:t message, $ollo=e by a nee to look up a %onta%t...all o$ =hi%h might be su$$i%ient to ki%k your a%tivity out o$ memory. 4he ne:t %hapter =ill %over the various events An roi =ill take your a%tivity throughP hook the proper ones an be sure to shut o=n your ba%kgroun threa %leanly =hen you have the %han%e.
4he possibility that your user =ill get irritate i$ you %he= up a lot o$ C!" time an battery li$e =ithout giving any payba%k. 4a%ti%ally, this means using 1rogress6ar or other means o$ letting the user kno= that something is happening. #trategi%ally, this means you still nee to be e$$i%ient at =hat you o O ba%kgroun threa s are no pana%ea $or sluggish or pointless %o e. 4he possibility that you =ill 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 /oti$i%ation! an shutting o=n the ba%kgroun threa may be your best option.
*1Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
CHAPTER 1)
While this may soun like a broken re%or ...please remember that An roi evi%es, by an large, are phones. As su%h, some a%tivities are more important that others O 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%tivity6s memory. 4hink o$ it as the An roi e;uivalent o$ the Q%ir%le o$ li$eQ O your a%tivity ies so others may live, an so on. @ou %annot assume that your a%tivity =ill run until you think it is %omplete, or even until the user thinks it is %omplete. 4his is one e:ample O perhaps the most important e:ample O o$ ho= an a%tivity6s li$e%y%le =ill a$$e%t your o=n appli%ation logi%. 4his %hapter %overs the various states an %allba%ks that make up an a%tivity6s li$e%y%le an ho= you %an hook into them appropriately.
SchroedingerAs (ctivity
An a%tivity, generally speaking, is in one o$ $our states at any point in time*
*10
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
Active* the a%tivity =as starte by the user, is running, an is in the $oregroun . 4his is =hat you6re use to thinking o$ in terms o$ your a%tivity6s operation. Paused* the a%tivity =as 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 =ith it. (or e:ample, i$ a %all %omes in, the user =ill get the opportunity to take the %all or ignore it. #topped* the a%tivity =as starte by the user, is running, but it is hi en by other a%tivities that have been laun%he or s=it%he to. @our appli%ation =ill not be able to present anything meaning$ul to the user ire%tly, only by =ay o$ a /oti$i%ation!. Dead* either the a%tivity =as never starte &e.g., Nust a$ter a phone reset' or the a%tivity =as terminate , perhaps ue to la%k o$ available memory.
2. -$ the a%tivity ha been running, then sometime later =as kille o$$, on)reate:; =ill be invoke =ith the 6undle $rom onSave.nstanceState:; as a parameter &see belo='. ?. -$ the a%tivity ha been running an you have set up your a%tivity to have i$$erent resour%es base on i$$erent evi%e states &e.g., lan s%ape versus portrait', your a%tivity =ill be re2%reate an on)reate:; =ill be %alle . )ere is =here you initialiMe your user inter$a%e an set up anything that nee s to be one on%e, regar less o$ ho= the a%tivity gets use . >n the other en o$ the li$e%y%le, onDestroy:; may be %alle =hen the a%tivity is shutting o=n, either be%ause the a%tivity %alle finis&:; &=hi%h Q$inishesQ the a%tivity' or be%ause An roi nee s RAM an is %losing the a%tivity prematurely. /ote that onDestroy:; may not get %alle i$ the nee $or RAM is urgent &e.g., in%oming phone %all' an that the a%tivity =ill Nust get shut o=n regar less. )en%e, onDestroy:; is mostly $or %leanly releasing resour%es you obtaine in on)reate:; &i$ any'.
stoppe state, or a$ter a pop2up ialog &e.g., in%oming %all' is %leare . 4his is a great pla%e to re$resh the "- base on things that may have o%%urre sin%e the user last =as looking at your a%tivity. (or e:ample, i$ you are polling a servi%e $or %hanges to some in$ormation &e.g., ne= entries $or a $ee ', onResume:; is a $ine time to both re$resh the %urrent vie= an , i$ appli%able, ki%k o$$ a ba%kgroun threa to up ate the vie= &e.g., via a 3andler'. Conversely, anything that steals your user a=ay $rom your a%tivity O mostly, the a%tivation o$ another a%tivity O =ill 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:%lusive2a%%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%tivity6s pro%ess at any point. )en%e, you shoul not be relying upon re%eiving any $urther events.
*17
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
get its $ormer state ba%k, so it %an restore the a%tivity to the =ay it appeare previously. #aving instan%e state is han le by onSave.nstanceState:;. 4his supplies a 6undle, into =hi%h a%tivities %an pour =hatever ata they nee &e.g., the number sho=ing on the %al%ulator6s isplay'. 4his metho implementation nee s to be spee y, so o not try to o too mu%h $an%y O Nust put your ata in the 6undle an e:it the metho . 4hat instan%e state is provi e to you again in t=o pla%es* ,. -n on)reate:;
2. -n onRestore.nstanceState:; -t is your %hoi%e =hen you =ish to re2apply the state ata to your a%tivity O either %allba%k is a reasonable option.
*19
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
CHAPTER 1*
>sing Preferences
An roi has many i$$erent =ays $or you to store ata $or long2term use by your a%tivity. 4he simplest to use is the pre$eren%es system. An roi allo=s a%tivities an appli%ations to keep pre$eren%es, in the $orm o$ keyUvalue pairs &akin to a Map', that =ill hang aroun bet=een invo%ations o$ an a%tivity. As the name suggests, the primary purpose is $or you to store user2spe%i$ie %on$iguration etails, su%h as the last $ee the user looke at in your $ee rea er, or =hat sort or er to use by e$ault on a list, or =hatever. >$ %ourse, you %an store in the pre$eren%es =hatever you like, so long as it is keye by a String an has a primitive value &boolean, String, 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 =riting.
2. getS&ared1references:; $rom =ithin your Activity &or other appli%ation )ontext', to a%%ess appli%ation2level pre$eren%es
*4Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
>sing Preferences
?. getDefaultS&ared1references:;, on 1referencesManager, to get the share pre$eren%es that =ork in %on%ert =ith An roi 6s overall pre$eren%e $rame=ork 4he $irst t=o take a se%urity mo e parameter O $or no=, pass in @. 4he getS&ared1references:; metho also takes a name o$ a set o$ pre$eren%es O get1references:; e$$e%tively %alls getS&ared1references:; =ith the a%tivity6s %lass name as the pre$eren%e set name. 4he getDefaultS&ared1references:;! metho takes the )ontext $or the pre$eren%es &e.g., your Activity'. All o$ those metho s return an instan%e o$ S&ared1references, =hi%h o$$ers a series o$ getters to a%%ess name pre$eren%es, returning a suitably2type result &e.g., get6oolean:; to return a boolean pre$eren%e'. 4he getters also take a e$ault value, =hi%h is returne i$ there is no pre$eren%e set un er the spe%i$ie key.
4he last one is important O i$ you mo i$y pre$eren%es via the e itor an $ail to commit:; the %hanges, those %hanges =ill evaporate on%e the e itor goes out o$ s%ope. Conversely, sin%e the pre$eren%es obNe%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' =ill have a%%ess to the %hange value imme iately.
*4$
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
>sing Preferences
4he root o$ the pre$eren%e DML is a 1referenceScreen element. We =ill e:plain =hy it is name that later in this %hapterP $or no=, take it on $aith that it is a sensible name. >ne o$ the things you %an have insi e a 1referenceScreen element, not surprisingly, are pre$eren%e e$initions. 4hese are sub%lasses o$ 1reference, su%h as )&ec 6ox1reference or Ringtone1reference, as sho=n above. As one might e:pe%t, these allo= you to %he%k a %he%kbo: or %hoose a ringtone, respe%tively. -n the %ase o$ Ringtone1reference, you have your option o$
*40
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
>sing Preferences
allo=ing users to %hoose the system e$ault ringtone, or to %hoose Qsilen%eQ as a ringtone.
As you %an see, there is not mu%h to see. All you nee to o is %all add1referencesEromResource:; an spe%i$y the DML resour%e %ontaining your pre$eren%es. @ou =ill also nee to a this as an a%tivity to your AndroidManifest.xml $ile*
">xml!version$%?.@%!encoding$%utf-A%>' "manifest!xmlns#android$%&ttp#//sc&emas.android.com/ap /res/android% !!!!pac age$%com.commonsware.android.prefs%' !!!!"application!android#label$%9string/app_name%' !!!!!!!!"activity !!!!!!!!!!!!android#name$%.Simple1refsDemo% !!!!!!!!!!!!android#label$%9string/app_name%' !!!!!!!!!!!!"intent-filter' !!!!!!!!!!!!!!!!"action!android#name$%android.intent.action.MA./%!/' !!!!!!!!!!!!!!!!"category!android#name$%android.intent.category.+A2/)3*R%!/' *41
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
>sing Preferences
An you =ill nee to arrange to invoke the a%tivity, su%h as $rom a menu option, here pulle $rom Simple1refsDemo*
9,verride public!boolean!onCreateOptions'enu:Menu!menu;!8 !!menu.add:Menu./,/*G!*D.-_.DG!Menu./,/*G!%*dit!1refs%; !!!!!!.setIcon:R.drawable.misc; !!!!!!.set#lpha!eticShortcut:[e[;5 !!menu.add:Menu./,/*G!)+,S*_.DG!Menu./,/*G!%)lose%; !!!!!!.setIcon:R.drawable.eject; !!!!!!.set#lpha!eticShortcut:[c[;5 !!return:super.onCreateOptions'enu:menu;;5 < 9,verride public!boolean!onOptionsItemSelected:Menu.tem!item;!8 !!switc&!:item.getItemId:;;!8 !!!!case!*D.-_.D# !!!!!!start#cti ity:new!Intent:t&isG!*dit1references.class;;5 !!!!!!return:true;5 !!!!case!)+,S*_.D# !!!!!!finish:;5 !!!!!!return:true;5 !!< !!return:super.onOptionsItemSelected:item;;5 <
)o=ever, that is all that is nee e , an it really is not that mu%h %o e outsi e o$ the pre$eren%es DML. When you get $or your e$$ort is an An roi 2 supplie pre$eren%e "-*
*44
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
>sing Preferences
4he %he%kbo: %an be ire%tly %he%ke or un%he%ke . 4o %hange the ringtone pre$eren%e, Nust %li%k on the entry in the pre$eren%e list to bring up a sele%tion ialog*
*47
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
>sing Preferences
/ote that there is no e:pli%it QsaveQ or Q%ommitQ button or menu O %hanges are persiste as soon as they are ma e. 4he Simple1refsDemo a%tivity, beyon having the a$orementione menu, also isplays the %urrent pre$eren%es via a -able+ayout*
">xml!version$%?.@%!encoding$%utf-A%>' "-able+ayout !!xmlns#android$%&ttp#//sc&emas.android.com/ap /res/android% !!android#layout_widt&$%fill_parent% !!android#layout_&eig&t$%fill_parent% ' !!"-ableRow' !!!!"-ext7iew !!!!!!!!android#text$%)&ec box#% !!!!!!!!android#paddingRig&t$%Lpx% !!!!/' !!!!"-ext7iew!android#id$%9Bid/c&ec box% !!!!/' !!"/-ableRow' !!"-ableRow' !!!!"-ext7iew !!!!!!!!android#text$%Ringtone#% !!!!!!!!android#paddingRig&t$%Lpx% !!!!/' !!!!"-ext7iew!android#id$%9Bid/ringtone%
*49
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
>sing Preferences
4his means the $iel s =ill be up ate =hen the a%tivity is opene an a$ter the pre$eren%es a%tivity is le$t &e.g., via the ba%k button'*
*7;
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
>sing Preferences
>sing Preferences
Any %hil ren o$ 1referenceScreen go on their o=n s%reen. -$ you nest 1referenceScreens, the parent s%reen isplays the s%reen as a pla%ehol er entry O tapping that entry brings up the %hil s%reen. (or e:ample, $rom the #tru%ture sample proNe%t, here is a pre$eren%e DML $ile that %ontains both 1reference)ategory an neste 1referenceScreen! elements*
"1referenceScreen !!xmlns#android$%&ttp#//sc&emas.android.com/ap /res/android%' !!"1reference)ategory!android#title$%Simple!1references%' !!!!")&ec 6ox1reference !!!!!!android# ey$%9string/c&ec box% !!!!!!android#title$%)&ec box!1reference% !!!!!!android#summary$%)&ec !it!onG!c&ec !it!off% !!!!/' !!!!"Ringtone1reference !!!!!!android# ey$%9string/ringtone% !!!!!!android#title$%Ringtone!1reference% !!!!!!android#s&owDefault$%true% !!!!!!android#s&owSilent$%true% !!!!!!android#summary$%1ing!a!toneG!any!toneG!even!silence% !!!!/' !!"/1reference)ategory' !!"1reference)ategory!android#title$%Detail!Screens%' !!!!"1referenceScreen !!!!!!android# ey$%detail% !!!!!!android#title$%Detail!Screen% !!!!!!android#summary$%Additional!preferences!&eld!in!anot&er!page%' !!!!!!")&ec 6ox1reference !!!!!!!!android# ey$%9string/c&ec boxH% !!!!!!!!android#title$%Anot&er!)&ec box% !!!!!!!!android#summary$%,n.!,ff.!.t!really!doesn[t!matter.% !!!!!!/' !!!!"/1referenceScreen' !!"/1reference)ategory' "/1referenceScreen'
4he result, =hen you use this pre$eren%e DML =ith your 1referenceActivity! implementation, is a %ategoriMe list o$ elements*
*7%
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
>sing Preferences
!igure 0%< The Structured pro2ectAs preference >86 sho)ing categories and a screen placeholder
An , i$ you tap on the Aetail #%reen entry, you are taken to the %hil pre$eren%e s%reen*
!igure 0-< The child preference screen of the Structured pro2ectAs preference >8 *7Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
>sing Preferences
*7$
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
>sing Preferences
!!!!!!android# ey$%9string/list% !!!!!!android#title$%Selection!Dialog% !!!!!!android#summary$%)lic !to!pop!up!a!list!to!c&oose!from% !!!!!!android#entries$%9array/cities% !!!!!!android#entry7alues$%9array/airport_codes% !!!!!!android#dialog-itle$%)&oose!a!1ennsylvania!city%!/' !!"/1reference)ategory' "/1referenceScreen'
With the $iel &*dit-ext1reference', in a ition to the title an summary you put on the pre$eren%e itsel$, you %an also supply the title to use $or the ialog. With the list &+ist1reference', you supply both a ialog title an t=o string2 array resour%es* one $or the isplay names, one $or the values. 4hese nee to be in the same or er O the in e: o$ the %hosen isplay name etermines =hi%h value is store as the pre$eren%e in the S&ared1references. (or e:ample, here are the arrays $or use by the +ist1reference sho=n above*
">xml!version$%?.@%!encoding$%utf-A%>' "resources' !!"string-array!name$%cities%' !!!!"item'1&iladelp&ia"/item' !!!!"item'1ittsburg&"/item' !!!!"item'Allentown/6et&le&em"/item' !!!!"item'*rie"/item' !!!!"item'Reading"/item' !!!!"item'Scranton"/item' !!!!"item'+ancaster"/item' !!!!"item'Altoona"/item' !!!!"item'3arrisburg"/item' !!"/string-array' !!"string-array!name$%airport_codes%' !!!!"item'13+"/item' !!!!"item'1.-"/item' !!!!"item'A6*"/item' !!!!"item'*R."/item' !!!!"item'RD0"/item' !!!!"item'A71"/item' !!!!"item'+/S"/item' !!!!"item'A,,"/item' !!!!"item'MD-"/item' !!"/string-array' "/resources'
When you bring up the pre$eren%e "-, you start =ith another %ategory =ith another pair o$ pre$eren%e entries*
*70
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
>sing Preferences
!igure 0$< The preference screen of the /ialogs pro2ectAs preference >8
4apping the 4e:t Intry Aialog one brings up...a te:t entry ialog O in this %ase, =ith the prior pre$eren%e entry pre2$ille 2in*
*71
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
>sing Preferences
4apping the #ele%tion Aialog one brings up...a sele%tion ialog, sho=ing the isplay names $rom the one array*
*74
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-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 =ill su$$i%e. An roi o$$ers t=o mo els $or a%%essing $iles* one $or $iles pre2pa%kage =ith your appli%ation, an one $or $iles %reate on2 evi%e by your appli%ation.
(ccessing !iles
or you =ill nee to provi e some means o$ up ating the ata. 4he simplest =ay 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 t=o %opies o$ the ata in storage. An alternative is to keep the re$eren%e ata as2is but keep mo i$i%ations in a $ile or atabase, an merge them together =hen 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 =ere elete by the user. -n the Static sample proNe%t, you =ill $in a re=orking o$ the listbo: e:ample $rom earlier, this time using a stati% DML $ile instea o$ a har =ire array in Gava. 4he layout is the same*
">xml!version$%?.@%!encoding$%utf-A%>' "+inear+ayout!xmlns#android$%&ttp#//sc&emas.android.com/ap /res/android% !!android#orientation$%vertical% !!android#layout_widt&$%fill_parent%! !!android#layout_&eig&t$%fill_parent%!' !!"-ext7iew !!!!android#id$%9Bid/selection% !!!!android#layout_widt&$%fill_parent% !!!!android#layout_&eig&t$%wrap_content% !!/' !!"+ist7iew !!!!android#id$%9android#id/list% !!!!android#layout_widt&$%fill_parent%! !!!!android#layout_&eig&t$%fill_parent% !!!!android#drawSelector,n-op$%false% !!/' "/+inear+ayout'
-n a ition to that DML $ile, you also nee an DML $ile =ith the =or s to sho= in the list*
"words' !!"word!value$%lorem%!/' !!"word!value$%ipsum%!/' !!"word!value$%dolor%!/' !!"word!value$%sit%!/' !!"word!value$%amet%!/' !!"word!value$%consectetuer%!/' !!"word!value$%adipiscing%!/' !!"word!value$%elit%!/' !!"word!value$%morbi%!/' !!"word!value$%vel%!/' !!"word!value$%ligula%!/'
*9;
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-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$%augue%!/' !!"word!value$%purus%!/' "/words'
While this DML stru%ture is not e:a%tly a mo el o$ spa%e e$$i%ien%y, it =ill su$$i%e $or a emo. 4he Gava %o e no= must rea in that DML $ile, parse out the =or 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 !!!!!!-oast !!!!!!!!.makeText:t&isG!%*xception#!%Bt.toString:;G!H@@@; !!!!!!!!.show:;5 !!!!< *9*
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
(ccessing !iles
!!!! !!!!setList#dapter:new!ArrayAdapter"String':t&isG !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!android.R.layout.simple_list_item_?G !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!items;;5 !!< !! !!public!void!onListItemClick:+ist7iew!parentG!7iew!vG!int!positionG !!!!!!!!!!!!!!!!!!long!id;!8 !!!!selection.setText:items.get:position;.toString:;;5 !!< <
4he i$$eren%es mostly lie =ithin on)reate:;. We get an .nputStream $or the DML $ile &getResources:;.openRawResource:R.raw.words;', then use the built2 in DML parsing logi% to parse the $ile into a A>M Document, pi%k out the =or elements, then pour the value attributes into an Array+ist $or use by the ArrayAdapter. 4he resulting a%tivity looks the same as be$ore, sin%e the list o$ =or s is the same, Nust relo%ate *
>$ %ourse, there are even easier =ays to have DML $iles available to you as pre2pa%kage $iles O using an DML resour%e. 4hat is %overe in the ne:t
*9%
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
(ccessing !iles
%hapter. )o=ever, =hile this e:ample use DML, the $ile %oul Nust as easily have been a simple one2=or 2per2line list, or in some other $ormat not han le natively by the An roi resour%e system.
3eadinA An WritinA
Rea ing an =riting your o=n, appli%ation2spe%i$i% ata $iles is nearly i enti%al to =hat you might o in a esktop Gava appli%ation. 4he key is to use openEile.nput:; an openEile,utput:; on your Activity or other )ontext! to get an .nputStream an ,utputStream, respe%tively. (rom that point $or=ar , it is not mu%h i$$erent than regular Gava -U> logi%*
Wrap those streams as nee e , su%h as using an .nputStreamReader or ,utputStreamCriter $or te:t2base -U> Rea or =rite the ata "se close:; to release the stream =hen one
Relative paths &i.e., those =ithout lea ing slashes' are lo%al to the appli%ation. -$ t=o appli%ations both try rea ing a notes.txt $ile via openEile.nput:;, they =ill ea%h a%%ess their o=n e ition o$ the $ile. -$ you nee to have one $ile a%%essible $rom many pla%es, you probably =ant to %reate a %ontent provi er, as =ill be es%ribe an up%oming %hapter. .elo= you =ill see the layout $or the =orl 6s most trivial te:t e itor, pulle $rom the ReadCrite sample appli%ation*
">xml!version$%?.@%!encoding$%utf-A%>' "+inear+ayout!xmlns#android$%&ttp#//sc&emas.android.com/ap /res/android% !!android#layout_widt&$%fill_parent%! !!android#layout_&eig&t$%fill_parent% !!android#orientation$%vertical%' !!"6utton!android#id$%9Bid/close% !!!!android#layout_widt&$%wrap_content%! !!!!android#layout_&eig&t$%wrap_content% !!!!android#text$%)lose%!/' !!"*dit-ext !!!!android#id$%9Bid/editor% !!!!android#layout_widt&$%fill_parent%! !!!!android#layout_&eig&t$%fill_parent% !!!!android#single+ine$%false%
*9Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
(ccessing !iles
!!!!/' "/+inear+ayout'
All =e have here is a large te:t2e iting =i get, =ith a QCloseQ button above it. 4he Gava is only slightly more %ompli%ate *
pac age!com.commonsware.android.files5 import!android.app.Activity5 import!android.os.6undle5 import!android.view.7iew5 import!android.widget.6utton5 import!android.widget.*dit-ext5 import!android.widget.-oast5 import!java.io.6ufferedReader5 import!java.io..nputStream5 import!java.io..nputStreamReader5 import!java.io..nputStream5 import!java.io.,utputStream5 import!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!:inX$null;!8 !!!!!!!!6ufferedReader!reader$new!Buffered$eader:new!InputStream$eader:in;;5 !!!!!!!!String!str5 !!!!!!!!String6uffer!buf$new!StringBuffer:;5 !!!!!!!!
*9$
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
(ccessing !iles
!!!!!!!!w&ile!::str!$!reader.readLine:;;!X$!null;!8 !!!!!!!!!!buf.append:strB%4n%;5 !!!!!!!!< !!!!!!!! !!!!!!!!in.close:;5 !!!!!!!!editor.setText:buf.toString:;;5 !!!!!!< !!!!< !!!!catc&!:java.io.Eile/otEound*xception!e;!8 !!!!!!//!t&at[s!,MG!we!probably!&aven[t!created!it!yet !!!!< !!!!catc&!:-&rowable!t;!8 !!!!!!-oast !!!!!!!!.makeText:t&isG!%*xception#!%Bt.toString:;G!H@@@; !!!!!!!!.show:;5 !!!!< !!< !! !!public!void!on(ause:;!8 !!!!super.on(ause:;5 !!!! !!!!try!8 !!!!!!,utputStreamCriter!out$ !!!!!!!!!!new!OutputStream&riter:open"ileOutput:%notes.txt%G!@;;5 !!!!!! !!!!!!out.write:editor.getText:;.toString:;;5 !!!!!!out.close:;5!!!! !!!!< !!!!catc&!:-&rowable!t;!8
(irst, =e =ire up the button to %lose out our a%tivity =hen %li%ke by using set,n)lic +istener:; to invoke finis&:; on the a%tivity. /e:t, =e hook into onResume:;, so =e get %ontrol =hen our e itor is %oming ba%k to li$e, $rom a $resh laun%h or a$ter having been $roMen. We use openEile.nput:; to rea in notes.txt an pour the %ontents into the te:t e itor. -$ the $ile is not $oun , =e assume this is the $irst time the a%tivity =as run &or the $ile =as elete by other means', an =e Nust leave the e itor empty. (inally, =e hook into on1ause:;, so =e 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, =e use openEile,utput:; to open notes.txt, into =hi%h =e pour the %ontents o$ the te:t e itor.
*90
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
(ccessing !iles
4he net result is that =e have a persistent notepa * =hatever is type in =ill remain until elete , surviving our a%tivity being %lose , the phone being turne o$$, or similar situations. >$ %ourse, it oesn6t look like mu%h*
!igure 09< The same application6 after entering some text *91
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
CHAPTER 1/
Resour%es are stati% bits o$ in$ormation hel outsi e the Gava sour%e %o e. @ou have seen one type o$ resour%e O the layout O $re;uently in the e:amples in this book. 4here are many other types o$ resour%e, su%h as images an strings, that you %an take a vantage o$ in your An roi appli%ations.
Animations &res/anim/', esigne $or short %lips as part o$ a user inter$a%e, su%h as an animation suggesting the turning o$ a page =hen a button is %li%ke -mages &res/drawable', $or putting stati% i%ons or other pi%tures in a user inter$a%e
*94
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
#trings, %olors, arrays, an imensions &res/values/', to both give these sorts o$ %onstants symboli% names an to keep them separate $rom the rest o$ the %o e &e.g., $or internationaliMation an lo%aliMation' DML &res/xml/', $or stati% DML $iles %ontaining your o=n ata an stru%ture
String Theory
Eeeping 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 =ith internationaliMation &-,8/' an lo%aliMation &L,0/', %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:ternaliMe strings, along =ith Qstring $ormatsQ, =here the string has pla%ehol ers $or ynami%ally2inserte in$ormation. >n top o$ that, An roi supports simple te:t $ormatting, %alle Qstyle te:tQ, so you %an make your =or s be bol or itali% intermingle =ith normal te:t.
Pl in Strin!s
7enerally speaking, all you nee to o is have an DML $ile in the res/values! ire%tory &typi%ally name res/values/strings.xml', =ith a resources root element, an one %hil string element $or ea%h string you =ish to en%o e as a resour%e. 4he string element takes a name attribute, =hi%h is the uni;ue name $or this string, an a single te:t element %ontaining the te:t o$ the string*
"resources' !!"string!name$%Juic %'-&e!Juic !brown!fox..."/string' !!"string!name$%laug&s%'3e!w&o!laug&s!last..."/string' "/resources'
4he only tri%ky part is i$ the string value %ontains a ;uote &%' or an apostrophe &['. -n those %ases, you =ill =ant to es%ape those values, by
*97
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
pre%e ing them =ith a ba%kslash &e.g., -&ese!are!t&e!times!t&at!try!men4[s! souls'. >r, i$ it is Nust an apostrophe, you %oul en%lose the value in ;uotes &e.g., %-&ese!are!t&e!times!t&at!try!men[s!souls.%'. @ou %an then re$eren%e this string $rom a layout $ile &as 9string/..., =here the ellipsis is the uni;ue name O e.g., 9string/laug&s'. >r you %an get the string $rom your Gava %o e by %alling getString:; =ith the resour%e -A o$ the string resour%e, that being the uni;ue name pre$i:e =ith R.string. &e.g., getString:R.string.Juic ;'.
Strin! :orm ts
As =ith other implementations o$ the Gava language, An roi 6s 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*
String!strEormat$getString:R.string.my_name;5 String!strResult$String.format:strEormatG!%-im%;5 ::-ext7iew;findViewById:R.layout.some_label;; !!.setText:strResult;5
Styled Te.t
-$ you =ant really ri%h te:t, you shoul have ra= resour%es %ontaining )4ML, then pour those into a WebEit =i get. )o=ever, $or light )4ML $ormatting, using "b', "i', an "u', you %an Nust use a string resour%e*
"resources' !!"string!name$%b%'-&is!&as!"b'bold"/b'!in!it."/string' !!"string!name$%i%'C&ereas!t&is!&as!"i'italics"/i'X"/string' "/resources'
@ou %an a%%ess these the same as =ith plain strings, =ith the e:%eption that the result o$ the getString:; %all is really a Spanned*
::-ext7iew;findViewById:R.layout.anot&er_label;; !!!!!!!!!!!!.setText:getString:R.string.laug&s;;5
*99
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
Styled :orm ts
Where style te:t gets tri%ky is =ith style string $ormats, as String.format:;! =orks on String obNe%ts, not Spanned obNe%ts =ith $ormatting instru%tions. -$ you really =ant to have style string $ormats, here is the =orkaroun * ,. Intity2es%ape the angle bra%kets in the string resour%e &e.g., t&is!is! Zlt5bZgt5\?]sZlt5/bZgt5'
2. Retrieve the string resour%e as normal, though it =ill not be style at this point &e.g., getString:R.string.fun y_format;' ?. 7enerate the $ormat results, being sure to es%ape any string values you substitute in, in %ase they %ontain angle bra%kets or ampersan s
String.format:getString:R.string.fun y_format;G !!!!!!!!!!!!!!-ext2tils.html*ncode:str/ame;;5
some-ext7iew.setText:3tml !!!!!!!!!!!!!!!!!!!!!.from,tml:resultEromStringEormat;;5
4o see this in a%tion, let6s look at the Strings emo. )ere is the layout $ile*
">xml!version$%?.@%!encoding$%utf-A%>' "+inear+ayout!xmlns#android$%&ttp#//sc&emas.android.com/ap /res/android% !!android#orientation$%vertical% !!android#layout_widt&$%fill_parent% !!android#layout_&eig&t$%fill_parent% !!' !!"+inear+ayout!xmlns#android$%&ttp#//sc&emas.android.com/ap /res/android% !!!!android#orientation$%&ori(ontal% !!!!android#layout_widt&$%fill_parent% !!!!android#layout_&eig&t$%wrap_content% !!!!' !!!!"6utton!android#id$%9Bid/format% !!!!!!android#layout_widt&$%wrap_content%! !!!!!!android#layout_&eig&t$%wrap_content% !!!!!!android#text$%9string/btn_name% !!!!!!/' !!!!"*dit-ext!android#id$%9Bid/name% !!!!!!android#layout_widt&$%fill_parent%! !!!!!!android#layout_&eig&t$%wrap_content%! !!!!!!/' !!"/+inear+ayout' !!"-ext7iew!android#id$%9Bid/result% %;;
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
As you %an see, it is Nust a button, a $iel , an a label. 4he 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 =ith a $ormatte message %ontaining their name. 4he 6utton in the layout $ile re$eren%es a string resour%e &9string/btn_name', so =e nee a string resour%e $ile &res/values/strings.xml'*
">xml!version$%?.@%!encoding$%utf-A%>' "resources' !!"string!name$%app_name%'StringsDemo"/string' !!"string!name$%btn_name%'/ame#"/string' !!"string!name$%fun y_format%'My!name!is!Zlt5bZgt5\?]sZlt5/bZgt5"/string' "/resources'
4he app_name resour%e is automati%ally %reate by the activity)reator s%ript. 4he btn_name string is the %aption o$ the 6utton, =hile our style string $ormat is in fun y_format. (inally, to hook all this together, =e nee a pin%h o$ Gava*
pac age!com.commonsware.android.resources5 import!android.app.Activity5 import!android.os.6undle5 import!android.text.-ext2tils5 import!android.text.3tml5 import!android.view.7iew5 import!android.widget.6utton5 import!android.widget.*dit-ext5 import!android.widget.-ext7iew5 public!class!StringsDemo!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-NC-SA 3.0 License Edition
!!!!result$:-ext7iew;findViewById:R.id.result;5 !!!! !!!!6utton!btn$:6utton;findViewById:R.id.format;5 !!!! !!!!btn.setOnClickListener:new!6utton.OnClickListener:;!8 !!!!!!public!void!onClick:7iew!v;!8 !!!!!!!!apply"ormat:;5 !!!!!!< !!!!<;5 !!< !! !!private!void!apply"ormat:;!8 !!!!String!format$getString:R.string.fun y_format;5 !!!!String!simpleResult$String.format:formatG !!!!!!!!!!!!!!!!!!!!!-ext2tils.html*ncode:name.getText:;.toString:;;;5 !!!!result.setText:3tml.from,tml:simpleResult;;5 !!< <
4he string resour%e manipulation %an be $oun in applyEormat:;, =hi%h is %alle =hen the button is %li%ke . (irst, =e get our $ormat via getString:; O something =e %oul have one at on)reate:; time $or e$$i%ien%y. /e:t, =e $ormat the value in the $iel using this $ormat, getting a String ba%k, sin%e the string resour%e is in entity2en%o e )4ML. /ote the use o$ -ext2tils.&tml*ncode:; to entity2en%o e the entere name, in %ase somebo y e%i es to use an ampersan or something. (inally, =e %onvert the simple )4ML into a style te:t obNe%t via 3tml.from3tml:; an up ate our label. When the a%tivity is $irst laun%he , =e have an empty label*
%;%
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
!igure 1*< The same application6 after filling in some heroic figureAs name
%;Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
=here com.example.app is the name o$ the Gava 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'
2. android.resource#//com.example.app/raw/..., =here com.example.app! is the name o$ the Gava pa%kage use by your appli%ation in AndroidManifest.xml an ... is the te:tual name o$ the ra= resour%e &e.g., foo $or res/drawable/foo.png' /ote that An roi ships =ith some image resour%es built in. 4hose are a resse in Gava =ith an android.R.drawable pre$i: to istinguish them $rom appli%ation2spe%i$i% resour%es &e.g., android.R.drawable.picture_frame'. #o, let6s up ate the previous e:ample to use an i%on $or the button instea o$ the string resour%e. 4his %an be $oun as .mages. (irst, =e slightly a Nust the layout $ile, using an .mage6utton an re$eren%ing a ra=able name 9drawable/icon*
">xml!version$%?.@%!encoding$%utf-A%>' "+inear+ayout!xmlns#android$%&ttp#//sc&emas.android.com/ap /res/android%
%;$
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
!!android#orientation$%vertical% !!android#layout_widt&$%fill_parent% !!android#layout_&eig&t$%fill_parent% !!' !!"+inear+ayout!xmlns#android$%&ttp#//sc&emas.android.com/ap /res/android% !!!!android#orientation$%&ori(ontal% !!!!android#layout_widt&$%fill_parent% !!!!android#layout_&eig&t$%wrap_content% !!!!' !!!!".mage6utton!android#id$%9Bid/format% !!!!!!android#layout_widt&$%wrap_content%! !!!!!!android#layout_&eig&t$%wrap_content% !!!!!!android#src$%9drawable/icon% !!!!!!/' !!!!"*dit-ext!android#id$%9Bid/name% !!!!!!android#layout_widt&$%fill_parent%! !!!!!!android#layout_&eig&t$%wrap_content%! !!!!!!/' !!"/+inear+ayout' !!"-ext7iew!android#id$%9Bid/result% !!!!android#layout_widt&$%fill_parent% !!!!android#layout_&eig&t$%wrap_content% !!!!/' "/+inear+ayout'
/e:t, =e nee to put an image $ile in res/drawable =ith a base name o$ i%on. -n this %ase, =e use a ?2:?2 !/7 $ile $rom the /uvola i%on set. (inally, =e t=i le the Gava sour%e, repla%ing our 6utton =ith an .mage6utton*
pac age!com.commonsware.android.resources5 import!android.app.Activity5 import!android.os.6undle5 import!android.text.-ext2tils5 import!android.text.3tml5 import!android.view.7iew5 import!android.widget.6utton5 import!android.widget..mage6utton5 import!android.widget.*dit-ext5 import!android.widget.-ext7iew5 public!class!.magesDemo!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
%;0
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
!!!! !!!!.mage6utton!btn$:.mage6utton;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 !!!!String!format$getString:R.string.fun y_format;5 !!!!String!simpleResult$String.format:formatG !!!!!!!!!!!!!!!!!!!!-ext2tils.html*ncode:name.getText:;.toString:;;;5 !!!!result.setText:3tml.from,tml:simpleResult;;5 !!< <
%;1
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
import!org.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 !!!!selection$:-ext7iew;findViewById:R.id.selection;5 !!!! !!!!try!8 !!!!!!Uml1ull1arser!xpp$get$esources:;.get-ml:R.xml.words;5 !!!!!! !!!!!!w&ile!:xpp.get* entType:;X$Uml1ull1arser.*/D_D,)2M*/-;!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 !!!!!!-oast !!!!!!!!.makeText:t&isG!%ReJuest!failed#!%Bt.toString:;G!O@@@; !!!!!!!!.show:;5 !!!!< !!!! !!!!setList#dapter:new!ArrayAdapter"String':t&isG !!!!!!!!!!!!!!!!!!!!!!!!!!!android.R.layout.simple_list_item_?G !!!!!!!!!!!!!!!!!!!!!!!!!!!items;;5 !!< !! !!public!void!onListItemClick:+ist7iew!parentG!7iew!vG!int!positionG !!!!!!!!!!!!!!!!!!long!id;!8 !!!!selection.setText:items.get:position;.toString:;;5 !!< <
/o=, insi e our try...catc& blo%k, =e 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.get/ame:;.eJuals:%word%;', then =e get the one2 an 2only attribute an pop that into our list o$ items $or the sele%tion =i get. #in%e =e6re in %omplete %ontrol over the DML $ile, it is sa$e enough to assume there is e:a%tly one attribute. .ut, i$ you =ere not as %om$ortable that the DML is properly e$ine , you might %onsi er %he%king the attribute %ount &getAttribute)ount:;' an the name o$ the attribute
%;7
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
&getAttribute/ame:;' be$ore blin ly assuming the @2in e: attribute is =hat you think it is. 4he result looks the same as be$ore, albeit =ith a i$$erent name in the title bar*
+iscellaneous Falues
-n the res/values/ ire%tory, you %an pla%e one &or more' DML $iles es%ribing simple resour%es* imensions, %olors, an arrays. We have alrea y seen uses o$ imensions an %olors in previous e:amples, =here they =ere passe as simple strings &e.g., %?@px%' as parameters to %alls. @ou %an, o$ %ourse, set these up as Gava stati% $inal obNe%ts an use their symboli% names...but this only =orks insi e Gava sour%e, not in layout DML $iles. .y putting these values in resour%e DML $iles, you %an re$eren%e them $rom both Gava an layouts, plus have them %entrally lo%ate $or easy e iting. Resour%e DML $iles have a root element o$ resourcesP everything else is a %hil o$ that root.
%;9
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
Dimensions
Aimensions are use in several pla%es in An roi to es%ribe istan%es, su%h a =i get6s 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*
in
on the
$or points, =hi%h in publishing terms is ,U12n o$ an in%h &again, base on the a%tual physi%al siMe o$ the s%reen' an sp $or evi%e2in epen ent pi:els an s%ale2in epen ent pi:els O one pi:el e;uals one p $or a ,30 pi resolution s%reen, =ith the ratio s%aling base on the a%tual s%reen pi:el ensity &s%ale2 in epen ent pi:els also take into a%%ount the user6s pre$erre $ont siMe'
4o en%o e a imension as a resour%e, a a dimen element, =ith 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/..., =here 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 Gava, you re$eren%e imension resour%es by the uni;ue name pre$i:e =ith R.dimen. &e.g., Resources.getDimen:R.dimen.t∈'.
Colors
Colors in An roi are he:a e%imal R7. values, also optionally spe%i$ying an alpha %hannel. @ou have your %hoi%e o$ single2%hara%ter he: values or ouble2%hara%ter he: values, leaving you =ith $our styles*
DR06
%*;
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
4hese =ork similarly to their %ounterparts in Cas%a ing #tyle #heets &C##'. @ou %an, o$ %ourse, put these R7. values as string literals in Gava sour%e or layout resour%es. -$ you =ish to turn them into resour%es, though, all you nee to o is a color elements to the resour%es $ile, =ith a name attribute $or your uni;ue name $or this %olor, an a single te:t element %ontaining the R7. value itsel$*
"resources' !!"color!name$%yellow_orange%'DEEDLLL"/color' !!"color!name$%forest_green%'D@@LL@@"/color' !!"color!name$%burnt_umber%'DAAIIHO"/color' "/resources'
-n a layout, you %an re$eren%e %olors as 9color/..., repla%ing the ellipsis =ith your uni;ue name $or the %olor &e.g., burnt_umber'. -n Gava, you re$eren%e %olor resour%es by the uni;ue name pre$i:e =ith R.color. &e.g., Resources.get)olor:R.dimen.forest_green;'.
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 string-array element per array, =ith a name! attribute $or the uni;ue name you are giving the array. 4hen, a one or more %hil item elements, ea%h o$ =hi%h having a single te:t element =ith the value $or that entry in the array*
"resources' !!"array!name$%&onorifics%' !!!!"item'Dr."/item' !!!!"item'Mr."/item' !!!!"item'Mrs."/item'
%**
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
(rom your Gava %o e, you %an then use Resources.getStringArray:; to get a StringPQ o$ the items in the list. 4he parameter to getStringArray:; is your uni;ue name $or the array, pre$i:e =ith R.array. &e.g., Resources.getStringArray:R.array.&onorifics;'.
#creen orientation* is the s%reen in a portrait orientationC Lan s%apeC -s the s%reen s;uare an , there$ore, oes not really have an orientationC #creen siBe* ho= many pi:els oes the s%reen have, so you %an siMe your resour%es a%%or ingly &e.g., large versus small i%ons'C Touchscreen* oes the evi%e have a tou%hs%reenC -$ so, is the tou%hs%reen set up to be use =ith a stylus or a $ingerC 6ey5oard* =hat keyboar oes the user have &HWIR4@, numeri%, neither', either no= or as an optionC Ather input* oes the evi%e have some other $orm o$ input, like a ire%tional pa or %li%k2=heelC
4he =ay An roi presently han les this is by having multiple resour%e ire%tories, =ith the %riteria $or ea%h embe e in their names.
%*%
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
#uppose, $or e:ample, you =ant to support strings in both Inglish an #panish. /ormally, $or a single2language setup, you =oul put your strings in a $ile name res/values/strings.xml. 4o support both Inglish an #panish, you =oul %reate t=o $ol ers, res/values-en an res/values-es, =here the value a$ter the hyphen is the -#> 3?02, t=o2letter %o e $or the language you =ant. @our Inglish2language strings =oul go in res/valuesen/strings.xml an the #panish ones in res/values-es/strings.xml. An roi =ill %hoose the proper $ile base on the user6s evi%e settings. #eems easy, rightC Where things start to get %ompli%ate is =hen you nee to use multiple isparate %riteria $or your resour%es. 4his may %ome most $re;uently =ith layouts, as you might =ant 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 $inger2input versus other types o$ input &keyboar , stylus'. 4his =ill allo= you to make the best use o$ the available s%reen Qreal estateQ, =ithout 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*
4he %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. 4he An roi o%umentation outlines the spe%i$i% or er in =hi%h these options %an appear. (or the purposes o$ this e:ample, s%reen orientation must pre%e e tou%hs%reen type, =hi%h must pre%e e s%reen siMe. 4here %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 O ea%h =ill re;uire its o=n name res/layout... $ol er. >ptions are %ase sensitive
#o, $or the s%enario es%ribe above, in theory, =e =oul nee the $ollo=ing ire%tories*
%*Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
res/layout-sJuare-notouc&
res/layout-land-notouc&-NO@xOA@ res/layout-stylus res/layout-sJuare-stylus res/layout-land-stylus-NO@xOA@
/ote that $or some o$ these, the a%tual layout $iles =ill be i enti%al. (or e:ample, =e only %are about $inger layouts being i$$erent than the other t=o, but sin%e =e %annot %ombine those t=o, =e =oul theoreti%ally have to have separate ire%tories =ith i enti%al %ontents $or notouc& an stylus. Also note that there is nothing preventing you $rom also having a ire%tory =ith 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 O having a e$ault layout might make the i$$eren%e bet=een your appli%ation =orking or $ailing on that ne= evi%e. /o=, =e %an Q%heatQ a bit, by e%o ing the rules An roi uses $or etermining =hi%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 siMe o$ the evi%e is ?20:2<0, the NO@xOA@! ire%tories =oul be roppe as %an i ates, sin%e they spe%i$i%ally %all $or some other siMe.
2. /e:t, An roi %ounts the number o$ mat%hes $or ea%h $ol er, an only pays attention to those =ith the most mat%hes.
%*$
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
?. (inally, An roi goes in the or er o$ pre%e en%e o$ the options O in other =or s, it goes $rom le$t to right in the ire%tory name. #o =e %oul skate by =ith only the $ollo=ing %on$igurations*
res/layout-land-finger-NO@xOA@ res/layout-land-NO@xOA@ res/layout-finger res/layout
-$ the evi%e is in portrait or s;uare mo e, or oes not have a 3<0:<80 s%reen siMe, the $irst t=o %an i ates =ill be skippe , an the layout =ill be %hosen base on =hether the evi%e supports $inger input or not. >ther=ise, one o$ the t=o lan s%ape 3<0:<80 layouts =ill be %hosen, as they =oul be a QstrongerQ mat%h than the others, =ith the $inal etermination being on =hether the evi%e supports $inger input or not.
%*0
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
CHAPTER 12
#HLite is a very popular embe e atabase, as it %ombines a %lean #HL inter$a%e =ith 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, 7oogle, #un, #ymbian' an open sour%e proNe%ts &MoMilla, !)!, !ython' all ship pro u%ts =ith #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$or=ar to use $or people =ith e:perien%e in other #HL2 base atabases. )o=ever, its native A!- is not GA.C, an GA.C might be too mu%h overhea $or a memory2limite evi%e like a phone, any=ay. )en%e, An roi programmers have a i$$erent A!- to learn O the goo ne=s being is that it is not that i$$i%ult. 4his %hapter =ill %over the basi%s o$ #HLite use in the %onte:t o$ =orking on An roi . -t by no means is a thorough %overage o$ #HLite as a =hole. -$ you =ant to learn more about #HLite an ho= to use it in other environment than An roi , a $ine book is 4he Ae$initive 7ui e to #HLite by Mi%hael >=ens. A%tivities =ill 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 =ill $in a $ull e:ample
%*4
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
o$ a %ontent provi er that a%%esses a atabase in the .uil ing a Content !rovi er %hapter.
#HLite are meant to solve i$$erent problems, an that you =ill not be seeing a $ull %opy o$ >ra%le on a phone any time real soon, in all likelihoo .
4he %onstru%tor, %haining up=ar to the ST+ite,pen3elper! %onstru%tor. 4his takes the )ontext &e.g., an Activity', the name o$ the atabase, an optional %ursor $a%tory &typi%ally, Nust pass null', an an integer representing the version o$ the atabase s%hema you are using.
on)reate:;,
=hi%h passes you a ST+iteDatabase obNe%t that you nee to populate =ith tables an initial ata, as appropriate. =hi%h passes you a ST+iteDatabase obNe%t an the ol an ne= version numbers, so you %an $igure out ho= best to %onvert the atabase $rom the ol s%hema to the ne= one. 4he simplest, albeit least $rien ly, approa%h is to simply rop the ol tables an %reate ne= ones. 4his is %overe in greater etail in the %hapter on %reating a %ontent provi er.
on2pgrade:;,
4he rest o$ this %hapter =ill is%uss ho= you a%tually %reate tables, insert ata, rop tables, et%., an =ill sho= sample %o e $rom a ST+ite,pen3elper! sub%lass. 4o use your ST+ite,pen3elper sub%lass, %reate an instan%e an ask it to getReadableDatabase:; or getCriteableDatabase:;, epen ing upon =hether or not you =ill be %hanging its %ontents*
%*9
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
db$:new!Data!ase,elper:getContext:;;;.get&rita!leData!ase:;5 return!:db!$$!null;!>!false!#!true5
4his =ill return a ST+iteDatabase instan%e, =hi%h you %an then use to ;uery the atabase or mo i$y its ata. When you are one =ith the atabase &e.g., your a%tivity is being %lose ', simply %all close:; on the ST+iteDatabase to release your %onne%tion.
(or %reating your tables an in e:es, you =ill nee to %all execST+:; on your provi ing the AAL statement you =ish to apply against the atabase. .arring a atabase error, this metho returns nothing.
4his =ill %reate a table, name constants, =ith a primary key %olumn name that is an auto2in%remente integer &i.e., #HLite =ill assign the value $or you =hen you insert ro=s', plus t=o ata %olumns* title &te:t' an value &a $loat, or QrealQ in #HLite terms'. #HLite =ill 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.
_id
Most likely, you =ill %reate tables an in e:es =hen you $irst %reate the atabase, or possibly =hen the atabase nee s upgra ing to a%%ommo ate a ne= 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, Nust use execST+:;! to invoke DR,1!./D*U an DR,1!-A6+* statements as nee e .
%%;
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
+akinA /ata
7iven that you have a atabase an one or more tables, you probably =ant to put some ata in them an su%h. @ou have t=o maNor approa%hes $or oing this. @ou %an al=ays use execST+:;, Nust like you i $or %reating the tables. 4he execST+:; metho =orks $or any #HL that oes not return results, so it %an han le ./S*R-, 21DA-*, D*+*-*, et%. Nust $ine. #o, $or e:ample*
db.execS/L:%./S*R-!./-,!widgets!:nameG!inventory;%B !!!!!!!!!!!!%7A+2*S!:[Sproc et[G!L;%;5
@our alternative is to use the insert:;, update:;, an delete:; metho s on the ST+iteDatabase obNe%t. 4hese are Qbuil erQ sorts o$ metho s, in that the break o=n the #HL statements into is%rete %hunks, then take those %hunks as parameters. 4hese metho s make use o$ )ontent7alues obNe%ts, =hi%h implement a Map2 es;ue inter$a%e, albeit one that has a itional metho s $or =orking =ith #HLite types. (or e:ample, in a ition to get:; to retrieve a value by its key, you have getAs.nteger:;, getAsString:;, an so $orth. 4he insert:; metho takes the name o$ the table, the name o$ one %olumn as the Qnull %olumn ha%kQ, an a )ontent7alues =ith the initial values you =ant put into this ro=. 4he Qnull %olumn ha%kQ is $or the %ase =here the )ontent7alues instan%e is empty O the %olumn name as the Qnull %olumn ha%kQ =ill be e:pli%itly assigne the value /2++ in the #HL ./S*R- statement generate by insert:;.
)ontent7alues!cv$new!ContentValues:;5 cv.put:)onstants.-.-+*G!%0ravityG!Deat&!Star!.%;5 cv.put:)onstants.7A+2*G!SensorManager.0RA7.-F_D*A-3_S-AR_.;5 db.insert:%constants%G!get%ullColumn,ack:;G!cv;5
4he update:; metho takes the name o$ the table, a )ontent7alues! representing the %olumns an repla%ement values to use, an optional C3*R*!
%%*
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
%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 =ith $i:e values, versus ones %ompute base on other in$ormation, you may nee to use execST+:; to a%%omplish some en s. 4he C3*R* %lause an parameter list =orks akin to the positional #HL parameters you may be use to $rom other #HL A!-s. (or e:ample*
//!replacements!is!a!)ontent7alues!instance StringPQ!parms$new!StringPQ!8%snic lefrit(%<5 db.update:%widgets%G!replacementsG!%name$>%G!parms;5
4he delete:; metho =orks akin to update:;, taking the name o$ the table, the optional C3*R* %lause, an the %orrespon ing parameters to $ill into the C3*R* %lause.
2. @ou %an use Juery:; to buil up a ;uery $rom its %omponent parts Con$oun ing matters $urther is the ST+iteTuery6uilder %lass an the issue o$ %ursors an %ursor $a%tories. Let6s take all o$ this one pie%e at a time.
R # ;ueries
4he simplest solution, at least in terms o$ the A!-, is rawTuery:;. #imply %all it =ith your #HL S*+*)- statement. 4he S*+*)- statement %an in%lu e positional parametersP the array o$ these $orms your se%on parameter to rawTuery:;. #o, =e =in up =ith*
)ursor!c$db.raw/uery:%S*+*)-!name!ER,M!sJlite_master!C3*R*!type$[table[!A/D! name$[constants[%G!null;5
%%%
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
-n this e:ample, =e a%tually ;uery a #HLite system table & sJlite_master' to see i$ our %onstants table alrea y e:ists. 4he return value is a )ursor, =hi%h %ontains metho s $or iterating over results &see belo='. -$ your ;ueries are pretty mu%h Qbake intoQ your appli%ation, this is a very straight$or=ar =ay to use them. )o=ever, it gets %ompli%ate i$ parts o$ the ;uery are ynami%, beyon =hat positional parameters %an really han le. (or e:ample, i$ the set o$ %olumns you nee to retrieve is not kno=n at %ompile time, puttering aroun %on%atenating %olumn names into a %omma2 elimite list %an be annoying...=hi%h is =here Juery:; %omes in.
Re!ul r ;ueries
4he Juery:; metho takes the is%rete pie%es o$ a #ILIC4 statement an buil s the ;uery $rom them. 4he pie%es, in or er that they appear as parameters to Juery:;, are*
4he name o$ the table to ;uery against 4he list o$ %olumns to retrieve 4he C3*R* %lause, optionally in%lu ing positional parameters 4he list o$ values to substitute in $or those positional parameters 4he 0R,21!6F %lause, i$ any 4he ,RD*R!6F %lause, i$ any
4hese %an be null =hen they are not nee e &e:%ept the table name, o$ %ourse'. #o, our previous snippet %onverts into*
StringPQ!columns$8%.D%G!%inventory%<5 StringPQ!parms$8%snic lefrit(%<5 )ursor!result$db..uery:%widgets%G!columnsG!%name$>%G !!!!!!!!!!!!!!!!!!!!!!!parmsG!nullG!nullG!null;5
%%Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
Content provi ers are e:plaine in greater etail later in the book, so some o$ this you =ill have to take on $aith until then. )ere, =e see*
A ST+iteTuery6uilder is %onstru%te
%%$
-t is tol the table to use $or the ;uery &set-ables:get-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 ro= 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 preset values =ith those supplie on the %all to Juery:; &Jb.Juery:dbG!projectionG! selectionG!selectionArgsG!nullG!nullG!order6y;'
-nstea o$ having the ST+iteTuery6uilder e:e%ute the ;uery ire%tly, =e %oul have %alle buildTuery:; to have it generate an return the #HL S*+*)-! statement =e nee e , =hi%h =e %oul then e:e%ute ourselves.
+sin! Cursors
/o matter ho= you e:e%ute the ;uery, you get a )ursor ba%k. 4his 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 ho= many ro=s are in the result set via count:; -terate over the ro=s via first:;, next:;, an isAfter+ast:; (in out the names o$ the %olumns via get)olumn/ames:;, %onvert those into %olumn numbers via get)olumn.ndex:;, an get values $or the %urrent ro= $or a given %olumn via metho s like getString:;, get.nt:;, et%. Re2e:e%ute the ;uery that %reate the %ursor via reJuery:; Release the %ursor6s resour%es via close:;
(or e:ample, here =e iterate over the =i gets table entries $rom the previous snippets*
)ursor!result$ !!db.raw/uery:%S*+*)-!.DG!nameG!inventory!ER,M!widgets%;5 w&ile!:Xresult.is#fterLast:;;!8 int!id$result.getInt:@;5
%%0
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
%%1
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
)ere your.app.pac age is the Gava 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:;. /ote, ho=ever, that the An roi 0.0 #AE appears to be missing the sJliteI! %omman . 4he sJliteI program =orks, an i$ you are use to poking aroun your tables using a %onsole inter$a%e, you are =el%ome to use it. -$ you pre$er something a little bit $rien lier, you %an al=ays %opy the #HLite atabase o$$ the evi%e onto your evelopment ma%hine, then use a #HLite2a=are %lient program to putter aroun . /ote, though, that you are =orking o$$ a %opy o$ the atabaseP i$ you =ant your %hanges to go ba%k to the evi%e, you =ill nee to trans$er the atabase ba%k over. 4o get the atabase o$$ the evi%e, you %an use the adb!pull %omman &or the e;uivalent in your -AI', =hi%h takes the path to the on2 evi%e atabase an the lo%al estination as parameters. 4o store a mo i$ie atabase on the evi%e, use adb!pus&, =hi%h takes the lo%al path to the atabase an the on2 evi%e estination as parameters. >ne o$ the most2a%%essible #HLite %lients is the #HLite Manager e:tension $or (ire$o:, as it =orks a%ross all plat$orms.
%%4
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
%%7
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
CHAPTER &6
Gava has as many, i$ not more, thir 2party libraries than any other mo ern programming language. )ere, Qthir 2party librariesQ re$er to the innumerable GARs that you %an in%lu e in a server or esktop Gava appli%ation O the things that the Gava #AEs themselves o not provi e. -n the %ase o$ An roi , the Aalvik +M at its heart is not pre%isely Gava, an =hat it provi es in its #AE is not pre%isely the same as any tra itional Gava #AE. 4hat being sai , many Gava thir 2party libraries still provi e %apabilities that An roi la%ks natively an there$ore may be o$ use to you in your proNe%t, $or the ones you %an get =orking =ith An roi 6s $lavor o$ Gava. 4his %hapter e:plains =hat it =ill take $or you to leverage su%h libraries an the limitations on An roi 6s support $or arbitrary thir 2party %o e.
.xpected Platform AP%s* Aoes the %o e assume a ne=er G+M than the one An roi is base onC >r, oes the %o e assume the e:isten%e o$ Gava A!-s that ship =ith G2#I but not =ith An roi , su%h as #=ingC
%%9
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
#iBe* I:isting Gava %o e esigne $or use on esktops or servers nee not =orry too mu%h about on2 isk siMe, or, to some e:tent, even in2 RAM siMe. An roi , o$ %ourse, is short on both. "sing thir 2party Gava %o e, parti%ularly =hen pre2pa%kage as GARs, may balloon the siMe o$ your appli%ation. Performance* Aoes the Gava %o e e$$e%tively assume a mu%h more po=er$ul C!" than =hat you may $in on many An roi evi%esC Gust be%ause a esktop %an run it =ithout issue oesn6t mean your average mobile phone =ill han le it =ell. %nterface* Aoes the Gava %o e assume a %onsole inter$a%eC >r is it a pure A!- that you %an =rap your o=n inter$a%e aroun C
>ne tri%k $or a ressing some o$ these %on%erns is to use open sour%e Gava %o e, an a%tually =ork =ith the %o e to make it more An roi 2$rien ly. (or e:ample, i$ you6re only using ,0J o$ the thir 2party library, maybe it6s =orth=hile to re%ompile the subset o$ the proNe%t to be only =hat you nee , or at least removing the unne%essary %lasses $rom the GAR. 4he $ormer approa%h is sa$er, in that you get %ompiler help to make sure you6re not is%ar ing some essential pie%e o$ %o e, though it may be more te ious to o.
(or e:ample, in a previous e ition o$ this book, =e ha a Mail.uMM proNe%t. Mail.uMM, as the name suggests, ealt =ith email. 4o a%%omplish that en , Mail.uMM leverage the GavaMail A!-s an nee s t=o GavaMail GARs* mail-?.O.jar an activation-?.?.jar. With both o$ those in the libs/! ire%tory, the classpat& tells javac to link against those GARs, so any GavaMail re$eren%es in the Mail.uMM %o e %an be %orre%tly resolve . 4hen, those GARs are liste , along =ith the Mail.uMM %ompile %lasses, in the task that invokes the dex tool to %onvert the Gava %o e into Aalvik +M instru%tions. Without this step, even though your %o e may %ompile, it =on6t $in the GavaMail %lasses at runtime an =ill $ail =ith an e:%eption. As it turne out, though, the Aalvik +M an %ompiler supplie =ith the An roi 0.0 #AE no longer supporte some Gava language $eatures use by GavaMail. An , =hile the GavaMail sour%e %o e is available, it is un er an open sour%e li%ense &CAAL' that...has issues.
.eanshell GAR that a%%ompanies the sour%e %o e $or this book, up on the CommonsWare site. (rom there, using .eanshell on An roi is no i$$erent than using .eanshell in any other Gava environment* ,. Create an instan%e o$ the .eanshell .nterpreter %lass
2. #et any 5globals8 $or the s%riptWs use via .nterpreterDset:; ?. Call .nterpreterDeval:; to run the s%ript an , optionally, get the result o$ the last statement (or e:ample, here is the DML layout $or the =orl Ws smallest .eanshell -AI*
">xml!version$%?.@%!encoding$%utf-A%>' "+inear+ayout!xmlns#android$%&ttp#//sc&emas.android.com/ap /res/android% !!!!android#orientation$%vertical% !!!!android#layout_widt&$%fill_parent% !!!!android#layout_&eig&t$%fill_parent% !!!!' "6utton !!!!android#id$%9Bid/eval% !!!!android#layout_widt&$%fill_parent%! !!!!android#layout_&eig&t$%wrap_content% !!!!android#text$%0oX%! !!!!/' "*dit-ext !!!!android#id$%9Bid/script% !!!!android#layout_widt&$%fill_parent%! !!!!android#layout_&eig&t$%fill_parent%! !!!!android#single+ine$%false% !!!!android#gravity$%top% !!!!/' "/+inear+ayout'
%-%
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
public!class!MainActivity!extends!Activity!8 !!private!.nterpreter!i$new!Interpreter:;5 !! !!9,verride !!public!void!onCreate:6undle!icicle;!8 !!!!super.onCreate:icicle;5 !!!!setContentView:R.layout.main;5 !!!!6utton!btn$:6utton;findViewById:R.id.eval;5 !!!!final!*dit-ext!script$:*dit-ext;findViewById:R.id.script;5 !!!! !!!!btn.setOnClickListener:new!7iew.OnClickListener:;!8 !!!!!!public!void!onClick:7iew!view;!8 !!!!!!!!String!src$script.getText:;.toString:;5 !!!!!!!! !!!!!!!!try!8 !!!!!!!!!!i.set:%context%G!MainActivity.t&is;5 !!!!!!!!!!i.e al:src;5 !!!!!!!!< !!!!!!!!catc&!:bs&.*val*rror!e;!8 !!!!!!!!!!AlertDialog.6uilder!builder$ !!!!!!!!!!!!!!!!!!!!new!AlertDialog.Builder:MainActivity.t&is;5 !!!!!!!!!! !!!!!!!!!!builder !!!!!!!!!!!!.setTitle:%*xceptionX%; !!!!!!!!!!!!.set'essage:e.toString:;; !!!!!!!!!!!!.set(ositi eButton:%,M%G!null; !!!!!!!!!!!!.show:;5 !!!!!!!!< !!!!!!< !!!!<;5 !!< <
Compile an run it &in%lu ing in%orporating the .eanshell GAR as mentione above', an install it on the emulator. (ire it up, an you get a trivial -AI, =ith a large te:t area $or your s%ript an a big Q7o9Q button to e:e%ute it*
%-Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
/ote the use o$ context to re$er to the a%tivity =hen making the -oast. 4hat is the global set by the a%tivity to re$eren%e ba%k to itsel$. @ou %oul %all this global variable anything you =ant, so long as the set:; %all an the s%ript %o e use the same name. 4hen, %li%k the 7o9 button, an you get*
%-$
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
An no=, some %aveats... (irst, not all s%ripting languages =ill =ork. (or e:ample, those that implement their o=n $orm o$ Nust2in2time &G-4' %ompilation, generating Gava byte%o es on the $ly, =oul probably have to be augmente to generate Aalvik +M byte%o es instea o$ those $or sto%k Gava implementations. #impler languages that e:e%ute o$$ o$ parse s%ripts, %alling Gava re$le%tion A!-s to %all ba%k into %ompile %lasses, =ill likely =ork better. Iven there, though, not every $eature o$ the language may =ork, i$ it relies upon some $a%ility in a tra itional Gava A!- that oes not e:ist in Aalvik O $or e:ample, there %oul be stu$$ hi en insi e .eanshell or the a 2on GARs that oes not =ork on to ayWs An roi . #e%on , s%ripting languages =ithout G-4 =ill inevitably be slo=er than %ompile Aalvik appli%ations. #lo=er may mean users e:perien%e sluggishness. #lo=er e$initely means more battery li$e is %onsume $or the same amount o$ =ork. #o, buil ing a =hole An roi appli%ation in .eanshell, simply be%ause you $eel it is easier to program in, may %ause your users to be unhappy.
%-0
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
4hir , s%ripting languages that e:pose the =hole Gava A!-, like .eanshell, %an pretty mu%h o anything the un erlying An roi se%urity mo el allo=s. #o, i$ your appli%ation has the R*AD_),/-A)-S permission, e:pe%t any .eanshell s%ripts your appli%ation runs to have the same permission. Last, but %ertainly not least, is that language interpreter GARs ten to be...portly. 4he .eanshell GAR use in this e:ample is 200E.. 4hat is not ri i%ulous, %onsi ering =hat it oes, but it =ill make appli%ations that use .eanshell that mu%h bigger to o=nloa , take up that mu%h more spa%e on the evi%e, et%.
%-1
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
CHAPTER &1
4he e:pe%tation is that most, i$ not all, An roi evi%es =ill have built2in -nternet a%%ess. 4hat %oul be Wi(i, %ellular ata servi%es &IA7I, ?7, et%.', or possibly something else entirely. Regar less, most people O or at least those =ith a ata plan or Wi(i a%%ess O =ill be able to get to the -nternet $rom their An roi phone. /ot surprisingly, the An roi plat$orm gives evelopers a =i e range o$ =ays to make use o$ this -nternet a%%ess. #ome o$$er high2level a%%ess, su%h as the integrate WebEit bro=ser %omponent =e sa= in an earlier %hapter. -$ you =ant, you %an rop all the =ay o=n to using ra= so%kets. >r, in bet=een, you %an leverage A!-s O both on2 evi%e an $rom ?r 2party GARs O that give you a%%ess to spe%i$i% proto%ols* )44!, DM!!, #M4!, an so on. 4he emphasis o$ this book is on the higher2level $orms o$ a%%ess* the WebEit %omponent an -nternet2a%%ess A!-s, as busy %o ers shoul be trying to reuse e:isting %omponents versus rolling one6s o=n on2the2=ire proto%ol =herever possible.
style Web servi%esQ is e$ine as Qsimple )44! re;uests $or or inary "RLs over the $ull range o$ )44! verbs, =ith $ormatte payloa s &DML, G#>/, et%.' as responsesQ. More e:pansive tutorials, (AHs, an )>W4>s %an be $oun at the )ttpComponents Web site. )ere, =e6ll %over the basi%s, =hile %he%king the =eather.
$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, =e =ill only sho= relevant pie%es o$ the Gava %o e here in this %hapter, though you %an al=ays o=nloa the $ull sour%e $rom the CommonsWare Web site. 4o make this a bit more interesting, =e use the An roi lo%ation servi%es to $igure out =here =e are...sort o$. 4he $ull etails o$ ho= that =orks is es%ribe in the %hapter on lo%ation servi%es. -n the onResume:; metho , =e toggle on in$orme =here =e are no= an =hen &,0km'. When a lo%ation is available O movement O =e retrieve the /ational updateEorecast:; metho * lo%ation up ates, so =e =ill be =e move a signi$i%ant istan%e either at the start or base on Weather #ervi%e ata via our
private!void!update"orecast:+ocation!loc;!8 !!String!url$String.format:formatG!loc.getLatitude:;G!loc.getLongitude:;;5 !!3ttp0et!getMet&od$new!,ttpGet:url;5 !!try!8 !!!!Response3andler"String'!response3andler!$!new!Basic$esponse,andler:;5 !!!!String!response6ody$client.execute:getMet&odG!response3andler;5 !!!!!uild"orecasts:response6ody;5 !!!!String!page$generate(age:;5 !!!!browser.loadData&ithBase)$L:nullG!pageG!%text/&tml%G !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!%2-E-A%G!null;5 !!< !!catc&!:-&rowable!t;!8 !!!!-oast !!!!!!.makeText:t&isG!%ReJuest!failed#!%Bt.toString:;G!O@@@; !!!!!!.show:;5 !!< <
4he updateEorecast:; metho takes a +ocation as a parameter, obtaine $rom the lo%ation up ate pro%ess. (or no=, all you nee to kno= is that +ocation sports get+atitude:; an get+ongitude:; metho s that return the latitu e an longitu e o$ the evi%e6s position, respe%tively.
%-9
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
We hol the "RL to the /ational Weather #ervi%e DML in a string resour%e, an pour in the latitu e an longitu e at runtime. 7iven our 3ttp)lient! obNe%t %reate in on)reate:;, =e populate an 3ttp0et =ith that %ustomiMe "RL, then e:e%ute that metho . 7iven the resulting DML $rom the RI#4 servi%e, =e buil the $ore%ast )4ML page &see belo=' an pour that into the CebMit =i get. -$ the 3ttp)lient blo=s up =ith an e:%eption, =e provi e that error as a -oast.
P rsin! Responses
4he response you get =ill be $ormatte using some system O )4ML, DML, G#>/, =hatever. -t is up to you, o$ %ourse, to pi%k out =hat in$ormation you nee an o something use$ul =ith it. -n the %ase o$ the Ceat&erDemo, =e 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 )4ML page $rom it. An roi in%lu es*
4hree DML parsers* the tra itional W?C A>M &org.wIc.dom', a #AD parser &org.xml.sax', an the DML pull parser is%usse in the %hapter on resour%es A G#>/ parser &org.json'
@ou are also =el%ome to use thir 2party Gava %o e, =here possible, to han le other $ormats, su%h as a e i%ate R##UAtom parser $or a $ee rea er. 4he use o$ thir 2party Gava %o e is is%usse in a separate %hapter. (or Ceat&erDemo, =e use the W?C A>M parser in our buildEorecasts:;! metho *
void!!uild"orecasts:String!raw;!t&rows!*xception!8 !!Document6uilder!builder$Document6uilderEactory !!!!!!!!!!!!!!!!!!!!!!!!!!!.newInstance:; !!!!!!!!!!!!!!!!!!!!!!!!!!!.newDocumentBuilder:;5 !!Document!doc$builder.parse:new!InputSource:new!String$eader:raw;;;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
%$;
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
!!!!Eorecast!forecast$new!"orecast:;5 !!!!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-lin %;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 !!< <
4he /ational Weather #ervi%e DML $ormat is...%uriously stru%ture , relying heavily on se;uential position in lists versus the more obNe%t2oriente style you $in in $ormats like R## or Atom. 4hat being sai , =e %an take a $e= liberties an simpli$y the parsing some=hat, taking a vantage o$ the $a%t that the elements =e =ant &start-valid-time $or the $ore%ast time, value $or the temperature, an icon-lin $or the i%on "RL' are all uni;ue =ithin the o%ument. 4he )4ML %omes in as an .nputStream an is $e into the A>M parser. (rom there, =e s%an $or the start-valid-time elements an populate a set o$ Eorecast mo els using those start times. 4hen, =e $in the temperature value elements an icon-lin "RLs an $ill those in to the Eorecast obNe%ts. -n turn, the generate1age:; metho %reates a ru imentary )4ML table =ith the $ore%asts*
String!generate(age:;!8 !!String6uffer!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
%$*
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
!!for!:Eorecast!forecast!#!forecasts;!8 !!!!bufResult.append:%"tr'"td!align$4%center4%'%;5 !!!!bufResult.append:forecast.getTime:;;5 !!!!bufResult.append:%"/td'"td!align$4%center4%'%;5 !!!!bufResult.append:forecast.getTemp:;;5 !!!!bufResult.append:%"/td'"td'"img!src$4%%;5 !!!!bufResult.append:forecast.getIcon:;;5 !!!!bufResult.append:%4%'"/td'"/tr'%;5 !!< !!bufResult.append:%"/table'"/body'"/&tml'%;5 !!return:bufResult.toString:;;5 <
Stu,, To Consider
-$ you nee to use ##L, bear in min that the e$ault 3ttp)lient setup oes not in%lu e ##L support. Mostly, this is be%ause you nee to e%i e ho= to han le ##L %erti$i%ate presentation O o you blin ly a%%ept all %erti$i%ates,
%$%
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
even sel$2signe or e:pire onesC >r o you =ant to ask the user i$ they really =ant to use some strange %erti$i%atesC #imilarly, 3ttp)lient, by e$ault, is esigne $or single2threa e use. -$ you =ill be using 3ttp)lient $rom a servi%e or some other pla%e =here multiple threa s might be an issue, you %an rea ily set up 3ttp)lient to support multiple threa s. (or these sorts o$ topi%s, you are best serve by %he%king out the )ttpComponents Web site $or o%umentation an support.
%$Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
PART IV Intents
CHAPTER &&
"p to no=, the $o%us o$ this book has been on a%tivities opene ire%tly by the user $rom the evi%e6s laun%her. 4his, 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 =ay the user =ill start using your appli%ation. )o=ever, remember that the An roi system is base upon lots o$ loosely2 %ouple %omponents. What you might a%%omplish in a esktop 7"- via ialog bo:es, %hil =in o=s, an the like are mostly suppose to be in epen ent a%tivities. While one a%tivity =ill be Qspe%ialQ, in that it sho=s up in the laun%her, the other a%tivities all nee to be rea%he ...someho=. 4he Qho=Q is via intents. An intent is basi%ally a message that you pass to An roi saying, Q@o9 - =ant to o...er...something9 @eah9Q )o= spe%i$i% the QsomethingQ is epen s on the situation O sometimes you kno= e:a%tly =hat you =ant to o &e.g., open up one o$ your other a%tivities', an sometimes you on6t. -n the abstra%t, An roi is all about intents an re%eivers o$ those intents. #o, no= that =e are =ell2verse in %reating a%tivities, let6s ive into intents, so =e %an %reate more %omple: appli%ations =hile simultaneously being Qgoo An roi %itiMensQ.
%$4
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
#ome o$ the material in this %hapter is base on the author6s posts to the .uil ing 6Aroi s %olumn on An roi 7uys.%om.
Pieces o, Intents
4he t=o most important pie%es o$ an intent are the a%tion an =hat An roi re$ers to as the Q ataQ. 4hese are almost e:a%tly analogous to )44! verbs an "RLs O 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 A)-.,/_7.*C &to bring up a vie=er $or the resour%e', A)-.,/_*D.- &to e it the resour%e', or A)-.,/_1.)M &to %hoose an available item given a 2ri representing a %olle%tion, su%h as content#//contacts/people'. -$ you =ere to %reate an intent %ombining A)-.,/_7.*C =ith a %ontent "ri o$ an pass that intent to An roi , An roi =oul kno= to $in an open an a%tivity %apable o$ vie=ing that resour%e.
content#//contacts/people/?,
%$7
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
4here are other %riteria you %an pla%e insi e an intent &represente as an -ntent obNe%t', besi es the a%tion an Q ataQ 2ri, su%h as*
A %ategory. @our QmainQ a%tivity =ill be in the +A2/)3*R %ategory, in i%ating it shoul sho= up on the laun%her menu. >ther a%tivities =ill 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 =ant to operate on, i$ you on6t kno= a %olle%tion 2ri. A %omponent, =hi%h is to say, the %lass o$ the a%tivity that is suppose to re%eive this intent. "sing %omponents this =ay obviates the nee $or the other properties o$ the intent. )o=ever, it oes make the intent more $ragile, as it assumes spe%i$i% implementations. QI:trasQ, =hi%h is a 6undle o$ other in$ormation you =ant to pass along to the re%eiver =ith the intent, that the re%eiver might =ant 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 =ell2 o%umente .
@ou =ill $in rosters o$ the stan ar a%tions an %ategories in the An roi #AE o%umentation $or the .ntent %lass.
Intent Routin!
As note above, i$ you spe%i$y the target %omponent in your intent, An roi has no oubt =here the intent is suppose to be route to O it =ill laun%h the name a%tivity. 4his might be >E i$ the target intent is in your appli%ation. -t e$initely is not re%ommen e $or sen ing intents to other appli%ations. Component names, by an large, are %onsi ere private to the appli%ation an are subNe%t to %hange. Content 2ri templates an M-MI types are the pre$erre =ays o$ i enti$ying servi%es you =ish thir 2party %o e to supply. -$ you o not spe%i$y the target %omponent, then An roi has to $igure out =hat a%tivities &or other intent re%eivers' are eligible to re%eive the intent. /ote the use o$ the plural Qa%tivitiesQ, as a broa ly2=ritten intent might =ell resolve to several a%tivities. 4hat is the...ummm...intent &par on the pun', as
%$9
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
you =ill see later in this %hapter. 4his routing approa%h is re$erre impli%it routing.
to as
.asi%ally, there are three rules, all o$ =hi%h must be true $or a given a%tivity to be eligible $or a given intent* ,. 4he a%tivity must support the spe%i$ie a%tion
2. 4he a%tivity must support the state M-MI type &i$ supplie ' ?. 4he a%tivity must support all o$ the %ategories name in the intent 4he upshot is that you =ant to make your intents spe%i$i% enough to $in the right re%eiver&s', an no more spe%i$i% than that. 4his =ill be%ome %learer as =e =ork through some e:amples later in this %hapter.
%0;
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
/ote the intent-filter element un er the a%tivity element. )ere, =e e%lare that this a%tivity*
-s the main a%tivity $or this appli%ation -t is in the +A2/)3*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 kno=s this is the %omponent it shoul laun%h =hen somebo y %hooses the appli%ation $rom the main menu. 4he intent $ilter also has a label & android#label!$!%)onsActivity%'. -n this %ase, this %ontrols the name asso%iate =ith the appli%ation6s i%on in the main menu. @ou are =el%ome to have more than one a%tion or more than one %ategory in your intent $ilters. 4hat in i%ates that the asso%iate %omponent &e.g., a%tivity' han les multiple i$$erent sorts o$ intents. More than likely, you =ill also =ant to have your se%on ary &non2MA./' a%tivities spe%i$y the M-MI type o$ ata they =ork on. 4hen, i$ an intent is targete $or that M-MI type O either ire%tly, or in ire%tly by the 2ri! re$eren%ing something o$ that type O An roi =ill kno= that the %omponent han les su%h ata. (or e:ample, you %oul have an a%tivity e%lare like this*
"activity!android#name$%.-our7iewActivity%' !!"intent-filter' !!!!"action!android#name$%android.intent.action.7.*C%!/' !!!!"category!android#name$%android.intent.category.D*EA2+-%!/' !!!!"data!android#mime-ype$%vnd.android.cursor.item/vnd.commonsware.tour%!/' !!"/intent-filter' "/activity'
4his a%tivity =ill get laun%he by an intent re;uesting to vie= a 2ri! representing a vnd.android.cursor.item/vnd.commonsware.tour pie%e o$ %ontent. 4hat intent %oul %ome $rom another a%tivity in the same appli%ation &e.g., the MA-/ a%tivity $or this appli%ation' or $rom another
%0*
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
a%tivity in another An roi appli%ation that happens to kno= a 2ri that this a%tivity han les.
5arro) 3eceivers
-n the e:amples sho=n above, the intent $ilters =ere set up on a%tivities. #ometimes, tying intents to a%tivities is not e:a%tly =hat =e =ant*
#ome system events might %ause us to =ant 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, =here the %riteria are not solely base on the intent itsel$, but some other state &e.g., i$ =e get intent D an the atabase has a @, then laun%h a%tivity MP i$ the atabase oes not have a @, then laun%h a%tivity /'
(or these %ases, An roi o$$ers the intent re%eiver, e$ine as a %lass implementing the 6roadcastReceiver inter$a%e. -ntent re%eivers are isposable obNe%ts esigne to re%eive intents O parti%ularly broa %ast intents O an take a%tion, typi%ally involving laun%hing other intents to trigger logi% in an a%tivity, servi%e, or other %omponent. 4he 6roadcastReceiver inter$a%e has only one metho * onReceive:;. -ntent re%eivers implement that metho , =here they o =hatever it is they =ish to o upon an in%oming intent. 4o e%lare an intent re%eiver, a an re%eiver element to your AndroidManifest.xml $ile*
"receiver!android#name$%.My.ntentReceiver)lass/ame%!/'
An intent re%eiver is only alive $or as long as it takes to pro%ess onReceive:; O as soon as that metho returns, the re%eiver instan%e is subNe%t to garbage %olle%tion an =ill not be reuse . 4his means intent re%eivers are some=hat limite in =hat 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:.
%0%
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
4he e:%eption is i$ the 6roadcastReceiver is implemente on some longer2 live %omponent, su%h as an a%tivity or servi%e O in that %ase, the intent re%eiver lives as long as its QhostQ oes &e.g., until the a%tivity is $roMen'. )o=ever, in this %ase, you %annot e%lare the intent re%eiver via AndroidManifest.xml. -nstea , you nee to %all registerReceiver:; on your Activity6s onResume:; %allba%k to e%lare interest in an intent, then %all unregisterReceiver:; $rom your Activity6s on1ause:; =hen you no longer nee those intents.
@our re%eiver oes not %are i$ it misses messages be%ause it =as not a%tive, or @ou provi e some means o$ getting the re%eiver Q%aught upQ on messages it misse =hile it =as ina%tive
-n the %hapters on %reating an using servi%es, you =ill see an e:ample o$ the $ormer %on ition, =here the re%eiver &servi%e %lient' =ill use .ntent2 base messages =hen they are available but oes not nee them i$ the %lient is not a%tive.
%0Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
CHAPTER &'
As is%usse previously, the theory behin the An roi "- ar%hite%ture is that evelopers shoul e%ompose their appli%ation into istin%t a%tivities, ea%h implemente as an Activity, ea%h rea%hable via intents, =ith 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 vie=ing the %alen ar, vie=ing a single event, e iting an event &in%lu ing a ing a ne= one', an so $orth. 4his, 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 vie=2 %alen ar a%tivity, you might =ant to sho= the vie=2event a%tivity $or that event. 4his means that, someho=, you nee to be able to %ause the vie=2 event a%tivity to laun%h an sho= a spe%i$i% event &the one the user %li%ke upon'. 4his %an be $urther broken o=n into t=o s%enarios* ,. @ou kno= =hat a%tivity you =ant to laun%h, probably be%ause it is another a%tivity in your o=n appli%ation
2. @ou have a %ontent 2ri to...something, an you =ant your users to be able to o...something =ith it, but you o not kno= up $ront =hat the options are
%00
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
4his %hapter %overs the $irst s%enarioP the ne:t %hapter han les the se%on .
%01
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
% $e n Intent
As is%usse in a previous %hapter, intents en%apsulate a re;uest, ma e to An roi , $or some a%tivity or other intent re%eiver to o something. -$ the a%tivity you inten to laun%h is one o$ your o=n, you may $in it simplest to %reate an e:pli%it intent, naming the %omponent you =ish to laun%h. (or e:ample, $rom =ithin your a%tivity, you %oul %reate an intent like this*
new!Intent:t&isG!3elpActivity.class;5
4his =oul stipulate that you =ante to laun%h the 3elpActivity. 4his a%tivity =oul nee to be name in your AndroidManifest.xml $ile, though not ne%essarily =ith 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:%geo#%Blat.toString:;B%G%Blon.toString:;;5 .ntent!i$new!Intent:.ntent.A)-.,/_7.*CG!uri;5
)ere, given that =e have the latitu e an longitu e o$ some position &lat! an lon, respe%tively' o$ type Double, =e %onstru%t a geo s%heme 2ri an %reate an intent re;uesting to vie= this 2ri &A)-.,/_7.*C'.
% $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* ,. 4he simplest option is to %all startActivity:; =ith the intent O this =ill %ause An roi to $in the best2mat%h a%tivity or intent re%eiver an pass the intent to it $or han ling. @our a%tivity =ill not be in$orme =hen the 5%hil 8 a%tivity is %omplete.
%04
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
2. @ou %an %all startSubActivity:;, passing it the intent an a number &uni;ue to the %alling a%tivity'. An roi =ill $in the best2mat%h han ler an pass the intent over to it. )o=ever, your a%tivity =ill be noti$ie =hen the %hil a%tivity is %omplete via the onActivityResult:; %allba%k &see belo='. ?. @ou %an %all broadcast.ntent:;. -n this %ase, An roi =ill pass the intent to all registere a%tivities an intent re%eivers that %oul possibly =ant this intent, not Nust the best mat%h. <. @ou %an %all broadcast.ntentSeriali(ed:;. )ere, An roi =ill pass the intent to all %an i ate a%tivities an intent re%eivers one at a time O i$ any one 5%onsumes8 the intent, the rest o$ the %an i ates are not noti$ie . Most o$ the time, you =ill =in up using startActivity:; or startSubActivity:; O 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 =hen the %hil a%tivity has %omplete its =ork. 4he %allba%k re%eives the uni;ue number supplie to startSubActivity:;, so you %an etermine =hi%h %hil a%tivity is the one that has %omplete . @ou also get*
A result %o e, $rom the %hil a%tivity %alling setResult:;. 4ypi%ally this is R*S2+-_,M or R*S2+-_)A/)*++*D, though you %an %reate your o=n return %o es &pi%k a number starting =ith R*S2+-_E.RS-_2S*R' An optional String %ontaining some result ata, possibly a "RL to some internal or e:ternal resour%e O $or e:ample, a A)-.,/_1.)M! 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
4o emonstrate laun%hing a peer a%tivity, take a peek at the +aunc& sample appli%ation. 4he DML layout is $airly straight$or=ar * t=o $iel s $or the latitu e an longitu e, plus a button*
%07
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
">xml!version$%?.@%!encoding$%utf-A%>' "+inear+ayout!xmlns#android$%&ttp#//sc&emas.android.com/ap /res/android% !!android#orientation$%vertical% !!android#layout_widt&$%fill_parent% !!android#layout_&eig&t$%fill_parent% !!' !!"-able+ayout !!!!android#layout_widt&$%fill_parent%! !!!!android#layout_&eig&t$%wrap_content% !!!!android#stretc&)olumns$%?GH% !!' !!!!"-ableRow' !!!!!!"-ext7iew !!!!!!!!android#layout_widt&$%wrap_content%! !!!!!!!!android#layout_&eig&t$%wrap_content% !!!!!!!!android#padding+eft$%Hdip% !!!!!!!!android#paddingRig&t$%Odip% !!!!!!!!android#text$%+ocation#% !!!!!!/' !!!!!!"*dit-ext!android#id$%9Bid/lat% !!!!!!!!android#layout_widt&$%fill_parent%! !!!!!!!!android#layout_&eig&t$%wrap_content% !!!!!!!!android#cursor7isible$%true% !!!!!!!!android#editable$%true% !!!!!!!!android#single+ine$%true% !!!!!!!!android#layout_weig&t$%?% !!!!!!/' !!!!!!"*dit-ext!android#id$%9Bid/lon% !!!!!!!!android#layout_widt&$%fill_parent%! !!!!!!!!android#layout_&eig&t$%wrap_content% !!!!!!!!android#cursor7isible$%true% !!!!!!!!android#editable$%true% !!!!!!!!android#single+ine$%true% !!!!!!!!android#layout_weig&t$%?% !!!!!!/' !!!!"/-ableRow' !!"/-able+ayout' !!"6utton!android#id$%9Bid/map% !!!!android#layout_widt&$%fill_parent%! !!!!android#layout_&eig&t$%wrap_content% !!!!android#text$%S&ow!MeX% !!/' "/+inear+ayout'
4he button6s ,n)lic +istener simply takes the latitu e an longitu e, pours them into a geo s%heme 2ri, then starts the a%tivity.
pac age!com.commonsware.android.activities5 import!android.app.Activity5 import!android.content..ntent5 import!android.net.2ri5
%09
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
import!android.os.6undle5 import!android.view.7iew5 import!android.widget.6utton5 import!android.widget.*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 !!!!!!!!String!_lat$lat.getText:;.toString:;5 !!!!!!!!String!_lon$lon.getText:;.toString:;5 !!!!!!!!2ri!uri$2ri.parse:%geo#%B_latB%G%B_lon;5 !!!!!!!! !!!!!!!!start#cti ity:new!Intent:.ntent.A)-.,/_7.*CG!uri;;5 !!!!!!< !!!!<;5 !!< <
%1;
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
-$ you $ill in a lo%ation &e.g., ?8.880, latitu e an 211.0<02 longitu e' an %li%k the button, the resulting map is more interesting. /ote that this is the built2in An roi map a%tivity O =e i not %reate our o=n a%tivity to isplay this map.
%1*
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
!igure 19< The map launched by aunch /emo6 sho)ing the incoln +emorial in Washington /C
-n a later %hapter, you =ill see ho= you %an %reate maps in your o=n a%tivities, in %ase you nee greater %ontrol over ho= the map is isplaye .
%1%
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
CHAPTER &(
#ometimes, you kno= Nust =hat you =ant to o, su%h as isplay one o$ your other a%tivities. #ometimes, you have a pretty goo i ea o$ =hat you =ant to o, su%h as vie= the %ontent represente by a 2ri, or have the user pi%k a pie%e o$ %ontent o$ some M-MI type. #ometimes, you6re lost. All you have is a %ontent 2ri, an you on6t really kno= =hat you %an o =ith it. (or e:ample, suppose you =ere %reating a %ommon tagging subsystem $or An roi , =here users %oul tag pie%es o$ %ontent O %onta%ts, Web "RLs, geographi% lo%ations, et%. @our subsystem =oul 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. 4hat6s all =ell an goo . )o=ever, you probably nee some sort o$ maintenan%e a%tivity, =here users %oul vie= all their tags an the pie%es o$ %ontent so tagge . 4his might even serve as a ;uasi2bookmark servi%e $or items on their phone. 4he problem is, the user is going to e:pe%t to be able to o use$ul things =ith the %ontent they $in in your subsystem, su%h as ial a %onta%t or sho= a map $or a lo%ation.
%1Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
4he problem is, you have absolutely no i ea =hat is all possible =ith any given %ontent 2ri. @ou probably %an vie= any o$ them, but %an you e it themC Can you ial themC #in%e ne= appli%ations =ith ne= types o$ %ontent %oul be a e by any user at any time, you %an6t even assume you kno= all possible %ombinations Nust 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 =hi%h you %an present to your users a set o$ likely a%tivities to spa=n $or a given %ontent 2ri...even i$ you have no i ea =hat that %ontent 2ri really represents. 4his %hapter e:plores some o$ these 2ri a%tion introspe%tion tools.
Pick AEm
#ometimes, you kno= 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'. 4o o this, you nee to %reate an intent $or the A)-.,/_1.)M on the target 2ri, then start a sub a%tivity &via startSubActivity:;' to allo= 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 1ic in the sample appli%ations. 4his a%tivity gives you a $iel $or a %olle%tion 2ri &=ith content#//contacts/people pre2 $ille in $or your %onvenien%e', plus a really big 57imme98 button*
">xml!version$%?.@%!encoding$%utf-A%>' "+inear+ayout!xmlns#android$%&ttp#//sc&emas.android.com/ap /res/android% !!android#orientation$%vertical% !!android#layout_widt&$%fill_parent% !!android#layout_&eig&t$%fill_parent% !!' !!"*dit-ext!android#id$%9Bid/type%
%1$
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
!!!!android#layout_widt&$%fill_parent%! !!!!android#layout_&eig&t$%wrap_content% !!!!android#cursor7isible$%true% !!!!android#editable$%true% !!!!android#single+ine$%true% !!!!android#text$%content#//contacts/people% !!/' !!"6utton !!!!android#id$%9Bid/pic % !!!!android#layout_widt&$%fill_parent%! !!!!android#layout_&eig&t$%fill_parent% !!!!android#text$%0immeX% !!!!android#layout_weig&t$%?% !!/' "/+inear+ayout'
"pon being %li%ke , the button %reates the A)-.,/_1.)M on the user2supplie %olle%tion 2ri an starts the sub2a%tivity. When that sub2a%tivity %ompletes =ith R*S2+-_,M, the A)-.,/_7.*C is invoke on the resulting %ontent 2ri.
public!class!1ic Demo!extends!Activity!8 !!static!final!int!1.)M_R*T2*S-$?IIV5 !!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.pic ;5 !!!! !!!!btn.setOnClickListener:new!7iew.OnClickListener:;!8 !!!!!!public!void!onClick:7iew!view;!8 !!!!!!!!.ntent!i$new!Intent:.ntent.A)-.,/_1.)MG !!!!!!!!!!!!!!!!!!!!2ri.parse:type.getText:;.toString:;;;5 !!!!!!!!start#cti ity"or$esult:iG!1.)M_R*T2*S-;5 !!!!!!< !!!!<;5 !!< !!9,verride !!protected!void!on#cti ity$esult:int!reJuest)odeG!int!result)odeG !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.ntent!data;!8 !!!!if!:reJuest)ode$$1.)M_R*T2*S-;!8 !!!!!!if!:result)ode$$R*S2+-_,M;!8 !!!!!!!!!!start#cti ity:new!Intent:.ntent.A)-.,/_7.*CG !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!data.getData:;;;5 !!!!!!< !!!!<
%10
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
!!< <
4he result* the user %hooses a %olle%tion, pi%ks a pie%e o$ %ontent, an vie=s it.
%11
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
!igure 4*< The same application6 after clicking the ='imme!= button6 sho)ing the list of available people
!igure 4%< ( vie) of a contact6 launched by Pick/emo after choosing one of the people from the pick list
%14
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
>ne $la= in this appli%ation is that it may not have permission to vie= =hatever %ontent %olle%tion the user entere . (or the sample, =e ha to spe%i$i%ally re;uest permission to rea the user6s %onta%ts, via a uses2 permission element in AndroidManifest.xml. We6ll %over more about re;uesting &an re;uiring' permissions later in this book.
a %ategory o$ A+-*R/A-*_)A-*0,RF. 4he %ategory A+-*R/A-*_)A-*0,RF is the %onvention $or one appli%ation a ing a%tions to another appli%ation6s %ontent. -$ you =ant to =rite a%tivities that are a=are o$ possible a 2ons like tagging, you shoul use add.ntent,ptions:; to a those a 2ons6 a%tions to your options menu, su%h as the $ollo=ing*
.ntent!intent!$!new!Intent:nullG!my)ontent2ri;5 intent.addCategory:.ntent.A+-*R/A-.7*_)A-*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, my)ontent2ri is the %ontent 2ri o$ =hatever is being vie=e 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 =e are using to pi%k a%tions $rom re;uires that appropriate intent re%eivers support the A+-*R/A-.7*_)A-*0,RF. 4hen, =e a the options to the menu =ith add.ntent,ptions:; an the $ollo=ing parameters*
4he 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 )omponent/ame instan%e representing the a%tivity that is populating its menu O this is use to $ilter out the a%tivity6s o=n a%tions, so the a%tivity %an han le its o=n a%tions as it sees $it An array o$ .ntent instan%es that are the 5spe%i$i%8 mat%hes O any a%tions mat%hing those intents are sho=n $irst in the menu be$ore any other possible a%tions 4he .ntent $or =hi%h you =ant the available a%tions
%19
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
A set o$ $lags. 4he only one o$ likely relevan%e is represente as MA-)3_D*EA2+-_,/+F, =hi%h means mat%hing a%tions must also implement the D*EA2+-_)A-*0,RF %ategory. -$ you o not nee this, use a value o$ @ $or the $lags. An array o$ Menu..tem, =hi%h =ill hol the menu items mat%hing the array o$ .ntent instan%es supplie as the 5spe%i$i%s8, or null i$ you o not nee those items &or are not using 5spe%i$i%s8'
(sking (round
the ActivityAdapter $amily an add.ntent,ptions:; use Juery.ntentActivity,ptions:; $or the 5heavy li$ting8 o$ $in ing possible a%tions. 4he Juery.ntentActivity,ptions:; metho is implemente on 1ac ageManager, =hi%h is available to your a%tivity via get1ac ageManager:;. 4he Juery.ntentActivity,ptions:; metho takes some o$ the same parameters as oes add.ntent,ptions:;, notably the %aller )omponent/ame, the 5spe%i$i%s8 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, =ith the 5spe%i$i%s8 ones $irst. -$ you =oul like to o$$er alternative a%tions to users, but by means other add.ntent,ptions:;, 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'. .oth
%4;
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
CHAPTER &)
Any 2ri in An roi that begins =ith 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 O you neither kno= nor %are =here the ata represente by the 2ri %omes $rom, so long as it is available to you =hen nee e . 4he ata %oul be store in a #HLite atabase, or in $lat $iles, or retrieve o$$ a evi%e, or be store on some $ar2o$$ server a%%esse over the -nternet. 7iven 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. 7iven a %olle%tion 2ri, you %an %reate ne= pie%es o$ %ontent via insert operations. 7iven 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 o=n. 4his %hapter %overs using %ontent provi ersP the ne:t %hapter =ill e:plain ho= you %an serve up your o=n ata using the %ontent provi er $rame=ork.
Pieces of +e
4he 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
%4Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
slashes in "RL2style notation. 4he s%heme o$ a %ontent "ri is al=ays content#//. #o, a %ontent 2ri o$ content#//constants/L represents the %onstants instan%e =ith an i enti$ier o$ L. 4he %ombination o$ the s%heme an the namespa%e is kno=n as the 5base "ri8 o$ a %ontent provi er, or a set o$ ata supporte by a %ontent provi er. -n the e:ample above, content#//constants is the base 2ri $or a %ontent provi er that serves up in$ormation about 5%onstants8 &in this %ase, physi%al %onstants'. 4he 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. 4he base 2ri represents a %olle%tion o$ instan%es. 4he base 2ri %ombine =ith 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 obNe%ts, though in %ommon is%ussion, it is simpler to think o$ them as strings. 4he 2ri.parse:; stati% metho %reates a 2ri out o$ the string representation.
'etting a Dandle
#o, =here o these 2ri instan%es %ome $romC 4he most popular starting point, i$ you kno= the type o$ ata you =ant to =ork =ith, is to get the base 2ri $rom the %ontent provi er itsel$ in %o e. (or e:ample, android.provider.),/-*/-_2R. is the base 2ri $or %onta%ts represente as people O this maps to content#//contacts/people. -$ you Nust nee the %olle%tion, this 2ri =orks as2isP i$ you nee an instan%e an kno= its i enti$ier, you %an %all add.d:; on the 2ri to inNe%t it, so you have a 2ri $or the instan%e.
%4$
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
@ou might also get 2ri instan%es han e to you $rom other sour%es. -n the pre%e ing %hapter, =e sa= ho= you got 2ri han les $or %onta%ts via sub2 a%tivities respon ing to A)-.,/_1.)M 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 2=ire literal String obNe%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 =ith content#//contacts/people pre2$ille in. 4his isn6t an i eal solution, as the base 2ri values %oul %on%eivably %hange over time.
+akinA Gueries
7iven a base 2ri, you %an run a ;uery to return ata out o$ the %ontent provi er relate to that 2ri. 4his has mu%h o$ the $eel o$ #HL* you spe%i$y the 5%olumns8 to return, the %onstraints to etermine =hi%h 5ro=s8 to return, a sort or er, et%. 4he 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'. 4he ne:us o$ this is the managedTuery:; metho available to your a%tivity. 4his metho takes $ive parameters* ,. 4he base 2ri o$ the %ontent provi er to ;uery, or the instan%e 2ri o$ a spe%i$i% obNe%t to ;uery
2. An array o$ properties o$ instan%es $rom that %ontent provi er that you =ant 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 4his metho returns a )ursor obNe%t, =hi%h you %an use to retrieve the ata returne by the ;uery.
%40
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
5!roperties8 is to %ontent provi ers as %olumns are to atabases. -n other =or s, ea%h instan%e &ro=' returne by a ;uery %onsists o$ a set o$ properties &%olumns', ea%h representing some pie%e o$ ata. 4his =ill hope$ully make more sense given an e:ample. >ur %ontent provi er e:amples %ome $rom the Constants sample appli%ation, spe%i$i%ally the )onstants6rowser %lass*
constants)ursor$managed/uery:1rovider.)onstants.),/-*/-_2R.G !!!!!!!!!!!!!!!!!!!!!!!!!!!!!1R,=*)-.,/G!nullG!nullG!null;5
4he 2ri passe into the a%tivity by the %aller &),/-*/-_2R.', in this %ase representing the %olle%tion o$ physi%al %onstants manage by the %ontent provi er A list o$ properties to retrieve &see %o e belo=' 4hree null values, in i%ating that =e o not nee a %onstraint %lause &the 2ri represents the instan%e =e nee ', nor parameters $or the %onstraint, nor a sort or er &=e shoul only get one entry ba%k'
4he biggest 5magi%8 here is the list o$ properties. 4he lineup o$ =hat 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, =e e$ine logi%al values on the 1rovider %ontent provi er implementation %lass that represent the various properties &namely, the uni;ue i enti$ier, the isplay name or title, an the value o$ the %onstant'.
%41
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
A$ter e:e%uting the managedTuery:; an getting the )ursor, )onstants6rowser! %reates a Simple)ursorAdapter =ith the $ollo=ing parameters*
4he a%tivity &or other )ontext' %reating the a apterP in this %ase, the )onstants6rowser itsel$ 4he i enti$ier $or a layout to be use $or ren ering the list entries &R.layout.row' 4he %ursor &constants)ursor'
%44
4he properties to pull out o$ the %ursor an use $or %on$iguring the list entry +ie= instan%es &-.-+* an 7A+2*' 4he %orrespon ing i enti$iers o$ -ext7iew =i gets in the list entry layout that those properties shoul go into &R.id.title an R.id.value'
-$ you nee more %ontrol over the vie=s than you %an reasonably a%hieve =ith the sto%k vie= %onstru%tion logi%, sub%lass Simple)ursorAdapter an overri e get7iew:; to %reate your o=n =i gets to go into the list, as emonstrate earlier in this book.
/oing 8t By Dand
>$ %ourse, you %an al=ays o it the 5har =ay8 O pulling ata out o$ the )ursor by han . 4he )ursor inter$a%e is similar in %on%ept to other atabase a%%ess A!-s o$$ering %ursors as obNe%ts, though, as al=ays, the evil is in the etails.
%47
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
Position
)ursor
instan%es have a built2in notion o$ position, akin to the Gava .terator! inter$a%e. 4o get to the various ro=s, you %an use*
move-oEirst:; to move to the $irst ro= in the move-o+ast:; to move to the last ro= in the result set move-o/ext:;
result set or
to move to the ne:t ro= an etermine i$ there is yet another ro= to pro%ess &move-o/ext:; returns true i$ it points to another ro= a$ter moving, false other=ise'
move-o1revious:; move-o/ext:;
move-o1osition:; to move to a spe%i$i% in e:, or move:; to move to a relative position plus or minus $rom your %urrent position get1osition:; to return your %urrent in
e:
a =hole host o$ %on ition metho s, in%lu ing isEirst:;, is+ast:;, is6eforeEirst:;, an isAfter+ast:;
Gettin! Properties
>n%e you have the )ursor positione at a ro= o$ interest, you have a variety o$ metho s to retrieve properties $rom that ro=, =ith i$$erent metho s supporting i$$erent types &getString:;, get.nt:;, getEloat:;, et%.'. Ia%h metho takes the Mero2base in e: o$ the property you =ant to retrieve. -$ you =ant to see i$ a given property has a value, you %an use is/ull:; to test it $or null2ness.
%49
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
4o insert ata into a %ontent provi er, you have t=o options available on the )ontent1rovider inter$a%e &available through get)ontent1rovider:; to your a%tivity'* ,. "se insert:; =ith a %olle%tion 2ri an a )ontent7alues stru%ture es%ribing the initial set o$ ata to put in the ro=
2. "se bul .nsert:; =ith a %olle%tion 2ri an an array o$ )ontent7alues! stru%tures to populate several ro=s at on%e 4he insert:; metho returns a 2ri $or you to use $or $uture operations on that ne= obNe%t. 4he bul .nsert:; metho returns the number o$ %reate ro=sP you =oul nee to o a ;uery to get ba%k at the ata you Nust inserte . (or e:ample, here is a snippet o$ %o e $rom )onstants6rowser to insert a ne= %onstant into the %ontent provi er, given a DialogCrapper that %an provi e a%%ess to the title an value o$ the %onstant*
private!void!process#dd:DialogCrapper!wrapper;!8 !!)ontent7alues!values$new!ContentValues:H;5 !!values.put:1rovider.)onstants.-.-+*G!wrapper.getTitle:;;5 !!values.put:1rovider.)onstants.7A+2*G!wrapper.getValue:;;5 !!getContent$esol er:;.insert:1rovider.)onstants.),/-*/-_2R.G !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!values;5 !!constants)ursor.re.uery:;5 <
-n this %ase, all =e o is populate the title. #in%e =e get a 2ri ba%k, =e %an turn aroun an get a )ursor on that 2ri &via managedTuery:uriG!1R,=*)-.,/G! nullG!null;' an reuse our e:isting up ate logi% to a in any a itional ata beyon the title itsel$. Also, i$ =e alrea y have an outstan ing )ursor $or the %ontent provi er6s %ontents, %all reJuery:; on that to up ate )ursor. 4his, in turn, =ill up ate any Simple)ursorAdapter you may have =rapping the )ursor O an that =ill up ate any sele%tion =i gets &e.g., +ist7iew' you have using the a apter.
%7;
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
4o elete one or more ro=s $rom the %ontent provi er, use the delete:;! metho on )ontentResolver. 4his =orks akin to a #HL D*+*-* statement an takes three parameters* ,. A 2ri representing the %olle%tion &or instan%e' you =ish to up ate
2. A %onstraint statement, $un%tioning like a #HL C3*R* %lause, to etermine =hi%h ro=s shoul be up ate ?. An optional set o$ parameters to bin repla%ing any > that appear there into the %onstraint %lause,
%7*
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
CHAPTER &*
.uil ing a %ontent provi er is probably the most %ompli%ate an te ious task in all o$ An roi evelopment. 4here 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 =ay 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'. 4hat being sai , buil ing a %ontent provi er is o$ huge importan%e i$ your appli%ation =ishes 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, Nust a%%essing the ata ire%tly $rom your a%tivities. .ut, i$ you =ant your ata to possibly be use by others O $or e:ample, you are buil ing a $ee rea er an you =ant other programs to be able to a%%ess the $ee s you are o=nloa ing an %a%hing O then a %ontent provi er is right $or you.
%7Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
When buil ing a %ontent provi er, though, you nee to kno= a bit more about the innar s o$ the %ontent 2ri. A %ontent 2ri has t=o to $our pie%es, epen ing on situation*
-t al=ays has a s%heme &content#//', in i%ating it is a %ontent 2ri! instea o$ a 2ri to a Web resour%e &&ttp#//'. -t al=ays has an authority, =hi%h is the $irst path segment a$ter the s%heme. 4he authority is a uni;ue string i enti$ying the %ontent provi er that han les the %ontent asso%iate =ith this 2ri. -t may have a ata type path, =hi%h is the list o$ path segments a$ter the authority an be$ore the instan%e i enti$ier &i$ any'. 4he 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/goo' as nee e to han le =hatever ata a%%ess s%enarios the %ontent provi er re;uires. -t may have an instan%e i enti$ier, =hi%h is an integer i enti$ying a spe%i$i% pie%e o$ %ontent. A %ontent 2ri =ithout an instan%e i enti$ier re$ers to the %olle%tion o$ %ontent represente by the authority &an , =here provi e , the ata path'.
(or e:ample, a %ontent 2ri %oul be as simple as content#//se rits, =hi%h =oul re$er to the %olle%tion o$ %ontent hel by =hatever %ontent provi er =as tie to the se rits authority &e.g., Secrets1rovider'. >r, it %oul be as %omple: as content#//se rits/card/pin/?V, =hi%h =oul re$er to a pie%e o$ %ontent &i enti$ie as ?V' manage by the se rits %ontent provi er that is o$ the ata type card/pin.
types. >ne M-MI type =ill represent the %olle%tionP the other =ill represent an instan%e. 4hese map to the 2ri patterns above $or no2i enti$ier an i enti$ier, respe%tively. As you sa= 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., A)-.,/_1.)M 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'. 4he %olle%tion M-MI type shoul be o$ the $orm vnd.U.cursor.dir/F, =here U is the name o$ your $irm, organiMation, or proNe%t, an F is a ot2 elimite type name. #o, $or e:ample, you might use vnd.tlagency.cursor.dir/se rits.card.pin as the M-MI type $or your %olle%tion o$ se%rets. 4he 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 '.
onCre te89
As =ith an a%tivity, the main entry point to a %ontent provi er is on)reate:;. )ere, you %an o =hatever initialiMation you =ant. -n parti%ular, here is =here you shoul laMy2initialiMe your ata store. (or e:ample, i$ you plan on storing your ata in su%h2an 2so ire%tory on an #A %ar , =ith an DML $ile serving as a Qtable o$ %ontentsQ, you shoul %he%k an see i$ that ire%tory
%70
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
an DML $ile are there an , i$ not, %reate them so the rest o$ your %ontent provi er kno=s they are out there an available $or use. #imilarly, i$ you have re=ritten your %ontent provi er su$$i%iently to %ause the ata store to shi$t stru%ture, you shoul %he%k to see =hat stru%ture you have no= an a Nust it i$ =hat you have is out o$ ate. @ou on6t =rite your o=n QinstallerQ program an so have no great =ay o$ etermining i$, =hen on)reate:; is %alle , i$ this is the $irst time ever $or the %ontent provi er, the $irst time $or a ne= release o$ a %ontent provi er that =as upgra e in2pla%e, or i$ this is Nust a normal startup. -$ your %ontent provi er uses #HLite $or storage, you %an ete%t to see i$ your tables e:ist by ;uerying on the sJlite_master table. 4his is use$ul $or laMy2 %reating a table your %ontent provi er =ill nee . (or e:ample, here is the on)reate:; metho $or 1rovider, $rom the Constants sample appli%ation*
9,verride public!boolean!onCreate:;!8 !!db$:new!Data!ase,elper:getContext:;;;.get&rita!leData!ase:;5 !!return!:db!$$!null;!>!false!#!true5 <
While that
Database3elper obNe%t,
oesn6t seem all that spe%ial, the Qmagi%Q is in the private es%ribe in the %hapter on atabase a%%ess.
=uery89
As one might e:pe%t, the Juery:; metho is =here your %ontent provi er gets etails on a ;uery some a%tivity =ants to per$orm. -t is up to you to a%tually pro%ess sai ;uery. 4he ;uery metho gets, as parameters*
%71
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
be
A String representing =hat amounts to a #HL C3*R* %lause, %onstraining =hi%h instan%es shoul be %onsi ere $or the ;uery results A StringPQ representing values to Qpour intoQ the C3*R* %lause, repla%ing any > $oun there A String representing =hat amounts to a #HL ,RD*R!6F %lause
@ou are responsible $or interpreting these parameters ho=ever they make sense an returning a )ursor that %an be use to iterate over an a%%ess the ata. As you %an imagine, these parameters are aime to=ar s people using a #HLite atabase $or storage. @ou are =el%ome to ignore some o$ these parameters &e.g., you ele%t not to try to roll your o=n #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 #HLite2ba%ke storage provi ers, ho=ever, the Juery:; metho implementation shoul be largely boilerplate. "se a ST+iteTuery6uilder to %onvert the various parameters into a single #HL statement, then use Juery:; on the buil er to a%tually invoke the ;uery an give you a )ursor! ba%k. 4he )ursor is =hat your Juery:; metho then returns. (or e:ample, here is Juery:; $rom 1rovider*
9,verride public!)ursor!.uery:2ri!urlG!StringPQ!projectionG!String!selectionG !!!!!!!!!!!!!!!!!!!!!StringPQ!selectionArgsG!String!sort;!8 !!ST+iteTuery6uilder!Jb$new!S/Lite/ueryBuilder:;5 !!Jb.setTa!les:getTa!le%ame:;;5 !!if!:isCollection)ri:url;;!8 !!!!Jb.set(ro0ection'ap:getDefault(ro0ection:;;5 !!< !!else!8 !!!!Jb.append&here:getIdColumn%ame:;B%$%Burl.get(athSegments:;.get:?;;5
%74
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
!!< !!String!order6y5 !!if!:-ext2tils.is*mpty:sort;;!8 !!!!order6y$getDefaultSortOrder:;5 !!<!else!8 !!!!order6y$sort5 !!< !!)ursor!c$Jb..uery:dbG!projectionG!selectionG!selectionArgsG !!!!!!!!!!!!!!!!!!!!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. /ote that the ;uery %oul be base aroun either a %olle%tion or an instan%e 2ri O in the latter %ase, =e nee to a the instan%e -A to the ;uery. When one, =e use the Juery:; metho on the buil er to get a )ursor $or the results.
insert89
@our insert&' metho =ill re%eive a 2ri representing the %olle%tion an a )ontent7alues stru%ture =ith the initial ata $or the ne= instan%e. @ou are responsible $or %reating the ne= instan%e, $illing in the supplie ata, an returning a 2ri to the ne= instan%e. -$ this is a #HLite2ba%ke %ontent provi er, on%e again, the implementation is mostly boilerplate* vali ate that all re;uire values =ere supplie by the a%tivity, merge your o=n notion o$ e$ault values =ith 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!)ontent7alues!initial7alues;!8 !!long!row.D5 !!)ontent7alues!values5 !!if!:initial7aluesX$null;!8 !!!!values$new!ContentValues:initial7alues;5 !!<!else!8
%77
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
!!!!values$new!ContentValues:;5 !!< !!if!:XisCollection)ri:url;;!8 !!!!t&row!new!Illegal#rgument*xception:%2n nown!2R+!%!B!url;5 !!< !!for!:String!col/ame!#!get$e.uiredColumns:;;!8 !!!!if!:values.contains1ey:col/ame;!$$!false;!8 !!!!!!t&row!new!Illegal#rgument*xception:%Missing!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$)ontent2ris.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 <
4he 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 =e vali ate that by %alling is)ollection2ri:; 4he provi er also kno=s =hat %olumns are re;uire &getReJuired)olumns:;', so =e iterate over those an %on$irm our supplie values %over the re;uirements 4he 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
upd te89
@our update:; metho gets the 2ri o$ the instan%e or %olle%tion to %hange, a )ontent7alues stru%ture =ith the ne= values to apply, a #tring $or a #HL C3*R* %lause, an a StringPQ =ith 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
%79
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
&base on the 2ri an C3*R* %lause', then repla%e those instan%es6 %urrent property values =ith the ones supplie . 4his =ill be annoying, unless you6re using #HLite $or storage. 4hen, you %an pretty mu%h pass all the parameters you re%eive to the update:; %all to the atabase, though the update:; %all =ill vary slightly epen ing on =hether you are up ating one instan%e or several. (or e:ample, here is update:; $rom 1rovider*
9,verride public!int!update:2ri!urlG!)ontent7alues!valuesG!String!w&ereG!StringPQ! w&ereArgs;!8 !!int!count5 !!if!:isCollection)ri:url;;!8 !!!!count$db.update:getTa!le%ame:;G!valuesG!w&ereG!w&ereArgs;5 !!< !!else!8 !!!!String!segment$url.get(athSegments:;.get:?;5 !!!!count$db !!!!!!!!.update:getTa!le%ame:;G!valuesG!getIdColumn%ame:;B%$% !!!!!!!!!!!!B!segment !!!!!!!!!!!!B!:X-ext2tils.is*mpty:w&ere;!>!%!A/D!:%!B!w&ere !!!!!!!!!!!!!!!!B![;[!#!%%;G!w&ereArgs;5 !!< !!getContext:;.getContent$esol er:;.notifyChange:urlG!null;5 !!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 =e %he%k the 2ri &is)ollection2ri:;' an , i$ it is an up ate $or the %olle%tion, Nust per$orm the up ate. -$ =e are up ating a single instan%e, =e nee to a a %onstraint to the C3*R* %lause to only up ate $or the re;ueste ro=.
delete89
As =ith update:;, delete:; re%eives a 2ri representing the instan%e or %olle%tion to =ork =ith 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
%9;
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
open2en e set o$ instan%es, using the C3*R* %lause to %onstrain =hi%h ones to elete. As =ith update:;, though, this is simple i$ you are using #HLite $or atabase storage &sense a themeC'. @ou %an let it han le the i iosyn%rasies o$ parsing an applying the C3*R* %lause O 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!String!w&ereG!StringPQ!w&ereArgs;!8 !!int!count5 !!long!row.d$@5 !!if!:isCollection)ri:url;;!8 !!!!count$db.delete:getTa!le%ame:;G!w&ereG!w&ereArgs;5 !!< !!else!8 !!!!String!segment$url.get(athSegments:;.get:?;5 !!!!row.d$+ong.parseLong:segment;5 !!!!count$db !!!!!!!!.delete:getTa!le%ame:;G!getIdColumn%ame:;B%$% !!!!!!!!!!!!B!segment !!!!!!!!!!!!B!:X-ext2tils.is*mpty:w&ere;!>!%!A/D!:%!B!w&ere !!!!!!!!!!!!!!!!B![;[!#!%%;G!w&ereArgs;5 !!< !!getContext:;.getContent$esol er:;.notifyChange:urlG!null;5 !!return!count5 <
4his is almost a %lone o$ the update:; implementation es%ribe above O 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'.
!etType89
4he last metho you nee returns the M-MI type %olle%tion or an instan%e an return the %orrespon to implement is get-ype:;. 4his takes a 2ri an asso%iate =ith that 2ri. 4he 2ri %oul be a 2riP you nee to etermine =hi%h =as provi e ing M-MI type.
%9*
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
As you %an see, most o$ the logi% elegates to private get)ollection-ype:;! an getSingle-ype:; metho s*
private!String!getCollectionType:;!8 !!return:%vnd.android.cursor.dir/vnd.commonsware.constant%;5 < private!String!getSingleType:;!8 !!return:%vnd.android.cursor.item/vnd.commonsware.constant%;5 <
@ou may =ish to use the same namespa%e $or the %ontent 2ri that you use $or your Gava %lasses, to re u%e the %han%e o$ %ollision =ith others.
%9%
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
#pe%i$i%ally, you =ant a publi% stati% %lass implementing 6ase)olumns that %ontains your property names, su%h as this e:ample $rom 1rovider*
public!static!final!class!)onstants!implements!6ase)olumns!8 !!public!static!final!2ri!),/-*/-_2R. !!!!!!$2ri.parse:%content#//com.commonsware.android.constants.1rovider/constants %;5 !!public!static!final!String!D*EA2+-_S,R-_,RD*R$%title%5 !!public!static!final!String!-.-+*$%title%5 !!public!static!final!String!7A+2*$%value%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 Nust pass the proNe%tion &array o$ properties' to #HLite on a Juery:;, or pass the )ontent7alues on an insert:; or update:;. /ote that nothing in here stipulates the types o$ the properties. 4hey %oul be strings, integers, or =hatever. 4he biggest limitation is =hat a )ursor %an provi e a%%ess to via its property getters. 4he $a%t that there is nothing in %o e that en$or%es type sa$ety means you shoul o%ument the property types =ell, so people attempting to use your %ontent provi er kno= =hat they %an e:pe%t.
4he android#name property is the name o$ the %ontent provi er %lass, =ith a lea ing ot to in i%ate it is in the sto%k namespa%e $or this appli%ation6s %lasses &Nust like you use =ith a%tivities'.
%9Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
4he android#aut&orities property shoul be a semi%olon2 elimite list o$ the authority values supporte by the %ontent provi er. Re%all, $rom earlier 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 ),/-*/-_2R.! value shoul be in%lu e in the android#aut&orities list. /o=, =hen 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. 4hat tells An roi =hi%h appli%ation an %lass implements the %ontent provi er, an $rom there An roi %an bri ge bet=een 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$y2on2%hange support. 4his means that your %ontent provi er =ill let %lients kno= 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 user6s $ee subs%riptions &via >!ML, perhaps'. 4he %ontent provi er o$$ers rea 2only a%%ess to the %ontents o$ the $ee s, =ith an eye to=ar s several appli%ations on the phone using those $ee s versus everyone implementing their o=n $ee poll2$et%h2 an 2%a%he system. @ou have also implemente a servi%e that =ill 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%h2an 2so $ee =as 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 notify)&ange:; on your )ontentResolver instan%e &available in your %ontent provi er via get)ontext:;.get)ontentResolver:;'. 4his takes t=o parameters* the 2ri o$ the pie%e o$ %ontent that %hange an the )ontent,bserver that initiate the %hange. -n many %ases, the latter =ill be nullP a non2null value simply means that observer =ill not be noti$ie o$ its o=n %hanges.
%9$
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
%onsumer si e, an a%tivity %an %all register)ontent,bserver:; on its )ontentResolver &via get)ontentResolver:;'. 4his ties a )ontent,bserver instan%e to a supplie 2ri O the observer =ill be noti$ie =henever notify)&ange:; is %alle $or that spe%i$i% 2ri. When the %onsumer is one =ith the 2ri, unregister)ontent,bserver:; releases the %onne%tion.
>n
the
%ontent
%90
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
CHAPTER &-
-n the late ,0006s, a =ave o$ viruses sprea through the -nternet, elivere via email, using %onta%t in$ormation %ulle $rom Mi%roso$t >utlook. A virus =oul simply email %opies o$ itsel$ to ea%h o$ the >utlook %onta%ts that ha an email a ress. 4his =as 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!- =as esigne $or or inary evelopers, not virus authors. /o=a 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. 4hose rights %oul be grante on a %ase2by2%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 =rite %onta%t ata. An roi 6s permission system is use$ul =ell beyon %onta%t ata, an $or %ontent provi ers an servi%es beyon those supplie by the An roi $rame=ork. @ou, as an An roi eveloper, =ill $re;uently nee to ensure your appli%ations have the appropriate permissions to o =hat you =ant to o =ith other appli%ations6 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. 4his %hapter %overs ho= to a%%omplish both these en s.
%94
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
+other6 +ay 8:
Re;uesting the use o$ other appli%ations6 ata or servi%es re;uires the usespermission element to be a e to your AndroidManifest.xml $ile. @our mani$est may have Mero or more uses-permission elements, all as ire%t %hil ren o$ the root manifest element. 4he uses-permission element takes a single attribute, android#name, =hi%h is the name o$ the permission your appli%ation re;uires*
"uses-permission !!android#name$%android.permission.A))*SS_+,)A-.,/%!/'
4he sto%k system permissions all begin =ith android.permission an are liste in the An roi #AE o%umentation $or Manifest.permission. 4hir 2 party appli%ations may have their o=n permissions, =hi%h hope$ully they have o%umente $or you. )ere are some o$ the more important built2in permissions*
A))*SS_M,)M_+,)A-.,/,
provi er
./-*R/*-,
i$ your appli%ation =ishes to a%%ess the -nternet through any means, $rom ra= Gava so%kets through the Ceb7iew =i get
R*AD_)A+*/DAR, R*AD_),/-A)-S,
an the like $or rea ing ata out o$ the an the like $or mo i$ying ata in
CR.-*_)A+*/DAR, CR.-*_),/-A)-S,
the built2in %ontent provi ers !ermissions are %on$irme at the time the appli%ation is installe O the user =ill be prompte to %on$irm it is >E $or your appli%ation to o =hat the permission %alls $or. 4his prompt is not available in the %urrent emulator, ho=ever. -$ 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 O $ailures may %ome in other $orms,
%97
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
4o see the e$$e%ts o$ permissions, go ba%k to the 1ic e:ample proNe%t. -$ you look at the AndroidManifest.xml $ile, you =ill see it re;uests the R*AD_),/-A)-S permission. 4his is =hat allo=s you to vie= the %onta%t in$ormation. Comment out the uses-permission element in the mani$est, re%ompile, an try out the ne= version in the emulator. @ou shoul get a Security*xception. >AT.* you may nee to restart the emulator, i$ you =ere using the 1ic Demo be$ore uring this same emulator session.
%99
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
Ae%laring a permission is slightly more %ompli%ate than using a permission. 4here are three pie%es o$ in$ormation you nee to supply* ,. 4he symboli% name o$ the permission. 4o keep your permissions $rom %olli ing =ith those $rom other appli%ations, you shoul use your appli%ation6s Gava namespa%e as a pre$i: be
2. A label $or the permission* something short that =oul un erstan able by users
?. A es%ription $or the permission* something a =ee bit longer that is un erstan able by your users
"permission !!android#name$%vnd.tlagency.se rits.S**_S*MR.-S% !!android#label$%9string/see_se rits_label% !!android#description$%9string/see_se rits_description%!/'
4his 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.
-;;
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
>nly appli%ations that have re;ueste your in i%ate permission =ill be able to a%%ess the se%ure %omponent. -n this %ase, 5a%%ess8 means*
A%tivities %annot be starte =ithout the permission #ervi%es %annot be starte , stoppe , or boun to an a%tivity =ithout the permission -ntent re%eivers ignore messages sent via broadcast.ntent:; unless the sen er has the permission istin%t attributes* read1ermission an
"provider !!android#name$%.Se rit1rovider% !!android#aut&orities$%vnd.tla.se rits.Se rit1rovider% !!android#read1ermission$%vnd.tla.se rits.S**_S*MR.-S% !!android#write1ermission$%vnd.tla.se rits.M,D_S*MR.-S%!/'
-n this %ase, read1ermission %ontrols a%%ess to ;uerying the %ontent provi er, =hile write1ermission %ontrols a%%ess to insert, up ate, or elete ata in the %ontent provi er.
%he%k permissions on a per2%all basis via c&ec )alling1ermission:;. 4his returns 1*RM.SS.,/_0RA/-*D or 1*RM.SS.,/_D*/.*D epen ing on =hether the %aller has the permission you spe%i$ie . (or e:ample, i$ your servi%e implements separate rea an =rite 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 Gava. Also, you %an in%lu e a permission =hen you %all send6roadcast:;. 4his means that eligible re%eivers must hol that permissionP those =ithout the permission are ineligible to re%eive it. (or e:ample, the An roi subsystem presumably in%lu es the R*)*.7*_SMS permission =hen it broa %asts that an
-;*
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
#M# message has arrive O this =ill restri%t the re%eivers o$ that intent to be only those authoriMe to re%eive #M# messages.
-;%
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
CHAPTER &/
Creating a Service
As note previously, An roi servi%es are $or long2running pro%esses that may nee to keep running even =hen e%ouple $rom any a%tivity. I:amples in%lu e playing musi% even i$ the QplayerQ a%tivity gets garbage2%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 =hen manually starte &via an A!- %all' or =hen some a%tivity tries %onne%ting to the servi%e via inter2pro%ess %ommuni%ation &-!C'. #ervi%es =ill live until no longer nee e an i$ RAM nee s to be re%laime . Running $or a long time isn6t =ithout 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%e6s battery to get use up too ;ui%kly. 4his %hapter %overs ho= you %an %reate your o=n servi%esP the ne:t %hapter %overs ho= you %an use su%h servi%es $rom your a%tivities or other %onte:ts. .oth %hapters =ill analyMe the Weather!lus sample appli%ation, =ith this %hapter $o%using mostly on the Ceat&er1lusService implementation. Ceat&er1lusService e:ten s the =eather2$et%hing logi% o$ the original Weather sample, by bun ling it in a servi%e that monitors %hanges in lo%ation, so the =eather is up ate as the emulator is Qmove Q.
-;Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
Creating a Service
2. onStart:;, =hi%h is %alle =hen 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:; =hi%h is %alle as the servi%e is being shut o=n Common startup an shut o=n logi% shoul go in on)reate:; an onDestroy:;P onStart:; is mostly i$ your servi%e nee s ata passe into it $rom the starting pro%ess an you on6t =ish to use -!C. (or e:ample, here is the on)reate:; metho $or Ceat&er1lusService*
9,verride public!void!onCreate:;!8 !!super.onCreate:;5 !!client$new!Default,ttpClient:;5 !!format$getString:R.string.url;5 !!bac ground$new!Thread:new!$unna!le:;!8 !!!!public!void!run:;!8 !!!!!!try!8 !!!!!!!!,bject!event$null5 !!!!!!!!w&ile!:true;!8 !!!!!!!!!!event$Jueue.poll:;5
-;$
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
Creating a Service
!!!!!!!!!!if!:event$$S32-D,C/;!8 !!!!!!!!!!!!brea 5 !!!!!!!!!!< !!!!!!!!!!else!8 !!!!!!!!!!!!update"orecast::+ocation;event;5 !!!!!!!!!!< !!!!!!!!< !!!!!!< !!!!!!catc&!:-&rowable!t;!8 !!!!!!!!//!just!end!t&e!bac ground!t&read !!!!!!< !!!!< !!<;5 !!my+ocationManager$:+ocationManager;getSystemSer ice:)ontext.+,)A-.,/_S*R7.)*;5 !!init'ock(ro ider:;5 !!bac ground.start:;5 !!ena!leLocation(oll:;5 <
(irst, =e %hain up=ar to the super%lass, so An roi %an o any setup =ork it nee s to have one. 4hen =e initialiMe our 3ttp)lient an $ormat string as =e i in the Weather emo. /e:t, =e set up a ba%kgroun threa to monitor a )oncurrent+in edTueue, looking $or ne= events. As =e6ll see, the ;ueue allo=s us to o the a%tual retrieval o$ =eather in a separate threa than those use $or the in%oming -!C metho %alls $rom the Ceat&er1lus! a%tivity. 4he on)reate:; metho =raps up by preparing the lo%ation2monitoring logi%, =hi%h =ill be is%usse in greater etail in the %hapter on lo%ation2 base servi%es. 4he onDestroy:; metho is mu%h simpler*
9,verride public!void!onDestroy:;!8 !!super.onDestroy:;5 !!disa!leLocation(oll:;5 !!Jueue.add:S32-D,C/;5 !!moc ery.close:;5 <
-;0
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
Creating a Service
)ere, =e Nust shut o=n the timer an lo%ation2monitoring logi%, in a ition to %haining up=ar 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:;. 4his metho returns an .6inder, =hi%h is the lin%hpin behin the -!C me%hanism. -$ you6re %reating a servi%e %lass =hile rea ing this %hapter, Nust have this metho return null $or no=, an =e6ll $ill in the $ull implementation in the ne:t se%tion.
-;1
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
Creating a Service
As =ith a Gava inter$a%e, you e%lare a pa%kage at the top. As =ith a Gava inter$a%e, the metho s are =rappe in an inter$a%e e%laration &interface! .Ceat&er!8!...!<'. An , as =ith a Gava inter$a%e, you list the metho s you are making available. 4he i$$eren%es, though, are %riti%al. (irst, not every Gava type %an be use as a parameter. @our %hoi%es are*
&$rom java.util'
Any other A-AL2 e$ine inter$a%es Any Gava %lasses that implement the 1arcelable inter$a%e, =hi%h is An roi 6s $lavor o$ serialiMation &see belo='
-n the %ase o$ the latter t=o %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&ing'. 4his is true even i$ these %lasses are in your o=n pa%kage O you have to import them any=ay. /e: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 =ill be propagate ba%k to the %lient. !rimitives &e.g., int' %an only be inP =e in%lu e in $or the A-AL $or enable:; Nust $or illustration purposes. Also, you %annot thro= any e:%eptions. @ou =ill nee to %at%h all e:%eptions in your %o e, eal =ith them, an return $ailure in i%ations some other =ay &e.g., error %o e return values'. /ame your A-AL $iles =ith the .aidl e:tension an pla%e them in the proper ire%tory base on the pa%kage name.
-;4
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
Creating a Service
When you buil your proNe%t, either via an -AI or via Ant, the aidl utility $rom the An roi #AE =ill translate your A-AL into a server stub an a %lient pro:y.
.Stub
%lass &e.g.,
-mplement metho s mat%hing up =ith 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
-n this %ase, the stub %alls the %orrespon ing metho on the servi%e itsel$. 4hat metho , =hi%h simply returns the %a%he most2re%ent =eather $ore%ast $or the %urrent lo%ation, is sho=n belo=*
sync&roni(ed!private!String!get"orecast(ageImpl:;!8 !!return:forecast;5 <
/ote 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 =ork.
-;7
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
Creating a Service
+anifest /estiny
(inally, you nee to a the servi%e to your AndroidManifest.xml $ile, $or it to be re%ogniMe as an available servi%e $or use. 4hat 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 Weather!lus*
">xml!version$%?.@%!encoding$%utf-A%>' "manifest!xmlns#android$%&ttp#//sc&emas.android.com/ap /res/android% !!!!pac age$%com.commonsware.android.service%' !!"uses-permission!android#name$%android.permission.7.6RA-*%!/' !!"uses-permission!android#name$%android.permission../-*R/*-%!/' !!"uses-permission!android#name$%android.permission.A))*SS_+,)A-.,/%!/' !!"uses-permission!android#name$%android.permission.A))*SS_M,)M_+,)A-.,/%!/' !!"application!android#label$%9string/app_name%' !!!!"activity!android#name$%.Ceat&er1lus%!android#label$%9string/app_name%' !!!!!!"intent-filter' !!!!!!!!"action!android#name$%android.intent.action.MA./%!/' !!!!!!!!"category!android#name$%android.intent.category.+A2/)3*R%!/' !!!!!!"/intent-filter' !!!!"/activity' !!!!"service!android#name$%.Ceat&er1lusService%!/' !!"/application' "/manifest'
#in%e the servi%e %lass is in the same Gava namespa%e as everything else in this appli%ation, =e %an use the shorthan ot2notation &%.Ceat&er1lusService%' to re$eren%e our %lass. -$ you =ish to re;uire some permission o$ those =ho =ish to start or bin to the servi%e, a an android#permission attribute naming the permission you are man ating O see the %hapter on permissions $or more etails.
Creating a Service
An alternative approa%h, $irst mentione in the %hapter on .ntent $ilters, is to have the servi%e sen a broa %ast .ntent that %an be pi%ke up by the a%tivity...assuming the a%tivity is still aroun an is not pause . We =ill e:amine the %lient si e o$ this e:%hange in the ne:t %hapterP $or no=, let us e:amine ho= the servi%e %an sen a broa %ast. 4he theory behin the Ceat&er1lusService implementation is that the servi%e gets Qti%kle Q =hen the evi%e &or emulator' position %hanges. At that point, the servi%e %alls out to the Web servi%e an generates a ne= $ore%ast Web page $or the a%tivity to isplay. At the same time, though, the servi%e also sen s a broa %ast, to alert the a%tivity that there is a page up ate available i$ it =ants it. )ere is the high2level implementation o$ the a$orementione $lo=*
private!void!update"orecast:+ocation!loc;!8 !!String!url$String.format:formatG!loc.getLatitude:;G !!!!!!!!!!!!!!!!!!!!!!!!!!!loc.getLongitude:;;5 !!3ttp0et!getMet&od$new!,ttpGet:url;5 !!try!8 !!!!Response3andler"String'!response3andler$new!Basic$esponse,andler:;5 !!!!String!response6ody$client.execute:getMet&odG!response3andler;5 !!!!String!page$generate(age:!uild"orecasts:response6ody;;5 !!!!sync&roni(ed:t&is;!8 !!!!!!forecast$page5 !!!!< !!!!sendBroadcast:broadcast;5 !!< !!catc&!:-&rowable!t;!8 !!!!android.util.+og.e:%Ceat&er1lus%G !!!!!!!!!!!!!!!!!!!!!!!%*xception!in!updateEorecast:;%G!t;5 !!< <
Mu%h o$ this is similar to the e;uivalent pie%e o$ the original Weather emo O per$orm the )44! re;uest, %onvert that into a set o$ Eorecast obNe%ts, an turn those into a Web page. 4he $irst i$$eren%e is that the Web page is simply %a%he in the servi%e, sin%e the servi%e %annot ire%tly put the page into the a%tivity6s Ceb7iew. 4he se%on i$$eren%e is that =e %all send6roadcast:;, =hi%h takes an -ntent an sen s it out to all intereste parties. 4hat .ntent is e%lare up $ront in the %lass prologue*
-*;
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
Creating a Service
private!.ntent!broadcast$new!Intent:6R,AD)AS-_A)-.,/;5
)ere, 6R,AD)AS-_A)-.,/ is simply a stati% String =ith a value that =ill istinguish this .ntent $rom all others*
public!static!final!String!6R,AD)AS-_A)-.,/$ !!!!!!!!!!%com.commonsware.android.service.Eorecast2pdate*vent%5
-**
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
CHAPTER &2
8nvoking a Service
#ervi%es %an be use by any appli%ation %omponent that Qhangs aroun Q $or a reasonable perio o$ time. 4his in%lu es a%tivities, %ontent provi ers, an other servi%es. /otably, 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 =ill get garbage %olle%te imme iately a$ter ea%h instan%e pro%esses one in%oming .ntent. 4o 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 =ere a lo%al obNe%t. When one, you %an release the inter$a%e, in i%ating you no longer nee the servi%e. -n this %hapter, =e =ill look at the %lient si e o$ the Weather!lus sample appli%ation &Ceat&er1lus'. 4he Weather!lus a%tivity looks an a=$ul lot like the original Weather appli%ation O Nust a Web page sho=ing a =eather $ore%ast*
-*Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
8nvoking a Service
4he i$$eren%e is that, as the emulator QmovesQ, the =eather $ore%ast %hanges, base on up ates provi e by the servi%e.
-*$
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
8nvoking a Service
the servi%e
2. onServiceDisconnected:;, =hi%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 )omponent/ame, =hi%h simply i enti$ies the servi%e you %onne%te to. More importantly, onService)onnected:; re%eives an .6inder instan%e, =hi%h is your gate=ay to the -!C inter$a%e. @ou =ill =ant to %onvert the .6inder into an instan%e o$ your A-AL inter$a%e %lass, so you %an use -!C as i$ you =ere %alling regular metho s on a regular Gava %lass &.Ceat&er.Stub.as.nterface:binder;'. 4o a%tually hook your a%tivity to the servi%e, %all bindService:; on the a%tivity*
!indSer ice:service.ntentG!svc)onnG!6./D_A2-,_)R*A-*;5
4he bindService:; metho takes three parameters* ,. An .ntent representing the servi%e you =ish to invoke O $or your o=n servi%e, it6s easiest to use an intent re$eren%ing the servi%e %lass ire%tly &new!.ntent:t&isG!Ceat&er1lusService.class;'
2. @our Service)onnection instan%e ?. A set o$ $lags O most times, you =ill =ant to pass in 6./D_A2-,_)R*A-*, =hi%h =ill start up the servi%e i$ it is not alrea y running A$ter your bindService:; %all, your onService)onnected:; %allba%k in the Service)onnection =ill eventually be invoke , at =hi%h time your %onne%tion is rea y $or use.
-*0
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
8nvoking a Service
Prometheus >nbound
When you are one =ith the -!C inter$a%e, %all unbindService:;, passing in the Service)onnection. Iventually, your %onne%tion6s onServiceDisconnected:; %allba%k =ill be invoke , at =hi%h point you shoul null out your inter$a%e obNe%t, isable relevant =i gets, or other=ise $lag yoursel$ as no longer being able to use the servi%e. (or obNe%t. @ou %an al=ays re%onne%t to the servi%e, via bindService:;, i$ you nee to use it again. e:ample, in the Weather!lus implementation o$ sho=n above, =e null out the .Ceat&er servi%e
onServiceDisconnected:;
+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. 4his is parti%ularly use$ul in %ases =here you =ant the servi%e to keep running in epen ently o$ your a%tivities O
-*1
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
8nvoking a Service
other=ise, on%e you unbin the servi%e, your servi%e %oul =ell be %lose o=n. 4o start a servi%e, simply %all startService:;, provi ing t=o parameters* ,. 4he .ntent spe%i$ying the servi%e to start &again, the easiest =ay is probably to spe%i$y the servi%e %lass, i$ its your o=n servi%e'
2. A 6undle provi ing %on$iguration ata, =hi%h eventually gets passe to the servi%e6s onStart:; metho Conversely, to stop the servi%e, %all stopService:; =ith the .ntent you use in the %orrespon ing startService:; %all.
Catching the ob
-n the pre%e ing %hapter, =e sho=e ho= the servi%e sen s a broa %ast to let the Ceat&er1lus a%tivity kno= a %hange =as ma e to the $ore%ast base on movement. /o=, =e %an see ho= the a%tivity re%eives an uses that broa %ast. )ere are the implementations o$ onResume:; an on1ause:; $or Ceat&er1lus*
9,verride public!void!on$esume:;!8 !!super.on$esume:;5 !!register$ecei er:receiverG !!!!!!!!new!Intent"ilter:Ceat&er1lusService.6R,AD)AS-_A)-.,/;;5 < 9,verride public!void!on(ause:;!8 !!super.on(ause:;5 !!unregister$ecei er:receiver;5 <
-n onResume:;, =e register a stati% 6roadcastReceiver to re%eive .ntents mat%hing the a%tion e%lare by the servi%e. -n on1ause:;, =e isable that
-*4
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
8nvoking a Service
6roadcastReceiver,
pause , any=ay. 4he 6roadcastReceiver, in turn, simply arranges to up ate the $ore%ast on the "- threa *
private!6roadcastReceiver!receiver$new!Broadcast$ecei er:;!8 !!public!void!on$ecei e:)ontext!contextG!.ntent!intent;!8 !!!!runOn)iThread:new!$unna!le:;!8 !!!!!!public!void!run:;!8 !!!!!!!!update"orecast:;5 !!!!!!< !!!!<;5 !!< <5
An updateEorecast:; uses the inter$a%e stub to %all into the servi%e an retrieve the latest $ore%ast page, also han ling the %ase =here the $ore%ast is not yet rea y &null'*
private!void!update"orecast:;!8 !!try!8 !!!!String!page$service.get"orecast(age:;5 !!!!if!:page$$null;!8 !!!!!!browser.postDelayed:new!$unna!le:;!8 !!!!!!!!public!void!run:;!8 !!!!!!!!!!update"orecast:;5 !!!!!!!!< !!!!!!<G!O@@@;5 !!!!!!-oast !!!!!!!!.makeText:t&isG!%/o!forecast!available%G!HL@@; !!!!!!!!.show:;5 !!!!< !!!!else!8 !!!!!!browser.loadData&ithBase)$L:nullG!pageG!%text/&tml%G !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!%2-E-A%G!null;5 !!!!< !!< !!catc&!:final!-&rowable!t;!8 !!!!svc)onn.onSer iceDisconnected:null;5 !!!!runOn)iThread:new!$unna!le:;!8 !!!!!!public!void!run:;!8 !!!!!!!!goBlooey:t;5 !!!!!!< !!!!<;5
-*7
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
8nvoking a Service
!!< <
-*9
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
CHAPTER '6
!op2up messages. 4ray 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 Nust in%oming %alls* lo= battery, alarm %lo%ks, appointment noti$i%ations, in%oming te:t message or email, et%. /ot surprisingly, An roi has a =hole $rame=ork $or ealing =ith these sorts o$ things, %olle%tively %alle Qnoti$i%ationsQ.
Types of Pestering
A servi%e, running in the ba%kgroun , nee s a =ay to users kno= something o$ interest has o%%urre , su%h as =hen email has been re%eive . Moreover, the servi%e may nee some =ay to steer the user to an a%tivity =here they %an a%t upon the event O 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 kno=n as Qnoti$i%ationsQ. @our %urrent phone may =ell have su%h i%ons, to in i%ate battery li$e, signal strength, =hether .luetooth is enable , an the like. With An roi , appli%ations %an a their o=n status bar i%ons, =ith an eye to=ar s having them appear only =hen nee e &e.g., a message has arrive '.
-%*
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
-n An roi , you %an raise noti$i%ations via the /otificationManager. 4he /otificationManager is a system servi%e. 4o use it, you nee to get the servi%e obNe%t via getSystemService:/,-.E.)A-.,/_S*R7.)*; $rom your a%tivity. 4he /otificationManager gives you three metho s* one to pester ¬ify:;' an t=o to stop pestering &cancel:; an cancelAll:;'. 4he notify:; metho takes a /otification, =hi%h is a ata stru%ture that spells out =hat $orm your pestering shoul take. )ere is =hat is at your isposal &bearing in min that not all evi%es =ill ne%essarily support all o$ these'*
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 =hat6s so important. 4o set up an i%on $or a /otification, you nee to set icon, =here you provi e the i enti$ier o$ a Drawable resour%e representing the i%on, an
-%%
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
content.ntent, =here you supply an 1ending.ntent to be raise is %li%ke . @ou shoul be sure the 1ending.ntent =ill
=hen the i%on be %aught by something, perhaps your o=n appli%ation %o e, to take appropriate steps to let the user eal =ith the event triggering the noti$i%ation. @ou %an also supply a te:t blurb to appear =hen the i%on is put on the status bar &tic er-ext'. -$ you =ant all three, the simpler approa%h is to %all set+atest*vent.nfo:;, =hi%h =raps all three o$ those in a single %all.
-%Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
!!!!!!!!!! !!!!!!!!mgr.cancel:/,-.EF_M*_.D;5 !!!!!!< !!!!<;5 !!< !! !!private!void!notify'e:;!8 !!!!final!/otificationManager!mgr$ !!!!!!:/otificationManager;getSystemSer ice:/,-.E.)A-.,/_S*R7.)*;5 !!!!/otification!note$new!%otification:R.drawable.red_ballG !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!%Status!messageX%G !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!System.currentTime'illis:;;5 !!!!1ending.ntent!i$1ending.ntent.get#cti ity:t&isG!@G !!!!!!!!!!!!!!!!!!!!!!!!!!!new!Intent:t&isG!/otifyMessage.class;G !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!@;5 !!!! !!!!note.setLatest* entInfo:t&isG!%/otification!-itle%G !!!!!!!!!!!!!!!!!!!!!!!!!!!%-&is!is!t&e!notification!message%G!i;5 !!!! !!!!mgr.notify:/,-.EF_M*_.DG!note;5 !!< <
4his a%tivity sports t=o large buttons, one to ki%k o$$ a noti$i%ation a$ter a $ive2se%on elay, an one to %an%el that noti$i%ation &i$ it is a%tive'*
,.
2. Create a /otification obNe%t =ith our i%on &re ball', a message to $lash on the status bar as the noti$i%ation is raise , an the time asso%iate =ith this event ?. Create a 1ending.ntent that =ill trigger the isplay o$ another a%tivity &/otifyMessage' <. "se set+atest*vent.nfo:; to spe%i$y that, =hen the noti$i%ation is %li%ke on, =e are to isplay a %ertain title an message, an i$ that is %li%ke on, =e laun%h the 1ending.ntent B. 4ell the /otificationManager to isplay the noti$i%ation )en%e, i$ =e %li%k the top button, a$ter $ive se%on s, our re ball i%on =ill appear in the status bar, brie$ly along =ith our status message*
!igure 41< ,ur notification as it appears on the status bar6 )ith our status message
-$ you %li%k on the re ball, a ra=er =ill appear beneath the status bar. Arag that ra=er all the =ay to the bottom o$ the s%reen to sho= the outstan ing noti$i%ations, in%lu ing our o=n*
-%0
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
!igure 44< The notifications dra)er6 fully expanded6 )ith our notification
-$ you %li%k on the noti$i%ation entry in the ra=er, you6ll be taken to a trivial a%tivity isplaying a message O though in a real appli%ation, this a%tivity =oul o something use$ul base upon the event that o%%urre &e.g., take users to the ne=ly2arrive mail messages'. Cli%king on the %an%el button, or %li%king on the Clear /oti$i%ations button in the ra=er, =ill remove the re ball $rom the status bar.
-%1
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
CHAPTER '1
A popular $eature on %urrent2era mobile evi%es is 7!# %apability, so the evi%e %an tell you =here you are at any point in time. While the most popular use o$ 7!# servi%e is mapping an ire%tions, there are other things you %an o i$ you kno= your lo%ation. (or e:ample, you might set up a ynami% %hat appli%ation =here the people you %an %hat =ith are base on physi%al lo%ation, so you6re %hatting =ith those you are nearest. >r, you %oul automati%ally QgeotagQ posts to 4=itter or similar servi%es. 7!# is not the only =ay a mobile Alternatives in%lu e*
4he Iuropean e;uivalent to 7!#, %alle 7alileo, =hi%h is still un er evelopment at the time o$ this =riting Cell to=er triangulation, =here your position is etermine base on signal strength to nearby %ell to=ers !ro:imity to publi% Wi(i QhotspotsQ that have kno=n 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 =hat provi ers are available. 4here are even =ays $or you to simulate your lo%ation in the emulator, $or use in testing your lo%ation2enable appli%ations.
-%9
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
!inding .ourself
4he obvious thing to o =ith a lo%ation servi%e is to $igure out =here you are right no=. 4o o that, you nee to get a +ocationManager O %all $rom your a%tivity or servi%e an %ast it
getSystemService:+,)A-.,/_S*R7.)*; to be a +ocationManager.
out =here you are is to get the name o$ the )ere, you have t=o main options*
--;
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
,.
2. (in the best2mat%h provi er base on a set o$ %riteria -$ you =ant the user to pi%k a provi er, %alling get1roviders:; on the +ocationManager =ill give you a +ist o$ provi ers, =hi%h you %an then present to the user $or sele%tion. >r, you %an %reate an populate a )riteria obNe%t, stating the parti%ulars o$ =hat you =ant out o$ a +ocation1rovider, su%h as*
setAltitudeReJuired:;
not
setAccuracy:;
position
to %ontrol i$ the provi er must be $ree or i$ it %an in%ur a %ost on behal$ o$ the evi%e user
set)ostAllowed:;
7iven a $ille 2in )ritieria obNe%t, %all get6est1rovider:; on your +ocationManager, an An roi =ill si$t through the %riteria an give you the best ans=er. /ote that not all o$ your %riteria =ill be met O all but the monetary %ost %riterion might be rela:e i$ nothing mat%hes. (or e:ample, here is ho= Weather!lus#ervi%e $in s its lo%ation provi er*
void!ena!leLocation(oll:;!8 !!)riteria!criteria$new!Criteria:;5 !!criteria.set#ccuracy:)riteria.A))2RA)F_),ARS*;5 !!criteria.set#ltitude$e.uired:false;5 !!criteria.setCost#llowed:true;5 !!criteria.set(ower$e.uirement:)riteria.1,C*R_+,C;5 !!criteria.setSpeed$e.uired:false;5 !!String!provider$my+ocationManager.getBest(ro ider:criteriaG !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!true;5 !!my+ocationManager.re.uestLocation)pdates:providerG!?@@@@G !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!?@@@@.@fG !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!on+ocation)⦤5 <
--*
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
>n%e you kno= the name o$ the +ocation1rovider, you %an %all get+astMnown1osition:; to $in out =here you =ere re%ently. /ote, ho=ever, that Qre%entlyQ might be $airly out o$ ate &e.g., phone =as turne o$$ ' or even null i$ there has been no lo%ation re%or e $or that provi er yet. >n the other han , get+astMnown1osition:; in%urs no monetary or po=er %ost, sin%e the provi er oes not nee to be a%tivate to get the value. 4hese metho s return a +ocation obNe%t, =hi%h %an give you the latitu e an longitu e o$ the evi%e in egrees as a Gava double. -$ the parti%ular lo%ation provi er o$$ers other ata, you %an get at that as =ell*
(or altitu e, &asAltitude:; =ill tell you i$ there is an altitu e value, an getAltitude:; =ill return the altitu e in meters. (or bearing &i.e., %ompass2style ire%tion', &as6earing:; =ill tell you i$ there is a bearing available, an get6earing:; =ill return it as egrees east o$ true north. (or spee , &asSpeed:; =ill tell you i$ the spee is kno=n an getSpeed:; =ill return the spee in meters per se%on .
A more likely approa%h to getting the +ocation $rom a +ocation1rovider, though, is to register $or up ates, as es%ribe in the ne:t se%tion.
,n the +ove
/ot all lo%ation provi ers are ne%essarily imme iately responsive. 7!#, $or e:ample, re;uires a%tivating a ra io an getting a $i: $rom the satellites be$ore you get a lo%ation. 4hat is =hy An roi oes not o$$er a getMeMy)urrent+ocation/ow:; metho . Combine that =ith the $a%t that your users may =ell =ant their movements to be re$le%te in your appli%ation, an you are probably best o$$ registering $or lo%ation up ates an using that as your means o$ getting the %urrent lo%ation. 4he %o e sample sho=n in the pre%e ing se%tion not only sho=s $in ing the best2available provi er via a set o$ )riteria, but it also sho=s ho= to register $or up ates O %all reJuest+ocation2pdates:; on your +ocationManager! instan%e. 4his takes $our parameters*
--%
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
,.
2. )o= long, in millise%on s, must have elapse be$ore =e might get a lo%ation up ate ?. )o= $ar, in meters, must the evi%e have move be$ore =e might get a lo%ation up ate <. A +ocation+istener that =ill be noti$ie events, as sho=n belo=* o$ key lo%ation2relate
+ocation+istener!on+ocation)&ange$new!LocationListener:;!8 !!public!void!onLocationChanged:+ocation!location;!8 !!!!update"orecast:location;5 !!< !!public!void!on(ro iderDisa!led:String!provider;!8 !!!!//!reJuired!for!interfaceG!not!used !!< !!public!void!on(ro ider*na!led:String!provider;!8 !!!!//!reJuired!for!interfaceG!not!used !!< !!public!void!onStatusChanged:String!providerG!int!statusG !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!6undle!extras;!8 !!!!//!reJuired!for!interfaceG!not!used !!< <5
)ere, all =e o is %all updateEorecast:; =ith the +ocation supplie to the on+ocation)&anged:; %allba%k metho . 4he updateEorecast:;! implementation, as sho=n in the %hapter on %reating servi%es, buil s a Web page =ith the %urrent $ore%ast $or the lo%ation an sen s a broa %ast so the a%tivity kno=s an up ate is available. When you no longer nee the up ates, %all remove2pdates:; =ith the +ocation+istener you registere .
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. 4o a%%omplish this, +ocationManager o$$ers add1roximityAlert:;. 4his registers an 1ending.ntent, =hi%h =ill be $ire o$$ =hen the evi%e gets =ithin a %ertain istan%e o$ a %ertain lo%ation. 4he add1roximityAlert:;! metho takes, as parameters*
4he latitu e an longitu e o$ the position that you are intereste in A ra ius, spe%i$ying ho= %lose you shoul be to that position $or the .ntent to be raise A uration $or the registration, in millise%on s O a$ter this perio , the registration automati%ally lapses. A value o$ -? means the registration lasts until you manually remove it via remove1roximityAlert:;. 4he 1ending.ntent to be raise =hen the evi%e is =ithin the Qtarget MoneQ e:presse by the position an ra ius
/ote that it is not guarantee that you =ill 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 Mone 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 Mone, or go by so ;ui%kly that the evi%e6s lo%ation isn6t sample =hile in the target Mone. -t is up to you to arrange $or an a%tivity or intent re%eiver to respon to the .ntent you register =ith the pro:imity alert. What you then o =hen 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%. /ote that you =ill re%eive the .ntent =henever the position is sample an you are =ithin the target Mone O not Nust upon entering the Mone. )en%e, you =ill get the .ntent several times, perhaps ;uite a $e= times epen ing on the siMe o$ the target Mone an the spee o$ the evi%e6s movement.
--$
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
Testing<<<Testing<<<
4he An roi emulator oes not have the ability to get a $i: $rom 7!#, triangulate your position $rom %ell to=ers, or i enti$y your lo%ation by some nearby Wi(i signal. #o, i$ you =ant to simulate a moving evi%e, you =ill nee to %reate an use a mo%k lo%ation provi er. 4his basi%ally allo=s you to a in your o=n sour%e o$ lo%ation in$ormation an use that in testing your appli%ations. As part o$ the Weather!lus appli%ation, you =ill $in a $rame=ork $or mo%k lo%ation provi ers, %alle Moc ery. 4his se%tion =ill e:plain ho= Moc ery! =orks an ho= Weather!lus integrates =ith it to simulate a moving evi%e.
When you think about it, a lo%ation provi er shoul really supplying a stea y $ee o$ lo%ations. @ou ask the provi er $or a lo%ation, an it tells you =here you are. /o=, the pra%ti%alities o$ 7!# an %ell to=er triangulation mean that +ocation1rovider %annot be =ritten that =ay. .ut, $or our lo%ation mo%king $rame=ork, =e %an sa$ely avoi reality. )en%e, the Moc ery $rame=ork has the notion o$ a lo%ation $ee , e$ine via the ._+ocationEeed inter$a%e*
pac age!com.commonsware.android.service5 import!android.location.+ocation5 public!interface!._+ocationEeed!8 !!+ocation!get%extLocation:;5 <
A Moc ery =ill use a lo%ation $ee to $in out the lo%ations it shoul pour into the An roi mo%k lo%ation provi er system. .y using an inter$a%e, =e
--0
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
%oul , in prin%iple %reate $ee s that pull $rom $iles, $rom an array o$ +ocations har =ire in %o e, or =herever else =e %hoose. -n Weather!lus, =e have a +inear+ocationEeed. 4his %lass takes a beginning an en ing position, plus a length o$ time it shoul take to move bet=een them. 4he $ee oles out lo%ations base on elapse time, in a straight line $rom beginning to en . >n%e the en is rea%he , it $lips ire%tion an starts to $ee ba%k the other =ay. 4his bears little resemblan%e to any real2=orl movements, but all it re;uires is t=o latitu eUlongitu e pairs, an so re;uires very little =ork.
class!+inear+ocationEeed!implements!._+ocationEeed!8 !!+ocation!start$null5 !!+ocation!end$null5 !!long!duration$@5 !!double!latDelta$@.@d5 !!double!lonDelta$@.@d5 !!long!timeStart$@5 !! !!LinearLocation"eed:+ocation!startG!+ocation!endG !!!!!!!!!!!!!!!!!!!!!long!duration;!8 !!!!t&is.start$start5 !!!!t&is.end$end5 !!!!t&is.duration$duration5 !!!! !!!!latDelta$end.getLatitude:;-start.getLatitude:;5 !!!!lonDelta$end.getLongitude:;-start.getLongitude:;5 !!< !! !!public!+ocation!get%extLocation:;!8 !!!!if!:timeStart$$@;!8 !!!!!!timeStart$System.currentTime'illis:;5 !!!!< !!!! !!!!long!now$System.currentTime'illis:;5 !!!!long!time*lapsed$now-timeStart5 !!!! !!!!w&ile!:time*lapsed'duration;!8 !!!!!!timeStart$timeStartBduration5 !!!!!!time*lapsed$now-timeStart5 !!!!!! !!!!!!+ocation!tmp$start5 !!!!!! !!!!!!start$end5 !!!!!!end$tmp5 !!!!!!latDelta$-?.@dRlatDelta5 !!!!!!lonDelta$-?.@dRlonDelta5 !!!!< !!!!
--1
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
!!!!double!pct)omplete$:double;time*lapsed/:double;duration5 !!!! !!!!+ocation!result$new!Location:start;5 !!!! !!!!result.setLatitude:start.getLatitude:;B:pct)ompleteRlatDelta;;5 !!!!result.setLongitude:start.getLongitude:;B:pct)ompleteRlonDelta;;5 !!!!result.setTime:now;5 !!!! !!!!return:result;5 !!< <
% $in!
7iven that =e have isolate the pro%ess o$ etermining the %urrent +ocation! in the lo%ation $ee %lasses, Moc ery itsel$ is $airly straight$or=ar *
Inable sai provi er >n a perio i% basis, ask the lo%ation $ee $or the %urrent lo%ation an pass that into An roi as the %urrent position o$ the test lo%ation provi er the
(or the perio i% up ates, =e use a -imer an a -imer-as , to avoi hea a%he o$ setting up our o=n ba%kgroun threa *
class!Moc ery!8 !!private!-imer!timer$null5 !!private!._+ocationEeed!feed$null5 !!private!+ocationManager!locMgr$null5 !!private!String!moc $null5 !! !!'ockery:._+ocationEeed!feedG!long!time6etween2pdatesG !!!!!!!!!!String!moc G!+ocationManager!locMgr;!8 !!!!t&is.feed$feed5 !!!!t&is.moc $moc 5 !!!!t&is.locMgr$locMgr5 !!!! !!!!timer$new!Timer:;5 !!!! !!!!if!:locMgr.get(ro ider:moc ;$$null;!8 !!!!!!locMgr.addTest(ro ider:moc G!falseG!falseG!falseG !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!falseG!falseG!falseG!falseG !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!)riteria.1,C*R_+,CG !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!)riteria.A))2RA)F_),ARS*;5 !!!!<
--4
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
!!!! !!!! !!!!locMgr.setTest(ro ider*na!led:moc G!true;5 !!!! !!!!-imer-as !tas $new!TimerTask:;!8 !!!!!!public!void!run:;!8 !!!!!!!!update:;5 !!!!!!< !!!!<5 !!!! !!!!timer.schedule#t"ixed$ate:tas G!@G!time6etween2pdates;5 !!< !! !!void!close:;!8 !!!!timer.cancel:;5 !!!!timer$null5 !!!!locMgr.setTest(ro ider*na!led:moc G!false;5 !!< !! !!private!void!update:;!8 !!!!+ocation!loc$feed.get%extLocation:;5 !!!! !!!!locMgr.setTest(ro iderLocation:moc G!loc;5 !!< <
uring
)ere, =e %ra$t t=o lo%ations, one $or /e= @ork City an one $or Los Angeles, an have our +inear+ocationEeed set up to move bet=een them every hour &a.k.a., Qa brisk pa%eQ'. We then =ire in a Moc ery to have it pass the $ee 6s ata to the An roi test provi er system. 4he Ceat&er1lusService %lass6 enable+ocation1oll:; metho shoul , in theory, Nust use the M,)M test lo%ation provi er, to ensure =e use the same provi er that =e have mo%ke =ith the Moc ery. (or the purposes o$ illustration, though, enable+ocation1oll:; uses a )riteria obNe%t an $in s the best mat%h, using the same values as Moc ery uses to e$ine the test provi er.
--9
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
CHAPTER '&
>ne o$ 7oogle6s most popular servi%es O a$ter sear%h, o$ %ourse O is 7oogle Maps, =here you %an $in everything $rom the nearest piMMa parlor to ire%tions $rom /e= @ork City to #an (ran%is%o &only 2,00B miles9' to street vie=s an satellite imagery. An roi , not surprisingly, integrates 7oogle Maps. 4here 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, =hi%h allo= you to integrate maps into your o=n appli%ations. /ot only %an you isplay maps, %ontrol the Moom level, an allo= people to pan aroun , but you %an tie in An roi 6s lo%ation2base servi%es to sho= =here the evi%e is an =here it is going. (ortunately, integrating basi% mapping $eatures into your An roi proNe%t is $airly easy. )o=ever, there is a $air bit o$ po=er available to you, i$ you =ant to get $an%y.
MapActivity
-n your layout $or the MapActivity sub%lass, you nee to a an element name , at the time o$ this =riting, com.google.android.maps.Map7iew. 4his is the Qlonghan Q =ay to spell out the names o$ =i get %lasses, by in%lu ing the $ull pa%kage name along =ith the %lass name. 4his is ne%essary be%ause Map7iew is not in the com.google.android.widget namespa%e. @ou %an give the Map7iew =i get =hatever android#id attribute value you =ant, plus han le all the layout etails to have it ren er properly alongsi e your other =i gets. )o=ever, you o nee to have*
android#apiMey,
=hi%h in pro u%tion =ill nee to be a 7oogle Maps A!- key. (or no=, though, you %an substitute =hatever string you like here.
android#clic able!$!%true%,
(or e:ample, $rom the /oo@a=k sample appli%ation, here is the main layout*
">xml!version$%?.@%!encoding$%utf-A%>' "Relative+ayout!xmlns#android$%&ttp#//sc&emas.android.com/ap /res/android% !!android#layout_widt&$%fill_parent% !!android#layout_&eig&t$%fill_parent%' !!"com.google.android.maps.Map7iew!android#id$%9Bid/map% !!!!android#layout_widt&$%fill_parent% !!!!android#layout_&eig&t$%fill_parent% !!!!android#apiMey$%/ooFaw % !!!!android#clic able$%true%!/' !!"+inear+ayout!android#id$%9Bid/(oom% !!!!android#layout_widt&$%wrap_content% !!!!android#layout_&eig&t$%wrap_content% !!!!android#layout_align1arent6ottom$%true% !!!!android#layout_align1arent+eft$%true%!/' "/Relative+ayout'
We6ll %over that mysterious (oom +inear+ayout in the ne:t se%tion. -n a ition, you =ill AndroidManifest.xml $ile* nee a %ouple o$ e:tra things in your
-$%
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
4he ./-*R/*- an A))*SS_),ARS*_+,)A-.,/ permissions -nsi e your "application', a "uses-library' element android#name!$!%com.google.android.maps%, to in i%ate you are one o$ the optional An roi A!-s =ith using
4hat is pretty mu%h all you nee $or starters, plus to sub%lass your a%tivity $rom MapActivity. -$ you =ere to o nothing else, an built that proNe%t an tosse it in the emulator, you6 get a ni%e map o$ the =orl . /ote, ho=ever, that MapA%tivity is abstra%t O you nee to implement isRouteDisplayed:; to in i%ate i$ you are supplying some sort o$ riving ire%tions or not. -n theory, the user %oul pan aroun the map using the ire%tional pa . )o=ever, that6s not terribly use$ul =hen the user has the =hole =orl in her han s. #in%e a map o$ the =orl is not mu%h goo by itsel$, =e nee to a things... a $e=
.et=een the Map7iew an Map)ontroller, you have a $air bit o$ %apability to etermine =hat the map sho=s an ho= it behaves. )ere are some likely $eatures you =ill =ant to use*
@oom
4he map o$ the =orl you start =ith is rather broa . "sually, people looking at a map on a phone =ill be e:pe%ting something a bit narro=er in s%ope, su%h as a $e= %ity blo%ks. @ou %an %ontrol the Moom level ire%tly via the setKoom:; metho on the Map)ontroller. 4his takes an integer representing the level o$ Moom, =here , is the =orl vie= an 2, is the tightest Moom you %an get. Ia%h level is a oubling o$ the e$$e%tive resolution* , has the e;uator measuring 2B3 pi:els =i e, =hile 2, has the e;uator measuring 238,<?B,<B3 pi:els =i e. #in%e the phone6s isplay probably oesn6t have 238,<?B,<B3 pi:els in either imension, the user sees a small map $o%use on one tiny %orner o$ the globe. A level o$ ,3 =ill sho= you several %ity blo%ks in ea%h imension an is probably a reasonable starting point $or you to e:periment =ith. -$ you =ish to allo= users to %hange the Moom level, you =ill nee to o a $e= things*
(irst, pi%k a spot on the s%reen =here you =ant the Moom %ontrols to appear. 4hese are not huge, an they only appear =hen being use , so they %an overlay the a%tual map itsel$ i$ you %hoose. -n the layout sho=n above, $or e:ample, the Moom %ontrols are pla%e over the map, in the lo=er2le$t %orner o$ the s%reen. @ou shoul use a +inear+ayout or other simple %ontainer $or the Moom %ontrols6 position in your layout. -n your a%tivity6s on)reate:; metho , get your Moom %ontrols6 %ontainer via find7iew6y.d:; A the result o$ map.getKoom)ontrols:; to that %ontainer a%tivity6s on)reate:;!
(or e:ample, here are the lines $rom the /ooFaw metho that a%%omplish the latter points*
-$$
Subscribe to updates at http://commonsware.com
7iew0roup!(oom$:7iew0roup;findViewById:R.id.(oom;5 (oom.addView:map.get2oomControls:;;5
4hen, you %an manually get the Moom %ontrols to appear by %alling displayKoom)ontrols:; on your Map7iew, or they =ill automati%ally appear =hen the user pans the map.
Center
4ypi%ally, you =ill nee to %ontrol =hat the map is sho=ing, beyon the Moom level, su%h as the user6s %urrent lo%ation, or a lo%ation save =ith some ata in your a%tivity. 4o %hange the map6s position, %all set)enter:; on the Map)ontroller. 4his takes a 0eo1oint as a parameter. A 0eo1oint represents a lo%ation, via latitu e an longitu e. 4he %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 ?*N. 4his 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
-$0
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
to o to %onvert the 0eo1oint into a map position. )o=ever, it oes mean you have to remember to multiple the Qreal =orl Q latitu e an longitu e by ?*N.
3ugged Terrain
Gust as the 7oogle Maps you use on your $ull2siMe %omputer %an isplay satellite imagery, so too %an An roi maps. o$$ers toggleSatellite:;, =hi%h, as the names suggest, toggle on an o$$ this perspe%tive on the area being vie=e . @ou %an have the user trigger these via an options menu or, in the %ase o$ /ooFaw , via keypresses*
Map7iew
!9,verride !!public!boolean!on1eyDown:int! ey)odeG!Mey*vent!event;!8 !!!!if!: ey)ode!$$!Mey*vent.M*F),D*_S;!8 !!!!!!map.setSatellite:Xmap.isSatellite:;;5 !!!!!!return:true;5 !!!!< !!!!else!if!: ey)ode!$$!Mey*vent.M*F),D*_K;!8 !!!!!!map.display2oomControls:true;5 !!!!!!return:true;5 !!!!< !!!! !!!!return:super.on1eyDown: ey)odeG!event;;5 !!<
-$1
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
0verl y Cl sses
Any overlay you =ant to a to your map nee s to be implemente as a sub%lass o$ ,verlay. 4here is an .temi(ed,verlay sub%lass available i$ you are looking to a push2pins or the likeP .temi(ed,verlay simpli$ies this pro%ess. 4o atta%h an overlay %lass to your map, Nust %all get,verlays:; on your Map7iew an add:; your ,verlay instan%e to it*
Drawable!mar er$get$esources:;.getDrawa!le:R.drawable.mar er;5 mar er.setBounds:@G!@G!mar er.getIntrinsic&idth:;G !!!!!!!!!!!!!!!!!!!!!!!mar er.getIntrinsic,eight:;;5 map.getO erlays:;.add:new!SitesO erlay:mar er;;5
(irst, overri e .temi(ed,verlay",verlay.tem' as your o=n sub%lass &in this e:ample, Sites,verlay' -n the %onstru%tor, buil your roster o$ ,verlay.tem instan%es, an %all populate:; =hen they are rea y $or use by the overlay -mplement si(e:; to return the number o$ items to be han le by the overlay >verri e create.tem:; to return ,verlay.tem instan%es given an in e: When you instantiate your .temi(ed,verlay sub%lass, provi e it =ith a Drawable that represents the e$ault i%on &e.g., push2pin' to isplay $or ea%h item
-$4
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
4he marker $rom the /oo@a=k %onstru%tor is the Drawable use $or the $ourth bullet above O it sho=s a push2pin, as illustrate in the s%reen shot sho=n earlier in this %hapter. @ou may also =ish to overri e draw:; to o a better Nob o$ han ling the sha o= $or your markers. While the map =ill han le %asting a sha o= $or you, it appears you nee to provi e a bit o$ assistan%e $or it to kno= =here the QbottomQ o$ your i%on is, so it %an ra= the sha o= appropriately. (or e:ample, here is Sites,verlay*
private!class!Sites,verlay!extends!.temi(ed,verlay",verlay.tem'!8 !!private!+ist",verlay.tem'!items$new!Array+ist",verlay.tem':;5 !!private!Drawable!mar er$null5 !!public!SitesO erlay:Drawable!mar er;!8 !!!!super:mar er;5 !!!!t&is.mar er$mar er5 !!!!items.add:new!O erlayItem:get(oint:O@.VOASNIAOVI?N@IOG !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!-VI.SNA@V?SIVLN?@O;G !!!!!!!!!!!!!!!!!!!!!!!!!!!!!%2/%G!%2nited!/ations%;;5 !!!!items.add:new!O erlayItem:get(oint:O@.VNANNHSSSVOIAVG !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!-VI.SAHNAON?HHVO?V;G !!!!!!!!!!!!!!!!!!!!!!!!!!!!!%+incoln!)enter%G !!!!!!!!!!!!!!!!!!!!!!!!!!!!!%3ome!of!=a((!at!+incoln!)enter%;;5 !!!!items.add:new!O erlayItem:get(oint:O@.VNL?INOILI?NVLLG !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!-VI.SVSASL??OASANA;G !!!!!!!!!!!!!!!!!!!!!!!!!!!!!%)arnegie!3all%G !!!!!!!!!!!!%C&ere!you!go!wit&!practiceG!practiceG!practice%;;5 !!!!items.add:new!O erlayItem:get(oint:O@.V@NANO?VOS?VSSG !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!-VO.@?LVHSOHVIIVNL;G !!!!!!!!!!!!!!!!!!!!!!!!!!!!!%-&e!Downtown!)lub%G !!!!!!!!!!!!!!!!!!!!!%,riginal!&ome!of!t&e!3eisman!-rop&y%;;5 !!!!populate:;5 !!< !!9,verride !!protected!,verlay.tem!createItem:int!i;!8 !!!!return:items.get:i;;5 !!< !!9,verride !!public!void!draw:)anvas!canvasG!Map7iew!map7iewG !!!!!!!!!!!!!!!!!!!!boolean!s&adow;!8 !!!!super.draw:canvasG!map7iewG!s&adow;5 !!!!!oundCenterBottom:mar er;5
-$7
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
!!< !!9,verride !!protected!boolean!onTap:int!i;!8 !!!!-oast.makeText:/ooFaw .t&isG !!!!!!!!!!!!!!!!!!!!items.get:i;.getSnippet:;G !!!!!!!!!!!!!!!!!!!!-oast.+*/0-3_S3,R-;.show:;5 !!!!return:true;5 !!< !!9,verride !!public!int!si+e:;!8 !!!!return:items.si+e:;;5 !!< <
H ndlin! Screen T ps
An ,verlay sub%lass %an also implement on-ap:;, to be noti$ie =hen the user taps on the map, so the overlay %an a Nust =hat it ra=s. (or e:ample, in $ull2siMe 7oogle Maps, %li%king on a push2pin pops up a bubble =ith in$ormation about the business at that pin6s lo%ation. With on-ap:;, you %an o mu%h the same in An roi . 4he on-ap:; metho $or .temi(ed,verlay re%eives the in e: o$ the ,verlay.tem that =as %li%ke . -t is up to you to o something =orth=hile =ith this event. -n the %ase o$ Sites,verlay, as sho=n above, on-ap:; looks like this*
9,verride protected!boolean!onTap:int!i;!8 !!-oast.makeText:/ooFaw .t&isG !!!!!!!!!!!!!!!!!!items.get:i;.getSnippet:;G !!!!!!!!!!!!!!!!!!-oast.+*/0-3_S3,R-;.show:;5 !!return:true;5 <
)ere, =e Nust toss up a short -oast =ith the QsnippetQ $rom the ,verlay.tem, returning true to in i%ate =e han le the tap.
-$9
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
CHAPTER ''
Many, i$ not most, An roi evi%es =ill be phones. As su%h, not only =ill users be e:pe%ting to pla%e an re%eive %alls using An roi , but you =ill have the opportunity to help them pla%e %alls, i$ you =ish. Why might you =ant toC
Maybe you are =riting an An roi inter$a%e to a sales management appli%ation &a la #ales$or%e.%om' an you =ant to o$$er users the ability to %all prospe%ts =ith a single button %li%k, an =ithout them having to keep those %onta%ts both in your appli%ation an in the phone6s %onta%ts appli%ation Maybe you are =riting a so%ial net=orking 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 net=ork %onta%ts =ith the phone6s %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 =ith 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 the means to let you manipulate the phone Nust like any other pie%e o$ the An roi system.
-0*
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
Aetermine i$ the phone is in use via get)allState:;, =ith return values o$ )A++_S-A-*_.D+* &phone not in use', )A++_S-A-*_R./0./0! &%all re;ueste but still being %onne%te ', an )A++_S-A-*_,EE3,,M! &%all in progress' (in out the #-M -A &-M#-' via getSubscriber.d:; (in out the phone type &e.g., 7#M' via get1&one-ype:; or $in out the ata %onne%tion type &e.g., 7!R#, IA7I' via get/etwor -ype:;
-0%
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
!!!!"*dit-ext!android#id$%9Bid/number% !!!!!!android#layout_widt&$%fill_parent%! !!!!!!android#layout_&eig&t$%wrap_content% !!!!!!android#cursor7isible$%true% !!!!!!android#editable$%true% !!!!!!android#single+ine$%true% !!!!/' !!"/+inear+ayout' !!"6utton!android#id$%9Bid/dial% !!!!android#layout_widt&$%fill_parent%! !!!!android#layout_&eig&t$%wrap_content% !!!!android#layout_weig&t$%?% !!!!android#text$%Dial!.tX% !!/' "/+inear+ayout'
We have a labele $iel $or typing in a phone number, plus a button $or ialing sai number. 4he Gava %o e simply laun%hes the ialer using the phone number $rom the $iel *
pac age!com.commonsware.android.dialer5 import!android.app.Activity5 import!android.content..ntent5 import!android.net.2ri5 import!android.os.6undle5 import!android.view.7iew5 import!android.widget.6utton5 import!android.widget.*dit-ext5 public!class!DialerDemo!extends!Activity!8 !!9,verride !!public!void!onCreate:6undle!icicle;!8 !!!!super.onCreate:icicle;5 !!!!setContentView:R.layout.main;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 !!!!!!!!String!toDial$%tel#%Bnumber.getText:;.toString:;5 !!!!!!!! !!!!!!!!start#cti ity:new!Intent:.ntent.A)-.,/_D.A+G !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!2ri.parse:toDial;;;5 !!!!!!< !!!!<;5 !!< < -0Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
)o=ever, the ialer you get $rom %li%king the ial button is better, sho=ing you the number you are about to ial*
-0$
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
-00
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
CHAPTER '(
>ne o$ the $irms behin the >pen )an set Allian%e O 7oogle O has a teeny =eeny Web sear%h servi%e, one you might have hear o$ in passing. 7iven that, it6s not surprising that An roi has some amount o$ built2in 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 allo=ing your appli%ation6s ata to be sear%he . /ote that this is $airly ne= 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
4here are t=o types o$ sear%h in An roi * lo%al an global. Lo%al sear%h sear%hes =ithin the %urrent appli%ationP global sear%h sear%hes the Web via 7oogle6s sear%h engine. @ou %an initiate either type o$ sear%h in a variety o$ =ays, in%lu ing*
@ou %an %all onSearc&ReJuested:; $rom a button or menu %hoi%e, =hi%h =ill initiate a lo%al sear%h &unless you overri e this metho in your a%tivity'
-04
@ou %an ire%tly %all startSearc&:; to initiate a lo%al or global sear%h, in%lu ing optionally supplying a sear%h string to use as a starting point @ou %an ele%t to have keyboar entry ki%k o$$ a sear%h via setDefaultMeyMode:;, $or either lo%al sear%h &setDefaultMeyMode:D*EA2+-_M*FS_S*AR)3_+,)A+;' or global sear%h &setDefaultMeyMode:D*EA2+-_M*FS_S*AR)3_0+,6A+;'
-n either %ase, the sear%h appears as a set o$ "- %omponents a%ross the top o$ the s%reen, =ith your a%tivity blurre un erneath it.
-07
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
!igure 7%< The (ndroid global search popup6 sho)ing a drop"do)n )ith previous searches
Search .ourself
>ver the long haul, there =ill be t=o $lavors o$ sear%h available via the An roi sear%h system* ,. Huery2style sear%h, =here the user6s sear%h string is passe to an a%tivity =hi%h is responsible $or %on u%ting the sear%h an isplaying the results
2. (ilter2style sear%h, =here the user6s 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 no= by the An roi team, let6s $o%us on the $irst one.
-09
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
-1;
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
!!/' "/+inear+ayout'
-n terms o$ Gava %o e, most o$ the guts o$ the a%tivities are poure into an abstra%t +orem6ase %lass*
abstract!public!class!+orem6ase!extends!+istActivity!8 !!abstract!+istAdapter!make'e#n#dapter:.ntent!intent;5 !! !!private!static!final!int!+,)A+_S*AR)3_.D!$!Menu.E.RS-B?5 !!private!static!final!int!0+,6A+_S*AR)3_.D!$!Menu.E.RS-BH5 !!private!static!final!int!)+,S*_.D!$!Menu.E.RS-BI5 !!-ext7iew!selection5 !!Array+ist"String'!items$new!Array+ist"String':;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 !!!!!!Uml1ull1arser!xpp$get$esources:;.get-ml:R.xml.words;5 !!!!!! !!!!!!w&ile!:xpp.get* entType:;X$Uml1ull1arser.*/D_D,)2M*/-;!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 !!!!!!-oast !!!!!!!!.makeText:t&isG!%ReJuest!failed#!%Bt.toString:;G!O@@@; !!!!!!!!.show:;5 !!!!< !!!! !!!!setDefault1ey'ode:D*EA2+-_M*FS_S*AR)3_+,)A+;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 !!!!<
-1*
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
!!!!else!8 !!!!!!setList#dapter:adapter;5 !!!!< !!< !! !!public!void!onListItemClick:+ist7iew!parentG!7iew!vG!int!positionG !!!!!!!!!!!!!!!!!!long!id;!8 !!!!selection.setText:items.get:position;.toString:;;5 !!< !!!! !!9,verride !!public!boolean!onCreateOptions'enu:Menu!menu;!8 !!!!menu.add:Menu./,/*G!+,)A+_S*AR)3_.DG!Menu./,/*G!%+ocal!Searc&%; !!!!!!!!!!!!.setIcon:android.R.drawable.ic_searc&_category_default;5 !!!!menu.add:Menu./,/*G!0+,6A+_S*AR)3_.DG!Menu./,/*G!%0lobal!Searc&%; !!!!!!!!!!!!.setIcon:R.drawable.searc&; !!!!!!!!!!!!.set#lpha!eticShortcut:Searc&Manager.M*/2_M*F;5 !!!!menu.add:Menu./,/*G!)+,S*_.DG!Menu./,/*G!%)lose%; !!!!!!!!!!!!.setIcon:R.drawable.eject; !!!!!!!!!!!!.set#lpha!eticShortcut:[c[;5 !! !!!!return:super.onCreateOptions'enu:menu;;5 !!< !!9,verride !!public!boolean!onOptionsItemSelected:Menu.tem!item;!8 !!!!switc&!:item.getItemId:;;!8 !!!!!!case!+,)A+_S*AR)3_.D# !!!!!!!!onSearch$e.uested:;5! !!!!!!!!return:true;5 !!!!!! !!!!!!case!0+,6A+_S*AR)3_.D# !!!!!!!!startSearch:nullG!falseG!nullG!true;5! !!!!!!!!return:true;5 !!!!!! !!!!!!case!)+,S*_.D# !!!!!!!!finish:;5 !!!!!!!!return:true;5 !!!!< !!!!return:super.onOptionsItemSelected:item;;5 !!< <
4his a%tivity takes %are o$ everything relate to sho=ing a list o$ =or s, even loa ing the =or s out o$ the DML resour%e. What it oes not o is %ome up =ith the +istAdapter to put into the +ist7iew O that is elegate to the sub%lasses. 4he main a%tivity O +oremDemo O Nust uses a +istAdapter $or the =hole =or list*
-1%
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
pac age!com.commonsware.android.searc&5 import!android.content..ntent5 import!android.widget.ArrayAdapter5 import!android.widget.+istAdapter5 public!class!+oremDemo!extends!+orem6ase!8 !!9,verride !!+istAdapter!make'e#n#dapter:.ntent!intent;!8 !!!!return:new!ArrayAdapter"String':t&isG !!!!!!!!!!!!!!!!!!!!!android.R.layout.simple_list_item_?G !!!!!!!!!!!!!!!!!!!!!items;;5 !!< <
4he sear%h a%tivity, though, oes things a bit i$$erently. (irst, it inspe%ts the .ntent supplie to the abstra%t ma eMeAnAdpater:;! metho . 4hat .ntent %omes $rom either on)reate:; or on/ew.ntent:;. -$ the intent is a A)-.,/_S*AR)3, then =e kno= 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$ =or s an $in only those %ontaining the sear%h string. 4hat list then gets =rappe in a +istAdapter an returne $or isplay*
pac age!com.commonsware.android.searc&5 import!android.app.Searc&Manager5 import!android.content..ntent5 import!android.widget.ArrayAdapter5 import!android.widget.+istAdapter5 import!java.util.Array+ist5 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.A)-.,/_S*AR)3;;!8 !!!!!!String!Juery$intent.getString*xtra:Searc&Manager.T2*RF;5 !!!!!!+ist"String'!results$searchItems:Juery;5 !!!!!! !!!!!!adapter$new!ArrayAdapter"String':t&isG !!!!!!!!!!!!!!!!!!!!!!!android.R.layout.simple_list_item_?G !!!!!!!!!!!!!!!!!!!!!!!results;5 !!!!!!setTitle:%+oremSearc&!for#!%BJuery;5 !!!!< !!!! !!!!return:adapter;5
-1Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
!!< !! !!private!+ist"String'!searchItems:String!Juery;!8 !!!!+ist"String'!results$new!Array+ist"String':;5 !!!! !!!!for!:String!item!#!items;!8 !!!!!!if!:item.indexOf:Juery;'-?;!8 !!!!!!!!results.add:item;5 !!!!!!< !!!!< !!!! !!!!return:results;5 !!< <
-1$
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
,.
4he +oremDemo main a%tivity gets a meta-data element, =ith 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*AR)3, so sear%h intents =ill be pi%ke up
2. 4he
$or
?. 4he +oremSearc& a%tivity is set to have android#launc&Mode ! $! %single-op%, =hi%h means at most one instan%e o$ this a%tivity =ill be open at any time, so =e on6t =in up =ith a =hole bun%h o$ little sear%h a%tivities %luttering up the a%tivity sta%k <. 4he +oremSearc& a%tivity gets a meta-data element, =ith an android#name o$ android.app.searc&able an a android#value o$ an DML resour%e %ontaining more in$ormation about the sear%h $a%ility o$$ere by this a%tivity &9xml/searc&able'
"searc&able!xmlns#android$%&ttp#//sc&emas.android.com/ap /res/android% !!!!android#label$%9string/searc&+abel% !!!!android#&int$%9string/searc&3int%!/'
4hat DML resour%e provi es t=o 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 =here she is sear%hing &android#label'
2. What hint te:t shoul appear in the sear%h $iel , to give the user a %lue as to =hat they shoul be typing in &android#&int'
-10
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
!igure 7-< The orem sample application6 sho)ing the local search popup
4yping in a letter or t=o, then %li%king #ear%h, =ill bring up the sear%h a%tivity an the subset o$ =or s %ontaining =hat you type , =ith your sear%h ;uery in the a%tivity title bar*
-11
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
!igure 7$< The results of searching for AcoA in the orem search sample
@ou %an get the same e$$e%t i$ you Nust start typing in the main a%tivity, sin%e it is set up $or triggering a lo%al sear%h.
-14
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
@ey)ord 8ndex
Class..................................................
AbsoluteLayout.....................................................,28 A%tionIvent............................................................20 A%tionListener........................................................20 A%tivity 8, 1<, ,B,, ,B2, ,30, ,32, ,33, ,1?, ,1<, ,0?, 2,0, 2B?, 2BB A%tivityA apter.......................................1<, 238, 210 A%tivity-%onA apter...............................................1< A%tivityManager....................................................,B1 A apter.......................................................00, 02, 0? A apterWrapper............................................,00, ,,0 AlertAialog.....................................................,B2, ,B? AnalogClo%k..........................................................,20 ArrayA apter..............12, 1?, 1B, 82, 0,, ,02, ,0<, ,02 ArrayList................................................................,02 AutoComplete........................................................8B AutoComplete4e:t+ie=.............................?8, 8<283 .aseColumns........................................................20? .o:..........................................................................<1 .o:Layout...............................................................<1
.roa %astRe%eiver...........................2B2, 2B?, ?,1, ?,8 .uil er.............................................................,B2, ,B? .un le.....................................,31, ,30, 2<0, 2B8, ?,1 .utton................................2B, 212?0, ?<, ?B, 20,, 20B Calen ar.................................................................,,8 Char#e;uen%e.......................................................?01 Che%kA apter.......................................................,0< Che%k.o:....................................................?0, <2, << Che%k.o:!re$eren%e.............................................,1B Chrono...................................................................,,3 Clo%ks....................................................................,20 Component/ame..................................230, 210, ?,B Compoun .utton..................................................<2 Con%urrentLinke Hueue.....................................?0B Constants.ro=ser.................................213, 211, 280 ContentManager...................................................?22 Content>bserver..........................................20<, 20B Content!rovi er............................22<, 280, 28,, 28B ContentResolver....................................28,, 20<, 20B Content+alues.......................22,, 280, 288, 280, 20?
-17
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
@ey)ord 8ndex
Conte:t.........................12, ,B2, ,1?, ,1<, ,0?, 2,0, 211 Conte:tMenu..................................................,?2, ,?? Conte:tMenu.Conte:tMenu-n$o..........................,?2 Criteria....................................................??,, ??2, ??0 Critieria..................................................................??, Cursor...1?, 0B, ,0<, 22?, 22B, 223, 21B, 211228,, 281, 288, 20? CursorA apter........................................................1? Aatabase)elper...................................................283 Aate(ormat............................................................,,8 Aate!i%ker..............................................................,,B Aate!i%kerAialog............................................,,B, ,,8 Aea >bNe%tI:%eption...........................................?,3 Ae$ault)ttpClient................................................2?8 Aialer.....................................................................?B2 AialogWrapper.....................................................280 AigitalClo%k..........................................................,20 Ao%ument.............................................................,02 Aouble...................................................................2B1 Ara=able...........................88, ,2B, 20<, ?22, ?<1, ?<8 I it!re$eren%es.....................................................,13 I it4e:t!re$eren%e................................................,8B I it+ie=..................................?3, ?1, 8<, 8B, ,,B, 21B I:pan ableList+ie=.............................................,28 (iel .........................................................................?1 (lo=Layout.............................................................<8 (ore%ast..........................................................2<,, ?,0 (rameLayout...................................................,2?2,2B 7allery...............................................................1,, 88 7eo!oint.......................................................?<B, ?<3 7ri ..........................................................................8, 7ri +ie=.....................................................80, 8,, 88 )an ler....................................................,B12,32, ,38 )elpA%tivity..........................................................2B1 )ttpClient.............................2?8, 2<0, 2<2, 2<?, ?0B )ttp7et.........................................................2?8, 2<0 )ttp!ost................................................................2?8 )ttpRe;uest.........................................................2?8 )ttpResponse.......................................................2?8 -[Lo%ation(ee .....................................................??B -.in er...........................................................?03, ?,B -mage.utton...........................................?B, 20<, 20B -mages...................................................................20< -mage+ie=............................?B, 0<, 08, ,0,, 20<, 28, -nputMetho ..........................................................?1 -nput#tream.....................................,80, ,02, ,0?, 2<, -nput#treamRea er...............................................,0? -nteger...................................................................,0< -ntent. .,22, ,<3, 2<0, 2B?, 2382210, 28B, ?,0, ?,,, ?,?, ?,B, ?,1, ?,8, ??<, ?B2, ?3? -nterpreter.............................................................2?2 -temiMe >verlay...........................................?<1, ?<0 -terator..................................................................210 -Weather...............................................................?03 G.utton...............................................................20, 2, GChe%k.o:...............................................................12 GCombo.o:.............................................................13 GLabel......................................................................12 GList.........................................................................12 G4abbe !ane..........................................................,22 G4able......................................................................12 Label.......................................................................?<
-19
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
@ey)ord 8ndex
Laun%h..................................................................2B8 Layout-n$later..................................................0<, ,,, Linear.......................................................................B, LinearLayout<12B2, 3<, 00, 0<, ,0B, ,,,, ,2B, ?<2, ?<< LinearLo%ation(ee ......................................??3, ??0 List..............................................1<, ,??, 210, ?01, ??, ListA%tivity..........................................1<, 1B, ,2<, ?<, ListA apter.........................,082,,0, ,,?, ,28, ?32, ?3? ListCellRen erer.....................................................12 ListAemo...............................................................,?3 List!re$eren%e.......................................................,8B List+ie=....1?, 1<, 13, 11, 8820,, 0B, 03, ,0,, ,02, ,08, ,,?, ,??, 2?0, 211, 218, 280, ?<,, ?30, ?32 Lo%ation..................................2?0, ??2, ???, ??3, ??1 Lo%ationListener...................................................??? Lo%ationManager...................................??02??2, ??< Lo%ation!rovi er....................................??02??2, ??B Lorem....................................................................?30 Lorem.ase.............................................................?3, LoremAemo..................................................?32, ?3B Lorem#ear%h.........................................................?3B Map.........................................................,1?, 22,, ?01 MapA%tivity....................................................?<,2?<? MapController..............................................?<<, ?<B Map+ie=........................................................?<,2?<1 Menu.......................................................,?0, ,?2, 238 Menu.-tem............................................................210 Menu-tem.........................................................,?,2,?? Menus....................................................................,?? Message.............................................,B?, ,B8, ,30, ,3, Mo%kery..................................................??B, ??12??0 MyA%tivity............................................................230 /oo@a=k.......................................................?<<, ?<3 /oti$i%ation...................................................?22, ?2B /oti$i%ationManager....................................?22, ?2B /oti$yAemo..........................................................?2? /oti$yMessage......................................................?2B /o=..............................................................,0, 20, ?0 /o=Re u:..............................................................20 >nChe%ke ChangeListener......................?0, <0, B< >nCli%kListener................................20, ,,8, ,BB, 2B0 >nAateChange Listener......................................,,3 >nAate#etListener.........................................,,3, ,,8 >n-tem#ele%te Listener........................................18 >n4imeChange Listener.....................................,,3 >n4ime#etListener.........................................,,3, ,,8 >utput#tream.......................................................,0? >utput#treamWriter............................................,0? >verlay..........................................................?<1, ?<0 >verlay-tem..................................................?<1, ?<0 !a%kageManager..................................................210 !ar%elable..............................................................?01 !en ing-ntent........................................?2?, ?2B, ??< !i%k...............................................................23<, 200 !i%kAemo.............................................................200 !re$eren%e..............................................................,1B !re$eren%eA%tivity.................................................,82 !re$eren%eCategory........................................,8,, ,82 !re$eren%e#%reen.....................................,1B, ,8,, ,82 !re$eren%esManager..............................................,1< !rogress.ar......................................,22, ,B0, ,30, ,3?
-4;
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
@ey)ord 8ndex
!rovi er..................................213, 2832288, 200220? Ra io.utton..........................................<22<<, <1, B2 Ra io7roup...............................<2, <?, <1, B2, B<, BB RateableWrapper.......................................,,0, ,,,, ,,? RateList+ie=.............................................,08, ,,2, ,,? Rating.ar.......................,0,, ,02, ,0<, ,0B, ,,,, ,,?, ,,< Rea Write..............................................................,0? Relative...................................................................B0 RelativeLayout...........................<1, B3, B1, 30, 3,, 3B RemoteI:%eption..................................................?,3 Resour%es.......................................................,80, 201 Ringtone!re$eren%e...............................................,1B Ro=Mo el......................................................,0<, ,0B Runnable...........................................,B1, ,B8, ,3,, ,32 #%roll.......................................................................33 #%roll+ie=..................................................<1, 33, 38 #e%rets!rovi er....................................................28< #e%urityI:%eption........................................208, 200 #ervi%e...........................................................?0<, ?08 #ervi%eConne%tion.........................................?,<2?,3 #hare !re$eren%es...................................,1<, ,1B, ,8B #impleA apter........................................................1? #impleCursorA apter...........................211, 218, 280 #imple!re$sAemo..........................................,11, ,10 #ites>verlay...................................................?<12?<0 #panne ........................................................,00, 200 #pinner..........................................13, 11, 8<, 88, 211 #HLiteAatabase..............................................2,0222, #HLiteAatabase.Cursor(a%tory...........................223 #HLite>pen)elper...............................................2,0 #HLiteHuery.uil er.............222, 22<, 22B, 281, 288 #tati%..............................................................,00, 201 #tring. ,0<, ,B2, ,B?, ,1?, 200, 202, 2?8, 2B8, 21B, 281, ?01, ?,, #trings...................................................................200 4ab.........................................................................,2< 4abA%tivity.....................................................,2<, ,2B 4ab)ost...........................................................,222,23 4able.......................................................................3B 4ableLayout..........................................<1, 3223B, ,10 4ableRo=...........................................................3223< 4ab#pe%..........................................................,2B, ,23 4abWi get.......................................................,2?2,2B 4elephonyManager...............................................?B2 4e:t+ie= 28, ??2?3, ?0, <2, 1?, 82, 8?, 0,, 0<, 08, ,0,, ,0B, ,,8, ,20, 218, ?30 4e:tWat%her.....................................................8B, 83 4ime!i%ker.......................................................,,B, ,,3 4ime!i%kerAialog.....................................,,B, ,,3, ,,8 4imer.....................................................................??1 4imer4ask.............................................................??1 4oast..................................,B,, ,B2, ,BB, 2?<, 2<0, ?<0 "-4hrea "tilities..................................................,B1 "ri......?B, 20<, 22B, 2<8, 2<0, 2B,, 2B2, 2BB, 2B1, 2B0, 23?223B, 230, 21?2213, 280, 28,, 28?2202, 20<, 20B, ?22, ?B2 +ie=....2B, 20, <<, 3<, 38, 18, 00, 02, 0<203, 08, ,00, ,0,, ,0B, ,,,, ,?2, ,B2, ,B1, ,3,, ,32 +ie=-n$late.............................................................0< +ie=Wrapper..............................002,0,, ,0<, ,0B, ,,2 Weather................................................................2?8 WeatherAemo......................................................2<0 Weather!lus.....................................?0B, ?,?, ?,<, ?,1
-4*
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
@ey)ord 8ndex
Weather!lus#ervi%e...............?0?, ?0<, ?,0, ??8, ??0 WebEit..........................................................2?8, 2<0 Web#ettings..........................................................,<0 Web+ie=.............................,<,2,<?, ,<B2,<0, 208, ?,0 Web+ie=Client.............................................,<3, ,<8 Dml!ull!arser..............................................201, 208 AL4IR/A4-+I[CA4I7>R@...............................230 .-/A[A"4>[CRIA4I.........................................?,B C>/4I/4["R-...................................................20< AI(A"L4..............................................................2<0 AI(A"L4[CA4I7>R@........................................210 AILI4I..................................................22,, 222, 28, I/A[A>C"MI/4..............................................201
Command..........................................
a%tivityCreator......................................................2?0 a b pull.................................................................221 a b push................................................................221 a b shell................................................................223 ant.........................................................................8, 0 ant Nar%ore..............................................................2?, ant release................................................................0 e:..........................................................................2?, Narsigner....................................................................0 s;lite?............................................................223, 221
I/A[4A7.............................................................201 7I4.......................................................................2?8 )>R-L>/4AL.......................................................<8 -/#IR4....................................................2,8, 22,, 222 -/4I7IR...............................................................2,8 LAR7IR.................................................................,<0 LA"/C)IR...................................................2<0, 2B, LI/74)[L>/7...................................................,B2 LI/74)[#)>R4.................................................,B2 MA-/.....................................................................2B, MA4C)[AI(A"L4[>/L@..................................210 /"LL.....................................................................22, >RAIR .@............................................................21B !IRM-##->/[AI/-IA........................................?0, !IRM-##->/[7RA/4IA....................................?0, !>#4.....................................................................2?8 R..............................................................................20 RIAA[C>/4AC4#..............................................200 RICI-+I[#M#......................................................?0, RI#"L4[CA/CILLIA.........................................2B8 RI#"L4[(-R#4["#IR.........................................2B8 RI#"L4[>E.........................................2B8, 23<, 23B #ILIC4...................................................2,8, 222, 22B
Constant............................................
ACCI##[A##-#4IA[7!#.....................................??0 ACCI##[CILL[-A................................................??0 ACCI##[7!#........................................................??0 ACCI##[L>CA4->/...........................................??0 AC4->/[IA-4.....................................................2<8 AC4->/[!-CE..............2<8, 2B8, 23<, 23B, 21B, 28B AC4->/[#IARC)...............................................?3? AC4->/[4A7......................................................238 AC4->/[+-IW....................................2<8, 2B1, 23B AL4IR/A4I[CA4I7>R@...................................230 AL4IR/A4-+I.............................................2<0, 230
-4%
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
@ey)ord 8ndex
#MALLI#4............................................................,<0 #4AR4[4A7..................................................201, 208 4ID4.....................................................................201 4-4LI....................................................................218 "!AA4I.........................................................22,, 222 +IR4-CAL..............................................................<8 W)IRI..............22,222?, 22B, 21B, 28,, 281, 280220, [i .........................................................................220 %an7o.a%k&'..........................................................,<B %an7o.a%k>r(or=ar &'.......................................,<3 %an7o(or=ar &'....................................................,<B %he%k&'..............................................................<2, <? %he%kCalling!ermission&'....................................?0, %lear&'.....................................................................,1< %learCa%he&'..........................................................,<3 %learChe%k&'...........................................................<2 %lear)istory&'........................................................,<3
ðod..............................................
a a a a a a a a &'.........................................................,?0, ,?,, ?<1 - &'..................................................................21< -ntent>ptions&'................................,?,, 2382210 Menu&'.............................................................,?, !re$eren%es(romResour%e&'...........................,13 !ro:imityAlert&'.............................................??< #ubMenu&'.......................................................,?, 4ab&'................................................................,23
%lose&'.....................................................,0?, 220, 22B %ommit&'................................................................,1< %ount&'..................................................................22B %reate&'...................................................................,B? %reateAatabase&'..................................................221 %reate-tem&'..........................................................?<1 elete&'....................................22,, 222, 28,, 200, 20, isplayLoomControls&'........................................?<B ra=&'...................................................................?<8 e it&'......................................................................,1< enable&'.................................................................?01 enableLo%ation!oll&'............................................??0 e;uery&'.................................................................22B e:e%#HL&'......................................................2202222 e:e%ute&'...............................................................2?8 $in +ie=.y- &'.20, ?0, <B, 03, 082,00, ,23, ,80, ?<?, ?<< $inish&'............................................................,31, ,0B $irst&'.....................................................................22B generate!age&'......................................................2<, get&'........................................................................22, getAltitu e&'.........................................................??2
appen Where&'....................................................22B apply(ormat&'.......................................................202 applyMenuChoi%e&'.......................................,?B, ,?3 be$ore4e:tChange &'.............................................83 bin #ervi%e&'..................................................?,B, ?,3 broa %ast-ntent&'..........................................2B8, ?0, broa %ast-ntent#erialiMe &'.................................2B8 buil (ore%asts&'...................................................2<0 buil Huery&'.........................................................22B bulk-nsert&'..........................................................280 %an%el&'.................................................................?22 %an%elAll&'.............................................................?22
-4Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
@ey)ord 8ndex
getAs-nteger&'.......................................................22, getAs#tring&'.........................................................22, getAttributeCount&'.............................................208 getAttribute/ame&'.............................................200 get.earing&'..........................................................??2 get.est!rovi er&'..................................................??, get.oolean&'..........................................................,1< getCall#tate&'........................................................?B2 getChe%ke Ra io.utton- &'.................................<2 getColle%tion4ype&'.............................................202 getColumn-n e:&'................................................22B getColumn/ames&'..............................................22B getContent!rovi er&'...........................................280 getContentResolver&'...........................................20B getAe$ault#hare !re$eren%es&'.....................,1<, ,1B get(loat&'..............................................................210 get-nput#tream&'..................................................28, get-nt&'..........................................................22B, 210 get-ntent&'............................................................?30 getLastEno=n!osition&'......................................??2 getLatitu e&'.........................................................2?0 getLongitu e&'.....................................................2?0 getMapController&'..............................................?<? getMeMyCurrentLo%ation/o=&'.........................??2 get/et=ork4ype&'.................................................?B2 get>utput#tream&'...............................................28, get>verlays&'........................................................?<1 get!a%kageManager&'..........................................210 get!arent&'..............................................................<B get!hone4ype&'....................................................?B2 get!osition&'.........................................................210 get!re$eren%es&'..............................................,1?, ,1< get!rogress&'.........................................................,22 get!rovi ers&'........................................................??, getRea ableAatabase&'.........................................2,0 getRe;uire Columns&'........................................280 getResour%es&'......................................................,80 getRoot+ie=&'........................................................<B get#ettings&'..........................................................,<0 get#hare !re$eren%es&'..................................,1?, ,1< get#ingle4ype&'....................................................202 get#pee &'.............................................................??2 get#tring&'......................................,00, 202, 22B, 210 get#tringArray&'....................................................2,2 get#ubs%riber- &'..................................................?B2 get4ag&'...........................................................00, ,0< get4ype&'........................................................20,, 202 get+ie=&'.....1?, 82, 02, 0?, 0B, 03, ,00, ,0<, ,08, ,,0, ,,,, 218 getWriteableAatabase&'.......................................2,0 getDml&'................................................................201 go.a%k&'.................................................................,<B go.a%k>r(or=ar &'.......................................,<B, ,<3 go(or=ar &'...........................................................,<B han leMessage&'............................................,B8, ,30 hasAltitu e&'.........................................................??2 has.earing&'..........................................................??2 has#pee &'............................................................??2 in%rement!rogress.y&'.........................................,22 initMo%k!rovi er&'..............................................??8 insert&'...................................22,, 280, 288, 280, 20?
-4$
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
@ey)ord 8ndex
isA$terLast&'..................................................22B, 210 is.e$ore(irst&'.......................................................210 isChe%ke &'.......................................................?0, <2 isColle%tion"ri&'..........................................280, 200 isInable &'.............................................................<< is(irst&'..................................................................210 is(o%use &'.............................................................<< isLast&'..................................................................210 is/ull&'..................................................................210 isRouteAisplaye &'...............................................?<? loa Aata&'.............................................................,<< loa 4ime&'............................................................,<8 loa "rl&'.........................................................,<22,<< makeMeAnA pater&'...........................................?3? make4e:t&'.............................................................,B2 manage Huery&'...........................................21B2211 MenuKset7roupChe%kable&'.................................,?, Menu-temKsetChe%kable&'...................................,?, move&'...................................................................210 move4o(irst&'.......................................................210 move4oLast&'........................................................210 move4o/e:t&'.......................................................210 move4o!osition&'.................................................210 move4o!revious&'................................................210 ne=Cursor&'.........................................................223 ne=4ab#pe%&'.................................................,2B, ,23 ne:t&'.............................................................201, 22B noti$y&'..................................................................?22 noti$yChange&'.............................................20<, 20B noti$yMe&'.............................................................?2< obtainMessage&'....................................................,B8 onA%tivityResult&'........................................2B8, 23< on.in &'.......................................................?03, ?08 onChe%ke Change &'......................................<0, B< onCli%k&'............................................................20, 2, onConte:t-tem#ele%te &'...............................,??, ,?B onCreate&'............20, 2,, 28, 20, <?, B<, ,?0, ,?B, ,<2, ,332,30, ,80, ,02, 202, 2,0, 2<0, 211, 28B, 283, ?0<, ?0B, ?<<, ?30, ?3? onCreateConte:tMenu&'.........................,?2, ,??, ,?B onCreate>ptionsMenu&'........................,?0, ,?2, ,?B onCreate!anelMenu&'...........................................,?, onAestroy&'...........................................,31, ?0<, ?0B onList-temCli%k&'............................................1B, ,0< onLo%ationChange &'..........................................??? on/e=-ntent&'..............................................?30, ?3? on>ptions-tem#ele%te &'.........................,?,2,??, ,?B on!age#tarte &'....................................................,<3 on!ause&'.................................,38, ,0B, 2B?, ?0<, ?,1 onRating.arChange &'.........................................,,2 onRatingChange &'..............................................,0< onRe%eive&'...........................................................2B2 onRe%eive )ttpAuthRe;uest&'...........................,<3 onRestart&'............................................................,31 onRestore-nstan%e#tate&'.....................................,30 onResume&'.......,31, ,38, ,80, ,0B, 2?0, 2B?, ?0<, ?,1 on#ave-nstan%e#tate&'...................................,31, ,30 on#ear%hRe;ueste &'...................................?B1, ?3B on#ervi%eConne%te &'..........................................?,B on#ervi%eAis%onne%te &'..............................?,B, ?,3 on#tart&'...................................,30, ,3,, ,31, ?0<, ?,1
-40
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
@ey)ord 8ndex
on#top&'.................................................................,31 on4ap&'.................................................................?<0 on4e:tChange &'...................................................83 on4ooManyRe ire%ts&'.........................................,<3 on"pgra e&'..........................................................2,0 open(ile-nput&'..............................................,0?, ,0B open(ile>utput&'..........................................,0?, ,0B openRa=Resour%e&'..............................................,80 populate&'.............................................................?<1 populateAe$ault+alues&'.....................................280 populateMenu&'.............................................,?B, ,?3 post&'...............................................................,3,, ,32 postAelaye &'........................................................,3, ;uery&'....................................222222B, 2832288, 20? ;uery-ntentA%tivity>ptions&'.............................210 ;ueryWith(a%tory&'.............................................223 ra=Huery&'...........................................................222 ra=HueryWith(a%tory&'......................................223 registerContent>bserver&'..................................20B register(orConte:tMenu&'....................................,?2 registerRe%eiver&'..................................................2B? reloa &'..................................................................,<B remove&'................................................................,1< remove!ro:imityAlert&'.......................................??< remove"p ates&'..................................................??? re;uery&'...............................................................280 re;uest(o%us&'.......................................................<< re;uestLo%ation"p ates&'...................................??2 run>n"-4hrea &'.................................................,32 sen .roa %ast&'.............................................?0,, ?,0 sen Message&'.......................................................,B8 sen MessageAt(ront>$Hueue&'..........................,B8 sen MessageAt4ime&'..........................................,B8 sen MessageAelaye &'.........................................,B8 set&'.......................................................................2?< setA%%ura%y&'.........................................................??, setA apter&'...................................1<, 13, 80, 8<, ,,? setAlphabeti%#hort%ut&'........................................,?, setAltitu eRe;uire &'...........................................??, setCellRen erer&'...................................................12 setCenter&'............................................................?<B setChe%ke &'.....................................................?0, <? setColumnCollapse &'...........................................3B setColumn#hrinkable&'.........................................3B setColumn#tret%hable&'........................................3B setContent&'...................................................,2B, ,23 setContent+ie=&'.......................................20, 20, <B setCostAllo=e &'...................................................??, setCurrent4ab&'....................................................,23 setAe$ault(ont#iMe&'............................................,<0 setAe$aultEeyMo e&'...........................................?B8 setAropAo=n+ie=Resour%e&'...............................13 setAuration&'.........................................................,B2 setInable &'...........................................................<< set(antasy(ont(amily&'........................................,<0 set7ravity&'.............................................................B0 set7roupChe%kable&'............................................,?0 set-%on&'.................................................................,B? set-mage"R-&'........................................................?B set-n eterminate&'................................................,22
-41
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
@ey)ord 8ndex
set-n i%ator&'.................................................,2B, ,23 setGava#%riptCan>penWin o=sAutomati%ally&' ...............................................................................,<0 setGava#%riptInable &'.........................................,<0 setLatestIvent-n$o&'.....................................?2?, ?2B setListA apter&'.....................................................1B setMa:&'.................................................................,22 setMessage&'..........................................................,B? set/egative.utton&'..............................................,B? set/eutral.utton&'................................................,B? set/umeri%#hort%ut&'...........................................,?, set>nCli%kListener&'......................................20, ,0B set>n-tem#ele%te Listener&'....................1<, 13, 80 set>rientation&'.....................................................<8 set!a ing&'...........................................................B0 sho=&'......................................................,B2, ,B?, ,BB siMe&'......................................................................?<1 startA%tivity&'........................................2B1, 2B8, ?B2 start#ear%h&'.................................................?B8, ?3B start#ervi%e&'.........................................................?,1 start#ubA%tivity&'.........................................2B8, 23< stop#ervi%e&'..........................................................?,1 s=it%h&'..................................................................,?2 toggle&'..............................................................?0, <2 toggle#atellite&'....................................................?<3 to#tring&'................................................................12 unbin #ervi%e&'....................................................?,3 unregisterContent>bserver&'..............................20B unregisterRe%eiver&'.............................................2B? up ate&'...................................22,, 222, 280220,, 20? up ate(ore%ast&'....................................2?0, ?,8, ??? up ateLabel&'........................................................,,8 up ate4ime&'.........................................................20
set!ositive.utton&'...............................................,B? set!rogress&'..........................................................,22 set!roNe%tionMap&'..............................................22B setH=ertyMo e&'...................................................,?, setResult&'.............................................................2B8 set4ag&'....................................................00, ,00, ,0B set4e:t&'...................................................................2, set4e:t#iMe&'..........................................................,<0 set4itle&'................................................................,B? set4ype$a%e&'..........................................................23 setup&'............................................................,2B, ,23 set"serAgent&'......................................................,<0 set+ie=&'................................................................,B2 setWeb+ie=Client&'.............................................,<3 setLoom&'.............................................................?<< shoul >verri e"rlLoa ing&'.......................,<3, ,<8
Property............................................
an roi *authorities..............................................20< an roi *auto4e:t....................................................?3 an roi *ba%kgroun ..............................................<< an roi *%apitaliMe..................................................?3 an roi *%ollapseColumns......................................3B an roi *%olumnWi th..........................................80 an roi *%ompletion4hreshol ..............................8< an roi * igits.........................................................?3 an roi * ra=#ele%tor>n4op...........................11, 88 an roi *horiMontal#pa%ing...................................80
-44
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
@ey)ord 8ndex
an roi *i .................................21, 28, <2, B1, ,2?2,2B an roi *inputMetho ............................................?1 an roi *label...........................................................,< an roi *layout[above............................................B8 an roi *layout[align.aseline................................B8 an roi *layout[align.ottom.................................B8 an roi *layout[alignLe$t.......................................B8 an roi *layout[align!arent.ottom......................B1 an roi *layout[align!arentLe$t............................B1 an roi *layout[align!arentRight..........................B1 an roi *layout[align!arent4op.......................B1, 3, an roi *layout[alignRight.....................................B8 an roi *layout[align4op..................................B8, B0 an roi *layout[belo=............................................B8 an roi *layout[%enter)oriMontal..........................B1 an roi *layout[%enter-n!arent.............................B1 an roi *layout[%enter+erti%al...............................B1 an roi *layout[%olumn.........................................3? an roi *layout[gravity...........................................B0 an roi *layout[height........................21, <0, B0, ,2< an roi *layout[span..............................................3? an roi *layout[toLe$t>$........................................B8 an roi *layout[toRight>$.....................................B8 an roi *layout[=eight...........................................<0 an roi *layout[=i th...........................21, <0, B?, B0 an roi *mani$est.....................................................,2 an roi *ma:..........................................................,B0 an roi *name..........................,<, 20?, 208, ?00, ?3B an roi *ne:t(o%usAo=n.......................................<< an roi *ne:t(o%usLe$t...........................................<< an roi *ne:t(o%usRight........................................<< an roi *ne:t(o%us"p............................................<< an roi *numColumns...........................................80 an roi *numeri%.....................................................?1 an roi *orientation...............................................<8 an roi *pa an roi *pa an roi *pa an roi *pa an roi *pa ing...............................................B0, B, ing.ottom.........................................B, ingLe$t...............................................B, ingRight............................................B, ing4op........................................B,, ,2<
an roi *pass=or ...................................................?1 an roi *permission......................................?00, ?00 an roi *phone/umber..........................................?1 an roi *shrinkColumns........................................3< an roi *singleLine............................................?3, ?1 an roi *spa%ing.....................................................88 an roi *spinner#ele%tor........................................88 an roi *sr%..............................................................?B an roi *stret%hColumns.......................................3< an roi *stret%hMo e.............................................80 an roi *te:t.......................................................21, ?? an roi *te:tColor.............................................?<, ?0 an roi *te:t#tyle..............................................??, ?3 an roi *type$a%e.....................................................?? an roi *value........................................................?3B an roi *verti%al#pa%ing.........................................80 an roi *visibility....................................................<<
-47
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
@ey)ord 8ndex
-49
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition