Académique Documents
Professionnel Documents
Culture Documents
//012 34 2 56
78910: 94 ;< = ->?@
9
8
5
80 1 1 0 234 567
by Mark L. Murphy
The Busy Coder's Guide to Android Development by Mark L. Murphy Copyright 2008-2011 CommonsWare, LLC. All ights eser!e". #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, Mar 2011,-ersion ../ 0%12, 348-0-381/480-0-3
5he CommonsWare name an" logo, 61usy Co"er7s 8ui"e9, an" relate" tra"e "ress are tra"emarks o& CommonsWare, LLC. All other tra"emarks re&eren'e" in this book are tra"emarks o& their respe'ti!e &irms. 5he publisher an" author(s) assume no responsibility &or errors or omissions or &or "amages resulting &rom the use o& the in&ormation 'ontaine" herein.
Table of Contents
Welcome to the Warescription!........................................................xxiii Preface.................................................................................................xxv Wel'ome to the 1ook:..............................................................................;;! Wares'ription............................................................................................;;! 1ook 1ug 1ounty.....................................................................................;;!i %our'e Co"e An" 0ts Li'ense.................................................................;;!ii Creati!e Commons an" the *our-to-*ree (<2*) 8uarantee...............;;!iii A'kno=le"gments...................................................................................;;i; The Bi Picture.........................................................................................! What An"roi"s Are Ma"e >&........................................................................ A'ti!ities.................................................................................................. %er!i'es...................................................................................................< Content #ro!i"ers..................................................................................< 0ntents.....................................................................................................< %tu&& At ?our @isposal..................................................................................A %torage.....................................................................................................A 2et=ork...................................................................................................A Multime"ia.............................................................................................A 8#%..........................................................................................................A
iii
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
#hone %er!i'es......................................................................................../ 5he 1ig #i'ture...>& 5his 1ook..................................................................../ "o# To Get $tarted.................................................................................% %tep B1, Ca!a...................................................................................................4 0nstall the C@D........................................................................................4 Learn Ca!a...............................................................................................8 %tep B2, 0nstall the An"roi" %@D................................................................3 0nstall the 1ase 5ools.............................................................................3 0nstall the %@Ds an" A""->ns..............................................................3 %tep B., 0nstall the A@5 &or E'lipse...........................................................1. %tep B<, 0nstall Apa'he Ant........................................................................1A %tep BA, %et $p the Emulator.....................................................................1/ %tep B/, %et $p the @e!i'e.........................................................................2. Win"o=s...............................................................................................2< >% F an" Linu;.....................................................................................2A &our 'irst Android Pro(ect....................................................................)% %tep B1, Create the 2e= #roGe't.................................................................24 E'lipse...................................................................................................24 Comman" Line.......................................................................................1 %tep B2, 1uil", 0nstall, an" un the Appli'ation in ?our Emulator or @e!i'e...........................................................................................................2 E'lipse.....................................................................................................2 Comman" Line....................................................................................... *xaminin &our 'irst Pro(ect................................................................+% #roGe't %tru'ture..........................................................................................4 oot Contents........................................................................................4 5he %=eat >&& ?our 1ro=.....................................................................8
iv
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
An" 2o=, 5he est o& the %tory...........................................................3 What ?ou 8et >ut >& 0t......................................................................<0 0nsi"e ?our Mani&est..................................................................................<0 0n 5he 1eginning, 5here Was the oot, An" 0t Was 8oo"...............<1 An Appli'ation *or ?our Appli'ation.................................................<2 A Bit A,out *clipse................................................................................-. What the A@5 8i!es ?ou...........................................................................<A Coping =ith E'lipse....................................................................................</ +o= to 0mport a 2on-E'lipse #roGe't................................................</ +o= to 8et 5o @@M%...........................................................................A1 +o= to Create an Emulator.................................................................A. +o= to un a #roGe't...........................................................................A< +o= 2ot to un ?our #roGe't.............................................................AA Alternati!e 0@Es..........................................................................................AA More on the 5ools......................................................................................A/ 0@Es...An" 5his 1ook.................................................................................A4 *nhancin &our 'irst Pro(ect................................................................./ %upporting Multiple %'reens.....................................................................A3 %pe'i&ying -ersions..................................................................................../0 0e#ritin &our 'irst Pro(ect.................................................................1. 5he A'ti!ity................................................................................................./A @isse'ting the A'ti!ity...............................................................................// 1uil"ing an" unning the A'ti!ity.........................................................../8 About the emaining E;amples................................................................/3 2sin 3456Based 5ayouts.....................................................................%! What 0s an FML-1ase" LayoutH.................................................................41 Why $se FML-1ase" LayoutsH..................................................................42
v
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
>D, %o What @oes 0t Look LikeH...............................................................4. What7s With the I %ignsH.........................................................................4< An" We Atta'h 5hese to the Ca!a...+o=H................................................4< 5he est o& the %tory..................................................................................4A *mployin Basic Wid ets......................................................................%/ Assigning Labels.........................................................................................43 1utton, 1utton, Who7s 8ot the 1uttonH...................................................80 *leeting 0mages...........................................................................................81 *iel"s o& 8reen. >r >ther Colors..............................................................8. Cust Another 1o; to Che'k.........................................................................8A 5urn the a"io $p......................................................................................88 0t7s Juite a -ie=.........................................................................................30 #a""ing.................................................................................................30 >ther $se&ul #roperties......................................................................30 $se&ul Metho"s.....................................................................................31 Colors.....................................................................................................31 Wor7in #ith Containers....................................................................../+ 5hinking Linearly.......................................................................................3< Con'epts an" #roperties.....................................................................3< E;ample.................................................................................................34 5he 1o; Mo"el....................................................................................102 All 5hings Are elati!e.............................................................................10< Con'epts an" #roperties....................................................................10< E;ample...............................................................................................104 >!erlap................................................................................................103 5abula asa.................................................................................................111 Con'epts an" #roperties.....................................................................112
vi
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
E;ample................................................................................................11< %'roll=ork...................................................................................................11A The 8nput 4ethod 'rame#or7............................................................!!/ Deyboar"s, +ar" an" %o&t.........................................................................113 5ailore" 5o ?our 2ee"s............................................................................120 5ell An"roi" Where 0t Can 8o.................................................................12< *itting 0n.....................................................................................................124 Cane, %top 5his CraKy 5hing:....................................................................128 2sin $election Wid ets.......................................................................!+! A"apting to the Cir'umstan'es.................................................................1.1 $sing ArrayA"apter............................................................................1.2 Lists o& 2aughty an" 2i'e.........................................................................1.. %ele'tion Mo"es..................................................................................1.A %pin Control...............................................................................................1.4 8ri" ?our Lions (>r %omething Like 5hat...)..........................................1<1 *iel"s, 2o= With .AL Less 5yping:.........................................................1<A 8alleries, 8i!e >r 5ake 5he Art...............................................................1<3 Gettin 'ancy With 5ists......................................................................!.! 8etting 5o *irst 1ase..................................................................................1A1 A @ynami' #resentation...........................................................................1A< 0n&lating o=s >ursel!es..........................................................................1A/ A %i"ebar About 0n&lation..................................................................1A/ An" 2o=, 1a'k 5o >ur %tory............................................................1A8 1etter. %tronger. *aster.............................................................................1A3 $sing 'on!ert-ie=..............................................................................1A3 $sing the +ol"er #attern....................................................................1/1 0ntera'ti!e o=s........................................................................................1/<
vii
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
$till 4ore Wid ets and Containers......................................................!%! #i'k an" Choose.........................................................................................141 5ime Deeps *lo=ing Like a i!er.............................................................14/ %eeking esolution....................................................................................148 #utting 0t >n My 5ab................................................................................143 5he #ie'es............................................................................................180 Wiring 0t 5ogether..............................................................................181 A""ing 5hem $p................................................................................18< *lipping 5hem >&&.....................................................................................188 8etting 0n %omebo"y7s @ra=er................................................................13. >ther 8oo" %tu&&.......................................................................................134 *m,eddin the We,9it Bro#ser.........................................................!// A 1ro=ser, Writ %mall..............................................................................133 Loa"ing 0t $p............................................................................................202 2a!igating the Waters..............................................................................20. Entertaining the Client............................................................................20< %ettings, #re&eren'es, an" >ptions (>h, My:).......................................20/ Applyin 4enus...................................................................................):/ *la!ors o& Menu........................................................................................203 Menus o& >ptions......................................................................................210 Menus in Conte;t......................................................................................212 5aking a #eek.............................................................................................21. ?et More 0n&lation.....................................................................................218 Menu FML %tru'ture..........................................................................213 Menu >ptions an" FML....................................................................213 0n&lating the Menu..............................................................................221 0n the Lan" o& Menus an" +oney............................................................22.
viii
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
$ho#in Pop62p 4essa es..................................................................)). aising 5oasts............................................................................................22A Alert: Alert:................................................................................................22/ Che'king 5hem >ut.................................................................................224 "andlin Activity 5ifecycle *vents......................................................)+! %'hroe"inger7s A'ti!ity..............................................................................2.1 Li&e, @eath, an" ?our A'ti!ity.................................................................2.2 onCreate() an" on@estroy()..............................................................2.2 on%tart(), on estart(), an" on%top()................................................2.. on#ause() an" on esume()...............................................................2.< 5he 8ra'e o& %tate.....................................................................................2.< "andlin 0otation...............................................................................)+% A #hilosophy o& @estru'tion....................................................................2.4 0t7s All 5he %ame, Cust @i&&erent..............................................................2.8 #i'king an" -ie=ing a Conta't.........................................................2<0 %a!ing ?our %tate...............................................................................2<2 2o= With More %a!ings:.........................................................................2<A @0? otation.............................................................................................2<4 ...1ut 8oogle @oes 2ot e'ommen" 5his........................................2A0 *or'ing the 0ssue........................................................................................2A1 Making %ense o& it All...............................................................................2A. Dealin #ith Threads...........................................................................).. 5he Main Appli'ation 5hrea"..................................................................2AA Making #rogress =ith #rogress1ars........................................................2A4 8etting 5hrough the +an"lers................................................................2A8 Messages.............................................................................................2A8 unnables...........................................................................................2/2
ix
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
Where, >h Where +as My $0 5hrea" 8oneH........................................2/2 Asyn'ing *eeling.......................................................................................2/2 5he 5heory..........................................................................................2/. Asyn'5ask, 8eneri's, an" -arargs....................................................2/< 5he %tages o& Asyn'5ask...................................................................2/< A %ample 5ask....................................................................................2/A 5hrea"s an" otation...............................................................................240 Manual A'ti!ity Asso'iation..............................................................241 *lo= o& E!ents....................................................................................24< Why 5his Works.................................................................................24A An" 2o=, 5he Ca!eats.............................................................................24/ Creatin 8ntent 'ilters.........................................................................)%% What7s ?our 0ntentH.................................................................................248 #ie'es o& 0ntents.................................................................................248 0ntent outing....................................................................................243 %tating ?our 0ntent(ions).........................................................................280 2arro= e'ei!ers......................................................................................282 5he #ause Ca!eat......................................................................................28. 5aunchin Activities and $u,6Activities.............................................);. #eers an" %ubs..........................................................................................28/ %tart 7Em $p..............................................................................................28/ Make an 0ntent...................................................................................28/ Make the Call......................................................................................284 5abbe" 1ro=sing, %ort >&........................................................................231 Wor7in #ith 0esources.....................................................................)/% 5he esour'e Lineup................................................................................234 %tring 5heory............................................................................................238
x
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
#lain %trings........................................................................................238 %tring *ormats....................................................................................233 %tyle" 5e;t...........................................................................................00 %tyle" 5e;t an" *ormats.....................................................................00 8ot the #i'tureH.........................................................................................0< FML, 5he esour'e Way..........................................................................0/ Mis'ellaneous -alues................................................................................03 @imensions..........................................................................................03 Colors....................................................................................................10 Arrays.....................................................................................................11 @i&&erent %trokes &or @i&&erent *olks........................................................12 5L Languages, 8oing 1oth Ways............................................................14 Definin and 2sin $tyles....................................................................+!/ %tyles, @0? @ ?..........................................................................................13 Elements o& %tyle........................................................................................21 Where to Apply a %tyle.......................................................................22 5he A!ailable Attributes.....................................................................22 0nheriting a %tyle.................................................................................2. 5he #ossible -alues.............................................................................2< 5hemes, Woul" a %tyle 1y Any >ther 2ame..........................................2A "andlin 4ultiple $creen $i<es..........................................................+)% 5aking the @e&ault.....................................................................................28 Whole in >ne.............................................................................................23 @on7t 5hink About #ositions, 5hink About ules.............................0 Consi"er #hysi'al @imensions.............................................................1 A!oi" M ealM #i;els................................................................................1 Choose %'alable @ra=ables.................................................................2
xi
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
5ailor Ma"e, Cust *or ?ou (An" ?ou, An" ?ou, An"...)...........................2 Nsupports-s'reensO................................................................................ esour'es an" esour'e %ets...............................................................< *in"ing ?our %iKe..................................................................................A Ain7t 2othing Like the eal 5hing............................................................/ @ensity @i&&ers....................................................................................../ A"Gusting the @ensity...........................................................................4 uthlessly E;ploiting the %ituation...........................................................8 epla'e Menus =ith 1uttons...............................................................3 epla'e 5abs =ith a %imple A'ti!ity...................................................3 Consoli"ate Multiple A'ti!ities.........................................................<0 E;ample, E$<?ou......................................................................................<0 5he *irst Cut.........................................................................................<1 *i;ing the *onts...................................................................................<4 *i;ing the 0'ons...................................................................................A0 $sing the %pa'e...................................................................................A0 What 0& 0t 0s 2ot a 1ro=serH...............................................................A. 8ntroducin the "oneycom, 28..........................................................+.% Why +oney'ombH.....................................................................................A4 What the $ser %ees....................................................................................A8 5he +olographi' 5heme.........................................................................../. @ealing =ith the est o& the @e!i'es......................................................./< 2sin the Action Bar............................................................................+1% Enabling the A'tion 1ar............................................................................/4 #romoting Menu 0tems to the A'tion 1ar.............................................../8 espon"ing to the Logo............................................................................/3 A""ing Custom -ie=s to the A'tion 1ar.................................................40
xii
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
@e&ining the Layout............................................................................40 #utting the Layout in the MMenuM......................................................42 8etting Control o& $ser 0nput............................................................4. @on7t *orget the #hones:...........................................................................4A 'ra ments.............................................................................................+%% 0ntro"u'ing *ragments..............................................................................44 5he #roblem........................................................................................48 5he *ragments %olution.....................................................................48 5he An"roi" Compatibility Library...................................................80 Creating *ragment Classes........................................................................81 8eneral *ragments...............................................................................81 List*ragment........................................................................................8. >ther *ragment 1ase Classes.............................................................88 *ragments, Layouts, A'ti!ities, an" Multiple %'reen %iKes....................83 E$<?ou................................................................................................30 @etailsA'ti!ity.....................................................................................3A *ragments an" Con&iguration Changes...................................................3/ @esigning &or *ragments...........................................................................34 "andlin Platform Chan es...............................................................+// 5hings 5hat Make ?ou 8o M1oomM..........................................................33 -ie= +ierar'hy..................................................................................<00 Changing esour'es..........................................................................<00 +an"ling A#0 Changes..............................................................................<01 Minimum, Ma;imum, 5arget, an" 1uil" -ersions..........................<01 @ete'ting the -ersion........................................................................<0< Wrapping the A#0..............................................................................<0< #atterns &or +oney'omb..........................................................................<04
xiii
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
5he A'tion 1ar...................................................................................<04 Writing 5ablet->nly Apps................................................................<03 Accessin 'iles......................................................................................-!+ ?ou An" 5he +orse ?ou o"e 0n >n.......................................................<1. ea"in7 7n Writin7.......................................................................................<14 E;ternal %torage, 8iant E'onomy-%iKe %pa'e.........................................<21 Where to Write..................................................................................<22 When to Write....................................................................................<22 %tri'tMo"e, A!oi"ing Canky Co"e...........................................................<2. %etting up %tri't Mo"e.......................................................................<2< %eeing 0t 0n A'tion.............................................................................<2< @e!elopment >nly, #lease:...............................................................<2A Con"itionally 1eing %tri't.................................................................<2A Linu; *ilesystems, ?ou %yn', ?ou Win...................................................<28 2sin Preferences................................................................................-+! 8etting What ?ou Want...........................................................................<.1 %tating ?our #re&eren'e............................................................................<.2 0ntro"u'ing #re&eren'eA'ti!ity...............................................................<.. Letting $sers +a!e 5heir %ay..................................................................<.< A""ing a Wee 1it >7 %tru'ture................................................................<.3 5he Din" >& #op-$ps ?ou Like...............................................................<<2 #re&eren'es !ia *ragments.......................................................................<</ 5he +oney'omb Way........................................................................<<4 A""ing 1a'k=ar"s Compatibility.....................................................<A2 4ana in and Accessin 5ocal Data,ases.........................................-.. A Jui'k %JLite #rimer............................................................................<A4 %tart at the 1eginning...............................................................................<A4
xiv
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
%etting the 5able.......................................................................................</1 Makin7 @ata...............................................................................................</2 What 8oes Aroun", Comes Aroun".......................................................</. a= Jueries........................................................................................</. egular Jueries.................................................................................</< $sing Cursors.....................................................................................</A Custom CursorA"apters....................................................................<// Making ?our >=n Cursors................................................................</4 *lash, %oun"s *aster 5han 0t 0s...............................................................</4 @ata, @ata, E!ery=here...........................................................................</8 5evera in =ava 5i,raries.....................................................................-%! Ants an" Cars..............................................................................................<41 5he >uter Limits......................................................................................<42 *ollo=ing the %'ript.................................................................................<4. e!ie=ing the %'ript.................................................................................<48 Communicatin via the 8nternet........................................................-;! E%5 an" ela;ation.................................................................................<81 +55# >perations !ia Apa'he +ttpClient........................................<82 #arsing esponses..............................................................................<8< %tu&& 5o Consi"er...............................................................................<8/ An"roi"+ttpClient.............................................................................<84 Le!eraging 0nternet-A=are An"roi" Components................................<88 @o=nloa"ing *iles.............................................................................<88 Continuing >ur Es'ape *rom Canky Co"e.............................................A00 $ervices> The Theory.............................................................................:+ Why %er!i'esH...........................................................................................A0. %etting $p a %er!i'e.................................................................................A0<
xv
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
5he %er!i'e Class................................................................................A0< Li&e'y'le Metho"s..............................................................................A0A Mani&est Entry....................................................................................A0A Communi'ating 5o %er!i'es....................................................................A0/ %en"ing Comman"s =ith start%er!i'e()..........................................A0/ 1in"ing =ith bin"%er!i'e()...............................................................A08 Communi'ating *rom %er!i'es...............................................................A03 Callba'kPListener >bGe'ts.................................................................A03 1roa"'ast 0ntents................................................................................A10 #en"ing esults....................................................................................A11 Messenger.............................................................................................A11 2oti&i'ations........................................................................................A12 Basic $ervice Patterns...........................................................................!+ 5he @o=nloa"er........................................................................................A1. 5he @esign...........................................................................................A1< 5he %er!i'e 0mplementation..............................................................A1< $sing the %er!i'e.................................................................................A14 5he Musi' #layer.......................................................................................A18 5he @esign...........................................................................................A13 5he %er!i'e 0mplementation..............................................................A13 $sing the %er!i'e.................................................................................A21 5he Web %er!i'e 0nter&a'e.......................................................................A22 5he @esign..........................................................................................A2. 5he otation Challenge.....................................................................A2. 5he %er!i'e 0mplementation.............................................................A2< $sing the %er!i'e................................................................................A23
xvi
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
Alertin 2sers ?ia @otifications...........................................................+% 2oti&i'ation Con&iguration.......................................................................A.4 +ar"=are 2oti&i'ations.....................................................................A.8 0'ons....................................................................................................A.3 2oti&i'ations in A'tion.............................................................................A<0 %taying in the *oregroun".......................................................................A<A *ake#layer, e"u;..............................................................................A</ 2oti&i'ations an" +oney'omb................................................................A<8 0eAuestin and 0eAuirin Permissions...............................................+ Mother, May 0H..........................................................................................AA< +alt: Who 8oes 5hereH............................................................................AAA En&or'ing #ermissions !ia the Mani&est...........................................AA/ En&or'ing #ermissions Else=here.....................................................AA4 May 0 %ee ?our @o'umentsH....................................................................AA4 2e= #ermissions in >l" Appli'ations....................................................AA8 #ermissions, $p *ront >r 2ot At All......................................................AA8 Accessin 5ocation6Based $ervices......................................................1+ Lo'ation #ro!i"ers, 5hey Dno= Where ?ou7re +i"ing.........................A/< *in"ing ?oursel&.......................................................................................A/< >n the Mo!e.............................................................................................A// Are We 5here ?etH Are We 5here ?etH Are We 5here ?etH.................A/8 5esting...5esting.......................................................................................A/3 4appin #ith 4ap?ie# and 4apActivity............................................%! 5erms, 2ot o& En"earment.......................................................................A41 #iling >n....................................................................................................A42 5he Dey 5o 0t All.......................................................................................A42 5he 1are 1ones.........................................................................................A4<
xvii
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
>ptional Maps....................................................................................A4/ E;er'ising ?our Control...........................................................................A4/ Qoom....................................................................................................A44 Center..................................................................................................A44 Layers $pon Layers..................................................................................A48 >!erlay Classes...................................................................................A48 @ra=ing the 0temiKe">!erlay...........................................................A48 +an"ling %'reen 5aps........................................................................A80 My, Mysel&, an" MyLo'ation>!erlay.......................................................A81 ugge" 5errain.........................................................................................A82 Maps an" *ragments................................................................................A8< Limit ?oursel& to An"roi" ..0...........................................................A8< $se onCreate-ie=() an" onA'ti!ityCreate"().................................A8A +ost the *ragment in a MapA'ti!ity................................................A8/ "andlin Telephone Calls...................................................................;/ eport 5o 5he Manager...........................................................................A30 ?ou Make the Call:...................................................................................A30 2o, eally, ?ou Make the Call:................................................................A3. 'onts....................................................................................................../. Lo!e 5he >ne ?ou7re With......................................................................A3A +ere a 8lyph, 5here a 8lyph...................................................................A33 4ore Development Tools....................................................................1:! +ierar'hy -ie=er, +o= @eep 0s ?our Co"eH........................................../01 @@M%, $n"er An"roi"7s +oo".............................................................../0/ Logging.............................................................................................../08 *ile #ush an" #ull............................................................................../03 %'reenshots........................................................................................./10
xviii
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
Lo'ation $p"ates................................................................................./11 #la'ing Calls an" Messages................................................................/12 Memory Management......................................................................../1/ a"b, Like @@M%, With More 5yping......................................................./14 The 0ole of Alternative *nvironments...............................................1)! 0n the 1eginning, 5here Was Ca!a.........................................................../22 ...An" 0t Was >D......................................................................................./22 1u'king the 5ren"..................................................................................../2. %upport, %tru'ture..................................................................................../2< Ca!eat @e!eloper....................................................................................../2< "T45...................................................................................................1)% >&&line Appli'ations................................................................................./24 What @oes 0t MeanH........................................................................../24 +o= @o ?ou $se 0tH........................................................................../28 Web %torage............................................................................................../.< What @oes 0t MeanH........................................................................../.A +o= @o ?ou $se 0tH..........................................................................././ Web %JL @atabase............................................................................/.4 8oing 5o #ro"u'tion................................................................................/.8 5esting................................................................................................./.8 %igning an" @istribution.................................................................../.8 $p"ates.............................................................................................../.3 0ssues ?ou May En'ounter......................................................................./.3 An"roi" @e!i'e -ersions.................................................................../.3 %'reen %iKes an" @ensities................................................................/<0 Limite" #lat&orm 0ntegration............................................................/<0 #er&orman'e an" 1attery.................................................................../<1
xix
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
Look an" *eel...................................................................................../<2 @istribution......................................................................................../<2 +5MLA an" Alternati!e An"roi" 1ro=sers............................................/<. *ire&o; Mobile..................................................................................../<. >pera Mobile....................................................................................../<. @olphin 1ro=ser +@ <.0.................................................................../<. +5MLA, 5he 1aseline.............................................................................../<. PhoneGap.............................................................................................1-. What 0s #hone8apH................................................................................../<A What @o ?ou Write 0nH...................................................................../<A What *eatures @o ?ou 8etH............................................................./</ What @o Apps Look LikeH................................................................/<4 +o= @oes @istribution WorkH........................................................./<4 What About >ther #lat&ormsH........................................................./<8 $sing #hone8ap......................................................................................./<8 0nstallation........................................................................................./<3 Creating an" 0nstalling ?our #roGe't................................................/<3 #hone8apP1uil"................................................................................./A0 #hone8ap an" the Che'klist %ample....................................................../A< %ti'king to the %tan"ar"s................................................................../A< A""ing #hone8ap A#0s...................................................................../A4 0ssues ?ou May En'ounter......................................................................//0 %e'urity...............................................................................................//0 %'reen %iKes an" @ensities.................................................................//1 Look an" *eel.....................................................................................//2 *or More 0n&ormation..............................................................................//.
xx
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
Bther Alternative *nvironments........................................................11. ho"es.......................................................................................................//A *lash, *le;, an" A0 ................................................................................./// C uby an" uboto..................................................................................../// Mono@roi"...............................................................................................//4 App 0n!entor.............................................................................................//4 5itanium Mobile......................................................................................//3 >ther C-M Compile" Languages............................................................/40 Dealin With Devices..........................................................................1%+ 5his App Contains E;pli'it... 0nstru'tions............................................../4. 0mplie" *eature eRuests................................................................../4A A 8uarantee" Market.............................................................................../4/ >ther %tu&& 5hat -aries............................................................................/44 1ugs, 1ugs, 1ugs......................................................................................./48 @e!i'e 5esting........................................................................................../48 Where Do We Go 'rom "ereC.............................................................1;! Juestions. %ometimes, With Ans=ers..................................................../81 +ea"ing to the %our'e............................................................................./82 8etting ?our 2e=s *i;............................................................................./8.
xxi
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
We hope you enGoy this ebook an" its up"ates S 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 a!ailable. All e"itions o& CommonsWare titles, print an" ebook, &ollo= a so&t=arestyle numbering system. MaGor releases (1.0, 2.0, et'.) are a!ailable in both print an" ebookT minor releases (0.1, 0.3, et'.) are a!ailable in ebook &orm &or Wares'ription subs'ribers only. eleases en"ing in .3 are Mrelease 'an"i"atesM &or the ne;t maGor release, la'king perhaps an in"e; but other=ise being 'omplete. Ea'h Wares'ription ebook is li'ense" &or the e;'lusi!e use o& its subs'riber an" is tagge" =ith the subs'riber7s name. We ask that you not "istribute these books. 0& you =ork &or a &irm an" =ish to ha!e se!eral employees ha!e a''ess, enterprise Wares'riptions are a!ailable. Cust 'onta't us at enterpriseI'ommons=are.'om. Also, bear in min" that e!entually this e"ition o& this title =ill be release" un"er a Creati!e Commons li'ense S more on this in the pre&a'e. emember that the CommonsWare Web site has errata an" resour'es (e.g., sour'e 'o"e) &or ea'h o& our titles. Cust !isit the Web page &or the book you are intereste" in an" &ollo= the links. ?ou 'an sear'h through the #@* using most #@* rea"ers (e.g., A"obe ea"er). 0& you =ish to sear'h all o& the CommonsWare books at on'e, an"
xxiii
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
your operating system "oes not support that "ire'tly, you 'an al=ays 'ombine the #@*s into one, using tools like #@* %plit-An"-Merge or the Linu; 'omman" pdftk *.pdf cat output combined.pdf.
xxiv
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
Preface
Warescription
5his book =ill be publishe" both in print an" in "igital (ebook) &orm. 5he ebook !ersions o& all CommonsWare titles are a!ailable !ia an annual subs'ription S the Wares'ription. 5he Wares'ription entitles you, &or the "uration o& your subs'ription, to ebook &orms o& all CommonsWare titles, not Gust the one you are rea"ing.
xxv
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
#resently, CommonsWare o&&ers #@* an" Din"leT other ebook &ormats =ill be a""e" base" on interest an" the openness o& the &ormat. Ea'h subs'riber gets personaliKe" e"itions o& all e"itions o& ea'h title, both those mirroring printe" e"itions an" in-bet=een up"ates that are only a!ailable in ebook &orm. 5hat =ay, your ebooks are ne!er out o& "ate &or long, an" you 'an take a"!antage o& ne= material as it is ma"e a!ailable instea" o& ha!ing to =ait &or a =hole ne= print e"ition. *or e;ample, =hen ne= releases o& the An"roi" %@D are ma"e a!ailable, this book =ill be Rui'kly up"ate" to be a''urate =ith 'hanges in the A#0s. *rom time to time, subs'ribers =ill also re'ei!e a''ess to subs'riber-only online material, both short arti'les an" not-yet-publishe" 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. 0& you are intereste" in a Wares'ription, !isit the Wares'ription se'tion o& the CommonsWare Web site. ?ou 'an &in" out =hen ne= releases o& this book are a!ailable !ia,
5he '=-an"roi" 8oogle 8roup, =hi'h is also a great pla'e to ask Ruestions about the book an" its e;amples 5he 'ommonsguy 5=itter &ee" 5he Wares'ription ne=sletter, =hi'h you 'an subs'ribe to o&& o& your Wares'ription page
'oupon to a &rien", 'olleague, or some ran"om person you meet on the sub=ay. 1y M'on'reteM problem, =e mean things like,
5ypographi'al errors %ample appli'ations that "o not =ork as a"!ertise", in the en!ironment "es'ribe" in the book *a'tual errors that 'annot be open to interpretation
1y MuniRueM, =e mean ones not yet reporte". Ea'h book has an errata page on the CommonsWare Web siteT most kno=n problems =ill be liste" there. >ne 'oupon is gi!en per email 'ontaining !ali" bug reports. We appre'iate hearing about Mso&terM 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"" sample appli'ations, or e;pan" upon the e;isting material %amples that "o not =ork "ue to Mshi&ting san"sM o& the un"erlying en!ironment (e.g., 'hange" A#0s =ith ne= releases o& an %@D)
+o=e!er, those Mso&terM issues "o not Ruali&y &or the &ormal bounty program. 1e sure to 'he'k the book7s errata page, though, to see i& your issue has alrea"y been reporte". Juestions about the bug bounty, or problems you =ish to report &or bounty 'onsi"eration, shoul" be sent to bountyI'ommons=are.'om.
0& you =ish to use the sour'e 'o"e &rom the CommonsWare Web site, bear in min" a &e= things, 1. 5he proGe'ts are set up to be built by Ant, not by E'lipse. 0& you =ish to use the 'o"e =ith E'lipse, you =ill nee" to 'reate a suitable An"roi" E'lipse proGe't an" import the 'o"e an" other assets.
2. ?ou shoul" "elete buil".;ml, then run android update project -p ... (=here ... is the path to a proGe't o& interest) on those proGe'ts you =ish to use, so the buil" &iles are up"ate" &or your An"roi" %@D !ersion.
xxviii
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
Ackno)ledgments
0 =oul" like to thank the An"roi" team, not only &or putting out a goo" pro"u't, but &or in!aluable assistan'e on the An"roi" 8oogle 8roups. %ome o& the i'ons use" in the sample 'o"e =ere pro!i"e" by the 2u!ola i'on set.
xxix
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
CHAPTER 1
An"roi" is e!ery=here. #hones. 5ablets. 5-s an" set-top bo;es po=ere" by 8oogle 5-. %oon, An"roi" =ill be in 'ars an" all sort o& other pla'es as =ell. +o=e!er, the general theme o& An"roi" "e!i'es =ill be smaller s'reens an"Por no har"=are keyboar". An", by the numbers, An"roi" =ill probably be most asso'iate" =ith smartphones &or the &oreseeable &uture. *or "e!elopers, this has bene&its an" "ra=ba'ks. >n the plus si"e, An"roi"-style smartphones are se;y. >&&ering 0nternet ser!i'es o!er mobile "e!i'es "ates ba'k to the mi"-13307s an" the +an"hel" @e!i'e Markup Language (+@ML). +o=e!er, only in re'ent years ha!e phones 'apable o& 0nternet a''ess taken o&&. 2o=, thanks to tren"s like te;t messaging an" to pro"u'ts like Apple7s i#hone, phones that 'an ser!e as 0nternet a''ess "e!i'es are rapi"ly gaining popularity. %o, =orking on An"roi" appli'ations gi!es you e;perien'e =ith an interesting te'hnology (An"roi") in a &ast-mo!ing market segment (0nternet-enable" phones), =hi'h is al=ays a goo" thing. 5he problem 'omes =hen you a'tually ha!e to program the "arn things. Anyone =ith e;perien'e in programming &or #@As or phones has &elt the pain o& phones simply being small in all sorts o& "imensions,
*
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
%'reens are small (you =ill not get 'omments like, Mis that a 2<-in'h LC@ in your po'ket, or...HM) Deyboar"s, i& they e;ist, are small #ointing "e!i'es, i& they e;ist, are annoying (as anyone =ho has lost their stylus =ill tell you) or ine;a't (large &ingers an" Mmulti-tou'hM LC@s 'an sometimes be...problemati') C#$ spee" an" memory are tight 'ompare" to "esktops an" ser!ers you may be use" to An" so on
Moreo!er, appli'ations running on a phone ha!e to "eal =ith the &a't that they7re on a phone. #eople =ith mobile phones ten" to get !ery irritate" =hen those phones "o not =ork. %imilarly, those same people =ill get irritate" at you i& your program MbreaksM their phones,
...by tying up the C#$ su'h that 'alls 'an7t be re'ei!e" ...by not =orking properly =ith the rest o& the phone7s >%, su'h that your appli'ation "oes not Ruietly &a"e to the ba'kgroun" =hen a 'all 'omes in or nee"s to be pla'e" ...by 'rashing the phone7s operating system, su'h as by leaking memory like a sie!e
+en'e, "e!eloping programs &or a phone is a "i&&erent e;perien'e than "e!eloping "esktop appli'ations, Web sites, or ba'k-en" ser!er pro'esses. ?ou =in" up =ith "i&&erent-looking tools, "i&&erent-beha!ing &rame=orks, an" M"i&&erent than you are use" toM limitations on =hat you 'an "o =ith your program. What An"roi" tries to "o is meet you hal&=ay,
?ou get a 'ommonly-use" programming language (Ca!a) =ith some 'ommonly use" libraries (e.g., some Apa'he Commons A#0s), =ith support &or tools you may be use" to (E'lipse)
&
?ou get a &airly rigi" an" un'ommon &rame=ork in =hi'h your programs nee" to run so they 'an be Mgoo" 'itiKensM 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"!antage o& its 'apabilities.
Activities
5he buil"ing blo'k o& the user inter&a'e is the activity. ?ou 'an think o& an a'ti!ity as being the An"roi" analogue &or the =in"o= or "ialog in a "esktop appli'ation, or the page in a 'lassi' Web app. An"roi" is "esigne" to support lots o& 'heap a'ti!ities, so you 'an allo= users to keep 'li'king to bring up ne= a'ti!ities an" tapping the 1ACD button to ba'k up, Gust like they "o in a Web bro=ser.
Services
A'ti!ities are short-li!e" an" 'an be shut "o=n at any time. %er!i'es, on the other han", are "esigne" to keep running, i& nee"e", in"epen"ent o& any a'ti!ity. ?ou might use a ser!i'e &or 'he'king &or up"ates to an %% &ee", or to play ba'k musi' e!en i& the 'ontrolling a'ti!ity is no longer operating. ?ou =ill also use ser!i'es &or s'he"ule" tasks (M'ron GobsM) an" &or e;posing 'ustom A#0s to other appli'ations on the "e!i'e, though those are relati!ely a"!an'e" 'apabilities.
Content Providers
Content pro!i"ers pro!i"e a le!el o& abstra'tion &or any "ata store" on the "e!i'e that is a''essible by multiple appli'ations. 5he An"roi" "e!elopment mo"el en'ourages you to make your o=n "ata a!ailable to other appli'ations, as =ell as your o=n S buil"ing a 'ontent pro!i"er lets you "o that, =hile maintaining 'omplete 'ontrol o!er ho= your "ata gets a''esse".
Intents
0ntents are system messages, running aroun" the insi"e o& the "e!i'e, noti&ying appli'ations o& !arious e!ents, &rom har"=are state 'hanges (e.g., an %@ 'ar" =as inserte"), to in'oming "ata (e.g., an %M% message arri!e"), to appli'ation e!ents (e.g., your a'ti!ity =as laun'he" &rom the "e!i'e7s main menu). 2ot only 'an you respon" to an Intent, but you 'an 'reate your o=n, to laun'h other a'ti!ities, or to let you kno= =hen spe'i&i' situations arise (e.g., raise su'h-an"-so Intent =hen the user gets =ithin 100 meters o& this-an"-su'h lo'ation).
"et#or$
An"roi" "e!i'es =ill generally be 0nternet-rea"y, through one 'ommuni'ations me"ium or another. ?ou 'an take a"!antage o& the 0nternet a''ess at any le!el you =ish, &rom ra= Ca!a so'kets all the =ay up to a built-in WebDit-base" Web bro=ser =i"get you 'an embe" in your appli'ation.
%ultimedi
An"roi" "e!i'es ha!e the ability to play ba'k an" re'or" au"io an" !i"eo. While the spe'i&i's may !ary &rom "e!i'e to "e!i'e, you 'an Ruery the "e!i'e to learn its 'apabilities an" then take a"!antage 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 note-taking.
GPS
An"roi" "e!i'es =ill &reRuently ha!e a''ess to lo'ation pro!i"ers, su'h as 8#%, that 'an tell your appli'ations =here the "e!i'e is on the &a'e o& the Earth. 0n turn, you 'an "isplay maps or other=ise take a"!antage o& the lo'ation "ata, su'h as tra'king a "e!i'e7s mo!ements i& the "e!i'e has been stolen.
Phone Services
An", o& 'ourse, An"roi" "e!i'es are typi'ally phones, allo=ing your so&t=are to initiate 'alls, sen" an" re'ei!e %M% messages, an" e!erything else you e;pe't &rom a mo"ern bit o& telephony te'hnology.
CHAPTER &
Without &urther a"o, let us get you set up =ith the pie'es an" parts ne'essary to buil" an An"roi" app. @BT*, the instru'tions presente" here are a''urate as o& the time o& this =riting. +o=e!er, the tools 'hange rapi"ly, an" so these instru'tions may be out o& "ate by the time you rea" this. #lease re&er to the An"roi" @e!elopers Web site &or 'urrent instru'tions, using this as a base gui"eline o& =hat to e;pe't.
7
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
shoul" su&&i'e. *ollo= the instru'tions supplie" by >ra'le or Apple &or installing it on your ma'hine. At the time o& this =riting, An"roi" supports Ca!a A an" Ca!a /, the latter being the no=-'urrent e"ition.
)e rn ' v
5his book, like most books an" "o'umentation on An"roi", assumes that you ha!e basi' Ca!a programming e;perien'e. 0& you la'k this, you really shoul" 'onsi"er spen"ing a bit o& time on Ca!a &un"amentals, be&ore you "i!e into An"roi". >ther=ise, you may &in" the e;perien'e to be &rustrating. 0& you are in nee" o& a 'rash 'ourse in Ca!a to get in!ol!e" in An"roi" "e!elopment, here are the 'on'epts you nee" to su''ee", presente" in no parti'ular or"er,
Language &un"amentals (&lo= 'ontrol, et'.) Classes an" obGe'ts Metho"s an" "ata members #ubli', pri!ate, an" prote'te" %tati' an" instan'e s'ope E;'eptions 5hrea"s an" 'on'urren'y 'ontrol Colle'tions 8eneri's
8
At this point, =hile you ha!e some o& the buil" tools, you la'k the Ca!a &iles ne'essary to 'ompile an An"roi" appli'ation. ?ou also la'k a &e= a""itional buil" tools, plus the &iles ne'essary to run an An"roi" emulator. 5o a""ress this, 'li'k on the A!ailable #a'kages option on the le&t. 5his brings up a tree,
*<
>pen the An"roi" epository bran'h o& the tree. A&ter a short pause, you =ill see a s'reen similar to this,
M%@D #lat&ormM &or all An"roi" %@D releases you =ant to test against M@o'umentation &or An"roi" %@DM &or the latest An"roi" %@D release M%amples &or %@DM &or the latest An"roi" %@D release, an" perhaps &or ol"er releases i& you =ish
5hen, open the 5hir"-#arty A""->ns bran'h o& the tree. A&ter a short pause, you =ill see a s'reen similar to this,
**
*ol" open the M8oogle 0n'. a""-onsM bran'h, =hi'h =ill "isplay something like this,
Most likely, you =ill =ant to 'he'k the M8oogle A#0s by 8oogle 0n'.M items that mat'h up =ith the %@D !ersions you sele'te" in the An"roi" epository bran'h. 5he M8oogle A#0sM in'lu"e support &or 8oogle Maps, both &rom your 'o"e an" in the An"roi" emulator.
*&
When you ha!e 'he'ke" all o& the items you =ant to "o=nloa", 'li'k the 0nstall %ele'te" button, =hi'h brings up a li'ense 'on&irmation "ialog,
e!ie= an" a''ept the li'enses, then 'li'k the 0nstall button. At this point, this is a &ine time to go get lun'h. >r, perhaps "inner. $nless you ha!e a substantial 0nternet 'onne'tion, "o=nloa"ing all o& this "ata an" unpa'king it =ill take a &air bit o& time. When the "o=nloa" is 'omplete, you 'an 'lose up the %@D an" A-@ Manager i& you =ish, though =e =ill use it to set up the emulator in a later step o& this 'hapter.
*-
2e;t, you nee" to install the An"roi" @e!eloper 5ools (A@5) plug-in. 5o "o this, go to +elp U 0nstall 2e= %o&t=are... in the E'lipse main menu. 5hen, 'li'k the A"" button to a"" a ne= sour'e o& plug-ins. 8i!e it some name (e.g., An"roi") an" supply the &ollo=ing $ L, https://dlssl.google.com/android/eclipse/. 5hat shoul" trigger E'lipse to "o=nloa" the roster o& plug-ins a!ailable &rom that site,
Che'k the 'he'kbo; to the le&t o& M@e!eloper 5oolsM an" 'li'k the 2e;t button. *ollo= the rest o& the =iKar" to re!ie= the tools to be "o=nloa"e" an" their respe'ti!e li'ense agreements. When the *inish button is enable", 'li'k it, an" E'lipse =ill "o=nloa" an" install the plug-ins. When "one, E'lipse =ill ask to restart S please let it. 5hen, you nee" to tea'h A@5 =here your An"roi" %@D installation is &rom the pre'e"ing se'tion. 5o "o this, 'hoose Win"o= U #re&eren'es &rom the
*%
E'lipse main menu (or the eRui!alent #re&eren'es option &or >% F). Cli'k on the An"roi" entry in the list on the le&t,
5hen, 'li'k the 1ro=se... button to &in" the "ire'tory =here you installe" the %@D. A&ter 'hoosing it, 'li'k Apply on the #re&eren'es =in"o=, an" you shoul" see the An"roi" %@D !ersions you installe" pre!iously. 5hen, 'li'k >D, an" the A@5 =ill be rea"y &or use.
=ill nee" Ant !ersion 1.8.1, so "ouble-'he'k your 'urrent 'opy (e.g., ant -version) to ensure you are on the proper e"ition. 0& you "o not ha!e Ant, you 'an obtain it &rom the Apa'he Ant Web site. 5hey ha!e &ull installation instru'tions in the Ant manual, but the basi' steps are, 1. $npa'k the Q0# ar'hi!e =here!er it may make sense on your ma'hine
2. A"" a JAVA !"#$ en!ironment !ariable, pointing to =here your C@D is installe", i& you "o not ha!e one alrea"y .. A"" an A%& !"#$ en!ironment !ariable, pointing to the "ire'tory =here you unpa'ke" Ant in the &irst step abo!e <. A"" 'JAVA !"#$/bin an" 'A%& !"#$/bin to your (A&! A. un ant -version to 'on&irm that Ant is installe" properly
*2
Cli'k the 2e=... button to 'reate a ne= A-@ &ile. 5his brings up a "ialog =here you 'an 'on&igure =hat this A-@ shoul" look an" =ork like,
*7
A name &or the A-@. %in'e the name goes into &iles on your "e!elopment ma'hine, you =ill be limite" by &ilename 'on!entions &or your operating system (e.g., no ba'kslashes on Win"o=s). 5he An"roi" !ersion you =ant the emulator to run (a.k.a., the MtargetM). Choose one o& the %@Ds you installe" !ia the "rop-"o=n list. 2ote that in a""ition to MpureM An"roi" en!ironments, you =ill ha!e options base" on the thir"-party a""-ons you sele'te". *or e;ample, you probably ha!e some options &or setting up A-@s 'ontaining the 8oogle A#0s, an" you =ill nee" su'h an A-@ &or testing an appli'ation that uses 8oogle Maps. @etails about the %@ 'ar" the emulator shoul" emulate. %in'e An"roi" "e!i'es in!ariably ha!e some &orm o& Me;ternal storageM, you probably =ant to set up an %@ 'ar", by supplying a siKe in the asso'iate" &iel". +o=e!er, sin'e a &ile =ill be 'reate" on your "e!elopment ma'hine o& =hate!er siKe you spe'i&y &or the 'ar", you probably "o not =ant to 'reate a 281 emulate" %@ 'ar". .2M1 is a ni'e starting point, though you 'an go larger i& nee"e". 5he MskinM or resolution the emulator shoul" run in. 5he skin options you ha!e =ill "epen" upon =hat target you 'hose. 5he skins let you 'hoose a typi'al An"roi" s'reen resolution (e.g., W-8A800 &or 800;<80). ?ou 'an also manually spe'i&y a resolution =hen you =ant to test a non-stan"ar" 'on&iguration.
?ou 'an skip the M+ar"=areM se'tion &or no=, as 'hanging those settings is usually only reRuire" &or a"!an'e" 'on&igurations. 5he resulting "ialog might look something like this,
*8
Cli'k the Create A-@ button, an" your A-@ stub =ill be 'reate". 5o start the emulator, highlight it in the list an" 'li'k %tart... ?ou 'an skip the laun'h options &or no= an" Gust 'li'k Laun'h. 5he &irst time you laun'h a ne= A-@, it =ill take a long time to start up. 5he se'on" an" subseRuent times you start the A-@, it =ill 'ome up a bit &aster, an" usually you only nee" to start it up on'e per "ay (e.g., =hen you start "e!elopment). ?ou "o not nee" to stop an" restart the emulator e!ery time you =ant to test your appli'ation, in most 'ases. 5he emulator =ill go through a &e= startup phases, &irst =ith a plain-te;t MA2@ >0@M label,
*:
&<
be&ore e!entually lan"ing at the home s'reen (the &irst time you run the A-@, sho=n belo=) or the keyguar",
&*
0& you get the keyguar" (sho=n belo=), press the ME2$ button, or sli"e the green lo'k on the s'reen to the right, to get to the emulator7s home s'reen,
&&
&-
8enerally, you =ill =ant to enable $%1 "ebugging, so you 'an use your "e!i'e =ith the An"roi" buil" tools. ?ou 'an lea!e the other settings alone &or no= i& you =ish, though you may &in" the M%tay a=akeM option to be han"y, as it sa!es you &rom ha!ing to unlo'k your phone all o& the time =hile it is plugge" into $%1. 2e;t, you nee" to get your "e!elopment ma'hine set up to talk to your "e!i'e. 5hat pro'ess !aries by the operating system o& your "e!elopment ma'hine, as is 'o!ere" in the &ollo=ing se'tions.
,indo#s
When you &irst plug in your An"roi" "e!i'e, Win"o=s =ill attempt to &in" a "ri!er &or it. 0t is possible that, by !irtue o& other so&t=are you ha!e installe", that the "ri!er is rea"y &or use. 0& it &in"s a "ri!er, you are probably rea"y to go.
&%
0& the "ri!er is not &oun", here are some options &or getting one.
,indo#s -pd te
%ome !ersions o& Win"o=s (e.g., -ista) =ill prompt you to sear'h Win"o=s $p"ate &or "ri!ers. 5his is 'ertainly =orth a shot, though not e!ery "e!i'e =ill ha!e supplie" its "ri!er to Mi'roso&t.
St nd rd Android Driver
0n your An"roi" %@D installation, you =ill &in" a google-usb driver "ire'tory, 'ontaining a generi' Win"o=s "ri!er &or An"roi" "e!i'es. ?ou 'an try pointing the "ri!er =iKar" at this "ire'tory to see i& it thinks this "ri!er is suitable &or your "e!i'e.
+S / nd )inu0
>""s are "e'ent that simply plugging in your "e!i'e =ill MGust =orkM. ?ou 'an see i& An"roi" re'ogniKes your "e!i'e !ia running adb devices in a shell (e.g., >% F 5erminal), =here adb is in your platform-tools/ "ire'tory o& your %@D. 0& you get output similar to the &ollo=ing, An"roi" "ete'te" your "e!i'e,
)ist of devices attached !&*+((,-*./0 device
0& you are running $buntu (or perhaps other Linu; !ariants), an" this 'omman" "i" not =ork, you may nee" to a"" some udev rules. *or e;ample,
&0
here is a .1-android.rules &ile that =ill han"le the "e!i'es &rom a han"&ul o& manu&a'turers,
234252&$#667usb78 25292:idVendor;667-bb<78 #"=$67-0007 234252&$#667usb78 25292:idVendor;667>>b,78 #"=$67-0007 234252&$#667usb78 25292:idVendor;6671,d178 #"=$67-0007 234252&$#2667usb78 A&&?2:idVendor;6671,d178 A&&?2:id(roduct;667-c-178 #"=$67-00078 "@%$?67AmeB7 234252&$#667usb78 25292:idVendor;6671*d>78 25292:id(roduct;6671C.<78 #"=$67-0007 234252&$#667usb78 25292:idVendor;667-<e,78 25292:id(roduct;6670,1c78 #"=$67-0007
@rop that in your /etc/udev/rules.d "ire'tory on $buntu, then either reboot the 'omputer or other=ise reloa" the udev rules (e.g., sudo service udev reload). 5hen, unplug an" re-plug in the "e!i'e an" see i& it is "ete'te".
&2
CHAPTER 1
2o= that you ha!e the An"roi" %@D, it is time to make your &irst An"roi" proGe't. 5he goo" ne=s is that this reRuires Kero lines o& 'o"e S An"roi"7s tools 'reate a M+ello, =orl":M appli'ation &or you as part o& 'reating a ne= proGe't. All you nee" to "o is buil" it, install it, an" see it 'ome up on your emulator or "e!i'e.
Eclipse
*rom the E'lipse main menu, 'hoose *ile U 2e= U #roGe't..., an" this =ill bring up a list o& proGe't types to 'hoose &rom. *ol" open the An"roi" option an" 'li'k on An"roi" #roGe't,
&7
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
#ress 2e;t to a"!an'e the =iKar" to the main An"roi" proGe't page,
&8
5he name o& the proGe't (e.g., 2o=) 5he An"roi" %@D you =ish to 'ompile against (e.g., 8oogle A#0s &or An"roi" 2....) 5he name o& the Ca!a pa'kage in =hi'h this proGe't goes (e.g., 'om.'ommons=are.an"roi".skeleton)
&:
-<
Comm nd )ine
+ere is a sample 'omman" that 'reates an An"roi" proGe't &rom the 'omman" line,
android create project --target 7Doogle Inc.:Doogle A(Is:/7 --path 2keleton/%oE --activitF %oE --package com.commonsEare.android.skeleton
5his =ill 'reate an appli'ation skeleton &or you, 'omplete =ith e!erything you nee" to buil" your &irst An"roi" appli'ation, Ca!a sour'e 'o"e, buil" instru'tions, et'. +o=e!er, you are probably going to nee" to 'ustomiKe this some=hat. +ere are =hat those 'omman"-line s=it'hes mean,
in"i'ates =hat !ersion o& An"roi" you are MtargetingM in terms o& your buil" pro'ess. ?ou nee" to supply the 0@ o& a target that is installe" on your "e!elopment ma'hine, one you "o=nloa"e" !ia the %@D an" A-@ Manager. ?ou 'an &in" out =hat targets are a!ailable !ia the android list targets 'omman". 5ypi'ally, your buil" pro'ess =ill target the ne=est !ersion o& An"roi" that you ha!e a!ailable.
--target
in"i'ates =here you =ant the proGe't &iles to be generate". An"roi" =ill 'reate a "ire'tory i& the one you name "oes not e;ist. *or e;ample, in the 'omman" sho=n abo!e, a 2keleton/%oE/ "ire'tory =ill be 'reate" (or use" i& it e;ists) un"erneath the 'urrent =orking "ire'tory, an" the proGe't &iles =ill be store" there.
--path
in"i'ates the Ca!a 'lass name o& your &irst a'ti!ity &or this proGe't. @o not in'lu"e a pa'kage name, an" the name has to meet Ca!a 'lass naming 'on!entions.
--activitF
in"i'ates the Ca!a pa'kage in =hi'h your &irst a'ti!ity =ill be lo'ate". 5his pa'kage also uniRuely i"enti&ies your proGe't on any "e!i'e on =hi'h you install it, an" this pa'kage also nee"s to be uniRue on the An"roi" Market i& you plan on "istributing your appli'ation there. +en'e, typi'ally, you 'onstru't your pa'kage base" on a "omain name you o=n (e.g., com.commonsEare.android.skeleton), to re"u'e the o""s o& an a''i"ental pa'kage name 'ollision =ith somebo"y else.
--package
-*
*or your "e!elopment ma'hine, you =ill nee" to pi'k a suitable target, an" you may =ish to 'hange the path. 5he a'ti!ity an" pa'kage you 'an lea!e alone &or no=.
Step 4&5 Build@ nstall@ and Cun the Application in .our =mulator or /evice
+a!ing a proGe't is ni'e an" all, but it =oul" be e!en better i& =e 'oul" buil" an" run it, =hether on the An"roi" emulator or your An"roi" "e!i'e. >n'e again, the pro'ess "i&&ers some=hat "epen"ing on =hether you are using E'lipse or not.
Eclipse
With your proGe't sele'te" in the #a'kage E;plorer pane, 'li'k the green MplayM button in the E'lipse toolbar to run your proGe't. 5he &irst time you "o this, you =ill ha!e to go through a &e= steps to set up a Mrun 'on&igurationM, so E'lipse kno=s =hat you =ant to "o. *irst, in the M un AsM list, 'hoose MAn"roi" Appli'ationM,
0& you ha!e more than one emulator A-@ or "e!i'e a!ailable, you =ill then get an option to 'hoose =hi'h you =ish to run the appli'ation on. >ther=ise, i& you "o not ha!e a "e!i'e plugge" in, the emulator =ill start up =ith the A-@ you 'reate" earlier. 5hen, E'lipse =ill install the appli'ation on your "e!i'e or emulator an" start it up.
Comm nd )ine
*or "e!elopers not using E'lipse, in your terminal, 'hange into the 2keleton/%oE "ire'tory, then run the &ollo=ing 'omman",
ant clean install
5he Ant-base" buil" shoul" emit a list o& steps in!ol!e" in the installation pro'ess, =hi'h look like this,
4uildfile: /home/some-balding-guF/projects/2keleton/%oE/build.Gml AsetupB Android 2=H &ools ?evision , AsetupB (roject &arget: Doogle A(Is AsetupB Vendor: Doogle Inc. AsetupB (latform Version: >.1-update1 AsetupB A(I level: / AsetupB AsetupB -----------------AsetupB ?esolving librarF dependencies: AsetupB %o librarF dependencies. AsetupB AsetupB -----------------AsetupB AsetupB @A?%I%D: %o min2dkVersion value set. Application Eill install on all Android versions. AsetupB AsetupB Importing rules file: tools/ant/main rules.Gml clean: AdeleteB =eleting directorF /home/some-balding-guF/projects/2keleton/%oE/bin -debug-obfuscation-check: -set-debug-mode: -compile-tested-if-test: -dirs: AechoB +reating output directories if needed... AmkdirB +reated dir: /home/some-balding-guF/projects/2keleton/%oE/bin
--
AmkdirB +reated dir: /home/some-balding-guF/projects/2keleton/%oE/gen AmkdirB +reated dir: /home/some-balding-guF/projects/2keleton/%oE/bin/classes -pre-build: -resource-src: AechoB Denerating ?.java / #anifest.java from the resources... -aidl: AechoB +ompiling aidl files into Java classes... -pre-compile: compile: AjavacB /opt/android-sdk-linuG/tools/ant/main rules.Gml:C01: Earning: IincludeantruntimeI Eas not set8 defaulting to build.sFsclasspath6lastJ set to false for repeatable builds AjavacB +ompiling > source files to /home/some-baldingguF/projects/2keleton/%oE/bin/classes -post-compile: -obfuscate: -deG: AechoB +onverting compiled files and eGternal libraries into /home/somebalding-guF/projects/2keleton/%oE/bin/classes.deG... -package-resources: AechoB (ackaging resources AaaptB +reating full resource package... -package-debug-sign: AapkbuilderB +reating %oE-debug-unaligned.apk and signing it Eith a debug keF... debug: AechoB ?unning Kip align on final apk... AechoB =ebug (ackage: /home/some-balding-guF/projects/2keleton/%oE/bin/%oEdebug.apk 43I)= 23++$2293) &otal time: < seconds
2ote the 43I)= 23++$2293) at the bottom S that is ho= you kno= the appli'ation 'ompile" su''ess&ully. When you ha!e a 'lean buil", in your emulator or "e!i'e, open up the appli'ation laun'her, typi'ally &oun" at the bottom o& the home s'reen,
-%
2oti'e there is an i'on &or your %oE appli'ation. Cli'k on it to open it an" see your &irst a'ti!ity in a'tion. 5o lea!e the appli'ation an" return to the laun'her, press the M1ACD buttonM, lo'ate" to the right o& the VME2$W button, an" looks like an arro= pointing to the le&t.
-0
CHAPTER 2
5he pre!ious 'hapter steppe" you through 'reating a stub proGe't. 2o=, let us take a peek at =hat is insi"e o& this proGe't, so you un"erstan" =hat An"roi" gi!es you at the outset an" =hat the roles are &or the !arious "ire'tories an" &iles.
ProAect Structure
5he An"roi" buil" system is organiKe" aroun" a spe'i&i' "ire'tory tree stru'ture &or your An"roi" proGe't, mu'h like any other Ca!a proGe't. 5he spe'i&i's, though, are &airly uniRue to An"roi" S the An"roi" buil" tools "o a &e= e;tra things to prepare the a'tual appli'ation that =ill run on the "e!i'e or emulator. +ere7s a Rui'k primer on the proGe't stru'ture, to help you make sense o& it all, parti'ularly &or the sample 'o"e re&eren'e" in this book.
Root Contents
When you 'reate a ne= An"roi" proGe't (e.g., !ia android create project), you get se!eral items in the proGe't7s root "ire'tory, in'lu"ing,
Android#anifest.Gml, =hi'h
is an FML &ile "es'ribing the appli'ation being built an" =hat 'omponents S a'ti!ities, ser!i'es, et'. S are being supplie" by that appli'ation
bin/, =hi'h
libs/, res/,
=hi'h hol"s any thir"-party Ca!a CA s your appli'ation reRuires =hi'h hol"s Mresour'esM, su'h as i'ons, 8$0 layouts, an" the like, that get pa'kage" =ith the 'ompile" Ca!a in the appli'ation
src/, =hi'h
0n a""ition to the &iles an" "ire'tories sho=n abo!e, you may &in" any o& the &ollo=ing in An"roi" proGe'ts,
assets/, =hi'h hol" other stati' &iles you =ish pa'kage" =ith the appli'ation &or "eployment onto the "e!i'e gen/,
=here An"roi"7s buil" tools =ill pla'e sour'e 'o"e that they generate
build.Gml an" *.properties, =hi'h are use" as part o& the Ant-base" 'omman"-line buil" pro'ess, i& you are not using E'lipse proguard.cfg,
=hi'h is use" &or integration =ith #ro8uar" &or ob&us'ating your An"roi" 'o"e
-8
the samples =here =e re&eren'e things in ?.java (e.g., re&erring to a layout7s i"enti&ier !ia ?.laFout.main).
res/raE/ &or general-purpose &iles (e.g,. an au"io 'lip, a C%- &ile o& a''ount in&ormation) res/values/
%ome o& the "ire'tory names may ha!e su&&i;es, like res/draEable-hdpi/. 5his in"i'ates that the "ire'tory o& resour'es shoul" only be use" in 'ertain 'ir'umstan'es S in this 'ase, the "ra=able resour'es shoul" only be use" on "e!i'es =ith high-"ensity s'reens. We =ill 'o!er all o& these, an" more, in later 'hapters o& this book. 0n your initial proGe't, you =ill &in",
res/draEable-hdpi/icon.png, res/draEable-mdpi/icon.png, res/draEable-ldpi/icon.png, an" =hi'h are three ren"itions o& a pla'ehol"er i'on &or your appli'ation &or high-, lo=-, an" me"ium"ensity s'reens, respe'ti!ely res/laFout/main.Gml,
=hi'h 'ontains an FML &ile that "es'ribes the !ery simple layout o& your user inter&a'e
-:
notably
hol"s the 'ompile" Ca!a 'lasses hol"s the e;e'utable 'reate" &rom those 'ompile"
bin/classes.deG
Ca!a 'lasses
hol"s your appli'ation7s resour'es, pa'kage" as a Q0# &ile (=here Fourapp is the name o& your appli'ation)
bin/Fourapp.ap bin/Fourapp-*.apk
5he .apk &ile is a Q0# ar'hi!e 'ontaining the .deG &ile, the 'ompile" e"ition o& your resour'es (resources.arsc), any un-'ompile" resour'es (su'h as =hat you put in res/raE/) an" the Android#anifest.Gml &ile. 0& you buil" a "ebug !ersion o& the appli'ation S =hi'h is the "e&ault S you =ill ha!e Fourapp-debug.apk an" Fourapp-debug-aligned.apk as t=o !ersions o& your A#D. 5he latter has been optimiKe" =ith the Kipalign utility to make it run &aster.
a &e= minor mo"i&i'ations. >n the other en" o& the spe'trum, the mani&est &ile &or the An"roi" A#0 "emo suite is o!er 1,000 lines long. ?our pro"u'tion An"roi" appli'ations =ill probably &all some=here in the mi""le.
2ote the namespa'e "e'laration. Curiously, the generate" mani&ests only apply it on the attributes, not the elements (e.g., manifest, not android:manifest). +o=e!er, that pattern =orks, so unless An"roi" 'hanges, sti'k =ith their pattern. 5he biggest pie'e o& in&ormation you nee" to supply on the manifest element is the package attribute (also 'uriously not-namespa'e"). +ere, you 'an pro!i"e the name o& the Ca!a pa'kage that =ill be 'onsi"ere" the MbaseM o& your appli'ation. 5hen, e!ery=here else in the mani&est &ile that nee"s a 'lass name, you 'an Gust substitute a lea"ing "ot as shorthan" &or the pa'kage. *or e;ample, i& you nee"e" to re&er to com.commonsEare.android.search.2nicklefritK in this mani&est sho=n abo!e, you 'oul" Gust use .2nicklefritK, sin'e com.commonsEare.android.search is "e&ine" as the appli'ation7s pa'kage. As note" in the pre!ious 'hapter, your pa'kage also is a uniRue i"enti&ier &or your appli'ation. A "e!i'e 'an only ha!e one appli'ation installe" =ith a gi!en pa'kage, an" the An"roi" Market =ill only list one proGe't =ith a gi!en pa'kage. ?our mani&est also spe'i&ies android:version%ame an" android:version+ode attributes. 5hese represent the !ersions o& your appli'ation. 5he android:version%ame !alue is =hat the user =ill see in the Appli'ations list in
%*
their %ettings appli'ation. Also, the !ersion name is use" by the An"roi" Market listing, i& you are "istributing your appli'ation that =ay. 5he !ersion name 'an be any string !alue you =ant. 5he android:version+ode, on the other han", must be an integer, an" ne=er !ersions must ha!e higher !ersion 'o"es than "o ol"er !ersions. An"roi" an" the An"roi" Market =ill 'ompare the !ersion 'o"e o& a ne= A#D to the !ersion 'o"e o& an installe" appli'ation to "etermine i& the ne= A#D is in"ee" an up"ate. 5he typi'al approa'h is to start the !ersion 'o"e at 1 an" in'rement it =ith ea'h pro"u'tion release o& your appli'ation, though you 'an 'hoose another 'on!ention i& you =ish.
%&
5his element supplies android:name &or the 'lass implementing the a'ti!ity, android:label &or the "isplay name o& the a'ti!ity, an" (&reRuently) an Lintent-filterM 'hil" element "es'ribing un"er =hat 'on"itions this a'ti!ity =ill be "isplaye". 5he sto'k LactivitFM element sets up your a'ti!ity to appear in the laun'her, so users 'an 'hoose to run it. As =e7ll see later in this book, you 'an ha!e se!eral a'ti!ities in one proGe't, i& you so 'hoose.
%-
CHAPTER 6
E'lipse is an e;tremely popular 0@E, parti'ularly &or Ca!a "e!elopment. 0t is also "esigne" to be e;tensible !ia an a""-in system. 5o top it o&&, E'lipse is open sour'e. 5hat 'ombination ma"e it an i"eal 'hoi'e o& 0@E to get attention &rom the 'ore An"roi" "e!eloper team. %pe'i&i'ally, to go alongsi"e the An"roi" %@D, 8oogle has publishe" some a""-ins &or the E'lipse en!ironment. #rimary among these is the An"roi" @e!eloper 5ools (A@5) a""-in, =hi'h gi!es the 'ore o& E'lipse a=areness o& An"roi".
2e= proGe't =iKar"s to 'reate regular An"roi" proGe'ts, An"roi" test proGe'ts, et'. 5he ability to run an An"roi" proGe't Gust like you might run a regular Ca!a appli'ation S !ia the green un button in the toolbar S "espite the &a't that this really in!ol!es pushing the An"roi" appli'ation o!er to an emulator or "e!i'e, possibly e!en starting up the emulator i& it is not running 5ooltip support &or An"roi" 'lasses an" metho"s An" so on
%0
0n a""ition, the latest !ersion o& the A@5 pro!i"es you =ith preliminary support &or "rag-an"-"rop 8$0 e"iting. While this book =ill &o'us on the FML &iles that E'lipse =ill generate, E'lipse no= lets you assemble those FML &iles by "ragging $0 'omponents aroun" on the s'reen, a"Gusting properties as you go. @rag-an"-"rop 8$0 e"iting is &airly ne=, an" so there may be a &e= rough e"ges &or a =hile as the 'ommunity an" 8oogle i"enti&y the problems an" limitations =ith the 'urrent implementation.
Ho# to Import
"on*Eclipse Pro7ect
2ot all An"roi" proGe'ts ship =ith E'lipse proGe't &iles, su'h as the sample proGe'ts asso'iate" =ith this book. +o=e!er, these 'an still be easily a""e" to your E'lipse =orkspa'e, i& you =ish. +ere is ho= to "o it: *irst, 'hoose *ile O 2e= O #roGe't... &rom the E'lipse main menu,
%2
5hen, 'hoose An"roi" O An"roi" #roGe't &rom the tree o& a!ailable proGe't types,
%7
2ote, i& you "o not see this option, you ha!e not installe" the An"roi" @e!eloper 5ools. 5hen, in the ne;t page o& the proGe't 'reation =iKar", 'hoose the MCreate proGe't &rom e;isting sour'eM ra"io button, 'li'k the V1ro=se...W button, an" open the "ire'tory 'ontaining your proGe't7s An"roi"Mani&est.;ml &ile. 5his =ill populate most o& the rest o& this s'reen, though you may nee" to also spe'i&y a buil" target &rom the table,
%8
5hen, 'li'k V*inishW. 5his =ill return you to E'lipse, =ith the importe" proGe't in your =orkspa'e,
%:
2e;t, right-'li'k o!er the proGe't name, an" 'hoose 1uil" #ath O Con&igure 1uil" #ath &rom the 'onte;t menu,
5his brings up the buil" path portion o& the proGe't properties =in"o=,
0& the An"roi" CA is not 'he'ke" (see the An"roi" 2.2 entry in the abo!e image), 'he'k it, then 'lose the properties =in"o=. At this point, your proGe't shoul" be rea"y &or use.
0*
0&
5his =ill a"" the @@M% perspe'ti!e to your =orkspa'e an" open it in your E'lipse 0@E. @@M% is 'o!ere" in greater "etail in a later 'hapter o& this book.
0-
5hat brings up the same =in"o= as you 'an get by running android &rom the 'omman" line.
Ho# to Run
Pro7ect
8i!en that you ha!e an A-@ "e&ine", or that you ha!e a "e!i'e set up &or "ebugging an" 'onne'te" to your "e!elopment ma'hine, you 'an run your proGe't in the emulator. *irst, 'li'k the un toolbar button, or 'hoose #roGe't O un &rom the main menu. 5his =ill bring up the M un AsM "ialog the &irst time you run the proGe't,
0%
Choose An"roi" Appli'ation an" 'li'k >D. 0& you ha!e more than one A-@ or "e!i'e a!ailable, you =ill be presente" =ith a =in"o= =here you 'hoose the "esire" target en!ironment. 5hen, the emulator =ill start up to run your appli'ation. 2ote that you =ill nee" to unlo'k the lo'k s'reen on the emulator (or "e!i'e) i& it is lo'ke".
Alternative /=s
0& you really like E'lipse an" the A@5, you may =ant to 'onsi"er M>5>@E- %tu"io &or An"roi". 5his is another set o& a""-ins &or E'lipse,
00
augmenting the A@5 an" o&&ering a number o& other An"roi"-relate" "e!elopment &eatures, in'lu"ing,
More =iKar"s &or helping you 'reate An"roi" 'lasses 0ntegrate" %JLite bro=sing, so you 'an manipulate a %JLite "atabase in your emulator right &rom your 0@E More !ali"ators to 'he'k &or 'ommon bugs, an" a library o& 'o"e snippets to ha!e &e=er bugs at the outset Assistan'e =ith translating your appli'ation to multiple languages An" mu'h more
While M>5>@E- %tu"io &or An"roi" is publishe" by Motorola, you 'an use it to buil" appli'ations &or all An"roi" "e!i'es, not only those manu&a'ture" by Motorola themsel!es. >ther 0@Es are slo=ly getting their eRui!alents o& the A@5, albeit =ith minimal assistan'e &rom 8oogle. *or e;ample, 0ntelliC7s 0@EA has a mo"ule &or An"roi" S originally 'ommer'ial, it is part o& the open sour'e 'ommunity e"ition o& 0@EA as o& !ersion 10. An", o& 'ourse, you "o not nee" to use an 0@E at all. While this may soun" sa'rilegious to some, 0@Es are not the only =ay to buil" appli'ations. Mu'h o& =hat is a''omplishe" !ia the A@5 'an be a''omplishe" through 'omman"-line eRui!alents, meaning a shell an" an e"itor is all you truly nee". *or e;ample, the author o& this book "oes not presently use an 0@E an" has no intention o& a"opting E'lipse any time soon.
02
07
CHAPTER 8
5he An"roi"Mani&est.;ml &ile that An"roi" generate" &or your &irst proGe't gets the Gob "one. +o=e!er, &or a pro"u'tion appli'ation, you may =ish to 'onsi"er a""ing a &e= attributes an" elements, su'h as those "es'ribe" in this 'hapter.
%mall (un"er .M) 2ormal (.M to aroun" <.AM) Large (<.AM to aroun" 10M) E;tra-large (o!er 10M)
1y "e&ault, your appli'ation =ill not support small s'reens, =ill support normal s'reens, an" may support large an" e;tra-large s'reens !ia some automate" 'on!ersion 'o"e built into An"roi". 5o truly support all the s'reen siKes you =ant, you shoul" 'onsi"er a""ing a Lsupports-screensM element. 5his enumerates the s'reen siKes you ha!e e;pli'it support &or. *or e;ample, i& you =ant to support small s'reens, you
0:
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
=ill nee" the Lsupports-screensM element. %imilarly, i& you are pro!i"ing 'ustom $0 support &or large or e;tra-large s'reens, you =ill =ant to ha!e the Lsupports-screensM element. %o, =hile the starting mani&est &ile =orks, han"ling multiple s'reen siKes is something you =ill =ant to think about. Mu'h more in&ormation about pro!i"ing soli" support &or all s'reen siKes 'an be &oun" later in this book.
Specifying ;ersions
As =as note" in the pre!ious 'hapter, your mani&est alrea"y 'ontains some !ersion in&ormation, about your o=n appli'ation7s !ersion. +o=e!er, you probably =ant to a"" a Luses-sdkM element as a 'hil" o& the LmanifestM element to your Android#anifest.Gml &ile, to spe'i&y =hat !ersions o& An"roi" you are supporting. 1y "e&ault, your appli'ation is assume" to support e!ery An"roi" !ersion &rom 1.0 to the 'urrent ..0 an" on=ar" to any !ersion in the &uture. Most likely, that is not =hat you =ant. 5he important attribute &or your Luses-sdkM element is android:min2dkVersion. 5his in"i'ates =hat is the ol"est !ersion o& An"roi" you are testing =ith your appli'ation. 5he !alue o& the attribute is an integer representing the An"roi" %@D !ersion,
most
An"roi" 1.0 X 1 An"roi" 1.1 X 2 An"roi" 1.A X . An"roi" 1./ X < An"roi" 2.0 X A An"roi" 2.0.1 X / An"roi" 2.1 X 4 An"roi" 2.2 X 8 An"roi" 2.. X 3 An"roi" 2.... X 10
2<
An"roi" ..0 X 11
%o, i& you are only testing your appli'ation on An"roi" 2.1 an" ne=er !ersions o& An"roi", you =oul" set your android:min2dkVersion to be /. ?ou may also =ish to spe'i&y an android:target2dkVersion attribute. 5his in"i'ates =hat !ersion o& An"roi" you are thinking o& as you are =riting your 'o"e. 0& your appli'ation is run on a ne=er !ersion o& An"roi", An"roi" may "o some things to try to impro!e 'ompatibility o& your 'o"e =ith respe't to 'hanges ma"e in the ne=er An"roi". %o, right no=, you might spe'i&y android:target2dkVersion671-7, in"i'ating you are =riting your appli'ation =ith An"roi" 2.... in min" S i& your app some"ay is run on an An"roi" ..0 "e!i'e, An"roi" may take some e;tra steps to make sure your 2....-'entri' 'o"e runs 'orre'tly on the ..0 "e!i'e. 0n parti'ular, to get the ne= M+oney'ombM look-an"-&eel =hen running on an An"roi" ..0 (or higher) tablet, you nee" to spe'i&y a target %@D !ersion o& 11 S this =ill be 'o!ere" in more "etail later in the book.
2*
PART II Activities
CHAPTER 9
5he proGe't you 'reate" in a pre!ious 'hapter =as Gust the "e&ault &iles generate" by the An"roi" buil" tools S you "i" not =rite any Ca!a 'o"e yoursel&. 0n this 'hapter, =e =ill mo"i&y that proGe't to ha!e a some=hat more intera'ti!e sample. Along the =ay, =e =ill e;amine the basi' Ca!a 'o"e that makes up an An"roi" a'ti!ity. 2>5E, 5he instru'tions in this 'hapter assume you &ollo=e" the original instru'tions in terms o& the names o& pa'kages an" &iles. 0& you use" "i&&erent names ba'k then, you =ill nee" to a"Gust the &ollo=ing steps to mat'h.
The Activity
?our proGe't7s src/ "ire'tory 'ontains the stan"ar" Ca!a-style tree o& "ire'tories base" upon the Ca!a pa'kage you 'hose =hen you 'reate" the proGe't (e.g., com.commonsEare.android results in src/com/commonsEare/android/). 0nsi"e the innermost "ire'tory you shoul" &in" a pre-generate" sour'e &ile name" %oE.java, =hi'h is =here your &irst a'ti!ity =ill go. >pen %oE.java in your e"itor an" paste in the &ollo=ing 'o"e,
package com.commonsEare.android.skeletonJ import android.app.ActivitFJ
20
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
public class %oE eGtends ActivitF implements VieE."n+lick)istener : 4utton btnJ O"verride public void onCreateP4undle icicleQ : super.onCreatePicicleQJ btn6neE ButtonPthisQJ btn.setOnClickListenerPthisQJ updateTimePQJ setContentViewPbtnQJ
public void onClickPVieE vieEQ : updateTimePQJ ; private void updateTimePQ : btn.setTextPneE DatePQ.toStringPQQJ ; ;
>r, i& you "o=nloa" the sour'e &iles o&& the Web site, you 'an Gust use the 2keleton/%oE proGe't "ire'tly.
5he pa'kage "e'laration nee"s to be the same as the one you use" =hen 'reating the proGe't. An", like any other Ca!a proGe't, you nee" to import any 'lasses you re&eren'e. Most o& the An"roi"-spe'i&i' 'lasses are in the android pa'kage.
22
emember that not e!ery Ca!a %E 'lass is a!ailable to An"roi" programs: -isit the An"roi" 'lass re&eren'e to see =hat is an" is not a!ailable.
public class %oE eGtends ActivitF implements VieE."n+lick)istener : 4utton btnJ
A'ti!ities are publi' 'lasses, inheriting &rom the android.app.ActivitF base 'lass. 0n this 'ase, the a'ti!ity hol"s a button ( btn). %in'e, &or simpli'ity, =e =ant to trap all button 'li'ks Gust =ithin the a'ti!ity itsel&, =e also ha!e the a'ti!ity 'lass implement "n+lick)istener.
O"verride public void onCreateP4undle icicleQ : super.onCreatePicicleQJ btn6neE ButtonPthisQJ btn.setOnClickListenerPthisQJ updateTimePQJ setContentViewPbtnQJ ;
5he on+reatePQ metho" is in!oke" =hen the a'ti!ity is starte". 5he &irst thing you shoul" "o is 'hain up=ar" to the super'lass, so the sto'k An"roi" a'ti!ity initialiKation 'an be "one. 0n our implementation, =e then 'reate the button instan'e (neE 4uttonPthisQ), tell it to sen" all button 'li'ks to the a'ti!ity instan'e itsel& (!ia set"n+lick)istenerPQ), 'all a pri!ate update&imePQ metho" (see belo=), an" then set the a'ti!ity7s 'ontent !ie= to be the button itsel& (!ia set+ontentVieEPQ). We =ill "is'uss that magi'al 4undle icicle in a later 'hapter. *or the moment, 'onsi"er it an opaRue han"le that all a'ti!ities re'ei!e upon 'reation.
public void onClickPVieE vieEQ : updateTimePQJ ;
on+lickPQ
to be in!oke" in the "n+lick)istener instan'e 'on&igure" &or the button. 5he listener is pro!i"e" the !ie= that triggere" the 'li'k (in this 'ase, the button). All =e "o here is 'all that pri!ate update&imePQ metho",
private void updateTimePQ : btn.setTextPneE DatePQ.toStringPQQJ ;
When =e open the a'ti!ity (on+reatePQ) or =hen the button is 'li'ke" (on+lickPQ), =e up"ate the button7s label to be the 'urrent time !ia set&eGtPQ, =hi'h &un'tions mu'h the same as the J4utton eRui!alent.
28
Cli'king the button S in other =or"s, pretty mu'h any=here on the phone7s s'reen S =ill up"ate the time sho=n in the button7s label. 2ote that the label is 'entere" horiKontally an" !erti'ally, as those are the "e&ault styles applie" to button 'aptions. We 'an 'ontrol that &ormatting, =hi'h =ill be 'o!ere" in a later 'hapter. A&ter you are "one gaKing at the a=esomeness o& A"!an'e" #ush-1utton 5e'hnologyY, you 'an 'li'k the ba'k button on the emulator to return to the laun'her.
2:
CHAPTER :
While it is te'hni'ally possible to 'reate an" atta'h =i"gets to our a'ti!ity purely through Ca!a 'o"e, the =ay =e "i" in the pre'e"ing 'hapter, the more 'ommon approa'h is to use an FML-base" layout &ile. @ynami' instantiation o& =i"gets is reser!e" &or more 'ompli'ate" s'enarios, =here the =i"gets are not kno=n at 'ompile-time (e.g., populating a 'olumn o& ra"io buttons base" on "ata retrie!e" o&& the 0nternet). With that in min", it7s time to break out the FML an" learn ho= to lay out An"roi" a'ti!ity !ie=s that =ay.
An"roi"7s %@D ships =ith a tool (aapt) =hi'h uses the layouts. 5his tool shoul" be automati'ally in!oke" by your An"roi" tool 'hain (e.g., E'lipse, Ant7s build.Gml). >& parti'ular importan'e to you as a "e!eloper is that aapt generates the ?.java sour'e &ile =ithin your proGe't7s gen/ "ire'tory, allo=ing you to a''ess layouts an" =i"gets =ithin those layouts "ire'tly &rom your Ca!a 'o"e, as =ill be "emonstrate" later in this 'hapter.
7&
5he 'lass name o& the =i"get S 4utton S &orms the name o& the FML element. %in'e 4utton is an An"roi"-supplie" =i"get, =e 'an Gust use the bare 'lass name. 0& you 'reate your o=n =i"gets as sub'lasses o& android.vieE.VieE, you =oul" nee" to pro!i"e a &ull pa'kage "e'laration as =ell (e.g., com.commonsEare.android.#F@idget). 5he root element nee"s to "e'lare the An"roi" FML namespa'e,
Gmlns:android67http://schemas.android.com/apk/res/android7
All other elements =ill be 'hil"ren o& the root an" =ill inherit that namespa'e "e'laration. 1e'ause =e =ant to re&eren'e this button &rom our Ca!a 'o"e, =e nee" to gi!e it an i"enti&ier !ia the android:id attribute. We =ill 'o!er this 'on'ept in greater "etail later in this 'hapter. 5he remaining attributes are properties o& this 4utton instan'e,
in"i'ates the initial te;t to be "isplaye" on the button &a'e (in this 'ase, an empty string)
android:teGt android:laFout Eidth an" android:laFout height
tell An"roi" to ha!e the button7s =i"th an" height &ill the MparentM, in this 'ase the entire s'reen S these attributes =ill be 'o!ere" in greater "etail in a later 'hapter
7-
%in'e this single =i"get is the only 'ontent in our a'ti!ity7s !ie=, =e only nee" this single element. Comple; !ie=s =ill reRuire 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 FML layout &orm =hene!er pra'ti'al, so there are "oKens o& other e;amples o& more 'omple; layouts &or you to peruse.
5his is the same set+ontentVieEPQ =e use" earlier, passing it an instan'e o& a VieE sub'lass (in that 'ase, a 4utton). 5he An"roi"-built VieE, 'onstru'te" &rom our layout, is a''esse" &rom that 'o"e-generate" ? 'lass. All o& the layouts are a''essible un"er ?.laFout, keye" by the base name o& the layout &ile S res/laFout/main.Gml results in ?.laFout.main. 5o a''ess our i"enti&ie" =i"gets, use findVieE4FIdPQ, passing it the numeri' i"enti&ier o& the =i"get in Ruestion. 5hat numeri' i"enti&ier =as generate" by An"roi" in the ? 'lass as ?.id.something (=here something is the spe'i&i' =i"get you are seeking). 5hose =i"gets are simply sub'lasses o& VieE, Gust like the 4utton instan'e =e 'reate" in the pre!ious 'hapter.
public class %oE?eduG eGtends ActivitF implements VieE."n+lick)istener : 4utton btnJ O"verride public void onCreateP4undle icicleQ : super.onCreatePicicleQJ setContentViewP?.laFout.mainQJ btn6P4uttonQfindViewByIdP?.id.buttonQJ btn.setOnClickListenerPthisQJ updateTimePQJ
70
; public void onClickPVieE vieEQ : updateTimePQJ ; private void updateTimePQ : btn.setTextPneE DatePQ.toStringPQQJ ; ;
5he &irst "i&&eren'e is that rather than setting the 'ontent !ie= to be a !ie= =e 'reate" in Ca!a 'o"e, =e set it to re&eren'e the FML layout (set+ontentVieEP?.laFout.mainQ). 5he ?.java sour'e &ile =ill be up"ate" =hen =e rebuil" this proGe't to in'lu"e a re&eren'e to our layout &ile (store" as main.Gml in our proGe't7s res/laFout "ire'tory). 5he other "i&&eren'e is that =e nee" to get our han"s on our 4utton instan'e, &or =hi'h =e use the findVieE4FIdPQ 'all. %in'e =e i"enti&ie" our button as ORid/button, =e 'an re&eren'e the button7s i"enti&ier as ?.id.button. 2o=, =ith the 4utton instan'e in han", =e 'an set the 'allba'k an" set the label as nee"e". 5he results look the same as =ith the original %oE "emo,
72
77
CHAPTER ;
E!ery 8$0 toolkit has some basi' =i"gets, &iel"s, labels, buttons, et'. An"roi"7s toolkit is no "i&&erent in s'ope, an" the basi' =i"gets =ill pro!i"e a goo" intro"u'tion as to ho= =i"gets =ork in An"roi" a'ti!ities.
Assigning !abels
5he simplest =i"get is the label, re&erre" to in An"roi" as a &eGtVieE. Like in most 8$0 toolkits, labels are bits o& te;t not e"itable "ire'tly by users. 5ypi'ally, they are use" to i"enti&y a"Ga'ent =i"gets (e.g., a M2ame,M label be&ore a &iel" =here one &ills in a name). 0n Ca!a, you 'an 'reate a label by 'reating a &eGtVieE instan'e. More 'ommonly, though, you =ill 'reate labels in FML layout &iles by a""ing a &eGtVieE element to the layout, =ith an android:teGt property to set the !alue o& the label itsel&. 0& you nee" to s=ap labels base" on 'ertain 'riteria, su'h as internationaliKation, you may =ish to use a string resour'e re&eren'e in the FML instea", as =ill be "es'ribe" later in this book.
&eGtVieE
has numerous other properties o& rele!an'e &or labels, su'h as, to set the type&a'e to use &or the label (e.g., be ma"e bol"
android:tFpeface monospace)
android:teGt2tFle to in"i'ate that the type&a'e shoul" (bold), itali' (italic), or bol" an" itali' (bold italic)
7:
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
81 he;
*or e;ample, in the 4asic/)abel proGe't, you =ill &in" the &ollo=ing layout &ile,
LNGml version671.-7 encoding67utf-,7NM L&eGtVieE Gmlns:android67http://schemas.android.com/apk/res/android7 android:laFout Eidth67fill parent7 android:laFout height67Erap content7 android:teGt675ou Eere eGpecting something profoundN7 /M
Cust that layout alone, =ith the stub Ca!a sour'e pro!i"e" by An"roi"7s proGe't buil"er (e.g., android create project), gi!es you,
8<
"is'usse" in the pre'e"ing se'tion in terms o& &ormatting the &a'e o& the button still hol"s. +o=e!er, An"roi" 1./ a""e" a ne= &eature &or the "e'laration o& the Mon'li'kM listener &or a 4utton. 0n a""ition to the 'lassi' approa'h o& "e&ining some obGe't (su'h as the a'ti!ity) as implementing the VieE."n+lick)istener inter&a'e, you 'an no= take a some=hat simpler approa'h,
@e&ine some metho" on your ActivitF that hol"s the button that takes a single VieE parameter, has a void return !alue, an" is public 0n your layout FML, on the 4utton element, in'lu"e the android:on+lick attribute =ith the name o& the metho" you "e&ine" in the pre!ious step
*or e;ample, =e might ha!e a metho" on our ActivitF that looks like,
public void someMethodPVieE the4uttonQ : // do something useful here ;
5hen, =e 'oul" use this FML "e'laration &or the 4utton itsel&, in'lu"ing android:on+lick,
L4utton android:on+lick67some#ethod7 ... /M
5his is enough &or An"roi" to M=ire togetherM the 4utton =ith the 'li'k han"ler.
"leeting mages
An"roi" has t=o =i"gets to help you embe" images in your a'ti!ities, ImageVieE an" Image4utton. As the names suggest, they are image-base" analogues to &eGtVieE an" 4utton, respe'ti!ely.
8*
Ea'h =i"get takes an android:src attribute (in an FML layout) to spe'i&y =hat pi'ture to use. 5hese usually re&eren'e a "ra=able resour'e, "es'ribe" in greater "etail in the 'hapter on resour'es.
Image4utton, a sub'lass o& ImageVieE, mi;es in the stan"ar" 4utton beha!iors, &or respon"ing to 'li'ks an" =hatnot.
*or e;ample, take a peek at the main.Gml layout &rom the 4asic/ImageVieE sample proGe't,
LNGml version671.-7 encoding67utf-,7NM LImageVieE Gmlns:android67http://schemas.android.com/apk/res/android7 android:id67ORid/icon7 android:laFout Eidth67fill parent7 android:laFout height67fill parent7 android:adjustVieE4ounds67true7 android:src67OdraEable/molecule7 /M
5he result, Gust using the 'o"e-generate" a'ti!ity, is simply the image,
8&
to 'ontrol i& the &iel" shoul" automati'ally 'apitaliKe the &irst letter o& entere" te;t (e.g., &irst name, 'ity)
android:digits, to 'on&igure
android:single)ine, to 'ontrol i& the &iel" is &or single-line input or multiple-line input (e.g., "oes NEnterO mo!e you to the ne;t =i"get or a"" a ne=lineH)
Most o& those are also a!ailable &rom the ne= android:input&Fpe attribute, a""e" in An"roi" 1.A as part o& a""ing Mso&t keyboar"sM to An"roi" S this =ill be "is'usse" in an up'oming 'hapter. *or e;ample, &rom the 4asic/9ield proGe't, here is an FML layout &ile sho=ing an $dit&eGt,
LNGml version671.-7 encoding67utf-,7NM L$dit&eGt Gmlns:android67http://schemas.android.com/apk/res/android7 android:id67ORid/field7 android:laFout Eidth67fill parent7 android:laFout height67fill parent7 android:single)ine67false7 /M
2ote that android:single)ine is &alse, so users =ill be able to enter in se!eral lines o& te;t.
8-
*or this proGe't, the 9ield=emo.java &ile populates the input &iel" =ith some prose,
package com.commonsEare.android.fieldJ import android.app.ActivitFJ import android.os.4undleJ import android.Eidget.$dit&eGtJ public class 9ield=emo eGtends ActivitF : O"verride public void onCreateP4undle icicleQ : super.onCreatePicicleQJ setContentViewP?.laFout.mainQJ $dit&eGt fld6P$dit&eGtQfindViewByIdP?.id.fieldQJ fld.setTextP7)icensed under the Apache )icense8 Version >.- 7 R 7Pthe T7)icenseT7QJ Fou maF not use this file 7 R 7eGcept in compliance Eith the )icense. 5ou maF 7 R 7obtain a copF of the )icense at 7 R 7http://EEE.apache.org/licenses/)I+$%2$->.-7QJ ; ;
5he result, on'e built an" installe" into the emulator, is,
8%
Another &la!or o& &iel" is one that o&&ers auto-'ompletion, to help users supply a !alue =ithout typing in the =hole te;t. 5hat is pro!i"e" in An"roi" as the Auto+omplete&eGtVieE =i"get, "is'usse" in greater "etail later in this book.
to &or'e the 'he'kbo; into a 'he'ke" or un'he'ke" the 'he'kbo; as i& the user 'he'ke" it
state
togglePQ to toggle
Also, you 'an register a listener obGe't (in this 'ase, an instan'e o& "n+hecked+hange)istener) to be noti&ie" =hen the state o& the 'he'kbo; 'hanges. *or e;ample, &rom the 4asic/+heck4oG proGe't, here is a simple 'he'kbo; layout,
LNGml version671.-7 encoding67utf-,7NM L+heck4oG Gmlns:android67http://schemas.android.com/apk/res/android7 android:id67ORid/check7 android:laFout Eidth67Erap content7 android:laFout height67Erap content7 android:teGt67&his checkboG is: unchecked7 /M
80
5he 'orrespon"ing +heck4oG=emo.java retrie!es an" 'on&igures the beha!ior o& the 'he'kbo;,
public class +heck4oG=emo eGtends ActivitF implements +ompound4utton."n+hecked+hange)istener : +heck4oG cbJ O"verride public void onCreateP4undle icicleQ : super.onCreatePicicleQJ setContentViewP?.laFout.mainQJ cb6P+heck4oGQfindViewByIdP?.id.checkQJ cb.setOnCheckedChangeListenerPthisQJ
public void onCheckedChangedP+ompound4utton buttonVieE8 boolean is+heckedQ : if Pis+heckedQ : cb.setTextP7&his checkboG is: checked7QJ ; else : cb.setTextP7&his checkboG is: unchecked7QJ ; ; ;
2ote that the a'ti!ity ser!es as its o=n listener &or 'he'kbo; state 'hanges sin'e it implements the "n+hecked+hange)istener inter&a'e (!ia cb.set"n+hecked+hange)istenerPthisQ). 5he 'allba'k &or the listener is on+hecked+hangedPQ, =hi'h re'ei!es the 'he'kbo; =hose state has 'hange" an" =hat the ne= state is. 0n this 'ase, =e up"ate the te;t o& the 'he'kbo; to re&le't =hat the a'tual bo; 'ontains. 5he resultH Cli'king the 'he'kbo; imme"iately up"ates its te;t, as sho=n belo=,
82
"igure -71 The CheckBox/emo sample application@ )ith the checkbox unchecked
"igure -81 The same application@ no) )ith the checkbox checked
87
to 'lear all ra"io buttons, so none in the group are o& the 'urrently-'he'ke"
'he'ke"
get+hecked?adio4uttonIdPQ to get the 0@ ra"io button (or -1 i& none are 'he'ke")
2ote that the mutual-e;'lusion &eature o& ?adioDroup only applies to ?adio4utton =i"gets that are imme"iate 'hil"ren o& the ?adioDroup. ?ou 'annot ha!e other 'ontainers S "is'usse" in the ne;t 'hapter S bet=een the ?adioDroup an" its ?adio4utton =i"gets. *or e;ample, &rom the 4asic/?adio4utton sample appli'ation, here is an FML layout sho=ing a ?adioDroup =rapping a set o& ?adio4utton =i"gets,
LNGml version671.-7 encoding67utf-,7NM L?adioDroup Gmlns:android67http://schemas.android.com/apk/res/android7 android:orientation67vertical7 android:laFout Eidth67fill parent7 88
android:laFout height67fill parent7 M L?adio4utton android:id67ORid/radio17 android:laFout Eidth67Erap content7 android:laFout height67Erap content7 android:teGt67?ock7 /M L?adio4utton android:id67ORid/radio>7 android:laFout Eidth67Erap content7 android:laFout height67Erap content7 android:teGt672cissors7 /M L?adio4utton android:id67ORid/radioC7 android:laFout Eidth67Erap content7 android:laFout height67Erap content7 android:teGt67(aper7 /M L/?adioDroupM
$sing the sto'k An"roi"-generate" Ca!a &or the proGe't an" this layout, you get,
2ote that the ra"io button group is initially set to be 'ompletely un'he'ke" at the outset. 5o preset one o& the ra"io buttons to be 'he'ke", use either set+heckedPQ on the ?adio4utton or checkPQ on the ?adioDroup &rom =ithin your on+reatePQ 'allba'k in your a'ti!ity.
8:
P ddin!
Wi"gets ha!e a minimum siKe, one that may be in&luen'e" by =hat is insi"e o& them. %o, &or e;ample, a 4utton =ill e;pan" to a''ommo"ate the siKe o& its 'aption. ?ou 'an 'ontrol this siKe using pa""ing. A""ing pa""ing =ill in'rease the spa'e bet=een the 'ontents (e.g., the 'aption o& a 4utton) an" the e"ges o& the =i"get. #a""ing 'an be set on'e in FML &or all &our si"es ( android:padding) or on a per-si"e basis (android:padding)eft, et'.). #a""ing 'an also be set in Ca!a !ia the set(addingPQ metho". 5he !alue o& any o& these is a "imension S a 'ombination o& a unit o& measure an" a 'ount. %o, .pG is A pi;els, 1-dip is 10 "ensity-in"epen"ent pi;els, or >mm is 2 millimeters. We =ill e;amine "imension in greater "etail in an up'oming 'hapter.
!isible
android:neGt9ocus=oEn, android:neGt9ocus?ight,
an" &o'us or"er i& the user uses the @-pa", tra'kball, or similar pointing "e!i'e
:<
android:content=escription, =hi'h is roughly eRui!alent to the alt attribute on an +5ML LimgM tag, an" is use" by a''essibility tools to
help people =ho 'annot see the s'reen na!igate the appli'ation
-se.ul %ethods
?ou 'an toggle =hether or not a =i"get is enable" !ia set$nabledPQ an" see i& it is enable" !ia is$nabledPQ. >ne 'ommon use pattern &or this is to "isable some =i"gets base" on a +heck4oG or ?adio4utton sele'tion. ?ou 'an gi!e a =i"get &o'us !ia reUuest9ocusPQ an" see i& it is &o'use" !ia is9ocusedPQ. ?ou might use this in 'on'ert =ith "isabling =i"gets as mentione" abo!e, to ensure the proper =i"get has the &o'us on'e your "isabling operation is 'omplete. 5o help na!igate the tree o& =i"gets an" 'ontainers that make up an a'ti!ity7s o!erall !ie=, you 'an use,
get(arentPQ to findVieE4FIdPQ get?ootVieEPQ
&in" the parent =i"get or 'ontainer to &in" a 'hil" =i"get =ith a 'ertain 0@
to get the root o& the tree (e.g., =hat you pro!i"e" to the a'ti!ity !ia set+ontentVieEPQ)
Colors
5here are t=o types o& 'olor attributes in An"roi" =i"gets. %ome, like take a single 'olor (or a graphi' image to ser!e as the ba'kgroun"). >thers, like android:teGt+olor on &eGtVieE (an" sub'lasses) 'an take a +olor2tate)ist, in'lu"ing !ia the Ca!a setter (in this 'ase, set&eGt+olorPQ).
android:background,
A +olor2tate)ist allo=s you to spe'i&y "i&&erent 'olors &or "i&&erent 'on"itions. *or e;ample, =hen you get to sele'tion =i"gets in an up'oming 'hapter, you =ill see ho= a &eGtVieE has a "i&&erent te;t 'olor =hen it is the sele'te" item in a list 'ompare" to =hen it is in the list but not sele'te". 5his is han"le" !ia the "e&ault +olor2tate)ist asso'iate" =ith &eGtVieE.
:*
0& you =ish to 'hange the 'olor o& a &eGtVieE =i"get in Ca!a 'o"e, you ha!e t=o main 'hoi'es, 1. $se +olor2tate)ist.value"fPQ, =hi'h returns a +olor2tate)ist in =hi'h all states are 'onsi"ere" to ha!e the same 'olor, =hi'h you supply as the parameter to the value"fPQ metho". 5his is the Ca!a eRui!alent o& the android:teGt+olor approa'h, to make the &eGtVieE al=ays a spe'i&i' 'olor regar"less o& 'ir'umstan'es.
2. Create a +olor2tate)ist =ith "i&&erent !alues &or "i&&erent states, either !ia the 'onstru'tor or !ia an FML "ra=able resour'e, a 'on'ept "is'usse" in a later 'hapter
:&
CHAPTER 1<
Containers pour a 'olle'tion o& =i"gets (an" possibly 'hil" 'ontainers) into spe'i&i' stru'tures you like. 0& you =ant a &orm =ith labels on the le&t an" &iel"s on the right, you =ill nee" a 'ontainer. 0& you =ant >D 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. Cust &rom a pure FML perspe'ti!e, i& you ha!e multiple =i"gets (beyon" ?adio4utton =i"gets in a ?adioDroup), you =ill nee" a 'ontainer Gust to ha!e a root element to pla'e the =i"gets insi"e. Most 8$0 toolkits ha!e some notion o& layout management, &reRuently organiKe" into 'ontainers. 0n Ca!aP%=ing, &or e;ample, you ha!e layout managers like 4oG)aFout an" 'ontainers that use them (e.g., 4oG). %ome toolkits sti'k stri'tly to the bo; mo"el, su'h as F$L an" *le;, &iguring that any "esire" layout 'an be a'hie!e" through the right 'ombination o& neste" bo;es. An"roi", through )inear)aFout, also o&&ers a Mbo;M mo"el, but in a""ition supports a range o& 'ontainers pro!i"ing "i&&erent layout rules. 0n this 'hapter, =e =ill look at three 'ommonly-use" 'ontainers, )inear)aFout (the bo; mo"el), ?elative)aFout (a rule-base" mo"el), an" &able)aFout (the gri" mo"el), along =ith 2crollVieE, a 'ontainer "esigne" to assist =ith implementing s'rolling 'ontainers.
:Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
Thinking !inearly
As note" abo!e, )inear)aFout is a bo; mo"el S =i"gets or 'hil" 'ontainers are line" up in a 'olumn or ro=, one a&ter the ne;t. 5his =orks similarly to 9loE)aFout in Ca!aP%=ing, vboG an" hboG in *le; an" F$L, et'. *le; an" F$L use the bo; as their primary unit o& layout. 0& you =ant, you 'an use )inear)aFout in mu'h the same =ay, es'he=ing some o& the other 'ontainers. 8etting the !isual representation you =ant is mostly a matter o& i"enti&ying =here bo;es shoul" nest an" =hat properties those bo;es shoul" ha!e, su'h as alignment vis--vis other bo;es.
Concepts nd Properties
5o 'on&igure a )inear)aFout, you ha!e &i!e main areas o& 'ontrol besi"es the 'ontainer7s 'ontents, the orientation, the &ill mo"el, the =eight, the gra!ity, an" the pa""ing.
+rient tion
>rientation in"i'ates =hether the )inear)aFout represents a ro= or a 'olumn. Cust a"" the android:orientation property to your )inear)aFout element in your FML layout, setting the !alue to be horiKontal &or a ro= or vertical &or a 'olumn. 5he orientation 'an be mo"i&ie" at runtime by in!oking set"rientationPQ on the )inear)aFout, supplying it either !"?IV"%&A) or V$?&I+A).
5ill %odel
Let7s imagine a ro= o& =i"gets, su'h as a pair o& ra"io buttons. 5hese =i"gets ha!e a MnaturalM siKe base" on their te;t. 5heir 'ombine" siKes probably "o not e;a'tly mat'h the =i"th o& the An"roi" "e!i'e7s s'reen S parti'ularly sin'e s'reens 'ome in !arious siKes. We then ha!e the issue o& =hat to "o =ith the remaining spa'e.
:%
All =i"gets insi"e a )inear)aFout must supply android:laFout Eidth an" android:laFout height properties to help a""ress this issue. 5hese properties7 !alues ha!e three &la!ors,
?ou 'an pro!i"e a spe'i&i' "imension, su'h as 1>.dip to in"i'ate the =i"get shoul" take up e;a'tly a 'ertain siKe ?ou 'an pro!i"e Erap 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"-=rap as nee"e" to make it &it ?ou 'an pro!i"e fill parent, =hi'h means the =i"get shoul" &ill up all a!ailable spa'e in its en'losing 'ontainer, a&ter all other =i"gets are taken 'are o&
5he latter t=o &la!ors are the most 'ommon, as they are in"epen"ent o& s'reen siKe, allo=ing An"roi" to a"Gust your !ie= to &it the a!ailable spa'e. @BT*, 0n A#0 le!el 8 (An"roi" 2.2), fill parent =as rename" to match parent, &or unkno=n reasons. ?ou 'an still use fill parent, as it =ill be supporte" &or the &oreseeable &uture. +o=e!er, at su'h point in time as you are only supporting A#0 le!el 8 or higher (e.g., android:min2dkVersion67,7 in your mani&est), you shoul" probably s=it'h o!er to match parent.
,ei!ht
1ut, =hat happens i& =e ha!e t=o =i"gets that shoul" split the a!ailable &ree spa'eH *or e;ample, suppose =e ha!e t=o multi-line &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 ha!e been allo'ate" their spa'e. 5o make this =ork, in a""ition to setting android:laFout Eidth (&or ro=s) or android:laFout height (&or 'olumns) to fill parent, you must also set android:laFout Eeight. 5his property in"i'ates =hat proportion o& the &ree spa'e shoul" go to that =i"get. 0& you set android:laFout Eeight to be the same non-Kero !alue &or a pair o& =i"gets (e.g., 1), the &ree spa'e =ill be split e!enly bet=een them. 0& you set it to be 1 &or one =i"get an" > &or
:0
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. 5he =eight &or a =i"get is Kero by "e&ault. Another pattern &or using =eights is i& you =ant to allo'ate siKes on a per'entage basis. 5o use this te'hniRue &or, say, a horiKontal layout,
%et all the android:laFout Eidth !alues to be - &or the =i"gets in the layout %et the android:laFout Eeight !alues to be the "esire" per'entage siKe &or ea'h =i"get in the layout Make sure all those =eights a"" up to 1--
Gr vity
1y "e&ault, e!erything in a )inear)aFout is le&t- an" top-aligne". %o, i& you 'reate a ro= o& =i"gets !ia a horiKontal )inear)aFout, the ro= =ill start &lush on the le&t si"e o& the s'reen. 0& that is not =hat you =ant, you nee" to spe'i&y a gra!ity. $sing android:laFout gravitF on a =i"get (or 'alling setDravitFPQ at runtime on the =i"get7s Ca!a obGe't), you 'an tell the =i"get an" its 'ontainer ho= to align it vis--vis the s'reen. *or o& =i"gets, 'ommon gra!ity !alues are left, center horiKontal, an" right &or le&t-aligne", 'entere", an" right-aligne" =i"gets respe'ti!ely. *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 in!isible line that letters seem to Msit onM), though you may =ish to spe'i&y a gra!ity o& center vertical to 'enter the =i"gets along the ro=7s !erti'al mi"point. a 'olumn
:2
% r!ins
1y "e&ault, =i"gets are tightly pa'ke", one ne;t to the other. ?ou 'an 'ontrol this !ia the use o& margins, a 'on'ept that is reminis'ent o& the pa""ing "es'ribe" in a pre!ious 'hapter. 5he "i&&eren'e bet=een pa""ing an" margins 'omes in terms o& the ba'kgroun". Wi"gets =ith a transparent ba'kgroun" S like the "e&ault look o& a &eGtVieE S pa""ing an" margins ha!e similar !isual e&&e't, in'reasing the spa'e bet=een the =i"get an" a"Ga'ent =i"gets. +o=e!er, =i"gets =ith a non-transparent ba'kgroun" S like a 4utton S pa""ing is 'onsi"ere" insi"e the ba'kgroun" =hile margins are outsi"e. 0n other =or"s, a""ing pa""ing =ill in'rease the spa'e bet=een the 'ontents (e.g., the 'aption o& a 4utton) an" the e"ges, =hile a""ing margin in'reases the empty spa'e bet=een the e"ges an" a"Ga'ent =i"gets. Margins 'an be set in FML, either on a per-si"e basis (e.g., android:laFout margin&op) or on all si"es !ia android:laFout margin. >n'e again, the !alue o& any o& these is a "imension S a 'ombination o& a unit o& measure an" a 'ount, su'h as .pG &or A pi;els.
E0 mple
Let7s look at an e;ample ( +ontainers/)inear) that sho=s )inear)aFout properties set both in the FML layout &ile an" at runtime. +ere is the layout,
LNGml version671.-7 encoding67utf-,7NM L)inear)aFout Gmlns:android67http://schemas.android.com/apk/res/android7 android:orientation67vertical7 android:laFout Eidth67fill parent7 android:laFout height67fill parent7 M L?adioDroup android:id67ORid/orientation7 android:orientation67horiKontal7 android:laFout Eidth67Erap content7 android:laFout height67Erap content7 android:padding67.dip7M
:7
L?adio4utton android:id67ORid/horiKontal7 android:teGt67horiKontal7 /M L?adio4utton android:id67ORid/vertical7 android:teGt67vertical7 /M L/?adioDroupM L?adioDroup android:id67ORid/gravitF7 android:orientation67vertical7 android:laFout Eidth67fill parent7 android:laFout height67Erap content7 android:padding67.dip7M L?adio4utton android:id67ORid/left7 android:teGt67left7 /M L?adio4utton android:id67ORid/center7 android:teGt67center7 /M L?adio4utton android:id67ORid/right7 android:teGt67right7 /M L/?adioDroupM L/)inear)aFoutM
2ote that =e ha!e a )inear)aFout =rapping t=o ?adioDroup sets. ?adioDroup is a sub'lass o& )inear)aFout, so our e;ample "emonstrates neste" bo;es as i& they =ere all )inear)aFout 'ontainers. 5he top ?adioDroup sets up a ro= (android:orientation 6 7horiKontal7) o& ?adio4utton =i"gets. 5he ?adioDroup has .dip o& pa""ing on all si"es, separating it &rom the other ?adioDroup, =here dip stan"s &or "ensityin"epen"ent pi;els (think o& them as or"inary pi;els &or no= S =e =ill get into the "istin'tion later in the book). 5he =i"th an" height are both set to Erap content, so the ra"io buttons =ill only take up the spa'e that they nee". 5he bottom ?adioDroup is a 'olumn (android:orientation 6 7vertical7) o& three ?adio4utton =i"gets. Again, =e ha!e .dip o& pa""ing on all si"es an" a MnaturalM height (android:laFout height 6 7Erap content7). +o=e!er, =e ha!e set android:laFout Eidth to be fill parent, meaning the 'olumn o& ra"io buttons M'laimsM the entire =i"th o& the s'reen. 5o a"Gust these settings at runtime base" on user input, =e nee" some Ca!a 'o"e,
:8
package com.commonsEare.android.linearJ import import import import import import import android.app.ActivitFJ android.os.4undleJ android.vieE.DravitFJ android.teGt.&eGt@atcherJ android.Eidget.)inear)aFoutJ android.Eidget.?adioDroupJ android.Eidget.$dit&eGtJ )inear)aFout=emo eGtends ActivitF ?adioDroup."n+hecked+hange)istener : orientationJ gravitFJ
O"verride public void onCreateP4undle icicleQ : super.onCreatePicicleQJ setContentViewP?.laFout.mainQJ orientation6P?adioDroupQfindViewByIdP?.id.orientationQJ orientation.setOnCheckedChangeListenerPthisQJ gravitF6P?adioDroupQfindViewByIdP?.id.gravitFQJ gravitF.setOnCheckedChangeListenerPthisQJ
public void onCheckedChangedP?adioDroup group8 int checkedIdQ : sEitch PcheckedIdQ : case ?.id.horiKontal: orientation.setOrientationP)inear)aFout.!"?IV"%&A)QJ breakJ case ?.id.vertical: orientation.setOrientationP)inear)aFout.V$?&I+A)QJ breakJ case ?.id.left: gravitF.set ra!ityPDravitF.)$9&QJ breakJ case ?.id.center: gravitF.set ra!ityPDravitF.+$%&$? !"?IV"%&A)QJ breakJ case ?.id.right: gravitF.set ra!ityPDravitF.?ID!&QJ breakJ ; ; ;
0n on+reatePQ, =e look up our t=o ?adioDroup 'ontainers an" register a listener on ea'h, so =e are noti&ie" =hen the ra"io buttons 'hange state
::
(set"n+hecked+hange)istenerPthisQ). %in'e the a'ti!ity "n+hecked+hange)istener, the a'ti!ity itsel& is the listener.
implements
0n on+hecked+hangedPQ (the 'allba'k &or the listener), =e see =hi'h ?adio4utton ha" a state 'hange. 1ase" on the 'li'ke"-upon item, =e a"Gust either the orientation o& the &irst )inear)aFout or the gra!ity o& the se'on" )inear)aFout. +ere is the result =hen it is &irst laun'he" insi"e the emulator,
0& =e toggle on the M!erti'alM ra"io button, the top ?adioDroup a"Gusts to mat'h,
*<<
"igure %*1 The same application@ )ith the vertical radio button selected
0& =e toggle the M'enterM or MrightM ra"io buttons, the bottom ?adioDroup a"Gusts to mat'h,
"igure %&1 The same application@ )ith the vertical and center radio buttons selected *<*
"igure %-1 The same application@ )ith the vertical and right radio buttons selected
/M L4utton android:teGt67&hirtF (ercent7 android:laFout Eidth67fill parent7 android:laFout height67-dip7 android:laFout Eeight67C-7 /M L4utton android:teGt67&EentF (ercent7 android:laFout Eidth67fill parent7 android:laFout height67-dip7 android:laFout Eeight67>-7 /M L/)inear)aFoutM
Ea'h o& the three =i"gets =ill take up a 'ertain per'entage o& the !erti'al spa'e &or the )inear)aFout. %in'e the )inear)aFout is set to &ill the s'reen, this means that the three =i"gets =ill "i!i"e up the s'reen base" upon their reRueste" per'entages. 5o reRuest a per'entage, ea'h 4utton,
%ets its android:laFout height to be -dip (note, =e use height here be'ause it is a !erti'al )inear)aFout =e are sub-"i!i"ing) %ets its android:laFout Eeight to be the "esire" per'entage (e.g., android:laFout Eeight67.-7)
%o long as the =eights sum to 1--, as they "o in this 'ase, you =ill get your "esire" break"o=n by per'entage,
*<-
5his is reminis'ent o& Cames Elliot7s elati!eLayout &or use =ith Ca!aP%=ing.
Concepts nd Properties
5o make all this =ork, =e nee" =ays to re&eren'e other =i"gets =ithin an FML layout &ile, plus =ays to in"i'ate the relati!e positions o& those =i"gets.
*<%
says the =i"get7s bottom shoul" align =ith the bottom o& the 'ontainer
android:laFout align(arent4ottom
says the =i"get7s le&t si"e shoul" align =ith the le&t si"e o& the 'ontainer
android:laFout align(arent)eft
says the =i"get7s right si"e shoul" align =ith the right si"e o& the 'ontainer
android:laFout align(arent?ight android:laFout center!oriKontal says the =i"get positione" horiKontally at the 'enter o& the 'ontainer android:laFout centerVertical android:laFout centerIn(arent
shoul"
be
says the =i"get shoul" be positione" !erti'ally at the 'enter o& the 'ontainer says the =i"get shoul" be positione" both horiKontally an" !erti'ally at the 'enter o& the 'ontainer
All o& these properties take a simple boolean !alue (true or false). 2ote that the pa""ing o& the =i"get is taken into a''ount =hen per&orming these !arious alignments. 5he alignments are base" on the =i"get7s o!erall 'ell ('ombination o& its natural spa'e plus the pa""ing).
*<0
5he &irst o''urren'e o& an id !alue shoul" ha!e the plus sign (ORid/Eidget a)T the se'on" an" subseRuent times that id !alue is use" in the layout &ile shoul" "rop the plus sign ( Oid/Eidget a). 5his allo=s the buil" tools to better help you 'at'h typos in your =i"get id !alues S i& you "o not ha!e a plus sign &or a =i"get id !alue that has not been seen be&ore, that =ill be 'aught at 'ompile time. *or e;ample, i& Wi"get A is i"enti&ie" as ORid/Eidget a, Wi"get 1 'an re&er to Wi"get A in one o& its o=n properties !ia the i"enti&ier Oid/Eidget a.
in"i'ates that the =i"get shoul" be pla'e" abo!e the =i"get re&eren'e" in the property
android:laFout above android:laFout beloE
in"i'ates that the =i"get shoul" be pla'e" belo= the =i"get re&eren'e" in the property 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
android:laFout to)eft"f
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:laFout to?ight"f
1eyon" those &our, there are &i!e a""itional properties that 'an 'ontrol one =i"get7s alignment relati!e to another,
in"i'ates that the =i"get7s top shoul" be aligne" =ith the top o& the =i"get re&eren'e" in the property
android:laFout align&op
in"i'ates that the =i"get7s bottom shoul" be aligne" =ith the bottom o& the =i"get re&eren'e" in the property
android:laFout align4ottom
in"i'ates that the =i"get7s le&t shoul" be aligne" =ith the le&t o& the =i"get re&eren'e" in the property
android:laFout align)eft
*<2
android:laFout align?ight
in"i'ates that the =i"get7s right shoul" be aligne" =ith the right o& the =i"get re&eren'e" in the property in"i'ates that the baselines o& the t=o =i"gets shoul" be aligne" (=here the MbaselineM is that in!isible line that te;t appears to sit on)
android:laFout align4aseline
5he last one is use&ul &or aligning labels an" &iel"s so that the te;t appears MnaturalM. %in'e &iel"s ha!e a bo; aroun" them an" labels "o not, android:laFout align&op =oul" align the top o& the &iel"7s bo; =ith the top o& the label, =hi'h =ill 'ause the te;t o& the label to be higher on-s'reen than the te;t entere" into the &iel". %o, i& =e =ant Wi"get 1 to be positione" to the right o& Wi"get A, in the FML element &or Wi"get 1, =e nee" to in'lu"e android:laFout to?ight"f 6 7Oid/Eidget a7 (assuming Oid/Eidget a is the i"entity o& Wi"get A).
+rder o. Ev lu tion
0t use" to be that An"roi" =oul" use a single pass to pro'ess ?elative)aFout-"e&ine" rules. 5hat meant you 'oul" not re&eren'e a =i"get (e.g., !ia android:laFout above) until it ha" been "e'lare" in the FML. 5his ma"e "e&ining some layouts a bit 'ompli'ate". %tarting in An"roi" 1./, An"roi" uses t=o passes to pro'ess the rules, so you 'an no= sa&ely ha!e &or=ar" re&eren'es to as-yet-un"e&ine" =i"gets.
E0 mple
With all that in min", let7s e;amine a typi'al M&ormM =ith a &iel", a label, plus a pair o& buttons labele" M>DM an" MCan'elM. +ere is the FML layout, pulle" &rom the +ontainers/?elative sample proGe't,
LNGml version671.-7 encoding67utf-,7NM L?elative)aFout Gmlns:android67http://schemas.android.com/apk/res/android7
*<7
android:laFout Eidth67fill parent7 android:laFout height67Erap content7M L&eGtVieE android:id67ORid/label7 android:laFout Eidth67Erap content7 android:laFout height67Erap content7 android:teGt673?):7 android:laFout align4aseline67ORid/entrF7 android:laFout align(arent)eft67true7/M L$dit&eGt android:id67Oid/entrF7 android:laFout Eidth67fill parent7 android:laFout height67Erap content7 android:laFout to?ight"f67Oid/label7 android:laFout align(arent&op67true7/M L4utton android:id67ORid/ok7 android:laFout Eidth67Erap content7 android:laFout height67Erap content7 android:laFout beloE67Oid/entrF7 android:laFout align?ight67Oid/entrF7 android:teGt67"H7 /M L4utton android:id67ORid/cancel7 android:laFout Eidth67Erap content7 android:laFout height67Erap content7 android:laFout to)eft"f67Oid/ok7 android:laFout align&op67Oid/ok7 android:teGt67+ancel7 /M L/?elative)aFoutM
*irst, =e open up the ?elative)aFout. 0n this 'ase, =e =ant to use the &ull =i"th o& the s'reen (android:laFout Eidth 6 7fill parent7) an" only as mu'h height as =e nee" (android:laFout height 6 7Erap content7). 2e;t, =e "e&ine the label as a &eGtVieE. We in"i'ate that =e =ant its le&t e"ge aligne" =ith the le&t e"ge o& the ?elative)aFout (android:laFout align(arent)eft67true7) an" that =e =ant its baseline aligne" =ith the baseline o& the yet-to-be-"e&ine" $dit&eGt. %in'e the $dit&eGt has not been "e'lare" yet, =e use the R sign in the 0@ (android:laFout align4aseline67ORid/entrF7). A&ter that, =e a"" in the &iel" as an $dit&eGt. We =ant the &iel" to be to the right o& the label, ha!e the &iel" be aligne" =ith the top o& the ?elative)aFout, an" &or the &iel" to take up the rest o& this Mro=M in the layout. 5hose are han"le" by three properties,
android:laFout to?ight"f 6 7Oid/label7
*<8
5hen, the >D button is set to be belo= the &iel" ( android:laFout beloE 6 7Oid/entrF7) an" ha!e its right si"e align =ith the right si"e o& the &iel" (android:laFout align?ight 6 7Oid/entrF7). 5he Can'el button is set to be to the le&t o& the >D button (android:laFout to)eft 6 7Oid/ok7) an" ha!e its top aligne" =ith the >D button (android:laFout align&op 6 7Oid/ok7). With no 'hanges to the auto-generate" Ca!a 'o"e, the emulator gi!es us,
+verl p
?elative)aFout also has a &eature that )inear)aFout la'ks S the ability to ha!e =i"gets o!erlap one another. Later 'hil"ren o& a ?elative)aFout are Mhigher in the Q a;isM than are earlier 'hil"ren, meaning that later 'hil"ren =ill o!erlap earlier 'hil"ren i& they are set up to o''upy the same spa'e in the layout.
*<:
5his =ill be 'learer =ith an e;ample. +ere is a layout, &rom +ontainers/?elative"verlap, =ith a ?elative)aFout hol"ing t=o 4utton =i"gets,
LNGml version671.-7 encoding67utf-,7NM L?elative)aFout Gmlns:android67http://schemas.android.com/apk/res/android7 android:laFout Eidth67fill parent7 android:laFout height67fill parent7 M L4utton android:teGt67I A# 4ID7 android:teGt2iKe671>-dip7 android:teGt2tFle67bold7 android:laFout Eidth67fill parent7 android:laFout height67fill parent7 /M L4utton android:teGt67I am small7 android:laFout Eidth67Erap content7 android:laFout height67Erap content7 android:laFout centerIn(arent67true7 /M L/?elative)aFoutM
5he &irst 4utton is set to &ill the s'reen. 5he se'on" 4utton is set to be 'entere" insi"e the parent, but only take up as mu'h spa'e as is nee"e" &or its 'aption. +en'e, the se'on" 4utton =ill appear to M&loatM o!er the &irst 4utton,
**<
1oth 4utton =i"gets 'an still be 'li'ke", though 'li'king on the smaller 4utton "oes not also 'li'k the bigger 4utton. ?our 'li'ks =ill be han"le" by the =i"get on top in the 'ase o& an o!erlap like this.
Tabula Casa
0& you like +5ML tables, sprea"sheet gri"s, an" the like, you =ill like An"roi"7s &able)aFout S 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)aFout
=orks in 'onGun'tion =ith &able?oE. &able)aFout 'ontrols the o!erall beha!ior o& the 'ontainer, =ith the =i"gets themsel!es poure" into one or more &able?oE '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 li!e outsi"e o& ro=s.
5he number o& 'olumns are "etermine" by An"roi"T you 'ontrol the number o& 'olumns in an in"ire't &ashion. *irst, there =ill be at least one 'olumn per =i"get in your longest ro=. %o i& you ha!e 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=e!er, a =i"get 'an take up more than one 'olumn by in'lu"ing the android:laFout span property, in"i'ating the number o& 'olumns the =i"get spans. 5his is akin to the colspan attribute one &in"s in table 'ells in +5ML,
L&able?oEM L&eGtVieE android:teGt673?):7 /M L$dit&eGt android:id67ORid/entrF7 android:laFout span67C7/M L/&able?oEM
0n the abo!e FML layout &ragment, the &iel" spans three 'olumns. >r"inarily, =i"gets are put into the &irst a!ailable 'olumn. 0n the abo!e &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 1 through C). +o=e!er, you 'an put a =i"get into a "i&&erent 'olumn !ia the android:laFout column property, spe'i&ying the -base" 'olumn the =i"get belongs to,
**&
L&able?oEM L4utton android:id67ORid/cancel7 android:laFout column67>7 android:teGt67+ancel7 /M L4utton android:id67ORid/ok7 android:teGt67"H7 /M L/&able?oEM
0n the pre'e"ing FML layout &ragment, the Can'el button goes in the thir" 'olumn ('olumn >). 5he >D button then goes into the ne;t a!ailable 'olumn, =hi'h is the &ourth 'olumn.
**-
Con!ersely, you 'an pla'e a android:shrink+olumns property on the &able)aFout. Again, this shoul" be a single 'olumn number or a 'omma"elimite" list o& 'olumn numbers. 5he 'olumns liste" in this property =ill try to =or"-=rap their 'ontents to re"u'e the e&&e'ti!e =i"th o& the 'olumn S by "e&ault, =i"gets are not =or"-=rappe". 5his helps i& you ha!e 'olumns =ith potentially =or"y 'ontent that might 'ause some 'olumns to be pushe" o&& the right si"e o& the s'reen. ?ou 'an also le!erage an android:collapse+olumns property on the &able)aFout, again =ith a 'olumn number or 'omma-"elimite" list o& 'olumn numbers. 5hese 'olumns =ill start out M'ollapse"M, meaning they =ill be part o& the table in&ormation but =ill be in!isible. #rogrammati'ally, you 'an 'ollapse an" un-'ollapse 'olumns by 'alling set+olumn+ollapsedPQ on the &able)aFout. ?ou might use this to allo= users to 'ontrol =hi'h 'olumns are o& importan'e to them an" shoul" be sho=n !ersus =hi'h ones are less important an" 'an be hi""en. ?ou 'an also 'ontrol stret'hing an" shrinking at runtime !ia set+olumn2tretchablePQ an" set+olumn2hrinkablePQ.
E0 mple
5he FML layout &ragments sho=n abo!e, =hen 'ombine", gi!e us a ren"ition o& the M&ormM =e 'reate" &or ?elative)aFout, =ith the a""ition o& a "i!i"er line bet=een the labelP&iel" an" the t=o buttons (&oun" in the +ontainers/&able "emo),
&able)aFout
LNGml version671.-7 encoding67utf-,7NM L&able)aFout Gmlns:android67http://schemas.android.com/apk/res/android7 android:laFout Eidth67fill parent7 android:laFout height67fill parent7 android:stretch+olumns6717M L&able?oEM L&eGtVieE android:teGt673?):7 /M L$dit&eGt android:id67ORid/entrF7 android:laFout span67C7/M L/&able?oEM LVieE android:laFout height67>dip7
**%
android:background67S----997 /M L&able?oEM L4utton android:id67ORid/cancel7 android:laFout column67>7 android:teGt67+ancel7 /M L4utton android:id67ORid/ok7 android:teGt67"H7 /M L/&able?oEM L/&able)aFoutM
When 'ompile" against the generate" Ca!a 'o"e an" run on the emulator, =e get,
Scroll)ork
#hone s'reens ten" to be small, =hi'h reRuires "e!elopers to use some tri'ks to present a lot o& in&ormation in the limite" a!ailable spa'e. >ne tri'k &or "oing this is to use s'rolling, so only part o& the in&ormation is !isible at one time, the rest a!ailable !ia s'rolling up or "o=n. is a 'ontainer that pro!i"es s'rolling &or its 'ontents. ?ou 'an take a layout that might be too big &or some s'reens, =rap it in a 2crollVieE,
2crollVieE
**0
an" still use your e;isting layout logi'. 0t Gust so happens that the user 'an only see part o& your layout at one time, the rest a!ailable !ia s'rolling. *or e;ample, here is a 2crollVieE use" in an FML layout &ile (&rom the +ontainers/2croll "emo),
LNGml version671.-7 encoding67utf-,7NM L2crollVieE Gmlns:android67http://schemas.android.com/apk/res/android7 android:laFout Eidth67fill parent7 android:laFout height67Erap content7M L&able)aFout android:laFout Eidth67fill parent7 android:laFout height67fill parent7 android:stretch+olumns67-7M L&able?oEM LVieE android:laFout height67,-dip7 android:background67S------7/M L&eGtVieE android:teGt67S------7 android:padding)eft67<dip7 android:laFout gravitF67center vertical7 /M L/&able?oEM L&able?oEM LVieE android:laFout height67,-dip7 android:background67S<<----7 /M L&eGtVieE android:teGt67S<<----7 android:padding)eft67<dip7 android:laFout gravitF67center vertical7 /M L/&able?oEM L&able?oEM LVieE android:laFout height67,-dip7 android:background67S,,<<--7 /M L&eGtVieE android:teGt67S,,<<--7 android:padding)eft67<dip7 android:laFout gravitF67center vertical7 /M L/&able?oEM L&able?oEM LVieE android:laFout height67,-dip7 android:background67Saa,,<<7 /M L&eGtVieE android:teGt67Saa,,<<7 android:padding)eft67<dip7 android:laFout gravitF67center vertical7 /M L/&able?oEM L&able?oEM LVieE android:laFout height67,-dip7 android:background67Sffaa,,7 /M
**2
L&eGtVieE android:teGt67Sffaa,,7 android:padding)eft67<dip7 android:laFout gravitF67center vertical7 /M L/&able?oEM L&able?oEM LVieE android:laFout height67,-dip7 android:background67Sffffaa7 /M L&eGtVieE android:teGt67Sffffaa7 android:padding)eft67<dip7 android:laFout gravitF67center vertical7 /M L/&able?oEM L&able?oEM LVieE android:laFout height67,-dip7 android:background67Sffffff7 /M L&eGtVieE android:teGt67Sffffff7 android:padding)eft67<dip7 android:laFout gravitF67center vertical7 /M L/&able?oEM L/&able)aFoutM L/2crollVieEM
Without the 2crollVieE, the table =oul" take up at least A/0 pi;els (4 ro=s at 80 pi;els ea'h, base" on the VieE "e'larations). 5here may be some "e!i'es =ith s'reens 'apable o& sho=ing that mu'h in&ormation, but many =ill be smaller. 5he 2crollVieE lets us keep the table as-is, but only present part o& it at a time. >n the sto'k An"roi" emulator, =hen the a'ti!ity is &irst !ie=e", you see,
**7
2oti'e ho= only &i!e ro=s an" part o& the si;th are !isible. 1y pressing the upP"o=n buttons on the "ire'tional pa", you 'an s'roll up an" "o=n to see the remaining ro=s. Also note ho= the right si"e o& the 'ontent gets 'lippe" by the s'rollbar S 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. An"roi" 1.A intro"u'e" !oriKontal2crollVieE, =hi'h =orks like 2crollVieE... Gust horiKontally. 5his =oul" be goo" &or &orms that might be too =i"e rather than too tall. 2ote that neither 2crollVieE nor !oriKontal2crollVieE =ill gi!e you bi-"ire'tional s'rolling S you ha!e to 'hoose !erti'al or horiKontal. Also, note that you 'annot put s'rollable items into a 2crollVieE. *or e;ample, a )istVieE =i"get S =hi'h =e =ill see in an up'oming 'hapter S alrea"y kno=s ho= to s'roll. ?ou "o not nee" to put a )istVieE in a 2crollVieE, an" i& you =ere to try, it =oul" not =ork !ery =ell.
**8
CHAPTER 11
An"roi" 1.A intro"u'e" the input metho" &rame=ork (0M*), =hi'h is 'ommonly re&erre" to as Mso&t keyboar"sM. +o=e!er, the Mso&t keyboar"M term is not ne'essarily a''urate, as 0M* 'oul" be use" &or han"=riting re'ognition or other means o& a''epting te;t input !ia the s'reen.
"igure %:1 The input method editor@ as seen in the "ield/emo sample application
0t =oul" be ni'e to ha!e more 'ontrol o!er ho= this appears, an" &or other beha!ior o& the 0ME. *ortunately, the &rame=ork as a =hole gi!es you many options &or this, as is "es'ribe" o!er the bulk o& this 'hapter.
(the "e&ault)
number
*&<
Many o& these 'lasses o&&er one or more mo"i&iers, to &urther re&ine =hat the user =ill be entering. 5o help e;plain those, take a look at the res/laFout/main.Gml &ile &rom the Input#ethod/I#$=emo1 proGe't,
LNGml version671.-7 encoding67utf-,7NM L&able)aFout Gmlns:android67http://schemas.android.com/apk/res/android7 android:laFout Eidth67fill parent7 android:laFout height67fill parent7 android:stretch+olumns6717 M L&able?oEM L&eGtVieE android:teGt67%o special rules:7 /M L$dit&eGt /M L/&able?oEM L&able?oEM L&eGtVieE android:teGt67$mail address:7 /M L$dit&eGt android:input&Fpe67teGtWteGt$mailAddress7 /M L/&able?oEM L&able?oEM L&eGtVieE android:teGt672igned decimal number:7 /M L$dit&eGt android:input&Fpe67numberWnumber2ignedWnumber=ecimal7 /M L/&able?oEM L&able?oEM L&eGtVieE android:teGt67=ate:7 /M L$dit&eGt android:input&Fpe67date7 /M L/&able?oEM L&able?oEM L&eGtVieE android:teGt67#ulti-line teGt:7 /M
*&*
+ere, you =ill see a &able)aFout 'ontaining &i!e ro=s, ea'h "emonstrating a slightly "i&&erent &la!or o& $dit&eGt, 1. >ne has no attributes at all on the $dit&eGt, meaning you get a plain te;t entry &iel"
2. >ne has android:input&Fpe 6 7teGtWteGt$mailAddress7, meaning it is te;t entry, but spe'i&i'ally seeks an email a""ress .. >ne allo=s &or signe" "e'imal numeri' input, !ia android:input&Fpe
6 7numberWnumber2ignedWnumber=ecimal7
<. >ne is set up to allo= &or "ata entry o& a "ate ( android:input&Fpe 6 7date7) A. 5he last allo=s &or multi-line input =ith auto-'orre'tion o& probable spelling errors (android:input&Fpe 6 7teGtWteGt#ulti)ineW teGtAuto+orrect7) 5he 'lass an" mo"i&iers tailor the keyboar". %o, a plain te;t entry &iel" results in a plain so&t keyboar",
*&&
An email a""ress &iel" might put the O symbol on the so&t keyboar", at the 'ost o& a smaller spa'ebar,
*&-
2ote, though, that this beha!ior is spe'i&i' to the input metho" e"itor. %ome e"itors might put an I sign on the primary keyboar" &or an email &iel". %ome might put a M.'omM button on the primary keyboar". %ome might not rea't at all. 0t is up to the implementation o& the input metho" e"itor S all you 'an "o is supply the hint. 2umbers an" "ates restri't the keys to numeri' keys, plus a set o& symbols that may or may not be !ali" on a gi!en &iel",
"igure 0&1 The input method editor for signed decimal numbers
An" so on. 1y 'hoosing the appropriate android:input&Fpe, you 'an gi!e the user a so&t keyboar" that best suits =hat it is they shoul" be entering.
*&%
lo=er-right 'orner o& the so&t keyboar", the se'on" &iel"7s e"itor has a M2e;tM button, =hile the &irst &iel"7s e"itor has a ne=line button. 5his points out t=o things, 1.
$dit&eGt =i"gets android:input&Fpe
2. ?ou 'an 'ontrol =hat goes on =ith that lo=er-right-han" button, 'alle" the a''essory button 1y "e&ault, on an $dit&eGt =here you ha!e spe'i&ie" android:input&Fpe, the a''essory button =ill be M2e;tM, mo!ing you to the ne;t $dit&eGt in seRuen'e, or M@oneM, i& you are on the last $dit&eGt on the s'reen. ?ou 'an manually stipulate =hat the a''essory button =ill be labele" !ia the android:ime"ptions attribute. *or e;ample, in the res/laFout/main.Gml &rom Input#ethod/I#$=emo>, you =ill see an augmente" !ersion o& the pre!ious e;ample, =here t=o input &iel"s spe'i&y =hat their a''essory button shoul" look like,
LNGml version671.-7 encoding67utf-,7NM L2crollVieE Gmlns:android67http://schemas.android.com/apk/res/android7 android:laFout Eidth67fill parent7 android:laFout height67fill parent7 M L&able)aFout android:laFout Eidth67fill parent7 android:laFout height67fill parent7 android:stretch+olumns6717 M L&able?oEM L&eGtVieE android:teGt67%o special rules:7 /M L$dit&eGt /M L/&able?oEM L&able?oEM L&eGtVieE android:teGt67$mail address:7 /M L$dit&eGt android:input&Fpe67teGtWteGt$mailAddress7 android:ime"ptions67action2end7 /M L/&able?oEM L&able?oEM
*&0
L&eGtVieE android:teGt672igned decimal number:7 /M L$dit&eGt android:input&Fpe67numberWnumber2ignedWnumber=ecimal7 android:ime"ptions67action=one7 /M L/&able?oEM L&able?oEM L&eGtVieE android:teGt67=ate:7 /M L$dit&eGt android:input&Fpe67date7 /M L/&able?oEM L&able?oEM L&eGtVieE android:teGt67#ulti-line teGt:7 /M L$dit&eGt android:input&Fpe67teGtWteGt#ulti)ineWteGtAuto+orrect7 android:min)ines67C7 android:gravitF67top7 /M L/&able?oEM L/&able)aFoutM L/2crollVieEM
+ere, =e atta'h a M%en"M a'tion to the a''essory button &or the email a""ress (android:ime"ptions 6 7action2end7), an" the M@oneM a'tion on the mi""le &iel" (android:ime"ptions 6 7action=one7). 1y "e&ault, M2e;tM =ill mo!e the &o'us to the ne;t $dit&eGt an" M@oneM =ill 'lose up the input metho" e"itor. +o=e!er, &or those, or &or any other ones like M%en"M, you 'an use set"n$ditorAction)istenerPQ on $dit&eGt (te'hni'ally, on the &eGtVieE super'lass) to get 'ontrol =hen the a''essory button is 'li'ke" or the user presses the L$nterM key. ?ou are pro!i"e" =ith a &lag in"i'ating the "esire" a'tion (e.g., I#$ A+&I"% 2$%=), an" you 'an then "o something to han"le that reRuest (e.g., sen" an email to the supplie" email a""ress).
*&2
"itting n
?ou =ill noti'e that the I#$=emo> layout sho=n abo!e has another "i&&eren'e &rom its I#$=emo1 pre"e'essor, the use o& a 2crollVieE 'ontainer =rapping the &able)aFout. 5his ties into another le!el o& 'ontrol you ha!e o!er the input metho" e"itors, =hat happens to your a'ti!ity7s o=n layout =hen the input metho" e"itor appearsH 5here are three possibilities, "epen"ing on 'ir'umstan'es,
An"roi" 'an MpanM your a'ti!ity, e&&e'ti!ely sli"ing the =hole layout up to a''ommo"ate the input metho" e"itor, or o!erlaying your layout, "epen"ing on =hether the $dit&eGt being e"ite" is at the top or bottom. 5his has the e&&e't o& hi"ing some portion o& your $0. An"roi" 'an resiKe your a'ti!ity, e&&e'ti!ely 'ausing it to shrink to a smaller s'reen "imension, allo=ing the input metho" e"itor to sit belo= the a'ti!ity itsel&. 5his is great =hen the layout 'an rea"ily be shrunk (e.g., it is "ominate" by a list or multi-line input &iel" that "oes not nee" the =hole s'reen to be &un'tional). 0n lan"s'ape mo"e, An"roi" may "isplay the input metho" e"itor &ull-s'reen, obs'uring your entire a'ti!ity. 5his allo=s &or a bigger keyboar" an" generally easier "ata entry.
An"roi" 'ontrols the &ull-s'reen option purely on its o=n. An", by "e&ault, An"roi" =ill 'hoose bet=een pan an" resiKe mo"es "epen"ing on =hat your layout looks like. 0& you =ant to spe'i&i'ally 'hoose bet=een pan an" resiKe, you 'an "o so !ia an android:EindoE2oftInput#ode attribute on the LactivitFM element in your Android#anifest.Gml &ile. *or e;ample, here is the mani&est &rom I#$=emo>,
LNGml version671.-7 encoding67utf-,7NM Lmanifest Gmlns:android67http://schemas.android.com/apk/res/android7 package67com.commonsEare.android.imf.tEo7 android:version+ode6717 android:version%ame671.-7M Lapplication android:label67Ostring/app name7 android:icon67OdraEable/cE7M LactivitF android:name67.I#$=emo>7 android:label67Ostring/app name7 android:EindoE2oftInput#ode67adjust?esiKe7M Lintent-filterM Laction android:name67android.intent.action.#AI%7/M LcategorF android:name67android.intent.categorF.)A3%+!$?7/M *&7
1e'ause =e spe'i&ie" resiKe, An"roi" =ill shrink our layout to a''ommo"ate the input metho" e"itor. With the 2crollVieE in pla'e, this means the s'roll bar =ill appear as nee"e",
*&8
(=here fld is the $dit&eGt =hose input metho" e"itor you =ant to hi"e) 5his =ill al=ays 'lose the input metho" e"itor. +o=e!er, bear in min" that there are t=o =ays &or a user to ha!e opene" that input metho" e"itor in the &irst pla'e, 1. 0& their "e!i'e "oes not ha!e a har"=are keyboar" e;pose", an" they tap on the $dit&eGt, the input metho" e"itor shoul" appear
2. 0& they pre!iously "ismisse" the e"itor, or i& they are using the e"itor &or a =i"get that "oes not normally pop one up (e.g., )istVieE), an" they long-tap on the ME2$ button, the input metho" e"itor shoul" appear 0& you only =ant to 'lose the input metho" e"itor &or the &irst s'enario, but not the se'on", use Input#ethod#anager.!I=$ I#()I+I& "%)5 as a &lag &or the se'on" parameter to your 'all to hide2oftInput9rom@indoEPQ, instea" o& the sho=n in the pre!ious e;ample.
*&:
CHAPTER 1&
1a'k in the 'hapter on input metho" e"itors, you sa= ho= &iel"s 'oul" ha!e 'onstraints pla'e" upon them to limit possible input, su'h as numeri'-only or phone-number-only. 5hese sorts o& 'onstraints help users Mget it rightM =hen entering in&ormation, parti'ularly on a mobile "e!i'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' $0 toolkits ha!e listbo;es, 'ombobo;es, "rop-"o=n lists, an" the like &or that !ery purpose. An"roi" has many o& the same sorts o& =i"gets, plus others o& parti'ular interest &or mobile "e!i'es (e.g., the DallerF &or e;amining sa!e" photos). Moreo!er, An"roi" o&&ers a ≤ible &rame=ork &or "etermining =hat 'hoi'es are a!ailable in these =i"gets. %pe'i&i'ally, An"roi" o&&ers a &rame=ork o& "ata a"apters that pro!i"e a 'ommon inter&a'e to sele'tion lists ranging &rom stati' arrays to "atabase 'ontents. %ele'tion !ie=s S =i"gets &or presenting lists o& 'hoi'es S are han"e" an a"apter to supply the a'tual 'hoi'es.
listbo;. 5his use o& Ca!a inter&a'es is &airly 'ommon (e.g., Ca!aP%=ing7s mo"el a"apters &or J&able), an" Ca!a is &ar &rom the only en!ironment o&&ering this sort o& abstra'tion (e.g., *le;7s FML "ata-bin"ing &rame=ork a''epts FML inline" as stati' "ata or retrie!e" &rom the 0nternet). An"roi"7s a"apters are responsible &or pro!i"ing the roster o& "ata &or a sele'tion =i"get plus 'on!erting in"i!i"ual elements o& "ata into spe'i&i' !ie=s to be "isplaye" insi"e the sele'tion =i"get. 5he latter &a'et o& the a"apter system may soun" a little o"", but in reality it is not that "i&&erent &rom other 8$0 toolkits7 =ays o& o!erri"ing "e&ault "isplay beha!ior. *or e;ample, in Ca!aP%=ing, i& you =ant a J)ist-ba'ke" listbo; to a'tually be a 'he'klist (=here in"i!i"ual ro=s are a 'he'kbo; plus label, an" 'li'ks a"Gust the state o& the 'he'kbo;), you ine!itably =in" up 'alling set+ell?endererPQ to supply your o=n )ist+ell?enderer, =hi'h in turn 'on!erts strings &or the list into J+heck4oG-plus-J)abel 'omposite =i"gets.
5he +onteGt to use (typi'ally this =ill be your a'ti!ity instan'e) 5he resour'e 0@ o& a !ie= to use (su'h as a built-in system resour'e 0@, as sho=n abo!e) 5he a'tual array or list o& items to sho=
1y "e&ault, the ArraFAdapter =ill in!oke to2tringPQ on the obGe'ts in the list an" =rap ea'h o& those strings in the !ie= "esignate" by the supplie" resour'e. android.?.laFout.simple list item 1 simply turns those strings
*-&
into &eGtVieE obGe'ts. 5hose &eGtVieE =i"gets, in turn, =ill be sho=n in the list or spinner or =hate!er =i"get uses this ArraFAdapter. 0& you =ant to see =hat android.?.laFout.simple list item 1 looks like, you 'an &in" a 'opy o& it in your %@D installation S Gust sear'h &or simple list item 1.Gml. We =ill see in a later 'hapter ho= to sub'lass an Adapter an" o!erri"e ro= 'reation, to gi!e you greater 'ontrol o!er ho= ro=s appear.
*--
/M L/)inear)aFoutM
0t is Gust a list =ith a label on top to sho= the 'urrent sele'tion. 5he Ca!a 'o"e to 'on&igure the list an" 'onne't the list =ith the label is,
public class )istVieE=emo eGtends )istActivitF : private &eGtVieE selectionJ private static final 2tringAB items6:7lorem78 7ipsum78 7dolor78 7sit78 7amet78 7consectetuer78 7adipiscing78 7elit78 7morbi78 7vel78 7ligula78 7vitae78 7arcu78 7aliUuet78 7mollis78 7etiam78 7vel78 7erat78 7placerat78 7ante78 7porttitor78 7sodales78 7pellentesUue78 7augue78 7purus7;J O"verride public void onCreateP4undle icicleQ : super.onCreatePicicleQJ setContentViewP?.laFout.mainQJ setList$dapterPneE ArraFAdapterL2tringMPthis8 android.?.laFout.simple list item 18 itemsQQJ selection6P&eGtVieEQfindViewByIdP?.id.selectionQJ ; public void onListItemClickP)istVieE parent8 VieE v8 int position8 long idQ : selection.setTextPitemsApositionBQJ ; ;
With )istActivitF, you 'an set the list a"apter !ia set)istAdapterPQ S in this 'ase, pro!i"ing an ArraFAdapter =rapping an array o& nonsense strings. 5o &in" out =hen the list sele'tion 'hanges, o!erri"e on)istItem+lickPQ an" take appropriate steps base" on the supplie" 'hil" !ie= an" position (in this 'ase, up"ating the label =ith the te;t &or that position). 5he resultsH
*-%
5he
to our ArraFAdapter S android.?.laFout.simple list item 1 S 'ontrols =hat the ro=s look like. 5he !alue use" in the pre'e"ing e;ample pro!i"es the stan"ar" An"roi" list ro=, big &ont, lots o& pa""ing, =hite te;t.
se'on"
parameter
Selection %odes
1y "e&ault, )istVieE is set up simply to 'olle't 'li'ks on list entries. %ometimes, though, you =ant a list that tra'ks a user7s sele'tion, or possibly multiple sele'tions. )istVieE 'an han"le that as =ell, but it reRuires a &e= 'hanges. *irst, you =ill nee" to 'all set+hoice#odePQ on the )istVieE in Ca!a 'o"e to set the 'hoi'e mo"e, supplying either +!"I+$ #"=$ 2I%D)$ or +!"I+$ #"=$ #3)&I()$ as the !alue. ?ou 'an get your )istVieE &rom a )istActivitF !ia get)istVieEPQ. ?ou 'an also "e'lare this !ia the android:choice#ode attribute in your layout FML.
*-0
5hen, rather than use android.?.laFout.simple list item 1 as the layout &or the list ro=s in your ArraFAdapter 'onstru'tor, you =ill nee" to use either android.?.laFout.simple list item single choice or android.?.laFout.simple list item multiple choice &or single-'hoi'e or multiple-'hoi'e lists, respe'ti!ely. *or e;ample, here is an a'ti!ity layout &rom the 2election/+hecklist sample proGe't,
LNGml version671.-7 encoding67utf-,7NM L)istVieE Gmlns:android67http://schemas.android.com/apk/res/android7 android:id67Oandroid:id/list7 android:laFout Eidth67fill parent7 android:laFout height67fill parent7 android:draE2elector"n&op67false7 android:choice#ode67multiple+hoice7 /M
0t is a &ull-s'reen )istVieE, =ith the android:choice#ode67multiple+hoice7 attribute to in"i'ate that =e =ant multiple 'hoi'e support. >ur a'ti!ity Gust uses a stan"ar" ArraFAdapter on our list o& nonsense =or"s, but uses android.?.laFout.simple list item multiple choice as the ro= layout,
package com.commonsEare.android.checklistJ import import import import android.os.4undleJ android.app.)istActivitFJ android.Eidget.ArraFAdapterJ android.Eidget.)istVieEJ
public class +hecklist=emo eGtends )istActivitF : private static final 2tringAB items6:7lorem78 7ipsum78 7dolor78 7sit78 7amet78 7consectetuer78 7adipiscing78 7elit78 7morbi78 7vel78 7ligula78 7vitae78 7arcu78 7aliUuet78 7mollis78 7etiam78 7vel78 7erat78 7placerat78 7ante78 7porttitor78 7sodales78 7pellentesUue78 7augue78 7purus7;J O"verride public void onCreateP4undle icicleQ : super.onCreatePicicleQJ setContentViewP?.laFout.mainQJ setList$dapterPneE ArraFAdapterL2tringMPthis8
*-2
; ;
What the user sees is the list o& =or"s =ith 'he'kbo;es "o=n the right e"ge,
0& =e =ante", =e 'oul" 'all metho"s like get+heckedItem(ositionsPQ on our )istVieE to &in" out =hi'h items the user 'he'ke", or setItem+heckedPQ i& =e =ante" to 'he'k (or un-'he'k) a spe'i&i' entry oursel!es.
Spin Control
0n An"roi", the 2pinner is the eRui!alent o& the "rop-"o=n sele'tor you might &in" in other toolkits (e.g., J+ombo4oG in Ca!aP%=ing). #ressing the 'enter button on the @-pa" pops up a sele'tion "ialog &or the user to 'hoose an item &rom. ?ou basi'ally get the ability to sele't &rom a list
*-7
=ithout taking up all the s'reen spa'e o& a )istVieE, at the 'ost o& an e;tra 'li'k or s'reen tap to make a 'hange. As =ith )istVieE, you pro!i"e the a"apter &or "ata an" 'hil" !ie=s !ia setAdapterPQ an" hook in a listener obGe't &or sele'tions !ia set"nItem2elected)istenerPQ. 0& you =ant to tailor the !ie= use" =hen "isplaying the "rop-"o=n perspe'ti!e, you nee" to 'on&igure the a"apter, not the 2pinner =i"get. $se the set=rop=oEnVieE?esourcePQ metho" to supply the resour'e 0@ o& the !ie= to use. *or e;ample, 'ulle" &rom the 2election/2pinner sample proGe't, here is an FML layout &or a simple !ie= =ith a 2pinner,
LNGml version671.-7 encoding67utf-,7NM L)inear)aFout Gmlns:android67http://schemas.android.com/apk/res/android7 android:orientation67vertical7 android:laFout Eidth67fill parent7 android:laFout height67fill parent7 M L&eGtVieE android:id67ORid/selection7 android:laFout Eidth67fill parent7 android:laFout height67Erap content7 /M L2pinner android:id67ORid/spinner7 android:laFout Eidth67fill parent7 android:laFout height67Erap content7 android:draE2elector"n&op67true7 /M L/)inear)aFoutM
5his is the same !ie= as sho=n in the pre!ious se'tion, Gust =ith a 2pinner instea" o& a )istVieE. 5he 2pinner property android:draE2elector"n&op 'ontrols =hether the arro=s are "ra=n on the sele'tor button on the right si"e o& the 2pinner $0. 5o populate an" use the 2pinner, =e nee" some Ca!a 'o"e,
*-8
public class 2pinner=emo eGtends ActivitF implements AdapterVieE."nItem2elected)istener : private &eGtVieE selectionJ private static final 2tringAB items6:7lorem78 7ipsum78 7dolor78 7sit78 7amet78 7consectetuer78 7adipiscing78 7elit78 7morbi78 7vel78 7ligula78 7vitae78 7arcu78 7aliUuet78 7mollis78 7etiam78 7vel78 7erat78 7placerat78 7ante78 7porttitor78 7sodales78 7pellentesUue78 7augue78 7purus7;J O"verride public void onCreateP4undle icicleQ : super.onCreatePicicleQJ setContentViewP?.laFout.mainQJ selection6P&eGtVieEQfindViewByIdP?.id.selectionQJ 2pinner spin6P2pinnerQfindViewByIdP?.id.spinnerQJ spin.setOnItemSelectedListenerPthisQJ ArraFAdapterL2tringM aa6neE ArraFAdapterL2tringMPthis8 android.?.laFout.simple spinner item8 itemsQJ aa.setDropDownView%esourceP android.?.laFout.simple spinner dropdoEn itemQJ spin.set$dapterPaaQJ
public void onItemSelectedPAdapterVieELNM parent8 VieE v8 int position8 long idQ : selection.setTextPitemsApositionBQJ ; public void on&othingSelectedPAdapterVieELNM parentQ : selection.setTextP77QJ ;
+ere, =e atta'h the a'ti!ity itsel& as the sele'tion listener (spin.set"nItem2elected)istenerPthisQ). 5his =orks be'ause the a'ti!ity implements the "nItem2elected)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 "rop-"o=n !ie= (!ia aa.set=rop=oEnVieE?esourcePQ). Also note the use o& android.?.laFout.simple spinner item as the built-in VieE &or sho=ing items in the spinner itsel&. *inally, =e implement the 'allba'ks reRuire" by "nItem2elected)istener to a"Gust the sele'tion label base" on user input. What =e get is,
*-:
"igure 071 The same application@ )ith the spinner drop#do)n list displayed
*%<
spells out ho= many 'olumns there are, or, i& you supply a !alue o& auto fit, An"roi" =ill 'ompute the number o& 'olumns base" on a!ailable spa'e an" the properties liste" belo=.
android:num+olumns
an" android:horiKontal2pacing in"i'ate ho= mu'h =hitespa'e there shoul" be bet=een items in the gri".
android:vertical2pacing android:column@idth
shoul" be.
&or gri"s =ith auto fit &or happen &or any a!ailable spa'e not taken up by 'olumns or spa'ing S this shoul" be column@idth to ha!e the 'olumns take up a!ailable spa'e or spacing@idth to ha!e the =hitespa'e bet=een 'olumns absorb e;tra spa'e.
>ther=ise, the DridVieE =orks mu'h like any other sele'tion =i"get S use setAdapterPQ to pro!i"e the "ata an" 'hil" !ie=s, in!oke set"nItem2elected)istenerPQ to register a sele'tion listener, et'. *or e;ample, here is an FML layout &rom the 2election/Drid sample proGe't, sho=ing a DridVieE 'on&iguration,
LNGml version671.-7 encoding67utf-,7NM L)inear)aFout Gmlns:android67http://schemas.android.com/apk/res/android7 android:orientation67vertical7 android:laFout Eidth67fill parent7 android:laFout height67fill parent7 M L&eGtVieE android:id67ORid/selection7 *%*
android:laFout Eidth67fill parent7 android:laFout height67Erap content7 /M LDridVieE android:id67ORid/grid7 android:laFout Eidth67fill parent7 android:laFout height67fill parent7 android:vertical2pacing67<-dip7 android:horiKontal2pacing67.dip7 android:num+olumns67auto fit7 android:column@idth671--dip7 android:stretch#ode67column@idth7 android:gravitF67center7 /M L/)inear)aFoutM
*or this gri", =e take up the entire s'reen e;'ept &or =hat our sele'tion label reRuires. 5he number o& 'olumns is 'ompute" by An"roi" (android:num+olumns 6 7auto fit7) base" on our horiKontal spa'ing (android:horiKontal2pacing 6 7.dip7) an" 'olumns =i"th (android:column@idth 6 71--dip7), =ith the 'olumns absorbing any MslopM =i"th le&t o!er (android:stretch#ode 6 7column@idth7). 5he Ca!a 'o"e to 'on&igure the DridVieE is,
package com.commonsEare.android.gridJ import import import import import import import import android.app.ActivitFJ android.content.+onteGtJ android.os.4undleJ android.vieE.VieEJ android.Eidget.AdapterVieEJ android.Eidget.ArraFAdapterJ android.Eidget.DridVieEJ android.Eidget.&eGtVieEJ
public class Drid=emo eGtends ActivitF implements AdapterVieE."nItem2elected)istener : private &eGtVieE selectionJ private static final 2tringAB items6:7lorem78 7ipsum78 7dolor78 7sit78 7amet78 7consectetuer78 7adipiscing78 7elit78 7morbi78 7vel78 7ligula78 7vitae78 7arcu78 7aliUuet78 7mollis78 7etiam78 7vel78 7erat78 7placerat78 7ante78 7porttitor78 7sodales78 7pellentesUue78 7augue78 7purus7;J O"verride public void onCreateP4undle icicleQ : super.onCreatePicicleQJ
*%&
setContentViewP?.laFout.mainQJ selection6P&eGtVieEQfindViewByIdP?.id.selectionQJ DridVieE g6PDridVieEQ findViewByIdP?.id.gridQJ g.set$dapterPneE ArraFAdapterL2tringMPthis8 ?.laFout.cell8 itemsQQJ g.setOnItemSelectedListenerPthisQJ
public void onItemSelectedPAdapterVieELNM parent8 VieE v8 int position8 long idQ : selection.setTextPitemsApositionBQJ ; public void on&othingSelectedPAdapterVieELNM parentQ : selection.setTextP77QJ ;
5he gri" 'ells are "e&ine" by a separate res/laFout/cell.Gml &ile, re&eren'e" in our ArraFAdapter as ?.laFout.cell,
LNGml version671.-7 encoding67utf-,7NM L&eGtVieE Gmlns:android67http://schemas.android.com/apk/res/android7 android:laFout Eidth67Erap content7 android:laFout height67Erap content7 android:teGt2iKe671<dip7 /M
With the !erti'al spa'ing &rom the FML layout ( android:vertical2pacing 6 7<-dip7), the gri" o!er&lo=s the boun"aries o& the emulator7s s'reen,
*%-
"igure 0:1 The same application@ scrolled to the bottom of the grid
*%%
0n a""ition, Auto+omplete&eGtVieE has a android:completion&hreshold property, to in"i'ate the minimum number o& 'hara'ters a user must enter be&ore the list &iltering begins. ?ou 'an gi!e Auto+omplete&eGtVieE an a"apter 'ontaining the list o& 'an"i"ate !alues !ia setAdapterPQ. +o=e!er, sin'e the user 'oul" type something not in the list, Auto+omplete&eGtVieE "oes not support sele'tion listeners. 0nstea", you 'an register a &eGt@atcher, like you 'an =ith any $dit&eGt, to be noti&ie" =hen the te;t 'hanges. 5hese e!ents =ill o''ur either be'ause o& manual typing or &rom a sele'tion &rom the "rop-"o=n list. 1elo= =e ha!e a &amiliar-looking FML layout, this time 'ontaining an Auto+omplete&eGtVieE (pulle" &rom the 2election/Auto+omplete sample appli'ation),
LNGml version671.-7 encoding67utf-,7NM L)inear)aFout Gmlns:android67http://schemas.android.com/apk/res/android7 android:orientation67vertical7 android:laFout Eidth67fill parent7 android:laFout height67fill parent7 M L&eGtVieE android:id67ORid/selection7 android:laFout Eidth67fill parent7 android:laFout height67Erap content7 /M
*%0
LAuto+omplete&eGtVieE android:id67ORid/edit7 android:laFout Eidth67fill parent7 android:laFout height67Erap content7 android:completion&hreshold67C7/M L/)inear)aFoutM
public class Auto+omplete=emo eGtends ActivitF implements &eGt@atcher : private &eGtVieE selectionJ private Auto+omplete&eGtVieE editJ private static final 2tringAB items6:7lorem78 7ipsum78 7dolor78 7sit78 7amet78 7consectetuer78 7adipiscing78 7elit78 7morbi78 7vel78 7ligula78 7vitae78 7arcu78 7aliUuet78 7mollis78 7etiam78 7vel78 7erat78 7placerat78 7ante78 7porttitor78 7sodales78 7pellentesUue78 7augue78 7purus7;J O"verride public void onCreateP4undle icicleQ : super.onCreatePicicleQJ setContentViewP?.laFout.mainQJ selection6P&eGtVieEQfindViewByIdP?.id.selectionQJ edit6PAuto+omplete&eGtVieEQfindViewByIdP?.id.editQJ edit.addTextChangedListenerPthisQJ edit.set$dapterPneE ArraFAdapterL2tringMPthis8 android.?.laFout.simple dropdoEn item 1line8 itemsQQJ
public void onTextChangedP+har2eUuence s8 int start8 int before8 int countQ : selection.setTextPedit.getTextPQQJ ; public void 'eforeTextChangedP+har2eUuence s8 int start8 int count8 int afterQ : // needed for interface8 but not used ;
*%2
5his time, our a'ti!ity implements &eGt@atcher, =hi'h means our 'allba'ks are on&eGt+hangedPQ, before&eGt+hangedPQ, an" after&eGt+hangedPQ. 0n this 'ase, =e are only intereste" in the &ormer, an" =e up"ate the sele'tion label to mat'h the Auto+omplete&eGtVieE7s 'urrent 'ontents. +ere =e ha!e the results,
*%7
"igure 2*1 The same application@ after a fe) matching letters )ere entered@ sho)ing the auto#complete drop#do)n
"igure 2&1 The same application@ after the auto#complete value )as selected
*%8
the list
'ontrols =hat is use" to in"i'ate a sele'tion S this 'an either be a re&eren'e to a =raEable (see the resour'es 'hapter) or an 81 !alue in SAA??DD44 or similar notation
android:spinner2elector android:draE2elector"n&op in"i'ates i& the sele'tion bar (or =raEable) shoul" be "ra=n be&ore (false) or a&ter (true) "ra=ing the sele'te" 'hil" S 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
*%:
CHAPTER 11
5he humble )istVieE is one o& the most important =i"gets in all o& An"roi", simply be'ause it is use" so &reRuently. Whether 'hoosing a 'onta't to 'all or an email message to &or=ar" or an ebook to rea", )istVieE =i"gets are employe" in a =i"e range o& a'ti!ities. >& 'ourse, it =oul" be ni'e i& they =ere more than Gust plain te;t. 5he goo" ne=s is that they 'an be as &an'y as you =ant, =ithin the limitations o& a mobile "e!i'e7s s'reen, o& 'ourse. +o=e!er, making them &an'y takes some =ork an" some &eatures o& An"roi" that =e =ill 'o!er in this 'hapter.
*0*
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
*or e;ample, suppose you =ant a )istVieE =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 res/laFout/roE.Gml in the 9ancF)ists/2tatic sample proGe't,
LNGml version671.-7 encoding67utf-,7NM L)inear)aFout Gmlns:android67http://schemas.android.com/apk/res/android7 android:laFout Eidth67fill parent7 android:laFout height67Erap content7 android:orientation67horiKontal7 M LImageVieE android:id67ORid/icon7 android:padding67>dip7 android:laFout Eidth67Erap content7 android:laFout height67Erap content7 android:src67OdraEable/ok7 /M L&eGtVieE android:id67ORid/label7 android:laFout Eidth67Erap content7 android:laFout height67Erap content7 android:teGt2iKe67<-sp7 /M L/)inear)aFoutM
5his layout uses a )inear)aFout 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. 1y "e&ault, though, An"roi" has no i"ea that you =ant to use this layout =ith your )istVieE. 5o make the 'onne'tion, you nee" to supply your Adapter =ith the resour'e 0@ o& the 'ustom layout sho=n abo!e,
public class 2tatic=emo eGtends )istActivitF : private &eGtVieE selectionJ private static final 2tringAB items6:7lorem78 7ipsum78 7dolor78 7sit78 7amet78 7consectetuer78 7adipiscing78 7elit78 7morbi78 7vel78 7ligula78 7vitae78 7arcu78 7aliUuet78 7mollis78 7etiam78 7vel78 7erat78 7placerat78 7ante78 7porttitor78 7sodales78 7pellentesUue78 7augue78 7purus7;J O"verride public void onCreateP4undle icicleQ : super.onCreatePicicleQJ setContentViewP?.laFout.mainQJ setList$dapterPneE ArraFAdapterL2tringMPthis8 ?.laFout.roE8 ?.id.label8
*0&
itemsQQJ selection6P&eGtVieEQfindViewByIdP?.id.selectionQJ
public void onListItemClickP)istVieE parent8 VieE v8 int position8 long idQ : selection.setTextPitemsApositionBQJ ;
5his &ollo=s the general stru'ture &or the pre!ious List-ie= sample. 5he key in this e;ample is that you ha!e tol" ArraFAdapter that you =ant to use your 'ustom layout (?.laFout.roE) an" that the &eGtVieE =here the =or" shoul" go is kno=n as ?.id.label =ithin that 'ustom layout. emember, to re&eren'e a layout ( roE.Gml), use ?.laFout as a pre&i; on the base name o& the layout FML &ile (?.laFout.roE). 5he result is a )istVieE =ith i'ons "o=n the le&t si"e. 0n parti'ular, all the i'ons are the same,
*0-
A /ynamic Presentation
5his te'hniRue S supplying an alternate layout to use &or ro=s S han"les simple 'ases !ery ni'ely. +o=e!er, =hat happens =hen =e =ant the i'on to 'hange base" on the ro= "ataH *or e;ample, perhaps =e =ant to use one i'on &or small =or"s an" a "i&&erent i'on &or large =or"s. 0n the 'ase o& ArraFAdapter, you =ill nee" to e;ten" it, 'reating your o=n 'ustom sub'lass (e.g., IconicAdapter) that in'orporates your business logi'. 0n parti'ular, it =ill nee" to o!erri"e getVieEPQ. 5he getVieEPQ metho" o& an Adapter is =hat an AdapterVieE (like )istVieE or 2pinner) 'alls =hen it nee"s the VieE asso'iate" =ith a gi!en pie'e o& "ata the Adapter is managing. 0n the 'ase o& an ArraFAdapter, getVieEPQ is 'alle" as nee"e" &or ea'h position in the array S Mget me the VieE &or the &irst ro=M, Mget me the VieE &or the se'on" ro=M, et'. *or e;ample, let us re=ork the abo!e 'o"e to use getVieEPQ, so =e 'an ha!e "i&&erent i'ons &or "i&&erent ro=s S in this 'ase, one i'on &or short =or"s an" one &or long =or"s (&rom the 9ancF)ists/=Fnamic sample proGe't),
public class =Fnamic=emo eGtends )istActivitF : &eGtVieE selectionJ private static final 2tringAB items6:7lorem78 7ipsum78 7dolor78 7sit78 7amet78 7consectetuer78 7adipiscing78 7elit78 7morbi78 7vel78 7ligula78 7vitae78 7arcu78 7aliUuet78 7mollis78 7etiam78 7vel78 7erat78 7placerat78 7ante78 7porttitor78 7sodales78 7pellentesUue78 7augue78 7purus7;J O"verride public void onCreateP4undle icicleQ : super.onCreatePicicleQJ setContentViewP?.laFout.mainQJ setList$dapterPneE Iconic$dapterPQQJ selection6P&eGtVieEQfindViewByIdP?.id.selectionQJ ; public void onListItemClickP)istVieE parent8 VieE v8 int position8 long idQ :
*0%
selection.setTextPitemsApositionBQJ ; class IconicAdapter eGtends ArraFAdapterL2tringM : Iconic$dapterPQ : superP=Fnamic=emo.this8 ?.laFout.roE8 ?.id.label8 itemsQJ ; public VieE getViewPint position8 VieE convertVieE8 VieEDroup parentQ : VieE roE6super.getViewPposition8 convertVieE8 parentQJ ImageVieE icon6PImageVieEQroE.findViewByIdP?.id.iconQJ if PitemsApositionB.lengthPQM<Q : icon.setImage%esourceP?.draEable.deleteQJ ; else : icon.setImage%esourceP?.draEable.okQJ ; returnProEQJ ; ; ;
>ur IconicAdapter S an inner 'lass o& the a'ti!ity S has t=o metho"s. *irst, it has the 'onstru'tor, =hi'h Gust passes to ArraFAdapter the same "ata =e use" in the ArraFAdapter 'onstru'tor in 2tatic=emo. %e'on", it has our getVieEPQ implementation, =hi'h "oes t=o things, 1. 0t 'hains to the super'lass7 implementation o& getVieEPQ, =hi'h returns to us an instan'e o& our ro= VieE, as prepare" by ArraFAdapter. 0n parti'ular, our =or" has alrea"y been put into the &eGtVieE, sin'e ArraFAdapter "oes that normally.
2. 0t &in"s our ImageVieE an" applies a business rule to set =hi'h i'on shoul" be use", re&eren'ing one o& t=o "ra=able resour'es (?.draEable.ok an" ?.draEable.delete). 5his gi!es us,
*00
*02
5he goo" ne=s is that the &ine &olk on the An"roi" team =rappe" all that up into a 'lass 'alle" )aFoutInflater that =e 'an use oursel!es. When it 'omes to &an'y lists, &or e;ample, =e =ill =ant to in&late VieEs &or ea'h ro= sho=n in the list, so =e 'an use the 'on!enient shorthan" o& the FML layout to "es'ribe =hat the ro=s are suppose" to look like. *or e;ample, let us look at a slightly "i&&erent implementation o& the =Fnamic=emo 'lass, &rom the 9ancF)ists/=Fnamic$G proGe't,
public class =Fnamic=emo eGtends )istActivitF : &eGtVieE selectionJ private static final 2tringAB items6:7lorem78 7ipsum78 7dolor78 7sit78 7amet78 7consectetuer78 7adipiscing78 7elit78 7morbi78 7vel78 7ligula78 7vitae78 7arcu78 7aliUuet78 7mollis78 7etiam78 7vel78 7erat78 7placerat78 7ante78 7porttitor78 7sodales78 7pellentesUue78 7augue78 7purus7;J O"verride public void onCreateP4undle icicleQ : super.onCreatePicicleQJ setContentViewP?.laFout.mainQJ setList$dapterPneE Iconic$dapterPQQJ selection6P&eGtVieEQfindViewByIdP?.id.selectionQJ ; public void onListItemClickP)istVieE parent8 VieE v8 int position8 long idQ : selection.setTextPitemsApositionBQJ ; class IconicAdapter eGtends ArraFAdapterL2tringM : Iconic$dapterPQ : superP=Fnamic=emo.this8 ?.laFout.roE8 itemsQJ ; public VieE getViewPint position8 VieE convertVieE8 VieEDroup parentQ : )aFoutInflater inflater6getLayoutInflaterPQJ VieE roE6inflater.inflateP?.laFout.roE8 parent8 falseQJ &eGtVieE label6P&eGtVieEQroE.findViewByIdP?.id.labelQJ label.setTextPitemsApositionBQJ ImageVieE icon6PImageVieEQroE.findViewByIdP?.id.iconQJ if PitemsApositionB.lengthPQM<Q : icon.setImage%esourceP?.draEable.deleteQJ ; else :
*07
icon.setImage%esourceP?.draEable.okQJ ; ; ; ; returnProEQJ
+ere =e in&late our ?.laFout.roE layout by use o& a )aFoutInflater obGe't, obtaine" &rom our ActivitF !ia get)aFoutInflaterPQ. 5his gi!es us a VieE obGe't ba'k =hi'h, in reality, is our )inear)aFout =ith an ImageVieE an" a &eGtVieE, Gust as ?.laFout.roE spe'i&ies. +o=e!er, rather than ha!ing to 'reate all those obGe'ts oursel!es an" =ire them together, the FML an" )aFoutInflater han"le the Mhea!y li&tingM &or us.
*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 ImageVieE i'on =i"get an" repla'e the sto'k resour'e =ith a "i&&erent one
5he user sees nothing "i&&erent S =e ha!e simply 'hange" ho= those ro=s are being 'reate". >b!iously, this =as a &airly 'ontri!e" e;ample, but you 'an see =here this te'hniRue 'oul" be use" to 'ustomiKe ro=s base" on any sort o& 'riteria.
*08
-sin! convert>ie#
5he getVieEPQ metho" re'ei!es, as one o& its parameters, a VieE name", by 'on!ention, convertVieE. %ometimes, convertVieE =ill be null. 0n those 'ases, you ha!e to 'reate a ne= ro= VieE &rom s'rat'h (e.g., !ia in&lation), Gust as =e "i" be&ore. +o=e!er, i& convertVieE is not null, then it is a'tually one o& your pre!iously-'reate" VieE obGe'ts: 5his =ill happen primarily =hen the user s'rolls the )istVieE S as ne= ro=s appear, An"roi" =ill attempt to re'y'le the !ie=s o& the ro=s that s'rolle" o&& the other en" o& the list, to sa!e you ha!ing to rebuil" them &rom s'rat'h. Assuming that ea'h o& your ro=s has the same basi' stru'ture, you 'an use findVieE4FIdPQ to get at the in"i!i"ual =i"gets that make up your ro= an"
*0:
'hange their 'ontents, then return convertVieE &rom getVieEPQ, rather than 'reate a =hole ne= ro=. *or e;ample, here is the getVieEPQ implementation &rom last time, no= optimiKe" !ia convertVieE (&rom the 9ancF)ists/?ecFcling proGe't),
public class ?ecFcling=emo eGtends )istActivitF : private &eGtVieE selectionJ private static final 2tringAB items6:7lorem78 7ipsum78 7dolor78 7sit78 7amet78 7consectetuer78 7adipiscing78 7elit78 7morbi78 7vel78 7ligula78 7vitae78 7arcu78 7aliUuet78 7mollis78 7etiam78 7vel78 7erat78 7placerat78 7ante78 7porttitor78 7sodales78 7pellentesUue78 7augue78 7purus7;J O"verride public void onCreateP4undle icicleQ : super.onCreatePicicleQJ setContentViewP?.laFout.mainQJ setList$dapterPneE Iconic$dapterPQQJ selection6P&eGtVieEQfindViewByIdP?.id.selectionQJ ; public void onListItemClickP)istVieE parent8 VieE v8 int position8 long idQ : selection.setTextPitemsApositionBQJ ; class IconicAdapter eGtends ArraFAdapterL2tringM : Iconic$dapterPQ : superP?ecFcling=emo.this8 ?.laFout.roE8 itemsQJ ; public VieE getViewPint position8 VieE convertVieE8 VieEDroup parentQ : VieE roE6convertVieEJ if ProE66nullQ : )aFoutInflater inflater6getLayoutInflaterPQJ ; roE6inflater.inflateP?.laFout.roE8 parent8 falseQJ
*2<
+ere, =e 'he'k to see i& the convertVieE is null an", i& so, =e then in&late our ro= S but i& it is not-null, =e Gust reuse it. 5he =ork to &ill in the 'ontents (i'on image, te;t) is the same in either 'ase. 5he a"!antage is that =e a!oi" the potentially-e;pensi!e in&lation step. 0n &a't, a''or"ing to statisti's 'ite" by 8oogle at the 2010 8oogle 0U> 'on&eren'e, a )istVieE that uses a re'y'ling )istAdapter =ill per&orm 1A0L &aster than one that "oes not. 0n &a't, &or 'omple; ro=s, that might un"erstate the bene&it. 2ot only is this &aster, but it uses mu'h less memory. Ea'h =i"get or 'ontainer S in other =or"s, ea'h sub'lass o& VieE S hol"s onto up to 2D1 o& "ata, not 'ounting things like images in ImageVieE =i"gets. Ea'h o& our ro=s, there&ore, might be as big as /D1. *or our list o& 2A nonsense =or"s, 'onsuming as mu'h as 1A0D1 &or a non-re'y'ling list (2A ro=s at /D1 ea'h) =oul" be ine&&i'ient but not a huge problem. A list o& 1,000 nonsense =or"s, though, 'onsuming as mu'h as /M1 o& AM, =oul" be a mu'h bigger issue. 1ear in min" that your appli'ation may only ha!e 1/M1 o& Ca!a heap memory to =ork =ith. e'y'ling allo=s us to han"le arbitrary list lengths =ith only as mu'h VieE memory 'onsume" as is nee"e" &or the ro=s !isible on s'reen. 2ote that ro= re'y'ling is only an issue i& =e are 'reating the ro=s oursel&. 0& =e let ArraFAdapter 'reate the ro=s, by le!eraging its implementation o& getVieEPQ as sho=n in the 9ancF)ists/=Fnamic proGe't, then it "eals =ith the re'y'ling.
their assigne" i"enti&iers, so =e 'an 'ustomiKe the =i"get 'ontents (e.g., 'hange the te;t o& a &eGtVieE, 'hange the i'on in an ImageVieE). %in'e findVieE4FIdPQ 'an &in" =i"gets any=here in the tree o& 'hil"ren o& the ro=7s root VieE, this 'oul" take a &air number o& instru'tions to e;e'ute, parti'ularly i& =e keep ha!ing to re-&in" =i"gets =e ha" &oun" on'e be&ore. 0n some 8$0 toolkits, this problem is a!oi"e" by ha!ing the 'omposite VieE obGe'ts, like our ro=s, be "e'lare" totally in program 'o"e (in this 'ase, Ca!a). 5hen, a''essing in"i!i"ual =i"gets is merely the matter o& 'alling a getter or a''essing a &iel". An" you 'an 'ertainly "o that =ith An"roi", but the 'o"e gets rather !erbose. What =oul" be ni'e is a =ay =here =e 'an still use the layout FML yet 'a'he our ro=7s key 'hil" =i"gets so =e only ha!e to &in" them on'e. 5hat7s =here the hol"er pattern 'omes into play, in a 'lass =e7ll 'all VieE!older. All VieE obGe'ts ha!e get&agPQ an" set&agPQ metho"s. 5hese allo= you to asso'iate an arbitrary obGe't =ith the =i"get. What the hol"er pattern "oes is use that MtagM to hol" an obGe't that, in turn, hol"s ea'h o& the 'hil" =i"gets o& interest. 1y atta'hing that hol"er to the ro= VieE, e!ery time =e use the ro=, =e alrea"y ha!e a''ess to the 'hil" =i"gets =e 'are about, =ithout ha!ing to 'all findVieE4FIdPQ again. %o, let[s take a look at one o& these hol"er 'lasses (taken &rom the 9ancF)ists/VieE!older sample proGe't),
package com.commonsEare.android.fancFlists.fiveJ import android.vieE.VieEJ import android.Eidget.ImageVieEJ class VieE!older : ImageVieE icon6nullJ View(olderPVieE baseQ : this.icon6PImageVieEQbase.findViewByIdP?.id.iconQJ ;
*2&
VieE!older
hol"s onto the 'hil" =i"gets, initialiKe" !ia findVieE4FIdPQ in its 'onstru'tor. 5he =i"gets are simply pa'kage-prote'te" "ata members, a''essible &rom other 'lasses in this proGe't...su'h as a VieE!older=emo a'ti!ity. 0n this 'ase, =e are only hol"ing onto one =i"get S the i'on S sin'e =e =ill let ArrayA"apter han"le our label &or us. $sing VieE!older is a matter o& 'reating an instan'e =hene!er =e in&late a ro= an" atta'hing sai" instan'e to the ro= VieE !ia set&agPQ, as sho=n in this re=rite o& getVieEPQ, &oun" in VieE!older=emo,
public VieE getViewPint position8 VieE convertVieE8 VieEDroup parentQ : VieE roE6super.getViewPposition8 convertVieE8 parentQJ VieE!older holder6PVieE!olderQroE.getTagPQJ if Pholder66nullQ : holder6neE View(olderProEQJ roE.setTagPholderQJ ; if PgetModelPpositionQ.lengthPQM<Q : holder.icon.setImage%esourceP?.draEable.deleteQJ ; else : holder.icon.setImage%esourceP?.draEable.okQJ ; returnProEQJ ;
+ere, =e go ba'k to allo=ing ArraFAdapter to han"le our ro= in&lation an" re'y'ling &or us. 0& the 'all to get&agPQ on the ro= returns null, =e kno= =e nee" to 'reate a ne= VieE!older, =hi'h =e then atta'h to the ro= !ia set&agPQ &or later reuse. 5hen, a''essing the 'hil" =i"gets is merely a matter o& a''essing the "ata members on the hol"er. 5he &irst time the )istVieE is "isplaye", all ne= ro=s nee" to be in&late", an" =e =in" up 'reating a VieE!older &or ea'h. As the user s'rolls, ro=s get re'y'le", an" =e 'an reuse their 'orrespon"ing VieE!older =i"get 'a'hes. $sing a hol"er helps per&orman'e, but the e&&e't is not as "ramati'. Whereas re'y'ling 'an gi!e you a 1A0L per&orman'e impro!ement, a""ing in a hol"er in'reases the impro!ement to 14AL. +en'e, =hile you may =ish to implement re'y'ling up &ront =hen you 'reate your a"apter, a""ing in a
*2-
hol"er might be something you "eal =ith later, =hen you are =orking spe'i&i'ally on per&orman'e tuning. 0n this parti'ular 'ase, =e 'ertainly 'oul" simpli&y all o& this, by skipping VieE!older an" using get&agPQ an" set&agPQ =ith the ImageVieE "ire'tly. 5his e;ample is =ritten as it is to "emonstrate ho= to han"le a more 'omple; s'enario, =here you might ha!e se!eral =i"gets that =oul" nee" to be 'a'he" !ia the hol"er pattern.
nteractive Co)s
Lists =ith pretty i'ons ne;t to them are all &ine an" =ell. 1ut, 'an =e 'reate )istVieE =i"gets =hose ro=s 'ontain intera'ti!e 'hil" =i"gets instea" o& Gust passi!e =i"gets like &eGtVieE an" ImageVieEH *or e;ample, there is a ?ating4ar =i"get that allo=s users to assign a rating by 'li'king on a set o& star i'ons. Coul" =e 'ombine the ?ating4ar =ith te;t in or"er to allo= people to s'roll a list o&, say, songs an" rate them right insi"e the listH 5here is goo" ne=s an" ba" ne=s. 5he goo" ne=s is that intera'ti!e =i"gets in ro=s =ork Gust &ine. 5he ba" ne=s is that it is a little tri'ky, spe'i&i'ally =hen it 'omes to taking a'tion =hen the intera'ti!e =i"get7s state 'hanges (e.g., a !alue is type" into a &iel"). We nee" to store that state some=here, sin'e our ?ating4ar =i"get =ill be re'y'le" =hen the )istVieE is s'rolle". We nee" to be able to set the ?ating4ar state base" upon the a'tual =or" =e are !ie=ing as the ?ating4ar is re'y'le", an" =e nee" to sa!e the state =hen it 'hanges so it 'an be restore" =hen this parti'ular ro= is s'rolle" ba'k into !ie=. What makes this interesting is that, by "e&ault, the ?ating4ar has absolutely no i"ea =hat item in the ArraFAdapter it represents. A&ter all, the ?ating4ar is Gust a =i"get, use" in a ro= o& a )istVieE. We nee" to tea'h the ro=s =hi'h item in the ArraFAdapter they are 'urrently "isplaying, so =hen their ?ating4ar is 'he'ke", they kno= =hi'h item7s state to mo"i&y.
*2%
%o, let7s see ho= this is "one, using the a'ti!ity in the 9ancF)ists/?ate)ist sample proGe't. We =ill use the same basi' 'lasses as our pre!ious "emo S =e are sho=ing a list o& nonsense =or"s, =hi'h you 'an then rate. 0n a""ition, =or"s gi!en a top rating are put in all 'aps,
package com.commonsEare.android.fancFlists.siGJ import import import import import import import import import import import import import android.app.ActivitFJ android.os.4undleJ android.app.)istActivitFJ android.vieE.VieEJ android.vieE.VieEDroupJ android.vieE.)aFoutInflaterJ android.Eidget.AdapterVieEJ android.Eidget.ArraFAdapterJ android.Eidget.?ating4arJ android.Eidget.)inear)aFoutJ android.Eidget.)istVieEJ android.Eidget.&eGtVieEJ java.util.ArraF)istJ
public class ?ate)ist=emo eGtends )istActivitF : private static final 2tringAB items6:7lorem78 7ipsum78 7dolor78 7sit78 7amet78 7consectetuer78 7adipiscing78 7elit78 7morbi78 7vel78 7ligula78 7vitae78 7arcu78 7aliUuet78 7mollis78 7etiam78 7vel78 7erat78 7placerat78 7ante78 7porttitor78 7sodales78 7pellentesUue78 7augue78 7purus7;J O"verride public void onCreateP4undle icicleQ : super.onCreatePicicleQJ ArraF)istL?oE#odelM list6neE ArraF)istL?oE#odelMPQJ for P2tring s : itemsQ : list.addPneE %owModelPsQQJ ; ; setList$dapterPneE %ating$dapterPlistQQJ
private ?oE#odel getModelPint positionQ : returnPPP?atingAdapterQgetList$dapterPQQ.getItemPpositionQQJ ; class ?atingAdapter eGtends ArraFAdapterL?oE#odelM : %ating$dapterPArraF)istL?oE#odelM listQ : superP?ate)ist=emo.this8 ?.laFout.roE8 ?.id.label8 listQJ ; public VieE getViewPint position8 VieE convertVieE8
*20
VieEDroup parentQ : VieE roE6super.getViewPposition8 convertVieE8 parentQJ VieE!older holder6PVieE!olderQroE.getTagPQJ if Pholder66nullQ : holder6neE View(olderProEQJ roE.setTagPholderQJ ?ating4ar."n?ating4ar+hange)istener l6 neE ?ating4ar.On%atingBarChangeListenerPQ : public void on%atingChangedP?ating4ar rating4ar8 float rating8 boolean from&ouchQ : Integer mF(osition6PIntegerQrating4ar.getTagPQJ ?oE#odel model6getModelPmF(ositionQJ model.rating6ratingJ )inear)aFout parent6P)inear)aFoutQrating4ar.get)arentPQJ &eGtVieE label6P&eGtVieEQparent.findViewByIdP?.id.labelQJ ; ;J ; holder.rate.setOn%atingBarChangeListenerPlQJ label.setTextPmodel.toStringPQQJ
?oE#odel model6getModelPpositionQJ holder.rate.setTagPneE IntegerPpositionQQJ holder.rate.set%atingPmodel.ratingQJ ; ; class ?oE#odel : 2tring labelJ float rating6>.-fJ %owModelP2tring labelQ : this.label6labelJ ; public 2tring toStringPQ : if PratingM6C.-Q : returnPlabel.to*pperCasePQQJ ; returnPlabelQJ ; ; ; returnProEQJ
*22
+ere is =hat is "i&&erent in this a'ti!ity an" getVieEPQ implementation than be&ore, 1. While =e are still using 2tringVW items as the list o& nonsense =or"s, rather than pour that 2tring array straight into an ArraFAdapter, =e turn it into a list o& ?oE#odel obGe'ts. ?oE#odel is the mutable mo"el, it hol"s the nonsense =or" plus the 'urrent 'he'ke" state. 0n a real system, these might be obGe'ts populate" &rom a "atabase, an" the properties =oul" ha!e more business meaning.
2. $tility metho"s like on)istItem+lickPQ ha" to be up"ate" to re&le't the 'hange &rom a pure-2tring mo"el to use a ?oE#odel. .. 5he ArraFAdapter sub'lass (?atingAdapter), in getVieEPQ, lets ArraFAdapter in&late an" re'y'le the ro=, then 'he'ks to see i& =e ha!e a VieE!older in the ro=7s tag. 0& not, =e 'reate a ne= VieE!older an" asso'iate it =ith the ro=. *or the ro=7s ?ating4ar, =e a"" an anonymous on?ating+hangedPQ listener that looks at the ro=7s tag (get&agPQ) an" 'on!erts that into an Integer, representing the position =ithin the ArraFAdapter that this ro= is "isplaying. $sing that, the rating bar 'an get the a'tual ?oE#odel &or the ro= an" up"ate the mo"el base" upon the ne= state o& the rating bar. 0t also up"ates the te;t a"Ga'ent to the ?ating4ar =hen 'he'ke" to mat'h the rating bar state. <. We al=ays make sure that the ?ating4ar has the proper 'ontents an" has a tag (!ia set&agPQ) pointing to the position in the a"apter the ro= is "isplaying. 5he ro= layout is !ery simple, Gust a ?ating4ar an" a &eGtVieE insi"e a )inear)aFout,
LNGml version671.-7 encoding67utf-,7NM L)inear)aFout Gmlns:android67http://schemas.android.com/apk/res/android7 android:laFout Eidth67fill parent7 android:laFout height67Erap content7 android:orientation67horiKontal7 M L?ating4ar android:id67ORid/rate7 android:laFout Eidth67Erap content7 android:laFout height67Erap content7 android:num2tars67C7
*27
android:step2iKe6717 android:rating67>7 /M L&eGtVieE android:id67ORid/label7 android:padding67>dip7 android:teGt2iKe671,sp7 android:laFout gravitF67leftWcenter vertical7 android:laFout Eidth67fill parent7 android:laFout height67Erap content7/M L/)inear)aFoutM
5he VieE!older is similarly simple, Gust e;tra'ting the ?ating4ar out o& the ro= VieE &or 'a'hing purposes,
package com.commonsEare.android.fancFlists.siGJ import android.vieE.VieEJ import android.Eidget.?ating4arJ class VieE!older : ?ating4ar rate6nullJ View(olderPVieE baseQ : this.rate6P?ating4arQbase.findViewByIdP?.id.rateQJ ; ;
*28
5his in'lu"es the toggle" rating bars turning their =or"s into all 'aps,
*2:
CHAPTER 12
5his book has 'o!ere" a number o& =i"gets an" 'ontainers so &ar. 5his 'hapter is the last that &o'uses e;'lusi!ely on =i"gets an" 'ontainers, 'o!ering a number o& popular options, &rom "ate an" time =i"gets to tabs. A&ter this 'hapter, =e =ill still intro"u'e the o''asional ne= =i"get, but in the 'onte;t o& some other topi', su'h as intro"u'ing the (rogress4ar in the 'hapter on threa"s.
*7*
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
that the month runs &rom - &or Canuary through 11 &or @e'ember. Most importantly, both let you pro!i"e a 'allba'k obGe't ( "n=ate+hanged)istener or "n=ate2et)istener) =here you are in&orme" o& a ne= "ate sele'te" by the user. 0t 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, &ime(icker an" &ime(icker=ialog let you,
set the initial time the user 'an a"Gust, in the &orm o& an hour ( through >C) an" a minute (- through .*) in"i'ate i& the sele'tion shoul" be in 12-hour mo"e =ith an AMP#M toggle, or in 2<-hour mo"e (=hat in the $% is thought o& as Mmilitary timeM an" mu'h o& the rest o& the =orl" is thought o& as Mthe =ay times are suppose" to beM) pro!i"e 'allba'k obGe't ("n&ime+hanged)istener or "n&ime2et)istener) 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 a
*or e;ample, &rom the 9ancF/+hrono sample proGe't, here7s a tri!ial layout 'ontaining a label an" t=o buttons S the buttons =ill pop up the "ialog &la!ors o& the "ate an" time pi'kers,
LNGml version671.-7 encoding67utf-,7NM L)inear)aFout Gmlns:android67http://schemas.android.com/apk/res/android7 android:orientation67vertical7 android:laFout Eidth67fill parent7 android:laFout height67fill parent7 M L&eGtVieE android:id67ORid/dateAnd&ime7 android:laFout Eidth67fill parent7 android:laFout height67Erap content7 /M L4utton android:id67ORid/date4tn7 android:laFout Eidth67fill parent7 android:laFout height67Erap content7 android:teGt672et the =ate7 android:on+lick67choose=ate7 /M L4utton android:id67ORid/time4tn7 android:laFout Eidth67fill parent7 android:laFout height67Erap content7
*7&
public class +hrono=emo eGtends ActivitF : =ate9ormat fmt=ateAnd&ime6=ate9ormat.getDateTimeInstancePQJ &eGtVieE dateAnd&ime)abelJ +alendar dateAnd&ime6+alendar.getInstancePQJ O"verride public void onCreateP4undle icicleQ : super.onCreatePicicleQJ setContentViewP?.laFout.mainQJ dateAnd&ime)abel6P&eGtVieEQfindViewByIdP?.id.dateAnd&imeQJ updateLa'elPQJ ; public void chooseDatePVieE vQ : neE Date)ickerDialogP+hrono=emo.this8 d8 dateAnd&ime.getP+alendar.5$A?Q8 dateAnd&ime.getP+alendar.#"%&!Q8 dateAnd&ime.getP+alendar.=A5 "9 #"%&!QQ .showPQJ ; public void chooseTimePVieE vQ : neE Time)ickerDialogP+hrono=emo.this8 t8 dateAnd&ime.getP+alendar.!"3? "9 =A5Q8 dateAnd&ime.getP+alendar.#I%3&$Q8 trueQ .showPQJ ; private void updateLa'elPQ : dateAnd&ime)abel.setTextPfmt=ateAnd&ime
*7-
.formatPdateAnd&ime.getTimePQQQJ ; : =ate(icker=ialog."n=ate2et)istener d6neE =ate(icker=ialog.OnDateSetListenerPQ public void onDateSetP=ate(icker vieE8 int Fear8 int month"f5ear8 int daF"f#onthQ : dateAnd&ime.setP+alendar.5$A?8 FearQJ dateAnd&ime.setP+alendar.#"%&!8 month"f5earQJ dateAnd&ime.setP+alendar.=A5 "9 #"%&!8 daF"f#onthQJ updateLa'elPQJ ;
;J :
&ime(icker=ialog."n&ime2et)istener t6neE &ime(icker=ialog.OnTimeSetListenerPQ public void onTimeSetP&ime(icker vieE8 int hour"f=aF8 int minuteQ : dateAnd&ime.setP+alendar.!"3? "9 =A58 hour"f=aFQJ dateAnd&ime.setP+alendar.#I%3&$8 minuteQJ updateLa'elPQJ ;
;J ;
5he Mmo"elM &or this a'ti!ity is Gust a +alendar instan'e, initially set to be the 'urrent "ate an" time. We pour it into the !ie= !ia a =ate9ormat &ormatter. 0n the update)abelPQ metho", =e take the 'urrent +alendar, &ormat it, an" put it in the &eGtVieE. Ea'h button has a 'orrespon"ing metho" that =ill get 'ontrol =hen the user 'li'ks it (choose=atePQ an" choose&imePQ). When the button is 'li'ke", either a =ate(icker=ialog or a &ime(icker=ialog is sho=n. 0n the 'ase o& the =ate(icker=ialog, =e gi!e it a "n=ate2et)istener 'allba'k that up"ates the +alendar =ith the ne= "ate (year, month, "ay o& month). We also gi!e the "ialog the last-sele'te" "ate, getting the !alues out o& the +alendar. 0n the 'ase o& the &ime(icker=ialog, it gets a "n&ime2et)istener 'allba'k to up"ate the time portion o& the +alendar, the last-sele'te" time, an" a true in"i'ating =e =ant 2<-hour mo"e on the time sele'tor. With all this =ire" together, the resulting a'ti!ity looks like this,
*7%
"igure 281 The same application@ sho)ing the date picker dialog
*70
"igure 2:1 The same application@ sho)ing the time picker dialog
*72
Without any Ca!a 'o"e other than the generate" stub, =e 'an buil" this proGe't an" get the &ollo=ing a'ti!ity,
0& you are looking &or more o& a timer, +hronometer may be o& interest. With a +hronometer, you 'an tra'k elapse" time &rom a starting point. ?ou simply tell it =hen to startPQ an" stopPQ, an" possibly o!erri"e the &ormat string that "isplays the te;t,
*77
"igure 7*1 The ;ie)sKChronometer AP /emo from the Android &1< S/9
Seeking Cesolution
5he 2eek4ar is an input =i"get, allo=ing the user to sele't a !alue along a range o& possible !alues,
*78
"igure 7&1 The ;ie)sKSeekBar AP /emo from the Android &1< S/9
5he user 'an either "rag the MthumbM or 'li'k on either si"e o& it to reposition the thumb. 5he thumb then points to a parti'ular !alue along a range. 5hat range =ill be - to some ma;imum !alue, 1-- by "e&ault, that you 'ontrol !ia a 'all to set#aGPQ. ?ou 'an &in" out =hat the 'urrent position is !ia get(rogressPQ, or &in" out =hen the user makes a 'hange to the thumb7s position by registering a listener !ia set"n2eek4ar+hange)istenerPQ. We sa= another !ariation on this theme =ith the ?ating4ar in the pre!ious 'hapter.
Putting t ,n +y Tab
5he general An"roi" philosophy is to keep a'ti!ities short an" s=eet. 0& 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'ti!ity ki'ke" o&& !ia an Intent, as =ill be "es'ribe" later in this book. +o=e!er, that 'an be 'ompli'ate" to set up. Moreo!er, sometimes there legitimately is a lot o& in&ormation that nee"s to be 'olle'te" to be pro'esse" as an atomi' operation.
*7:
0n a tra"itional $0, you might use tabs to a''omplish this en", su'h as a J&abbed(ane in Ca!aP%=ing. 0n An"roi", you no= ha!e an option o& using a &ab!ost 'ontainer in mu'h the same =ay S a portion o& your a'ti!ity7s s'reen is taken up =ith tabs =hi'h, =hen 'li'ke", s=ap out part o& the !ie= an" repla'e it =ith something else. *or e;ample, you might ha!e an a'ti!ity =ith a tab &or entering a lo'ation an" a se'on" tab &or sho=ing a map o& that lo'ation. %ome 8$0 toolkits re&er to MtabsM as being Gust the things a user 'li'ks on to toggle &rom one !ie= to another. %ome toolkits re&er to MtabsM as being the 'ombination o& the 'li'kable button-ish 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 Mtab buttonsM an" Mtab 'ontentsM in this se'tion.
The Pieces
5here are a &e= =i"gets an" 'ontainers you nee" to use in or"er to set up a tabbe" portion o& a !ie=,
&ab!ost is the o!erar'hing 'ontainer &or the tab buttons an" tab 'ontents &ab@idget implements the ro= o& tab buttons, =hi'h 'ontain te;t labels an" optionally 'ontain i'ons
is the 'ontainer &or the tab 'ontentsT ea'h tab 'ontent is a 'hil" o& the 9rame)aFout
9rame)aFout
5his is similar to the approa'h that MoKilla7s F$L takes. 0n F$L7s 'ase, the tabboG element 'orrespon"s to An"roi"7s &ab!ost, the tabs element 'orrespon"s to &ab@idget, an" tabpanels 'orrespon"s to the 9rame)aFout. *or e;ample, here is a layout "e&inition &or a tabbe" a'ti!ity, &rom 9ancF/&ab,
LNGml version671.-7 encoding67utf-,7NM L&ab!ost Gmlns:android67http://schemas.android.com/apk/res/android7 android:id67ORid/tabhost7
*8<
android:laFout Eidth67fill parent7 android:laFout height67fill parent7M L)inear)aFout android:orientation67vertical7 android:laFout Eidth67fill parent7 android:laFout height67fill parent7M L&ab@idget android:id67Oandroid:id/tabs7 android:laFout Eidth67fill parent7 android:laFout height67Erap content7 /M L9rame)aFout android:id67Oandroid:id/tabcontent7 android:laFout Eidth67fill parent7 android:laFout height67fill parent7M LAnalog+lock android:id67ORid/tab17 android:laFout Eidth67fill parent7 android:laFout height67fill parent7 /M L4utton android:id67ORid/tab>7 android:laFout Eidth67fill parent7 android:laFout height67fill parent7 android:teGt67A semi-random button7 /M L/9rame)aFoutM L/)inear)aFoutM L/&ab!ostM
2ote that the &ab@idget an" 9rame)aFout are in"ire't 'hil"ren o& the &ab!ost, an" the 9rame)aFout itsel& has 'hil"ren representing the !arious tabs. 0n this 'ase, there are t=o tabs, a 'lo'k an" a button. 0n a more 'ompli'ate" s'enario, the tabs are probably some &orm o& 'ontainer (e.g., )inear)aFout) =ith their o=n 'ontents.
,irin! It To!ether
?ou 'an put these =i"gets in a regular ActivitF or a &abActivitF. &abActivitF, like )istActivitF, =raps a 'ommon $0 pattern (a'ti!ity ma"e up entirely o& tabs) into a pattern-a=are a'ti!ity sub'lass. 0& you =ish to use the &abActivitF, you must gi!e the &ab!ost an android:id o& Oandroid:id/tabhost. Con!ersely, i& you "o not =ish to use &abActivitF, you nee" to get your &ab!ost !ia findVieE4FIdPQ, then 'all setupPQ on the &ab!ost, be&ore you "o anything else. 5he rest o& the Ca!a 'o"e nee"s to tell the &ab!ost =hat !ie=s represent the tab 'ontents an" =hat the tab buttons shoul" look like. 5his is all =rappe"
*8*
up in &ab2pec obGe'ts. ?ou get a &ab2pec instan'e &rom the host !ia neE&ab2pecPQ, &ill it out, then a"" it to the host in the proper seRuen'e. 5he t=o key metho"s on &ab2pec are,
set+ontentPQ, =here you in"i'ate =hat goes in the tab 'ontent &or this tab, typi'ally the android:id o& the !ie= you =ant sho=n =hen this tab is sele'te" setIndicatorPQ,
=here you pro!i"e the 'aption &or the tab button an", in some &la!ors o& this metho", supply a =raEable to represent the i'on &or the tab
2ote that tab Min"i'atorsM 'an a'tually be !ie=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 setupPQ on the &ab!ost be&ore 'on&iguring any o& these &ab2pec obGe'ts. 5he 'all to setupPQ is not nee"e" i& you are using the &abActivitF base 'lass &or your a'ti!ity. *or e;ample, here is the Ca!a 'o"e to =ire together the tabs &rom the pre'e"ing layout e;ample,
package com.commonsEare.android.fancFJ import android.app.ActivitFJ import android.os.4undleJ import android.Eidget.&ab!ostJ public class &ab=emo eGtends ActivitF : O"verride public void onCreateP4undle icicleQ : super.onCreatePicicleQJ setContentViewP?.laFout.mainQJ &ab!ost tabs6P&ab!ostQfindViewByIdP?.id.tabhostQJ tabs.setupPQJ &ab!ost.&ab2pec spec6tabs.newTa'SpecP7tag17QJ spec.setContentP?.id.tab1QJ spec.setIndicatorP7+lock7QJ tabs.addTa'PspecQJ
*8&
We &in" our &ab!ost !ia the &amiliar findVieE4FIdPQ metho", then ha!e it setupPQ. A&ter that, =e get a &ab2pec !ia neE&ab2pecPQ, supplying a tag =hose purpose is unkno=n at this time. 8i!en the spe', you 'all set+ontentPQ an" setIndicatorPQ, then 'all add&abPQ ba'k on the &ab!ost to register the tab as a!ailable &or use. *inally, you 'an 'hoose =hi'h tab is the one to sho= !ia set+urrent&abPQ, pro!i"ing the --base" in"e; o& the tab. 5he resultH
"igure 7-1 The Tab/emo sample application@ sho)ing the first tab
*8-
Addin! Them -p
&ab@idget
is set up to allo= you to easily "e&ine tabs at 'ompile time. +o=e!er, sometimes, you =ant to a"" tabs to your a'ti!ity "uring runtime. *or e;ample, imagine an email 'lient =here in"i!i"ual email messages get opene" in their o=n tab, &or easy toggling bet=een messages. 0n this 'ase, you "o not kno= ho= many tabs or =hat their 'ontents =ill be until runtime, =hen the user 'hooses to open a message. *ortunately, An"roi" also supports a""ing tabs "ynami'ally at runtime.
A""ing tabs "ynami'ally at runtime =orks mu'h like the 'ompile-time tabs sho=n abo!e, e;'ept you use a "i&&erent &la!or o& set+ontentPQ, one that takes a &ab!ost.&ab+ontent9actorF instan'e. 5his is Gust a 'allba'k that =ill be in!oke" S you pro!i"e an implementation o& create&ab+ontentPQ an" use it to buil" an" return the VieE that be'omes the 'ontent o& the tab. Let us take a look at an e;ample (9ancF/=Fnamic&ab).
*8%
*irst, here is some layout FML &or an a'ti!ity that sets up the tabs an" "e&ines one tab, 'ontaining a single button,
LNGml version671.-7 encoding67utf-,7NM L&ab!ost Gmlns:android67http://schemas.android.com/apk/res/android7 android:id67ORid/tabhost7 android:laFout Eidth67fill parent7 android:laFout height67fill parent7M L)inear)aFout android:orientation67vertical7 android:laFout Eidth67fill parent7 android:laFout height67fill parent7M L&ab@idget android:id67Oandroid:id/tabs7 android:laFout Eidth67fill parent7 android:laFout height67Erap content7 /M L9rame)aFout android:id67Oandroid:id/tabcontent7 android:laFout Eidth67fill parent7 android:laFout height67fill parent7M L4utton android:id67ORid/buttontab7 android:laFout Eidth67fill parent7 android:laFout height67fill parent7 android:teGt67A semi-random button7 android:on+lick67add&ab7 /M L/9rame)aFoutM L/)inear)aFoutM L/&ab!ostM
What =e =ant to "o is a"" ne= tabs =hene!er the button is 'li'ke". 5hat 'an be a''omplishe" in Gust a &e= lines o& 'o"e,
package com.commonsEare.android.dFnamictabJ import import import import import android.app.ActivitFJ android.os.4undleJ android.vieE.VieEJ android.Eidget.Analog+lockJ android.Eidget.&ab!ostJ
public class =Fnamic&ab=emo eGtends ActivitF : private &ab!ost tabs6nullJ O"verride public void onCreateP4undle icicleQ : super.onCreatePicicleQJ setContentViewP?.laFout.mainQJ tabs6P&ab!ostQfindViewByIdP?.id.tabhostQJ tabs.setupPQJ
*80
&ab!ost.&ab2pec spec6tabs.newTa'SpecP7buttontab7QJ spec.setContentP?.id.buttontabQJ spec.setIndicatorP74utton7QJ tabs.addTa'PspecQJ ; public void addTa'PVieE vQ : &ab!ost.&ab2pec spec6tabs.newTa'SpecP7tag17QJ spec.setContentPneE &ab!ost.Ta'Content"actoryPQ : public VieE createTa'ContentP2tring tagQ : returnPneE $nalogClockP=Fnamic&ab=emo.thisQQJ ; ;QJ spec.setIndicatorP7+lock7QJ tabs.addTa'PspecQJ
; ;
0n our button7s add&abPQ 'allba'k, =e 'reate a &ab!ost.&ab2pec obGe't an" gi!e it an anonymous &ab!ost.&ab+ontent9actorF. 5he &a'tory, in turn, returns the VieE to be use" &or the tab S in this 'ase, Gust an Analog+lock. 5he logi' &or 'onstru'ting the tab[s VieE 'oul" be mu'h more elaborate, su'h as using )aFoutInflater to 'onstru't a !ie= &rom layout FML. 0nitially, =hen the a'ti!ity is laun'he", =e Gust ha!e the one tab,
*82
"igure 701 The /ynamicTab application@ )ith the single initial tab
*87
*or e;ample, here is a layout &or a simple a'ti!ity (9ancF/9lipper1) using a 4utton an" a VieE9lipper,
LNGml version671.-7 encoding67utf-,7NM L)inear)aFout Gmlns:android67http://schemas.android.com/apk/res/android7 android:orientation67vertical7 android:laFout Eidth67fill parent7 android:laFout height67fill parent7 M L4utton android:id67ORid/flip me7 android:laFout Eidth67fill parent7 android:laFout height67Erap content7 android:teGt679lip #eX7 android:on+lick67flip7 /M LVieE9lipper android:id67ORid/details7 android:laFout Eidth67fill parent7 android:laFout height67fill parent7 M L&eGtVieE android:laFout Eidth67fill parent7 android:laFout height67Erap content7 android:teGt2tFle67bold7 android:teGt+olor67S99--99--7 android:teGt67&his is the first panel7 /M L&eGtVieE
*88
android:laFout Eidth67fill parent7 android:laFout height67Erap content7 android:teGt2tFle67bold7 android:teGt+olor67S9999----7 android:teGt67&his is the second panel7 /M L&eGtVieE android:laFout Eidth67fill parent7 android:laFout height67Erap content7 android:teGt2tFle67bold7 android:teGt+olor67S999999--7 android:teGt67&his is the third panel7 /M L/VieE9lipperM L/)inear)aFoutM
2oti'e that the layout "e&ines three 'hil" !ie=s &or the VieE9lipper, ea'h a &eGtVieE =ith a simple message. >& 'ourse, you 'oul" ha!e !ery 'ompli'ate" 'hil" !ie=s, i& you so 'hose. 5o manually &lip the !ie=s, =e nee" to hook into the 4utton an" &lip them oursel!es =hen the button is 'li'ke",
package com.commonsEare.android.flipper1J import import import import android.app.ActivitFJ android.os.4undleJ android.vieE.VieEJ android.Eidget.VieE9lipperJ
public class 9lipper=emo eGtends ActivitF : VieE9lipper flipperJ O"verride public void onCreateP4undle icicleQ : super.onCreatePicicleQJ setContentViewP?.laFout.mainQJ ; flipper6PVieE9lipperQfindViewByIdP?.id.detailsQJ
5his is Gust a matter o& 'alling shoE%eGtPQ on the VieE9lipper, like you 'an on any VieEAnimator 'lass.
*8:
5he result is a tri!ial a'ti!ity, 'li'k the button, an" the ne;t &eGtVieE in seRuen'e is "isplaye", =rapping aroun" to the &irst a&ter !ie=ing the last,
"igure 781 The same application@ after s)itching to the second panel
*:<
5his, o& 'ourse, 'oul" be han"le" more simply by ha!ing a single &eGtVieE an" 'hanging the te;t an" 'olor on ea'h 'li'k. +o=e!er, you 'an imagine that the VieE9lipper 'ontents 'oul" be mu'h more 'ompli'ate", like the 'ontents you might put into a &abVieE. As =ith the &ab@idget, sometimes, your VieE9lipper 'ontents may not be kno=n at 'ompile time. As =ith &ab@idget, though, you 'an a"" ne= 'ontents on the &ly =ith ease. *or e;ample, let us look at another sample a'ti!ity ( 9ancF/9lipper>), using this layout,
LNGml version671.-7 encoding67utf-,7NM L)inear)aFout Gmlns:android67http://schemas.android.com/apk/res/android7 android:orientation67vertical7 android:laFout Eidth67fill parent7 android:laFout height67fill parent7 M LVieE9lipper android:id67ORid/details7 android:laFout Eidth67fill parent7 android:laFout height67fill parent7 M L/VieE9lipperM L/)inear)aFoutM
2oti'e that the VieE9lipper has no 'ontents at 'ompile time. Also note that there is no 4utton &or &lipping bet=een the 'ontents S more on this in a moment. *or the VieE9lipper 'ontents, =e =ill 'reate large 4utton =i"gets, ea'h 'ontaining one o& the ran"om =or"s use" in many 'hapters in this book. An", =e =ill set up the VieE9lipper to automati'ally rotate bet=een the 4utton =i"gets,
package com.commonsEare.android.flipper>J import import import import import import android.app.ActivitFJ android.os.4undleJ android.vieE.VieEJ android.vieE.VieEDroupJ android.Eidget.4uttonJ android.Eidget.VieE9lipperJ
*:*
public class 9lipper=emo> eGtends ActivitF : static 2tringAB items6:7lorem78 7ipsum78 7dolor78 7sit78 7amet78 7consectetuer78 7adipiscing78 7elit78 7morbi78 7vel78 7ligula78 7vitae78 7arcu78 7aliUuet78 7mollis78 7etiam78 7vel78 7erat78 7placerat78 7ante78 7porttitor78 7sodales78 7pellentesUue78 7augue78 7purus7;J VieE9lipper flipperJ O"verride public void onCreateP4undle icicleQ : super.onCreatePicicleQJ setContentViewP?.laFout.mainQJ flipper6PVieE9lipperQfindViewByIdP?.id.detailsQJ for P2tring item : itemsQ : 4utton btn6neE ButtonPthisQJ btn.setTextPitemQJ flipper.addViewPbtn8 neE VieEDroup.Layout)aramsP VieEDroup.)aFout(arams.9I)) (A?$%&8 VieEDroup.)aFout(arams.9I)) (A?$%&QQJ
; ;
flipper.set"lipInter!alP>---QJ flipper.start"lippingPQJ
A&ter iterating o!er the &unky =or"s, turning ea'h into a 4utton, an" a""ing the 4utton as a 'hil" o& the VieE9lipper, =e set up the &lipper to automati'ally &lip bet=een 'hil"ren ( flipper.set9lipIntervalP>---QJ) an" to start &lipping (flipper.start9lippingPQJ). 5he result is an en"less series o& buttons, ea'h appearing, then being repla'e" by the ne;t button in seRuen'e a&ter 2 se'on"s, =rapping aroun" to the &irst a&ter the last has been sho=n,
*:&
5he auto-&lipping VieE9lipper is use&ul &or status panels or other situations =here you ha!e a lot o& in&ormation to "isplay, but not mu'h room. 5he key is that, sin'e it automati'ally &lips bet=een !ie=s, e;pe'ting users to intera't =ith in"i!i"ual !ie=s is "i'ey S the !ie= might s=it'h a=ay part=ay through their intera'tion.
allo=s multiple =i"gets to sit atop ea'h other. ?elative)aFout an" 9rame)aFout satis&y this reRuirement, =here 9rame)aFout is a 'ontainer purely &or sta'king =i"gets atop one another. >n the &lip si"e, )inear)aFout "oes not allo= =i"gets to sta'k (they &all one a&ter another in a ro= or 'olumn), an" so you shoul" not ha!e a 2liding=raEer as an imme"iate 'hil" o& a )inear)aFout. +ere is a layout, sho=ing a 2liding=raEer in a 9rame)aFout, &rom the
9ancF/=raEer=emo proGe't,
LNGml version671.-7 encoding67utf-,7NM L9rame)aFout Gmlns:android67http://schemas.android.com/apk/res/android7 android:laFout Eidth67fill parent7 android:laFout height67fill parent7 android:background67S99<<<<++7 M L2liding=raEer android:id67ORid/draEer7 android:laFout Eidth67fill parent7 android:laFout height67fill parent7 android:handle67ORid/handle7 android:content67ORid/content7M LImageVieE android:id67Oid/handle7 android:laFout Eidth67Erap content7 android:laFout height67Erap content7 android:src67OdraEable/traF handle normal7 /M L4utton android:id67Oid/content7 android:laFout Eidth67fill parent7 android:laFout height67fill parent7 android:teGt67IIm in hereX7 /M L/2liding=raEerM L/9rame)aFoutM
5he 2liding=raEer shoul" 'ontain t=o things, 1. A han"le, &reRuently an ImageVieE or something along those lines, su'h as the one use" here, pulle" &rom the An"roi" open sour'e proGe't
2. 5he 'ontents o& the "ra=er itsel&, usually some sort o& 'ontainer, though in this 'ase =e are using a 4utton
*:%
Moreo!er, 2liding=raEer nee"s to kno= the android:id !alues o& the han"le an" 'ontents, !ia the android:handle an" android:content attributes, respe'ti!ely. 5his tells the "ra=er ho= to animate itsel& as it sli"es open an" 'lose". +ere is =hat the 2liding=raEer looks like 'lose", using the supplie" han"le,
*:0
As one might e;pe't, you 'an open an" 'lose the "ra=er &rom Ca!a 'o"e as =ell as !ia user tou'h e!ents. +o=e!er, you ha!e t=o sets o& these metho"s, ones that take pla'e instantaneously (openPQ, closePQ, an" togglePQ) an" ones that use the animation ( animate"penPQ, animate+losePQ, animate&ogglePQ). ?ou 'an also lockPQ an" unlockPQ the "ra=erT =hile lo'ke", the "ra=er =ill not respon" to tou'h e!ents. ?ou 'an also register three types o& 'allba'ks i& you =ish, 1. A listener to be in!oke" =hen the "ra=er is opene"
2. A listener to be in!oke" =hen the "ra=er is 'lose" .. A listener to be in!oke" =hen the "ra=er is Ms'rolle"M (i.e., the user "rags or &lings the han"le) *or e;ample, the Laun'her7s 2liding=raEer toggles the i'on on the han"le &rom open to 'lose" to M"eleteM (i& you long-tap something on the "esktop). 0t a''omplishes this, in part, through 'allba'ks like these.
*:2
2liding=raEer
'an be !erti'al or horiKontal. 2ote, though, that it keeps its orientation "espite the s'reen orientation. 0n other =or"s, i& you rotate the An"roi" "e!i'e or emulator running =raEer=emo, the "ra=er al=ays opens &rom the bottom S it "oes not al=ays Msti'kM to the original si"e it opene" &rom. 5his means that i& you =ant the "ra=er to al=ays open &rom the same si"e, like the Laun'her "oes, you =ill nee" separate layouts &or portrait !ersus lan"s'ape, a topi' =e "is'uss in the 'hapter on resour'es.
a &eGtVieE that 'an either ha!e a 'he'kbo; or a ra"io button ne;t to it, use" =ith single-'hoi'e an" multi-'hoi'e lists
+hronometer, a stop=at'h-style 'ount"o=n timer DallerF,
a horiKontal s'rolling sele'tion =i"get, "esigne" &or thumbnail pre!ie=s o& images (e.g., 'amera photos, album 'o!ers)
*:7
#ultiAuto+omplete&eGtVieE,
like an Auto+omplete&eGtVieE, e;'ept that the user 'an make multiple 'hoi'es &rom the "rop-"o=n list, rather than Gust one
Yuick+ontact4adge,
gi!en the i"entity o& a 'onta't &rom the user7s 'onta'ts "atabase, "isplays a roster o& i'ons representing a'tions to be per&orme" on that 'onta't (pla'e a 'all, sen" a te;t message, sen" an email, et'.)
&oggle4utton, VieE2Eitcher
a t=o-state button =here the states are in"i'ate" by a MlightM an" prose (M>2M, M>**M) instea" o& a 'he'kmark (an" the Image2Eitcher an" &eGt2Eitcher sub'lasses), like a simpli&ie" VieE9lipper &or toggling bet=een t=o !ie=s
*:8
CHAPTER 16
>ther 8$0 toolkits let you use +5ML &or presenting in&ormation, &rom limite" +5ML ren"erers (e.g., Ca!aP%=ing, =;Wi"gets) to embe""ing 0nternet E;plorer into .2E5 appli'ations. An"roi" is mu'h the same, in that you 'an embe" the built-in Web bro=ser as a =i"get in your o=n a'ti!ities, &or "isplaying +5ML or &ull-&le"ge" bro=sing. 5he An"roi" bro=ser is base" on WebDit, the same engine that po=ers Apple7s %a&ari Web bro=ser. 5he An"roi" bro=ser is su&&i'iently 'omple; that it gets its o=n Ca!a pa'kage (android.Eebkit), though using the @ebVieE =i"get itsel& 'an be simple or po=er&ul, base" upon your reRuirements.
*::
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). 5he Ca!a 'o"e is eRually simple,
package com.commonsEare.android.broEser1J import android.app.ActivitFJ import android.os.4undleJ import android.Eebkit.@ebVieEJ public class 4roEser=emo1 eGtends ActivitF : @ebVieE broEserJ O"verride public void onCreateP4undle icicleQ : super.onCreatePicicleQJ setContentViewP?.laFout.mainQJ broEser6P@ebVieEQfindViewByIdP?.id.EebkitQJ ; ; broEser.load*rlP7http://commonsEare.com7QJ
5he only thing unusual =ith this e"ition o& on+reatePQ is that =e in!oke load3rlPQ on the @ebVieE =i"get, to tell it to loa" a Web page (in this 'ase, the home page o& some ran"om &irm). +o=e!er, =e also ha!e to make one 'hange to Android#anifest.Gml, reRuesting permission to a''ess the 0nternet,
LNGml version671.-7NM Lmanifest Gmlns:android67http://schemas.android.com/apk/res/android7 package67com.commonsEare.android.broEser17M Luses-permission android:name67android.permission.I%&$?%$&7/M Lapplication android:icon67OdraEable/cE7M LactivitF android:name67.4roEser=emo17 android:label674roEser=emo17M Lintent-filterM Laction android:name67android.intent.action.#AI%7/M LcategorF android:name67android.intent.categorF.)A3%+!$?7/M L/intent-filterM L/activitFM L/applicationM Lsupports-screens android:large2creens67true7 android:normal2creens67true7 android:small2creens67true7 android:anF=ensitF67true7/M L/manifestM
&<<
0& =e &ail to a"" this permission, the bro=ser =ill re&use to loa" pages. #ermissions =ill be 'o!ere" in greater "etail in a later 'hapter. 5he resulting a'ti!ity looks like a Web bro=ser, Gust =ith hi""en s'rollbars,
As =ith the regular An"roi" bro=ser, you 'an pan aroun" the page by "ragging it, =hile the "ire'tional pa" mo!es you aroun" all the &o'usable elements on the page. What is missing is all the e;tra stu&& that make up a Web bro=ser, su'h as a na!igational toolbar. 2o=, you may be tempte" to repla'e the $ L in that sour'e 'o"e =ith something else, su'h as 8oogle7s home page or something else that relies upon Ca!as'ript. 1y "e&ault Ca!as'ript is turne" o&& in @ebVieE =i"gets. 0& you =ant to enable Ca!as'ript, 'all get2ettingsPQ.setJava2cript$nabledPtrueQJ on the @ebVieE instan'e. 5his notion =ill be 'o!ere" in a bit more "etail later in this 'hapter.
&<*
!oading t >p
5here are t=o main =ays to get 'ontent into the @ebVieE. >ne, sho=n abo!e, is to pro!i"e the bro=ser =ith a $ L an" ha!e the bro=ser "isplay that page !ia load3rlPQ. 5he bro=ser =ill a''ess the 0nternet through =hate!er means are a!ailable to that spe'i&i' "e!i'e at the present time (Wi*i, 28, .8, WiMa;, =ell-traine" tiny 'arrier pigeons, et'.). 5he alternati!e is to use load=ataPQ. +ere, you supply the +5ML &or the bro=ser to !ie=. ?ou might use this to,
"isplay a manual that =as installe" as a &ile =ith your appli'ation pa'kage "isplay snippets o& +5ML you retrie!e" 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 +5ML, instea" o& using the An"roi" =i"get set
5here are t=o &la!ors o& load=ataPQ. 5he simpler one allo=s you to pro!i"e the 'ontent, the M0ME type, an" the en'o"ing, all as strings. 5ypi'ally, your M0ME type =ill be teGt/html an" your en'o"ing =ill be 3&9-, &or or"inary +5ML. *or e;ample, i& you repla'e the load3rlPQ in!o'ation in the pre!ious e;ample =ith the &ollo=ing,
broEser.loadDataP7LhtmlMLbodFM!ello8 EorldXL/bodFML/htmlM78 7teGt/html78 73&9-,7QJ
?ou get,
&<&
to go ba'k one step in the bro=ser history, an" canDo4ackPQ to "etermine i& there is any history to go ba'k to
go9orEardPQ to go &or=ar" one step in the bro=ser history, an" canDo9orEardPQ to "etermine i& there is any history to go &or=ar" to
&<-
go4ack"r9orEardPQ
to go ba'k=ar"s or &or=ar"s in the bro=ser history, =here negati!e numbers represent a 'ount o& steps to go ba'k=ar"s, an" positi!e numbers represent ho= many steps to go &or=ar"s 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 positi!ePnegati!e 'on!ention as go4ack"r9orEardPQ)
canDo4ack"r9orEardPQ
to 'lear the bro=ser resour'e 'a'he an" clear!istorFPQ to 'lear the bro=sing history
clear+achePQ
et'.
A 'ommon hook =ill be should"verride3rl)oadingPQ, =here your 'allba'k is passe" a $ L (plus the @ebVieE itsel&) an" you return true i& you =ill han"le the reRuest or false i& you =ant "e&ault han"ling (e.g., a'tually &et'h the Web page re&eren'e" by the $ L). 0n the 'ase o& a &ee" rea"er appli'ation, &or e;ample, you =ill probably not ha!e a &ull bro=ser =ith na!igation built into your rea"er, so i& the user 'li'ks a $ L, you probably =ant to use an
&<%
Intent
to ask An"roi" to loa" that page in a &ull bro=ser. 1ut, i& you ha!e inserte" a M&akeM $ L into the +5ML, representing a link to some a'ti!itypro!i"e" 'ontent, you 'an up"ate the @ebVieE yoursel&. *or e;ample, let7s amen" the &irst bro=ser e;ample to be a bro=ser-base" eRui!alent o& our original e;ample, an appli'ation that, upon a 'li'k, sho=s the 'urrent time. *rom @ebHit/4roEserC, here is the re!ise" Ca!a,
public class 4roEser=emoC eGtends ActivitF : @ebVieE broEserJ O"verride public void onCreateP4undle icicleQ : super.onCreatePicicleQJ setContentViewP?.laFout.mainQJ broEser6P@ebVieEQfindViewByIdP?.id.EebkitQJ broEser.set#e'ViewClientPneE Call'ackPQQJ loadTimePQJ ; void loadTimePQ : 2tring page67LhtmlMLbodFMLa href6T7clockT7M7 RneE DatePQ.toStringPQ R7L/aML/bodFML/htmlM7J broEser.loadDataPpage8 7teGt/html78 73&9-,7QJ ; private class +allback eGtends @ebVieE+lient : public boolean shouldO!erride*rlLoadingP@ebVieE vieE8 2tring urlQ : loadTimePQJ ; ; ; returnPtrueQJ
+ere, =e loa" a simple Web page into the bro=ser ( load&imePQ) that 'onsists o& the 'urrent time, ma"e into a hyperlink to the /clock $ L. We also atta'h an instan'e o& a @ebVieE+lient sub'lass, pro!i"ing our implementation o& should"verride3rl)oadingPQ. 0n this 'ase, no matter =hat the $ L, =e =ant to Gust reloa" the @ebVieE !ia load&imePQ.
&<0
%ele'ting the link an" 'li'king the @-pa" 'enter button =ill M'li'kM the link, 'ausing us to rebuil" the page =ith the ne= time.
Control the &ont siKing !ia set=efault9ont2iKePQ (to use a point siKe) or set&eGt2iKePQ (to use 'onstants in"i'ating relati!e siKes like )A?D$? an" 2#A))$2&) Control Ca!as'ript !ia setJava2cript$nabledPQ (to "isable it outright) an" setJava2cript+an"pen@indoEsAutomaticallFPQ (to merely stop it &rom opening pop-up =in"o=s) Control Web site ren"ering !ia set3serAgentPQ, so you 'an supply your o=n user agent string to make the Web ser!er think you are a "esktop bro=ser, another mobile "e!i'e (e.g., i#hone), or =hate!er
5he settings you 'hange are not persistent, so you shoul" store them some=here (su'h as !ia the An"roi" pre&eren'es engine) i& you are allo=ing your users to "etermine the settings, !ersus har"-=iring the settings in your appli'ation.
&<7
CHAPTER 18
Applying +enus
Like appli'ations &or the "esktop an" some mobile operating systems, An"roi" supports a'ti!ities =ith Mappli'ationM menus. Most An"roi" phones =ill ha!e a "e"i'ate" menu key &or popping up the menuT other "e!i'es =ill o&&er alternate means &or triggering the menu to appear, su'h as the on-s'reen button use" by the A C+>% A An"roi" tablet. Also, as =ith many 8$0 toolkits, you 'an 'reate M'onte;t menusM. >n a tra"itional 8$0, this might be triggere" by the right-mouse button. >n mobile "e!i'es, 'onte;t menus typi'ally appear =hen the user Mtaps-an"hol"sM o!er a parti'ular =i"get. *or e;ample, i& a &eGtVieE ha" a 'onte;t menu, an" the "e!i'e =as "esigne" &or &inger-base" tou'h input, you 'oul" push the &eGtVieE =ith your &inger, hol" it &or a se'on" or t=o, an" a popup menu =ill appear &or the user to 'hoose &rom.
"lavors of +enu
An"roi" 'onsi"ers the t=o types o& menu "es'ribe" abo!e as being the Moptions menuM an" M'onte;t menuM. 5he options menu is triggere" by pressing the har"=are MMenu button on the "e!i'e, =hile the 'onte;t menu is raise" by a tap-an"-hol" on the =i"get sporting the menu. 0n 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 MMenu button, the i'on mo"e =ill appear, sho=ing up to the &irst si; menu 'hoi'es as large, &inger&<:
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
Applying +enus
&rien"ly buttons in a gri" at the bottom o& the s'reen. 0& the menu has more than si; 'hoi'es, the si;th button =ill be'ome MMoreM S 'li'king that option =ill bring up the e;pan"e" mo"e, sho=ing the remaining 'hoi'es not !isible in the regular menu. 5he menu is s'rollable, so the user 'an get to any o& the menu 'hoi'es.
+enus of ,ptions
ather than buil"ing your a'ti!ity7s options menu "uring on+reatePQ, the =ay you =ire up the rest o& your $0, you instea" nee" to implement on+reate"ptions#enuPQ. 5his 'allba'k re'ei!es an instan'e o& #enu. 5he &irst thing you shoul" "o is 'hain up=ar" to the super'lass (super.on+reate"ptions#enuPmenuQ), so the An"roi" &rame=ork 'an a"" in any menu 'hoi'es it &eels are ne'essary. 5hen, you 'an go about a""ing your o=n options, "es'ribe" belo=. 0& you =ill nee" to a"Gust the menu "uring your a'ti!ity7s use (e.g., "isable a no=-in!ali" menu 'hoi'e), Gust hol" onto the #enu instan'e you re'ei!e in on+reate"ptions#enuPQ. >r, implement on(repare"ptions#enuPQ, =hi'h is 'alle" Gust be&ore "isplaying the menu ea'h time it is reRueste". 8i!en that you ha!e re'ei!e" a #enu obGe't !ia on+reate"ptions#enuPQ, you a"" menu 'hoi'es by 'alling addPQ. 5here are many &la!ors o& this metho", =hi'h reRuire 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 setDroup+heckablePQ (see belo=) A 'hoi'e i"enti&ier (also an int), &or use in i"enti&ying this 'hoi'e in the on"ptionsItem2electedPQ '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"-supplie" 'hoi'es alongsi"e your o=n S &or no=, Gust use %"%$ 5he te;t o& the menu 'hoi'e, as a %tring or a resour'e 0@
&*<
Applying +enus
5he addPQ &amily o& metho"s all return an instan'e o& #enuItem, =here you 'an a"Gust any o& the menu item settings you ha!e 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 S single-'hara'ter mnemoni's that 'hoose that menu 'hoi'e =hen the menu is !isible. An"roi" supports both an alphabeti' (or MR=ertyM) set o& short'uts an" a numeri' set o& short'uts. 5hese are set in"i!i"ually by 'alling setAlphabetic2hortcutPQ an" set%umeric2hortcutPQ respe'ti!ely. 5he menu is pla'e" into alphabeti' short'ut mo"e by 'alling setYEertF#odePQ on the menu =ith a true parameter. 5he 'hoi'e an" group i"enti&iers are keys use" to unlo'k a""itional menu &eatures, su'h as,
Calling #enuItemSset+heckablePQ =ith a 'hoi'e i"enti&ier, to 'ontrol i& the menu 'hoi'e has a t=o-state 'he'kbo; alongsi"e the title, =here the 'he'kbo; !alue gets toggle" =hen the user 'hooses that menu 'hoi'e Calling #enuSsetDroup+heckablePQ =ith a group i"enti&ier, to turn a set o& menu 'hoi'es into ones =ith a mutual-e;'lusion ra"io button bet=een them, so one out o& the group 'an be in the M'he'ke"M state at any time
*inally, you 'an 'reate &ly-out sub-menus by 'alling add2ub#enuPQ, supplying the same parameters as add#enuPQ. An"roi" =ill e!entually 'all on+reate(anel#enuPQ, passing it the 'hoi'e i"enti&ier o& your sub-menu, along =ith another #enu instan'e representing the sub-menu itsel&. As =ith on+reate"ptions#enuPQ, you shoul" 'hain up=ar" to the super'lass, then a"" menu 'hoi'es to the sub-menu. >ne limitation is that you 'annot in"e&initely nest sub-menus S a menu 'an ha!e a sub-menu, but a submenu 'annot ha!e a sub-sub-menu. 0& the user makes a menu 'hoi'e, your a'ti!ity =ill be noti&ie" !ia the on"ptionsItem2electedPQ 'allba'k that a menu 'hoi'e =as sele'te". ?ou are gi!en the #enuItem obGe't 'orrespon"ing to the sele'te" menu 'hoi'e. A typi'al pattern is to sEitchPQ on the menu 0@ (item.getItemIdPQ) an" take appropriate beha!ior. 2ote that on"ptionsItem2electedPQ is use" regar"less o& =hether the 'hosen menu item =as in the base menu or in a submenu.
&**
Applying +enus
+enus in Context
1y an" large, 'onte;t menus use the same guts as options menus. 5he 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'ti!ity ha!e 'onte;t menus. 5o "o this, 'all register9or+onteGt#enuPQ &rom your a'ti!ity, supplying the VieE that is the =i"get nee"ing a 'onte;t menu. 2e;t, you nee" to implement on+reate+onteGt#enuPQ, =hi'h, among other things, is passe" the VieE you supplie" in register9or+onteGt#enuPQ. ?ou 'an use that to "etermine =hi'h menu to buil", assuming your a'ti!ity has more than one. 5he on+reate+onteGt#enuPQ metho" gets the +onteGt#enu itsel&, the VieE the 'onte;t menu is asso'iate" =ith, an" a +onteGt#enu.+onteGt#enuInfo, =hi'h tells you =hi'h item in the list the user "i" the tap-an"-hol" o!er, in 'ase you =ant to 'ustomiKe the 'onte;t menu base" on that in&ormation. *or e;ample, you 'oul" toggle a 'he'kable menu 'hoi'e base" upon the 'urrent state o& the item. 0t is also important to note that on+reate+onteGt#enuPQ gets 'alle" &or ea'h time the 'onte;t menu is reRueste". $nlike the options menu (=hi'h is only built on'e per a'ti!ity), '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" +onteGt#enu obGe'tT Gust rely on getting the 'han'e to rebuil" the menu to suit your a'ti!ity7s nee"s on an on-"eman" basis base" on user a'tions. 5o &in" out =hen a 'onte;t menu 'hoi'e =as 'hosen, implement on+onteGtItem2electedPQ on the a'ti!ity. 2ote that you only get the #enuItem instan'e that =as 'hosen in this 'allba'k. As a result, i& your a'ti!ity has t=o or more 'onte;t menus, you may =ant to ensure they ha!e uniRue menu item i"enti&iers &or all their 'hoi'es, so you 'an tell them apart in this 'allba'k. Also, you 'an 'all get#enuInfoPQ on the #enuItem to get the +onteGt#enu.+onteGt#enuInfo you re'ei!e" in on+reate+onteGt#enuPQ.
&*&
Applying +enus
Taking a Peek
0n the sample proGe't #enus/#enus, you =ill &in" an amen"e" !ersion o& the sample ()ist) =ith asso'iate" menus. %in'e the menus "o not a&&e't the layout, the FML layout &ile nee"s not 'hange an" is not reprinte" here.
)istVieE
public class #enu=emo eGtends )istActivitF : private static final 2tringAB items6:7lorem78 7ipsum78 7dolor78 7sit78 7amet78 7consectetuer78 7adipiscing78 7elit78 7morbi78 7vel78 7ligula78 7vitae78 7arcu78 7aliUuet78 7mollis78 7etiam78 7vel78 7erat78 7placerat78 7ante78 7porttitor78 7sodales78 7pellentesUue78 7augue78 7purus7;J public static final int #$%3 A== 6 #enu.9I?2&R1J public static final int #$%3 ?$2$& 6 #enu.9I?2&R>J public static final int #$%3 +A( 6 #enu.9I?2&RCJ public static final int #$%3 ?$#"V$ 6 #enu.9I?2&R<J private ArraF)istL2tringM Eords6nullJ O"verride public void onCreateP4undle icicleQ : super.onCreatePicicleQJ init$dapterPQJ register"orContextMenuPgetListViewPQQJ ; &*-
Applying +enus
O"verride public boolean onCreateOptionsMenuP#enu menuQ : menu .addP#enu.%"%$8 #$%3 A==8 #enu.%"%$8 7Add7Q .setIconP?.draEable.ic menu addQJ menu .addP#enu.%"%$8 #$%3 ?$2$&8 #enu.%"%$8 7?eset7Q .setIconP?.draEable.ic menu refreshQJ returnPsuper.onCreateOptionsMenuPmenuQQJ ; O"verride public void onCreateContextMenuP+onteGt#enu menu8 VieE v8 +onteGt#enu.+onteGt#enuInfo menuInfoQ : menu.addP#enu.%"%$8 #$%3 +A(8 #enu.%"%$8 7+apitaliKe7QJ menu.addP#enu.%"%$8 #$%3 ?$#"V$8 #enu.%"%$8 7?emove7QJ ; O"verride public boolean onOptionsItemSelectedP#enuItem itemQ : sEitch Pitem.getItemIdPQQ : case #$%3 A==: addPQJ returnPtrueQJ case #$%3 ?$2$&: init$dapterPQJ returnPtrueQJ
; ;
returnPsuper.onOptionsItemSelectedPitemQQJ O"verride public boolean onContextItemSelectedP#enuItem itemQ : AdapterVieE.Adapter+onteGt#enuInfo info6 PAdapterVieE.Adapter+onteGt#enuInfoQitem.getMenuInfoPQJ ArraFAdapterL2tringM adapter6PArraFAdapterL2tringMQgetList$dapterPQJ sEitch Pitem.getItemIdPQQ : case #$%3 +A(: 2tring Eord6Eords.getPinfo.positionQJ Eord6Eord.to*pperCasePQJ adapter.remo!ePEords.getPinfo.positionQQJ adapter.insertPEord8 info.positionQJ returnPtrueQJ case #$%3 ?$#"V$: adapter.remo!ePEords.getPinfo.positionQQJ
&*%
Applying +enus
; ;
returnPtrueQJ
returnPsuper.onContextItemSelectedPitemQQJ private void init$dapterPQ : Eords6neE ArraF)istL2tringMPQJ for P2tring s : itemsQ : Eords.addPsQJ ; setList$dapterPneE ArraFAdapterL2tringMPthis8 android.?.laFout.simple list item 18 EordsQQJ
private void addPQ : final VieE addVieE6getLayoutInflaterPQ.inflateP?.laFout.add8 nullQJ neE Alert=ialog.BuilderPthisQ .setTitleP7Add a @ord7Q .setViewPaddVieEQ .set)ositi!eButtonP7"H78 neE =ialogInterface.OnClickListenerPQ : public void onClickP=ialogInterface dialog8 int Ehich4uttonQ : ArraFAdapterL2tringM adapter6PArraFAdapterL2tringMQgetList$dapterPQJ $dit&eGt title6P$dit&eGtQaddVieE.findViewByIdP?.id.titleQJ ; adapter.addPtitle.getTextPQ.toStringPQQJ
; ;
0n on+reatePQ, =e register our )istVieE =i"get as ha!ing a 'onte;t menu. We also "elegate loa"ing the a"apter to an initAdapterPQ pri!ate metho", one that 'opies the "ata out o& our stati' 2tring array an" pours it into an ArraF)ist, using the ArraF)ist &or the ArraFAdapter. 5he reason, =e =ant to be able to 'hange the 'ontents o& the list on the &ly, an" that is mu'h easier i& you use an ArraF)ist rather than an or"inary 2tring array. *or the options menu, =e o!erri"e on+reate"ptions#enuPQ an" a"" t=o menu items, one to a"" a ne= =or" to the list an" one to reset the =or"s to their initial state. 5hese menu items ha!e 0@s "e&ine" lo'ally as stati' "ata
&*0
Applying +enus
members (#$%3 A== an" #$%3 ?$2$&), an" they also sport i'ons 'opie" out o& the An"roi" open sour'e proGe't. 0& the user "isplays the menu, it looks like this,
"igure 801 The +enu/emo sample application and its options menu
We also o!erri"e on"ptionsItem2electedPQ, =hi'h =ill be 'alle" i& the user makes a 'hoi'e &rom the menu. 5he supplie" #enuItem has a getItemIdPQ metho" that shoul" map to either #$%3 A== or #$%3 ?$2$&. 0n the 'ase o& #$%3 A==, =e 'all a pri!ate addPQ metho" that "isplays an Alert=ialog =ith a 'ustom -ie= as its 'ontents, in&late" &rom res/laFout/add.Gml,
LNGml version671.-7 encoding67utf-,7NM L)inear)aFout Gmlns:android67http://schemas.android.com/apk/res/android7 android:orientation67horiKontal7 android:laFout Eidth67fill parent7 android:laFout height67Erap content7 M L&eGtVieE android:teGt67@ord:7 android:laFout Eidth67Erap content7 android:laFout height67Erap content7 /M L$dit&eGt
&*2
Applying +enus
android:id67ORid/title7 android:laFout Eidth67fill parent7 android:laFout height67Erap content7 android:laFout margin)eft67<dip7 /M L/)inear)aFoutM
0& the user 'li'ks the >D button, =e get our ArraFAdapter an" 'all addPQ on it, a""ing the entere" =or" to the en" o& the list. 0& the user 'hooses #$%3 ?$2$&, =e 'all initAdapterPQ again, setting up a ne= ArraFAdapter an" atta'hing the ne= one to our )istActivitF. *or the 'onte;t menu, =e o!erri"e on+reate+onteGt#enuPQ. >n'e again, =e "e&ine a pair o& menu items =ith lo'al 0@s, #$%3 +A( (to 'apitaliKe the longtappe"-upon =or") an" #$%3 ?$#"V$ (to remo!e the =or"). %in'e 'onte;t
&*7
Applying +enus
menus ha!e no i'ons, =e 'an skip that part. 5hat gi!es the user a 'onte;t menu i& they long tap on a =or",
We also o!erri"e on+onteGt#enu2electedPQ. %in'e this is a 'onte;t menu &or a our #enuItem has some e;tra in&ormation &or us S spe'i&i'ally, =hi'h item =as long-tappe"-upon in the list. 5o "o that, =e 'all get#enuInfoPQ on the #enuItem an" 'ast the result to be an AdapterVieE.Adapter+onteGt#enuInfo. 5hat obGe't, in turn, has a position "ata member, =hi'h is the in"e; into our array o& the =or" the user 'hose. *rom there, =e =ork =ith our ArraFAdapter to 'apitaliKe or remo!e the =or", as reRueste".
)istVieE,
Applying +enus
implementation o& menu-han"ling logi', an" it pro!i"es easier =ays to "e!elop menu-authoring tools.
?ou must start =ith a menu root element 0nsi"e a menu are item elements an" group elements, the latter representing a 'olle'tion o& menu items that 'an be operate" upon as a group %ubmenus are spe'i&ie" by a""ing a menu element as a 'hil" o& an item element, using this ne= menu element to "es'ribe the 'ontents o& the submenu 0& you =ant to "ete't =hen an item is 'hosen, or to re&eren'e an item or group &rom your Ca!a 'o"e, be sure to apply an android:id, Gust as you "o =ith VieE layout FML
Applying +enus
Title
5he title o& a menu item is pro!i"e" !ia the android:title attribute on an item element. 5his 'an be either a literal string or a re&eren'e to a string resour'e (e.g., Ostring/foo).
Icon
Menu items optionally ha!e i'ons. 5o pro!i"e an i'on S in the &orm o& a re&eren'e to a "ra=able resour'e (e.g., OdraEable/eject), use the android:icon attribute on the item element.
+rder
1y "e&ault, the or"er o& the items in the menu is "etermine" by the or"er they appear in the menu FML. 0& you =ant, you 'an 'hange that, by spe'i&ying the android:orderIn+ategorF attribute on item element. 5his is a --base" in"e; o& the or"er &or the items asso'iate" =ith the 'urrent 'ategory. 5here is an impli'it "e&ault 'ategoryT groups 'an pro!i"e an android:menu+ategorF attribute to spe'i&y a "i&&erent 'ategory to use &or items in that group. 8enerally, though, it is simplest Gust to put the items in the FML in the or"er you =ant them to appear.
En =led
0tems an" groups 'an be enable" or "isable", 'ontrolle" in the FML !ia the android:enabled attribute on the item or group element. 1y "e&ault, items an" groups are enable". @isable" items an" groups appear in the menu but 'annot be sele'te". ?ou 'an 'hange an item7s status at runtime !ia the set$nabledPQ metho" on #enuItem, or 'hange a group7s status !ia setDroup$nabledPQ on #enu.
&&<
Applying +enus
>isi=le
%imilarly, items an" groups 'an be !isible or in!isible, 'ontrolle" in the FML !ia the android:visible attribute on the item or group element. 1y "e&ault, items an" groups are !isible. 0n!isible items an" groups "o not appear in the menu at all. ?ou 'an 'hange an item7s status at runtime !ia the setVisiblePQ metho" on #enuItem, or 'hange a group7s status !ia setDroupVisiblePQ on #enu.
Shortcut
0tems 'an ha!e short'uts S single letters ( android:alphabetic2hortcut) or numbers (android:numeric2hortcut) that 'an be presse" to 'hoose the item =ithout ha!ing to use the tou'hs'reen, @-pa", or tra'kball to na!igate the &ull menu.
5he Ca!a 'o"e is nearly i"enti'al, 'hanging mostly in the implementation o& on+reate"ptions#enuPQ an" on+reate+onteGt#enuPQ,
&&*
Applying +enus
O"verride public boolean onCreateOptionsMenuP#enu menuQ : neE MenuInflaterPthisQ.inflateP?.menu.option8 menuQJ returnPsuper.onCreateOptionsMenuPmenuQQJ ; O"verride public void onCreateContextMenuP+onteGt#enu menu8 VieE v8 +onteGt#enu.+onteGt#enuInfo menuInfoQ : neE MenuInflaterPthisQ.inflateP?.menu.conteGt8 menuQJ ;
+ere, =e see ho= #enuInflater Mpours inM the menu items spe'i&ie" in the menu resour'e (e.g., ?.menu.option) into the supplie" #enu or +onteGt#enu obGe't. We also nee" to 'hange on"ptionsItem2electedPQ an" to use the android:id !alues spe'i&ie" in the FML,
on+onteGtItem2electedPQ
O"verride public boolean onOptionsItemSelectedP#enuItem itemQ : sEitch Pitem.getItemIdPQQ : case ?.id.add: addPQJ returnPtrueQJ case ?.id.reset: init$dapterPQJ returnPtrueQJ ; ; returnPsuper.onOptionsItemSelectedPitemQQJ
O"verride public boolean onContextItemSelectedP#enuItem itemQ : AdapterVieE.Adapter+onteGt#enuInfo info6 PAdapterVieE.Adapter+onteGt#enuInfoQitem.getMenuInfoPQJ ArraFAdapterL2tringM adapter6PArraFAdapterL2tringMQgetList$dapterPQJ sEitch Pitem.getItemIdPQQ : case ?.id.cap: 2tring Eord6Eords.getPinfo.positionQJ Eord6Eord.to*pperCasePQJ adapter.remo!ePEords.getPinfo.positionQQJ adapter.insertPEord8 info.positionQJ
&&&
Applying +enus
returnPsuper.onContextItemSelectedPitemQQJ
&&-
CHAPTER 19
%ometimes, your a'ti!ity (or other pie'e o& An"roi" 'o"e) =ill nee" to speak up. 2ot e!ery intera'tion =ith An"roi" users =ill be neat, ti"y, an" 'ontainable in a'ti!ities 'ompose" o& !ie=s. Errors =ill 'rop up. 1a'kgroun" tasks may take =ay longer than e;pe'te". %omething asyn'hronous may o''ur, su'h as an in'oming message. 0n 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=. Error messages in the &orm o& "ialog bo;es ha!e been aroun" &or a !ery long time. More subtle in"i'ators also e;ist, &rom task tray i'ons to boun'ing "o'k i'ons to a !ibrating 'ell phone. An"roi" has Ruite a &e= systems &or letting you alert your users outsi"e the boun"s o& an ActivitF-base" $0. >ne, noti&i'ations, is tie" hea!ily into intents an" ser!i'es an", as su'h, is 'o!ere" in a later 'hapter. 0n this 'hapter, you =ill see t=o means o& raising pop-up messages, toasts an" alerts.
Caising Toasts
A &oast is a transient message, meaning that it "isplays an" "isappears on its o=n =ithout user intera'tion. Moreo!er, it "oes not take &o'us a=ay
&&0
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
&rom the 'urrently-a'ti!e ActivitF, so i& the user is busy =riting the ne;t 8reat #rogramming 8ui"e, they =ill not ha!e keystrokes be MeatenM by the message. %in'e a &oast is transient, you ha!e no =ay o& kno=ing i& the user e!en 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"!isory messages, su'h as in"i'ating a long-running ba'kgroun" task is 'omplete", the battery has "roppe" to a lo=-but-not-too-lo= le!el, et'. Making a &oast is &airly easy. 5he &oast 'lass o&&ers a stati' make&eGtPQ that a''epts a 2tring (or string resour'e 0@) an" returns a &oast instan'e. 5he make&eGtPQ metho" also nee"s the ActivitF (or other +onteGt) plus a "uration. 5he "uration is e;presse" in the &orm o& the )$%D&! 2!"?& or )$%D&! )"%D 'onstants to in"i'ate, on a relati!e basis, ho= long the message shoul" remain !isible. 0& you =oul" pre&er your &oast be ma"e out o& some other VieE, rather than be a boring ol" pie'e o& te;t, simply 'reate a ne= &oast instan'e !ia the 'onstru'tor (=hi'h takes a +onteGt), then 'all setVieEPQ to supply it =ith the !ie= to use an" set=urationPQ to set the "uration. >n'e your &oast is 'on&igure", 'all its shoEPQ metho", an" the message =ill be "isplaye". We =ill see an e;ample o& this in a'tion later in this 'hapter.
Alert! Alert!
0& you =oul" pre&er something in the more 'lassi' "ialog bo; style, =hat you =ant is an Alert=ialog. As =ith any other mo"al "ialog bo;, an Alert=ialog pops up, grabs the &o'us, an" stays there until 'lose" by the user. ?ou might use this &or a 'riti'al error, a !ali"ation message that 'annot be e&&e'ti!ely "isplaye" in the base a'ti!ity $0, or something else =here you are sure that the user nee"s to see the message an" nee"s to see it no=. 5he simplest =ay to 'onstru't an Alert=ialog is to use the 4uilder 'lass. *ollo=ing in true buil"er style, 4uilder o&&ers a series o& metho"s to
&&2
'on&igure an Alert=ialog, ea'h metho" returning the 4uilder &or easy 'haining. At the en", you 'all shoEPQ on the buil"er to "isplay the "ialog bo;. Commonly-use" 'on&iguration metho"s on 4uilder in'lu"e,
i& you =ant the Mbo"yM o& the "ialog to be a simple te;tual message, &rom either a supplie" 2tring or a supplie" string resour'e 0@.
set#essagePQ
an" setIconPQ, to 'on&igure the te;t an"Por i'on to appear in the title bar o& the "ialog bo;.
set&itlePQ set(ositive4uttonPQ, set%eutral4uttonPQ, an" set%egative4uttonPQ, to 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'ti!ely), =hat their 'aptions shoul" be, an" =hat logi' shoul" be in!oke" =hen the button is 'li'ke" (besi"es "ismissing the "ialog).
0& you nee" to 'on&igure the Alert=ialog beyon" =hat the buil"er allo=s, instea" o& 'alling shoEPQ, 'all createPQ to get the partially-built Alert=ialog instan'e, 'on&igure it the rest o& the =ay, then 'all one o& the &la!ors o& shoEPQ on the Alert=ialog itsel&. >n'e shoEPQ is 'alle", the "ialog bo; =ill appear an" a=ait user input. 2ote that pressing any o& the buttons =ill 'lose the "ialog, e!en i& you ha!e registere" a listener &or the button in Ruestion. +en'e, i& all you nee" a button to "o is 'lose the "ialog, gi!e it a 'aption an" a null listener. 5here is no option, =ith Alert=ialog, to ha!e a button at the bottom in!oke a listener yet not 'lose the "ialog.
&&7
LNGml version671.-7 encoding67utf-,7NM L4utton Gmlns:android67http://schemas.android.com/apk/res/android7 android:id67ORid/alert7 android:teGt67?aise an alert7 android:laFout Eidth67fill parent7 android:laFout height67fill parent7 android:on+lick67shoEAlert7 /M
5he layout is unremarkable S Gust a really large 4utton to sho= the Alert=ialog. When you 'li'k the 4utton, =e use a buil"er (neE 4uilderPthisQ) to set the title (set&itleP7#essage=emo7Q), message (set#essageP7)etIs raise a toastX7Q), an" Mneutral buttonM (set%eutral4uttonP7!ere8 hereX78 neE "n+lick)istenerPQ ...) be&ore sho=ing the "ialog. When the button is 'li'ke", the "n+lick)istener 'allba'k triggers the &oast 'lass to make us a te;t-base" toast (make&eGtPthis8 7Lclink8 clinkM78 )$%D&! 2!"?&Q), =hi'h =e then shoEPQ. 5he result is a typi'al "ialog bo;,
&&8
"igure 881 The +essage/emo sample application@ after clicking the DCaise an alertD button
When you 'lose the "ialog !ia the button, it raises the toast,
&&:
"igure 8:1 The same application@ after clicking the D+ake a toastD button
&-<
CHAPTER 1:
While this may soun" like a broken re'or"...please remember that An"roi" "e!i'es, by an" large, are phones. As su'h, some a'ti!ities are more important than others S 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 AM than "oes your 'urrent "esktop or notebook. As a result, your a'ti!ity may &in" itsel& being kille" o&& be'ause other a'ti!ities are going on an" the system nee"s your a'ti!ity7s memory. 5hink o& it as the An"roi" eRui!alent o& the M'ir'le o& li&eM S your a'ti!ity "ies so others may li!e, an" so on. ?ou 'annot assume that your a'ti!ity =ill run until you think it is 'omplete, or e!en until the user thinks it is 'omplete. 5his is one e;ample S perhaps the most important e;ample S o& ho= an a'ti!ity7s li&e'y'le =ill a&&e't your o=n appli'ation logi'. 5his 'hapter 'o!ers the !arious states an" 'allba'ks that make up an a'ti!ity7s li&e'y'le an" ho= you 'an hook into them appropriately.
SchroedingerGs Activity
An a'ti!ity, generally speaking, is in one o& &our states at any point in time,
&-*
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
Active, the a'ti!ity =as starte" by the user, is running, an" is in the &oregroun". 5his is =hat you are use" to thinking o& in terms o& your a'ti!ity7s operation. Paused, the a'ti!ity =as starte" by the user, is running, an" is !isible, but a noti&i'ation or something is o!erlaying part o& the s'reen. @uring this time, the user 'an see your a'ti!ity 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'ti!ity =as starte" by the user, is running, but it is hi""en by other a'ti!ities that ha!e 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 2oti&i'ation. Dead, either the a'ti!ity =as ne!er starte" (e.g., Gust a&ter a phone reset) or the a'ti!ity =as terminate", perhaps "ue to la'k o& a!ailable memory.
&-&
1.
When the a'ti!ity is &irst starte" (e.g., sin'e a system restart), on+reatePQ =ill be in!oke" =ith a null parameter.
2. 0& the a'ti!ity ha" been running, then sometime later =as kille" o&&, on+reatePQ =ill be in!oke" =ith the 4undle &rom on2aveInstance2tatePQ as a parameter (see belo=). .. 0& the a'ti!ity ha" been running an" you ha!e set up your a'ti!ity to ha!e "i&&erent resour'es base" on "i&&erent "e!i'e states (e.g., lan"s'ape !ersus portrait), your a'ti!ity =ill be re-'reate" an" on+reatePQ =ill be 'alle". +ere is =here you initialiKe your user inter&a'e an" set up anything that nee"s to be "one on'e, regar"less o& ho= the a'ti!ity gets use". >n the other en" o& the li&e'y'le, on=estroFPQ may be 'alle" =hen the a'ti!ity is shutting "o=n, either be'ause the a'ti!ity 'alle" finishPQ (=hi'h M&inishesM the a'ti!ity) or be'ause An"roi" nee"s AM an" is 'losing the a'ti!ity prematurely. 2ote that on=estroFPQ may not get 'alle" i& the nee" &or AM is urgent (e.g., in'oming phone 'all) an" that the a'ti!ity =ill Gust get shut "o=n regar"less. +en'e, on=estroFPQ is mostly &or 'leanly releasing resour'es you obtaine" in on+reatePQ (i& any).
&--
&-%
5o make all this =ork, a'ti!ities nee" to be able to sa!e their appli'ationinstan'e state, an" to "o so Rui'kly an" 'heaply. %in'e a'ti!ities 'oul" get kille" o&& at any time, a'ti!ities may nee" to sa!e their state more &reRuently than one might e;pe't. 5hen, =hen the a'ti!ity restarts, the a'ti!ity shoul" get its &ormer state ba'k, so it 'an restore the a'ti!ity to the =ay it appeare" pre!iously. 5hink o& it as establishing a bookmark, su'h that =hen the user returns to that bookmark, you 'an return the appli'ation to the same state as =hen they le&t it. %a!ing instan'e state is han"le" by on2aveInstance2tatePQ. 5his supplies a 4undle, into =hi'h a'ti!ities 'an pour =hate!er "ata they nee" (e.g., the number sho=ing on the 'al'ulator7s "isplay). 5his metho" implementation nee"s to be spee"y, so "o not try to "o too mu'h &an'y S Gust put your "ata in the 4undle an" e;it the metho". 5hat instan'e state is pro!i"e" to you again in t=o pla'es, 1. 0n on+reatePQ
2. 0n on?estoreInstance2tatePQ 0t is your 'hoi'e =hen you =ish to re-apply the state "ata to your a'ti!ity S either 'allba'k is a reasonable option. 5he built-in implementation o& on2aveInstance2tatePQ =ill sa!e likely mutable state &rom a subset o& =i"gets. *or e;ample, it =ill sa!e the te;t in an $dit&eGt, but it =ill not sa!e =hether or not a 4utton is enable" or "isable". 5his =orks so long as the =i"gets are uniRuely i"enti&ie" !ia their android:id attributes. +en'e, i& you implement on2aveInstance2tatePQ, you 'an ele't to either 'hain up=ar" an" le!erage the inherite" implementation or not an" o!erri"e the inherite" implementation. %imilarly, some a'ti!ities may not nee" on2aveInstance2tatePQ to be implemente" at all, as the built-in one han"les e!erything that is nee"e".
&-0
CHAPTER 1;
3andling Cotation
%ome An"roi" han"sets o&&er a sli"e-out keyboar" that triggers rotating the s'reen &rom portrait to lan"s'ape. >ther han"sets use a''elerometers to "etermine =hen the s'reen rotates. As a result, it is reasonable to assume that s=it'hing &rom portrait to lan"s'ape an" ba'k again may be something your users =ill look to "o. An"roi" has a number o& =ays &or you to han"le s'reen rotation, so your appli'ation 'an properly han"le either orientation. All these &a'ilities "o is help you "ete't an" manage the rotation pro'ess S you are still reRuire" to make sure you ha!e layouts that look "e'ent on ea'h orientation.
A Philosophy of /estruction
1y "e&ault, =hen there is a 'hange in the phone 'on&iguration that might a&&e't resour'e sele'tion, An"roi" =ill "estroy an" re-'reate any running or pause" a'ti!ities the ne;t time they are to be !ie=e". While this 'oul" happen &or a !ariety o& "i&&erent 'on&iguration 'hanges (e.g., 'hange o& language sele'tion), it =ill most likely trip you up mostly &or rotations, sin'e a 'hange in orientation 'an 'ause you to loa" a "i&&erent set o& resour'es (e.g., layouts). 5he types o& 'on&iguration 'hanges that trigger this "estroy-an"-re'reate beha!ior in'lu"e,
3andling Cotation
E;ten"ing or hi"ing a physi'al keyboar", &or "e!i'es that ha!e su'h sli"ing keyboar"s #utting the "e!i'e in a 'ar or "esk "o'k, or remo!ing it &rom a "o'k Changing the lo'ale, an" thereby 'hanging the pre&erre" language
5he key here is that this is the "e&ault beha!ior. 0t is probably the beha!ior that is best &or most o& your a'ti!ities. ?ou "o ha!e some 'ontrol o!er the matter, though, an" 'an tailor ho= your a'ti!ities respon" to orientation 'hanges or similar 'on&iguration s=it'hes.
&-8
3andling Cotation
L4utton android:id67ORid/vieE7 android:laFout Eidth67fill parent7 android:laFout height67fill parent7 android:laFout Eeight6717 android:teGt67VieE7 android:enabled67false7 android:on+lick67vieE+ontact7 /M L/)inear)aFoutM
1asi'ally, it is a pair o& buttons, ea'h taking up hal& the s'reen. 0n portrait mo"e, the buttons are sta'ke"T in lan"s'ape mo"e, they are si"e-by-si"e. 0& you =ere to simply 'reate a proGe't, put in those t=o layouts, an" 'ompile it, the appli'ation =oul" appear to =ork Gust &ine S a rotation ( L+trlM-L91>M in the emulator) =ill 'ause the layout to 'hange. An" =hile buttons la'k state, i& you =ere using other =i"gets (e.g., $dit&eGt), you =oul" e!en &in" that An"roi" hangs onto some o& the =i"get state &or you (e.g., the te;t entere" in the $dit&eGt).
&-:
3andling Cotation
What An"roi" 'annot automati'ally help you =ith is anything hel" outsi"e the =i"gets.
Pic$in! nd >ie#in!
Cont ct
5his appli'ation lets you pi'k a 'onta't, then !ie= the 'onta't, !ia separate buttons, =ith the M-ie=M button only enable" =hen =e a'tually ha!e a 'onta't. Let us take a 'loser look at ho= this &eat is a''omplishe". When the user 'li'ks the #i'k button, =e 'all startActivitF9or?esultPQ. 5his is a !ariation on startActivitFPQ, "esigne" &or a'ti!ities that are set up to return some sort o& result S a user7s 'hoi'e o& &ile, or 'onta't, or =hate!er. elati!ely &e= a'ti!ities are set up this =ay, so you 'annot e;pe't to 'all startActivitF9or?esultPQ an" get ans=ers &rom any a'ti!ity you 'hoose. 0n this 'ase, =e =ant to pi'k a 'onta't. 5here is an A+&I"% (I+H Intent a'tion a!ailable in An"roi", "esigne" &or this sort o& s'enario. An A+&I"% (I+H Intent in"i'ates to An"roi" that =e =ant to pi'k...something. 5he MsomethingM is "etermine" by the 3ri =e put in the 0ntent. 0n our 'ase, it turns out that =e 'an use an A+&I"% (I+H Intent &or 'ertain system-"e&ine" 3ri !alues to let the user pi'k a 'onta't out o& the "e!i'e7s 'onta'ts. 0n parti'ular, on An"roi" 2.0 an" higher, =e 'an use android.provider.+ontacts+ontract.+ontacts.+"%&$%& 3?I &or this purpose,
public void pickContactPVieE vQ : Intent i6neE IntentPIntent.A+&I"% (I+H8 +ontacts.+"%&$%& 3?IQJ start$cti!ity"or%esultPi8 (I+H ?$Y3$2&QJ ;
*or
An"roi"
1./
an"
android.provider.+ontacts.+"%&$%& 3?I
separate
5he se'on" parameter to startActivitF9or?esultPQ is an i"enti&ying number, to help us "istinguish this 'all to startActivitF9or?esultPQ &rom any others =e might make.
&%<
3andling Cotation
Calling startActivitF9or?esultPQ =ith an A+&I"% (I+H Intent &or the +ontacts.+"%&$%& 3?I =ill bring up a 'onta't-pi'ker a'ti!ity, supplie" by An"roi". When the user taps a 'onta't, the pi'ker a'ti!ity en"s (e.g., !ia finishPQ), an" 'ontrol returns to our a'ti!ity. At that point, our a'ti!ity is 'alle" =ith onActivitF?esultPQ. An"roi" supplies us =ith three pie'es o& in&ormation, 1. 5he i"enti&ying number =e supplie" to startActivitF9or?esultPQ, so =e 'an mat'h this result to its original reRuest
2. A result status, either ?$23)& "H or ?$23)& +A%+$)$=, to in"i'ate i& the user ma"e a positi!e sele'tion or i& the user aban"one" the pi'ker (e.g., by 'li'king the 1ACD button) .. An 0ntent that represents the result "ata itsel&, &or a ?$23)& "H response 5he "etails o& =hat is in the Intent =ill nee" to be "o'umente" by the a'ti!ity that you 'alle". 0n the 'ase o& an A+&I"% (I+H Intent &or the +ontacts.+"%&$%& 3?I, the returne" Intent has its o=n 3ri (!ia get=ataPQ) that represents the 'hosen 'onta't. 0n the ?otation"ne e;ample, =e sti'k that in a "ata member o& the a'ti!ity an" enable the -ie= button,
O"verride protected void on$cti!ity%esultPint reUuest+ode8 int result+ode8 Intent dataQ : if PreUuest+ode66(I+H ?$Y3$2&Q : if Presult+ode66?$23)& "HQ : contact6data.getDataPQJ vieE4utton.set+na'ledPtrueQJ ; ; ;
0& the user 'li'ks the no=-enable" -ie= button, =e 'reate an A+&I"% VI$@ Intent on the 'onta't7s 3ri, an" 'all startActivitFPQ on that Intent,
public void !iewContactPVieE vQ : start$cti!ityPneE IntentPIntent.A+&I"% VI$@8 contactQQJ ;
&%*
3andling Cotation
5his =ill bring up an An"roi"-supplie" a'ti!ity to !ie= "etails o& that 'onta't.
S vin! 3our St te
8i!en that =e ha!e use" startActivitF9or?esultPQ to pi'k a 'onta't, no= =e nee" to hang onto that 'onta't =hen the s'reen orientation 'hanges. 0n the ?otation"ne e;ample, =e "o this !ia on2aveInstance2tatePQ,
package com.commonsEare.android.rotation.oneJ import import import import import import import import android.app.ActivitFJ android.content.IntentJ android.net.3riJ android.os.4undleJ android.provider.+ontacts+ontract.+ontactsJ android.vieE.VieEJ android.Eidget.4uttonJ android.util.)ogJ
public class ?otation"ne=emo eGtends ActivitF : static final int (I+H ?$Y3$2&61CC/J 4utton vieE4utton6nullJ 3ri contact6nullJ O"verride public void onCreateP4undle savedInstance2tateQ : super.onCreatePsavedInstance2tateQJ setContentViewP?.laFout.mainQJ vieE4utton6P4uttonQfindViewByIdP?.id.vieEQJ restoreMePsavedInstance2tateQJ ; vieE4utton.set+na'ledPcontactX6nullQJ
O"verride protected void on$cti!ity%esultPint reUuest+ode8 int result+ode8 Intent dataQ : if PreUuest+ode66(I+H ?$Y3$2&Q : if Presult+ode66?$23)& "HQ : contact6data.getDataPQJ vieE4utton.set+na'ledPtrueQJ ; ; ; public void pickContactPVieE vQ : Intent i6neE IntentPIntent.A+&I"% (I+H8 +ontacts.+"%&$%& 3?IQJ &%&
3andling Cotation
public void !iewContactPVieE vQ : start$cti!ityPneE IntentPIntent.A+&I"% VI$@8 contactQQJ ; O"verride protected void onSa!eInstanceStateP4undle out2tateQ : super.onSa!eInstanceStatePout2tateQJ if PcontactX6nullQ : out2tate.putStringP7contact78 contact.toStringPQQJ ; ; private void restoreMeP4undle stateQ : contact6nullJ if PstateX6nullQ : 2tring contact3ri6state.getStringP7contact7QJ if Pcontact3riX6nullQ : contact63ri.parsePcontact3riQJ ;
; ; ;
1y an" large, it looks like a normal a'ti!ity...be'ause it is. 0nitially, the Mmo"elM S a 3ri name" contact S is null. 0t is set as the result o& spa=ning the A+&I"% (I+H sub-a'ti!ity. 0ts string representation is sa!e" in on2aveInstance2tatePQ an" restore" in restore#ePQ ('alle" &rom on+reatePQ). 0& the 'onta't is not null, the M-ie=M button is enable" an" 'an be use" to !ie= the 'hosen 'onta't. -isually, it looks pretty mu'h as one =oul" e;pe't,
&%-
3andling Cotation
5he bene&it to this implementation is that it han"les a number o& system e!ents beyon" mere rotation, su'h as being 'lose" by An"roi" "ue to lo= memory. *or &un, 'omment out the restore#ePQ 'all in on+reatePQ an" try running the appli'ation. ?ou =ill see that the appli'ation M&orgetsM a 'onta't sele'te" in one orientation =hen you rotate the emulator or "e!i'e.
&%%
3andling Cotation
&%0
3andling Cotation
public class ?otation&Eo=emo eGtends ActivitF : static final int (I+H ?$Y3$2&61CC/J 4utton vieE4utton6nullJ 3ri contact6nullJ O"verride public void onCreateP4undle savedInstance2tateQ : super.onCreatePsavedInstance2tateQJ setContentViewP?.laFout.mainQJ vieE4utton6P4uttonQfindViewByIdP?.id.vieEQJ restoreMePQJ ; vieE4utton.set+na'ledPcontactX6nullQJ
O"verride protected void on$cti!ity%esultPint reUuest+ode8 int result+ode8 Intent dataQ : if PreUuest+ode66(I+H ?$Y3$2&Q : if Presult+ode66?$23)& "HQ : contact6data.getDataPQJ vieE4utton.set+na'ledPtrueQJ ; ; ; public void pickContactPVieE vQ : Intent i6neE IntentPIntent.A+&I"% (I+H8 +ontacts.+"%&$%& 3?IQJ ; start$cti!ity"or%esultPi8 (I+H ?$Y3$2&QJ
public void !iewContactPVieE vQ : start$cti!ityPneE IntentPIntent.A+&I"% VI$@8 contactQQJ ; O"verride public "bject on%etain&onConfigurationInstance PQ : returnPcontactQJ ; private void restoreMePQ : contact6nullJ if PgetLast&onConfigurationInstance PQX6nullQ : contact6P3riQgetLast&onConfigurationInstance PQJ
&%2
3andling Cotation
; ; ;
0n this 'ase, =e o!erri"e on?etain%on+onfigurationInstancePQ, returning the a'tual 3ri &or our 'onta't, rather than a string representation o& it. 0n turn, restore#ePQ 'alls get)ast%on+onfigurationInstancePQ, an" i& it is not null, =e hol" onto it as our 'onta't an" enable the M-ie=M button. 5he a"!antage here is that =e are passing aroun" the 3ri rather than a string representation. 0n this 'ase, that is not a big sa!ings. 1ut our state 'oul" be mu'h more 'ompli'ate", in'lu"ing threa"s an" so'kets an" other things =e 'annot pa'k into a 4undle.
/ . Cotation
E!en this, though, may still be too intrusi!e to your appli'ation. %uppose, &or e;ample, you are 'reating a real-time game, su'h as a &irst-person shooter. 5he Mhi''upM your users e;perien'e as your a'ti!ity is "estroye" an" re-'reate" might be enough to get them shot, =hi'h they may not appre'iate. While this =oul" be less o& an issue on the 5-Mobile 81, sin'e a rotation reRuires sli"ing open the keyboar" an" there&ore is unlikely to be "one mi"-game, other "e!i'es might rotate base" solely upon the "e!i'e7s position as "etermine" by a''elerometers. 5he thir" possibility &or han"ling rotations, there&ore, is to tell An"roi" that you =ill han"le them 'ompletely yoursel& an" that you "o not =ant assistan'e &rom the &rame=ork. 5o "o this, 1. #ut an android:config+hanges entry in your Android#anifest.Gml &ile, listing the 'on&iguration 'hanges you =ant to han"le yoursel& !ersus allo=ing An"roi" to han"le &or you
2. 0mplement on+onfiguration+hangedPQ in your ActivitF, =hi'h =ill be 'alle" =hen one o& the 'on&iguration 'hanges you liste" in android:config+hanges o''urs
&%7
3andling Cotation
2o=, &or any 'on&iguration 'hange you =ant, you 'an bypass the =hole a'ti!ity-"estru'tion pro'ess an" simply get a 'allba'k letting you kno= o& the 'hange. 5o see this in a'tion, turn to the ?otation/?otation&hree sample appli'ation. >n'e again, our layouts are the same, so the appli'ation looks the same as the pre'e"ing t=o samples. +o=e!er, the Ca!a 'o"e is signi&i'antly "i&&erent, be'ause =e are no longer 'on'erne" =ith sa!ing our state, but rather =ith up"ating our $0 to "eal =ith the layout. 1ut &irst, =e nee" to make a small 'hange to our mani&est,
LNGml version671.-7 encoding67utf-,7NM Lmanifest Gmlns:android67http://schemas.android.com/apk/res/android7 package67com.commonsEare.android.rotation.three7 android:version+ode6717 android:version%ame671.-.-7M Luses-sdk android:min2dkVersion67.7 android:target2dkVersion6707/M Lapplication android:label67Ostring/app name7 android:icon67OdraEable/cE7M LactivitF android:name67.?otation&hree=emo7 android:label67Ostring/app name7 android:config+hanges67keFboard!iddenW orientation7M Lintent-filterM Laction android:name67android.intent.action.#AI%7/M LcategorF android:name67android.intent.categorF.)A3%+!$?7/M L/intent-filterM L/activitFM L/applicationM Lsupports-screens android:large2creens67true7 android:normal2creens67true7 android:small2creens67true7 android:anF=ensitF67true7/M L/manifestM
+ere, =e state that =e =ill han"le keFboard!idden an" orientation 'on&iguration 'hanges oursel!es. 5his 'o!ers us &or any 'ause o& the MrotationM S =hether it is a sli"ing keyboar" or a physi'al rotation. 2ote that this is set on the a'ti!ity, not the appli'ation S i& you ha!e se!eral a'ti!ities, you =ill nee" to "e'i"e &or ea'h =hi'h o& the ta'ti's outline" in this 'hapter you =ish to use. 0n a""ition, =e nee" to a"" an android:id to our )inear)aFout 'ontainers, su'h as,
LNGml version671.-7 encoding67utf-,7NM L)inear)aFout Gmlns:android67http://schemas.android.com/apk/res/android7
&%8
3andling Cotation
android:id67ORid/container7 android:orientation67vertical7 android:laFout Eidth67fill parent7 android:laFout height67fill parent7 M L4utton android:id67ORid/pick7 android:laFout Eidth67fill parent7 android:laFout height67fill parent7 android:laFout Eeight6717 android:teGt67(ick7 android:enabled67true7 android:on+lick67pick+ontact7 /M L4utton android:id67ORid/vieE7 android:laFout Eidth67fill parent7 android:laFout height67fill parent7 android:laFout Eeight6717 android:teGt67VieE7 android:enabled67false7 android:on+lick67vieE+ontact7 /M L/)inear)aFoutM
public class ?otation&hree=emo eGtends ActivitF : static final int (I+H ?$Y3$2&61CC/J 4utton vieE4utton6nullJ 3ri contact6nullJ O"verride public void onCreateP4undle savedInstance2tateQ : super.onCreatePsavedInstance2tateQJ setContentViewP?.laFout.mainQJ vieE4utton6P4uttonQfindViewByIdP?.id.vieEQJ vieE4utton.set+na'ledPcontactX6nullQJ ; O"verride protected void on$cti!ity%esultPint reUuest+ode8 int result+ode8
&%:
3andling Cotation
Intent dataQ : if PreUuest+ode66(I+H ?$Y3$2&Q : if Presult+ode66?$23)& "HQ : contact6data.getDataPQJ vieE4utton.set+na'ledPtrueQJ ; ; ; public void pickContactPVieE vQ : Intent i6neE IntentPIntent.A+&I"% (I+H8 +ontacts.+"%&$%& 3?IQJ ; start$cti!ity"or%esultPi8 (I+H ?$Y3$2&QJ
public void !iewContactPVieE vQ : start$cti!ityPneE IntentPIntent.A+&I"% VI$@8 contactQQJ ; public void onConfigurationChangedP+onfiguration neE+onfigQ : super.onConfigurationChangedPneE+onfigQJ )inear)aFout container6P)inear)aFoutQfindViewByIdP?.id.containerQJ if PneE+onfig.orientation66+onfiguration."?I$%&A&I"% )A%=2+A($Q : container.setOrientationP)inear)aFout.!"?IV"%&A)QJ ; else : container.setOrientationP)inear)aFout.V$?&I+A)QJ ; ; ;
>ur on+onfiguration+hangedPQ nee"s to up"ate the $0 to re&le't the orientation 'hange. +ere, =e &in" our )inear)aFout an" tell it to 'hange its orientation to mat'h that o& the "e!i'e. 5he orientation &iel" on the +onfiguration obGe't =ill tell us ho= the "e!i'e is oriente".
3andling Cotation
5he
is &orgetting about resour'es. With the on+onfiguration+hangedPQ approa'h, you must take steps to ensure that ea'h an" e!ery resour'e that might possibly ha!e 'hange" as a result o& this 'on&iguration 'hange gets up"ate". 5hat in'lu"es strings, layouts, "ra=ables, menus, animations, pre&eren'es, "imensions, 'olors, an" all the others. 0& you are in'omplete, your app =ill ha!e a =hole series o& little (or not so little) bugs as a result. Allo=ing An"roi" to "estroy an" re'reate your a'ti!ity guarantees you =ill get the proper resour'es. All you nee" to "o is arrange to pass the proper "ata &rom the ol" to the ne= a'ti!ity. 5he on+onfiguration+hangedPQ approa'h is there =here the user =oul" be "ire'tly a&&e'te" by a "estroy-an"-'reate 'y'le. *or e;ample, imagine a !i"eo player appli'ation, playing a streaming !i"eo. @estroying an" re'reating the a'ti!ity =oul" ne'essarily 'ause us to ha!e to re'onne't to the stream, losing our bu&&ere" "ata. $sers =ill get &rustrate" i& an a''i"ental mo!ement 'auses the "e!i'e to 'hange orientation an" interrupt their !i"eo playba'k. 0n this 'ase, sin'e the user =ill per'ei!e problems =ith a "estroy-an"-'reate 'y'le, on+onfiguration+hangedPQ is an appropriate 'hoi'e.
primary
'on'ern
&0*
3andling Cotation
package67com.commonsEare.android.rotation.four7 android:version+ode6717 android:version%ame671.-.-7M Luses-sdk android:min2dkVersion67.7 android:target2dkVersion6707/M Lapplication android:label67Ostring/app name7 android:icon67OdraEable/cE7M LactivitF android:name67.?otation9our=emo7 android:screen"rientation67portrait7 android:label67Ostring/app name7M Lintent-filterM Laction android:name67android.intent.action.#AI%7/M LcategorF android:name67android.intent.categorF.)A3%+!$?7/M L/intent-filterM L/activitFM L/applicationM Lsupports-screens android:large2creens67true7 android:normal2creens67true7 android:small2creens67true7 android:anF=ensitF67true7/M L/manifestM
%in'e this is applie" on a per-a'ti!ity basis, you =ill nee" to "e'i"e =hi'h o& your a'ti!ities may nee" this turne" on. At this point, your a'ti!ity is lo'ke" into =hate!er orientation you spe'i&ie", regar"less o& =hat you "o. 5he &ollo=ing s'reen shots sho= the same a'ti!ity as in the pre!ious three se'tions, but using the abo!e mani&est an" =ith the emulator set &or both portrait an" lan"s'ape orientation. 2ote that the $0 "oes not mo!e a bit, but remains in portrait mo"e.
&0&
3andling Cotation
2ote that An"roi" =ill still "estroy an" re'reate your a'ti!ity, e!en i& you ha!e the orientation set to a spe'i&i' !alue as sho=n here. 0& you =ish to a!oi" that, you =ill also nee" to set android:config+hanges in the mani&est, as "es'ribe" earlier in this 'hapter. >r, you 'an still use on2aveInstance2tatePQ or on?etain%on+onfigurationInstancePQ to sa!e your a'ti!ity7s mutable state.
&0-
3andling Cotation
0& you ha!e an a'ti!ity that shoul" 'hange orientation base" on the a''elerometer, e!en i& the "e!i'e has a si"e-sli"er keyboar", Gust a"" android:screen"rientation 6 7sensor7 to your Android#anifest.Gml &ile (as seen in the ?otation/?otation9ive sample proGe't),
LNGml version671.-7 encoding67utf-,7NM Lmanifest Gmlns:android67http://schemas.android.com/apk/res/android7 package67com.commonsEare.android.rotation.five7 android:version+ode6717 android:version%ame671.-.-7M Luses-sdk android:min2dkVersion67.7 android:target2dkVersion6707/M Lapplication android:label67Ostring/app name7 android:icon67OdraEable/cE7M LactivitF android:name67.?otation9ive=emo7 android:screen"rientation67sensor7 android:label67Ostring/app name7M Lintent-filterM Laction android:name67android.intent.action.#AI%7/M LcategorF android:name67android.intent.categorF.)A3%+!$?7/M L/intent-filterM L/activitFM L/applicationM Lsupports-screens android:large2creens67true7 android:normal2creens67true7 android:small2creens67true7 android:anF=ensitF67true7/M L/manifestM
5he 6sensor9, in this 'ase, tells An"roi" you =ant the a''elerometers to 'ontrol the s'reen orientation, so the physi'al shi&t in the "e!i'e orientation 'ontrols the s'reen orientation. An"roi" 2.. a""s a number o& other possible !alues &or android:orientation, in'lu"ing,
an" reverse(ortrait, in"i'ating that you =ant the s'reen to be in lan"s'ape or portrait, respe'ti!ely, but Mupsi"e "o=nM 'ompare" to the normal lan"s'ape an" portrait orientations
reverse)andscape
an" sensor(ortrait, in"i'ating you =ant to be lo'ke" to lan"s'ape or portrait, respe'ti!ely, but the sensors 'an be use" to "etermine =hi'h si"e is MupM
sensor)andscape full2ensor,
=hi'h allo=s the sensors to put the s'reen in any o& the &our possible orientations (portrait, re!erse portrait, lan"s'ape, re!erse lan"s'ape), =hereas sensor only toggles bet=een portrait an" lan"s'ape
&0%
CHAPTER &<
$sers like snappy appli'ations. $sers "o not like appli'ations that &eel sluggish. 5he =ay to help your appli'ation &eel snappy is to use the stan"ar" threa"ing 'apabilities built into An"roi". 5his 'hapter =ill go through the issues in!ol!e" =ith threa" management in An"roi" an" =ill =alk you through some o& the options &or keeping the user inter&a'e 'risp an" responsi!e.
pro'essing messages, the s'reen =ill up"ate, user input =ill be han"le", an" so on. +o=e!er, the main appli'ation threa" is also use" &or nearly all 'allba'ks into your a'ti!ity. ?our on+reatePQ, on+lickPQ, on)istItem+lickPQ, an" similar metho"s are all 'alle" on the main appli'ation threa". While your 'o"e is e;e'uting in these metho"s, An"roi" is not pro'essing messages on the Rueue, an" so the s'reen "oes not up"ate, user input is not han"le", an" so on. 5his, o& 'ourse, is ba". %o ba", that i& you take more than a &e= se'on"s to "o =ork on the main appli'ation threa", An"roi" may "isplay the "rea"e" MAppli'ation 2ot espon"ingM "ialog (A2 &or short), an" your a'ti!ity may be kille" o&&. +en'e, you =ant to make sure that all o& your =ork on the main appli'ation threa" happens Rui'kly. 5his means that anything slo= shoul" be "one in a ba'kgroun" threa", so as not to tie up the main appli'ation threa". 5his in'lu"es things like,
0nternet a''ess, su'h as sen"ing "ata to a Web ser!i'e or "o=nloa"ing an image %igni&i'ant &ile operations, sin'e &lash storage 'an be remarkably slo= at times Any sort o& 'omple; 'al'ulations
*ortunately, An"roi" supports threa"s using the stan"ar" &hread 'lass &rom Ca!a, plus all o& the =rappers an" 'ontrol stru'tures you =oul" e;pe't, su'h as the java.util.concurrent 'lass pa'kage. +o=e!er, there is one big limitation, you 'annot mo"i&y the $0 &rom a ba'kgroun" threa". ?ou 'an only mo"i&y the $0 &rom the main appli'ation threa". +en'e, you nee" to get long-running =ork mo!e" into ba'kgroun" threa"s, but those threa"s nee" to "o something to arrange to up"ate the $0 using
&02
the main appli'ation threa". *ortunately, An"roi" pro!i"es a =i"e range o& tools to "o Gust that, an" these tools are the primary &o'us o& this 'hapter.
&07
%ess !es
5o sen" a #essage to a !andler, &irst in!oke obtain#essagePQ to get the obGe't out o& the pool. 5here are a &e= &la!ors o& obtain#essagePQ, allo=ing you to Gust 'reate empty #essage obGe'ts, or ones populate" =ith message i"enti&iers an" arguments. 5he more 'ompli'ate" your !andler pro'essing nee"s to be, the more likely it is you =ill nee" to put "ata into the #essage to help the !andler "istinguish "i&&erent e!ents.
#essage
5hen, you sen" the #essage to the !andler !ia its message Rueue, using one o& the send#essage...PQ &amily o& metho"s, su'h as,
send#essagePQ
puts the message on the Rueue imme"iately, an" moreo!er puts it at the &ront o& the message Rueue (!ersus the ba'k, as is the "e&ault), so your message takes priority o!er all others
send#essageAt9ront"fYueuePQ
puts the message on the Rueue at the state" time, e;presse" in the &orm o& millise'on"s base" on system uptime (2Fstem+lock.uptime#illisPQ)
send#essageAt&imePQ
&08
send#essage=elaFedPQ send$mptF#essagePQ,
puts the message on the Rueue a&ter a "elay, e;presse" in millise'on"s =hi'h sen"s an empty #essage obGe't to the Rueue, allo=ing you to skip the obtain#essagePQ step i& you =ere planning on lea!ing it empty any=ay
5o
these messages, your !andler nee"s to implement handle#essagePQ, =hi'h =ill be 'alle" =ith ea'h message that appears on the message Rueue. 5here, the han"ler 'an up"ate the $0 as nee"e". +o=e!er, it shoul" still "o that =ork Rui'kly, as other $0 =ork is suspen"e" until the !andler is "one. *or e;ample, let7s 'reate a (rogress4ar an" up"ate it !ia a !andler. +ere is the layout &rom the &hreads/!andler sample proGe't,
LNGml version671.-7 encoding67utf-,7NM L)inear)aFout Gmlns:android67http://schemas.android.com/apk/res/android7 android:orientation67vertical7 android:laFout Eidth67fill parent7 android:laFout height67fill parent7 M L(rogress4ar android:id67ORid/progress7 stFle67Nandroid:attr/progress4ar2tFle!oriKontal7 android:laFout Eidth67fill parent7 android:laFout height67Erap content7 /M L/)inear)aFoutM
pro'ess
5he (rogress4ar, in a""ition to setting the =i"th an" height as normal, also employs the stFle property. 5his parti'ular style in"i'ates this (rogress4ar shoul" be "ra=n as the tra"itional horiKontal bar sho=ing the amount o& =ork that has been 'omplete". An" here is the Ca!a,
package com.commonsEare.android.threadsJ import import import import import import android.app.ActivitFJ android.os.4undleJ android.os.!andlerJ android.os.#essageJ android.Eidget.(rogress4arJ java.util.concurrent.atomic.Atomic4ooleanJ
&0:
public class !andler=emo eGtends ActivitF : (rogress4ar barJ !andler handler6neE (andlerPQ : O"verride public void handleMessageP#essage msgQ : bar.increment)rogressByP.QJ ; ;J Atomic4oolean is?unning6neE $tomicBooleanPfalseQJ O"verride public void onCreateP4undle icicleQ : super.onCreatePicicleQJ setContentViewP?.laFout.mainQJ bar6P(rogress4arQfindViewByIdP?.id.progressQJ ; public void onStartPQ : super.onStartPQJ bar.set)rogressP-QJ &hread background6neE ThreadPneE %unna'lePQ : public void runPQ : trF : for Pint i6-JiL>- ZZ is?unning.getPQJiRRQ : &hread.sleepP1---QJ handler.sendMessagePhandler.o'tainMessagePQQJ ; ; catch P&hroEable tQ : // just end the background thread ; ; ;QJ is?unning.setPtrueQJ background.startPQJ
As part o& 'onstru'ting the ActivitF, =e 'reate an instan'e o& !andler, =ith our implementation o& handle#essagePQ. 1asi'ally, &or any message re'ei!e", =e up"ate the (rogress4ar by . points, then e;it the message han"ler.
&2<
We then take a"!antage o& on2tartPQ an" on2topPQ. 0n on2tartPQ, =e set up a ba'kgroun" threa". 0n a real system, this threa" =oul" "o something meaning&ul. +ere, =e Gust sleep one se'on", post a #essage to the !andler, an" repeat &or a total o& >- passes. 5his, 'ombine" =ith the A-point in'rease in the (rogress4ar position, =ill mar'h the bar 'lear a'ross the s'reen, as the "e&ault ma;imum !alue &or (rogress4ar is 1--. ?ou 'an a"Gust that ma;imum !ia set#aGPQ, su'h as setting the ma;imum to be the number o& "atabase ro=s you are pro'essing, an" up"ating on'e per ro=. 2ote that =e then leave on2tartPQ. 5his is 'ru'ial. 5he on2tartPQ metho" is in!oke" on the a'ti!ity $0 threa", so it 'an up"ate =i"gets an" su'h. +o=e!er, that means =e nee" to get out o& on2tartPQ, both to let the !andler get its =ork "one, an" also so An"roi" "oes not think our a'ti!ity is stu'k. 5he resulting a'ti!ity is simply a horiKontal progress bar,
2ote, though, that =hile (rogress4ar samples like this one sho= your 'o"e arranging to up"ate the progress on the $0 threa", &or this spe'i&i' =i"get, that is not ne'essary. At least as o& An"roi" 1.A, (rogress4ar is no= M$0
&2*
threa" sa&eM, in that you 'an up"ate it &rom any threa", an" it =ill han"le the "etails o& per&orming the a'tual $0 up"ate on the $0 threa".
Runn =les
0& you =oul" rather not &uss =ith #essage obGe'ts, you 'an also pass ?unnable obGe'ts to the !andler, =hi'h =ill run those ?unnable obGe'ts on the a'ti!ity $0 threa". !andler o&&ers a set o& post...PQ metho"s &or passing ?unnable obGe'ts in &or e!entual pro'essing. Cust as !andler supports postPQ an" post=elaFedPQ to a"" ?unnable obGe'ts to the e!ent Rueue, you 'an use those same metho"s on any VieE (i.e., any =i"get or 'ontainer). 5his slightly simpli&ies your 'o"e, in that you 'an then skip the !andler obGe't.
Asyncing "eeling
An"roi" 1.A intro"u'e" a ne= =ay o& thinking about ba'kgroun" operations, AsFnc&ask. 0n one (reasonably) 'on!enient 'lass, An"roi" =ill han"le all o& the 'hores o& "oing =ork on the $0 threa" !ersus on a ba'kgroun" threa". Moreo!er, An"roi" itsel& allo'ates an" remo!es that
&2&
ba'kgroun" threa". An", it maintains a small =ork Rueue, &urther a''entuating the M&ire an" &orgetM &eel to AsFnc&ask.
The Theory
5here is a saying, popular in marketing 'ir'les, MWhen a man buys a 1P<M "rill bit at a har"=are store, he "oes not =ant a 1P<M "rill bit S he =ants 1P<M holesM. +ar"=are stores 'annot sell holes, so they sell the ne;t-best thing, "e!i'es ("rills an" "rill bits) that make 'reating holes easy. %imilarly, An"roi" "e!elopers =ho ha!e struggle" =ith ba'kgroun" threa" management "o not stri'tly =ant ba'kgroun" threa"s S they =ant =ork to be "one o&& the $0 threa", so users are not stu'k =aiting an" a'ti!ities "o not get the "rea"e" Mappli'ation not respon"ingM (A2 ) error. An" =hile An"roi" 'annot magi'ally 'ause =ork to not 'onsume $0 threa" time, An"roi" 'an o&&er things that make su'h ba'kgroun" operations easier an" more transparent. AsFnc&ask is one su'h e;ample. 5o use AsFnc&ask, you must,
Create a sub'lass o& AsFnc&ask, 'ommonly as a pri!ate inner 'lass o& something that uses the task (e.g., an a'ti!ity) >!erri"e one or more AsFnc&ask metho"s to a''omplish the ba'kgroun" =ork, plus =hate!er =ork asso'iate" =ith the task that nee"s to be "one on the $0 threa" (e.g., up"ate progress) When nee"e", 'reate an instan'e o& the AsFnc&ask sub'lass an" 'all eGecutePQ to ha!e it begin "oing its =ork
Create your o=n ba'kgroun" threa" 5erminate that ba'kgroun" threa" at an appropriate time Call all sorts o& metho"s to arrange &or bits o& pro'essing to be "one on the $0 threa"
&2-
5he type o& in&ormation that is nee"e" to pro'ess the task (e.g., $ Ls to "o=nloa") 5he type o& in&ormation that is passe" =ithin the task to in"i'ate progress 5he type o& in&ormation that is passe" =hen the task is 'omplete" to the post-task 'o"e
What makes this all the more 'on&using is that the &irst t=o "ata types are a'tually use" as !arargs, meaning that an array o& these types is use" =ithin your AsFnc&ask sub'lass. 5his shoul" be'ome 'learer as =e =ork our =ay to=ar"s an e;ample.
&2%
5he doIn4ackgroundPQ metho" must return a !alue o& the thir" "ata type liste" abo!e S the result o& the ba'kgroun" =ork. ?ou may =ish to o!erri"e on(re$GecutePQ. 5his metho" is 'alle", &rom the $0 threa", be&ore the ba'kgroun" threa" e;e'utes doIn4ackgroundPQ. +ere, you might initialiKe a (rogress4ar or other=ise in"i'ate that ba'kgroun" =ork is 'ommen'ing. Also, you may =ish to o!erri"e on(ost$GecutePQ. 5his metho" is 'alle", &rom the $0 threa", a&ter doIn4ackgroundPQ 'ompletes. 0t re'ei!es, as a parameter, the !alue returne" by doIn4ackgroundPQ (e.g., su''ess or &ailure &lag). +ere, you might "ismiss the (rogress4ar an" make use o& the =ork "one in the ba'kgroun", su'h as up"ating the 'ontents o& a list. you may =ish to o!erri"e on(rogress3pdatePQ. 0& doIn4ackgroundPQ 'alls the task7s publish(rogressPQ metho", the obGe't(s) passe" to that metho" are pro!i"e" to on(rogress3pdatePQ, but in the $0 threa". 5hat =ay, on(rogress3pdatePQ 'an alert the user as to the progress that has been ma"e on the ba'kgroun" =ork, su'h as up"ating a (rogress4ar or 'ontinuing an animation. 5he on(rogress3pdatePQ metho" =ill re'ei!e a !arargs o& the se'on" "ata type &rom the abo!e list S the "ata publishe" by doIn4ackgroundPQ !ia publish(rogressPQ. 0n a""ition,
A S mple T s$
As mentione" earlier, implementing an AsFnc&ask is not Ruite as easy as implementing a ?unnable. +o=e!er, on'e you get past the generi's an" !arargs, it is not too ba". *or e;ample, belo= you =ill &in" an implementation o& a )istActivitF that uses an AsFnc&ask, &rom the 5hrea"sPAsyn'er sample proGe't,
package com.commonsEare.android.asFncJ import import import import android.app.)istActivitFJ android.os.AsFnc&askJ android.os.4undleJ android.os.2Fstem+lockJ
&20
import android.Eidget.ArraFAdapterJ import android.Eidget.&oastJ import java.util.ArraF)istJ public class AsFnc=emo eGtends )istActivitF : private static final 2tringAB items6:7lorem78 7ipsum78 7dolor78 7sit78 7amet78 7consectetuer78 7adipiscing78 7elit78 7morbi78 7vel78 7ligula78 7vitae78 7arcu78 7aliUuet78 7mollis78 7etiam78 7vel78 7erat78 7placerat78 7ante78 7porttitor78 7sodales78 7pellentesUue78 7augue78 7purus7;J O"verride public void onCreateP4undle savedInstance2tateQ : super.onCreatePsavedInstance2tateQJ setContentViewP?.laFout.mainQJ setList$dapterPneE ArraFAdapterL2tringMPthis8 android.?.laFout.simple list item 18 neE $rrayListPQQQJ neE $ddStringTaskPQ.executePQJ ; class Add2tring&ask eGtends AsFnc&askLVoid8 2tring8 VoidM : O"verride protected Void doInBackgroundPVoid... unusedQ : for P2tring item : itemsQ : pu'lish)rogressPitemQJ 2Fstem+lock.sleepP>--QJ ; ; returnPnullQJ
O"verride protected void on)rogress*pdateP2tring... itemQ : PPArraFAdapterQgetList$dapterPQQ.addPitemA-BQJ ; O"verride protected void on)ost+xecutePVoid unusedQ : &oast .makeTextPAsFnc=emo.this8 7=oneX78 &oast.)$%D&! 2!"?&Q .showPQJ ; ; ;
&22
5his is another !ariation on the lorem ipsum list o& =or"s, use" &reRuently throughout this book. 5his time, rather than simply han" the list o& =or"s to an ArraFAdapter, =e simulate ha!ing to =ork to 'reate these =or"s in the ba'kgroun" using Add2tring&ask, our AsFnc&ask implementation. Let7s e;amine this pie'e by pie'e,
+ere, =e use the generi's to set up the spe'i&i' types o& "ata =e are going to le!erage in Add2tring&ask. %pe'i&i'ally,
We "o not nee" any 'on&iguration in&ormation in this 'ase, so our &irst type is Void We =ant to pass ea'h string Mgenerate"M by our ba'kgroun" task to on(rogress3pdatePQ, so =e 'an a"" it to our list, so our se'on" type is
2tring
We "o not ha!e any results, stri'tly speaking (beyon" the up"ates), so our thir" type is Void
5he doIn4ackgroundPQ metho" is in!oke" in a ba'kgroun" threa". +en'e, =e 'an take as long as =e like. 0n a pro"u'tion appli'ation, =e =oul" be, perhaps, iterating o!er a list o& $ Ls an" "o=nloa"ing ea'h. +ere, =e iterate o!er our stati' list o& lorem ipsum =or"s, 'all publish(rogressPQ &or ea'h, an" then sleep 200 millise'on"s to simulate real =ork being "one.
&27
%in'e =e ele'te" to ha!e no 'on&iguration in&ormation, =e shoul" not nee" parameters to doIn4ackgroundPQ. +o=e!er, the 'ontra't =ith AsFnc&ask says =e nee" to a''ept a !arargs o& the &irst "ata type, =hi'h is =hy our metho" parameter is Void... unused. %in'e =e ele'te" to ha!e no results, =e shoul" not nee" to return anything. Again, though, the 'ontra't =ith AsFnc&ask says =e ha!e to return an obGe't o& the thir" "ata type. %in'e that "ata type is Void, our returne" obGe't is null.
5he on(rogress3pdatePQ metho" is 'alle" on the $0 threa", an" =e =ant to "o something to let the user kno= =e are progressing on loa"ing up these strings. 0n this 'ase, =e simply a"" the string to the ArraFAdapter, so it gets appen"e" to the en" o& the list. 5he on(rogress3pdatePQ metho" re'ei!es a 2tring... !arargs be'ause that is the se'on" "ata type in our 'lass "e'laration. %in'e =e are only passing one string per 'all to publish(rogressPQ, =e only nee" to e;amine the &irst entry in the !arargs array.
5he on(ost$GecutePQ metho" is 'alle" on the $0 threa", an" =e =ant to "o something to in"i'ate that the ba'kgroun" =ork is 'omplete. 0n a real
&28
system, there may be some (rogress4ar to "ismiss or some animation to stop. +ere, =e simply raise a &oast. %in'e =e ele'te" to ha!e no results, =e shoul" not nee" any parameters. 5he 'ontra't =ith AsFnc&ask says =e ha!e to a''ept a single !alue o& the thir" "ata type. %in'e that "ata type is Void, our metho" parameter is Void unused.
The Activity
neE $ddStringTaskPQ.executePQJ
5o use Add2tring&ask, =e simply 'reate an instan'e an" 'all eGecutePQ on it. 5hat starts the 'hain o& e!ents e!entually lea"ing to the ba'kgroun" threa" "oing its =ork. 0& Add2trings&ask reRuire" 'on&iguration parameters, =e =oul" ha!e not use" Void as our &irst "ata type, an" the 'onstru'tor =oul" a''ept Kero or more parameters o& the "e&ine" type. 5hose !alues =oul" e!entually be passe" to doIn4ackgroundPQ.
The Results
0& you buil", install, an" run this proGe't, you =ill see the list being populate" in Mreal timeM o!er a &e= se'on"s, &ollo=e" by a &oast in"i'ating 'ompletion.
&2:
"igure :01 The Async/emo@ part)ay through loading the list of )ords
&7<
LNGml version671.-7 encoding67utf-,7NM L)inear)aFout Gmlns:android67http://schemas.android.com/apk/res/android7 android:orientation67vertical7 android:laFout Eidth67fill parent7 android:laFout height67fill parent7 M L(rogress4ar android:id67ORid/progress7 stFle67Nandroid:attr/progress4ar2tFle!oriKontal7 android:laFout Eidth67fill parent7 android:laFout height67Erap content7 /M L&eGtVieE android:id67ORid/completed7 android:laFout Eidth67fill parent7 android:laFout height67Erap content7 android:teGt67@ork completedX7 android:visibilitF67invisible7 /M L/)inear)aFoutM
5he Mbusiness logi'M is &or an AsFnc&ask to "o some (&ake) =ork in the ba'kgroun", up"ating the (rogress4ar along the =ay, an" making the &eGtVieE !isible =hen it is &inishe". More importantly, it nee"s to "o this in su'h a =ay as to beha!e properly i& the s'reen is rotate",
We 'annot MloseM our AsFnc&ask, ha!ing it 'ontinue "oing =ork an" up"ating the =rong a'ti!ity We 'annot start a se'on" AsFnc&ask, thereby "oubling our =orkloa" We nee" to ha!e the $0 'orre'tly re&le't our =ork7s progress or 'ompletion
but in reality it =ill be hol"ing onto an impli'it re&eren'e to the ol" a'ti!ity, not one a&ter an orientation 'hange. %o, in ?otationAsFnc, the ?otationAEare&ask 'lass is a stati' inner 'lass. 5his means ?otationAEare&ask "oes not ha!e any impli'it re&eren'e to any ?otationAsFnc ActivitF (ol" or ne=),
import import import import import import import android.app.ActivitFJ android.os.AsFnc&askJ android.os.4undleJ android.os.2Fstem+lockJ android.util.)ogJ android.vieE.VieEJ android.Eidget.(rogress4arJ
public class ?otationAsFnc eGtends ActivitF : private (rogress4ar bar6nullJ private ?otationAEare&ask task6nullJ O"verride public void onCreateP4undle savedInstance2tateQ : super.onCreatePsavedInstance2tateQJ setContentViewP?.laFout.mainQJ bar6P(rogress4arQfindViewByIdP?.id.progressQJ task6P?otationAEare&askQgetLast&onConfigurationInstance PQJ if Ptask66nullQ : task6neE %otation$wareTaskPthisQJ task.executePQJ ; else : task.attachPthisQJ update)rogressPtask.get)rogressPQQJ if Ptask.get)rogressPQM61--Q : mark$sDonePQJ ; ; ;
&7&
bar.set)rogressPprogressQJ ; void mark$sDonePQ : findViewByIdP?.id.completedQ.setVisi'ilityPVieE.VI2I4)$QJ ; static class ?otationAEare&ask eGtends AsFnc&askLVoid8 Void8 VoidM : ?otationAsFnc activitF6nullJ int progress6-J %otation$wareTaskP?otationAsFnc activitFQ : attachPactivitFQJ ; O"verride protected Void doInBackgroundPVoid... unusedQ : for Pint i6-JiL>-JiRRQ : 2Fstem+lock.sleepP.--QJ pu'lish)rogressPQJ ; returnPnullQJ ; O"verride protected void on)rogress*pdatePVoid... unusedQ : if PactivitF66nullQ : )og.wP7?otationAsFnc78 7on(rogress3pdatePQ skipped [ no activitF7QJ ; else : progressR6.J activitF.update)rogressPprogressQJ ; ; O"verride protected void on)ost+xecutePVoid unusedQ : if PactivitF66nullQ : )og.wP7?otationAsFnc78 7on(ost$GecutePQ skipped [ no activitF7QJ ; else : activitF.mark$sDonePQJ ; ; void detachPQ : activitF6nullJ ; void attachP?otationAsFnc activitFQ : this.activitF6activitFJ ;
&7-
%in'e =e =ant ?otationAEare&ask to up"ate the 'urrent ?otationAsFnc ActivitF, =e supply that ActivitF =hen =e 'reate the task, !ia the 'onstru'tor. ?otationAEare&ask also has attachPQ an" detachPQ metho"s to 'hange =hat ActivitF the task kno=s about, as =e =ill see shortly.
5lo# o. Events
When ?otationAsFnc starts up &or the &irst time, it 'reates a ne= instan'e o& the ?otationAEare&ask 'lass an" e;e'utes it. At this point, the task has a re&eren'e to the ?otationAsFnc ActivitF an" 'an "o its (&ake) =ork, telling ?otationAsFnc to up"ate the progress along the =ay. 2o=, suppose that "uring the mi""le o& the doIn4ackgroundPQ pro'essing, the user rotates the s'reen. >ur ActivitF =ill be 'alle" =ith on?etain%on+onfigurationInstancePQ. +ere, =e =ant to "o t=o things, 1. %in'e this ActivitF instan'e is being "estroye", =e nee" to make sure the task no longer hol"s onto a re&eren'e to it. +en'e, =e 'all detachPQ, 'ausing the task to set its ?otationAsFnc "ata member (activitF) to null.
2. We return the ?otationAEare&ask obGe't, so that our ne= ?otationAsFnc instan'e 'an get a''ess to it E!entually, the ne= ?otationAsFnc instan'e =ill be 'reate". 0n on+reatePQ, =e try to get a''ess to any 'urrent ?otationAEare&ask instan'e !ia get)ast%on+onfigurationInstancePQ. 0& that =as null, then =e kno= that this is a ne=ly-'reate" a'ti!ity, an" so =e 'reate a ne= task. 0&, ho=e!er, get)ast%on+onfigurationInstancePQ returne" the task obGe't &rom the ol" ?otationAsFnc instan'e, =e hol" onto it an" up"ate our $0 to re&le't the 'urrent progress that has been ma"e. We also attachPQ the ne=
&7%
?otationAsFnc
to the ?otationAEare&ask, so as &urther progress is ma"e, the task 'an noti&y the proper a'ti!ity. 5he net result is that our (rogress4ar smoothly progresses &rom 0 to 100, e!en =hile rotations are going on.
&70
5he possibility that users =ill intera't =ith your a'ti!ity7s $0 =hile the ba'kgroun" threa" is 'hugging along. 0& the =ork that the ba'kgroun" threa" is "oing is altere" or in!ali"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". 5he possibility that the a'ti!ity =ill be kille" o&& =hile ba'kgroun" =ork is going on. *or e;ample, a&ter starting your a'ti!ity, the user might ha!e 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'ti!ity out o& memory. 5he ne;t 'hapter =ill 'o!er the !arious e!ents An"roi" =ill take your a'ti!ity throughT hook the proper ones an" be sure to shut "o=n your ba'kgroun" threa" 'leanly =hen you ha!e the 'han'e. 5he possibility that your user =ill get irritate" i& you 'he= up a lot o& C#$ time an" battery li&e =ithout gi!ing any payba'k. 5a'ti'ally, this means using (rogress4ar 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 S ba'kgroun" threa"s are no pana'ea &or sluggish or pointless 'o"e. 5he possibility that you =ill en'ounter an error "uring ba'kgroun" pro'essing. *or e;ample, i& you are gathering in&ormation o&& the 0nternet, the "e!i'e might lose 'onne'ti!ity. Alerting the user o& the problem !ia a 2oti&i'ation an" shutting "o=n the ba'kgroun" threa" may be your best option.
&72
CHAPTER &1
$p to no=, the &o'us o& this book has been on a'ti!ities opene" "ire'tly by the user &rom the "e!i'e7s laun'her. 5his, o& 'ourse, is the most ob!ious 'ase &or getting your a'ti!ity up an" !isible to the user. An", in many 'ases it is the primary =ay the user =ill start using your appli'ation. +o=e!er, remember that the An"roi" system is base" upon lots o& loosely'ouple" 'omponents. What you might a''omplish in a "esktop 8$0 !ia "ialog bo;es, 'hil" =in"o=s, an" the like are mostly suppose" to be in"epen"ent a'ti!ities. While one a'ti!ity =ill be Mspe'ialM, in that it sho=s up in the laun'her, the other a'ti!ities all nee" to be rea'he"...someho=. 5he Mho=M is !ia intents. An intent is basi'ally a message that you pass to An"roi" saying, M?o: 0 =ant to "o...er...something: ?eah:M +o= spe'i&i' the MsomethingM is "epen"s on the situation S sometimes you kno= e;a'tly =hat you =ant to "o (e.g., open up one o& your other a'ti!ities), an" sometimes you "o not. 0n the abstra't, An"roi" is all about intents an" re'ei!ers o& those intents. %o, no= that =e are =ell-!erse" in 'reating a'ti!ities, let7s "i!e into intents, so =e 'an 'reate more 'omple; appli'ations =hile simultaneously being Mgoo" An"roi" 'itiKensM.
&77
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
Pieces o. Intents
5he t=o most important pie'es o& an intent are the a'tion an" =hat An"roi" re&ers to as the M"ataM. 5hese are almost e;a'tly analogous to +55# !erbs an" $ Ls S the a'tion is the !erb, an" the M"ataM is a 3ri, su'h as content://contacts/people/1 representing a 'onta't in the 'onta'ts "atabase. A'tions are 'onstants, su'h as A+&I"% VI$@ (to bring up a !ie=er &or the resour'e), A+&I"% $=I& (to e"it the resour'e), or A+&I"% (I+H (to 'hoose an a!ailable item gi!en a 3ri representing a 'olle'tion, su'h as content://contacts/people). 0& you =ere to 'reate an intent 'ombining A+&I"% VI$@ =ith a 'ontent $ri o& an" pass that intent to An"roi", An"roi" =oul" kno= to &in" an" open an a'ti!ity 'apable o& !ie=ing that resour'e.
content://contacts/people/1,
5here are other 'riteria you 'an pla'e insi"e an intent (represente" as an 0ntent obGe't), besi"es the a'tion an" M"ataM 3ri, su'h as,
&78
A 'ategory. ?our MmainM a'ti!ity =ill be in the )A3%+!$? 'ategory, in"i'ating it shoul" sho= up on the laun'her menu. >ther a'ti!ities =ill probably be in the =$9A3)& or A)&$?%A&IV$ 'ategories. A M0ME type, in"i'ating the type o& resour'e you =ant to operate on, i& you "o not kno= a 'olle'tion 3ri. A 'omponent, =hi'h is to say, the 'lass o& the a'ti!ity that is suppose" to re'ei!e this intent. $sing 'omponents this =ay ob!iates the nee" &or the other properties o& the intent. +o=e!er, it "oes make the intent more &ragile, as it assumes spe'i&i' implementations. ME;trasM, =hi'h is a 4undle o& other in&ormation you =ant to pass along to the re'ei!er =ith the intent, that the re'ei!er might =ant to take a"!antage o&. What pie'es o& in&ormation a gi!en re'ei!er 'an use is up to the re'ei!er an" (hope&ully) is =ell-"o'umente".
?ou =ill &in" rosters o& the stan"ar" a'tions an" 'ategories in the An"roi" %@D "o'umentation &or the Intent 'lass.
Intent Routin!
As note" abo!e, 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 S it =ill laun'h the name" a'ti!ity. 5his might be >D i& the target intent is in your appli'ation. 0t "e&initely is not re'ommen"e" &or sen"ing intents to other appli'ations. Component names, by an" large, are 'onsi"ere" pri!ate to the appli'ation an" are subGe't to 'hange. Content 3ri templates an" M0ME types are the pre&erre" =ays o& i"enti&ying ser!i'es you =ish thir"-party 'o"e to supply. 0& you "o not spe'i&y the target 'omponent, then An"roi" has to &igure out =hat a'ti!ities (or other re'ei!ers) are eligible to re'ei!e the intent. 2ote the use o& the plural Ma'ti!itiesM, as a broa"ly-=ritten intent might =ell resol!e to se!eral a'ti!ities. 5hat is the...ummm...intent (par"on the pun), as you =ill see later in this 'hapter. 5his routing approa'h is re&erre" to as impli'it routing.
&7:
1asi'ally, there are three rules, all o& =hi'h must be true &or a gi!en a'ti!ity to be eligible &or a gi!en intent, 1. 5he a'ti!ity must support the spe'i&ie" a'tion
2. 5he a'ti!ity must support the state" M0ME type (i& supplie") .. 5he a'ti!ity must support all o& the 'ategories name" in the intent 5he upshot is that you =ant to make your intents spe'i&i' enough to &in" the right re'ei!er(s), an" no more spe'i&i' than that. 5his =ill be'ome 'learer as =e =ork through some e;amples later in this 'hapter.
2ote the intent-filter element un"er the a'ti!ity element. +ere, =e "e'lare that this a'ti!ity,
&8<
0s the main a'ti!ity &or this appli'ation 0t is in the )A3%+!$? 'ategory, meaning it gets an i'on in the An"roi" main menu
1e'ause this a'ti!ity 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. ?ou are =el'ome to ha!e more than one a'tion or more than one 'ategory in your intent &ilters. 5hat in"i'ates that the asso'iate" 'omponent (e.g., a'ti!ity) han"les multiple "i&&erent sorts o& intents. More than likely, you =ill also =ant to ha!e your se'on"ary (non- #AI%) a'ti!ities spe'i&y the M0ME type o& "ata they =ork on. 5hen, i& an intent is targete" &or that M0ME type S either "ire'tly, or in"ire'tly by the 3ri re&eren'ing something o& that type S An"roi" =ill kno= that the 'omponent han"les su'h "ata. *or e;ample, you 'oul" ha!e an a'ti!ity "e'lare" like this,
LactivitF android:name67.&ourVieEActivitF7M Lintent-filterM Laction android:name67android.intent.action.VI$@7 /M LcategorF android:name67android.intent.categorF.=$9A3)&7 /M Ldata android:mime&Fpe67vnd.android.cursor.item/vnd.commonsEare.tour7 /M L/intent-filterM L/activitFM
5his a'ti!ity =ill get laun'he" by an intent reRuesting to !ie= a 3ri representing a vnd.android.cursor.item/vnd.commonsEare.tour pie'e o& 'ontent. 5hat Intent 'oul" 'ome &rom another a'ti!ity in the same appli'ation (e.g., the MA02 a'ti!ity &or this appli'ation) or &rom another a'ti!ity in another An"roi" appli'ation that happens to kno= a 3ri that this a'ti!ity han"les.
&8*
?arro) Ceceivers
0n the e;amples sho=n abo!e, the intent &ilters =ere set up on a'ti!ities. %ometimes, tying intents to a'ti!ities is not e;a'tly =hat =e =ant,
%ome system e!ents might 'ause us to =ant to trigger something in a ser!i'e rather than an a'ti!ity %ome e!ents might nee" to laun'h "i&&erent a'ti!ities 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 F an" the "atabase has a ?, then laun'h a'ti!ity MT i& the "atabase "oes not ha!e a ?, then laun'h a'ti!ity 2)
*or these 'ases, An"roi" o&&ers the re'ei!er, "e&ine" as a 'lass implementing the 4roadcast?eceiver inter&a'e. 1roa"'ast re'ei!ers are "isposable obGe'ts "esigne" to re'ei!e intents S spe'i&i'ally, broa"'ast intents S an" take a'tion. 5he 4roadcast?eceiver inter&a'e has only one metho", on?eceivePQ. e'ei!ers implement that metho", =here they "o =hate!er it is they =ish to "o upon an in'oming intent. 5o "e'lare an re'ei!er, a"" a receiver element to your Android#anifest.Gml &ile,
Lreceiver android:name67.#FIntent?eceiver+lass%ame7 /M
An re'ei!er is only ali!e &or as long as it takes to pro'ess on?eceivePQ S as soon as that metho" returns, the re'ei!er instan'e is subGe't to garbage 'olle'tion an" =ill not be reuse". 5his means re'ei!ers are some=hat limite" in =hat they 'an "o, mostly to a!oi" anything that in!ol!es any sort o& 'allba'k. *or e;ample, they 'annot bin" to a ser!i'e, an" they 'annot open a "ialog bo;. 5he e;'eption is i& the 4roadcast?eceiver is implemente" on some longerli!e" 'omponent, su'h as an a'ti!ity or ser!i'e S in that 'ase, the re'ei!er li!es as long as its MhostM "oes (e.g., until the a'ti!ity is &roKen). +o=e!er, in this 'ase, you 'annot "e'lare the re'ei!er !ia Android#anifest.Gml. 0nstea", you nee" to 'all register?eceiverPQ on your ActivitF7s on?esumePQ 'allba'k
&8&
to "e'lare interest in an intent, then 'all unregister?eceiverPQ &rom your ActivitF7s on(ausePQ =hen you no longer nee" those intents.
?our re'ei!er "oes not 'are i& it misses messages be'ause it =as not a'ti!e, or ?ou pro!i"e some means o& getting the re'ei!er M'aught upM on messages it misse" =hile it =as ina'ti!e, or ?our re'ei!er is registere" in the mani&est
&8-
CHAPTER &&
5he theory behin" the An"roi" $0 ar'hite'ture is that "e!elopers shoul" "e'ompose their appli'ation into "istin't a'ti!ities. *or e;ample, a 'alen"ar appli'ation 'oul" ha!e a'ti!ities &or !ie=ing the 'alen"ar, !ie=ing a single e!ent, e"iting an e!ent (in'lu"ing a""ing a ne= one), an" so &orth. 5his, o& 'ourse, implies that one o& your a'ti!ities has the means to start up another a'ti!ity. *or e;ample, i& somebo"y 'li'ks on an e!ent &rom the !ie=-'alen"ar a'ti!ity, you might =ant to sho= the !ie=-e!ent a'ti!ity &or that e!ent. 5his means that, someho=, you nee" to be able to 'ause the !ie=-e!ent a'ti!ity to laun'h an" sho= a spe'i&i' e!ent (the one the user 'li'ke" upon). 5his 'an be &urther broken "o=n into t=o s'enarios, 1. ?ou kno= =hat a'ti!ity you =ant to laun'h, probably be'ause it is another a'ti!ity in your o=n appli'ation
2. ?ou ha!e a 'ontent 3ri 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 5his 'hapter 'o!ers the &irst s'enarioT the 'ompanion a"!an'e" An"roi" book han"les the se'on".
&80
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 pre!ious 'hapter, intents en'apsulate a reRuest, ma"e to An"roi", &or some a'ti!ity or other re'ei!er to "o something.
&82
0& the a'ti!ity 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'ti!ity, you 'oul" 'reate an intent like this,
neE IntentPthis8 !elpActivitF.classQJ
5his =oul" stipulate that you =ante" to laun'h the !elpActivitF. 5his a'ti!ity =oul" nee" to be name" in your Android#anifest.Gml &ile, though not ne'essarily =ith any intent &ilter, sin'e you are trying to reRuest it "ire'tly. >r, you 'oul" put together an intent &or some 3ri, reRuesting a parti'ular a'tion,
3ri uri63ri.parseP7geo:7Rlat.toStringPQR787Rlon.toStringPQQJ Intent i6neE IntentPIntent.A+&I"% VI$@8 uriQJ
+ere, gi!en that =e ha!e the latitu"e an" longitu"e o& some position ( lat an" lon, respe'ti!ely) o& type =ouble, =e 'onstru't a geo s'heme 3ri an" 'reate an intent reRuesting to !ie= this 3ri (A+&I"% VI$@).
% $e the C ll
>n'e you ha!e your intent, you nee" to pass it to An"roi" an" get the 'hil" a'ti!ity to laun'h. ?ou ha!e t=o 'hoi'es, 1. 5he simplest option is to 'all startActivitFPQ =ith the Intent S this =ill 'ause An"roi" to &in" the best-mat'h a'ti!ity an" pass the intent to it &or han"ling. ?our a'ti!ity =ill not be in&orme" =hen the 6'hil"9 a'ti!ity is 'omplete.
2. ?ou 'an 'all startActivitF9or?esultPQ, passing it the Intent an" a number (uniRue to the 'alling a'ti!ity). An"roi" =ill &in" the bestmat'h a'ti!ity an" pass the intent o!er to it. +o=e!er, your a'ti!ity =ill be noti&ie" =hen the 'hil" a'ti!ity is 'omplete !ia the onActivitF?esultPQ 'allba'k (see belo=).
&87
With startActivitF9or?esultPQ, as note", you 'an implement the onActivitF?esultPQ 'allba'k to be noti&ie" =hen the 'hil" a'ti!ity has 'omplete" its =ork. 5he 'allba'k re'ei!es the uniRue number supplie" to startActivitF9or?esultPQ, so you 'an "etermine =hi'h 'hil" a'ti!ity is the one that has 'omplete". ?ou also get,
A result 'o"e, &rom the 'hil" a'ti!ity 'alling set?esultPQ. 5ypi'ally this is ?$23)& "H or ?$23)& +A%+$)$=, though you 'an 'reate your o=n return 'o"es (pi'k a number starting =ith ?$23)& 9I?2& 32$?) An optional 2tring 'ontaining some result "ata, possibly a $ L to some internal or e;ternal resour'e S &or e;ample, a A+&I"% (I+H intent typi'ally returns the sele'te" bit o& 'ontent !ia this "ata string An optional 4undle 'ontaining a""itional in&ormation beyon" the result 'o"e an" "ata string
5o "emonstrate laun'hing a peer a'ti!ity, take a peek at the Activities/)aunch sample appli'ation. 5he FML layout is &airly straight&or=ar", t=o &iel"s &or the latitu"e an" longitu"e, plus a button,
LNGml version671.-7 encoding67utf-,7NM L)inear)aFout Gmlns:android67http://schemas.android.com/apk/res/android7 android:orientation67vertical7 android:laFout Eidth67fill parent7 android:laFout height67fill parent7 M L&able)aFout android:laFout Eidth67fill parent7 android:laFout height67Erap content7 android:stretch+olumns6718>7 M L&able?oEM L&eGtVieE android:laFout Eidth67Erap content7 android:laFout height67Erap content7 android:padding)eft67>dip7 android:padding?ight67<dip7 android:teGt67)ocation:7 /M L$dit&eGt android:id67ORid/lat7 android:laFout Eidth67fill parent7 android:laFout height67Erap content7 android:cursorVisible67true7 android:editable67true7 android:single)ine67true7
&88
android:laFout Eeight6717 /M L$dit&eGt android:id67ORid/lon7 android:laFout Eidth67fill parent7 android:laFout height67Erap content7 android:cursorVisible67true7 android:editable67true7 android:single)ine67true7 android:laFout Eeight6717 /M L/&able?oEM L/&able)aFoutM L4utton android:id67ORid/map7 android:laFout Eidth67fill parent7 android:laFout height67Erap content7 android:teGt672hoE #eX7 android:on+lick67shoE#e7 /M L/)inear)aFoutM
5he button7s shoE#ePQ 'allba'k metho" simply takes the latitu"e an" longitu"e, pours them into a geo s'heme 3ri, then starts the a'ti!ity.
package com.commonsEare.android.activitiesJ import import import import import import android.app.ActivitFJ android.content.IntentJ android.net.3riJ android.os.4undleJ android.vieE.VieEJ android.Eidget.$dit&eGtJ
public class )aunch=emo eGtends ActivitF : private $dit&eGt latJ private $dit&eGt lonJ O"verride public void onCreateP4undle icicleQ : super.onCreatePicicleQJ setContentViewP?.laFout.mainQJ lat6P$dit&eGtQfindViewByIdP?.id.latQJ lon6P$dit&eGtQfindViewByIdP?.id.lonQJ ; public void showMePVieE vQ : 2tring lat6lat.getTextPQ.toStringPQJ 2tring lon6lon.getTextPQ.toStringPQJ 3ri uri63ri.parseP7geo:7R latR787R lonQJ start$cti!ityPneE IntentPIntent.A+&I"% VI$@8 uriQQJ
&8:
; ;
0& you &ill in a lo'ation (e.g., .8.8831 latitu"e an" -44.0<32 longitu"e) an" 'li'k the button, the resulting map is more interesting. 2ote that this is the built-in An"roi" map a'ti!ity S =e "i" not 'reate our o=n a'ti!ity to "isplay this map.
&:<
"igure :71 The map launched by !aunch /emo@ sho)ing the !incoln +emorial in Washington /C
0n a later 'hapter, you =ill see ho= you 'an 'reate maps in your o=n a'ti!ities, in 'ase you nee" greater 'ontrol o!er ho= the map is "isplaye". 2ote that this geo: Intent =ill only =ork on "e!i'es or emulators that ha!e 8oogle Maps installe", or on "e!i'es that ha!e some other mapping appli'ation that supports the geo: $ L.
&:*
As you may re'all &rom the se'tion on tabbe" !ie=s &rom earlier in this book, a tab 'an ha!e a VieE as its 'ontents. 0t 'an also ha!e an ActivitF as its 'ontents. 0& you =ant to use an ActivitF as the 'ontent o& a tab, you pro!i"e an Intent that =ill laun'h the "esire" ActivitFT An"roi"7s tab-management &rame=ork =ill then pour the ActivitF7s user inter&a'e into the tab. ?our natural instin't might be to use an http: 3ri the =ay =e use" a geo: 3ri in the pre!ious e;ample,
Intent i6neE IntentPIntent.A+&I"% VI$@QJ i.setDataP3ri.parseP7http://commonsEare.com7QQJ
5hat =ay, you 'oul" use the built-in 1ro=ser appli'ation an" get all o& the &eatures that it o&&ers. Alas, this "oes not =ork. ?ou 'annot host other appli'ations7 a'ti!ities in your tabs, only your o=n a'ti!ities, &or se'urity reasons. %o, =e "ust o&& our @ebVieE "emos &rom the 'hapter on WebDit an" use those instea", repa'kage" as Activities/Intent&ab. +ere is the sour'e to the main a'ti!ity, the one hosting the &abVieE,
package com.commonsEare.android.intenttabJ import import import import import import import android.app.ActivitFJ android.app.&abActivitFJ android.content.IntentJ android.net.3riJ android.os.4undleJ android.Eebkit.@ebVieEJ android.Eidget.&ab!ostJ
public class Intent&ab=emo eGtends &abActivitF : O"verride public void onCreateP4undle savedInstance2tateQ : super.onCreatePsavedInstance2tateQJ &ab!ost host6getTa'(ostPQJ Intent i6neE IntentPthis8 +@4roEser.classQJ i.put+xtraP+@4roEser.3?)8 7http://commonsEare.com7QJ host.addTa'Phost.newTa'SpecP7one7Q
&:&
; ;
As you 'an see, =e are using &abActivitF as the base 'lass, an" so =e "o not nee" our o=n layout FML S &abActivitF supplies it &or us. All =e "o is get a''ess to the &ab!ost an" a"" t=o tabs, ea'h spe'i&ying an 0ntent that "ire'tly re&ers to another 'lass. 0n this 'ase, our t=o tabs =ill ea'h host a +@4roEser, =ith a $ L to loa" supplie" !ia an Intent e;tra. 5he +@4roEser a'ti!ity is simple mo"i&i'ation to the earlier bro=ser "emos,
package com.commonsEare.android.intenttabJ import import import import import android.app.ActivitFJ android.content.IntentJ android.net.3riJ android.os.4undleJ android.Eebkit.@ebVieEJ
public class +@4roEser eGtends ActivitF : public static final 2tring 3?)67com.commonsEare.android.intenttab.3?)7J private @ebVieE broEserJ O"verride public void onCreateP4undle icicleQ : super.onCreatePicicleQJ broEser6neE #e'ViewPthisQJ setContentViewPbroEserQJ broEser.load*rlPgetIntentPQ.getString+xtraP3?)QQJ ; ;
5hey simply loa" a "i&&erent $ L into the bro=ser, the CommonsWare home page in one, the An"roi" home page in the other. 5he resulting $0 sho=s =hat tabbe" bro=sing 'oul" look like on An"roi",
&:-
"igure :81 The ntentTab/emo sample application@ sho)ing the first tab
"igure ::1 The ntentTab/emo sample application@ sho)ing the second tab
+o=e!er, this approa'h is rather =aste&ul. 5here is a &air bit o& o!erhea" in 'reating an a'ti!ity, that one "oes not nee" Gust to populate tabs in a &ab!ost. 0n parti'ular, it in'reases the amount o& sta'k spa'e nee"e" by your
&:%
appli'ation, an" running out o& sta'k spa'e is a signi&i'ant problem in An"roi", as =ill be "es'ribe" in a later 'hapter.
&:0
CHAPTER &1
esour'es are stati' bits o& in&ormation hel" outsi"e the Ca!a sour'e 'o"e. ?ou ha!e seen one type o& resour'e S the layout S &reRuently in the e;amples in this book. 5here are many other types o& resour'e, su'h as images an" strings, that you 'an take a"!antage o& in your An"roi" appli'ations.
0mages (res/draEable/), &or putting stati' i'ons or other pi'tures in a user inter&a'e a= (res/raE/), &or putting arbitrary &iles that ha!e meaning to your appli'ation but not ne'essarily to An"roi" &rame=orks
&:7
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 gi!e these sorts o& 'onstants symboli' names an" to keep them separate &rom the rest o& the 'o"e (e.g., &or internationaliKation an" lo'aliKation) FML (res/Gml/), &or stati' FML &iles 'ontaining your o=n "ata an" stru'ture
String Theory
Deeping 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 !ery goo" i"ea. 0n parti'ular, it helps =ith internationaliKation (0182) an" lo'aliKation (L102), 'o!ere" later in this 'hapter. E!en i& you are not going to translate your strings to other languages, it is easier to make 'orre'tions i& all the strings are in one spot instea" o& s'attere" throughout your sour'e 'o"e. An"roi" supports regular e;ternaliKe" strings, along =ith Mstring &ormatsM, =here the string has pla'ehol"ers &or "ynami'ally-inserte" in&ormation. >n top o& that, An"roi" supports simple te;t &ormatting, 'alle" Mstyle" te;tM, so you 'an make your =or"s be bol" or itali' intermingle" =ith normal te;t.
Pl in Strin!s
8enerally speaking, all you nee" to "o is ha!e an FML &ile in the res/values "ire'tory (typi'ally name" res/values/strings.Gml), =ith a resources root element, an" one 'hil" string element &or ea'h string you =ish to en'o"e as a resour'e. 5he string element takes a name attribute, =hi'h is the uniRue name &or this string, an" a single te;t element 'ontaining the te;t o& the string,
LresourcesM Lstring name67Uuick7M&he Uuick broEn foG...L/stringM Lstring name67laughs7M!e Eho laughs last...L/stringM L/resourcesM
5he only tri'ky part is i& the string !alue 'ontains a Ruote ( 7) or an apostrophe (I). 0n those 'ases, you =ill =ant to es'ape those !alues, by
&:8
pre'e"ing them =ith a ba'kslash (e.g., &hese are the times that trF menTIs souls). >r, i& it is Gust an apostrophe, you 'oul" en'lose the !alue in Ruotes (e.g., 7&hese are the times that trF menIs souls.7). ?ou 'an then re&eren'e this string &rom a layout &ile (as Ostring/..., =here the ellipsis is the uniRue name S e.g., Ostring/laughs). >r you 'an get the string &rom your Ca!a 'o"e by 'alling get2tringPQ =ith the resour'e 0@ o& the string resour'e, that being the uniRue name pre&i;e" =ith ?.string. (e.g., get2tringP?.string.UuickQ).
Strin! 5orm ts
As =ith other implementations o& the Ca!a language, An"roi"7s @al!ik -M supports string &ormats. +ere, the string 'ontains pla'ehol"ers representing "ata to be repla'e" at runtime by !ariable in&ormation (e.g., #F name is \1's). #lain strings store" as resour'es 'an be use" as string &ormats,
2tring str9ormat6getStringP?.string.mF nameQJ 2tring str?esult62tring.formatPstr9ormat8 7&im7QJ PP&eGtVieEQfindViewByIdP?.id.some labelQQ.setTextPstr?esultQJ
5here is also a &la!or o& get2tringPQ that "oes the 2tring.formatPQ 'all &or you,
2tring str?esult6getStringP?.string.mF name8 7&im7QJ PP&eGtVieEQfindViewByIdP?.id.some labelQQ.setTextPstr?esultQJ
0t is !ery important that you use the !ersion o& the pla'ehol"ers that take an in"e; S \1's instea" o& Gust \s. %trategi'ally, translations o& your string resour'es may 'ause you to apply the !ariable "ata in a "i&&erent or"er than "i" your original translation, an" using non-in"e;e" pla'ehol"ers lo'k you into a parti'ular or"er. 5a'ti'ally, your proGe't =ill &ail to 'ompile, as the An"roi" buil" tools reGe't non-in"e;e" pla'ehol"ers no=a"ays.
&::
Styled Te0t
0& you =ant really ri'h te;t, you shoul" ha!e ra= resour'es 'ontaining +5ML, then pour those into a WebDit =i"get. +o=e!er, &or light +5ML &ormatting, using inline elements like LbM, LiM, an" LuM, you 'an Gust use them in a string resour'e,
LresourcesM Lstring name67b7M&his has LbMboldL/bM in it.L/stringM Lstring name67i7M@hereas this has LiMitalicsL/iMXL/stringM L/resourcesM
?ou 'an a''ess these !ia get&eGtPQ, =here you =ill get ba'k an obGe't supporting the android.teGt.2panned inter&a'e an" there&ore has all o& the &ormatting applie",
PP&eGtVieEQfindViewByIdP?.id.another labelQQ .setTextPgetTextP?.string.bQQJ
.. 8enerate the &ormat results, being sure to es'ape any string !alues you substitute in, in 'ase they 'ontain angle bra'kets or ampersan"s
2tring.formatPgetStringP?.string.funkF formatQ8 &eGt3tils.html+ncodePstr%ameQQJ
-<<
some&eGtVieE.setTextP!tml .from(tmlPresult9rom2tring9ormatQQJ
5o see this in a'tion, let7s look at the ?esources/2trings "emo. +ere is the layout &ile,
LNGml version671.-7 encoding67utf-,7NM L)inear)aFout Gmlns:android67http://schemas.android.com/apk/res/android7 android:orientation67vertical7 android:laFout Eidth67fill parent7 android:laFout height67fill parent7 M L)inear)aFout android:orientation67horiKontal7 android:laFout Eidth67fill parent7 android:laFout height67Erap content7 M L4utton android:id67ORid/format7 android:laFout Eidth67Erap content7 android:laFout height67Erap content7 android:teGt67Ostring/btn name7 android:on+lick67applF9ormat7 /M L$dit&eGt android:id67ORid/name7 android:laFout Eidth67fill parent7 android:laFout height67Erap content7 /M L/)inear)aFoutM L&eGtVieE android:id67ORid/result7 android:laFout Eidth67fill parent7 android:laFout height67Erap content7 /M L/)inear)aFoutM
As you 'an see, it is Gust a button, a &iel", an" a label. 5he intent is &or somebo"y to enter their name in the &iel", then 'li'k the button to 'ause the label to be up"ate" =ith a &ormatte" message 'ontaining their name. 5he 4utton in the layout &ile re&eren'es a string resour'e (Ostring/btn name), so =e nee" a string resour'e &ile (res/values/strings.Gml),
LNGml version671.-7 encoding67utf-,7NM LresourcesM Lstring name67app name7M2trings=emoL/stringM Lstring name67btn name7M%ame:L/stringM Lstring name67funkF format7M#F name is ZltJbZgtJ\1'sZltJ/bZgtJL/stringM L/resourcesM
-<*
5he app name resour'e is automati'ally 'reate" by the android create project 'omman". 5he btn name string is the 'aption o& the 4utton, =hile our style" string &ormat is in funkF format. *inally, to hook all this together, =e nee" a pin'h o& Ca!a,
package com.commonsEare.android.stringsJ import import import import import import import android.app.ActivitFJ android.os.4undleJ android.teGt.&eGt3tilsJ android.teGt.!tmlJ android.vieE.VieEJ android.Eidget.$dit&eGtJ android.Eidget.&eGtVieEJ
public class 2trings=emo eGtends ActivitF : $dit&eGt nameJ &eGtVieE resultJ O"verride public void onCreateP4undle icicleQ : super.onCreatePicicleQJ setContentViewP?.laFout.mainQJ name6P$dit&eGtQfindViewByIdP?.id.nameQJ result6P&eGtVieEQfindViewByIdP?.id.resultQJ
public void apply"ormatPVieE vQ : 2tring format6getStringP?.string.funkF formatQJ 2tring simple?esult62tring.formatPformat8 &eGt3tils.html+ncodePname.getTextPQ.toStringPQQQJ result.setTextP!tml.from(tmlPsimple?esultQQJ ;
5he string resour'e manipulation 'an be &oun" in applF9ormatPQ, =hi'h is 'alle" =hen the button is 'li'ke". *irst, =e get our &ormat !ia get2tringPQ S something =e 'oul" ha!e "one at on+reatePQ time &or e&&i'ien'y. 2e;t, =e &ormat the !alue in the &iel" using this &ormat, getting a 2tring ba'k, sin'e the string resour'e is in entity-en'o"e" +5ML. 2ote the use o& &eGt3tils.html$ncodePQ to entity-en'o"e the entere" name, in 'ase somebo"y "e'i"es to use an ampersan" or something. *inally, =e 'on!ert the simple +5ML into a style" te;t obGe't !ia !tml.from!tmlPQ an" up"ate our label.
-<&
-<-
"igure *<*1 The same application@ after filling in some heroic figureGs name
-<%
res/draEable
=ith a base name o& i'on. 0n this 'ase, =e use a .2;.2 #28 &ile &rom the 2u!ola i'on set,
LNGml version671.-7 encoding67utf-,7NM L)inear)aFout Gmlns:android67http://schemas.android.com/apk/res/android7 android:orientation67vertical7 android:laFout Eidth67fill parent7 android:laFout height67fill parent7 M L)inear)aFout android:orientation67horiKontal7 android:laFout Eidth67fill parent7 android:laFout height67Erap content7 M LImage4utton android:id67ORid/format7 android:laFout Eidth67Erap content7 android:laFout height67Erap content7 android:src67OdraEable/icon7 android:on+lick67applF9ormat7 /M L$dit&eGt android:id67ORid/name7 android:laFout Eidth67fill parent7 android:laFout height67Erap content7 /M L/)inear)aFoutM L&eGtVieE android:id67ORid/result7 android:laFout Eidth67fill parent7 android:laFout height67Erap content7 /M L/)inear)aFoutM
-<0
res/Gml/.
5he layout stays the same, so all that nee"s repla'ing is the Ca!a
sour'e,
package com.commonsEare.android.resourcesJ import import import import import import import import import import import import import android.app.ActivitFJ android.os.4undleJ android.app.)istActivitFJ android.vieE.VieEJ android.Eidget.AdapterVieEJ android.Eidget.ArraFAdapterJ android.Eidget.)istVieEJ android.Eidget.&eGtVieEJ android.Eidget.&oastJ java.io.Input2treamJ java.util.ArraF)istJ org.Gmlpull.v1.]ml(ull(arserJ org.Gmlpull.v1.]ml(ull(arser$GceptionJ
public class ]#)?esource=emo eGtends )istActivitF : &eGtVieE selectionJ ArraF)istL2tringM items6neE ArraF)istL2tringMPQJ O"verride public void onCreateP4undle icicleQ : super.onCreatePicicleQJ setContentViewP?.laFout.mainQJ selection6P&eGtVieEQfindViewByIdP?.id.selectionQJ trF : ]ml(ull(arser Gpp6get%esourcesPQ.get,mlP?.Gml.EordsQJ Ehile PGpp.get+!entTypePQX6]ml(ull(arser.$%= ="+3#$%&Q : if PGpp.get+!entTypePQ66]ml(ull(arser.2&A?& &ADQ : if PGpp.get&amePQ.e-ualsP7Eord7QQ : items.addPGpp.get$ttri'uteValueP-QQJ ; ; ; Gpp.nextPQJ
; catch P&hroEable tQ : &oast .makeTextPthis8 7?eUuest failed: 7Rt.toStringPQ8 &oast.)$%D&! )"%DQ .showPQJ ; setList$dapterPneE ArraFAdapterL2tringMPthis8 android.?.laFout.simple list item 18 itemsQQJ ;
-<7
public void onListItemClickP)istVieE parent8 VieE v8 int position8 long idQ : selection.setTextPitems.getPpositionQ.toStringPQQJ ;
2o=, insi"e our trF...catch blo'k, =e get our ]ml(ull(arser an" loop until the en" o& the "o'ument. 0& the 'urrent e!ent is 2&A?& &AD an" the name o& the element is Eord (Gpp.get%amePQ.eUualsP7Eord7Q), then =e get the onean"-only attribute an" pop that into our list o& items &or the sele'tion =i"get. %in'e =e7re in 'omplete 'ontrol o!er the FML &ile, it is sa&e enough to assume there is e;a'tly one attribute. 1ut, i& you =ere not as 'om&ortable that the FML is properly "e&ine", you might 'onsi"er 'he'king the attribute 'ount (getAttribute+ountPQ) an" the name o& the attribute (getAttribute%amePQ) be&ore blin"ly assuming the --in"e; attribute is =hat you think it is. 5he result looks the same as be&ore, albeit =ith a "i&&erent name in the title bar,
-<8
+iscellaneous ;alues
0n the res/values/ "ire'tory, in a""ition to string resour'es, you 'an pla'e one (or more) FML &iles "es'ribing other simple resour'es, su'h as "imensions, 'olors, an" arrays. We ha!e alrea"y seen uses o& "imensions an" 'olors in pre!ious e;amples, =here they =ere passe" as simple strings (e.g., 71-dip7) as parameters to 'alls. ?ou 'an, o& 'ourse, set these up as Ca!a stati' &inal obGe'ts an" use their symboli' names...but this only =orks insi"e Ca!a sour'e, not in layout FML &iles. 1y putting these !alues in resour'e FML &iles, you 'an re&eren'e them &rom both Ca!a an" layouts, plus ha!e them 'entrally lo'ate" &or easy e"iting. esour'e FML &iles ha!e a root element o& resourcesT e!erything else is a 'hil" o& that root.
Dimensions
@imensions are use" in se!eral pla'es in An"roi" to "es'ribe "istan'es, su'h as a =i"get7s pa""ing. 5here are se!eral "i&&erent units o& measurement a!ailable to you,
an" mm &or in'hes an" millimeters, respe'ti!ely, base" on the a'tual siKe o& the s'reen
in pt
&or points, =hi'h in publishing terms is 1P42n" o& an in'h (again, base" on the a'tual physi'al siKe o& the s'reen) an" sp &or "e!i'e-in"epen"ent pi;els an" s'ale-in"epen"ent pi;els S one pi;el eRuals one dip &or a 1/0"pi resolution s'reen, =ith the ratio s'aling base" on the a'tual s'reen pi;el "ensity (s'alein"epen"ent pi;els also take into a''ount the user7s pre&erre" &ont siKe)
dip
5o en'o"e a "imension as a resour'e, a"" a dimen element, =ith a name attribute &or your uniRue name &or this resour'e, an" a single 'hil" te;t element representing the !alue,
-<:
0n a layout, you 'an re&eren'e "imensions as Odimen/..., =here the ellipsis is a pla'ehol"er &or your uniRue name &or the resour'e (e.g., thin an" fat &rom the sample abo!e). 0n Ca!a, you re&eren'e "imension resour'es by the uniRue name pre&i;e" =ith ?.dimen. (e.g., ?esources.get=imenP?.dimen.thinQ).
Colors
Colors in An"roi" are he;a"e'imal 81 !alues, also optionally spe'i&ying an alpha 'hannel. ?ou ha!e your 'hoi'e o& single-'hara'ter he; !alues or "ouble-'hara'ter he; !alues, lea!ing you =ith &our styles,
S?D4 SA?D4 S??DD44 SAA??DD44
5hese =ork similarly to their 'ounterparts in Cas'a"ing %tyle %heets (C%%). ?ou 'an, o& 'ourse, put these 81 !alues as string literals in Ca!a sour'e or layout resour'es. 0& 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 uniRue name &or this 'olor, an" a single te;t element 'ontaining the 81 !alue itsel&,
LresourcesM Lcolor name67FelloE orange7MS99=...L/colorM Lcolor name67forest green7MS--..--L/colorM Lcolor name67burnt umber7MS,ACC><L/colorM L/resourcesM
0n a layout, you 'an re&eren'e 'olors as Ocolor/..., repla'ing the ellipsis =ith your uniRue name &or the 'olor (e.g., burnt umber). 0n Ca!a, you
-*<
re&eren'e 'olor resour'es by the uniRue name pre&i;e" =ith ?.color. (e.g., ?esources.get+olorP?.color.forest greenQ).
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., @r., et'.). 0n the resour'e &ile, you nee" one string-arraF element per array, =ith a name attribute &or the uniRue name you are gi!ing the array. 5hen, a"" one or more 'hil" item elements, ea'h o& =hi'h ha!ing a single te;t element =ith the !alue &or that entry in the array,
LNGml version671.-7 encoding67utf-,7NM LresourcesM Lstring-arraF name67cities7M LitemM(hiladelphiaL/itemM LitemM(ittsburghL/itemM LitemMAllentoEn/4ethlehemL/itemM LitemM$rieL/itemM LitemM?eadingL/itemM LitemM2crantonL/itemM LitemM)ancasterL/itemM LitemMAltoonaL/itemM LitemM!arrisburgL/itemM L/string-arraFM Lstring-arraF name67airport codes7M LitemM(!)L/itemM LitemM(I&L/itemM LitemMA4$L/itemM LitemM$?IL/itemM LitemM?=DL/itemM LitemMAV(L/itemM LitemM)%2L/itemM LitemMA""L/itemM LitemM#=&L/itemM L/string-arraFM L/resourcesM
*rom your Ca!a 'o"e, you 'an then use ?esources.get2tringArraFPQ to get a 2tringAB o& the items in the list. 5he parameter to get2tringArraFPQ is your uniRue name &or the array, pre&i;e" =ith ?.arraF. (e.g., ?esources.get2tringArraFP?.arraF.honorificsQ).
-**
$creen orientation, is the s'reen in a portrait orientationH Lan"s'apeH 0s the s'reen sRuare an", there&ore, "oes not really ha!e an orientationH $creen si<e, ho= many pi;els "oes the s'reen ha!e, so you 'an siKe your resour'es a''or"ingly (e.g., large !ersus small i'ons)H Touchscreen, "oes the "e!i'e ha!e a tou'hs'reenH 0& so, is the tou'hs'reen set up to be use" =ith a stylus or a &ingerH 9ey,oard, =hat keyboar" "oes the user ha!e (JWE 5?, numeri', neither), either no= or as an optionH Bther input, "oes the "e!i'e ha!e some other &orm o& input, like a "ire'tional pa" or 'li'k-=heelH
5he =ay An"roi" 'urrently han"les this is by ha!ing multiple resour'e "ire'tories, =ith the 'riteria &or ea'h embe""e" in their names. %uppose, &or e;ample, you =ant to support strings in both English an" %panish. 2ormally, &or a single-language setup, you =oul" put your strings in a &ile name" res/values/strings.Gml. 5o support both English an" %panish, you =oul" 'reate t=o &ol"ers, res/values-en/ an" res/values-es/, =here the !alue a&ter the hyphen is the 0%> /.3-1 t=o-letter 'o"e &or the language you =ant. ?our English-language strings =oul" go in res/valuesen/strings.Gml an" the %panish ones in res/values-es/strings.Gml. An"roi" =ill 'hoose the proper &ile base" on the user7s "e!i'e settings.
-*&
An e!en better approa'h is &or you to 'onsi"er some language to be your "e&ault, an" put those strings in res/values/strings.Gml. 5hen, 'reate other resour'e "ire'tories &or your translations (e.g., res/values-es/strings.Gml &or %panish). An"roi" =ill try to mat'h a spe'i&i' language set o& resour'esT &ailing that, it =ill &all ba'k to the "e&ault o& res/values/strings.Gml. %eems easy, rightH Where things start to get 'ompli'ate" is =hen you nee" to use multiple "isparate 'riteria &or your resour'es. *or e;ample, let us suppose you =ant to "e!elop both &or the 5-Mobile 81, the %amsung 8ala;y 5ab, an" the Motorola Charm.
5he 5-Mobile 81 has a normal-siKe, me"ium-"ensity s'reen an" a har"=are keyboar" 5he %amsung 8ala;y 5ab has a large siKe, high-"ensity s'reen an" no har"=are keyboar" 5he Motorola Charm has a small siKe, me"ium-"ensity s'reen an" a har"=are keyboar"
?ou may =ant to ha!e some=hat "i&&erent layouts &or these "e!i'es, to take a"!antage o& "i&&erent s'reen real estate an" "i&&erent input options. %pe'i&i'ally,
?ou =ant "i&&erent layouts &or ea'h 'ombination o& siKe, orientation, an" keyboar" ?ou =ant "i&&erent "ra=ables &or ea'h "ensity
>n'e you get into these sorts o& situations, though, all sorts o& rules 'ome into play, su'h as,
5he 'on&iguration options (e.g., -en) ha!e a parti'ular or"er o& pre'e"en'e, an" they must appear in the "ire'tory name in that or"er. 5he An"roi" "o'umentation outlines the spe'i&i' or"er in =hi'h these options 'an appear. *or the purposes o& this e;ample, s'reen siKe is more important than s'reen orientation, =hi'h is
-*-
more important than s'reen "ensity, =hi'h is more important than =hether or not the "e!i'e has a keyboar".
5here 'an only be one !alue o& ea'h 'on&iguration option 'ategory per "ire'tory. >ptions are 'ase sensiti!e
%o, &or the s'enario "es'ribe" abo!e, in theory, =e =oul" nee" the &ollo=ing "ire'tories, representing the possible 'ombinations,
res/laFout-large-port-mdpi-UEertF res/laFout-large-port-mdpi-nokeFs res/laFout-large-port-hdpi-UEertF res/laFout-large-port-hdpi-nokeFs res/laFout-large-land-mdpi-UEertF res/laFout-large-land-mdpi-nokeFs res/laFout-large-land-hdpi-UEertF res/laFout-large-land-hdpi-nokeFs res/laFout-normal-port-mdpi-UEertF res/laFout-normal-port-mdpi-nokeFs res/laFout-normal-port-finger-UEertF res/laFout-normal-port-hdpi-nokeFs res/laFout-normal-land-mdpi-UEertF res/laFout-normal-land-mdpi-nokeFs res/laFout-normal-land-hdpi-UEertF res/laFout-normal-land-hdpi-nokeFs res/draEable-large-port-mdpi-UEertF res/draEable-large-port-mdpi-nokeFs res/draEable-large-port-hdpi-UEertF res/draEable-large-port-hdpi-nokeFs res/draEable-large-land-mdpi-UEertF res/draEable-large-land-mdpi-nokeFs res/draEable-large-land-hdpi-UEertF
-*%
@on7t pani': We =ill shorten this list in Gust a moment: 2ote that there is nothing pre!enting you &rom also ha!ing a "ire'tory =ith the una"orne" base name (res/laFout). 0n &a't, this is really 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 S ha!ing a "e&ault layout might make the "i&&eren'e bet=een your appli'ation =orking or &ailing on that ne= "e!i'e. Also, =e 'an 'ut the number o& reRuire" "ire'tories a lot by "e'o"ing the rules An"roi" uses &or "etermining =hi'h, among a set o& 'an"i"ates, is the MrightM resour'e "ire'tory to use, 1. *irst up, An"roi" tosses out ones that are spe'i&i'ally in!ali". %o, &or e;ample, i& the s'reen siKe o& the "e!i'e is MnormalM, the -large "ire'tories =oul" be "roppe" as 'an"i"ates, sin'e they 'all &or some other siKe.
2. 2e;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. .. *inally, An"roi" goes in the or"er o& pre'e"en'e o& the options S in other =or"s, it goes &rom le&t to right in the "ire'tory name. Also, our "ra=ables are only !arying by "ensity, an" our layouts are not !arying by "ensity, so =e 'an 'lear out a lot o& 'ombinations by &o'using on only the rele!ant plat&orm "i&&eren'es.
-*0
+ere, =e take a"!antage o& the &a't that spe'i&i' mat'hes take pre'e"en'e o!er Munspe'i&ie"M !alues. %o, a "e!i'e =ith a JWE 5? keyboar" =ill 'hoose a resour'e =ith UEertF in the "ire'tory o!er a resour'e that "oes not spe'i&y its keyboar" type. We 'oul" re&ine this e!en &urther, to only 'o!er the spe'i&i' "e!i'es =e are targeting (e.g., there is no large "e!i'e =ith UEertF),
res/laFout-large-land res/laFout-large res/laFout-land-UEertF res/laFout-UEertF res/laFout-land res/laFout res/draEable-hdpi res/draEable
0& =e "i" not 'are about ha!ing "i&&erent layouts &or =hether the "e!i'e ha" a har"=are keyboar", =e 'oul" "rop the t=o -UEertF resour'e sets. We =ill see these resour'e sets again in the 'hapter on supporting multiple s'reen siKes, later in the book.
-*2
Are your &eGtVieE =i"gets aligne" on the le&t si"e =ith other =i"gets or 'ontainersH 0& so, is that the right ans=er &or your 5L usersH Will there be any issues =ith your $dit&eGt =i"gets =hen users start entering 5L te;t, su'h as inappropriate s'rolling be'ause you ha!e not properly 'onstraine" the $dit&eGt =i"get7s =i"thH 0& you 'reate" your o=n &orms o& te;t input, outsi"e o& $dit&eGt an" the input metho" &rame=ork (e.g., 'ustom on-s'reen !irtual keyboar"s), =ill they support 5L languagesH
-*7
CHAPTER &2
E!ery no= an" then, you =ill &in" some 'o"e =ith a 'rypti' style attribute in a layout element. *or e;ample, in the 'hapter on threa"ing, there =as our (rogress4ar,
LNGml version671.-7 encoding67utf-,7NM L)inear)aFout Gmlns:android67http://schemas.android.com/apk/res/android7 android:orientation67vertical7 android:laFout Eidth67fill parent7 android:laFout height67fill parent7 M L(rogress4ar android:id67ORid/progress7 stFle67Nandroid:attr/progress4ar2tFle!oriKontal7 android:laFout Eidth67fill parent7 android:laFout height67Erap content7 /M L/)inear)aFoutM
%omething about that magi' stFle attribute 'hange" our (rogress4ar &rom a normal 'ir'le to a horiKontal bar. 5his 'hapter =ill brie&ly e;plore the 'on'ept o& styles, ho= you 'an 'reate them, an" ho= you 'an apply them to your o=n =i"gets.
Styles5 / . /C.
5he purpose o& styles is to en'apsulate a set o& attributes that you inten" to use repeate"ly, 'on"itionally, or other=ise =ish to keep separate &rom your layouts proper. 5he primary use 'ase is M"on7t repeat yoursel&M (@ ?) S i& you ha!e a bun'h o& =i"gets that look the same, use a style to use a single
-*:
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
"e&inition &or Mlook the sameM, rather than 'opying the look &rom =i"get to =i"get. An" that paragraph =ill make a bit more sense i& =e look at an e;ample, spe'i&i'ally the 2tFles/%oE2tFled sample proGe't. 5his is the same proGe't =e e;amine" in an earlier 'hapter, =ith a &ulls'reen button that sho=s the "ate an" time o& =hen the a'ti!ity =as laun'he" or =hen the button =as pushe". 5his time, though, =e =ant to 'hange the =ay the te;t on the &a'e o& the button appears, an" =e =ill "o so using a style. 5he res/laFout/main.Gml &ile in this proGe't is the same as it =as, =ith the a""ition o& a stFle attribute,
LNGml version671.-7 encoding67utf-,7NM L4utton Gmlns:android67http://schemas.android.com/apk/res/android7 android:id67ORid/button7 android:teGt677 android:laFout Eidth67fill parent7 android:laFout height67fill parent7 stFle67OstFle/bigred7 /M
2ote that the stFle attribute is part o& sto'k FML an" there&ore is not in the android namespa'e, so it "oes not get the android: pre&i;. 5he !alue, OstFle/bigred, points to a style resour'e. %tyle resour'es are !alues resour'es an" 'an be &oun" in the res/values/ "ire'tory in your proGe't, or in other resour'e sets (e.g., res/values-v11/ &or !alues resour'es only to be use" on A#0 Le!el 11 or higher). 5he 'on!ention is &or styles resour'es to be hel" in a stFles.Gml &ile, su'h as the one &rom the %oE2tFled proGe't,
LNGml version671.-7 encoding67utf-,7NM LresourcesM LstFle name67bigred7M Litem name67android:teGt2iKe7MC-spL/itemM Litem name67android:teGt+olor7MS9999----L/itemM L/stFleM L/resourcesM
-&<
5he LstFleM element supplies the name o& the style, =hi'h is =hat =e use =hen re&erring to the style &rom a layout. 5he LitemM 'hil"ren o& the LstFleM element represent !alues o& attributes to be applie" to =hate!er the style is applie" to=ar"s S in our e;ample, our 4utton =i"get. %o, our 4utton =ill ha!e a 'omparati!ely large &ont (android:teGt2iKe set to C-sp) an" ha!e the te;t appear in re" (android:teGt+olor set to S9999----). 5here are no 'hanges nee"e" else=here in the proGe't S nothing nee"s to be a"Guste" in the mani&est, in the Ca!a 'o"e o& the a'ti!ity, et'. Cust "e&ining the style an" applying it to the =i"get gi!es us results,
=lements of Style
5here are &our elements to 'onsi"er =hen applying a style, 1. Where "o you put the style attributes to say you =ant to apply a styleH
-&*
2. What attributes 'an you "e&ine !ia a styleH .. +o= "o you inherit &rom a pre!iously-"e&ine" style (one o& your o=n or one &rom An"roi")H <. What !alues 'an those attributes ha!e in a style "e&initionH
,here to Apply
Style
5he stFle attribute 'an be applie" to a =i"get, to only a&&e't that =i"get. 5he stFle attribute 'an be applie" to a 'ontainer, to a&&e't that 'ontainer. +o=e!er, "oing this "oes not automati'ally style its 'hil"ren. *or e;ample, suppose res/laFout/main.Gml looke" instea" like this,
LNGml version671.-7 encoding67utf-,7NM L)inear)aFout Gmlns:android67http://schemas.android.com/apk/res/android7 android:laFout Eidth67fill parent7 android:laFout height67fill parent7 stFle67OstFle/bigred7 M L4utton android:id67ORid/button7 android:teGt677 android:laFout Eidth67fill parent7 android:laFout height67fill parent7 /M L/)inear)aFoutM
5he resulting $0 =oul" not ha!e the 4utton te;t in a big re" &ont, "espite the stFle attribute. 5he style only a&&e'ts the 'ontainer, not the 'ontents o& the 'ontainer. ?ou 'an also apply a style to an a'ti!ity or an appli'ation as a =hole, though then it is re&erre" to as a MthemeM, =hi'h =ill be 'o!ere" a bit later in this 'hapter.
AttributesM or M0nherite" FML AttributesM portions o& the An"roi" Ca!a@o's, you 'an put it in a style. 2ote that An"roi" =ill ignore in!ali" styles. %o, ha" =e applie" the bigred style to the )inear)aFout as sho=n abo!e, e!erything =oul" run &ine, Gust =ith no !isible results. @espite the &a't that )inear)aFout has no android:teGt2iKe or android:teGt+olor attribute, there is no 'ompile-time &ailure nor a runtime e;'eption. Also, layout "ire'ti!es, su'h as android:laFout Eidth, 'an be put in a style.
Inheritin!
Style
?ou 'an also in"i'ate that you =ant to inherit style attributes &rom another style, by spe'i&ying an parent attribute on the LstFleM element. *or e;ample, take a look at this style resour'e,
LNGml version671.-7 encoding67utf-,7NM LresourcesM LstFle name67activated7 parent67android:&heme.!olo7M Litem name67android:background7MN android:attr/activated4ackgroundIndicatorL/itemM L/stFleM L/resourcesM
We =ill see this resour'e again in a later 'hapter on using the ne= &ragment $0 &rame=ork. +ere, =e are in"i'ating that =e =ant to inherit the &heme.!olo style &rom =ithin An"roi". +en'e, in a""ition to all o& our o=n attribute "e&initions, =e are spe'i&ying that =e =ant all o& the attribute "e&initions &rom &heme.!olo as =ell. 0n many 'ases, this =ill not be ne'essary. 0& you "o not spe'i&y a parent, your attribute "e&initions =ill be blen"e" into =hate!er "e&ault style is being applie" to the =i"get or 'ontainer.
-&-
+ere, =e are in"i'ating that the !alue o& android:background is not some 'onstant !alue, or e!en a re&eren'e to a "ra=able resour'e (e.g., OdraEable/mF background). 0nstea", =e are re&erring to the !alue o& some other attribute S activated4ackgroundIndicator S &rom our inherite" theme. Whate!er the theme "e&ines as being the activated4ackgroundIndicator is =hat our ba'kgroun" shoul" be. %ometimes, this is applie" to a style as a =hole. *or e;ample, let7s look again at the (rogress4ar,
LNGml version671.-7 encoding67utf-,7NM L)inear)aFout Gmlns:android67http://schemas.android.com/apk/res/android7 android:orientation67vertical7 android:laFout Eidth67fill parent7 android:laFout height67fill parent7 M L(rogress4ar android:id67ORid/progress7 stFle67Nandroid:attr/progress4ar2tFle!oriKontal7 android:laFout Eidth67fill parent7 android:laFout height67Erap content7 /M L/)inear)aFoutM
-&%
+ere, our style attribute S not a style resour'e S is pointing to a themesupplie" attribute (progress4ar2tFle!oriKontal). 0& you poke through the An"roi" sour'e 'o"e, you =ill see that this is "e&ine" as being a style resour'e, spe'i&i'ally Oandroid:stFle/@idget.(rogress4ar.!oriKontal. +en'e, =e are saying to An"roi" that =e =ant our (rogress4ar style" as Oandroid:stFle/@idget.(rogress4ar.!oriKontal, !ia the in"ire'tion o& N android:attr/progress4ar2tFle!oriKontal. 5his portion o& the An"roi" style system is !ery un"er-"o'umente", to the point =here 8oogle itsel& re'ommen"s you look at the An"roi" sour'e 'o"e listing the !arious styles to see =hat is possible. 5his is one pla'e =here inheriting a style be'omes important. 0n the &irst e;ample sho=n in this se'tion, =e inherite" &rom &heme.!olo, be'ause =e spe'i&i'ally =ante" the activated4ackgroundIndicator !alue &rom &heme.!olo. 5hat !alue might not e;ist in other styles, or it might not ha!e the !alue =e =ant.
-&0
0t spe'i&ies that the a'ti!ity shoul" take o!er the entire s'reen, remo!ing the status bar on An"roi" 1.; an" 2.; "e!i'es ( android:EindoE9ullscreen set to true). 0t also spe'i&ies that the M'ontent o!erlayM S a layout that =raps aroun" your a'ti!ity7s 'ontent !ie= S shoul" be set to nothing (android:EindoE+ontent"verlaF set to Onull), ha!ing the e&&e't o& remo!ing the title bar. A theme might also spe'i&y other styles that are applie" to spe'i&i' =i"gets. *or e;ample, it is in the root theme (&heme) that =e see,
Litem name67progress4ar2tFle!oriKontal7MOandroid:stFle/@idget.(rogress4ar.!oriKontalL/ itemM
pointing to ho= =e are able to in our (rogress4ar =i"get, an" =e 'oul" 'reate our o=n theme that re-"e&ines progress4ar2tFle!oriKontal to point to some other style (e.g., =e =ant to 'hange the roun"e" re'tangle use" &or the a'tual progress bar image itsel&).
-&2
CHAPTER &6
*or the &irst year or so sin'e An"roi" 1.0 =as release", all pro"u'tion An"roi" "e!i'es ha" the same s'reen resolution (+-8A, .20;<80) an" siKe (aroun" ..AM P 3'm). %tarting in the &all o& 2003, though, "e!i'es starte" arri!ing =ith =i"ely "isparate s'reen siKes an" resolutions, &rom tiny J-8A (2<0;.20) s'reens to mu'h larger W-8A (<80;800) s'reens. An", in the &all o& 2010, tablets an" 8oogle 5- "e!i'es appeare", o&&ering yet more s'reen siKes. >& 'ourse, users =ill be e;pe'ting your appli'ation to be &un'tional on all o& these, an" perhaps take a"!antage o& larger s'reen siKes to a"" greater !alue. 5o that en", An"roi" 1./ a""e" ne= 'apabilities to help better support these "i&&ering s'reen siKes an" resolutions, an" these 'apabilities ha!e been e;ten"e" in subseRuent An"roi" releases. 5he An"roi" "o'umentation has e;tensi!e 'o!erage o& the me'hani's o& han"ling multiple s'reen siKes. ?ou are en'ourage" to rea" that page along =ith this 'hapter, to get the best un"erstan"ing o& ho= best to 'ope =ith, an" perhaps take a"!antage o&, multiple s'reen siKes. A&ter a number o& se'tions "is'ussing the options an" theory, the 'hapter =raps =ith an in"epth look at making a &airly simple appli'ation han"le multiple s'reen siKes =ell.
-&7
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
0& your appli'ation is installe" on a "e!i'e =ith a larger s'reen, An"roi" =ill run your appli'ation in M'ompatibility mo"eM, s'aling e!erything base" on the a'tual s'reen siKe. %o, suppose you ha!e a ><pG sRuare #28 &ile, an" An"roi" install an" runs your appli'ation on a "e!i'e =ith the stan"ar" physi'al siKe but a W-8A resolution (a so-'alle" Mhigh-"ensityM s'reen). An"roi" might s'ale your #28 &ile to be C0pG =hen it "isplays it, so it =ill take up the same !isible spa'e on the s'reen. >n the plus si"e, An"roi" han"les this automati'allyT on the minus si"e, bitmap s'aling algorithms ten" to make the images a bit &uKKy. An"roi" =ill blo'k your appli'ation &rom running on a "e!i'e =ith a smaller s'reen. +en'e, J-8A "e!i'es, like the +5C 5attoo, =ill be unable to get your appli'ation, e!en i& it is a!ailable on the An"roi" Market.
As an e;ample o& ho= this a&&e'ts your app, take a peek at the +ontainers/&able sample appli'ation as !ie=e" on an +5C 5attoo, =ith its J-8A s'reen,
-&8
0& your appli'ation is 'ompile" &or An"roi" 1./ or higher, An"roi" assumes that you are properly han"ling all s'reen siKes, an" there&ore =ill not run your appli'ation in M'ompatibility mo"eM. We =ill see ho= to tailor this in a later se'tion.
Whole in ,ne
5he simplest approa'h to han"ling multiple s'reen siKes in An"roi" is to "esign your user inter&a'es su'h that they automati'ally s'ale &or the s'reen siKe, =ithout any siKe-spe'i&i' 'o"e or resour'es. 0n other =or"s, Mit Gust =orksM. 5his implies, though, that e!erything you use in your user inter&a'e 'an be gra'e&ully s'ale" by An"roi" an" that e!erything =ill &it, e!en on a J-8A s'reen. +ere are some tips &or a'hie!ing this Mall in oneM solution,
-&:
5he ri'hest en!ironment &or easily spe'i&ying rules is to use ?elative)aFout. While 'ompli'ate" on the sur&a'e, ?elative)aFout "oes an e;'ellent Gob o& letting you 'ontrol your layout =hile still a"apting it to other s'reen siKes. *or e;ample, you 'an,
E;pli'itly an'hor =i"gets to the bottom or right si"e o& the s'reen, rather than hoping they =ill =in" up there 'ourtesy o& some other layout Control the "istan'es bet=een =i"gets that are M'onne'te"M (e.g., a label &or a &iel" shoul" be to the le&t o& the &iel") =ithout ha!ing to rely on pa""ing or margins
5he greatest 'ontrol &or spe'i&ying rules is to 'reate your o=n layout 'lass. *or e;ample, suppose you are 'reating a series o& appli'ations that
--<
implement 'ar" games. ?ou may =ant to ha!e a layout 'lass that kno=s about playing 'ar"s, ho= they o!erlap, =hi'h are &a'e up !ersus &a'e "o=n, ho= big to be to han"le !arying number o& 'ar"s, et'. While you 'oul" a'hie!e the "esire" look =ith, say, a ?elative)aFout, you may be better ser!e" implementing a (laFing+ard)aFout or a !and"f+ards)aFout or something that is more e;pli'itly tailore" &or your appli'ation. $n&ortunately, 'reating 'ustom layout 'lasses is un"er-"o'umente" at this point in time.
--*
An"roi" o&&ers "imensions measure" in "ensity-in"epen"ent pi;els ( dip). 5hese map 1,1 to pi;els &or a 1/0"pi s'reen (e.g., a 'lassi' +-8A An"roi" "e!i'e) an" s'ale &rom there. *or e;ample, on a 2<0"pi "e!i'e (e.g., a phone-siKe" W-8A "e!i'e), the ratio is 2,., so .-dip X .-pG at 1/0"pi X /.pG at 2<0"pi. 5he a"!antage to the user o& going =ith "ip is that the a'tual siKe o& the "imension stays the same, so !isibly there is no "i&&eren'e bet=een .-dip at 1/0"pi an" .-dip at 2<0"pi. An"roi" also o&&ers "imensions measure" in s'ale" pi;els ( sp). %'ale" pi;els, in theory, are s'ale" base" on the user7s 'hoi'e o& &ont siKe (9"%& 2+A)$ !alue in 2Fstem.2ettings).
Tailor +ade@ 6ust "or .ou $And .ou@ And .ou@ And111'
5here =ill be times, though, =hen you =ant to ha!e "i&&erent looks or beha!iors base" upon s'reen siKe or "ensity. An"roi" has =ays &or you to s=it'h out resour'es or 'o"e blo'ks base" on the en!ironment in =hi'h your appli'ation runs. When properly use" in 'ombination =ith the abo!e te'hniRues, a'hie!ing s'reen siKe- an" "ensity-in"epen"en'e is eminently possible, at least &or "e!i'es running An"roi" 1./ an" ne=er.
--&
Csupports*screensD
5he &irst step to proa'ti!ely supporting s'reen siKes is to a"" the LsupportsscreensM element to your Android#anifest.Gml &ile. 5his spe'i&ies =hi'h s'reen siKes you e;pli'itly support an" =hi'h you "o not. 5hose that you "o not =ill be han"le" by the automati' M'ompatibility mo"eM "es'ribe" pre!iously. +ere is a mani&est 'ontaining a Lsupports-screensM element,
LNGml version671.-7 encoding67utf-,7NM Lmanifest Gmlns:android67http://schemas.android.com/apk/res/android7 package67com.commonsEare.android.eu<Fou7 android:version+ode6717 android:version%ame671.-7M Lsupports-screens android:large2creens67true7 android:normal2creens67true7 android:small2creens67true7 android:anF=ensitF67true7 /M Lapplication android:label67Ostring/app name7 android:icon67OdraEable/cE7M LactivitF android:name67.$3<5ou7 android:label67Ostring/app name7M Lintent-filterM Laction android:name67android.intent.action.#AI%7 /M LcategorF android:name67android.intent.categorF.)A3%+!$?7 /M L/intent-filterM L/activitFM L/applicationM L/manifestM
5hree o& these attributes are almost sel&-e;planatory, android:small2creens, android:normal2creens, an" android:large2creens ea'h take a boolean !alue in"i'ating i& your appli'ation e;pli'itly supports those s'reens ( true) or reRuires M'ompatibility mo"eM assistan'e ( false). An"roi" 2.. has also a""e" an android:Glarge2creens &or larger tablets an" (perhaps) tele!isions. 5he android:anF=ensitF attribute in"i'ates =hether you are taking "ensity into a''ount in your 'al'ulations (true) or not (false). 0& false, An"roi" =ill preten" as though all o& your "imensions (e.g., <pG) are &or a normal-"ensity (1/0"pi) s'reen. 0& your appli'ation is running on a s'reen =ith lo=er or higher "ensity, An"roi" =ill s'ale your "imensions a''or"ingly. 0& you
---
in"i'ate that android:anF=ensitF 6 7true7, you are telling An"roi" not to "o that, putting the onus on you to use "ensity-in"epen"ent units, su'h as dip, mm, or in.
--%
--0
MlongM in"i'ates a 1/,3 or similar aspe't ratio, 'ompare" to <,.). *or e;ample, here =e test to see i& =e are running on a large s'reen,
if Pget%esourcesPQ.getConfigurationPQ.screen)aFout Z +onfiguration.2+?$$%)A5"3& 2IV$ )A?D$Q 66+onfiguration.2+?$$%)A5"3& 2IV$ )A?D$Q : // Fes8 Ee are large ; else : // no8 Ee are not ;
%imilarly, you 'an &in" out your s'reen "ensity, or the e;a't number o& pi;els in your s'reen siKe, using the =isplaF#etrics 'lass.
Mobile "e!i'e LC@s may ha!e a mu'h higher "ensity than "oes your "e!elopment ma'hine A mouse allo=s &or mu'h more pre'ise Mtou'hs'reenM input than "oes an a'tual &ingertip
Where possible, you are going to nee" to either use the emulator in ne= an" e;'iting =ays, or try to get your han"s on a'tual "e!i'es =ith alternati!e s'reen resolutions.
Density Di..ers
5he Motorola @ >0@ has a 2<0"pi, ..4-in'h, <80;8A< pi;el s'reen. 5o emulate a @ >0@ s'reen, base" on pi;el 'ount, takes up one thir" o& a 13M 1280;102< LC@ monitor, be'ause the LC@ monitor7s "ensity is mu'h lo=er than that o& the @ >0@ S aroun" 3/"pi. %o, =hen you &ire up your
--2
An"roi" emulator &or an *W-8A "isplay like that o& the @ >0@, you =ill get a massi!e emulator =in"o=. 5his is still per&e'tly &ine &or "etermining the o!erall look o& your appli'ation in an *W-8A en!ironment. egar"less o& "ensity, =i"gets =ill still align the same, siKes =ill ha!e the same relationships (e.g., Wi"get A might be t=i'e as tall as Wi"get 1, an" that =ill be true regar"less o& "ensity), an" so on. +o=e!er,
5hings that might appear to be a suitable siKe =hen !ie=e" on a 13M LC@ may be entirely too small on a mobile "e!i'e s'reen o& the same resolution 5hings that you 'an easily 'li'k upon in the emulator =ith a mouse may be mu'h too small to pi'k out on a physi'ally smaller an" "enser s'reen =hen use" =ith a &inger
--7
1y "e&ault, the M%'ale "isplay to real siKeM 'he'kbo; is un'he'ke", an" An"roi" =ill open the emulator =in"o= normally. ?ou 'an, ho=e!er, 'he'k that 'he'kbo; an" then pro!i"e t=o bits o& s'aling in&ormation, 1. 5he s'reen siKe o& the "e!i'e you =ish to emulate, in in'hes (e.g., ..4 in'hes &or the Motorola @ >0@)
2. 5he "pi o& your monitor S 'li'k the MHM button to bring up a 'al'ulator to help you "etermine =hat your "pi !alue is 5his =ill gi!e you an emulator =in"o= that more a''urately "epi'ts =hat your user inter&a'e =ill look like on a physi'al "e!i'e, at least in terms o& siKes. +o=e!er, sin'e the emulator is using &ar &e=er pi;els than =ill a "e!i'e, &onts may be "i&&i'ult to rea", images may be blo'ky, et'.
like on the @ell %treak An"roi" tablet, a 4M LC@ like on the %amsung 8ala;y 5ab), rather than simply ha!ing more pi;els in the same physi'al spa'e. +ere are some =ays you might take a"!antage o& a""itional spa'e,
Repl ce T =s #ith
Simple Activity
?ou may ha!e intro"u'e" a &ab!ost into your $0 to allo= you to "isplay more =i"gets in the a!ailable s'reen spa'e. %o long as the =i"get spa'e you Msa!eM by mo!ing them to a separate tab is more than the spa'e taken up by the tabs themsel!es, you =in. +o=e!er, ha!ing multiple tabs means more
--:
user steps to na!igate your $0, parti'ularly i& they nee" to &lip ba'k an" &orth bet=een tabs &reRuently. 0& you only ha!e t=o tabs, 'onsi"er 'hanging your $0 to o&&er a large-s'reen layout that remo!es the tabs an" puts all the =i"gets on one s'reen. 5his puts e!erything in &ront o& the user, =ithout ha!ing to s=it'h tabs all the time. 0& you ha!e three or more tabs, you probably =ill la'k s'reen spa'e to put all those tabs7 'ontents on one a'ti!ity. +o=e!er, you might 'onsi"er going hal&-an"-hal&, ha!e popular =i"gets be on the a'ti!ity all o& the time, lea!ing your &ab!ost to han"le the rest on (roughly) hal& o& the s'reen.
=xample5 =>%.ou
5o e;amine ho= to use some o& these te'hniRues, let us look at the 2creen2iKes/$3<5ou sample appli'ation. 5his appli'ation has one a'ti!ity ($3<5ou) that 'ontains a )istVieE =ith the roster o& European $nion members an" their respe'ti!e &lags. Cli'king on one o& the 'ountries brings up the mobile Wikipe"ia page &or that 'ountry.
-%<
0n the sour'e 'o"e to this book, you =ill &in" &our !ersions o& this appli'ation, as =e start =ith an appli'ation that is ignorant o& s'reen siKe an" slo=ly a"" in more s'reen-relate" &eatures.
?ou =ill note =e ha!e the Lsupports-screensM element, saying that =e in"ee" "o support all s'reen siKes. 5his blo'ks most o& the automati' s'aling that An"roi" =oul" "o i& =e sai" =e "i" not support 'ertain s'reen siKes. >ur main layout is siKe-in"epen"ent, as it is Gust a &ull-s'reen )istVieE,
LNGml version671.-7 encoding67utf-,7NM L)istVieE Gmlns:android67http://schemas.android.com/apk/res/android7 android:id67Oandroid:id/list7 android:laFout Eidth67fill parent7 android:laFout height67fill parent7 /M
-%*
*or e;ample, right no=, our &ont siKe is set to be >-dip, =hi'h =ill not !ary by s'reen siKe or "ensity. >ur $3<5ou a'ti!ity is a bit !erbose, mostly be'ause there are a lot o& E$ members, an" =e ha!e to ha!e the smarts to "isplay the &lag an" the te;t in the ro=,
package com.commonsEare.android.eu<FouJ import import import import import import import import import import import android.app.)istActivitFJ android.content.IntentJ android.net.3riJ android.os.4undleJ android.vieE.VieEJ android.vieE.VieEDroupJ android.Eidget.ArraFAdapterJ android.Eidget.ImageVieEJ android.Eidget.)istVieEJ android.Eidget.&eGtVieEJ java.util.ArraF)istJ
public class $3<5ou eGtends )istActivitF : static private ArraF)istL+ountrFM $36neE ArraF)istL+ountrFMPQJ static : $3.addPneE CountryP?.string.austria8 ?.draEable.austria8
-%&
?.string.austria urlQQJ $3.addPneE CountryP?.string.belgium8 ?.draEable.belgium8 ?.string.belgium urlQQJ $3.addPneE CountryP?.string.bulgaria8 ?.draEable.bulgaria8 ?.string.bulgaria urlQQJ $3.addPneE CountryP?.string.cFprus8 ?.draEable.cFprus8 ?.string.cFprus urlQQJ $3.addPneE CountryP?.string.cKech republic8 ?.draEable.cKech republic8 ?.string.cKech republic urlQQJ $3.addPneE CountryP?.string.denmark8 ?.draEable.denmark8 ?.string.denmark urlQQJ $3.addPneE CountryP?.string.estonia8 ?.draEable.estonia8 ?.string.estonia urlQQJ $3.addPneE CountryP?.string.finland8 ?.draEable.finland8 ?.string.finland urlQQJ $3.addPneE CountryP?.string.france8 ?.draEable.france8 ?.string.france urlQQJ $3.addPneE CountryP?.string.germanF8 ?.draEable.germanF8 ?.string.germanF urlQQJ $3.addPneE CountryP?.string.greece8 ?.draEable.greece8 ?.string.greece urlQQJ $3.addPneE CountryP?.string.hungarF8 ?.draEable.hungarF8 ?.string.hungarF urlQQJ $3.addPneE CountryP?.string.ireland8 ?.draEable.ireland8 ?.string.ireland urlQQJ $3.addPneE CountryP?.string.italF8 ?.draEable.italF8 ?.string.italF urlQQJ $3.addPneE CountryP?.string.latvia8 ?.draEable.latvia8 ?.string.latvia urlQQJ $3.addPneE CountryP?.string.lithuania8 ?.draEable.lithuania8 ?.string.lithuania urlQQJ $3.addPneE CountryP?.string.luGembourg8 ?.draEable.luGembourg8 ?.string.luGembourg urlQQJ $3.addPneE CountryP?.string.malta8 ?.draEable.malta8 ?.string.malta urlQQJ $3.addPneE CountryP?.string.netherlands8 ?.draEable.netherlands8 ?.string.netherlands urlQQJ $3.addPneE CountryP?.string.poland8 ?.draEable.poland8 ?.string.poland urlQQJ $3.addPneE CountryP?.string.portugal8 ?.draEable.portugal8 ?.string.portugal urlQQJ $3.addPneE CountryP?.string.romania8 ?.draEable.romania8 ?.string.romania urlQQJ $3.addPneE CountryP?.string.slovakia8 ?.draEable.slovakia8 ?.string.slovakia urlQQJ $3.addPneE CountryP?.string.slovenia8 ?.draEable.slovenia8 ?.string.slovenia urlQQJ $3.addPneE CountryP?.string.spain8 ?.draEable.spain8 ?.string.spain urlQQJ $3.addPneE CountryP?.string.sEeden8 ?.draEable.sEeden8 ?.string.sEeden urlQQJ $3.addPneE CountryP?.string.united kingdom8 ?.draEable.united kingdom8
-%-
?.string.united kingdom urlQQJ ; O"verride public void onCreateP4undle savedInstance2tateQ : super.onCreatePsavedInstance2tateQJ setContentViewP?.laFout.mainQJ setList$dapterPneE Country$dapterPQQJ ; O"verride protected void onListItemClickP)istVieE l8 VieE v8 int position8 long idQ : start$cti!ityPneE IntentPIntent.A+&I"% VI$@8 3ri.parsePgetStringP$3.getPpositionQ.urlQQQQJ ; static class +ountrF : int nameJ int flagJ int urlJ CountryPint name8 int flag8 int urlQ : this.name6nameJ this.flag6flagJ this.url6urlJ ; ; class +ountrFAdapter eGtends ArraFAdapterL+ountrFM : Country$dapterPQ : superP$3<5ou.this8 ?.laFout.roE8 ?.id.name8 $3QJ ; O"verride public VieE getViewPint position8 VieE convertVieE8 VieEDroup parentQ : +ountrF@rapper Erapper6nullJ if PconvertVieE66nullQ : convertVieE6getLayoutInflaterPQ.inflateP?.laFout.roE8 nullQJ Erapper6neE Country#rapperPconvertVieEQJ convertVieE.setTagPErapperQJ ; else : Erapper6P+ountrF@rapperQconvertVieE.getTagPQJ ; Erapper.populate"romPgetItemPpositionQQJ returnPconvertVieEQJ ; ;
-%%
class +ountrF@rapper : private &eGtVieE name6nullJ private ImageVieE flag6nullJ private VieE roE6nullJ Country#rapperPVieE roEQ : this.roE6roEJ ; &eGtVieE get&amePQ : if Pname66nullQ : name6P&eGtVieEQroE.findViewByIdP?.id.nameQJ ; returnPnameQJ ; ImageVieE get"lagPQ : if Pflag66nullQ : flag6PImageVieEQroE.findViewByIdP?.id.flagQJ ; returnPflagQJ ; void populate"romP+ountrF nationQ : get&amePQ.setTextPnation.nameQJ get"lagPQ.setImage%esourcePnation.flagQJ ; ; ;
-%0
/M L&eGtVieE android:id67ORid/name7 android:laFout Eidth67Erap content7 android:laFout height67Erap content7 android:laFout gravitF67center verticalWright7 android:teGt2iKe67.mm7 /M L/)inear)aFoutM
...an" W-8A,
-%8
....an" J-8A,
-%:
2o= our &ont is a 'onsistent siKe, an" large enough to mat'h the &lags.
5he
5his e&&e't is subtle in this 'ase an" =ill not really sho= up =ell in this book.
-sin! the Sp ce
While the a'ti!ity looks &ine on W-8A in portrait mo"e, it really =astes a lot o& spa'e in lan"s'ape mo"e,
-0<
We 'an put that to better use by ha!ing the Wikipe"ia 'ontent appear right on the main a'ti!ity =hen in large-s'reen lan"s'ape mo"e, instea" o& ha!ing to spa=n a separate 1ro=ser a'ti!ity. 5o "o this, =e &irst must 'lone the main.Gml layout into a res/laFout-largeland ren"ition that in'orporates a @ebVieE =i"get, as seen in 2creen2iKes/$3<5ou <,
LNGml version671.-7 encoding67utf-,7NM L)inear)aFout Gmlns:android67http://schemas.android.com/apk/res/android7 android:laFout Eidth67fill parent7 android:laFout height67fill parent7 M L)istVieE android:id67Oandroid:id/list7 android:laFout Eidth67fill parent7 android:laFout height67fill parent7 android:laFout Eeight6717 /M L@ebVieE android:id67ORid/broEser7 android:laFout Eidth67fill parent7 android:laFout height67fill parent7 android:laFout Eeight6717 /M L/)inear)aFoutM
5hen, =e nee" to a"Gust our a'ti!ity to look &or that @ebVieE an" use it =hen &oun", "e&aulting to laun'hing a 1ro=ser a'ti!ity other=ise,
O"verride public void onCreateP4undle savedInstance2tateQ :
-0*
O"verride protected void onListItemClickP)istVieE l8 VieE v8 int position8 long idQ : 2tring url6getStringP$3.getPpositionQ.urlQJ if PbroEser66nullQ : start$cti!ityPneE IntentPIntent.A+&I"% VI$@8 3ri.parsePurlQQQJ ; else : broEser.load*rlPurlQJ ;
"igure **%1 =>%.ou@ landscape W;(A $8<<x%8< pixels'@ set for normal density@ and sho)ing the embedded Web;ie)
>& 'ourse, i& the user 'li'ks a link in the Wikipe"ia page, that =ill open up the &ull 1ro=ser, &or easier sur&ing.
-0&
2ote that testing this !ersion o& the a'ti!ity, to see this beha!ior, reRuires a bit o& e;tra emulator =ork. 1y "e&ault, An"roi" sets up W-8A "e!i'es as being high-"ensity, meaning W-8A is not large in terms o& resour'e sets, but rather normal. ?ou =ill nee" to 'reate a "i&&erent emulator A-@ that is set &or normal (medium) "ensity, =hi'h =ill result in a large s'reen siKe.
,h t I. It Is "ot
Bro#serF
>& 'ourse, $3<5ou "oes 'heat a bit. 5he se'on" a'ti!ity is a 1ro=ser (or @ebVieE in the embe""e" &orm), not some a'ti!ity o& your o=n 'reation. 5hings get slightly more 'ompli'ate" i& the se'on" a'ti!ity is some a'ti!ity o& yours, =ith many =i"gets in a layout, an" you =ant to use it both as an a'ti!ity (&or smaller s'reens) an" ha!e it embe""e" in your main a'ti!ity $0 (&or larger s'reens). 5he best =ay to approa'h this problem, &or An"roi" 1./ an" ne=er, is to employ the ne= &ragments system. While this =as intro"u'e" =ith An"roi" ..0, the An"roi" Compatibility Library makes &ragments a!ailable in earlier !ersions o& An"roi". 5he basi' use o& &ragments S 'omplete =ith another e"ition o& the E$<?ou sample S =ill be 'o!ere" later in this book.
-0-
CHAPTER &8
*ebruary 2011 sa= the intro"u'tion o& An"roi" ..0 an" a $0 para"igm that, &or no=, =e =ill re&er to by the An"roi" ..0 'o"ename o& M+oney'ombM. An"roi" ..0 itsel& is e;'lusi!ely targete" at tablets, though elements o& the +oney'omb $0 system =ill make it into &uture !ersions o& An"roi" that support phones as =ell. 5he +oney'omb $0 is perhaps the biggest single 'hange in An"roi" sin'e An"roi" 0.3, be&ore the &irst phones =ere a!ailable. An", the impa'ts o& +oney'omb =ill resoun" through the An"roi" e'osystem &or a long time, as people a"Gust to make use o& =hat =e no= ha!e. Lea"ing o&& some 'hapters on the +oney'omb 'apabilities, this 'hapter is &o'use" more on Mthe big pi'tureM o& +oney'omb an" its pla'e =ithin An"roi".
Why 3oneycombF
0n prin'iple, An"roi"7s original phone-'entri' $0 'an run on tablets. A&ter all, a &e= tablets shippe" =ith An"roi" 2.2 support, su'h as the %amsung 8ala;y 5ab. Clearly, those manu&a'turers thought the An"roi" o& the time =as strong enough &or their tablet "e!i'es. 5hat being sai", as you get into larger tablets (e.g., the Motorola F>>M =ith its 10M "iagonal s'reen), the An"roi" phone $0 starts to be'ome more...'lunky. While appli'ations 'an s'ale up to use the larger s'reen, the
-07
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
"e&ault =ay to s'ale up is Gust to make e!erything bigger, &reRuently resulting in a lot o& =aste" spa'e. While an email 'lient on a phone might "e"i'ate an a'ti!ity to sho=ing the list o& emails in the inbo;, an email 'lient on a tablet really ought to sho= the list o& emails plus something else, su'h as the 'ontent o& a sele'te" email. We ha!e the room S =e may as =ell use it. %imilarly, the "epen"en'e on menus, =hile reasonable on a phone, makes less sense on a tablet. We ha!e the spa'e to sho= more o& those &un'tions right on the s'reen. +i"ing them in menus makes them less "is'o!erable to users an" reRuire e;tra 'li'ks to a''ess. %o, +oney'omb is "esigne" to retain the essen'e o& the An"roi" user e;perien'e, =hile allo=ing appli'ations to (relati!ely) gra'e&ully take a"!antage o& the spa'e that is a!ailable.
"igure **01 The Android -1< app launcher@ as seen on the emulator
-08
5he status bar at the top o& the s'reen has been mo!e" to the bottom o& the s'reen an" is no= 'alle" the Msystem barM. >n the le&t are on-s'reen buttons &or 1ACD, +>ME, an" re'ent tasks (=hat &ormerly =oul" take a long-press o& the +>ME button). >n the right, along =ith the 'lo'k an" signalPbattery strength in"i'ators, =ill be =here noti&i'ation i'ons go S the 'on'ept o& noti&i'ations =ill be 'o!ere" later in this book. 0& =e look at an appli'ation that has not been optimiKe" &or An"roi" ..;, =e see mu'h the same $0,
5he only substanti!e "i&&eren'e is the ne= i'on in the system bar, =hi'h =ill bring up an An"roi" 2.; options menu, i& the appli'ation has one. +o=e!er, An"roi" ..0-optimiKe" appli'ations =ill look a bit "i&&erent,
-0:
>n the top, =e see the Ma'tion barM. 5he a'tion bar largely repla'es options menus, e!en though you "e&ine one the same =ay you "e&ine an options menu. +ere, M@oneM an" MCan'elM are the &irst t=o options menu 'hoi'es. 5he i'on to the right represents other options menu 'hoi'es, =hi'h =ill appear =hen the user taps that i'on,
-2<
"igure **81 The options menu portion of the action bar in Android -1<
5he i'on in the upper-le&t is tappable, an" in this 'ase takes the user MupM in the hierar'hy o& a'tions in this appli'ation, in"i'ate" by the north=estpointing arro=hea". 0n this 'ase, going MupM &rom a""ing a ne= 'onta't takes you to the list o& e;isting 'onta'ts,
-2*
0n An"roi" 2.;, the 'onta'ts $0 =oul" ha!e one a'ti!ity =ith the list o& 'onta'ts, an" a separate a'ti!ity to !ie= the "etails o& that 'onta't. 0n An"roi" ..0, these are 'ombine" in a single a'ti!ity. ?et, in the &uture, =hen the +oney'omb $0 is applie" to phones, the same 'o"e base =ill re!ert ba'k to the one-a'ti!ity-per-operation mo"e &rom be&ore. 5his is a''omplishe" through the use o& &ragments, =hi'h =ill be 'o!ere" later in this book.
5o the right o& that is a sear'h &iel", built into the a'tion bar. Also, the menu items on the right si"e o& the a'tion bar no= represent a mi; o& options menu items (e.g., a"" a ne= 'onta't) an" 'onte;t menu items &or the sele'te" 'onta't (e.g., e"it the 'onta't). *un'tionally, e!erything is there that you =oul" see in An"roi" 2.;. 0t has been reorganiKe" &or An"roi" ..;, =ith an emphasis on taking &ormerly hi""en things like menus an" a""ing them to the main s'reen &or ease o& "is'o!ery an" use.
-2&
"igure *&*1 The "ancyK/ynamicTabs sample application@ updated for Android -1<
0& you are 'reating your o=n 'ustom styles, there are t=o that you =ill =ant to 'onsi"er inheriting &rom,
-2-
1.
&heme.!olo
-2%
5he resulting appli'ation =orks &ine on ol"er "e!i'es, but =ith no other 'hanges, =e get this on a Motorola F>>M,
"igure *&&1 The =>%.ou sample application@ lightly updated for Android -1<
0& you =ant to take a"!antage o& some o& the ne=er &eatures "es'ribe" in this set o& +oney'omb 'hapters, you =ill also nee" to think about ba'k=ar"s 'ompatibility, to make sure that =hat you "o =ill =ork su''ess&ully on both ne=er an" ol"er !ersions o& An"roi". 5his topi' is also 'o!ere" later in this book. 0& you ha!e resour'es, su'h as styles, that nee" to be !ersion-spe'i&i', you 'an use the -v11 resour'e set su&&i;. *or e;ample, you 'oul" ha!e a res/values/stFles.Gml an" a res/values-v11/stFles.Gml S the latter =oul" be use" on +oney'omb, the &ormer on ol"er !ersions o& An"roi".
-20
1ut &irst, =e nee" to e;plain =hat all is possible &or you to use to take &ull a"!antage o& the +oney'omb $0, =hi'h is the point o& the ne;t &e= 'hapters.
-22
CHAPTER &9
>ne o& the easiest =ays &or an appli'ation to blen" in better =ith the +oney'omb $0 is to make use o& the a'tion bar, "es'ribe" in an earlier 'hapter. What makes it MeasyM is that most o& the basi' &un'tionality is ba'k=ar"s-'ompatible S your +oney'omb settings =ill not 'ause the appli'ation to 'rash on earlier !ersions o& An"roi". 5he sample proGe't sho=n in this 'hapter is #enus/Action4ar, =hi'h e;ten"s the #enus/Inflation proGe't sho=n in a pre!ious 'hapter.
-27
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
Laction android:name67android.intent.action.#AI%7/M LcategorF android:name67android.intent.categorF.)A3%+!$?7/M L/intent-filterM L/activitFM L/applicationM Luses-sdk android:min2dkVersion67<7 android:target2dkVersion67117 /M Lsupports-screens android:Glarge2creens67true7 android:large2creens67true7 android:normal2creens67true7 android:small2creens67true7 android:anF=ensitF67true7/M L/manifestM
5his =ill 'ause your options menu to appear in the upper-right 'orner o& the s'reen, un"er a menu i'on in the a'tion bar, as sho=n in an earlier 'hapter. Also, your a'ti!ity7s i'on =ill appear in the upper-le&t 'orner, =ith your a'ti!ity7s name (&rom the android:label attribute in the mani&est) alongsi"e o& it. While this gi!es you the basi' +oney'omb look an" &eel S in'lu"ing the +oney'omb-theme" =i"gets, su'h as the ne= 2pinner =ith the southeastpointing arro=hea" S you ha!e not really 'hange" the user e;perien'e all that mu'h.
5o
"o
this,
-28
a"Ga'ent to the item7s i'on, instea" o& only the i'on being put in the a'tion bar. *or e;ample, the #enus/Action4ar proGe't7s options.Gml menu resour'e has android:shoEAsAction on the &irst t=o menu items,
LNGml version671.-7 encoding67utf-,7NM Lmenu Gmlns:android67http://schemas.android.com/apk/res/android7M Litem android:id67ORid/add7 android:title67Add7 android:icon67OdraEable/ic menu add7 android:action)aFout67OlaFout/add7 android:shoEAsAction67if?oom7/M Litem android:id67ORid/reset7 android:title67?eset7 android:icon67OdraEable/ic menu refresh7 android:shoEAsAction67if?oomWEith&eGt7/M Litem android:id67ORid/about7 android:title67About7 android:icon67OdraEable/ic menu info details7 /M L/menuM
5he se'on" menu item S &or resetting the 'ontents o& our list S is a normal M=ith te;tM a'tion bar button. 5he &irst menu item "oes something a bit "i&&erent, =hi'h =e =ill e;amine later in this 'hapter. 5he &a't that the thir" menu item "oes not ha!e android:shoEAsAction means that it =ill remain in the menu, e!en i& there is room in the a'tion bar itsel&. 2ote that the Ca!a 'o"e "oes not 'hange S on+reate"ptions#enuPQ an" on"ptionsItem2electedPQ &or our Inflation=emo a'ti!ity "o not nee" to be a"Guste" be'ause menu items are promote" into the a'tion bar !ia the menu FML resour'e alone.
O"verride public boolean onOptionsItemSelectedP#enuItem itemQ : sEitch Pitem.getItemIdPQQ : case ?.id.add: addPQJ returnPtrueQJ case ?.id.reset: init$dapterPQJ returnPtrueQJ case ?.id.about: case android.?.id.home: &oast .makeTextPthis8 7Action 4ar 2ample App78 &oast.)$%D&! )"%DQ .showPQJ returnPtrueQJ ; ; returnPsuper.onOptionsItemSelectedPitemQQJ
0n a proGe't =ith multiple a'ti!ities, though, the e;pe'tation is that 'li'king the logo =ill take you to the MhomeM a'ti!ity &or the appli'ation, =hate!er that might mean.
that the #enus/Inflation sample =rappe" in a 'ustom Alert=ialog &or =hen the MA""M options menu item =as 'li'ke". 5hat original layout looke" like this,
LNGml version671.-7 encoding67utf-,7NM L)inear)aFout Gmlns:android67http://schemas.android.com/apk/res/android7 android:orientation67horiKontal7 android:laFout Eidth67fill parent7 android:laFout height67Erap content7 M L&eGtVieE android:teGt67@ord:7 android:laFout Eidth67Erap content7 android:laFout height67Erap content7 /M L$dit&eGt android:id67ORid/title7 android:laFout Eidth67fill parent7 android:laFout height67Erap content7 android:laFout margin)eft67<dip7 /M L/)inear)aFoutM
We nee" to make some minor a"Gustments to this layout to use it &or the a'tion bar,
LNGml version671.-7 encoding67utf-,7NM L)inear)aFout Gmlns:android67http://schemas.android.com/apk/res/android7 android:orientation67horiKontal7 android:laFout Eidth67fill parent7 android:laFout height67Erap content7 M L&eGtVieE android:teGt67@ord:7 android:laFout Eidth67Erap content7 android:laFout height67Erap content7 android:teGtAppearance67Oandroid:stFle/&eGtAppearance.#edium7 /M L$dit&eGt android:id67ORid/title7 android:laFout Eidth67fill parent7 android:laFout height67Erap content7 android:laFout margin)eft67<dip7 android:Eidth6710-sp7 android:input&Fpe67teGt7 android:imeActionId671CC/7 android:ime"ptions67action=one7 /M L/)inear)aFoutM
-7*
%pe'i&i'ally,
We a"" an android:teGtAppearance attribute to the &eGtVieE representing our MA"",M 'aption. 5he android:teGtAppearance attribute allo=s us to "e&ine the &ont type, siKe, 'olor, an" =eight (e.g., bol") in one shot. We spe'i&i'ally use a Mmagi' !alueM o& Oandroid:stFle/&eGtAppearance.#edium, so the 'aption mat'hes the styling o& the M esetM label on our other menu item =e promote" to the a'tion bar. We spe'i&y android:Eidth6710-sp7 &or the $dit&eGt =i"get, be'ause android:laFout Eidth67fill parent7 is ignore" in the a'tion bar S other=ise, =e =oul" take up the =hole rest o& the bar. We spe'i&y android:input&Fpe67teGt7 on the $dit&eGt =i"get, =hi'h, among other things, =ill restri't us to a single line o& te;t. We also spe'i&y android:imeActionId an" android:ime"ptions on the =i"get to 'ontrol the Ma'tion buttonM o& the so&t keyboar", so =e get 'ontrol =hen the user presses NEnterO on the so&t keyboar".
$dit&eGt
-7&
+o=e!er, =hile the user 'oul" type something in, =e ha!e no =ay to &in" out =hat they type in, =hen they are "one, et'.
asso'iate" =ith our MA""M option. 5his =ill return the root o& the !ie= hierar'hy in&late" &rom the layout resour'e =e "e&ine" in the android:action)aFout attribute in the menu resour'e. 0n this 'ase, that is the )inear)aFout &rom res/laFout/add.Gml, so =e nee" to 'all findVieE4FIdPQ on it to get the $dit&eGt,
O"verride public boolean onCreateOptionsMenuP#enu menuQ : neE MenuInflaterPthisQ.inflateP?.menu.option8 menuQJ $dit&eGt add6P$dit&eGtQmenu .findItemP?.id.addQ .get$ctionViewPQ .findViewByIdP?.id.titleQJ add.setOn+ditor$ctionListenerPon2earchQJ ; returnPsuper.onCreateOptionsMenuPmenuQQJ
5hen, =e 'an 'all set"n$ditorAction)istenerPQ on the $dit&eGt, to register an "n$ditorAction)istener obGe't that =ill get 'ontrol =hen the user 'li'ks NEnterO on the har" or so&t keyboar",
private &eGtVieE."n$ditorAction)istener on2earch6 neE &eGtVieE.On+ditor$ctionListenerPQ : public boolean on+ditor$ctionP&eGtVieE v8 int actionId8 HeF$vent eventQ : if Pevent66null WW event.get$ctionPQ66HeF$vent.A+&I"% 3(Q : add#ordPvQJ Input#ethod#anager imm6PInput#ethod#anagerQgetSystemSer!icePI%(3& #$&!"= 2$?VI+$QJ imm.hideSoftInput"rom#indowPv.get#indowTokenPQ8 -QJ ; ; ;J returnPtrueQJ
5hat in turn 'alls an add@ordPQ metho", supplying the $dit&eGt, =hi'h a""s the =or" to the list !ia the ArraFAdapter,
private void add#ordP&eGtVieE titleQ : ArraFAdapterL2tringM adapter6PArraFAdapterL2tringMQgetList$dapterPQJ
-7%
adapter.addPtitle.getTextPQ.toStringPQQJ ;
5hat same add@ordPQ metho" 'an also be use" &rom the addPQ metho" that "isplays the Alert=ialog...e!en though that =ill not be use" on a +oney'omb tablet, sin'e the MA""M menu 'hoi'e no longer e;ists as a menu 'hoi'e,
private void addPQ : final VieE addVieE6getLayoutInflaterPQ.inflateP?.laFout.add8 nullQJ neE Alert=ialog.BuilderPthisQ .setTitleP7Add a @ord7Q .setViewPaddVieEQ .set)ositi!eButtonP7"H78 neE =ialogInterface.OnClickListenerPQ : public void onClickP=ialogInterface dialog8 int Ehich4uttonQ : add#ordPP&eGtVieEQaddVieE.findViewByIdP?.id.titleQQJ ; ;Q .set&egati!eButtonP7+ancel78 nullQ .showPQJ ;
5he net result is that =hen the user types in something in the MA"",M &iel" an" presses NEnterO, the =or" is a""e" to the bottom o& the list. 5his sa!es some 'li'ks o!er the phone $0, as the user "oes not ha!e to open the options menu, "oes not ha!e to 'li'k on the options menu item, an" "oes not ha!e to 'li'k a button on the "ialog. 2ote that our "n$ditorAction)istener "oes one more thing than simply a"" the =or" to the list, it hi"es the so&t keyboar". 0t "oes this using the Input#ethod#anager, as =as seen in a pre!ious 'hapter.
0&, ho=e!er, you =ant to use the 'ustom !ie= &eature, you ha!e a problem S the getActionVieEPQ metho" is ne= to A#0 Le!el 11 an" =ill be una!ailable on ol"er !ersions o& An"roi". 5his means you =ill nee" to 'ompile &or A#0 Le!el 11 (e.g., set your E'lipse target or Ant default.properties to re&eren'e android-11), an" you =ill nee" to take steps to a!oi" 'alling getActionVieEPQ on ol"er "e!i'es. We =ill e;plore ho= to pull o&& this &eat in a later 'hapter.
-72
CHAPTER &:
"ragments
#erhaps the largest 'hange in An"roi" ..0 &a'ing An"roi" "e!elopers is the intro"u'tion o& the &ragment system. 5his is an optional layer you 'an put bet=een your a'ti!ities an" your =i"gets, "esigne" to help you re'on&igure your a'ti!ities to support s'reens both large (e.g., tablets) an" small (e.g., phones). +o=e!er, they also a"" an e;tra layer o& 'omple;ity, one that =ill take the An"roi" "e!eloper 'ommunity some time to a"Gust to. +en'e, you =ill &in" &e=er blog posts or sample apps using &ragments, Gust be'ause they =ere intro"u'e" so long a&ter An"roi" itsel& =as. 5his 'hapter =ill 'o!er basi' uses o& &ragments, in'lu"ing supporting &ragments on pre-An"roi" ..0 "e!i'es.
ntroducing "ragments
*ragments are not =i"gets, like 4utton or $dit&eGt. *ragments are not 'ontainers, like )inear)aFout or ?elative)aFout. *ragments are not a'ti!ities. ather, &ragments aggregate =i"gets an" 'ontainers. *ragments then 'an be pla'e" into a'ti!ities S sometimes se!eral &ragments &or one a'ti!ity, sometimes one &ragment per a'ti!ity.
-77
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
"ragments
An" the reason &or this is the !ariation in An"roi" s'reen siKes.
The Pro=lem
A tablet has a larger s'reen than "oes a phone. A 5- has a larger s'reen than "oes a tablet. 0t =oul" seem to make sense to try to take a"!antage o& that e;tra s'reen spa'e, mu'h as =e outline" in the 'hapter on han"ling multiple s'reen siKes. 5here, =e pro&ile" an $3<5ou sample appli'ation, e!entually =in"ing up =ith an a'ti!ity that =oul" loa" in a "i&&erent layout &or larger-siKe" s'reens, one that ha" an embe""e" @ebVieE =i"get. 5he a'ti!ity =oul" "ete't that =i"get7s e;isten'e an" use it &or loa"ing Web 'ontent relate" to a sele'te" 'ountry, rather than laun'hing a separate bro=ser a'ti!ity or some a'ti!ity only 'ontaining a @ebVieE. +o=e!er, this =as a &airly tri!ial s'enario. 0magine i&, instea" o& a @ebVieE, =e ha" a &able)aFout 'ontaining 28 =i"gets. >n larger-siKe" s'reens, =e =ant the &able)aFout in the same a'ti!ity as an a"Ga'ent )istVieET on smaller s'reens, =e =ant the &able)aFout to be in a separate a'ti!ity, sin'e there =oul" not be enough room other=ise. 5o "o this using pre+oney'omb te'hnology, =e =oul" either nee" to "upli'ate all o& the &able)aFout-han"ling logi' in both a'ti!ities, or 'reate an a'ti!ity base 'lass an" hope they 'an both inherit &rom it, or turn the &able)aFout an" its 'ontents into a 'ustom VieEDroup, or something. An" that =oul" Gust be &or one su'h s'enario S multiply that by many a'ti!ities in a larger appli'ation, an" the 'omple;ity mounts.
-78
"ragments
0n the 'ase o& $3<5ou, =e =ill ha!e t=o &ragments. >ne &ragment represents the list o& 'ountries. 5he other &ragment represents the "etails &or that 'ountry (in our 'ase, a @ebVieE). >n a larger-s'reen "e!i'e, =e =ill =ant both &ragments to be in one a'ti!ity, =hile a smaller-s'reen "e!i'e =ill house those &ragments in separate a'ti!ities. 5his gi!es us the same bene&its as =e got =ith the last !ersion o& $3<5ou, =ith users getting more in&ormation in &e=er 'li'ks =hen they ha!e larger s'reens. ?et the te'hniRues =e "emonstrate =ith &ragments =ill be more s'alable, able to han"le more 'omple; $0 patterns than the simple @ebVieE-or-not 'ase o& $3<5ou. 0n this 'ase, our entire $0 =ill be insi"e o& &ragments. 5hat is not ne'essary. *ragments are an Mopt-inM te'hnology S you only nee" them &or the parts o& your $0 that 'oul" appear in "i&&erent a'ti!ities in "i&&erent s'enarios. 0n &a't, your a'ti!ities that "o not 'hange at all (say, a help s'reen) might not use &ragments =hatsoe!er. *ragments also gi!e us a &e= other bells an" =histles, in'lu"ing,
5he ability to "ynami'ally a"" &ragments, base" on user intera'tion. *or e;ample, the 8mail appli'ation initially sho=s a )ist9ragment o& the user7s mail &ol"ers. 5apping a &ol"er a""s a se'on" )ist9ragment to the s'reen, sho=ing the 'on!ersations in that &ol"er. 5apping a 'on!ersation a""s a thir" 9ragment to the s'reen, sho=ing the messages in that 'on!ersation. 5he ability to animate these "ynami' &ragments as they 'ome on an" o&& the s'reen. *or e;ample, =hen the user taps a 'on!ersation in 8mail, the &ol"er )ist9ragment sli"es o&& the s'reen to the le&t, the 'on!ersations )ist9ragment sli"es le&t an" shrinks to take up less room, an" the messages 9ragment sli"es in &rom the right. Automati' 1ACD button management &or "ynami' &ragments. *or e;ample, =hen the user presses 1ACD =hen !ie=ing the messages 9ragment, that 9ragment sli"es o&& to the right, the 'on!ersations )ist9ragment sli"es right an" e;pan"s to &ill more o& the s'reen, an" the &ol"ers )ist9ragment sli"es ba'k in &rom the le&t. 2one o& that has to be manage" by "e!elopers S simply "es'ribing a""ing the "ynami' &ragment !ia a 9ragment&ransaction allo=s An"roi" to
-7:
"ragments
A &ragment 'an a"" options to the options menu, an" there&ore to the a'tion bar. Call set!as"ptions#enuPQ in on+reatePQ o& your &ragment to register an interest in this, then o!erri"e on+reate"ptions#enuPQ an" on"ptionsItem2electedPQ in the &ragment the same =ay you might in an a'ti!ity. A &ragment 'an also register =i"gets to ha!e 'onte;t menus, an" han"le those 'onte;t menus, the same =ay as an a'ti!ity =oul". 5he a'tion bar 'an ha!e tabs S repla'ing a &ab!ost S =here ea'h tab7s 'ontents is a &ragment. %imilarly, the a'tion bar 'an ha!e a Mna!igation mo"eM =ith a 2pinner to s=it'h bet=een mo"es, =here ea'h mo"e is represente" by a &ragment.
-8<
"ragments
%in'e the ACL only supports ba'k to An"roi" 1./, An"roi" 1.A "e!i'es =ill not be able to use &ragment-base" appli'ations. 5his is a !ery small per'entage o& the An"roi" "e!i'e spe'trum at this time S ..0L as o& the time o& this =riting.
Gener l 5r !ments
1esi"es inheriting &rom 9ragment, the only thing reRuire" o& a &ragment is to o!erri"e on+reateVieEPQ. 5his =ill be 'alle" as part o& putting the &ragment on the s'reen. ?ou nee" to return a VieE that represents the bo"y o& the &ragment. Most likely, you =ill 'reate your &ragment7s $0 !ia an FML layout &ile, an" on+reateVieEPQ =ill in&late that &ragment layout &ile. *or e;ample, here is =etails9ragment &rom $3<5ou 0, =hi'h =ill =rap aroun" our @ebVieE to sho= the Web 'ontent &or a gi!en 'ountry,
import import import import import import android.support.v<.app.9ragmentJ android.os.4undleJ android.vieE.)aFoutInflaterJ android.vieE.VieEJ android.vieE.VieEDroupJ android.Eebkit.@ebVieEJ
public class =etails9ragment eGtends 9ragment : O"verride public VieE onCreateViewP)aFoutInflater inflater8 VieEDroup container8 4undle savedInstance2tateQ :
-8*
"ragments
2ote that =e are inheriting not &rom android.app.9ragment but &rom 5he latter is the 9ragment implementation &rom the ACL, an" so this 'an be use" a'ross An"roi" !ersions.
android.support.v<.app.9ragment.
5he on+reateVieEPQ implementation in&lates a layout =hi'h happens to ha!e a @ebVieE in it,
LNGml version671.-7 encoding67utf-,7NM L@ebVieE Gmlns:android67http://schemas.android.com/apk/res/android7 android:id67ORid/broEser7 android:laFout Eidth67fill parent7 android:laFout height67fill parent7 /M
0t also e;poses a load3rlPQ metho", to be use" by a hosting a'ti!ity to tell the &ragment that it is time to "isplay some Web 'ontent an" supply the $ L &or "oing the same. 5he implementation o& load3rlPQ in =etails9ragment uses getVieEPQ to retrie!e the VieE 'reate" in on+reateVieEPQ, &in"s the @ebVieE in it, an" "elegates the load3rlPQ 'all to the @ebVieE. 5here are a myria" o& other li&e'y'le metho"s a!ailable on 9ragment. 5he more important ones in'lu"e mirrors o& the stan"ar" on+reatePQ, on2tartPQ, on?esumePQ, on(ausePQ, on2topPQ, an" on=estroFPQ o& an a'ti!ity. %in'e the &ragment is the one =ith the =i"gets, the &ragment =ill implement more o& the business logi' that &ormerly might ha!e resi"e" in the a'ti!ity &or these metho"s. *or e;ample, in on(ausePQ or on2topPQ, sin'e the user may not be returning to you, you may =ish to sa!e any unsa!e" e"its to some temporary storage. 0n the 'ase o& =etails9ragment, there =as nothing that really Ruali&ie" here, so those li&e'y'le metho"s =ere le&t alone.
-8&
"ragments
)ist5r !ment
>ne *ragment sub'lass that is sure to be popular is )ist9ragment. 5his =raps a )istVieE in a 9ragment, "esigne" to simpli&y setting up lists o& things S 'ountries, mail &ol"ers, mail 'on!ersations, et'. %imilar to a )istActivitF, all you nee" to "o is 'all set)istAdapterPQ =ith your 'hosen an" 'on&igure" )istAdapter, plus o!erri"e on)istItem+lickPQ to respon" to =hen the user 'li'ks on a ro= in the list. 0n $3<5ou 0, =e ha!e a +ountries9ragment that represents the list o& a!ailable 'ountries. 0t initialiKes the )istAdapter in onActivitF+reatedPQ, =hi'h is 'alle" a&ter on+reatePQ has =rappe" up in the a'ti!ity that hol"s the &ragment,
O"verride public void on$cti!ityCreatedP4undle stateQ : super.onCreatePstateQJ setList$dapterPneE Country$dapterPQQJ if PstateX6nullQ : int position6state.getIntP2&A&$ +!$+H$=8 -1QJ if PpositionM-1Q : getListViewPQ.setItemCheckedPposition8 trueQJ ; ; ;
5he 'o"e "ealing =ith the 4undle supplie" to on+reatePQ =ill be e;plaine" a bit later in this 'hapter. 5he +ountrFAdapter is nearly i"enti'al to the one &rom past $3<5ou samples, e;'ept that there is no get)aFoutInflaterPQ metho" on a 9ragment, so =e ha!e to use the stati' fromPQ metho" on )aFoutInflater an" supply our a'ti!ity !ia getActivitFPQ,
class +ountrFAdapter eGtends ArraFAdapterL+ountrFM : Country$dapterPQ : superPget$cti!ityPQ8 ?.laFout.roE8 ?.id.name8 $3QJ ; O"verride
-8-
"ragments
public VieE getViewPint position8 VieE convertVieE8 VieEDroup parentQ : +ountrF@rapper Erapper6nullJ if PconvertVieE66nullQ : convertVieE6)aFoutInflater .fromPget$cti!ityPQQ .inflateP?.laFout.roE8 nullQJ Erapper6neE Country#rapperPconvertVieEQJ convertVieE.setTagPErapperQJ ; else : Erapper6P+ountrF@rapperQconvertVieE.getTagPQJ ; Erapper.populate"romPgetItemPpositionQQJ ; ; returnPconvertVieEQJ
-8%
"ragments
static : $3.addPneE CountryP?.string.austria8 ?.draEable.austria8 ?.string.austria urlQQJ $3.addPneE CountryP?.string.belgium8 ?.draEable.belgium8 ?.string.belgium urlQQJ $3.addPneE CountryP?.string.bulgaria8 ?.draEable.bulgaria8 ?.string.bulgaria urlQQJ $3.addPneE CountryP?.string.cFprus8 ?.draEable.cFprus8 ?.string.cFprus urlQQJ $3.addPneE CountryP?.string.cKech republic8 ?.draEable.cKech republic8 ?.string.cKech republic urlQQJ $3.addPneE CountryP?.string.denmark8 ?.draEable.denmark8 ?.string.denmark urlQQJ $3.addPneE CountryP?.string.estonia8 ?.draEable.estonia8 ?.string.estonia urlQQJ $3.addPneE CountryP?.string.finland8 ?.draEable.finland8 ?.string.finland urlQQJ $3.addPneE CountryP?.string.france8 ?.draEable.france8 ?.string.france urlQQJ $3.addPneE CountryP?.string.germanF8 ?.draEable.germanF8 ?.string.germanF urlQQJ $3.addPneE CountryP?.string.greece8 ?.draEable.greece8 ?.string.greece urlQQJ $3.addPneE CountryP?.string.hungarF8 ?.draEable.hungarF8 ?.string.hungarF urlQQJ $3.addPneE CountryP?.string.ireland8 ?.draEable.ireland8 ?.string.ireland urlQQJ $3.addPneE CountryP?.string.italF8 ?.draEable.italF8 ?.string.italF urlQQJ $3.addPneE CountryP?.string.latvia8 ?.draEable.latvia8 ?.string.latvia urlQQJ $3.addPneE CountryP?.string.lithuania8 ?.draEable.lithuania8 ?.string.lithuania urlQQJ $3.addPneE CountryP?.string.luGembourg8 ?.draEable.luGembourg8 ?.string.luGembourg urlQQJ $3.addPneE CountryP?.string.malta8 ?.draEable.malta8 ?.string.malta urlQQJ $3.addPneE CountryP?.string.netherlands8 ?.draEable.netherlands8 ?.string.netherlands urlQQJ $3.addPneE CountryP?.string.poland8 ?.draEable.poland8 ?.string.poland urlQQJ $3.addPneE CountryP?.string.portugal8 ?.draEable.portugal8 ?.string.portugal urlQQJ $3.addPneE CountryP?.string.romania8 ?.draEable.romania8 ?.string.romania urlQQJ $3.addPneE CountryP?.string.slovakia8 ?.draEable.slovakia8 ?.string.slovakia urlQQJ $3.addPneE CountryP?.string.slovenia8 ?.draEable.slovenia8 ?.string.slovenia urlQQJ $3.addPneE CountryP?.string.spain8 ?.draEable.spain8 ?.string.spain urlQQJ $3.addPneE CountryP?.string.sEeden8 ?.draEable.sEeden8 ?.string.sEeden urlQQJ
-80
"ragments
Persistent Hi!hli!ht
>ne thing leaps out at you =hen you use &ragment-base" appli'ations like 8mail. When you tap on a ro= in a list, an" another &ragment is sho=n (or up"ate") =ithin the same a'ti!ity, the ro= you tappe" remains highlighte". 5his runs 'ounter to the tra"itional use o& a )istVieE, =here the list sele'tor is only present =hen using a @-pa", tra'kball, or similar pointing "e!i'e. 5he purpose is to sho= the user the 'onte;t o& the a"Ga'ent &ragment. 5he a'tual implementation "i&&ers &rom =hat you might e;pe't. 5hese )istVieE =i"gets are a'tually implementing +!"I+$ #"=$ 2I%D)$, =hat normally =oul" be ren"ere" using a ?adio4utton along the right si"e o& the ro=s. 0n a )ist9ragment, though, the typi'al styling &or a single-'hoi'e )ist9ragment is !ia an Ma'ti!ate"M ba'kgroun". 0n $3<5ou 0, this is han"le" !ia the ro= layout ( res/laFout/roE.Gml) use" by our +ountrFAdapter,
LNGml version671.-7 encoding67utf-,7NM L)inear)aFout Gmlns:android67http://schemas.android.com/apk/res/android7 android:laFout Eidth67fill parent7 android:laFout height67Erap content7
-82
"ragments
android:padding67>dip7 android:min!eight67Nandroid:attr/list(referredItem!eight7 stFle67OstFle/activated7 M LImageVieE android:id67ORid/flag7 android:laFout Eidth67Erap content7 android:laFout height67Erap content7 android:laFout gravitF67center verticalWleft7 android:padding?ight67<dip7 /M L&eGtVieE android:id67ORid/name7 android:laFout Eidth67Erap content7 android:laFout height67Erap content7 android:laFout gravitF67center verticalWright7 android:teGt2iKe67.mm7 /M L/)inear)aFoutM
?ou =ill noti'e the stFle attribute, pointing to an activated style. 5hat is "e&ine" by $3<5ou 0 as a lo'al style, !ersus one pro!i"e" by the operating system. 0n &a't, it has to ha!e t=o implementations o& the style, be'ause the Ma'ti!ate"M 'on'ept is ne= to An"roi" ..0 an" 'annot be use" in pre!ious !ersions o& An"roi". %o, $3<5ou 0 has res/values/stFles.Gml =ith a ba'k=ar"s-'ompatible empty style,
LNGml version671.-7 encoding67utf-,7NM LresourcesM LstFle name67activated7M L/stFleM L/resourcesM
0t also has res/values-v11/stFles.Gml. 5he -v11 resour'e set su&&i; means that this =ill only be use" on A#0 Le!el 11 (An"roi" ..0) an" higher. +ere, the style inherits &rom the stan"ar" An"roi" Mholographi'M theme an" uses the stan"ar" a'ti!ate" ba'kgroun" 'olor,
LNGml version671.-7 encoding67utf-,7NM LresourcesM LstFle name67activated7 parent67android:&heme.!olo7M Litem name67android:background7MN android:attr/activated4ackgroundIndicatorL/itemM L/stFleM L/resourcesM
-87
"ragments
0n +ountries9ragment, the a'ti!ity =ill let us kno= i& +ountries9ragment appears alongsi"e =etails9ragment S there&ore nee"ing single-'hoi'e mo"e S !ia a enable(ersistent2electionPQ metho",
public void ena'le)ersistentSelectionPQ : getListViewPQ.setChoiceModeP)istVieE.+!"I+$ #"=$ 2I%D)$QJ ;
Also, in on)istItem+lickPQ, +ountries9ragment M'he'ksM the ro= the user 'li'ke" upon, thereby enabling the persistent highlight,
O"verride public void onListItemClickP)istVieE l8 VieE v8 int position8 long idQ : l.setItemCheckedPposition8 trueQJ if PlistenerX6nullQ : listener.onCountrySelectedP$3.getPpositionQQJ ; ;
(the listener obGe't an" 'all to on+ountrF2electedPQ =ill be e;plaine" later in this 'hapter)
-88
"ragments
2. ?ou 'an a"" them on the &ly !ia 9ragment#anager an" a 9ragment&ransaction. 5his gi!es more ≤ibility, but a""s a "egree o& 'omple;ity. 5his te'hniRue is not 'o!ere" in this book. >ne big limitation o& "ealing =ith multiple s'reen siKes is that the layouts nee" to ha!e the same starting &ragments &or any 'on&iguration 'hange. %o, a small-s'reen !ersion o& an a'ti!ity an" a large-s'reen !ersion o& an a'ti!ity 'an ha!e "i&&erent mi;es o& &ragment, but a portrait layout an" a lan"s'ape layout &or the same s'reen siKe must ha!e the same &ragments "e&ine". >ther=ise, =hen the s'reen is rotate", An"roi" =ill ha!e problems, trying to =ork =ith a &ragment that "oes not e;ist, &or e;ample. We =ill also nee" to =ork out 'ommuni'ations bet=een our &ragments an" our a'ti!ities. 5he a'ti!ities are the ones "e&ining =hat &ragments they hol", so they typi'ally kno= the 'lasses that implement those &ragments an" =ill
-8:
"ragments
be able to 'all metho"s on them "ire'tly. 5he &ragments, though, only kno= that they are hoste" by some a'ti!ity, an" that a'ti!ity may "i&&er &rom 'ase to 'ase. +en'e, the typi'al pattern =ill be to use inter&a'es &or &ragment-Oa'ti!ity 'ommuni'ation,
@e&ine an inter&a'e &or the metho"s that the &ragment =ill =ant to 'all on its a'ti!ity (or some other obGe't supplie" by that a'ti!ity) 5he a'ti!ity pro!i"es an implementation o& that inter&a'e !ia some setter metho" on the &ragment =hen the &ragment is 'reate" 5he &ragment uses that inter&a'e implementation as nee"e"
We =ill see all o& this as =e =ork through the $3<5ou 0 a'ti!ities an" their 'orrespon"ing layouts.
E-23ou
0n the earlier !ersions o& the $3<5ou proGe't, =e ha" only one a'ti!ity, also name" $3<5ou. 0n $3<5ou 0, though, =e =ill ha!e t=o a'ti!ities,
$3<5ou
=ill han"le "isplaying the +ountries9ragment in all s'reen siKes, plus the =etails9ragment on larger s'reens
=etailsActivitF =ill
While =e 'oul" probably get a=ay =ith ha!ing $3<5ou laun'h the bro=ser a'ti!ity &or smaller s'reens, rather than ha!e a =etailsActivitF host a @ebVieE-only =etails9ragment, the latter approa'h is more realisti' &or more &ragment-base" appli'ations. With that in min", let7s take a look at the pie'es o& the $3<5ou a'ti!ity.
The ) yout
*or normal-s'reen "e!i'es, =e =ant to Gust "isplay the +ountries9ragment. 5hat is a''omplishe" !ia res/laFout/main.Gml Gust ha!ing the appropriate LfragmentM element,
-:<
"ragments
LNGml version671.-7 encoding67utf-,7NM Lfragment Gmlns:android67http://schemas.android.com/apk/res/android7 class67com.commonsEare.android.eu<Fou.+ountries9ragment7 android:id67ORid/countries7 android:laFout Eidth67fill parent7 android:laFout height67fill parent7 /M
5he class attribute in"i'ates =hat Ca!a 'lass implements the &ragment. >ther=ise, this layout is unremarkable. 2ote that &ragments "o not get liste" in the mani&est &ile the =ay a'ti!ities "o.
-:*
"ragments
android:orientation67horiKontal7 android:laFout Eidth67fill parent7 android:laFout height67fill parent7M Lfragment class67com.commonsEare.android.eu<Fou.+ountries9ragment7 android:id67ORid/countries7 android:laFout Eeight67C-7 android:laFout Eidth67-pG7 android:laFout height67fill parent7 /M Lfragment class67com.commonsEare.android.eu<Fou.=etails9ragment7 android:id67ORid/details7 android:laFout Eeight67/-7 android:laFout Eidth67-pG7 android:laFout height67fill parent7 /M L/)inear)aFoutM
2ote that =e are responsible &or the positioning o& the &ragments, so here =e use a horiKontal )inear)aFout to =rap aroun" the t=o LfragmentM elements.
5he +ountries9ragment hol"s onto an instan'e o& +ountrF)istener, supplie" by the hosting a'ti!ity,
public void setCountryListenerP+ountrF)istener listenerQ : this.listener6listenerJ ; -:&
"ragments
An", =hen the user 'li'ks on a 'ountry an" triggers on)istItem+lickPQ, +ountries9ragment 'alls the on+ountrF2electedPQ metho" on the inter&a'e,
O"verride public void onListItemClickP)istVieE l8 VieE v8 int position8 long idQ : l.setItemCheckedPposition8 trueQJ if PlistenerX6nullQ : listener.onCountrySelectedP$3.getPpositionQQJ ; ;
The Activity
5he $3<5ou a'ti!ity is not long, though it is a bit tri'ky,
package com.commonsEare.android.eu<FouJ import import import import import import import android.content.IntentJ android.content.res.+onfigurationJ android.net.3riJ android.os.4undleJ android.support.v<.app.9ragmentJ android.support.v<.app.9ragmentActivitFJ android.vieE.VieEJ
public class $3<5ou eGtends 9ragmentActivitF implements +ountrF)istener : private boolean detailsInline6falseJ O"verride public void onCreateP4undle savedInstance2tateQ : super.onCreatePsavedInstance2tateQJ setContentViewP?.laFout.mainQJ +ountries9ragment countries 6P+ountries9ragmentQgetSupport"ragmentManagerPQ .find"ragmentByIdP?.id.countriesQJ countries.setCountryListenerPthisQJ 9ragment f6getSupport"ragmentManagerPQ.find"ragmentByIdP?.id.detailsQJ detailsInline6PfX6null ZZ Pget%esourcesPQ.getConfigurationPQ.orientation66 +onfiguration."?I$%&A&I"% )A%=2+A($QQJ if PdetailsInlineQ : countries.ena'le)ersistentSelectionPQJ ;
-:-
"ragments
else if PfX6nullQ : f.getViewPQ.setVisi'ilityPVieE.D"%$QJ ; ; O"verride public void onCountrySelectedP+ountrF cQ : 2tring url6getStringPc.urlQJ if PdetailsInlineQ : PP=etails9ragmentQgetSupport"ragmentManagerPQ .find"ragmentByIdP?.id.detailsQQ .load*rlPurlQJ ; else : Intent i6neE IntentPthis8 =etailsActivitF.classQJ i.put+xtraP=etailsActivitF.$]&?A 3?)8 urlQJ start$cti!ityPiQJ ; ; ;
>ur mission in on+reatePQ is to =ire up our &ragments. 5he &ragments themsel!es are 'reate" by our 'all to set+ontentVieEPQ, in&lating our layout an" the &ragments "e&ine" therein. 0n a""ition, though, $3<5ou,
*in"s
+ountries9ragment an" registers itsel& +ountrF)istener, sin'e $3<5ou implements that inter&a'e.
the
as
the
*in"s the =etails9ragment, i& it e;ists. 0& it e;ists an" =e are in lan"s'ape mo"e, =e tell the +ountries9ragment to enable the persistent highlight, to remin" the user =hat "etails are being loa"e" on the right. 0& =etails9ragment e;ists, but =e are in portrait mo"e, =e a'tually "o not =ant =etails9ragment but nee" it to be 'onsistent =ith the layout mo"e, so =e mark the &ragment7s 'ontents as being D"%$. >ther=ise, the =etails9ragment "oes not e;ist, an" so =e "o not ha!e to "o anything spe'ial.
0n An"roi" ..0, getting the 9ragment#anager &or 'alls like find9ragment4FIdPQ is a''omplishe" !ia get9ragment#anagerPQ. 5he ACL, ho=e!er, "e&ines a separate get2upport9ragment#anagerPQ, to ensure you are =orking =ith the ACL7s implementation o& 9ragment#anager an" to =ork a'ross the =i"er range o& An"roi" !ersions.
-:%
"ragments
0n a""ition, sin'e $3<5ou implements the +ountrF)istener inter&a'e, it must implement on+ountrF2electedPQ. +ere, $3<5ou notes =hether =e shoul" be routing to an inline e"ition o& =etails9ragment or not. 0& =e are, then on+ountrF2electedPQ passes the +ountrF to the =etails9ragment, so it loa"s that 'ountry7s Web page. >ther=ise, =e laun'h the =etailsActivitF, supplying the $ L as an e;tra.
Det ilsActivity
5he =etailsActivitF =ill be use" in 'ases =here the =etails9ragment is not being sho=n in the $3<5ou a'ti!ity, in'lu"ing,
When the "e!i'e has a normal s'reen siKe an" there&ore "oes not ha!e the =etails9ragment in the layout When the "e!i'e has a large s'reen in the portrait siKe an" there&ore $3<5ou is hi"ing its o=n =etails9ragment
The ) yout
5he layout Gust has our LfragmentM element in it, sin'e there is nothing else to sho=,
LNGml version671.-7 encoding67utf-,7NM Lfragment Gmlns:android67http://schemas.android.com/apk/res/android7 class67com.commonsEare.android.eu<Fou.=etails9ragment7 android:id67ORid/details7 android:laFout Eidth67fill parent7 android:laFout height67fill parent7 /M
The Activity
=etailsActivitF simply passes the $ L &rom the Intent =etails9ragment, telling it =hat Web 'ontent to "isplay,
package com.commonsEare.android.eu<FouJ import android.support.v<.app.9ragmentActivitFJ import android.content.IntentJ
e;tra on to the
-:0
"ragments
import android.net.3riJ import android.os.4undleJ public class =etailsActivitF eGtends 9ragmentActivitF : public static final 2tring $]&?A 3?)67com.commonsEare.android.eu<Fou.$]&?A 3?)7J O"verride public void onCreateP4undle savedInstance2tateQ : super.onCreatePsavedInstance2tateQJ setContentViewP?.laFout.detailsQJ =etails9ragment details 6P=etails9ragmentQgetSupport"ragmentManagerPQ .find"ragmentByIdP?.id.detailsQJ details.load*rlPgetIntentPQ.getString+xtraP$]&?A 3?)QQJ ; ;
-:2
"ragments
-:7
CHAPTER &;
An"roi" is going to un"ergo rapi" e!olution o!er the ne;t &e= years. #erhaps, in time, the rate o& 'hange =ill "e'line some. +o=e!er, &or the here an" no=, you ha!e to assume signi&i'ant An"roi" releases e!ery /-12 months, an" 'hanges to the lineup o& possible An"roi" har"=are on an ongoing basis. %o, =hile right no=, the &o'us o& An"roi" is phones, soon you =ill see An"roi" netbooks, An"roi" tablets, An"roi" me"ia players, an" so on. Many o& these 'hanges =ill ha!e little impa't on your e;isting 'o"e. %ome, though, =ill ne'essitate at least ne= roun"s o& testing &or your appli'ations, an" perhaps 'hanges to those appli'ations base" upon the test results. 0n this 'hapter, =e 'o!er a number o& the areas =hi'h may 'ause you trouble in the &uture as An"roi" e!ol!es, an" ho= to "eal =ith them.
-::
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
Deep your !ie= hierar'hies shallo= S on'e you "ri&t into "ouble"igit "epth, you are in'reasingly likely to run out o& sta'k spa'e 0& you en'ounter a 2tack"verfloE$Gception, an" the sta'k tra'e looks like it is some=here in the mi""le o& "ra=ing your =i"gets, your !ie= hierar'hy is probably too 'omple;
Ch n!in! Resources
5he 'ore An"roi" team may 'hange resour'es =ith an An"roi" upgra"e, an" those may ha!e une;pe'te" e&&e'ts in your appli'ation. *or e;ample, in An"roi" 1.A, they 'hange" the sto'k 4utton ba'kgroun", to allo= &or smaller buttons. +o=e!er, appli'ations that impli'itly relie" upon the &ormer larger minimum siKe =oun" up MbreakingM an" nee"ing some $0 a"Gustment. %imilarly, appli'ations 'an reuse publi' resour'es, su'h as i'ons, a!ailable insi"e o& An"roi" proper. While "oing so sa!es some storage spa'e, many o& these resour'es are publi' by ne'essity an" are not 'onsi"ere" part o& the %@D. *or e;ample, har"=are manu&a'turers may 'hange the i'ons to &it some alternati!e $0 look-an"-&eel. elying upon the e;isting ones to al=ays
%<<
look as they "o is a bit "angerous. ?ou are better ser!e" 'opying those resour'es out o& the An"roi" open sour'e proGe't into your o=n 'o"e base.
3andling AP Changes
5he 'ore An"roi" team has generally "one a goo" Gob o& keeping A#0s stable, an" supporting a "epre'ation mo"el =here they 'hange A#0s. 0n An"roi", being "epre'ate" "oes not mean it is going a=ay, Gust that its 'ontinue" use is "is'ourage". An", o& 'ourse, ne= A#0s are release" =ith e!ery ne= An"roi" up"ate. Changes to the A#0s are =ell-"o'umente" =ith ea'h release !ia an A#0 "i&&eren'es report. $n&ortunately, the An"roi" Market S the primary "istribution 'hannel &or An"roi" appli'ations S only allo=s you to uploa" one A#D &or ea'h appli'ation. +en'e, you nee" that one A#D to "eal =ith as many An"roi" !ersions as possible. Many times, your 'o"e =ill MGust =orkM an" not reRuire 'hanging. >ther times, though, you =ill nee" to make a"Gustments, parti'ularly i& you =ant to support ne= A#0s on ne= !ersions =hile not breaking on ol" !ersions. Let us e;amine some te'hniRues &or han"ling these 'ases.
%<*
proGe'ts, primarily to "etermine =hat !ersion o& the %@D buil" tools =ill be use" to buil" your proGe't. A target 'ombines an A#0 le!el =ith an in"i'ator o& =hether or not the target in'lu"es 8oogle A#0s (e.g., 8oogle Maps support). An A#0 le!el is an integer representing a !ersion o& the An"roi" A#0. Ea'h An"roi" >% release that makes 'hanges to the An"roi" A#0 triggers a ne= A#0 le!el. %o, =e ha!e,
An"roi" 1.Ar1, 1.Ar2, an" 1.Ar. all using A#0 Le!el C An"roi" 1./r1 an" 1./r2 using A#0 Le!el < An"roi" 2.0 using A#0 Le!el . An"roi" 2.0.1 using A#0 Le!el 0 An"roi" 2.1 using A#0 Le!el / An"roi" 2.2 using A#0 Le!el , An"roi" 2.. using A#0 Le!el * An"roi" 2.... using A#0 Le!el 1An"roi" ..0 using A#0 Le!el 11
8oogle maintains a Web page outlining =hi'h !ersions o& An"roi" are in use to"ay, base" on reRuests ma"e to the An"roi" Market.
those "e!i'es in the An"roi" Market listings, shoul" you ele't to publish !ia that "istributor. 0& you skip this attribute, An"roi" assumes you =ork on all An"roi" A#0 !ersions. 5hat may be true, but it is rather "angerous to assume i& you ha!e not teste" it. +en'e, set android:min2dkVersion to the lo=est le!el you are testing an" are =illing to support.
%<-
o& your appli'ation, i& you "o not release an up"ate =ith a higher ma;imum %@D !ersion. 5he 'ore An"roi" team re'ommen"s not using this option an" relying upon An"roi"7s intrinsi' ba'k=ar"s 'ompatibility S parti'ularly le!eraging your android:target2dkVersion !alue S to allo= your appli'ation to 'ontinue to run on ne= An"roi" >% !ersions.
With that in min", there are three primary tri'ks to "eal =ith this situation, outline" in the &ollo=ing se'tions.
Detectin! Cl sses
#erhaps all you nee" to "o is "isable some &eatures in your app that lea" to things that are not possible on a gi!en "e!i'e. *or e;ample, maybe you ha!e an a'ti!ity that uses the ne= An"roi" ..0 M&ragmentsM &eature. ?ou 'annot su''ess&ully start that a'ti!ity on a pre-..0 "e!i'e. %topping that may Gust be a matter o& "isabling a menu 'hoi'e or 4utton or something. 5o see i& a 'ertain 'lass S say, )ist9ragment S is a!ailable to you, you 'an 'all +lass.for%amePQ. 5his =ill either return a +lass obGe't representing the reRueste" 'lass, or it =ill thro= an $Gception i& it is not a!ailable. ?ou 'an use the e;'eption han"ler as the spot to "isable the $0 paths that =oul" 'ause you to try starting an a'ti!ity that uses the una!ailable 'lass.
Re.lection
0& you nee" limite" a''ess to a 'lass that =ill not e;ist on ol"er !ersions o& An"roi", you 'an use a bit o& re&le'tion. *or e;ample, in the 'hapter on rotation, =e use" a series o& sample appli'ations that allo=e" the user to pi'k a 'onta't. 5hat relie" upon an A+&I"% (I+H Intent, using a spe'i&i' 3ri &or the 'onta'ts 'ontent pro!i"er. 0n those samples, =e spe'i&i'ally use" +ontacts+ontract, the re!ise" 'onta'ts A#0 o&&ere" in An"roi" 2.0 an" beyon". 5hat means those proGe'ts =ill not =ork on ol"er !ersions o& An"roi". +o=e!er, all =e really nee" is this magi' 3ri !alue. 0& =e 'an "e!ise a =ay to get the right 3ri &or ol"er !ersions o& An"roi", as =ell as the right 3ri &or ne=er !ersions o& An"roi", =ithout 'ausing problems, =e 'an be more ba'k=ar"s-'ompatible. *ortunately, this is &airly easy to "o =ith some re&le'tion,
%<0
static : int sdk6neE IntegerP4uild.V$?2I"%.2=HQ.intValuePQJ if PsdkM6.Q : trF : +lass claKK6+lass.for&ameP7android.provider.+ontacts+ontract'+ontacts7QJ +"%&$%& 3?I6P3riQclaKK.get"ieldP7+"%&$%& 3?I7Q.getPclaKKQJ ; catch P&hroEable tQ : )og.eP7(ick=emo78 7$Gception Ehen determining +"%&$%& 3?I78 tQJ ;
+ere, =e e;amine the A#0 le!el o& the "e!i'e, by looking at 4uild.V$?2I"%.2=H (=e 'oul" use 4uild.V$?2I"%.2=H I%&, but that =as only a""e" =ith An"roi" 1./ S the 'o"e sho=n here =orks on An"roi" 1.A as =ell). 0& =e are at An"roi" 2.0 (A#0 le!el A) or higher, =e use +lass.for%amePQ to get at the ne= +ontacts+ontract.+ontacts 'lass, then use re&le'tion to get at the +"%&$%& 3?I stati' "ata member on that 'lass. 0& =e are on an ol"er !ersion o& An"roi", =e simply use the 3ri publishe" by the ol"er +ontacts.(eople 'lass. %in'e =e are not "ire'tly re&eren'ing +ontacts+ontract.+ontacts in our 'o"e, =e 'an sa&ely e;e'ute this, e!en on ol"er !ersions o& An"roi".
Condition l Cl ss )o din!
e&le'tion =orks but is a pain &or anything 'omple;. Also, it is slo=er than 'alling 'o"e "ire'tly. 5he most po=er&ul te'hniRue, there&ore, is simply to organiKe your 'o"e su'h that you ha!e regular 'lasses using ne=er A#0s, but you "o not loa" those 'lasses on ol"er "e!i'es. We =ill e;amine this te'hniRue later in this book.
%<2
The Action B r
As note" in the 'hapter on the a'tion bar, many o& its basi' &eatures =ill =ork in a ba'k=ar"s-'ompatible &ashion. *or e;ample, in"i'ating than an options menu item 'an be sho=n in the a'tion bar reRuires Gust an attribute in the menu resour'e FML, an attribute that =ill be ignore" on ol"er !ersions o& An"roi". +oney'omb-'apable "e!i'es =ill put the item in the a'tion bar, =hile "e!i'es running pre!ious An"roi" !ersions =ill not. +o=e!er, not e!erything in!ol!e" =ith the a'tion bar is ba'k=ar"s 'ompatible. 0n the #enus/Action4ar sample appli'ation, =e a""e" a 'ustom VieE to the a'tion bar, to allo= people to a"" =or"s to our list =ithout "ealing =ith menus an" "ialogs. +o=e!er, this reRuire" some 'o"e that =oul" only =ork on A#0 Le!el 11 (An"roi" ..0) an" higher. More a"!an'e" a'tion bar 'apabilities S ones beyon" the s'ope o& this book S =ill ha!e similar reRuirements. ?ou nee" to arrange to only use those a'tion bar metho"s on "e!i'es that run A#0 Le!el 11 or higher. Con"itional 'lass loa"ing, outline" in a pre!ious se'tion o& this 'hapter, is one su'h te'hniRue, an" is the te'hniRue use" in the #enus/Action4ar4+ sample appli'ation. Let7s take a look at ho= this =orks.
%<7
O"verride public boolean onCreateOptionsMenuP#enu menuQ : neE MenuInflaterPthisQ.inflateP?.menu.option8 menuQJ $dit&eGt add6P$dit&eGtQmenu .findItemP?.id.addQ .get$ctionViewPQ .findViewByIdP?.id.titleQJ add.setOn+ditor$ctionListenerPon2earchQJ ; returnPsuper.onCreateOptionsMenuPmenuQQJ
5his is &ine, but it =ill only =ork on A#0 Le!el 11 an" higher, as getActionVieEPQ only e;ists &rom that A#0 le!el on=ar". +en'e, =e 'annot run this 'o"e, or e!en loa" this 'lass, on ol"er !ersions o& An"roi" =ithout getting a VerifF$rror. 5he ne= !ersion o& on+reate"ptions#enuPQ hi"es the o&&en"ing 'o"e an" 'he'ks the A#0 le!el,
O"verride public boolean onCreateOptionsMenuP#enu menuQ : neE MenuInflaterPthisQ.inflateP?.menu.option8 menuQJ $dit&eGt add6nullJ if P4uild.V$?2I"%.2=H I%&M64uild.V$?2I"% +"=$2.!"%$5+"#4Q : VieE v6!oneFcomb!elper.get$dd$ctionViewPmenuQJ if PvX6nullQ : add6P$dit&eGtQv.findViewByIdP?.id.titleQJ ; ; if PaddX6nullQ : add.setOn+ditor$ctionListenerPon2earchQJ ; ; returnPsuper.onCreateOptionsMenuPmenuQQJ
We only hi"e the 'o"e that retrie!es the VieE that =e theoreti'ally ha!e put in the a'tion bar. 0& =e are on an ol"er !ersion o& An"roi", the !"%$5+"#4 'he'k =ill &ail, an" =e =ill =in" up =ith a null VieE, so =e skip a""ing the "n$ditorAction)istener to the $dit&eGt insi"e o& that VieE.
%<8
5his has another bene&it, it =orks i& the An"roi" "e!i'e runs A#0 Le!el 11 or higher but "oes not ha!e room &or our 'ustom VieE. An"roi" tablets =ill ha!e an a'tion bar an" ha!e su&&i'ient room, but &uture +oney'omb'apable phones might ha!e an a'tion bar but la'k su&&i'ient room. 0n that 'ase, the phone =oul" lea!e the MA""M options menu item in pla'e, an" =e still =oul" =in" up =ith a null VieE. 5his 'o"e han"les that s'enarioT the original 'o"e "i" not.
!oneFcomb!elper has a single getAddActionVieEPQ stati' VieE &or the A"" a'tion bar entry, i& there is one.
%in'e =e "o not try e;e'uting any 'o"e on this 'lass e;'ept insi"e the are=e-on-!"%$5+"#4 'he'k, it is sa&e to ha!e this 'lass on ol"er !ersions o& An"roi". 5he #enus/Action4ar!+ app =orks on An"roi" 1./ an" ne=er.
%<:
5o "o this, you 'an take a"!antage o& the &a't that =hile An"roi" =ill s'ale apps up, it =ill not s'ale apps "o=n. 0n other =or"s, i& you say that you "o not support some larger s'reen siKe (e.g., android:Glarge2creens67false7 in your Lsupports-screensM element in your Android#anifest.Gml &ile), An"roi" =ill still allo= your app to run on su'h s'reens, =ith An"roi" taking steps to help your app run =ith the a""itional s'reen spa'e. +o=e!er, i& you say that you "o not support some smaller s'reen siKe (e.g., android:small2creens67false7 in your Lsupports-screensM element), An"roi" =ill not run your app, an" you =ill be &iltere" out o& the An"roi" Market &or su'h "e!i'es. +en'e, i& your appli'ation =ill only make sense &or larger-s'reen "e!i'es, use a Lsupports-screensM element like this,
Lsupports-screens android:Glarge2creens67true7 android:large2creens67true7 android:normal2creens67false7 android:small2creens67false7 android:anF=ensitF67true7/M
%*<
CHAPTER 1<
Accessing "iles
While An"roi" o&&ers stru'ture" storage, !ia 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 pre-pa'kage" =ith your appli'ation, an" one &or &iles 'reate" on-"e!i'e by your appli'ation.
Accessing "iles
appli'ation pa'kage, either the re&eren'e "ata has to be !ali" &or the &oreseeable &uture, or you =ill nee" to pro!i"e some means o& up"ating the "ata. 5he 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 alternati!e is to keep the re&eren'e "ata as-is 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& $ Ls, you 'oul" ha!e a se'on" &ile that tra'ks $ Ls a""e" by the user or re&eren'e $ Ls that =ere "elete" by the user. 0n the 9iles/2tatic sample proGe't, you =ill &in" a re=orking o& the listbo; e;ample &rom earlier, this time using a stati' FML &ile instea" o& a har"=ire" array in Ca!a. 5he layout is the same,
LNGml version671.-7 encoding67utf-,7NM L)inear)aFout Gmlns:android67http://schemas.android.com/apk/res/android7 android:orientation67vertical7 android:laFout Eidth67fill parent7 android:laFout height67fill parent7 M L&eGtVieE android:id67ORid/selection7 android:laFout Eidth67fill parent7 android:laFout height67Erap content7 /M L)istVieE android:id67Oandroid:id/list7 android:laFout Eidth67fill parent7 android:laFout height67fill parent7 android:draE2elector"n&op67false7 /M L/)inear)aFoutM
0n a""ition to that FML &ile, you also nee" an FML &ile =ith the =or"s to sho= in the list,
LEordsM LEord LEord LEord LEord LEord LEord LEord LEord value67lorem7 /M value67ipsum7 /M value67dolor7 /M value67sit7 /M value67amet7 /M value67consectetuer7 /M value67adipiscing7 /M value67elit7 /M
%*%
Accessing "iles
LEord value67morbi7 /M LEord value67vel7 /M LEord value67ligula7 /M LEord value67vitae7 /M LEord value67arcu7 /M LEord value67aliUuet7 /M LEord value67mollis7 /M LEord value67etiam7 /M LEord value67vel7 /M LEord value67erat7 /M LEord value67placerat7 /M LEord value67ante7 /M LEord value67porttitor7 /M LEord value67sodales7 /M LEord value67pellentesUue7 /M LEord value67augue7 /M LEord value67purus7 /M L/EordsM
While this FML 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. 5he Ca!a 'o"e no= must rea" in that FML &ile, parse out the =or"s, an" put them somepla'e &or the list to pi'k up,
public class 2tatic9ile=emo eGtends )istActivitF : &eGtVieE selectionJ ArraF)istL2tringM items6neE ArraF)istL2tringMPQJ O"verride public void onCreateP4undle icicleQ : super.onCreatePicicleQJ setContentViewP?.laFout.mainQJ selection6P&eGtVieEQfindViewByIdP?.id.selectionQJ trF : Input2tream in6get%esourcesPQ.open%aw%esourceP?.raE.EordsQJ =ocument4uilder builder6=ocument4uilder9actorF .newInstancePQ .newDocumentBuilderPQJ =ocument doc6builder.parsePin8 nullQJ %ode)ist Eords6doc.get+lementsByTag&ameP7Eord7QJ for Pint i6-JiLEords.getLengthPQJiRRQ : items.addPPP$lementQEords.itemPiQQ.get$ttri'uteP7value7QQJ ; in.closePQJ ; catch P&hroEable tQ : &oast %*0
Accessing "iles
setList$dapterPneE ArraFAdapterL2tringMPthis8 android.?.laFout.simple list item 18 itemsQQJ ; public void onListItemClickP)istVieE parent8 VieE v8 int position8 long idQ : selection.setTextPitems.getPpositionQ.toStringPQQJ ; ;
5he "i&&eren'es mostly lie =ithin on+reatePQ. We get an Input2tream &or the FML &ile (get?esourcesPQ.open?aE?esourceP?.raE.EordsQ), then use the builtin FML parsing logi' to parse the &ile into a @>M =ocument, pi'k out the =or" elements, then pour the !alue attributes into an ArraF)ist &or use by the ArraFAdapter. 5he resulting a'ti!ity looks the same as be&ore, sin'e the list o& =or"s is the same, Gust relo'ate",
%*2
Accessing "iles
>& 'ourse, there are e!en easier =ays to ha!e FML &iles a!ailable to you as pre-pa'kage" &iles, su'h as by using an FML resour'e. 5hat is 'o!ere" in the ne;t 'hapter. +o=e!er, =hile this e;ample use" FML, the &ile 'oul" Gust as easily ha!e been a simple one-=or"-per-line list, or in some other &ormat not han"le" nati!ely by the An"roi" resour'e system.
CeadinG Gn WritinG
ea"ing an" =riting your o=n, appli'ation-spe'i&i' "ata &iles is nearly i"enti'al to =hat you might "o in a "esktop Ca!a appli'ation. 5he key is to use open9ileInputPQ an" open9ile"utputPQ on your ActivitF or other +onteGt to get an Input2tream an" "utput2tream, respe'ti!ely. *rom that point &or=ar", it is not mu'h "i&&erent than regular Ca!a 0P> logi',
Wrap those streams as nee"e", su'h as using an Input2tream?eader or "utput2tream@riter &or te;t-base" 0P> ea" or =rite the "ata $se closePQ to release the stream =hen "one
0& t=o appli'ations both try rea"ing a notes.tGt &ile !ia open9ileInputPQ, they =ill ea'h a''ess their o=n e"ition o& the &ile. 0& you nee" to ha!e one &ile a''essible &rom many pla'es, you probably =ant to 'reate a 'ontent pro!i"er, as =ill be "es'ribe" in an up'oming 'hapter. 2ote that open9ileInputPQ an" open9ile"utputPQ "o not a''ept &ile paths (e.g., path/to/file.tGt), Gust simple &ilenames. 1elo= you =ill see the layout &or the =orl"7s most tri!ial te;t e"itor, pulle" &rom the 9iles/?ead@rite sample appli'ation,
LNGml version671.-7 encoding67utf-,7NM L$dit&eGt Gmlns:android67http://schemas.android.com/apk/res/android7 android:id67ORid/editor7 android:laFout Eidth67fill parent7 android:laFout height67fill parent7 android:single)ine67false7 android:gravitF67top7 /M
%*7
Accessing "iles
All =e ha!e here is a large te;t-e"iting =i"get...=hi'h is pretty boring. 5he Ca!a is only slightly more 'ompli'ate",
package com.commonsEare.android.readEriteJ import import import import import import import import import import import import android.app.ActivitFJ android.os.4undleJ android.vieE.VieEJ android.Eidget.4uttonJ android.Eidget.$dit&eGtJ android.Eidget.&oastJ java.io.4uffered?eaderJ java.io.9ileJ java.io.Input2treamJ java.io.Input2tream?eaderJ java.io."utput2treamJ java.io."utput2tream@riterJ
public class ?ead@rite9ile=emo eGtends ActivitF : private final static 2tring %"&$267notes.tGt7J private $dit&eGt editorJ O"verride public void onCreateP4undle icicleQ : super.onCreatePicicleQJ setContentViewP?.laFout.mainQJ editor6P$dit&eGtQfindViewByIdP?.id.editorQJ ; public void on%esumePQ : super.on%esumePQJ trF : Input2tream in6open"ileInputP%"&$2QJ if PinX6nullQ : Input2tream?eader tmp6neE InputStream%eaderPinQJ 4uffered?eader reader6neE Buffered%eaderPtmpQJ 2tring strJ 2tring4uilder buf6neE StringBuilderPQJ Ehile PPstr 6 reader.readLinePQQ X6 nullQ : buf.appendPstrR7Tn7QJ ; in.closePQJ editor.setTextPbuf.toStringPQQJ ; ; catch Pjava.io.9ile%ot9ound$Gception eQ : // thatIs "H8 Ee probablF havenIt created it Fet
%*8
Accessing "iles
public void on)ausePQ : super.on)ausePQJ trF : "utput2tream@riter out6 neE OutputStream#riterPopen"ileOutputP%"&$28 -QQJ out.writePeditor.getTextPQ.toStringPQQJ out.closePQJ ; catch P&hroEable tQ : &oast .makeTextPthis8 7$Gception: 7Rt.toStringPQ8 &oast.)$%D&! )"%DQ .showPQJ ; ; ;
*irst, =e hook into on?esumePQ, so =e get 'ontrol =hen our e"itor is 'oming ba'k to li&e, &rom a &resh laun'h or a&ter ha!ing been &roKen. We use open9ileInputPQ to rea" in notes.tGt an" pour the 'ontents into the te;t e"itor. 0& the &ile is not &oun", =e assume this is the &irst time the a'ti!ity =as run (or the &ile =as "elete" by other means), an" =e Gust lea!e the e"itor empty. *inally, =e hook into on(ausePQ, so =e get 'ontrol as our a'ti!ity gets hi""en by another a'ti!ity or is 'lose", su'h as !ia the "e!i'e7s 1ACD button. +ere, =e use open9ile"utputPQ to open notes.tGt, into =hi'h =e pour the 'ontents o& the te;t e"itor. 5he net result is that =e ha!e a persistent notepa", =hate!er is type" in =ill remain until "elete", sur!i!ing our a'ti!ity being 'lose" (e.g., !ia the 1ACD button), the phone being turne" o&&, or similar situations.
%*:
Accessing "iles
%&<
Accessing "iles
Another approa'h &or =orking =ith appli'ation-lo'al &iles is to use get9iles=irPQ. 5his returns a 9ile obGe't pointing to a pla'e in the on-boar" &lash =here an appli'ation 'an store &iles. 5his "ire'tory is =here open9ileInputPQ an" open9ile"uptutPQ =ork. +o=e!er, =hile open9ileInputPQ an" open9ile"utputPQ "o not support sub"ire'tories, the 9ile &rom get9iles=irPQ 'an be use" to 'reate an" na!igate sub"ire'tories i& "esire". 5he &iles store" here are a''essible only to your appli'ation, by "e&ault. >ther appli'ations on the "e!i'e ha!e no rights to rea", let alone =rite, to this spa'e. +o=e!er, bear in min" that some users MrootM their An"roi" phones, gaining superuser a''ess. 5hese users =ill be able to rea" an" =rite =hate!er &iles they =ish. As a result, please 'onsi"er appli'ation-lo'al &iles to be se'ure against mal=are but not ne'essarily se'ure against intereste" users.
%&*
Accessing "iles
,here to ,rite
0& you ha!e &iles that are tie" to your appli'ation that are simply too big to risk putting in the appli'ation-lo'al &ile area, you 'an use get$Gternal9iles=irPQ, a!ailable on any a'ti!ity or other +onteGt. 5his =ill gi!e you a 9ile obGe't pointing to an automati'ally-'reate" "ire'tory on e;ternal storage, uniRue &or your appli'ation. While not se'ure against other appli'ations, it "oes ha!e one big a"!antage, =hen your appli'ation is uninstalle", these &iles are automati'ally "elete", Gust like the ones in the appli'ation-lo'al &ile area. 0& you ha!e &iles that belong more to the user than to your app S pi'tures taken by the 'amera, "o=nloa"e" M#. &iles, et'. S a better solution is to use get$Gternal2torage(ublic=irectorFPQ, a!ailable on the $nvironment 'lass. 5his =ill gi!e you a 9ile obGe't pointing to a "ire'tory set asi"e &or a 'ertain type o& &ile, base" on the type you pass into get$Gternal2torage(ublic=irectorFPQ. *or e;ample, you 'an ask &or =I?$+&"?5 #"VI$2, =I?$+&"?5 #32I+, or =I?$+&"?5 (I+&3?$2 &or storing M#<, M#., or C#E8 &iles, respe'ti!ely. 5hese &iles =ill be le&t behin" =hen your appli'ation is uninstalle". ?ou =ill also &in" a get$Gternal2torage=irectorFPQ metho" on $nvironment, pointing to the root o& the e;ternal storage. 5his is no longer the pre&erre" approa'h S the metho"s "es'ribe" abo!e help keep the user7s &iles better organiKe". +o=e!er, i& you are supporting ol"er An"roi" "e!i'es, you may nee" to use get$Gternal2torage=irectorFPQ, simply be'ause the ne=er options may not be a!ailable to you.
,hen to ,rite
%tarting =ith An"roi" 1./, you =ill also nee" to hol" permissions to =ork =ith e;ternal storage (e.g., @?I&$ $]&$?%A) 2&"?AD$) S the 'on'ept o& permissions =ill be 'o!ere" in a later 'hapter. Also, e;ternal storage may be tie" up by the user ha!ing mounte" it as a $%1 storage "e!i'e. ?ou 'an use get$Gternal2torage2tatePQ (a stati' metho"
%&&
Accessing "iles
*lash 0P>, both &or the on-boar" storage an" &or Me;ternal storageM (e.g., the %@ 'ar") 2et=ork 0P>
+o=e!er, e!en here, it may not be ob!ious that you are per&orming these operations on the main appli'ation threa". 5his is parti'ularly true =hen the operations are really being "one by An"roi"7s 'o"e that you are simply 'alling. 5hat is =here 2trict#ode 'omes in. 0ts mission is to help you "etermine =hen you are "oing things on the main appli'ation threa" that might 'ause a Ganky user e;perien'e.
%&-
Accessing "iles
Ea'h poli'y "i'tates =hat 2trict#ode shoul" =at'h &or (e.g., &lash rea"s are >D but &lash =rites are not) an" ho= 2trict#ode shoul" rea't =hen you !iolate the rules, su'h as,
5he simplest thing to "o is 'all the stati' enable=efaultsPQ metho" on 2trict#ode &rom on+reatePQ o& your &irst a'ti!ity. 5his =ill set up normal operation, reporting all !iolations by simply logging to LogCat. +o=e!er, you 'an set your o=n 'ustom poli'ies !ia 4uilder obGe'ts i& you so 'hoose.
Seein! It In Action
5he &hreads/?ead@rite2trict sample appli'ation is a re=orking o& the 9iles/?ead@rite sample sho=n earlier in this 'hapter. All it a""s is a 'ustom 2trict#ode threa" poli'y,
2trict#ode.setThread)olicyPneE 2trict#ode.&hread(olicF.BuilderPQ .detect$llPQ .penaltyLogPQ .'uildPQQJ
0& you run the appli'ation, the user =ill see no "i&&eren'e. +o=e!er, you =ill ha!e a "ebug-le!el log message in LogCat =ith the &ollo=ing sta'k tra'e,
%&%
Accessing "iles
1>->, 1/:1*:<-.--*: =$43D/2trict#odeP<,-Q: 2trict#ode policF violationJ ^duration610* ms: android.os.2trict#ode'2trict#ode=isk?eadViolation: policF6>C violation6> 1>->, 1/:1*:<-.--*: =$43D/2trict#odeP<,-Q: at android.os.2trict#ode'Android4lockDuard(olicF.on?ead9rom=iskP2trict#ode.java:/<. Q 1>->, 1/:1*:<-.--*: =$43D/2trict#odeP<,-Q: at dalvik.sFstem.4lockDuard'@rapped9ile2Fstem.openP4lockDuard.java:>>,Q 1>->, 1/:1*:<-.--*: =$43D/2trict#odeP<,-Q: at android.app.+onteGtImpl.open9ile"utputP+onteGtImpl.java:<1-Q 1>->, 1/:1*:<-.--*: =$43D/2trict#odeP<,-Q: at android.content.+onteGt@rapper.open9ile"utputP+onteGt@rapper.java:1.,Q 1>->, 1/:1*:<-.--*: =$43D/2trict#odeP<,-Q: at com.commonsEare.android.readErite.?ead@rite9ile=emo.on(auseP?ead@rite9ile=emo.ja va:,>Q ...
+ere, 2trict#ode is =arning you that you attempte" a &lash =rite on the main appli'ation threa" (the threa" on =hi'h you set the 2trict#ode poli'y). 0"eally, =e =oul" re=rite this proGe't to use an AsFnc&ask or something &or =riting out the "ata.
%imply 'omment out or remo!e the 2trict#ode setup 'o"e =hen you prepare your pro"u'tion buil"s $se some sort o& pro"u'tion &lag to skip the 2trict#ode setup 'o"e =hen nee"e"
%&0
Accessing "iles
te'hniRues &or "ealing =ith this, but using re&le'tion &or 'on&iguring 2trict#ode =oul" be rather pain&ul. 5he right approa'h, there&ore, is simply to organiKe your 'o"e su'h that you ha!e regular 'lasses using ne=er A#0s, but you "o not loa" those 'lasses on ol"er "e!i'es. 5he A(IVersions/?ead@rite2trict proGe't "emonstrates this, allo=ing an appli'ation to use An"roi" 2..7s 2trict#ode =here a!ailable, or skipping it =here it is not a!ailable. When =e e;amine" 2trict#ode earlier in this se'tion , =e 'on&igure" 2trict#ode right in the on+reatePQ metho" o& our sample a'ti!ity. 5his =orks, but only on An"roi" 2.. an" ne=er. 5o allo= this to =ork on ol"er !ersions o& An"roi", =e ha!e 2trict@rapper,
package com.commonsEare.android.readEriteJ import android.os.4uildJ abstract class 2trict@rapper : static private 2trict@rapper I%2&A%+$6nullJ static public void initPQ : if P4uild.V$?2I"%.2=H I%&M64uild.V$?2I"% +"=$2.DI%D$?4?$A=Q : I%2&A%+$6neE Strict"or%eal.PQJ ; else : I%2&A%+$6neE &ot$llThatStrictPQJ ; ; static class %otAll&hat2trict eGtends 2trict@rapper : // no methods needed ; ;
5his o""-looking 'lass en'apsulates our M"o-=e-or-"on7t-=eM logi' &or "ealing =ith 2trict#ode. 0t 'ontains an initPQ metho" that, =hen 'alle", 'he'ks to see =hat !ersion o& An"roi" the appli'ation is running on, an" 'reates a singleton instan'e o& a 2trict@rapper sub'lass base" upon it S 2trict9or?ealK &or An"roi" 2.. an" higher, %otAll&hat2trict &or ol"er !ersions o& An"roi". 5he latter 'lass, a stati' inner 'lass o& 2trict@rapper,
%&2
Accessing "iles
"oes nothing, re&le'ting that there is no 2trict#ode in ne=er !ersions o& An"roi".
2trict9or?ealK 'ontains the 2trict#ode
initialiKation logi',
package com.commonsEare.android.readEriteJ import android.os.2trict#odeJ class 2trict9or?ealK eGtends 2trict@rapper : Strict"or%eal.PQ : 2trict#ode.setThread)olicyPneE 2trict#ode.&hread(olicF.BuilderPQ .detect$llPQ .penaltyLogPQ .'uildPQQJ ; ;
An", our on+reatePQ metho" o& our a'ti!ity 'alls initPQ on 2trict@rapper, to trigger 'reating the proper obGe't,
O"verride public void onCreateP4undle icicleQ : super.onCreatePicicleQJ setContentViewP?.laFout.mainQJ 2trict@rapper.initPQJ ; editor6P$dit&eGtQfindViewByIdP?.id.editorQJ
When the a'ti!ity &irst starts up, neither 2trict@rapper nor 2trict9or?ealK are loa"e" in the pro'ess. As soon as =e rea'h the initPQ statement in on+reatePQ, An"roi" loa"s 2trict@rapper into the pro'ess, but this is sa&e, as it "oes not re&er to any potentially-none;istent 'lasses. 5he initPQ metho" on 2trict@rapper then only e;e'utes a statement in!ol!ing 2trict9or?ealK i& =e are sa&ely on a supporte" !ersion o& An"roi". +en'e, 2trict9or?ealK =ill only be loa"e" into the pro'ess i& =e are on a ne=er An"roi" release, an" hen'e our use o& 2trict#ode in 2trict9or?ealK =ill not trigger a VerifF$rror. +ere, all =e nee"e" =as a bit o& initialiKation. 5he singleton pattern is use" to "emonstrate that you 'oul" e;pose an !ersion-"epen"ent A#0 implementation i& you "esire". %imply "e&ine the A#0 as abstra't metho"s
%&7
Accessing "iles
on the abstra't 'lass ( 2trict@rapper) an" ha!e !ersion-"epen"ent 'on'rete implementations o& those abstra't metho"s on the 'on'rete sub'lasses (2trict9or?ealK, %otAll&hat2trict).
Accessing "iles
=hen you 'all closePQ on the stream. 0nstea", you 'all on the 9ile"utput2tream to trigger the fsFncPQ. 2ote that this may be time-'onsuming, an" so "isk =rites shoul" be "one o&& the main appli'ation threa" =here!er pra'ti'al, su'h as !ia an AsFnc&ask.
%&:
CHAPTER 11
>sing Preferences
An"roi" has many "i&&erent =ays &or you to store "ata &or long-term use by your a'ti!ity. 5he simplest to use is the pre&eren'es system. An"roi" allo=s a'ti!ities an" appli'ations to keep pre&eren'es, in the &orm o& keyP!alue pairs (akin to a #ap), that =ill hang aroun" bet=een in!o'ations o& an a'ti!ity. As the name suggests, the primary purpose is &or you to store user-spe'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 =hate!er. >& 'ourse, you 'an store in the pre&eren'es =hate!er you like, so long as it is keye" by a 2tring an" has a primiti!e !alue (boolean, 2tring, et'.) #re&eren'es 'an either be &or a single a'ti!ity or share" among all a'ti!ities in an appli'ation. >ther 'omponents, su'h as ser!i'es, also 'an =ork =ith share" pre&eren'es.
2. get2hared(referencesPQ &rom =ithin your ActivitF (or other appli'ation +onteGt), to a''ess appli'ation-le!el pre&eren'es
%-*
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
>sing Preferences
.. get=efault2hared(referencesPQ, on (reference#anager, to get the share" pre&eren'es that =ork in 'on'ert =ith An"roi"7s o!erall pre&eren'e &rame=ork 5he &irst t=o take a se'urity mo"e parameter S the right ans=er here is #"=$ (?IVA&$, so no other appli'ations 'an a''ess the &ile. 5he get2hared(referencesPQ metho" also takes a name o& a set o& pre&eren'es S get(referencesPQ e&&e'ti!ely 'alls get2hared(referencesPQ =ith the a'ti!ity7s 'lass name as the pre&eren'e set name. 5he get=efault2hared(referencesPQ metho" takes the +onteGt &or the pre&eren'es (e.g., your ActivitF). All o& those metho"s return an instan'e o& 2hared(references, =hi'h o&&ers a series o& getters to a''ess name" pre&eren'es, returning a suitably-type" result (e.g., get4ooleanPQ to return a boolean pre&eren'e). 5he getters also take a "e&ault !alue, =hi'h is returne" i& there is no pre&eren'e set un"er the spe'i&ie" key. $nless you ha!e a goo" reason to "o other=ise, you are best ser!e" using the thir" option abo!e S get=efault2hared(referencesPQ S as that =ill gi!e you the 2hared(references obGe't that =orks =ith a (referenceActivitF by "e&ault, as =ill be "es'ribe" later in this 'hapter.
clearPQ to get ri" o& all pre&eren'es commitPQ to persist your 'hanges
5he last one is important S i& you mo"i&y pre&eren'es !ia the e"itor an" &ail to commitPQ the 'hanges, those 'hanges =ill e!aporate on'e the e"itor goes out o& s'ope. 2ote that An"roi" 2.. has an applFPQ metho", that =orks like commitPQ, but runs &aster.
%-&
>sing Preferences
Con!ersely, sin'e the pre&eren'es obGe't supports li!e 'hanges, i& one part o& your appli'ation (say, an a'ti!ity) mo"i&ies share" pre&eren'es, another part o& your appli'ation (say, a ser!i'e) =ill ha!e a''ess to the 'hange" !alue imme"iately.
ntroducing PreferenceActivity
?ou 'oul" roll your o=n a'ti!ity to 'olle't pre&eren'es &rom the user. >n the =hole, this is a ba" i"ea. 0nstea", use pre&eren'e FML resour'es an" a (referenceActivitF. WhyH >ne o& the 'ommon 'omplaints about An"roi" "e!elopers is that they la'k "is'ipline, not &ollo=ing any stan"ar"s or 'on!entions inherent in the plat&orm. *or other operating systems, the "e!i'e manu&a'turer might pre!ent you &rom "istributing apps that !iolate their human inter&a'e gui"elines. With An"roi", that is not the 'ase S but this is not a blanket permission to "o =hate!er you =ant. Where there is a stan"ar" or 'on!ention, please &ollo= it, so that users =ill &eel more 'om&ortable =ith your app an" their "e!i'e. $sing a (referenceActivitF &or 'olle'ting pre&eren'es is one su'h 'on!ention. 5he lin'hpin to the pre&eren'es &rame=ork an" (referenceActivitF is yet another FML "ata stru'ture. ?ou 'an "es'ribe your appli'ation7s pre&eren'es in an FML &ile store" in your proGe't7s res/Gml/ "ire'tory. 8i!en that, An"roi" 'an present a pleasant $0 &or manipulating those pre&eren'es, =hi'h are then store" in the 2hared(references you get ba'k &rom get=efault2hared(referencesPQ. 1elo=, you =ill &in" the pre&eren'e FML &or the (refs/2imple pre&eren'es sample proGe't,
%--
>sing Preferences
L(reference2creen Gmlns:android67http://schemas.android.com/apk/res/android7M L+heck4oG(reference android:keF67checkboG7 android:title67+heckboG (reference7 android:summarF67+heck it on8 check it off7 /M L?ingtone(reference android:keF67ringtone7 android:title67?ingtone (reference7 android:shoE=efault67true7 android:shoE2ilent67true7 android:summarF67(ick a tone8 anF tone7 /M L/(reference2creenM
5he root o& the pre&eren'e FML is a (reference2creen element. We =ill e;plain =hy it is name" that later in this 'hapterT &or no=, take it on &aith that it is a sensible name. >ne o& the things you 'an ha!e insi"e a (reference2creen element, not surprisingly, are pre&eren'e "e&initions. 5hese are sub'lasses o& (reference, su'h as +heck4oG(reference or ?ingtone(reference, as sho=n abo!e. As one might e;pe't, these allo= you to 'he'k a 'he'kbo; or 'hoose a ringtone, respe'ti!ely. 0n the 'ase o& ?ingtone(reference, you ha!e your option o& allo=ing users to 'hoose the system "e&ault ringtone, or to 'hoose Msilen'eM as a ringtone.
%-%
>sing Preferences
public class $dit(references eGtends (referenceActivitF : O"verride public void onCreateP4undle savedInstance2tateQ : super.onCreatePsavedInstance2tateQJ add)references"rom%esourceP?.Gml.preferencesQJ ; ;
As you 'an see, there is not mu'h to see. All you nee" to "o is 'all the FML resour'e 'ontaining your pre&eren'es.
add(references9rom?esourcePQ an" spe'i&y
?ou =ill also nee" to a"" this as an a'ti!ity to your Android#anifest.Gml &ile,
LNGml version671.-7 encoding67utf-,7NM Lmanifest Gmlns:android67http://schemas.android.com/apk/res/android7 package67com.commonsEare.android.simple7M Lapplication android:label67Ostring/app name7 android:icon67OdraEable/cE7M LactivitF android:name67.2imple(refs=emo7 android:label67Ostring/app name7M Lintent-filterM Laction android:name67android.intent.action.#AI%7/M LcategorF android:name67android.intent.categorF.)A3%+!$?7/M L/intent-filterM L/activitFM LactivitF android:name67.$dit(references7 android:label67Ostring/app name7M L/activitFM L/applicationM Lsupports-screens android:large2creens67true7 android:normal2creens67true7 android:small2creens67true7 android:anF=ensitF67true7/M L/manifestM
An" you =ill nee" to arrange to in!oke the a'ti!ity, su'h as &rom a menu option, here pulle" &rom 2imple(refs=emo,
public boolean onCreateOptionsMenuP#enu menuQ : menu.addP#enu.%"%$8 $=I& I=8 #enu.%"%$8 7$dit (refs7Q .setIconP?.draEable.miscQ .set$lpha'eticShortcutPIeIQJ returnPsuper.onCreateOptionsMenuPmenuQQJ ; O"verride public boolean onOptionsItemSelectedP#enuItem itemQ :
%-0
>sing Preferences
sEitch Pitem.getItemIdPQQ : case $=I& I=: start$cti!ityPneE IntentPthis8 $dit(references.classQQJ returnPtrueQJ ; returnPsuper.onOptionsItemSelectedPitemQQJ ; ;
+o=e!er, that is all that is nee"e", an" it really is not that mu'h 'o"e outsi"e o& the pre&eren'es FML. What you get &or your e&&ort is an An"roi"supplie" pre&eren'e $0,
5he 'he'kbo; 'an be "ire'tly 'he'ke" or un'he'ke". 5o 'hange the ringtone pre&eren'e, Gust 'li'k on the entry in the pre&eren'e list to bring up a sele'tion "ialog,
%-2
>sing Preferences
2ote that there is no e;pli'it Msa!eM or M'ommitM button or menu on the (referenceActivitF S 'hanges are persiste" automati'ally. 5he 2imple(refs=emo a'ti!ity, beyon" ha!ing the a&orementione" menu, also "isplays the 'urrent pre&eren'es !ia a &able)aFout,
LNGml version671.-7 encoding67utf-,7NM L&able)aFout Gmlns:android67http://schemas.android.com/apk/res/android7 android:laFout Eidth67fill parent7 android:laFout height67fill parent7 M L&able?oEM L&eGtVieE android:teGt67+heckboG:7 android:padding?ight67.dip7 /M L&eGtVieE android:id67ORid/checkboG7 /M L/&able?oEM L&able?oEM L&eGtVieE android:teGt67?ingtone:7 android:padding?ight67.dip7 /M L&eGtVieE android:id67ORid/ringtone7
%-7
>sing Preferences
/M L/&able?oEM L/&able)aFoutM
5his means the &iel"s =ill be up"ate" =hen the a'ti!ity is opene" an" a&ter the pre&eren'es a'ti!ity is le&t (e.g., !ia the 1ACD button),
%-8
>sing Preferences
>sing Preferences
Any 'hil"ren o& (reference2creen go on their o=n s'reen. 0& you nest (reference2creens, the parent s'reen "isplays the s'reen as a pla'ehol"er entry S tapping that entry brings up the 'hil" s'reen. *or e;ample, &rom the (refs/2tructured sample proGe't, here is a pre&eren'e FML &ile that 'ontains both (reference+ategorF an" neste" (reference2creen elements,
L(reference2creen Gmlns:android67http://schemas.android.com/apk/res/android7M L(reference+ategorF android:title672imple (references7M L+heck4oG(reference android:keF67checkboG7 android:title67+heckboG (reference7 android:summarF67+heck it on8 check it off7 /M L?ingtone(reference android:keF67ringtone7 android:title67?ingtone (reference7 android:shoE=efault67true7 android:shoE2ilent67true7 android:summarF67(ick a tone8 anF tone7 /M L/(reference+ategorFM L(reference+ategorF android:title67=etail 2creens7M L(reference2creen android:keF67detail7 android:title67=etail 2creen7 android:summarF67Additional preferences held in another page7M L+heck4oG(reference android:keF67checkboG>7 android:title67Another +heckboG7 android:summarF67"n. "ff. It reallF doesnIt matter.7 /M L/(reference2creenM L/(reference+ategorFM L/(reference2creenM
5he result, =hen you use this pre&eren'e FML =ith your (referenceActivitF implementation, is a 'ategoriKe" list o& elements,
%%<
>sing Preferences
"igure *-<1 The Structured proAectGs preference > @ sho)ing categories and a screen placeholder
An", i& you tap on the @etail %'reen entry, you are taken to the 'hil" pre&eren'e s'reen,
%%*
>sing Preferences
"igure *-*1 The child preference screen of the Structured proAectGs preference >
%%&
>sing Preferences
android:keF67ringtone7 android:title67?ingtone (reference7 android:shoE=efault67true7 android:shoE2ilent67true7 android:summarF67(ick a tone8 anF tone7 /M L/(reference+ategorFM L(reference+ategorF android:title67=etail 2creens7M L(reference2creen android:keF67detail7 android:title67=etail 2creen7 android:summarF67Additional preferences held in another page7M L+heck4oG(reference android:keF67checkboG>7 android:title67Another +heckboG7 android:summarF67"n. "ff. It reallF doesnIt matter.7 /M L/(reference2creenM L/(reference+ategorFM L(reference+ategorF android:title67"ther (references7M L$dit&eGt(reference android:keF67teGt7 android:title67&eGt $ntrF =ialog7 android:summarF67+lick to pop up a field for entrF7 android:dialog&itle67$nter something useful7 /M L)ist(reference android:keF67list7 android:title672election =ialog7 android:summarF67+lick to pop up a list to choose from7 android:entries67OarraF/cities7 android:entrFValues67OarraF/airport codes7 android:dialog&itle67+hoose a (ennsFlvania citF7 /M L/(reference+ategorFM L/(reference2creenM
With the &iel" ($dit&eGt(reference), 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 ()ist(reference), you supply both a "ialog title an" t=o stringarray resour'es, one &or the "isplay names, one &or the !alues. 5hese nee" to be in the same or"er S the in"e; o& the 'hosen "isplay name "etermines =hi'h !alue is store" as the pre&eren'e in the 2hared(references. *or e;ample, here are the arrays &or use by the )ist(reference sho=n abo!e,
LNGml version671.-7 encoding67utf-,7NM LresourcesM Lstring-arraF name67cities7M
%%-
>sing Preferences
LitemM(hiladelphiaL/itemM LitemM(ittsburghL/itemM LitemMAllentoEn/4ethlehemL/itemM LitemM$rieL/itemM LitemM?eadingL/itemM LitemM2crantonL/itemM LitemM)ancasterL/itemM LitemMAltoonaL/itemM LitemM!arrisburgL/itemM L/string-arraFM Lstring-arraF name67airport codes7M LitemM(!)L/itemM LitemM(I&L/itemM LitemMA4$L/itemM LitemM$?IL/itemM LitemM?=DL/itemM LitemMAV(L/itemM LitemM)%2L/itemM LitemMA""L/itemM LitemM#=&L/itemM L/string-arraFM L/resourcesM
When you bring up the pre&eren'e $0, you start =ith another 'ategory =ith another pair o& pre&eren'e entries,
"igure *-&1 The preference screen of the /ialogs proAectGs preference >
%%%
>sing Preferences
5apping the 5e;t Entry @ialog one brings up a te;t entry "ialog S in this 'ase, =ith the prior pre&eren'e entry pre-&ille"-in,
5apping the %ele'tion @ialog one brings up a sele'tion "ialog, sho=ing the "isplay names &rom the one array,
%%0
>sing Preferences
%%2
>sing Preferences
>n the minus si"e, the ne= system is not part o& the An"roi" Compatibility Library, an" as su'h 'annot "ire'tly be use" on pre-+oney'omb !ersions o& An"roi". 5hat being sai", it is possible to =ork out a ba'k=ar"s-'ompatible solution, though it may reRuire some re"esign o& your pre&eren'es, i& you ha!e a lot o& them an" ha!e been using neste" (reference2creen elements. 0n &a't, this is pretty mu'h reRuire", as the neste" (reference2creen approa'h looks lousy on +oney'omb "e!i'es.
The Honeycom= , y
0n pre-+oney'omb !ersions o& An"roi", a (referenceActivitF sub'lass =oul" loa" pre&eren'es &rom resour'e &iles, to in"i'ate =hat shoul" go on the s'reen. 0n +oney'omb, a (referenceActivitF sub'lass loa"s pre&eren'e headers &rom resour'e &iles, to in"i'ate =hat shoul" go on the s'reen.
%%7
>sing Preferences
Pre.erence He ders
-isually, pre&eren'e hea"ers are not pre&eren'e 'ategories (pla'ing a hea"er o!er a set o& pre&eren'es). ather, pre&eren'e hea"ers are the term &or the maGor 'lusters o& pre&eren'es. 5he hea"ers are liste" on the le&t, =ith the pre&eren'es &or the sele'te" hea"er sho=n on the right, as "epi'te" in the pre'e"ing s'reenshot. %o, instea" o& 'alling add(references9rom?esourcePQ, a +oney'omb (referenceActivitF =ill 'all load!eaders9rom?esourcePQ, pointing to another FML resour'e, this time "es'ribing the pre&eren'e hea"ers. *or e;ample, here is res/Gml/preference headers.Gml (refs/9ragments sample proGe't, &rom the
Lpreference-headers Gmlns:android67http://schemas.android.com/apk/res/android7M Lheader android:fragment67com.commonsEare.android.preffrags.2tock(reference9ragment7 android:title67"riginal7 android:summarF67&he original set from the other eGamples7M LeGtra android:name67resource7 android:value67preferences7 /M L/headerM Lheader android:fragment67com.commonsEare.android.preffrags.2tock(reference9ragment7 android:title67"ther 2tuff7 android:summarF67@ell8 Ee needed to shoE tEo sets here...7M LeGtra android:name67resource7 android:value67preferences>7 /M L/headerM L/preference-headersM
Ea'h LheaderM element in"i'ates the (reference9ragment sub'lass that =ill be "es'ribing the pre&eren'es that belong to the hea"er. 0n a""ition, the LheaderM "es'ribes the title an" summary &or the hea"er, along =ith an optional i'on (android:icon attribute). A LheaderM element may also ha!e one or more LeGtraM 'hil" elements, pro!i"ing a key-!alue pair o& e;tra "ata that a (reference9ragment 'an use &or 'on&iguration. 0n the e;ample sho=n abo!e, ea'h LheaderM element has one LeGtraM element "e&ining the name o& an FML resour'e that =ill hol" the pre&eren'es &or that hea"er. +en'e, the (referenceActivitF is still as short as be&ore, Gust =ith a slightly "i&&erent stru'ture,
%%8
>sing Preferences
package com.commonsEare.android.preffragsJ import android.os.4undleJ import android.preference.(referenceActivitFJ import java.util.)istJ public class $dit(references eGtends (referenceActivitF : O"verride public void onBuild(eadersP)istL!eaderM targetQ : load(eaders"rom%esourceP?.Gml.preference headers8 targetQJ ; ;
0nstea" o& "e&ining the hea"ers in on+reatePQ, you o!erri"e an on)oad!eadersPQ metho" an" 'all load!eaders9rom?esourcePQ there.
>sing Preferences
2tock(reference9ragment
package com.commonsEare.android.preffragsJ import android.os.4undleJ import android.preference.(reference9ragmentJ public class 2tock(reference9ragment eGtends (reference9ragment : O"verride public void onCreateP4undle savedInstance2tateQ : super.onCreatePsavedInstance2tateQJ int res6get$cti!ityPQ .get%esourcesPQ .getIdentifierPget$rgumentsPQ.getStringP7resource7Q8 7Gml78 get$cti!ityPQ.get)ackage&amePQQJ add)references"rom%esourcePresQJ ; ;
5o get at the e;tras, a (reference9ragment 'an 'all getArgumentsPQ, =hi'h returns a 4undle. 0n our 'ase, =e 'an get the resources e;tra !alue !ia getArgumentsPQ.get2tringP7resource7Q. 5he problem is, this is a 2tring, not a resour'e 0@. 0n or"er to 'all add(references9rom?esourcePQ, =e nee" the resour'e 0@ o& the pre&eren'e that =e only kno= by name. 5he tri'k is to use getIdentifierPQ. 5he getIdentifierPQ metho" on the ?esources obGe't S itsel& obtaine" by 'alling get?esourcesPQ on an ActivitF S =ill use re&le'tion to &in" the resour'e 0@ gi!en three pie'es o& in&ormation, 1. 5he name o& the resour'e (in this 'ase, the !alue &rom the arguments)
2. 5he type o& the resour'e (in this 'ase, Gml) .. 5he pa'kage =here this 0@ shoul" resi"e (typi'ally, your o=n pa'kage, obtaine" by 'alling get(ackage%amePQ on an ActivitF)
%0<
>sing Preferences
%o, 2tock(reference9ragment uses getIdentifierPQ to 'on!ert the resource e;tra into a resour'e 0@, =hi'h it then uses =ith add(references9rom?esourcePQ. 2ote that getIdentifierPQ is not parti'ularly &ast, sin'e it uses re&le'tion. @o not use this in a tight loop, or in getVieEPQ o& an Adapter, or any pla'e =here it may be 'alle" thousan"s o& times.
%0*
>sing Preferences
Lheader android:icon67OdraEable/something7 android:title679ancF 2tuff7 android:summarF67+lick here to transcend Four plane of eGistence7M Lintent android:action67com.commonsEare.android.#5 +32&"# A+&I"%7 /M L/headerM
5hen, so long as you ha!e an a'ti!ity =ith an Lintent-filterM spe'i&ying your "esire" a'tion (com.commonsEare.android.#5 +32&"# A+&I"%), that a'ti!ity =ill get 'ontrol =hen the user taps on the asso'iate" hea"er.
*irst,
the
%0&
>sing Preferences
add)references"rom%esourceP?.Gml.preferencesQJ add)references"rom%esourceP?.Gml.preferences>QJ ; ;
+ere, =e take a"!antage o& the &a't that add(references9rom?esourcePQ 'an be 'alle" multiple times to simply 'hain together our t=o pre&eren'e hea"ers7 =orth o& pre&eren'es. An", the options menu 'hoi'e &or opening our (referenceActivitF 'hanges to 'hoose the right one, base" on our 4uild.V$?2I"%.2=H I%& !alue,
; O"verride public boolean onOptionsItemSelectedP#enuItem itemQ : sEitch Pitem.getItemIdPQQ : case $=I& I=: if P4uild.V$?2I"%.2=H I%&L4uild.V$?2I"% +"=$2.!"%$5+"#4Q : start$cti!ityPneE IntentPthis8 $dit(references.classQQJ ; else : start$cti!ityPneE IntentPthis8 $dit(references!+.classQQJ ; ; returnPtrueQJ
+en'e, =e only use the $dit(references!+ 'lass =hen that is kno=n to be sa&e. >ther=ise, =e use the ol"er one.
%0-
CHAPTER 1&
%JLite is a !ery popular embe""e" "atabase, as it 'ombines a 'lean %JL inter&a'e =ith a !ery small memory &ootprint an" "e'ent spee". Moreo!er, it is publi' "omain, so e!eryone 'an use it. Lots o& &irms (A"obe, Apple, 8oogle, %un, %ymbian) an" open sour'e proGe'ts (MoKilla, #+#, #ython) all ship pro"u'ts =ith %JLite. *or An"roi", %JLite is Mbake" intoM the An"roi" runtime, so e!ery An"roi" appli'ation 'an 'reate %JLite "atabases. %in'e %JLite uses a %JL inter&a'e, it is &airly straight&or=ar" to use &or people =ith e;perien'e in other %JLbase" "atabases. +o=e!er, its nati!e A#0 is not C@1C, an" C@1C might be too mu'h o!erhea" &or a memory-limite" "e!i'e like a phone, any=ay. +en'e, An"roi" programmers ha!e a "i&&erent A#0 to learn S the goo" ne=s being is that it is not that "i&&i'ult. 5his 'hapter =ill 'o!er the basi's o& %JLite use in the 'onte;t o& =orking on An"roi". 0t by no means is a thorough 'o!erage o& %JLite as a =hole. 0& you =ant to learn more about %JLite an" ho= to use it in en!ironments other than An"roi", a &ine book is 5he @e&initi!e 8ui"e to %JLite by Mi'hael >=ens. Mu'h o& the sample 'o"e sho=n in this 'hapter 'omes &rom the =atabase/+onstants appli'ation. 5his appli'ation presents a list o& physi'al 'onstants, =ith names an" !alues 'ulle" &rom An"roi"7s 2ensor#anager,
%00
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
?ou 'an pop up a menu to a"" a ne= 'onstant, =hi'h brings up a "ialog to &ill in the name an" !alue o& the 'onstant,
%02
5he 'onstant is then a""e" to the list. A long-tap on an e;isting 'onstant =ill bring up a 'onte;t menu =ith a M@eleteM option S a&ter 'on&irmation, that =ill "elete the 'onstant. An", o& 'ourse, all o& this is store" in a %JLite "atabase.
%07
5o 'reate an" open a "atabase, your best option is to 'ra&t a sub'lass o& 2Y)ite"pen!elper. 5his 'lass =raps up the logi' to 'reate an" upgra"e a "atabase, per your spe'i&i'ations, as nee"e" by your appli'ation. ?our sub'lass o& 2Y)ite"pen!elper =ill nee" three metho"s,
5he 'onstru'tor, 'haining up=ar" to the 2Y)ite"pen!elper 'onstru'tor. 5his takes the +onteGt (e.g., an ActivitF), the name o& the "atabase, an optional 'ursor &a'tory (typi'ally, Gust pass null), an" an integer representing the !ersion o& the "atabase s'hema you are using.
on+reatePQ,
=hi'h passes you a 2Y)ite=atabase obGe't that you use to populate =ith tables an" initial "ata, as appropriate.
on3pgradePQ,
=hi'h passes you a 2Y)ite=atabase obGe't an" the ol" an" ne= !ersion numbers, so you 'an &igure out ho= best to 'on!ert the "atabase &rom the ol" s'hema to the ne= one. 5he simplest, albeit least &rien"ly, approa'h is to simply "rop the ol" tables an" 'reate ne= ones.
*or e;ample, here is a =atabase!elper 'lass &rom =atabase/+onstants that, in 'reates a table an" a""s a number o& ro=s, an" in on3pgradePQ M'heatsM by "ropping the e;isting table an" e;e'uting on+reatePQ,
on+reatePQ,
package com.commonsEare.android.constantsJ import import import import import import import android.content.+ontentValuesJ android.content.+onteGtJ android.database.+ursorJ android.database.2Y)$GceptionJ android.database.sUlite.2Y)ite"pen!elperJ android.database.sUlite.2Y)ite=atabaseJ android.hardEare.2ensor#anagerJ
public class =atabase!elper eGtends 2Y)ite"pen!elper : private static final 2tring =A&A4A2$ %A#$67db7J static final 2tring &I&)$67title7J static final 2tring VA)3$67value7J public Data'ase(elperP+onteGt conteGtQ : superPconteGt8 =A&A4A2$ %A#$8 null8 1QJ ; O"verride public void onCreateP2Y)ite=atabase dbQ : db.execS/LP7+?$A&$ &A4)$ constants P id I%&$D$? (?I#A?5 H$5 A3&"I%+?$#$%&8
%08
title &$]&8 value ?$A)QJ7QJ +ontentValues cv6neE ContentValuesPQJ cv.putP&I&)$8 7DravitF8 =eath 2tar I7QJ cv.putPVA)3$8 2ensor#anager.D?AVI&5 =$A&! 2&A? IQJ db.insertP7constants78 &I&)$8 cvQJ cv.putP&I&)$8 7DravitF8 $arth7QJ cv.putPVA)3$8 2ensor#anager.D?AVI&5 $A?&!QJ db.insertP7constants78 &I&)$8 cvQJ cv.putP&I&)$8 7DravitF8 Jupiter7QJ cv.putPVA)3$8 2ensor#anager.D?AVI&5 J3(I&$?QJ db.insertP7constants78 &I&)$8 cvQJ cv.putP&I&)$8 7DravitF8 #ars7QJ cv.putPVA)3$8 2ensor#anager.D?AVI&5 #A?2QJ db.insertP7constants78 &I&)$8 cvQJ cv.putP&I&)$8 7DravitF8 #ercurF7QJ cv.putPVA)3$8 2ensor#anager.D?AVI&5 #$?+3?5QJ db.insertP7constants78 &I&)$8 cvQJ cv.putP&I&)$8 7DravitF8 #oon7QJ cv.putPVA)3$8 2ensor#anager.D?AVI&5 #""%QJ db.insertP7constants78 &I&)$8 cvQJ cv.putP&I&)$8 7DravitF8 %eptune7QJ cv.putPVA)3$8 2ensor#anager.D?AVI&5 %$(&3%$QJ db.insertP7constants78 &I&)$8 cvQJ cv.putP&I&)$8 7DravitF8 (luto7QJ cv.putPVA)3$8 2ensor#anager.D?AVI&5 ()3&"QJ db.insertP7constants78 &I&)$8 cvQJ cv.putP&I&)$8 7DravitF8 2aturn7QJ cv.putPVA)3$8 2ensor#anager.D?AVI&5 2A&3?%QJ db.insertP7constants78 &I&)$8 cvQJ cv.putP&I&)$8 7DravitF8 2un7QJ cv.putPVA)3$8 2ensor#anager.D?AVI&5 23%QJ db.insertP7constants78 &I&)$8 cvQJ cv.putP&I&)$8 7DravitF8 &he Island7QJ cv.putPVA)3$8 2ensor#anager.D?AVI&5 &!$ I2)A%=QJ db.insertP7constants78 &I&)$8 cvQJ cv.putP&I&)$8 7DravitF8 3ranus7QJ cv.putPVA)3$8 2ensor#anager.D?AVI&5 3?A%32QJ db.insertP7constants78 &I&)$8 cvQJ cv.putP&I&)$8 7DravitF8 Venus7QJ cv.putPVA)3$8 2ensor#anager.D?AVI&5 V$%32QJ
%0:
db.insertP7constants78 &I&)$8 cvQJ ; O"verride public void on*pgradeP2Y)ite=atabase db8 int oldVersion8 int neEVersionQ : android.util.)og.wP7+onstants78 73pgrading database8 Ehich Eill destroF all old data7QJ db.execS/LP7=?"( &A4)$ I9 $]I2&2 constants7QJ onCreatePdbQJ ; ;
We =ill take a 'loser look at =hat on+reatePQ is "oing S in terms o& eGec2Y)PQ an" insertPQ 'alls S later in this 'hapter. 5o use your 2Y)ite"pen!elper sub'lass, 'reate an" hol" onto an instan'e o& it. 5hen, =hen you nee" a 2Y)ite=atabase obGe't to "o Rueries or "ata mo"i&i'ations, ask your 2Y)ite"pen!elper to get?eadable=atabasePQ or get@riteable=atabasePQ, "epen"ing upon =hether or not you =ill be 'hanging its 'ontents. *or e;ample, our +onstants4roEser a'ti!ity opens the "atabase in on+reatePQ as part o& "oing a Ruery,
constants+ursor6db .get%eada'leData'asePQ .raw/ueryP72$)$+& I=8 title8 value 7R 79?"# constants "?=$? 45 title78 nullQJ
When you are "one =ith the "atabase (e.g., your a'ti!ity is being 'lose"), simply 'all closePQ on your 2Y)ite"pen!elper to release your 'onne'tion. *or on3pgradePQ to =ork properly, your !ersion numbers &or your "atabase s'hema must in'rease as you mo!e &or=ar". A typi'al pattern is to start =ith 1 an" =ork your =ay up &rom there. 5here are t=o other metho"s you 'an ele't to o!erri"e in your 2Y)ite"pen!elper, i& you &eel the nee", 1. ?ou 'an o!erri"e on"penPQ, to get 'ontrol =hen somebo"y opens this "atabase. $sually, this is not reRuire".
%2<
2. An"roi" ..0 intro"u'e" on=oEngradePQ, =hi'h =ill be 'alle" i& the 'o"e reRuests an ol"er s'hema than =hat is in the "atabase presently. 5his is the 'on!erse o& on3pgradePQ S i& your !ersion numbers "i&&er, one o& these t=o metho"s =ill be in!oke". %in'e normally you are mo!ing &or=ar" =ith up"ates, you 'an usually skip on=oEngradePQ.
5his =ill 'reate a table, name" constants, =ith a primary key 'olumn name" id that is an auto-in'remente" integer (i.e., %JLite =ill assign the !alue &or you =hen you insert ro=s), plus t=o "ata 'olumns, title (te;t) an" value (a &loat, or MrealM in %JLite terms). %JLite =ill automati'ally 'reate an in"e; &or you on your primary key 'olumn S you 'oul" a"" other in"e;es here !ia some +?$A&$ I%=$] statements, i& you so 'hose to. 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. 0& you "o not 'hange your table s'hemas, you might ne!er "rop your tables or in"e;es, but i& you "o, Gust use eGec2Y)PQ to in!oke =?"( I%=$] an" =?"( &A4)$ statements as nee"e".
%2*
+akinG /ata
8i!en that you ha!e a "atabase an" one or more tables, you probably =ant to put some "ata in them an" su'h. ?ou ha!e t=o maGor approa'hes &or "oing this. ?ou 'an al=ays use eGec2Y)PQ, Gust like you "i" &or 'reating the tables. 5he eGec2Y)PQ metho" =orks &or any %JL that "oes not return results, so it 'an han"le I%2$?&, 3(=A&$, =$)$&$, et'. Gust &ine. ?our alternati!e is to use the insertPQ, updatePQ, an" deletePQ metho"s on the 2Y)ite=atabase obGe't, =hi'h eliminate mu'h o& the %JL synta; reRuire" to "o basi' operations. *or e;ample, here =e insertPQ a ne= ro= into our constants table,
private void process$ddP=ialog@rapper ErapperQ : +ontentValues values6neE ContentValuesP>QJ values.putP=atabase!elper.&I&)$8 Erapper.getTitlePQQJ values.putP=atabase!elper.VA)3$8 Erapper.getValuePQQJ db.get#rita'leData'asePQ.insertP7constants78 =atabase!elper.&I&)$8 valuesQJ constants+ursor.re-ueryPQJ
5hese metho"s make use o& +ontentValues obGe'ts, =hi'h implement a #apesRue inter&a'e, albeit one that has a""itional metho"s &or =orking =ith %JLite types. *or e;ample, in a""ition to getPQ to retrie!e a !alue by its key, you ha!e getAsIntegerPQ, getAs2tringPQ, an" so &orth. 5he insertPQ metho" takes the name o& the table, the name o& one 'olumn as the Mnull 'olumn ha'kM, an" a +ontentValues =ith the initial !alues you =ant put into this ro=. 5he Mnull 'olumn ha'kM is &or the 'ase =here the +ontentValues instan'e is empty S the 'olumn name" as the Mnull 'olumn ha'kM =ill be e;pli'itly assigne" the !alue %3)) in the %JL I%2$?& statement generate" by insertPQ. 5his is reRuire" "ue to a Ruirk in %JLite7s support &or the %JL I%2$?& statement.
%2&
5he updatePQ metho" takes the name o& the table, a +ontentValues representing the 'olumns an" repla'ement !alues to use, an optional @!$?$ 'lause, an" an optional list o& parameters to &ill into the @!$?$ 'lause, to repla'e any embe""e" Ruestion marks ( N). %in'e updatePQ only repla'es 'olumns =ith &i;e" !alues, !ersus ones 'ompute" base" on other in&ormation, you may nee" to use eGec2Y)PQ to a''omplish some en"s. 5he @!$?$ 'lause an" parameter list =orks akin to the positional %JL parameters you may be use" to &rom other %JL A#0s. 5he deletePQ metho" =orks akin to updatePQ, taking the name o& the table, the optional @!$?$ 'lause, an" the 'orrespon"ing parameters to &ill into the @!$?$ 'lause. *or e;ample, here =e deletePQ a ro= &rom our constants table, gi!en its ]0@,
private void processDeletePlong roEIdQ : 2tringAB args6:2tring.!alueOfProEIdQ;J db.get#rita'leData'asePQ.deleteP7constants78 7 I=6N78 argsQJ constants+ursor.re-ueryPQJ
2. ?ou 'an use UuerFPQ to buil" up a Ruery &rom its 'omponent parts Con&oun"ing matters &urther is the 2Y)iteYuerF4uilder 'lass an" the issue o& 'ursors an" 'ursor &a'tories. Let7s take all o& this one pie'e at a time.
R # Hueries
5he simplest solution, at least in terms o& the A#0, is raEYuerFPQ. %imply 'all it =ith your %JL 2$)$+& statement. 5he 2$)$+& statement 'an in'lu"e positional parametersT the array o& these &orms your se'on" parameter to raEYuerFPQ. %o, =e =in" up =ith,
%2-
constants+ursor6db .get%eada'leData'asePQ .raw/ueryP72$)$+& I=8 title8 value 7R 79?"# constants "?=$? 45 title78 nullQJ
5he return !alue is a +ursor, =hi'h 'ontains metho"s &or iterating o!er results (see belo=). 0& your Rueries are pretty mu'h Mbake" intoM your appli'ation, this is a !ery straight&or=ar" =ay to use them. +o=e!er, it gets 'ompli'ate" i& parts o& the Ruery are "ynami', beyon" =hat positional parameters 'an really han"le. *or e;ample, i& the set o& 'olumns you nee" to retrie!e is not kno=n at 'ompile time, puttering aroun" 'on'atenating 'olumn names into a 'omma-"elimite" list 'an be annoying...=hi'h is =here UuerFPQ 'omes in.
Re!ul r Hueries
5he UuerFPQ metho" takes the "is'rete pie'es o& a %ELEC5 statement an" buil"s the Ruery &rom them. 5he pie'es, in or"er that they appear as parameters to UuerFPQ, are,
5he name o& the table to Ruery against 5he list o& 'olumns to retrie!e 5he @!$?$ 'lause, optionally in'lu"ing positional parameters 5he list o& !alues to substitute in &or those positional parameters 5he D?"3( 45 'lause, i& any 5he !AVI%D 'lause, i& any 5he "?=$? 45 'lause, i& any
5hese 'an be null =hen they are not nee"e" (e;'ept the table name, o& 'ourse),
2tringAB columns6:7I=78 7inventorF7;J 2tringAB parms6:7snicklefritK7;J
%2%
-sin! Cursors
2o matter ho= you e;e'ute the Ruery, you get a +ursor ba'k. 5his is the An"roi"P%JLite 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 !ia get+ountPQ 0terate o!er the ro=s !ia move&o9irstPQ, move&o%eGtPQ, an"
isAfter)astPQ
*in" out the names o& the 'olumns !ia get+olumn%amesPQ, 'on!ert those into 'olumn numbers !ia get+olumnIndeGPQ, an" get !alues &or the 'urrent ro= &or a gi!en 'olumn !ia metho"s like get2tringPQ, getIntPQ, et'. e-e;e'ute the Ruery that 'reate" the 'ursor !ia reUuerFPQ elease the 'ursor7s resour'es !ia closePQ
result.closePQJ
?ou 'an also =rap a +ursor in a 2imple+ursorAdapter or other implementation, then han" the resulting a"apter to a )istVieE or other sele'tion =i"get. 2ote, though, that i& you are going to use +ursorAdapter or its sub'lasses (like 2imple+ursorAdapter), your result set o& your Ruery must 'ontain an integer 'olumn name" I= that is uniRue &or the result set. 5his
%20
Mi"M !alue is then supplie" to metho"s like on)istItem+lickPQ, to i"enti&y =hat item the user 'li'ke" upon in the AdapterVieE. *or e;ample, a&ter retrie!ing the sorte" list o& 'onstants, =e pop those into the )istVieE &or the +onstants4roEser a'ti!ity in Gust a &e= lines o& 'o"e,
)istAdapter adapter6neE SimpleCursor$dapterPthis8 ?.laFout.roE8 constants+ursor8 neE 2tringAB :=atabase!elper.&I&)$8 =atabase!elper.VA)3$;8 neE intAB :?.id.title8 ?.id.value;QJ
%22
%27
"es'ribe" in the 'hapter on threa"s. 5his =ay, the "atabase =rite operations =ill not slo= "o=n your user inter&a'e. 2ote that the emulator beha!es "i&&erently, be'ause it is typi'ally using a &ile on your har" "ri!e &or storing "ata, rather than &lash. While the emulator ten"s to be mu'h slo=er than har"=are &or C#$ an" 8#$ operations, the emulator =ill ten" to be mu'h &aster &or =riting "ata to &lash. +en'e, Gust be'ause you are not seeing any $0 slo="o=ns "ue to "atabase 0P> in the emulator, "o not assume that =ill be the same =hen your 'o"e is running on a real An"roi" "e!i'e.
+ere Four.app.package is the Ca!a pa'kage &or your appli'ation (e.g., com.commonsEare.android) an" Four-db-name is the name o& your "atabase, as supplie" to create=atabasePQ. 5he sUliteC 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. 0& you pre&er something a little bit &rien"lier, you 'an al=ays 'opy the %JLite "atabase o&& the "e!i'e onto your "e!elopment ma'hine, then use a %JLite-a=are 'lient program to putter aroun". 2ote, though, that you are =orking o&& a 'opy o& the "atabaseT i& you =ant your 'hanges to go ba'k to the "e!i'e, you =ill nee" to trans&er the "atabase ba'k o!er.
%28
5o get the "atabase o&& the "e!i'e, you 'an use the adb pull 'omman" (or the eRui!alent in your 0@E, or the *ile Manager in @@M%), =hi'h takes the path to the on-"e!i'e "atabase an" the lo'al "estination as parameters. 5o store a mo"i&ie" "atabase on the "e!i'e, use adb push, =hi'h takes the lo'al path to the "atabase an" the on-"e!i'e "estination as parameters. >ne o& the most-a''essible %JLite 'lients is the %JLite Manager e;tension &or *ire&o;, as it =orks a'ross all plat&orms.
?ou 'an &in" other 'lient tools on the %JLite Web site.
%2:
CHAPTER 11
Ca!a has as many, i& not more, thir"-party libraries than any other mo"ern programming language. +ere, Mthir"-party librariesM re&er to the innumerable CA s that you 'an in'lu"e in a ser!er or "esktop Ca!a appli'ation S the things that the Ca!a %@Ds themsel!es "o not pro!i"e. 0n the 'ase o& An"roi", the @al!ik -M at its heart is not pre'isely Ca!a, an" =hat it pro!i"es in its %@D is not pre'isely the same as any tra"itional Ca!a %@D. 5hat being sai", many Ca!a thir"-party libraries still pro!i"e 'apabilities that An"roi" la'ks nati!ely an" there&ore may be o& use to you in your proGe't, &or the ones you 'an get =orking =ith An"roi"7s &la!or o& Ca!a. 5his 'hapter e;plains =hat it =ill take &or you to le!erage su'h libraries an" the limitations on An"roi"7s support &or arbitrary thir"-party 'o"e.
%7*
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
0& you 'hoose to use an e;isting CA , perhaps one &or =hi'h you "o not ha!e the sour'e 'o"e, you =ill nee" to tea'h your buil" 'hain ho= to use the CA . *irst, pla'e the CA in the libs/ "ire'tory in your An"roi" proGe't. 5hen, i& you are using an 0@E, you probably nee" to a"" the CA to your buil" path (Ant =ill automati'ally pi'k up all CA s &oun" in libs/) S this is "e&initely reRuire" &or E'lipse. An" that7s it. A""ing thir"-party 'o"e to your An"roi" appli'ation is &airly easy. 8etting to a'tually work may be some=hat more 'ompli'ate", ho=e!er.
*xpected Platform AP8s, @oes the 'o"e assume a ne=er C-M than the one An"roi" is base" onH >r, "oes the 'o"e assume the e;isten'e o& Ca!a A#0s that ship =ith C2%E but not =ith An"roi", su'h as %=ingH $i<e, E;isting Ca!a 'o"e "esigne" &or use on "esktops or ser!ers nee" not =orry too mu'h about on-"isk siKe, or, to some e;tent, e!en in- AM siKe. An"roi", o& 'ourse, is short on both. $sing thir"party Ca!a 'o"e, parti'ularly =hen pre-pa'kage" as CA s, may balloon the siKe o& your appli'ation. Performance, @oes the Ca!a 'o"e e&&e'ti!ely assume a mu'h more po=er&ul C#$ than =hat you may &in" on many An"roi" "e!i'esH Cust be'ause a "esktop 'an run it =ithout issue "oes not mean your a!erage mobile phone =ill han"le it =ell. 8nterface, @oes the Ca!a 'o"e assume a 'onsole inter&a'eH >r is it a pure A#0 that you 'an =rap your o=n inter&a'e aroun"H >perating %ystem, @oes the Ca!a 'o"e assume the e;isten'e o& 'ertain 'onsole programsH @oes the Ca!a 'o"e assume it 'an use a Win"o=s @LLH
%7&
Language -ersion, Was the CA 'ompile" =ith an ol"er !ersion o& Ca!a (1.<.2 or ol"er)H Was the CA 'ompile" =ith a "i&&erent 'ompiler than the o&&i'ial one &rom %un (e.g., 8CC)H @epen"en'ies, @oes the Ca!a 'o"e "epen" on other thir"-party CA s that might ha!e some o& these problems as =ellH @oes the Ca!a 'o"e "epen" upon thir"-party libraries (e.g., the org.Gson C%>2 library) that are built into An"roi", but the thir" party e;pe'ts a "i&&erent !ersion o& that libraryH
>ne tri'k &or a""ressing some o& these 'on'erns is to use open sour'e Ca!a 'o"e, an" a'tually =ork =ith the 'o"e to make it more An"roi"-&rien"ly. *or e;ample, i& you are only using 10L o& the thir"-party library, maybe it7s =orth=hile to re'ompile the subset o& the proGe't to be only =hat you nee", or at least remo!ing the unne'essary 'lasses &rom the CA . 5he &ormer approa'h is sa&er, in that you get 'ompiler help to make sure you are not "is'ar"ing some essential pie'e o& 'o"e, though it may be more te"ious to "o.
%7-
1ean%hell CA that a''ompanies the sour'e 'o"e &or this book, up on the CommonsWare site, in the Java/And2hell proGe't. *rom there, using 1ean%hell on An"roi" is no "i&&erent than using 1ean%hell in any other Ca!a en!ironment, 1. Create an instan'e o& the 1ean%hell Interpreter 'lass
2. %et any 6globals9 &or the s'ript[s use !ia InterpreterSsetPQ .. Call InterpreterSevalPQ to run the s'ript an", optionally, get the result o& the last statement *or e;ample, here is the FML layout &or the =orl"[s smallest 1ean%hell 0@E,
LNGml version671.-7 encoding67utf-,7NM L)inear)aFout Gmlns:android67http://schemas.android.com/apk/res/android7 android:orientation67vertical7 android:laFout Eidth67fill parent7 android:laFout height67fill parent7 M L4utton android:id67ORid/eval7 android:laFout Eidth67fill parent7 android:laFout height67Erap content7 android:teGt67DoX7 android:on+lick67go7 /M L$dit&eGt android:id67ORid/script7 android:laFout Eidth67fill parent7 android:laFout height67fill parent7 android:single)ine67false7 android:gravitF67top7 /M L/)inear)aFoutM
%7%
public class #ainActivitF eGtends ActivitF : private Interpreter i6neE InterpreterPQJ O"verride public void onCreateP4undle icicleQ : super.onCreatePicicleQJ setContentViewP?.laFout.mainQJ ; public void goPVieE vQ : $dit&eGt script6P$dit&eGtQfindViewByIdP?.id.scriptQJ 2tring src6script.getTextPQ.toStringPQJ trF : i.setP7conteGt78 #ainActivitF.thisQJ i.e!alPsrcQJ ; catch Pbsh.$val$rror eQ : Alert=ialog.4uilder builder6 neE Alert=ialog.BuilderP#ainActivitF.thisQJ builder .setTitleP7$GceptionX7Q .setMessagePe.toStringPQQ .set)ositi!eButtonP7"H78 nullQ .showPQJ ; ; ;
Compile an" run it (in'lu"ing in'orporating the 1ean%hell CA as mentione" abo!e), an" install it on the emulator. *ire it up, an" you get a tri!ial 0@E, =ith a large te;t area &or your s'ript an" a big M8o:M button to e;e'ute it,
%70
"igure *-:1 The AndShell BeanShell /= import android.Eidget.&oastJ &oast.makeTextPconteGt8 7!ello8 EorldX78 &oast.)$%D&! )"%DQ.showPQJ
2ote the use o& conteGt to re&er to the a'ti!ity =hen making the &oast. 5hat is the global set by the a'ti!ity to re&eren'e ba'k to itsel&. ?ou 'oul" 'all this global !ariable anything you =ant, so long as the setPQ 'all an" the s'ript 'o"e use the same name. 5hen, 'li'k the 8o: button, an" you get,
%72
An" no=, some 'a!eats... *irst, not all s'ripting languages =ill =ork. *or e;ample, those that implement their o=n &orm o& Gust-in-time (C05) 'ompilation, generating Ca!a byte'o"es on the &ly, =oul" probably ha!e to be augmente" to generate @al!ik -M byte'o"es instea" o& those &or sto'k Ca!a implementations. %impler languages that e;e'ute o&& o& parse" s'ripts, 'alling Ca!a re&le'tion A#0s to 'all ba'k into 'ompile" 'lasses, =ill likely =ork better. E!en there, though, not e!ery &eature o& the language may =ork, i& it relies upon some &a'ility in a tra"itional Ca!a A#0 that "oes not e;ist in @al!ik S &or e;ample, there 'oul" be stu&& hi""en insi"e 1ean%hell or the a""-on CA s that "oes not =ork on to"ay[s An"roi". %e'on", s'ripting languages =ithout C05 =ill ine!itably be slo=er than 'ompile" @al!ik 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 1ean%hell, simply be'ause you &eel it is easier to program in, may 'ause your users to be unhappy.
%77
5hir", s'ripting languages that e;pose the =hole Ca!a A#0, like 1ean%hell, 'an pretty mu'h "o anything the un"erlying An"roi" se'urity mo"el allo=s. %o, i& your appli'ation has the ?$A= +"%&A+&2 permission, e;pe't any 1ean%hell s'ripts your appli'ation runs to ha!e the same permission. Last, but 'ertainly not least, is that language interpreter CA s ten" to be...portly. 5he 1ean%hell CA use" in this e;ample is 200D1. 5hat is not ri"i'ulous, 'onsi"ering =hat it "oes, but it =ill make appli'ations that use 1ean%hell that mu'h bigger to "o=nloa", take up that mu'h more spa'e on the "e!i'e, et'.
#erl #ython C uby Lua Ca!as'ript (implemente" !ia interpreter =ritten in Ca!a) #+# hino, the MoKilla Ca!as'ript
%78
5hese s'ripts are not &ull-&le"ge" appli'ations, though the %L<A team is =orking on allo=ing you to turn them into A#D &iles 'omplete =ith basi' $0s. *or on-"e!i'e "e!elopment, %L<A is a &ine 'hoi'e.
%7:
CHAPTER 12
5he e;pe'tation is that most, i& not all, An"roi" "e!i'es =ill ha!e built-in 0nternet a''ess. 5hat 'oul" be Wi*i, 'ellular "ata ser!i'es (E@8E, .8, et'.), or possibly something else entirely. egar"less, most people S or at least those =ith a "ata plan or Wi*i a''ess S =ill be able to get to the 0nternet &rom their An"roi" phone. 2ot surprisingly, the An"roi" plat&orm gi!es "e!elopers a =i"e range o& =ays to make use o& this 0nternet a''ess. %ome o&&er high-le!el a''ess, su'h as the integrate" WebDit bro=ser 'omponent =e sa= in an earlier 'hapter. 0& you =ant, you 'an "rop all the =ay "o=n to using ra= so'kets. >r, in bet=een, you 'an le!erage A#0s S both on-"e!i'e an" &rom .r"-party CA s S that gi!e you a''ess to spe'i&i' proto'ols, +55#, FM##, %M5#, an" so on. 5he emphasis o& this book is on the higher-le!el &orms o& a''ess, the WebDit 'omponent an" 0nternet-a''ess A#0s, as busy 'o"ers shoul" be trying to reuse e;isting 'omponents !ersus rolling one7s o=n on-the-=ire proto'ol =here!er possible.
ser!i'esM is "e&ine" as Msimple +55# reRuests &or or"inary $ Ls o!er the &ull range o& +55# !erbs, =ith &ormatte" payloa"s (FML, C%>2, et'.) as responsesM. More e;pansi!e tutorials, *AJs, an" +>W5>s 'an be &oun" at the +ttpClient Web site. +ere, =e7ll 'o!er the basi's, =hile 'he'king the =eather.
=hi'h is poure" into a @ebHit =i"get &or "isplay. ebuil"ing this "emo using a )istVieE is le&t as an e;er'ise &or the rea"er. Also, sin'e this sample is relati!ely long, =e =ill only sho= rele!ant pie'es o& the Ca!a 'o"e here in this 'hapter, though you 'an al=ays "o=nloa" the &ull sour'e &rom the CommonsWare Web site. 5o make this a bit more interesting, =e use the An"roi" lo'ation ser!i'es to &igure out =here =e are...sort o&. 5he &ull "etails o& ho= that =orks is "es'ribe" in the 'hapter on lo'ation ser!i'es. 0n the on?esumePQ metho", =e toggle on lo'ation up"ates, so =e =ill be in&orme" =here =e are no= an" =hen =e mo!e a signi&i'ant "istan'e (10km). When a lo'ation is a!ailable S either at the start or base" on mo!ement S =e retrie!e the 2ational Weather %er!i'e "ata !ia our update9orecastPQ metho",
private void update"orecastP)ocation locQ : 2tring url62tring.formatPformat8 loc.getLatitudePQ8 loc.getLongitudePQQJ !ttpDet get#ethod6neE (ttp etPurlQJ trF : ?esponse!andlerL2tringM response!andler6neE Basic%esponse(andlerPQJ 2tring response4odF6client.executePget#ethod8 response!andlerQJ 'uild"orecastsPresponse4odFQJ 2tring page6generate)agePQJ broEser.loadData#ithBase*%LPnull8 page8 7teGt/html78 73&9-,78 nullQJ ; catch P&hroEable tQ : android.util.)og.eP7@eather=emo78 7$Gception fetching data78 tQJ &oast .makeTextPthis8 7?eUuest failed: 7Rt.toStringPQ8 &oast.)$%D&! )"%DQ .showPQJ ;
5he update9orecastPQ 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)atitudePQ an" get)ongitudePQ metho"s that return the latitu"e an" longitu"e o& the "e!i'e7s position, respe'ti!ely.
%8-
We hol" the $ L to the 2ational Weather %er!i'e FML in a string resour'e, an" pour in the latitu"e an" longitu"e at runtime. 8i!en our !ttp+lient obGe't 'reate" in on+reatePQ, =e populate an !ttpDet =ith that 'ustomiKe" $ L, then e;e'ute that metho". 8i!en the resulting FML &rom the E%5 ser!i'e, =e buil" the &ore'ast +5ML page (see belo=) an" pour that into the @ebHit =i"get. 0& the !ttp+lient blo=s up =ith an e;'eption, =e pro!i"e that error as a &oast. 2ote that =e also shut "o=n the !ttp+lient obGe't in on=estroFPQ.
P rsin! Responses
5he response you get =ill be &ormatte" using some system S +5ML, FML, C%>2, =hate!er. 0t is up to you, o& 'ourse, to pi'k out =hat in&ormation you nee" an" "o something use&ul =ith it. 0n the 'ase o& the @eather=emo, =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 +5ML page &rom it. An"roi" in'lu"es,
5hree FML parsers, the tra"itional W.C @>M (org.ECc.dom), a %AF parser (org.Gml.saG), an" the FML pull parser "is'usse" in the 'hapter on resour'es A C%>2 parser (org.json)
?ou are also =el'ome to use thir"-party Ca!a 'o"e, =here possible, to han"le other &ormats, su'h as a "e"i'ate" %%PAtom parser &or a &ee" rea"er. 5he use o& thir"-party Ca!a 'o"e is "is'usse" in a separate 'hapter. *or @eather=emo, =e use the W.C @>M parser in our build9orecastsPQ metho",
void 'uild"orecastsP2tring raEQ throEs $Gception : =ocument4uilder builder6=ocument4uilder9actorF .newInstancePQ .newDocumentBuilderPQJ =ocument doc6builder.parsePneE InputSourcePneE String%eaderPraEQQQJ %ode)ist times6doc.get+lementsByTag&ameP7start-valid-time7QJ
%8%
for Pint i6-JiLtimes.getLengthPQJiRRQ : $lement time6P$lementQtimes.itemPiQJ 9orecast forecast6neE "orecastPQJ forecasts.addPforecastQJ forecast.setTimePtime.get"irstChildPQ.get&odeValuePQQJ ; %ode)ist temps6doc.get+lementsByTag&ameP7value7QJ for Pint i6-JiLtemps.getLengthPQJiRRQ : $lement temp6P$lementQtemps.itemPiQJ 9orecast forecast6forecasts.getPiQJ ; forecast.setTempPneE IntegerPtemp.get"irstChildPQ.get&odeValuePQQQJ
%ode)ist icons6doc.get+lementsByTag&ameP7icon-link7QJ for Pint i6-JiLicons.getLengthPQJiRRQ : $lement icon6P$lementQicons.itemPiQJ 9orecast forecast6forecasts.getPiQJ forecast.setIconPicon.get"irstChildPQ.get&odeValuePQQJ ; ;
5he 2ational Weather %er!i'e FML &ormat is...'uriously stru'ture", relying hea!ily on seRuential position in lists !ersus the more obGe't-oriente" style you &in" in &ormats like %% or Atom. 5hat being sai", =e 'an take a &e= liberties an" simpli&y the parsing some=hat, taking a"!antage o& the &a't that the elements =e =ant (start-valid-time &or the &ore'ast time, value &or the temperature, an" icon-link &or the i'on $ L) are all uniRue =ithin the "o'ument. 5he +5ML 'omes in as an Input2tream an" is &e" into the @>M parser. *rom there, =e s'an &or the start-valid-time elements an" populate a set o& 9orecast mo"els using those start times. 5hen, =e &in" the temperature value elements an" icon-link $ Ls an" &ill those in to the 9orecast obGe'ts. 0n turn, the generate(agePQ metho" 'reates a ru"imentary +5ML table =ith the &ore'asts,
2tring generate)agePQ : 2tring4uilder buf?esult6neE StringBuilderP7LhtmlMLbodFMLtableM7QJ
%80
buf?esult.appendP7LtrMLth Eidth6T7.-\T7M&imeL/thM7R 7LthM&emperatureL/thMLthM9orecastL/thML/trM7QJ for P9orecast forecast : forecastsQ : buf?esult.appendP7LtrMLtd align6T7centerT7M7QJ buf?esult.appendPforecast.getTimePQQJ buf?esult.appendP7L/tdMLtd align6T7centerT7M7QJ buf?esult.appendPforecast.getTempPQQJ buf?esult.appendP7L/tdMLtdMLimg src6T77QJ buf?esult.appendPforecast.getIconPQQJ buf?esult.appendP7T7ML/tdML/trM7QJ ; buf?esult.appendP7L/tableML/bodFML/htmlM7QJ returnPbuf?esult.toStringPQQJ ;
Stu.. To Consider
0& you nee" to use %%L, bear in min" that the "e&ault !ttp+lient setup "oes not in'lu"e %%L support. Mostly, this is be'ause you nee" to "e'i"e ho= to
%82
han"le %%L 'erti&i'ate presentation S "o you blin"ly a''ept all 'erti&i'ates, e!en sel&-signe" or e;pire" onesH >r "o you =ant to ask the user i& they really =ant to use some strange 'erti&i'atesH %imilarly, !ttp+lient, by "e&ault, is "esigne" &or single-threa"e" use. 0& you =ill be using !ttp+lient &rom some other pla'e =here multiple threa"s might be an issue, you 'an rea"ily set up !ttp+lient to support multiple threa"s. *or these sorts o& topi's, you are best ser!e" by 'he'king out the +ttpClient Web site &or "o'umentation an" support.
AndroidHttpClient
%tarting in An"roi" 2.2 (A#0 le!el 8), you 'an use the Android!ttp+lient 'lass, &oun" in the android.net.http pa'kage. 5his is an implementation o& the !ttp+lient inter&a'e, like =efault!ttp+lient. +o=e!er, it is pre'on&igure" =ith settings that the 'ore An"roi" team &eels make sense &or the plat&orm. What you gain is,
%%L management A "ire't =ay to spe'i&y the user agent string S this is supplie" in your 'all to the stati' neEInstancePQ metho" to get an instan'e o&
Android!ttp+lient
$tility metho"s &or =orking =ith material 'ompresse" !ia 8Q0#, &or parsing "ates in +55# hea"ers, et'.
What you lose is automati' 'ookie storage. A regular =efault!ttp+lient =ill 'a'he 'ookies in memory an" use them on subseRuent reRuests =here they are nee"e". Android!ttp+lient "oes not. 5here are =ays to &i; that, by using an !ttp+onteGt obGe't, as is "es'ribe" in the Android!ttp+lient "o'umentation.
%87
Also, Android!ttp+lient pre!ents you &rom using it on the main appli'ation threa" S reRuests 'an only be ma"e on a ba'kgroun" threa". 5his is a &eature, e!en i& some people might 'onsi"er it to be a bug. %in'e this 'lass is only a!ailable in An"roi" 2.2 an" beyon", it may not make sense to "o mu'h =ith it until su'h time as you are only supporting A#0 le!el 8 or higher.
@etermining =hether the user is on Wi*i or mobile "ata, an" i& so, =hether the "o=nloa" shoul" o''ur +an"ling =hen the user, pre!iously on Wi*i, mo!es out o& range o& the a''ess point an" M&ails o!erM to mobile "ata Ensuring the "e!i'e stays a=ake =hile the "o=nloa" pro'ee"s
%88
=oEnload#anager
itsel& is less 'ompli'ate" than the alternati!e o& =riting all o& it yoursel&. +o=e!er, it "oes present a &e= 'hallenges. 0n this se'tion, =e =ill e;amine the Internet/=oEnload sample proGe't that uses =oEnload#anager.
The Permissions
5o use =oEnload#anager, you =ill nee" to hol" the I%&$?%$& permission. @epen"ing on =here you ele't to "o=nloa" the &ile, you may also nee" the @?I&$ $]&$?%A) 2&"?AD$ permission. +o=e!er, at the time o& this =riting, i& you la'k su&&i'ient permissions, you may get an error 'omplaining that you are missing A++$22 A)) ="@%)"A=2. 5his appears to be a bug in the =oEnload#anager implementation S it shoul" be 'omplaining about I%&$?%$& an"Por @?I&$ $]&$?%A) 2&"?AD$. ?ou "o not nee" to hol" the A++$22 A)) ="@%)"A=2 permission, =hi'h is not e!en "o'umente" as o& An"roi" ..0. *or e;ample, here is the mani&est &or the Internet/=oEnload appli'ation,
LNGml version671.-7 encoding67utf-,7NM Lmanifest Gmlns:android67http://schemas.android.com/apk/res/android7 package67com.commonsEare.android.doEnload7 android:version+ode6717 android:version%ame671.-7M LX-- Luses-permission android:name67android.permission.A++$22 A)) ="@%)"A=27 /M --M Luses-permission android:name67android.permission.I%&$?%$&7/M Luses-permission android:name67android.permission.@?I&$ $]&$?%A) 2&"?AD$7/M Lapplication android:label67Ostring/app name7 android:icon67OdraEable/cE7M LactivitF android:name67=oEnload=emo7 android:label67Ostring/app name7M Lintent-filterM Laction android:name67android.intent.action.#AI%7/M LcategorF android:name67android.intent.categorF.)A3%+!$?7/M L/intent-filterM L/activitFM L/applicationM Lsupports-screens android:large2creens67true7 android:normal2creens67true7 android:small2creens67true7 android:anF=ensitF67true7/M L/manifestM
%8:
The ) yout
>ur sample appli'ation has a simple layout, 'onsisting o& three buttons,
>ne to ki'k o&& a "o=nloa" >ne to Ruery the status o& a "o=nloa" >ne to "isplay a system-supplie" a'ti!ity 'ontaining the roster o& "o=nloa"e" &iles
LNGml version671.-7 encoding67utf-,7NM L)inear)aFout Gmlns:android67http://schemas.android.com/apk/res/android7 android:orientation67vertical7 android:laFout Eidth67fill parent7 android:laFout height67fill parent7 M L4utton android:id67ORid/start7 android:teGt672tart =oEnload7 android:laFout Eidth67fill parent7 android:laFout height67-dip7 android:laFout Eeight6717 android:on+lick67start=oEnload7 /M L4utton android:id67ORid/UuerF7 android:teGt67YuerF 2tatus7 android:laFout Eidth67fill parent7 android:laFout height67-dip7 android:laFout Eeight6717 android:on+lick67UuerF2tatus7 android:enabled67false7 /M L4utton android:teGt67VieE )og7 android:laFout Eidth67fill parent7 android:laFout height67-dip7 android:laFout Eeight6717 android:on+lick67vieE)og7 /M L/)inear)aFoutM
=ant, an" re'ei!e the system ser!i'e obGe't ba'k. +o=e!er, sin'e get2Fstem2ervicePQ supports a =i"e range o& these obGe'ts, you nee" to 'ast it to the proper type &or the ser!i'e you reRueste". %o, &or e;ample, here is a line &rom on+reatePQ o& the =oEnload=emo a'ti!ity =here =e get the =oEnload#anager,
mgr6P=oEnload#anagerQgetSystemSer!iceP="@%)"A= 2$?VI+$QJ
Most o& these managers ha!e no closePQ or releasePQ or goAEaF(leasePQ sort o& metho"s S you 'an Gust use them an" let garbage 'olle'tion take 'are o& 'leaning them up. 8i!en the manager, =e 'an no= 'all an enUueuePQ metho" to reRuest a "o=nloa". 5he name is rele!ant S "o not assume that your "o=nloa" =ill begin imme"iately, though o&ten times it =ill. 5he enUueuePQ metho" takes a =oEnload#anager.?eUuest obGe't as a parameter. 5he ?eUuest obGe't uses the buil"er pattern, in that most metho"s return the ?eUuest itsel&, so you 'an 'hain a series o& 'alls together =ith less typing. *or e;ample, the top-most button in our layout is tie" to a start=oEnloadPQ metho" in =oEnload=emo, sho=n belo=,
public void startDownloadPVieE vQ : 3ri uri63ri.parseP7http://commonsEare.com/misc/test.mp<7QJ $nvironment .get+xternalStorage)u'licDirectory P$nvironment.=I?$+&"?5 ="@%)"A=2Q .mkdirsPQJ last=oEnload6 mgr.en-ueuePneE =oEnload#anager.%e-uestPuriQ .set$llowed&etworkTypesP=oEnload#anager.?eUuest.%$&@"?H @I9I W =oEnload#anager.?eUuest.%$&@"?H #"4I)$Q .set$llowedO!er%oamingPfalseQ .setTitleP7=emo7Q .setDescriptionP72omething useful. %o8 reallF.7Q .setDestinationIn+xternal)u'licDir P$nvironment.=I?$+&"?5 ="@%)"A =28 7test.mp<7QQJ v.set+na'ledPfalseQJ
%:*
findViewByIdP?.id.UuerFQ.set+na'ledPtrueQJ ;
We are "o=nloa"ing a sample M#< &ile, an" =e =ant to "o=nloa" it to the e;ternal storage area. 5o "o the latter, =e are using get$Gternal2torage(ublic=irectorFPQ on $nvironment, =hi'h gi!es us a "ire'tory suitable &or storing a 'ertain 'lass o& 'ontent. 0n this 'ase, =e are going to store the "o=nloa" in the $nvironment.=I?$+&"?5 ="@%)"A=2, though =e 'oul" Gust as easily ha!e 'hosen $nvironment.=I?$+&"?5 #"VI$2, sin'e =e are "o=nloa"ing a !i"eo 'lip. 2ote that the 9ile obGe't returne" by get$Gternal2torage(ublic=irectorFPQ may point to a not-yet-'reate" "ire'tory, =hi'h is =hy =e 'all mkdirsPQ on it, to ensure the "ire'tory e;ists. We then 'reate the =oEnload#anager.?eUuest obGe't, =ith the &ollo=ing attributes,
We are "o=nloa"ing the spe'i&i' $ L =e =ant, 'ourtesy o& the 3ri supplie" to the ?eUuest 'onstru'tor We are =illing to use either mobile "ata or Wi*i &or the "o=nloa" (setAlloEed%etEork&FpesPQ), but =e "o not =ant the "o=nloa" to in'ur roaming 'harges (setAlloEed"ver?oamingPQ) We =ant the &ile "o=nloa"e" as test.mp< in the "o=nloa"s area on the e;ternal storage (set=estinationIn$Gternal(ublic=irPQ)
We also pro!i"e a name ( set&itlePQ) an" "es'ription (set=escriptionPQ), =hi'h are use" as part o& the noti&i'ation "ra=er entry &or this "o=nloa". 5he user =ill see these =hen they sli"e "o=n the "ra=er =hile the "o=nloa" is progressing. 5he enRueue() metho" returns an 0@ o& this "o=nloa", =hi'h =e hol" onto &or use in Ruerying the "o=nloa" status.
"es'ribing =hat "o=nloa"(s) you are intereste" in. 0n our 'ase, =e use the !alue =e got &rom the enUueuePQ metho" =hen the user reRueste" the "o=nloa",
public void -ueryStatusPVieE vQ : +ursor c6mgr.-ueryPneE =oEnload#anager./ueryPQ.set"ilterByIdPlast=oEnloadQQJ if Pc66nullQ : &oast.makeTextPthis8 7=oEnload not foundX78 &oast.)$%D&! )"%DQ.showPQJ ; else : c.mo!eTo"irstPQJ )og.dPgetClassPQ.get&amePQ8 7+")3#% I=: 7R c.getLongPc.getColumnIndexP=oEnload#anager.+")3#% I=QQQJ )og.dPgetClassPQ.get&amePQ8 7+")3#% 45&$2 ="@%)"A=$= 2" 9A?: 7R c.getLongPc.getColumnIndexP=oEnload#anager.+")3#% 45&$2 ="@%)"A=$= 2" 9A?QQQJ )og.dPgetClassPQ.get&amePQ8 7+")3#% )A2& #"=I9I$= &I#$2&A#(: 7R c.getLongPc.getColumnIndexP=oEnload#anager.+")3#% )A2& #"=I9I$= &I#$2& A#(QQQJ )og.dPgetClassPQ.get&amePQ8 7+")3#% )"+A) 3?I: 7R c.getStringPc.getColumnIndexP=oEnload#anager.+")3#% )"+A) 3?IQQQJ )og.dPgetClassPQ.get&amePQ8 7+")3#% 2&A&32: 7R c.getIntPc.getColumnIndexP=oEnload#anager.+")3#% 2&A&32QQQJ )og.dPgetClassPQ.get&amePQ8 7+")3#% ?$A2"%: 7R c.getIntPc.getColumnIndexP=oEnload#anager.+")3#% ?$A2"%QQQJ &oast.makeTextPthis8 statusMessagePcQ8 &oast.)$%D&! )"%DQ.showPQJ ; ;
5he UuerFPQ metho" returns a +ursor, 'ontaining a series o& 'olumns representing the "etails about our "o=nloa". 5here are a series o& 'onstants on the =oEnload#anager 'lass outlining =hat is possible. 0n our 'ase, =e retrie!e (an" "ump to LogCat),
5he 0@ o& the "o=nloa" (+")3#% I=) 5he amount o& "ata that has been "o=nloa"e" to "ate (+")3#% 45&$2 ="@%)"A=$= 2" 9A?) What the last-mo"i&ie" timestamp (+")3#% )A2& #"=I9I$= &I#$2&A#() What the a'tual status is (+")3#% 2&A&32) is on the "o=nloa"
%:-
5here are a number o& possible status 'o"es (e.g., 2&A&32 9AI)$=, 2&A&32 23++$2293), 2&A&32 ?3%%I%D). %ome, like 2&A&32 9AI)$=, may ha!e an a''ompanying reason to pro!i"e more "etails.
Cli'king the &irst "isables the button =hile the "o=nloa" is going on, an" a "o=nloa" i'on appears in the status bar (though it is a bit "i&&i'ult to see, gi!en the poor 'ontrast bet=een An"roi"7s i'on an" An"roi"7s status bar),
%:%
%li"ing "o=n the noti&i'ation "ra=er sho=s the user the progress in the &orm o& a (rogress4ar =i"get,
%:0
5apping on the entry in the noti&i'ation "ra=er returns 'ontrol to our original a'ti!ity, =here they see a &oast,
%:2
"igure *%01 The /o)nload sample application@ after coming to the foreground from the notification
0& they tap the mi""le button "uring the "o=nloa", a &oast =ill appear in"i'ating that the "o=nloa" is in progress,
%:7
"igure *%21 The /o)nload sample application@ sho)ing the status mid# do)nload
A""itional "etails are also "umpe" to LogCat, !isible !ia @@M% or adb logcat,
1>-1- -,:<.:-1.>,*: =$43D/com.commonsEare.android.doEnload.=oEnload=emoPC/>Q: +")3#% I=: 1> 1>-1- -,:<.:-1.>,*: =$43D/com.commonsEare.android.doEnload.=oEnload=emoPC/>Q: +")3#% 45&$2 ="@%)"A=$= 2" 9A?: 01.<-1>-1- -,:<.:-1.>,*: =$43D/com.commonsEare.android.doEnload.=oEnload=emoPC/>Q: +")3#% )A2& #"=I9I$= &I#$2&A#(: 1>*1*,,0*0>C> 1>-1- -,:<.:-1.>,*: =$43D/com.commonsEare.android.doEnload.=oEnload=emoPC/>Q: +")3#% )"+A) 3?I: file:///mnt/sdcard/=oEnload/test.mp< 1>-1- -,:<.:-1.>**: =$43D/com.commonsEare.android.doEnload.=oEnload=emoPC/>Q: +")3#% 2&A&32: > 1>-1- -,:<.:-1.>**: =$43D/com.commonsEare.android.doEnload.=oEnload=emoPC/>Q: +")3#% ?$A2"%: -
>n'e the "o=nloa" is 'omplete, tapping the mi""le button =ill in"i'ate that the "o=nloa" is, in"ee", 'omplete, an" &inal in&ormation about the "o=nloa" is emitte" to LogCat,
%:8
1>-1- -,:<*:>/.C0-: =$43D/com.commonsEare.android.doEnload.=oEnload=emoPC/>Q: +")3#% I=: 1> 1>-1- -,:<*:>/.C0-: =$43D/com.commonsEare.android.doEnload.=oEnload=emoPC/>Q: +")3#% 45&$2 ="@%)"A=$= 2" 9A?: 0>1*>>* 1>-1- -,:<*:>/.C/-: =$43D/com.commonsEare.android.doEnload.=oEnload=emoPC/>Q: +")3#% )A2& #"=I9I$= &I#$2&A#(: 1>*1*,,/1C<-* 1>-1- -,:<*:>/.C/-: =$43D/com.commonsEare.android.doEnload.=oEnload=emoPC/>Q: +")3#% )"+A) 3?I: file:///mnt/sdcard/=oEnload/test.mp< 1>-1- -,:<*:>/.C/-: =$43D/com.commonsEare.android.doEnload.=oEnload=emoPC/>Q: +")3#% 2&A&32: , 1>-1- -,:<*:>/.C/-: =$43D/com.commonsEare.android.doEnload.=oEnload=emoPC/>Q: +")3#% ?$A2"%: -
5apping the bottom button brings up the a'ti!ity "isplaying all "o=nloa"s, in'lu"ing both su''esses an" &ailures,
"igure *%71 The /o)nloads screen@ sho)ing everything do)nloaded by the /o)nload+anager
An", o& 'ourse, the &ile is "o=nloa"e". 0n An"roi" 2.., in the emulator, our 'hosen lo'ation maps to /mnt/sdcard/=oEnloads/test.mp<.
%::
)imit tions
+55# $ Ls, but not +55#% (%%L) $ Ls. 5his is un&ortunate, as more an" more sites are s=it'hing to %%L en'ryption a'ross the boar", to "eal =ith !arious se'urity 'hallenges. +ope&ully, in the &uture, =oEnload#anager =ill ha!e more options here. 0& you "isplay the list o& all "o=nloa"s, an" your "o=nloa" is among them, it is a really goo" i"ea to make sure that some a'ti!ity (perhaps one o& yours) is able to respon" to an A+&I"% VI$@ Intent on that "o=nloa"7s M0ME type. >ther=ise, =hen the user taps on the entry in the list, they =ill get a &oast in"i'ating that there is nothing a!ailable to !ie= the "o=nloa". 5his may 'on&use users. Alternati!ely, use setVisibleIn=oEnloads3iPQ on your reRuest, passing in false, to suppress it &rom this list.
=oEnload#anager =orks =ith
intro"u'e" in an earlier 'hapter, =ill =arn you i& you attempt to a''ess the 0nternet on the main appli'ation threa". Android!ttp+lient =ill simply 'rash i& you attempt to make Web reRuests on the main appli'ation threa". +o=e!er, these 'apabilities are only a!ailable in ne=er !ersions o& An"roi". 5hat being sai", there are =ays to ha!e 2trict#ode in your appli'ation yet only use it in ne=er !ersions o& An"roi" using 'on"itional 'lass loa"ing S this te'hniRue =as 'o!ere" earlier in this book.
0<<
PART V Services
CHAPTER 16
As note" pre!iously, An"roi" ser!i'es are &or long-running pro'esses that may nee" to keep running e!en =hen "e'ouple" &rom any a'ti!ity. E;amples in'lu"e playing musi' e!en i& the MplayerM a'ti!ity gets garbage'olle'te", polling the 0nternet &or %%PAtom &ee" up"ates, an" maintaining an online 'hat 'onne'tion e!en i& the 'hat 'lient loses &o'us "ue to an in'oming phone 'all. %er!i'es are 'reate" =hen manually starte" (!ia an A#0 'all) or =hen some a'ti!ity tries 'onne'ting to the ser!i'e !ia inter-pro'ess 'ommuni'ation (0#C). %er!i'es =ill li!e until spe'i&i'ally shut "o=n or until An"roi" is "esperate &or AM an" "estroys them prematurely. unning &or a long time has its 'osts, though, so ser!i'es nee" to be 'are&ul not to use too mu'h C#$ or keep ra"ios a'ti!e too mu'h o& the time, lest the ser!i'e 'ause the "e!i'e7s battery to get use" up too Rui'kly. 5his 'hapter outlines the basi' theory behin" 'reating an" 'onsuming ser!i'es. 5he ne;t 'hapter =ill outline a &e= spe'i&i' patterns &or ser!i'es, ones that may 'losely mat'h your parti'ular nee"s. +en'e, this 'hapter is short on 'o"e e;amples S you =ill &in" them an" more in the ne;t 'hapter.
Why ServicesF
%er!i'es are a M%=iss Army kni&eM &or a =i"e range o& &un'tions that "o not reRuire "ire't a''ess to an a'ti!ity7s user inter&a'e, su'h as,
0<Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
#er&orming operations that nee" to 'ontinue e!en i& the user lea!es the appli'ation7s a'ti!ities, like a long "o=nloa" (as seen =ith the An"roi" Market) or playing musi' (as seen =ith An"roi" musi' apps) #er&orming operations that nee" to e;ist regar"less o& a'ti!ities 'oming an" going, su'h as maintaining a 'hat 'onne'tion in support o& a 'hat appli'ation #ro!i"ing a lo'al A#0 to remote A#0s, su'h as might be pro!i"e" by a Web ser!i'e #er&orming perio"i' =ork =ithout user inter!ention, akin to 'ron Gobs or Win"o=s s'he"ule" tasks
E!en things like home s'reen app =i"gets o&ten in!ol!e a ser!i'e to assist =ith long-running =ork. Many appli'ations =ill not nee" any ser!i'es. -ery &e= appli'ations =ill nee" more than one. +o=e!er, the ser!i'e is a po=er&ul tool &or an An"roi" "e!eloper7s toolbo; an" is a subGe't =ith =hi'h any Ruali&ie" An"roi" "e!eloper shoul" be &amiliar.
The Service Cl ss
Cust as an a'ti!ity in your appli'ation e;ten"s either ActivitF or an An"roi"supplie" ActivitF sub'lass, a ser!i'e in your appli'ation e;ten"s either 2ervice or an An"roi"-supplie" 2ervice sub'lass. 5he most 'ommon 2ervice sub'lass is Intent2ervice, use" primarily &or the 'omman" pattern, "es'ribe" later in this 'hapter. 5hat being sai", many ser!i'es simply e;ten" 2ervice.
0<%
)i.ecycle %ethods
Cust as a'ti!ities ha!e on+reatePQ, on?esumePQ, on(ausePQ an" kin, 2ervice implementations ha!e their o=n li&e'y'le metho"s, su'h as, 1.
on+reatePQ,
=hi'h, as =ith a'ti!ities, is 'alle" =hen the ser!i'e pro'ess is 'reate", by any means
2. on2tart+ommandPQ, =hi'h is 'alle" ea'h time the ser!i'e is sent a 'omman" !ia start2ervicePQ .. on4indPQ, =hi'h is 'alle" =hene!er a 'lient bin"s to the ser!i'e !ia
bind2ervicePQ
<. on=estroFPQ =hi'h is 'alle" as the ser!i'e is being shut "o=n As =ith a'ti!ities, ser!i'es initialiKe =hate!er they nee" in on+reatePQ an" 'lean up those items in on=estroFPQ. An", as =ith a'ti!ities, the on=estroFPQ metho" o& a ser!i'e might not be 'alle", i& An"roi" terminates the entire appli'ation pro'ess, su'h as &or emergen'y AM re'lamation. 5he on2tart+ommandPQ an" on4indPQ li&e'y'le metho"s =ill be implemente" base" on your 'hoi'e o& 'ommuni'ating to the 'lient, as =ill be e;plaine" later in this 'hapter.
% ni.est Entry
*inally, you nee" to a"" the ser!i'e to your Android#anifest.Gml &ile, &or it to be re'ogniKe" as an a!ailable ser!i'e &or use. 5hat is simply a matter o& a""ing a LserviceO element as a 'hil" o& the application element, pro!i"ing android:name to re&eren'e your ser!i'e 'lass. %in'e the ser!i'e 'lass is in the same Ca!a namespa'e as e!erything else in this appli'ation, =e 'an use the shorthan" (7@eather2ervice7 or 7.@eather2ervice7) to re&eren'e our 'lass.
0<0
0& you =ish to reRuire some permission o& those =ho =ish to start or bin" to the ser!i'e, a"" an android:permission attribute naming the permission you are man"ating S see the 'hapter on permissions &or more "etails. *or e;ample, here is a mani&est sho=ing the LserviceM element,
LNGml version671.-7 encoding67utf-,7NM Lmanifest Gmlns:android67http://schemas.android.com/apk/res/android7 package67com.commonsEare.android.doEnloader7 android:version+ode6717 android:version%ame671.-7M Luses-permission android:name67android.permission.I%&$?%$&7/M Luses-permission android:name67android.permission.@?I&$ $]&$?%A) 2&"?AD$7/M Lapplication android:label67Ostring/app name7 android:icon67OdraEable/cE7M LactivitF android:name67=oEnloader=emo7 android:label67Ostring/app name7M Lintent-filterM Laction android:name67android.intent.action.#AI%7/M LcategorF android:name67android.intent.categorF.)A3%+!$?7/M L/intent-filterM L/activitFM Lservice android:name67=oEnloader7/M L/applicationM Lsupports-screens android:large2creens67true7 android:normal2creens67true7 android:small2creens67true7 android:anF=ensitF67true7/M L/manifestM
Communicating To Services
Clients o& ser!i'es S &reRuently a'ti!ities, though not ne'essarily S ha!e t=o main =ays to sen" reRuests or in&ormation to a ser!i'e. >ne approa'h is to sen" a 'omman", =hi'h 'reates no lasting 'onne'tion to the ser!i'e. 5he other approa'h is to bin" to the ser!i'e, establishing a bi-"ire'tional 'ommuni'ations 'hannel that lasts as long as the 'lient nee"s it.
%upply parameters, in the &orm o& Intent e;tras, to tell the ser!i'e =hat it is suppose" to "o
*or a lo'al ser!i'e S the &o'us o& this book S the simplest &orm o& Intent is one that i"enti&ies the 'lass that implements the Intent (e.g., neE IntentPthis8 #F2ervice.classQJ). 5he 'all to start2ervicePQ is asyn'hronous, so the 'lient =ill not blo'k. 5he ser!i'e =ill be 'reate" i& it is not alrea"y running, an" it =ill re'ei!e the Intent !ia a 'all to the on2tart+ommandPQ li&e'y'le metho". 5he ser!i'e 'an "o =hate!er it nee"s to in on2tart+ommandPQ, but sin'e on2tart+ommandPQ is 'alle" on the main appli'ation threa", it shoul" "o its =ork !ery Rui'kly. Anything that might take a =hile shoul" be "elegate" to a ba'kgroun" threa". 5he on2tart+ommandPQ metho" 'an return one o& se!eral !alues, mostly to in"i'ate to An"roi" =hat shoul" happen i& the ser!i'e7s pro'ess shoul" be kille" =hile it is running. 5he most likely return !alues are,
2&A?& 2&I+H5,
meaning that the ser!i'e shoul" be mo!e" ba'k into the starte" state (as i& on2tart+ommandPQ ha" been 'alle"), but "o not re-"eli!er the Intent to on2tart+ommandPQ
2&A?& ?$=$)IV$? I%&$%&, meaning that the ser!i'e shoul" be restarte" !ia a 'all to on2tart+ommandPQ, supplying the same Intent as
meaning that the ser!i'e shoul" remain stoppe" until e;pli'itly starte" by appli'ation 'o"e
1y "e&ault, 'alling start2ervicePQ not only sen"s the 'omman", but tells An"roi" to keep the ser!i'e running until something tells it to stop. >ne =ay to stop a ser!i'e is to 'all stop2ervicePQ, supplying the same Intent use" =ith start2ervicePQ, or at least one that is eRui!alent (e.g., i"enti&ies the same 'lass). At that point, the ser!i'e =ill stop an" =ill be "estroye". 2ote that stop2ervicePQ "oes not employ any sort o& re&eren'e 'ounting, so three 'alls to start2ervicePQ =ill result in a single ser!i'e running, =hi'h =ill be stoppe" by a 'all to stop2ervicePQ.
0<7
Another possibility &or stopping a ser!i'e is to ha!e the ser!i'e 'all stop2elfPQ on itsel&. ?ou might "o this i& you use start2ervicePQ to ha!e a ser!i'e begin running an" "oing some =ork on a ba'kgroun" threa", then ha!ing the ser!i'e stop itsel& =hen that ba'kgroun" =ork is 'omplete".
0<8
E!entually, the 'lient =ill nee" to 'all unbind2ervicePQ, to in"i'ate it no longer nee"s to 'ommuni'ate =ith the ser!i'e. *or e;ample, an a'ti!ity might 'all bind2ervicePQ in its on+reatePQ metho", then 'all unbind2ervicePQ in its on=estroFPQ metho". 5he 'all to unbind2ervicePQ e!entually triggers on2ervice=isconnectedPQ to be 'alle" on the 2ervice+onnection obGe't S at this point, the 'lient 'an no longer sa&ely use the 4inder obGe't. 0& there are no other boun" 'lients to the ser!i'e, An"roi" =ill shut "o=n the ser!i'e as =ell, releasing its memory. +en'e, =e "o not nee" to 'all stop2ervicePQ oursel!es S An"roi" han"les that, i& nee"e", as a si"e e&&e't o& unbin"ing. 0& the 'lient is an a'ti!ity, there are t=o important steps to take to ensure that the bin"ing sur!i!es a 'on&iguration 'hange, like a s'reen rotation, 1. 0nstea" o& 'alling bind2ervicePQ on the a'ti!ity itsel&, 'all bind2ervicePQ on the Application +onteGt (obtaine" !ia getApplication+onteGtPQ).
2. Make sure the 2ervice+onnection gets &rom the ol" instan'e o& the a'ti!ity to the ne= one, probably !ia on?etain%on+onfigurationInstancePQ. 5his allo=s the bin"ing to persist bet=een a'ti!ity instan'es.
0<:
1.
2. 8i!e the ser!i'e a publi' A#0 to register an" retra't listeners .. +a!e the ser!i'e use those listeners at appropriate times, to noti&y those =ho registere" the listener o& some e!ent <. +a!e the a'ti!ity register an" retra't a listener as nee"e" A. +a!e the a'ti!ity respon" to the listener-base" e!ents in some suitable &ashion 5he biggest 'at'h is to make sure that the a'ti!ity retra'ts the listeners =hen it is "one. Listener obGe'ts generally kno= their a'ti!ity, e;pli'itly (!ia a "ata member) or impli'itly (by being implemente" as an inner 'lass). 0& the ser!i'e is hol"ing onto "e&un't listener obGe'ts, the 'orrespon"ing a'ti!ities =ill linger in memory, e!en i& the a'ti!ities are not being use" by An"roi" any more. 5his represents a big memory leak. ?ou may =ish to use @eak?eferences, 2oft?eferences, or similar 'onstru'ts to ensure that i& an a'ti!ity is "estroye", any listeners it registers =ith your ser!i'e =ill not keep that a'ti!ity in memory.
Bro dc st Intents
An alternati!e approa'h, &irst mentione" in the 'hapter on 0ntent &ilters, is to ha!e the ser!i'e sen" a broa"'ast Intent that 'an be pi'ke" up by the a'ti!ity...assuming the a'ti!ity is still aroun" an" is not pause". 5he ser!i'e 'an 'all send4roadcastPQ, supplying an 0ntent that i"enti&ies the broa"'ast, "esigne" to be pi'ke" up by a 4roadcast?eceiver. 5his 'oul" be a 'omponent-spe'i&i' broa"'ast (e.g., neE IntentPthis8 #F?eceiver.classQ), i& the 4roadcast?eceiver is registere" in the mani&est. >r, it 'an be base" on some a'tion string, perhaps one e!en "o'umente" an" "esigne" &or thir"party appli'ations to listen &or. turn, 'an register a 4roadcast?eceiver !ia though this approa'h =ill only =ork &or Intent obGe'ts spe'i&ying some a'tion, not ones i"enti&ying a parti'ular 'omponent. 1ut, =hen the a'ti!ity7s 4roadcast?eceiver re'ei!es the broa"'ast, it 'an "o =hat it =ants to in&orm the user or other=ise up"ate itsel&.
register?eceiverPQ,
0*<
5he
a'ti!ity,
in
Pendin! Results
?our a'ti!ity 'an 'all create(ending?esultPQ. 5his returns a (endingIntent S an obGe't that represents an Intent an" the 'orrespon"ing a'tion to be per&orme" upon that Intent (e.g., use it to start an a'ti!ity). 0n this 'ase, the (endingIntent =ill 'ause a result to be "eli!ere" to your a'ti!ity7s implementation o& onActivitF?esultPQ, Gust as i& another a'ti!ity ha" been 'alle" =ith startActivitF9or?esultPQ an", in turn, 'alle" set?esultPQ to sen" ba'k a result. %in'e a (endingIntent is (arcelable, an" 'an there&ore be put into an Intent e;tra, your a'ti!ity 'an pass this (endingIntent to the ser!i'e. 5he ser!i'e, in turn, 'an 'all one o& se!eral &la!ors o& the sendPQ metho" on the (endingIntent, to noti&y the a'ti!ity (!ia onActivitF?esultPQ) o& an e!ent, possibly e!en supplying "ata (in the &orm o& an Intent) representing that e!ent.
%essen!er
?et another possibility is to use a #essenger obGe't. A #essenger sen"s messages to an a'ti!ity7s !andler. Within a single a'ti!ity, a !andler 'an be use" to sen" messages to itsel&, as =as "emonstrate" in the 'hapter on threa"s. +o=e!er, bet=een 'omponents S su'h as bet=een an a'ti!ity an" a ser!i'e S you =ill nee" a #essenger to ser!e as the bri"ge. As =ith a (endingIntent, a #essenger is (arcelable, an" so 'an be put into an Intent e;tra. 5he a'ti!ity 'alling start2ervicePQ or bind2ervicePQ =oul" atta'h a #essenger as an e;tra on the Intent. 5he ser!i'e =oul" obtain that #essenger &rom the Intent. When it is time to alert the a'ti!ity o& some e!ent, the ser!i'e =oul",
Call #essage.obtainPQ to get an empty #essage obGe't #opulate that #essage obGe't as nee"e", =ith =hate!er "ata the ser!i'e =ishes to pass to the a'ti!ity Call sendPQ on the #essenger, supplying the #essage as a parameter
0**
5he !andler =ill then re'ei!e the message !ia handle#essagePQ, on the main appli'ation threa", an" so 'an up"ate the $0 or =hate!er is ne'essary.
"oti.ic tions
Another approa'h is &or the ser!i'e to let the user kno= "ire'tly about the =ork that =as 'omplete". 5o "o that, a ser!i'e 'an raise a 2oti&i'ation S putting an i'on in the status bar an" optionally shaking or beeping or something. 5his te'hniRue is 'o!ere" in an up'oming 'hapter.
0*&
CHAPTER 18
2o= that you ha!e seen the pie'es that make up ser!i'es an" their 'lients, let us e;amine a &e= s'enarios that employ ser!i'es an" ho= those s'enarios might be implemente".
The /o)nloader
0& you ele't to "o=nloa" something &rom the An"roi" Market, you are =el'ome to ba'k out o& the Market appli'ation entirely. 5his "oes not 'an'el the "o=nloa" S the "o=nloa" an" installation run to 'ompletion, "espite no Market a'ti!ity being on-s'reen. ?ou may ha!e similar 'ir'umstan'es in your appli'ation, &rom "o=nloa"ing a pur'hase" e-book to "o=nloa"ing a map &or a game to "o=nloa"ing a &ile &rom some sort o& M"rop bo;M &ile-sharing ser!i'e. An"roi" 2.. intro"u'e" the =oEnload#anager ('o!ere" in a pre!ious 'hapter), =hi'h =oul" han"le this &or you. +o=e!er, you might nee" that sort o& 'apability on ol"er !ersions o& An"roi", at least through 2011. 5he sample proGe't re!ie=e" in this se'tion is 2ervices/=oEnloader.
0*Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
The Desi!n
5his sort o& situation is a per&e't use &or the 'omman" pattern an" an Intent2ervice. 5he Intent2ervice has a ba'kgroun" threa", so "o=nloa"s 'an take as long as nee"e". An Intent2ervice =ill automati'ally shut "o=n =hen the =ork is "one, so the ser!i'e =ill not linger an" you "o not nee" to =orry about shutting it "o=n yoursel&. ?our a'ti!ity 'an simply sen" a 'omman" !ia start2ervicePQ to the Intent2ervice to tell it to go "o the =ork. A"mitte"ly, things get a bit tri'kier =hen you =ant to ha!e the a'ti!ity &in" out =hen the "o=nloa" is 'omplete. 5his e;ample =ill sho= the use o& #essenger &or this.
public class =oEnloader eGtends Intent2ervice : public static final 2tring $]&?A #$22$%D$?67com.commonsEare.android.doEnloader.$]&?A #$22$%D$?7J private !ttp+lient client6nullJ public DownloaderPQ : superP7=oEnloader7QJ ;
0*%
O"verride public void onDestroyPQ : super.onDestroyPQJ client.getConnectionManagerPQ.shutdownPQJ ; O"verride public void on(andleIntentPIntent iQ : !ttpDet get#ethod6neE (ttp etPi.getDataPQ.toStringPQQJ int result6ActivitF.?$23)& +A%+$)$=J trF : ?esponse!andlerLbFteABM response!andler6neE Byte$rray%esponse(andlerPQJ bFteAB response4odF6client.executePget#ethod8 response!andlerQJ 9ile output6neE "ileP$nvironment.get+xternalStorageDirectoryPQ8 i.getDataPQ.getLast)athSegmentPQQJ if Poutput.existsPQQ : output.deletePQJ ; 9ile"utput2tream fos6neE "ileOutputStreamPoutput.get)athPQQJ fos.writePresponse4odFQJ fos.closePQJ result6ActivitF.?$23)& "HJ ; catch PI"$Gception e>Q : )og.ePgetClassPQ.get&amePQ8 7$Gception in doEnload78 e>QJ ; 4undle eGtras6i.get+xtrasPQJ if PeGtrasX6nullQ : #essenger messenger6P#essengerQeGtras.getP$]&?A #$22$%D$?QJ #essage msg6#essage.o'tainPQJ msg.arg16resultJ trF : messenger.sendPmsgQJ ; catch Pandroid.os.?emote$Gception e1Q : )og.wPgetClassPQ.get&amePQ8 7$Gception sending message78 e1QJ ;
0*0
; ; ;
0n on+reatePQ, =e obtain a =efault!ttp+lient obGe't, as =as "es'ribe" in the 'hapter on 0nternet a''ess. 0n on=estroFPQ, =e shut "o=n the 'lient. 5his =ay, i& se!eral "o=nloa" reRuests are in!oke" in seRuen'e, =e 'an use a single =efault!ttp+lient obGe't S the Intent2ervice =ill only shut "o=n a&ter all enRueue" =ork has been 'omplete". 5he bulk o& the =ork is a''omplishe" in on!andleIntentPQ, =hi'h is 'alle" on the Intent2ervice, on a ba'kgroun" threa", e!ery time start2ervicePQ is 'alle". *or the Intent, =e obtain the $ L o& the &ile to "o=nloa" !ia a 'all to get=ataPQ on the supplie" Intent. A'tually "o=nloa"ing the &ile uses the =efault!ttp+lient obGe't, along =ith an !ttpDet obGe't. +o=e!er, sin'e the &ile might be binary (e.g., M#.) instea" o& te;t, =e 'annot use a 4asic?esponse!andler. 0nstea", =e use a 4FteArraF?esponse!andler S a 'ustom ?esponse!andler 'lone" &rom the sour'e &or 4asic?esponse!andler, but one that returns a bFteAB instea" o& a 2tring,
package com.commonsEare.android.doEnloaderJ import import import import import import import java.io.I"$GceptionJ org.apache.http.!ttp$ntitFJ org.apache.http.!ttp?esponseJ org.apache.http.2tatus)ineJ org.apache.http.client.?esponse!andlerJ org.apache.http.client.!ttp?esponse$GceptionJ org.apache.http.util.$ntitF3tilsJ
public class 4FteArraF?esponse!andler implements ?esponse!andlerLbFteABM : public bFteAB handle%esponsePfinal !ttp?esponse responseQ throEs I"$Gception8 !ttp?esponse$Gception : 2tatus)ine status)ine6response.getStatusLinePQJ if Pstatus)ine.getStatusCodePQM6C--Q : throE neE (ttp%esponse+xceptionPstatus)ine.getStatusCodePQ8 status)ine.get%eason)hrasePQQJ ; !ttp$ntitF entitF6response.get+ntityPQJ if PentitF66nullQ : returnPnullQJ ;
0*2
returnP$ntitF3tils.toByte$rrayPentitFQQJ ; ;
>n'e the &ile is "o=nloa"e" to e;ternal storage, =e nee" to alert the a'ti!ity that the =ork is 'omplete". 0& the a'ti!ity is intereste" in this sort o& message, it =ill ha!e atta'he" a #essenger obGe't as $]&?A #$22$%D$? to the Intent. =oEnloader gets the #essenger, 'reates an empty #essage obGe't, an" puts a result 'o"e in the arg1 &iel" o& the #essage. 0t then sen"s the #essage to the a'ti!ity. 0& the a'ti!ity =as "estroye" be&ore this point, the reRuest to sen" the message =ill &ail =ith a ?emote"bject$Gception. %in'e this is an Intent2ervice, it =ill automati'ally shut "o=n =hen on!andleIntentPQ 'ompletes, i& there is no more =ork Rueue" to be "one.
When the user 'li'ks the button, do&he=oEnloadPQ is 'alle" to "isable the button (to pre!ent a''i"ental "upli'ate "o=nloa"s) an" 'all start2ervicePQ,
0*7
public void doTheDownloadPVieE vQ : b.set+na'ledPfalseQJ Intent i6neE IntentPthis8 =oEnloader.classQJ i.setDataP3ri.parseP7http://commonsEare.com/Android/eGcerpt.pdf7QQJ i.put+xtraP=oEnloader.$]&?A #$22$%D$?8 neE MessengerPhandlerQQJ startSer!icePiQJ ;
+ere, the Intent =e pass o!er has the $ L o& the &ile to "o=nloa" (in this 'ase, a $ L pointing to a #@*), plus a #essenger in the $]&?A #$22$%D$? e;tra. 5hat #essenger is 'reate" =ith an atta'hment to the a'ti!ity7s !andler,
private !andler handler6neE (andlerPQ : O"verride public void handleMessageP#essage msgQ : b.set+na'ledPtrueQJ &oast .makeTextP=oEnloader=emo.this8 7=oEnload completeX78 &oast.)$%D&! )"%DQ .showPQJ
; ;J
0& the a'ti!ity is still aroun" =hen the "o=nloa" is 'omplete, the !andler enables the button an" "isplays a &oast to let the user kno= that the "o=nloa" is 'omplete. 2ote that the a'ti!ity is ignoring the result 'o"e supplie" by the ser!i'e, though in prin'iple it 'oul" "o something "i&&erent in both the su''ess an" &ailure 'ases.
The Desi!n
>n'e again, =e =ill use start2ervicePQ, sin'e =e =ant the ser!i'e to run e!en =hen the a'ti!ity starting it has been "estroye". +o=e!er, this time, =e =ill use a regular 2ervice, rather than an Intent2ervice. An Intent2ervice is "esigne" to "o =ork an" stop itsel&, =hereas in this 'ase, =e =ant the user to be able to stop the musi' playba'k. %in'e musi' playba'k is outsi"e the s'ope o& this book, the ser!i'e =ill simply stub out those parti'ular operations.
public class (laFer2ervice eGtends 2ervice : public static final 2tring $]&?A ()A5)I2&67$]&?A ()A5)I2&7J public static final 2tring $]&?A 2!399)$67$]&?A 2!399)$7J private boolean is(laFing6falseJ O"verride public int onStartCommandPIntent intent8 int flags8 int startIdQ : 2tring plaFlist6intent.getString+xtraP$]&?A ()A5)I2&QJ boolean use2huffle6intent.getBoolean+xtraP$]&?A 2!399)$8 falseQJ playPplaFlist8 use2huffleQJ returnP2&A?& %"& 2&I+H5QJ ; O"verride public void onDestroyPQ : stopPQJ ; O"verride public I4inder onBindPIntent intentQ : returnPnullQJ
0*:
; private void playP2tring plaFlist8 boolean use2huffleQ : if PXis(laFingQ : )og.wPgetClassPQ.get&amePQ8 7Dot to plaFPQX7QJ is(laFing6trueJ ; ; private void stopPQ : if Pis(laFingQ : )og.wPgetClassPQ.get&amePQ8 7Dot to stopPQX7QJ is(laFing6falseJ ; ; ;
0n this 'ase, =e really "o not nee" anything &or on+reatePQ, so that li&e'y'le metho" is skippe". >n the other han", =e ha!e to implement on4indPQ, be'ause that is a reRuire" metho" o& 2ervice sub'lasses. Intent2ervice implements on4indPQ &or us, =hi'h is =hy that =as not nee"e" &or the =oEnloader sample. When the 'lient 'alls start2ervicePQ, on2tart+ommandPQ is 'alle" in (laFer2ervice. +ere, =e get the Intent an" pi'k out some e;tras to tell us =hat to play ba'k ($]&?A ()A5)I2&) an" other 'on&iguration "etails (e.g., $]&?A 2!399)$). on2tart+ommandPQ 'alls plaFPQ, =hi'h simply &lags that =e are playing an" logs a message to LogCat S a real musi' player =oul" use #edia(laFer to start playing the &irst song in the playlist. on2tart+ommandPQ returns 2&A?& %"& 2&I+H5, in"i'ating that i& An"roi" has to kill o&& this ser!i'e (e.g., lo= memory), it shoul" not restart it on'e 'on"itions impro!e.
on=estroFPQ stops the musi' &rom playing S theoreti'ally, any=ay S by 'alling a stopPQ metho". >n'e again, this Gust logs a message to LogCat,
0n the up'oming 'hapter on noti&i'ations, =e =ill re!isit this sample an" "is'uss the use o& start9oregroundPQ to make it easier &or the user to get ba'k to the musi' player, plus let An"roi" kno= that the ser!i'e is "eli!ering part o& the &oregroun" e;perien'e an" there&ore shoul" not be shut "o=n.
0&<
public class 9ake(laFer eGtends ActivitF : O"verride public void onCreateP4undle savedInstance2tateQ : super.onCreatePsavedInstance2tateQJ setContentViewP?.laFout.mainQJ ; public void start)layerPVieE vQ : Intent i6neE IntentPthis8 (laFer2ervice.classQJ i.put+xtraP(laFer2ervice.$]&?A ()A5)I2&8 7main7QJ i.put+xtraP(laFer2ervice.$]&?A 2!399)$8 trueQJ startSer!icePiQJ
0&*
5he on+reatePQ metho" merely loa"s the $0. 5he start(laFerPQ metho" 'onstru'ts an Intent =ith &ake !alues &or $]&?A ()A5)I2& an" $]&?A 2!399)$, then 'alls start2ervicePQ. A&ter you press the top button, you =ill see the 'orrespon"ing message in LogCat. %imilarly, stop(laFerPQ 'alls stop2ervicePQ, triggering the se'on" LogCat message. 2otably, you "o not nee" to keep the a'ti!ity running in bet=een those button 'li'ks S you 'an e;it the a'ti!ity !ia 1ACD an" 'ome ba'k later to stop the ser!i'e.
0&&
The Desi!n
5o use the bin"ing pattern, =e =ill nee" to e;pose an A#0 &rom a Mbin"erM obGe't. %in'e the =eather &ore'ast arri!es in a singularly a=&ul FML stru'ture, =e =ill ha!e the bin"er be responsible &or parsing the FML. +en'e, =e 'an say that the bin"er =ill ha!e a get9orecastPQ metho" to get us an ArraF)ist o& 9orecast obGe'ts, ea'h 9orecast representing one timestampPtemperaturePpre'ipitation triple. >n'e again, to supply the latitu"e an" longitu"e o& the &ore'ast roster to retrie!e, =e =ill use a )ocation obGe't, =hi'h =ill be obtaine" &rom 8#%. 5his part o& the sample =ill be "es'ribe" in greater "etail in the 'hapter on lo'ation management. %in'e the Web ser!i'e 'all may take a =hile, it is unsa&e to "o this on the main appli'ation threa". 0n this sample, =e =ill ha!e the ser!i'e use an AsFnc&ask to 'all our =eather A#0, so the a'ti!ity largely 'an be ignorant o& threa"ing issues.
0&-
2. #ass the 2ervice+onnection representing this bin"ing &rom the ol" a'ti!ity instan'e to the ne= one as part o& the 'on&iguration 'hange 5o a''omplish the se'on" &eat, you =ill nee" to use the same on?etain%on+onfigurationInstancePQ tri'k as =as use" =ith threa"s.
The 5orec st
5he 9orecast 'lass merely en'apsulates the three pie'es o& the &ore'ast "ata triple, the timestamp, the temperature, an" the i'on in"i'ating the e;pe'te" pre'ipitation (i& any),
package com.commonsEare.android.EeatherJ class 9orecast : 2tring time677J Integer temp6nullJ 2tring icon3rl677J 2tring getTimePQ : returnPtimeQJ ; void setTimeP2tring timeQ : this.time6time.su'stringP-810Q.replacePI&I8 I IQJ ; Integer getTempPQ : returnPtempQJ ; void setTempPInteger tempQ : this.temp6tempJ ; 2tring getIconPQ : returnPicon3rlQJ ; void setIconP2tring icon3rlQ :
0&%
this.icon3rl6icon3rlJ ; ;
The Inter. ce
1e'ause =e are going to &et'h the a'tual =eather &ore'ast on a ba'kgroun" threa" in the ser!i'e, =e ha!e a slight A#0 'hallenge S 'alls on our bin"er are syn'hronous. +en'e, =e 'annot ha!e a get9orecastPQ metho" that returns our &ore'ast. ather, =e nee" to gi!e some =ay &or the ser!i'e to get the &ore'ast ba'k to our a'ti!ity. 0n this 'ase, =e =ill pass in a listener obGe't (@eather)istener), that the ser!i'e =ill use =hen a &ore'ast is rea"y,
package com.commonsEare.android.EeatherJ import java.util.ArraF)istJ public interface @eather)istener : void update"orecastPArraF)istL9orecastM forecastQJ void handle+rrorP$Gception eQJ ;
The Binder
5he @eather4inder e;ten"s 4inder, a reRuirement &or the lo'al bin"ing pattern. >ther than that, the A#0 is up to us. +en'e, =e e;pose three metho"s, 1.
on+reatePQ, to be 'alle" =hen get a =efault!ttp+lient obGe't
the @eather4inder is set up, so =e 'an to use =ith the Web ser!i'e
2. on=estroFPQ, to be 'alle" =hen the @eather4inder is no longer nee"e", so =e 'an shut "o=n that =efault!ttp+lient obGe't .. get9orecastPQ, the main publi' A#0 &or use by our a'ti!ity, to ki'k o&& the ba'kgroun" =ork to 'reate our ArraF)ist o& 9orecast obGe'ts gi!en a )ocation
package com.commonsEare.android.EeatherJ import android.app.2erviceJ
0&0
import import import import import import import import import import import import import import import import import import import import
android.content.+onteGtJ android.content.IntentJ android.location.)ocationJ android.os.AsFnc&askJ android.os.4inderJ android.os.4undleJ java.io.I"$GceptionJ java.io.2tring?eaderJ java.util.ArraF)istJ javaG.Gml.parsers.=ocument4uilderJ javaG.Gml.parsers.=ocument4uilder9actorFJ org.apache.http.client.?esponse!andlerJ org.apache.http.client.!ttp+lientJ org.apache.http.client.methods.!ttpDetJ org.apache.http.impl.client.4asic?esponse!andlerJ org.apache.http.impl.client.=efault!ttp+lientJ org.ECc.dom.=ocumentJ org.ECc.dom.$lementJ org.ECc.dom.%ode)istJ org.Gml.saG.Input2ourceJ
public class @eather4inder eGtends 4inder : private 2tring forecast6nullJ private !ttp+lient client6nullJ private 2tring format6nullJ void onCreateP+onteGt ctGtQ : client6neE Default(ttpClientPQJ format6ctGt.getStringP?.string.urlQJ ; void onDestroyPQ : client.getConnectionManagerPQ.shutdownPQJ ; void get"orecastP)ocation loc8 @eather)istener listenerQ : neE "etch"orecastTaskPlistenerQ.executePlocQJ ; private ArraF)istL9orecastM 'uild"orecastsP2tring raEQ throEs $Gception : ArraF)istL9orecastM forecasts6neE ArraF)istL9orecastMPQJ =ocument4uilder builder6=ocument4uilder9actorF .newInstancePQ .newDocumentBuilderPQJ =ocument doc6builder.parsePneE InputSourcePneE String%eaderPraEQQQJ %ode)ist times6doc.get+lementsByTag&ameP7start-valid-time7QJ for Pint i6-JiLtimes.getLengthPQJiRRQ : $lement time6P$lementQtimes.itemPiQJ 9orecast forecast6neE "orecastPQJ forecasts.addPforecastQJ forecast.setTimePtime.get"irstChildPQ.get&odeValuePQQJ ;
0&2
%ode)ist temps6doc.get+lementsByTag&ameP7value7QJ for Pint i6-JiLtemps.getLengthPQJiRRQ : $lement temp6P$lementQtemps.itemPiQJ 9orecast forecast6forecasts.getPiQJ ; forecast.setTempPneE IntegerPtemp.get"irstChildPQ.get&odeValuePQQQJ
%ode)ist icons6doc.get+lementsByTag&ameP7icon-link7QJ for Pint i6-JiLicons.getLengthPQJiRRQ : $lement icon6P$lementQicons.itemPiQJ 9orecast forecast6forecasts.getPiQJ forecast.setIconPicon.get"irstChildPQ.get&odeValuePQQJ ; ; : returnPforecastsQJ
class 9etch9orecast&ask eGtends AsFnc&askL)ocation8 Void8 ArraF)istL9orecastMM $Gception e6nullJ @eather)istener listener6nullJ "etch"orecastTaskP@eather)istener listenerQ : this.listener6listenerJ ; O"verride protected ArraF)istL9orecastM doInBackgroundP)ocation... locsQ : ArraF)istL9orecastM result6nullJ trF : )ocation loc6locsA-BJ 2tring url62tring.formatPformat8 loc.getLatitudePQ8 loc.getLongitudePQQJ !ttpDet get#ethod6neE (ttp etPurlQJ ?esponse!andlerL2tringM response!andler6neE Basic%esponse(andlerPQJ 2tring response4odF6client.executePget#ethod8 response!andlerQJ result6'uild"orecastsPresponse4odFQJ ; catch P$Gception eQ : this.e6eJ ; ; returnPresultQJ
0&7
; ; ; ;
Most o&
is merely "oing the Web ser!i'e reRuest using an" an !ttpDet obGe't, plus using the @>M parser to 'on!ert the FML into the 9orecast obGe'ts. +o=e!er, this is =rappe" in a 9etch9orecast&ask S an AsFnc&ask that =ill "o the +55# operation an" parsing on a ba'kgroun" threa". 0n on(ost$GecutePQ, the task in!okes our @eather)istener, either to supply the &ore'ast ( update9orecastPQ) or han" o!er an $Gception that =as raise" (handle$rrorPQ).
=efault!ttp+lient
this
The Service
5he @eather2ervice, there&ore, is &airly short, =ith the business logi' "elegate" to @eather4inder,
package com.commonsEare.android.EeatherJ import import import import android.app.2erviceJ android.content.IntentJ android.os.I4inderJ java.util.ArraF)istJ
public class @eather2ervice eGtends 2ervice : private final @eather4inder binder6neE #eatherBinderPQJ O"verride public void onCreatePQ : super.onCreatePQJ ; binder.onCreatePthisQJ
0&8
>ur on+reatePQ an" on=estroFPQ metho"s "elegate to the @eather4inder, an" on4indPQ returns the @eather4inder itsel&.
1in" to the ser!i'e in on+reatePQ Arrange to get 8#% &i;es, in the &orm o& )ocation obGe'ts When a &i; 'omes in, use the @eather4inder to get a &ore'ast, 'on!ert it to +5ML, an" "isplay it in a @ebVieE $nbin" &rom the ser!i'e in on=estroFPQ
+o=e!er, our "e'ision to use the bin"ing pattern an" to ha!e the a'ti!ity "eal =ith the ba'kgroun" threa" means there is more =ork in!ol!e" than those bullet points. *irst, here is the &ull @eather=emo implementation,
package com.commonsEare.android.EeatherJ import import import import import import import import import import import import android.app.ActivitFJ android.app.Alert=ialogJ android.content.+omponent%ameJ android.content.+onteGtJ android.content.IntentJ android.content.Intent9ilterJ android.content.2ervice+onnectionJ android.location.)ocationJ android.location.)ocation)istenerJ android.location.)ocation#anagerJ android.os.AsFnc&askJ android.os.4undleJ
0&:
public class @eather=emo eGtends ActivitF : private @ebVieE broEserJ private )ocation#anager mgr6nullJ private 2tate state6nullJ private boolean is+onfiguration+hanging6falseJ O"verride public void onCreateP4undle savedInstance2tateQ : super.onCreatePsavedInstance2tateQJ setContentViewP?.laFout.mainQJ broEser6P@ebVieEQfindViewByIdP?.id.EebkitQJ state6P2tateQgetLast&onConfigurationInstance PQJ if Pstate66nullQ : state6neE StatePQJ get$pplicationContextPQ .'indSer!icePneE IntentPthis8 @eather2ervice.classQ8 state.svc+onn8 4I%= A3&" +?$A&$QJ ; else if Pstate.last9orecastX6nullQ : show"orecastPQJ ; state.attachPthisQJ mgr6P)ocation#anagerQgetSystemSer!iceP)"+A&I"% 2$?VI+$QJ mgr.re-uestLocation*pdatesP)ocation#anager.D(2 (?"VI=$?8 C0-----8 1---8 on)ocation+hangeQJ
O"verride public void onDestroyPQ : super.onDestroyPQJ if PmgrX6nullQ : mgr.remo!e*pdatesPon)ocation+hangeQJ ; if PXis+onfiguration+hangingQ : get$pplicationContextPQ.un'indSer!icePstate.svc+onnQJ ; ; O"verride public "bject on%etain&onConfigurationInstance PQ : is+onfiguration+hanging6trueJ
0-<
returnPstateQJ
private void goBlooeyP&hroEable tQ : Alert=ialog.4uilder builder6neE Alert=ialog.BuilderPthisQJ builder .setTitleP7$GceptionX7Q .setMessagePt.toStringPQQ .set)ositi!eButtonP7"H78 nullQ .showPQJ
static 2tring generate)agePArraF)istL9orecastM forecastsQ : 2tring4uilder buf?esult6neE StringBuilderP7LhtmlMLbodFMLtableM7QJ buf?esult.appendP7LtrMLth Eidth6T7.-\T7M&imeL/thM7R 7LthM&emperatureL/thMLthM9orecastL/thML/trM7QJ for P9orecast forecast : forecastsQ : buf?esult.appendP7LtrMLtd align6T7centerT7M7QJ buf?esult.appendPforecast.getTimePQQJ buf?esult.appendP7L/tdMLtd align6T7centerT7M7QJ buf?esult.appendPforecast.getTempPQQJ buf?esult.appendP7L/tdMLtdMLimg src6T77QJ buf?esult.appendPforecast.getIconPQQJ buf?esult.appendP7T7ML/tdML/trM7QJ ; buf?esult.appendP7L/tableML/bodFML/htmlM7QJ returnPbuf?esult.toStringPQQJ ; void show"orecastPQ : broEser.loadData#ithBase*%LPnull8 state.last9orecast8 7teGt/html78 73&9-,78 nullQJ ; )ocation)istener on)ocation+hange6neE LocationListenerPQ : public void onLocationChangedP)ocation locationQ : if Pstate.EeatherX6nullQ : state.Eeather.get"orecastPlocation8 stateQJ ; else : )og.wPgetClassPQ.get&amePQ8 73nable to fetch forecast [ no @eather4inder7QJ ; ; public void on)ro!iderDisa'ledP2tring providerQ : // reUuired for interface8 not used ;
0-*
public void on)ro!ider+na'ledP2tring providerQ : // reUuired for interface8 not used ; public void onStatusChangedP2tring provider8 int status8 4undle eGtrasQ : // reUuired for interface8 not used ; ;J static class 2tate implements @eather)istener : @eather4inder Eeather6nullJ @eather=emo activitF6nullJ 2tring last9orecast6nullJ void attachP@eather=emo activitFQ : this.activitF6activitFJ ; public void update"orecastPArraF)istL9orecastM forecastQ : last9orecast6generate)agePforecastQJ activitF.show"orecastPQJ ; public void handle+rrorP$Gception eQ : activitF.goBlooeyPeQJ ; 2ervice+onnection svc+onn6neE Ser!iceConnectionPQ : public void onSer!iceConnectedP+omponent%ame class%ame8 I4inder raE4inderQ : Eeather6P@eather4inderQraE4inderJ ; public void onSer!iceDisconnectedP+omponent%ame class%ameQ : Eeather6nullJ ;
;J ; ;
2o=, let us look at the highlights o& the ser!i'e 'onne'tion an" the ba'kgroun" threa".
% n !in! the St te
We nee" to ensure that our 2ervice+onnection 'an be passe" bet=een a'ti!ity instan'es on a 'on&iguration 'hange. +en'e, =e ha!e a 2tate stati'
0-&
inner 'lass to hol" that, plus t=o other bits o& in&ormation, the ActivitF the state is asso'iate" =ith, an" a 2tring sho=ing the last &ore'ast =e retrie!e",
static class 2tate implements @eather)istener : @eather4inder Eeather6nullJ @eather=emo activitF6nullJ 2tring last9orecast6nullJ void attachP@eather=emo activitFQ : this.activitF6activitFJ ; public void update"orecastPArraF)istL9orecastM forecastQ : last9orecast6generate)agePforecastQJ activitF.show"orecastPQJ ; public void handle+rrorP$Gception eQ : activitF.goBlooeyPeQJ ; 2ervice+onnection svc+onn6neE Ser!iceConnectionPQ : public void onSer!iceConnectedP+omponent%ame class%ame8 I4inder raE4inderQ : Eeather6P@eather4inderQraE4inderJ ; public void onSer!iceDisconnectedP+omponent%ame class%ameQ : Eeather6nullJ ;
;J ;
5he last9orecast 2tring is to allo= us to re-"isplay the generate" +5ML a&ter a 'on&iguration 'hange. >ther=ise, i& the user rotates the s'reen, =e =ill lose our &ore'ast (only hel" in the ol" instan'e7s @ebVieE) an" either ha!e to retrie!e a &resh one or =ait &or a 8#% &i;. We return this 2tate obGe't &rom on?etain%on+onfigurationInstancePQ,
O"verride public "bject on%etain&onConfigurationInstance PQ : is+onfiguration+hanging6trueJ ; returnPstateQJ
0--
0n on+reatePQ, i& there is no non-'on&iguration instan'e, =e 'reate a &resh 2tate an" bin" to the ser!i'e, sin'e =e "o not ha!e a ser!i'e 'onne'tion at present. >n the other han", i& on+reatePQ gets a 2tate &rom get)ast%on+onfigurationInstancePQ, it simply hol"s onto that state an" reloa"s our &ore'ast in the @ebVieE. 0n either 'ase, on+reatePQ in"i'ates to the 2tate that the ne= a'ti!ity instan'e is the 'urrent one,
O"verride public void onCreateP4undle savedInstance2tateQ : super.onCreatePsavedInstance2tateQJ setContentViewP?.laFout.mainQJ broEser6P@ebVieEQfindViewByIdP?.id.EebkitQJ state6P2tateQgetLast&onConfigurationInstance PQJ if Pstate66nullQ : state6neE StatePQJ get$pplicationContextPQ .'indSer!icePneE IntentPthis8 @eather2ervice.classQ8 state.svc+onn8 4I%= A3&" +?$A&$QJ ; else if Pstate.last9orecastX6nullQ : show"orecastPQJ ; state.attachPthisQJ mgr6P)ocation#anagerQgetSystemSer!iceP)"+A&I"% 2$?VI+$QJ mgr.re-uestLocation*pdatesP)ocation#anager.D(2 (?"VI=$?8 C0-----8 1---8 on)ocation+hangeQJ
Time to -n=ind
We bin" to the ser!i'e =hen on+reatePQ is 'alle", i& it "i" not re'ei!e a 2tate !ia get)ast%on+onfigurationInstancePQ (in =hi'h 'ase, =e are alrea"y boun"). 5his begs the Ruestion, =hen "o =e unbin" &rom the ser!i'eH We =ant to unbin" =hen the a'ti!ity is "estroye"...but not i& the a'ti!ity is being "estroye" be'ause o& a 'on&iguration 'hange. $n&ortunately, there is no built-in =ay to make that "etermination &rom on=estroFPQ. 5here is an is9inishingPQ metho" you 'an 'all on an ActivitF, =hi'h =ill return true i& the a'ti!ity is going a=ay &or goo" or false
0-%
other=ise. 5his "oes return false &or a 'on&iguration 'hange, but it =ill also return false i& the a'ti!ity is being "estroye" to &ree up AM an" the user might be able to return to it !ia the 1ACD button. 5his is =hy on?etain%on+onfigurationInstancePQ is+onfiguration+hanging &lag in @eather=emo to true. 5hat &lag false. We then 'he'k that &lag to see i& =e shoul" unbin" &rom or not, &lips a is initially the ser!i'e
0-0
CHAPTER 19
#op-up messages. 5ray i'ons an" their asso'iate" MbubbleM messages. 1oun'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 Gust in'oming 'alls, lo= battery, alarm 'lo'ks, appointment noti&i'ations, in'oming te;t message or email, et'. 2ot surprisingly, An"roi" has a =hole &rame=ork &or "ealing =ith these sorts o& things, 'olle'ti!ely 'alle" Mnoti&i'ationsM.
?otification Configuration
A ser!i'e, running in the ba'kgroun", nee"s a =ay to let users kno= something o& interest has o''urre", su'h as =hen email has been re'ei!e". Moreo!er, the ser!i'e may nee" some =ay to steer the user to an a'ti!ity =here they 'an a't upon the e!ent S rea"ing a re'ei!e" message, &or e;ample. *or this, An"roi" supplies status bar i'ons, &lashing lights, an" other in"i'ators 'olle'ti!ely kno=n as Mnoti&i'ationsM. ?our 'urrent phone may =ell ha!e su'h i'ons, to in"i'ate battery li&e, signal strength, =hether 1luetooth 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 ha!ing them appear only =hen nee"e" (e.g., a message has arri!e").
0-7
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
0n An"roi", you 'an raise noti&i'ations !ia the %otification#anager. 5he %otification#anager is a system ser!i'e. 5o use it, you nee" to get the ser!i'e obGe't !ia get2Fstem2erviceP%"&I9I+A&I"% 2$?VI+$Q &rom your a'ti!ity. 5he %otification#anager gi!es you three metho"s, one to raise a %otification (notifFPQ) an" t=o to get ri" o& an e;isting %otification (cancelPQ an" cancelAllPQ). 5he notifFPQ metho" takes a %otification, =hi'h is a "ata stru'ture that spells out =hat &orm your pestering shoul" take S the 'apabilities o& this obGe't are "es'ribe" in the &ollo=ing se'tions.
0-8
All o& these, by "e&ault, happen on'e (e.g., one LE@ &lash, one playba'k o& the soun"). 0& you =ant to ha!e them persist until the %otification is 'an'ele", you =ill nee" to set the flags publi' &iel" in your %otification to in'lu"e 9)AD I%2I2&$%&. 0nstea" o& manually spe'i&ying the har"=are options, you 'an also use the defaults &iel" in the %otification, setting it to =$9A3)& )ID!&2, =$9A3)& 2"3%=, =$9A3)& VI4?A&$, or =$9A3)& A)), =hi'h =ill use plat&orm "e&aults &or all har"=are options.
Icons
While the &lashing lights, soun"s, an" !ibrations are aime" at getting somebo"y to look at the "e!i'e, i'ons are "esigne" to take them the ne;t step an" tell them =hat7s so important. 5o set up an i'on &or a %otification, you nee" to set t=o publi' &iel"s, icon, =here you pro!i"e the i"enti&ier o& a =raEable resour'e representing the i'on, an" contentIntent, =here you supply a (endingIntent to be raise" =hen the i'on is 'li'ke". A (endingIntent is a =rapper aroun" a regular Intent that allo=s the Intent to be in!oke" later, by another pro'ess, to start an a'ti!ity or =hate!er. 5ypi'ally, a %otification =ill trigger an a'ti!ity, in =hi'h 'ase you =oul" 'reate the (endingIntent !ia the stati' getActivitFPQ metho" an" gi!e it an Intent that i"enti&ies one o& your a'ti!ities. 5hat being sai", you 'oul" ha!e the %otification sen" a broa"'ast Intent instea" by using a get4roadcastPQ !ersion o& a (endingIntent. ?ou 'an also supply a te;t blurb to appear =hen the i'on is put on the status bar (ticker&eGt). 0& you =ant all three, the simpler approa'h is to 'all set)atest$ventInfoPQ, =hi'h =raps all three o& those in a single 'all. ?ou 'an also set a !alue in the number publi' &iel" o& your %otification. 5his =ill 'ause the number you supply to be "ra=n o!er top o& the icon in one
0-:
'orner. 5his is use", &or e;ample, to sho= the number o& unrea" email messages, to sa!e you &rom ha!ing to ha!e a bun'h o& "i&&erent i'ons, one &or ea'h possible number o& unrea" messages. 1y "e&ault, the number =ill be ignore" an" not use". 2ote that the siKe o& the i'ons use" =ith a %otification 'hange" =ith An"roi" 2... 0t use" to be that 2Ap; sRuare =as the "esire" siKe. 2o=, they pre&er per-"ensity i'ons in a more re'tangular shape,
2<p; sRuare (insi"e a 2<p; =i"e by .8p; high boun"ing bo;) &or high-"ensity s'reens 1/p; sRuare (insi"e a 1/p; by 2Ap; boun"ing bo;) &or me"ium"ensity s'reens 12p; sRuare (insi"e a 12p; by 13p; boun"ing bo;) &or lo=-"ensity s'reens
Appli'ations &ollo=ing these rules =ill =ant to use spe'i&i' resour'e sets &or the ne= i'ons,
res/draEable-hdpi-v*/ res/draEable-mdpi-v*/ res/draEable-ldpi-v*/ res/draEable/
&or the high-"ensity An"roi" 2.. e"itions &or the me"ium-"ensity An"roi" 2.. e"itions &or the lo=-"ensity An"roi" 2.. e"itions
More "etails on gui"elines &or all i'ons, in'lu"ing status bar i'ons, 'an be &oun" in the An"roi" "e!eloper "o'umentation.
?otifications in Action
Let us no= take a peek at the %otifications/%otifF1 sample proGe't, in parti'ular the %otifF=emo 'lass,
package com.commonsEare.android.notifFJ import android.app.ActivitFJ import android.app.%otificationJ
0%<
public class %otifF=emo eGtends ActivitF : private static final int %"&I95 #$ I=61CC/J private int count6-J private %otification#anager mgr6nullJ O"verride public void onCreateP4undle savedInstance2tateQ : super.onCreatePsavedInstance2tateQJ setContentViewP?.laFout.mainQJ mgr6P%otification#anagerQgetSystemSer!iceP%"&I9I+A&I"% 2$?VI+$QJ ; public void notifyMePVieE vQ : %otification note6neE &otificationP?.draEable.stat notifF chat8 72tatus messageX78 2Fstem.currentTimeMillisPQQJ (endingIntent i6(endingIntent.get$cti!ityPthis8 -8 neE IntentPthis8 %otifF#essage.classQ8 -QJ note.setLatest+!entInfoPthis8 7%otification &itle78 7&his is the notification message78 iQJ note.number6RRcountJ note.vibrate6neE longAB :.--)8 >--)8 >--)8 .--);J note.flagsW6%otification.9)AD A3&" +A%+$)J ; mgr.notifyP%"&I95 #$ I=8 noteQJ
5his a'ti!ity sports t=o large buttons, one to ki'k o&& a noti&i'ation a&ter a &i!e-se'on" "elay, an" one to 'an'el that noti&i'ation (i& it is a'ti!e),
0%*
Creating the noti&i'ation, in notifF#ePQ, is a''omplishe" in a han"&ul o& steps, 1. Create a %otification obGe't =ith our i'on, a message to &lash on the status bar as the noti&i'ation is raise", an" the time asso'iate" =ith this e!ent
2. Create a (endingIntent that =ill trigger the "isplay o& another a'ti!ity (%otifF#essage) .. $se set)atest$ventInfoPQ 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 (endingIntent <. $p"ate the MnumberM asso'iate" =ith the noti&i'ation A. %pe'i&y a !ibration pattern S A00ms on, 200ms o&&, 200ms on, A00ms o&& /. 0n'lu"e 9)AD A3&" +A%+$) in the %otification obGe't7s flags &iel"
0%&
4. 5ell the %otification#anager (obtaine" in on+reatePQ)to "isplay the noti&i'ation +en'e, i& =e 'li'k the top button, our i'on =ill appear in the status bar, brie&ly along =ith our status message.
"igure *%:1 ,ur notification as it appears on the status bar@ )ith our status message
A&ter the status message goes a=ay, the i'on =ill ha!e our number (initially 1) superimpose" on the lo=er-right 'orner S you might use this to signi&y the number o& unrea" messages.
0%-
0& you "rag "o=n the i'on, a "ra=er =ill appear beneath the status bar. @rag 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%%
"igure *0*1 The notifications dra)er@ fully expanded@ )ith our notification
0& you 'li'k on the noti&i'ation entry in the "ra=er, you7ll be taken to a tri!ial a'ti!ity "isplaying a message S though in a real appli'ation, this a'ti!ity =oul" "o something use&ul base" upon the e!ent that o''urre" (e.g., take users to the ne=ly-arri!e" mail messages). Cli'king on the 'an'el button, or 'li'king on the Clear button in the "ra=er, or 'li'king on the noti&i'ation entry in the "ra=er, =ill remo!e the i'on &rom the status bar. 5he latter is be'ause =e in'lu"e" 9)AD A3&" +A%+$) in the %otification, in"i'ating that a tap on the "ra=er entry shoul" 'an'el the %otification itsel&.
seems to ha!e been hanging aroun" memory too long. 0"eally, you "esign your ser!i'es to "eal =ith the &a't that they may not run in"e&initely. +o=e!er, some ser!i'es =ill be misse" by the user i& they mysteriously !anish. *or e;ample, the "e&ault musi' player appli'ation that ships =ith An"roi" uses a ser!i'e &or the a'tual musi' playba'k. 5hat =ay, the user 'an listen to musi' =hile 'ontinuing to use their phone &or other purposes. 5he ser!i'e only stops =hen the user goes in an" presses the stop button in the musi' player a'ti!ity. 0& that ser!i'e =ere to be shut "o=n une;pe'te"ly, the user might =on"er =hat is =rong. %er!i'es like this 'an "e'lare themsel!es as being part o& the M&oregroun"M. 5his =ill 'ause their priority to rise an" make them less likely to be bumpe" out o& memory. 5he tra"e-o&& is that the ser!i'e has to maintain a %otification, so the user kno=s that this ser!i'e is 'laiming part o& the &oregroun". An", i"eally, that %otification pro!i"es an easy path ba'k to some a'ti!ity =here the user 'an stop the ser!i'e. 5o "o this, on on+reatePQ o& your ser!i'e (or =here!er else in the ser!i'e7s li&e it =oul" make sense), 'all start9oregroundPQ. 5his takes a %otification an" a lo'ally-uniRue integer, Gust like the notifFPQ metho" on %otification#anager. 0t 'auses the %otification to appear an" mo!es the ser!i'e into &oregroun" priority. Later on, you 'an 'all stop9oregroundPQ to return to normal priority. 2ote that this metho" =as a""e" =ith An"roi" 2.0 (A#0 le!el A). 5here =as an earlier metho", set9oregroundPQ, that per&orms a similar &un'tion in earlier !ersions o& An"roi".
0%2
+o=e!er, An"roi" may not 'onsi"er (laFer2ervice to be part o& the user e;perien'e, sin'e ser!i'es normally intera't !ery little "ire'tly =ith users. 5his means An"roi" may run (laFer2ervice in a =ay that 'aps C#$ usage (not ne'essarily ba") an" might ele't to shut "o=n the ser!i'e i& it thinks it has been running too long (probably ba"). 5he ans=er is to use start9oregroundPQ an" stop9oregroundPQ. We 'an 'all start9oregroundPQ =hen =e start the musi' playing in our plaFPQ metho",
private void playP2tring plaFlist8 boolean use2huffleQ : if PXis(laFingQ : )og.wPgetClassPQ.get&amePQ8 7Dot to plaFPQX7QJ is(laFing6trueJ %otification note6neE &otificationP?.draEable.stat notifF chat8 7+an Fou hear the musicN78 2Fstem.currentTimeMillisPQQJ Intent i6neE IntentPthis8 9ake(laFer.classQJ i.set"lagsPIntent.9)AD A+&IVI&5 +)$A? &"(W Intent.9)AD A+&IVI&5 2I%D)$ &"(QJ (endingIntent pi6(endingIntent.get$cti!ityPthis8 -8 i8 -QJ note.setLatest+!entInfoPthis8 79ake (laFer78 7%oE (laFing: T73mmmm8 %othingT778 piQJ note.flagsW6%otification.9)AD %" +)$A?J ; ; start"oregroundP1CC/8 noteQJ
5he plus si"e is that our ser!i'e =ill ha!e more C#$ a!ailability i& nee"e" an" =ill be &ar less likely to be kille". 5he user =ill see an i'on in the status bar, though. 0& they sli"e "o=n the noti&i'ation "ra=er an" tap on our %otification7s entry, they =ill be taken ba'k to 9ake(laFer S the e;isting instan'e i& there is one, other=ise a &resh instan'e, 'ourtesy o& our 0ntent &lags (Intent.9)AD A+&IVI&5 +)$A? &"(W Intent.9)AD A+&IVI&5 2I%D)$ &"(). *or a musi' player, this $0 pattern is a goo" thing, as it makes it easy &or the user to Rui'kly go ba'k to stop the musi' =hen nee"e". %topping the musi', !ia our stopPQ metho", =ill 'all stop9oregroundPQ,
0%7
5he true !alue passe" to stop9oregroundPQ tells An"roi" to remo!e the %otification, =hi'h =oul" be the typi'al approa'h &or this pattern.
0%8
>ther than the An"roi" ..0 !ersion o& the status bar, an" the e;tra-huge buttons, this is no "i&&erent than =hat you =oul" see on a pre-+oney'omb phone. 2o=, i& =e 'li'k the top button, our 2oti&i'ation appears, this time in the lo=er right, =ith the i'on an" ti'ker te;t,
2ote that i& the user taps the ti'ker, it triggers your (endingIntent, Gust as i& they ha" tappe" on the noti&i'ation "ra=er entry on a phone. When the ti'ker is remo!e", our i'on remains...=ithout the number,
0%:
0& the user taps that i'on, a noti&i'ation "ra=er-style pop-up appears nearby,
00<
5apping the i'on or the te;t triggers the (endingIntent, =hile 'li'king the F on the right 'an'els this %otification.
00*
CHAPTER 1:
0n the late 13307s, a =a!e o& !iruses sprea" through the 0nternet, "eli!ere" !ia email, using 'onta't in&ormation 'ulle" &rom Mi'roso&t >utlook. A !irus =oul" simply email 'opies o& itsel& to ea'h o& the >utlook 'onta'ts that ha" an email a""ress. 5his =as possible be'ause, at the time, >utlook "i" not take any steps to prote't "ata &rom programs using the >utlook A#0, sin'e that A#0 =as "esigne" &or or"inary "e!elopers, not !irus authors. 2o=a"ays, many appli'ations that hol" onto 'onta't "ata se'ure that "ata by reRuiring that a user e;pli'itly grant rights &or other programs to a''ess the 'onta't in&ormation. 5hose rights 'oul" be grante" on a 'ase-by-'ase basis or all at on'e at install time. An"roi" is no "i&&erent, in that it reRuires permissions &or appli'ations to rea" or =rite 'onta't "ata. An"roi"7s permission system is use&ul =ell beyon" 'onta't "ata, an" &or 'ontent pro!i"ers an" ser!i'es beyon" those supplie" by the An"roi" &rame=ork. ?ou, as an An"roi" "e!eloper, =ill &reRuently nee" to ensure your appli'ations ha!e the appropriate permissions to "o =hat you =ant to "o =ith other appli'ations7 "ata. ?ou may also ele't to reRuire permissions &or other appli'ations to use your "ata or ser!i'es, i& you make those a!ailable to other An"roi" 'omponents. 5his 'hapter 'o!ers ho= to a''omplish both these en"s.
00Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
+other@ +ay F
eRuesting the use o& other appli'ations7 "ata or ser!i'es reRuires the useselement to be a""e" to your Android#anifest.Gml &ile. ?our mani&est may ha!e Kero or more uses-permission elements, all as "ire't 'hil"ren o& the root manifest element.
permission
5he uses-permission element takes a single attribute, android:name, =hi'h is the name o& the permission your appli'ation reRuires,
Luses-permission android:name67android.permission.A++$22 )"+A&I"%7 /M
5he sto'k system permissions all begin =ith android.permission an" are liste" in the An"roi" %@D "o'umentation &or #anifest.permission. 5hir"party appli'ations may ha!e their o=n permissions, =hi'h hope&ully they ha!e "o'umente" &or you. +ere are some o& the permissions =e =ill see in this book,
I%&$?%$&,
i& your appli'ation =ishes to a''ess the 0nternet through any means, &rom ra= Ca!a so'kets through the @ebVieE =i"get
@?I&$ $]&$?%A) 2&"?AD$, A++$22 +"A?2$ )"+A&I"%
&or =riting "ata to the %@ 'ar" (or =hate!er the "e!i'e has "esignate" as Me;ternal storageM) =here the "e!i'e is an" A++$22 9I%$ )"+A&I"%, &or "etermining
+A)) (!"%$,
to allo= the appli'ation to pla'e phone 'alls "ire'tly, =ithout user inter!ention
#ermissions are 'on&irme" at the time the appli'ation is installe" S the user =ill be prompte" to 'on&irm it is >D &or your appli'ation to "o =hat the permission 'alls &or. +en'e, it is important &or you to ask &or as &e= permissions as possible an" to Gusti&y those you ask &or, so users "o not ele't to skip installing your appli'ation be'ause you ask &or too many unne'essary permissions. 5his prompt =ill not appear =hen loa"ing an appli'ation !ia $%1, su'h as "uring "e!elopment.
00%
0& you "o not ha!e the "esire" permission an" try to "o something that nee"s it, you shoul" get a 2ecuritF$Gception in&orming you o& the missing permission. 2ote that you =ill only &ail on a permission 'he'k i& you &orgot to ask &or the permission S it is impossible &or your appli'ation to be running an" not ha!e been grante" your reRueste" permissions.
000
2. A label &or the permission, something short that =oul" be un"erstan"able by users .. A "es'ription &or the permission, something a =ee bit longer that is un"erstan"able by your users
Lpermission android:name67vnd.tlagencF.sekrits.2$$ 2$H?I&27 android:label67Ostring/see sekrits label7 android:description67Ostring/see sekrits description7 /M
5his "oes not en&or'e the permission. ather, it in"i'ates that it is a possible permissionT your appli'ation must still &lag se'urity !iolations as they o''ur.
>nly appli'ations that ha!e reRueste" your in"i'ate" permission =ill be able to a''ess the se'ure" 'omponent. 0n this 'ase, 6a''ess9 means,
002
%er!i'es 'annot be starte", stoppe", or boun" to an a'ti!ity =ithout the permission 0ntent re'ei!ers ignore messages sent !ia send4roadcastPQ unless the sen"er has the permission
?our
ser!i'es
'an
'he'k
Also, you 'an in'lu"e a permission =hen you 'all send4roadcastPQ. 5his means that eligible broa"'ast re'ei!ers must hol" that permissionT those =ithout the permission are ineligible to re'ei!e it. We =ill e;amine send4roadcastPQ in greater "etail else=here in this book.
+ay
5here is no automati' "is'o!ery o& permissions at 'ompile timeT all permission &ailures o''ur at runtime. +en'e, it is important that you "o'ument the permissions reRuire" &or your publi' A#0s, in'lu"ing 'ontent pro!i"ers, ser!i'es, an" a'ti!ities inten"e" &or laun'hing &rom other a'ti!ities. >ther=ise, the programmers attempting to inter&a'e =ith your appli'ation =ill ha!e to &in" out the permission rules by trial an" error. *urthermore, you shoul" e;pe't that users o& your appli'ation =ill be prompte" to 'on&irm any permissions your appli'ation says it nee"s. +en'e, you nee" to "o'ument &or your users =hat they shoul" e;pe't, lest they get 'on&use" by the Ruestion pose" by the phone an" ele't to not install or use your appli'ation. ?ou may =ish to use string resour'es &or this,
007
so you 'an internationaliKe your permission "etails the =ay you internationaliKe all the other messages an" prompts in your appli'ation.
?ou 'annot 'reate optional permissions, ones the user 'oul" say Mno, thanksM to, that your appli'ation 'oul" rea't to "ynami'ally ?ou 'annot reRuest ne= permissions a&ter installation, so e!en i& a permission is only nee"e" &or some lightly-use" &eature, you ha!e to ask &or it any=ay
+en'e, it is important as you 'ome up =ith the &eature list &or your app that you keep permissions in min". E!ery a""itional permission that your reRuest is a &ilter that =ill 'ost you some portion o& your prospe'ti!e au"ien'e. Certain 'ombinations S su'h as I%&$?%$& an" ?$A= +"%&A+&2 S =ill ha!e a stronger e&&e't, as users &ear =hat the 'ombination 'an "o. ?ou =ill nee" to "e'i"e &or yoursel& i& the a""itional users you =ill get &rom ha!ing the &eature =ill be =orth the 'ost o& reRuiring the permissions the &eature nee"s to operate.
00:
CHAPTER 1;
A popular &eature on 'urrent-era mobile "e!i'es is 8#% 'apability, so the "e!i'e 'an tell you =here you are at any point in time. While the most popular use o& 8#% ser!i'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 you are 'hatting =ith those you are nearest. >r, you 'oul" automati'ally MgeotagM posts to 5=itter or similar ser!i'es. 8#% is not the only =ay a mobile "e!i'e 'an i"enti&y your lo'ation. Alternati!es in'lu"e,
5he European eRui!alent to 8#%, 'alle" 8alileo, =hi'h is still un"er "e!elopment 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 MhotspotsM that ha!e kno=n geographi' lo'ations
An"roi" "e!i'es may ha!e one or more o& these ser!i'es a!ailable to them. ?ou, as a "e!eloper, 'an ask the "e!i'e &or your lo'ation, plus "etails on =hat pro!i"ers are a!ailable. 5here are e!en =ays &or you to simulate your lo'ation in the emulator, &or use in testing your lo'ation-enable" appli'ations.
02Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
"inding .ourself
5he ob!ious thing to "o =ith a lo'ation ser!i'e is to &igure out =here you are right no=. 5o get a )ocation#anager S 'all get2Fstem2erviceP)"+A&I"% 2$?VI+$Q &rom your a'ti!ity or ser!i'e an" 'ast it to be a )ocation#anager. 5he ne;t step to &in" out =here you are is to get the name o& the ha!e t=o main options, 1. Ask the user to pi'k a pro!i"er "o that, you nee" to
0& you =ant the user to pi'k a pro!i"er, 'alling get(rovidersPQ on the )ocation#anager =ill gi!e you a )ist o& pro!i"ers, =hi'h you 'an then present to the user &or sele'tion. >r, you 'an 'reate an" populate a +riteria obGe't, stating the parti'ulars o& =hat you =ant out o& a )ocation(rovider, su'h as,
setAltitude?eUuiredPQ
not
setAccuracFPQ
position
to 'ontrol i& the pro!i"er must be &ree or i& it 'an in'ur a 'ost on behal& o& the "e!i'e user
set+ostAlloEedPQ
8i!en a &ille"-in +riteria obGe't, 'all get4est(roviderPQ on your )ocation#anager, an" An"roi" =ill si&t through the 'riteria an" gi!e you the best ans=er. 2ote that not all o& your 'riteria may be met S all but the monetary 'ost 'riterion might be rela;e" i& nothing mat'hes. ?ou are also =el'ome to har"-=ire in a )ocation(rovider name (e.g., D(2 (?"VI=$?), perhaps Gust &or testing purposes. >n'e you kno= the name o& the )ocation(rovider, you 'an 'all get)astHnoEn(ositionPQ to &in" out =here you =ere re'ently. +o=e!er, unless something else is 'ausing the "esire" pro!i"er to 'olle't &i;es (e.g., unless the 8#% ra"io is on), get)astHnoEn(ositionPQ =ill return null, in"i'ating that there is no kno=n position. >n the other han", get)astHnoEn(ositionPQ in'urs no monetary or po=er 'ost, sin'e the pro!i"er "oes not nee" to be a'ti!ate" to get the !alue. 5hese metho"s return a )ocation obGe't, =hi'h 'an gi!e you the latitu"e an" longitu"e o& the "e!i'e in "egrees as a Ca!a double. 0& the parti'ular lo'ation pro!i"er o&&ers other "ata, you 'an get at that as =ell,
*or altitu"e, hasAltitudePQ =ill tell you i& there is an altitu"e !alue, an" getAltitudePQ =ill return the altitu"e in meters.
020
*or bearing (i.e., 'ompass-style "ire'tion), has4earingPQ =ill tell you i& there is a bearing a!ailable, an" get4earingPQ =ill return it as "egrees east o& true north. *or spee", has2peedPQ =ill tell you i& the spee" is kno=n an" get2peedPQ =ill return the spee" in meters per se'on".
A more likely approa'h to getting the )ocation &rom a )ocation(rovider, though, is to register &or up"ates, as "es'ribe" in the ne;t se'tion.
,n the +ove
2ot all lo'ation pro!i"ers are ne'essarily imme"iately responsi!e. 8#%, &or e;ample, reRuires a'ti!ating a ra"io an" getting a &i; &rom the satellites be&ore you get a lo'ation. 5hat is =hy An"roi" "oes not o&&er a get#e#F+urrent)ocation%oEPQ metho". Combine that =ith the &a't that your users may =ell =ant their mo!ements 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. 5he Internet/@eather an" 2ervice/@eatherA(I sample appli'ations sho= ho= to register &or up"ates S 'all reUuest)ocation3pdatesPQ on your )ocation#anager instan'e. 5his takes &our parameters, 1. 5he name o& the lo'ation pro!i"er you =ish to use
2. +o= long, in millise'on"s, should ha!e elapse" be&ore =e might get a lo'ation up"ate .. +o= &ar, in meters, must the "e!i'e ha!e mo!e" be&ore =e might get a lo'ation up"ate <. A )ocation)istener that =ill be noti&ie" o& key lo'ation-relate" e!ents, as sho=n belo=,
)ocation)istener on)ocation+hange6neE LocationListenerPQ : public void onLocationChangedP)ocation locationQ : if Pstate.EeatherX6nullQ : state.Eeather.get"orecastPlocation8 stateQJ ; else :
022
)og.wPgetClassPQ.get&amePQ8 73nable to fetch forecast [ no @eather4inder7QJ ; ; public void on)ro!iderDisa'ledP2tring providerQ : // reUuired for interface8 not used ; public void on)ro!ider+na'ledP2tring providerQ : // reUuired for interface8 not used ; public void onStatusChangedP2tring provider8 int status8 4undle eGtrasQ : // reUuired for interface8 not used ; ;J
+ere, all =e "o is trigger a 9etch9orecast&ask =ith the )ocation supplie" to the on)ocation+hangedPQ 'allba'k metho". 1ear in min" that the time parameter is only a gui"e to help steer An"roi" &rom a po=er 'onsumption stan"point. ?ou may get many more lo'ation up"ates than this. 5o get the ma;imum number o& lo'ation up"ates, supply - &or both the time an" "istan'e 'onstraints. When you no longer nee" the up"ates, 'all remove3pdatesPQ =ith the )ocation)istener you registere". 0& you &ail to "o this, your appli'ation =ill 'ontinue re'ei!ing lo'ation up"ates e!en a&ter all a'ti!ities an" su'h are 'lose" up, =hi'h =ill also pre!ent An"roi" &rom re'laiming your appli'ation7s memory. 5here is another !ersion o& reUuest)ocation3pdatesPQ that takes a (endingIntent rather than a )ocation)istener. 5his is use&ul i& you =ant to be noti&ie" o& 'hanges in your position e!en =hen your 'o"e is not running. *or e;ample, i& you are logging mo!ements, you 'oul" use a (endingIntent that triggers a 4roadcast?eceiver (get4roadcastP)) an" ha!e the 4roadcast?eceiver a"" the entry to the log. 5his =ay, your 'o"e is only in memory =hen the position 'hanges, so you "o not tie up system resour'es =hile the "e!i'e is not mo!ing.
027
5he 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 Intent to be raise" A "uration &or the registration, in millise'on"s S a&ter this perio", the registration automati'ally lapses. A !alue o& -1 means the registration lasts until you manually remo!e it !ia remove(roGimitFAlertPQ. 5he (endingIntent to be raise" =hen the "e!i'e is =ithin the Mtarget KoneM e;presse" by the position an" ra"ius
2ote that it is not guarantee" that you =ill a'tually re'ei!e an Intent, i& there is an interruption in lo'ation ser!i'es, or i& the "e!i'e is not in the target Kone "uring the perio" o& time the pro;imity alert is a'ti!e. *or e;ample, i& the position is o&& by a bit, an" the ra"ius is a little too tight, the "e!i'e might only skirt the e"ge o& the target Kone, or go by so Rui'kly that the "e!i'e7s lo'ation isn7t sample" =hile in the target Kone. 0t is up to you to arrange &or an a'ti!ity or re'ei!er to respon" to the Intent you register =ith the pro;imity alert. What you then "o =hen the Intent arri!es is up to you, set up a noti&i'ation (e.g., !ibrate the "e!i'e), log the in&ormation to a 'ontent pro!i"er, post a message to a Web site, et'. 2ote that you =ill re'ei!e the Intent =hene!er the position is sample" an" you are =ithin the target Kone S not Gust upon entering the Kone. +en'e, you
028
=ill get the Intent se!eral times, perhaps Ruite a &e= times "epen"ing on the siKe o& the target Kone an" the spee" o& the "e!i'e7s mo!ement.
Testing111Testing111
5he An"roi" emulator "oes not ha!e the ability to get a &i; &rom 8#%, 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 mo!ing "e!i'e, you =ill nee" to ha!e some means o& pro!i"ing mo'k lo'ation "ata to the emulator. *or =hate!er reason, this parti'ular area has un"ergone signi&i'ant 'hanges as An"roi" itsel& has e!ol!e". 0t use" to be that you 'oul" pro!i"e mo'k lo'ation "ata =ithin your appli'ation, =hi'h =as !ery han"y &or "emonstration purposes. Alas, those options ha!e all been remo!e" as o& An"roi" 1.0. >ne likely option &or supplying mo'k lo'ation "ata is the @al!ik @ebug Monitor %er!i'e (@@M%). 5his is an e;ternal program, separate &rom the emulator, =here you 'an &ee" it single lo'ation points or &ull routes to tra!erse, in a &e= "i&&erent &ormats. @@M% is "es'ribe" in greater "etail in the 'hapter on An"roi" "e!elopment tools.
02:
CHAPTER 2<
>ne o& 8oogle7s most popular ser!i'es S a&ter sear'h, o& 'ourse S is 8oogle Maps, =here you 'an &in" e!erything &rom the nearest piKKa parlor to "ire'tions &rom 2e= ?ork City to %an *ran'is'o (only 2,30A miles:) to street !ie=s an" satellite imagery. Most An"roi" "e!i'es, not surprisingly, integrate 8oogle Maps. *or those that "o, there is a mapping a'ti!ity a!ailable to users straight o&& the main An"roi" laun'her. More rele!ant to you, as a "e!eloper, are #apVieE an" #apActivitF, =hi'h allo= you to integrate maps into your o=n appli'ations. 2ot only 'an you "isplay maps, 'ontrol the Koom le!el, an" allo= people to pan aroun", but you 'an tie in An"roi"7s lo'ation-base" ser!i'es to sho= =here the "e!i'e is an" =here it is going. *ortunately, integrating basi' mapping &eatures into your An"roi" proGe't is &airly easy. +o=e!er, there is a &air bit o& po=er a!ailable to you, i& you =ant to get sophisti'ate".
07*
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
0& you are 'onsi"ering 8oogle Maps, please re!ie= these terms 'losely to "etermine i& your inten"e" use =ill not run a&oul o& any 'lauses. ?ou are strongly re'ommen"e" to seek pro&essional legal 'ounsel i& there are any potential areas o& 'on&li't. Also, keep your eyes peele" &or other mapping options, base" o&& o& other sour'es o& map "ata, su'h as >pen%treetMap.
Piling ,n
As o& An"roi" 1.A, 8oogle Maps are not stri'tly part o& the An"roi" %@D. 0nstea", they are part o& the 8oogle A#0s A""->n, an e;tension o& the sto'k %@D. 5he An"roi" a""-on system pro!i"es hooks &or other subsystems that may be part o& some "e!i'es, but not others. A&ter all, 8oogle Maps is not part o& the An"roi" open sour'e proGe't, an" un"oubte"ly there =ill be some "e!i'es that la'k 8oogle Maps "ue to li'ensing issues. *or e;ample, at the time o& this =riting, the A C+>% A An"roi" tablet "oes not ha!e 8oogle Maps. 1y an" large, the &a't that 8oogle Maps is in an a""-on "oes not a&&e't your "ay-to-"ay "e!elopment. +o=e!er, bear in min",
?ou =ill nee" to 'reate your proGe't =ith an appropriate target to ensure the 8oogle Maps A#0s =ill be a!ailable 5o test your 8oogle Maps integration, you =ill also nee" an A-@ that uses an appropriate target
07&
5hat7s be'ause the A#0 key in the sour'e 'o"e is in!ali" &or your "e!elopment ma'hine. 0nstea", you =ill nee" to generate your o=n A#0 key(s) &or use =ith your appli'ation. 5his also hol"s true &or any mapenable" proGe'ts you 'reate on your o=n &rom s'rat'h. *ull instru'tions &or generating A#0 keys, &or "e!elopment an" pro"u'tion use, 'an be &oun" on the An"roi" Web site. 0n the interest o& bre!ity, let7s &o'us on the narro= 'ase o& getting %oo5aEk running in your emulator. @oing this reRuires the &ollo=ing steps, 1. 2. -isit the A#0 key signup page an" re!ie= the terms o& ser!i'e. e-rea" those terms o& ser!i'e an" make really really sure you =ant to agree to them.
.. *in" the M@A "igest o& the 'erti&i'ate use" &or signing your "ebugmo"e appli'ations ("es'ribe" in "etail belo=) <. >n the A#0 key signup page, paste in that M@A signature an" submit the &orm A. >n the resulting page, 'opy the A#0 key an" paste it as the !alue o& apiHeF in your #apVieE-using layout 5he tri'kiest part is &in"ing the M@A signature o& the 'erti&i'ate use" &or signing your "ebug-mo"e appli'ations... an" mu'h o& the 'omple;ity is merely in making sense o& the 'on'ept. All An"roi" appli'ations are signe" using a "igital signature generate" &rom a 'erti&i'ate. ?ou are automati'ally gi!en a "ebug 'erti&i'ate =hen you set up the %@D, an" there is a separate pro'ess &or 'reating a sel&-signe" 'erti&i'ate &or use in your pro"u'tion appli'ations. 5his signature pro'ess in!ol!es the use o& the Ca!a keFtool an" jarsigner utilities. *or the purposes o& getting your A#0 key, you only nee" to =orry about keFtool. 5o get your M@A "igest o& your "ebug 'erti&i'ate, i& you are on >% F or Linu;, use the &ollo=ing 'omman",
keFtool -list -alias androiddebugkeF -keFstore ^/.android/debug.keFstore -storepass android -keFpass android
07-
>n other "e!elopment plat&orms, you =ill nee" to repla'e the !alue o& the -keFstore s=it'h =ith the lo'ation &or your plat&orm an" user a''ount,
(=here LuserM is your a''ount name) 5he se'on" line o& the output 'ontains your M@A "igest, as a series o& pairs o& he; "igits separate" by 'olons.
8oogle Maps A#0 key i& you =ant users to be able to 'li'k an"
android:clickable 6 7true7,
*or e;ample, &rom the #aps/%oo5aEk sample appli'ation, here is the main layout,
07%
LNGml version671.-7 encoding67utf-,7NM L?elative)aFout Gmlns:android67http://schemas.android.com/apk/res/android7 android:laFout Eidth67fill parent7 android:laFout height67fill parent7M Lcom.google.android.maps.#apVieE android:id67ORid/map7 android:laFout Eidth67fill parent7 android:laFout height67fill parent7 android:apiHeF67--F!j-k/ /vGbuY*KEF]I<b%#JrAj5rJ*HH!gbY7 android:clickable67true7 /M L/?elative)aFoutM
0n a""ition, you =ill nee" a 'ouple o& e;tra things in your Android#anifest.Gml &ile,
5he I%&$?%$& an" A++$22 9I%$ )"+A&I"% permissions (the latter &or use =ith the #F)ocation"verlaF 'lass, "es'ribe" later in this 'hapter) 0nsi"e your LapplicationM, a Luses-librarFM element android:name 6 7com.google.android.maps7, to in"i'ate you are one o& the optional An"roi" A#0s =ith using
5hat is pretty mu'h all you nee" &or starters, plus to sub'lass your a'ti!ity &rom #apActivitF. 0& you =ere to "o nothing else, an" built that proGe't an" tosse" it in the emulator, you7" get a ni'e map o& the =orl". 2ote, ho=e!er, that #apActivitF is abstra't S you nee" to implement is?oute=isplaFedPQ to in"i'ate i& you are supplying some sort o& "ri!ing "ire'tions or not. %in'e
070
"isplaying "ri!ing "ire'tions is not supporte" by the 'urrent e"ition o& the terms o& ser!i'e, you shoul" ha!e is?oute=isplaFedPQ return false.
+ption l % ps
2ot e!ery An"roi" "e!i'e =ill ha!e 8oogle Maps, be'ause they "i" not ele't to li'ense it &rom 8oogle. While most mainstream "e!i'es =ill ha!e 8oogle Maps, a &e= per'ent o& An"roi" "e!i'es =ill be =ithout it. ?ou nee" to "e'i"e i& ha!ing 8oogle Maps is essential &or your appli'ation7s operation, or not. 0& it is, the Luses-librarFM element sho=n abo!e is the right ans=er, as that =ill reRuire any "e!i'e running your app to ha!e 8oogle Maps. 0&, ho=e!er, you =ant 8oogle Maps to be optional, there is an un"o'umente" android:reUuired attribute a!ailable on Luses-librarFM. %et that to false, an" then 8oogle Maps =ill be loa"e" into your appli'ation i& it is a!ailable, but your appli'ation =ill run regar"less. ?ou =ill then nee" to use something like +lass.for%ameP7com.google.android.maps.#apVieE7Q to see i& 8oogle Maps is a!ailable to you. 0& it is not, you 'an "isable the menu items or =hate!er =oul" lea" the user to your #apActivitF. While this attribute is un"o'umente", 8oogle has in"i'ate" that it is an a!ailable option, an" hope&ully it =ill be o&&i'ially "o'umente" in a &uture An"roi" release.
072
Koom
5he 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 Koom le!el "ire'tly !ia the setVoomPQ metho" on the #ap+ontroller. 5his takes an integer representing the le!el o& Koom, =here 1 is the =orl" !ie= an" 21 is the tightest Koom you 'an get. Ea'h le!el is a "oubling o& the e&&e'ti!e resolution, 1 has the eRuator measuring 2A/ pi;els =i"e, =hile 21 has the eRuator measuring 2/8,<.A,<A/ pi;els =i"e. %in'e the phone7s "isplay probably "oes not ha!e 2/8,<.A,<A/ pi;els in either "imension, the user sees a small map &o'use" on one tiny 'orner o& the globe. A le!el o& 14 =ill sho= you se!eral 'ity blo'ks in ea'h "imension an" is probably a reasonable starting point &or you to e;periment =ith. 0& to 'hange the Koom le!el, 'all the user =ill be able to Koom in an" out o& the map !ia Koom 'ontrols &oun" in the bottom 'enter o& the map.
set4uiltInVoom+ontrolsPtrueQJ, an"
you
=ish
to
allo=
users
Center
5ypi'ally, you =ill nee" to 'ontrol =hat the map is sho=ing, beyon" the Koom le!el, su'h as the user7s 'urrent lo'ation, or a lo'ation sa!e" =ith some "ata in your a'ti!ity. 5o 'hange the map7s position, 'all set+enterPQ on the #ap+ontroller. 5his takes a Deo(oint as a parameter. A Deo(oint represents a lo'ation, !ia latitu"e an" longitu"e. 5he 'at'h is that the Deo(oint stores latitu"e an" longitu"e as integers representing the a'tual latitu"e an" longitu"e in mi'ro"egrees ("egrees multiplie" by 1$0). 5his sa!es a bit o& memory !ersus storing a float or double, an" it greatly spee"s up some internal 'al'ulations An"roi" nee"s to "o to 'on!ert the Deo(oint into a map position. +o=e!er, it "oes mean you ha!e to remember to multiply the Mreal =orl"M latitu"e an" longitu"e by 1$0.
077
+verl y Cl sses
Any o!erlay you =ant to a"" to your map nee"s to be implemente" as a sub'lass o& "verlaF. 5here is an ItemiKed"verlaF sub'lass a!ailable i& you are looking to a"" push-pins or the likeT ItemiKed"verlaF simpli&ies this pro'ess. 5o atta'h an o!erlay 'lass to your map, Gust 'all get"verlaFsPQ on your #apVieE an" addPQ your "verlaF instan'e to it, as =e "o here =ith a 'ustom 2ites"verlaF,
marker.setBoundsP-8 -8 marker.getIntrinsic#idthPQ8 marker.getIntrinsic(eightPQQJ map.getO!erlaysPQ.addPneE SitesO!erlayPmarkerQQJ
*irst, o!erri"e ItemiKed"verlaFL"verlaFItemM as your o=n sub'lass (in this e;ample, 2ites"verlaF) 0n the 'onstru'tor, buil" your roster o& "verlaFItem instan'es, an" 'all populatePQ =hen they are rea"y &or use by the o!erlay 0mplement siKePQ to return the number o& items to be han"le" by the o!erlay >!erri"e createItemPQ to return "verlaFItem instan'es gi!en an in"e; When you instantiate your ItemiKed"verlaF sub'lass, pro!i"e it =ith a =raEable that represents the "e&ault i'on (e.g., push-pin) to "isplay &or ea'h item, on =hi'h you 'all bound+enter4ottomPQ to enable the "rop-sha"o= e&&e't
5he marker &rom the %oo5aEk 'onstru'tor is the =raEable use" &or the last bullet abo!e S it sho=s a push-pin. *or e;ample, here is 2ites"verlaF,
private class 2ites"verlaF eGtends ItemiKed"verlaFL"verlaFItemM : private )istL"verlaFItemM items6neE ArraF)istL"verlaFItemMPQJ private =raEable marker6nullJ public SitesO!erlayP=raEable markerQ : superPmarkerQJ this.marker6markerJ 'oundCenterBottomPmarkerQJ items.addPneE O!erlayItemPget)ointP<-./<,*0C,</C10-C<8 -/C.*0,-/1*C/.01-<Q8 73%78 73nited %ations7QQJ items.addPneE O!erlayItemPget)ointP<-./0,00>***/<C,/8 -/C.*,>0,<01>>/<1/Q8 7)incoln +enter78 7!ome of JaKK at )incoln +enter7QQJ items.addPneE O!erlayItemPget)ointP<-./0.1C0<C.C10/..8 -/C.*/*,*.11<,*,0,Q8 7+arnegie !all78 7@here Fou go Eith practice8 practice8 practice7QQJ items.addPneE O!erlayItemPget)ointP<-./-0,0<1/<*1/**8 -/<.-1./>*<>/CC/0.Q8 7&he =oEntoEn +lub78 7"riginal home of the !eisman &rophF7QQJ
07:
populatePQJ ; O"verride protected "verlaFItem createItemPint iQ : returnPitems.getPiQQJ ; O"verride protected boolean onTapPint iQ : &oast.makeTextP%oo5aEk.this8 items.getPiQ.getSnippetPQ8 &oast.)$%D&! 2!"?&Q.showPQJ returnPtrueQJ ; O"verride public int si.ePQ : returnPitems.si.ePQQJ ; ;
H ndlin! Screen T ps
An "verlaF sub'lass 'an also implement on&apPQ, to be noti&ie" =hen the user taps on the map, so the o!erlay 'an a"Gust =hat it "ra=s. *or e;ample, in &ull-siKe 8oogle Maps, 'li'king on a push-pin pops up a bubble =ith in&ormation about the business at that pin7s lo'ation. With on&apPQ, you 'an "o mu'h the same in An"roi". 5he on&apPQ metho" &or ItemiKed"verlaF "verlaFItem that =as 'li'ke". 0t is up to you =ith this e!ent. 0n the 'ase o& 2ites"verlaF, as sho=n abo!e, on&apPQ looks like this,
O"verride protected boolean onTapPint iQ : &oast.makeTextP%oo5aEk.this8 items.getPiQ.getSnippetPQ8 &oast.)$%D&! 2!"?&Q.showPQJ returnPtrueQJ ;
08<
+ere, =e Gust toss up a short &oast =ith the MsnippetM &rom the "verlaFItem, returning true to in"i'ate =e han"le" the tap.
2. %ho=ing =here you are pointe", base" on the built-in 'ompass sensor, =here a!ailable All you nee" to "o is 'reate a #F)ocation"verlaF instan'e, a"" it to your #apVieE7s list o& o!erlays, an" enable an" "isable the "esire" &eatures at appropriate times. 5he Mat appropriate timesM notion is &or ma;imiKing battery li&e. 5here is no sense in up"ating lo'ations or "ire'tions =hen the a'ti!ity is pause", so it is re'ommen"e" that you enable these &eatures in on?esumePQ an" "isable them in on(ausePQ. *or e;ample, %oo5aEk =ill "isplay a 'ompass rose using #F)ocation"verlaF. 5o "o this, =e &irst nee" to 'reate the o!erlay an" a"" it to the list o& o!erlays,
me6neE MyLocationO!erlayPthis8 mapQJ map.getO!erlaysPQ.addPmeQJ
(=here me is the #F)ocation"verlaF instan'e as a pri!ate "ata member) 5hen, =e enable an" "isable the 'ompass rose as appropriate,
O"verride public void on%esumePQ : super.on%esumePQJ me.ena'leCompassPQJ ;
08*
"igure *021 The ?oo.a)k map@ sho)ing a compass rose and t)o ,verlay tems
Cugged Terrain
Cust as the 8oogle Maps you use on your &ull-siKe 'omputer 'an "isplay satellite imagery, so too 'an An"roi" maps. o&&ers toggle2atellitePQ, =hi'h, as the name suggests, toggles on an" o&& this perspe'ti!e on the area being !ie=e". ?ou 'an ha!e the user trigger these !ia an options menu or, in the 'ase o& %oo5aEk, !ia keypresses,
#apVieE
08&
O"verride public boolean on0eyDownPint keF+ode8 HeF$vent eventQ : if PkeF+ode 66 HeF$vent.H$5+"=$ 2Q : map.setSatellitePXmap.isSatellitePQQJ returnPtrueQJ ; else if PkeF+ode 66 HeF$vent.H$5+"=$ VQ : map.display1oomControlsPtrueQJ returnPtrueQJ ; ; returnPsuper.on0eyDownPkeF+ode8 eventQQJ
%o, &or e;ample, here is %oo5aEk sho=ing a satellite !ie=, 'ourtesy o& pressing the 2 key,
"igure *071 The ?oo.a)k map@ sho)ing a compass rose and t)o ,verlay tems@ overlaid on the satellite vie)
08-
?ou 'annot use the An"roi" Compatibility Library (ACL), be'ause that reRuires you to inherit &rom 9ragmentActivitF, an" Ca!a "oes not support multiple inheritan'e. +en'e, you 'an only use maps-in&ragments on An"roi" ..0 an" higher, &alling ba'k to some alternati!e implementation on ol"er !ersions o& An"roi". Any a'ti!ity that might host a map in a &ragment =ill ha!e to inherit &rom #apActivitF, e!en i& in some 'ases it might not host a map in a &ragment.
Also, #apVieE makes some assumptions about the timing o& !arious e!ents, in a &ashion that makes setting up a map-base" &ragment a bit more 'omple; than it might other=ise ha!e to be. 0t is entirely possible that some"ay these problems =ill be resol!e", through a 'ombination o& an up"ate" 8oogle A#0s A""->n &or An"roi" =ith &ragment support, an" possibly an up"ate" ACL. 0n the meantime, here is the re'ipe &or getting maps to =ork, as =ell as they 'an, in &ragments.
08%
an"
ne=er.
*or
is
the
mani&est
&rom
the
LNGml version671.-7 encoding67utf-,7NM Lmanifest Gmlns:android67http://schemas.android.com/apk/res/android7 package67com.commonsEare.android.maps7M Luses-permission android:name67android.permission.I%&$?%$&7/M Luses-permission android:name67android.permission.A++$22 9I%$ )"+A&I"%7/M Lapplication android:label67Ostring/app name7 android:icon67OdraEable/cE7 android:hardEareAccelerated67true7M Luses-librarF android:name67com.google.android.maps7/M LactivitF android:name67.%oo5aEk7 android:label67Ostring/app name7M Lintent-filterM Laction android:name67android.intent.action.#AI%7/M LcategorF android:name67android.intent.categorF.)A3%+!$?7/M L/intent-filterM L/activitFM L/applicationM Luses-sdk android:min2dkVersion67117 android:target2dkVersion67117 /M Lsupports-screens android:large2creens67true7 android:normal2creens67true7 android:small2creens67true7 android:anF=ensitF67true7/M L/manifestM
080
5hen, in onActivitF+reatedPQ S on'e on+reatePQ has been 'omplete" in the hosting #apActivitF S you 'an a"" a #apVieE to that 'ontainer an" 'ontinue =ith the rest o& your normal setup,
O"verride public void on$cti!ityCreatedP4undle savedInstance2tateQ : super.on$cti!ityCreatedPsavedInstance2tateQJ map6neE MapViewPget$cti!ityPQ8 7--F!j-k/ /vGbuY*KEF]I<b%#JrAj5rJ*HH!gbY7QJ map.setClicka'lePtrueQJ map.getControllerPQ.setCenterPget)ointP<-./0/*C10***>-<<8 -/C.*,1,-<,<//1/>*QQJ map.getControllerPQ.set1oomP1/QJ map.setBuiltIn1oomControlsPtrueQJ =raEable marker6get%esourcesPQ.getDrawa'leP?.draEable.markerQJ marker.setBoundsP-8 -8 marker.getIntrinsic#idthPQ8 marker.getIntrinsic(eightPQQJ map.getO!erlaysPQ.addPneE SitesO!erlayPmarkerQQJ me6neE MyLocationO!erlayPget$cti!ityPQ8 mapQJ map.getO!erlaysPQ.addPmeQJ PPVieEDroupQgetViewPQQ.addViewPmapQJ ;
2ote that =e are 'reating a #apVieE in Ca!a 'o"e, =hi'h means our Maps A#0 key resi"es in the Ca!a 'o"e (or something rea'hable &rom the Ca!a 'o"e, su'h as a string resour'e). ?ou 'oul" in&late a layout 'ontaining a #apVieE here i& you =ishe" S the 'hange &or #ap9ragment =as simply to illustrate 'reating a #apVieE &rom Ca!a 'o"e.
% pActivity
?ou must make sure that =hate!er a'ti!ity hosts the map-enable" &ragment is a #apActivitF. %o, e!en though the %oo5aEk a'ti!ity no longer has mu'h to "o =ith mapping, it must still be a #apActivitF,
082
package com.commonsEare.android.mapsJ import android.os.4undleJ import com.google.android.maps.#apActivitFJ public class %oo5aEk eGtends #apActivitF : O"verride public void onCreateP4undle savedInstance2tateQ : super.onCreatePsavedInstance2tateQJ setContentViewP?.laFout.mainQJ ; O"verride protected boolean is%outeDisplayedPQ : returnPfalseQJ ;
5he resulting appli'ation looks like the original %oo5aEk a'ti!ity =oul" on a large s'reen, be'ause =e are not "oing anything mu'h else =ith the &ragment system (e.g., ha!ing other &ragments alongsi"e in a lan"s'ape layout),
087
088
CHAPTER 21
Many, i& not most, An"roi" "e!i'es =ill be phones. As su'h, not only =ill users be e;pe'ting to pla'e an" re'ei!e 'alls using An"roi", but you =ill ha!e the opportunity to help them pla'e 'alls, i& you =ish. Why might you =ant toH
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 ha!ing to keep those 'onta'ts both in your appli'ation an" in the phone7s '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 Msyn'M the so'ial net=ork 'onta'ts =ith the phone7s 'onta't "atabase, you let people pla'e 'alls "ire'tly &rom your appli'ation Maybe you are 'reating an alternati!e 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
Whate!er the reason, An"roi" has the means to let you manipulate the phone Gust like any other pie'e o& the An"roi" system.
08:
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
@etermine i& the phone is in use !ia get+all2tatePQ, =ith return !alues o& +A)) 2&A&$ I=)$ (phone not in use), +A)) 2&A&$ ?I%DI%D ('all reRueste" but still being 'onne'te"), an" +A)) 2&A&$ "99!""H ('all in progress) *in" out the %0M 0@ (0M%0) !ia get2ubscriberIdPQ *in" out the phone type (e.g., 8%M) !ia get(hone&FpePQ or &in" out the "ata 'onne'tion type (e.g., 8# %, E@8E) !ia get%etEork&FpePQ
0:<
L$dit&eGt android:id67ORid/number7 android:laFout Eidth67fill parent7 android:laFout height67Erap content7 android:cursorVisible67true7 android:editable67true7 android:single)ine67true7 /M L/)inear)aFoutM L4utton android:id67ORid/dial7 android:laFout Eidth67fill parent7 android:laFout height67Erap content7 android:laFout Eeight6717 android:teGt67=ial ItX7 android:on+lick67dial7 /M L/)inear)aFoutM
We ha!e a labele" &iel" &or typing in a phone number, plus a button &or "ialing sai" number. 5he Ca!a 'o"e simply laun'hes the "ialer using the phone number &rom the &iel",
package com.commonsEare.android.dialerJ import import import import import import android.app.ActivitFJ android.content.IntentJ android.net.3riJ android.os.4undleJ android.vieE.VieEJ android.Eidget.$dit&eGtJ
public class =ialer=emo eGtends ActivitF : O"verride public void onCreateP4undle icicleQ : super.onCreatePicicleQJ setContentViewP?.laFout.mainQJ ; public void dialPVieE vQ : $dit&eGt number6P$dit&eGtQfindViewByIdP?.id.numberQJ 2tring to=ial67tel:7Rnumber.getTextPQ.toStringPQJ start$cti!ityPneE IntentPIntent.A+&I"% =IA)8 3ri.parsePto=ialQQQJ ; ;
0:*
+o=e!er, the "ialer you get &rom 'li'king the "ial button is better, sho=ing you the number you are about to "ial,
0:&
0:-
CHAPTER 2&
"onts
0ne!itably, you[ll get the Ruestion 6hey, 'an =e 'hange this &ontH9 =hen "oing appli'ation "e!elopment. 5he ans=er "epen"s on =hat &onts 'ome =ith the plat&orm, =hether you 'an a"" other &onts, an" ho= to apply them to the =i"get or =hate!er nee"s the &ont 'hange. An"roi" is no "i&&erent. 0t 'omes =ith some &onts plus a means &or a""ing ne= &onts. 5hough, as =ith any ne= en!ironment, there are a &e= i"iosyn'rasies to "eal =ith.
0:0
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
"onts
L&eGtVieE android:teGt67sans:7 android:laFout margin?ight67<dip7 android:teGt2iKe67>-sp7 /M L&eGtVieE android:id67ORid/sans7 android:teGt67!ello8 EorldX7 android:tFpeface67sans7 android:teGt2iKe67>-sp7 /M L/&able?oEM L&able?oEM L&eGtVieE android:teGt67serif:7 android:laFout margin?ight67<dip7 android:teGt2iKe67>-sp7 /M L&eGtVieE android:id67ORid/serif7 android:teGt67!ello8 EorldX7 android:tFpeface67serif7 android:teGt2iKe67>-sp7 /M L/&able?oEM L&able?oEM L&eGtVieE android:teGt67monospace:7 android:laFout margin?ight67<dip7 android:teGt2iKe67>-sp7 /M L&eGtVieE android:id67ORid/monospace7 android:teGt67!ello8 EorldX7 android:tFpeface67monospace7 android:teGt2iKe67>-sp7 /M L/&able?oEM L&able?oEM L&eGtVieE android:teGt67+ustom:7 android:laFout margin?ight67<dip7 android:teGt2iKe67>-sp7 /M L&eGtVieE android:id67ORid/custom7 android:teGt67!ello8 EorldX7 android:teGt2iKe67>-sp7 /M L/&able?oEM L&able?oE android:id67ORid/fileroE7M L&eGtVieE android:teGt67+ustom from 9ile:7 android:laFout margin?ight67<dip7
0:2
"onts
5his layout buil"s a table sho=ing short samples o& &i!e &onts. 2oti'e ho= the &irst three ha!e the android:tFpeface attribute, =hose !alue is one o& the three built-in &ont &a'es (e.g., 6sans9). 5he three built-in &onts are !ery ni'e. +o=e!er, it may be that a "esigner, or a manager, or a 'ustomer =ants a "i&&erent &ont than one o& those three. >r perhaps you =ant to use a &ont &or spe'ialiKe" purposes, su'h as a 6"ingbats9 &ont instea" o& a series o& #28 graphi's. 5he easiest =ay to a''omplish this is to pa'kage the "esire" &ont(s) =ith your appli'ation. 5o "o this, simply 'reate an assets/ &ol"er in the proGe't root, an" put your 5rue5ype (55*) &onts in the assets. ?ou might, &or e;ample, 'reate assets/fontsP an" put your 55* &iles in there. 5hen, you nee" to tell your =i"gets to use that &ont. $n&ortunately, you 'an no longer use layout FML &or this, sin'e the FML "oes not kno= about any &onts you may ha!e tu'ke" a=ay as an appli'ation asset. 0nstea", you nee" to make the 'hange in Ca!a 'o"e,
import android.Eidget.&eGtVieEJ import java.io.9ileJ public class 9ont2ampler eGtends ActivitF : O"verride public void onCreateP4undle icicleQ : super.onCreatePicicleQJ setContentViewP?.laFout.mainQJ &eGtVieE tv6P&eGtVieEQfindViewByIdP?.id.customQJ &Fpeface face6&Fpeface.create"rom$ssetPget$ssetsPQ8 7fonts/!andmade&FpeEriter.ttf7QJ tv.setTypefacePfaceQJ
0:7
"onts
9ile font6neE "ileP$nvironment.get+xternalStorageDirectoryPQ8 7#g"pen+osmetica4old.ttf7QJ if Pfont.existsPQQ : tv6P&eGtVieEQfindViewByIdP?.id.fileQJ face6&Fpeface.create"rom"ilePfontQJ tv.setTypefacePfaceQJ ; else : findViewByIdP?.id.fileroEQ.setVisi'ilityPVieE.D"%$QJ ;
; ;
+ere =e grab the &eGtVieE &or our 6'ustom9 sample, then 'reate a &Fpeface obGe't !ia the stati' create9romAssetPQ buil"er metho". 5his takes the appli'ation[s Asset#anager (&rom getAssetsPQ) an" a path =ithin your assets/ "ire'tory to the &ont you =ant. 5hen, it is Gust a matter o& telling the &eGtVieE to set&FpefacePQ, pro!i"ing the &Fpeface you Gust 'reate". 0n this 'ase, =e are using the +an"ma"e 5ype=riter &ont. ?ou 'an also loa" a &ont out o& a lo'al &ile an" use it. 5he bene&it is that you 'an 'ustomiKe your &onts a&ter your appli'ation has been "istribute". >n the other han", you ha!e to someho= arrange to get the &ont onto the "e!i'e. 1ut Gust as you 'an get a &Fpeface !ia create9romAssetPQ, you 'an get a &Fpeface !ia create9rom9ilePQ. 0n our 9ont2ampler, =e look in the root o& Me;ternal storageM (typi'ally the %@ 'ar") &or the Mg>penCosmeti'a1ol" 5rue5ype &ont &ile, an" i& it is &oun", =e use it &or the &i&th ro= o& the table. >ther=ise, =e hi"e that ro=. 5he resultsH
0:8
"onts
We =ill go into more "etails regar"ing assets an" lo'al &iles in an up'oming 'hapter. 2ote that An"roi" "oes not seem to like all 5rue5ype &onts. When An"roi" "islikes a 'ustom &ont, rather than raise an $Gception, it seems to substitute @roi" %ans (9sans9) Ruietly. %o, i& you try to use a "i&&erent &ont an" it "oes not seem to be =orking, it may be that the &ont in Ruestion is in'ompatible =ith An"roi", &or =hate!er reason.
"onts
Con!ersely, bear in min" that &onts may not ha!e all o& the glyphs that you nee". As an e;ample, let us talk about the ellipsis. An"roi"7s &eGtVieE 'lass has the built-in ability to MellipsiKeM te;t, trun'ating it an" a""ing an ellipsis i& the te;t is longer than the a!ailable spa'e. ?ou 'an use this !ia the android:ellipsiKe attribute, &or e;ample. 5his =orks &airly =ell, at least &or single-line te;t. 5he ellipsis that An"roi" uses is not three perio"s. ather it uses an a'tual ellipsis 'hara'ter, =here the three "ots are 'ontaine" in a single glyph. +en'e, any &ont that you use that you also use the MellipsiKingM &eature =ill nee" the ellipsis glyph. 1eyon" that, though, An"roi" pa"s out the string that gets ren"ere" ons'reen, su'h that the length (in 'hara'ters) is the same be&ore an" a&ter MellipsiKingM. 5o make this =ork, An"roi" repla'es one 'hara'ter =ith the ellipsis, an" repla'es all other remo!e" 'hara'ters =ith the $ni'o"e 'hara'ter 7QE > W0@5+ 2>-1 EAD %#ACE7 ( 3R9$99). 5his means the Me;traM 'hara'ters a&ter the ellipsis "o not take up any !isible spa'e on s'reen, yet they 'an be part o& the string. +o=e!er, this means any 'ustom &onts you use &or &eGtVieE =i"gets that you use =ith android:ellipsiKe must also support this spe'ial $ni'o"e 'hara'ter. 2ot all &onts "o, an" you =ill get arti&a'ts in the on-s'reen representation o& your shortene" strings i& your &ont la'ks this 'hara'ter (e.g., rogue F7s appear at the en" o& the line). An", o& 'ourse, An"roi"7s international "eployment means your &ont must han"le any language your users might be looking to enter, perhaps through a language-spe'i&i' input metho" e"itor. +en'e, =hile using 'ustom &onts in An"roi" is !ery possible, there are many potential problems, an" so you must =eigh 'are&ully the bene&its o& the 'ustom &onts !ersus their potential 'osts.
2<<
CHAPTER 21
5he An"roi" %@D is more than a library o& Ca!a 'lasses an" A#0 'alls. 0t also in'lu"es a number o& tools to assist in appli'ation "e!elopment. E'lipse, o& 'ourse, ten"s to "ominate the "is'ussion. +o=e!er, that is not the only tool at your "isposal, so, let7s take a Rui'k tour o& =hat else is a!ailable to you.
2<*
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
5he roots o& the table sho= the emulator instan'es presently running on your "e!elopment ma'hine. 5he lea!es represent appli'ations running on that parti'ular emulator. ?our a'ti!ity =ill be i"enti&ie" by appli'ation pa'kage an" 'lass (e.g., com.commonsEare.android.files/...). Where things get interesting, though, is =hen you 'hoose a =in"o= an" 'li'k Loa" -ie= +ierar'hy. A&ter a &e= se'on"s, the "etails spring into, er, !ie=,
2<&
5he main area o& the Layout -ie= sho=s a tree o& the !arious =i"gets an" stu&& that make up your a'ti!ity, starting &rom the o!erall system =in"o= an" "ri!ing "o=n into the in"i!i"ual $0 =i"gets that users are suppose" to intera't =ith. 5his in'lu"es both =i"gets an" 'ontainers "e&ine" by your appli'ation an" others that are supplie" by the system, in'lu"ing the title bar. Cli'king on one o& the !ie=s a""s more in&ormation to this perspe'ti!e,
2<-
2o=, in the right region o& the -ie=er, =e see properties o& the sele'te" =i"get or 'ontainer, plus timing "etails &or ho= long it took to ren"er that 'ontainer an" its 'hil"ren. Also, the =i"get is highlighte" in re" in the =ire&rame o& the a'ti!ity, sho=n beneath the properties (by "e&ault, !ie=s are sho=n as =hite outlines on a bla'k ba'kgroun"). 5his 'an help you ensure you ha!e sele'te" the right =i"get, i&, say, you ha!e se!eral buttons an" 'annot rea"ily tell &rom the tree =hat is =hat. ?ou 'an also,
%a!e the tree "iagram as a #28 &ile %a!e the $0 as a #hotoshop #%@ &ile, =ith "i&&erent layers &or the "i&&erent =i"gets an" 'ontainers *or'e the $0 to repaint in the emulator or re-loa" the hierar'hy, in 'ase you ha!e ma"e 'hanges to a "atabase or to the app7s 'ontents an" nee" a &resh "iagram
2<%
1a'k on the main s'reen, instea" o& 'li'king Loa" -ie= +ierar'hy, you 'oul" ha!e 'li'ke" 0nspe't %'reenshot. 5his puts the -ie=er in a =hole ne= perspe'ti!e, 'alle" the #i;el #er&e't -ie=,
>n the le&t, you see a tree representing the =i"gets an" other VieEs in your a'ti!ity. 0n the mi""le, you see a Koome" !ie= o& your a'ti!ity, sho=n at normal siKe on the right. 5he 'rosshairs o!erlaying the a'ti!ity sho= the position being Koome" upon Z Gust 'li'k on a ne= area to 'hange =here =hat you are seeing. 5here is a sli"er to 'ontrol the le!el o& Koom. Cli'king on a pi;el also in"i'ates the position an" 'olor o& that pi;el. 0& you toggle the Auto e&resh 'he'kbo; in the toolbar, the -ie=er =ill poll an" reloa" the $0 &rom your a'ti!ity perio"i'ally, =ith the &reRuen'y 'ontrolle" by another sli"er.
2<0
2<2
Cli'king on an emulator allo=s you to bro=se the e!ent log on the bottom an" manipulate the emulator !ia the tabs on the right,
2<7
)o!!in!
ather than use adb logcat, @@M% lets you !ie= your logging in&ormation in a s'rollable table. Cust highlight the emulator or "e!i'e you =ant to monitor, an" the bottom hal& o& the s'reen sho=s the logs. 0n a""ition, you 'an,
*ilter the Log tab by any o& the &i!e logging le!els, sho=n as the through E toolbar buttons. Create a 'ustom &ilter, so you 'an !ie= only those tagge" =ith your appli'ation7s tag, by pressing the \ toolbar button an" 'ompleting the &orm (sho=n belo=). 5he name you enter in the &orm =ill be
2<8
use" as the name o& another logging output tab in the bottom portion o& the @@M% main =in"o=.
%a!e the log in&ormation to a te;t &ile &or later perusal, or &or sear'hing.
2<:
Cust bro=se to the &ile you =ant an" 'li'k either the pull (le&t-most) or push (mi""le) toolbar button to trans&er the &ile toP&rom your "e!elopment ma'hine. >r, 'li'k the "elete (right-most) toolbar button to "elete the &ile. 5here are a &e= 'a!eats to this,
?ou 'annot 'reate "ire'tories through this tool. ?ou =ill either nee" to use adb shell or 'reate them &rom =ithin your appli'ation. While you 'an putter through most o& the &iles on an emulator, you 'an a''ess !ery little outsi"e o& /sdcard on an a'tual "e!i'e, "ue to An"roi" se'urity restri'tions.
Screenshots
5o take a s'reenshot o& the An"roi" emulator or "e!i'e, simply press L+trlM-L2M or 'hoose DeviceD $creen capture... &rom the main menu. 5his =ill bring up a "ialog bo; 'ontaining an image o& the 'urrent s'reen,
2*<
*rom here, you 'an 'li'k E$aveF to sa!e the image as a #28 &ile some=here on your "e!elopment ma'hine, E0efreshF to up"ate the image base" on the 'urrent state o& the emulator or "e!i'e, or EDoneF to 'lose the "ialog.
2**
5he Manual tab is &airly sel&-e;planatory, pro!i"e a latitu"e an" longitu"e an" 'li'k the %en" button to submit that lo'ation to the emulator. 5he emulator, in turn =ill noti&y any lo'ation listeners o& the ne= position. @is'ussion o& the 8#F an" DML options is reser!e" &or a &uture e"ition o& this book.
2*&
>n the Emulator Control tab, abo!e the Lo'ation Controls group, is the 5elephony A'tions group,
5o simulate an in'oming 'all, &ill in a phone number, 'hoose the -oi'e ra"io button, an" 'li'k Call. At that point, the emulator =ill sho= the in'oming 'all, allo=ing you to a''ept it (!ia the green phone button) or reGe't it (!ia the re" phone button),
2*-
5o simulate in an in'oming te;t message, &ill in a phone number, 'hoose the %M% ra"io button, enter a message in the pro!i"e" te;t area, an" 'li'k %en". 5he te;t message =ill then appear as a noti&i'ation,
2*%
An", o& 'ourse, you 'an 'li'k on the noti&i'ation to !ie= the message in the &ull-&le"ge" Messaging appli'ation,
2*0
%emory % n !ement
@@M% also helps you "iagnose issues relate" to ho= your appli'ation makes use o& memory, parti'ularly heap spa'e. >n the M%ysin&oM tab, you 'an see a pie 'hart o& the o!erall memory allo'ation &or the emulator,
>n the MAllo'ation 5ra'kerM tab, you 'an re'or" ea'h an" e!ery time your 'o"e (or 'o"e you 'all insi"e o& An"roi") allo'ates memory. %imply highlight your appli'ation7s pro'ess in the tree-table, then 'li'k the %tart 5ra'king button on the Allo'ation 5ra'ker tab. When you =ant to see =hat you ha!e allo'ate" sin'e you 'li'ke" %tart 5ra'king, 'li'k the 8et Allo'ations button, =hi'h =ill &ill in a table sho=ing ea'h allo'ation, ho= mu'h memory it =as, an" =here in the 'o"e the memory =as allo'ate",
2*2
An", you 'an e!en "ump the entire heap &or your appli'ation !ia the @ump +# >* option, a!ailable !ia a toolbar button (looks like a hal&-empty 'an =ith a "o=n=ar"-pointing arro= to its right). 5he resulting +# >* &ile 'an be use" =ith MA5, an a""-in &or E'lipse, to see =hat obGe'ts are still on the heap an" =ho is 'ausing them to sti'k aroun". 1e&ore "umping the +# >* &ile, you may =ish to &or'e a garbage 'olle'tion run on your pro'ess S this 'an be "one by 'li'king the toolbar button that looks like a 'lassi' metal garbage 'an.
2*7
1.
1ehin" the s'enes, it ser!es as a bri"ge bet=een your emulatorsP"e!i'es an" the rest o& the tools. *or e;ample, A@5, +ierar'hy -ie=er, an" @@M% all 'ommuni'ate =ith your emulator !ia the adb bri"ge. 5his bri"ge 'omes in the &orm o& a "aemon pro'ess, spa=ne" the &irst time you try using any o& those tools sin'e your last reboot.
2. 0t o&&ers 'omman"-line eRui!alents &or many &eatures o& the other tools, notably @@M%. %ome o& the things you 'an "o =ith adb in'lu"e,
stop
(adb
kill-server)
the
List all o& the re'ogniKe" An"roi" "e!i'es an" emulators presently !isible (adb devices) 8et a''ess to a Linu; shell insi"e your "e!i'e or emulator ( adb shell) 0nstall or uninstall An"roi" appli'ations on your "e!i'e or emulator (adb install) Copy &iles to (adb push) or &rom (adb pull) the emulator, mu'h like @@M%7s *ile E;plorer E;amine LogCat (adb logcat)
2*8
CHAPTER 22
?ou might think that An"roi" is all about Ca!a. 5he o&&i'ial An"roi" %o&t=are @e!elopment Dit (%@D) is &or Ca!a "e!elopment, the buil" tools are &or Ca!a "e!elopment, the "is'ussion groups an" blog posts an", yes, most books are &or Ca!a "e!elopment. +e'k, most o& this book is about Ca!a. +o=e!er (an" =ith apologies to William 8ol"man), it Gust so happens that An"roi" is only mostly Ca!a. 5here7s a big "i&&eren'e bet=een mostly Ca!a an" all Ca!a. Mostly Ca!a is slightly not Ca!a. %o, =hile An"roi"7s Ms=eet spotM =ill remain Ca!a-base" appli'ations &or the near term, you 'an still 'reate appli'ations using other te'hnologies. 5his part o& the book =ill take a peek at some o& those alternati!es. 5his 'hapter starts =ith an e;amination o& the pros an" 'ons o& An"roi"7s Ca!a-'entri' strategy. 0t then enumerates some reasons =hy you might =ant to use something else &or your An"roi" appli'ations. 5he "o=nsi"es o& alternati!e An"roi" appli'ation en!ironments S la'k o& support an" te'hni'al 'hallenges S are also "is'usse".
2&*
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
111And t Was ,9
2o mobile "e!elopment en!ironment is per&e't, an" so the 'ombination o& Ca!a an" An"roi" has its issues. At the time o& this =riting, Ca!a, as implemente" &or the @al!ik !irtual ma'hine, is interprete", =ithout any o& the MGust-in-time 'ompilerM tri'ks regular Ca!a uses to boost per&orman'e. 5his is a bigger problem in mobile, sin'e the "e!i'es An"roi" runs upon ten" to be less po=er&ul than your a!erage "esktop, notebook, or Web ser!er. +en'e, there =ill be some things you Gust 'an7t "o on An"roi" =ith Ca!a be'ause it is too slo=.
2&&
Ca!a uses garbage 'olle'tion to sa!e people &rom ha!ing to keep tra'k o& all o& their memory allo'ations. 5hat =orks &or the most part, an" it is generally a boon to "e!eloper pro"u'ti!ity. +o=e!er, it is not a 'ure-all &or e!ery memory an" resour'e allo'ation problem. ?ou 'an still ha!e =hat amounts to Mmemory leaksM in Ca!a, e!en i& the pre'ise me'hani's o& those leaks "i&&er &rom the 'lassi' leaks you get in C, C\\, et'. Most importantly, though, not e!erybo"y likes Ca!a. 0t 'oul" be be'ause they la'k e;perien'e =ith it, or perhaps they ha!e e;perien'e =ith it an" "i" not enGoy that e;perien'e. Certainly, Ca!a is slo=ly being 'onsi"ere" as a language &or big enterprise systems an", there&ore, is not ne'essarily M'oolM. A"!o'ates o& "i&&erent languages =ill ha!e their o=n pet pee!es =ith Ca!a as =ell (e.g., to a uby "e!eloper, Ca!a is really !erbose). %o, =hile Ca!a =as not a ba" 'hoi'e &or An"roi", it =as not per&e't, either.
An", o& 'ourse, you might Gust &in" Ca!a programming to be irritating. ?ou =oul" not be the &irst, nor the last, to ha!e that sentiment. #arti'ularly i& you are getting into An"roi" as a hobby, rather than as part o& your M"ay GobM, ha!ing &un =ill be important to you, an" you might not &in" Ca!a to be mu'h &un. *ortunately, An"roi" is &rien"ly to=ar"s alternati!e =ays o& buil"ing appli'ations, unlike some mobile plat&orms.
Support@ Structure
+o=e!er, M&rien"lyM an" M&ully supporte"M are t=o "i&&erent things. %ome alternati!es to Ca!a-base" "e!elopment are o&&i'ially supporte" by the 'ore An"roi" team, su'h as CPC\\ "e!elopment !ia the 2ati!e @e!elopment Dit (2@D) an" Web-style "e!elopment !ia +5MLA. %ome alternati!es to Ca!a-base" "e!elopment are supporte" by 'ompanies. A"obe supports A0 , 2itobi supports #hone8ap, homobile supports ho"es, an" so on. >ther alternati!es are supporte" by stan"ar"s bo"ies, like the Worl" Wi"e Web Consortium (W.C) supporting +5MLA. %till others are Gust tiny proGe'ts =ith only the ba'king o& a 'ouple o& "e!elopers. ?ou =ill nee" to make the "e'ision &or yoursel& =hi'h o& these le!els o& support =ill meet your reRuirements. *or many things, support is not mu'h o& an issue, but there =ill al=ays be 'ases =here support be'omes paramount (e.g., enterprise appli'ation "e!elopment).
Caveat /eveloper
>& 'ourse, going outsi"e the tra"itional Ca!a en!ironment &or An"roi" "e!elopment has its issues, beyon" Gust ho= mu'h support might be a!ailable.
2&%
%ome may be less e&&i'ient, in terms o& pro'essor time, memory, or battery li&e, than =ill "e!elopment in Ca!a. CPC\\, on the =hole, is probably better than Ca!a, but +5MLA may be =orse, &or e;ample. @epen"ing on =hat you are =riting an" ho= hea!ily it =ill be use" =ill "etermine ho= 'riti'al that ine&&i'ien'y =ill be. %ome may not be a!ailable on all "e!i'es. ight no=, *lash is the best e;ample o& this S some "e!i'es o&&er some amount o& *lash support, =hile other "e!i'es ha!e no *lash at all. %imilarly, +5MLA support =as only a""e" to An"roi" in An"roi" 2.0, so "e!i'es running ol"er !ersions o& An"roi" "o not ha!e +5MLA as a built-in option. E!ery layer bet=een you an" o&&i'ially supporte" en!ironments makes it that mu'h more "i&&i'ult &or you to ensure 'ompatibility =ith ne= !ersions o& An"roi", =hen they arise. *or e;ample, i& you 'reate an appli'ation using #hone8ap, an" a ne= An"roi" !ersion be'omes a!ailable, there may be in'ompatibilities that only the #hone8ap team 'an a""ress. While they =ill probably a""ress those Rui'kly S an" they may pro!i"e some measure o& insulation to you &rom those in'ompatibilities S the response time is outsi"e o& your 'ontrol. 0n some 'ases, that is not a problem, but in other 'ases, that might be ba" &or your proGe't. +en'e, Gust be'ause you are "e!eloping outsi"e o& Ca!a "oes not mean e!erything is per&e't. ?ou simply ha!e to tra"e o&& bet=een these problems an" the ones Ca!a-base" "e!elopment might 'ause you. Where the balan'e lies is up to ea'h in"i!i"ual "e!eloper or &irm.
2&0
CHAPTER 26
3T+!0
#rior to the 'urrent =a!e o& interest in mobile appli'ations, the te'hnology du )our =as Web appli'ations. A lot o& attention =as pai" to ACAF, uby on ails, an" other te'hniRues an" te'hnologies that ma"e Web appli'ations 'limb 'lose to e;perien'e o& a "esktop appli'ation, an" sometimes superior. 5he e;plosion o& Web appli'ations e!entually "ro!e the ne;t roun" o& enhan'ements to Web stan"ar"s, 'olle'ti!ely 'alle" +5MLA. An"roi" 2.0 a""e" the &irst roun" o& support &or these +5MLA enhan'ements. 2otably, An"roi" supports o&&line appli'ations an" Web storage, meaning that +5MLA be'omes a rele!ant te'hniRue &or 'reating An"roi" appli'ations, =ithout "ealing =ith Ca!a.
,ffline Applications
5he lin'hpin &or using +5MLA &or o&&line appli'ations S on An"roi" or else=here S is the ability &or those appli'ations to be use" =hen there is no 'onne'ti!ity, either "ue to problems on the 'lient si"e (e.g., on an airplane sans Wi*i) or on the ser!er si"e (e.g., Web ser!er maintenan'e).
,h t Does It %e nF
+istori'ally, Web appli'ations ha!e ha" this annoying ten"en'y to reRuire Web ser!ers. 5his le" to all sorts o& =orkaroun"s &or o&&line use, up to an" in'lu"ing shipping a Web ser!er an" "eploying it to the "esktop.
2&7
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
3T+!0
+5MLA sol!es this problem by allo=ing Web pages to spe'i&y their o=n 'a'hing rules. A Web app 'an publish a M'a'he mani&estM, "es'ribing =hi'h resour'es,
Can be sa&ely 'a'he", su'h that i& the Web ser!er is una!ailable, the bro=ser =ill Gust use the 'a'he" 'opy Cannot be sa&ely 'a'he", su'h that i& the Web ser!er is una!ailable, the bro=ser shoul" &ail like it normally "oes +a!e a M&allba'kM resour'e, su'h that i& the Web ser!er is una!ailable, the 'a'he" &allba'k resour'e shoul" be use" instea"
*or mobile "e!i'es, this means that a &ully +5MLA-'apable bro=ser shoul" be able to loa" all its assets up &ront an" keep them 'a'he". 0& the user loses 'onne'ti!ity, the appli'ation =ill still run. 0n this respe't, the Web app beha!es almost i"enti'ally to a regular app.
2&8
3T+!0
?ou 'an enter some te;t in the top &iel" an" 'li'k the A"" button to a"" it to the list,
2&:
3T+!0
?ou 'an M'he'k o&&M in"i!i"ual items, =hi'h are then "isplaye" in strikethrough,
2-<
3T+!0
?ou 'an also "elete the 'he'ke" entries (!ia the @elete Che'ke" button) or all entries (!ia the @elete All button), =hi'h =ill pop up a 'on&irmation "ialog be&ore pro'ee"ing,
2-*
3T+!0
2-&
3T+!0
LX="+&5($ htmlM Lhtml lang67en7 manifest67checklist.manifest7M LheadM Lmeta http-eUuiv67+ontent-&Fpe7 content67teGt/htmlJ charset6utf-,7 /M LtitleM+hecklistL/titleM Lmeta name67vieEport7 content67Eidth6device-EidthJ initial-scale61.-J maGimum-scale61.-J userscalable6-J7 /M Lmeta name67apple-mobile-Eeb-app-capable7 content67Fes7 /M Lmeta name67apple-mobile-Eeb-app-status-bar-stFle7 /M Llink rel67apple-touch-startup-image7 href67splashscreen.png7 /M Llink rel67stFlesheet7 href67stFles.css7 /M Llink rel67apple-touch-icon-precomposed7 href67apple-touch-icon-precomposed.png7 /M L/headM LbodFM LsectionM LheaderM Lbutton tFpe67button7 id67sendmail7M#ailL/buttonM Lh1M+hecklistL/h1M L/headerM LarticleM Lform id67inputarea7 onsubmit67add%eEItemPQ7M Linput tFpe67teGt7 name67name7 id67name7 maGlength67/.7 autocorrect placeholder67&ap to enter a neE itemZhellipJ7 /M Lbutton tFpe67button7 id67add7MAddL/buttonM L/formM Lul id67maillist7M Lli class67emptF7MLa href677 id67maillink7M#ail remaining itemsL/aML/liM L/ulM Lp id67totals7MLspan id67tallF17M&otal: Lspan id67total7M-L/spanML/spanM Lspan id67tallF>7M?emaining: Lspan id67remaining7M-L/spanML/spanML/pM Lul id67checklist7M Lli class67emptF7M)oadingZhellipJL/liM L/ulM L/articleM LfieldsetM Lbutton tFpe67button7 id67deletechecked7M=elete +heckedL/buttonM Lbutton tFpe67button7 id67deleteall7M=elete AllL/buttonM L/fieldsetM L/sectionM Lscript src67main.js7ML/scriptM L/bodFM L/htmlM
*or the purposes o& o&&line appli'ations, though, the key is the manifest attribute o& our html element,
Lhtml lang67en7 manifest67checklist.manifest7M
2--
3T+!0
+ere, =e spe'i&y the relati!e path to a mani&est &ile, in"i'ating =hat the rules are &or 'a'hing !arious portions o& this appli'ation o&&line.
5he +5MLA mani&est &ormat is e;tremely simple. 0t starts =ith a +A+!$ #A%I9$2& line, &ollo=e" by a list o& &iles (te'hni'ally, relati!e $ Ls) that shoul" be 'a'he". 0t also supports 'omments, =hi'h are lines beginning =ith S. 5he mani&est 'an also ha!e a %$&@"?H: line, &ollo=e" by relati!e $ Ls that shoul" ne!er be 'a'he". %imilarly, the mani&est 'an ha!e a 9A))4A+H: line, &ollo=e" by pairs o& relati!e $ Ls, the $ L to try to &et'h o&& the net=ork, &ollo=e" by the $ L o& a 'a'he" resour'e to use i& the net=ork is not a!ailable. 0n prin'iple, the mani&est shoul" reRuest 'a'hing &or e!erything that the appli'ation nee"s to run, though the page that reRueste" the 'a'hing (indeG.html in this 'ase) is also 'a'he".
Web Storage
Ca'hing the +5MLA appli'ation7s assets &or o&&line use is all =ell an" goo", but that =ill be rather limiting on its o=n. 0n an o&&line situation, the appli'ation =oul" not be able to use ACAF te'hniRues to intera't =ith a Web ser!i'e. %o, i& the appli'ation is going to be able to store in&ormation, it =ill nee" to "o so on the bro=ser itsel&.
2-%
3T+!0
8oogle 8ears an" relate" tools pioneere" this 'on'ept an" blaKe" the trail &or =hat is no= !ariously 'alle" MWeb %torageM or M@>M %torageM &or +5MLA appli'ations. An +5MLA app 'an store "ata persistently on the 'lient, =ithin 'lient-impose" limits. 5hat, in 'onGun'tion =ith o&&line asset 'a'hing, means an +5MLA appli'ation 'an "eli!er &ar more !alue =hen it la'ks an 0nternet 'onne'tion, or &or "ata that Gust "oes not make sense to store Min the 'lou"M. 2ote that, te'hni'ally, Web %torage is not part o& +5MLA, but is a relate" spe'i&i'ation. +o=e!er, it ten"s to get Mlumpe" in =ithM +5MLA in 'ommon 'on!ersation.
,h t Does It %e nF
>n a Web %torage-enable" bro=ser, your Ca!as'ript 'o"e =ill ha!e a''ess to a local2torage obGe't, representing your appli'ation7s "ata. More a''urately, ea'h MoriginM (i.e., "omain) =ill ha!e a "istin't local2torage obGe't on the bro=ser. 5he local2torage obGe't is an Masso'iati!e arrayM, meaning you 'an =ork =ith it either !ia numeri'al in"e;es or string-base" keys at your "is'retion. -alues typi'ally are strings. ?ou 'an,
*in" out ho= many entries are in the array !ia lengthPQ 8et an" set items by key !ia getItemPQ an" setItemPQ 8et the key &or a numeri'al in"e; !ia keFPQ
clearPQ
5his means you "o not ha!e the &ull ri'hness o& a %JL "atabase, like you might ha!e =ith %JLite in a nati!e An"roi" appli'ation. 1ut, &or many appli'ations, this shoul" su&&i'e.
2-0
3T+!0
+ere is the 'o"e =here those items are pulle" ba'k out o& storage an" put into an array &or sorting an", later, "isplay as @>M elements on the Web page itsel&,
/*get all items from local2torage and push them one bF one into an arraF.*/ for Pi 6 -J i L6 listlengthJ iRRQ : var item 6 local2torage.keyPiQJ mFArraF.pushPitemQJ
When the user 'he'ks the 'he'kmark ne;t to an item, the storage is up"ate" to toggle the 'he'ke" setting persistently,
/*toggle the check flag.*/ if Ptarget.previous2ibling.checkedQ : data 6 -J ; else : data 6 1J ; /*save item in local2torage.*/ trF : local2torage.setItemPname8 dataQJ ; catch PeQ : if Pe 66 Y3"&A $]+$$=$= $??Q : alertPIYuota eGceededXIQJ
2-2
3T+!0
; ;
Che'klist also has 'o"e to "elete items &rom storage, either all those marke" as 'he'ke",
/*remove everF item from local2torage that has the data flag checked.*/ Ehile Pi L6 local2torage.length-1Q : var keF 6 local2torage.keyPiQJ if Plocal2torage.getItemPkeFQ 666 I1IQ : local2torage.remo!eItemPkeFQJ ; else : iRRJ ;
,e= SH) D t = se
An"roi"7s built-in bro=ser also supports a MWeb %JL @atabaseM option, one =here you 'an use %JLite-style "atabases &rom Ca!as'ript. 5his a""s a lot more po=er than basi' Web %torage, albeit at a 'omple;ity 'ost. 0t is also not part o& an a'ti!e stan"ar" S the W+A5W8 team =orking on this stan"ar" has set it asi"e &or the time being.
2-7
3T+!0
?ou might 'onsi"er e!aluating La=n'hair, =hi'h is a Ca!as'ript A#0 that allo=s you to store arbitrary C%>2-en'o"e" obGe'ts. 0t =ill use =hate!er storage options are a!ailable, an" there&ore =ill help you "eal =ith 'rossplat&orm !ariety. 0n parti'ular, it supports the 8oogle 8ears &a'ility &oun" in some ol"er !ersions o& An"roi".
(oing To Production
Creating a little test appli'ation reRuires nothing magi'al. #resumably, though, you are intereste" in others using your appli'ation S perhaps many others. Classi' Ca!a-base" An"roi" appli'ations ha!e to "eal =ith testing, ha!ing the appli'ation "igitally signe" &or pro"u'tion, "istribution through !arious 'hannels (su'h as the An"roi" Market), an" up"ates to the appli'ation by one means or another. 5hose issues "o not all magi'ally !anish be'ause +5MLA is use" as the appli'ation en!ironment. +o=e!er, +5MLA "oes 'hange things signi&i'antly &rom =hat Ca!a "e!elopers ha!e to "o.
Testin!
%in'e +5MLA =orks in other bro=sers, testing your business logi' 'oul" easily take a"!antage o& any number o& +5ML an" Ca!as'ript testing tools, &rom %elenium to J$nit to Casmine. *or testing on An"roi" proper S to ensure there are no issues relate" to An"roi"7s bro=ser implementation S you 'an use %elenium7s An"roi" @ri!er or emote Control mo"es.
Si!nin! nd Distri=ution
$nlike nati!e An"roi" appli'ations, you "o not nee" to =orry about signing your +5MLA appli'ations. 5he "o=nsi"e o& this is that there is no support &or "istribution o& +5MLA appli'ations through the An"roi" Market, =hi'h to"ay only supports nati!e
2-8
3T+!0
An"roi" apps. $sers =ill ha!e to &in" your appli'ation by one means or another, !isit it in the bro=ser, bookmark the page, an" possibly 'reate a home s'reen short'ut to that bookmark.
-pd tes
$nlike nati!e An"roi" appli'ations, =hi'h by "e&ault must be up"ate" manually, +5MLA appli'ations =ill be transparently up"ate" the ne;t time they run the app =hile 'onne'te" to the 0nternet. 5he o&&line 'a'hing proto'ol =ill 'he'k the Web ser!er &or ne= e"itions o& &iles be&ore &alling ba'k to the 'a'he" 'opies. +en'e, there is nothing more &or you to "o other than publish the latest Web app assets.
2-:
3T+!0
As you 'an see, it is &ormatte" like a typi'al mo"ern user-agent string, meaning it is Ruite a mess. 0t "oes in"i'ate it is running Android >.1update1. E!entually, somebo"y =ill 'reate a "atabase o& user-agent strings &or "i&&erent "e!i'e mo"els, an" &rom there =e 'an "eri!e appropriate regular e;pressions or similar algorithms to "etermine =hether a gi!en "e!i'e 'an support +5MLA appli'ations.
Laun'h another appli'ation Work =ith the 'onta'ts "atabase aise a noti&i'ation @o =ork truly in the ba'kgroun" (though MWeb =orkersM may alle!iate this some=hat some"ay) 0ntera't =ith 1luetooth "e!i'es
2%<
3T+!0
e'or" au"io or !i"eo $se the stan"ar" An"roi" pre&eren'e system $se spee'h re'ognition or te;t-to-spee'h An" so on
Many appli'ations =ill not nee" these 'apabilities, o& 'ourse. An", one 'an e;pe't that other appli'ation en!ironments, like #hone8ap, =ill e!ol!e into M+5MLA #lusM &or An"roi". 5hat =ay, you 'oul" 'reate a sto'k appli'ation that =orks a'ross all "e!i'es an" an enhan'e" An"roi" appli'ation that le!erages greater plat&orm integration, at the 'ost o& some a""itional amount o& programming.
2%*
3T+!0
)oo$ nd 5eel
+5MLA appli'ations 'an 'ertainly look !ery sli'k an" pro&essional S a&ter all, they are built =ith Web te'hnologies, an" Web apps 'an look !ery sli'k an" pro&essional. +o=e!er, +5MLA appli'ations =ill not ne'essarily look like stan"ar" An"roi" appli'ations, at least not initially. %ome enterprising "e!elopers =ill, no "oubt, 'reate some reusable C%%, Ca!as'ript, an" images that =ill, &or e;ample, mirror an An"roi" nati!e 2pinner =i"get (a type o& "rop-"o=n 'ontrol). %imilarly, +5MLA appli'ations =ill ten" to la'k options menus, noti&i'ations, or other $0 &eatures that a nati!e An"roi" appli'ation may =ell use. 5his is not ne'essarily ba". Consi"ering the "i&&i'ulty in 'reating a !ery sli'k-looking An"roi" appli'ation, +5MLA appli'ations may ten" to look better than their An"roi" 'ounterparts. A&ter all, there are many more people skille" in 'reating sli'k Web apps than are skille" in 'reating sli'k An"roi" apps. +o=e!er, some users may 'omplain about the look-an"-&eel "isparity, Gust be'ause it is "i&&erent.
Distri=ution
+5MLA appli'ations 'an be tri!ially a""e" to a user7s "e!i'e S bro=se, bookmark, an" a"" a short'ut to the home s'reen. +o=e!er, +5MLA appli'ations =ill not sho= up in the An"roi" Market, so users traine" to look at the Market &or a!ailable appli'ations =ill not &in" +5MLA appli'ations, e!en ones that may be better than their nati!e 'ounterparts. 0t is 'on'ei!able that, some"ay, the An"roi" Market =ill support +5MLA appli'ations. 0t is also 'on'ei!able that, some"ay, An"roi" users =ill ten" to &in" their apps by means other than sear'hing the An"roi" Market, an" =ill
2%&
3T+!0
be able to get their +5MLA apps that =ay. +o=e!er, until one o& those be'omes true, +5MLA appli'ations may be less M"is'o!erableM than their nati!e eRui!alents.
5ire.o0 %o=ile
*ire&o; Mobile is presently in beta &orm. 0t supports o&&line 'a'hing an" lo'al storage. +o=e!er, it is unable to run the Che'klist sample 'orre'tly at this time, &or reasons presently unkno=n.
+per %o=ile
>pera Mobile, also in beta, "oes not support lo'al storage, ren"ering Che'klist moot. 0t also "oes not support o&&line 'a'hing at this time.
3T+!0
0t is &airly likely that, o!er time, +5MLA =ill be the B2 option &or An"roi" appli'ation "e!elopment, a&ter the 'on!entional Ca!a appli'ation =ritten to the An"roi" %@D. 5hat =ill make +5MLA the baseline &or 'omparing alternati!e An"roi" "e!elopment options S not only =ill those options be 'ompare" to using the %@D, they =ill be 'ompare" to using +5MLA.
2%%
CHAPTER 28
Phone(ap
#hone8ap is perhaps the original alternati!e appli'ation &rame=ork &or An"roi", arri!ing on the s'ene in early 2003. #hone8ap is open sour'e, ba'ke" by 2itobi, =ho o&&ers a mi; o& open sour'e an" 'ommer'ial pro"u'ts, along =ith 'onsulting an" training ser!i'es.
What s Phone(apF
As the #hone8ap About page puts it, The Phone*ap mission is to +eb-enable native device !unctionality with open standards like ,TML" -'' and .ava'cript so that you can !ocus on the app you/re building" not on authoring comple0 plat!orm compatibility layers. #hone8ap, to"ay, &o'uses on bri"ging the gap bet=een Web te'hnologies an" nati!e mobile "e!elopment, =ith a''ess to more &eatures than +5MLA appli'ations ha!e.
2%0
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
Phone(ap
Web assets are pa'kage" =ith the appli'ation, rather than "o=nloa"e" on the &ly. A pre-installe" #hone8ap appli'ation, there&ore, 'an 'ontain 'omparati!ely large assets, su'h as 'omple; Ca!a%'ript libraries, that might be too slo= to "o=nloa" o!er slo=er E@8E 'onne'tions. +o=e!er, #hone8ap =ill still be limite" by the spee" o& mobile "e!i'es an" ho= Rui'kly WebDit 'an loa" an" pro'ess those assets. Also, "e!elopment &or WebDit-&or-mobile has its "i&&eren'es o!er "e!elopment &or WebDit-&or-"esktops, parti'ularly =ith respe't to tou'h !ersus mouse e!ents. ?ou may =ant to "e!elop using mobile layers o& Ca!a%'ript &rame=orks (e.g., GR5ou'h !ersus plain GJuery) =here pra'ti'al.
A''elerometer a''ess, &or "ete'ting mo!ement o& the "e!i'e Au"io re'or"ing Camera a''ess, &or taking still pi'tures @atabase a''ess, both to "atabases o& your 'reation (%JLite) or others built into An"roi" (e.g., 'onta'ts) *ile system a''ess, su'h as to the %@ 'ar" or other e;ternal storage 8eolo'ation, &or "etermining =here the "e!i'e is -ibration, &or shaking the phone (e.g., &or'e-&ee"ba'k)
%in'e some o& these are part o& the +5MLA spe'i&i'ation (e.g., geolo'ation), you ha!e your 'hoi'e o& A#0s. Also, this list 'hanges o!er time, so you may ha!e a''ess to more than =hat is "es'ribe" here.
2%2
Phone(ap
2%7
Phone(ap
Ca!a%'ript to make up your appli'ation. 5hen, you "igitally sign the appli'ation an" uploa" it to the An"roi" Market or any other "istribution me'hanism you =ish to use.
2. 2ot all #hone8ap Ca!a%'ript A#0s are a!ailable on all "e!i'es as yet, "ue to a !ariety o& &a'tors (e.g., not e;pose" in the plat&orm7s nati!e A#0s, la'k o& engineering time to hoist the 'apability into the #hone8ap A#0s). 5here is a table on the #hone8ap =iki that =ill keep you apprise" o& =hat =orks an" =hat "oes not a'ross the "e!i'es. ?ou =ill =ant to restri't your &eature use to mat'h your "esire" plat&orms, or restri't your plat&orms to mat'h your "esire" &eatures.
>sing Phone(ap
2o=, let7s look at more o& the me'hani's &or using #hone8ap. #hone8ap7s installation an" usage, as o& the time o& this =riting, normally reRuires an e;pert in Ca!a-base" An"roi" "e!elopment. ?ou nee" to install a
2%8
Phone(ap
=hole bun'h o& tools, e"it 'on&iguration &iles by han", an" so &orth. 0& you =ant to "o all o& that, "o'umentation is a!ailable on the #hone8ap site. 0& you are rea"ing this 'hapter, there7s a "e'ent 'han'e that you =oul" rather skip all o& that. +en'e, &or many, the best ans=er is the #hone8apP1uil" ser!i'e, still in pri!ate beta at the time o& this =riting.
Inst ll tion
5he #hone8ap Web site =ill allo= you to "o=nloa" the latest #hone8ap tools as a Q0# ar'hi!e. ?ou 'an unpa'k those =here!er it makes sense &or your "e!elopment ma'hine an" plat&orm. *or An"roi" "e!elopment, that is all o& the #hone8ap-spe'i&i' installation you =ill nee". +o=e!er, you =ill nee" the An"roi" %@D an" relate" tools (e.g., E'lipse, i& you =ish to use E'lipse) &or setting up the proGe't.
2. Create an assets/EEE/ "ire'tory in your proGe't. 5hen, 'opy o!er the #hone8ap C% &ile &rom the Android/ "ire'tory o& =here!er you unQ0#pe" the #hone8ap Q0# &ile. .. A"Gust the stan"ar" M+ello, Worl"M a'ti!ity to inherit &rom =roidDap instea" o& ActivitF. 5his =ill reRuire you to import com.phonegap.=roidDap.
2%:
Phone(ap
A. 0n your mani&est, a"" all o& the permissions that #hone8ap reRuests, liste" later in this 'hapter. /. Also in your mani&est, a"" a suitable Lsupports-screensM element base" upon =hat s'reen siKes you are =illing to test an" support. 4. Also in your mani&est, a"" android:config+hanges67orientationW keFboard!idden7 to your LactivitFM element, as =roidDap han"les orientation-relate" 'on&iguration 'hanges At this point, you 'an 'reate an assets/EEE/indeG.html &ile in your proGe't an" start 'reating your #hone8ap appli'ation using +5ML, C%%, an" Ca!as'ript. ?ou =ill nee" to ha!e a re&eren'e to the #hone8ap Ca!as'ript &ile (e.g., Lscript tFpe67teGt/javascript7 charset67utf-,7 src67phonegap.-.*.<.js7 /M). When you =ant to test the appli'ation, you 'an buil" an" install it like any other An"roi" appli'ation (e.g., ant clean install i& you are using the 'omman" line buil" pro'ess). *or somebo"y e;perien'e" in An"roi" %@D "e!elopment, setting this up is not a big 'hallenge.
PhoneG pJBuild
#hone8apP1uil" is a 5ools-as-a-%er!i'e (5aa%) hoste" approa'h to 'reating #hone8ap proGe'ts. 5his =ay, all o& the An"roi" buil" pro'ess is han"le" &or you by #hone8ap-supplie" ser!ers. ?ou Gust &o'us on 'reating your +5ML, C%%, an" Ca!as'ript as you see &it. As note" earlier, #hone8apP1uil" is still in pri!ate beta at the time o& this =riting, though hope&ully it =ill be open to the publi' in the near &uture. When you log into #hone8apP1uil", you are &irst prompte" to 'reate your initial proGe't, by supplying a name an" the Web assets to go into the app,
20<
Phone(ap
?ou =ill be able to a"" ne= proGe'ts later on !ia a 2e= App button, =hi'h gi!es you the same set o& options. ?our 'hoi'es &or the assets are to uploa" a Q0# &ile 'ontaining all o& them, or to spe'i&y the $ L to a publi' 8it+ub repository that #hone8apP1uil" 'an pull &rom. 5he latter ten"s to be more 'on!enient, i& you are use" to using 8it &or !ersion 'ontrol, an" i& your proGe't is open sour'e (an" there&ore has a publi' repository). >n'e you 'li'k the $ploa" button, the #hone8apP1uil" ser!er =ill imme"iately start buil"ing your appli'ation &or An"roi", plus 1la'kberry, %ymbian, an" Web>%,
20*
Phone(ap
Ea'h o& the targets has its o=n &ile e;tension (e.g., apk &or An"roi"). Cli'king that link =ill let you "o=nloa" that &ile. >r, 'li'k on the name o& the proGe't, an" you get J 'o"es to enable "o=nloa"s straight to your test "e!i'e,
20&
Phone(ap
5his page also gi!es you a link to up"ate the app &rom its 8it+ub repo (i& you 'hose that option). >r, 'li'k E"it to spe'i&y more options, su'h as the !ersion o& your appli'ation or its laun'her i'on,
All in all, i& you "o not other=ise nee" the An"roi" %@D an" relate" tools on your "e!elopment ma'hine, #hone8apP1uil" 'ertainly simpli&ies the #hone8ap buil"ing pro'ess. 2ote, though, that at the present time, 2itobi (the &irm behin" #hone8ap an" #hone8apP1uil") is planning on #hone8apP1uil" to be a 'ommer'ial ser!i'e &or non-open-sour'e appli'ations, though rates ha!e not yet been announ'e" at this time.
20-
Phone(ap
2. Copy the +5ML, C%%, Ca!as'ript, an" images &rom the +5MLA proGe't into the assets/EEE/ "ire'tory o& the #hone8ap proGe't (note that you "o not nee" things uniRue to +5MLA, su'h as the 'a'he mani&est) .. Make sure that your +5ML entry point &ilename mat'hes the path you use" =ith the load3rlPQ 'all in your a'ti!ity (e.g., indeG.html) <. A"" a re&eren'e to the #hone8ap Ca!as'ript &ile &rom your +5ML A. 1uil" an" install the proGe't +ere is the =roidDap a'ti!ity &or our app, &rom the (honeDap/+hecklist proGe't,
package com.commonsEare.pg.checklistJ import android.app.ActivitFJ import android.os.4undleJ
20%
Phone(ap
import com.phonegap.=roidDapJ public class +hecklist eGtends =roidDap : O"verride public void onCreateP4undle savedInstance2tateQ : super.onCreatePsavedInstance2tateQJ super.load*rlP7file:///android asset/EEE/indeG.html7QJ ; ;
+ere is the mani&est, =ith all o& the #hone8ap-reRueste" settings a""e",
LNGml version671.-7 encoding67utf-,7NM Lmanifest Gmlns:android67http://schemas.android.com/apk/res/android7 package67com.commonsEare.pg.checklist7 android:version+ode6717 android:version%ame671.-7M Lapplication android:label67Ostring/app name7 android:icon67OdraEable/cE7M LactivitF android:name67+hecklist7 android:config+hanges67orientationWkeFboard!idden7 android:label67Ostring/app name7M Lintent-filterM Laction android:name67android.intent.action.#AI%7 /M LcategorF android:name67android.intent.categorF.)A3%+!$?7 /M L/intent-filterM L/activitFM L/applicationM Lsupports-screens android:large2creens67true7 android:normal2creens67true7 android:small2creens67true7 android:resiKeable67true7 android:anF=ensitF67true7 /M Luses-permission android:name67android.permission.+A#$?A7 /M Luses-permission android:name67android.permission.VI4?A&$7 /M Luses-permission android:name67android.permission.A++$22 +"A?2$ )"+A&I"%7 /M Luses-permission android:name67android.permission.A++$22 9I%$ )"+A&I"%7 /M Luses-permission android:name67android.permission.A++$22 )"+A&I"% $]&?A +"##A%=27 /M Luses-permission android:name67android.permission.?$A= (!"%$ 2&A&$7 /M Luses-permission android:name67android.permission.I%&$?%$&7 /M Luses-permission android:name67android.permission.?$+$IV$ 2#27 /M Luses-permission android:name67android.permission.?$+"?= A3=I"7 /M Luses-permission android:name67android.permission.#"=I95 A3=I" 2$&&I%D27 /M Luses-permission android:name67android.permission.?$A= +"%&A+&27 /M Luses-permission android:name67android.permission.@?I&$ +"%&A+&27 /M Luses-permission android:name67android.permission.@?I&$ $]&$?%A) 2&"?AD$7 /M Luses-permission android:name67android.permission.A++$22 %$&@"?H 2&A&$7 /M L/manifestM
200
Phone(ap
An" here is the +5ML S almost i"enti'al to the +5MLA original, remo!ing some +5MLA o&&line stu&& (e.g., i#hone i'ons) an" a""ing in the re&eren'e to #hone8ap7s Ca!as'ript &ile,
LX="+&5($ htmlM Lhtml lang67en7 manifest67checklist.manifest7M LheadM Lmeta http-eUuiv67+ontent-&Fpe7 content67teGt/htmlJ charset6utf-,7 /M LtitleM+hecklistL/titleM Lmeta name67vieEport7 content67Eidth6device-EidthJ initial-scale61.-J maGimum-scale61.-J userscalable6-J7 /M Llink rel67stFlesheet7 href67stFles.css7 /M Lscript tFpe67teGt/javascript7 charset67utf-,7 src67phonegap.-.*.<.js7ML/scriptM L/headM LbodFM LsectionM LheaderM Lbutton tFpe67button7 id67sendmail7M#ailL/buttonM Lh1M+hecklistL/h1M L/headerM LarticleM Lform id67inputarea7 onsubmit67add%eEItemPQ7M Linput tFpe67teGt7 name67name7 id67name7 maGlength67/.7 autocorrect placeholder67&ap to enter a neE itemZhellipJ7 /M Lbutton tFpe67button7 id67add7MAddL/buttonM L/formM Lul id67maillist7M Lli class67emptF7MLa href677 id67maillink7M#ail remaining itemsL/aML/liM L/ulM Lp id67totals7MLspan id67tallF17M&otal: Lspan id67total7M-L/spanML/spanM Lspan id67tallF>7M?emaining: Lspan id67remaining7M-L/spanML/spanML/pM Lul id67checklist7M Lli class67emptF7M)oadingZhellipJL/liM L/ulM L/articleM LfieldsetM Lbutton tFpe67button7 id67deletechecked7M=elete +heckedL/buttonM Lbutton tFpe67button7 id67deleteall7M=elete AllL/buttonM L/fieldsetM L/sectionM Lscript src67main.js7ML/scriptM L/bodFM L/htmlM
202
Phone(ap
*or many appli'ations, this is all you =ill nee" S you are simply looking at #hone8ap to gi!e you something you 'an "istribute on the An"roi" Market, on the i>% App %tore, an" so on.
2. 0n on)oadPQ, use add$vent)istenerPQ to register another global Ca!as'ript &un'tion (e.g., on=evice?eadFPQ) &or the devicereadF e!ent .. 0n on=evice?eadFPQ, start using the #hone8ap A#0s
207
Phone(ap
here is a Ca!as'ript &ile (props.js &rom the (honeDap/+hecklist$G proGe't) that implements an on)oadPQ &un'tion (to register &or devicereadF) an" an on=evice?eadFPQ &un'tion (to use the device obGe't7s properties),
// (honeDapIs A(Is are not immediatelF readF8 so set up an // event handler to find out Ehen theF are readF function onLoadPQ : document.add+!entListenerP7devicereadF78 on=evice?eadF8 falseQJ ; // %oE (honeDapIs A(Is are readF function onDe!ice%eadyPQ : var element6document.get+lementByIdPIpropsIQJ element.inner!&#)6ILliM#odel: IRdevice.nameRIL/liMI R ILliM"2 and Version: IRdevice.platform RI IRdevice.versionRIL/liMI R ILliM(honeDap Version: IRdevice.phonegapRIL/liMIJ ;
*or
e;ample,
5he on=evice?eadFPQ &un'tion nee"s a list element =ith an id o& props. 5hat, plus loa"ing this Ca!as'ript in the &irst pla'e, =ill reRuire some minor mo"i&i'ations to our +5ML,
LX="+&5($ htmlM Lhtml lang67en7 manifest67checklist.manifest7M LheadM Lmeta http-eUuiv67+ontent-&Fpe7 content67teGt/htmlJ charset6utf-,7 /M LtitleM+hecklistL/titleM Lmeta name67vieEport7 content67Eidth6device-EidthJ initial-scale61.-J maGimum-scale61.-J userscalable6-J7 /M Llink rel67stFlesheet7 href67stFles.css7 /M Lscript tFpe67teGt/javascript7 charset67utf-,7 src67phonegap.-.*.<.js7ML/scriptM Lscript tFpe67teGt/javascript7 charset67utf-,7 src67props.js7ML/scriptM L/headM LbodF onload67on)oadPQ7M LsectionM LheaderM Lbutton tFpe67button7 id67sendmail7M#ailL/buttonM Lh1M+hecklistL/h1M L/headerM LarticleM Lform id67inputarea7 onsubmit67add%eEItemPQ7M Linput tFpe67teGt7 name67name7 id67name7 maGlength67/.7 autocorrect placeholder67&ap to enter a neE itemZhellipJ7 /M
208
Phone(ap
Lbutton tFpe67button7 id67add7MAddL/buttonM L/formM Lul id67maillist7M Lli class67emptF7MLa href677 id67maillink7M#ail remaining itemsL/aML/liM L/ulM Lp id67totals7MLspan id67tallF17M&otal: Lspan id67total7M-L/spanML/spanM Lspan id67tallF>7M?emaining: Lspan id67remaining7M-L/spanML/spanML/pM Lul id67checklist7M Lli class67emptF7M)oadingZhellipJL/liM L/ulM L/articleM LfieldsetM Lbutton tFpe67button7 id67deletechecked7M=elete +heckedL/buttonM Lbutton tFpe67button7 id67deleteall7M=elete AllL/buttonM L/fieldsetM LfooterM Lh>M=evice (ropertiesL/h>M Lul id67props7ML/ulM L/footerM L/sectionM Lscript src67main.js7ML/scriptM L/bodFM L/htmlM
20:
Phone(ap
>b!iously, rea"ing a han"&ul o& properties is &ar simpler than, say, taking a pi'ture =ith the "e!i'e7s 'amera. +o=e!er, the "i&&eren'e in 'omple;ity is mostly in =hat #hone8ap7s !irtual Ca!as'ript obGe'ts gi!e you an" ho= you 'an use them, more so than anything pe'uliar to An"roi".
Security
An"roi" appli'ations use a permission system to reRuest a''ess to 'ertain system &eatures, su'h as making 0nternet reRuests or rea"ing the user7s 'onta'ts. Appli'ations must reRuest these permissions at install time, so the user 'an ele't to aban"on the installation i& the reRueste" permissions seem suspe't. A general rule o& thumb is that you shoul" reRuest as &e= permissions as possible, an" make sure that you 'an Gusti&y =hy you are reRuesting the remaining permissions. #hone8ap, &or a ne= proGe't, reRuests Ruite a &e= permissions,
+A#$?A VI4?A&$ A++$22 +"A?2$ )"+A&I"% A++$22 9I%$ )"+A&I"% A++$22 )"+A&I"% $]&?A +"##A%=2 ?$A= (!"%$ 2&A&$ I%&$?%$& ?$+$IV$ 2#2 ?$+"?= A3=I"
22<
Phone(ap
#"=I95 A3=I" 2$&&I%D2 ?$A= +"%&A+&2 @?I&$ +"%&A+&2 @?I&$ $]&$?%A) 2&"?AD$ A++$22 %$&@"?H 2&A&$
Lea!ing this roster inta't =ill gi!e you an appli'ation that 'an use e!ery A#0 #hone8ap makes a!ailable to your Ca!as'ript...an" an appli'ation that =ill s'are a=ay many users. A&ter all, it is unlikely that your appli'ation =ill be able to use, let alone Gusti&y, all o& these permissions. 0t is 'ertainly possible &or you to trim "o=n this list, by mo"i&ying the Android#anifest.Gml &ile in the root o& your #hone8ap proGe't. +o=e!er, you =ill then nee" to thoroughly test your appli'ation to make sure you "i" not get ri" o& a permission that you a'tually nee". Also, it may be un'lear to you =hi'h permissions you 'an sa&ely remo!e. E!entually, the #hone8ap proGe't may ha!e tools to help gui"e you in the 'hoi'e o& permissions, perhaps by stati'ally analyKing your Ca!as'ript 'o"e to see =hi'h #hone8ap A#0s you are using. 0n the meantime, though, getting the proper set o& permissions =ill in!ol!e a lot o& trial an" error.
22*
Phone(ap
siKe in the netbookPnotebookP"esktop realm. 5hat is be'ause s'reen "ensity is &airly 'onsistent a'ross their LC@s, an" that "ensity is &airly lo=. %martphones, on the other han", ha!e se!eral "i&&erent "ensities, 'ausing the 'onne'tion bet=een resolution an" siKe to be broken. %ome lo=-en" phones, parti'ularly =ith small (e.g., .M) LC@s, ha!e "ensities on par =ith ni'e monitors. Mi"-range phones ha!e t=i'e the "ensity (2<0"pi !ersus 120"pi). Apple7s i#hone < has e!en higher "ensity, an" one 'an imagine that there =ill soon be some An"roi" "e!i'es =ith so-'alle" Mretina "isplaysM as =ell. +en'e, an 800;<80 resolution 'oul" be on a s'reen ranging any=here &rom <M to 4M, &or e;ample. 5ablets a"" e!en more possible siKes to the mi;. 5his is 'ompoun"e" by the problems 'ause" by tou'hs'reens. A mouse 'an get pi;el-le!el pre'ision in its 'li'ks. *ingers are mu'h less pre'ise. +en'e, you ten" to nee" to make your buttons an" su'h that mu'h bigger on a tou'hs'reen, so it 'an be M&inger-&rien"lyM. 5his 'auses some problems =ith s'aling o& assets, parti'ularly images. What might be M&inger-&rien"lyM on a lo=-"ensity .M "e!i'e might be entirely too small &or a high-"ensity <M "e!i'e. 2ati!e An"roi" appli'ations ha!e built-in logi' &or "ealing =ith this issue, in the &orm o& multiple sets o& Mresour'esM (e.g., images) that 'an be s=appe" in base" upon "e!i'e 'hara'teristi's. E!entually, #hone8ap an" similar tools =ill nee" to pro!i"e rele!ant a"!i'e &or their users &or ho= to 'reate appli'ations that 'an similarly a"apt to 'ir'umstan'es.
)oo$ nd 5eel
A Web app ne!er Ruite looks like a nati!e one. 5his is not ne'essarily a ba" thing. +o=e!er, some users may &in" it "is'on'erting, parti'ularly sin'e they =ill not un"erstan" =hy their ne=ly-installe" app (ma"e =ith #hone8ap, &or e;ample) =oul" ne'essarily look substantially "i&&erent than any other similar app they may alrea"y ha!e.
22&
Phone(ap
As +5MLA appli'ations be'ome more prominent on An"roi", this issue shoul" "e'line in importan'e. +o=e!er, it is something to keep in min" &or the ne;t year or t=o.
22-
CHAPTER 29
5he alternati!e appli'ation en!ironments "es'ribe" in the pre'e"ing 'hapters are but the tip o& the i'eberg. +ere, =e =ill take a look at a &e= other alternati!e appli'ation en!ironments, &rom the gro=ing &loo" o& su'h te'hnologies. 2ote that this area 'hanges rapi"ly, an" so the material in this 'hapter may be some=hat out o& "ate relati!e to the progress ea'h o& these te'hnologies has ma"e.
Chodes
%piritually, ho"es is similar to #hone8ap, in that you "e!elop an An"roi" appli'ation =hose user inter&a'e is "e&ine" !ia +5ML, C%%, an" Ca!as'ript. 5he "i&&eren'e is that ho"es bakes in a &ull uby en!ironment, =ith a ails-esRue &rame=ork. ?our uby 'o"e generates +5ML an" su'h to be Mser!e"M to an a'ti!ity !ia a @ebVieE =i"get, mu'h like a ser!er-si"e uby Web app =oul" generate +5ML to be ser!e" to a stan"alone Web bro=ser. %imilar to #hone8ap, you 'an either buil" the proGe't on your "e!elopment ma'hine or use their hoste" buil" pro'ess. 5he latter is re'ommen"e", partly be'ause the reRuirements &or lo'al buil"s are higher than those &or #hone8ap S notably, ho"es reRuires the 2ati!e @e!elopment Dit (2@D) &or buil"ing an" linking the uby interpreter to your appli'ation.
220
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
ho"es =in"s up 'reating larger appli'ations than "oes #hone8ap, "ue to the o!erhea" o& the uby interpreter (^1.AM1). +o=e!er, i& you are use" to ser!er-si"e Web "e!elopment, ho"es may be easier &or you to pi'k up than =oul" #hone8ap.
222
5his is =here uboto 'omes in. uboto is a &rame=ork &or a generi' C ubyPAn"roi" appli'ation. 0t pro!i"es skeletal a'ti!ities !ia a 'o"e generator an" allo=s C uby s'ripts to "e&ine han"lers &or all o& the li&e'y'le metho"s (e.g., on+reatePQ), plus "e&ine user inter&a'es using C uby 'o"e, et'. 5he result 'an be pa'kage" up as an A#D &ile using supplie" ake s'ript. 5he results 'an be uploa"e" to the An"roi" Market or "istribute" ho=e!er else you "esire.
+ono/roid
Mono is a re-implementation o& CB an" .2E5 &or non-Win"o=s en!ironments. Mono has ha" its &air share o& 'ontro!ersies, mostly stemming &rom Mi'roso&t, su'h as =hether Mi'roso&t =ill some"ay sRuash Mono o!er patent 'onsi"erations. Mono@roi" has been in the =orks &or some time. 5his =oul" allo= Mono "e!elopers to target An"roi" &or their apps. 0n prin'iple, one 'oul" "e!elop CB appli'ations &or An"roi" this =ay. While Mono itsel& is an open sour'e proGe't, MMono@roi" is a 'ommer'ial pro"u't...li'ense" on a per-"e!eloper basisM, a''or"ing to the Mono proGe't. 5his may 'ome as a bit o& a sho'k to those e;pe'ting Mono-on-An"roi" to remain open sour'e. Mono@roi", =hile eagerly anti'ipate", has not been release" as o& the time o& this =riting, beyon" a beta.
App nventor
App 0n!entor is an An"roi" appli'ation "e!elopment tool ma"e a!ailable by 8oogle, but outsi"e o& the normal An"roi" "e!eloper site. App 0n!entor =as originally "e!elope" &or use in e"u'ation, but they ha!e been in!iting others into their 'lose" beta.
227
App 0n!entor is theoreti'ally a Web-base" "e!elopment tool. +ere, Mtheoreti'allyM means that, in pra'ti'e, users ha!e to "o a &air amount o& =ork outsi"e o& the bro=ser to get e!erything set up,
+a!e Ca!a installe" an" &un'tioning in the bro=ser, 'apable o& running Ca!a Web %tart (.Gnlp) appli'ations @o=nloa" an" install a large (^AAM1) 'lient-si"e set o& tools +a!e a phone an" ha!e it 'on&igure" to =ork =ith App 0n!entor an" the An"roi" %@D
>n'e set up, App 0n!entor gi!es you a "rag-an"-"rop 8$0 e"itor,
...an" a Mblo'ksM e"itor, =here you atta'h beha!iors to e!ents (e.g., button 'li'ks) by snapping together !arious Mblo'ksM representing e!ents, metho"s, an" properties,
228
While =orking in the 8$0 e"itor, you see =hat you are buil"ing li!e on an atta'he" phone an" 'an be teste" in real time. Later, =hen you are rea"y, you 'an pa'kage the appli'ation into a stan"ar" A#D &ile. +o=e!er, App 0n!entor is not really set up &or pro"u'tion appli'ation use to"ay,
?ou 'annot "istribute App 0n!entor apps on the An"roi" Market 0t has more 'omponents aime" at MsiKKleM (e.g., 5=itter integration) an" &e=er "eli!ering 'apabilities that a typi'al mo"ern app might nee" (e.g., relational "atabases, lists) >nly one "e!eloper at a time 'an =ork on a proGe't
0n the &uture, it is possible that App 0n!entor =ill be'ome a soli" option, or that App 0n!entor =ill trigger other &irms to 'reate similar sorts o& programming-&ree "e!elopment options &or An"roi".
Titanium +obile
5itanium Mobile7s 'laim to &ame is using Ca!as'ript to 'ompletely "e&ine the user inter&a'e, es'he=ing +5ML entirely. ather, their Ca!as'ript library S in a""ition to pro!i"ing a''ess to "atabases an" plat&orm 'apabilities S also
22:
lets you "e'lare user inter&a'e =i"gets. 0ts layout 'apabilities, &or positioning sai" =i"gets, lea!es a bit to be "esire". As o& the time o& this =riting, App'elerator S the 'reators o& 5itanium Mobile S "oes not o&&er a 'lou"-base" set o& tools. 5heir 5itanium tool has a !ery sli'k-looking $0, but it still reRuires the Ca!a %@D an" An"roi" %@D in or"er to be able to buil" An"roi" appli'ations, making the setup a bit "aunting &or some. As o& the time o& this =riting, 5itanium Mobile supports "e!elopment &or An"roi" an" i>%, =ith 1la'kberry support in a pri!ate beta.
27<
CHAPTER 2:
An"roi" is M&ree as in beerM &or "e!i'e manu&a'turers, as it is an open sour'e proGe't. +en'e, "e!i'e manu&a'turers ha!e carte blanche to "o =hat they =ant =ith An"roi" as they put it on their "e!i'es. 5his means a brea"th o& 'hoi'es &or "e!i'e users, =ho =ill be able to ha!e An"roi" "e!i'es in all shapes, siKes, an" 'olors. 5his also means "e!elopers =ill ha!e some "e!i'e "i&&eren'es an" i"iosyn'rasies to take into a''ount. 5his 'hapter =ill gi!e you some tips an" a"!i'e &or "ealing =ith these "e!i'e-spe'i&i' issues, to go along =ith the s'reen siKe material &rom the pre!ious 'hapter.
*ortunately, starting =ith An"roi" 1.A, you 'an no= a"" e;pli'it instru'tions, telling An"roi" =hat you nee", so your appli'ation is not installe" on "e!i'es la'king su'h har"=are. 0n a""ition to using the target 0@ system to in"i'ate =hat le!el o& "e!i'e your proGe't is targeting, you 'an use a ne= Android#anifest.Gml element to spe'i&y har"=are that is reRuire" &or your appli'ation to run properly. ?ou 'an a"" one or more Luses-configurationM elements insi"e the LmanifestM element. Ea'h Luses-configurationM element spe'i&ies one !ali" 'on&iguration o& har"=are that your appli'ation =ill =ork =ith. At the present time, there are &i!e possible har"=are reRuirements you 'an spe'i&y this =ay,
to in"i'ate you nee" a A-=ay na!igation pointing "e!i'e o& some &orm (e.g, android:reU9ive@aF%av 6 7true7)
android:reU9ive@aF%av android:reU%avigation
to restri't the A-=ay na!igation pointing "e!i'e to a spe'i&i' type (e.g, android:reU%avigation 6 7trackball7)
android:reU!ardHeFboard to spe'i&y i& a har"=are (physi'al) is reRuire" (e.g, android:reU!ardHeFboard 6 7true7) android:reUHeFboard&Fpe, android:reU!ardHeFboard,
keyboar"
probably use" in 'onGun'tion =ith to in"i'ate a spe'i&i' type o& har"=are keyboar" that is reRuire" (e.g, android:reUHeFboard&Fpe 6 7UEertF7)
android:reU&ouch2creen to in"i'ate =hat type o& tou'hs'reen reRuire", i& any (e.g, android:reU&ouch2creen 6 7finger7)
is
%tarting in An"roi" 1./, there is a similar mani&est element, Luses-featureM, =hi'h is "esigne" to "o'ument reRuirements an appli'ation has o& other optional &eatures on An"roi" "e!i'es. *or e;ample, the &ollo=ing attributes 'an be pla'e" in a Luses-featureM element,
android:gl$sVersion in"i'ates that your appli'ation reRuires >pen8L, =here the !alue o& the attribute in"i'ates =hat le!el o& >pen8L support (e.g., -G---1---> &or >pen8L 1.2 or higher) android:name 6 7android.hardEare.camera7
appli'ation
nee"s
'amera,
=hile
27%
Ea'h An"roi" release a""s more an" more &eatures you 'an reRuire. 5hese reRuests =ill 'ause the An"roi" Market S an" other thir"-party markets, one hopes S to &ilter your appli'ation out &rom "e!i'es &or =hi'h it is unsuitable. 5he Luses-featureM element has an android:reUuired attribute that you 'an spe'i&y. 1y "e&ault, it is set to true, meaning you absolutely nee" this &eature. 0& you set it to false, you are a"!ertising that you 'an take a"!antage o& the &eature i& it e;ists, but you "o not absolutely nee" it. 5o &in" out at runtime =hether the &eature is there, you 'an use the has2Fstem9eaturePQ metho" on (ackage#anager to interrogate the "e!i'e to see i& =hat you =ant is a!ailable.
5he F>>M "oes not ha!e telephony Z the &irst An"roi" Market-'ompliant "e!i'e =ith that limitation. While it 'an ha!e a "ata plan, it has no !oi'e or %M% 'apability, an" so it is treate" as not ha!ing android.hardEare.telephonF. 1ut, i& you reRuest permissions like +A)) (!"%$, the An"roi" Market by "e&ault =ill assume you need
270
android.hardEare.telephonF.
Market &or the F>>M. 5he solution is simple, &or any har"=are &eatures that might be implie" by permissions but that you "o not absolutely nee", manually a"" the appropriate Luses-featureM element to your mani&est =ith android:reUuired67false7,
Luses-feature android:name67android.hardEare.telephonF7 android:reUuired67false7 /M
5hen, be&ore you try pla'ing a phone 'all or sen"ing an %M% or something, use (ackage#anager an" get2FstemAvailable9eaturesPQ to &in" out i& android.hardEare.telephonF is in"ee" a!ailable on the "e!i'e. *or e;ample, you might 'he'k &or telephony early on an" "isable !arious menu 'hoi'es S buttons that might lea" to the user to pla'e a 'all or sen" an %M%. 2o=, i& your appli'ation absolutely nee"s telephony, then the implie" Luses-featureM =ill =ork, though you may =ish to 'onsi"er putting one in e;pli'itly. +o=e!er, Gust bear in min" that this means your app =ill not =ork on the F>>M or other tablets that la'k telephony.
A (uaranteed +arket
As mentione" in the intro"u'tion to the 'hapter, An"roi" is open sour'e. %pe'i&i'ally, it is mostly a!ailable un"er the Apa'he %o&t=are Li'ense 2.0. 5his li'ense pla'es &e= restri'tions on "e!i'e manu&a'turers. 5here&ore, it is !ery possible &or a "e!i'e manu&a'turer to 'reate a "e!i'e that, &rankly, "oes not run An"roi" !ery =ell. 0t might =ork &ine &or stan"ar" appli'ations shippe" on the "e!i'e but "o a poor Gob o& han"ling thir"-party appli'ations, like the ones you might =rite. 5o help a""ress this, 8oogle has some appli'ations, su'h as the An"roi" Market, that it has not release" as open sour'e. While these appli'ations are a!ailable to "e!i'e manu&a'turers, the "e!i'es that run the An"roi"
272
Market are teste" &irst, to help ensure that a user7s e;perien'e =ith the "e!i'e =ill be reasonable. A 8oogle engineer 'ite" one 'ase =here a "e!i'e manu&a'turer =as rea"ying a phone that ha" a J-8A s'reen, be&ore the release o& An"roi" 1./ =here J-8A support =as o&&i'ially a""e" to the plat&orm. While that manu&a'turer ha" arrange" &or the built-in appli'ations to =ork a''eptably on the smaller-resolution s'reen, thir" party appli'ations =ere a mess. 8oogle apparently "e'line" to pro!i"e the An"roi" Market to the manu&a'turer &or this "e!i'e. +en'e, the e;isten'e o& the An"roi" Market on a "e!i'e, beyon" pro!i"ing a "istribution means &or your appli'ations, also ser!es as a bit o& a Mseal o& appro!alM that the "e!i'e shoul" support =ell-=ritten thir"-party appli'ations. %pe'i&i'ally, any "e!i'e that has the An"roi" Market,
Will meet the 'riteria outline" in the Compatibility @e&inition @o'ument (C@@) Will ha!e passe" the Compatibility 5est %uite (C5%)
What lo'ation te'hnologies are a!ailable (8#%H Cell to=er pro;imityH 8alileoH) What 'amera &eatures are a!ailable (&lashH auto-&o'usH sepia toneH) What sensors are a!ailable (a''elerometerH gyros'opeH barometerH)
5he strategy &or these is to interrogate the system to &in" out =hat the possibilities are, then "e'i"e =hi'h to use, =here the "e'ision 'oul" be ma"e solely by you or =ith user input. *or e;ample, you 'an use +riteria to "etermine =hi'h is the best lo'ation pro!i"er to use =ith )ocation#anager.
277
/evice Testing
0"eally, you try to test your apps on a !ariety o& har"=are. 5his 'an get e;pensi!e. +ere are some options &or trying to "o it more 'heaply,
%ign up &or @e!i'eAny=here7s in"epen"ent "e!eloper plan, =hi'h is a lo=er-'ost =ay o& being able to a''ess their "e!i'e &arm &or testing &rom remote %ome "e!i'e manu&a'turers hol" M"e!i'e labsM at !arious e!ents, su'h as Motorola hel" at An@e!Con 2011 %ome 'arriers ha!e perpetual "e!i'e labs, su'h as >range7s M"e!eloper 'entresM
278
?ou may be able to arrange short-term (e.g., 1A minute) "e!i'e s=aps as part o& a Meetup or 8oogle 5e'hnology $ser 8roup =ith &ello= An"roi" "e!elopers
27:
CHAPTER 2;
>b!iously, this book "oes not 'o!er e!erything. An" =hile your B1 resour'e (besi"es the book) is going to be the An"roi" %@D "o'umentation, you are likely to nee" in&ormation beyon" =hat7s 'o!ere" in either o& those pla'es. %ear'hing online &or Man"roi"M an" a 'lass name is a goo" =ay to turn up tutorials that re&eren'e a gi!en An"roi" 'lass. +o=e!er, bear in min" that tutorials =ritten be&ore late August 2008 are probably =ritten &or the MA %@D an", as su'h, =ill reRuire 'onsi"erable a"Gustment to =ork properly in 'urrent %@Ds. 1eyon" ran"omly hunting aroun" &or tutorials, though, this 'hapter outlines some other resour'es to keep in min".
%ta'k>!er&lo=7s an"roi" tag an"roi"-"e!elopers, &or %@D Ruestions an" ans=ers an"roi"-"is'uss, "esigne" &or &ree-&orm "is'ussion o& anything An"roi"-relate", not ne'essarily &or programming Ruestions an" ans=ers
28*
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
5he An"roi" tutorials an" programming &orums o!er at an""e!.org 5he An"Mob =iki 5he Sandroid-dev 0 C 'hannel on &reeno"e (ir'.&reeno"e.net) 5he An"roi" boar" on Ca!a an'h
0t is important, parti'ularly &or %ta'k>!er&lo= an" the 8oogle 8roups, to =rite =ell-=ritten Ruestions,
0n'lu"e rele!ant portions o& the sour'e 'o"e (e.g., the metho" in =hi'h you are getting an e;'eption) 5he sta'k tra'e &rom LogCat, i& the problem is an unhan"le" e;'eption >n %ta'k>!er&lo=, make sure your sour'e 'o"e an" sta'k tra'e are &ormatte" as sour'e 'o"eT on 8oogle 8roups, 'onsi"er posting long listings on gist.github.'om or a similar sort o& 'o"e-paste site E;plain thoroughly =hat you are trying to "o, ho= you are trying to "o it, an" =hy you are "oing it this =ay (i& you think your goal or approa'h may be a little o&&beat) >n %ta'k>!er&lo=, respon" to ans=ers an" 'omments =ith your o=n 'omments, a""ressing the person using the I synta; (e.g., ICommonsWare), to ma;imiKe the o""s you =ill get a reply >n the 8oogle 8roups, "o not MpingM or reply to your o=n message to try to eli'it a response until a reasonable amount o& time has gone by (e.g., 2< hours)
28&
5he sour'e 'o"e an" relate" resour'es http,PPsour'e.an"roi".'om. +ere, you 'an,
'an
be
&oun"
at
@o=nloa" or bro=se the sour'e 'o"e *ile bug reports against the operating system itsel& %ubmit pat'hes an" learn about the pro'ess &or ho= su'h pat'hes get e!aluate" an" appro!e" Coin a separate set o& 8oogle 8roups &or An"roi" plat&orm "e!elopment
ather than "o=nloa" the multi-gigabyte An"roi" sour'e 'o"e snapshot, you may =ish to use 8oogle Co"e %ear'h instea". Cust a"" the android:package 'onstraint to your sear'h Ruery, an" it =ill only sear'h in An"roi" an" relate" proGe'ts.
28-
9ey)ord ndex
Class...............................................
AbsoluteLayout........................................134, ..0 A'tionE!ent......................................................./4 A'tionListener.................................................../4 A'ti!ity......8, 81, 1.., 1A8, 181, 22A, 22/, 2.2, 2<4, 2/0, 2/2, 241, 242, 24<, 282, 28., 232, ..A, .81, <14, <.1, <.2, <A0, <A8, A0<, A.., A.<, A</, A42, /<4 A"apter........................................1.., 1A2, 1A<, <A1 A"apter-ie=............................................1A<, </A A"apter-ie=.A"apterConte;tMenu0n&o........218 A""%trings5ask...............................................2/3 A""%tring5ask.........................................2/4, 2/3 Alert@ialog.........................21/, 22/-228, .41, .4A AnalogClo'k.............................................14/, 18/ an"roi".te;t.%panne"......................................00 An"roi"+ttpClient.........................<84, <88, A00 Appli'ation......................................................A03 ArrayA"apter...1.2-1./, 1<., 1A.-1A/, 1/1, 1/., 1/<, 1/4, 21A, 214, 218, 2/4, 2/8, .4<, <1/, <// ArrayList.....................................21A, <1/, A2., A2A AssetManager..................................................A3/
Asyn'5ask. .2/2-2/A, 2/4-241, 24A, <2., <2A, <23, </4, A2., A28 AutoComplete5e;t-ie=..............8A, 1<A, 1<4, 138 1asi' esponse+an"ler....................................A1/ 1in"er.......................................A08, A03, A22, A2A 1o;.....................................................................3. 1o;Layout..........................................................3. 1roa"'ast e'ei!er....................282, 28., A10, A/A 1uil"................................................................/4/ 1uil"er..............................................22/, 224, <2< 1un"le.......2.., 2.A, 2.8, 2<A, 2<4, 243, 288, .8., .3/, <A0 1utton...41, 4.-4/, 80-82, 30, 34, 102, 10., 110, 111, 188, 183, 131, 132, 13<, 228, 2.A, .01, .21, .22, ..1, .44, <00, <0A 1yteArray esponse+an"ler............................A1/ Calen"ar...........................................................14< Che'k1o;...............................................8A, 88, 31 Che'k1o;#re&eren'e.......................................<.< Che'ke"5e;t-ie=............................................134 Chronometer.............................................144, 134 Class.................................................................<0A
280
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
9ey)ord ndex
Color%tateList..............................................31, 32 Compoun"1utton.............................................88 Con&iguration...........................................2A0, ..A Constants1ro=ser..................................</0, <// Conta'ts.#eople..............................................<0/ Conta'tsContra't............................................<0A Conta'tsContra't.Conta'ts............................<0/ ContentManager.............................................A.8 Content-alues.........................................</2, </. Conte;t1.2, 22/, 241, <14, <22, <.1, <.2, <A8, <30, A03, A2. Conte;tMenu............................................212, 222
@ialog#re&eren'e.............................................<A1 @igitalClo'k.....................................................14/ @isplayMetri's.................................................../ @o'ument........................................................<1/ @ouble.............................................................284 @o=nloa"@emo..............................................<31 @o=nloa"er.......................................A1<, A14, A20 @o=nloa"Manager..................<88-<31, <3., A00 @o=nloa"Manager.Juery..............................<3. @o=nloa"Manager. eRuest...................<31, <32 @ra=able....................1<3, 182, 2<A, .0<, A.3, A44 @ra=er@emo....................................................134
Conte;tMenu.Conte;tMenu0n&o....................212 @roi"8ap........................................./<4, /<8, /A2 Countries*ragment...................8., .88, .30-.3< @ynami'@emo..........................................1A/, 1A4 Country.....................................................8/, .3A E"it#re&eren'es.......................................<.<, <A2 CountryA"apter........................................8., .8/ E"it#re&eren'es+C..................................<A2, <A. CountryListener................................32, .3<, .3A CountryWrapper..............................................8< Criteria.....................................................A/., /4A Cursor..............................<2<, </<, </A, </4, <3. CursorA"apter........................................</A, <// CW1ro=ser......................................................23. @atabase+elper.......................................<A8, </1 @ate*ormat......................................................14< @ate#i'ker.........................................................141 @ate#i'ker@ialog......................................141, 14< @e&ault+ttpClient............<82, <84, A1/, A2A, A28 @etailsA'ti!ity..........................................30, .3A @etails*ragment .81, .82, .88, .30, .31, .3<, .3A @ialog*ragment...............................................88 E"it5e;t.....8., 108, 113, 120, 122, 12A-124, 123, 1<A, 141, 2.A, 2.3, .14, .42-.4<, .44, <08 E"it5e;t#re&eren'e..........................................<<. En!ironment....................................<22, <2., <32 E$<?ou...............................<0, .<2, .A., .30-.3A E;'eption.........................................<0A, A28, A34 E;pan"ableList-ie=........................................134 *ake#layer.........................................A21, A</, A<4 *an'yListsP-ie=+ol"er...................................1/2 *et'h*ore'ast5ask...................................A28, A/A *iel"@emo........................................................113 *ile....................................................<21, <22, <32 *ile>utput%tream...................................<28, <23 *lo=Layout........................................................3<
282
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
9ey)ord ndex
*ont%ampler....................................................A3/ *ore'ast.....................................<8A, A2.-A2A, A28 *ragment.............................43, .81-.8., .88, A8. *ragmentA'ti!ity.............................83, .3/, A82 *ragmentManager............................83, .31, .3< *ragment5ransa'tion........................43, .83, .31 *rameLayout.......................180, 181, 188, 13<, A8. 8allery.................................................1.1, 1<3, 134 8eo#oint..........................................................A4A 8ra"ient@ra=able.............................................2 8ri"-ie=.............................................1<1, 1<2, 1<3 +an"ler.........2.<, 2A8-2/2, 240, 24/, A11, A12, A18 +an">&Car"sLayout..........................................1 +elpA'ti!ity....................................................284 +oney'omb+elper.........................................<03 +oriKontal%'roll-ie=.......................................118 +ttpClient.......................<82, <8<, <8/, <84, A00 +ttpConte;t....................................................<84 +ttp8et....................................<82, <8<, A1/, A28 +ttp#ost..........................................................<82 +ttp eRuest....................................................<82 +ttp esponse..................................................<82 +ttp$rlConne'tion........................................A00 0'oni'A"apter............................................1A<, 1AA 0mage1utton.................................81, 82, .0<, ..3 0mage%=it'her.................................................138 0mage-ie=. 81, 82, 1AA, 1A8, 1/1, 1/2, 1/<, 13<, .0< 0ME@emo1........................................................124 0ME@emo2.......................................................124 0n&lation@emo................................................../3
0nputMetho"Manager.............................128, .4A 0nput%tream...............................<1., <1/, <14, <8A 0nput%tream ea"er.........................................<14 0nteger..............................................................1/4 0ntent.....<, 143, 20<, 2<0, 2<1, 243, 281, 28., 284, 231-23., .3A, <0A, <A1, A00, A0/-A08, A10, A11, A1/-A18, A20, A22, A.3, A//, A/4, A88, A31 0ntent%er!i'e...............A0<, A1<, A1/, A14, A13, A20 0nterpreter.......................................................<4< 0temiKe">!erlay...............................A4/-A48, A8. C1utton........................................................./4, /8 CChe'k1o;.........................................................1.2 CCombo1o;.......................................................1.4 CLabel................................................................1.2 CList...................................................................1.2 C5abbe"#ane....................................................180 C5able................................................................1.2 Layout0n&later............................1A4, 1A8, 18/, .8. LinearLayout....3.-38, 100, 102, 10., 103, 11., 1A2, 1A8, 1/4, 181, 13<, 2<8, 2A0, .2., .4<, .44, .32 List.............................................................21., A/. ListA'ti!ity. . .1..-1.A, 181, 214, 2/A, .<0, .8., .83, .34, A42 ListA"apter........................................1/1, 134, .8. ListCell en"erer..............................................1.2 List*ragment.....................43, .8., .8/, .83, <0A List#re&eren'e.................................................<<. List-ie=.....118, 123, 1.., 1.A-1.8, 1<3, 1A1-1A<, 1A/, 1A3, 1/1, 1/., 1/<, 21., 21A, 218, ..3-.<1, .48, .8., .8/, </A, <//, <8., A42 Lo'ation.....................<8., A2., A2A, A23, A/.-A/A Lo'ationListener.....................................A/<, A/A Lo'ationManager.....................A/2-A/<, A//, /4A
287
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
9ey)ord ndex
Lo'ation#ro!i"er.............................A/2-A/<, /03 Map...........................................................<.1, </2 MapA'ti!ity.......................A/3, A42-A4<, A82-A8< MapController.........................................A4<, A4A Map*ragment..........................................A8., A8< Map-ie=. .<88, A/3, A41, A42, A4<, A4/, A43, A80, A82-A8A Me"ia#layer.....................................................A20
>n5imeChange"Listener................................142 >n5ime%etListener..................................142, 14< >utput%tream..................................................<14 >utput%treamWriter.......................................<14 >!erlay.....................................................A4/, A48 >!erlay0tem.............................................A4/-A43 #a'kageManager...................................../4., /4< #ar'elable..........................................................A11
Menu...........................................210, 211, 220-222 #en"ing0ntent....A11, A.3, A<2, A<3, AA0, A/A, A// Menu0n&later.............................................221, 222 #layer%er!i'e..............................A13-A21, A</, A<4 Menu0tem..............211, 212, 21/, 218, 220, 221, .4. #layingCar"Layout.............................................1 Message.......................2A8, 2A3, 2/1, 2/2, A11, A14 #re&eren'e.................................................<.<, <A1 Messenger....................................A11, A1<, A14, A18 MultiAutoComplete5e;t-ie=.........................138 MyLo'ation>!erlay.................................A4., A43 2oo?a=k.............A4., A4/, A44, A43-A81, A8<, A8A 2otAll5hat%tri't.....................................<2/, <28 2oti&i'ation........2.2, A.8-A<0, A<2, A<A-A<8, AA0 2oti&i'ationManager.......................A.8, A<., A</ 2oti&y@emo.....................................................A<0 2oti&yMessage.................................................A<2 2o=..............................................................4A, 4/ 2o= e"u;.........................................................4A >bGe't..............................................................2<A >nChe'ke"ChangeListener................8A, 8/, 100 >nCli'kListener................................../4, /8, 228 >n@ateChange"Listener.................................142 >n@ate%etListener...................................142, 14< >nE"itorA'tionListener..................4<, .4A, <08 >n0tem%ele'te"Listener.................................1.3 #re&eren'eA'ti!ity...88, <.2, <.., <.4, <<0, <</<<3, <A2, <A. #re&eren'eCategory................................<.3, <<0 #re&eren'e*ragment.........................88, <<8-<A0 #re&eren'eManager.........................................<.2 #re&eren'e%'reen.....<.<, <.3, <<0, <</, <<4, <A1 #rogress1ar. .141, 2A4, 2A3-2/1, 2/A, 2/3-241, 24A, 24/, .13, .2<-.2/, <3A #rogress@ialog.................................................2A4 Jui'kConta't1a"ge........................................138 a"io1utton...............88, 30, 31, 3., 38, 100, .8/ a"io8roup...............................88, 30, 3., 38-101 an"omA''ess*ile..........................................<28 atingA"apter..................................................1/4 ating1ar....................................1/<, 1/4, 1/8, 143 elati!eLayout 3., 10<, 10A, 104-110, 11<, 13<, ..0, ..1, .44 emote>bGe'tE;'eption.................................A14 esour'es...........................................0A, <1., <A0
288
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
9ey)ord ndex
%tri't*or ealK..........................................<2/-<28 %tri'tMo"e........................................<2.-<24, A00 %tri'tWrapper..........................................<2/-<28 %tring. .1/4, 21A, 22/, 224, 2/4, 288, .00, .02, <.1, <A0, <82, A1/, A.. %ystem.%ettings..................................................2
unnable..................................2A8, 2/2, 2/<, 2/A 5abA'ti!ity..................................181, 182, 231, 23. %'roll-ie=...............................3., 11A-118, 124, 128 5ab+ost..............180-18., 23., 23<, ..3, .<0, .80 %e'urityE;'eption............................................AA. 5ab+ost.5abContent*a'tory...................18<, 18/ %eek1ar.............................................................148 5ab+ost.5ab%pe'.............................................18/ %ensorManager................................................<AA 5ableLayout..............3., 111-11<, 122, 124, .48, <.4 %er!i'e...............................A0<, A0A, A13, A20, A</ 5able o=......................................................111-11. %er!i'eConne'tion...................A08, A03, A2<, A.2 5ab%pe'.....................................................182, 18. %hare"#re&eren'es...................<28, <.2, <.., <<. 5ab-ie=.....................................................131, 232 %impleCursorA"apter.....................................</A 5abWi"get....................180, 181, 18<, 188, 131, ./. %imple#re&s@emo....................................<.A, <.4 5elephonyManager.........................................A88 %ites>!erlay.............................................A4/-A48 5e;t%=it'her....................................................138 %li"ing@ra=er............................................13.-134 %o&t e&eren'e...................................................A10 %panne"............................................................00 %pinner 1.4, 1.8, 1<A, 1<3, 1A<, ./., ./8, .80, /<0, /<A %JLite@atabase...............................<A8, </0-</2 %JLite@atabase.Cursor*a'tory......................</4 %JLite>pen+elper.................................<A8, </0 %JLiteJuery1uil"er.......................................</. %ta'k>!er&lo=E;'eption................................<00 %tate..........................................................A.2-A.< %tati'.................................................................0/ %tati'@emo.......................................................1AA %to'k#re&eren'e*ragment.......................<<3-<A1 5e;t-ie=......4<, 43-81, 8., 8A, 88, 31, 32, 34, 108, 12/, 1.., 1A., 1AA, 1A8, 1/2, 1/<, 1/4, 14<, 183-131, 134, 203, 2AA, 240, 241, .1/, .42, A3/, A38 5e;tWat'her..............................................1<A, 1<4 5hrea"..............................................................2A/ 5ime#i'ker.................................................141, 142 5ime#i'ker@ialog...............................141, 142, 14< 5oast22A, 22/, 228, 2/3, ./3, <4/, <8<, <3/, <34, A00, A18, A43 5oggle1utton...................................................138 toolsP..................................................................1/ 5ype&a'e...........................................................A3/ $ri......2<0, 2<1, 2<., 2<4, 248, 243, 281, 28A, 284, 283, 232, <0A, <0/, <32, A.8, A88 -eri&yError.......................................<0<, <08, <24
28:
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
9ey)ord ndex
-ie=. . .41, 4A, 81, 30, 11., 114, 1.3, 1A1, 1A<-1A3, 1/11/., 1/8, 18<, 18/, 188, 212, 218, 213, 22/, 2/2, 232, .81, .82, <04-<03, <//, /0. -ie=.>nCli'kListener.......................................81 -ie=Animator.................................................183 -ie=*lipper..........................188, 183, 131-13., 138 -ie=8roup........................................................48 -ie=+ol"er.................................1/2-1/<, 1/4, 1/8 -ie=+ol"er@emo............................................1/. -ie=%=it'her...................................................138 -oi"..........................................................2/4-2/3 Weak e&eren'e................................................A10 Weather1in"er.........................A2<, A2A, A28, A23 Weather@emo.................................<8<, A23, A.A WeatherListener..............................A2<, A2A, A28 Weather%er!i'e........................................A2<, A28 WebDit.....................................................<8., <8< Web%ettings....................................................20/ Web-ie=.....133-20/, 232, .A1, .A., .48, .43, .81, .82, .88-.31, <88, A23, A.., A.<, AA2, //. Web-ie=Client.......................................20<, 20A Web-ie=*ragment..........................................88 Fml#ull#arser...........................................0A, .04
a"b shell...........................................</8, /08, /1/ a"b start-ser!er................................................/1/ an"roi"..........................................................3, A< an"roi" 'reate proGe't...................4, .8, 280, .01 an"roi" list targets..............................................1 an"roi" up"ate proGe't -p ..........................;;!iii ant.................................................................8, <0 ant -!ersion........................................................1/ ant 'lean install......................................../8, /<8 ant Gar'ore........................................................<4. ""ms................................................................/0< hierar'hy!ie=er......................................<00, A33 Garsigner............................................................A41 keytool..............................................................A41 p"&tk _.p"& 'at output 'ombine".p"&............;;i! sRlite...............................................................</8 su"o ser!i'e u"e! reloa"..................................2/ Kipalign..............................................................<0
Constant.........................................
ACCE%%]C>A %E]L>CA50>2.....................A/2 ACCE%%]*02E]L>CA50>2............................A/2 AC50>2]E@05................................................248 AC50>2]#0CD........................................248, 288 AC50>2]-0EW.......................................248, 284 AL5E 2A50-E................................................243 @E*A$L5.........................................................243 @ELE5E...................................................</2, </. E2@]@>C$ME25..........................................0A E2@]5A8.........................................................0A
Command......................................
a"b............................................................./1A, /1/ a"b "e!i'es.................................................2A, /1/ a"b install........................................................./1/ a"b kill-ser!er................................................../1/ a"b log'at........................................<38, /0/, /1/ a"b pull............................................</8, /04, /1/ a"b push..........................................</3, /04, /1/
2:<
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
9ey)ord ndex
02%E 5.............................................<A4, </2, </. a""%ubMenu()..................................................211 025E8E .........................................................<A4 a""5ab()....................................................18., 18/ LA 8E ...........................................................204 a""Wor"().................................................4<, .4A LA$2C+E ..............................................243, 281 a&ter5e;tChange"()..........................................1<4 LE285+]L>28.............................................22/ animateClose()................................................13/ LE285+]%+> 5...........................................22/ animate>pen()................................................13/ MA02................................................................281 animate5oggle()..............................................13/ 2$LL...............................................................</2 apply()..............................................................<.2 #E M0%%0>2]@E20E@..................................AAA apply*ormat()...................................................02 #E M0%%0>2]8 A25E@...............................AAA atta'h()............................................................24< #>%5................................................................<82 be&ore5e;tChange"().......................................1<4 ......................................................................... 4A bin"%er!i'e().............................A0A, A08, A03, A11 E%$L5]CA2CELE@.....................................288 bin"-ie=()......................................................<// E%$L5]*0 %5]$%E ....................................288 boun"Center1ottom()....................................A44 E%$L5]>D....................................................288 buil"*ore'asts()..............................................<8< %ELEC5....................................................<A4, </. 'an'el()............................................................A.8 %MALLE%5.......................................................204 'an'elAll().......................................................A.8 %5A 5]5A8..............................................0A, .04 'an8o1a'k()....................................................20. 5EF5.................................................................0A 'an8o1a'k>r*or=ar"().................................20< $#@A5E...................................................</2, </. 'an8o*or=ar"()..............................................20. -E 50CAL.........................................................3< 'he'k()........................................................88, 30 W+E E...................................................</., </< 'he'kCalling#ermission()...............................AAA ]i".....................................................................</1 'hoose@ate()....................................................14<
4ethod...........................................
a""().............................210, 211, 21/, 214, .4A, A4/ a""E!entListener()........................................./AA a""Menu()........................................................211
2:*
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
9ey)ord ndex
'lear+istory()..................................................20< 'lose()...............................13/, <14, <23, </0, </A 'ommit()..........................................................<.2 'reate().............................................................224 'reate@atabase().............................................</8 'reate*romAsset()..........................................A3/ 'reate*rom*ile().............................................A3/ 'reate0tem().....................................................A44 'reate#en"ing esult()......................................A11 'reate5abContent().........................................18< "elete()....................................................</2, </. "eta'h()...........................................................24< "o0n1a'kgroun"()....2/<, 2/A, 2/4-2/3, 24<, 24A "o5he@o=nloa"()...........................................A14 e"it()................................................................<.2 enable@e&aults().............................................<2< enable#ersistent%ele'tion().............................88 enRueue().................................................<31, <3. e;e'%JL()................................................</0-</. e;e'ute()..........................................2/., 2/3, <82 &in"*ragment1y0"().........................................3< &in"-ie=1y0"()....4A, 4/, 31, 1A3, 1/1-1/., 181, 18., .4., .4<, <1., A4< &inish().......................................................2.., 2<1
getA""A'tion-ie=()......................................<03 getAltitu"e()....................................................A/< getAppli'ationConte;t().........................A03, A2. getArguments()...............................................<A0 getAs0nteger().................................................</2 getAssets().......................................................A3/ getAs%tring()...................................................</2 getAttributeCount().........................................04 getAttribute2ame().........................................04 get1earing().....................................................A/< get1est#ro!i"er()............................................A/. get1oolean()....................................................<.2 get1roa"'ast(..................................................A/A get1roa"'ast().................................................A.3 getCall%tate()..................................................A88 getChe'ke"0tem#ositions().............................1.4 getChe'ke" a"io1utton0"()............................88 getColumn0n"e;()..........................................</A getColumn2ames()........................................</A getController()................................................A4< getCount().......................................................</A get@ata()...................................................2<1, A1/ get@e&ault%hare"#re&eren'es()..............<.2, <.. getE;ternal*iles@ir()......................................<22
&rom()................................................................8. getE;ternal%torage@ire'tory().......................<22 &syn'()......................................................<28, <23 getE;ternal%torage#ubli'@ire'tory()....<22, <32 generate#age()................................................<8A getE;ternal%torage%tate()..............................<22 get().................................................................</2 get*iles@ir().....................................................<21 getA'tion-ie=()...............................4., .4/, <08 get*ore'ast()............................................A2., A2A getA'ti!ity()..............................................8., A.3 get*ragmentManager()...................................3<
2:&
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
9ey)ord ndex
get0"enti&ier()...........................................<A0, <A1 get0nt()............................................................</A get0tem()........................................................../.. get0tem0"().......................................................21/ getLastDno=n#osition().................................A/. getLast2onCon&iguration0nstan'e().....2<4, 24<, A.< getLatitu"e()...................................................<8.
get%upport*ragmentManager()......................3< get%ystemA!ailable*eatures()......................../4< get%ystem%er!i'e()..................................<30, <31 get5ag()..............................................1/2-1/<, 1/4 get5e;t()...........................................................00 get-ie=().1A<, 1AA, 1A3-1/1, 1/., 1/4, .82, <A1, <// getWriteable@atabase().................................</0 getFml()............................................................0A
getLayout0n&later()...................................1A8, .8. go1a'k()...........................................................20. getList-ie=()....................................................1.A go1a'k>r*or=ar"()................................20., 20< getLongitu"e()................................................<8. go*or=ar"().....................................................20. getMeMyCurrentLo'ation2o=()...................A/< han"leError()..................................................A28 getMenu0n&o()...........................................212, 218 han"leMessage()..............................2A3, 2/0, A12 get2et=ork5ype()...........................................A88 hasAltitu"e()...................................................A/< get>!erlays()...................................................A4/ has1earing()....................................................A/< get#a'kage2ame()..........................................<A0 has%pee"().......................................................A/< get#arent().........................................................31 has%ystem*eature()........................................./4. get#hone5ype()...............................................A88 hi"e%o&t0nput*romWin"o=().........................123 get#re&eren'es().......................................<.1, <.2 in'rement#rogress1y()...................................2A4 get#rogress()............................................143, 2A4 init().........................................................<2/, <24 get#ro!i"ers()..................................................A/. initA"apter().............................................21A, 214 get ea"able@atabase()..................................</0 insert().....................................................</0, </2 get esour'es()..........................................<1., <A0 isA&terLast()....................................................</A get oot-ie=()....................................................31 isChe'ke"().................................................8A, 88 get%ettings()....................................................20/ isCon&igurationChanging................................A.A get%hare"#re&eren'es()...........................<.1, <.2 isEnable"().........................................................31 get%pee"().......................................................A/< is*inishing().....................................................A.< get%tring().......................................233, .02, </A is*o'use"().........................................................31 get%tringArray().................................................11 is oute@isplaye"()..................................A4., A4< get%ubs'riber0"()............................................A88 key()................................................................./..
2:Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
9ey)ord ndex
length()............................................................/.. loa"@ata()........................................................202 loa"+ea"ers*rom esour'e().................<<8, <<3 loa"5ime().......................................................20A loa"$rl()...................................200, 202, .82, /A2 lo'k()................................................................13/ make5e;t()......................................................22/ MenuBset8roupChe'kable()...........................211 Menu0temBsetChe'kable()..............................211 mk"irs()...........................................................<32 mo!e5o*irst()..................................................</A mo!e5o2e;t().................................................</A ne=Cursor()....................................................</4 ne=0nstan'e().................................................<84 ne=5ab%pe'()...........................................182, 18. ne=-ie=().......................................................<// ne;t().................................................................0A noti&y().....................................................A.8, A</ noti&yMe()........................................................A<2 obtainMessage()......................................2A8, 2A3 onA'ti!ityCreate"().........................8., .3/, A8< onA'ti!ity esult().....................2<1, 284, 288, A11 on1in"()...................................A0A, A08, A20, A23 onChe'ke"Change"()...............................8/, 100 onCli'k()..................................................../8, 2A/ onCon&igurationChange"().............2<4, 2A0, 2A1 onConte;t0tem%ele'te"()........................212, 222 onConte;tMenu%ele'te"()..............................218 onCountry%ele'te"()........................88, .3., .3A
onCreate()..../4, /8, 4<, 4A, 30, 33, 200, 210, 21A, 2.2-2.A, 2<., 2<<, 2A/, 24<, 24A, .02, .4., .80, .82, .8., .3<, .3/, <1/, <2<, <2/, <24, <.8, <<3, <A8, </0, </1, <8<, <31, A0A, A03, A1/, A14, A20, A22, A2A, A23, A.<, A<., A</, A8<, /<4, //A onCreateConte;tMenu()...................212, 214, 222 onCreate>ptionsMenu()...210, 211, 21A, 222, ./3, .4., .80, <04, <08 onCreate#anelMenu()......................................211 onCreate-ie=().................................81, .82, A8. on@estroy()......2.., .82, <8<, A0A, A03, A1/, A20, A2A, A23, A.< on@e!i'e ea"y()...................................../AA, /A/ on@o=ngra"e()...............................................</1 on+an"le0ntent().....................................A1/, A14 onList0temCli'k().....1.<, 1/4, 2A/, .8., .88, .3., .34, </A onLoa"()................................................../AA, /A/ onLoa"+ea"ers()............................................<<3 onLo'ationChange"().....................................A/A on>pen().........................................................</0 on>ptions0tem%ele'te"()...210, 211, 21., 21/, 222, ./3, .80 on#age%tarte"()..............................................20< on#ause()..................2.<, 28., .82, <13, A0A, A43 on#ostE;e'ute().......................2/A, 2/8, 24A, A28 on#reE;e'ute()................................................2/A on#repare>ptionsMenu()...............................210 on#rogress$p"ate()........................2/A, 2/4, 2/8 on atingChange"().........................................1/4 on e'ei!e()......................................................282 on e'ei!e"+ttpAuth eRuest().....................20< on estart().......................................................2.. on estore0nstan'e%tate().......................2.A, .3/
2:%
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
9ey)ord ndex
on esume()......2.., 2.<, 282, .82, <13, <.8, <8., A0A, A43 on etain2onCon&iguration0nstan'e(). .2<4, 2A., 24<, 24A, .3/, .34, A03, A2., A2<, A.., A.A on%a!e0nstan'e%tate().....2.., 2.A, 2<2, 2<., 2A., .3/ on%er!i'eConne'te"()....................................A08 on%er!i'e@is'onne'te"()...............................A03 on%tart()............................................2.., 2/1, .82 on%tartComman"().........................A0A, A04, A20 on%top()............................................2.., 2/1, .82 on5ap()............................................................A48 on5e;tChange"().............................................1<4 on5ooMany e"ire'ts()...................................20< on$pgra"e()....................................<A8, </0, </1 open()...............................................................13/ open*ile0nput().................................<14, <13, <21 open*ile>uptut()............................................<21 open*ile>utput()..............................<14, <13, <21 open a= esour'e().........................................<1. play()........................................................A20, A<4 populate()........................................................A44 post()................................................................2/2 post@elaye"()..................................................2/2 publish#rogress()............................2/A, 2/4, 2/8 Ruery().....................................</., </<, <32, <3. RueryWith*a'tory()........................................</4 ra=Juery()......................................................</. ra=JueryWith*a'tory().................................</4 register*orConte;tMenu()..............................212 register e'ei!er().....................................282, A10
reloa"()............................................................20. remo!e()..........................................................<.2 remo!e0tem().................................................../.. remo!e#ro;imityAlert().................................A// remo!e$p"ates()............................................A/A reRuery()..........................................................</A reRuest*o'us()...................................................31 reRuestLo'ation$p"ates()......................A/<, A/A restoreMe()......................................2<., 2<<, 2<4 run>n$i5hrea"()...........................................2/2 sen"()................................................................A11 sen"1roa"'ast().......................................A10, AAA sen"EmptyMessage()......................................2A3 sen"Message().................................................2A8 sen"MessageAt*ront>&Jueue()....................2A8 sen"MessageAt5ime()....................................2A8 sen"Message@elaye"()...................................2A3 set()..................................................................<4/ setA''ura'y()...................................................A/. setA"apter().................................1.., 1.8, 1<1, 1<A setAllo=e"2et=ork5ypes()............................<32 setAllo=e">!er oaming()............................<32 setAlphabeti'%hort'ut()...................................211 setAltitu"e eRuire"().....................................A/. setCell en"erer().............................................1.2 setCenter().......................................................A4A setChe'ke"()...............................................8A, 30 setChoi'eMo"e()..............................................1.A setColumnCollapse"().....................................11< setColumn%hrinkable()....................................11<
2:0
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
9ey)ord ndex
setColumn%tret'hable()...................................11< setContent()..............................................182-18< setContent-ie=().................../4, 4A, 31, .3<, /<4 setCostAllo=e"().............................................A/. setCurrent5ab()...............................................18. set@e&ault*ont%iKe().......................................204 set@es'ription()..............................................<32 set@estination0nE;ternal#ubli'@ir()............<32 set@rop@o=n-ie= esour'e()........................1.8 set@uration()...................................................22/ setEnable"()................................................31, 221 set*antasy*ont*amily()..................................20/ set*oregroun"()..............................................A</ set8ra!ity().......................................................3/ set8roupChe'kable()......................................210 set8roupEnable"()..........................................221 set8roup-isible().............................................221 set+as>ptionsMenu().....................................80 set0'on()...........................................................224 set0n"eterminate()..........................................2A4 set0n"i'ator()............................................182, 18. set0tem()........................................................../.. set0temChe'ke"().............................................1.4 setCa!a%'riptCan>penWin"o=sAutomati'ally( )........................................................................ 204 setCa!a%'riptEnable"()....................................204
set2egati!e1utton()........................................224 set2eutral1utton()..........................................224 set2umeri'%hort'ut()......................................211 set>nCli'kListener()......................................../4 set>nE"itorA'tionListener()..................12/, .4< set>n0tem%ele'te"Listener().............1.., 1.8, 1<1 set>n%eek1arChangeListener().....................143 set>rientation()................................................3< set#a""ing()......................................................30 set#ositi!e1utton().........................................224 set#rogress()....................................................2A4 setJ=ertyMo"e().............................................211 set esult().................................................288, A11 set5ag()...............................................1/2-1/<, 1/4 set5e;t()...................................................../8, 2AA set5e;tColor()....................................................31 set5e;t%iKe()....................................................204 set5itle()..................................................224, <32 set5ype&a'e().............................................42, A3/ setup()........................................................181-18. set$serAgent()................................................204 set-ie=()..........................................................22/ set-isible().......................................................221 set-isible0n@o=nloa"s$i()............................A00 setWeb-ie=Client().......................................20< setQoom()........................................................A4A
setLatestE!ent0n&o()................................A.3, A<2 shoul">!erri"e$rlLoa"ing().................20<, 20A setListA"apter().......................................1.<, .8. sho=().......................................................22/-228 setMa;().............................................143, 2A4, 2/1 sho=Me()........................................................283 setMessage()....................................................224 sho=2e;t()......................................................183
2:2
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
9ey)ord ndex
siKe().................................................................A44 start()................................................................144 startA'ti!ity()...2<0, 2<1, 284, .34, <A1, A0/, A88, A31 startA'ti!ity*or esult()....2<0-2<2, 284, 288, A11
start@o=nloa"()..............................................<31 an"roi",horiKontal%pa'ing..............................1<1 start*oregroun"()............................A20, A</, A<4 an"roi",i".........................4., 4<, 88, 10A, 181, 182 start#layer().....................................................A22 an"roi",label.....................................................<2 start%er!i'e() A0A-A08, A11, A1<, A1/, A14, A13, A20, A22 stop().................................................144, A20, A<4 stop*oregroun"()....................................A</-A<8 stop#layer().....................................................A22 stop%el&().........................................................A08 stop%er!i'e()....................................A04, A03, A22 s=it'h().............................................................211 toggle().................................................8A, 88, 13/ toggle%atellite()...............................................A80 to%tring()..........................................................1.2 unbin"%er!i'e()......................................A08, A03 unlo'k()............................................................13/ unregister e'ei!er().......................................28. up"ate()...................................................</2, </. up"ate*ore'ast().....................................<8., A28 up"ateLabel()...................................................14< up"ate5ime()............................................../4, /8 !alue>&()...........................................................32 an"roi",layout]abo!e......................................10/ an"roi",layout]align1aseline.........................104 an"roi",layout]align1ottom..........................10/ an"roi",layout]alignLe&t................................10/ an"roi",layout]align#arent1ottom................10A an"roi",layout]align#arentLe&t......................10A an"roi",layout]align#arent ight...................10A an"roi",layout]align#arent5op......................10A an"roi",layout]align ight..............................104 an"roi",layout]align5op..........................10/, 104 an"roi",layout]belo=.....................................10/ an"roi",layout]'enter+oriKontal...................10A an"roi",layout]'enter0n#arent......................10A an"roi",layout]'enter-erti'al........................10A an"roi",layout]'olumn....................................112 an"roi",layout]gra!ity.....................................3/ an"roi",layout]height................................4., 3A an"roi",layout]span.........................................112 an"roi",layout]toLe&t>&.................................10/
Property.........................................
an"roi",auto5e;t...............................................8. an"roi",'apitaliKe.............................................8.
2:7
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
9ey)ord ndex
an"roi",mani&est...............................................<1 an"roi",name.....................................<2, A0A, AA2 an"roi",ne;t*o'us@o=n..................................30 an"roi",ne;t*o'usLe&t.....................................30 an"roi",ne;t*o'us ight...................................30 an"roi",ne;t*o'us$p.......................................30 an"roi",numColumns......................................1<1 an"roi",orientation..........................................3< an"roi",permission.................................A0/, AA< an"roi",shrinkColumns...................................11< an"roi",singleLine............................................8.
an"roi",spa'ing...............................................1<3 an"roi",spinner%ele'tor..................................1<3 an"roi",sr'........................................................82 an"roi",stret'hColumns..................................11. an"roi",stret'hMo"e.......................................1<1 an"roi",te;t.................................................4., 43 an"roi",te;tColor.......................................80, 8A an"roi",te;t%tyle.........................................43, 8. an"roi",type&a'e...............................................43 an"roi",!erti'al%pa'ing...................................1<1 an"roi",!isibility...............................................30
2:8
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition