Professional Documents
Culture Documents
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, -o! 2011,.ersion /.0 1%2-, 308-0-3814080-0-3
5he CommonsWare name an" logo, 62usy 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 2ook:..............................................................................;;! Wares'ription............................................................................................;;! 8etting +elp.............................................................................................;;!i 2ook 2ug 2ounty....................................................................................;;!ii %our'e Co"e An" 1ts Li'ense................................................................;;!iii 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..................................................................................< 1ntents.....................................................................................................< %tu&& At ?our @isposal..................................................................................A %torage.....................................................................................................A -et=ork...................................................................................................A Multime"ia.............................................................................................A
iii
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
8#%..........................................................................................................A #hone %er!i'es........................................................................................4 5he 2ig #i'ture...>& 5his 2ook....................................................................4 "o# To Get $tarted.................................................................................% +ar"=are eBuirements..............................................................................0 Ca!a.................................................................................................................8 1nstall the C@D........................................................................................8 Learn Ca!a...............................................................................................3 1nstall the An"roi" %@D...............................................................................3 1nstall the 2ase 5ools............................................................................10 1nstall the %@Ds an" A""->ns.............................................................10 1nstall the A@5 &or E'lipse..........................................................................11 1nstall Apa'he Ant.......................................................................................1/ %et $p the Emulator....................................................................................1< %et $p the @e!i'e........................................................................................21 Win"o=s...............................................................................................22 >% F an" Linu;.....................................................................................2/ &our 'irst Android Pro(ect....................................................................)* %tep G1, Create the -e= #roHe't.................................................................2A E'lipse...................................................................................................2A Comman" Line...................................................................................../0 %tep G2, 2uil", 1nstall, an" un the Appli'ation in ?our Emulator or @e!i'e.........................................................................................................../1 E'lipse..................................................................................................../1 Comman" Line...................................................................................../2 +xaminin &our 'irst Pro(ect................................................................,% #roHe't %tru'ture........................................................................................./0
iv
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
oot Contents......................................................................................./0 5he %=eat >&& ?our 2ro=..................................................................../8 An" -o=, 5he est o& the %tory........................................................../3 What ?ou 8et >ut >& 1t......................................................................<0 1nsi"e ?our Mani&est..................................................................................<0 1n 5he 2eginning, 5here Was the oot, An" 1t 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....................................................................................<4 +o= to 1mport a -on-E'lipse #roHe't................................................<4 +o= to 8et 5o @@M%..........................................................................A0 +o= to Create an Emulator.................................................................A2 +o= to un a #roHe't...........................................................................A/ +o= -ot to un ?our #roHe't.............................................................A< Alternati!e 1@Es..........................................................................................AA More on the 5ools.......................................................................................AA 1@Es...An" 5his 2ook.................................................................................A4 +nhancin &our 'irst Pro(ect................................................................*% %upporting Multiple %'reens.....................................................................A0 %pe'i&ying .ersions....................................................................................A8 /e#ritin &our 'irst Pro(ect.................................................................0, 5he A'ti!ity.................................................................................................4/ @isse'ting the A'ti!ity...............................................................................4< 2uil"ing an" unning the A'ti!ity...........................................................44 About the emaining E;amples................................................................40
v
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
1sin 2345Based 4ayouts....................................................................06 What 1s an FML-2ase" LayoutI................................................................43 Why $se FML-2ase" LayoutsI.................................................................00 >D, %o What @oes 1t Look LikeI...............................................................01 What7s With the J %ignsI..........................................................................02 An" We Atta'h 5hese to the Ca!a...+o=I.................................................02 5he est o& the %tory..................................................................................0/ +mployin Basic Wid ets......................................................................%% Assigning Labels.........................................................................................00 2utton, 2utton, Who7s 8ot the 2uttonI...................................................08 *leeting 1mages...........................................................................................03 *iel"s o& 8reen. >r >ther Colors...............................................................81 Cust Another 2o; to Che'k.........................................................................8/ @on7t Like Che'kbo;esI +o= About 5ogglesI........................................84 5urn the a"io $p......................................................................................80 1t7s Kuite a .ie=.........................................................................................30 #a""ing.................................................................................................30 >ther $se&ul #roperties......................................................................30 $se&ul Metho"s.....................................................................................31 Colors.....................................................................................................31 Wor7in #ith Containers......................................................................6, 5hinking Linearly.......................................................................................3< Con'epts an" #roperties.....................................................................3< E;ample................................................................................................33 5he 2o; Mo"el....................................................................................10< All 5hings Are elati!e.............................................................................104 Con'epts an" #roperties....................................................................104
vi
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
E;ample...............................................................................................103 >!erlap..................................................................................................111 5abula asa.................................................................................................11/ Con'epts an" #roperties.....................................................................11< E;ample................................................................................................114 %'roll=ork...................................................................................................110 The 8nput 3ethod 'rame#or7.............................................................!)! Deyboar"s, +ar" an" %o&t..........................................................................121 5ailore" 5o ?our -ee"s............................................................................122 5ell An"roi" Where 1t Can 8o.................................................................124 *itting 1n....................................................................................................123 Cane, %top 5his CraLy 5hing:....................................................................1/0 1sin $election Wid ets......................................................................!,, Cli'ks !ersus %ele'tions.............................................................................1// A"apting to the Cir'umstan'es................................................................1/< $sing ArrayA"apter............................................................................1/A Lists o& -aughty an" -i'e.........................................................................1/4 %ele'tion Mo"es..................................................................................1/8 Cli'ks !ersus %ele'tions, e!isite"....................................................1<0 %pin Control...............................................................................................1<1 8ri" ?our Lions (>r %omething Like 5hat...).........................................1<< *iel"s, -o= With /AM Less 5yping:........................................................1<8 8alleries, 8i!e >r 5ake 5he Art...............................................................1A2 Gettin 'ancy With 4ists......................................................................!** 8etting 5o *irst 2ase.................................................................................1AA A @ynami' #resentation...........................................................................1A8 1n&lating o=s >ursel!es..........................................................................140
vii
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
A %i"ebar About 1n&lation..................................................................140 An" -o=, 2a'k 5o >ur %tory............................................................142 2etter. %tronger. *aster.............................................................................14/ $sing 'on!ert.ie=..............................................................................14/ $sing the +ol"er #attern...................................................................14A 1ntera'ti!e o=s........................................................................................140 $till 3ore Wid ets and Containers.....................................................!%* #i'k an" Choose........................................................................................10A 5ime Deeps *lo=ing Like a i!er.............................................................180 %eeking esolution....................................................................................182 #utting 1t >n My 5ab................................................................................18/ 5he #ie'es............................................................................................18< Wiring 1t 5ogether..............................................................................18A A""ing 5hem $p................................................................................188 *lipping 5hem >&&.....................................................................................13< 8etting 1n %omebo"y7s @ra=er...............................................................200 >ther 8oo" %tu&&......................................................................................20< +m-eddin the We-9it Bro#ser........................................................):% A 2ro=ser, Writ %mall..............................................................................200 Loa"ing 1t $p.............................................................................................210 -a!igating the Waters...............................................................................211 Entertaining the Client.............................................................................212 %ettings, #re&eren'es, an" >ptions (>h, My:)........................................21< Applyin 3enus....................................................................................)!% *la!ors o& Menu.........................................................................................210 Menus o& >ptions......................................................................................218 Menus in Conte;t.....................................................................................220
viii
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
5aking a #eek.............................................................................................221 ?et More 1n&lation....................................................................................224 Menu FML %tru'ture.........................................................................220 Menu >ptions an" FML....................................................................228 1n&lating the Menu.............................................................................223 1n the Lan" o& Menus an" +oney............................................................2/1 $ho#in Pop51p 3essa es..................................................................),, aising 5oasts............................................................................................2// Alert: Alert:................................................................................................2/< Che'king 5hem >ut.................................................................................2/A "andlin Activity 4ifecycle +vents.....................................................),6 %'hroe"inger7s A'ti!ity.............................................................................2/3 Li&e, @eath, an" ?our A'ti!ity.................................................................2<0 onCreate() an" on@estroy()..............................................................2<0 on%tart(), on estart(), an" on%top().................................................2<1 on#ause() an" on esume()...............................................................2<2 5he 8ra'e o& %tate.....................................................................................2<2 When A'ti!ities @ie.................................................................................2<< "andlin /otation...............................................................................).* A #hilosophy o& @estru'tion....................................................................2<A 1t7s All 5he %ame, Cust @i&&erent..............................................................2<4 #i'king an" .ie=ing a Conta't.........................................................2<8 %a!ing ?our %tate...............................................................................2A0 -o= With More %a!ings:.........................................................................2A/ @1? otation..............................................................................................2AA ...2ut 8oogle @oes -ot e'ommen" 5his........................................2A3 *or'ing the 1ssue.......................................................................................2A3
ix
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
Making %ense o& it All...............................................................................242 Dealin #ith Threads..........................................................................)0* 5he Main Appli'ation 5hrea".................................................................24A Making #rogress =ith #rogress2ars........................................................240 8etting 5hrough the +an"lers................................................................248 Messages.............................................................................................248 unnables............................................................................................202 Where, >h Where +as My $1 5hrea" 8oneI........................................20/ Asyn'ing *eeling.......................................................................................20/ 5he 5heory..........................................................................................20/ Asyn'5ask, 8eneri's, an" .arargs....................................................20< 5he %tages o& Asyn'5ask....................................................................20A A %ample 5ask....................................................................................204 5hrea"s an" otation...............................................................................281 Manual A'ti!ity Asso'iation.............................................................282 *lo= o& E!ents....................................................................................28< Why 5his Works................................................................................28A An" -o=, 5he Ca!eats.............................................................................284 8ntents and 'ilters...............................................................................);6 What7s ?our 1ntentI.................................................................................230 #ie'es o& 1ntents.................................................................................230 1ntent outing.....................................................................................231 %tating ?our 1ntent(ions).........................................................................232 -arro= e'ei!ers......................................................................................23< 5he #ause Ca!eat......................................................................................23A 4aunchin Activities............................................................................)6% #eers an" %ubs..........................................................................................238
x
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
%tart 7Em $p..............................................................................................238 Make an 1ntent...................................................................................238 Make the Call.....................................................................................233 5abbe" 2ro=sing, %ort >&......................................................................../0/ Wor7in #ith /esources.....................................................................,:6 5he esour'e Lineup................................................................................/03 %tring 5heory............................................................................................./10 #lain %trings........................................................................................./10 %tring *ormats....................................................................................../11 %tyle" 5e;t.........................................................................................../12 %tyle" 5e;t an" *ormats...................................................................../12 8ot the #i'tureI........................................................................................./14 FML, 5he esour'e Way........................................................................../18 Mis'ellaneous .alues................................................................................/21 @imensions........................................................................................../21 Colors.................................................................................................../22 Arrays.................................................................................................../2/ @i&&erent %trokes &or @i&&erent *olks......................................................./2< 5L Languages, 8oing 2oth Ways........................................................../23 Definin and 1sin $tyles....................................................................,,! %tyles, @1? @ ?..........................................................................................//1 Elements o& %tyle......................................................................................./// Where to Apply a %tyle......................................................................//< 5he A!ailable Attributes....................................................................//A 1nheriting a %tyle................................................................................//A 5he #ossible .alues............................................................................//4 5hemes, Woul" a %tyle 2y Any >ther -ame..........................................//0
xi
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
"andlin 3ultiple $creen $i<es..........................................................,,6 5aking the @e&ault..................................................................................../<0 Whole in >ne............................................................................................/<1 @on7t 5hink About #ositions, 5hink About ules.........................../<2 Consi"er #hysi'al @imensions........................................................../</ A!oi" N ealN #i;els............................................................................../</ Choose %'alable @ra=ables.............................................................../<< 5ailor Ma"e, Cust *or ?ou (An" ?ou, An" ?ou, An"...)......................../<< Osupports-s'reensP............................................................................/<A esour'es an" esour'e %ets............................................................/<4 *in"ing ?our %iLe.............................................................................../<0 Ain7t -othing Like the eal 5hing........................................................../<8 @ensity @i&&ers..................................................................................../<8 A"Husting the @ensity......................................................................../<3 uthlessly E;ploiting the %ituation........................................................./A0 epla'e Menus =ith 2uttons............................................................../A1 epla'e 5abs =ith a %imple A'ti!ity................................................../A1 Consoli"ate Multiple A'ti!ities........................................................./A2 E;ample, E$<?ou...................................................................................../A2 5he *irst Cut......................................................................................./A/ *i;ing the *onts................................................................................../40 *i;ing the 1'ons................................................................................../4/ $sing the %pa'e................................................................................../4/ What 1& 1t 1s -ot a 2ro=serI............................................................../44 8ntroducin the "oneycom-5$tyle 18................................................,06 Why +oney'ombI..................................................................................../43 What the $ser %ees.................................................................................../00
xii
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
5he +olographi' 5heme........................................................................../0A %tan"ar" 5hemes !ersus @e&ault 5hemes......................................../04 @ealing =ith the est o& the @e!i'es....................................................../00 1sin the Action Bar............................................................................,%6 Enabling the A'tion 2ar.........................................................................../03 #romoting Menu 1tems to the A'tion 2ar............................................../80 espon"ing to the Logo............................................................................/81 A""ing Custom .ie=s to the A'tion 2ar................................................/82 @e&ining the Layout.........................................................................../8/ #utting the Layout in the NMenuN...................................................../8< 8etting Control o& $ser 1nput.........................................................../8A @on7t *orget the #hones:........................................................................./80 #re-+oney'omb @e!i'es.................................................................../88 1'e Cream %an"=i'h an" 2eyon"...................................................../83 'ra ments.............................................................................................,6, 1ntro"u'ing *ragments............................................................................./3/ 5he #roblem......................................................................................./3< 5he *ragments %olution..................................................................../3< 5he An"roi" %upport #a'kage........................................................../34 Creating *ragment Classes......................................................................./30 8eneral *ragments............................................................................./30 List*ragment....................................................................................../33 >ther *ragment 2ase Classes...........................................................<0< *ragments, Layouts, A'ti!ities, an" Multiple %'reen %iLes...................<0A E$<?ou...............................................................................................<04 @etailsA'ti!ity......................................................................................<11 *ragments an" Con&iguration Changes...................................................<12
xiii
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
@esigning &or *ragments..........................................................................<1/ "andlin Platform Chan es.................................................................!* 5hings 5hat Make ?ou 8o N2oomN..........................................................<1A .ie= +ierar'hy...................................................................................<14 Changing esour'es...........................................................................<14 +an"ling A#1 Changes..............................................................................<10 Minimum, Ma;imum, 5arget, an" 2uil" .ersions..........................<10 @ete'ting the .ersion........................................................................<20 Wrapping the A#1..............................................................................<20 #atterns &or the +oney'omb $1..............................................................<2/ 5he A'tion 2ar....................................................................................<2/ Writing 5ablet->nly Apps................................................................<24 Accessin 'iles.......................................................................................,! ?ou An" 5he +orse ?ou o"e 1n >n.......................................................</1 ea"in7 7n Writin7......................................................................................</A E;ternal %torage, 8iant E'onomy-%iLe %pa'e........................................</3 Where to Write..................................................................................<<0 When to Write...................................................................................<<0 %tri'tMo"e, A!oi"ing Canky Co"e............................................................<<1 %etting up %tri't Mo"e.......................................................................<<2 %eeing 1t 1n A'tion.............................................................................<<2 @e!elopment >nly, #lease:...............................................................<</ Con"itionally 2eing %tri't.................................................................<<< Linu; *ilesystems, ?ou %yn', ?ou Win..................................................<<4 1sin Preferences..................................................................................6 8etting What ?ou Want..........................................................................<<3 %tating ?our #re&eren'e...........................................................................<A0
xiv
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
1ntro"u'ing #re&eren'eA'ti!ity................................................................<A1 Letting $sers +a!e 5heir %ay..................................................................<A2 A""ing a Wee 2it >7 %tru'ture................................................................<A0 5he Din" >& #op-$ps ?ou Like...............................................................<40 #re&eren'es !ia *ragments.......................................................................<4< 5he +oney'omb Way........................................................................<4A A""ing 2a'k=ar"s Compatibility.....................................................<00 3ana in and Accessin 4ocal Data-ases...........................................%, A Kui'k %KLite #rimer............................................................................<0A %tart at the 2eginning...............................................................................<0A %etting the 5able......................................................................................<03 Makin7 @ata...............................................................................................<03 What 8oes Aroun", Comes Aroun"........................................................<81 a= Kueries........................................................................................<81 egular Kueries..................................................................................<82 $sing Cursors.....................................................................................<8/ Custom CursorA"apters....................................................................<8< Making ?our >=n Cursors................................................................<8A *lash, %oun"s *aster 5han 1t 1s...............................................................<8A @ata, @ata, E!ery=here...........................................................................<84 4evera in =ava 4i-raries.....................................................................;6 Ants an" Cars.............................................................................................<83 5he >uter Limits......................................................................................<30 *ollo=ing the %'ript..................................................................................<31 e!ie=ing the %'ript................................................................................<34 Communicatin via the 8nternet.........................................................66 ?our +55# A#1 Choi'es..........................................................................<33
xv
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
E%5 an" ela;ation................................................................................A00 +55# >perations !ia Apa'he +ttpClient.........................................A01 #arsing esponses..............................................................................A0/ %tu&& 5o Consi"er................................................................................A0A An"roi"+ttpClient.............................................................................A04 Le!eraging 1nternet-A=are An"roi" Components................................A00 @o=nloa"ing *iles..............................................................................A00 Continuing >ur Es'ape *rom Canky Co"e..............................................A13 Making etro A#1s *eel -e= Again.........................................................A13 $ervices> The Theory............................................................................*), Why %er!i'esI............................................................................................A2/ %etting $p a %er!i'e..................................................................................A2< 5he %er!i'e Class................................................................................A2< Li&e'y'le Metho"s...............................................................................A2A Mani&est Entry....................................................................................A2A Communi'ating 5o %er!i'es....................................................................A24 %en"ing Comman"s =ith start%er!i'e()...........................................A24 2in"ing =ith bin"%er!i'e()................................................................A28 Communi'ating *rom %er!i'es...............................................................A23 Callba'kQListener >bHe'ts.................................................................A/0 2roa"'ast 1ntents................................................................................A/0 #en"ing esults...................................................................................A/1 Messenger............................................................................................A/1 -oti&i'ations........................................................................................A/2 Basic $ervice Patterns..........................................................................*,, 5he @o=nloa"er........................................................................................A// 5he @esign..........................................................................................A/<
xvi
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
5he %er!i'e 1mplementation.............................................................A/< $sing the %er!i'e................................................................................A/0 5he Musi' #layer......................................................................................A/8 5he @esign..........................................................................................A/3 5he %er!i'e 1mplementation.............................................................A/3 $sing the %er!i'e.................................................................................A<1 5he Web %er!i'e 1nter&a'e.......................................................................A<2 5he @esign..........................................................................................A</ 5he otation Challenge.....................................................................A</ 5he %er!i'e 1mplementation.............................................................A<< $sing the %er!i'e................................................................................A<8 Alertin 1sers ?ia @otifications..........................................................*** -oti&i'ation Con&iguration.......................................................................AAA +ar"=are -oti&i'ations.....................................................................AA4 1'ons....................................................................................................AA0 -oti&i'ations in A'tion.............................................................................AA8 %taying in the *oregroun".......................................................................A4/ *ake#layer, e"u;..............................................................................A4< -oti&i'ations an" the +oney'omb $1....................................................A44 /eAuestin and /eAuirin Permissions.............................................*%! Mother, May 1I..........................................................................................A02 +alt: Who 8oes 5hereI............................................................................A0/ En&or'ing #ermissions !ia the Mani&est...........................................A0< En&or'ing #ermissions Else=here.....................................................A0A May 1 %ee ?our @o'umentsI....................................................................A0A -e= #ermissions in >l" Appli'ations....................................................A04 #ermissions, $p *ront >r -ot At All......................................................A04
xvii
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
Accessin 4ocation5Based $ervices.....................................................*;! Lo'ation #ro!i"ers, 5hey Dno= Where ?ou7re +i"ing.........................A82 *in"ing ?oursel&........................................................................................A82 >n the Mo!e.............................................................................................A8< Are We 5here ?etI Are We 5here ?etI Are We 5here ?etI.................A84 5esting...5esting.......................................................................................A80 3appin #ith 3ap?ie# and 3apActivity..........................................*;6 5erms, -ot o& En"earment......................................................................A83 #iling >n...................................................................................................A30 5he Dey 5o 1t All.......................................................................................A30 5he 2are 2ones.........................................................................................A32 >ptional Maps....................................................................................A3< E;er'ising ?our Control...........................................................................A3A Room...................................................................................................A3A Center..................................................................................................A3A Layers $pon Layers..................................................................................A34 >!erlay Classes...................................................................................A34 @ra=ing the 1temiLe">!erlay...........................................................A30 +an"ling %'reen 5aps........................................................................A38 My, Mysel&, an" MyLo'ation>!erlay......................................................A33 ugge" 5errain.........................................................................................400 Maps an" *ragments................................................................................402 Limit ?oursel& to An"roi" /.0...........................................................402 $se onCreate.ie=() an" onA'ti!ityCreate"().................................40/ +ost the *ragment in a MapA'ti!ity................................................40< "andlin Telephone Calls..................................................................0:% eport 5o 5he Manager...........................................................................408
xviii
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
?ou Make the Call:...................................................................................408 -o, eally, ?ou Make the Call:.................................................................411 'onts.....................................................................................................0!, Lo!e 5he >ne ?ou7re With.......................................................................41/ +ere a 8lyph, 5here a 8lyph....................................................................410 3ore Development Tools....................................................................0!6 +ierar'hy .ie=er, +o= @eep 1s ?our Co"eI..........................................413 @@M%, $n"er An"roi"7s +oo"...............................................................42< Logging...............................................................................................424 *ile #ush an" #ull...............................................................................420 %'reenshots.........................................................................................428 Lo'ation $p"ates...............................................................................423 #la'ing Calls an" Messages...............................................................4/0 Memory Management.......................................................................4/< a"b, Like @@M%, With More 5yping......................................................4/A The /ole of Alternative +nvironments...............................................0,6 1n the 2eginning, 5here Was Ca!a...........................................................4<0 ...An" 1t Was >D......................................................................................4<0 2u'king the 5ren"....................................................................................4<1 %upport, %tru'ture....................................................................................4<2 Ca!eat @e!eloper......................................................................................4<2 "T34*..................................................................................................0.* >&&line Appli'ations.................................................................................4<A What @oes 1t MeanI..........................................................................4<A +o= @o ?ou $se 1tI..........................................................................4<4 Web %torage..............................................................................................4A2 What @oes 1t MeanI..........................................................................4A/
xix
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
+o= @o ?ou $se 1tI..........................................................................4A< Web %KL @atabase............................................................................4AA 8oing 5o #ro"u'tion................................................................................4A4 5esting................................................................................................4A4 %igning an" @istribution...................................................................4A4 $p"ates...............................................................................................4A0 1ssues ?ou May En'ounter.......................................................................4A0 An"roi" @e!i'e .ersions...................................................................4A0 %'reen %iLes an" @ensities................................................................4A8 Limite" #lat&orm 1ntegration............................................................4A8 #er&orman'e an" 2attery...................................................................4A3 Look an" *eel.....................................................................................440 @istribution........................................................................................440 +5MLA an" Alternati!e An"roi" 2ro=sers............................................441 *ire&o; Mobile.....................................................................................441 >pera Mobile......................................................................................441 @olphin 2ro=ser +@ <.0....................................................................441 +5MLA, 5he 2aseline...............................................................................441 PhoneGap.............................................................................................00, What 1s #hone8apI..................................................................................44/ What @o ?ou Write 1nI.....................................................................44/ What *eatures @o ?ou 8etI.............................................................44< What @o Apps Look LikeI................................................................44A +o= @oes @istribution WorkI.........................................................44A What About >ther #lat&ormsI.........................................................444 +o= 1s 1t Li'ense"I...........................................................................444 $sing #hone8ap.......................................................................................440
xx
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
1nstallation..........................................................................................440 Creating an" 1nstalling ?our #roHe't................................................440 #hone8apQ2uil".................................................................................448 #hone8ap an" the Che'klist %ample......................................................402 %ti'king to the %tan"ar"s...................................................................40/ A""ing #hone8ap A#1s.....................................................................404 1ssues ?ou May En'ounter......................................................................403 %e'urity...............................................................................................403 %'reen %iLes an" @ensities................................................................480 Look an" *eel......................................................................................481 *or More 1n&ormation..............................................................................482 Bther Alternative +nvironments........................................................0;, ho"es.......................................................................................................48/ *lash, *le;, an" A1 ..................................................................................48< C uby an" uboto....................................................................................48< Mono &or An"roi"....................................................................................48A App 1n!entor.............................................................................................48A 5itanium Mobile.......................................................................................480 >ther C.M Compile" Languages............................................................488 Dealin With Devices..........................................................................06! 5his App Contains E;pli'it... 1nstru'tions..............................................431 1mplie" *eature eBuests..................................................................43/ A 8uarantee" Market..............................................................................43< >ther %tu&& 5hat .aries............................................................................43A 2ugs, 2ugs, 2ugs.......................................................................................434 @e!i'e 5esting..........................................................................................434
xxi
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
Where Do We Go 'rom "ereC.............................................................066 Kuestions. %ometimes, With Ans=ers...................................................433 +ea"ing to the %our'e.............................................................................000 8etting ?our -e=s *i;..............................................................................001
xxii
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
We hope you enHoy 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. MaHor 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 Nrelease 'an"i"atesN &or the ne;t maHor release, la'king perhaps an in"e; but other=ise being 'omplete. #ersonaliLe" materials that you pur'hase as part o& a Wares'ription are &or the your use only. 5hat means that =hile you are =el'ome to make 'opies as nee"e" (e.g., home use, o&&i'e use, mobile "e!i'e use) &or your o=n use, you are not =el'ome to make 'opies a!ailable to other people or organiLations. 1& CommonsWare "etermines that your personaliLe" materials ha!e been illi'itly 'opie", your a''ount =ill be imme"iately suspen"e". 1& 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 enterpriseJ'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.
xxiii
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
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, or &ollo= the links 'ontaine" in the book7s pre&a'e. ?ou 'an sear'h through the #@* using most #@* rea"ers (e.g., A"obe ea"er). 1& you =ish to sear'h all o& the CommonsWare books at on'e, an" 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 Hust 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 personaliLe" 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 Bui'kly up"ate" to be a''urate =ith 'hanges in the A#1s. *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. 1& 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 'ommonsguy 5=itter &ee" 5he Commons2log 5he Wares'ription ne=sletter, =hi'h you 'an subs'ribe to o&& o& your Wares'ription page
Getting Help
1& you ha!e Buestions about the book e;amples, !isit %ta'k>!er&lo= an" ask a Buestion, tagge" =ith android an" commons#are. 1& you ha!e general An"roi" "e!eloper Buestions, !isit %ta'k>!er&lo= an" ask a Buestion, tagge" =ith android (an" any other rele!ant tags, su'h as (ava).
xxvi
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
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
2y NuniBueN, =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 Nso&terN 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 Nshi&ting san"sN o& the un"erlying en!ironment (e.g., 'hange" A#1s =ith ne= releases o& an %@D)
+o=e!er, those Nso&terN issues "o not Buali&y &or the &ormal bounty program. 2e sure to 'he'k the book7s errata page, though, to see i& your issue has alrea"y been reporte".
xxvii
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
Kuestions about the bug bounty, or problems you =ish to report &or bounty 'onsi"eration, shoul" be sent to bountyJ'ommons=are.'om.
Source Co e !n
"ts #icense
5he sour'e 'o"e samples sho=n in this book are a!ailable &or "o=nloa" &rom the book7s 8it+ub repository. All o& the An"roi" proHe'ts are li'ense" un"er the Apa'he 2.0 Li'ense, in 'ase you ha!e the "esire to reuse any o& it. 1& you =ish to use the sour'e 'o"e &rom the CommonsWare Web site, bear in min" a &e= things, 1. 5he proHe'ts are set up to be built by Ant, not by E'lipse. 1& you =ish to use the 'o"e =ith E'lipse, you =ill nee" to 'reate a suitable An"roi" E'lipse proHe'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 proHe't o& interest) on those proHe'ts you =ish to use, so the buil" &iles are up"ate" &or your An"roi" %@D !ersion.
the $our%to%$ree
Ea'h CommonsWare book e"ition =ill be a!ailable &or use un"er the Creati!e Commons Attribution--on'ommer'ial-%hareAlike /.0 li'ense as o& the &ourth anni!ersary o& its publi'ation "ate, or =hen <,000 'opies o& the e"ition ha!e been sol", =hi'he!er 'omes &irst. 5hat means that, on'e &our years ha!e elapse" (perhaps sooner:), you 'an use this prose &or non'ommer'ial purposes. 5hat is our *our-to-*ree 8uarantee to our rea"ers an" the broa"er 'ommunity. *or the purposes o& this guarantee, ne= Wares'riptions an" rene=als =ill be 'ounte" as sales o& this e"ition, starting &rom the time the e"ition is publishe". 5his e"ition o& this book =ill be a!ailable un"er the a&orementione" Creati!e Commons li'ense on ! @ovem-er ):!*. >& 'ourse, =at'h the CommonsWare Web site, as this e"ition might be reli'ense" sooner base" on sales.
xxviii
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
*or more "etails on the Creati!e Commons Attribution--on'ommer'ial%hareAlike /.0 li'ense, !isit the Creati!e Commons Web site. -ote that &uture e"itions o& this book =ill be'ome &ree on later "ates, ea'h &our years &rom the publi'ation o& that e"ition or base" on sales o& that spe'i&i' e"ition. eleasing one e"ition un"er the Creati!e Commons li'ense "oes not automati'ally release all e"itions un"er that li'ense.
!ckno*le gments
1 =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 -u!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"Qor 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 1nternet 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& 1nternet a''ess taken o&&. -o=, thanks to tren"s like te;t messaging an" to pro"u'ts like Apple7s i#hone, phones that 'an ser!e as 1nternet 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 (1nternet-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, Nis that a 2<-in'h LC@ in your po'ket, or...IN) 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" Nmulti-tou'hN 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 NbreaksN 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 Buietly &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" N"i&&erent than you are use" toN 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#1s), =ith support &or tools you may be use" to (E'lipse)
(
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
?ou get a &airly rigi" an" un'ommon &rame=ork in =hi'h your programs nee" to run so they 'an be Ngoo" 'itiLensN 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 2ACD button to ba'k up, Hust like they "o in a Web bro=ser.
.
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
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 (N'ron HobsN) an" &or e;posing 'ustom A#1s 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
1ntents 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). -ot 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).
'
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
"et#or$
An"roi" "e!i'es =ill generally be 1nternet-rea"y, through one 'ommuni'ations me"ium or another. ?ou 'an take a"!antage o& the 1nternet 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 Buery 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 &reBuently 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. 1n 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.
1
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
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.
3
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
CHAPTER &
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.
Core i0 =ith 5urbo 2oost. *or a emulator simulating a larger-s'reene" "e!i'e (e.g., tablet, tele!ision), a Core i0 that 'an NboostN up to /.<8+L makes "e!elopment mu'h more pleasant. Con!ersely, a C#$ like a Core 2 @uo =ith a 2.A8+L 'lo'k spee" results in a tablet emulator that is nearly unusable. %maller s'reens (e.g., phones) 'an run a''eptably on 2.A8+L an" (slightly) slo=er C#$s.
7ava
When you =rite An"roi" appli'ations, you typi'ally =rite them in Ca!a sour'e 'o"e. 5hat Ca!a sour'e 'o"e is then turne" into the stu&& that An"roi" a'tually runs (@al!ik byte'o"e in an A#D &ile). +en'e, the &irst thing you nee" to "o is get set up =ith a Ca!a "e!elopment en!ironment an" be rea"y to start =riting Ca!a 'lasses.
8
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
)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. 1& 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. 1& 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" obHe'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 *ile 1Q> e&le'tion 1nter&a'es
S09
5he An"roi" %@D gi!es you all the tools you nee" to 'reate an" test An"roi" appli'ations. 1t 'omes in t=o parts, the base tools, plus !ersionspe'i&i' %@Ds an" relate" a""-ons.
:
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
N%@D #lat&ormN &or all An"roi" %@D releases you =ant to test against S &or this book A#1 8 (An"roi" 2.2) is re'ommen"e" N@o'umentation &or An"roi" %@DN an" NA M EA21 !0a %ystem 1mageN&or the latest An"roi" %@D release N%amples &or %@DN &or the latest An"roi" %@D release, an" perhaps &or ol"er releases i& you =ish N8oogle A#1s by 8oogle 1n'.N&or ea'h An"roi" %@D release &or =hi'h you are "o=nloa"ing the plat&orm (see &irst bullet) An"roi" %@D #lat&orm-tools An"roi" %upport pa'kage (in the E;tras group at the bottom o& the tree)
5hen, 'li'k the 1nstall button beneath the tree on the right, =hi'h brings up a li'ense 'on&irmation "ialog,
+;
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
$igure +2 !n roi
e!ie= an" a''ept the li'enses, then 'li'k the 1nstall button. At this point, this is a &ine time to go get lun'h. >r, perhaps "inner. $nless you ha!e a substantial 1nternet '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 Manager i& you =ish, though =e =ill use it to set up the emulator in a later step o& this 'hapter.
++
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
ssl.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& N@e!eloper 5oolsN an" 'li'k the -e;t button. *ollo= the rest o& the =iLar" 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. 5his shoul" o''ur on your ne;t restart o& E'lipse, !ia a N=el'ome =iLar"N. >ther=ise, to "o this, 'hoose Win"o= U #re&eren'es &rom the E'lipse main menu (or the eBui!alent #re&eren'es option &or >% F). Cli'k on the An"roi" entry in the list on the le&t,
+(
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
5hen, 'li'k the 2ro=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.
+.
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
1& 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 R1# 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
+'
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
Cli'k the -e=... 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,
+1
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
$igure 12 !
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 NtargetN). Choose one o& the %@Ds you installe" !ia the "rop-"o=n list. -ote that in a""ition to NpureN 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#1s, 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& Ne;ternal storageN, you probably =ant to set up an %@ 'ar", by supplying a siLe in the asso'iate" &iel". +o=e!er, sin'e a &ile =ill be 'reate" on your
+3
"e!elopment ma'hine o& =hate!er siLe you spe'i&y &or the 'ar", you probably "o not =ant to 'reate a 282 emulate" %@ 'ar". /2M2 is a ni'e starting point, though you 'an go larger i& nee"e".
5he NskinN 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.
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" Hust '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" subseBuent 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, typi'ally &irst =ith a plain-te;t NA-@ >1@N label,
+6
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
$igure 32 !n roi
+8
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
$igure 62 !n roi
be&ore e!entually lan"ing at the home s'reen (the &irst time you run the A.@, sho=n belo=) or the keyguar",
+:
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
$igure 82 !n roi
home screen
1& you get the keyguar" (sho=n belo=), press the ME-$ button, or sli"e the green lo'k on the s'reen to the right, to get to the emulator7s home s'reen,
(;
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
$igure :2 !n roi
keyguar
(+
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
evice
evelopment settings
8enerally, you =ill =ant to enable $%2 "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 N%tay a=akeN 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 $%2. -e;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. 1t is possible that, by !irtue o& other so&t=are you ha!e installe", that the "ri!er is rea"y &or use. 1& it &in"s a "ri!er, you are probably rea"y to go.
((
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
1& the "ri!er is not &oun", here are some options &or getting one.
Windows Update
%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.
Manufacturer-Supplied Driver
1& you still "o not ha!e a "ri!er, sear'h the C@ that 'ame =ith the "e!i'e (i& any) or sear'h the Web site o& the "e!i'e manu&a'turer. Motorola, &or e;ample, has "ri!ers a!ailable &or all o& their "e!i'es in one spot &or "o=nloa".
+S - nd )inu.
>""s are "e'ent that simply plugging in your "e!i'e =ill NHust =orkN. ?ou 'an see i& An"roi" re'ogniLes 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. 1& you get output similar to the &ollo=ing, An"roi" "ete'te" your "e!i'e,
)ist of devices attached !&*+((,-*./0 device
1& 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,
(.
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
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".
('
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
CHAPTER /
ProAect
-o= that you ha!e the An"roi" %@D, it is time to make your &irst An"roi" proHe't. 5he goo" ne=s is that this reBuires Lero lines o& 'o"e S An"roi"7s tools 'reate a N+ello, =orl":N appli'ation &or you as part o& 'reating a ne= proHe'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 -e= U #roHe't..., an" this =ill bring up a list o& proHe't types to 'hoose &rom. *ol" open the An"roi" option an" 'li'k on An"roi" #roHe't,
(1
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
ProAect
#ress -e;t to a"!an'e the =iLar" to the main An"roi" proHe't page,
(3
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
ProAect
ProAect
+ere, you 'an simply &ill in the name o& the proHe't (e.g., -o=) in the N#roHe't nameN &iel", then 'li'k -e;t to bring up the ne;t page o& the =iLar",
(6
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
ProAect
ProAect &continue )
+ere, 'hoose the An"roi" %@D !ersion that you =ish to 'ompile against (e.g., 8oogle A#1s &or An"roi" 2.2) in the N2uil" 5argetN table, then 'li'k -e;t to bring up the &inal page o& the =iLar",
(8
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
ProAect
ProAect &continue )
5he "isplay name &or your appli'ation (e.g., N-o= %ample AppN) in the NAppli'ation nameN &iel"
(:
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
ProAect
5he name o& the Ca!a pa'kage in =hi'h this proHe't goes (e.g., com.commonsDare.android.skeleton) in the N#a'kage nameN &iel" 5he name o& the initial a'ti!ity to 'reate (e.g., -o=) in the NCreate A'ti!ityN &iel"
Comm nd )ine
+ere is a sample 'omman" that 'reates an An"roi" proHe't &rom the 'omman" line,
android create project --target 7Eoogle Inc.:Eoogle A(Is:/7 --path 2keleton/%oD --activitF %oD --package com.commonsDare.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 'ustomiLe this some=hat. +ere are =hat those 'omman"-line s=it'hes mean,
in"i'ates =hat !ersion o& An"roi" you are NtargetingN in terms o& your buil" pro'ess. ?ou nee" to supply the 1@ 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 --path in"i'ates =here you =ant the proHe'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/%oD/ "ire'tory =ill be 'reate" (or use" i& it e;ists) un"erneath the 'urrent =orking "ire'tory, an" the proHe't &iles =ill be store" there.
in"i'ates the Ca!a 'lass name o& your &irst a'ti!ity &or this proHe't. @o not in'lu"e a pa'kage name, an" the name has to meet Ca!a 'lass naming 'on!entions.
--activitF
.;
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
ProAect
in"i'ates the Ca!a pa'kage in =hi'h your &irst a'ti!ity =ill be lo'ate". 5his pa'kage also uniBuely i"enti&ies your proHe't on any "e!i'e on =hi'h you install it, an" this pa'kage also nee"s to be uniBue 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.commonsDare.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 B(C Buil @ "nstall@ an 4un the !pplica% tion in /our <mulator or 0evice
+a!ing a proHe'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 proHe't sele'te" in the #a'kage E;plorer pane, 'li'k the green NplayN button in the E'lipse toolbar to run your proHe't. 5he &irst time you "o this, you =ill ha!e to go through a &e= steps to set up a Nrun 'on&igurationN, so E'lipse kno=s =hat you =ant to "o. *irst, in the N un AsN list, 'hoose NAn"roi" Appli'ationN,
.+
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
ProAect
1& 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/%oD "ire'tory, then run the &ollo=ing 'omman",
ant clean debug 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/%oD/build.Gml AsetupB Android 2=H &ools ?evision 1AsetupB (roject &arget: Android 1.0 AsetupB A(I level: < AsetupB AsetupB -----------------AsetupB ?esolving librarF dependencies:
.(
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
ProAect
AsetupB %o librarF dependencies. AsetupB AsetupB -----------------AsetupB AsetupB @A?%I%E: %o min2dkVersion value set. Application Dill 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/%oD/bin AdeleteB =eleting directorF /home/some-balding-guF/projects/2keleton/%oD/gen -debug-obfuscation-check: -set-debug-mode: -compile-tested-if-test: -pre-build: -dirs: AechoB +reating output directories if needed... AmkdirB +reated dir: /home/some-balding-guF/projects/2keleton/%oD/bin AmkdirB +reated dir: /home/some-balding-guF/projects/2keleton/%oD/gen AmkdirB +reated dir: /home/some-baldingguF/projects/2keleton/%oD/bin/classes -aidl: AechoB +ompiling aidl files into Java classes... -renderscript: AechoB +ompiling ?ender2cript files into Java classes and ?ender2cript bFtecode... -resource-src: AechoB Eenerating ?.java / #anifest.java from the resources... -pre-compile: compile: AjavacB /opt/android-sdk-linuG/tools/ant/main rules.Gml:C,<: Darning: IincludeantruntimeI Das not set8 defaulting to build.sFsclasspath6lastJ set to false for repeatable builds AjavacB +ompiling > source files to /home/some-baldingguF/projects/2keleton/%oD/bin/classes -post-compile: -obfuscate: -deG: AechoB +onverting compiled files and eGternal libraries into /home/somebalding-guF/projects/2keleton/%oD/bin/classes.deG...
..
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
ProAect
-package-resources: AechoB (ackaging resources AaaptB +reating full resource package... -package-debug-sign: AapkbuilderB +reating %oD-debug-unaligned.apk and signing it Dith a debug keF... debug: AechoB ?unning Kip align on final apk... AechoB =ebug (ackage: /home/some-balding-guF/projects/2keleton/%oD/bin/%oDdebug.apk install: AechoB Installing /home/some-balding-guF/projects/2keleton/%oD/bin/%oDdebug.apk onto default emulator or device... AeGecB *, H4/s L<0>0 bFtes in -.-<.sM AeGecB pkg: /data/local/tmp/%oD-debug.apk AeGecB 2uccess 43I)= 23++$2293) &otal time: 1- seconds
-ote 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,
.'
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
ProAect
-oti'e there is an i'on &or your %oD 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 N2ACD buttonN, lo'ate" to the right o& the VME-$W button, an" looks like an arro= pointing to the le&t.
.1
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
CHAPTER 0
5he pre!ious 'hapter steppe" you through 'reating a stub proHe't. -o=, let us take a peek at =hat is insi"e o& this proHe'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 organiLe" aroun" a spe'i&i' "ire'tory tree stru'ture &or your An"roi" proHe't, mu'h like any other Ca!a proHe't. 5he spe'i&i's, though, are &airly uniBue 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 Bui'k primer on the proHe'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" proHe't (e.g., !ia android create project), you get se!eral items in the proHe'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 reBuires =hi'h hol"s Nresour'esN, su'h as i'ons, 8$1 layouts, an" the like, that get pa'kage" =ith the 'ompile" Ca!a in the appli'ation
src/, =hi'h
1n a""ition to the &iles an" "ire'tories sho=n abo!e, you may &in" any o& the &ollo=ing in An"roi" proHe'ts,
assets/, =hi'h hol"s 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
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
the samples =here =e re&eren'e things in ?.java (e.g., re&erring to a layout7s i"enti&ier !ia ?.laFout.main).
res/raD/ &or general-purpose &iles (e.g,. an au"io 'lip, a C%. &ile o& a''ount in&ormation) res/values/ res/Gml/
%ome o& the "ire'tory names may ha!e su&&i;es, like res/draDable-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. 1n your initial proHe't, you =ill &in" &iles like,
res/draDable-hdpi/icon.png, res/draDable-mdpi/icon.png, res/draDable-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
.:
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
notably
hol"s the 'ompile" Ca!a 'lasses hol"s the e;e'utable 'reate" &rom those 'ompile"
bin/classes.deG
Ca!a 'lasses
bin/Fourapp.ap
hol"s your appli'ation7s resour'es, pa'kage" as a R1# &ile (=here Fourapp is the name o& your appli'ation)
bin/Fourapp-*.apk
5he .apk &ile is a R1# 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/raD/) an" the Android#anifest.Gml &ile. 1& 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 optimiLe" =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#1 "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.
-ote 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 NbaseN o& your appli'ation. 5hen, e!ery=here else in the mani&est &ile that nee"s a 'lass name, you 'an Hust substitute a lea"ing "ot as shorthan" &or the pa'kage. *or e;ample, i& you nee"e" to re&er to com.commonsDare.android.search.2nicklefritK in this mani&est sho=n abo!e, you 'oul" Hust use .2nicklefritK, sin'e com.commonsDare.android.search is "e&ine" as the appli'ation7s pa'kage. As note" in the pre!ious 'hapter, your pa'kage also is a uniBue 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 proHe'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
'+
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
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.
'(
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
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" (&reBuently) an Nintent-filterO 'hil" element "es'ribing un"er =hat 'on"itions this a'ti!ity =ill be "isplaye". 5he sto'k NactivitFO 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 proHe't, i& you so 'hoose.
'.
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
CHAPTER 5
E'lipse is an e;tremely popular 1@E, parti'ularly &or Ca!a "e!elopment. 1t 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& 1@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".
-e= proHe't =iLar"s to 'reate regular An"roi" proHe'ts, An"roi" test proHe'ts, et'. 5he ability to run an An"roi" proHe't Hust 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
'1
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
An" so on
1n a""ition, the latest !ersion o& the A@5 pro!i"es you =ith preliminary support &or "rag-an"-"rop 8$1 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 $1 'omponents aroun" on the s'reen, a"Husting properties as you go. @rag-an"-"rop 8$1 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 Pro6ect
-ot all An"roi" proHe'ts ship =ith E'lipse proHe't &iles, su'h as the sample proHe'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 P -e= P #roHe't... &rom the E'lipse main menu,
'3
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
5hen, 'hoose An"roi" P An"roi" #roHe't &rom the tree o& a!ailable proHe't types,
'6
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
in <clipse
-ote, 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 proHe't 'reation =iLar", 'hoose the NCreate proHe't &rom e;isting sour'eN ra"io button, 'li'k the V2ro=se...W button, an" open the "ire'tory 'ontaining your proHe't7s Android#anifest.Gml &ile. 5his =ill populate most o& the rest o& the =iLar", though you may =ish to "ouble-'he'k the !arious settings be&ore e!entually 'li'king V*inishW. 5his =ill return you to the main E'lipse =in"o=, =ith the importe" proHe't in your =orkspa'e,
'8
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
-e;t, right-'li'k o!er the proHe't name, an" 'hoose 2uil" #ath P Con&igure 2uil" #ath &rom the 'onte;t menu,
5his brings up the buil" path portion o& the proHe't properties =in"o=,
1& 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 proHe't shoul" be rea"y &or use.
1;
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
1+
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
5his =ill a"" the @@M% perspe'ti!e to your =orkspa'e an" open it in your E'lipse 1@E. @@M% is 'o!ere" in greater "etail in a later 'hapter o& this book.
1(
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
5hat brings up the same =in"o= as you 'an get by running android &rom the 'omman" line.
Ho# to Run
Pro6ect
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 proHe't in the emulator. *irst, 'li'k the un toolbar button, or 'hoose #roHe't P un &rom the main menu. 5his =ill bring up the N un AsN "ialog the &irst time you run the proHe't,
1.
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
Choose An"roi" Appli'ation an" 'li'k >D. 1& 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. -ote that you =ill nee" to unlo'k the lo'k s'reen on the emulator (or "e!i'e) i& it is lo'ke".
1'
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
!lternative "0<s
1& 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, augmenting the A@5 an" o&&ering a number o& other An"roi"-relate" "e!elopment &eatures, in'lu"ing,
More =iLar"s &or helping you 'reate An"roi" 'lasses 1ntegrate" %KLite bro=sing, so you 'an manipulate a %KLite "atabase in your emulator right &rom your 1@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 1@Es are slo=ly getting their eBui!alents o& the A@5, albeit =ith minimal assistan'e &rom 8oogle. *or e;ample, 1ntelliC7s 1@EA has a mo"ule &or An"roi" S originally 'ommer'ial, it is part o& the open sour'e 'ommunity e"ition o& 1@EA as o& !ersion 10. An", o& 'ourse, you "o not nee" to use an 1@E at all. While this may soun" sa'rilegious to some, 1@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 eBui!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 1@E an" has no intention o& a"opting E'lipse any time soon.
"0<s222!n
This Book
?ou are =el'ome to use E'lipse as you =ork through this book. ?ou are =el'ome to use another 1@E i& you =ish. ?ou are e!en =el'ome to skip the 1@E outright an" Hust use an e"itor. 5his book is &o'use" on "emonstrating An"roi" 'apabilities an" the A#1s &or e;ploiting those 'apabilities. 1t is not aime" at tea'hing the use o& any one 1@E. As su'h, the sample 'o"e sho=n shoul" =ork in any 1@E, parti'ularly i& you &ollo= the instru'tions &or importing non-E'lipse proHe'ts into E'lipse supplie" abo!e.
13
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
CHAPTER 7
5he An"roi"Mani&est.;ml &ile that An"roi" generate" &or your &irst proHe't gets the Hob "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 /N) -ormal (/N to aroun" <.AN) Large (<.AN to aroun" 10N) E;tra-large (o!er 10N)
2y "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 siLes you =ant, you shoul" 'onsi"er a""ing a Nsupports-screensO element. 5his enumerates the s'reen siLes you ha!e e;pli'it support &or. *or e;ample, i& you =ant to support small s'reens, you
16
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
=ill nee" the Nsupports-screensO element. %imilarly, i& you are pro!i"ing 'ustom $1 support &or large or e;tra-large s'reens, you =ill =ant to ha!e the Nsupports-screensO element. %o, =hile the starting mani&est &ile =orks, han"ling multiple s'reen siLes is something you =ill =ant to think about. Mu'h more in&ormation about pro!i"ing soli" support &or all s'reen siLes '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 Nuses-sdkO element as a 'hil" o& the NmanifestO element to your Android#anifest.Gml &ile, to spe'i&y =hat !ersions o& An"roi" you are supporting. 2y "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 Nuses-sdkO element is 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,
android:min2dkVersion.
most
An"roi" 1.0 X 1 An"roi" 1.1 X 2 An"roi" 1.A X / An"roi" 1.4 X < An"roi" 2.0 X A An"roi" 2.0.1 X 4 An"roi" 2.1 X 0 An"roi" 2.2 X 8 An"roi" 2./ X 3 An"roi" 2././ X 10
18
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. 1& 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. 1n parti'ular, to get the ne= N+oney'ombN 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.
1:
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
PART II Activities
CHAPTER 8
5he proHe't you 'reate" in a pre!ious 'hapter =as Hust the "e&ault &iles generate" by the An"roi" buil" tools S you "i" not =rite any Ca!a 'o"e yoursel&. 1n this 'hapter, =e =ill mo"i&y that proHe'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. ->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. 1& you use" "i&&erent names ba'k then, you =ill nee" to a"Hust the &ollo=ing steps to mat'h.
The !ctivity
?our proHe'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 proHe't (e.g., com.commonsDare.android results in src/com/commonsDare/android/). 1nsi"e the innermost "ire'tory you shoul" &in" a pre-generate" sour'e &ile name" %oD.java, =hi'h is =here your &irst a'ti!ity =ill go. >pen %oD.java in your e"itor an" paste in the &ollo=ing 'o"e,
package com.commonsDare.android.skeletonJ import android.app.ActivitFJ 3.
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
public class %oD eGtends ActivitF implements VieD."n+lick)istener : 4utton btnJ Q"verride public void onCreateL4undle icicleM : super.onCreateLicicleMJ btn6neD ButtonLthisMJ btn.setOnClickListenerLthisMJ updateTimeLMJ setContentViewLbtnMJ
public void onClickLVieD vieDM : updateTimeLMJ ; private void updateTimeLM : btn.setTextLneD DateLM.toStringLMMJ ; ;
>r, i& you "o=nloa" the sour'e &iles o&& the Web site, you 'an Hust use the 2keleton/%oD proHe't "ire'tly.
5he pa'kage "e'laration nee"s to be the same as the one you use" =hen 'reating the proHe't. An", like any other Ca!a proHe'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.
3'
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
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 %oD eGtends ActivitF implements VieD."n+lick)istener : 4utton btnJ
A'ti!ities are publi' 'lasses, inheriting &rom the android.app.ActivitF base 'lass. 1n this 'ase, the a'ti!ity hol"s a button ( btn). %in'e, &or simpli'ity, =e =ant to trap all button 'li'ks Hust =ithin the a'ti!ity itsel&, =e also ha!e the a'ti!ity 'lass implement "n+lick)istener.
Q"verride public void onCreateL4undle icicleM : super.onCreateLicicleMJ btn6neD ButtonLthisMJ btn.setOnClickListenerLthisMJ updateTimeLMJ setContentViewLbtnMJ ;
5he on+reateLM 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 initialiLation 'an be "one. 1n our implementation, =e then 'reate the button instan'e ( neD 4uttonLthisM), tell it to sen" all button 'li'ks to the a'ti!ity instan'e itsel& (!ia set"n+lick)istenerLM), 'all a pri!ate update&imeLM metho" (see belo=), an" then set the a'ti!ity7s 'ontent !ie= to be the button itsel& (!ia set+ontentVieDLM). We =ill "is'uss that magi'al 4undle icicle in a later 'hapter. *or the moment, 'onsi"er it an opaBue han"le that all a'ti!ities re'ei!e upon 'reation.
public void onClickLVieD vieDM : updateTimeLMJ ;
on+lickLM
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&imeLM metho",
private void updateTimeLM : btn.setTextLneD DateLM.toStringLMMJ ;
When =e open the a'ti!ity (on+reateLM) or =hen the button is 'li'ke" (on+lickLM), =e up"ate the button7s label to be the 'urrent time !ia set&eGtLM, =hi'h &un'tions mu'h the same as the J4utton eBui!alent.
Buil ing an
5o buil" the a'ti!ity, either use your 1@E7s built-in An"roi" pa'kaging tool, or run ant clean debug install in the base "ire'tory o& your proHe't. 5hen, run the a'ti!ity S it shoul" be automati'ally laun'he" &or you i& you are using E'lipse, else &in" the a'ti!ity in the home s'reen laun'her. ?ou shoul" see an a'ti!ity akin to,
emonstration activity
33
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
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. -ote that the label is 'entere" horiLontally 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 gaLing at the a=esomeness o& A"!an'e" #ush-2utton 5e'hnologyY, you 'an 'li'k the ba'k button on the emulator to return to the laun'her.
36
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
CHAPTER 9
=sing F,#%Base
#ayouts
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 1nternet). 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.
#ayoutG
As the name suggests, an FML-base" layout is a spe'i&i'ation o& =i"gets7 relationships to ea'h other S an" to 'ontainers S en'o"e" in FML &ormat. %pe'i&i'ally, An"roi" 'onsi"ers FML-base" layouts to be resour'es, an" as su'h layout &iles are store" in the res/laFout "ire'tory insi"e your An"roi" proHe't. Ea'h FML &ile 'ontains a tree o& elements spe'i&ying a layout o& =i"gets an" 'ontainers that make up one VieD. 5he attributes o& the FML elements are properties, "es'ribing ho= a =i"get shoul" look or ho= a 'ontainer shoul" beha!e. *or e;ample, i& a 4utton element has an attribute !alue o& android:teGt2tFle 6 7bold7, that means that the te;t appearing on the &a'e o& the button shoul" be ren"ere" in a bol"&a'e &ont style.
3:
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
=sing F,#%Base
#ayouts
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 proHe'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.
#ayoutsG
Almost e!erything you "o using FML layout &iles 'an be a'hie!e" through Ca!a 'o"e. *or e;ample, you 'oul" use set&FpefaceLM to ha!e a button ren"er its te;t in bol", instea" o& using a property in an FML layout. %in'e FML layouts are yet another &ile &or you to keep tra'k o&, =e nee" goo" reasons &or using su'h &iles. #erhaps the biggest reason is to assist in the 'reation o& tools &or !ie= "e&inition, su'h as a 8$1 buil"er in an 1@E like E'lipse or a "e"i'ate" An"roi" 8$1 "esigner like @roi"@ra=. %u'h 8$1 buil"ers 'oul", in prin'iple, generate Ca!a 'o"e instea" o& FML. 5he 'hallenge is re-rea"ing the "e&inition in to support e"its S that is &ar simpler i& the "ata is in a stru'ture" &ormat like FML than in a programming language. Moreo!er, keeping the generate" bits separate" out &rom han"-=ritten 'o"e makes it less likely that somebo"y7s 'ustom-'ra&te" sour'e =ill get 'lobbere" by a''i"ent =hen the generate" bits get re-generate". FML &orms a ni'e mi""le groun" bet=een something that is easy &or tool-=riters to use an" easy &or programmers to =ork =ith by han" as nee"e". Also, FML as a 8$1 "e&inition &ormat is be'oming more 'ommonpla'e. Mi'roso&t7s FAML, A"obe7s *le;, 8oogle7s 8W5, an" MoLilla7s F$L all take a similar approa'h to that o& An"roi", put layout "etails in an FML &ile an" put programming smarts in sour'e &iles (e.g., Ca!as'ript &or F$L). Many less-=ell-kno=n 8$1 &rame=orks, su'h as RD, also use FML &or !ie= "e&inition. While N&ollo=ing the her"N is not ne'essarily the best poli'y, it "oes ha!e the a"!antage o& helping to ease the transition into An"roi" &rom any other FML-'entere" !ie= "es'ription language.
6;
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
=sing F,#%Base
#ayouts
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 Hust use the bare 'lass name. 1& you 'reate your o=n =i"gets as sub'lasses o& android.vieD.VieD, you =oul" nee" to pro!i"e a &ull pa'kage "e'laration as =ell (e.g., com.commonsDare.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. 2e'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 Didth an" android:laFout height tell An"roi" to
ha!e the button7s =i"th an" height &ill the NparentN, in this 'ase the entire s'reen S these attributes =ill be 'o!ere" in greater "etail in a later 'hapter
6+
=sing F,#%Base
#ayouts
%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 reBuire 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 "oLens o& other e;amples o& more 'omple; layouts &or you to peruse.
!n
8i!en that you ha!e painstakingly set up the =i"gets an" 'ontainers &or your !ie= in an FML layout &ile name" main.Gml store" in res/laFout, all you nee" is one statement in your a'ti!ity7s on+reateLM 'allba'k to use that layout,
6(
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
=sing F,#%Base
#ayouts
setContentViewL?.laFout.mainMJ
5his is the same set+ontentVieDLM =e use" earlier, passing it an instan'e o& a VieD sub'lass (in that 'ase, a 4utton). 5he An"roi"-built VieD, '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 findVieD4FIdLM, passing it the numeri' i"enti&ier o& the =i"get in Buestion. 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& VieD, Hust like the 4utton instan'e =e 'reate" in the pre!ious 'hapter.
public class %oD?eduG eGtends ActivitF implements VieD."n+lick)istener : 4utton btnJ Q"verride public void onCreateL4undle icicleM : super.onCreateLicicleMJ setContentViewL?.laFout.mainMJ
6.
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
=sing F,#%Base
#ayouts
btn6L4uttonMfindViewByIdL?.id.buttonMJ btn.setOnClickListenerLthisMJ updateTimeLMJ ; public void onClickLVieD vieDM : updateTimeLMJ ; private void updateTimeLM : btn.setTextLneD DateLM.toStringLMMJ ;
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+ontentVieDL?.laFout.mainM). 5he ?.java sour'e &ile =ill be up"ate" =hen =e rebuil" this proHe't to in'lu"e a re&eren'e to our layout &ile (store" as main.Gml in our proHe'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 findVieD4FIdLM 'all. %in'e =e i"enti&ie" our button as QRid/button, =e 'an re&eren'e the button7s i"enti&ier as ?.id.button. -o=, =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 %oD "emo,
6'
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
=sing F,#%Base
#ayouts
61
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
CHAPTER :
E!ery 8$1 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.
!ssigning #abels
5he simplest =i"get is the label, re&erre" to in An"roi" as a &eGtVieD. Like in most 8$1 toolkits, labels are bits o& te;t not e"itable "ire'tly by users. 5ypi'ally, they are use" to i"enti&y a"Ha'ent =i"gets (e.g., a N-ame,N label be&ore a &iel" =here one &ills in a name). 1n Ca!a, you 'an 'reate a label by 'reating a &eGtVieD instan'e. More 'ommonly, though, you =ill 'reate labels in FML layout &iles by a""ing a &eGtVieD element to the layout, =ith an android:teGt property to set the !alue o& the label itsel&. 1& you nee" to s=ap labels base" on 'ertain 'riteria, su'h as internationaliLation, 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.
&eGtVieD
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)
66
82 he;
*or e;ample, in the 4asic/)abel proHe't, you =ill &in" the &ollo=ing layout &ile,
NPGml version671.-7 encoding67utf-,7PO N&eGtVieD Gmlns:android67http://schemas.android.com/apk/res/android7 android:laFout Didth67fill parent7 android:laFout height67Drap content7 android:teGt675ou Dere eGpecting something profoundP7 /O
Cust that layout alone, =ith the stub Ca!a sour'e pro!i"e" by An"roi"7s proHe't buil"er (e.g., android create project), gi!es you,
68
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
"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.4 a""e" a ne= &eature &or the "e'laration o& the Non'li'kN listener &or a 4utton. 1n a""ition to the 'lassi' approa'h o& "e&ining some obHe't (su'h as the a'ti!ity) as implementing the VieD."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 VieD parameter, has a void return !alue, an" is public 1n 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 someMethodLVieD the4uttonM : // do something useful here ;
5hen, =e 'oul" use this FML "e'laration &or the 4utton itsel&, in'lu"ing android:on+lick,
N4utton android:on+lick67some#ethod7 ... /O
5his is enough &or An"roi" to N=ire togetherN 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, ImageVieD an" Image4utton. As the names suggest, they are image-base" analogues to &eGtVieD an" 4utton, respe'ti!ely.
6:
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
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& ImageVieD, 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/ImageVieD sample proHe't,
NPGml version671.-7 encoding67utf-,7PO NImageVieD Gmlns:android67http://schemas.android.com/apk/res/android7 android:id67QRid/icon7 android:laFout Didth67fill parent7 android:laFout height67fill parent7 android:adjustVieD4ounds67true7 android:src67QdraDable/molecule7 /O
5he result, Hust using the 'o"e-generate" a'ti!ity, is simply the image,
8;
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
to 'ontrol i& the &iel" shoul" automati'ally 'apitaliLe the &irst letter o& entere" te;t (e.g., &irst name, 'ity)
android:digits, to 'on&igure the
android:single)ine, to 'ontrol i& the &iel" is &or single-line input or multiple-line input (e.g., "oes OEnterP mo!e you to the ne;t =i"get or a"" a ne=lineI)
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 Nso&t keyboar"sN to An"roi" S this =ill be "is'usse" in an up'oming 'hapter. *or e;ample, &rom the 4asic/9ield proHe't, here is an FML layout &ile sho=ing an $dit&eGt,
NPGml version671.-7 encoding67utf-,7PO N$dit&eGt Gmlns:android67http://schemas.android.com/apk/res/android7 android:id67QRid/field7 android:laFout Didth67fill parent7 android:laFout height67fill parent7 android:single)ine67false7 /O
-ote that android:single)ine is &alse, so users =ill be able to enter in se!eral lines o& te;t.
8+
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
*or this proHe't, the 9ield=emo.java &ile populates the input &iel" =ith some prose,
package com.commonsDare.android.fieldJ import android.app.ActivitFJ import android.os.4undleJ import android.Didget.$dit&eGtJ public class 9ield=emo eGtends ActivitF : Q"verride public void onCreateL4undle icicleM : super.onCreateLicicleMJ setContentViewL?.laFout.mainMJ $dit&eGt fld6L$dit&eGtMfindViewByIdL?.id.fieldMJ fld.setTextL7)icensed under the Apache )icense8 Version >.- 7 R 7Lthe T7)icenseT7MJ Fou maF not use this file 7 R 7eGcept in compliance Dith the )icense. 5ou maF 7 R 7obtain a copF of the )icense at 7 R 7http://DDD.apache.org/licenses/)I+$%2$->.-7MJ ; ;
5he result, on'e built an" installe" into the emulator, is,
8(
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
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&eGtVieD =i"get, "is'usse" in greater "etail later in this book.
to "etermine i& the 'he'kbo; has been 'he'ke" to &or'e the 'he'kbo; into a 'he'ke" or un'he'ke" i& the user 'he'ke" it
set+heckedLM
state
toggleLM to toggle the 'he'kbo; as
Also, you 'an register a listener obHe'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 proHe't, here is a simple 'he'kbo; layout,
NPGml version671.-7 encoding67utf-,7PO N+heck4oG Gmlns:android67http://schemas.android.com/apk/res/android7 android:id67QRid/check7 android:laFout Didth67Drap content7 android:laFout height67Drap content7 android:teGt67&his checkboG is: unchecked7 /O
8.
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
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 Q"verride public void onCreateL4undle icicleM : super.onCreateLicicleMJ setContentViewL?.laFout.mainMJ cb6L+heck4oGMfindViewByIdL?.id.checkMJ cb.setOnCheckedChangeListenerLthisMJ
public void onCheckedChangedL+ompound4utton buttonVieD8 boolean is+heckedM : if Lis+heckedM : cb.setTextL7&his checkboG is: checked7MJ ; else : cb.setTextL7&his checkboG is: unchecked7MJ ; ; ;
-ote 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)istenerLthisM). 5he 'allba'k &or the listener is on+hecked+hangedLM, =hi'h re'ei!es the 'he'kbo; =hose state has 'hange" an" =hat the ne= state is. 1n this 'ase, =e up"ate the te;t o& the 'he'kbo; to re&le't =hat the a'tual bo; 'ontains. 5he resultI Cli'king the 'he'kbo; imme"iately up"ates its te;t, as sho=n belo=,
8'
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
$igure .+2 The CheckBox0emo sample application@ *ith the checkbox unchecke
$igure .(2 The same application@ no* *ith the checkbox checke
81
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
ToggleButton
83
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
$igure .'2 The same application@ sho*ing the ToggleButton *hen checke
>ther=ise, &oggle4utton beha!es mu'h like +heck4oG. ?ou 'an put it in a layout &ile, as seen in the 4asic/&oggle4utton sample,
NPGml version671.-7 encoding67utf-,7PO N&oggle4utton Gmlns:android67http://schemas.android.com/apk/res/android7 android:id67QRid/toggle7 android:laFout Didth67Drap content7 android:laFout height67Drap content7 /O
?ou 'an also set up an "n+hecked+hange)istener to be noti&ie" =hen the user 'hanges the state o& the &oggle4utton.
Turn the 4a io =p
As =ith other implementations o& ra"io buttons in other toolkits, An"roi"7s ra"io buttons are t=o-state, like 'he'kbo;es, but 'an be groupe" su'h that only one ra"io button in the group 'an be 'he'ke" at any time.
86
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
Like +heck4oG, ?adio4utton inherits &rom +ompound4utton, =hi'h in turn inherits &rom &eGtVieD. +en'e, all the stan"ar" &eGtVieD properties &or &ont &a'e, style, 'olor, et'. are a!ailable &or 'ontrolling the look o& ra"io buttons. %imilarly, you 'an 'all is+heckedLM on a ?adio4utton to see i& it is sele'te", toggleLM to sele't it, an" so on, like you 'an =ith a +heck4oG. Most times, you =ill =ant to put your ?adio4utton =i"gets insi"e o& a ?adioEroup. 5he ?adioEroup in"i'ates a set o& ra"io buttons =hose state is tie", meaning only one button out o& the group 'an be sele'te" at any time. 1& you assign an android:id to your ?adioEroup in your FML layout, you 'an a''ess the group &rom your Ca!a 'o"e an" in!oke,
checkLM to 'he'k a spe'i&i' group.checkL?.id.radio1M) clear+heckLM
to 'lear all ra"io buttons, so none in the group are o& the 'urrently-'he'ke"
'he'ke"
get+hecked?adio4uttonIdLM to get the 1@ ra"io button (or -1 i& none are 'he'ke")
-ote that the mutual-e;'lusion &eature o& ?adioEroup only applies to =i"gets that are imme"iate 'hil"ren o& the ?adioEroup. ?ou 'annot ha!e other 'ontainers S "is'usse" in the ne;t 'hapter S bet=een the ?adioEroup an" its ?adio4utton =i"gets.
?adio4utton
*or e;ample, &rom the 4asic/?adio4utton sample appli'ation, here is an FML layout sho=ing a ?adioEroup =rapping a set o& ?adio4utton =i"gets,
NPGml version671.-7 encoding67utf-,7PO N?adioEroup Gmlns:android67http://schemas.android.com/apk/res/android7 android:orientation67vertical7 android:laFout Didth67fill parent7 android:laFout height67fill parent7 O N?adio4utton android:id67QRid/radio17 android:laFout Didth67Drap content7 android:laFout height67Drap content7 android:teGt67?ock7 /O N?adio4utton android:id67QRid/radio>7 android:laFout Didth67Drap content7
88
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
android:laFout height67Drap content7 android:teGt672cissors7 /O N?adio4utton android:id67QRid/radioC7 android:laFout Didth67Drap content7 android:laFout height67Drap content7 android:teGt67(aper7 /O N/?adioEroupO
$sing the sto'k An"roi"-generate" Ca!a &or the proHe't an" this layout, you get,
-ote that the ra"io button group is initially set to be 'ompletely un'he'ke" at the outset. 5o preset one o& the ra"io buttons to be 'he'ke", use either set+heckedLM on the ?adio4utton or checkLM on the ?adioEroup &rom =ithin your on+reateLM 'allba'k in your a'ti!ity.
8:
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
P ddin!
Wi"gets ha!e a minimum siLe, 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 siLe o& its 'aption. ?ou 'an 'ontrol this siLe 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(addingLM 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=oDn, android:neGt9ocus?ight,
android:neGt9ocus)eft, an" android:neGt9ocus3p, =hi'h 'ontrol the &o'us or"er i& the user uses the @-pa", tra'kball, or similar pointing "e!i'e
:;
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
android:content=escription, =hi'h is roughly eBui!alent to attribute on an +5ML NimgO tag, an" is use" by a''essibility
the alt tools to help people =ho 'annot see the s'reen na!igate the appli'ation
;se1ul %ethods
?ou 'an toggle =hether or not a =i"get is enable" !ia set$nabledLM an" see i& it is enable" !ia is$nabledLM. >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 reUuest9ocusLM an" see i& it is &o'use" !ia is9ocusedLM. ?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(arentLM
to &in" the parent =i"get or 'ontainer to &in" a 'hil" =i"get =ith a 'ertain 1@
findVieD4FIdLM get?ootVieDLM
to get the root o& the tree (e.g., =hat you pro!i"e" to the a'ti!ity !ia set+ontentVieDLM)
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 &eGtVieD (an" sub'lasses) 'an take a +olor2tate)ist, in'lu"ing !ia the Ca!a setter (in this 'ase, set&eGt+olorLM).
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 &eGtVieD has a "i&&erent te;t 'olor =hen it is the
:+
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
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 &eGtVieD. 1& you =ish to 'hange the 'olor o& a &eGtVieD =i"get in Ca!a 'o"e, you ha!e t=o main 'hoi'es, 1. $se +olor2tate)ist.value"fLM, =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"fLM metho". 5his is the Ca!a eBui!alent o& the android:teGt+olor approa'h, to make the &eGtVieD 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
:(
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
CHAPTER 1<
Containers pour a 'olle'tion o& =i"gets (an" possibly 'hil" 'ontainers) into spe'i&i' stru'tures you like. 1& you =ant a &orm =ith labels on the le&t an" &iel"s on the right, you =ill nee" a 'ontainer. 1& 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 ?adioEroup), you =ill nee" a 'ontainer Hust to ha!e a root element to pla'e the =i"gets insi"e. Most 8$1 toolkits ha!e some notion o& layout management, &reBuently organiLe" into 'ontainers. 1n Ca!aQ%=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 Nbo;N mo"el, but in a""ition supports a range o& 'ontainers pro!i"ing "i&&erent layout rules. 1n 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 2crollVieD, 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 9loD)aFout in Ca!aQ%=ing, vboG an" hboG in *le; an" F$L, et'. *le; an" F$L use the bo; as their primary unit o& layout. 1& 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.
Orientation
>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"rientationLM on the )inear)aFout, supplying it either !"?IV"%&A) or V$?&I+A).
Fill Model
Let7s imagine a ro= o& =i"gets, su'h as a pair o& ra"io buttons. 5hese =i"gets ha!e a NnaturalN siLe base" on their te;t. 5heir 'ombine" siLes 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 siLes. We then ha!e the issue o& =hat to "o =ith the remaining spa'e.
:'
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
All =i"gets insi"e a )inear)aFout must supply android:laFout Didth 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 siLe ?ou 'an pro!i"e Drap 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 siLe, allo=ing An"roi" to a"Hust your !ie= to &it the a!ailable spa'e. @BT+, 1n A#1 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#1 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.
Weight
2ut, =hat happens i& =e ha!e t=o =i"gets that shoul" split the a!ailable &ree spa'eI *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 Didth (&or ro=s) or android:laFout height (&or 'olumns) to fill parent, you must also set android:laFout Deight. 5his property in"i'ates =hat proportion o& the &ree spa'e shoul" go to that =i"get. 1& you set android:laFout Deight to be the same non-Lero !alue &or a pair o& =i"gets (e.g., 1), the &ree spa'e =ill be split e!enly bet=een them. 1& you set it to be 1 &or one =i"get an" > &or
:1
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
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 Lero by "e&ault. Another pattern &or using =eights is i& you =ant to allo'ate siLes on a per'entage basis. 5o use this te'hniBue &or, say, a horiLontal layout,
%et all the android:laFout Didth !alues to be - &or the =i"gets in the layout %et the android:laFout Deight !alues to be the "esire" per'entage siLe &or ea'h =i"get in the layout Make sure all those =eights a"" up to 1--
ravit!
2y "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 horiLontal )inear)aFout, the ro= =ill start &lush on the le&t si"e o& the s'reen. 1& that is not =hat you =ant, you nee" to spe'i&y a gra!ity. $nlike the physi'al =orl", An"roi" has t=o types o& gra!ity, the gra!ity o& a =i"get =ithin a )inear)aFout, an" the gra!ity o& the 'ontents o& a =i"get or 'ontainer. 5he android:gravitF property o& some =i"gets an" 'ontainers S =hi'h also 'an be "e&ine" !ia set8ra!ity() in Ca!a S tells An"roi" to sli"e the 'ontents o& the =i"get or 'ontainer in a parti'ular "ire'tion. *or e;ample, android:gravitF67right7 says to sli"e the 'ontents o& the =i"get to the rightT android:gravitF67rightWbottom7 says to sli"e the 'ontents o& the =i"get to the right an" the bottom. +ere, N'ontentsN !aries. &eGtVieD supports android:gravitF, an" the N'ontentsN is the te;t hel" =ithin the &eGtVieD. )inear)aFout supports android:gravitF, an" the N'ontentsN are the =i"gets insi"e the 'ontainer. An" so on.
:3
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
Chil"ren o& a
)inear)aFout also ha!e the option o& spe'i&ying android:laFout gravitF. +ere, the 'hil" is telling the )inear)aFout Ni& there
*or e;ample, let7s suppose that =e ha!e a horiLontal )inear)aFout =ith three 'hil" =i"gets. 2y "e&ault, they =ill be le&t-aligne",
1& =e spe'i&ie" android:gravitF67right7 on the )inear)aFout, all three =i"gets =oul" sli"e o!er to the right,
:6
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
1&, on the other han", =e le&t android:gravitF alone, but spe'i&ie" android:laFout gravitF67right7 on the thir" =i"get, that =i"get alone =oul" sli"e to the right,
$igure .82 ! #inear#ayout *ith three chil ren@ *ith the thir
one right%aligne
*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.
'olumn
:8
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
*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 Nsit onN), 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.
Margins
2y "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 &eGtVieD S pa""ing an" margins ha!e similar !isual e&&e't, in'reasing the spa'e bet=een the =i"get an" a"Ha'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. 1n 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"Ha'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.
E. 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,
NPGml version671.-7 encoding67utf-,7PO N)inear)aFout Gmlns:android67http://schemas.android.com/apk/res/android7 android:orientation67vertical7 ::
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
android:laFout Didth67fill parent7 android:laFout height67fill parent7 O N?adioEroup android:id67QRid/orientation7 android:orientation67horiKontal7 android:laFout Didth67Drap content7 android:laFout height67Drap content7 android:padding67.dip7O N?adio4utton android:id67QRid/horiKontal7 android:teGt67horiKontal7 /O N?adio4utton android:id67QRid/vertical7 android:teGt67vertical7 /O N/?adioEroupO N?adioEroup android:id67QRid/gravitF7 android:orientation67vertical7 android:laFout Didth67fill parent7 android:laFout height67Drap content7 android:padding67.dip7O N?adio4utton android:id67QRid/left7 android:teGt67left7 /O N?adio4utton android:id67QRid/center7 android:teGt67center7 /O N?adio4utton android:id67QRid/right7 android:teGt67right7 /O N/?adioEroupO N/)inear)aFoutO
-ote that =e ha!e a )inear)aFout =rapping t=o ?adioEroup sets. ?adioEroup 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 ?adioEroup sets up a ro= (android:orientation 6 7horiKontal7) o& ?adio4utton =i"gets. 5he ?adioEroup has .dip o& pa""ing on all si"es, separating it &rom the other ?adioEroup, =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 Drap content, so the ra"io buttons =ill only take up the spa'e that they nee". 5he bottom ?adioEroup 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 NnaturalN height (android:laFout height 6 7Drap content7). +o=e!er, =e
+;;
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
ha!e set android:laFout Didth to be fill parent, meaning the 'olumn o& ra"io buttons N'laimsN the entire =i"th o& the s'reen. 5o a"Hust these settings at runtime base" on user input, =e nee" some Ca!a 'o"e,
package com.commonsDare.android.linearJ import import import import import import import android.app.ActivitFJ android.os.4undleJ android.vieD.EravitFJ android.teGt.&eGt@atcherJ android.Didget.)inear)aFoutJ android.Didget.?adioEroupJ android.Didget.$dit&eGtJ )inear)aFout=emo eGtends ActivitF ?adioEroup."n+hecked+hange)istener : orientationJ gravitFJ
Q"verride public void onCreateL4undle icicleM : super.onCreateLicicleMJ setContentViewL?.laFout.mainMJ orientation6L?adioEroupMfindViewByIdL?.id.orientationMJ orientation.setOnCheckedChangeListenerLthisMJ gravitF6L?adioEroupMfindViewByIdL?.id.gravitFMJ gravitF.setOnCheckedChangeListenerLthisMJ ; public void onCheckedChangedL?adioEroup group8 int checkedIdM : sDitch LcheckedIdM : case ?.id.horiKontal: orientation.setOrientationL)inear)aFout.!"?IV"%&A)MJ breakJ case ?.id.vertical: orientation.setOrientationL)inear)aFout.V$?&I+A)MJ breakJ case ?.id.left: gravitF.set ra!ityLEravitF.)$9&MJ breakJ case ?.id.center: gravitF.set ra!ityLEravitF.+$%&$? !"?IV"%&A)MJ breakJ case ?.id.right:
+;+
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
; ; ;
1n on+reateLM, =e look up our t=o ?adioEroup 'ontainers an" register a listener on ea'h, so =e are noti&ie" =hen the ra"io buttons 'hange state (set"n+hecked+hange)istenerLthisM). %in'e the a'ti!ity implements "n+hecked+hange)istener, the a'ti!ity itsel& is the listener. 1n on+hecked+hangedLM (the 'allba'k &or the listener), =e see =hi'h ?adio4utton ha" a state 'hange. 2ase" on the 'li'ke"-upon item, =e a"Hust 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,
1& =e toggle on the N!erti'alN ra"io button, the top ?adioEroup a"Husts to mat'h,
+;(
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
$igure ';2 The same application@ *ith the vertical ra io button selecte
1& =e toggle the N'enterN or NrightN ra"io buttons, the bottom ?adioEroup a"Husts to mat'h,
$igure '+2 The same application@ *ith the vertical an selecte +;.
Subscribe to updates at http://commonsware.com
center ra io buttons
right ra io buttons
+;'
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
android:laFout Didth67fill parent7 android:laFout height67-dip7 android:laFout Deight67.-7 /O N4utton android:teGt67&hirtF (ercent7 android:laFout Didth67fill parent7 android:laFout height67-dip7 android:laFout Deight67C-7 /O N4utton android:teGt67&DentF (ercent7 android:laFout Didth67fill parent7 android:laFout height67-dip7 android:laFout Deight67>-7 /O N/)inear)aFoutO
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 reBueste" per'entages. 5o reBuest 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 Deight to be the "esire" per'entage (e.g., android:laFout Deight67.-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,
+;1
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
as the name suggests, lays out =i"gets base" upon their relationship to other =i"gets in the 'ontainer an" the parent 'ontainer. ?ou 'an pla'e Wi"get F belo= an" to the le&t o& Wi"get ?, or ha!e Wi"get R7s bottom e"ge align =ith the bottom o& the 'ontainer, an" so on. 5his is reminis'ent o& Cames Elliot7s elati!eLayout &or use =ith Ca!aQ%=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.
+;3
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
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" horiLontally 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 horiLontally an" !erti'ally at the 'enter o& the 'ontainer
All o& these properties take a simple boolean !alue (true or false). -ote 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).
+;6
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
The first occurrence of an id value should have the plus si n DQRid/Didget aEF the second and su-seAuent times that id value is used in the layout file should drop the plus si n D Qid/Didget aE. 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 appears in the ?elative)aFout be&ore Wi"get 2, an" Wi"get is i"enti&ie" as QRid/Didget a, Wi"get 2 'an re&er to Wi"get A in one o& its o=n properties !ia the i"enti&ier Qid/Didget 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 beloD
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
2eyon" 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
+;8
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
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 NbaselineN 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 NnaturalN. %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 2 to be positione" to the right o& Wi"get A, in the FML element &or Wi"get 2, =e nee" to in'lu"e android:laFout to?ight"f 6 7Qid/Didget a7 (assuming Qid/Didget a is the i"entity o& Wi"get A).
Order of %valuation
1t 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.4, 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.
E. mple
With all that in min", let7s e;amine a typi'al N&ormN =ith a &iel", a label, plus a pair o& buttons labele" N>DN an" NCan'elN. +ere is the FML layout, pulle" &rom the +ontainers/?elative sample proHe't,
NPGml version671.-7 encoding67utf-,7PO N?elative)aFout Gmlns:android67http://schemas.android.com/apk/res/android7
+;:
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
android:laFout Didth67fill parent7 android:laFout height67Drap content7O N&eGtVieD android:id67QRid/label7 android:laFout Didth67Drap content7 android:laFout height67Drap content7 android:teGt673?):7 android:laFout align4aseline67QRid/entrF7 android:laFout align(arent)eft67true7/O N$dit&eGt android:id67Qid/entrF7 android:laFout Didth67fill parent7 android:laFout height67Drap content7 android:laFout to?ight"f67Qid/label7 android:laFout align(arent&op67true7/O N4utton android:id67QRid/ok7 android:laFout Didth67Drap content7 android:laFout height67Drap content7 android:laFout beloD67Qid/entrF7 android:laFout align?ight67Qid/entrF7 android:teGt67"H7 /O N4utton android:id67QRid/cancel7 android:laFout Didth67Drap content7 android:laFout height67Drap content7 android:laFout to)eft"f67Qid/ok7 android:laFout align&op67Qid/ok7 android:teGt67+ancel7 /O N/?elative)aFoutO
*irst, =e open up the ?elative)aFout. 1n this 'ase, =e =ant to use the &ull =i"th o& the s'reen ( android:laFout Didth 6 7fill parent7) an" only as mu'h height as =e nee" (android:laFout height 6 7Drap content7). -e;t, =e "e&ine the label as a &eGtVieD. 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 1@ (android:laFout align4aseline67QRid/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 Nro=N in the layout. 5hose are han"le" by three properties,
android:laFout to?ight"f 6 7Qid/label7
++;
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
5hen, the >D button is set to be belo= the &iel" ( android:laFout beloD 6 7Qid/entrF7) an" ha!e its right si"e align =ith the right si"e o& the &iel" (android:laFout align?ight 6 7Qid/entrF7). 5he Can'el button is set to be to the le&t o& the >D button (android:laFout to)eft 6 7Qid/ok7) an" ha!e its top aligne" =ith the >D button (android:laFout align&op 6 7Qid/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 Nhigher in the R a;isN 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.
+++
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
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,
NPGml version671.-7 encoding67utf-,7PO N?elative)aFout Gmlns:android67http://schemas.android.com/apk/res/android7 android:laFout Didth67fill parent7 android:laFout height67fill parent7 O N4utton android:teGt67I A# 4IE7 android:teGt2iKe671>-dip7 android:teGt2tFle67bold7 android:laFout Didth67fill parent7 android:laFout height67fill parent7 /O N4utton android:teGt67I am small7 android:laFout Didth67Drap content7 android:laFout height67Drap content7 android:laFout centerIn(arent67true7 /O N/?elative)aFoutO
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 N&loatN o!er the &irst 4utton,
++(
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
2oth 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 4asa
1& 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 'onHun'tion =ith &able?oD. &able)aFout 'ontrols the o!erall beha!ior o& the 'ontainer, =ith the =i"gets themsel!es poure" into one or more &able?oD 'ontainers, one per ro= in the gri".
++.
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
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,
N&able?oDO N&eGtVieD android:teGt673?):7 /O N$dit&eGt android:id67QRid/entrF7 android:laFout span67C7/O N/&able?oDO
1n the abo!e FML layout &ragment, the &iel" spans three 'olumns. >r"inarily, =i"gets are put into the &irst a!ailable 'olumn. 1n 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,
++'
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
N&able?oDO N4utton android:id67QRid/cancel7 android:laFout column67>7 android:teGt67+ancel7 /O N4utton android:id67QRid/ok7 android:teGt67"H7 /O N/&able?oDO
1n 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.
++1
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
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 N'ollapse"N, 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+ollapsedLM 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 set+olumn2tretchableLM an" set+olumn2hrinkableLM. at runtime !ia
E. mple
5he FML layout &ragments sho=n abo!e, =hen 'ombine", gi!e us a ren"ition o& the N&ormN =e 'reate" &or ?elative)aFout, =ith the a""ition o& a "i!i"er line bet=een the labelQ&iel" an" the t=o buttons (&oun" in the +ontainers/&able "emo),
&able)aFout
NPGml version671.-7 encoding67utf-,7PO N&able)aFout Gmlns:android67http://schemas.android.com/apk/res/android7 android:laFout Didth67fill parent7 android:laFout height67fill parent7 android:stretch+olumns6717O N&able?oDO N&eGtVieD android:teGt673?):7 /O N$dit&eGt android:id67QRid/entrF7 android:laFout span67C7/O N/&able?oDO NVieD android:laFout height67>dip7
++3
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
android:background67S----997 /O N&able?oDO N4utton android:id67QRid/cancel7 android:laFout column67>7 android:teGt67+ancel7 /O N4utton android:id67QRid/ok7 android:teGt67"H7 /O N/&able?oDO N/&able)aFoutO
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 reBuires "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 2crollVieD,
2crollVieD
++6
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
an" still use your e;isting layout logi'. 1t Hust 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 2crollVieD use" in an FML layout &ile (&rom the +ontainers/2croll "emo),
NPGml version671.-7 encoding67utf-,7PO N2crollVieD Gmlns:android67http://schemas.android.com/apk/res/android7 android:laFout Didth67fill parent7 android:laFout height67Drap content7O N&able)aFout android:laFout Didth67fill parent7 android:laFout height67fill parent7 android:stretch+olumns67-7O N&able?oDO NVieD android:laFout height67,-dip7 android:background67S------7/O N&eGtVieD android:teGt67S------7 android:padding)eft67<dip7 android:laFout gravitF67center vertical7 /O N/&able?oDO N&able?oDO NVieD android:laFout height67,-dip7 android:background67S<<----7 /O N&eGtVieD android:teGt67S<<----7 android:padding)eft67<dip7 android:laFout gravitF67center vertical7 /O N/&able?oDO N&able?oDO NVieD android:laFout height67,-dip7 android:background67S,,<<--7 /O N&eGtVieD android:teGt67S,,<<--7 android:padding)eft67<dip7 android:laFout gravitF67center vertical7 /O N/&able?oDO N&able?oDO NVieD android:laFout height67,-dip7 android:background67Saa,,<<7 /O N&eGtVieD android:teGt67Saa,,<<7 android:padding)eft67<dip7 android:laFout gravitF67center vertical7 /O N/&able?oDO N&able?oDO NVieD android:laFout height67,-dip7 android:background67Sffaa,,7 /O
++8
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
N&eGtVieD android:teGt67Sffaa,,7 android:padding)eft67<dip7 android:laFout gravitF67center vertical7 /O N/&able?oDO N&able?oDO NVieD android:laFout height67,-dip7 android:background67Sffffaa7 /O N&eGtVieD android:teGt67Sffffaa7 android:padding)eft67<dip7 android:laFout gravitF67center vertical7 /O N/&able?oDO N&able?oDO NVieD android:laFout height67,-dip7 android:background67Sffffff7 /O N&eGtVieD android:teGt67Sffffff7 android:padding)eft67<dip7 android:laFout gravitF67center vertical7 /O N/&able?oDO N/&able)aFoutO N/2crollVieDO
Without the 2crollVieD, the table =oul" take up at least A40 pi;els (0 ro=s at 80 pi;els ea'h, base" on the VieD "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 2crollVieD 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,
++:
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
-oti'e ho= only &i!e ro=s an" part o& the si;th are !isible. 2y pressing the upQ"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" !oriKontal2crollVieD, =hi'h =orks like 2crollVieD... Hust horiLontally. 5his =oul" be goo" &or &orms that might be too =i"e rather than too tall. -ote that neither 2crollVieD nor !oriKontal2crollVieD =ill gi!e you bi-"ire'tional s'rolling S you ha!e to 'hoose !erti'al or horiLontal. Also, note that you 'annot put s'rollable items into a 2crollVieD. *or e;ample, a )istVieD =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 )istVieD in a 2crollVieD, an" i& you =ere to try, it =oul" not =ork !ery =ell.
+(;
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
CHAPTER 11
$rame*ork
An"roi" 1.A intro"u'e" the input metho" &rame=ork (1M*), =hi'h is 'ommonly re&erre" to as Nso&t keyboar"sN. +o=e!er, the Nso&t keyboar"N term is not ne'essarily a''urate, as 1M* 'oul" be use" &or han"=riting re'ognition or other means o& a''epting te;t input !ia the s'reen.
9eyboar s@ Har
an
Soft
%ome An"roi" "e!i'es ha!e a har"=are keyboar" that is !isible some o& the time (=hen it is sli" out). A &e= An"roi" "e!i'es ha!e a har"=are keyboar" that is al=ays !isible (so-'alle" NbarN or NslabN phones). Most An"roi" "e!i'es, though, ha!e no har"=are keyboar" at all. 5he 1M* han"les all o& these s'enarios. 1n short, i& there is no har"=are keyboar", an input metho" e"itor (1ME) =ill be a!ailable to the user =hen they tap on an enable" $dit&eGt. 5his reBuires no 'o"e 'hanges to your appli'ation...i& the "e&ault &un'tionality o& the 1ME is =hat you =ant. *ortunately, An"roi" is &airly smart about guessing =hat you =ant, so it may be you 'an Hust test =ith the 1ME but other=ise make no spe'i&i' 'o"e 'hanges. >& 'ourse, the keyboar" may not Buite beha!e ho= you =oul" like. *or e;ample, in the 4asic/9ield sample proHe't, the 9ield=emo a'ti!ity has the 1ME o!erlaying the multiple-line $dit&eGt,
+(+
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
$rame*ork
1t =oul" be ni'e to ha!e more 'ontrol o!er ho= this appears, an" &or other beha!ior o& the 1ME. *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.
Tailore
To /our ?ee s
An"roi" 1.1 an" earlier o&&ere" many attributes on $dit&eGt =i"gets to 'ontrol their style o& input, su'h as android:passDord to in"i'ate a &iel" shoul" be &or pass=or" entry (shrou"ing the pass=or" keystrokes &rom prying eyes). %tarting in An"roi" 1.A, =ith the 1M*, many o& these ha!e been 'ombine" into a single android:input&Fpe attribute. 5he android:input&Fpe attribute takes a 'lass plus mo"i&iers, in a pipe"elimite" list (=here W is the pipe 'hara'ter). 5he 'lass generally "es'ribes =hat the user is allo=e" to input, an" this "etermines the basi' set o& keys a!ailable on the so&t keyboar". 5he a!ailable 'lasses are,
teGt
(the "e&ault)
+((
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
$rame*ork
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 proHe't,
NPGml version671.-7 encoding67utf-,7PO N&able)aFout Gmlns:android67http://schemas.android.com/apk/res/android7 android:laFout Didth67fill parent7 android:laFout height67fill parent7 android:stretch+olumns6717 O N&able?oDO N&eGtVieD android:teGt67%o special rules:7 /O N$dit&eGt /O N/&able?oDO N&able?oDO N&eGtVieD android:teGt67$mail address:7 /O N$dit&eGt android:input&Fpe67teGtWteGt$mailAddress7 /O N/&able?oDO N&able?oDO N&eGtVieD android:teGt672igned decimal number:7 /O N$dit&eGt android:input&Fpe67numberWnumber2ignedWnumber=ecimal7 /O N/&able?oDO N&able?oDO N&eGtVieD android:teGt67=ate:7 /O N$dit&eGt android:input&Fpe67date7 /O N/&able?oDO N&able?oDO N&eGtVieD
+(.
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
$rame*ork
+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",
+('
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
$rame*ork
input metho
An email a""ress &iel" might put the Q symbol on the so&t keyboar", at the 'ost o& a smaller spa'ebar,
resses
+(1
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
$rame*ork
-ote, though, that this beha!ior is spe'i&i' to the input metho" e"itor. %ome e"itors might put an J sign on the primary keyboar" &or an email &iel". %ome might put a N.'omN button on the primary keyboar". %ome might not rea't at all. 1t is up to the implementation o& the input metho" e"itor S all you 'an "o is supply the hint. -umbers 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",
ecimal numbers
An" so on. 2y '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.
Tell !n roi
?ou may ha!e noti'e" a subtle "i&&eren'e bet=een the &irst an" se'on" input metho" e"itors, beyon" the a""ition o& the Q key. 1& you look in the
+(3
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
$rame*ork
lo=er-right 'orner o& the so&t keyboar", the se'on" &iel"7s e"itor has a N-e;tN 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 2y "e&ault, on an $dit&eGt =here you ha!e spe'i&ie" android:input&Fpe, the a''essory button =ill be N-e;tN, mo!ing you to the ne;t $dit&eGt in seBuen'e, or N@oneN, 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,
NPGml version671.-7 encoding67utf-,7PO N2crollVieD Gmlns:android67http://schemas.android.com/apk/res/android7 android:laFout Didth67fill parent7 android:laFout height67fill parent7 O N&able)aFout android:laFout Didth67fill parent7 android:laFout height67fill parent7 android:stretch+olumns6717 O N&able?oDO N&eGtVieD android:teGt67%o special rules:7 /O N$dit&eGt /O N/&able?oDO N&able?oDO N&eGtVieD android:teGt67$mail address:7 /O N$dit&eGt android:input&Fpe67teGtWteGt$mailAddress7 android:ime"ptions67action2end7 /O N/&able?oDO N&able?oDO
+(6
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
$rame*ork
N&eGtVieD android:teGt672igned decimal number:7 /O N$dit&eGt android:input&Fpe67numberWnumber2ignedWnumber=ecimal7 android:ime"ptions67action=one7 /O N/&able?oDO N&able?oDO N&eGtVieD android:teGt67=ate:7 /O N$dit&eGt android:input&Fpe67date7 /O N/&able?oDO N&able?oDO N&eGtVieD android:teGt67#ulti-line teGt:7 /O N$dit&eGt android:input&Fpe67teGtWteGt#ulti)ineWteGtAuto+orrect7 android:min)ines67C7 android:gravitF67top7 /O N/&able?oDO N/&able)aFoutO N/2crollVieDO
+ere, =e atta'h a N%en"N a'tion to the a''essory button &or the email a""ress (android:ime"ptions 6 7action2end7), an" the N@oneN a'tion on the mi""le &iel" (android:ime"ptions 6 7action=one7). 2y "e&ault, N-e;tN =ill mo!e the &o'us to the ne;t $dit&eGt an" N@oneN =ill 'lose up the input metho" e"itor. +o=e!er, &or those, or &or any other ones like N%en"N, you 'an use set"n$ditorAction)istenerLM on $dit&eGt (te'hni'ally, on the &eGtVieD super'lass) to get 'ontrol =hen the a''essory button is 'li'ke" or the user presses the N$nterO 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 reBuest (e.g., sen" an email to the supplie" email a""ress).
+(8
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
$rame*ork
$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 2crollVieD '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 appearsI 5here are three possibilities, "epen"ing on 'ir'umstan'es,
An"roi" 'an NpanN 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 $1. An"roi" 'an resiLe 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). 1n 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" resiLe mo"es "epen"ing on =hat your layout looks like. 1& you =ant to spe'i&i'ally 'hoose bet=een pan an" resiLe, you 'an "o so !ia an android:DindoD2oftInput#ode attribute on the NactivitFO element in your Android#anifest.Gml &ile. *or e;ample, here is the mani&est &rom I#$=emo>,
NPGml version671.-7 encoding67utf-,7PO Nmanifest android:version+ode6717 android:version%ame671.-7 package67com.commonsDare.android.imf.tDo7 Gmlns:android67http://schemas.android.com/apk/res/android7O Napplication android:icon67QdraDable/cD7 android:label67Qstring/app name7O NactivitF android:label67Qstring/app name7 android:name67.I#$=emo>7 +(:
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
$rame*ork
android:DindoD2oftInput#ode67adjust?esiKe7O Nintent-filterO Naction android:name67android.intent.action.#AI%7 /O NcategorF android:name67android.intent.categorF.)A3%+!$?7 /O N/intent-filterO N/activitFO N/applicationO Nsupports-screens android:anF=ensitF67true7 android:large2creens67true7 android:normal2creens67true7 android:small2creens67true7 /O N/manifestO
2e'ause =e spe'i&ie" resiLe, An"roi" =ill shrink our layout to a''ommo"ate the input metho" e"itor. With the 2crollVieD in pla'e, this means the s'roll bar =ill appear as nee"e",
+.;
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
$rame*ork
5o hi"e the e"itor, you =ill nee" to make a 'all to the Input#ethod#anager, a system ser!i'e that 'ontrols these input metho" e"itors,
Input#ethod#anager mgr6LInput#ethod#anagerMgetSystemSer!iceLI%(3& #$&!"= 2$?VI+$MJ mgr.hideSoftInput"rom#indowLfld.get#indowTokenLM8 -MJ
(=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. 1& 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. 1& 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., )istVieD), an" they long-tap on the ME-$ button, the input metho" e"itor shoul" appear 1& 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@indoDLM, instea" o& the sho=n in the pre!ious e;ample.
+.+
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
CHAPTER 1&
2a'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 Nget it rightN =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' $1 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 EallerF &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.
Well, no. At least, not in An"roi". At least not all o& the time. An"roi" is "esigne" to be use" =ith tou'hs'reen "e!i'es an" nontou'hs'reen "e!i'es. +istori'ally, An"roi" has been "ominate" by "e!i'es that only o&&ere" tou'hs'reens. +o=e!er, 8oogle 5. "e!i'es are not tou'hs'reens at present. An" some An"roi" "e!i'es o&&er both tou'hs'reens an" some other sort o& pointing "e!i'e S @-pa", tra'kball, arro= keys, et'. 5o a''ommo"ate both styles o& "e!i'e, An"roi" sometimes makes a "istin'tion bet=een sele'tion e!ents an" 'li'k e!ents. Wi"gets base" o&& o& the NspinnerN para"igm S in'lu"ing 2pinner an" EallerF S treat e!erything as sele'tion e!ents. >ther =i"gets S like )istVieD an" EridVieD S treat sele'tion e!ents an" 'li'k e!ents "i&&erently. *or these =i"gets, sele'tion e!ents are "ri!en by the pointing "e!i'e, su'h as using arro= keys to mo!e a highlight bar up an" "o=n a list. Cli'k e!ents are =hen the user either N'li'ksN the pointing "e!i'e (e.g., presses the 'enter @-pa" button) or taps on something in the =i"get using the tou'hs'reen.
the state o& the 'he'kbo;), you ine!itably =in" up 'alling set+ell?endererLM 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 1@ o& a !ie= to use (su'h as a built-in system resour'e 1@, as sho=n abo!e) 5he a'tual array or list o& items to sho=
2y "e&ault, the ArraFAdapter =ill in!oke to2tringLM on the obHe'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 &eGtVieD obHe'ts. 5hose &eGtVieD =i"gets, in turn, =ill be sho=n in the list or spinner or =hate!er =i"get uses this ArraFAdapter. 1& 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 Hust 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.
+.1
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
#ists of ?aughty an
?ice
5he 'lassi' listbo; =i"get in An"roi" is kno=n as )istVieD. 1n'lu"e one o& these in your layout, in!oke setAdapterLM to supply your "ata an" 'hil" !ie=s, an" atta'h a listener !ia set"nItem2elected)istenerLM to &in" out =hen the sele'tion has 'hange". With that, you ha!e a &ully-&un'tioning listbo;. +o=e!er, i& your a'ti!ity is "ominate" by a single list, you might =ell 'onsi"er 'reating your a'ti!ity as a sub'lass o& )istActivitF, rather than the regular ActivitF base 'lass. 1& your main !ie= is Hust the list, you "o not e!en nee" to supply a layout S )istActivitF =ill 'onstru't a &ull-s'reen list &or you. 1& you "o =ant to 'ustomiLe the layout, you 'an, so long as you i"enti&y your )istVieD as Qandroid:id/list, so )istActivitF kno=s =hi'h =i"get is the main list &or the a'ti!ity. *or e;ample, here is a layout pulle" &rom the 2election/)ist sample proHe't,
NPGml version671.-7 encoding67utf-,7PO N)inear)aFout Gmlns:android67http://schemas.android.com/apk/res/android7 android:orientation67vertical7 android:laFout Didth67fill parent7 android:laFout height67fill parent7 O N&eGtVieD android:id67QRid/selection7 android:laFout Didth67fill parent7 android:laFout height67Drap content7/O N)istVieD android:id67Qandroid:id/list7 android:laFout Didth67fill parent7 android:laFout height67fill parent7 android:draD2elector"n&op67false7 /O N/)inear)aFoutO
1t is Hust 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,
private static final 2tringAB items6:7lorem78 7ipsum78 7dolor78 7sit78 7amet78
+.3
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
7consectetuer78 7adipiscing78 7elit78 7morbi78 7vel78 7ligula78 7vitae78 7arcu78 7aliUuet78 7mollis78 7etiam78 7vel78 7erat78 7placerat78 7ante78 7porttitor78 7sodales78 7pellentesUue78 7augue78 7purus7;J Q"verride public void onCreateL4undle icicleM : super.onCreateLicicleMJ setContentViewL?.laFout.mainMJ setList$dapterLneD ArraFAdapterN2tringOLthis8 android.?.laFout.simple list item 18 itemsMMJ selection6L&eGtVieDMfindViewByIdL?.id.selectionMJ ; public void onListItemClickL)istVieD parent8 VieD v8 int position8 long idM : selection.setTextLitemsApositionBMJ ; ;
With )istActivitF, you 'an set the list a"apter !ia set)istAdapterLM 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+lickLM 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 resultsI
+.6
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
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
2y "e&ault, )istVieD 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. )istVieD 'an han"le that as =ell, but it reBuires a &e= 'hanges. *irst, you =ill nee" to 'all set+hoice#odeLM on the )istVieD in Ca!a 'o"e to set the 'hoi'e mo"e, supplying either +!"I+$ #"=$ 2I%E)$ or +!"I+$ #"=$ #3)&I()$ as the !alue. ?ou 'an get your )istVieD &rom a )istActivitF !ia get)istVieDLM. ?ou 'an also "e'lare this !ia the android:choice#ode attribute in your layout FML.
+.8
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
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 proHe't,
NPGml version671.-7 encoding67utf-,7PO N)istVieD Gmlns:android67http://schemas.android.com/apk/res/android7 android:id67Qandroid:id/list7 android:laFout Didth67fill parent7 android:laFout height67fill parent7 android:draD2elector"n&op67false7 android:choice#ode67multiple+hoice7 /O
1t is a &ull-s'reen )istVieD, =ith the android:choice#ode67multiple+hoice7 attribute to in"i'ate that =e =ant multiple 'hoi'e support. >ur a'ti!ity Hust 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.commonsDare.android.checklistJ import import import import android.os.4undleJ android.app.)istActivitFJ android.Didget.ArraFAdapterJ android.Didget.)istVieDJ
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 Q"verride public void onCreateL4undle icicleM : super.onCreateLicicleMJ setContentViewL?.laFout.mainMJ setList$dapterLneD ArraFAdapterN2tringOLthis8
+.:
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
; ;
What the user sees is the list o& =or"s =ith 'he'kbo;es "o=n the right e"ge,
1& =e =ante", =e 'oul" 'all metho"s like get+heckedItem(ositionsLM on our )istVieD to &in" out =hi'h items the user 'he'ke", or setItem+heckedLM i& =e =ante" to 'he'k (or un-'he'k) a spe'i&i' entry oursel!es.
+';
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
mo!e a highlight bar in the )istVieD), that triggers onItem2electedLM in an "nItem2elected)istener. Many times, parti'ularly i& the )istVieD is the entire $1 at present, you only 'are about 'li'ks. %ometimes, parti'ularly i& the )istVieD is a"Ha'ent to something else (e.g., on a 5., =here you ha!e more s'reen spa'e and "o not ha!e a tou'hs'reen), you =ill 'are more about sele'tion e!ents. Either =ay, you 'an get the e!ents you nee".
Spin Control
1n An"roi", the 2pinner is the eBui!alent o& the "rop-"o=n sele'tor you might &in" in other toolkits (e.g., J+ombo4oG in Ca!aQ%=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 =ithout taking up all the s'reen spa'e o& a )istVieD, at the 'ost o& an e;tra 'li'k or s'reen tap to make a 'hange. As =ith )istVieD, you pro!i"e the a"apter &or "ata an" 'hil" !ie=s !ia setAdapterLM an" hook in a listener obHe't &or sele'tions !ia set"nItem2elected)istenerLM. 1& 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=oDnVieD?esourceLM metho" to supply the resour'e 1@ o& the !ie= to use. *or e;ample, 'ulle" &rom the 2election/2pinner sample proHe't, here is an FML layout &or a simple !ie= =ith a 2pinner,
NPGml version671.-7 encoding67utf-,7PO N)inear)aFout Gmlns:android67http://schemas.android.com/apk/res/android7 android:orientation67vertical7 android:laFout Didth67fill parent7 android:laFout height67fill parent7 O N&eGtVieD
+'+
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
android:id67QRid/selection7 android:laFout Didth67fill parent7 android:laFout height67Drap content7 /O N2pinner android:id67QRid/spinner7 android:laFout Didth67fill parent7 android:laFout height67Drap content7 android:draD2elector"n&op67true7 /O N/)inear)aFoutO
5his is the same !ie= as sho=n in the pre!ious se'tion, Hust =ith a 2pinner instea" o& a )istVieD. 5he 2pinner property android:draD2elector"n&op 'ontrols =hether the arro=s are "ra=n on the sele'tor button on the right si"e o& the 2pinner $1. 5o populate an" use the 2pinner, =e nee" some Ca!a 'o"e,
public class 2pinner=emo eGtends ActivitF implements AdapterVieD."nItem2elected)istener : private &eGtVieD 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 Q"verride public void onCreateL4undle icicleM : super.onCreateLicicleMJ setContentViewL?.laFout.mainMJ selection6L&eGtVieDMfindViewByIdL?.id.selectionMJ 2pinner spin6L2pinnerMfindViewByIdL?.id.spinnerMJ spin.setOnItemSelectedListenerLthisMJ ArraFAdapterN2tringO aa6neD ArraFAdapterN2tringOLthis8 android.?.laFout.simple spinner item8 itemsMJ aa.setDropDownView%esourceL android.?.laFout.simple spinner dropdoDn itemMJ spin.set$dapterLaaMJ ; public void onItemSelectedLAdapterVieDNPO parent8 VieD v8 int position8 long idM : selection.setTextLitemsApositionBMJ ;
+'(
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
+ere, =e atta'h the a'ti!ity itsel& as the sele'tion listener (spin.set"nItem2elected)istenerLthisM), as 2pinner =i"gets only support sele'tion e!ents, not 'li'k e!ents 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=oDnVieD?esourceLM). Also note the use o& android.?.laFout.simple spinner item as the built-in VieD &or sho=ing items in the spinner itsel&. *inally, =e implement the 'allba'ks reBuire" by "nItem2elected)istener to a"Hust the sele'tion label base" on user input. What =e get is,
+'.
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
isplaye
Gri
As the name suggests, EridVieD gi!es you a t=o-"imensional gri" o& items to 'hoose &rom. ?ou ha!e mo"erate 'ontrol o!er the number an" siLe o& the 'olumnsT the number o& ro=s is "ynami'ally "etermine" base" on the number o& items the supplie" a"apter says are a!ailable &or !ie=ing. 5here are a &e= properties =hi'h, =hen 'ombine", "etermine the number o& 'olumns an" their siLes,
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.
+''
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
&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 EridVieD =orks mu'h like any other sele'tion =i"get S use setAdapterLM to pro!i"e the "ata an" 'hil" !ie=s, in!oke set"nItem2elected)istenerLM to register a sele'tion listener, et'. *or e;ample, here is an FML layout &rom the 2election/Erid sample proHe't, sho=ing a EridVieD 'on&iguration,
NPGml version671.-7 encoding67utf-,7PO N)inear)aFout Gmlns:android67http://schemas.android.com/apk/res/android7 android:orientation67vertical7 android:laFout Didth67fill parent7 android:laFout height67fill parent7 O N&eGtVieD android:id67QRid/selection7 android:laFout Didth67fill parent7 android:laFout height67Drap content7 /O NEridVieD android:id67QRid/grid7 android:laFout Didth67fill 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 /O N/)inear)aFoutO
*or this gri", =e take up the entire s'reen e;'ept &or =hat our sele'tion label reBuires. 5he number o& 'olumns is 'ompute" by An"roi" (android:num+olumns 6 7auto fit7) base" on our horiLontal spa'ing (android:horiKontal2pacing 6 7.dip7) an" 'olumns =i"th (android:column@idth 6 71--dip7), =ith the 'olumns absorbing any NslopN =i"th le&t o!er (android:stretch#ode 6 7column@idth7).
+'1
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
public class Erid=emo eGtends ActivitF implements AdapterVieD."nItem+lick)istener : private &eGtVieD 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 Q"verride public void onCreateL4undle icicleM : super.onCreateLicicleMJ setContentViewL?.laFout.mainMJ selection6L&eGtVieDMfindViewByIdL?.id.selectionMJ EridVieD g6LEridVieDM findViewByIdL?.id.gridMJ g.set$dapterLneD ArraFAdapterN2tringOLthis8 ?.laFout.cell8 itemsMMJ g.setOnItemClickListenerLthisMJ
public void onItemClickLAdapterVieDNPO parent8 VieD v8 int position8 long idM : selection.setTextLitemsApositionBMJ ;
5he gri" 'ells are "e&ine" by a separate res/laFout/cell.Gml &ile, re&eren'e" in our ArraFAdapter as ?.laFout.cell,
NPGml version671.-7 encoding67utf-,7PO N&eGtVieD Gmlns:android67http://schemas.android.com/apk/res/android7 android:laFout Didth67Drap content7 android:laFout height67Drap content7
+'3
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
android:teGt2iKe671<dip7 /O
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,
+'6
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
EridVieD,
like )istVieD, supports both 'li'k e!ents an" sele'tion e!ents. 1n this sample, =e register an "nItem+lick)istener to listen &or 'li'k e!ents.
+'8
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
1n a""ition, Auto+omplete&eGtVieD 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&eGtVieD an a"apter 'ontaining the list o& 'an"i"ate !alues !ia setAdapterLM. +o=e!er, sin'e the user 'oul" type something not in the list, Auto+omplete&eGtVieD "oes not support sele'tion listeners. 1nstea", 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. 2elo= =e ha!e a &amiliar-looking FML layout, this time 'ontaining an Auto+omplete&eGtVieD (pulle" &rom the 2election/Auto+omplete sample appli'ation),
NPGml version671.-7 encoding67utf-,7PO N)inear)aFout Gmlns:android67http://schemas.android.com/apk/res/android7 android:orientation67vertical7 android:laFout Didth67fill parent7 android:laFout height67fill parent7 O N&eGtVieD android:id67QRid/selection7 android:laFout Didth67fill parent7 android:laFout height67Drap content7 /O NAuto+omplete&eGtVieD android:id67QRid/edit7 android:laFout Didth67fill parent7 android:laFout height67Drap content7 android:completion&hreshold67C7/O N/)inear)aFoutO
+':
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
import android.Didget.Auto+omplete&eGtVieDJ import android.Didget.&eGtVieDJ public class Auto+omplete=emo eGtends ActivitF implements &eGt@atcher : private &eGtVieD selectionJ private Auto+omplete&eGtVieD 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 Q"verride public void onCreateL4undle icicleM : super.onCreateLicicleMJ setContentViewL?.laFout.mainMJ selection6L&eGtVieDMfindViewByIdL?.id.selectionMJ edit6LAuto+omplete&eGtVieDMfindViewByIdL?.id.editMJ edit.addTextChangedListenerLthisMJ edit.set$dapterLneD ArraFAdapterN2tringOLthis8 android.?.laFout.simple dropdoDn item 1line8 itemsMMJ ; public void onTextChangedL+har2eUuence s8 int start8 int before8 int countM : selection.setTextLedit.getTextLMMJ ; public void 'eforeTextChangedL+har2eUuence s8 int start8 int count8 int afterM : // needed for interface8 but not used ; public void afterTextChangedL$ditable sM : // needed for interface8 but not used ;
5his time, our a'ti!ity implements &eGt@atcher, =hi'h means our 'allba'ks are on&eGt+hangedLM, before&eGt+hangedLM, an" after&eGt+hangedLM. 1n this 'ase, =e are only intereste" in the &ormer, an" =e up"ate the sele'tion label to mat'h the Auto+omplete&eGtVieD7s 'urrent 'ontents. +ere =e ha!e the results,
+1;
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
$igure 3;2 The same application@ after a fe* matching letters *ere entere @ sho*ing the auto%complete rop% o*n
+1+
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
$igure 3+2 The same application@ after the auto%complete value *as selecte
android:spacing
the list
'ontrols =hat is use" to in"i'ate a sele'tion S this 'an either be a re&eren'e to a =raDable (see the resour'es 'hapter) or an 82 !alue in SAA??EE44 or similar notation
android:spinner2elector android:draD2elector"n&op in"i'ates i& the sele'tion bar (or =raDable) 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
+1.
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
CHAPTER 1/
5he humble )istVieD is one o& the most important =i"gets in all o& An"roi", simply be'ause it is use" so &reBuently. Whether 'hoosing a 'onta't to 'all or an email message to &or=ar" or an ebook to rea", )istVieD =i"gets are employe" in a =i"e range o& a'ti!ities. >& 'ourse, it =oul" be ni'e i& they =ere more than Hust 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.
+11
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
*or e;ample, suppose you =ant a )istVieD =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/roD.Gml in the 9ancF)ists/2tatic sample proHe't,
NPGml version671.-7 encoding67utf-,7PO N)inear)aFout Gmlns:android67http://schemas.android.com/apk/res/android7 android:laFout Didth67fill parent7 android:laFout height67Drap content7 android:orientation67horiKontal7 O NImageVieD android:id67QRid/icon7 android:padding67>dip7 android:laFout Didth67Drap content7 android:laFout height67Drap content7 android:src67QdraDable/ok7 /O N&eGtVieD android:id67QRid/label7 android:laFout Didth67Drap content7 android:laFout height67Drap content7 android:teGt2iKe67<-sp7 /O N/)inear)aFoutO
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. 2y "e&ault, though, An"roi" has no i"ea that you =ant to use this layout =ith your )istVieD. 5o make the 'onne'tion, you nee" to supply your Adapter =ith the resour'e 1@ o& the 'ustom layout sho=n abo!e,
public class 2tatic=emo eGtends )istActivitF : private &eGtVieD 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 Q"verride public void onCreateL4undle icicleM : super.onCreateLicicleMJ setContentViewL?.laFout.mainMJ setList$dapterLneD ArraFAdapterN2tringOLthis8 ?.laFout.roD8 ?.id.label8
+13
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
itemsMMJ selection6L&eGtVieDMfindViewByIdL?.id.selectionMJ
public void onListItemClickL)istVieD parent8 VieD v8 int position8 long idM : selection.setTextLitemsApositionBMJ ;
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.roD) an" that the &eGtVieD =here the =or" shoul" go is kno=n as ?.id.label =ithin that 'ustom layout. emember, to re&eren'e a layout ( roD.Gml), use ?.laFout as a pre&i; on the base name o& the layout FML &ile (?.laFout.roD). 5he result is a )istVieD =ith i'ons "o=n the le&t si"e. 1n parti'ular, all the i'ons are the same,
+16
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
! 0ynamic Presentation
5his te'hniBue 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= "ataI *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. 1n 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'. 1n parti'ular, it =ill nee" to o!erri"e getVieDLM. 5he getVieDLM metho" o& an Adapter is =hat an AdapterVieD (like )istVieD or 2pinner) 'alls =hen it nee"s the VieD asso'iate" =ith a gi!en pie'e o& "ata the Adapter is managing. 1n the 'ase o& an ArraFAdapter, getVieDLM is 'alle" as nee"e" &or ea'h position in the array S Nget me the VieD &or the &irst ro=N, Nget me the VieD &or the se'on" ro=N, et'. *or e;ample, let us re=ork the abo!e 'o"e to use getVieDLM, 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 proHe't),
package com.commonsDare.android.fancFlists.threeJ import import import import import import import import android.app.)istActivitFJ android.os.4undleJ android.vieD.VieDJ android.vieD.VieDEroupJ android.Didget.ArraFAdapterJ android.Didget.ImageVieDJ android.Didget.)istVieDJ android.Didget.&eGtVieDJ
public class =Fnamic=emo eGtends )istActivitF : &eGtVieD 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
+18
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
Q"verride public void onCreateL4undle icicleM : super.onCreateLicicleMJ setContentViewL?.laFout.mainMJ setList$dapterLneD Iconic$dapterLMMJ selection6L&eGtVieDMfindViewByIdL?.id.selectionMJ ; public void onListItemClickL)istVieD parent8 VieD v8 int position8 long idM : selection.setTextLitemsApositionBMJ ; class IconicAdapter eGtends ArraFAdapterN2tringO : Iconic$dapterLM : superL=Fnamic=emo.this8 ?.laFout.roD8 ?.id.label8 itemsMJ ; public VieD getViewLint position8 VieD convertVieD8 VieDEroup parentM : VieD roD6super.getViewLposition8 convertVieD8 parentMJ ImageVieD icon6LImageVieDMroD.findViewByIdL?.id.iconMJ if LitemsApositionB.lengthLMO<M : icon.setImage%esourceL?.draDable.deleteMJ ; else : icon.setImage%esourceL?.draDable.okMJ ; ; ; ; returnLroDMJ
>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 Hust passes to ArraFAdapter the same "ata =e use" in the ArraFAdapter 'onstru'tor in 2tatic=emo. %e'on", it has our getVieDLM implementation, =hi'h "oes t=o things, 1. 1t 'hains to the super'lass7 implementation o& getVieDLM, =hi'h returns to us an instan'e o& our ro= VieD, as prepare" by ArraFAdapter. 1n parti'ular, our =or" has alrea"y been put into the &eGtVieD, sin'e ArraFAdapter "oes that normally.
2. 1t &in"s our ImageVieD 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 (?.draDable.ok an" ?.draDable.delete).
+1:
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
+3;
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
the spe'i&ie" VieD 'lass, =alk the attributes, 'on!ert those into property setter 'alls, iterate o!er all 'hil" elements, lather, rinse, repeat. 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 VieDs &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 proHe't,
package com.commonsDare.android.fancFlists.threeGJ import import import import import import import import import android.app.)istActivitFJ android.os.4undleJ android.vieD.)aFoutInflaterJ android.vieD.VieDJ android.vieD.VieDEroupJ android.Didget.ArraFAdapterJ android.Didget.ImageVieDJ android.Didget.)istVieDJ android.Didget.&eGtVieDJ
public class =Fnamic=emo eGtends )istActivitF : &eGtVieD 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 Q"verride public void onCreateL4undle icicleM : super.onCreateLicicleMJ setContentViewL?.laFout.mainMJ setList$dapterLneD Iconic$dapterLMMJ selection6L&eGtVieDMfindViewByIdL?.id.selectionMJ ; public void onListItemClickL)istVieD parent8 VieD v8 int position8 long idM : selection.setTextLitemsApositionBMJ ; class IconicAdapter eGtends ArraFAdapterN2tringO : Iconic$dapterLM :
+3+
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
superL=Fnamic=emo.this8 ?.laFout.roD8 itemsMJ ; public VieD getViewLint position8 VieD convertVieD8 VieDEroup parentM : )aFoutInflater inflater6getLayoutInflaterLMJ VieD roD6inflater.inflateL?.laFout.roD8 parent8 falseMJ &eGtVieD label6L&eGtVieDMroD.findViewByIdL?.id.labelMJ label.setTextLitemsApositionBMJ ImageVieD icon6LImageVieDMroD.findViewByIdL?.id.iconMJ if LitemsApositionB.lengthLMO<M : icon.setImage%esourceL?.draDable.deleteMJ ; else : icon.setImage%esourceL?.draDable.okMJ ; returnLroDMJ ; ; ;
+ere =e in&late our ?.laFout.roD layout by use o& a )aFoutInflater obHe't, obtaine" &rom our ActivitF !ia get)aFoutInflaterLM. 5his gi!es us a VieD obHe't ba'k =hi'h, in reality, is our )inear)aFout =ith an ImageVieD an" a &eGtVieD, Hust as ?.laFout.roD spe'i&ies. +o=e!er, rather than ha!ing to 'reate all those obHe'ts oursel!es an" =ire them together, the FML an" )aFoutInflater han"le the Nhea!y li&tingN &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 ImageVieD i'on =i"get an" repla'e the sto'k resour'e =ith a "i&&erent one
+3(
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'hniBue 'oul" be use" to 'ustomiLe ro=s base" on any sort o& 'riteria.
;sin! convert>ie#
5he getVieDLM metho" re'ei!es, as one o& its parameters, a VieD name", by 'on!ention, convertVieD. %ometimes, convertVieD =ill be null. 1n those 'ases, you ha!e to 'reate a ne= ro= VieD &rom s'rat'h (e.g., !ia in&lation), Hust as =e "i" be&ore. +o=e!er, i& convertVieD is not null, then it is a'tually one o& your pre!iously-'reate" VieD obHe'ts: 5his =ill happen primarily =hen the user
+3.
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
s'rolls the )istVieD 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 findVieD4FIdLM to get at the in"i!i"ual =i"gets that make up your ro= an" 'hange their 'ontents, then return convertVieD &rom getVieDLM, rather than 'reate a =hole ne= ro=. *or e;ample, here is the getVieDLM implementation &rom last time, no= optimiLe" !ia convertVieD (&rom the 9ancF)ists/?ecFcling proHe't),
public VieD getViewLint position8 VieD convertVieD8 VieDEroup parentM : VieD roD6convertVieDJ if LroD66nullM : )aFoutInflater inflater6getLayoutInflaterLMJ ; roD6inflater.inflateL?.laFout.roD8 parent8 falseMJ
&eGtVieD label6L&eGtVieDMroD.findViewByIdL?.id.labelMJ label.setTextLitemsApositionBMJ ImageVieD icon6LImageVieDMroD.findViewByIdL?.id.iconMJ if LitemsApositionB.lengthLMO<M : icon.setImage%esourceL?.draDable.deleteMJ ; else : icon.setImage%esourceL?.draDable.okMJ ; ; returnLroDMJ
+ere, =e 'he'k to see i& the convertVieD is null an", i& so, =e then in&late our ro= S but i& it is not null, =e Hust 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. 1n &a't, a''or"ing to statisti's 'ite" by 8oogle at the 2010 8oogle 1U> 'on&eren'e, a )istVieD that uses a re'y'ling )istAdapter =ill per&orm 1A0M &aster than one that "oes not. 1n &a't, &or 'omple; ro=s, that might un"erstate the bene&it.
+3'
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
-ot 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& VieD S hol"s onto up to 2D2 o& "ata, not 'ounting things like images in ImageVieD =i"gets. Ea'h o& our ro=s, there&ore, might be as big as 4D2. *or our list o& 2A nonsense =or"s, 'onsuming as mu'h as 1A0D2 &or a non-re'y'ling list (2A ro=s at 4D2 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 4M2 o& AM, =oul" be a mu'h bigger issue. 2ear in min" that your appli'ation may only ha!e 14M2 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 VieD memory 'onsume" as is nee"e" &or the ro=s !isible on s'reen. -ote that ro= re'y'ling is only an issue i& =e are 'reating the ro=s oursel&. 1& =e let ArraFAdapter 'reate the ro=s, by le!eraging its implementation o& getVieDLM as sho=n in the 9ancF)ists/=Fnamic proHe't, then it "eals =ith the re'y'ling.
+31
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
5hat7s =here the hol"er pattern 'omes into play, in a 'lass =e7ll 'all VieD!older. All VieD obHe'ts ha!e get&agLM an" set&agLM metho"s. 5hese allo= you to asso'iate an arbitrary obHe't =ith the =i"get. What the hol"er pattern "oes is use that NtagN to hol" an obHe't that, in turn, hol"s ea'h o& the 'hil" =i"gets o& interest. 2y atta'hing that hol"er to the ro= VieD, 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 findVieD4FIdLM again. %o, let[s take a look at one o& these hol"er 'lasses (taken &rom the 9ancF)ists/VieD!older sample proHe't),
package com.commonsDare.android.fancFlists.fiveJ import android.vieD.VieDJ import android.Didget.ImageVieDJ class VieD!older : ImageVieD icon6nullJ View(olderLVieD baseM : this.icon6LImageVieDMbase.findViewByIdL?.id.iconMJ ;
hol"s onto the 'hil" =i"gets, initialiLe" !ia findVieD4FIdLM in its 'onstru'tor. 5he =i"gets are simply pa'kage-prote'te" "ata members, a''essible &rom other 'lasses in this proHe't...su'h as a VieD!older=emo a'ti!ity. 1n 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.
VieD!older
$sing VieD!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= VieD !ia set&agLM, as sho=n in this re=rite o& getVieDLM, &oun" in VieD!older=emo,
public VieD getViewLint position8 VieD convertVieD8 VieDEroup parentM : VieD roD6super.getViewLposition8 convertVieD8 parentMJ VieD!older holder6LVieD!olderMroD.getTagLMJ if Lholder66nullM :
+33
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
+ere, =e go ba'k to allo=ing ArraFAdapter to han"le our ro= in&lation an" re'y'ling &or us. 1& the 'all to get&agLM on the ro= returns null, =e kno= =e nee" to 'reate a ne= VieD!older, =hi'h =e then atta'h to the ro= !ia set&agLM &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 )istVieD is "isplaye", all ne= ro=s nee" to be in&late", an" =e =in" up 'reating a VieD!older &or ea'h. As the user s'rolls, ro=s get re'y'le", an" =e 'an reuse their 'orrespon"ing VieD!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 1A0M per&orman'e impro!ement, a""ing in a hol"er in'reases the impro!ement to 10AM. +en'e, =hile you may =ish to implement re'y'ling up &ront =hen you 'reate your a"apter, a""ing in a hol"er might be something you "eal =ith later, =hen you are =orking spe'i&i'ally on per&orman'e tuning. 1n this parti'ular 'ase, =e 'ertainly 'oul" simpli&y all o& this, by skipping VieD!older an" using get&agLM an" set&agLM =ith the ImageVieD "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 4o*s
Lists =ith pretty i'ons ne;t to them are all &ine an" =ell. 2ut, 'an =e 'reate )istVieD =i"gets =hose ro=s 'ontain intera'ti!e 'hil" =i"gets instea" o&
+36
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
Hust passi!e =i"gets like &eGtVieD an" ImageVieDI *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 listI 5here is goo" ne=s an" ba" ne=s. 5he goo" ne=s is that intera'ti!e =i"gets in ro=s =ork Hust &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 )istVieD 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 Hust a =i"get, use" in a ro= o& a )istVieD. 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. %o, let7s see ho= this is "one, using the a'ti!ity in the 9ancF)ists/?ate)ist sample proHe'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. 1n a""ition, =or"s gi!en a top rating are put in all 'aps,
package com.commonsDare.android.fancFlists.siGJ import import import import import import import import import import import import android.app.ActivitFJ android.os.4undleJ android.app.)istActivitFJ android.vieD.VieDJ android.vieD.VieDEroupJ android.vieD.)aFoutInflaterJ android.Didget.AdapterVieDJ android.Didget.ArraFAdapterJ android.Didget.?ating4arJ android.Didget.)inear)aFoutJ android.Didget.)istVieDJ android.Didget.&eGtVieDJ
+38
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
import 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 Q"verride public void onCreateL4undle icicleM : super.onCreateLicicleMJ ArraF)istN?oD#odelO list6neD ArraF)istN?oD#odelOLMJ for L2tring s : itemsM : list.addLneD %owModelLsMMJ ; setList$dapterLneD %ating$dapterLlistMMJ ; private ?oD#odel getModelLint positionM : returnLLL?atingAdapterMgetList$dapterLMM.getItemLpositionMMJ ; class ?atingAdapter eGtends ArraFAdapterN?oD#odelO : %ating$dapterLArraF)istN?oD#odelO listM : superL?ate)ist=emo.this8 ?.laFout.roD8 ?.id.label8 listMJ ; public VieD getViewLint position8 VieD convertVieD8 VieDEroup parentM : VieD roD6super.getViewLposition8 convertVieD8 parentMJ VieD!older holder6LVieD!olderMroD.getTagLMJ if Lholder66nullM : holder6neD View(olderLroDMJ roD.setTagLholderMJ ?ating4ar."n?ating4ar+hange)istener l6 neD ?ating4ar.On%atingBarChangeListenerLM : public void on%atingChangedL?ating4ar rating4ar8 float rating8 boolean from&ouchM : Integer mF(osition6LIntegerMrating4ar.getTagLMJ ?oD#odel model6getModelLmF(ositionMJ model.rating6ratingJ )inear)aFout parent6L)inear)aFoutMrating4ar.get)arentLMJ &eGtVieD label6L&eGtVieDMparent.findViewByIdL?.id.labelMJ
+3:
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
holder.rate.setOn%atingBarChangeListenerLlMJ
class ?oD#odel : 2tring labelJ float rating6>.-fJ %owModelL2tring labelM : this.label6labelJ ; public 2tring toStringLM : if LratingO6C.-M : returnLlabel.to*pperCaseLMMJ ; ; ; ; returnLlabelMJ
+ere is =hat is "i&&erent in this a'ti!ity an" getVieDLM 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& ?oD#odel obHe'ts. ?oD#odel is the mutable mo"el, it hol"s the nonsense =or" plus the 'urrent 'he'ke" state. 1n a real system, these might be obHe'ts populate" &rom a "atabase, an" the properties =oul" ha!e more business meaning.
2. $tility metho"s like on)istItem+lickLM ha" to be up"ate" to re&le't the 'hange &rom a pure-2tring mo"el to use a ?oD#odel. /. 5he ArraFAdapter sub'lass (?atingAdapter), in getVieDLM, lets ArraFAdapter in&late an" re'y'le the ro=, then 'he'ks to see i& =e
+6;
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
ha!e a VieD!older in the ro=7s tag. 1& not, =e 'reate a ne= VieD!older an" asso'iate it =ith the ro=. *or the ro=7s ?ating4ar, =e a"" an anonymous on?ating+hangedLM listener that looks at the ro=7s tag (get&agLM) 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 ?oD#odel &or the ro= an" up"ate the mo"el base" upon the ne= state o& the rating bar. 1t also up"ates the te;t a"Ha'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&agLM) pointing to the position in the a"apter the ro= is "isplaying. 5he ro= layout is !ery simple, Hust a ?ating4ar an" a &eGtVieD insi"e a )inear)aFout,
NPGml version671.-7 encoding67utf-,7PO N)inear)aFout Gmlns:android67http://schemas.android.com/apk/res/android7 android:laFout Didth67fill parent7 android:laFout height67Drap content7 android:orientation67horiKontal7 O N?ating4ar android:id67QRid/rate7 android:laFout Didth67Drap content7 android:laFout height67Drap content7 android:num2tars67C7 android:step2iKe6717 android:rating67>7 /O N&eGtVieD android:id67QRid/label7 android:padding67>dip7 android:teGt2iKe671,sp7 android:laFout gravitF67leftWcenter vertical7 android:laFout Didth67fill parent7 android:laFout height67Drap content7/O N/)inear)aFoutO
5he VieD!older is similarly simple, Hust e;tra'ting the ?ating4ar out o& the ro= VieD &or 'a'hing purposes,
package com.commonsDare.android.fancFlists.siGJ import android.vieD.VieDJ import android.Didget.?ating4arJ +6+
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
5his in'lu"es the toggle" rating bars turning their =or"s into all 'aps,
+6(
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
*or
+6.
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
CHAPTER 10
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.
Pick an
Choose
With limite"-input "e!i'es like phones, ha!ing =i"gets an" "ialogs that are a=are o& the type o& stu&& somebo"y is suppose" to be entering is !ery help&ul. 1t minimiLes keystrokes an" s'reen taps, plus re"u'es the 'han'e o& making some sort o& error (e.g., entering a letter somepla'e =here only numbers are e;pe'te"). As sho=n pre!iously, $dit&eGt has 'ontent-a=are &la!ors &or entering in numbers, phone numbers, et'. An"roi" also supports =i"gets ( =ate(icker, &ime(icker) an" "ialogs (=ate(icker=ialog, &ime(icker=ialog) &or helping users enter "ates an" times. 5he =ate(icker an" =ate(icker=ialog allo= you to set the starting "ate &or the sele'tion, in the &orm o& a year, month, an" "ay o& month !alue. -ote
+61
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
Containers
that the month runs &rom - &or Canuary through 11 &or @e'ember. Most importantly, both let you pro!i"e a 'allba'k obHe't ( "n=ate+hanged)istener or "n=ate2et)istener) =here you are in&orme" o& a ne= "ate sele'te" by the user. 1t 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"Hust, 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 AMQ#M toggle, or in 2<-hour mo"e (=hat in the $% is thought o& as Nmilitary timeN an" mu'h o& the rest o& the =orl" is thought o& as Nthe =ay times are suppose" to beN) pro!i"e 'allba'k obHe'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 proHe'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,
NPGml version671.-7 encoding67utf-,7PO N)inear)aFout Gmlns:android67http://schemas.android.com/apk/res/android7 android:orientation67vertical7 android:laFout Didth67fill parent7 android:laFout height67fill parent7 O N&eGtVieD android:id67QRid/dateAnd&ime7 android:laFout Didth67fill parent7 android:laFout height67Drap content7 /O N4utton android:id67QRid/date4tn7 android:laFout Didth67fill parent7 android:laFout height67Drap content7 android:teGt672et the =ate7 android:on+lick67choose=ate7 /O N4utton android:id67QRid/time4tn7 android:laFout Didth67fill parent7 android:laFout height67Drap content7
+63
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
Containers
public class +hrono=emo eGtends ActivitF : &eGtVieD dateAnd&ime)abelJ +alendar dateAnd&ime6+alendar.getInstanceLMJ Q"verride public void onCreateL4undle icicleM : super.onCreateLicicleMJ setContentViewL?.laFout.mainMJ dateAnd&ime)abel6L&eGtVieDMfindViewByIdL?.id.dateAnd&imeMJ ; updateLa'elLMJ
public void chooseDateLVieD vM : neD Date)ickerDialogL+hrono=emo.this8 d8 dateAnd&ime.getL+alendar.5$A?M8 dateAnd&ime.getL+alendar.#"%&!M8 dateAnd&ime.getL+alendar.=A5 "9 #"%&!MM .showLMJ ; public void chooseTimeLVieD vM : neD Time)ickerDialogL+hrono=emo.this8 t8 dateAnd&ime.getL+alendar.!"3? "9 =A5M8 dateAnd&ime.getL+alendar.#I%3&$M8 trueM .showLMJ ; private void updateLa'elLM : dateAnd&ime)abel .setTextL=ate3tils
+66
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
Containers
.formatDateTimeLthis8 dateAnd&ime.getTimeInMillisLM8 =ate3tils.9"?#A& 2!"@ =A&$W =ate3tils.9"?#A& 2!"@ &I#$MMJ ; =ate(icker=ialog."n=ate2et)istener d6neD =ate(icker=ialog.OnDateSetListenerLM : public void onDateSetL=ate(icker vieD8 int Fear8 int month"f5ear8 int daF"f#onthM : dateAnd&ime.setL+alendar.5$A?8 FearMJ dateAnd&ime.setL+alendar.#"%&!8 month"f5earMJ dateAnd&ime.setL+alendar.=A5 "9 #"%&!8 daF"f#onthMJ updateLa'elLMJ ; ;J : &ime(icker=ialog."n&ime2et)istener t6neD &ime(icker=ialog.OnTimeSetListenerLM public void onTimeSetL&ime(icker vieD8 int hour"f=aF8 int minuteM : dateAnd&ime.setL+alendar.!"3? "9 =A58 hour"f=aFMJ dateAnd&ime.setL+alendar.#I%3&$8 minuteMJ updateLa'elLMJ ; ; ;J
5he Nmo"elN &or this a'ti!ity is Hust a +alendar instan'e, initially set to be the 'urrent "ate an" time. 1n the update)abelLM metho", =e take the 'urrent +alendar, &ormat it using =ate3tils an" format=ate&imeLM, an" put it in the &eGtVieD. 5he ni'e thing about using An"roi"7s =ate3tils 'lass is that it =ill &ormat "ates an" times using the user7s 'hoi'e o& "ate &ormatting, "etermine" through the %ettings appli'ation. Ea'h button has a 'orrespon"ing metho" that =ill get 'ontrol =hen the user 'li'ks it (choose=ateLM an" choose&imeLM). When the button is 'li'ke", either a =ate(icker=ialog or a &ime(icker=ialog is sho=n. 1n 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. 1n 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.
+68
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
Containers
With all this =ire" together, the resulting a'ti!ity looks like this,
ate picker
ialog
+6:
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
Containers
ialog
-ote that An"roi" <.0 (1'e Cream %an"=i'h) 'hange" the "ialogs to remo!e the i'on an" go =ith a simple stati' N%et @ateN an" N%et 5imeN titles, rather than the "ynami'ally-a"Husting titles seen in earlier An"roi" releases.
+8;
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
Containers
O NAnalog+lock android:id67QRid/analog7 android:laFout Didth67fill parent7 android:laFout height67Drap content7 android:laFout center!oriKontal67true7 android:laFout align(arent&op67true7 /O N=igital+lock android:id67QRid/digital7 android:laFout Didth67Drap content7 android:laFout height67Drap content7 android:laFout center!oriKontal67true7 android:laFout beloD67Qid/analog7 /O N/?elative)aFoutO
Without any Ca!a 'o"e other than the generate" stub, =e 'an buil" this proHe't an" get the &ollo=ing a'ti!ity,
1& 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 startLM an" stopLM, an" possibly o!erri"e the &ormat string that "isplays the te;t,
+8+
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
Containers
(2; S09
Seeking 4esolution
5he 2eek4ar is an input =i"get, allo=ing the user to sele't a !alue along a range o& possible !alues,
+8(
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
Containers
(2; S09
5he user 'an either "rag the NthumbN 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#aGLM. ?ou 'an &in" out =hat the 'urrent position is !ia get(rogressLM, or &in" out =hen the user makes a 'hange to the thumb7s position by registering a listener !ia set"n2eek4ar+hange)istenerLM. We sa= another !ariation on this theme =ith the ?ating4ar in the pre!ious 'hapter.
Containers
1n a tra"itional $1, you might use tabs to a''omplish this en", su'h as a J&abbed(ane in Ca!aQ%=ing. 1n 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$1 toolkits re&er to NtabsN as being Hust the things a user 'li'ks on to toggle &rom one !ie= to another. %ome toolkits re&er to NtabsN 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 Ntab buttonsN an" Ntab 'ontentsN 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 MoLilla7s F$L takes. 1n 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,
NPGml version671.-7 encoding67utf-,7PO N&ab!ost Gmlns:android67http://schemas.android.com/apk/res/android7 android:id67QRid/tabhost7
+8'
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
Containers
android:laFout Didth67fill parent7 android:laFout height67fill parent7O N)inear)aFout android:orientation67vertical7 android:laFout Didth67fill parent7 android:laFout height67fill parent7O N&ab@idget android:id67Qandroid:id/tabs7 android:laFout Didth67fill parent7 android:laFout height67Drap content7 /O N9rame)aFout android:id67Qandroid:id/tabcontent7 android:laFout Didth67fill parent7 android:laFout height67fill parent7O NAnalog+lock android:id67QRid/tab17 android:laFout Didth67fill parent7 android:laFout height67fill parent7 /O N4utton android:id67QRid/tab>7 android:laFout Didth67fill parent7 android:laFout height67fill parent7 android:teGt67A semi-random button7 /O N/9rame)aFoutO N/)inear)aFoutO N/&ab!ostO
-ote 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. 1n this 'ase, there are t=o tabs, a 'lo'k an" a button. 1n 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 $1 pattern (a'ti!ity ma"e up entirely o& tabs) into a pattern-a=are a'ti!ity sub'lass. 1& you =ish to use the &abActivitF, you must gi!e the &ab!ost an android:id o& Qandroid:id/tabhost. Con!ersely, i& you "o not =ish to use &abActivitF, you nee" to get your &ab!ost !ia findVieD4FIdLM, then 'all setupLM 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"
+81
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
Containers
up in &ab2pec obHe'ts. ?ou get a &ab2pec instan'e &rom the host !ia neD&ab2pecLM, &ill it out, then a"" it to the host in the proper seBuen'e. 5he t=o key metho"s on &ab2pec are,
set+ontentLM, =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" setIndicatorLM,
=here you pro!i"e the 'aption &or the tab button an", in some &la!ors o& this metho", supply a =raDable to represent the i'on &or the tab
-ote that tab Nin"i'atorsN '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 setupLM on the &ab!ost be&ore 'on&iguring any o& these &ab2pec obHe'ts. 5he 'all to setupLM 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.commonsDare.android.fancFJ import android.app.ActivitFJ import android.os.4undleJ import android.Didget.&ab!ostJ public class &ab=emo eGtends ActivitF : Q"verride public void onCreateL4undle icicleM : super.onCreateLicicleMJ setContentViewL?.laFout.mainMJ &ab!ost tabs6L&ab!ostMfindViewByIdL?.id.tabhostMJ tabs.setupLMJ &ab!ost.&ab2pec spec6tabs.newTa'SpecL7tag17MJ spec.setContentL?.id.tab1MJ spec.setIndicatorL7+lock7MJ tabs.addTa'LspecMJ
+83
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
Containers
We &in" our &ab!ost !ia the &amiliar findVieD4FIdLM metho", then ha!e it setupLM. A&ter that, =e get a &ab2pec !ia neD&ab2pecLM, supplying a tag =hose purpose is unkno=n at this time. 8i!en the spe', you 'all set+ontentLM an" setIndicatorLM, then 'all add&abLM 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&abLM, pro!i"ing the --base" in"e; o& the tab. 5he resultI
$igure 6(2 The Tab0emo sample application@ sho*ing the first tab
+86
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
Containers
tab
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. 1n 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. +o=e!er, "oing it well reBuires a bit o& =ork. 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+ontentLM, one that takes a &ab!ost.&ab+ontent9actorF instan'e. 5his is Hust a 'allba'k that =ill be in!oke" S you pro!i"e an implementation o& create&ab+ontentLM an" use it to buil" an" return the VieD that be'omes the 'ontent o& the tab.
+88
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
Containers
5here are t=o tri'ky bits, though. *irst, by "e&ault, the tabs get smaller an" smaller as the user a""s more an" more o& them. E!entually, the tabs be'ome unrea"able. 5he solution &or this is to =rap the &ab@idget in a !oriKontal2crollVieD, =hi'h allo=s the tabs to remain their natural siLe an" lets the user s=ipe le&t an" right to !ie= all the tabs. +o=e!er, the "e&ault tab in"i'ators "o not =ork !ery =ell =hen use" =ith a &ab@idget in a !oriKontal2crollVieD, so =e =ill nee" to 'reate our o=n tab in"i'ators, =hi'h a""s some 'omple;ity to the pro'ess. 5o help 'lari&y all that, let us take a look at an e;ample ( 9ancF/=Fnamic&ab). *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,
NPGml version671.-7 encoding67utf-,7PO N&ab!ost Gmlns:android67http://schemas.android.com/apk/res/android7 android:id67QRid/tabhost7 android:laFout Didth67fill parent7 android:laFout height67fill parent7 O N)inear)aFout android:laFout Didth67fill parent7 android:laFout height67fill parent7 android:orientation67vertical7 O N!oriKontal2crollVieD android:id67QRid/scroll7 android:laFout Didth67fill parent7 android:laFout height67Drap content7 O N&ab@idget android:id67Qandroid:id/tabs7 android:laFout Didth67fill parent7 android:laFout height67Drap content7 /O N/!oriKontal2crollVieDO N9rame)aFout android:id67Qandroid:id/tabcontent7 android:laFout Didth67fill parent7 android:laFout height67fill parent7 O N4utton android:id67QRid/buttontab7 android:laFout Didth67fill parent7 android:laFout height67fill parent7 android:on+lick67add&ab7 android:teGt67A semi-random button7 /O N/9rame)aFoutO +8:
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
Containers
N/)inear)aFoutO N/&ab!ostO
5he other maHor "i&&eren'e, as note" abo!e, is that the &ab@idget is =rappe" in a !oriKontal2crollVieD. 5he on+reateLM metho" o& our a'ti!ity is mu'h the same as the pre!ious sample, e;'ept that =e only nee" to set up the one tab,
Q"verride public void onCreateL4undle icicleM : super.onCreateLicicleMJ setContentViewL?.laFout.mainMJ tabs6L&ab!ostMfindViewByIdL?.id.tabhostMJ tabs.setupLMJ &ab!ost.&ab2pec spec6tabs.newTa'SpecL7buttontab7MJ spec.setContentL?.id.buttontabMJ spec.setIndicatorL'uildTa'IndicatorL74utton7MMJ tabs.addTa'LspecMJ
public void addTa'LVieD vM : &ab!ost.&ab2pec spec6tabs.newTa'SpecL7tag17MJ spec.setContentLneD &ab!ost.Ta'Content"actoryLM : public VieD createTa'ContentL2tring tagM : returnLneD $nalogClockL=Fnamic&ab=emo.thisMMJ ; ;MJ spec.setIndicatorL'uildTa'IndicatorL7+lock7MMJ tabs.addTa'LspecMJ
1n our button7s add&abLM 'allba'k, =e 'reate a &ab!ost.&ab2pec obHe't an" gi!e it an anonymous &ab!ost.&ab+ontent9actorF. 5he &a'tory, in turn, returns the VieD to be use" &or the tab S in this 'ase, Hust an Analog+lock. 5he logi' &or 'onstru'ting the tab[s VieD 'oul" be mu'h more elaborate, su'h as using )aFoutInflater to 'onstru't a !ie= &rom layout FML. +o=e!er, note that our 'all to setIndicatorLM on the &ab2pec 'alls another pri!ate metho", build&abIndicatorLM,
+:;
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
Containers
private VieD 'uildTa'IndicatorL2tring msgM : VieD indicator6 getLayoutInflaterLM.inflateL?.laFout.tab indicator8 tabs.getTa'#idgetLM8 falseMJ &eGtVieD tv6L&eGtVieDMindicator.findViewByIdL?.id.titleMJ tv.setTextLmsgMJ returnLindicatorMJ ;
+ere, =e in&late a tab indicator layout resour'e, &in" a &eGtVieD insi"e it name" title, set the te;t o& that &eGtVieD to a supplie" !alue, an" return the in&late" layout. Where "i" =e get tab indicator &romI Well, =e nee" another layout resour'e &ile, one "e"i'ate" &or the tab in"i'ators. %pe'i&i'ally, =e use one 'ulle" &rom the An"roi" open sour'e 'o"e, =ith some minor pa""ing a"Hustments,
NPGml version671.-7 encoding67utf-,7PO NX-- +opFright L+M >--, &he Android "pen 2ource (roject )icensed under the Apache )icense8 Version >.- Lthe 7)icense7MJ Fou maF not use this file eGcept in compliance Dith the )icense. 5ou maF obtain a copF of the )icense at http://DDD.apache.org/licenses/)I+$%2$->.3nless reUuired bF applicable laD or agreed to in Driting8 softDare distributed under the )icense is distributed on an 7A2 I27 4A2I28 @I&!"3& @A??A%&I$2 "? +"%=I&I"%2 "9 A%5 HI%=8 either eGpress or implied. 2ee the )icense for the specific language governing permissions and limitations under the )icense. --O N?elative)aFout Gmlns:android67http://schemas.android.com/apk/res/android7 android:laFout Didth67-dip7 android:laFout height670<dip7 android:laFout Deight6717 android:laFout margin)eft67-Cdip7 android:laFout margin?ight67-Cdip7 android:orientation67vertical7 android:background67QdraDable/tab indicator7O NImageVieD android:id67QRid/icon7 android:laFout Didth67Drap content7 android:laFout height67Drap content7 android:laFout center!oriKontal67true7
+:+
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
Containers
/O N&eGtVieD android:id67QRid/title7 android:laFout Didth67Drap content7 android:laFout height67Drap content7 android:laFout align(arent4ottom67true7 android:laFout center!oriKontal67true7 android:padding?ight67,dp7 android:padding)eft67,dp7 stFle67Pandroid:attr/tab@idget2tFle7 /O N/?elative)aFoutO
?ou 'an &in" the original !ersion o& tab indicator.Gml in your An"roi" %@D S 'opies o& it =ill be insi"e ea'h o& the %@D !ersions &oun" in your platforms/ "ire'tory. 5he only mo"i&i'ation here is the a""ition o& the android:padding)eft an" android:padding?ight !alues on the &eGtVieD, to gi!e us a bit more room on the si"es, so the te;t "oes not run right up to the e"ges o& the tabs. -ote that the stFle attribute seen on that &eGtVieD =ill be e;plaine" in greater "etail later in the book. 1nitially, =hen the a'ti!ity is laun'he", =e Hust ha!e the one tab,
+:(
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
Containers
$igure 6'2 The 0ynamicTab application@ *ith the single initial tab
ynamically%create
tabs
+:.
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
Containers
An", i& =e 'li'k the button a lot more times, =e =ill see that =e 'an s'roll the tabs le&t an" right to !ie= all o& them,
ynamically%create
While in this 'ase =e a""e" ne= tabs base" on button 'li'ks, you 'oul" use any sort o& e!ent as the trigger &or a""ing a tab, long-tap on a )istVieD entry, options menu sele'tion, et'.
+:'
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
Containers
5he goo" ne=s is that the guts o& the !ie=-&lipping logi' &rom tabs 'an be &oun" in the VieD9lipper 'ontainer, =hi'h 'an be use" in other =ays than the tra"itional tab. inherits &rom 9rame)aFout, Hust like =e use" to "es'ribe the innar"s o& a &ab@idget. +o=e!er, initially, it Hust sho=s the &irst 'hil" !ie=. 1t is up to you to arrange &or the !ie=s to &lip, either manually by user intera'tion, or automati'ally !ia a timer.
VieD9lipper
*or e;ample, here is a layout &or a simple a'ti!ity ( 9ancF/9lipper1) using a 4utton an" a VieD9lipper,
NPGml version671.-7 encoding67utf-,7PO N)inear)aFout Gmlns:android67http://schemas.android.com/apk/res/android7 android:orientation67vertical7 android:laFout Didth67fill parent7 android:laFout height67fill parent7 O N4utton android:id67QRid/flip me7 android:laFout Didth67fill parent7 android:laFout height67Drap content7 android:teGt679lip #eX7 android:on+lick67flip7 /O NVieD9lipper android:id67QRid/details7 android:laFout Didth67fill parent7 android:laFout height67fill parent7 O N&eGtVieD android:laFout Didth67fill parent7 android:laFout height67Drap content7 android:teGt2tFle67bold7 android:teGt+olor67S99--99--7 android:teGt67&his is the first panel7 /O N&eGtVieD android:laFout Didth67fill parent7 android:laFout height67Drap content7 android:teGt2tFle67bold7 android:teGt+olor67S9999----7 android:teGt67&his is the second panel7 /O N&eGtVieD android:laFout Didth67fill parent7 android:laFout height67Drap content7 android:teGt2tFle67bold7 android:teGt+olor67S999999--7 android:teGt67&his is the third panel7
+:1
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
Containers
/O N/VieD9lipperO N/)inear)aFoutO
-oti'e that the layout "e&ines three 'hil" !ie=s &or the VieD9lipper, ea'h a &eGtVieD =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.commonsDare.android.flipper1J import import import import android.app.ActivitFJ android.os.4undleJ android.vieD.VieDJ android.Didget.VieD9lipperJ
public class 9lipper=emo eGtends ActivitF : VieD9lipper flipperJ Q"verride public void onCreateL4undle icicleM : super.onCreateLicicleMJ setContentViewL?.laFout.mainMJ ; flipper6LVieD9lipperMfindViewByIdL?.id.detailsMJ
5his is Hust a matter o& 'alling shoD%eGtLM on the VieD9lipper, like you 'an on any VieDAnimator 'lass. 5he result is a tri!ial a'ti!ity, 'li'k the button, an" the ne;t &eGtVieD in seBuen'e is "isplaye", =rapping aroun" to the &irst a&ter !ie=ing the last,
+:3
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
Containers
panel
5his, o& 'ourse, 'oul" be han"le" more simply by ha!ing a single &eGtVieD an" 'hanging the te;t an" 'olor on ea'h 'li'k. +o=e!er, you 'an imagine
+:6
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
Containers
that the VieD9lipper 'ontents 'oul" be mu'h more 'ompli'ate", like the 'ontents you might put into a &abVieD. As =ith the &ab@idget, sometimes, your VieD9lipper '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,
NPGml version671.-7 encoding67utf-,7PO N)inear)aFout Gmlns:android67http://schemas.android.com/apk/res/android7 android:orientation67vertical7 android:laFout Didth67fill parent7 android:laFout height67fill parent7 O NVieD9lipper android:id67QRid/details7 android:laFout Didth67fill parent7 android:laFout height67fill parent7 O N/VieD9lipperO N/)inear)aFoutO
-oti'e that the VieD9lipper 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 VieD9lipper '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 VieD9lipper to automati'ally rotate bet=een the 4utton =i"gets,
package com.commonsDare.android.flipper>J import import import import import import android.app.ActivitFJ android.os.4undleJ android.vieD.VieDJ android.vieD.VieDEroupJ android.Didget.4uttonJ android.Didget.VieD9lipperJ
public class 9lipper=emo> eGtends ActivitF : static 2tringAB items6:7lorem78 7ipsum78 7dolor78 7sit78 7amet78 7consectetuer78 7adipiscing78 7elit78
+:8
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
Containers
7morbi78 7vel78 7ligula78 7vitae78 7arcu78 7aliUuet78 7mollis78 7etiam78 7vel78 7erat78 7placerat78 7ante78 7porttitor78 7sodales78 7pellentesUue78 7augue78 7purus7;J VieD9lipper flipperJ Q"verride public void onCreateL4undle icicleM : super.onCreateLicicleMJ setContentViewL?.laFout.mainMJ flipper6LVieD9lipperMfindViewByIdL?.id.detailsMJ for L2tring item : itemsM : 4utton btn6neD ButtonLthisMJ btn.setTextLitemMJ flipper.addViewLbtn8 neD VieDEroup.Layout)aramsL VieDEroup.)aFout(arams.9I)) (A?$%&8 VieDEroup.)aFout(arams.9I)) (A?$%&MMJ ; flipper.set"lipInter!alL>---MJ flipper.start"lippingLMJ ; ;
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 VieD9lipper, =e set up the &lipper to automati'ally &lip bet=een 'hil"ren ( flipper.set9lipIntervalL>---MJ) an" to start &lipping (flipper.start9lippingLMJ). 5he result is an en"less series o& buttons, ea'h appearing, then being repla'e" by the ne;t button in seBuen'e a&ter 2 se'on"s, =rapping aroun" to the &irst a&ter the last has been sho=n,
+::
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
Containers
5he auto-&lipping VieD9lipper 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.
Containers
allo=s multiple =i"gets to sit atop ea'h other. ?elative)aFout an" 9rame)aFout satis&y this reBuirement, =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=raDer as an imme"iate 'hil" o& a )inear)aFout. +ere is a layout, sho=ing a 2liding=raDer in a 9rame)aFout, &rom the proHe't,
NPGml version671.-7 encoding67utf-,7PO N9rame)aFout Gmlns:android67http://schemas.android.com/apk/res/android7 android:laFout Didth67fill parent7 android:laFout height67fill parent7 android:background67S99<<<<++7 O N2liding=raDer android:id67QRid/draDer7 android:laFout Didth67fill parent7 android:laFout height67fill parent7 android:handle67QRid/handle7 android:content67QRid/content7O NImageVieD android:id67Qid/handle7 android:laFout Didth67Drap content7 android:laFout height67Drap content7 android:src67QdraDable/traF handle normal7 /O N4utton android:id67Qid/content7 android:laFout Didth67fill parent7 android:laFout height67fill parent7 android:teGt67IIm in hereX7 /O N/2liding=raDerO N/9rame)aFoutO
9ancF/=raDer=emo
5he 2liding=raDer shoul" 'ontain t=o things, 1. A han"le, &reBuently an ImageVieD or something along those lines, su'h as the one use" here, pulle" &rom the An"roi" open sour'e proHe't
2. 5he 'ontents o& the "ra=er itsel&, usually some sort o& 'ontainer, though in this 'ase =e are using a 4utton
(;+
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
Containers
Moreo!er, 2liding=raDer 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=raDer looks like 'lose", using the supplie" han"le,
(;(
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
Containers
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 (openLM, closeLM, an" toggleLM) an" ones that use the animation ( animate"penLM, animate+loseLM, animate&oggleLM). ?ou 'an also lockLM an" unlockLM 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 Ns'rolle"N (i.e., the user "rags or &lings the han"le) *or e;ample, the Laun'her7s 2liding=raDer toggles the i'on on the han"le &rom open to 'lose" to N"eleteN (i& you long-tap something on the "esktop). 1t a''omplishes this, in part, through 'allba'ks like these.
(;.
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
Containers
2liding=raDer
'an be !erti'al or horiLontal. -ote, though, that it keeps its orientation "espite the s'reen orientation. 1n other =or"s, i& you rotate the An"roi" "e!i'e or emulator running =raDer=emo, the "ra=er al=ays opens &rom the bottom S it "oes not al=ays Nsti'kN 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.
-ther Goo
Stuff
An"roi" o&&ers Absolute)aFout, =here the 'ontents are lai" out base" on spe'i&i' 'oor"inate positions. ?ou tell Absolute)aFout =here to pla'e a 'hil" in pre'ise F,? 'oor"inates, an" An"roi" puts it there, no Buestions aske". >n the plus si"e, this gi!es you pre'ise positioning. >n the minus si"e, it means your !ie=s =ill only look NrightN on s'reens o& a 'ertain "imension, or it reBuires you to =rite a bun'h o& 'o"e to a"Hust the 'oor"inates base" on s'reen siLe. %in'e An"roi" s'reens might run the gamut o& siLes, plus ha!e ne= siLes 'rop up perio"i'ally, using Absolute)aFout 'oul" get Buite annoying. Also, note that Absolute)aFout is o&&i'ially "epre'ate", meaning that =hile it is a!ailable to you, its use is "is'ourage". An"roi" also has the $Gpandable)istVieD. 5his pro!i"es a simpli&ie" tree representation, supporting t=o le!els o& "epth, groups an" 'hil"ren. 8roups 'ontain 'hil"renT 'hil"ren are Nlea!esN o& the tree. 5his reBuires a ne= set o& a"apters, sin'e the )istAdapter &amily "oes not pro!i"e any sort o& group in&ormation &or the items in the list. +ere are some other =i"gets a!ailable in An"roi" beyon" those 'o!ere" so &ar in this book,
+hecked&eGtVieD,
a &eGtVieD 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 EallerF,
a horiLontal s'rolling sele'tion =i"get, "esigne" &or thumbnail pre!ie=s o& images (e.g., 'amera photos, album 'o!ers)
(;'
Containers
#ultiAuto+omplete&eGtVieD,
like an Auto+omplete&eGtVieD, e;'ept that the user 'an make multiple 'hoi'es &rom the "rop-"o=n list, rather than Hust 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'.)
2Ditch, a t=o-state button =here the states are in"i'ate" by prose (N>-N, N>**N) that 'an be sli" le&t an" right to 'hange bet=een states
(an" the Image2Ditcher an" &eGt2Ditcher sub'lasses), like a simpli&ie" VieD9lipper &or toggling bet=een t=o !ie=s
VieD2Ditcher
(;1
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
CHAPTER 15
<mbe
>ther 8$1 toolkits let you use +5ML &or presenting in&ormation, &rom limite" +5ML ren"erers (e.g., Ca!aQ%=ing, =;Wi"gets) to embe""ing 1nternet E;plorer into .-E5 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.Debkit), though using the @ebVieD =i"get itsel& 'an be simple or po=er&ul, base" upon your reBuirements.
(;6
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
<mbe
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 eBually simple,
package com.commonsDare.android.broDser1J import android.app.ActivitFJ import android.os.4undleJ import android.Debkit.@ebVieDJ public class 4roDser=emo1 eGtends ActivitF : @ebVieD broDserJ Q"verride public void onCreateL4undle icicleM : super.onCreateLicicleMJ setContentViewL?.laFout.mainMJ broDser6L@ebVieDMfindViewByIdL?.id.DebkitMJ ; ; broDser.load*rlL7http://commonsDare.com7MJ
5he only thing unusual =ith this e"ition o& on+reateLM is that =e in!oke load3rlLM on the @ebVieD =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, reBuesting permission to a''ess the 1nternet,
NPGml version671.-7PO Nmanifest package67com.commonsDare.android.broDser17 Gmlns:android67http://schemas.android.com/apk/res/android7O Nuses-permission android:name67android.permission.I%&$?%$&7 /O Napplication android:icon67QdraDable/cD7O NactivitF android:label674roDser=emo17 android:name67.4roDser=emo17O Nintent-filterO Naction android:name67android.intent.action.#AI%7 /O NcategorF android:name67android.intent.categorF.)A3%+!$?7 /O N/intent-filterO N/activitFO N/applicationO Nsupports-screens android:anF=ensitF67true7 android:large2creens67true7 android:normal2creens67true7 (;8
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
<mbe
android:small2creens67true7 /O N/manifestO
1& =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, Hust =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. -o=, 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. 2y "e&ault Ca!as'ript is turne" o&& in @ebVieD =i"gets. 1& you =ant to enable Ca!as'ript, 'all get2ettingsLM.setJava2cript$nabledLtrueMJ
(;:
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
<mbe
on the @ebVieD instan'e. 5his notion =ill be 'o!ere" in a bit more "etail later in this 'hapter.
"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=ataLM. 5he simpler one allo=s you to pro!i"e the 'ontent, the M1ME type, an" the en'o"ing, all as strings. 5ypi'ally, your M1ME 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 load3rlLM in!o'ation in the pre!ious e;ample =ith the &ollo=ing,
broDser.loadDataL7NhtmlONbodFO!ello8 DorldXN/bodFON/htmlO78 7teGt/html78 73&9-,7MJ
?ou get,
(+;
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
<mbe
to go ba'k one step in the bro=ser history, an" canEo4ackLM to "etermine i& there is any history to go ba'k to
go4ackLM go9orDardLM to go &or=ar" one step in the bro=ser history, an" canEo9orDardLM to "etermine i& there is any history to go &or=ar" to
(++
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
<mbe
go4ack"r9orDardLM
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!eQnegati!e 'on!ention as go4ack"r9orDardLM)
canEo4ack"r9orDardLM
to 'lear the bro=ser resour'e 'a'he an" clear!istorFLM to 'lear the bro=sing history
clear+acheLM
et'.
A 'ommon hook =ill be should"verride3rl)oadingLM, =here your 'allba'k is passe" a $ L (plus the @ebVieD itsel&) an" you return true i& you =ill han"le the reBuest or false i& you =ant "e&ault han"ling (e.g., a'tually &et'h the Web page re&eren'e" by the $ L). 1n 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
(+(
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
<mbe
Intent
to ask An"roi" to loa" that page in a &ull bro=ser. 2ut, i& you ha!e inserte" a N&akeN $ L into the +5ML, representing a link to some a'ti!itypro!i"e" 'ontent, you 'an up"ate the @ebVieD yoursel&. *or e;ample, let7s amen" the &irst bro=ser e;ample to be a bro=ser-base" eBui!alent o& our original e;ample, an appli'ation that, upon a 'li'k, sho=s the 'urrent time. *rom @ebHit/4roDserC, here is the re!ise" Ca!a,
public class 4roDser=emoC eGtends ActivitF : @ebVieD broDserJ Q"verride public void onCreateL4undle icicleM : super.onCreateLicicleMJ setContentViewL?.laFout.mainMJ broDser6L@ebVieDMfindViewByIdL?.id.DebkitMJ broDser.set#e'ViewClientLneD Call'ackLMMJ loadTimeLMJ ; void loadTimeLM : 2tring page67NhtmlONbodFONa href6T7clockT7O7 RneD DateLM.toStringLM R7N/aON/bodFON/htmlO7J broDser.loadDataLpage8 7teGt/html78 73&9-,7MJ ; private class +allback eGtends @ebVieD+lient : public boolean shouldO!erride*rlLoadingL@ebVieD vieD8 2tring urlM : loadTimeLMJ ; ; ; returnLtrueMJ
+ere, =e loa" a simple Web page into the bro=ser ( load&imeLM) that 'onsists o& the 'urrent time, ma"e into a hyperlink to the /clock $ L. We also atta'h an instan'e o& a @ebVieD+lient sub'lass, pro!i"ing our implementation o& should"verride3rl)oadingLM. 1n this 'ase, no matter =hat the $ L, =e =ant to Hust reloa" the @ebVieD !ia load&imeLM.
(+.
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
<mbe
%ele'ting the link an" 'li'king the @-pa" 'enter button =ill N'li'kN the link, 'ausing us to rebuil" the page =ith the ne= time.
Settings@ Preferences@ an
With your &a!orite "esktop Web bro=ser, you ha!e some sort o& NsettingsN or Npre&eren'esN or NoptionsN =in"o=. 2et=een that an" the toolbar 'ontrols, you 'an t=eak an" t=i""le the beha!ior o& your bro=ser, &rom pre&erre" &onts to the beha!ior o& Ca!as'ript. %imilarly, you 'an a"Hust the settings o& your @ebVieD =i"get as you see &it, !ia the @eb2ettings instan'e returne" &rom 'alling the =i"get7s get2ettingsLM metho". 5here are lots o& options on @eb2ettings to play =ith. Most appear &airly esoteri' (e.g., set9antasF9ont9amilFLM). +o=e!er, here are some that you may &in" more use&ul,
(+'
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
<mbe
Control the &ont siLing !ia set=efault9ont2iKeLM (to use a point siLe) or set&eGt2iKeLM (to use 'onstants in"i'ating relati!e siLes like )A?E$? an" 2#A))$2&) Control Ca!as'ript !ia setJava2cript$nabledLM (to "isable it outright) an" setJava2cript+an"pen@indoDsAutomaticallFLM (to merely stop it &rom opening pop-up =in"o=s) Control Web site ren"ering !ia set3serAgentLM, 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.
(+1
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
CHAPTER 17
!pplying ,enus
Like appli'ations &or the "esktop an" some mobile operating systems, An"roi" supports a'ti!ities =ith Nappli'ationN 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$1 toolkits, you 'an 'reate N'onte;t menusN. >n a tra"itional 8$1, this might be triggere" by the right-mouse button. >n mobile "e!i'es, 'onte;t menus typi'ally appear =hen the user Ntaps-an"hol"sN o!er a parti'ular =i"get. *or e;ample, i& a &eGtVieD ha" a 'onte;t menu, an" the "e!i'e =as "esigne" &or &inger-base" tou'h input, you 'oul" push the &eGtVieD =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 Noptions menuN an" N'onte;t menuN. 5he options menu is triggere" by pressing the har"=are NMenu 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. 1n 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 NMenu button, the i'on mo"e =ill appear, sho=ing up to the &irst si; menu 'hoi'es as large, &inger(+6
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
!pplying ,enus
&rien"ly buttons in a gri" at the bottom o& the s'reen. 1& the menu has more than si; 'hoi'es, the si;th button =ill be'ome NMoreN 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+reateLM, the =ay you =ire up the rest o& your $1, you instea" nee" to implement on+reate"ptions#enuLM. 5his 'allba'k re'ei!es an instan'e o& #enu. 1& you =ill nee" to a"Hust the menu "uring your a'ti!ity7s use (e.g., "isable a no=-in!ali" menu 'hoi'e), Hust hol" onto the #enu instan'e you re'ei!e in on+reate"ptions#enuLM. >r, implement on(repare"ptions#enuLM, =hi'h is 'alle" Hust be&ore "isplaying the menu ea'h time it is reBueste". 8i!en that you ha!e re'ei!e" a #enu obHe't !ia on+reate"ptions#enuLM, you a"" menu 'hoi'es by 'alling addLM. 5here are many &la!ors o& this metho", =hi'h reBuire 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 setEroup+heckableLM (see belo=) A 'hoi'e i"enti&ier (also an int), &or use in i"enti&ying this 'hoi'e in the on"ptionsItem2electedLM '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=, Hust use %"%$ 5he te;t o& the menu 'hoi'e, as a %tring or a resour'e 1@
5he addLM &amily o& metho"s all return an instan'e o& #enuItem, =here you 'an a"Hust 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 NB=ertyN) set o&
(+8
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
!pplying ,enus
short'uts an" a numeri' set o& short'uts. 5hese are set in"i!i"ually by 'alling setAlphabetic2hortcutLM an" set%umeric2hortcutLM respe'ti!ely. 5he menu is pla'e" into alphabeti' short'ut mo"e by 'alling setYDertF#odeLM 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+heckableLM =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 #enuSsetEroup+heckableLM =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 N'he'ke"N state at any time
?ou 'an also 'reate &ly-out sub-menus by 'alling add2ub#enuLM, supplying the same parameters as add#enuLM. An"roi" =ill e!entually 'all on+reate(anel#enuLM, 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#enuLM, 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. 1& the user makes a menu 'hoi'e, your a'ti!ity =ill be noti&ie" !ia the on"ptionsItem2electedLM 'allba'k that a menu 'hoi'e =as sele'te". ?ou are gi!en the #enuItem obHe't 'orrespon"ing to the sele'te" menu 'hoi'e. A typi'al pattern is to sDitchLM on the menu 1@ (item.getItemIdLM) an" take appropriate beha!ior. -ote that on"ptionsItem2electedLM is use" regar"less o& =hether the 'hosen menu item =as in the base menu or in a submenu. >n'e you are "one 'on&iguring the menu, return by 'haining to the super'lass (returnLsuper.on+reate+onteGt#enuLmenuMMJ).
(+:
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
!pplying ,enus
,enus in Context
2y 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#enuLM &rom your a'ti!ity, supplying the VieD that is the =i"get nee"ing a 'onte;t menu. -e;t, you nee" to implement on+reate+onteGt#enuLM, =hi'h, among other things, is passe" the VieD you supplie" in register9or+onteGt#enuLM. ?ou 'an use that to "etermine =hi'h menu to buil", assuming your a'ti!ity has more than one. 5he on+reate+onteGt#enuLM metho" gets the +onteGt#enu itsel&, the VieD 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 'ustomiLe 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. 1t is also important to note that on+reate+onteGt#enuLM gets 'alle" &or ea'h time the 'onte;t menu is reBueste". $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 obHe'tT Hust 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+onteGtItem2electedLM on the a'ti!ity. -ote 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 uniBue 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#enuInfoLM on the #enuItem to get the +onteGt#enu.+onteGt#enuInfo you re'ei!e" in on+reate+onteGt#enuLM.
((;
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
!pplying ,enus
Taking a Peek
1n the sample proHe'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.
)istVieD
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)istN2tringO Dords6nullJ Q"verride public void onCreateL4undle icicleM : super.onCreateLicicleMJ init$dapterLMJ register"orContextMenuLgetListViewLMMJ ; ((+
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
!pplying ,enus
Q"verride public boolean onCreateOptionsMenuL#enu menuM : menu .addL#enu.%"%$8 #$%3 A==8 #enu.%"%$8 7Add7M .setIconL?.draDable.ic menu addMJ menu .addL#enu.%"%$8 #$%3 ?$2$&8 #enu.%"%$8 7?eset7M .setIconL?.draDable.ic menu refreshMJ returnLsuper.onCreateOptionsMenuLmenuMMJ ; Q"verride public void onCreateContextMenuL+onteGt#enu menu8 VieD v8 +onteGt#enu.+onteGt#enuInfo menuInfoM : menu.addL#enu.%"%$8 #$%3 +A(8 #enu.%"%$8 7+apitaliKe7MJ menu.addL#enu.%"%$8 #$%3 ?$#"V$8 #enu.%"%$8 7?emove7MJ ; Q"verride public boolean onOptionsItemSelectedL#enuItem itemM : sDitch Litem.getItemIdLMM : case #$%3 A==: addLMJ returnLtrueMJ case #$%3 ?$2$&: init$dapterLMJ returnLtrueMJ
; ;
returnLsuper.onOptionsItemSelectedLitemMMJ Q"verride public boolean onContextItemSelectedL#enuItem itemM : AdapterVieD.Adapter+onteGt#enuInfo info6 LAdapterVieD.Adapter+onteGt#enuInfoMitem.getMenuInfoLMJ ArraFAdapterN2tringO adapter6LArraFAdapterN2tringOMgetList$dapterLMJ sDitch Litem.getItemIdLMM : case #$%3 +A(: 2tring Dord6Dords.getLinfo.positionMJ Dord6Dord.to*pperCaseLMJ adapter.remo!eLDords.getLinfo.positionMMJ adapter.insertLDord8 info.positionMJ returnLtrueMJ case #$%3 ?$#"V$: adapter.remo!eLDords.getLinfo.positionMMJ
(((
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
!pplying ,enus
; ;
returnLtrueMJ
returnLsuper.onContextItemSelectedLitemMMJ private void init$dapterLM : Dords6neD ArraF)istN2tringOLMJ for L2tring s : itemsM : Dords.addLsMJ ; setList$dapterLneD ArraFAdapterN2tringOLthis8 android.?.laFout.simple list item 18 DordsMMJ
private void addLM : final VieD addVieD6getLayoutInflaterLM.inflateL?.laFout.add8 nullMJ neD Alert=ialog.BuilderLthisM .setTitleL7Add a @ord7M .setViewLaddVieDM .set)ositi!eButtonL7"H78 neD =ialogInterface.OnClickListenerLM : public void onClickL=ialogInterface dialog8 int Dhich4uttonM : ArraFAdapterN2tringO adapter6LArraFAdapterN2tringOMgetList$dapterLMJ $dit&eGt title6L$dit&eGtMaddVieD.findViewByIdL?.id.titleMJ ; adapter.addLtitle.getTextLM.toStringLMMJ
; ;
1n on+reateLM, =e register our )istVieD =i"get as ha!ing a 'onte;t menu. We also "elegate loa"ing the a"apter to an initAdapterLM 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#enuLM 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 1@s "e&ine" lo'ally as stati' "ata
((.
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
!pplying ,enus
members (#$%3 A== an" #$%3 ?$2$&), an" they also sport i'ons 'opie" out o& the An"roi" open sour'e proHe't. 1& the user "isplays the menu, it looks like this,
We also o!erri"e on"ptionsItem2electedLM, =hi'h =ill be 'alle" i& the user makes a 'hoi'e &rom the menu. 5he supplie" #enuItem has a getItemIdLM metho" that shoul" map to either #$%3 A== or #$%3 ?$2$&. 1n the 'ase o& #$%3 A==, =e 'all a pri!ate addLM metho" that "isplays an Alert=ialog =ith a 'ustom .ie= as its 'ontents, in&late" &rom res/laFout/add.Gml,
NPGml version671.-7 encoding67utf-,7PO N)inear)aFout Gmlns:android67http://schemas.android.com/apk/res/android7 android:orientation67horiKontal7 android:laFout Didth67fill parent7 android:laFout height67Drap content7 O N&eGtVieD android:teGt67@ord:7 android:laFout Didth67Drap content7 android:laFout height67Drap content7 /O N$dit&eGt
(('
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
!pplying ,enus
android:id67QRid/title7 android:laFout Didth67fill parent7 android:laFout height67Drap content7 android:laFout margin)eft67<dip7 /O N/)inear)aFoutO
%*or
ialog
1& the user 'li'ks the >D button, =e get our ArraFAdapter an" 'all addLM on it, a""ing the entere" =or" to the en" o& the list. 1& the user 'hooses #$%3 ?$2$&, =e 'all initAdapterLM 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#enuLM. >n'e again, =e "e&ine a pair o& menu items =ith lo'al 1@s, #$%3 +A( (to 'apitaliLe the longtappe"-upon =or") an" #$%3 ?$#"V$ (to remo!e the =or"). %in'e 'onte;t
((1
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
!pplying ,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#enu2electedLM. %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#enuInfoLM on the #enuItem an" 'ast the result to be an AdapterVieD.Adapter+onteGt#enuInfo. 5hat obHe'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 'apitaliLe or remo!e the =or", as reBueste".
)istVieD,
((3
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
!pplying ,enus
&or. 5his helps you keep your menu stru'ture separate &rom the 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 1nsi"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 1& 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, Hust as you "o =ith VieD layout FML
((6
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
!pplying ,enus
&itle
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., Qstring/foo).
+con
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., QdraDable/eject), use the android:icon attribute on the item element.
Order
2y "e&ault, the or"er o& the items in the menu is "etermine" by the or"er they appear in the menu FML. 1& 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 Hust to put the items in the FML in the or"er you =ant them to appear.
%na'led
1tems an" groups 'an be enable" or "isable", 'ontrolle" in the FML !ia the android:enabled attribute on the item or group element. 2y "e&ault, items an" groups are enable". @isable" items an" groups appear in the menu but
((8
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
!pplying ,enus
'annot be sele'te". ?ou 'an 'hange an item7s status at runtime !ia the set$nabledLM metho" on #enuItem, or 'hange a group7s status !ia setEroup$nabledLM on #enu.
,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. 2y "e&ault, items an" groups are !isible. 1n!isible items an" groups "o not appear in the menu at all. ?ou 'an 'hange an item7s status at runtime !ia the setVisibleLM metho" on #enuItem, or 'hange a group7s status !ia setEroupVisibleLM on #enu.
Shortcut
1tems '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.
((:
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
!pplying ,enus
5he Ca!a 'o"e is nearly i"enti'al, 'hanging mostly in the implementation o& on+reate"ptions#enuLM an" on+reate+onteGt#enuLM,
neD MenuInflaterLthisM.inflateL?.menu.option8 menuMJ ; returnLsuper.onCreateOptionsMenuLmenuMMJ
Q"verride public void onCreateContextMenuL+onteGt#enu menu8 VieD v8 +onteGt#enu.+onteGt#enuInfo menuInfoM : neD MenuInflaterLthisM.inflateL?.menu.conteGt8 menuMJ ; Q"verride
+ere, =e see ho= #enuInflater Npours inN the menu items spe'i&ie" in the menu resour'e (e.g., ?.menu.option) into the supplie" #enu or +onteGt#enu obHe't. We also nee" to 'hange on"ptionsItem2electedLM an" to use the android:id !alues spe'i&ie" in the FML,
on+onteGtItem2electedLM
Q"verride public boolean onOptionsItemSelectedL#enuItem itemM : sDitch Litem.getItemIdLMM : case ?.id.add: addLMJ returnLtrueMJ case ?.id.reset: init$dapterLMJ returnLtrueMJ
; ;
returnLsuper.onOptionsItemSelectedLitemMMJ QSuppress#arningsL7unchecked7M Q"verride public boolean onContextItemSelectedL#enuItem itemM : AdapterVieD.Adapter+onteGt#enuInfo info6 LAdapterVieD.Adapter+onteGt#enuInfoMitem.getMenuInfoLMJ ArraFAdapterN2tringO adapter6LArraFAdapterN2tringOMgetList$dapterLMJ sDitch Litem.getItemIdLMM : case ?.id.cap: 2tring Dord6Dords.getLinfo.positionMJ
(.;
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
!pplying ,enus
Dord6Dord.to*pperCaseLMJ adapter.remo!eLDords.getLinfo.positionMMJ adapter.insertLDord8 info.positionMJ returnLtrueMJ case ?.id.remove: adapter.remo!eLDords.getLinfo.positionMMJ returnLtrueMJ ; ; returnLsuper.onContextItemSelectedLitemMMJ
of ,enus an
Honey
An"roi" /.0 (a.k.a., +oney'omb) intro"u'e" a ne= look-an"-&eel &or An"roi" appli'ations, parti'ularly on tablets. >ptions menus in parti'ular 'hange &rom being something triggere" by some ME-$ button to a "rop"o=n menu &rom the Na'tion barN. *ortunately, this is ba'k=ar"s'ompatible, so your e;isting menus =ill not nee" to 'hange to a"opt this ne= look. 5he 'on'ept o& the ne= +oney'omb look is 'o!ere" later in this book, an" the a'tion bar itsel& is also 'o!ere" later in this book.
(.+
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
CHAPTER 18
%ometimes, your a'ti!ity (or other pie'e o& An"roi" 'o"e) =ill nee" to speak up. -ot 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. 2a'kgroun" tasks may take =ay longer than e;pe'te". %omething asyn'hronous may o''ur, su'h as an in'oming message. 1n 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 Buite a &e= systems &or letting you alert your users outsi"e the boun"s o& an ActivitF-base" $1. >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. 1n this 'hapter, you =ill see t=o means o& raising pop-up messages, toasts an" alerts.
4aising 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
(..
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 NeatenN 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&eGtLM that a''epts a 2tring (or string resour'e 1@) an" returns a &oast instan'e. 5he make&eGtLM metho" also nee"s the ActivitF (or other +onteGt) plus a "uration. 5he "uration is e;presse" in the &orm o& the )$%E&! 2!"?& or )$%E&! )"%E 'onstants to in"i'ate, on a relati!e basis, ho= long the message shoul" remain !isible. 1& you =oul" pre&er your &oast be ma"e out o& some other VieD, 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 setVieDLM to supply it =ith the !ie= to use an" set=urationLM to set the "uration. >n'e your &oast is 'on&igure", 'all its shoDLM metho", an" the message =ill be "isplaye". We =ill see an e;ample o& this in a'tion later in this 'hapter.
!lert! !lert!
1& 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 $1, 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
(.'
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
'on&igure an Alert=ialog, ea'h metho" returning the 4uilder &or easy 'haining. At the en", you 'all shoDLM on the buil"er to "isplay the "ialog bo;. Commonly-use" 'on&iguration metho"s on 4uilder in'lu"e,
i& you =ant the Nbo"yN o& the "ialog to be a simple te;tual message, &rom either a supplie" 2tring or a supplie" string resour'e 1@.
set#essageLM
an" setIconLM, to 'on&igure the te;t an"Qor i'on to appear in the title bar o& the "ialog bo;.
set&itleLM set(ositive4uttonLM, set%eutral4uttonLM, an" set%egative4uttonLM, 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).
1& you nee" to 'on&igure the Alert=ialog beyon" =hat the buil"er allo=s, instea" o& 'alling shoDLM, 'all createLM 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& shoDLM on the Alert=ialog itsel&. >n'e shoDLM is 'alle", the "ialog bo; =ill appear an" a=ait user input. -ote that pressing any o& the buttons =ill 'lose the "ialog, e!en i& you ha!e registere" a listener &or the button in Buestion. +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.
(.1
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
NPGml version671.-7 encoding67utf-,7PO N4utton Gmlns:android67http://schemas.android.com/apk/res/android7 android:id67QRid/alert7 android:teGt67?aise an alert7 android:laFout Didth67fill parent7 android:laFout height67fill parent7 android:on+lick67shoDAlert7 /O
5he layout is unremarkable S Hust a really large 4utton to sho= the Alert=ialog. When you 'li'k the 4utton, =e use a buil"er (neD 4uilderLthisM) to set the title (set&itleL7#essage=emo7M), message (set#essageL7)etIs raise a toastX7M), an" Nneutral buttonN (set%eutral4uttonL7!ear8 hearX78 neD "n+lick)istenerLM ...) 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&eGtLthis8 7Nclink8 clinkO78 )$%E&! 2!"?&M), =hi'h =e then shoDLM. 5he result is a typi'al "ialog bo;,
(.3
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
$igure 882 The ,essage0emo sample application@ after clicking the E4aise an alertE button
When you 'lose the "ialog !ia the button, it raises the toast,
(.6
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
$igure 8:2 The same application@ after clicking the E,ake a toastE button
(.8
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
CHAPTER 19
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 appli'ation 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" eBui!alent o& the N'ir'le o& li&eN S your appli'ation "ies so others may li!e, an" so on. ?ou 'annot assume that your appli'ation =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.
(.:
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 -oti&i'ation. Dead, either the a'ti!ity =as ne!er starte" (e.g., Hust a&ter a phone reset) or the a'ti!ity =as terminate", perhaps "ue the user pressing the 2ACD button.
#ife@ 0eath@ an
/our !ctivity
An"roi" =ill 'all into your a'ti!ity as the a'ti!ity transitions bet=een the &our states liste" abo!e. %ome transitions may result in multiple 'alls to your a'ti!ity, an" sometimes An"roi" =ill kill your appli'ation =ithout 'alling it. 5his =hole area is rather murky an" probably subHe't to 'hange, so pay 'lose attention to the o&&i'ial An"roi" "o'umentation as =ell as this se'tion =hen "e'i"ing =hi'h e!ents to pay attention to an" =hi'h you 'an sa&ely ignore. -ote that &or all o& these, you shoul" 'hain up=ar" an" in!oke the super'lass7 e"ition o& the metho", or An"roi" may raise an e;'eption.
(';
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
1.
When the a'ti!ity is &irst starte" (e.g., sin'e a system restart), on+reateLM =ill be in!oke" =ith a null parameter.
2. 1& the a'ti!ity ha" been running, then sometime later =as kille" o&&, on+reateLM =ill be in!oke" =ith the 4undle &rom on2aveInstance2tateLM as a parameter (see belo=). /. 1& 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+reateLM =ill be 'alle". +ere is =here you initialiLe 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=estroFLM may be 'alle" =hen the a'ti!ity is shutting "o=n, su'h as be'ause the a'ti!ity 'alle" finishLM (=hi'h N&inishesN the a'ti!ity) or the user presses the 2ACD button. +en'e, on=estroFLM is mostly &or 'leanly releasing resour'es you obtaine" in on+reateLM (i& any), plus making sure that anything you starte" up outsi"e o& li&e'y'le metho"s gets stoppe", su'h as ba'kgroun" threa"s.
('+
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
('(
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
5o make all this =ork, a'ti!ities nee" to be able to sa!e their appli'ationinstan'e state, an" to "o so Bui'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 &reBuently 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 on2aveInstance2tateLM. 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 Hust 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. 1n on+reateLM
2. 1n on?estoreInstance2tateLM 1t 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& on2aveInstance2tateLM =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 uniBuely i"enti&ie" !ia their android:id attributes. +en'e, i& you implement on2aveInstance2tateLM, 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" on2aveInstance2tateLM to be implemente" at all, as the built-in one han"les e!erything that is nee"e".
('.
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
(''
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
CHAPTER 1:
%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 reBuire" to make sure you ha!e layouts that look "e'ent on ea'h orientation.
! Philosophy of 0estruction
2y "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,
('1
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
>rientation 'hanges (i.e., rotating the s'reen) 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. 1t 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.
('3
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
android:on+lick67pick+ontact7 /O N4utton android:id67QRid/vieD7 android:laFout Didth67fill parent7 android:laFout height67fill parent7 android:laFout Deight6717 android:teGt67VieD7 android:enabled67false7 android:on+lick67vieD+ontact7 /O N/)inear)aFoutO
2asi'ally, it is a pair o& buttons, ea'h taking up hal& the s'reen. 1n portrait mo"e, the buttons are sta'ke"T in lan"s'ape mo"e, they are si"e-by-si"e. 1& you =ere to simply 'reate a proHe't, put in those t=o layouts, an" 'ompile it, the appli'ation =oul" appear to =ork Hust &ine S a rotation ( N+trlO-N91>O 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).
('6
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
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 N.ie=N 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?esultLM. 5his is a !ariation on startActivitFLM, "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?esultLM an" get ans=ers &rom any a'ti!ity you 'hoose. 1n 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 NsomethingN is "etermine" by the 3ri =e put in the 1ntent. 1n 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. 1n parti'ular, on An"roi" 2.0 an" higher, =e 'an use android.provider.+ontacts+ontract.+ontacts.+"%&$%& 3?I &or this purpose,
public void pickContactLVieD vM : Intent i6neD IntentLIntent.A+&I"% (I+H8 +ontacts.+"%&$%& 3?IMJ ; start$cti!ity"or%esultLi8 (I+H ?$Y3$2&MJ
*or
An"roi"
1.4
an"
separate
5he se'on" parameter to startActivitF9or?esultLM is an i"enti&ying number, to help us "istinguish this 'all to startActivitF9or?esultLM &rom any others =e might make.
('8
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
Calling startActivitF9or?esultLM =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 finishLM), an" 'ontrol returns to our a'ti!ity. At that point, our a'ti!ity is 'alle" =ith onActivitF?esultLM. An"roi" supplies us =ith three pie'es o& in&ormation, 1. 5he i"enti&ying number =e supplie" to startActivitF9or?esultLM, so =e 'an mat'h this result to its original reBuest
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 2ACD button) /. An 1ntent 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". 1n the 'ase o& an A+&I"% (I+H Intent &or the +ontacts.+"%&$%& 3?I, the returne" Intent has its o=n 3ri (!ia get=ataLM) that represents the 'hosen 'onta't. 1n the ?otation"ne e;ample, =e sti'k that in a "ata member o& the a'ti!ity an" enable the .ie= button,
protected void on$cti!ity%esultLint reUuest+ode8 int result+ode8 Intent dataM : if LreUuest+ode66(I+H ?$Y3$2&M : if Lresult+ode66?$23)& "HM : contact6data.getDataLMJ vieD4utton.set+na'ledLtrueMJ ; ; ;
1& the user 'li'ks the no=-enable" .ie= button, =e 'reate an A+&I"% VI$@ Intent on the 'onta't7s 3ri, an" 'all startActivitFLM on that Intent,
public void !iewContactLVieD vM : start$cti!ityLneD IntentLIntent.A+&I"% VI$@8 contactMMJ ;
(':
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
5his =ill bring up an An"roi"-supplie" a'ti!ity to !ie= "etails o& that 'onta't.
S vin! 2our St te
8i!en that =e ha!e use" startActivitF9or?esultLM to pi'k a 'onta't, no= =e nee" to hang onto that 'onta't =hen the s'reen orientation 'hanges. 1n the ?otation"ne e;ample, =e "o this !ia on2aveInstance2tateLM,
package com.commonsDare.android.rotation.oneJ 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.vieD.VieDJ android.Didget.4uttonJ
public class ?otation"ne=emo eGtends ActivitF : static final int (I+H ?$Y3$2&61CC/J 4utton vieD4utton6nullJ 3ri contact6nullJ Q"verride public void onCreateL4undle savedInstance2tateM : super.onCreateLsavedInstance2tateMJ setContentViewL?.laFout.mainMJ vieD4utton6L4uttonMfindViewByIdL?.id.vieDMJ restoreMeLsavedInstance2tateMJ ; vieD4utton.set+na'ledLcontactX6nullMJ
Q"verride protected void on$cti!ity%esultLint reUuest+ode8 int result+ode8 Intent dataM : if LreUuest+ode66(I+H ?$Y3$2&M : if Lresult+ode66?$23)& "HM : contact6data.getDataLMJ vieD4utton.set+na'ledLtrueMJ ; ; ; public void pickContactLVieD vM : Intent i6neD IntentLIntent.A+&I"% (I+H8 +ontacts.+"%&$%& 3?IMJ
(1;
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
public void !iewContactLVieD vM : start$cti!ityLneD IntentLIntent.A+&I"% VI$@8 contactMMJ ; Q"verride protected void onSa!eInstanceStateL4undle out2tateM : super.onSa!eInstanceStateLout2tateMJ if LcontactX6nullM : out2tate.putStringL7contact78 contact.toStringLMMJ ; ; private void restoreMeL4undle stateM : contact6nullJ if LstateX6nullM : 2tring contact3ri6state.getStringL7contact7MJ if Lcontact3riX6nullM : contact63ri.parseLcontact3riMJ ;
; ; ;
2y an" large, it looks like a normal a'ti!ity...be'ause it is. 1nitially, the Nmo"elN S a 3ri name" contact S is null. 1t is set as the result o& spa=ning the A+&I"% (I+H sub-a'ti!ity. 1ts string representation is sa!e" in on2aveInstance2tateLM an" restore" in restore#eLM ('alle" &rom on+reateLM). 1& the 'onta't is not null, the N.ie=N 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,
(1+
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
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#eLM 'all in on+reateLM an" try running the appli'ation. ?ou =ill see that the appli'ation N&orgetsN a 'onta't sele'te" in one orientation =hen you rotate the emulator or "e!i'e.
(1(
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
(1.
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
public class ?otation&Do=emo eGtends ActivitF : static final int (I+H ?$Y3$2&61CC/J 4utton vieD4utton6nullJ 3ri contact6nullJ Q"verride public void onCreateL4undle savedInstance2tateM : super.onCreateLsavedInstance2tateMJ setContentViewL?.laFout.mainMJ vieD4utton6L4uttonMfindViewByIdL?.id.vieDMJ restoreMeLMJ vieD4utton.set+na'ledLcontactX6nullMJ ; Q"verride protected void on$cti!ity%esultLint reUuest+ode8 int result+ode8 Intent dataM : if LreUuest+ode66(I+H ?$Y3$2&M : if Lresult+ode66?$23)& "HM : contact6data.getDataLMJ vieD4utton.set+na'ledLtrueMJ ; ; ; public void pickContactLVieD vM : Intent i6neD IntentLIntent.A+&I"% (I+H8 +ontacts.+"%&$%& 3?IMJ start$cti!ity"or%esultLi8 (I+H ?$Y3$2&MJ ; public void !iewContactLVieD vM : start$cti!ityLneD IntentLIntent.A+&I"% VI$@8 contactMMJ ; Q"verride public "bject on%etain&onConfigurationInstance LM : returnLcontactMJ ; private void restoreMeLM : contact6nullJ if LgetLast&onConfigurationInstance LMX6nullM : contact6L3riMgetLast&onConfigurationInstance LMJ ;
(1'
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
; ;
1n this 'ase, =e o!erri"e on?etain%on+onfigurationInstanceLM, returning the a'tual 3ri &or our 'onta't, rather than a string representation o& it. 1n turn, restore#eLM 'alls get)ast%on+onfigurationInstanceLM, an" i& it is not null, =e hol" onto it as our 'onta't an" enable the N.ie=N button. 5he a"!antage here is that =e are passing aroun" the 3ri rather than a string representation. 1n this 'ase, that is not a big sa!ings. 2ut 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.
0"/ 4otation
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 Nhi''upN 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 reBuires 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. 1mplement on+onfiguration+hangedLM in your ActivitF, =hi'h =ill be 'alle" =hen one o& the 'on&iguration 'hanges you liste" in android:config+hanges o''urs
(11
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
-o=, &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 $1 to "eal =ith the layout. 2ut &irst, =e nee" to make a small 'hange to our mani&est,
NPGml version671.-7 encoding67utf-,7PO Nmanifest android:version+ode6717 android:version%ame671.-.-7 package67com.commonsDare.android.rotation.three7 Gmlns:android67http://schemas.android.com/apk/res/android7O Nuses-sdk android:min2dkVersion67.7 android:target2dkVersion6707 /O Napplication android:icon67QdraDable/cD7 android:label67Qstring/app name7O NactivitF android:config+hanges67keFboard!iddenWorientation7 android:label67Qstring/app name7 android:name67.?otation&hree=emo7O Nintent-filterO Naction android:name67android.intent.action.#AI%7 /O NcategorF android:name67android.intent.categorF.)A3%+!$?7 /O N/intent-filterO N/activitFO N/applicationO Nsupports-screens android:anF=ensitF67true7 android:large2creens67true7 android:normal2creens67true7 android:small2creens67true7 /O N/manifestO
+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 NrotationN S =hether it is a sli"ing keyboar" or a physi'al rotation. -ote 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.
(13
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
public class ?otation&hree=emo eGtends ActivitF : static final int (I+H ?$Y3$2&61CC/J 4utton vieD4utton6nullJ 3ri contact6nullJ Q"verride public void onCreateL4undle savedInstance2tateM : super.onCreateLsavedInstance2tateMJ
(16
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
setContentViewL?.laFout.mainMJ vieD4utton6L4uttonMfindViewByIdL?.id.vieDMJ vieD4utton.set+na'ledLcontactX6nullMJ ; Q"verride protected void on$cti!ity%esultLint reUuest+ode8 int result+ode8 Intent dataM : if LreUuest+ode66(I+H ?$Y3$2&M : if Lresult+ode66?$23)& "HM : contact6data.getDataLMJ vieD4utton.set+na'ledLtrueMJ ; ; ; public void pickContactLVieD vM : Intent i6neD IntentLIntent.A+&I"% (I+H8 +ontacts.+"%&$%& 3?IMJ start$cti!ity"or%esultLi8 (I+H ?$Y3$2&MJ ; public void !iewContactLVieD vM : start$cti!ityLneD IntentLIntent.A+&I"% VI$@8 contactMMJ ; public void onConfigurationChangedL+onfiguration neD+onfigM : super.onConfigurationChangedLneD+onfigMJ )inear)aFout container6L)inear)aFoutMfindViewByIdL?.id.containerMJ if LneD+onfig.orientation66+onfiguration."?I$%&A&I"% )A%=2+A($M : container.setOrientationL)inear)aFout.!"?IV"%&A)MJ ; else : container.setOrientationL)inear)aFout.V$?&I+A)MJ ;
; ;
>ur on+onfiguration+hangedLM nee"s to up"ate the $1 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 obHe't =ill tell us ho= the "e!i'e is oriente".
(18
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
in any "esire" orientation, &or a'ti!ities =here this makes no sense, you 'an 'ontrol it. 5o blo'k An"roi" &rom rotating your a'ti!ity, all you nee" to "o is a"" android:screen"rientation 6 7portrait7 (or 7landscape7, as you pre&er) to your Android#anifest.Gml &ile, as sho=n belo= (&rom the ?otation/?otation9our sample proHe't),
NPGml version671.-7 encoding67utf-,7PO Nmanifest android:version+ode6717 android:version%ame671.-.-7 package67com.commonsDare.android.rotation.four7 Gmlns:android67http://schemas.android.com/apk/res/android7O Nuses-sdk android:min2dkVersion67.7 android:target2dkVersion6707 /O Napplication android:icon67QdraDable/cD7 android:label67Qstring/app name7O NactivitF android:label67Qstring/app name7 android:name67.?otation9our=emo7 android:screen"rientation67portrait7O Nintent-filterO Naction android:name67android.intent.action.#AI%7 /O NcategorF android:name67android.intent.categorF.)A3%+!$?7 /O N/intent-filterO N/activitFO N/applicationO Nsupports-screens android:anF=ensitF67true7 android:large2creens67true7 android:normal2creens67true7 android:small2creens67true7 /O N/manifestO
%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. -ote that the $1 "oes not mo!e a bit, but remains in portrait mo"e.
(3;
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
(3+
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
-ote 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. 1& 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 on2aveInstance2tateLM or on?etain%on+onfigurationInstanceLM to sa!e your a'ti!ity7s mutable state.
(3(
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
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 Nupsi"e "o=nN '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 NupN
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
(3.
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
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.
(31
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
5he Bueue is pro'esse" by one threa", !ariously 'alle" the Nmain appli'ation threa"N an" the N$1 threa"N. %o long as that threa" 'an keep 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+reateLM, on+lickLM, on)istItem+lickLM, 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 Bueue, 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" NAppli'ation -ot espon"ingN "ialog (A- &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 Bui'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,
1nternet 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 $1 &rom a ba'kgroun" threa". ?ou 'an only mo"i&y the $1 &rom the main appli'ation threa".
(33
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
+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 $1 using the main appli'ation threa". *ortunately, An"roi" pro!i"es a =i"e range o& tools to "o Hust that, an" these tools are the primary &o'us o& this 'hapter.
(36
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
%ess !es
5o sen" a #essage to a !andler, &irst in!oke obtain#essageLM to get the #essage obHe't out o& the pool. 5here are a &e= &la!ors o& obtain#essageLM, allo=ing you to Hust 'reate empty #essage obHe'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. 5hen, you sen" the #essage to the !andler !ia its message Bueue, using one o& the send#essage...LM &amily o& metho"s, su'h as,
send#essageLM
puts the message on the Bueue imme"iately, an" moreo!er puts it at the &ront o& the message Bueue (!ersus the ba'k, as is the "e&ault), so your message takes priority o!er all others
send#essageAt9ront"fYueueLM
puts the message on the Bueue at the state" time, e;presse" in the &orm o& millise'on"s base" on system uptime (2Fstem+lock.uptime#illisLM)
send#essageAt&imeLM
(38
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
send#essage=elaFedLM send$mptF#essageLM,
puts the message on the Bueue a&ter a "elay, e;presse" in millise'on"s =hi'h sen"s an empty #essage obHe't to the Bueue, allo=ing you to skip the obtain#essageLM step i& you =ere planning on lea!ing it empty any=ay
5o
these messages, your !andler nee"s to implement handle#essageLM, =hi'h =ill be 'alle" =ith ea'h message that appears on the message Bueue. 5here, the han"ler 'an up"ate the $1 as nee"e". +o=e!er, it shoul" still "o that =ork Bui'kly, as other $1 =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 proHe't,
NPGml version671.-7 encoding67utf-,7PO N)inear)aFout Gmlns:android67http://schemas.android.com/apk/res/android7 android:orientation67vertical7 android:laFout Didth67fill parent7 android:laFout height67fill parent7 O N(rogress4ar android:id67QRid/progress7 stFle67Pandroid:attr/progress4ar2tFle!oriKontal7 android:laFout Didth67fill parent7 android:laFout height67Drap content7 /O N/)inear)aFoutO
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 horiLontal bar sho=ing the amount o& =ork that has been 'omplete". An" here is the Ca!a,
package com.commonsDare.android.threadsJ import import import import import import android.app.ActivitFJ android.os.4undleJ android.os.!andlerJ android.os.#essageJ android.Didget.(rogress4arJ java.util.concurrent.atomic.Atomic4ooleanJ
(3:
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
public class !andler=emo eGtends ActivitF : (rogress4ar barJ !andler handler6neD (andlerLM : Q"verride public void handleMessageL#essage msgM : bar.increment)rogressByLmsg.arg1MJ ; ;J Atomic4oolean is?unning6neD $tomicBooleanLfalseMJ Q"verride public void onCreateL4undle icicleM : super.onCreateLicicleMJ setContentViewL?.laFout.mainMJ bar6L(rogress4arMfindViewByIdL?.id.progressMJ ; Q"verride public void on%esumeLM : super.on%esumeLMJ bar.set)rogressL-MJ &hread background6neD ThreadLneD %unna'leLM : public void runLM : trF : for Lint i6-JiN>- ZZ is?unning.getLMJiRRM : &hread.sleepL1---MJ #essage msg6handler.o'tainMessageLMJ msg.arg16.J msg.sendToTargetLMJ ; ; catch L&hroDable tM : // just end the background thread ;
; ;MJ
(6;
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
As part o& 'onstru'ting the ActivitF, =e 'reate an instan'e o& !andler, =ith our implementation o& handle#essageLM. 2asi'ally, &or any message re'ei!e", =e up"ate the (rogress4ar by a number o& points supplie" in the arg1 "ata member o& the #essage obHe't, then e;it the message han"ler. We then take a"!antage o& on(auseLM an" on?esumeLM. 1n on?esumeLM, =e set up a ba'kgroun" threa". 1n a real system, this threa" =oul" "o something meaning&ul. +ere, =e Hust sleep one se'on", post a #essage to the !andler (in"i'ating ho= &ar to a"!an'e the progress bar), an" repeat &or a total o& >passes. 5his =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"Hust that ma;imum !ia set#aGLM, 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=. -ote that =e then leave on?esumeLM. 5his is 'ru'ial. 5he on?esumeLM metho" is in!oke" on the a'ti!ity $1 threa", so it 'an up"ate =i"gets an" su'h. +o=e!er, that means =e nee" to get out o& on?esumeLM, 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 horiLontal progress bar,
(6+
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
-ote, though, that =hile (rogress4ar samples like this one sho= your 'o"e arranging to up"ate the progress on the $1 threa", &or this spe'i&i' =i"get, that is not ne'essary. At least as o& An"roi" 1.A, (rogress4ar is no= N$1 threa" sa&eN, in that you 'an up"ate it &rom any threa", an" it =ill han"le the "etails o& per&orming the a'tual $1 up"ate on the $1 threa".
Runn =les
1& you =oul" rather not &uss =ith #essage obHe'ts, you 'an also pass ?unnable obHe'ts to the !andler, =hi'h =ill run those ?unnable obHe'ts on the a'ti!ity $1 threa". !andler o&&ers a set o& post...LM metho"s &or passing ?unnable obHe'ts in &or e!entual pro'essing. 5he postLM metho" puts the ?unnable on the message Bueue &or e!entual pro'essing. post=elaFedLM =ill put the ?unnable on the Bueue &or pro'essing sometime a&ter a "elay perio" you spe'i&y. 5he ?unnable might not be e;e'ute" a&ter e;a'tly that "elay, as the main appli'ation threa" may be busy right then. Where possible, use static inner 'lasses (or separate stan"alone Ca!a 'lasses) &or your poste" ?unnable obHe'ts, to minimiLe the
(6(
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
'han'e o& temporary memory leaks i& the user presses 2ACD an" your a'ti!ity is "estroye". Cust as !andler supports postLM an" post=elaFedLM to a"" ?unnable obHe'ts to the e!ent Bueue, you 'an use those same metho"s on any VieD (i.e., any =i"get or 'ontainer). 5his slightly simpli&ies your 'o"e, in that you 'an then skip the !andler obHe't.
GoneG
%ometimes, you may not kno= i& you are 'urrently e;e'uting on the $1 threa" o& your appli'ation. *or e;ample, i& you pa'kage some o& your 'o"e in a CA &or others to reuse, you might not kno= =hether your 'o"e is being e;e'ute" on the $1 threa" or &rom a ba'kgroun" threa". 5o help 'ombat this problem, ActivitF o&&ers run"n3i&hreadLM. 5his =orks similarly to the postLM metho"s on !andler an" VieD, in that it Bueues up a ?unnable to run on the $1 threa"...i& you are not on the $1 threa" right no=. 1& you alrea"y are on the $1 threa", it in!okes the ?unnable imme"iately. 5his gi!es you the best o& both =orl"s, no "elay i& you are on the $1 threa", yet sa&ety in 'ase you are not.
!syncing $eeling
An"roi" 1.A intro"u'e" a ne= =ay o& thinking about ba'kgroun" operations, AsFnc&ask. 1n one (reasonably) 'on!enient 'lass, An"roi" =ill han"le all o& the 'hores o& "oing =ork on the $1 threa" !ersus on a ba'kgroun" threa". Moreo!er, An"roi" itsel& allo'ates an" remo!es that ba'kgroun" threa". An", it maintains a small =ork Bueue, &urther a''entuating the N&ire an" &orgetN &eel to AsFnc&ask.
The Theory
5here is a saying, popular in marketing 'ir'les, NWhen a man buys a 1Q<N "rill bit at a har"=are store, he "oes not =ant a 1Q<N "rill bit S he =ants 1Q<N
(6.
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
holesN. +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 $1 threa", so users are not stu'k =aiting an" a'ti!ities "o not get the "rea"e" Nappli'ation not respon"ingN (A- ) error. An" =hile An"roi" 'annot magi'ally 'ause =ork to not 'onsume $1 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 $1 threa" (e.g., up"ate progress) When nee"e", 'reate an instan'e o& the AsFnc&ask sub'lass an" 'all eGecuteLM 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 $1 threa"
5he type o& in&ormation that is nee"e" to pro'ess the task (e.g., $ Ls to "o=nloa")
(6'
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.
(61
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
Also, you may =ish to o!erri"e on(ost$GecuteLM. 5his metho" is 'alle", &rom the $1 threa", a&ter doIn4ackgroundLM 'ompletes. 1t re'ei!es, as a parameter, the !alue returne" by doIn4ackgroundLM (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(rogress3pdateLM. 1& doIn4ackgroundLM 'alls the task7s publish(rogressLM metho", the obHe't(s) passe" to that metho" are pro!i"e" to on(rogress3pdateLM, but in the $1 threa". 5hat =ay, on(rogress3pdateLM '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(rogress3pdateLM metho" =ill re'ei!e a !arargs o& the se'on" "ata type &rom the abo!e list S the "ata publishe" by doIn4ackgroundLM !ia publish(rogressLM. 1n a""ition,
A S mple T s$
As mentione" earlier, implementing an AsFnc&ask is not Buite 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"sQAsyn'er sample proHe't,
package com.commonsDare.android.asFncJ import import import import import import import android.app.)istActivitFJ android.os.AsFnc&askJ android.os.4undleJ android.os.2Fstem+lockJ android.Didget.ArraFAdapterJ android.Didget.&oastJ 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
(63
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
7porttitor78 7sodales78 7pellentesUue78 7augue78 7purus7;J Q"verride public void onCreateL4undle savedInstance2tateM : super.onCreateLsavedInstance2tateMJ setContentViewL?.laFout.mainMJ setList$dapterLneD ArraFAdapterN2tringOLthis8 android.?.laFout.simple list item 18 neD ArraF)istN2tringOLMMMJ neD $ddStringTaskLM.executeLMJ ; class Add2tring&ask eGtends AsFnc&askNVoid8 2tring8 VoidO : Q"verride protected Void doInBackgroundLVoid... unusedM : for L2tring item : itemsM : pu'lish)rogressLitemMJ 2Fstem+lock.sleepL>--MJ ; ; returnLnullMJ
QSuppress#arningsL7unchecked7M Q"verride protected void on)rogress*pdateL2tring... itemM : LLArraFAdapterN2tringOMgetList$dapterLMM.addLitemA-BMJ ; Q"verride protected void on)ost+xecuteLVoid unusedM : &oast .makeTextLAsFnc=emo.this8 7=oneX78 &oast.)$%E&! 2!"?&M .showLMJ ;
; ;
5his is another !ariation on the lorem ipsum list o& =or"s, use" &reBuently 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,
(66
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
+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 Ngenerate"N by our ba'kgroun" task to on(rogress3pdateLM, 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 doIn4ackgroundLM metho" is in!oke" in a ba'kgroun" threa". +en'e, =e 'an take as long as =e like. 1n 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(rogressLM &or ea'h, an" then sleep 200 millise'on"s to simulate real =ork being "one. %in'e =e ele'te" to ha!e no 'on&iguration in&ormation, =e shoul" not nee" parameters to doIn4ackgroundLM. +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 obHe't
(68
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
o& the thir" "ata type. %in'e that "ata type is Void, our returne" obHe't is null.
5he on(rogress3pdateLM metho" is 'alle" on the $1 threa", an" =e =ant to "o something to let the user kno= =e are progressing on loa"ing up these strings. 1n this 'ase, =e simply a"" the string to the ArraFAdapter, so it gets appen"e" to the en" o& the list. 5he on(rogress3pdateLM 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(rogressLM, =e only nee" to e;amine the &irst entry in the !arargs array.
5he on(ost$GecuteLM metho" is 'alle" on the $1 threa", an" =e =ant to "o something to in"i'ate that the ba'kgroun" =ork is 'omplete. 1n a real 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.
(6:
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
&he Activit!
neD $ddStringTaskLM.executeLMJ
5o use Add2tring&ask, =e simply 'reate an instan'e an" 'all eGecuteLM on it. 5hat starts the 'hain o& e!ents e!entually lea"ing to the ba'kgroun" threa" "oing its =ork. 1& Add2trings&ask reBuire" 'on&iguration parameters, =e =oul" ha!e not use" Void as our &irst "ata type, an" the 'onstru'tor =oul" a''ept Lero or more parameters o& the "e&ine" type. 5hose !alues =oul" e!entually be passe" to doIn4ackgroundLM.
&he #esults
1& you buil", install, an" run this proHe't, you =ill see the list being populate" in Nreal timeN o!er a &e= se'on"s, &ollo=e" by a &oast in"i'ating 'ompletion.
$igure :12 The !sync0emo@ part*ay through loa ing the list of *or s
(8;
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
Threa s an
4otation
>ne problem =ith the "e&ault "estroy-an"-'reate 'y'le that a'ti!ities go through on an orientation 'hange 'omes &rom ba'kgroun" threa"s. 1& the a'ti!ity has starte" some ba'kgroun" =ork S through an AsFnc&ask, &or e;ample S an" then the a'ti!ity is "estroye" an" re-'reate", someho= the AsFnc&ask nee"s to kno= about this. >ther=ise, the AsFnc&ask might =ell sen" up"ates an" &inal results to the old a'ti!ity, =ith the ne= a'ti!ity none the =iser. 1n &a't, the ne= a'ti!ity might start up the ba'kgroun" =ork again, =asting resour'es. >ne =ay to "eal =ith this is to "isable the "estroy-an"-'reate 'y'le, by taking o!er 'on&iguration 'hanges, as "es'ribe" in a pre!ious se'tion. Another alternati!e is to ha!e a smarter a'ti!ity an" AsFnc&ask. ?ou 'an see an e;ample o& that in the ?otation/?otationAsFnc sample proHe't. 5his proHe't uses a (rogress4ar, mu'h like the !andler "emo &rom earlier in this 'hapter. 1t also has a &eGtVieD to in"i'ate =hen the ba'kgroun" =ork is 'omplete", initially in!isible,
NPGml version671.-7 encoding67utf-,7PO N)inear)aFout Gmlns:android67http://schemas.android.com/apk/res/android7 android:orientation67vertical7 android:laFout Didth67fill parent7 android:laFout height67fill parent7 O N(rogress4ar android:id67QRid/progress7 stFle67Pandroid:attr/progress4ar2tFle!oriKontal7 android:laFout Didth67fill parent7 android:laFout height67Drap content7 /O N&eGtVieD android:id67QRid/completed7 android:laFout Didth67fill parent7 android:laFout height67Drap content7 android:teGt67@ork completedX7 android:visibilitF67invisible7 /O N/)inear)aFoutO
5he Nbusiness logi'N is &or an AsFnc&ask to "o some (&ake) =ork in the ba'kgroun", up"ating the (rogress4ar along the =ay, an" making the &eGtVieD !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",
(8+
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
We 'annot NloseN 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 $1 'orre'tly re&le't our =ork7s progress or 'ompletion
public class ?otationAsFnc eGtends ActivitF : private (rogress4ar bar6nullJ private ?otationADare&ask task6nullJ Q"verride public void onCreateL4undle savedInstance2tateM : (8(
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
super.onCreateLsavedInstance2tateMJ setContentViewL?.laFout.mainMJ bar6L(rogress4arMfindViewByIdL?.id.progressMJ task6L?otationADare&askMgetLast&onConfigurationInstance LMJ if Ltask66nullM : task6neD %otation$wareTaskLthisMJ task.executeLMJ ; else : task.attachLthisMJ update)rogressLtask.get)rogressLMMJ if Ltask.get)rogressLMO61--M : mark$sDoneLMJ ;
; ;
void update)rogressLint progressM : bar.set)rogressLprogressMJ ; void mark$sDoneLM : findViewByIdL?.id.completedM.setVisi'ilityLVieD.VI2I4)$MJ ; static class ?otationADare&ask eGtends AsFnc&askNVoid8 Void8 VoidO : ?otationAsFnc activitF6nullJ int progress6-J %otation$wareTaskL?otationAsFnc activitFM : attachLactivitFMJ ; Q"verride protected Void doInBackgroundLVoid... unusedM : for Lint i6-JiN>-JiRRM : 2Fstem+lock.sleepL.--MJ pu'lish)rogressLMJ ; ; returnLnullMJ
(8.
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
Q"verride protected void on)rogress*pdateLVoid... unusedM : if LactivitF66nullM : )og.wL7?otationAsFnc78 7on(rogress3pdateLM skipped [ no activitF7MJ ; else : progressR6.J activitF.update)rogressLprogressMJ ; ; Q"verride protected void on)ost+xecuteLVoid unusedM : if LactivitF66nullM : )og.wL7?otationAsFnc78 7on(ost$GecuteLM skipped [ no activitF7MJ ; else : activitF.mark$sDoneLMJ ; ; void detachLM : activitF6nullJ ; void attachL?otationAsFnc activitFM : this.activitF6activitFJ ; int get)rogressLM : returnLprogressMJ ;
; ;
%in'e =e =ant ?otationADare&ask to up"ate the 'urrent ?otationAsFnc ActivitF, =e supply that ActivitF =hen =e 'reate the task, !ia the 'onstru'tor. ?otationADare&ask also has attachLM an" detachLM metho"s to 'hange =hat ActivitF the task kno=s about, as =e =ill see shortly.
4lo# o1 Events
When ?otationAsFnc starts up &or the &irst time, it 'reates a ne= instan'e o& the ?otationADare&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.
(8'
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
-o=, suppose that "uring the mi""le o& the doIn4ackgroundLM pro'essing, the user rotates the s'reen. >ur ActivitF =ill be 'alle" =ith on?etain%on+onfigurationInstanceLM. +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 detachLM, 'ausing the task to set its ?otationAsFnc "ata member (activitF) to null.
2. We return the ?otationADare&ask obHe't, so that our ne= ?otationAsFnc instan'e 'an get a''ess to it E!entually, the ne= ?otationAsFnc instan'e =ill be 'reate". 1n on+reateLM, =e try to get a''ess to any 'urrent ?otationADare&ask instan'e !ia get)ast%on+onfigurationInstanceLM. 1& that =as null, then =e kno= that this is a ne=ly-'reate" a'ti!ity, an" so =e 'reate a ne= task. 1&, ho=e!er, get)ast%on+onfigurationInstanceLM returne" the task obHe't &rom the ol" ?otationAsFnc instan'e, =e hol" onto it an" up"ate our $1 to re&le't the 'urrent progress that has been ma"e. We also attachLM the ne= ?otationAsFnc to the ?otationADare&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.
(81
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
1n bet=een the 'all to on?etain%on+onfigurationInstanceLM instan'e o& the ol" a'ti!ity an" the 'ompletion o& on+reateLM o& the ne= a'ti!ity, the message Bueue is le&t alone. %o, let us suppose that, in bet=een on?etain%on+onfigurationInstanceLM a'ti!ity an" the subseBuent on+reateLM, our AsFnc&ask7s ba'kgroun" =ork 'ompletes. 5his =ill trigger on(ost$GecuteLM to be 'alle"...e!entually. +o=e!er, sin'e on(ost$GecuteLM is a'tually laun'he" &rom a message on the message Bueue, on(ost$GecuteLM =ill not be 'alle" until a&ter our on+reateLM has 'omplete". +en'e, our AsFnc&ask 'an keep running "uring the 'on&iguration 'hange, so long as =e "o t=o things, 1. 1n on+reateLM o& the ne= a'ti!ity instan'e, =e up"ate the AsFnc&ask to ha!e it =ork =ith our ne= a'ti!ity, rather than the ol" one
!n
2a'kgroun" threa"s, =hile eminently possible using the An"roi" !andler system, are not all happiness an" =arm puppies. 2a'kgroun" threa"s not only a"" 'omple;ity, but they ha!e real-=orl" 'osts in terms o& a!ailable memory, C#$, an" battery li&e. 5o that en", there is a =i"e range o& s'enarios you nee" to a''ount &or =ith your ba'kgroun" threa", in'lu"ing,
5he possibility that users =ill intera't =ith your a'ti!ity7s $1 =hile the ba'kgroun" threa" is 'hugging along. 1& 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".
(83
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
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 1nternet, the "e!i'e might lose 'onne'ti!ity. Alerting the user o& the problem !ia a -oti&i'ation an" shutting "o=n the ba'kgroun" threa" may be your best option.
(86
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
CHAPTER &1
"ntents an
$ilters
$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$1 !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 Nspe'ialN, in that it sho=s up in the laun'her, the other a'ti!ities all nee" to be rea'he"...someho=. 5he Nho=N is !ia intents. An intent is basi'ally a message that you pass to An"roi" saying, N?o: 1 =ant to "o...er...something: ?eah:N +o= spe'i&i' the NsomethingN 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. 1n 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 Ngoo" An"roi" 'itiLensN.
(8:
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
"ntents an
$ilters
Pieces o1 Intents
5he t=o most important pie'es o& an intent are the a'tion an" =hat An"roi" re&ers to as the N"ataN. 5hese are almost e;a'tly analogous to +55# !erbs an" $ Ls S the a'tion is the !erb, an" the N"ataN 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). 1& 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 1ntent obHe't), besi"es the a'tion an" N"ataN 3ri, su'h as,
(:;
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
"ntents an
$ilters
A 'ategory. ?our NmainN 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 M1ME 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. NE;trasN, =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. 1t "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 subHe't to 'hange. Content 3ri templates an" M1ME types are the pre&erre" =ays o& i"enti&ying ser!i'es you =ish thir"-party 'o"e to supply. 1& 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. -ote the use o& the plural Na'ti!itiesN, 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.
(:+
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
"ntents an
$ilters
2asi'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" M1ME 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.
(:(
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
"ntents an
$ilters
-ote the intent-filter element un"er the a'ti!ity element. +ere, =e "e'lare that this a'ti!ity,
1s the main a'ti!ity &or this appli'ation 1t is in the )A3%+!$? 'ategory, meaning it gets an i'on in the An"roi" main menu
2e'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 M1ME type o& "ata they =ork on. 5hen, i& an intent is targete" &or that M1ME 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,
NactivitF android:name67.&ourVieDActivitF7O Nintent-filterO Naction android:name67android.intent.action.VI$@7 /O NcategorF android:name67android.intent.categorF.=$9A3)&7 /O Ndata android:mime&Fpe67vnd.android.cursor.item/vnd.commonsDare.tour7 /O N/intent-filterO N/activitFO
5his a'ti!ity =ill get laun'he" by an intent reBuesting to !ie= a 3ri representing a vnd.android.cursor.item/vnd.commonsDare.tour pie'e o& 'ontent. 5hat Intent 'oul" 'ome &rom another a'ti!ity in the same appli'ation (e.g., the MA1- 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.
(:.
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
"ntents an
$ilters
?arro* 4eceivers
1n 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 -)
*or these 'ases, An"roi" o&&ers the re'ei!er, "e&ine" as a 'lass implementing the 4roadcast?eceiver inter&a'e. 2roa"'ast re'ei!ers are "isposable obHe'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?eceiveLM. 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 a re'ei!er, a"" a receiver element to your Android#anifest.Gml &ile,
Nreceiver android:name67.#FIntent?eceiver+lass%ame7 /O
An re'ei!er is only ali!e &or as long as it takes to pro'ess on?eceiveLM S as soon as that metho" returns, the re'ei!er instan'e is subHe'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 NhostN "oes (e.g., until the a'ti!ity is &roLen). +o=e!er, in this 'ase, you 'annot "e'lare the re'ei!er !ia Android#anifest.Gml. 1nstea", you nee" to 'all register?eceiverLM on your ActivitF7s on?esumeLM 'allba'k
(:'
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
"ntents an
$ilters
to "e'lare interest in an intent, then 'all unregister?eceiverLM &rom your ActivitF7s on(auseLM =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 N'aught upN on messages it misse" =hile it =as ina'ti!e, or ?our re'ei!er is registere" in the mani&est
(:1
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
CHAPTER &&
#aunching !ctivities
5he theory behin" the An"roi" $1 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".
(:6
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
#aunching !ctivities
Peers an
Subs
>ne key Buestion you nee" to ans=er =hen you "e'i"e to laun'h an a'ti!ity is, "oes your a'ti!ity nee" to kno= =hen the laun'he" a'ti!ity en"sI *or e;ample, suppose you =ant to spa=n an a'ti!ity to 'olle't authenti'ation in&ormation &or some Web ser!i'e you are 'onne'ting to S maybe you nee" to authenti'ate =ith >pen1@ in or"er to use an >Auth ser!i'e. 1n this 'ase, your main a'ti!ity =ill nee" to kno= =hen the authenti'ation is 'omplete so it 'an start to use the Web ser!i'e. >n the other han", imagine an email appli'ation in An"roi". When the user ele'ts to !ie= an atta'hment, neither you nor the user ne'essarily e;pe't the main a'ti!ity to kno= =hen the user is "one !ie=ing that atta'hment. 1n the &irst s'enario, the laun'he" a'ti!ity is 'learly subor"inate to the laun'hing a'ti!ity. 1n that 'ase, you probably =ant to laun'h the 'hil" as a sub-a'ti!ity, =hi'h means your a'ti!ity =ill be noti&ie" =hen the 'hil" a'ti!ity is 'omplete. 1n the se'on" s'enario, the laun'he" a'ti!ity is more a peer o& your a'ti!ity, so you probably =ant to laun'h the 6'hil"9 Hust as a regular a'ti!ity. ?our a'ti!ity =ill not be in&orme" =hen the 6'hil"9 is "one, but, then again, your a'ti!ity really "oes not nee" to kno=.
Start H<m =p
5he t=o pie'es &or starting an a'ti!ity are an intent an" your 'hoi'e o& ho= to start it up.
% $e n Intent
As "is'usse" in a pre!ious 'hapter, intents en'apsulate a reBuest, ma"e to An"roi", &or some a'ti!ity or other re'ei!er to "o something.
(:8
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
#aunching !ctivities
1& 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,
neD IntentLthis8 !elpActivitF.classMJ
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 reBuest it "ire'tly. >r, you 'oul" put together an intent &or some 3ri, reBuesting a parti'ular a'tion,
3ri uri63ri.parseL7geo:7Rlat.toStringLMR787Rlon.toStringLMMJ Intent i6neD IntentLIntent.A+&I"% VI$@8 uriMJ
+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 reBuesting 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 startActivitFLM =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?esultLM, passing it the Intent an" a number (uniBue 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?esultLM 'allba'k (see belo=).
(::
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
#aunching !ctivities
With startActivitF9or?esultLM, as note", you 'an implement the onActivitF?esultLM 'allba'k to be noti&ie" =hen the 'hil" a'ti!ity has 'omplete" its =ork. 5he 'allba'k re'ei!es the uniBue number supplie" to startActivitF9or?esultLM, 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?esultLM. 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,
NPGml version671.-7 encoding67utf-,7PO N)inear)aFout Gmlns:android67http://schemas.android.com/apk/res/android7 android:orientation67vertical7 android:laFout Didth67fill parent7 android:laFout height67fill parent7 O N&able)aFout android:laFout Didth67fill parent7 android:laFout height67Drap content7 android:stretch+olumns6718>7 O N&able?oDO N&eGtVieD android:laFout Didth67Drap content7 android:laFout height67Drap content7 android:padding)eft67>dip7 android:padding?ight67<dip7 android:teGt67)ocation:7 /O N$dit&eGt android:id67QRid/lat7 android:laFout Didth67fill parent7 android:laFout height67Drap content7 android:cursorVisible67true7 android:editable67true7 android:single)ine67true7
.;;
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
#aunching !ctivities
android:laFout Deight6717 /O N$dit&eGt android:id67QRid/lon7 android:laFout Didth67fill parent7 android:laFout height67Drap content7 android:cursorVisible67true7 android:editable67true7 android:single)ine67true7 android:laFout Deight6717 /O N/&able?oDO N/&able)aFoutO N4utton android:id67QRid/map7 android:laFout Didth67fill parent7 android:laFout height67Drap content7 android:teGt672hoD #eX7 android:on+lick67shoD#e7 /O N/)inear)aFoutO
5he button7s shoD#eLM '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.commonsDare.android.activitiesJ import import import import import import android.app.ActivitFJ android.content.IntentJ android.net.3riJ android.os.4undleJ android.vieD.VieDJ android.Didget.$dit&eGtJ
public class )aunch=emo eGtends ActivitF : private $dit&eGt latJ private $dit&eGt lonJ Q"verride public void onCreateL4undle icicleM : super.onCreateLicicleMJ setContentViewL?.laFout.mainMJ lat6L$dit&eGtMfindViewByIdL?.id.latMJ lon6L$dit&eGtMfindViewByIdL?.id.lonMJ ; public void showMeLVieD vM : 2tring lat6lat.getTextLM.toStringLMJ 2tring lon6lon.getTextLM.toStringLMJ 3ri uri63ri.parseL7geo:7R latR787R lonMJ start$cti!ityLneD IntentLIntent.A+&I"% VI$@8 uriMMJ
.;+
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
#aunching !ctivities
; ;
in
1& you &ill in a lo'ation (e.g., /8.8831 latitu"e an" -00.0<32 longitu"e) an" 'li'k the button, the resulting map is more interesting. -ote 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.
.;(
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
#aunching !ctivities
1n 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". -ote 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.
Tabbe
Bro*sing@ Sort -f
>ne o& the main &eatures o& the mo"ern "esktop Web bro=ser is tabbe" bro=sing, =here a single bro=ser =in"o= 'an sho= se!eral pages split a'ross a series o& tabs. >n a mobile "e!i'e, this may not make a lot o& sense, gi!en that you lose s'reen real estate &or the tabs themsel!es. 1n this book, ho=e!er, =e "o not let little things like sensibility stop us, so let us "emonstrate a tabbe" bro=ser, using &abActivitF an" Intent obHe'ts.
.;.
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
#aunching !ctivities
As you may re'all &rom the se'tion on tabbe" !ie=s &rom earlier in this book, a tab 'an ha!e a VieD as its 'ontents. 1t 'an also ha!e an ActivitF as its 'ontents. 1& 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 i6neD IntentLIntent.A+&I"% VI$@MJ i.setDataL3ri.parseL7http://commonsDare.com7MMJ
5hat =ay, you 'oul" use the built-in 2ro=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 @ebVieD "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 &abVieD,
package com.commonsDare.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.Debkit.@ebVieDJ android.Didget.&ab!ostJ
public class Intent&ab=emo eGtends &abActivitF : Q"verride public void onCreateL4undle savedInstance2tateM : super.onCreateLsavedInstance2tateMJ &ab!ost host6getTa'(ostLMJ Intent i6neD IntentLthis8 +@4roDser.classMJ i.put+xtraL+@4roDser.3?)8 7http://commonsDare.com7MJ host.addTa'Lhost.newTa'SpecL7one7M
.;'
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
#aunching !ctivities
; ;
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 1ntent that "ire'tly re&ers to another 'lass. 1n this 'ase, our t=o tabs =ill ea'h host a +@4roDser, =ith a $ L to loa" supplie" !ia an Intent e;tra. 5he +@4roDser a'ti!ity is simple mo"i&i'ation to the earlier bro=ser "emos,
package com.commonsDare.android.intenttabJ import import import import import android.app.ActivitFJ android.content.IntentJ android.net.3riJ android.os.4undleJ android.Debkit.@ebVieDJ
public class +@4roDser eGtends ActivitF : public static final 2tring 3?)67com.commonsDare.android.intenttab.3?)7J private @ebVieD broDserJ Q"verride public void onCreateL4undle icicleM : super.onCreateLicicleMJ broDser6neD #e'ViewLthisMJ setContentViewLbroDserMJ broDser.load*rlLgetIntentLM.getString+xtraL3?)MMJ ; ;
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 $1 sho=s =hat tabbe" bro=sing 'oul" look like on An"roi",
.;1
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
#aunching !ctivities
$igure :82 The "ntentTab0emo sample application@ sho*ing the first tab
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" Hust to populate tabs in a &ab!ost. 1n parti'ular, it in'reases the amount o& sta'k spa'e nee"e" by your
.;3
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
#aunching !ctivities
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.
.;6
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
CHAPTER &/
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 &reBuently 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.
1mages (res/draDable/), &or putting stati' i'ons or other pi'tures in a user inter&a'e a= (res/raD/), &or putting arbitrary &iles that ha!e meaning to your appli'ation but not ne'essarily to An"roi" &rame=orks
.;:
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 internationaliLation an" lo'aliLation) 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. 1n parti'ular, it helps =ith internationaliLation (118-) an" lo'aliLation (L10-), '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;ternaliLe" strings, along =ith Nstring &ormatsN, =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" Nstyle" te;tN, 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 uniBue name &or this string, an" a single te;t element 'ontaining the te;t o& the string,
NresourcesO Nstring name67Uuick7O&he Uuick broDn foG...N/stringO Nstring name67laughs7O!e Dho laughs last...N/stringO N/resourcesO
5he only tri'ky part is i& the string !alue 'ontains a Buote ( 7) or an apostrophe (I). 1n those 'ases, you =ill =ant to es'ape those !alues, by
.+;
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
pre'e"ing them =ith a ba'kslash (e.g., &hese are the times that trF menTIs souls). >r, i& it is Hust an apostrophe, you 'oul" en'lose the !alue in Buotes (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 Qstring/..., =here the ellipsis is the uniBue name S e.g., Qstring/laughs). >r you 'an get the string &rom your Ca!a 'o"e by 'alling get2tringLM =ith the resour'e 1@ o& the string resour'e, that being the uniBue name pre&i;e" =ith ?.string. (e.g., get2tringL?.string.UuickM).
Strin! 4orm 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 str9ormat6getStringL?.string.mF nameMJ 2tring str?esult62tring.formatLstr9ormat8 7&im7MJ LL&eGtVieDMfindViewByIdL?.id.some labelMM.setTextLstr?esultMJ
5here is also a &la!or o& get2tringLM that "oes the 2tring.formatLM 'all &or you,
2tring str?esult6getStringL?.string.mF name8 7&im7MJ LL&eGtVieDMfindViewByIdL?.id.some labelMM.setTextLstr?esultMJ
1t is !ery important that you use the !ersion o& the pla'ehol"ers that take an in"e; S \1's instea" o& Hust \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 proHe't =ill &ail to 'ompile, as the An"roi" buil" tools reHe't non-in"e;e" pla'ehol"ers no=a"ays.
.++
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
Styled Te.t
1& 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 NbO, NiO, an" NuO, you 'an Hust use them in a string resour'e,
NresourcesO Nstring name67b7O&his has NbOboldN/bO in it.N/stringO Nstring name67i7O@hereas this has NiOitalicsN/iOXN/stringO N/resourcesO
?ou 'an a''ess these !ia get&eGtLM, =here you =ill get ba'k an obHe't supporting the android.teGt.2panned inter&a'e an" there&ore has all o& the &ormatting applie",
LL&eGtVieDMfindViewByIdL?.id.another labelMM .setTextLgetTextL?.string.bMMJ
/. 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.formatLgetStringL?.string.funkF formatM8 &eGt3tils.html+ncodeLstr%ameMMJ
.+(
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
some&eGtVieD.setTextL!tml .from(tmlLresult9rom2tring9ormatMMJ
5o see this in a'tion, let7s look at the ?esources/2trings "emo. +ere is the layout &ile,
NPGml version671.-7 encoding67utf-,7PO N)inear)aFout Gmlns:android67http://schemas.android.com/apk/res/android7 android:orientation67vertical7 android:laFout Didth67fill parent7 android:laFout height67fill parent7 O N)inear)aFout android:orientation67horiKontal7 android:laFout Didth67fill parent7 android:laFout height67Drap content7 O N4utton android:id67QRid/format7 android:laFout Didth67Drap content7 android:laFout height67Drap content7 android:teGt67Qstring/btn name7 android:on+lick67applF9ormat7 /O N$dit&eGt android:id67QRid/name7 android:laFout Didth67fill parent7 android:laFout height67Drap content7 /O N/)inear)aFoutO N&eGtVieD android:id67QRid/result7 android:laFout Didth67fill parent7 android:laFout height67Drap content7 /O N/)inear)aFoutO
As you 'an see, it is Hust 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 (Qstring/btn name), so =e nee" a string resour'e &ile (res/values/strings.Gml),
NPGml version671.-7 encoding67utf-,7PO NresourcesO Nstring name67app name7O2trings=emoN/stringO Nstring name67btn name7ONiO%ame:N/iON/stringO Nstring name67funkF format7O#F name is ZltJbZgtJ\1'sZltJ/bZgtJN/stringO N/resourcesO
.+.
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
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.commonsDare.android.stringsJ import import import import import import import android.app.ActivitFJ android.os.4undleJ android.teGt.&eGt3tilsJ android.teGt.!tmlJ android.vieD.VieDJ android.Didget.$dit&eGtJ android.Didget.&eGtVieDJ
public class 2trings=emo eGtends ActivitF : $dit&eGt nameJ &eGtVieD resultJ Q"verride public void onCreateL4undle icicleM : super.onCreateLicicleMJ setContentViewL?.laFout.mainMJ name6L$dit&eGtMfindViewByIdL?.id.nameMJ result6L&eGtVieDMfindViewByIdL?.id.resultMJ
public void apply"ormatLVieD vM : 2tring format6getStringL?.string.funkF formatMJ 2tring simple?esult62tring.formatLformat8 &eGt3tils.html+ncodeLname.getTextLM.toStringLMMMJ result.setTextL!tml.from(tmlLsimple?esultMMJ ;
5he string resour'e manipulation 'an be &oun" in applF9ormatLM, =hi'h is 'alle" =hen the button is 'li'ke". *irst, =e get our &ormat !ia get2tringLM S something =e 'oul" ha!e "one at on+reateLM time &or e&&i'ien'y. -e;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. -ote the use o& &eGt3tils.html$ncodeLM 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 obHe't !ia !tml.from!tmlLM an" up"ate our label.
.+'
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
.+1
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
$igure +;+2 The same application@ after filling in some heroic figureHs name
.+3
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
res/draDable
=ith a base name o& i'on. 1n this 'ase, =e use a /2;/2 #-8 &ile &rom the -u!ola i'on set,
NPGml version671.-7 encoding67utf-,7PO N)inear)aFout Gmlns:android67http://schemas.android.com/apk/res/android7 android:orientation67vertical7 android:laFout Didth67fill parent7 android:laFout height67fill parent7 O N)inear)aFout android:orientation67horiKontal7 android:laFout Didth67fill parent7 android:laFout height67Drap content7 O NImage4utton android:id67QRid/format7 android:laFout Didth67Drap content7 android:laFout height67Drap content7 android:src67QdraDable/icon7 android:on+lick67applF9ormat7 /O N$dit&eGt android:id67QRid/name7 android:laFout Didth67fill parent7 android:laFout height67Drap content7 /O N/)inear)aFoutO N&eGtVieD android:id67QRid/result7 android:laFout Didth67fill parent7 android:laFout height67Drap content7 /O N/)inear)aFoutO
.+6
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
res/Gml/.
5he layout stays the same, so all that nee"s repla'ing is the Ca!a
sour'e,
package com.commonsDare.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.vieD.VieDJ android.Didget.AdapterVieDJ android.Didget.ArraFAdapterJ android.Didget.)istVieDJ android.Didget.&eGtVieDJ android.Didget.&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 : &eGtVieD selectionJ ArraF)istN2tringO items6neD ArraF)istN2tringOLMJ Q"verride public void onCreateL4undle icicleM : super.onCreateLicicleMJ setContentViewL?.laFout.mainMJ selection6L&eGtVieDMfindViewByIdL?.id.selectionMJ trF : ]ml(ull(arser Gpp6get%esourcesLM.get,mlL?.Gml.DordsMJ Dhile LGpp.get+!entTypeLMX6]ml(ull(arser.$%= ="+3#$%&M : if LGpp.get+!entTypeLM66]ml(ull(arser.2&A?& &AEM : if LGpp.get&ameLM.e-ualsL7Dord7MM : items.addLGpp.get$ttri'uteValueL-MMJ ; ; ; Gpp.nextLMJ
; catch L&hroDable tM : &oast .makeTextLthis8 7?eUuest failed: 7Rt.toStringLM8 &oast.)$%E&! )"%EM .showLMJ ; setList$dapterLneD ArraFAdapterN2tringOLthis8 android.?.laFout.simple list item 18 itemsMMJ ;
.+:
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
public void onListItemClickL)istVieD parent8 VieD v8 int position8 long idM : selection.setTextLitems.getLpositionM.toStringLMMJ ;
-o=, insi"e our trF...catch blo'k, =e get our ]ml(ull(arser an" loop until the en" o& the "o'ument. 1& the 'urrent e!ent is 2&A?& &AE an" the name o& the element is Dord (Gpp.get%ameLM.eUualsL7Dord7M), 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. 2ut, i& you =ere not as 'om&ortable that the FML is properly "e&ine", you might 'onsi"er 'he'king the attribute 'ount (getAttribute+ountLM) an" the name o& the attribute (getAttribute%ameLM) 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,
.(;
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
,iscellaneous >alues
1n 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 obHe'ts an" use their symboli' names...but this only =orks insi"e Ca!a sour'e, not in layout FML &iles. 2y 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 siLe o& the s'reen
in pt
&or points, =hi'h in publishing terms is 1Q02n" o& an in'h (again, base" on the a'tual physi'al siLe 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 eBuals one dip &or a 140"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 siLe)
dip
5o en'o"e a "imension as a resour'e, a"" a dimen element, =ith a name attribute &or your uniBue name &or this resour'e, an" a single 'hil" te;t element representing the !alue,
.(+
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
1n a layout, you 'an re&eren'e "imensions as Qdimen/..., =here the ellipsis is a pla'ehol"er &or your uniBue name &or the resour'e (e.g., thin an" fat &rom the sample abo!e). 1n Ca!a, you re&eren'e "imension resour'es by the uniBue name pre&i;e" =ith ?.dimen. (e.g., ?esources.get=imenL?.dimen.thinM).
Colors
Colors in An"roi" are he;a"e'imal 82 !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?E4 SA?E4 S??EE44 SAA??EE44
5hese =ork similarly to their 'ounterparts in Cas'a"ing %tyle %heets (C%%). ?ou 'an, o& 'ourse, put these 82 !alues as string literals in Ca!a sour'e or layout resour'es. 1& 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 uniBue name &or this 'olor, an" a single te;t element 'ontaining the 82 !alue itsel&,
NresourcesO Ncolor name67FelloD orange7OS99=...N/colorO Ncolor name67forest green7OS--..--N/colorO Ncolor name67burnt umber7OS,ACC><N/colorO N/resourcesO
1n a layout, you 'an re&eren'e 'olors as Qcolor/..., repla'ing the ellipsis =ith your uniBue name &or the 'olor (e.g., burnt umber). 1n Ca!a, you
.((
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
re&eren'e 'olor resour'es by the uniBue name pre&i;e" =ith ?.color. (e.g., ?esources.get+olorL?.color.forest greenM).
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'.). 1n the resour'e &ile, you nee" one string-arraF element per array, =ith a name attribute &or the uniBue 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,
NPGml version671.-7 encoding67utf-,7PO NresourcesO Nstring-arraF name67cities7O NitemO(hiladelphiaN/itemO NitemO(ittsburghN/itemO NitemOAllentoDn/4ethlehemN/itemO NitemO$rieN/itemO NitemO?eadingN/itemO NitemO2crantonN/itemO NitemO)ancasterN/itemO NitemOAltoonaN/itemO NitemO!arrisburgN/itemO N/string-arraFO Nstring-arraF name67airport codes7O NitemO(!)N/itemO NitemO(I&N/itemO NitemOA4$N/itemO NitemO$?IN/itemO NitemO?=EN/itemO NitemOAV(N/itemO NitemO)%2N/itemO NitemOA""N/itemO NitemO#=&N/itemO N/string-arraFO N/resourcesO
*rom your Ca!a 'o"e, you 'an then use ?esources.get2tringArraFLM to get a 2tringAB o& the items in the list. 5he parameter to get2tringArraFLM is your uniBue name &or the array, pre&i;e" =ith ?.arraF. (e.g., ?esources.get2tringArraFL?.arraF.honorificsM).
.(.
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
$creen orientation, is the s'reen in a portrait orientationI Lan"s'apeI 1s the s'reen sBuare an", there&ore, "oes not really ha!e an orientationI $creen si<e, ho= many pi;els "oes the s'reen ha!e, so you 'an siLe your resour'es a''or"ingly (e.g., large !ersus small i'ons)I Touchscreen, "oes the "e!i'e ha!e a tou'hs'reenI 1& so, is the tou'hs'reen set up to be use" =ith a stylus or a &ingerI 9ey-oard, =hat keyboar" "oes the user ha!e (KWE 5?, numeri', neither), either no= or as an optionI Bther input, "oes the "e!i'e ha!e some other &orm o& input, like a "ire'tional pa" or 'li'k-=heelI
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. -ormally, &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 1%> 4/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.
.('
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
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, rightI 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-siLe, me"ium-"ensity s'reen an" a har"=are keyboar" 5he %amsung 8ala;y 5ab 0N has a large siLe, high-"ensity s'reen an" no har"=are keyboar" 5he Motorola Charm has a small siLe, 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& siLe, 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 siLe is more important than s'reen orientation, =hi'h is
.(1
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
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-UDertF res/laFout-large-port-mdpi-nokeFs res/laFout-large-port-hdpi-UDertF res/laFout-large-port-hdpi-nokeFs res/laFout-large-land-mdpi-UDertF res/laFout-large-land-mdpi-nokeFs res/laFout-large-land-hdpi-UDertF res/laFout-large-land-hdpi-nokeFs res/laFout-normal-port-mdpi-UDertF res/laFout-normal-port-mdpi-nokeFs res/laFout-normal-port-finger-UDertF res/laFout-normal-port-hdpi-nokeFs res/laFout-normal-land-mdpi-UDertF res/laFout-normal-land-mdpi-nokeFs res/laFout-normal-land-hdpi-UDertF res/laFout-normal-land-hdpi-nokeFs res/draDable-large-port-mdpi-UDertF res/draDable-large-port-mdpi-nokeFs res/draDable-large-port-hdpi-UDertF res/draDable-large-port-hdpi-nokeFs res/draDable-large-land-mdpi-UDertF res/draDable-large-land-mdpi-nokeFs res/draDable-large-land-hdpi-UDertF
.(3
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
@on7t pani': We =ill shorten this list in Hust a moment: -ote that there is nothing pre!enting you &rom also ha!ing a "ire'tory =ith the una"orne" base name (res/laFout). 1n &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& reBuire" "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 NrightN 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 siLe o& the "e!i'e is NnormalN, the -large "ire'tories =oul" be "roppe" as 'an"i"ates, sin'e they 'all &or some other siLe.
2. -e;t, An"roi" 'ounts the number o& mat'hes &or ea'h &ol"er, an" only pays attention to those =ith the most mat'hes. /. *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.
.(6
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
+ere, =e take a"!antage o& the &a't that spe'i&i' mat'hes take pre'e"en'e o!er Nunspe'i&ie"N !alues. %o, a "e!i'e =ith a KWE 5? keyboar" =ill 'hoose a resour'e =ith UDertF 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 UDertF),
res/laFout-large-land res/laFout-large res/laFout-land-UDertF res/laFout-UDertF res/laFout-land res/laFout res/draDable-hdpi res/draDable
1& =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 -UDertF resour'e sets. We =ill see these resour'e sets again in the 'hapter on supporting multiple s'reen siLes, later in the book.
.(8
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
Are your &eGtVieD =i"gets aligne" on the le&t si"e =ith other =i"gets or 'ontainersI 1& so, is that the right ans=er &or your 5L usersI 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"thI 1& 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 languagesI
.(:
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
CHAPTER &0
0efining an
=sing Styles
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,
NPGml version671.-7 encoding67utf-,7PO N)inear)aFout Gmlns:android67http://schemas.android.com/apk/res/android7 android:orientation67vertical7 android:laFout Didth67fill parent7 android:laFout height67fill parent7 O N(rogress4ar android:id67QRid/progress7 stFle67Pandroid:attr/progress4ar2tFle!oriKontal7 android:laFout Didth67fill parent7 android:laFout height67Drap content7 /O N/)inear)aFoutO
%omething about that magi' stFle attribute 'hange" our (rogress4ar &rom a normal 'ir'le to a horiLontal 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.
..+
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
0efining an
=sing Styles
you ha!e a bun'h o& =i"gets that look the same, use a style to use a single "e&inition &or Nlook the sameN, 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/%oD2tFled sample proHe't. 5his is the same proHe'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 proHe't is the same as it =as, =ith the a""ition o& a stFle attribute,
NPGml version671.-7 encoding67utf-,7PO N4utton Gmlns:android67http://schemas.android.com/apk/res/android7 android:id67QRid/button7 android:teGt677 android:laFout Didth67fill parent7 android:laFout height67fill parent7 stFle67QstFle/bigred7 /O
-ote 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, QstFle/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 proHe't, or in other resour'e sets (e.g., res/values-v11/ &or !alues resour'es only to be use" on A#1 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 %oD2tFled proHe't,
NPGml version671.-7 encoding67utf-,7PO NresourcesO NstFle name67bigred7O Nitem name67android:teGt2iKe7OC-spN/itemO Nitem name67android:teGt+olor7OS9999----N/itemO
..(
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
0efining an
=sing Styles
N/stFleO N/resourcesO
5he NstFleO element supplies the name o& the style, =hi'h is =hat =e use =hen re&erring to the style &rom a layout. 5he NitemO 'hil"ren o& the NstFleO 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 proHe't S nothing nee"s to be a"Huste" 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,
sample application
<lements of Style
5here are &our elements to 'onsi"er =hen applying a style,
...
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
0efining an
=sing Styles
1.
Where "o you put the style attributes to say you =ant to apply a styleI
2. What attributes 'an you "e&ine !ia a styleI /. +o= "o you inherit &rom a pre!iously-"e&ine" style (one o& your o=n or one &rom An"roi")I <. What !alues 'an those attributes ha!e in a style "e&initionI
,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,
NPGml version671.-7 encoding67utf-,7PO N)inear)aFout Gmlns:android67http://schemas.android.com/apk/res/android7 android:laFout Didth67fill parent7 android:laFout height67fill parent7 stFle67QstFle/bigred7 O N4utton android:id67QRid/button7 android:teGt677 android:laFout Didth67fill parent7 android:laFout height67fill parent7 /O N/)inear)aFoutO
5he resulting $1 =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 NthemeN, =hi'h =ill be 'o!ere" a bit later in this 'hapter.
..'
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
0efining an
=sing Styles
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 NstFleO element. *or e;ample, take a look at this style resour'e,
NPGml version671.-7 encoding67utf-,7PO NresourcesO NstFle name67activated7 parent67android:&heme.!olo7O Nitem name67android:background7OP android:attr/activated4ackgroundIndicatorN/itemO N/stFleO N/resourcesO
(note, in some ren"itions o& this book, you may see the NitemO element split o!er t=o lines S this is 'ause" by =or"-=rapping, as this element shoul" be all on one line) We =ill see this resour'e again in a later 'hapter on using the ne= &ragment $1 &rame=ork.
..1
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
0efining an
=sing Styles
+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. 1n many 'ases, this =ill not be ne'essary. 1& 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., QdraDable/mF background). 1nstea", =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,
..3
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
0efining an
=sing Styles
NPGml version671.-7 encoding67utf-,7PO N)inear)aFout Gmlns:android67http://schemas.android.com/apk/res/android7 android:orientation67vertical7 android:laFout Didth67fill parent7 android:laFout height67fill parent7 O N(rogress4ar android:id67QRid/progress7 stFle67Pandroid:attr/progress4ar2tFle!oriKontal7 android:laFout Didth67fill parent7 android:laFout height67Drap content7 /O N/)inear)aFoutO
+ere, our style attribute S not a style resour'e S is pointing to a themesupplie" attribute (progress4ar2tFle!oriKontal). 1& 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 Qandroid:stFle/@idget.(rogress4ar.!oriKontal. +en'e, =e are saying to An"roi" that =e =ant our (rogress4ar style" as Qandroid:stFle/@idget.(rogress4ar.!oriKontal, !ia the in"ire'tion o& P 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. 1n 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.
ThemesC Woul
5hemes are styles, applie" to an a'ti!ity or appli'ation, !ia an android:theme attribute on the NactivitFO or NapplicationO element. 1& the theme you are applying is your o=n, Hust re&eren'e it as QstFle/..., Hust as you =oul" in a stFle attribute o& a =i"get. 1& the theme you are applying, though, 'omes &rom An"roi", typi'ally you =ill use a !alue =ith Qandroid:stFle/ as the pre&i;, su'h as Qandroid:stFle/&heme.=ialog or Qandroid:stFle/&heme.)ight.
..6
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
0efining an
=sing Styles
1n a theme, your &o'us is not so mu'h on styling =i"gets, but styling the a'ti!ity itsel&. *or e;ample, here is the "e&inition o& Qandroid:stFle/&heme.%o&itle4ar.9ullscreen,
NX-- Variant of the default LdarkM theme that has no title bar and fills the entire screen --O NstFle name67&heme.%o&itle4ar.9ullscreen7O Nitem name67android:DindoD9ullscreen7OtrueN/itemO Nitem name67android:DindoD+ontent"verlaF7OQnullN/itemO N/stFleO
1t 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:DindoD9ullscreen set to true). 1t also spe'i&ies that the N'ontent o!erlayN S a layout that =raps aroun" your a'ti!ity7s 'ontent !ie= S shoul" be set to nothing (android:DindoD+ontent"verlaF set to Qnull), 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,
Nitem name67progress4ar2tFle!oriKontal7OQandroid:stFle/@idget.(rogress4ar.!oriKontalN/ itemO
(note, in some ren"itions o& this book, you may see the NitemO element split o!er multiple lines S this is 'ause" by =or"-=rapping, as this element shoul" be all on one line) +ere,
progress4ar2tFle!oriKontal is Qandroid:stFle/@idget.(rogress4ar.!oriKontal. 5his is re&eren'e Pandroid:attr/progress4ar2tFle!oriKontal
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&).
..8
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
CHAPTER &5
*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" siLe (aroun" /.AN Q 3'm). %tarting in the &all o& 2003, though, "e!i'es starte" arri!ing =ith =i"ely "isparate s'reen siLes an" resolutions, &rom tiny K.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 siLes. >& '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 siLes to a"" greater !alue. 5o that en", An"roi" 1.4 a""e" ne= 'apabilities to help better support these "i&&ering s'reen siLes an" resolutions, an" these 'apabilities ha!e been e;ten"e" in subseBuent 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 siLes. ?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 siLes. 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 siLes =ell.
..:
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
1& your appli'ation is installe" on a "e!i'e =ith a larger s'reen, An"roi" =ill run your appli'ation in N'ompatibility mo"eN, s'aling e!erything base" on the a'tual s'reen siLe. %o, suppose you ha!e a ><pG sBuare #-8 &ile, an" An"roi" install an" runs your appli'ation on a "e!i'e =ith the stan"ar" physi'al siLe but a W.8A resolution (a so-'alle" Nhigh-"ensityN s'reen). An"roi" might s'ale your #-8 &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 &uLLy. An"roi" =ill blo'k your appli'ation &rom running on a "e!i'e =ith a smaller s'reen. +en'e, K.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 K.8A s'reen,
.';
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
1& your appli'ation is 'ompile" &or An"roi" 1.4 or higher, An"roi" assumes that you are properly han"ling all s'reen siLes, an" there&ore =ill not run your appli'ation in N'ompatibility mo"eN. 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 siLes in An"roi" is to "esign your user inter&a'es su'h that they automati'ally s'ale &or the s'reen siLe, =ithout any siLe-spe'i&i' 'o"e or resour'es. 1n other =or"s, Nit Hust =orksN. 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 K.8A s'reen. +ere are some tips &or a'hie!ing this Nall in oneN solution,
.'+
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
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 Hob o& letting you 'ontrol your layout =hile still a"apting it to other s'reen siLes. *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 N'onne'te"N (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
.'(
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
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.
.'.
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
An"roi" o&&ers "imensions measure" in "ensity-in"epen"ent pi;els ( dip). 5hese map 1,1 to pi;els &or a 140"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-siLe" W.8A "e!i'e), the ratio is 2,/, so .-dip X .-pG at 140"pi X /.pG at 2<0"pi. 5he a"!antage to the user o& going =ith "ip is that the a'tual siLe o& the "imension stays the same, so !isibly there is no "i&&eren'e bet=een .-dip at 140"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 siLe (9"%& 2+A)$ !alue in 2Fstem.2ettings).
/ou@ !n
/ou@
5here =ill be times, though, =hen you =ant to ha!e "i&&erent looks or beha!iors base" upon s'reen siLe 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'hniBues, a'hie!ing s'reen siLe- an" "ensity-in"epen"en'e is eminently possible, at least &or "e!i'es running An"roi" 1.4 an" ne=er.
.''
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
Csupports*screensD
5he &irst step to proa'ti!ely supporting s'reen siLes is to a"" the NsupportsscreensO element to your Android#anifest.Gml &ile. 5his spe'i&ies =hi'h s'reen siLes you e;pli'itly support an" =hi'h you "o not. 5hose that you "o not =ill be han"le" by the automati' N'ompatibility mo"eN "es'ribe" pre!iously. +ere is a mani&est 'ontaining a Nsupports-screensO element,
NPGml version671.-7 encoding67utf-,7PO Nmanifest android:version+ode6717 android:version%ame671.-7 package67com.commonsDare.android.eu<Fou7 Gmlns:android67http://schemas.android.com/apk/res/android7O Nsupports-screens android:anF=ensitF67true7 android:large2creens67true7 android:normal2creens67true7 android:small2creens67true7 /O Napplication android:icon67QdraDable/cD7 android:label67Qstring/app name7O NactivitF android:label67Qstring/app name7 android:name67.$3<5ou7O Nintent-filterO Naction android:name67android.intent.action.#AI%7 /O NcategorF android:name67android.intent.categorF.)A3%+!$?7 /O N/intent-filterO N/activitFO N/applicationO N/manifestO
5hree o& these attributes are almost sel&-e;planatory, android:small2creens, 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 reBuires N'ompatibility mo"eN assistan'e ( false). An"roi" 2./ has also a""e" an android:Glarge2creens &or larger tablets an" (perhaps) tele!isions.
android:normal2creens,
5he android:anF=ensitF attribute in"i'ates =hether you are taking "ensity into a''ount in your 'al'ulations (true) or not (false). 1& false, An"roi" =ill preten" as though all o& your "imensions (e.g., <pG) are &or a normal-"ensity (140"pi) s'reen. 1& 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. 1& you
.'1
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
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.
Default Scaling
2y "e&ault, An"roi" =ill s'ale all "ra=able resour'es. 5hose that are intrinsi'ally s'alable, as "es'ribe" in the pre!ious se'tion, =ill s'ale ni'ely. >r"inary bitmaps =ill be s'ale" Hust using a normal s'aling algorithm, =hi'h may or may not gi!e you great results. 1t also may slo= things "o=n a bit. 1& you =ish to a!oi" this, you =ill nee" to set up separate resour'e sets 'ontaining your non-s'alable bitmaps.
Densit!--ased Sets
1& you =ish to ha!e "i&&erent layouts, "imensions, or the like base" upon "i&&erent s'reen "ensities, you 'an use the -ldpi, -mdpi, -hdpi, an" -Ghdpi resour'e set labels. *or e;ample, res/values-hdpi/dimens.Gml =oul" 'ontain "imensions use" in high-"ensity "e!i'es. -ote that there is a bug in An"roi" 1.A (A#1 le!el /) =hen it 'omes to =orking =ith these s'reen "ensity resour'e sets. E!en though all An"roi" 1.A "e!i'es are me"ium "ensity, An"roi" 1.A might pi'k one o& the other "ensities by a''i"ent. %o long as you are aiming to support An"roi" 1.A an" use s'reen "ensity resour'e sets, you =ill nee" to 'lone the 'ontents o& your -mdpi set, =ith the 'lone name" -mdpi-vC. 5his N!ersion-base" setN is "es'ribe" in greater "etail a bit later in this se'tion.
.'3
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
Si1e--ased Sets
%imilarly, i& you =ish to ha!e "i&&erent resour'e sets base" upon s'reen siLe, An"roi" o&&ers -small, -normal, an" -large resour'e set labels. Creating res/laFout-large-land/ =oul" in"i'ate layouts to use on large s'reens (e.g., W.8A) in lan"s'ape orientation.
,ersion--ased Sets
5here may be times =hen earlier !ersions o& An"roi" get 'on&use" by ne=er resour'e set labels. 5o help =ith that, you 'an in'lu"e a !ersion label to your resour'e set, o& the &orm -v%, =here % is an A#1 le!el. +en'e, res/draDable-large-v</ in"i'ates these "ra=ables shoul" be use" on large s'reens at A#1 le!el < (An"roi" 1.4) an" ne=er. %o, i& you &in" that An"roi" 1.A emulators or "e!i'es are grabbing the =rong resour'e sets, 'onsi"er a""ing -v< to their resour'e set names to &ilter them out.
.'6
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
NlongN in"i'ates a 14,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 LLget%esourcesLM.getConfigurationLM.screen)aFout Z +onfiguration.2+?$$%)A5"3& 2IV$ #A2HM 66+onfiguration.2+?$$%)A5"3& 2IV$ )A?E$M : // Fes8 De are large ; else : // no8 De are not ;
%imilarly, you 'an &in" out your s'reen "ensity, or the e;a't number o& pi;els in your s'reen siLe, 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 Ntou'hs'reenN 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 Di11ers
5he Motorola @ >1@ has a 2<0"pi, /.0-in'h, <80;8A< pi;el s'reen. 5o emulate a @ >1@ s'reen, base" on pi;el 'ount, takes up one thir" o& a 13N 1280;102< LC@ monitor, be'ause the LC@ monitor7s "ensity is mu'h lo=er than that o& the @ >1@ S aroun" 34"pi. %o, =hen you &ire up your
.'8
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
An"roi" emulator &or an *W.8A "isplay like that o& the @ >1@, 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, siLes =ill ha!e the same relationships (e.g., Wi"get A might be t=i'e as tall as Wi"get 2, an" that =ill be true regar"less o& "ensity), an" so on. +o=e!er,
5hings that might appear to be a suitable siLe =hen !ie=e" on a 13N 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
.':
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
ialog
2y "e&ault, the N%'ale "isplay to real siLeN '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 siLe o& the "e!i'e you =ish to emulate, in in'hes (e.g., /.0 in'hes &or the Motorola @ >1@)
2. 5he "pi o& your monitor S 'li'k the NIN 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& siLes. +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 0N 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 $1 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 Nsa!eN 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
.1+
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
user steps to na!igate your $1, parti'ularly i& they nee" to &lip ba'k an" &orth bet=een tabs &reBuently. 1& you only ha!e t=o tabs, 'onsi"er 'hanging your $1 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. 1& 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.
<xampleC <='/ou
5o e;amine ho= to use some o& these te'hniBues, let us look at the 2creen2iKes/$3<5ou sample appli'ation. 5his appli'ation has one a'ti!ity ($3<5ou) that 'ontains a )istVieD =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.
.1(
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
1n 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 siLe an" slo=ly a"" in more s'reen-relate" &eatures.
?ou =ill note =e ha!e the Nsupports-screensO element, saying that =e in"ee" "o support all s'reen siLes. 5his blo'ks most o& the automati' s'aling that An"roi" =oul" "o i& =e sai" =e "i" not support 'ertain s'reen siLes. >ur main layout is siLe-in"epen"ent, as it is Hust a &ull-s'reen )istVieD,
NPGml version671.-7 encoding67utf-,7PO N)istVieD Gmlns:android67http://schemas.android.com/apk/res/android7 android:id67Qandroid:id/list7 android:laFout Didth67fill parent7 android:laFout height67fill parent7 /O
.1.
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
*or e;ample, right no=, our &ont siLe is set to be >-pG, =hi'h =ill not !ary by s'reen siLe 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.commonsDare.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.vieD.VieDJ android.vieD.VieDEroupJ android.Didget.ArraFAdapterJ android.Didget.ImageVieDJ android.Didget.)istVieDJ android.Didget.&eGtVieDJ java.util.ArraF)istJ
public class $3<5ou eGtends )istActivitF : static private ArraF)istN+ountrFO $36neD ArraF)istN+ountrFOLMJ static : $3.addLneD CountryL?.string.austria8 ?.draDable.austria8
.1'
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
?.string.austria urlMMJ $3.addLneD CountryL?.string.belgium8 ?.draDable.belgium8 ?.string.belgium urlMMJ $3.addLneD CountryL?.string.bulgaria8 ?.draDable.bulgaria8 ?.string.bulgaria urlMMJ $3.addLneD CountryL?.string.cFprus8 ?.draDable.cFprus8 ?.string.cFprus urlMMJ $3.addLneD CountryL?.string.cKech republic8 ?.draDable.cKech republic8 ?.string.cKech republic urlMMJ $3.addLneD CountryL?.string.denmark8 ?.draDable.denmark8 ?.string.denmark urlMMJ $3.addLneD CountryL?.string.estonia8 ?.draDable.estonia8 ?.string.estonia urlMMJ $3.addLneD CountryL?.string.finland8 ?.draDable.finland8 ?.string.finland urlMMJ $3.addLneD CountryL?.string.france8 ?.draDable.france8 ?.string.france urlMMJ $3.addLneD CountryL?.string.germanF8 ?.draDable.germanF8 ?.string.germanF urlMMJ $3.addLneD CountryL?.string.greece8 ?.draDable.greece8 ?.string.greece urlMMJ $3.addLneD CountryL?.string.hungarF8 ?.draDable.hungarF8 ?.string.hungarF urlMMJ $3.addLneD CountryL?.string.ireland8 ?.draDable.ireland8 ?.string.ireland urlMMJ $3.addLneD CountryL?.string.italF8 ?.draDable.italF8 ?.string.italF urlMMJ $3.addLneD CountryL?.string.latvia8 ?.draDable.latvia8 ?.string.latvia urlMMJ $3.addLneD CountryL?.string.lithuania8 ?.draDable.lithuania8 ?.string.lithuania urlMMJ $3.addLneD CountryL?.string.luGembourg8 ?.draDable.luGembourg8 ?.string.luGembourg urlMMJ $3.addLneD CountryL?.string.malta8 ?.draDable.malta8 ?.string.malta urlMMJ $3.addLneD CountryL?.string.netherlands8 ?.draDable.netherlands8 ?.string.netherlands urlMMJ $3.addLneD CountryL?.string.poland8 ?.draDable.poland8 ?.string.poland urlMMJ $3.addLneD CountryL?.string.portugal8 ?.draDable.portugal8 ?.string.portugal urlMMJ $3.addLneD CountryL?.string.romania8 ?.draDable.romania8 ?.string.romania urlMMJ $3.addLneD CountryL?.string.slovakia8 ?.draDable.slovakia8 ?.string.slovakia urlMMJ $3.addLneD CountryL?.string.slovenia8 ?.draDable.slovenia8 ?.string.slovenia urlMMJ $3.addLneD CountryL?.string.spain8 ?.draDable.spain8 ?.string.spain urlMMJ $3.addLneD CountryL?.string.sDeden8 ?.draDable.sDeden8 ?.string.sDeden urlMMJ $3.addLneD CountryL?.string.united kingdom8 ?.draDable.united kingdom8
.11
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
?.string.united kingdom urlMMJ ; Q"verride public void onCreateL4undle savedInstance2tateM : super.onCreateLsavedInstance2tateMJ setContentViewL?.laFout.mainMJ setList$dapterLneD Country$dapterLMMJ ; Q"verride protected void onListItemClickL)istVieD l8 VieD v8 int position8 long idM : start$cti!ityLneD IntentLIntent.A+&I"% VI$@8 3ri.parseLgetStringL$3.getLpositionM.urlMMMMJ ; static class +ountrF : int nameJ int flagJ int urlJ CountryLint name8 int flag8 int urlM : this.name6nameJ this.flag6flagJ this.url6urlJ ; ; class +ountrFAdapter eGtends ArraFAdapterN+ountrFO : Country$dapterLM : superL$3<5ou.this8 ?.laFout.roD8 ?.id.name8 $3MJ ; Q"verride public VieD getViewLint position8 VieD convertVieD8 VieDEroup parentM : +ountrF@rapper Drapper6nullJ if LconvertVieD66nullM : convertVieD6getLayoutInflaterLM.inflateL?.laFout.roD8 nullMJ Drapper6neD Country#rapperLconvertVieDMJ convertVieD.setTagLDrapperMJ ; else : Drapper6L+ountrF@rapperMconvertVieD.getTagLMJ ; Drapper.populate"romLgetItemLpositionMMJ returnLconvertVieDMJ ; ;
.13
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
class +ountrF@rapper : private &eGtVieD name6nullJ private ImageVieD flag6nullJ private VieD roD6nullJ Country#rapperLVieD roDM : this.roD6roDJ ; &eGtVieD get&ameLM : if Lname66nullM : name6L&eGtVieDMroD.findViewByIdL?.id.nameMJ ; returnLnameMJ ; ImageVieD get"lagLM : if Lflag66nullM : flag6LImageVieDMroD.findViewByIdL?.id.flagMJ ; returnLflagMJ ; void populate"romL+ountrF nationM : get&ameLM.setTextLnation.nameMJ get"lagLM.setImage%esourceLnation.flagMJ ; ; ;
.16
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
...an" 020p,
.1:
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
/O N&eGtVieD android:id67QRid/name7 android:laFout Didth67Drap content7 android:laFout height67Drap content7 android:laFout gravitF67center verticalWright7 android:teGt2iKe67.mm7 /O N/)inear)aFoutO
android:laFout Didth67Drap content7 android:laFout height67Drap content7 android:laFout gravitF67center verticalWleft7 android:padding?ight67<dip7
...an" W.8A,
.3+
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
....an" K.8A,
.3(
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
-o= our &ont is a 'onsistent siLe, 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,
.3.
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
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 2ro=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 @ebVieD =i"get, as seen in 2creen2iKes/$3<5ou <,
NPGml version671.-7 encoding67utf-,7PO N)inear)aFout Gmlns:android67http://schemas.android.com/apk/res/android7 android:laFout Didth67fill parent7 android:laFout height67fill parent7 O N)istVieD android:id67Qandroid:id/list7 android:laFout Didth67fill parent7 android:laFout height67fill parent7 android:laFout Deight6717 /O N@ebVieD android:id67QRid/broDser7 android:laFout Didth67fill parent7 android:laFout height67fill parent7 android:laFout Deight6717 /O N/)inear)aFoutO
5hen, =e nee" to a"Hust our a'ti!ity to look &or that @ebVieD an" use it =hen &oun", "e&aulting to laun'hing a 2ro=ser a'ti!ity other=ise,
Q"verride public void onCreateL4undle savedInstance2tateM :
.3'
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
Q"verride protected void onListItemClickL)istVieD l8 VieD v8 int position8 long idM : 2tring url6getStringL$3.getLpositionM.urlMJ if LbroDser66nullM : start$cti!ityLneD IntentLIntent.A+&I"% VI$@8 3ri.parseLurlMMMJ ; else : broDser.load*rlLurlMJ ;
$igure ++12 <='/ou@ lan scape W>G! &8;;x'8; pixels)@ set for normal an sho*ing the embe e Web>ie*
ensity@
>& 'ourse, i& the user 'li'ks a link in the Wikipe"ia page, that =ill open up the &ull 2ro=ser, &or easier sur&ing.
.31
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
-ote that testing this !ersion o& the a'ti!ity, to see this beha!ior, reBuires a bit o& e;tra emulator =ork. 2y "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 siLe.
,h t I1 It Is "ot
Bro#serF
>& 'ourse, $3<5ou "oes 'heat a bit. 5he se'on" a'ti!ity is a 2ro=ser (or @ebVieD 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 $1 (&or larger s'reens). 5he best =ay to approa'h this problem, &or An"roi" 1.4 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.
.33
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
CHAPTER &7
*ebruary 2011 sa= the intro"u'tion o& An"roi" /.0 an" a $1 para"igm that, &or no=, =e =ill re&er to by the An"roi" /.0 'o"ename o& N+oney'ombN. An"roi" <.0 (N1'e Cream %an"=i'hN) e;ten"e" this &rame=ork to support phones. 5he +oney'omb-style $1 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"Hust 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 Nthe big pi'tureN o& +oney'omb an" its pla'e =ithin An"roi".
Why HoneycombG
1n prin'iple, An"roi"7s original phone-'entri' $1 '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 10N "iagonal s'reen), the An"roi" phone $1 starts to be'ome more...'lunky. While appli'ations 'an s'ale up to use the larger s'reen, the
.3:
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 Hust to make e!erything bigger, &reBuently 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" reBuire 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.
.6;
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
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 Nsystem barN. >n the le&t are on-s'reen buttons &or 2ACD, +>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" signalQbattery 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. 1& =e look at an appli'ation that has not been optimiLe" &or An"roi" /.;, =e see mu'h the same $1,
.2;
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-optimiLe" appli'ations =ill look a bit "i&&erent,
.6+
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
$igure ++82 !
.2;
>n the top, =e see the Na'tion barN. 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, N@oneN an" NCan'elN 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,
.6(
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
$igure ++:2 The options menu portion of the action bar in !n roi
.2;
5he i'on in the upper-le&t is tappable, an" in this 'ase takes the user NupN in the hierar'hy o& a'tions in this appli'ation, in"i'ate" by the north=estpointing arro=hea". 1n this 'ase, going NupN &rom a""ing a ne= 'onta't takes you to the list o& e;isting 'onta'ts,
.2;
.6.
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
1n An"roi" 2.;, the 'onta'ts $1 =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. 1n An"roi" /.0, these are 'ombine" in a single a'ti!ity. ?et, in the &uture, =hen the +oney'omb $1 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.
.2;
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.;. 1t has been reorganiLe" &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.
.6'
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
for !n roi
.61
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
1& you are 'reating your o=n 'ustom styles, there are t=o that you =ill =ant to 'onsi"er inheriting &rom, 1. is the stan"ar" "ark Nholographi' themeN ("ark ba'kgroun", light te;t)
&heme.!olo
2. %pe'i&i'ally
/. @o not spe'i&y a "e&ault theme an" Nlet the 'hips &all =here they mayN
.63
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
.66
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
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,
for !n roi
.2;
1& 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. 1& 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". 2ut &irst, =e nee" to e;plain =hat all is possible &or you to use to take &ull a"!antage o& the +oney'omb $1, =hi'h is the point o& the ne;t &e= 'hapters.
.68
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
CHAPTER &8
>ne o& the easiest =ays &or an appli'ation to blen" in better =ith the +oney'omb $1 is to make use o& the a'tion bar, "es'ribe" in an earlier 'hapter. What makes it NeasyN 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 proHe't sho=n in this 'hapter is #enus/Action4ar, =hi'h e;ten"s the #enus/Inflation proHe't sho=n in a pre!ious 'hapter.
.6:
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
android:name67.Inflation=emo7O Nintent-filterO Naction android:name67android.intent.action.#AI%7 /O NcategorF android:name67android.intent.categorF.)A3%+!$?7 /O N/intent-filterO N/activitFO N/applicationO Nuses-sdk android:min2dkVersion67<7 android:target2dkVersion67117 /O Nsupports-screens android:anF=ensitF67true7 android:large2creens67true7 android:normal2creens67true7 android:small2creens67true7 android:Glarge2creens67true7 /O N/manifestO
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,
S i& you in'lu"e Dith&eGt, the title o& the menu item =ill appear a"Ha'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 proHe't7s options.Gml menu resour'e has android:shoDAsAction on the &irst t=o menu items,
NPGml version671.-7 encoding67utf-,7PO Nmenu Gmlns:android67http://schemas.android.com/apk/res/android7O Nitem android:id67QRid/add7 android:title67Add7 android:icon67QdraDable/ic menu add7 android:action)aFout67QlaFout/add7 android:shoDAsAction67if?oom7/O Nitem android:id67QRid/reset7 android:title67?eset7 android:icon67QdraDable/ic menu refresh7 android:shoDAsAction67if?oomWDith&eGt7/O Nitem android:id67QRid/about7 android:title67About7 android:icon67QdraDable/ic menu info details7 /O N/menuO
Dith&eGt)
5he se'on" menu item S &or resetting the 'ontents o& our list S is a normal N=ith te;tN 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:shoDAsAction means that it =ill remain in the menu, e!en i& there is room in the a'tion bar itsel&. -ote that the Ca!a 'o"e "oes not 'hange S on+reate"ptions#enuLM an" on"ptionsItem2electedLM &or our Inflation=emo a'ti!ity "o not nee" to be a"Huste" be'ause menu items are promote" into the a'tion bar !ia the menu FML resour'e alone.
.8+
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
same 'o"e that is in!oke" i& the user 'hooses the NAboutN options menu item S "isplaying a &oast,
public boolean onOptionsItemSelectedL#enuItem itemM : sDitch Litem.getItemIdLMM : case ?.id.add: addLMJ returnLtrueMJ case ?.id.reset: init$dapterLMJ returnLtrueMJ case ?.id.about: case android.?.id.home: &oast .makeTextLthis8 7Action 4ar 2ample App78 &oast.)$%E&! )"%EM .showLMJ returnLtrueMJ ; ; returnLsuper.onOptionsItemSelectedLitemMMJ
1n a proHe't =ith multiple a'ti!ities, though, the e;pe'tation is that 'li'king the logo =ill take you to the NhomeN a'ti!ity &or the appli'ation, =hate!er that might mean.
?ou 'an "o more =ith the a'tion bar, though, than simply 'on!erting options menu items into =hat amount to toolbar buttons. ?ou 'an a"" your o=n 'ustom $1 to the a'tion bar. 1n the 'ase o& #enus/Action4ar, =e are repla'ing the NA""N menu 'hoi'e an" resulting "ialog =ith an NA""N &iel" right in the a'tion bar itsel&. 5his, ho=e!er, gets a little bit tri'ky to implement.
.8(
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
We nee" to make some minor a"Hustments to this layout to use it &or the a'tion bar,
NPGml version671.-7 encoding67utf-,7PO N)inear)aFout Gmlns:android67http://schemas.android.com/apk/res/android7 android:orientation67horiKontal7 android:laFout Didth67fill parent7 android:laFout height67Drap content7 O N&eGtVieD android:teGt67@ord:7 android:laFout Didth67Drap content7 android:laFout height67Drap content7 android:teGtAppearance67Qandroid:stFle/&eGtAppearance.#edium7 /O N$dit&eGt android:id67QRid/title7 android:laFout Didth67fill parent7 android:laFout height67Drap content7 android:laFout margin)eft67<dip7
.8.
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
%pe'i&i'ally,
We a"" an android:teGtAppearance attribute to the &eGtVieD representing our NA"",N 'aption. 5he android:teGtAppearance attribute allo=s us to "e&ine the &ont type, siLe, 'olor, an" =eight (e.g., bol") in one shot. We spe'i&i'ally use a Nmagi' !alueN o& Qandroid:stFle/&eGtAppearance.#edium, so the 'aption mat'hes the styling o& the N esetN label on our other menu item =e promote" to the a'tion bar. We spe'i&y android:Didth6710-sp7 &or the $dit&eGt =i"get, be'ause android:laFout Didth67fill 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 Na'tion buttonN o& the so&t keyboar", so =e get 'ontrol =hen the user presses OEnterP on the so&t keyboar".
$dit&eGt
.8'
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
+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 NA""N 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. 1n this 'ase, that is the )inear)aFout &rom res/laFout/add.Gml, so =e nee" to 'all findVieD4FIdLM on it to get the $dit&eGt,
public boolean onCreateOptionsMenuL#enu menuM : neD MenuInflaterLthisM.inflateL?.menu.option8 menuMJ $dit&eGt add6L$dit&eGtMmenu .findItemL?.id.addM .get$ctionViewLM .findViewByIdL?.id.titleMJ add.setOn+ditor$ctionListenerLon2earchMJ returnLsuper.onCreateOptionsMenuLmenuMMJ ;
5hen, =e 'an 'all set"n$ditorAction)istenerLM on the $dit&eGt, to register an "n$ditorAction)istener obHe't that =ill get 'ontrol =hen the user 'li'ks OEnterP on the har" or so&t keyboar",
private &eGtVieD."n$ditorAction)istener on2earch6 neD &eGtVieD.On+ditor$ctionListenerLM : public boolean on+ditor$ctionL&eGtVieD v8 int actionId8 HeF$vent eventM : if Levent66null WW event.get$ctionLM66HeF$vent.A+&I"% 3(M : add#ordLvMJ Input#ethod#anager imm6LInput#ethod#anagerMgetSystemSer!iceLI%(3& #$&!"= 2$?VI+$MJ ; ; imm.hideSoftInput"rom#indowLv.get#indowTokenLM8 -MJ
returnLtrueMJ ;J
5hat in turn 'alls an add@ordLM metho", supplying the $dit&eGt, =hi'h a""s the =or" to the list !ia the ArraFAdapter,
QSuppress#arningsL7unchecked7M private void add#ordL&eGtVieD titleM : ArraFAdapterN2tringO adapter6LArraFAdapterN2tringOMgetList$dapterLMJ
.83
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
adapter.addLtitle.getTextLM.toStringLMMJ ;
5hat same add@ordLM metho" 'an also be use" &rom the addLM metho" that "isplays the Alert=ialog...e!en though that =ill not be use" on a +oney'omb tablet, sin'e the NA""N menu 'hoi'e no longer e;ists as a menu 'hoi'e,
private void addLM : final VieD addVieD6getLayoutInflaterLM.inflateL?.laFout.add8 nullMJ neD Alert=ialog.BuilderLthisM .setTitleL7Add a @ord7M .setViewLaddVieDM .set)ositi!eButtonL7"H78 neD =ialogInterface.OnClickListenerLM : public void onClickL=ialogInterface dialog8 int Dhich4uttonM : add#ordLL&eGtVieDMaddVieD.findViewByIdL?.id.titleMMJ ; ;M .set&egati!eButtonL7+ancel78 nullM .showLMJ ;
5he net result is that =hen the user types in something in the NA"",N &iel" an" presses OEnterP, the =or" is a""e" to the bottom o& the list. 5his sa!es some 'li'ks o!er the phone $1, 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. -ote that our "n$ditorAction)istener "oes one more thing than simply a"" the =or" to the list, it hi"es the so&t keyboar". 1t "oes this using the Input#ethod#anager, as =as seen in a pre!ious 'hapter.
2. 1s there anything =e nee" to "o &or phones running 1'e Cream %an"=i'h (or ne=er) that "o ha!e an a'tion bar, but one that is mu'h smaller than the ones on tabletsI
Pre*Honeycom= Devices
With the e;'eption o& the 'ustom !ie= &eature "es'ribe" in the pre'e"ing se'tion, e!erything sho=n in this 'hapter regar"ing the a'tion bar is automati'ally ba'k=ar"s-'ompatible to ol"er "e!i'es. 1&, ho=e!er, you =ant to use the 'ustom !ie= &eature, you ha!e a problem S the getActionVieDLM metho" is ne= to A#1 Le!el 11 an" =ill be una!ailable on ol"er !ersions o& An"roi". 5his means you =ill nee" to 'ompile &or A#1 Le!el 11 or higher (e.g., set your E'lipse target or Ant project.properties to re&eren'e android-11), an" you =ill nee" to take steps to a!oi" 'alling getActionVieDLM on ol"er "e!i'es. We =ill e;plore ho= to pull o&& this &eat in a later 'hapter. >& 'ourse, another approa'h is to a"" your o=n a'tion bar &or earlier "e!i'es. 5here are a &e= solutions &or this,
5he An"roi" %@D has the Action4ar+ompat sample appli'ation (A#1 Le!el 1< an" higher). 5his "emonstrates ho= to a"" an a'tion bar &or pre-+oney'omb "e!i'es =hile supporting the nati!e a'tion bar on +oney'omb an" higher. +o=e!er, the &a't that this is sample 'o"e, an" not part o& the An"roi" %upport pa'kage, suggests that perhaps it has not been a"eBuately teste" or is missing key &eatures, so use it as a re&eren'e more so than a pre-pa'kage" solution. 5here are !arious An"roi" open sour'e proHe'ts, su'h as an"roi"a'tionbar, "e"i'ate" to 'reating a'tion bars that you 'oul" mi; into your layouts &or pre-+oney'omb "e!i'es. ?ou 'oul" ha!e layouts =ithout the a'tion bar in -v11 resour'e sets (e.g., res/laFout-v11/) an" layouts =ith the library7s a'tion bar in regular resour'e sets (e.g., res/laFout/). 5his =ay, the thir"-party a'tion bar =oul" only be use" on "e!i'es running lo=er than A#1 Le!el 11. A'tion2ar%herlo'k is a &ork o& the An"roi" %upport pa'kage that in'orporates an a'tion bar into 9ragmentActivitF. >n the plus si"e, it han"les all An"roi" !ersions =ith an A#1 !ery similar to the nati!e
.88
a'tion bar &or +oney'omb an" higher. 5he "o=nsi"e is that it is a &ork o& the An"roi" %upport pa'kage, an" there&ore there may be times =hen the A'tion2ar%herlo'k e"ition is missing things a""e" re'ently to the o&&i'ial pa'kage.
on a Galaxy ?exus
2ase" on emulator beha!ior, it is proHe'te" that An"roi" 2.; "e!i'es being upgra"e" to An"roi" <.0, like the -e;us %, =ill not ha!e an on-s'reen
.8:
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
options menu S rather, an options menu =ill appear &rom the bottom o& the s'reen =hen the ME-$ button is presse". Most likely, this is to make &or an easier transition &or users o& su'h "e!i'es, =ho are alrea"y use" to pressing the ME-$ button to get the options menu. 1& you a""e" toolbar buttons or !ie=s !ia android:shoDAsAction, please use if?oom, rather than alDaFs. #hones ha!e mu'h less spa'e &or toolbar buttons than "o tablets, parti'ularly in portrait mo"e, so man"atory toolbar buttons may 'ause problems &or your a'tion bars on phones.
$igure +(32 The !ctionBarBC sample application@ *ith a split action bar on "ce Cream San *ich
5o "o this, simply a"" android:ui"ptions67splitAction4ar@hen%arroD7 to your NapplicationO element in the mani&est, or on =hi'he!er NactivitFO elements you =ish to ha!e this e&&e't,
NPGml version671.-7 encoding67utf-,7PO Nmanifest package67com.commonsDare.android.actionbarbc7 Gmlns:android67http://schemas.android.com/apk/res/android7O Napplication android:hardDareAccelerated67true7 .:;
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
android:icon67QdraDable/cD7 android:label67Qstring/app name7O NactivitF android:label67Qstring/app name7 android:name67.Inflation=emo7 android:ui"ptions67splitAction4ar@hen%arroD7O Nintent-filterO Naction android:name67android.intent.action.#AI%7 /O NcategorF android:name67android.intent.categorF.)A3%+!$?7 /O N/intent-filterO N/activitFO N/applicationO Nuses-sdk android:min2dkVersion67<7 android:target2dkVersion67117 /O Nsupports-screens android:anF=ensitF67true7 android:large2creens67true7 android:normal2creens67true7 android:small2creens67true7 android:Glarge2creens67true7 /O N/manifestO
-ote that the options menu =ill appear here as =ell, at least &or "e!i'es that la'k a har"=are ME-$ button like the 8ala;y -e;us,
$igure +(62 The !ctionBarBC sample application@ *ith a split action bar@ as vie*e on a Galaxy ?exus
.:+
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
1& you "o not a"" this, you may &in" that your 'ustom !ie=s or toolbar buttons o!erlap your title,
$igure +(82 The !ctionBarBC sample application@ *ith a split action bar on "ce Cream San *ich
1t has the a""e" a"!antage o& pro!i"ing more room &or toolbar buttons an" 'ustom !ie=s S note ho= the eset option is &or'e" ba'k into the menu =ithout the split a'tion bar.
.:(
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
CHAPTER &9
$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"Hust to. +en'e, you =ill &in" &e=er blog posts or sample apps using &ragments, Hust 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.
.:.
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 siLes.
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. 1t =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 siLes. 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-siLe" s'reens, one that ha" an embe""e" @ebVieD =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 @ebVieD. +o=e!er, this =as a &airly tri!ial s'enario. 1magine i&, instea" o& a @ebVieD, =e ha" a &able)aFout 'ontaining 28 =i"gets. >n larger-siLe" s'reens, =e =ant the &able)aFout in the same a'ti!ity as an a"Ha'ent )istVieDT 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 VieDEroup, or something. An" that =oul" Hust 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.
.:'
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
$ragments
1n 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 @ebVieD). >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'hniBues =e "emonstrate =ith &ragments =ill be more s'alable, able to han"le more 'omple; $1 patterns than the simple @ebVieD-or-not 'ase o& $3<5ou. 1n this 'ase, our entire $1 =ill be insi"e o& &ragments. 5hat is not ne'essary. *ragments are an Nopt-inN te'hnology S you only nee" them &or the parts o& your $1 that 'oul" appear in "i&&erent a'ti!ities in "i&&erent s'enarios. 1n &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' 2ACD button management &or "ynami' &ragments. *or e;ample, =hen the user presses 2ACD =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. -one 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
.:1
$ragments
A &ragment 'an a"" options to the options menu, an" there&ore to the a'tion bar. Call set!as"ptions#enuLM in on+reateLM o& your &ragment to register an interest in this, then o!erri"e on+reate"ptions#enuLM an" on"ptionsItem2electedLM 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 Nna!igation mo"eN =ith a 2pinner to s=it'h bet=een mo"es, =here ea'h mo"e is represente" by a &ragment.
.:3
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
$ragments
5o a"" the An"roi" %upport pa'kage to your proHe't, you 'an either,
Copy the CA &rom your %@D installation into your libs/ "ire'tory o& your proHe't, plus a"" it to the E'lipse buil" path, or ight-'li'k o!er your proHe't in E'lipse an" 'hoose NA"" 'ompatibility libraryN &rom the An"roi" 'onte;t menu 'hoi'e
5he latter option only =orks &or E'lipseT the &ormer option =ill =ork &or 'omman" line buil"s as =ell. %in'e the An"roi" %upport pa'kage only supports ba'k to An"roi" 1.4, 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 less than 1M at this point.
Gener l 4r !ments
2esi"es inheriting &rom 9ragment, the only thing reBuire" o& a &ragment is to o!erri"e on+reateVieDLM. 5his =ill be 'alle" as part o& putting the &ragment on the s'reen. ?ou nee" to return a VieD that represents the bo"y o& the &ragment. Most likely, you =ill 'reate your &ragment7s $1 !ia an FML layout &ile, an" on+reateVieDLM =ill in&late that &ragment layout &ile.
.:6
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
$ragments
*or e;ample, here is =etails9ragment &rom $3<5ou 0, =hi'h =ill =rap aroun" our @ebVieD 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.vieD.)aFoutInflaterJ android.vieD.VieDJ android.vieD.VieDEroupJ android.Debkit.@ebVieDJ
public class =etails9ragment eGtends 9ragment : Q"verride public VieD onCreateViewL)aFoutInflater inflater8 VieDEroup container8 4undle savedInstance2tateM : returnLinflater.inflateL?.laFout.details fragment8 container8 falseMMJ ; public void load*rlL2tring urlM : LL@ebVieDMLgetViewLM.findViewByIdL?.id.broDserMMM.load*rlLurlMJ ;
-ote that =e are inheriting not &rom android.app.9ragment but &rom 5he latter is the 9ragment implementation &rom the An"roi" %upport pa'kage, an" so this 'an be use" a'ross An"roi" !ersions.
android.support.v<.app.9ragment.
5he on+reateVieDLM implementation in&lates a layout =hi'h happens to ha!e a @ebVieD in it,
NPGml version671.-7 encoding67utf-,7PO N@ebVieD Gmlns:android67http://schemas.android.com/apk/res/android7 android:id67QRid/broDser7 android:laFout Didth67fill parent7 android:laFout height67fill parent7 /O
1t also e;poses a load3rlLM 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& load3rlLM in =etails9ragment uses getVieDLM to retrie!e the VieD 'reate" in on+reateVieDLM, &in"s the @ebVieD in it, an" "elegates the load3rlLM 'all to the @ebVieD.
.:8
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
$ragments
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+reateLM, on2tartLM, on?esumeLM, on(auseLM, on2topLM, an" on=estroFLM 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(auseLM or on2topLM, 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. 1n the 'ase o& =etails9ragment, there =as nothing that really Buali&ie" here, so those li&e'y'le metho"s =ere le&t alone.
)ist4r !ment
>ne *ragment sub'lass that is sure to be popular is )ist9ragment. 5his =raps a )istVieD 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)istAdapterLM =ith your 'hosen an" 'on&igure" )istAdapter, plus o!erri"e on)istItem+lickLM to respon" to =hen the user 'li'ks on a ro= in the list. 1n $3<5ou 0, =e ha!e a +ountries9ragment that represents the list o& a!ailable 'ountries. 1t initialiLes the )istAdapter in onActivitF+reatedLM, =hi'h is 'alle" a&ter on+reateLM has =rappe" up in the a'ti!ity that hol"s the &ragment,
Q"verride public void on$cti!ityCreatedL4undle stateM : super.on$cti!ityCreatedLstateMJ setList$dapterLneD Country$dapterLMMJ if LstateX6nullM : int position6state.getIntL2&A&$ +!$+H$=8 -1MJ if LpositionO-1M : getListViewLM.setItemCheckedLposition8 trueMJ ;
; ;
5he 'o"e "ealing =ith the 4undle supplie" to on+reateLM =ill be e;plaine" a bit later in this 'hapter.
.::
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
$ragments
5he +ountrFAdapter is nearly i"enti'al to the one &rom past $3<5ou samples, e;'ept that there is no get)aFoutInflaterLM metho" on a 9ragment, so =e ha!e to use the stati' fromLM metho" on )aFoutInflater an" supply our a'ti!ity !ia getActivitFLM,
class +ountrFAdapter eGtends ArraFAdapterN+ountrFO : Country$dapterLM : superLget$cti!ityLM8 ?.laFout.roD8 ?.id.name8 $3MJ ; Q"verride public VieD getViewLint position8 VieD convertVieD8 VieDEroup parentM : +ountrF@rapper Drapper6nullJ if LconvertVieD66nullM : convertVieD6)aFoutInflater .fromLget$cti!ityLMM .inflateL?.laFout.roD8 nullMJ Drapper6neD Country#rapperLconvertVieDMJ convertVieD.setTagLDrapperMJ ; else : Drapper6L+ountrF@rapperMconvertVieD.getTagLMJ ; Drapper.populate"romLgetItemLpositionMMJ returnLconvertVieDMJ ; ;
';;
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
$ragments
; ;
';+
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
$ragments
$3.addLneD CountryL?.string.romania8 ?.draDable.romania8 ?.string.romania urlMMJ $3.addLneD CountryL?.string.slovakia8 ?.draDable.slovakia8 ?.string.slovakia urlMMJ $3.addLneD CountryL?.string.slovenia8 ?.draDable.slovenia8 ?.string.slovenia urlMMJ $3.addLneD CountryL?.string.spain8 ?.draDable.spain8 ?.string.spain urlMMJ $3.addLneD CountryL?.string.sDeden8 ?.draDable.sDeden8 ?.string.sDeden urlMMJ $3.addLneD CountryL?.string.united kingdom8 ?.draDable.united kingdom8 ?.string.united kingdom urlMMJ ;
"ersistent 2ighlight
>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 )istVieD, =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"Ha'ent &ragment. 5he a'tual implementation "i&&ers &rom =hat you might e;pe't. 5hese )istVieD =i"gets are a'tually implementing +!"I+$ #"=$ 2I%E)$, =hat normally =oul" be ren"ere" using a ?adio4utton along the right si"e o& the ro=s. 1n a )ist9ragment, though, the typi'al styling &or a single-'hoi'e )ist9ragment is !ia an Na'ti!ate"N ba'kgroun".
';(
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
$ragments
1n $3<5ou 0, this is han"le" !ia the ro= layout ( res/laFout/roD.Gml) use" by our +ountrFAdapter,
NPGml version671.-7 encoding67utf-,7PO N)inear)aFout Gmlns:android67http://schemas.android.com/apk/res/android7 android:laFout Didth67fill parent7 android:laFout height67Drap content7 android:padding67>dip7 android:min!eight67Pandroid:attr/list(referredItem!eight7 stFle67QstFle/activated7 O NImageVieD android:id67QRid/flag7 android:laFout Didth67Drap content7 android:laFout height67Drap content7 android:laFout gravitF67center verticalWleft7 android:padding?ight67<dip7 /O N&eGtVieD android:id67QRid/name7 android:laFout Didth67Drap content7 android:laFout height67Drap content7 android:laFout gravitF67center verticalWright7 android:teGt2iKe67.mm7 /O N/)inear)aFoutO
?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. 1n &a't, it has to ha!e t=o implementations o& the style, be'ause the Na'ti!ate"N '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,
NPGml version671.-7 encoding67utf-,7PO NresourcesO NstFle name67activated7O N/stFleO N/resourcesO
1t also has res/values-v11/stFles.Gml. 5he -v11 resour'e set su&&i; means that this =ill only be use" on A#1 Le!el 11 (An"roi" /.0) an" higher. +ere, the style inherits &rom the stan"ar" An"roi" Nholographi'N theme an" uses the stan"ar" a'ti!ate" ba'kgroun" 'olor,
';.
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
$ragments
NPGml version671.-7 encoding67utf-,7PO NresourcesO NstFle name67activated7 parent67android:&heme.!olo7O Nitem name67android:background7OP android:attr/activated4ackgroundIndicatorN/itemO N/stFleO N/resourcesO
1n +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(ersistent2electionLM metho",
public void ena'le)ersistentSelectionLM : getListViewLM.setChoiceModeL)istVieD.+!"I+$ #"=$ 2I%E)$MJ ;
Also, in on)istItem+lickLM, +ountries9ragment N'he'ksN the ro= the user 'li'ke" upon, thereby enabling the persistent highlight,
Q"verride public void onListItemClickL)istVieD l8 VieD v8 int position8 long idM : l.setItemCheckedLposition8 trueMJ if LlistenerX6nullM : listener.onCountrySelectedL$3.getLpositionMMJ ; ;
(the listener obHe't an" 'all to on+ountrF2electedLM =ill be e;plaine" later in this 'hapter)
';'
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
$ragments
,ultiple
+a!ing some &ragment 'lasses an" their a''ompanying layouts is all =ell an" goo", but some=here along the line, =e nee" to hook them up to a'ti!ities an" get them on the s'reen. Along the =ay, =e =ill ha!e to think about "ealing =ith multiple s'reen siLes, mu'h like =e =ent =ith the @ebVieD-or-bro=ser approa'h =ith the pre!ious !ersion o& the $3<5ou sample. 1n An"roi" /.0 an" higher, any a'ti!ity 'an host a &ragment. +o=e!er, &or the An"roi" %upport pa'kage, you nee" to inherit &rom 9ragmentActivitF to use &ragments. 5his limitation o& the An"roi" %upport pa'kage "e&initely 'auses 'hallenges, parti'ularly i& you =ere aiming to put a map in a &ragment, a topi' =e =ill "is'uss later in this book. >ther a'ti!ity base 'lasses =ill pose less o& an issue S )istActivitF =oul" be repla'e" by )ist9ragment, &or e;ample. *ragments are a""e" in t=o =ays to an a'ti!ity, 1. ?ou 'an "e&ine them !ia NfragmentO elements in the a'ti!ity7s layout. 5hese &ragments are &i;e" an" =ill al=ays e;ist &or the li&etime o& this a'ti!ity instan'e.
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'hniBue is not 'o!ere" in this book. >ne big limitation o& "ealing =ith multiple s'reen siLes 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
';1
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
$ragments
layout &or the same s'reen siLe 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 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-Pa'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 obHe'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;02ou
1n the earlier !ersions o& the $3<5ou proHe't, =e ha" only one a'ti!ity, also name" $3<5ou. 1n $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 siLes, 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 @ebVieD-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.
';3
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
$ragments
&he (a!out
*or normal-s'reen "e!i'es, =e =ant to Hust "isplay the +ountries9ragment. 5hat is a''omplishe" !ia res/laFout/main.Gml Hust ha!ing the appropriate NfragmentO element,
NPGml version671.-7 encoding67utf-,7PO Nfragment Gmlns:android67http://schemas.android.com/apk/res/android7 class67com.commonsDare.android.eu<Fou0.+ountries9ragment7 android:id67QRid/countries7 android:laFout Didth67fill parent7 android:laFout height67fill parent7 /O
5he class attribute in"i'ates =hat Ca!a 'lass implements the &ragment. >ther=ise, this layout is unremarkable. -ote that &ragments "o not get liste" in the mani&est &ile the =ay a'ti!ities "o.
';6
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
$ragments
-ote that =e are responsible &or the positioning o& the &ragments, so here =e use a horiLontal )inear)aFout to =rap aroun" the t=o NfragmentO elements.
';8
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
$ragments
5he +ountries9ragment hol"s onto an instan'e o& +ountrF)istener, supplie" by the hosting a'ti!ity,
public void setCountryListenerL+ountrF)istener listenerM : this.listener6listenerJ ;
An", =hen the user 'li'ks on a 'ountry an" triggers on)istItem+lickLM, +ountries9ragment 'alls the on+ountrF2electedLM metho" on the inter&a'e,
Q"verride public void onListItemClickL)istVieD l8 VieD v8 int position8 long idM : l.setItemCheckedLposition8 trueMJ if LlistenerX6nullM : listener.onCountrySelectedL$3.getLpositionMMJ ;
&he Activit!
5he $3<5ou a'ti!ity is not long, though it is a bit tri'ky,
package com.commonsDare.android.eu<Fou0J import import import import import import android.content.IntentJ android.content.res.+onfigurationJ android.os.4undleJ android.support.v<.app.9ragmentJ android.support.v<.app.9ragmentActivitFJ android.vieD.VieDJ
public class $3<5ou eGtends 9ragmentActivitF implements +ountrF)istener : private boolean detailsInline6falseJ Q"verride public void onCreateL4undle savedInstance2tateM : super.onCreateLsavedInstance2tateMJ setContentViewL?.laFout.mainMJ +ountries9ragment countries 6L+ountries9ragmentMgetSupport"ragmentManagerLM .find"ragmentByIdL?.id.countriesMJ countries.setCountryListenerLthisMJ 9ragment f6getSupport"ragmentManagerLM.find"ragmentByIdL?.id.detailsMJ
';:
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
$ragments
detailsInline6LfX6null ZZ Lget%esourcesLM.getConfigurationLM.orientation66 +onfiguration."?I$%&A&I"% )A%=2+A($MMJ if LdetailsInlineM : countries.ena'le)ersistentSelectionLMJ ; else if LfX6nullM : f.getViewLM.setVisi'ilityLVieD.E"%$MJ ; ; Q"verride public void onCountrySelectedL+ountrF cM : 2tring url6getStringLc.urlMJ if LdetailsInlineM : LL=etails9ragmentMgetSupport"ragmentManagerLM .find"ragmentByIdL?.id.detailsMM .load*rlLurlMJ ; else : Intent i6neD IntentLthis8 =etailsActivitF.classMJ i.put+xtraL=etailsActivitF.$]&?A 3?)8 urlMJ start$cti!ityLiMJ ; ; ;
>ur mission in on+reateLM is to =ire up our &ragments. 5he &ragments themsel!es are 'reate" by our 'all to set+ontentVieDLM, in&lating our layout an" the &ragments "e&ine" therein. 1n a""ition, though, $3<5ou,
*in"s
the +ountries9ragment an" registers itsel& +ountrF)istener, sin'e $3<5ou implements that inter&a'e.
as
the
*in"s the =etails9ragment, i& it e;ists. 1& 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. 1& =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 E"%$. >ther=ise, the =etails9ragment "oes not e;ist, an" so =e "o not ha!e to "o anything spe'ial.
'+;
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
$ragments
1n An"roi" /.0, getting the 9ragment#anager &or 'alls like find9ragment4FIdLM is a''omplishe" !ia get9ragment#anagerLM. 5he An"roi" %upport pa'kage, ho=e!er, "e&ines a separate get2upport9ragment#anagerLM, to ensure you are =orking =ith the An"roi" %upport pa'kage7s implementation o& 9ragment#anager an" to =ork a'ross the =i"er range o& An"roi" !ersions. 1n a""ition, sin'e $3<5ou implements the +ountrF)istener inter&a'e, it must implement on+ountrF2electedLM. +ere, $3<5ou notes =hether =e shoul" be routing to an inline e"ition o& =etails9ragment or not. 1& =e are, then on+ountrF2electedLM 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 siLe 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 siLe an" there&ore $3<5ou is hi"ing its o=n =etails9ragment
&he (a!out
5he layout Hust has our NfragmentO element in it, sin'e there is nothing else to sho=,
NPGml version671.-7 encoding67utf-,7PO Nfragment Gmlns:android67http://schemas.android.com/apk/res/android7 class67com.commonsDare.android.eu<Fou0.=etails9ragment7 android:id67QRid/details7 android:laFout Didth67fill parent7 android:laFout height67fill parent7 /O
'++
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
$ragments
&he Activit!
=etailsActivitF simply passes the $ L &rom the Intent =etails9ragment, telling it =hat Web 'ontent to "isplay,
package com.commonsDare.android.eu<Fou0J import android.os.4undleJ import android.support.v<.app.9ragmentActivitFJ public class =etailsActivitF eGtends 9ragmentActivitF : public static final 2tring $]&?A 3?)67com.commonsDare.android.eu<Fou.$]&?A 3?)7J Q"verride public void onCreateL4undle savedInstance2tateM : super.onCreateLsavedInstance2tateMJ setContentViewL?.laFout.detailsMJ =etails9ragment details 6L=etails9ragmentMgetSupport"ragmentManagerLM .find"ragmentByIdL?.id.detailsMJ details.load*rlLgetIntentLM.getString+xtraL$]&?A 3?)MMJ ; ;
e;tra on to the
$ragments an
Configuration Changes
1n a pre!ious 'hapter, =e re!ie=e" ho= a'ti!ities 'an "eal =ith 'on&iguration 'hanges, su'h as s'reen rotations. +o= "oes this translate into a =orl" o& &ragmentsI Well, as is typi'al, there is goo" ne=s, an" there is other ne=s. 5he goo" ne=s is that &ragments ha!e on2aveInstance2tateLM metho"s that they 'an o!erri"e, beha!ing mu'h like their a'ti!ity 'ounterparts. 5he 4undle then is ma"e a!ailable in a !ariety o& pla'es, su'h as on+reateLM an" onActivitF+reatedLM, though there is no "e"i'ate" on?estoreInstance2tateLM.
'+(
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
$ragments
5he
not only "o &ragments la'k on?etain%on+onfigurationInstanceLM but the An"roi" %upport pa'kage7s 9ragmentActivitF "oes not allo= you to e;ten" on?etain%on+onfigurationInstanceLM, as that is use" internally. Appli'ations using the An"roi" /.0 implementation o& &ragments "ire'tly "o not su&&er &rom this problem. 5his limitation is substantial, an" it remains to be seen =hat te'hniBues =e 'olle'ti!ely =ork out to get past the limitation.
other
ne=s
is
that
'+.
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
$ragments
pa'kaging them in pre-&abri'ate" a'ti!ities an" &ragments &or reuse in the &orm o& libraries an" CA s.
'+'
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
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 4-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. 1n 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.
'+1
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 1& you en'ounter a 2tack"verfloD$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 siLe =oun" up NbreakingN an" nee"ing some $1 a"Hustment. %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 $1 look-an"-&eel. elying upon the e;isting ones to al=ays
'+3
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
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 proHe't into your o=n 'o"e base.
'+6
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
proHe'ts, primarily to "etermine =hat !ersion o& the %@D buil" tools =ill be use" to buil" your proHe't. A target 'ombines an A#1 le!el =ith an in"i'ator o& =hether or not the target in'lu"es 8oogle A#1s (e.g., 8oogle Maps support). An A#1 le!el is an integer representing a !ersion o& the An"roi" A#1. Ea'h An"roi" >% release that makes 'hanges to the An"roi" A#1 triggers a ne= A#1 le!el. %o, =e ha!e,
An"roi" 1.Ar1, 1.Ar2, an" 1.Ar/ all using A#1 Le!el C An"roi" 1.4r1 an" 1.4r2 using A#1 Le!el < An"roi" 2.0 using A#1 Le!el . An"roi" 2.0.1 using A#1 Le!el 0 An"roi" 2.1 using A#1 Le!el / An"roi" 2.2 using A#1 Le!el , An"roi" 2./ using A#1 Le!el * An"roi" 2././ using A#1 Le!el 1An"roi" /.0 using A#1 Le!el 11 An"roi" /.1 using A#1 Le!el 1> An"roi" /.2 using A#1 Le!el 1C An"roi" <.0 using A#1 Le!el 1< an" so on
8oogle maintains a Web page outlining =hi'h !ersions o& An"roi" are in use to"ay, base" on reBuests ma"e to the An"roi" Market.
5he most 'riti'al attribute to ha!e in Nuses-sdkO is android:min2dkVersion. 5his in"i'ates =hat the lo=est A#1 le!el is that you =ill support. @e!i'es running An"roi" >% !ersions asso'iate" =ith lo=er A#1 le!els =ill not be able to install your appli'ation. ?our appli'ation may not e!en appear to those "e!i'es in the An"roi" Market listings, shoul" you ele't to publish !ia that "istributor. 1& you skip this attribute, An"roi" assumes you =ork on all An"roi" A#1 !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.
'+:
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
+o=e!er, bear in min" that your appli'ation =ill be &iltere" out o& the An"roi" Market &or these ne=er "e!i'es. >!er time, this =ill limit the rea'h 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.
problem. 1t is only i& you e;e'ute 'o"e that triggers An"roi" to loa" that 'lass into your running pro'ess =ill you en'ounter the VerifF$rror. An"roi" 2.; an" beyon" is more generous S you 'an loa" 'o"e that re&ers to 'lasses an" metho"s that "o not e;ist, but you 'annot e;e'ute that 'o"e. With that in min", there are three primary tri'ks to "eal =ith this situation, outline" in the &ollo=ing se'tions.
Detecting Classes
#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 N&ragmentsN &eature. ?ou 'annot su''ess&ully start that a'ti!ity on a pre-/.0 "e!i'e. %topping that may Hust 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%ameLM. 5his =ill either return a +lass obHe't representing the reBueste" '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 $1 paths that =oul" 'ause you to try starting an a'ti!ity that uses the una!ailable 'lass.
#eflection
1& 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. 1n those samples, =e spe'i&i'ally use" +ontacts+ontract, the re!ise" 'onta'ts A#1 o&&ere" in An"roi" 2.0 an" beyon". 5hat means those proHe'ts =ill not =ork on ol"er !ersions o& An"roi".
'(+
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
+o=e!er, all =e really nee" is this magi' 3ri !alue. 1& =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,
static : int sdk6neD IntegerL4uild.V$?2I"%.2=HM.intValueLMJ if LsdkO6.M : trF : +lass claKK6+lass.for&ameL7android.provider.+ontacts+ontract'+ontacts7MJ +"%&$%& 3?I6L3riMclaKK.get"ieldL7+"%&$%& 3?I7M.getLclaKKMJ ; catch L&hroDable tM : )og.eL7(ick=emo78 7$Gception Dhen determining +"%&$%& 3?I78 tMJ ;
+ere, =e e;amine the A#1 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.4 S the 'o"e sho=n here =orks on An"roi" 1.A as =ell). 1& =e are at An"roi" 2.0 (A#1 le!el A) or higher, =e use +lass.for%ameLM 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. 1& =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".
'((
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
5he most po=er&ul te'hniBue, there&ore, is simply to organiLe your 'o"e su'h that you ha!e regular 'lasses using ne=er A#1s, but you "o not loa" those 'lasses on ol"er "e!i'es. We =ill e;amine this te'hniBue in this ne;t se'tion, =here =e apply it to keeping our +oney'omb 'o"e separate &rom the rest o& our appli'ation. Again, this is only reBuire" i& you are supporting An"roi" 1.; "e!i'es. 1& you are only supporting An"roi" 2.1 an" ne=er, you 'an simply isolate the ne=%@D 'o"e in an ifLM blo'k, testing the A#1 le!el, an" only e;e'uting the ne=er %@D 'o"e =hen you are on a ne=er "e!i'e.
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 that an options menu item 'an be sho=n in the a'tion bar reBuires Hust an attribute in the menu resour'e FML, an attribute that =ill be ignore" on ol"er !ersions o& An"roi". An"roi" /.; an" <.; "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. 1n the #enus/Action4ar sample appli'ation, =e a""e" a 'ustom VieD 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 reBuire" some 'o"e that =oul" only =ork on A#1 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 reBuirements.
'(.
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
?ou nee" to arrange to only use those a'tion bar metho"s on "e!i'es that run A#1 Le!el 11 or higher. Con"itional 'lass loa"ing is one su'h te'hniBue an" is the te'hniBue use" in the #enus/Action4ar4+ sample appli'ation. Let7s take a look at ho= this =orks.
5his is &ine, but it =ill only =ork on A#1 Le!el 11 an" higher, as getActionVieDLM only e;ists &rom that A#1 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#enuLM hi"es the o&&en"ing 'o"e an" 'he'ks the A#1 le!el,
public boolean onCreateOptionsMenuL#enu menuM : neD MenuInflaterLthisM.inflateL?.menu.option8 menuMJ $dit&eGt add6nullJ if L4uild.V$?2I"%.2=H I%&O64uild.V$?2I"% +"=$2.!"%$5+"#4M : VieD v6!oneFcomb!elper.get$dd$ctionViewLmenuMJ if LvX6nullM : add6L$dit&eGtMv.findViewByIdL?.id.titleMJ ; ; if LaddX6nullM : add.setOn+ditor$ctionListenerLon2earchMJ
'('
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
; returnLsuper.onCreateOptionsMenuLmenuMMJ ;
We only hi"e the 'o"e that retrie!es the VieD that =e theoreti'ally ha!e put in the a'tion bar. 1& =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 VieD, so =e skip a""ing the "n$ditorAction)istener to the $dit&eGt insi"e o& that VieD. 5his has another bene&it, it =orks i& the An"roi" "e!i'e runs A#1 Le!el 11 or higher but "oes not ha!e room &or our 'ustom VieD. 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. 1n that 'ase, the phone =oul" lea!e the NA""N options menu item in pla'e, an" =e still =oul" =in" up =ith a null VieD. 5his 'o"e han"les that s'enarioT the original 'o"e "i" not.
!oneFcomb!elper has a single getAddActionVieDLM stati' VieD &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/Action4ar4+ app =orks on An"roi" 1.4 an" ne=er.
'(1
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
1& =e only =ante" to support An"roi" 2.; an" higher, =e =oul" not nee" !oneFcomb!elper. 1nstea", =e 'oul" put the a'tion bar logi' right in on+reate"ptions#enuLM, but still prote'te" by the A#1 le!el test,
Q"verride public boolean onCreateOptionsMenuL#enu menuM : neD MenuInflaterLthisM.inflateL?.menu.option8 menuMJ $dit&eGt add6nullJ if L4uild.V$?2I"%.2=H I%&O64uild.V$?2I"% +"=$2.!"%$5+"#4M : VieD v6menu.findItemL?.id.addM.get$ctionViewLMJ if LvX6nullM : add6L$dit&eGtMv.findViewByIdL?.id.titleMJ ;
'(3
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
+en'e, i& your appli'ation =ill only make sense &or larger-s'reen "e!i'es, use a Nsupports-screensO element like this,
Nsupports-screens android:Glarge2creens67true7 android:large2creens67true7 android:normal2creens67false7 android:small2creens67false7 android:anF=ensitF67true7/O
'(6
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
CHAPTER /<
!ccessing $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.
/ou !n
Let7s suppose you ha!e some stati' "ata you =ant to ship =ith the appli'ation, su'h as a list o& =or"s &or a spell-'he'ker. 5he easiest =ay to "eploy that is to put the &ile in the res/raD "ire'tory, so it gets put in the An"roi" appli'ation .apk &ile as part o& the pa'kaging pro'ess as a ra= resour'e. 5o a''ess this &ile, you nee" to get yoursel& a ?esources obHe't. *rom an a'ti!ity, that is as simple as 'alling get?esourcesLM. A ?esources obHe't o&&ers open?aD?esourceLM to get an Input2tream on the &ile you spe'i&y. ather than a path, open?aD?esourceLM e;pe'ts an integer i"enti&ier &or the &ile as pa'kage". 5his =orks Hust like a''essing =i"gets !ia findVieD4FIdLM S i& you put a &ile name" Dords.Gml in res/raD, the i"enti&ier is a''essible in Ca!a as ?.raD.Dords. %in'e you 'an only get an Input2tream, you ha!e no means o& mo"i&ying this &ile. +en'e, it is really only use&ul &or stati' re&eren'e "ata. Moreo!er, sin'e it is un'hanging until the user installs an up"ate" !ersion o& your
'.+
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
!ccessing $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. 1n the 9iles/2tatic sample proHe'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,
NPGml version671.-7 encoding67utf-,7PO N)inear)aFout Gmlns:android67http://schemas.android.com/apk/res/android7 android:orientation67vertical7 android:laFout Didth67fill parent7 android:laFout height67fill parent7 O N&eGtVieD android:id67QRid/selection7 android:laFout Didth67fill parent7 android:laFout height67Drap content7 /O N)istVieD android:id67Qandroid:id/list7 android:laFout Didth67fill parent7 android:laFout height67fill parent7 android:draD2elector"n&op67false7 /O N/)inear)aFoutO
1n a""ition to that FML &ile, you also nee" an FML &ile =ith the =or"s to sho= in the list,
NDordsO NDord NDord NDord NDord NDord NDord NDord NDord value67lorem7 /O value67ipsum7 /O value67dolor7 /O value67sit7 /O value67amet7 /O value67consectetuer7 /O value67adipiscing7 /O value67elit7 /O
'.(
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
!ccessing $iles
NDord value67morbi7 /O NDord value67vel7 /O NDord value67ligula7 /O NDord value67vitae7 /O NDord value67arcu7 /O NDord value67aliUuet7 /O NDord value67mollis7 /O NDord value67etiam7 /O NDord value67vel7 /O NDord value67erat7 /O NDord value67placerat7 /O NDord value67ante7 /O NDord value67porttitor7 /O NDord value67sodales7 /O NDord value67pellentesUue7 /O NDord value67augue7 /O NDord value67purus7 /O N/DordsO
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 : &eGtVieD selectionJ ArraF)istN2tringO items6neD ArraF)istN2tringOLMJ Q"verride public void onCreateL4undle icicleM : super.onCreateLicicleMJ setContentViewL?.laFout.mainMJ selection6L&eGtVieDMfindViewByIdL?.id.selectionMJ trF : Input2tream in6get%esourcesLM.open%aw%esourceL?.raD.DordsMJ =ocument4uilder builder6=ocument4uilder9actorF .newInstanceLM .newDocumentBuilderLMJ =ocument doc6builder.parseLin8 nullMJ %ode)ist Dords6doc.get+lementsByTag&ameL7Dord7MJ for Lint i6-JiNDords.getLengthLMJiRRM : items.addLLL$lementMDords.itemLiMM.get$ttri'uteL7value7MMJ ; in.closeLMJ ; catch L&hroDable tM : &oast '..
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
!ccessing $iles
setList$dapterLneD ArraFAdapterN2tringOLthis8 android.?.laFout.simple list item 18 itemsMMJ ; public void onListItemClickL)istVieD parent8 VieD v8 int position8 long idM : selection.setTextLitems.getLpositionM.toStringLMMJ ; ;
5he "i&&eren'es mostly lie =ithin on+reateLM. We get an Input2tream &or the FML &ile (get?esourcesLM.open?aD?esourceL?.raD.DordsM), 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, Hust relo'ate",
'.'
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
!ccessing $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" Hust 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.
Wrap those streams as nee"e", su'h as using an Input2tream?eader or "utput2tream@riter &or te;t-base" 1Q> ea" or =rite the "ata $se closeLM to release the stream =hen "one
1& t=o appli'ations both try rea"ing a notes.tGt &ile !ia open9ileInputLM, they =ill ea'h a''ess their o=n e"ition o& the &ile. 1& 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. -ote that open9ileInputLM an" open9ile"utputLM "o not a''ept &ile paths (e.g., path/to/file.tGt), Hust simple &ilenames. 2elo= 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,
NPGml version671.-7 encoding67utf-,7PO N$dit&eGt Gmlns:android67http://schemas.android.com/apk/res/android7 android:id67QRid/editor7 android:laFout Didth67fill parent7 android:laFout height67fill parent7 android:single)ine67false7 android:gravitF67top7 /O
'.1
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
!ccessing $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.commonsDare.android.readDriteJ import import import import import import import import import import import import android.app.ActivitFJ android.os.4undleJ android.vieD.VieDJ android.Didget.4uttonJ android.Didget.$dit&eGtJ android.Didget.&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 Q"verride public void onCreateL4undle icicleM : super.onCreateLicicleMJ setContentViewL?.laFout.mainMJ editor6L$dit&eGtMfindViewByIdL?.id.editorMJ ; public void on%esumeLM : super.on%esumeLMJ trF : Input2tream in6open"ileInputL%"&$2MJ if LinX6nullM : Input2tream?eader tmp6neD InputStream%eaderLinMJ 4uffered?eader reader6neD Buffered%eaderLtmpMJ 2tring strJ 2tring4uilder buf6neD StringBuilderLMJ Dhile LLstr 6 reader.readLineLMM X6 nullM : buf.appendLstrR7Tn7MJ ; in.closeLMJ editor.setTextLbuf.toStringLMMJ ; ; catch Ljava.io.9ile%ot9ound$Gception eM : // thatIs "H8 De probablF havenIt created it Fet
'.3
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
!ccessing $iles
public void on)auseLM : super.on)auseLMJ trF : "utput2tream@riter out6 neD OutputStream#riterLopen"ileOutputL%"&$28 -MMJ out.writeLeditor.getTextLM.toStringLMMJ out.closeLMJ ; catch L&hroDable tM : &oast .makeTextLthis8 7$Gception: 7Rt.toStringLM8 &oast.)$%E&! )"%EM .showLMJ ; ; ;
*irst, =e hook into on?esumeLM, 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 &roLen. We use open9ileInputLM to rea" in notes.tGt an" pour the 'ontents into the te;t e"itor. 1& 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 Hust lea!e the e"itor empty. *inally, =e hook into on(auseLM, 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 2ACD button. +ere, =e use open9ile"utputLM 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 2ACD button), the phone being turne" o&&, or similar situations.
'.6
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
!ccessing $iles
'.8
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
!ccessing $iles
Another approa'h &or =orking =ith appli'ation-lo'al &iles is to use get9iles=irLM. 5his returns a 9ile obHe't pointing to a pla'e in the internal storage =here an appli'ation 'an store &iles. 5his "ire'tory is =here open9ileInputLM an" open9ile"uptutLM =ork. +o=e!er, =hile open9ileInputLM an" open9ile"utputLM "o not support sub"ire'tories, the 9ile &rom get9iles=irLM '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 NrootN 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.
'.:
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
!ccessing $iles
,here to ,rite
1& 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=irLM, a!ailable on any a'ti!ity or other +onteGt. 5his =ill gi!e you a 9ile obHe't pointing to an automati'ally-'reate" "ire'tory on e;ternal storage, uniBue &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", Hust like the ones in the appli'ation-lo'al &ile area. 5his metho" =as a""e" in A#1 Le!el 8. 1& 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=irectorFLM, a!ailable on the $nvironment 'lass. 5his =ill gi!e you a 9ile obHe'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=irectorFLM. *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". 5his metho" =as also a""e" in A#1 Le!el 8. ?ou =ill also &in" a get$Gternal2torage=irectorFLM 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 organiLe". +o=e!er, i& you are supporting ol"er An"roi" "e!i'es, you may nee" to use get$Gternal2torage=irectorFLM, simply be'ause the ne=er options may not be a!ailable to you.
,hen to ,rite
%tarting =ith An"roi" 1.4, you =ill also nee" to hol" permissions to =ork =ith e;ternal storage (e.g., @?I&$ $]&$?%A) 2&"?AE$) 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 $%2 storage "e!i'e. ?ou 'an use get$Gternal2torage2tateLM (a stati' metho"
'';
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
!ccessing $iles
on $nvironment) to "etermine i& there e;ternal storage is presently a!ailable or not. >n An"roi" /.0 an" higher, this shoul" be mu'h less o& an issue, as they 'hange" ho= the e;ternal storage is use" by the host #C S originally, this use" $%2 Mass %torage Mo"e (think thumb "ri!es) an" no= uses the $%2 Me"ia 5rans&er #roto'ol (think M#/ players). With M5#, both the An"roi" "e!i'e an" the #C it is 'onne'te" to 'an ha!e a''ess to the &iles simultaneouslyT Mass %torage Mo"e =oul" only allo= the host #C a''ess to the &iles i& e;ternal storage is mounte".
*lash 1Q>, both &or the on-boar" storage an" &or Ne;ternal storageN (e.g., the %@ 'ar") -et=ork 1Q>
+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.
''+
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
!ccessing $iles
5hat is =here 2trict#ode 'omes in. 1ts mission is to help you "etermine =hen you are "oing things on the main appli'ation threa" that might 'ause a Hanky user e;perien'e.
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=efaultsLM metho" on 2trict#ode &rom on+reateLM 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 obHe'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)olicyLneD 2trict#ode.&hread(olicF.BuilderLM .detect$llLM .penaltyLogLM .'uildLMMJ
''(
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
!ccessing $iles
1& 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,
1>->, 1/:1*:<-.--*: =$43E/2trict#odeL<,-M: 2trict#ode policF violationJ ^duration610* ms: android.os.2trict#ode'2trict#ode=isk?eadViolation: policF6>C violation6> 1>->, 1/:1*:<-.--*: =$43E/2trict#odeL<,-M: at android.os.2trict#ode'Android4lockEuard(olicF.on?ead9rom=iskL2trict#ode.java:/<. M 1>->, 1/:1*:<-.--*: =$43E/2trict#odeL<,-M: at dalvik.sFstem.4lockEuard'@rapped9ile2Fstem.openL4lockEuard.java:>>,M 1>->, 1/:1*:<-.--*: =$43E/2trict#odeL<,-M: at android.app.+onteGtImpl.open9ile"utputL+onteGtImpl.java:<1-M 1>->, 1/:1*:<-.--*: =$43E/2trict#odeL<,-M: at android.content.+onteGt@rapper.open9ile"utputL+onteGt@rapper.java:1.,M 1>->, 1/:1*:<-.--*: =$43E/2trict#odeL<,-M: at com.commonsDare.android.readDrite.?ead@rite9ile=emo.on(auseL?ead@rite9ile=emo.ja va:,>M ...
+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). 1"eally, =e =oul" re=rite this proHe'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"
''.
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
!ccessing $iles
is only &or An"roi" 2./ an" higher. +en'e, i& =e ha!e it in our 'o"e, e!en in "e!elopment mo"e, it might inter&ere =hen =e try testing on ol"er emulators or "e!i'es. As =e sa= in an earlier 'hapter, there are te'hniBues &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 organiLe your 'o"e su'h that you ha!e regular 'lasses using ne=er A#1s, but you "o not loa" those 'lasses on ol"er "e!i'es. 5he A(IVersions/?ead@rite2trict proHe'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+reateLM 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.commonsDare.android.rDversionsJ import android.os.4uildJ abstract class 2trict@rapper : static public void initLM : if L4uild.V$?2I"%.2=H I%&O64uild.V$?2I"% +"=$2.EI%E$?4?$A=M : neD Strict"or%eal.LMJ ; else : neD &ot$llThatStrictLMJ ; ; static class %otAll&hat2trict eGtends 2trict@rapper : // no methods needed ; ;
5his o""-looking 'lass en'apsulates our N"o-=e-or-"on7t-=eN logi' &or "ealing =ith 2trict#ode. 1t 'ontains an initLM metho" that, =hen 'alle", 'he'ks to see =hat !ersion o& An"roi" the appli'ation is running on, an"
'''
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
!ccessing $iles
'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, "oes nothing, re&le'ting that there is no 2trict#ode in ne=er !ersions o& An"roi".
2trict9or?ealK 'ontains
package com.commonsDare.android.rDversionsJ import android.os.2trict#odeJ class 2trict9or?ealK eGtends 2trict@rapper : Strict"or%eal.LM : 2trict#ode.setThread)olicyLneD 2trict#ode.&hread(olicF.BuilderLM .detect$llLM .penaltyLogLM .'uildLMMJ ; ;
An", our on+reateLM metho" o& our a'ti!ity 'alls initLM on 2trict@rapper, to trigger 'reating the proper obHe't,
Q"verride public void onCreateL4undle icicleM : super.onCreateLicicleMJ setContentViewL?.laFout.mainMJ 2trict@rapper.initLMJ editor6L$dit&eGtMfindViewByIdL?.id.editorMJ ;
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 initLM statement in on+reateLM, 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 initLM 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.
''1
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
!ccessing $iles
+ere, all =e nee"e" =as a bit o& initialiLation. 5he singleton pattern is use" to "emonstrate that you 'oul" e;pose an !ersion-"epen"ent A#1 implementation i& you "esire". %imply "e&ine the A#1 as abstra't metho"s 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).
''3
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
!ccessing $iles
1& you are using java.io.?andomAccess9ile in a syn'hronous mo"e, this step is han"le" &or you as =ell, so you =ill not nee" to =orry about it. +o=e!er, Ca!a "e!elopers ten" to use 9ile"utput2tream, =hi'h "oes not trigger an fsFncLM, e!en =hen you 'all closeLM on the stream. 1nstea", you 'all get9=LM.sFncLM on the 9ile"utput2tream to trigger the fsFncLM. -ote 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.
''6
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
CHAPTER /1
=sing Preferences
An"roi" has many "i&&erent =ays &or you to store "ata &or 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& keyQ!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(referencesLM &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(referencesLM, 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(referencesLM metho" also takes a name o& a set o& pre&eren'es S get(referencesLM e&&e'ti!ely 'alls get2hared(referencesLM =ith the a'ti!ity7s 'lass name as the pre&eren'e set name. 5he get=efault2hared(referencesLM 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., get4ooleanLM 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(referencesLM S as that =ill gi!e you the 2hared(references obHe't that =orks =ith a (referenceActivitF by "e&ault, as =ill be "es'ribe" later in this 'hapter.
5he last one is important S i& you mo"i&y pre&eren'es !ia the e"itor an" &ail to commitLM the 'hanges, those 'hanges =ill e!aporate on'e the e"itor goes out o& s'ope. -ote that An"roi" 2./ has an applFLM metho", that =orks like commitLM, but runs &aster.
'1;
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
=sing Preferences
Con!ersely, sin'e the pre&eren'es obHe'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.
'1+
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
=sing Preferences
N(reference2creen Gmlns:android67http://schemas.android.com/apk/res/android7O N+heck4oG(reference android:keF67checkboG7 android:title67+heckboG (reference7 android:summarF67+heck it on8 check it off7 /O N?ingtone(reference android:keF67ringtone7 android:title67?ingtone (reference7 android:shoD=efault67true7 android:shoD2ilent67true7 android:summarF67(ick a tone8 anF tone7 /O N/(reference2creenO
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. 1n the 'ase o& ?ingtone(reference, you ha!e your option o& allo=ing users to 'hoose the system "e&ault ringtone, or to 'hoose Nsilen'eN as a ringtone.
'1(
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
=sing Preferences
public class $dit(references eGtends (referenceActivitF : Q"verride public void onCreateL4undle savedInstance2tateM : super.onCreateLsavedInstance2tateMJ add)references"rom%esourceL?.Gml.preferencesMJ ; ;
As you 'an see, there is not mu'h to see. All you nee" to "o is 'all an" spe'i&y the FML resour'e 'ontaining your pre&eren'es.
add(references9rom?esourceLM
?ou =ill also nee" to a"" this as an a'ti!ity to your Android#anifest.Gml &ile,
NPGml version671.-7 encoding67utf-,7PO Nmanifest package67com.commonsDare.android.simple7 Gmlns:android67http://schemas.android.com/apk/res/android7O Napplication android:icon67QdraDable/cD7 android:label67Qstring/app name7O NactivitF android:label67Qstring/app name7 android:name67.2imple(refs=emo7O Nintent-filterO Naction android:name67android.intent.action.#AI%7 /O NcategorF android:name67android.intent.categorF.)A3%+!$?7 /O N/intent-filterO N/activitFO NactivitF android:label67Qstring/app name7 android:name67.$dit(references7ON/activitFO N/applicationO Nsupports-screens android:anF=ensitF67true7 android:large2creens67true7 android:normal2creens67true7 android:small2creens67true7 /O N/manifestO
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 onCreateOptionsMenuL#enu menuM : menu.addL#enu.%"%$8 $=I& I=8 #enu.%"%$8 7$dit (refs7M .setIconL?.draDable.miscM .set$lpha'eticShortcutLIeIMJ ; returnLsuper.onCreateOptionsMenuLmenuMMJ
'1.
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
=sing Preferences
Q"verride public boolean onOptionsItemSelectedL#enuItem itemM : sDitch Litem.getItemIdLMM : case $=I& I=: start$cti!ityLneD IntentLthis8 $dit(references.classMMJ returnLtrueMJ ; ; ; returnLsuper.onOptionsItemSelectedLitemMMJ
+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 $1,
5he 'he'kbo; 'an be "ire'tly 'he'ke" or un'he'ke". 5o 'hange the ringtone pre&eren'e, Hust 'li'k on the entry in the pre&eren'e list to bring up a sele'tion "ialog,
'1'
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
=sing Preferences
-ote that there is no e;pli'it Nsa!eN or N'ommitN 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,
NPGml version671.-7 encoding67utf-,7PO N&able)aFout Gmlns:android67http://schemas.android.com/apk/res/android7 android:laFout Didth67fill parent7 android:laFout height67fill parent7 O N&able?oDO N&eGtVieD android:teGt67+heckboG:7 android:padding?ight67.dip7 /O N&eGtVieD android:id67QRid/checkboG7 /O N/&able?oDO N&able?oDO N&eGtVieD android:teGt67?ingtone:7 android:padding?ight67.dip7 /O N&eGtVieD android:id67QRid/ringtone7
'11
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
=sing Preferences
/O N/&able?oDO N/&able)aFoutO
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 2ACD button),
'13
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
=sing Preferences
preferences
1& you ha!e a lot o& pre&eren'es &or users to set, ha!ing them all in one big list may be'ome troublesome. An"roi"7s pre&eren'e $1 gi!es you a &e= =ays to impose a bit o& stru'ture on your bag o& pre&eren'es, in'lu"ing 'ategories an" s'reens. Categories are a""e" !ia a (reference+ategorF element in your pre&eren'e FML an" are use" to group together relate" pre&eren'es. ather than ha!e your pre&eren'es all as 'hil"ren o& the root (reference2creen, you 'an put a &e= (reference+ategorF elements in the (reference2creen, an" then put your pre&eren'es in their appropriate 'ategories. .isually, this a""s a "i!i"er =ith the 'ategory title bet=een groups o& pre&eren'es. 1& you ha!e lots an" lots o& pre&eren'es S more than is 'on!enient &or users to s'roll through S you 'an also put them on separate Ns'reensN by intro"u'ing the (reference2creen element. ?es, that (reference2creen element.
'16
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
=sing Preferences
Any 'hil"ren o& (reference2creen go on their o=n s'reen. 1& 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 proHe't, here is a pre&eren'e FML &ile that 'ontains both (reference+ategorF an" neste" (reference2creen elements,
N(reference2creen Gmlns:android67http://schemas.android.com/apk/res/android7O N(reference+ategorF android:title672imple (references7O N+heck4oG(reference android:keF67checkboG7 android:title67+heckboG (reference7 android:summarF67+heck it on8 check it off7 /O N?ingtone(reference android:keF67ringtone7 android:title67?ingtone (reference7 android:shoD=efault67true7 android:shoD2ilent67true7 android:summarF67(ick a tone8 anF tone7 /O N/(reference+ategorFO N(reference+ategorF android:title67=etail 2creens7O N(reference2creen android:keF67detail7 android:title67=etail 2creen7 android:summarF67Additional preferences held in another page7O N+heck4oG(reference android:keF67checkboG>7 android:title67Another +heckboG7 android:summarF67"n. "ff. It reallF doesnIt matter.7 /O N/(reference2creenO N/(reference+ategorFO N/(reference2creenO
5he result, =hen you use this pre&eren'e FML =ith your (referenceActivitF implementation, is a 'ategoriLe" list o& elements,
'18
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
=sing Preferences
An", i& you tap on the @etail %'reen entry, you are taken to the 'hil" pre&eren'e s'reen,
'1:
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
=sing Preferences
proAectHs preference
The 9in
>& 'ourse, not all pre&eren'es are 'he'kbo;es an" ringtones. *or others, like entry &iel"s an" lists, An"roi" uses pop-up "ialogs. $sers "o not enter their pre&eren'e "ire'tly in the pre&eren'e $1 a'ti!ity, but rather tap on a pre&eren'e, &ill in a !alue, an" 'li'k >D to 'ommit the 'hange. %tru'turally, in the pre&eren'e FML, &iel"s an" lists are not signi&i'antly "i&&erent &rom other pre&eren'e types, as seen in this pre&eren'e FML &rom the (refs/=ialogs sample proHe't,
N(reference2creen Gmlns:android67http://schemas.android.com/apk/res/android7O N(reference+ategorF android:title672imple (references7O N+heck4oG(reference android:keF67checkboG7 android:title67+heckboG (reference7 android:summarF67+heck it on8 check it off7 /O N?ingtone(reference
'3;
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
=sing Preferences
android:keF67ringtone7 android:title67?ingtone (reference7 android:shoD=efault67true7 android:shoD2ilent67true7 android:summarF67(ick a tone8 anF tone7 /O N/(reference+ategorFO N(reference+ategorF android:title67=etail 2creens7O N(reference2creen android:keF67detail7 android:title67=etail 2creen7 android:summarF67Additional preferences held in another page7O N+heck4oG(reference android:keF67checkboG>7 android:title67Another +heckboG7 android:summarF67"n. "ff. It reallF doesnIt matter.7 /O N/(reference2creenO N/(reference+ategorFO N(reference+ategorF android:title67"ther (references7O N$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 /O N)ist(reference android:keF67list7 android:title672election =ialog7 android:summarF67+lick to pop up a list to choose from7 android:entries67QarraF/cities7 android:entrFValues67QarraF/airport codes7 android:dialog&itle67+hoose a (ennsFlvania citF7 /O N/(reference+ategorFO N/(reference2creenO
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,
NPGml version671.-7 encoding67utf-,7PO NresourcesO Nstring-arraF name67cities7O
'3+
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
=sing Preferences
NitemO(hiladelphiaN/itemO NitemO(ittsburghN/itemO NitemOAllentoDn/4ethlehemN/itemO NitemO$rieN/itemO NitemO?eadingN/itemO NitemO2crantonN/itemO NitemO)ancasterN/itemO NitemOAltoonaN/itemO NitemO!arrisburgN/itemO N/string-arraFO Nstring-arraF name67airport codes7O NitemO(!)N/itemO NitemO(I&N/itemO NitemOA4$N/itemO NitemO$?IN/itemO NitemO?=EN/itemO NitemOAV(N/itemO NitemO)%2N/itemO NitemOA""N/itemO NitemO#=&N/itemO N/string-arraFO N/resourcesO
When you bring up the pre&eren'e $1, you start =ith another 'ategory =ith another pair o& pre&eren'e entries,
$igure +.62 The preference screen of the 0ialogs proAectHs preference ="
'3(
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
=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,
'3.
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
=sing Preferences
'3'
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
=sing Preferences
Preference!ctivity
>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 reBuire some re"esign o& your pre&eren'es, i& you ha!e a lot o& them an" ha!e been using neste" (reference2creen elements. 1n &a't, this is pretty mu'h reBuire", as the neste" (reference2creen approa'h looks lousy on +oney'omb "e!i'es.
The Honeycom= , y
1n 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. 1n +oney'omb an" beyon", 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.
'31
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
=sing Preferences
"reference 2eaders
.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 maHor '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?esourceLM, a +oney'omb-style =ill 'all load!eaders9rom?esourceLM, 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 sample proHe't, &rom the
(referenceActivitF
(refs/9ragments
Npreference-headers Gmlns:android67http://schemas.android.com/apk/res/android7O Nheader android:fragment67com.commonsDare.android.preffrags.2tock(reference9ragment7 android:title67"riginal7 android:summarF67&he original set from the other eGamples7O NeGtra android:name67resource7 android:value67preferences7 /O N/headerO Nheader android:fragment67com.commonsDare.android.preffrags.2tock(reference9ragment7 android:title67"ther 2tuff7 android:summarF67@ell8 De needed to shoD tDo sets here...7O NeGtra android:name67resource7 android:value67preferences>7 /O N/headerO N/preference-headersO
Ea'h NheaderO element in"i'ates the (reference9ragment sub'lass that =ill be "es'ribing the pre&eren'es that belong to the hea"er. 1n a""ition, the NheaderO "es'ribes the title an" summary &or the hea"er, along =ith an optional i'on (android:icon attribute). A NheaderO element may also ha!e one or more NeGtraO 'hil" elements, pro!i"ing a key-!alue pair o& e;tra "ata that a (reference9ragment 'an use &or 'on&iguration. 1n the e;ample sho=n abo!e, ea'h NheaderO element has one NeGtraO 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, Hust =ith a slightly "i&&erent stru'ture,
'33
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
=sing Preferences
package com.commonsDare.android.preffragsJ import android.os.4undleJ import android.preference.(referenceActivitFJ import java.util.)istJ public class $dit(references eGtends (referenceActivitF : Q"verride public void onBuild(eadersL)istN!eaderO targetM : load(eaders"rom%esourceL?.Gml.preference headers8 targetMJ ; ;
1nstea" o& "e&ining the hea"ers in on+reateLM, you o!erri"e an on4uild!eadersLM metho" an" 'all load!eaders9rom?esourceLM there.
=sing Preferences
2tock(reference9ragment
package com.commonsDare.android.preffragsJ import android.os.4undleJ import android.preference.(reference9ragmentJ public class 2tock(reference9ragment eGtends (reference9ragment : Q"verride public void onCreateL4undle savedInstance2tateM : super.onCreateLsavedInstance2tateMJ int res6get$cti!ityLM .get%esourcesLM .getIdentifierLget$rgumentsLM.getStringL7resource7M8 7Gml78 get$cti!ityLM.get)ackage&ameLMMJ add)references"rom%esourceLresMJ ; ;
5o get at the e;tras, a (reference9ragment 'an 'all getArgumentsLM, =hi'h returns a 4undle. 1n our 'ase, =e 'an get the resources e;tra !alue !ia getArgumentsLM.get2tringL7resource7M. 5he problem is, this is a 2tring, not a resour'e 1@. 1n or"er to 'all add(references9rom?esourceLM, =e nee" the resour'e 1@ o& the pre&eren'e that =e only kno= by name. 5he tri'k is to use getIdentifierLM. 5he getIdentifierLM metho" on the ?esources obHe't S itsel& obtaine" by 'alling get?esourcesLM on an ActivitF S =ill use re&le'tion to &in" the resour'e 1@ 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 1@ shoul" resi"e (typi'ally, your o=n pa'kage, obtaine" by 'alling get(ackage%ameLM on an ActivitF)
'38
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
=sing Preferences
%o, 2tock(reference9ragment uses getIdentifierLM to 'on!ert the resource e;tra into a resour'e 1@, =hi'h it then uses =ith add(references9rom?esourceLM. -ote that getIdentifierLM is not parti'ularly &ast, sin'e it uses re&le'tion. @o not use this in a tight loop, or in getVieDLM o& an Adapter, or any pla'e =here it may be 'alle" thousan"s o& times.
'3:
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
=sing Preferences
Nheader android:icon67QdraDable/something7 android:title679ancF 2tuff7 android:summarF67+lick here to transcend Four plane of eGistence7O Nintent android:action67com.commonsDare.android.#5 +32&"# A+&I"%7 /O N/headerO
5hen, so long as you ha!e an a'ti!ity =ith an Nintent-filterO spe'i&ying your "esire" a'tion (com.commonsDare.android.#5 +32&"# A+&I"%), that a'ti!ity =ill get 'ontrol =hen the user taps on the asso'iate" hea"er.
*irst,
the
'6;
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
=sing Preferences
add)references"rom%esourceL?.Gml.preferencesMJ add)references"rom%esourceL?.Gml.preferences>MJ ; ;
+ere, =e take a"!antage o& the &a't that add(references9rom?esourceLM '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,
Q"verride public boolean onOptionsItemSelectedL#enuItem itemM : sDitch Litem.getItemIdLMM : case $=I& I=: if L4uild.V$?2I"%.2=H I%&N4uild.V$?2I"% +"=$2.!"%$5+"#4M : start$cti!ityLneD IntentLthis8 $dit(references.classMMJ ; else : start$cti!ityLneD IntentLthis8 $dit(references!+.classMMJ ; ; ; returnLtrueMJ
returnLsuper.onOptionsItemSelectedLitemMMJ
+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.
'6+
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
CHAPTER /&
,anaging an
%KLite is a !ery popular embe""e" "atabase, as it 'ombines a 'lean %KL 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 proHe'ts (MoLilla, #+#, #ython) all ship pro"u'ts =ith %KLite. *or An"roi", %KLite is Nbake" intoN the An"roi" runtime, so e!ery An"roi" appli'ation 'an 'reate %KLite "atabases. %in'e %KLite uses a %KL inter&a'e, it is &airly straight&or=ar" to use &or people =ith e;perien'e in other %KLbase" "atabases. +o=e!er, its nati!e A#1 is not C@2C, an" C@2C 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#1 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& %KLite use in the 'onte;t o& =orking on An"roi". 1t by no means is a thorough 'o!erage o& %KLite as a =hole. 1& you =ant to learn more about %KLite an" ho= to use it in en!ironments other than An"roi", a &ine book is 5he @e&initi!e 8ui"e to %KLite 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,
'6.
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
,anaging an
?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,
%constant
ialog
'6'
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
,anaging an
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 N@eleteN option S a&ter 'on&irmation, that =ill "elete the 'onstant. An", o& 'ourse, all o& this is store" in a %KLite "atabase.
'61
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
,anaging an
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, Hust pass null), an" an integer representing the !ersion o& the "atabase s'hema you are using.
on+reateLM,
=hi'h passes you a 2Y)ite=atabase obHe't that you use to populate =ith tables an" initial "ata, as appropriate.
on3pgradeLM,
=hi'h passes you a 2Y)ite=atabase obHe'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 on3pgradeLM N'heatsN by "ropping the e;isting table an" e;e'uting on+reateLM,
on+reateLM,
package com.commonsDare.android.constantsJ import import import import import android.content.+ontentValuesJ android.content.+onteGtJ android.database.sUlite.2Y)ite=atabaseJ android.database.sUlite.2Y)ite"pen!elperJ android.hardDare.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(elperL+onteGt conteGtM : superLconteGt8 =A&A4A2$ %A#$8 null8 1MJ ; Q"verride public void onCreateL2Y)ite=atabase dbM : db.execS/LL7+?$A&$ &A4)$ constants L id I%&$E$? (?I#A?5 H$5 A3&"I%+?$#$%&8 title &$]&8 value ?$A)MJ7MJ
'63
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
,anaging an
+ontentValues cv6neD ContentValuesLMJ cv.putL&I&)$8 7EravitF8 =eath 2tar I7MJ cv.putLVA)3$8 2ensor#anager.E?AVI&5 =$A&! 2&A? IMJ db.insertL7constants78 &I&)$8 cvMJ cv.putL&I&)$8 7EravitF8 $arth7MJ cv.putLVA)3$8 2ensor#anager.E?AVI&5 $A?&!MJ db.insertL7constants78 &I&)$8 cvMJ cv.putL&I&)$8 7EravitF8 Jupiter7MJ cv.putLVA)3$8 2ensor#anager.E?AVI&5 J3(I&$?MJ db.insertL7constants78 &I&)$8 cvMJ cv.putL&I&)$8 7EravitF8 #ars7MJ cv.putLVA)3$8 2ensor#anager.E?AVI&5 #A?2MJ db.insertL7constants78 &I&)$8 cvMJ cv.putL&I&)$8 7EravitF8 #ercurF7MJ cv.putLVA)3$8 2ensor#anager.E?AVI&5 #$?+3?5MJ db.insertL7constants78 &I&)$8 cvMJ cv.putL&I&)$8 7EravitF8 #oon7MJ cv.putLVA)3$8 2ensor#anager.E?AVI&5 #""%MJ db.insertL7constants78 &I&)$8 cvMJ cv.putL&I&)$8 7EravitF8 %eptune7MJ cv.putLVA)3$8 2ensor#anager.E?AVI&5 %$(&3%$MJ db.insertL7constants78 &I&)$8 cvMJ cv.putL&I&)$8 7EravitF8 (luto7MJ cv.putLVA)3$8 2ensor#anager.E?AVI&5 ()3&"MJ db.insertL7constants78 &I&)$8 cvMJ cv.putL&I&)$8 7EravitF8 2aturn7MJ cv.putLVA)3$8 2ensor#anager.E?AVI&5 2A&3?%MJ db.insertL7constants78 &I&)$8 cvMJ cv.putL&I&)$8 7EravitF8 2un7MJ cv.putLVA)3$8 2ensor#anager.E?AVI&5 23%MJ db.insertL7constants78 &I&)$8 cvMJ cv.putL&I&)$8 7EravitF8 &he Island7MJ cv.putLVA)3$8 2ensor#anager.E?AVI&5 &!$ I2)A%=MJ db.insertL7constants78 &I&)$8 cvMJ cv.putL&I&)$8 7EravitF8 3ranus7MJ cv.putLVA)3$8 2ensor#anager.E?AVI&5 3?A%32MJ db.insertL7constants78 &I&)$8 cvMJ cv.putL&I&)$8 7EravitF8 Venus7MJ cv.putLVA)3$8 2ensor#anager.E?AVI&5 V$%32MJ db.insertL7constants78 &I&)$8 cvMJ ;
'66
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
,anaging an
Q"verride public void on*pgradeL2Y)ite=atabase db8 int oldVersion8 int neDVersionM : android.util.)og.wL7+onstants78 73pgrading database8 Dhich Dill destroF all old data7MJ db.execS/LL7=?"( &A4)$ I9 $]I2&2 constants7MJ onCreateLdbMJ ; ;
We =ill take a 'loser look at =hat on+reateLM is "oing S in terms o& eGec2Y)LM an" insertLM '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 obHe't to "o Bueries or "ata mo"i&i'ations, ask your 2Y)ite"pen!elper to get?eadable=atabaseLM or get@riteable=atabaseLM, "epen"ing upon =hether or not you =ill be 'hanging its 'ontents. *or e;ample, our +onstants4roDser a'ti!ity opens the "atabase in on+reateLM as part o& "oing a Buery,
db6neD Data'ase(elperLthisMJ constants+ursor6db .get%eada'leData'aseLM .raw/ueryL72$)$+& I=8 title8 value 7R 79?"# constants "?=$? 45 title78 nullMJ
When you are "one =ith the "atabase (e.g., your a'ti!ity is being 'lose"), simply 'all closeLM on your 2Y)ite"pen!elper to release your 'onne'tion. *or on3pgradeLM 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"penLM, to get 'ontrol =hen somebo"y opens this "atabase. $sually, this is not reBuire".
2. An"roi" /.0 intro"u'e" on=oDngradeLM, =hi'h =ill be 'alle" i& the 'o"e reBuests an ol"er s'hema than =hat is in the "atabase
'68
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
,anaging an
presently. 5his is the 'on!erse o& on3pgradeLM 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=oDngradeLM.
5his =ill 'reate a table, name" constants, =ith a primary key 'olumn name" id that is an auto-in'remente" integer (i.e., %KLite =ill assign the !alue &or you =hen you insert ro=s), plus t=o "ata 'olumns, title (te;t) an" value (a &loat, or NrealN in %KLite terms). %KLite =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. 1& you "o not 'hange your table s'hemas, you might ne!er "rop your tables or in"e;es, but i& you "o, Hust use eGec2Y)LM to in!oke =?"( I%=$] an" =?"( &A4)$ statements as nee"e".
,akinH 0ata
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 maHor approa'hes &or "oing this.
'6:
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
,anaging an
?ou 'an al=ays use eGec2Y)LM, Hust like you "i" &or 'reating the tables. 5he eGec2Y)LM metho" =orks &or any %KL that "oes not return results, so it 'an han"le I%2$?&, 3(=A&$, =$)$&$, et'. Hust &ine. ?our alternati!e is to use the insertLM, updateLM, an" deleteLM metho"s on the 2Y)ite=atabase obHe't, =hi'h eliminate mu'h o& the %KL synta; reBuire" to "o basi' operations. *or e;ample, here =e insertLM a ne= ro= into our constants table,
private void process$ddL=ialog@rapper DrapperM : +ontentValues values6neD ContentValuesL>MJ values.putL=atabase!elper.&I&)$8 Drapper.getTitleLMMJ values.putL=atabase!elper.VA)3$8 Drapper.getValueLMMJ db.get#rita'leData'aseLM.insertL7constants78 =atabase!elper.&I&)$8 valuesMJ constants+ursor.re-ueryLMJ
5hese metho"s make use o& +ontentValues obHe'ts, =hi'h implement a #apesBue inter&a'e, albeit one that has a""itional metho"s &or =orking =ith %KLite types. *or e;ample, in a""ition to getLM to retrie!e a !alue by its key, you ha!e getAsIntegerLM, getAs2tringLM, an" so &orth. 5he insertLM metho" takes the name o& the table, the name o& one 'olumn as the Nnull 'olumn ha'kN, an" a +ontentValues =ith the initial !alues you =ant put into this ro=. 5he Nnull 'olumn ha'kN is &or the 'ase =here the +ontentValues instan'e is empty S the 'olumn name" as the Nnull 'olumn ha'kN =ill be e;pli'itly assigne" the !alue %3)) in the %KL I%2$?& statement generate" by insertLM. 5his is reBuire" "ue to a Buirk in %KLite7s support &or the %KL I%2$?& statement. 5he updateLM 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" Buestion marks ( P). %in'e updateLM only repla'es 'olumns =ith &i;e" !alues, !ersus ones 'ompute" base" on other in&ormation, you may nee" to use eGec2Y)LM to a''omplish some en"s. 5he
'8;
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
,anaging an
@!$?$
'lause an" parameter list =orks akin to the positional %KL parameters you may be use" to &rom other %KL A#1s. 5he deleteLM metho" =orks akin to updateLM, taking the name o& the table, the optional @!$?$ 'lause, an" the 'orrespon"ing parameters to &ill into the @!$?$ 'lause. *or e;ample, here =e deleteLM a ro= &rom our constants table, gi!en its ]1@,
private void processDeleteLlong roDIdM : 2tringAB args6:2tring.!alueOfLroDIdM;J db.get#rita'leData'aseLM.deleteL7constants78 7 I=6P78 argsMJ constants+ursor.re-ueryLMJ
2. ?ou 'an use UuerFLM to buil" up a Buery &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#1, is raDYuerFLM. %imply 'all it =ith your %KL 2$)$+& statement. 5he 2$)$+& statement 'an in'lu"e positional parametersT the array o& these &orms your se'on" parameter to raDYuerFLM. %o, =e =in" up =ith,
db6neD Data'ase(elperLthisMJ constants+ursor6db .get%eada'leData'aseLM .raw/ueryL72$)$+& I=8 title8 value 7R 79?"# constants "?=$? 45 title78 nullMJ
'8+
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
,anaging an
5he return !alue is a +ursor, =hi'h 'ontains metho"s &or iterating o!er results (see belo=). 1& your Bueries are pretty mu'h Nbake" intoN 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 Buery 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 UuerFLM 'omes in.
Re!ul r Hueries
5he UuerFLM metho" takes the "is'rete pie'es o& a %ELEC5 statement an" buil"s the Buery &rom them. 5he pie'es, in or"er that they appear as parameters to UuerFLM, are,
5he name o& the table to Buery 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 E?"3( 45 'lause, i& any 5he !AVI%E '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 +ursor result6db.-ueryL7Didgets78 columns8 7name6P78 parms8 null8 null8 nullMJ
'8(
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
,anaging an
;sin! Cursors
-o matter ho= you e;e'ute the Buery, you get a +ursor ba'k. 5his is the An"roi"Q%KLite 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+ountLM
isAfter)astLM
*in" out the names o& the 'olumns !ia get+olumn%amesLM, 'on!ert those into 'olumn numbers !ia get+olumnIndeGLM, an" get !alues &or the 'urrent ro= &or a gi!en 'olumn !ia metho"s like get2tringLM, getIntLM, et'. e-e;e'ute the Buery that 'reate" the 'ursor !ia reUuerFLM elease the 'ursor7s resour'es !ia closeLM
?ou 'an also =rap a +ursor in a 2imple+ursorAdapter or other implementation, then han" the resulting a"apter to a )istVieD or other sele'tion =i"get. -ote, though, that i& you are going to use +ursorAdapter or its sub'lasses (like 2imple+ursorAdapter), your result set o& your Buery must 'ontain an integer 'olumn name" I= that is uniBue &or the result set. 5his Ni"N !alue is then supplie" to metho"s like on)istItem+lickLM, to i"enti&y =hat item the user 'li'ke" upon in the AdapterVieD.
'8.
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
,anaging an
*or e;ample, a&ter retrie!ing the sorte" list o& 'onstants, =e pop those into the )istVieD &or the +onstants4roDser a'ti!ity in Hust a &e= lines o& 'o"e,
)istAdapter adapter6neD SimpleCursor$dapterLthis8 ?.laFout.roD8 constants+ursor8 neD 2tringAB :=atabase!elper.&I&)$8 =atabase!elper.VA)3$;8 neD intAB :?.id.title8 ?.id.value;MJ setList$dapterLadapterMJ
public void 'indViewLVieD roD8 +onteGt conteGt8 +ursor cursorM : VieD@rapper Drapper6LVieD@rapperMroD.getTagLMJ ; // actual logic to populate roD from +ursor goes here
'8'
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
,anaging an
'81
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
,anaging an
-ote 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, Hust be'ause you are not seeing any $1 slo="o=ns "ue to "atabase 1Q> 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.commonsDare.android) an" Four-db-name is the name o& your "atabase, as supplie" to create=atabaseLM. 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. 1& you pre&er something a little bit &rien"lier, you 'an al=ays 'opy the %KLite "atabase o&& the "e!i'e onto your "e!elopment ma'hine, then use a %KLite-a=are 'lient program to putter aroun". -ote, 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. 5o get the "atabase o&& the "e!i'e, you 'an use the adb pull 'omman" (or the eBui!alent in your 1@E, or the *ile Manager in @@M%), =hi'h takes the
'83
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
,anaging an
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 %KLite 'lients is the %KLite Manager e;tension &or *ire&o;, as it =orks a'ross all plat&orms.
?ou 'an &in" other 'lient tools on the %KLite Web site.
'86
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
CHAPTER //
Ca!a has as many, i& not more, thir"-party libraries than any other mo"ern programming language. +ere, Nthir"-party librariesN 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. 1n 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 proHe'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.
!nts an
7ars
?ou ha!e t=o 'hoi'es &or integrating thir"-party 'o"e into your proHe't, use sour'e 'o"e, or use pre-pa'kage" CA s. 1& you 'hoose to use their sour'e 'o"e, all you nee" to "o is 'opy it into your o=n sour'e tree (un"er src/ in your proHe't), so it 'an sit alongsi"e your e;isting 'o"e, then let the 'ompiler per&orm its magi'.
'8:
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
1& 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" proHe't. 5hen, i& you are using an 1@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 reBuire" &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" onI >r, "oes the 'o"e assume the e;isten'e o& Ca!a A#1s that ship =ith C2%E but not =ith An"roi", su'h as %=ingI $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 siLe, or, to some e;tent, e!en in- AM siLe. 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 siLe 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'esI 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'eI >r is it a pure A#1 that you 'an =rap your o=n inter&a'e aroun"I >perating %ystem, @oes the Ca!a 'o"e assume the e;isten'e o& 'ertain 'onsole programsI @oes the Ca!a 'o"e assume it 'an use a Win"o=s @LLI
':;
Language .ersion, Was the CA 'ompile" =ith an ol"er !ersion o& Ca!a (1.<.2 or ol"er)I Was the CA 'ompile" =ith a "i&&erent 'ompiler than the o&&i'ial one &rom %un (e.g., 8CC)I @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 =ellI @oes the Ca!a 'o"e "epen" upon thir"-party libraries (e.g., the org.Hson C%>- library) that are built into An"roi", but the thir" party e;pe'ts a "i&&erent !ersion o& that libraryI
>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 10M o& the thir"-party library, maybe it7s =orth=hile to re'ompile the subset o& the proHe'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.
':+
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
2ean%hell CA that a''ompanies the sour'e 'o"e &or this book, up on the CommonsWare site, in the Java/And2hell proHe't. *rom there, using 2ean%hell on An"roi" is no "i&&erent than using 2ean%hell in any other Ca!a en!ironment, 1. Create an instan'e o& the 2ean%hell Interpreter 'lass
2. %et any 6globals9 &or the s'ript[s use !ia InterpreterSsetLM /. Call InterpreterSevalLM 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 2ean%hell 1@E,
NPGml version671.-7 encoding67utf-,7PO N)inear)aFout Gmlns:android67http://schemas.android.com/apk/res/android7 android:orientation67vertical7 android:laFout Didth67fill parent7 android:laFout height67fill parent7 O N4utton android:id67QRid/eval7 android:laFout Didth67fill parent7 android:laFout height67Drap content7 android:teGt67EoX7 android:on+lick67go7 /O N$dit&eGt android:id67QRid/script7 android:laFout Didth67fill parent7 android:laFout height67fill parent7 android:single)ine67false7 android:gravitF67top7 /O N/)inear)aFoutO
':(
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
public class #ainActivitF eGtends ActivitF : private Interpreter i6neD InterpreterLMJ Q"verride public void onCreateL4undle icicleM : super.onCreateLicicleMJ setContentViewL?.laFout.mainMJ ; public void goLVieD vM : $dit&eGt script6L$dit&eGtMfindViewByIdL?.id.scriptMJ 2tring src6script.getTextLM.toStringLMJ trF : i.setL7conteGt78 #ainActivitF.thisMJ i.e!alLsrcMJ ; catch Lbsh.$val$rror eM : Alert=ialog.4uilder builder6 neD Alert=ialog.BuilderL#ainActivitF.thisMJ builder .setTitleL7$GceptionX7M .setMessageLe.toStringLMM .set)ositi!eButtonL7"H78 nullM .showLMJ ; ; ;
Compile an" run it (in'lu"ing in'orporating the 2ean%hell CA as mentione" abo!e), an" install it on the emulator. *ire it up, an" you get a tri!ial 1@E, =ith a large te;t area &or your s'ript an" a big N8o:N button to e;e'ute it,
':.
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
$igure +''2 The !n Shell BeanShell "0< import android.Didget.&oastJ &oast.makeTextLconteGt8 7!ello8 DorldX78 &oast.)$%E&! )"%EM.showLMJ
-ote 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 setLM 'all an" the s'ript 'o"e use the same name. 5hen, 'li'k the 8o: button, an" you get,
':'
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
An" no=, some 'a!eats... *irst, not all s'ripting languages =ill =ork. *or e;ample, those that implement their o=n &orm o& Hust-in-time (C15) '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#1s 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#1 that "oes not e;ist in @al!ik S &or e;ample, there 'oul" be stu&& hi""en insi"e 2ean%hell or the a""-on CA s that "oes not =ork on to"ay[s An"roi". %e'on", s'ripting languages =ithout C15 =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 2ean%hell, simply be'ause you &eel it is easier to program in, may 'ause your users to be unhappy.
':1
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
5hir", s'ripting languages that e;pose the =hole Ca!a A#1, like 2ean%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 2ean%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 2ean%hell CA use" in this e;ample is 200D2. 5hat is not ri"i'ulous, 'onsi"ering =hat it "oes, but it =ill make appli'ations that use 2ean%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 MoLilla Ca!as'ript
':3
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
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' $1s. *or on-"e!i'e "e!elopment, %L<A is a &ine 'hoi'e.
':6
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
CHAPTER /0
5he e;pe'tation is that most, i& not all, An"roi" "e!i'es =ill ha!e built-in 1nternet 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 1nternet &rom their An"roi" phone. -ot surprisingly, the An"roi" plat&orm gi!es "e!elopers a =i"e range o& =ays to make use o& this 1nternet 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. 1& you =ant, you 'an "rop all the =ay "o=n to using ra= so'kets. >r, in bet=een, you 'an le!erage A#1s 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" 1nternet-a''ess A#1s, 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.
'::
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
>riginally, 8oogle re'ommen"e" that you use +ttpClient, as it o&&ere" a number o& 'apabilities (e.g., automati' 'ookie management, 'onne'tion pooling) that !ttp3?)+onnection "i" not. +o=e!er, in re'ent releases, the 'ore An"roi" team has been &o'use" on impro!ing +55# per&orman'e, as many An"roi" appli'ations rely upon +55# operations. +ttpClient, =hile e;'ellent, is a highly 'omple; library, =ith "oLens upon "oLens o& 'lasses an" inter&a'es. !ttp3?)+onnection, by 'omparison, has a simpler A#1, making it easier &or engineers to make mo"i&i'ations Nun"er the 'o!ersN =ithout altering publi' metho" signatures. As a result, no=a"ays, 8oogle is re'ommen"ing that "e!elopers use !ttp3?)+onnection &or 8ingerbrea" an" higher (A#1 Le!el 3 an" higher). 5his book =as originally =ritten be&ore 8oogle ma"e any re'ommen"ations at all. 5he e;amples here use +ttpClient mostly. E!entually, these e;amples =ill be re=ritten to &o'us more on !ttp3?)+onnection. part o& 'lassi' Ca!a, is =ell-"o'umente" in books, Web sites, an" the like. %ome An"roi"-spe'i&i' notes 'an be &oun" later in this 'hapter.
!ttp3?)+onnection, as
4<ST an
4elaxation
An"roi" "oes not ha!e built-in %>A# or FML- #C 'lient A#1s. +o=e!er, it "oes ha!e the Apa'he +ttpClient library bake" in. ?ou 'an either layer a %>A#QFML- #C layer atop this library, or use it NstraightN &or a''essing E%5-style Web ser!i'es. *or the purposes o& this book, N E%5-style Web ser!i'esN is "e&ine" as Nsimple +55# reBuests &or or"inary $ Ls o!er the &ull range o& +55# !erbs, =ith &ormatte" payloa"s (FML, C%>-, et'.) as responsesN. More e;pansi!e tutorials, *AKs, an" +>W5>s 'an be &oun" at the +ttpClient Web site. +ere, =e7ll 'o!er the basi's, =hile 'he'king the =eather.
1;;
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
1n the on?esumeLM 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 -ational Weather %er!i'e "ata !ia our update9orecastLM metho",
private void update"orecastL)ocation locM : 2tring url62tring.formatLformat8 loc.getLatitudeLM8 loc.getLongitudeLMMJ !ttpEet get#ethod6neD (ttp etLurlMJ trF : ?esponse!andlerN2tringO response!andler6neD Basic%esponse(andlerLMJ 2tring response4odF6client.executeLget#ethod8 response!andlerMJ 'uild"orecastsLresponse4odFMJ 2tring page6generate)ageLMJ broDser.loadData#ithBase*%LLnull8 page8 7teGt/html78 73&9-,78 nullMJ ; catch L&hroDable tM : android.util.)og.eL7@eather=emo78 7$Gception fetching data78 tMJ &oast .makeTextLthis8 7?eUuest failed: 7Rt.toStringLM8 &oast.)$%E&! )"%EM .showLMJ ;
5he update9orecastLM 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)atitudeLM an" get)ongitudeLM metho"s that return the latitu"e an" longitu"e o& the "e!i'e7s position, respe'ti!ely. We hol" the $ L to the -ational 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 obHe't 'reate" in on+reateLM, =e populate an !ttpEet =ith that 'ustomiLe" $ 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. 1& the !ttp+lient blo=s up =ith an e;'eption, =e pro!i"e that error as a &oast. -ote that =e also shut "o=n the !ttp+lient obHe't in on=estroFLM.
1;(
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
P rsin! Responses
5he response you get =ill be &ormatte" using some system S +5ML, FML, C%>-, =hate!er. 1t is up to you, o& 'ourse, to pi'k out =hat in&ormation you nee" an" "o something use&ul =ith it. 1n 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.DCc.dom), a %AF parser (org.Gml.saG), an" the FML pull parser "is'usse" in the 'hapter on resour'es A C%>- 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" %%QAtom 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 build9orecastsLM metho",
void 'uild"orecastsL2tring raDM throDs $Gception : =ocument4uilder builder6=ocument4uilder9actorF .newInstanceLM .newDocumentBuilderLMJ =ocument doc6builder.parseLneD InputSourceLneD String%eaderLraDMMMJ %ode)ist times6doc.get+lementsByTag&ameL7start-valid-time7MJ for Lint i6-JiNtimes.getLengthLMJiRRM : $lement time6L$lementMtimes.itemLiMJ 9orecast forecast6neD "orecastLMJ forecasts.addLforecastMJ forecast.setTimeLtime.get"irstChildLM.get&odeValueLMMJ
1;.
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
forecast.setTempLneD IntegerLtemp.get"irstChildLM.get&odeValueLMMMJ ; %ode)ist icons6doc.get+lementsByTag&ameL7icon-link7MJ for Lint i6-JiNicons.getLengthLMJiRRM : $lement icon6L$lementMicons.itemLiMJ 9orecast forecast6forecasts.getLiMJ ; ; forecast.setIconLicon.get"irstChildLM.get&odeValueLMMJ
5he -ational Weather %er!i'e FML &ormat is...'uriously stru'ture", relying hea!ily on seBuential position in lists !ersus the more obHe'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 uniBue =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 obHe'ts. 1n turn, the generate(ageLM metho" 'reates a ru"imentary +5ML table =ith the &ore'asts,
2tring generate)ageLM : 2tring4uilder buf?esult6neD StringBuilderL7NhtmlONbodFONtableO7MJ buf?esult.appendL7NtrONth Didth6T7.-\T7O&imeN/thO7R 7NthO&emperatureN/thONthO9orecastN/thON/trO7MJ for L9orecast forecast : forecastsM : buf?esult.appendL7NtrONtd align6T7centerT7O7MJ buf?esult.appendLforecast.getTimeLMMJ buf?esult.appendL7N/tdONtd align6T7centerT7O7MJ buf?esult.appendLforecast.getTempLMMJ buf?esult.appendL7N/tdONtdONimg src6T77MJ buf?esult.appendLforecast.getIconLMMJ buf?esult.appendL7T7ON/tdON/trO7MJ ; buf?esult.appendL7N/tableON/bodFON/htmlO7MJ
1;'
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
returnLbuf?esult.toStringLMMJ
Stu11 To Consider
1& 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 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" onesI >r "o you =ant to ask the user i& they really =ant to use some strange 'erti&i'atesI %imilarly, !ttp+lient, by "e&ault, is "esigne" &or single-threa"e" use. 1& 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.
1;1
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
*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#1 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' neDInstanceLM metho" to get an instan'e o&
Android!ttp+lient
$tility metho"s &or =orking =ith material 'ompresse" !ia 8R1#, &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 subseBuent reBuests =here they are nee"e". Android!ttp+lient "oes not. 5here are =ays to &i; that, by using an !ttp+onteGt obHe't, as is "es'ribe" in the Android!ttp+lient "o'umentation. Also, Android!ttp+lient pre!ents you &rom using it on the main appli'ation threa" S reBuests '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#1 le!el 8 or higher.
1;3
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
Compo%
Where!er possible, aim to use built-in An"roi" 'omponents that 'an han"le your 1nternet a''ess &or you. %u'h 'omponents =ill ha!e been &airly rigorously teste" an" are more likely to han"le e"ge 'ases =ell, su'h as "ealing =ith users on Wi*i =ho mo!e out o& range o& the a''ess point an" &ail o!er to mobile "ata 'onne'tions (e.g., /8). *or e;ample, the @ebVieD =i"get (intro"u'e" in a pre!ious 'hapter) an" the #apVieD =i"get ('o!ere" in a later 'hapter) both han"le 1nternet a''ess &or you. While you still nee" the 1-5E -E5 permission, you "o not ha!e to per&orm +55# reBuests or the like yoursel&. 5his se'tion outlines some other =ays you 'an take a"!antage o& built-in 1nternet 'apability.
@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" N&ails o!erN to mobile "ata Ensuring the "e!i'e stays a=ake =hile the "o=nloa" pro'ee"s
itsel& is less 'ompli'ate" than the alternati!e o& =riting all o& it yoursel&. +o=e!er, it "oes present a &e= 'hallenges. 1n this se'tion, =e =ill e;amine the Internet/=oDnload sample proHe't that uses =oDnload#anager.
=oDnload#anager
1;6
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
&he "ermissions
5o use =oDnload#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&"?AE$ 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 =oDnload#anager implementation S it shoul" be 'omplaining about I%&$?%$& an"Qor @?I&$ $]&$?%A) 2&"?AE$. ?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/=oDnload appli'ation,
NPGml version671.-7 encoding67utf-,7PO Nmanifest android:version+ode6717 android:version%ame671.-7 package67com.commonsDare.android.doDnload7 Gmlns:android67http://schemas.android.com/apk/res/android7O NX-- Nuses-permission android:name67android.permission.A++$22 A)) ="@%)"A=27 /O --O Nuses-permission android:name67android.permission.I%&$?%$&7 /O Nuses-permission android:name67android.permission.@?I&$ $]&$?%A) 2&"?AE$7 /O Napplication android:icon67QdraDable/cD7 android:label67Qstring/app name7O NactivitF android:label67Qstring/app name7 android:name67=oDnload=emo7O Nintent-filterO Naction android:name67android.intent.action.#AI%7 /O NcategorF android:name67android.intent.categorF.)A3%+!$?7 /O N/intent-filterO N/activitFO N/applicationO Nsupports-screens android:anF=ensitF67true7 android:large2creens67true7 android:normal2creens67true7 android:small2creens67true7 /O N/manifestO
&he (a!out
>ur sample appli'ation has a simple layout, 'onsisting o& three buttons,
1;8
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
>ne to ki'k o&& a "o=nloa" >ne to Buery the status o& a "o=nloa" >ne to "isplay a system-supplie" a'ti!ity 'ontaining the roster o& "o=nloa"e" &iles
NPGml version671.-7 encoding67utf-,7PO N)inear)aFout Gmlns:android67http://schemas.android.com/apk/res/android7 android:orientation67vertical7 android:laFout Didth67fill parent7 android:laFout height67fill parent7 O N4utton android:id67QRid/start7 android:teGt672tart =oDnload7 android:laFout Didth67fill parent7 android:laFout height67-dip7 android:laFout Deight6717 android:on+lick67start=oDnload7 /O N4utton android:id67QRid/UuerF7 android:teGt67YuerF 2tatus7 android:laFout Didth67fill parent7 android:laFout height67-dip7 android:laFout Deight6717 android:on+lick67UuerF2tatus7 android:enabled67false7 /O N4utton android:teGt67VieD )og7 android:laFout Didth67fill parent7 android:laFout height67-dip7 android:laFout Deight6717 android:on+lick67vieD)og7 /O N/)inear)aFoutO
1;:
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
%o, &or e;ample, here is a line &rom on+reateLM o& the =oDnload=emo a'ti!ity =here =e get the =oDnload#anager,
mgr6L=oDnload#anagerMgetSystemSer!iceL="@%)"A= 2$?VI+$MJ
Most o& these managers ha!e no closeLM or releaseLM or goADaF(leaseLM sort o& metho"s S you 'an Hust use them an" let garbage 'olle'tion take 'are o& 'leaning them up. 8i!en the manager, =e 'an no= 'all an enUueueLM metho" to reBuest 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 enUueueLM metho" takes a =oDnload#anager.?eUuest obHe't as a parameter. 5he ?eUuest obHe'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=oDnloadLM metho" in =oDnload=emo, sho=n belo=,
public void startDownloadLVieD vM : 3ri uri63ri.parseL7http://commonsDare.com/misc/test.mp<7MJ $nvironment .get+xternalStorage)u'licDirectory L$nvironment.=I?$+&"?5 ="@%)"A=2M .mkdirsLMJ last=oDnload6 mgr.en-ueueLneD =oDnload#anager.%e-uestLuriM .set$llowed&etworkTypesL=oDnload#anager.?eUuest.%$&@"?H @I9I W =oDnload#anager.?eUuest.%$&@"?H #"4I)$M .set$llowedO!er%oamingLfalseM .setTitleL7=emo7M .setDescriptionL72omething useful. %o8 reallF.7M .setDestinationIn+xternal)u'licDir L$nvironment.=I?$+&"?5 ="@%)"A =28 7test.mp<7MMJ v.set+na'ledLfalseMJ findViewByIdL?.id.UuerFM.set+na'ledLtrueMJ ;
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=irectorFLM on $nvironment, =hi'h gi!es us a
1+;
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
"ire'tory suitable &or storing a 'ertain 'lass o& 'ontent. 1n this 'ase, =e are going to store the "o=nloa" in the $nvironment.=I?$+&"?5 ="@%)"A=2, though =e 'oul" Hust as easily ha!e 'hosen $nvironment.=I?$+&"?5 #"VI$2, sin'e =e are "o=nloa"ing a !i"eo 'lip. -ote that the 9ile obHe't returne" by get$Gternal2torage(ublic=irectorFLM may point to a not-yet-'reate" "ire'tory, =hi'h is =hy =e 'all mkdirsLM on it, to ensure the "ire'tory e;ists. We then 'reate the =oDnload#anager.?eUuest obHe'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" (setAlloDed%etDork&FpesLM), but =e "o not =ant the "o=nloa" to in'ur roaming 'harges (setAlloDed"ver?oamingLM) 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=irLM)
We also pro!i"e a name ( set&itleLM) an" "es'ription (set=escriptionLM), =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 enBueue() metho" returns an 1@ o& this "o=nloa", =hi'h =e hol" onto &or use in Buerying the "o=nloa" status.
1++
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
public void -ueryStatusLVieD vM : +ursor c6mgr.-ueryLneD =oDnload#anager./ueryLM.set"ilterByIdLlast=oDnloadMMJ if Lc66nullM : &oast.makeTextLthis8 7=oDnload not foundX78 &oast.)$%E&! )"%EM.showLMJ ; else : c.mo!eTo"irstLMJ )og.dLgetClassLM.get&ameLM8 7+")3#% I=: 7R c.getLongLc.getColumnIndexL=oDnload#anager.+")3#% I=MMMJ )og.dLgetClassLM.get&ameLM8 7+")3#% 45&$2 ="@%)"A=$= 2" 9A?: 7R c.getLongLc.getColumnIndexL=oDnload#anager.+")3#% 45&$2 ="@%)"A=$= 2" 9A?MMMJ )og.dLgetClassLM.get&ameLM8 7+")3#% )A2& #"=I9I$= &I#$2&A#(: 7R c.getLongLc.getColumnIndexL=oDnload#anager.+")3#% )A2& #"=I9I$= &I#$2& A#(MMMJ )og.dLgetClassLM.get&ameLM8 7+")3#% )"+A) 3?I: 7R c.getStringLc.getColumnIndexL=oDnload#anager.+")3#% )"+A) 3?IMMMJ )og.dLgetClassLM.get&ameLM8 7+")3#% 2&A&32: 7R c.getIntLc.getColumnIndexL=oDnload#anager.+")3#% 2&A&32MMMJ )og.dLgetClassLM.get&ameLM8 7+")3#% ?$A2"%: 7R c.getIntLc.getColumnIndexL=oDnload#anager.+")3#% ?$A2"%MMMJ &oast.makeTextLthis8 statusMessageLcM8 &oast.)$%E&! )"%EM.showLMJ ; ;
5he UuerFLM metho" returns a +ursor, 'ontaining a series o& 'olumns representing the "etails about our "o=nloa". 5here are a series o& 'onstants on the =oDnload#anager 'lass outlining =hat is possible. 1n our 'ase, =e retrie!e (an" "ump to LogCat),
5he 1@ 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) What the reason is &or that status (+")3#% ?$A2"%) is on the "o=nloa"
1+(
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
-ote that +")3#% )"+A) 3?I may be una!ailable, i& the user has "elete" the "o=nloa"e" &ile bet=een =hen the "o=nloa" 'omplete" an" the time you try to a''ess the 'olumn. 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%E). %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),
1+.
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
o*nloa
%li"ing "o=n the noti&i'ation "ra=er sho=s the user the progress in the &orm o& a (rogress4ar =i"get,
1+'
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
o*nloa
using
5apping on the entry in the noti&i'ation "ra=er returns 'ontrol to our original a'ti!ity, =here they see a &oast,
1+1
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
1& they tap the mi""le button "uring the "o=nloa", a &oast =ill appear in"i'ating that the "o=nloa" is in progress,
1+3
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
logcat,
A""itional "etails are also "umpe" to LogCat, !isible !ia @@M% or adb
1>-1- -,:<.:-1.>,*: =$43E/com.commonsDare.android.doDnload.=oDnload=emoLC/>M: +")3#% I=: 1> 1>-1- -,:<.:-1.>,*: =$43E/com.commonsDare.android.doDnload.=oDnload=emoLC/>M: +")3#% 45&$2 ="@%)"A=$= 2" 9A?: 01.<-1>-1- -,:<.:-1.>,*: =$43E/com.commonsDare.android.doDnload.=oDnload=emoLC/>M: +")3#% )A2& #"=I9I$= &I#$2&A#(: 1>*1*,,0*0>C> 1>-1- -,:<.:-1.>,*: =$43E/com.commonsDare.android.doDnload.=oDnload=emoLC/>M: +")3#% )"+A) 3?I: file:///mnt/sdcard/=oDnload/test.mp< 1>-1- -,:<.:-1.>**: =$43E/com.commonsDare.android.doDnload.=oDnload=emoLC/>M: +")3#% 2&A&32: > 1>-1- -,:<.:-1.>**: =$43E/com.commonsDare.android.doDnload.=oDnload=emoLC/>M: +")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,
1+6
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
1>-1- -,:<*:>/.C0-: =$43E/com.commonsDare.android.doDnload.=oDnload=emoLC/>M: +")3#% I=: 1> 1>-1- -,:<*:>/.C0-: =$43E/com.commonsDare.android.doDnload.=oDnload=emoLC/>M: +")3#% 45&$2 ="@%)"A=$= 2" 9A?: 0>1*>>* 1>-1- -,:<*:>/.C/-: =$43E/com.commonsDare.android.doDnload.=oDnload=emoLC/>M: +")3#% )A2& #"=I9I$= &I#$2&A#(: 1>*1*,,/1C<-* 1>-1- -,:<*:>/.C/-: =$43E/com.commonsDare.android.doDnload.=oDnload=emoLC/>M: +")3#% )"+A) 3?I: file:///mnt/sdcard/=oDnload/test.mp< 1>-1- -,:<*:>/.C/-: =$43E/com.commonsDare.android.doDnload.=oDnload=emoLC/>M: +")3#% 2&A&32: , 1>-1- -,:<*:>/.C/-: =$43E/com.commonsDare.android.doDnload.=oDnload=emoLC/>M: +")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,
o*nloa e
by the
An", o& 'ourse, the &ile is "o=nloa"e". 1n An"roi" 2./, in the emulator, our 'hosen lo'ation maps to /mnt/sdcard/=oDnloads/test.mp<.
1+8
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
(imitations
=oDnload#anager =orks =ith +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, =oDnload#anager =ill ha!e more options here.
1& 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 M1ME 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=oDnloads3iLM on your reBuest, passing in false, to suppress it &rom this list.
1+:
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
%%L han"ling =as impro!e". An"roi" =ill support 5L% an" %-1 &or ser!ers that o&&er it, transparently &alling ba'k to 'lassi' %%L &or those that "o not. 5his allo=s An"roi" to =ork =ith a =i"er range o& hosting pro!i"ers, as %-1 is use" by many o& them to allo= one Web host to ser!e multiple "istin't %%L sites. An"roi" transparently enables 8Rip en'o"ing &or reBuests ma"e o!er !ttp3?)+onnection, thereby re"u'ing ban"=i"th 'onsumption, at least &or ser!ers 'on&igure" to support it. +o=e!er,
5his breaks get+ontent)engthLM, inso&ar as it =ill return the number o& 'ompresse" bytes, =hi'h is typi'ally not a use&ul !alue. ?ou =ill simply ha!e to rea" in all "ata &rom the Input2tream (&rom getInput2treamLM) until it returns -1 to in"i'ate you ha!e run out o& "ata. 1& there are parti'ular reBuests &or =hi'h 8Rip en'o"ing "oes not make sense (e.g., alrea"y-'ompresse" M#< &iles, =here the ser!er =ill still 8Rip-'ompress it i& you reBuest it), you may =ish to "isable it by 'alling set?eUuest(ropertFL7Accept-$ncoding78 7identitF7M on your !ttp3?)+onnection be&ore e;e'uting the reBuest.
1(;
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
PART V Services
CHAPTER /5
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 NplayerN a'ti!ity gets garbage'olle'te", polling the 1nternet &or %%QAtom &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#1 'all) or =hen some a'ti!ity tries 'onne'ting to the ser!i'e !ia inter-pro'ess 'ommuni'ation (1#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 Bui'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 ServicesG
%er!i'es are a N%=iss Army kni&eN &or a =i"e range o& &un'tions that "o not reBuire "ire't a''ess to an a'ti!ity7s user inter&a'e, su'h as,
1(.
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#1 to remote A#1s, 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 Hobs 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 subHe't =ith =hi'h any Buali&ie" An"roi" "e!eloper shoul" be &amiliar.
Setting =p a Service
Creating a ser!i'e implementation shares many 'hara'teristi's =ith buil"ing an a'ti!ity. ?ou inherit &rom an An"roi"-supplie" base 'lass, o!erri"e some li&e'y'le metho"s, an" hook the ser!i'e into the system !ia the mani&est.
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.
1('
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
)i1ecycle %ethods
Cust as a'ti!ities ha!e on+reateLM, on?esumeLM, on(auseLM an" kin, 2ervice implementations ha!e their o=n li&e'y'le metho"s, su'h as, 1.
on+reateLM,
=hi'h, as =ith a'ti!ities, is 'alle" =hen the ser!i'e pro'ess is 'reate", by any means
2. on2tart+ommandLM, =hi'h is 'alle" ea'h time the ser!i'e is sent a 'omman" !ia start2erviceLM /. on4indLM, =hi'h is 'alle" =hene!er a 'lient bin"s to the ser!i'e !ia
bind2erviceLM
<. on=estroFLM =hi'h is 'alle" as the ser!i'e is being shut "o=n As =ith a'ti!ities, ser!i'es initialiLe =hate!er they nee" in on+reateLM an" 'lean up those items in on=estroFLM. An", as =ith a'ti!ities, the on=estroFLM 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+ommandLM an" on4indLM 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.
% ni1est Entry
*inally, you nee" to a"" the ser!i'e to your Android#anifest.Gml &ile, &or it to be re'ogniLe" as an a!ailable ser!i'e &or use. 5hat is simply a matter o& a""ing a NserviceP 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.
1(1
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
1& you =ish to reBuire 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 NserviceO element,
NPGml version671.-7 encoding67utf-,7PO Nmanifest android:version+ode6717 android:version%ame671.-7 package67com.commonsDare.android.doDnloader7 Gmlns:android67http://schemas.android.com/apk/res/android7O Nuses-permission android:name67android.permission.I%&$?%$&7 /O Nuses-permission android:name67android.permission.@?I&$ $]&$?%A) 2&"?AE$7 /O Napplication android:icon67QdraDable/cD7 android:label67Qstring/app name7O NactivitF android:label67Qstring/app name7 android:name67=oDnloader=emo7O Nintent-filterO Naction android:name67android.intent.action.#AI%7 /O NcategorF android:name67android.intent.categorF.)A3%+!$?7 /O N/intent-filterO N/activitFO Nservice android:name67=oDnloader7 /O N/applicationO Nsupports-screens android:anF=ensitF67true7 android:large2creens67true7 android:normal2creens67true7 android:small2creens67true7 /O N/manifestO
Communicating To Services
Clients o& ser!i'es S &reBuently a'ti!ities, though not ne'essarily S ha!e t=o main =ays to sen" reBuests 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.
1(3
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
"oes. 1n &a't, the Intent supplie" to start2erviceLM has the same t=o-part role as it "oes =ith startActivitFLM,
startActivitFLM
1"enti&y the ser!i'e to 'ommuni'ate =ith %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., neD IntentLthis8 #F2ervice.classMJ). 5he 'all to start2erviceLM 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+ommandLM li&e'y'le metho". 5he ser!i'e 'an "o =hate!er it nee"s to in on2tart+ommandLM, but sin'e on2tart+ommandLM is 'alle" on the main appli'ation threa", it shoul" "o its =ork !ery Bui'kly. Anything that might take a =hile shoul" be "elegate" to a ba'kgroun" threa". 5he on2tart+ommandLM 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+ommandLM ha" been 'alle"), but "o not re-"eli!er the Intent to on2tart+ommandLM
2&A?& ?$=$)IV$? I%&$%&, meaning that the ser!i'e shoul" be restarte" !ia a 'all to on2tart+ommandLM, supplying the same Intent as
meaning that the ser!i'e shoul" remain stoppe" until e;pli'itly starte" by appli'ation 'o"e
2y "e&ault, 'alling start2erviceLM 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 stop2erviceLM, supplying the same Intent use" =ith start2erviceLM, or at least one that is eBui!alent (e.g., i"enti&ies the same 'lass). At that point, the ser!i'e =ill stop an" =ill be "estroye".
1(6
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
-ote that stop2erviceLM "oes not employ any sort o& re&eren'e 'ounting, so three 'alls to start2erviceLM =ill result in a single ser!i'e running, =hi'h =ill be stoppe" by a 'all to stop2erviceLM. Another possibility &or stopping a ser!i'e is to ha!e the ser!i'e 'all stop2elfLM on itsel&. ?ou might "o this i& you use start2erviceLM 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".
1(8
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
e;isting ser!i'e to bin" to. E!entually, the 'lient =ill nee" to 'all unbind2erviceLM, 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 bind2erviceLM in its on+reateLM metho", then 'all unbind2erviceLM in its on=estroFLM metho". >n'e you 'all unbind2erviceLM, your 4inder obHe't is no longer sa&e to be use" by the 'lient. 1& 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 stop2erviceLM oursel!es S An"roi" han"les that, i& nee"e", as a si"e e&&e't o& unbin"ing. ?our 2ervice+onnection obHe't =ill also nee" an on2ervice=isconnectedLM metho". 5his =ill be 'alle" only i& there is an une;pe'te" "is'onne'tion, su'h as the ser!i'e 'rashing =ith an unhan"le" e;'eption. 1& 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, su'h as a s'reen rotation, 1. 1nstea" o& 'alling bind2erviceLM on the a'ti!ity itsel&, 'all bind2erviceLM on the Application +onteGt (obtaine" !ia getApplication+onteGtLM).
2. Make sure you trans&er the 2ervice+onnection &rom the ol" instan'e o& the a'ti!ity to the ne= one, probably !ia on?etain%on+onfigurationInstanceLM. 5his allo=s the bin"ing to persist bet=een a'ti!ity instan'es.
1(:
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
2. 8i!e the ser!i'e a publi' A#1 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 obHe'ts generally kno= their a'ti!ity, e;pli'itly (!ia a "ata member) or impli'itly (by being implemente" as an inner 'lass). 1& the ser!i'e is hol"ing onto "e&un't listener obHe'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 1ntent &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 send4roadcastLM, supplying an 1ntent 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., neD IntentLthis8 #F?eceiver.classM), 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.
1.;
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
in turn, 'an register a 4roadcast?eceiver !ia register?eceiverLM, though this approa'h =ill only =ork &or Intent obHe'ts spe'i&ying some a'tion, not ones i"enti&ying a parti'ular 'omponent. 2ut, =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&.
5he
a'ti!ity,
Pendin! Results
?our a'ti!ity 'an 'all create(ending?esultLM. 5his returns a (endingIntent S an obHe'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). 1n this 'ase, the (endingIntent =ill 'ause a result to be "eli!ere" to your a'ti!ity7s implementation o& onActivitF?esultLM, Hust as i& another a'ti!ity ha" been 'alle" =ith startActivitF9or?esultLM an", in turn, 'alle" set?esultLM 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 sendLM metho" on the (endingIntent, to noti&y the a'ti!ity (!ia onActivitF?esultLM) 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 obHe'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 start2erviceLM or bind2erviceLM =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",
1.+
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
Call #essage.obtainLM to get an empty #essage obHe't #opulate that #essage obHe't as nee"e", =ith =hate!er "ata the ser!i'e =ishes to pass to the a'ti!ity Call sendLM on the #essenger, supplying the #essage as a parameter
5he !andler =ill then re'ei!e the message !ia handle#essageLM, on the main appli'ation threa", an" so 'an up"ate the $1 or =hate!er is ne'essary.
"oti1ic 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 -oti&i'ation S putting an i'on in the status bar an" optionally shaking or beeping or something. 5his te'hniBue is 'o!ere" in an up'oming 'hapter.
1.(
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
CHAPTER /7
-o= 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 0o*nloa er
1& 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& N"rop bo;N &ile-sharing ser!i'e. An"roi" 2./ intro"u'e" the =oDnload#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 proHe't re!ie=e" in this se'tion is 2ervices/=oDnloader.
1..
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 start2erviceLM 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 =oDnloader eGtends Intent2ervice : public static final 2tring $]&?A #$22$%E$?67com.commonsDare.android.doDnloader.$]&?A #$22$%E$?7J private !ttp+lient client6nullJ public DownloaderLM : superL7=oDnloader7MJ ;
1.'
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
Q"verride public void onCreateLM : super.onCreateLMJ client6neD Default(ttpClientLMJ ; Q"verride public void onDestroyLM : super.onDestroyLMJ ; client.getConnectionManagerLM.shutdownLMJ
Q"verride public void on(andleIntentLIntent iM : !ttpEet get#ethod6neD (ttp etLi.getDataLM.toStringLMMJ int result6ActivitF.?$23)& +A%+$)$=J trF : ?esponse!andlerNbFteABO response!andler6neD Byte$rray%esponse(andlerLMJ bFteAB response4odF6client.executeLget#ethod8 response!andlerMJ 9ile output6neD "ileL$nvironment.get+xternalStorageDirectoryLM8 i.getDataLM.getLast)athSegmentLMMJ if Loutput.existsLMM : output.deleteLMJ ; 9ile"utput2tream fos6neD "ileOutputStreamLoutput.get)athLMMJ fos.writeLresponse4odFMJ fos.closeLMJ result6ActivitF.?$23)& "HJ
; catch LI"$Gception e>M : )og.eLgetClassLM.get&ameLM8 7$Gception in doDnload78 e>MJ ; 4undle eGtras6i.get+xtrasLMJ if LeGtrasX6nullM : #essenger messenger6L#essengerMeGtras.getL$]&?A #$22$%E$?MJ #essage msg6#essage.o'tainLMJ msg.arg16resultJ trF : messenger.sendLmsgMJ ; catch Landroid.os.?emote$Gception e1M : )og.wLgetClassLM.get&ameLM8 7$Gception sending message78 e1MJ ; ;
1.1
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
; ;
1n on+reateLM, =e obtain a =efault!ttp+lient obHe't, as =as "es'ribe" in the 'hapter on 1nternet a''ess. 1n on=estroFLM, =e shut "o=n the 'lient. 5his =ay, i& se!eral "o=nloa" reBuests are in!oke" in seBuen'e, =e 'an use a single =efault!ttp+lient obHe't S the Intent2ervice =ill only shut "o=n a&ter all enBueue" =ork has been 'omplete". 5he bulk o& the =ork is a''omplishe" in on!andleIntentLM, =hi'h is 'alle" on the Intent2ervice, on a ba'kgroun" threa", e!ery time start2erviceLM is 'alle". *or the Intent, =e obtain the $ L o& the &ile to "o=nloa" !ia a 'all to get=ataLM on the supplie" Intent. A'tually "o=nloa"ing the &ile uses the =efault!ttp+lient obHe't, along =ith an !ttpEet obHe'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. 1nstea", =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.commonsDare.android.doDnloaderJ 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!andlerNbFteABO : public bFteAB handle%esponseLfinal !ttp?esponse responseM throDs I"$Gception8 !ttp?esponse$Gception : 2tatus)ine status)ine6response.getStatusLineLMJ if Lstatus)ine.getStatusCodeLMO6C--M : throD neD (ttp%esponse+xceptionLstatus)ine.getStatusCodeLM8 status)ine.get%eason)hraseLMMJ ; !ttp$ntitF entitF6response.get+ntityLMJ if LentitF66nullM : returnLnullMJ ; returnL$ntitF3tils.toByte$rrayLentitFMMJ
1.3
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
; ;
>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". 1& the a'ti!ity is intereste" in this sort o& message, it =ill ha!e atta'he" a #essenger obHe't as $]&?A #$22$%E$? to the Intent. =oDnloader gets the #essenger, 'reates an empty #essage obHe't, an" puts a result 'o"e in the arg1 &iel" o& the #essage. 1t then sen"s the #essage to the a'ti!ity. 1& the a'ti!ity =as "estroye" be&ore this point, the reBuest 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!andleIntentLM 'ompletes, i& there is no more =ork Bueue" to be "one.
When the user 'li'ks the button, do&he=oDnloadLM is 'alle" to "isable the button (to pre!ent a''i"ental "upli'ate "o=nloa"s) an" 'all start2erviceLM,
1.6
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
public void doTheDownloadLVieD vM : b.set+na'ledLfalseMJ Intent i6neD IntentLthis8 =oDnloader.classMJ i.setDataL3ri.parseL7http://commonsDare.com/Android/eGcerpt.pdf7MMJ i.put+xtraL=oDnloader.$]&?A #$22$%E$?8 neD MessengerLhandlerMMJ startSer!iceLiMJ ;
+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$%E$? e;tra. 5hat #essenger is 'reate" =ith an atta'hment to the a'ti!ity7s !andler,
private !andler handler6neD (andlerLM : Q"verride public void handleMessageL#essage msgM : b.set+na'ledLtrueMJ &oast .makeTextL=oDnloader=emo.this8 7=oDnload completeX78 &oast.)$%E&! )"%EM .showLMJ
; ;J
1& 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. -ote 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 start2erviceLM, 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 Q"verride public int onStartCommandLIntent intent8 int flags8 int startIdM : 2tring plaFlist6intent.getString+xtraL$]&?A ()A5)I2&MJ boolean use2huffle6intent.getBoolean+xtraL$]&?A 2!399)$8 falseMJ playLplaFlist8 use2huffleMJ returnL2&A?& %"& 2&I+H5MJ ; Q"verride public void onDestroyLM : stopLMJ ; Q"verride public I4inder onBindLIntent intentM : returnLnullMJ
1.:
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
; private void playL2tring plaFlist8 boolean use2huffleM : if LXis(laFingM : )og.wLgetClassLM.get&ameLM8 7Eot to plaFLMX7MJ is(laFing6trueJ ; ; private void stopLM : if Lis(laFingM : )og.wLgetClassLM.get&ameLM8 7Eot to stopLMX7MJ is(laFing6falseJ ; ; ;
1n this 'ase, =e really "o not nee" anything &or on+reateLM, so that li&e'y'le metho" is skippe". >n the other han", =e ha!e to implement on4indLM, be'ause that is a reBuire" metho" o& 2ervice sub'lasses. Intent2ervice implements on4indLM &or us, =hi'h is =hy that =as not nee"e" &or the =oDnloader sample. When the 'lient 'alls start2erviceLM, on2tart+ommandLM 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+ommandLM 'alls plaFLM, =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+ommandLM 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=estroFLM stops the musi' &rom playing S theoreti'ally, any=ay S by 'alling a stopLM metho". >n'e again, this Hust logs a message to LogCat,
1n the up'oming 'hapter on noti&i'ations, =e =ill re!isit this sample an" "is'uss the use o& start9oregroundLM 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.
1';
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
public class 9ake(laFer eGtends ActivitF : Q"verride public void onCreateL4undle savedInstance2tateM : super.onCreateLsavedInstance2tateMJ setContentViewL?.laFout.mainMJ ; public void start)layerLVieD vM : Intent i6neD IntentLthis8 (laFer2ervice.classMJ i.put+xtraL(laFer2ervice.$]&?A ()A5)I2&8 7main7MJ i.put+xtraL(laFer2ervice.$]&?A 2!399)$8 trueMJ startSer!iceLiMJ
1'+
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
5he on+reateLM metho" merely loa"s the $1. 5he start(laFerLM metho" 'onstru'ts an Intent =ith &ake !alues &or $]&?A ()A5)I2& an" $]&?A 2!399)$, then 'alls start2erviceLM. A&ter you press the top button, you =ill see the 'orrespon"ing message in LogCat. %imilarly, stop(laFerLM 'alls stop2erviceLM, triggering the se'on" LogCat message. -otably, 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 2ACD an" 'ome ba'k later to stop the ser!i'e.
1'(
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
The Desi!n
5o use the bin"ing pattern, =e =ill nee" to e;pose an A#1 &rom a Nbin"erN obHe'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 get9orecastLM metho" to get us an ArraF)ist o& 9orecast obHe'ts, ea'h 9orecast representing one timestampQtemperatureQpre'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 obHe'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". 1n this sample, =e =ill ha!e the ser!i'e use an AsFnc&ask to 'all our =eather A#1, so the a'ti!ity largely 'an be ignorant o& threa"ing issues.
1'.
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
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+onfigurationInstanceLM tri'k as =as use" =ith threa"s.
&he Forecast
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.commonsDare.android.DeatherJ class 9orecast : 2tring time677J Integer temp6nullJ 2tring icon3rl677J 2tring getTimeLM : returnLtimeMJ ; void setTimeL2tring timeM : this.time6time.su'stringL-810M.replaceLI&I8 I IMJ ; Integer getTempLM : returnLtempMJ ; void setTempLInteger tempM : this.temp6tempJ ; 2tring getIconLM : returnLicon3rlMJ ; void setIconL2tring icon3rlM :
1''
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
this.icon3rl6icon3rlJ ; ;
&he +nterface
2e'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#1 'hallenge S 'alls on our bin"er are syn'hronous. +en'e, =e 'annot ha!e a get9orecastLM 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. 1n this 'ase, =e =ill pass in a listener obHe't (@eather)istener), that the ser!i'e =ill use =hen a &ore'ast is rea"y,
package com.commonsDare.android.DeatherJ import java.util.ArraF)istJ public interface @eather)istener : void update"orecastLArraF)istN9orecastO forecastMJ void handle+rrorL$Gception eMJ ;
&he -inder
5he @eather4inder e;ten"s 4inder, a reBuirement &or the lo'al bin"ing pattern. >ther than that, the A#1 is up to us. +en'e, =e e;pose t=o metho"s, 1. the 'onstru'tor, =here =e are passe" the $ L template to use &or 'reating the -ational Weather %er!i'e Web ser!i'e $ L
2. get9orecastLM, the main publi' A#1 &or use by our a'ti!ity, to ki'k o&& the ba'kgroun" =ork to 'reate our ArraF)ist o& 9orecast obHe'ts gi!en a )ocation
package com.commonsDare.android.DeatherJ import import import import import java.io.2tring?eaderJ java.util.ArraF)istJ javaG.Gml.parsers.=ocument4uilderJ javaG.Gml.parsers.=ocument4uilder9actorFJ org.apache.http.client.?esponse!andlerJ 1'1
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
import import import import import import import import import import
org.apache.http.client.methods.!ttpEetJ org.apache.http.impl.client.4asic?esponse!andlerJ org.apache.http.impl.client.=efault!ttp+lientJ org.DCc.dom.=ocumentJ org.DCc.dom.$lementJ org.DCc.dom.%ode)istJ org.Gml.saG.Input2ourceJ android.location.)ocationJ android.os.AsFnc&askJ android.os.4inderJ
public class @eather4inder eGtends 4inder : private 2tring format6nullJ #eatherBinderL2tring formatM : this.format6formatJ ; void get"orecastL)ocation loc8 @eather)istener listenerM : neD "etch"orecastTaskLlistenerM.executeLlocMJ ; private ArraF)istN9orecastO 'uild"orecastsL2tring raDM throDs $Gception : ArraF)istN9orecastO forecasts6neD ArraF)istN9orecastOLMJ =ocument4uilder builder6=ocument4uilder9actorF .newInstanceLM .newDocumentBuilderLMJ =ocument doc6builder.parseLneD InputSourceLneD String%eaderLraDMMMJ %ode)ist times6doc.get+lementsByTag&ameL7start-valid-time7MJ for Lint i6-JiNtimes.getLengthLMJiRRM : $lement time6L$lementMtimes.itemLiMJ 9orecast forecast6neD "orecastLMJ forecasts.addLforecastMJ forecast.setTimeLtime.get"irstChildLM.get&odeValueLMMJ
%ode)ist temps6doc.get+lementsByTag&ameL7value7MJ for Lint i6-JiNtemps.getLengthLMJiRRM : $lement temp6L$lementMtemps.itemLiMJ 9orecast forecast6forecasts.getLiMJ forecast.setTempLneD IntegerLtemp.get"irstChildLM.get&odeValueLMMMJ ; %ode)ist icons6doc.get+lementsByTag&ameL7icon-link7MJ for Lint i6-JiNicons.getLengthLMJiRRM : $lement icon6L$lementMicons.itemLiMJ 9orecast forecast6forecasts.getLiMJ forecast.setIconLicon.get"irstChildLM.get&odeValueLMMJ
1'3
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
; returnLforecastsMJ ; : class 9etch9orecast&ask eGtends AsFnc&askN)ocation8 Void8 ArraF)istN9orecastOO $Gception e6nullJ @eather)istener listener6nullJ "etch"orecastTaskL@eather)istener listenerM : this.listener6listenerJ ; Q"verride protected ArraF)istN9orecastO doInBackgroundL)ocation... locsM : =efault!ttp+lient client6neD Default(ttpClientLMJ ArraF)istN9orecastO result6nullJ trF : )ocation loc6locsA-BJ 2tring url62tring.formatLformat8 loc.getLatitudeLM8 loc.getLongitudeLMMJ !ttpEet get#ethod6neD (ttp etLurlMJ ?esponse!andlerN2tringO response!andler6neD Basic%esponse(andlerLMJ 2tring response4odF6client.executeLget#ethod8 response!andlerMJ result6'uild"orecastsLresponse4odFMJ ; catch L$Gception eM : this.e6eJ ; client.getConnectionManagerLM.shutdownLMJ ; returnLresultMJ
Q"verride protected void on)ost+xecuteLArraF)istN9orecastO forecastM : if LlistenerX6nullM : if LforecastX6nullM : listener.update"orecastLforecastMJ ; if LeX6nullM : listener.handle+rrorLeMJ ;
; ; ; ;
1'6
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
is merely "oing the Web ser!i'e reBuest using =efault!ttp+lient an" an !ttpEet obHe't, plus using the @>M parser to 'on!ert the FML into the 9orecast obHe'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". 1n on(ost$GecuteLM, the task in!okes our @eather)istener, either to supply the &ore'ast (update9orecastLM) or han" o!er an $Gception that =as raise" (handle$rrorLM).
&he Service
5he @eather2ervice, there&ore, is &airly short, =ith the business logi' "elegate" to @eather4inder,
package com.commonsDare.android.DeatherJ import android.app.2erviceJ import android.content.IntentJ import android.os.I4inderJ public class @eather2ervice eGtends 2ervice : private @eather4inder binder6nullJ Q"verride public void onCreateLM : super.onCreateLMJ ; binder6neD #eatherBinderLgetStringL?.string.urlMMJ
>ur on+reateLM metho" initialiLes the @eather4inder, an" on4indLM returns the @eather4inder itsel&.
Arrange to get 8#% &i;es, in the &orm o& )ocation obHe'ts When a &i; 'omes in, use the @eather4inder to get a &ore'ast, 'on!ert it to +5ML, an" "isplay it in a @ebVieD $nbin" &rom the ser!i'e in on=estroFLM
+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.commonsDare.android.DeatherJ import import import import import import import import import import import import import java.util.ArraF)istJ android.app.ActivitFJ android.app.Alert=ialogJ android.content.+omponent%ameJ android.content.IntentJ android.content.2ervice+onnectionJ android.location.)ocationJ android.location.)ocation)istenerJ android.location.)ocation#anagerJ android.os.4undleJ android.os.I4inderJ android.util.)ogJ android.Debkit.@ebVieDJ
public class @eather=emo eGtends ActivitF : private @ebVieD broDserJ private )ocation#anager mgr6nullJ private 2tate state6nullJ private boolean is+onfiguration+hanging6falseJ Q"verride public void onCreateL4undle savedInstance2tateM : super.onCreateLsavedInstance2tateMJ setContentViewL?.laFout.mainMJ broDser6L@ebVieDMfindViewByIdL?.id.DebkitMJ state6L2tateMgetLast&onConfigurationInstance LMJ if Lstate66nullM : state6neD StateLMJ get$pplicationContextLM .'indSer!iceLneD IntentLthis8 @eather2ervice.classM8 state8 4I%= A3&" +?$A&$MJ ; else if Lstate.last9orecastX6nullM :
1':
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
Q"verride public void onDestroyLM : super.onDestroyLMJ if LmgrX6nullM : mgr.remo!e*pdatesLon)ocation+hangeMJ ; if LXis+onfiguration+hangingM : get$pplicationContextLM.un'indSer!iceLstateMJ ; ; Q"verride public "bject on%etain&onConfigurationInstance LM : is+onfiguration+hanging6trueJ ; returnLstateMJ
private void goBlooeyL&hroDable tM : Alert=ialog.4uilder builder6neD Alert=ialog.BuilderLthisMJ builder .setTitleL7$GceptionX7M .setMessageLt.toStringLMM .set)ositi!eButtonL7"H78 nullM .showLMJ
static 2tring generate)ageLArraF)istN9orecastO forecastsM : 2tring4uilder buf?esult6neD StringBuilderL7NhtmlONbodFONtableO7MJ buf?esult.appendL7NtrONth Didth6T7.-\T7O&imeN/thO7R 7NthO&emperatureN/thONthO9orecastN/thON/trO7MJ for L9orecast forecast : forecastsM : buf?esult.appendL7NtrONtd align6T7centerT7O7MJ buf?esult.appendLforecast.getTimeLMMJ buf?esult.appendL7N/tdONtd align6T7centerT7O7MJ buf?esult.appendLforecast.getTempLMMJ buf?esult.appendL7N/tdONtdONimg src6T77MJ buf?esult.appendLforecast.getIconLMMJ buf?esult.appendL7T7ON/tdON/trO7MJ
11;
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
; buf?esult.appendL7N/tableON/bodFON/htmlO7MJ returnLbuf?esult.toStringLMMJ ; void show"orecastLM : broDser.loadData#ithBase*%LLnull8 state.last9orecast8 7teGt/html78 73&9-,78 nullMJ ; )ocation)istener on)ocation+hange6neD LocationListenerLM : public void onLocationChangedL)ocation locationM : if Lstate.DeatherX6nullM : state.Deather.get"orecastLlocation8 stateMJ ; else : )og.wLgetClassLM.get&ameLM8 73nable to fetch forecast [ no @eather4inder7MJ ; ; public void on)ro!iderDisa'ledL2tring providerM : // reUuired for interface8 not used ; public void on)ro!ider+na'ledL2tring providerM : // reUuired for interface8 not used ; public void onStatusChangedL2tring provider8 int status8 4undle eGtrasM : // reUuired for interface8 not used ; ;J static class 2tate implements @eather)istener8 2ervice+onnection : @eather4inder Deather6nullJ @eather=emo activitF6nullJ 2tring last9orecast6nullJ void attachL@eather=emo activitFM : this.activitF6activitFJ ; public void update"orecastLArraF)istN9orecastO forecastM : last9orecast6generate)ageLforecastMJ activitF.show"orecastLMJ ; public void handle+rrorL$Gception eM : activitF.goBlooeyLeMJ
11+
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
; public void onSer!iceConnectedL+omponent%ame class%ame8 I4inder raD4inderM : Deather6L@eather4inderMraD4inderJ ; public void onSer!iceDisconnectedL+omponent%ame class%ameM : Deather6nullJ ;
; ;
-o=, let us look at the highlights o& the ser!i'e 'onne'tion an" the ba'kgroun" threa".
11(
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
Deather6nullJ ; ;
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 @ebVieD) an" either ha!e to retrie!e a &resh one or =ait &or a 8#% &i;. We return this 2tate obHe't &rom on?etain%on+onfigurationInstanceLM,
Q"verride public "bject on%etain&onConfigurationInstance LM : is+onfiguration+hanging6trueJ returnLstateMJ ;
1n on+reateLM, 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+reateLM gets a 2tate &rom get)ast%on+onfigurationInstanceLM, it simply hol"s onto that state an" reloa"s our &ore'ast in the @ebVieD. 1n either 'ase, on+reateLM in"i'ates to the 2tate that the ne= a'ti!ity instan'e is the 'urrent one,
Q"verride public void onCreateL4undle savedInstance2tateM : super.onCreateLsavedInstance2tateMJ setContentViewL?.laFout.mainMJ broDser6L@ebVieDMfindViewByIdL?.id.DebkitMJ state6L2tateMgetLast&onConfigurationInstance LMJ if Lstate66nullM : state6neD StateLMJ get$pplicationContextLM .'indSer!iceLneD IntentLthis8 @eather2ervice.classM8 state8 4I%= A3&" +?$A&$MJ ; else if Lstate.last9orecastX6nullM : show"orecastLMJ ; state.attachLthisMJ mgr6L)ocation#anagerMgetSystemSer!iceL)"+A&I"% 2$?VI+$MJ
11.
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
&ime to Un'ind
We bin" to the ser!i'e =hen on+reateLM is 'alle", i& it "i" not re'ei!e a 2tate !ia get)ast%on+onfigurationInstanceLM (in =hi'h 'ase, =e are alrea"y boun"). 5his begs the Buestion, =hen "o =e unbin" &rom the ser!i'eI 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=estroFLM. 5here is an is9inishingLM 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 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 2ACD button. 5here is an is+hanging+onfigurationsLM metho" that meets our nee"s, but it =as intro"u'e" in A#1 Le!el 11 an" there&ore 'an only be use" on ne=er An"roi" "e!i'es. 5his is =hy on?etain%on+onfigurationInstanceLM 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,
Q"verride public void onDestroyLM : super.onDestroyLMJ if LmgrX6nullM : mgr.remo!e*pdatesLon)ocation+hangeMJ ; if LXis+onfiguration+hangingM : get$pplicationContextLM.un'indSer!iceLstateMJ ;
11'
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
CHAPTER /8
#op-up messages. 5ray i'ons an" their asso'iate" NbubbleN messages. 2oun'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 Hust in'oming 'alls, lo= battery, alarm 'lo'ks, appointment noti&i'ations, in'oming te;t message or email, et'. -ot surprisingly, An"roi" has a =hole &rame=ork &or "ealing =ith these sorts o& things, 'olle'ti!ely 'alle" Nnoti&i'ationsN.
?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 Nnoti&i'ationsN. ?our 'urrent phone may =ell ha!e su'h i'ons, to in"i'ate battery li&e, signal strength, =hether 2luetooth 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").
111
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
1n 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 obHe't !ia get2Fstem2erviceL%"&I9I+A&I"% 2$?VI+$M &rom your a'ti!ity. 5he %otification#anager gi!es you three metho"s, one to raise a %otification (notifFLM) an" t=o to get ri" o& an e;isting %otification (cancelLM an" cancelAllLM). 5he notifFLM 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 obHe't are "es'ribe" in the &ollo=ing se'tions.
113
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
All o& these, by "e&ault, happen on'e (e.g., one LE@ &lash, one playba'k o& the soun"). 1& 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)AE I%2I2&$%&. 1nstea" o& manually spe'i&ying the har"=are options, you 'an also use the defaults &iel" in the %otification, setting it to =$9A3)& )IE!&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 =raDable 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' getActivitFLM 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 get4roadcastLM !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). 1& you =ant all three, the simpler approa'h is to 'all set)atest$ventInfoLM, =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
116
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
'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. 2y "e&ault, the number =ill be ignore" an" not use". -ote that the siLe o& the i'ons use" =ith a %otification 'hange" =ith An"roi" 2./. 1t use" to be that 2Ap; sBuare =as the "esire" siLe. -o=, they pre&er per-"ensity i'ons in a more re'tangular shape,
2<p; sBuare (insi"e a 2<p; =i"e by /8p; high boun"ing bo;) &or high-"ensity s'reens 14p; sBuare (insi"e a 14p; by 2Ap; boun"ing bo;) &or me"ium"ensity s'reens 12p; sBuare (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/draDable-hdpi-v*/ res/draDable-mdpi-v*/ res/draDable-ldpi-v*/ res/draDable/
&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 !ction
Let us no= take a peek at the %otifications/%otifF1 sample proHe't, in parti'ular the %otifF=emo 'lass,
package com.commonsDare.android.notifFJ import android.app.ActivitFJ import android.app.%otificationJ
118
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
public class %otifF=emo eGtends ActivitF : private static final int %"&I95 #$ I=61CC/J private int count6-J private %otification#anager mgr6nullJ Q"verride public void onCreateL4undle savedInstance2tateM : super.onCreateLsavedInstance2tateMJ setContentViewL?.laFout.mainMJ mgr6L%otification#anagerMgetSystemSer!iceL%"&I9I+A&I"% 2$?VI+$MJ ; public void notifyMeLVieD vM : %otification note6neD &otificationL?.draDable.stat notifF chat8 72tatus messageX78 2Fstem.currentTimeMillisLMMJ (endingIntent i6(endingIntent.get$cti!ityLthis8 -8 neD IntentLthis8 %otifF#essage.classM8 -MJ note.setLatest+!entInfoLthis8 7%otification &itle78 7&his is the notification message78 iMJ note.number6RRcountJ note.vibrate6neD longAB :.--)8 >--)8 >--)8 .--);J note.flagsW6%otification.9)AE A3&" +A%+$)J ; mgr.notifyL%"&I95 #$ I=8 noteMJ
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),
11:
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
Creating the noti&i'ation, in notifF#eLM, is a''omplishe" in a han"&ul o& steps, 1. Create a %otification obHe'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$ventInfoLM 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 NnumberN asso'iate" =ith the noti&i'ation A. %pe'i&y a !ibration pattern S A00ms on, 200ms o&&, 200ms on, A00ms o&& 4. 1n'lu"e 9)AE A3&" +A%+$) in the %otification obHe't7s flags &iel"
13;
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
0. 5ell the %otification#anager (obtaine" in on+reateLM)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'2 -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.
13+
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
number
1& 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,
13(
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
1& 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)AE 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. 1"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. 1& 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 N&oregroun"N. 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, in on+reateLM o& your ser!i'e (or =here!er else in the ser!i'e7s li&e it =oul" make sense), 'all start9oregroundLM. 5his takes a %otification an" a lo'ally-uniBue integer, Hust like the notifFLM metho" on %otification#anager. 1t 'auses the %otification to appear an" mo!es the ser!i'e into &oregroun" priority. Later on, you 'an 'all stop9oregroundLM to return to normal priority. -ote that this metho" =as a""e" =ith An"roi" 2.0 (A#1 le!el A). 5here =as an earlier metho", set9oregroundLM, that per&orms a similar &un'tion in earlier !ersions o& An"roi".
13'
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
+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 start9oregroundLM an" stop9oregroundLM. We 'an 'all start9oregroundLM =hen =e start the musi' playing in our plaFLM metho",
private void playL2tring plaFlist8 boolean use2huffleM : if LXis(laFingM : )og.wLgetClassLM.get&ameLM8 7Eot to plaFLMX7MJ is(laFing6trueJ %otification note6neD &otificationL?.draDable.stat notifF chat8 7+an Fou hear the musicP78 2Fstem.currentTimeMillisLMMJ Intent i6neD IntentLthis8 9ake(laFer.classMJ i.set"lagsLIntent.9)AE A+&IVI&5 +)$A? &"(W Intent.9)AE A+&IVI&5 2I%E)$ &"(MJ (endingIntent pi6(endingIntent.get$cti!ityLthis8 -8 i8 -MJ note.setLatest+!entInfoLthis8 79ake (laFer78 7%oD (laFing: T73mmmm8 %othingT778 piMJ note.flagsW6%otification.9)AE %" +)$A?J ; ; start"oregroundL1CC/8 noteMJ
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. 1& 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 1ntent &lags (Intent.9)AE A+&IVI&5 +)$A? &"(W Intent.9)AE A+&IVI&5 2I%E)$ &"(). *or a musi' player, this $1 pattern is a goo" thing, as it makes it easy &or the user to Bui'kly go ba'k to stop the musi' =hen nee"e". %topping the musi', !ia our stopLM metho", =ill 'all stop9oregroundLM,
131
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
5he true !alue passe" to stop9oregroundLM tells An"roi" to remo!e the %otification, =hi'h =oul" be the typi'al approa'h &or this pattern.
?otifications an
5he +oney'omb $1 intro"u'e" in An"roi" /.0 supports noti&i'ations, Hust like all pre!ious !ersions o& An"roi". +o=e!er, the user e;perien'e is a bit "i&&erent. +ere is the unmo"i&ie" %otifications/%otifF1 proHe't, as seen in the An"roi" /.0 emulator,
.2; emulator
133
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
>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. -o=, i& =e 'li'k the top button, our -oti&i'ation appears, this time in the lo=er right, =ith the i'on an" ti'ker te;t,
-ote that i& the user taps the ti'ker, it triggers your (endingIntent, Hust 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,
136
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
1& the user taps that i'on, a noti&i'ation "ra=er-style pop-up appears nearby,
138
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
5apping the i'on or the te;t triggers the (endingIntent, =hile 'li'king the F on the right 'an'els this %otification.
13:
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
CHAPTER /9
1n the late 13307s, a =a!e o& !iruses sprea" through the 1nternet, "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#1, sin'e that A#1 =as "esigne" &or or"inary "e!elopers, not !irus authors. -o=a"ays, many appli'ations that hol" onto 'onta't "ata se'ure that "ata by reBuiring 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 reBuires 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 &reBuently 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 reBuire 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.
16+
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
4e5uesting an
4e5uiring Permissions
5he uses-permission element takes a single attribute, android:name, =hi'h is the name o& the permission your appli'ation reBuires,
Nuses-permission android:name67android.permission.A++$22 )"+A&I"%7 /O
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 1nternet through any means, &rom ra= Ca!a so'kets through the @ebVieD =i"get
@?I&$ $]&$?%A) 2&"?AE$, A++$22 +"A?2$ )"+A&I"%
&or =riting "ata to the %@ 'ar" (or =hate!er the "e!i'e has "esignate" as Ne;ternal storageN) =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 Husti&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 $%2, su'h as "uring "e!elopment.
16(
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
4e5uesting an
4e5uiring Permissions
1& 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. -ote 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 reBueste" permissions.
16.
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
4e5uesting an
4e5uiring Permissions
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
Npermission android:name67vnd.tlagencF.sekrits.2$$ 2$H?I&27 android:label67Qstring/see sekrits label7 android:description67Qstring/see sekrits description7 /O
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 reBueste" your in"i'ate" permission =ill be able to a''ess the se'ure" 'omponent. 1n this 'ase, 6a''ess9 means,
16'
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
4e5uesting an
4e5uiring Permissions
%er!i'es 'annot be starte", stoppe", or boun" to an a'ti!ity =ithout the permission 1ntent re'ei!ers ignore messages sent !ia send4roadcastLM 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 send4roadcastLM. 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 send4roadcastLM in greater "etail else=here in this book.
4e5uesting an
4e5uiring Permissions
so you 'an internationaliLe your permission "etails the =ay you internationaliLe all the other messages an" prompts in your appli'ation.
?e* Permissions in -l
!pplications
%ometimes, An"roi" intro"u'es ne= permissions that go!ern beha!ior that &ormerly "i" not reBuire permissions. @?I&$ $]&$?%A) 2&"?AE$ is one e;ample S originally, appli'ations 'oul" =rite to e;ternal storage =ithout any permission at all. An"roi" 1.4 intro"u'e" @?I&$ $]&$?%A) 2&"?AE$, reBuire" be&ore you 'an =rite to e;ternal storage. +o=e!er, appli'ations that =ere =ritten be&ore An"roi" 1.4 'oul" not possibly reBuest that permission, sin'e it "i" not e;ist at the time. 2reaking those appli'ations =oul" seem to be a harsh pri'e &or progress. What An"roi" "oes is Ngran"&atherN in 'ertain permissions &or appli'ations supporting earlier %@D !ersions. 1n parti'ular, i& you ha!e Nuses-sdk android:min2dkVersion67C7O in your mani&est, saying that you support An"roi" 1.A, your appli'ation =ill automati'ally reBuest @?I&$ $]&$?%A) 2&"?AE$ an" ?$A= (!"%$ 2&A&$, e!en i& you "o not e;pli'itly reBuest those permissions. #eople installing your appli'ation on an An"roi" 1.A "e!i'e =ill see these reBuests. E!entually, =hen you "rop support &or the ol"er !ersion (e.g., s=it'h to Nuses-sdk android:min2dkVersion67<7O), An"roi" =ill no longer automati'ally reBuest those permissions. +en'e, i& your 'o"e really does nee" those permissions, you =ill nee" to ask &or them yoursel&.
4e5uesting an
4e5uiring Permissions
?ou 'annot 'reate optional permissions, ones the user 'oul" say Nno, thanksN to, that your appli'ation 'oul" rea't to "ynami'ally ?ou 'annot reBuest 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 reBuest 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& reBuiring the permissions the &eature nee"s to operate.
166
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
CHAPTER /:
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 NgeotagN 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 eBui!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 NhotspotsN 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.
18+
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
!ccessing #ocation%Base
Services
5he ne;t step to &in" out =here you are is to get the name o& the )ocation(rovider you =ant to use. +ere, you ha!e t=o main options, 1. Ask the user to pi'k a pro!i"er
18(
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
!ccessing #ocation%Base
Services
2. *in" the best-mat'h pro!i"er base" on a set o& 'riteria 1& you =ant the user to pi'k a pro!i"er, 'alling get(rovidersLM 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 obHe't, stating the parti'ulars o& =hat you =ant out o& a )ocation(rovider, su'h as,
setAltitude?eUuiredLM
not
setAccuracFLM
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+ostAlloDedLM
8i!en a &ille"-in +riteria obHe't, 'all get4est(roviderLM on your )ocation#anager, an" An"roi" =ill si&t through the 'riteria an" gi!e you the best ans=er. -ote 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., E(2 (?"VI=$?), perhaps Hust &or testing purposes. >n'e you kno= the name o& the )ocation(rovider, you 'an 'all get)astHnoDn(ositionLM 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)astHnoDn(ositionLM =ill return null, in"i'ating that there is no kno=n position. >n the other han", get)astHnoDn(ositionLM 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 obHe'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. 1& the parti'ular lo'ation pro!i"er o&&ers other "ata, you 'an get at that as =ell,
18.
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
!ccessing #ocation%Base
Services
*or altitu"e, hasAltitudeLM =ill tell you i& there is an altitu"e !alue, an" getAltitudeLM =ill return the altitu"e in meters. *or bearing (i.e., 'ompass-style "ire'tion), has4earingLM =ill tell you i& there is a bearing a!ailable, an" get4earingLM =ill return it as "egrees east o& true north. *or spee", has2peedLM =ill tell you i& the spee" is kno=n an" get2peedLM =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
-ot all lo'ation pro!i"ers are ne'essarily imme"iately responsi!e. 8#%, &or e;ample, reBuires 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%oDLM 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)ocation3pdatesLM 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+hange6neD LocationListenerLM : public void onLocationChangedL)ocation locationM : if Lstate.DeatherX6nullM :
18'
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
!ccessing #ocation%Base
Services
state.Deather.get"orecastLlocation8 stateMJ ; else : )og.wLgetClassLM.get&ameLM8 73nable to fetch forecast [ no @eather4inder7MJ ; ; public void on)ro!iderDisa'ledL2tring providerM : // reUuired for interface8 not used ; public void on)ro!ider+na'ledL2tring providerM : // reUuired for interface8 not used ; public void onStatusChangedL2tring provider8 int status8 4undle eGtrasM : // reUuired for interface8 not used ;
;J
2ear 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 remove3pdatesLM =ith the )ocation)istener you registere". 1& 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)ocation3pdatesLM 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 (get4roadcastL)) 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.
181
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
!ccessing #ocation%Base
Services
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(roGimitFAlertLM. 5he (endingIntent to be raise" =hen the "e!i'e is =ithin the Ntarget LoneN e;presse" by the position an" ra"ius
-ote 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 Lone "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 Lone, or go by so Bui'kly that the "e!i'e7s lo'ation isn7t sample" =hile in the target Lone. 1t 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'. -ote that you =ill re'ei!e the Intent =hene!er the position is sample" an" you are =ithin the target Lone S not Hust upon entering the Lone. +en'e, you
183
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
!ccessing #ocation%Base
Services
=ill get the Intent se!eral times, perhaps Buite a &e= times "epen"ing on the siLe o& the target Lone an" the spee" o& the "e!i'e7s mo!ement.
Testing222Testing222
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". 1t 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.
186
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
CHAPTER 0<
>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 piLLa parlor to "ire'tions &rom -e= ?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 #apVieD an" #apActivitF, =hi'h allo= you to integrate maps into your o=n appli'ations. -ot only 'an you "isplay maps, 'ontrol the Loom 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" proHe'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".
,ap!ctivity
1& 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. 1nstea", they are part o& the 8oogle A#1s 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 proHe'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. 2y 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 proHe't =ith an appropriate target to ensure the 8oogle Maps A#1s =ill be a!ailable 5o test your 8oogle Maps integration, you =ill also nee" an A.@ that uses an appropriate target
1:;
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
,ap!ctivity
5hat7s be'ause the A#1 key in the sour'e 'o"e is in!ali" &or your "e!elopment ma'hine. 1nstea", you =ill nee" to generate your o=n A#1 key(s) &or use =ith your appli'ation. 5his also hol"s true &or any mapenable" proHe'ts you 'reate on your o=n &rom s'rat'h. *ull instru'tions &or generating A#1 keys, &or "e!elopment an" pro"u'tion use, 'an be &oun" on the An"roi" Web site. 1n the interest o& bre!ity, let7s &o'us on the narro= 'ase o& getting %oo5aDk running in your emulator. @oing this reBuires the &ollo=ing steps, 1. 2. .isit the A#1 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#1 key signup page, paste in that M@A signature an" submit the &orm A. >n the resulting page, 'opy the A#1 key an" paste it as the !alue o& apiHeF in your #apVieD-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#1 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
1:+
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
,ap!ctivity
>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 NuserO 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. ->5E, Ca!a 0 has a "i&&erent !ersion o& keFtool, one that generates an %+A hash by "e&ault. $se the -v s=it'h to ha!e the Ca!a 0 keFtool emit the M@A hash as =ell. -ote that the An"roi" "e!elopment tools "o not o&&i'ially support Ca!a 0 as o& the time o& this =riting.
1:(
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
,ap!ctivity
android:clickable 6 7true7 ,
pan through your map *or e;ample, &rom the #aps/%oo5aDk sample appli'ation, here is the main layout,
NPGml version671.-7 encoding67utf-,7PO N?elative)aFout Gmlns:android67http://schemas.android.com/apk/res/android7 android:laFout Didth67fill parent7 android:laFout height67fill parent7O Ncom.google.android.maps.#apVieD android:id67QRid/map7 android:laFout Didth67fill parent7 android:laFout height67fill parent7 android:apiHeF67-mjl0"ufr5-t!s0@9urt)/rs5F$#pd$U4+bFj]g7 android:clickable67true7 /O N/?elative)aFoutO
1n 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) 1nsi"e
NapplicationO, a Nuses-librarFO element android:name 6 7com.google.android.maps7, to in"i'ate you are
your
=ith using
1:.
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
,ap!ctivity
5hat is pretty mu'h all you nee" &or starters, plus to sub'lass your a'ti!ity &rom #apActivitF. 1& you =ere to "o nothing else, an" built that proHe't an" tosse" it in the emulator, you7" get a ni'e map o& the =orl". -ote, ho=e!er, that #apActivitF is abstra't S you nee" to implement is?oute=isplaFedLM to in"i'ate i& you are supplying some sort o& "ri!ing "ire'tions or not. %in'e "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=isplaFedLM return false.
+ption l % ps
-ot 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. 1& it is, the Nuses-librarFO element sho=n abo!e is the right ans=er, as that =ill reBuire any "e!i'e running your app to ha!e 8oogle Maps. 1&, ho=e!er, you =ant 8oogle Maps to be optional, there is an un"o'umente" android:reUuired attribute a!ailable on Nuses-librarFO. %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%ameL7com.google.android.maps.#apVieD7M to see i& 8oogle Maps is a!ailable to you. 1& 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.
1:'
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
,ap!ctivity
Joom
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 Loom le!el "ire'tly !ia the setVoomLM metho" on the #ap+ontroller. 5his takes an integer representing the le!el o& Loom, =here 1 is the =orl" !ie= an" 21 is the tightest Loom you 'an get. Ea'h le!el is a "oubling o& the e&&e'ti!e resolution, 1 has the eBuator measuring 2A4 pi;els =i"e, =hile 21 has the eBuator measuring 248,</A,<A4 pi;els =i"e. %in'e the phone7s "isplay probably "oes not ha!e 248,</A,<A4 pi;els in either "imension, the user sees a small map &o'use" on one tiny 'orner o& the globe. A le!el o& 10 =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. 1& users to 'hange the Loom le!el, 'all an" the user =ill be able to Loom in an" out o& the map !ia Loom 'ontrols &oun" in the bottom 'enter o& the map.
set4uiltInVoom+ontrolsLtrueMJ,
you
=ish
to
allo=
Center
5ypi'ally, you =ill nee" to 'ontrol =hat the map is sho=ing, beyon" the Loom 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+enterLM on the #ap+ontroller.
1:1
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
,ap!ctivity
5his takes a Eeo(oint as a parameter. A Eeo(oint represents a lo'ation, !ia latitu"e an" longitu"e. 5he 'at'h is that the Eeo(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 Eeo(oint into a map position. +o=e!er, it "oes mean you ha!e to remember to multiply the Nreal =orl"N latitu"e an" longitu"e by 1$0.
+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, Hust 'all get"verlaFsLM on your #apVieD an" addLM your "verlaF instan'e to it, as =e "o here =ith a 'ustom 2ites"verlaF,
marker.setBoundsL-8 -8 marker.getIntrinsic#idthLM8 marker.getIntrinsic(eightLMMJ map.getO!erlaysLM.addLneD SitesO!erlayLmarkerMMJ
1:3
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
,ap!ctivity
*irst, o!erri"e ItemiKed"verlaFN"verlaFItemO as your o=n sub'lass (in this e;ample, 2ites"verlaF) 1n the 'onstru'tor, buil" your roster o& "verlaFItem instan'es, an" 'all populateLM =hen they are rea"y &or use by the o!erlay 1mplement siKeLM to return the number o& items to be han"le" by the o!erlay >!erri"e createItemLM to return "verlaFItem instan'es gi!en an in"e; When you instantiate your ItemiKed"verlaF sub'lass, pro!i"e it =ith a =raDable that represents the "e&ault i'on (e.g., push-pin) to "isplay &or ea'h item, on =hi'h you 'all bound+enter4ottomLM to enable the "rop-sha"o= e&&e't
5he marker &rom the %oo5aDk 'onstru'tor is the =raDable use" &or the last bullet abo!e S it sho=s a push-pin. *or e;ample, here is 2ites"verlaF,
'oundCenterBottomLmarkerMJ items.addLneD O!erlayItemLget)ointL<-./<,*0C,</C10-C<8 -/C.*0,-/1*C/.01-<M8 73%78 73nited %ations7MMJ items.addLneD O!erlayItemLget)ointL<-./0,00>***/<C,/8 -/C.*,>0,<01>>/<1/M8 7)incoln +enter78 7!ome of JaKK at )incoln +enter7MMJ items.addLneD O!erlayItemLget)ointL<-./0.1C0<C.C10/..8 -/C.*/*,*.11<,*,0,M8 7+arnegie !all78
1:6
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
,ap!ctivity
7@here Fou go Dith practice8 practice8 practice7MMJ items.addLneD O!erlayItemLget)ointL<-./-0,0<1/<*1/**8 -/<.-1./>*<>/CC/0.M8 7&he =oDntoDn +lub78 7"riginal home of the !eisman &rophF7MMJ populateLMJ ; Q"verride protected "verlaFItem createItemLint iM : returnLitems.getLiMMJ ; Q"verride protected boolean onTapLint iM : &oast.makeTextL%oo5aDk.this8 items.getLiM.getSnippetLM8 &oast.)$%E&! 2!"?&M.showLMJ returnLtrueMJ ; Q"verride public int si.eLM : returnLitems.si.eLMMJ ; ; ;
H ndlin! Screen T ps
An "verlaF sub'lass 'an also implement on&apLM, to be noti&ie" =hen the user taps on the map, so the o!erlay 'an a"Hust =hat it "ra=s. *or e;ample, in &ull-siLe 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&apLM, you 'an "o mu'h the same in An"roi". 5he on&apLM metho" &or ItemiKed"verlaF "verlaFItem that =as 'li'ke". 1t is up to you =ith this e!ent. 1n the 'ase o& 2ites"verlaF, as sho=n abo!e, on&apLM looks like this,
Q"verride
1:8
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
,ap!ctivity
+ere, =e Hust toss up a short &oast =ith the NsnippetN &rom the "verlaFItem, returning true to in"i'ate =e han"le" the tap.
,y@ ,yself@ an
,y#ocation-verlay
An"roi" has a built-in o!erlay to han"le t=o 'ommon s'enarios, 1. %ho=ing =here you are on the map, base" on 8#% or other lo'ationpro!i"ing logi'
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 #apVieD7s list o& o!erlays, an" enable an" "isable the "esire" &eatures at appropriate times. 5he Nat appropriate timesN notion is &or ma;imiLing 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?esumeLM an" "isable them in on(auseLM. *or e;ample, %oo5aDk =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,
super.on%esumeLMJ
(=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,
1::
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
,ap!ctivity
t*o -verlay"tems
4ugge
Terrain
Cust as the 8oogle Maps you use on your &ull-siLe 'omputer 'an "isplay satellite imagery, so too 'an An"roi" maps.
3;;
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
,ap!ctivity
#apVieD
o&&ers toggle2atelliteLM, =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& %oo5aDk, !ia keypresses,
else if LkeF+ode 66 HeF$vent.H$5+"=$ VM : map.display0oomControlsLtrueMJ returnLtrueMJ ; ; returnLsuper.on1eyDownLkeF+ode8 eventMMJ
%o, &or e;ample, here is %oo5aDk sho=ing a satellite !ie=, 'ourtesy o& pressing the 2 key,
$igure +3(2 The ?oo/a*k map@ sho*ing a compass rose an overlai on the satellite vie*
t*o -verlay"tems@
3;+
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
,ap!ctivity
,aps an
$ragments
?ou might think that maps =oul" be an i"eal pla'e to use &ragments. A&ter all, on a large tablet s'reen, =e 'oul" allo'ate most o& the spa'e to the map but then ha!e other stu&& alongsi"e. Alas, as o& the time o& this =riting, maps an" &ragments are t=o great tastes that "o not taste so great together. *irst, #apVieD reBuires you to inherit &rom #apActivitF. 5his has a &e= rami&i'ations,
?ou 'annot use the An"roi" %upport pa'kage, be'ause that reBuires 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, #apVieD 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. 1t is entirely possible that some"ay these problems =ill be resol!e", through a 'ombination o& an up"ate" 8oogle A#1s A""->n &or An"roi" =ith &ragment support, an" possibly an up"ate" An"roi" %upport pa'kage. 1n the meantime, here is the re'ipe &or getting maps to =ork, as =ell as they 'an, in &ragments.
3;(
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
,ap!ctivity
an"
ne=er.
*or
is
the
mani&est
&rom
the
NPGml version671.-7 encoding67utf-,7PO Nmanifest package67com.commonsDare.android.mapfrags7 Gmlns:android67http://schemas.android.com/apk/res/android7O Nuses-permission android:name67android.permission.I%&$?%$&7 /O Nuses-permission android:name67android.permission.A++$22 9I%$ )"+A&I"%7 /O Napplication android:hardDareAccelerated67true7 android:icon67QdraDable/cD7 android:label67Qstring/app name7O Nuses-librarF android:name67com.google.android.maps7 /O NactivitF android:label67Qstring/app name7 android:name67.%oo5aDk7O Nintent-filterO Naction android:name67android.intent.action.#AI%7 /O NcategorF android:name67android.intent.categorF.)A3%+!$?7 /O N/intent-filterO N/activitFO N/applicationO Nuses-sdk android:min2dkVersion67117 android:target2dkVersion67117 /O Nsupports-screens android:anF=ensitF67true7 android:large2creens67true7 android:normal2creens67true7 android:small2creens67true7 /O N/manifestO
,ap!ctivity
5hen, in onActivitF+reatedLM S on'e on+reateLM has been 'omplete" in the hosting #apActivitF S you 'an a"" a #apVieD to that 'ontainer an" 'ontinue =ith the rest o& your normal setup,
map6neD MapViewLget$cti!ityLM8 7-mjl0"ufr5-t!s0@9urt)/rs5F$#pd$U4+bFj]g7MJ map.setClicka'leLtrueMJ map.getControllerLM.setCenterLget)ointL<-./0/*C10***>-<<8 -/C.*,1,-<,<//1/>*MMJ map.getControllerLM.set0oomL1/MJ map.setBuiltIn0oomControlsLtrueMJ =raDable marker6get%esourcesLM.getDrawa'leL?.draDable.markerMJ marker.setBoundsL-8 -8 marker.getIntrinsic#idthLM8 marker.getIntrinsic(eightLMMJ map.getO!erlaysLM.addLneD SitesO!erlayLmarkerMMJ me6neD MyLocationO!erlayLget$cti!ityLM8 mapMJ map.getO!erlaysLM.addLmeMJ LLVieDEroupMgetViewLMM.addViewLmapMJ ; Q"verride public void on%esumeLM : super.on%esumeLMJ
-ote that =e are 'reating a #apVieD in Ca!a 'o"e, =hi'h means our Maps A#1 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 #apVieD here i& you =ishe" S the 'hange &or #ap9ragment =as simply to illustrate 'reating a #apVieD &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 %oo5aDk a'ti!ity no longer has mu'h to "o =ith mapping, it must still be a #apActivitF,
3;'
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
,ap!ctivity
package com.commonsDare.android.mapfragsJ import android.os.4undleJ import com.google.android.maps.#apActivitFJ public class %oo5aDk eGtends #apActivitF : Q"verride public void onCreateL4undle savedInstance2tateM : super.onCreateLsavedInstance2tateMJ setContentViewL?.laFout.mainMJ ; Q"verride protected boolean is%outeDisplayedLM : returnLfalseMJ ;
5he resulting appli'ation looks like the original %oo5aDk 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),
3;1
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
,ap!ctivity
on a ,otorola F--,
3;3
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
CHAPTER 01
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 toI
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 Nsyn'N 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 Hust like any other pie'e o& the An"roi" system.
3;6
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+all2tateLM, =ith return !alues o& +A)) 2&A&$ I=)$ (phone not in use), +A)) 2&A&$ ?I%EI%E ('all reBueste" but still being 'onne'te"), an" +A)) 2&A&$ "99!""H ('all in progress) *in" out the %1M 1@ (1M%1) !ia get2ubscriberIdLM *in" out the phone type (e.g., 8%M) !ia get(hone&FpeLM or &in" out the "ata 'onne'tion type (e.g., 8# %, E@8E) !ia get%etDork&FpeLM
3;8
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
N$dit&eGt android:id67QRid/number7 android:laFout Didth67fill parent7 android:laFout height67Drap content7 android:cursorVisible67true7 android:editable67true7 android:single)ine67true7 /O N/)inear)aFoutO N4utton android:id67QRid/dial7 android:laFout Didth67fill parent7 android:laFout height67Drap content7 android:laFout Deight6717 android:teGt67=ial ItX7 android:on+lick67dial7 /O N/)inear)aFoutO
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.commonsDare.android.dialerJ import import import import import import android.app.ActivitFJ android.content.IntentJ android.net.3riJ android.os.4undleJ android.vieD.VieDJ android.Didget.$dit&eGtJ
public class =ialer=emo eGtends ActivitF : Q"verride public void onCreateL4undle icicleM : super.onCreateLicicleMJ setContentViewL?.laFout.mainMJ ; public void dialLVieD vM : $dit&eGt number6L$dit&eGtMfindViewByIdL?.id.numberMJ 2tring to=ial67tel:7Rnumber.getTextLM.toStringLMJ start$cti!ityLneD IntentLIntent.A+&I"% =IA)8 3ri.parseLto=ialMMMJ ; ;
3;:
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
+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,
from 0ialer0emo
3+;
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
3++
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
CHAPTER 0&
$onts
1ne!itably, you[ll get the Buestion 6hey, 'an =e 'hange this &ontI9 =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. 1t '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.
3+.
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
$onts
N&eGtVieD android:teGt67sans:7 android:laFout margin?ight67<dip7 android:teGt2iKe67>-sp7 /O N&eGtVieD android:id67QRid/sans7 android:teGt67!ello8 DorldX7 android:tFpeface67sans7 android:teGt2iKe67>-sp7 /O N/&able?oDO N&able?oDO N&eGtVieD android:teGt67serif:7 android:laFout margin?ight67<dip7 android:teGt2iKe67>-sp7 /O N&eGtVieD android:id67QRid/serif7 android:teGt67!ello8 DorldX7 android:tFpeface67serif7 android:teGt2iKe67>-sp7 /O N/&able?oDO N&able?oDO N&eGtVieD android:teGt67monospace:7 android:laFout margin?ight67<dip7 android:teGt2iKe67>-sp7 /O N&eGtVieD android:id67QRid/monospace7 android:teGt67!ello8 DorldX7 android:tFpeface67monospace7 android:teGt2iKe67>-sp7 /O N/&able?oDO N&able?oDO N&eGtVieD android:teGt67+ustom:7 android:laFout margin?ight67<dip7 android:teGt2iKe67>-sp7 /O N&eGtVieD android:id67QRid/custom7 android:teGt67!ello8 DorldX7 android:teGt2iKe67>-sp7 /O N/&able?oDO N&able?oD android:id67QRid/fileroD7O N&eGtVieD android:teGt67+ustom from 9ile:7 android:laFout margin?ight67<dip7
3+'
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
$onts
5his layout buil"s a table sho=ing short samples o& &i!e &onts. -oti'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'ialiLe" purposes, su'h as a 6"ingbats9 &ont instea" o& a series o& #-8 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 proHe't root, an" put your 5rue5ype (55*) &onts in the assets. ?ou might, &or e;ample, 'reate assets/fontsQ 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. 1nstea", you nee" to make the 'hange in Ca!a 'o"e,
import android.Didget.&eGtVieDJ import java.io.9ileJ public class 9ont2ampler eGtends ActivitF : Q"verride public void onCreateL4undle icicleM : super.onCreateLicicleMJ setContentViewL?.laFout.mainMJ &eGtVieD tv6L&eGtVieDMfindViewByIdL?.id.customMJ &Fpeface face6&Fpeface.create"rom$ssetLget$ssetsLM8 7fonts/!andmade&FpeDriter.ttf7MJ tv.setTypefaceLfaceMJ
3+1
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
$onts
9ile font6neD "ileL$nvironment.get+xternalStorageDirectoryLM8 7#g"pen+osmetica4old.ttf7MJ if Lfont.existsLMM : tv6L&eGtVieDMfindViewByIdL?.id.fileMJ face6&Fpeface.create"rom"ileLfontMJ tv.setTypefaceLfaceMJ ; else : findViewByIdL?.id.fileroDM.setVisi'ilityLVieD.E"%$MJ ;
; ;
+ere =e grab the &eGtVieD &or our 6'ustom9 sample, then 'reate a &Fpeface obHe't !ia the stati' create9romAssetLM buil"er metho". 5his takes the appli'ation[s Asset#anager (&rom getAssetsLM) an" a path =ithin your assets/ "ire'tory to the &ont you =ant. 5hen, it is Hust a matter o& telling the &eGtVieD to set&FpefaceLM, pro!i"ing the &Fpeface you Hust 'reate". 1n 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 'ustomiLe 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. 2ut Hust as you 'an get a &Fpeface !ia create9romAssetLM, you 'an get a &Fpeface !ia create9rom9ileLM. 1n our 9ont2ampler, =e look in the root o& Ne;ternal storageN (typi'ally the %@ 'ar") &or the Mg>penCosmeti'a2ol" 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 resultsI
3+3
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
$onts
We =ill go into more "etails regar"ing assets an" lo'al &iles in an up'oming 'hapter. -ote 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) Buietly. %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 Buestion 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 &eGtVieD 'lass has the built-in ability to NellipsiLeN 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 NellipsiLingN &eature =ill nee" the ellipsis glyph. 2eyon" 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 NellipsiLingN. 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 7RE > W1@5+ ->-2 EAD %#ACE7 ( 3R9$99). 5his means the Ne;traN '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 &eGtVieD =i"gets that you use =ith android:ellipsiKe must also support this spe'ial $ni'o"e 'hara'ter. -ot 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.
3+8
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
CHAPTER 0/
5he An"roi" %@D is more than a library o& Ca!a 'lasses an" A#1 'alls. 1t 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 Bui'k tour o& =hat else is a!ailable to you.
3+:
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.commonsDare.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=,
3(;
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
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 $1 =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,
3(+
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
-o=, 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 #-8 &ile %a!e the $1 as a #hotoshop #%@ &ile, =ith "i&&erent layers &or the "i&&erent =i"gets an" 'ontainers *or'e the $1 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
3((
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
2a'k on the main s'reen, instea" o& 'li'king Loa" .ie= +ierar'hy, you 'oul" ha!e 'li'ke" 1nspe'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 VieDs in your a'ti!ity. 1n the mi""le, you see a Loome" !ie= o& your a'ti!ity, sho=n at normal siLe on the right. 5he 'rosshairs o!erlaying the a'ti!ity sho= the position being Loome" upon Z Hust 'li'k on a ne= area to 'hange =here =hat you are seeing. 5here is a sli"er to 'ontrol the le!el o& Loom. Cli'king on a pi;el also in"i'ates the position an" 'olor o& that pi;el. 1& you toggle the Auto e&resh 'he'kbo; in the toolbar, the .ie=er =ill poll an" reloa" the $1 &rom your a'ti!ity perio"i'ally, =ith the &reBuen'y 'ontrolle" by another sli"er.
3(.
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
3('
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
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,
3(1
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
)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. 1n 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
3(3
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.
3(6
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
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 toQ&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 N+trlO-N2O or 'hoose DeviceG $creen capture... &rom the main menu. 5his =ill bring up a "ialog bo; 'ontaining an image o& the 'urrent s'reen,
3(8
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
*rom here, you 'an 'li'k H$aveI to sa!e the image as a #-8 &ile some=here on your "e!elopment ma'hine, H/efreshI to up"ate the image base" on the 'urrent state o& the emulator or "e!i'e, or HDoneI to 'lose the "ialog.
3(:
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
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.
3.;
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
>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 reHe't it (!ia the re" phone button),
3.+
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
incoming call
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,
3.(
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
text message
An", o& 'ourse, you 'an 'li'k on the noti&i'ation to !ie= the message in the &ull-&le"ge" Messaging appli'ation,
3..
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
%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 N%ysin&oN tab, you 'an see a pie 'hart o& the o!erall memory allo'ation &or the emulator,
>n the NAllo'ation 5ra'kerN 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",
3.'
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
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 obHe'ts are still on the heap an" =ho is 'ausing them to sti'k aroun". 2e&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.
3.1
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
1.
2ehin" the s'enes, it ser!es as a bri"ge bet=een your emulatorsQ"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. 1t o&&ers 'omman"-line eBui!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'ogniLe" 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) 1nstall 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)
3.3
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
CHAPTER 00
?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 Hust 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 Ns=eet spotN =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. 1t 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".
3.:
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
222!n
"t Was -9
-o mobile "e!elopment en!ironment is per&e't, an" so the 'ombination o& Ca!a an" An"roi" has its issues. 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 Nmemory leaksN 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'.
3';
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
Most importantly, though, not e!erybo"y likes Ca!a. 1t '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 enHoy 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 N'oolN. 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.
3'+
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
*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, N&rien"lyN an" N&ully supporte"N 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 CQC\\ "e!elopment !ia the -ati!e @e!elopment Dit (-@D) an" Web-style "e!elopment !ia +5MLA. %ome alternati!es to Ca!a-base" "e!elopment are supporte" by 'ompanies. A"obe supports A1 , -itobi 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 Hust tiny proHe'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 reBuirements. *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 0eveloper
>& 'ourse, going outsi"e the tra"itional Ca!a en!ironment &or An"roi" "e!elopment has its issues, beyon" Hust ho= mu'h support might be a!ailable. %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. CQC\\, 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.
3'(
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
%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 Bui'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. 1n some 'ases, that is not a problem, but in other 'ases, that might be ba" &or your proHe't. +en'e, Hust 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.
3'.
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
CHAPTER 05
HT,#1
#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'hniBues 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. -otably, An"roi" supports o&&line appli'ations an" Web storage, meaning that +5MLA be'omes a rele!ant te'hniBue &or 'reating An"roi" appli'ations, =ithout "ealing =ith Ca!a.
-ffline !pplications
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 reBuire 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.
3'1
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
HT,#1
+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 N'a'he mani&estN, "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 Hust 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 N&allba'kN 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". 1& the user loses 'onne'ti!ity, the appli'ation =ill still run. 1n this respe't, the Web app beha!es almost i"enti'ally to a regular app.
3'3
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
HT,#1
?ou 'an enter some te;t in the top &iel" an" 'li'k the A"" button to a"" it to the list,
3'6
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
HT,#1
?ou 'an N'he'k o&&N in"i!i"ual items, =hi'h are then "isplaye" in strikethrough,
3'8
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
HT,#1
as complete
?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,
3':
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
HT,#1
elete confirmation
ialog
31;
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
HT,#1
NX="+&5($ htmlO Nhtml lang67en7 manifest67checklist.manifest7O NheadO Nmeta http-eUuiv67+ontent-&Fpe7 content67teGt/htmlJ charset6utf-,7 /O NtitleO+hecklistN/titleO Nmeta name67vieDport7 content67Didth6device-DidthJ initial-scale61.-J maGimum-scale61.-J userscalable6-J7 /O Nmeta name67apple-mobile-Deb-app-capable7 content67Fes7 /O Nmeta name67apple-mobile-Deb-app-status-bar-stFle7 /O Nlink rel67apple-touch-startup-image7 href67splashscreen.png7 /O Nlink rel67stFlesheet7 href67stFles.css7 /O Nlink rel67apple-touch-icon-precomposed7 href67apple-touch-icon-precomposed.png7 /O N/headO NbodFO NsectionO NheaderO Nbutton tFpe67button7 id67sendmail7O#ailN/buttonO Nh1O+hecklistN/h1O N/headerO NarticleO Nform id67inputarea7 onsubmit67add%eDItemLM7O Ninput tFpe67teGt7 name67name7 id67name7 maGlength67/.7 autocorrect placeholder67&ap to enter a neD itemZhellipJ7 /O Nbutton tFpe67button7 id67add7OAddN/buttonO N/formO Nul id67maillist7O Nli class67emptF7ONa href677 id67maillink7O#ail remaining itemsN/aON/liO N/ulO Np id67totals7ONspan id67tallF17O&otal: Nspan id67total7O-N/spanON/spanO Nspan id67tallF>7O?emaining: Nspan id67remaining7O-N/spanON/spanON/pO Nul id67checklist7O Nli class67emptF7O)oadingZhellipJN/liO N/ulO N/articleO NfieldsetO Nbutton tFpe67button7 id67deletechecked7O=elete +heckedN/buttonO Nbutton tFpe67button7 id67deleteall7O=elete AllN/buttonO N/fieldsetO N/sectionO Nscript src67main.js7ON/scriptO N/bodFO N/htmlO
*or the purposes o& o&&line appli'ations, though, the key is the manifest attribute o& our html element,
Nhtml lang67en7 manifest67checklist.manifest7O
31+
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
HT,#1
+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. 1t 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". 1t 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. 1n prin'iple, the mani&est shoul" reBuest 'a'hing &or e!erything that the appli'ation nee"s to run, though the page that reBueste" 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. 1n an o&&line situation, the appli'ation =oul" not be able to use ACAF te'hniBues 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&.
31(
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
HT,#1
8oogle 8ears an" relate" tools pioneere" this 'on'ept an" blaLe" the trail &or =hat is no= !ariously 'alle" NWeb %torageN or N@>M %torageN &or +5MLA appli'ations. An +5MLA app 'an store "ata persistently on the 'lient, =ithin 'lient-impose" limits. 5hat, in 'onHun'tion =ith o&&line asset 'a'hing, means an +5MLA appli'ation 'an "eli!er &ar more !alue =hen it la'ks an 1nternet 'onne'tion, or &or "ata that Hust "oes not make sense to store Nin the 'lou"N. -ote 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 Nlumpe" in =ithN +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 obHe't, representing your appli'ation7s "ata. More a''urately, ea'h NoriginN (i.e., "omain) =ill ha!e a "istin't local2torage obHe't on the bro=ser. 5he local2torage obHe't is an Nasso'iati!e arrayN, 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 lengthLM 8et an" set items by key !ia getItemLM an" setItemLM 8et the key &or a numeri'al in"e; !ia keFLM emo!e in"i!i"ual entries !ia removeItemLM or remo!e all items !ia
clearLM
5his means you "o not ha!e the &ull ri'hness o& a %KL "atabase, like you might ha!e =ith %KLite in a nati!e An"roi" appli'ation. 2ut, &or many appli'ations, this shoul" su&&i'e.
31.
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
HT,#1
+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 Li 6 -J i N6 listlengthJ iRRM : var item 6 local2torage.keyLiMJ mFArraF.pushLitemMJ ; /*sort the arraF into alphabetical order.*/ mFArraF.sortLMJ
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 Ltarget.previous2ibling.checkedM : data 6 -J ; else : data 6 1J ; /*save item in local2torage.*/ trF : local2torage.setItemLname8 dataMJ ; catch LeM : if Le 66 Y3"&A $]+$$=$= $??M : alertLIYuota eGceededXIMJ
31'
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
HT,#1
; ;
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.*/ Dhile Li N6 local2torage.length-1M : var keF 6 local2torage.keyLiMJ if Llocal2torage.getItemLkeFM 666 I1IM : local2torage.remo!eItemLkeFMJ ; else : iRRJ ;
;8
,e= SH) D t = se
An"roi"7s built-in bro=ser also supports a NWeb %KL @atabaseN option, one =here you 'an use %KLite-style "atabases &rom Ca!as'ript. 5his a""s a lot more po=er than basi' Web %torage, albeit at a 'omple;ity 'ost. 1t 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.
311
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
HT,#1
?ou might 'onsi"er e!aluating La=n'hair, =hi'h is a Ca!as'ript A#1 that allo=s you to store arbitrary C%>--en'o"e" obHe'ts. 1t =ill use =hate!er storage options are a!ailable, an" there&ore =ill help you "eal =ith 'rossplat&orm !ariety. 1n parti'ular, it supports the 8oogle 8ears &a'ility &oun" in some ol"er !ersions o& An"roi".
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 K$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
313
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
HT,#1
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 1nternet. 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.
316
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
HT,#1
As you 'an see, it is &ormatte" like a typi'al mo"ern user-agent string, meaning it is Buite a mess. 1t "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 NWeb =orkersN may alle!iate this some=hat some"ay) 1ntera't =ith 2luetooth "e!i'es
318
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
HT,#1
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 N+5MLA #lusN &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.
31:
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
HT,#1
)oo$ nd 4eel
+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 $1 &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, Hust 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. 1t is 'on'ei!able that, some"ay, the An"roi" Market =ill support +5MLA appli'ations. 1t 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
33;
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
HT,#1
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 N"is'o!erableN than their nati!e eBui!alents.
HT,#1 an
!lternative !n roi
Bro*sers
While the built-in An"roi" bro=ser =ill be the 'hoi'e o& many An"roi" users, there are other bro=sers a!ailable. +ere is ho= some o& the betterkno=n alternati!es stan" in terms o& +5MLA support.
4ire1o. %o=ile
*ire&o; Mobile is presently in beta &orm. 1t 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. 1t also "oes not support o&&line 'a'hing at this time.
HT,#1
1t is &airly likely that, o!er time, +5MLA =ill be the G2 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.
33(
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
CHAPTER 07
PhoneGap
#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 A"obe, =ho in 2011 a'Buire" -itobi, the &irm &oun"e" by #hone8ap7s 'reators.
33.
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
PhoneGap
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= Bui'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., HB5ou'h !ersus plain HKuery) =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 (%KLite) 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#1s. Also, this list 'hanges o!er time, so you may ha!e a''ess to more than =hat is "es'ribe" here.
33'
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
PhoneGap
PhoneGap
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. -ot all #hone8ap Ca!a%'ript A#1s 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#1s, la'k o& engineering time to hoist the 'apability into the #hone8ap A#1s). 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.
Ho# Is It )icensedF
#hone8ap is a!ailable un"er the Apa'he %o&t=are Li'ense 2.0. 1n 2011, -itobi 'ontribute" #hone8ap to the Apa'he %o&t=are *oun"ation (A%*) &or in"epen"ent management, Hust prior to being a'Buire" by A"obe. 5he e;pe'tation is that the A%* =ill e!entually promote #hone8ap out o& the
333
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
PhoneGap
Nin'ubatorN to be a &ull-&le"ge" Apa'he proHe't, possibly using the proHe't name o& Callba'k.
=sing PhoneGap
-o=, let7s look at more o& the me'hani's &or using #hone8ap. #hone8ap7s installation an" usage, as o& the time o& this =riting, normally reBuires an e;pert in Ca!a-base" An"roi" "e!elopment. ?ou nee" to install a =hole bun'h o& tools, e"it 'on&iguration &iles by han", an" so &orth. 1& you =ant to "o all o& that, "o'umentation is a!ailable on the #hone8ap site. 1& 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 #hone8apQ2uil" ser!i'e.
Inst ll tion
5he #hone8ap Web site =ill allo= you to "o=nloa" the latest #hone8ap tools as a R1# 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 proHe't.
PhoneGap
"ire'tory o& your proHe't. 1& you are using E'lipse, you =ill also nee" to a"" it to your buil" path. 2. Create an assets/DDD/ "ire'tory in your proHe't. 5hen, 'opy o!er the #hone8ap C% &ile &rom the Android/ "ire'tory o& =here!er you unR1#pe" the #hone8ap R1# &ile. /. A"Hust the stan"ar" N+ello, Worl"N a'ti!ity to inherit &rom =roidEap instea" o& ActivitF. 5his =ill reBuire you to import com.phonegap.=roidEap. <. 1n your a'ti!ity7s on+reateLM metho", repla'e set+ontentVieDLM =ith
super.load3rlL7file:///android asset/DDD/indeG.html7MJ
A. 1n your mani&est, a"" all o& the permissions that #hone8ap reBuests, liste" later in this 'hapter. 4. Also in your mani&est, a"" a suitable Nsupports-screensO element base" upon =hat s'reen siLes you are =illing to test an" support. 0. Also in your mani&est, a"" android:config+hanges67orientationW keFboard!idden7 to your NactivitFO element, as =roidEap han"les orientation-relate" 'on&iguration 'hanges At this point, you 'an 'reate an assets/DDD/indeG.html &ile in your proHe'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., Nscript tFpe67teGt/javascript7 charset67utf-,7 src67phonegap.-.*.<.js7 /O). 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 debug 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 pIBuild
#hone8apQ2uil" is a 5ools-as-a-%er!i'e (5aa%) hoste" approa'h to 'reating #hone8ap proHe'ts. 5his =ay, all o& the An"roi" buil" pro'ess is han"le"
338
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
PhoneGap
&or you by #hone8ap-supplie" ser!ers. ?ou Hust &o'us on 'reating your +5ML, C%%, an" Ca!as'ript as you see &it. When you log into #hone8apQ2uil", you are &irst prompte" to 'reate your initial proHe't, by supplying a name an" the Web assets to go into the app,
?ou =ill be able to a"" ne= proHe'ts later on !ia a -e= App button, =hi'h gi!es you the same set o& options. ?our 'hoi'es &or the assets are to uploa" a R1# &ile 'ontaining all o& them, or to spe'i&y the $ L to a publi' 8it+ub repository that #hone8apQ2uil" '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 proHe't is open sour'e (an" there&ore has a publi' repository).
33:
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
PhoneGap
>n'e you 'li'k the $ploa" button, the #hone8apQ2uil" ser!er =ill imme"iately start buil"ing your appli'ation &or An"roi", plus 2la'kberry, %ymbian, an" Web>%,
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 proHe't, an" you get K 'o"es to enable "o=nloa"s straight to your test "e!i'e,
36;
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
PhoneGap
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,
36+
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
PhoneGap
All in all, i& you "o not other=ise nee" the An"roi" %@D an" relate" tools on your "e!elopment ma'hine, #hone8apQ2uil" 'ertainly simpli&ies the #hone8ap buil"ing pro'ess. #hone8apQ2uil" is &ree &or open sour'e (publi') proHe'ts, but there are &ees asso'iate" =ith pri!ate use beyon" a single app, starting at ^12 per month.
PhoneGap an
5he beauty o& #hone8ap is that it =raps aroun" +5ML, C%%, an" Ca!as'ript. 1n other =or"s, you "o not ha!e to "o mu'h o& anything #hone8ap-spe'i&i' to be able to take a"!antage o& #hone8ap "eli!ering to
36(
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
PhoneGap
you an A#D suitable &or installation on an An"roi" "e!i'e. 5hat being sai", #hone8ap "oes e;pose more stu&& to you than you 'an get &rom the stan"ar"s, i& you nee" them an" are =illing to use proprietary #hone8ap A#1s &or them.
2. Copy the +5ML, C%%, Ca!as'ript, an" images &rom the +5MLA proHe't into the assets/DDD/ "ire'tory o& the #hone8ap proHe't (note that you "o not nee" things uniBue 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 load3rlLM '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. 2uil" an" install the proHe't +ere is the =roidEap a'ti!ity &or our app, &rom the (honeEap/+hecklist proHe't,
package com.commonsDare.pg.checklistJ import android.app.ActivitFJ import android.os.4undleJ import com.phonegap.=roidEapJ public class +hecklist eGtends =roidEap : Q"verride public void onCreateL4undle savedInstance2tateM : super.onCreateLsavedInstance2tateMJ super.load*rlL7file:///android asset/DDD/indeG.html7MJ
36.
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
PhoneGap
; ;
+ere is the mani&est, =ith all o& the #hone8ap-reBueste" settings a""e",
NPGml version671.-7 encoding67utf-,7PO Nmanifest android:version+ode6717 android:version%ame671.-7 package67com.commonsDare.pg.checklist7 Gmlns:android67http://schemas.android.com/apk/res/android7O Napplication android:icon67QdraDable/cD7 android:label67Qstring/app name7O NactivitF android:config+hanges67orientationWkeFboard!idden7 android:label67Qstring/app name7 android:name67+hecklist7O Nintent-filterO Naction android:name67android.intent.action.#AI%7 /O NcategorF android:name67android.intent.categorF.)A3%+!$?7 /O N/intent-filterO N/activitFO N/applicationO Nsupports-screens android:anF=ensitF67true7 android:large2creens67true7 android:normal2creens67true7 android:resiKeable67true7 android:small2creens67true7 /O Nuses-permission android:name67android.permission.+A#$?A7 /O Nuses-permission android:name67android.permission.VI4?A&$7 /O Nuses-permission android:name67android.permission.A++$22 +"A?2$ )"+A&I"%7 /O Nuses-permission android:name67android.permission.A++$22 9I%$ )"+A&I"%7 /O Nuses-permission android:name67android.permission.A++$22 )"+A&I"% $]&?A +"##A%=27 /O Nuses-permission android:name67android.permission.?$A= (!"%$ 2&A&$7 /O Nuses-permission android:name67android.permission.I%&$?%$&7 /O Nuses-permission android:name67android.permission.?$+$IV$ 2#27 /O Nuses-permission android:name67android.permission.?$+"?= A3=I"7 /O Nuses-permission android:name67android.permission.#"=I95 A3=I" 2$&&I%E27 /O Nuses-permission android:name67android.permission.?$A= +"%&A+&27 /O Nuses-permission android:name67android.permission.@?I&$ +"%&A+&27 /O Nuses-permission android:name67android.permission.@?I&$ $]&$?%A) 2&"?AE$7 /O Nuses-permission android:name67android.permission.A++$22 %$&@"?H 2&A&$7 /O N/manifestO
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,
NX="+&5($ htmlO Nhtml lang67en7 manifest67checklist.manifest7O
36'
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
PhoneGap
NheadO Nmeta http-eUuiv67+ontent-&Fpe7 content67teGt/htmlJ charset6utf-,7 /O NtitleO+hecklistN/titleO Nmeta name67vieDport7 content67Didth6device-DidthJ initial-scale61.-J maGimum-scale61.-J userscalable6-J7 /O Nlink rel67stFlesheet7 href67stFles.css7 /O Nscript tFpe67teGt/javascript7 charset67utf-,7 src67phonegap.-.*.<.js7ON/scriptO N/headO NbodFO NsectionO NheaderO Nbutton tFpe67button7 id67sendmail7O#ailN/buttonO Nh1O+hecklistN/h1O N/headerO NarticleO Nform id67inputarea7 onsubmit67add%eDItemLM7O Ninput tFpe67teGt7 name67name7 id67name7 maGlength67/.7 autocorrect placeholder67&ap to enter a neD itemZhellipJ7 /O Nbutton tFpe67button7 id67add7OAddN/buttonO N/formO Nul id67maillist7O Nli class67emptF7ONa href677 id67maillink7O#ail remaining itemsN/aON/liO N/ulO Np id67totals7ONspan id67tallF17O&otal: Nspan id67total7O-N/spanON/spanO Nspan id67tallF>7O?emaining: Nspan id67remaining7O-N/spanON/spanON/pO Nul id67checklist7O Nli class67emptF7O)oadingZhellipJN/liO N/ulO N/articleO NfieldsetO Nbutton tFpe67button7 id67deletechecked7O=elete +heckedN/buttonO Nbutton tFpe67button7 id67deleteall7O=elete AllN/buttonO N/fieldsetO N/sectionO Nscript src67main.js7ON/scriptO N/bodFO N/htmlO
*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.
361
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
PhoneGap
2. 1n on)oadLM, use add$vent)istenerLM to register another global Ca!as'ript &un'tion (e.g., on=evice?eadFLM) &or the devicereadF e!ent /. 1n on=evice?eadFLM, start using the #hone8ap A#1s
ives 6ou
#hone8ap makes a number o& metho"s a!ailable to you through a series o& !irtual Ca!as'ript obHe'ts. +ere, N!irtualN means that you 'annot 'he'k to see i& the obHe'ts e;ist, but you 'an 'all metho"s an" rea" properties on them. %o, &or e;ample, there is a device obHe't that has a han"&ul o& use&ul properties, su'h as phonegap to return the #hone8ap !ersion an" version to return the >% !ersion. 5hese !irtual obHe'ts are rea"y &or use in or a&ter the devicereadF e!ent. *or here is a Ca!as'ript &ile (props.js &rom the (honeEap/+hecklist$G proHe't) that implements an on)oadLM &un'tion (to register &or devicereadF) an" an on=evice?eadFLM &un'tion (to use the device obHe't7s properties), e;ample,
363
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
PhoneGap
// (honeEapIs A(Is are not immediatelF readF8 so set up an // event handler to find out Dhen theF are readF function onLoadLM : document.add+!entListenerL7devicereadF78 on=evice?eadF8 falseMJ ; // %oD (honeEapIs A(Is are readF function onDe!ice%eadyLM : var element6document.get+lementByIdLIpropsIMJ element.inner!&#)6INliO#odel: IRdevice.nameRIN/liOI R INliO"2 and Version: IRdevice.platform RI IRdevice.versionRIN/liOI R INliO(honeEap Version: IRdevice.phonegapRIN/liOIJ ;
5he on=evice?eadFLM &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 reBuire some minor mo"i&i'ations to our +5ML,
NX="+&5($ htmlO Nhtml lang67en7 manifest67checklist.manifest7O NheadO Nmeta http-eUuiv67+ontent-&Fpe7 content67teGt/htmlJ charset6utf-,7 /O NtitleO+hecklistN/titleO Nmeta name67vieDport7 content67Didth6device-DidthJ initial-scale61.-J maGimum-scale61.-J userscalable6-J7 /O Nlink rel67stFlesheet7 href67stFles.css7 /O Nscript tFpe67teGt/javascript7 charset67utf-,7 src67phonegap.-.*.<.js7ON/scriptO Nscript tFpe67teGt/javascript7 charset67utf-,7 src67props.js7ON/scriptO N/headO NbodF onload67on)oadLM7O NsectionO NheaderO Nbutton tFpe67button7 id67sendmail7O#ailN/buttonO Nh1O+hecklistN/h1O N/headerO NarticleO Nform id67inputarea7 onsubmit67add%eDItemLM7O Ninput tFpe67teGt7 name67name7 id67name7 maGlength67/.7 autocorrect placeholder67&ap to enter a neD itemZhellipJ7 /O Nbutton tFpe67button7 id67add7OAddN/buttonO N/formO Nul id67maillist7O Nli class67emptF7ONa href677 id67maillink7O#ail remaining itemsN/aON/liO N/ulO Np id67totals7ONspan id67tallF17O&otal: Nspan id67total7O-N/spanON/spanO Nspan id67tallF>7O?emaining: Nspan id67remaining7O-N/spanON/spanON/pO
366
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
PhoneGap
Nul id67checklist7O Nli class67emptF7O)oadingZhellipJN/liO N/ulO N/articleO NfieldsetO Nbutton tFpe67button7 id67deletechecked7O=elete +heckedN/buttonO Nbutton tFpe67button7 id67deleteall7O=elete AllN/buttonO N/fieldsetO NfooterO Nh>O=evice (ropertiesN/h>O Nul id67props7ON/ulO N/footerO N/sectionO Nscript src67main.js7ON/scriptO N/bodFO N/htmlO
evice properties
>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
368
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
PhoneGap
mostly in =hat #hone8ap7s !irtual Ca!as'ript obHe'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 reBuest a''ess to 'ertain system &eatures, su'h as making 1nternet reBuests or rea"ing the user7s 'onta'ts. Appli'ations must reBuest these permissions at install time, so the user 'an ele't to aban"on the installation i& the reBueste" permissions seem suspe't. A general rule o& thumb is that you shoul" reBuest as &e= permissions as possible, an" make sure that you 'an Husti&y =hy you are reBuesting the remaining permissions. #hone8ap, &or a ne= proHe't, reBuests Buite 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" #"=I95 A3=I" 2$&&I%E2 ?$A= +"%&A+&2
36:
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
PhoneGap
Lea!ing this roster inta't =ill gi!e you an appli'ation that 'an use e!ery A#1 #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 Husti&y, all o& these permissions. 1t 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 proHe'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 proHe't may ha!e tools to help gui"e you in the 'hoi'e o& permissions, perhaps by stati'ally analyLing your Ca!as'ript 'o"e to see =hi'h #hone8ap A#1s you are using. 1n the meantime, though, getting the proper set o& permissions =ill in!ol!e a lot o& trial an" error.
38;
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
PhoneGap
%martphones, on the other han", ha!e se!eral "i&&erent "ensities, 'ausing the 'onne'tion bet=een resolution an" siLe to be broken. %ome lo=-en" phones, parti'ularly =ith small (e.g., /N) 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" Nretina "isplaysN as =ell. +en'e, an 800;<80 resolution 'oul" be on a s'reen ranging any=here &rom <N to 0N, &or e;ample. 5ablets a"" e!en more possible siLes 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 N&inger-&rien"lyN. 5his 'auses some problems =ith s'aling o& assets, parti'ularly images. What might be N&inger-&rien"lyN on a lo=-"ensity /N "e!i'e might be entirely too small &or a high-"ensity <N "e!i'e. -ati!e An"roi" appli'ations ha!e built-in logi' &or "ealing =ith this issue, in the &orm o& multiple sets o& Nresour'esN (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 4eel
A Web app ne!er Buite 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. 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.
38+
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
PhoneGap
38(
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
CHAPTER 08
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. -ote 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.
4ho es
%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-esBue &rame=ork. ?our uby 'o"e generates +5ML an" su'h to be Nser!e"N to an a'ti!ity !ia a @ebVieD =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 proHe't on your "e!elopment ma'hine or use their hoste" buil" pro'ess. 5he latter is re'ommen"e", partly be'ause the reBuirements &or lo'al buil"s are higher than those &or #hone8ap S notably, ho"es reBuires the -ati!e @e!elopment Dit (-@D) &or buil"ing an" linking the uby interpreter to your appli'ation.
38.
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.AM2). +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.
$lash@ $lex@ an
!"4
A"obe has been har" at =ork e;ten"ing their *lash, *le;, an" A1 te'hnologies to the mobile spa'e. ?ou 'an use *le; (the N+eroN e"ition) an" *lash 2uil"er (the N2urritoN e"ition... begging the Buestion o& =hether the NheroN is hungry) to 'reate An"roi" A#D &iles that 'an be "istribute" on the An"roi" Market an" "eploye" to An"roi" "e!i'es. 5hose "e!i'es =ill nee" to ha!e the A1 runtime installe" S this is &ree, but a large "o=nloa", an" it only =orks on An"roi" 2.2 "e!i'es. 5he same proHe'ts 'an be repa'kage" &or i>% an" the 2la'kberry #laybook tablet, an" possibly &uture "e!i'es "o=n the roa". A1 "oes not ha!e Buite as tight o& integration to the plat&orm as "oes #hone8ap (e.g., no a''ess to the "e!i'e7s 'onta'ts), though one imagines that this is an area on =hi'h A"obe =ill "e!ote more resour'es o!er time. An", A"obe is a large &irm, =ith a large e'osystem behin" it an" many e;isting *lash, *le;, an" A1 "e!eloper resour'es to tap into. -ote, though, that A"obe is o&&i'ially "is'ontinuing the *lash plug-in &or An"roi" a&ter the An"roi" <.0 (1'e Cream %an"=i'h) release, =hi'h 'asts some "oubt as to their long-term plans in the *lashQA1 spa'e on mobile.
74uby an
4uboto
>ne o& the most popular languages "esigne" to run on the C.M S besi"es Ca!a itsel& S is C uby. C uby =as Bui'kly porte" to run on An"roi", but =ith some optimiLations "isable", sin'e C uby is really running on the @al!ik !irtual ma'hine that un"erlies the An"roi" en!ironment, not a 'lassi' Ca!a .M.
38'
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
+o=e!er, C uby alone 'annot 'reate An"roi" appli'ations. As a s'ripting language, there is no =ay &or it to "e&ine an a'ti!ity or other 'omponent S those nee" to be registere" in the appli'ation7s mani&est as regular Ca!a 'lass &iles. 5his is =here uboto 'omes in. uboto is a &rame=ork &or a generi' C ubyQAn"roi" appli'ation. 1t 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+reateLM), 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.
!pp "nventor
App 1n!entor is an An"roi" appli'ation "e!elopment tool originally ma"e a!ailable by 8oogle, but outsi"e o& the normal An"roi" "e!eloper site. App
381
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
1n!entor =as originally "e!elope" &or use in e"u'ation, but they ha!e been in!iting others into their 'lose" beta. App 1n!entor is theoreti'ally a Web-base" "e!elopment tool. +ere, Ntheoreti'allyN 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 (.Hnlp) appli'ations @o=nloa" an" install a large (_AAM2) 'lient-si"e set o& tools +a!e a phone an" ha!e it 'on&igure" to =ork =ith App 1n!entor an" the An"roi" %@D
>n'e set up, App 1n!entor gi!es you a "rag-an"-"rop 8$1 e"itor,
...an" a Nblo'ksN e"itor, =here you atta'h beha!iors to e!ents (e.g., button 'li'ks) by snapping together !arious Nblo'ksN representing e!ents, metho"s, an" properties,
383
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
While =orking in the 8$1 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 1n!entor is not really set up &or pro"u'tion appli'ation use to"ay,
?ou 'annot "istribute App 1n!entor apps on the An"roi" Market 1t has more 'omponents aime" at NsiLLleN (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 proHe't
1n 2011, 8oogle "is'ontinue" "ire't support &or App 1n!entor, ele'ting to trans&er the proHe't to M157s Me"ia Lab &or ongoing "e!elopment.
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
386
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
lets you "e'lare user inter&a'e =i"gets. 1ts 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 $1, but it still reBuires 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 2la'kberry support in a pri!ate beta.
#anguages
1& your issue is less =ith regular An"roi" "e!elopment, but you Hust "o not like Ca!a, any language that 'an generate 'ompatible C.M byte'o"e shoul" =ork =ith An"roi". ?ou =oul" ha!e to mo"i&y the buil" 'hain &or that other language to "o the rest o& the An"roi" buil" pro'ess (e.g., generate ?.java &rom the resour'es, 'reate the A#D &ile in the en"). %'ala an" CloHure are t=o su'h languages, &or =hi'h their respe'ti!e 'ommunities ha!e put together instru'tions &or using their languages &or An"roi" "e!elopment.
388
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
CHAPTER 09
An"roi" is N&ree as in beerN &or "e!i'e manu&a'turers, as it is an open sour'e proHe'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, siLes, 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 siLe 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. 1n a""ition to using the target 1@ system to in"i'ate =hat le!el o& "e!i'e your proHe't is targeting, you 'an use a ne= Android#anifest.Gml element to spe'i&y har"=are that is reBuire" &or your appli'ation to run properly. ?ou 'an a"" one or more Nuses-configurationO elements insi"e the NmanifestO element. Ea'h Nuses-configurationO 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 reBuirements 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 reBuire" (e.g, android:reU!ardHeFboard 6 7true7) android:reUHeFboard&Fpe, android:reU!ardHeFboard,
keyboar"
probably use" in 'onHun'tion =ith to in"i'ate a spe'i&i' type o& har"=are keyboar" that is reBuire" (e.g, android:reUHeFboard&Fpe 6 7UDertF7)
android:reU&ouch2creen to in"i'ate =hat type o& tou'hs'reen reBuire", i& any (e.g, android:reU&ouch2creen 6 7finger7)
is
%tarting in An"roi" 1.4, there is a similar mani&est element, Nuses-featureO, =hi'h is "esigne" to "o'ument reBuirements 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 Nuses-featureO element,
android:gl$sVersion in"i'ates that your appli'ation reBuires >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.hardDare.camera7
appli'ation
nee"s
'amera,
=hile
3:(
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
Ea'h An"roi" release a""s more an" more &eatures you 'an reBuire. 5hese reBuests =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 Nuses-featureO element has an android:reUuired attribute that you 'an spe'i&y. 2y "e&ault, it is set to true, meaning you absolutely nee" this &eature. 1& 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 has2Fstem9eatureLM 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.hardDare.telephonF. 2ut, i& you reBuest permissions like +A)) (!"%$, the An"roi" Market by "e&ault =ill assume you need
3:.
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
android.hardDare.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 Nuses-featureO element to your mani&est =ith android:reUuired67false7,
Nuses-feature android:name67android.hardDare.telephonF7 android:reUuired67false7 /O
5hen, be&ore you try pla'ing a phone 'all or sen"ing an %M% or something, use (ackage#anager an" get2FstemAvailable9eaturesLM to &in" out i& android.hardDare.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%. -o=, i& your appli'ation absolutely nee"s telephony, then the implie" Nuses-featureO =ill =ork, though you may =ish to 'onsi"er putting one in e;pli'itly. +o=e!er, Hust bear in min" that this means your app =ill not =ork on the F>>M or other tablets that la'k telephony.
! Guarantee
,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. 1t might =ork &ine &or stan"ar" appli'ations shippe" on the "e!i'e but "o a poor Hob 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"
3:'
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
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 K.8A s'reen, be&ore the release o& An"roi" 1.4 =here K.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 Nseal o& appro!alN 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#%I Cell to=er pro;imityI 8alileoI) What 'amera &eatures are a!ailable (&lashI auto-&o'usI sepia toneI) What sensors are a!ailable (a''elerometerI gyros'opeI barometerI)
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.
3:1
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
0evice Testing
1"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" N"e!i'e labsN at !arious e!ents, su'h as Motorola hel" at An@e!Con 1 in 2011 %ome 'arriers ha!e perpetual "e!i'e labs, su'h as >range7s N"e!eloper 'entresN
3:3
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
?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 .arious ser!i'es ha!e appeare" that o&&er a =ay &or you to uploa" an app &or automate" testing a'ross a &leet o& "e!i'es, su'h as apku"o, Less#ain&ul, an" 5est@roi"
3:6
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
CHAPTER 0:
>b!iously, this book "oes not 'o!er e!erything. An" =hile your G1 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 Nan"roi"N 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 reBuire 'onsi"erable a"Hustment to =ork properly in 'urrent %@Ds. 2eyon" 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 Buestions an" ans=ers an"roi"-"is'uss, "esigne" &or &ree-&orm "is'ussion o& anything An"roi"-relate", not ne'essarily &or programming Buestions an" ans=ers
3::
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 1 C 'hannel on &reeno"e (ir'.&reeno"e.net) 5he An"roi" boar" on Ca!a an'h
1t is important, parti'ularly &or %ta'k>!er&lo= an" the 8oogle 8roups, to =rite =ell-=ritten Buestions,
1n'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 J synta; (e.g., JCommonsWare), to ma;imiLe the o""s you =ill get a reply >n the 8oogle 8roups, "o not NpingN 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)
6;;
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
5he sour'e 'o"e an" relate" resour'es http,QQsour'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
6;+
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
9ey*or
"n ex
Class...............................................
AbsoluteLayout.......................................20<, /<2 A'tionE!ent.......................................................4A A'tionListener...................................................4A A'ti!ity..../8, 03, 1/4, 142, 18A, 2//, 2/<, 2<0, 2AA, 201, 20/, 282, 28<, 28A, 23<, 23A, /0<, /<0, /30, </A, <<3, <A0, <48, <04, A2<, AA2, AA<, A4<, A32, 448 A"apter.......................................1/A, 1A4, 1A8, <43 A"apter.ie=............................................1A8, <8/ A"apter.ie=.A"apterConte;tMenu1n&o.......224 A""%trings5ask...............................................280 A""%tring5ask.................................200, 208, 280 Alert@ialog........................22<, 2/<-2/4, /8/, /80 AnalogClo'k.............................................180, 130 an"roi".te;t.%panne"....................................../12 An"roi"+ttpClient..................................A04, A13 Appli'ation......................................................A23 ArrayA"apter. .1/A, 1/0-1/3, 1<4, 1A0-140, 14A, 140, 148, 100, 101, 22/, 22A, 224, 200, 203, /84, </<, <8< ArrayList...................................22/, </<, A</, A<A
AssetManager..................................................414 Asyn'5ask..20/-203, 281, 282, 284, <<1, <</, <<0, <8A, A</, A<8 AutoComplete5e;t.ie=..............8/, 1<8-1A0, 20A 2asi' esponse+an"ler...................................A/4 2in"er.......................................A28, A23, A<2, A<A 2o;.....................................................................3/ 2o;Layout..........................................................3/ 2roa"'ast e'ei!er............23<, 23A, A/0, A/1, A8A 2uil"................................................................434 2uil"er..............................................2/<, 2/A, <<2 2un"le 2<1, 2</, 2<4, 2A/, 2AA, 231, /00, /33, <12, <48 2utton. 43, 01-0<, 08-80, 30, 33, 10<, 10A, 112, 11/, 13A, 134, 138, 133, 201, 2/4, 2</, /1/, /1<, ///, //<, /</, /3/, <14, <21 2yteArray esponse+an"ler...........................A/4 Calen"ar...........................................................108 Che'k2o;..........................................8/, 84-88, 31 Che'k2o;#re&eren'e.......................................<A2 Che'ke"5e;t.ie=...........................................20< Chronometer............................................181, 20<
6;.
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
9ey*or
Class..................................................................<21 Color%tateList..............................................31, 32 Compoun"2utton.............................................88 Con&iguration..........................................2A8, /<0 Constants2ro=ser...................................<08, <8< Conta'ts.#eople...............................................<22 Conta'tsContra't.............................................<21 Conta'tsContra't.Conta'ts............................<22 ContentManager.............................................AA4 Content.alues.................................................<80 Conte;t.....1/A, 2/<, 282, </A, <<0, <<3, <A0, <04, A03, A23, A</ Conte;tMenu...........................................220, 2/0 Conte;tMenu.Conte;tMenu1n&o....................220 Countries*ragment................../33, <0<, <04-<10 Country.....................................................<02, <11 CountryA"apter......................................<00, <0/ CountryListener........................................<08-<11 CountryWrapper.............................................<00 Criteria.....................................................A8/, 43A Cursor...............................<<2, <82, <8/, <8A, A12 CursorA"apter.........................................<8/, <8< CW2ro=ser....................................................../0A @atabase+elper......................................<04, <03 @ate#i'ker........................................................10A @ate#i'ker@ialog......................................10A, 108 @ate$tils..........................................................108 @e&ault+ttpClient....................A01, A04, A/4, A<8 @etailsA'ti!ity...................................<04, <11, <12 @etails*ragment..../38, /33, <0<, <04, <00, <10<12
"n ex
@ialog*ragment..............................................<0< @ialog#re&eren'e............................................<43 @igitalClo'k.....................................................180 @isplayMetri's................................................/<8 @o'ument........................................................</< @ouble.............................................................233 @o=nloa"@emo...............................................A10 @o=nloa"er......................................A/<, A/0, A<0 @o=nloa"Manager............................A00-A12, A13 @o=nloa"Manager.Kuery...............................A11 @o=nloa"Manager. eBuest.....................A10, A11 @ra=able.....................1A/, 184, 2A/, /14, AA0, A30 @ra=er@emo...................................................20< @roi"8ap.................................................448, 40/ @ynami'@emo..........................................140, 141 E"it#re&eren'es.......................................<A2, <00 E"it#re&eren'es+C..................................<00, <01 E"it5e;t81, 110, 121, 122, 12<, 120-123, 1/1, 1<8, 1<3, 10A, 2</, 2<0, /23, /8<-/84, /3/, <2A E"it5e;t#re&eren'e..........................................<41 En!ironment.....................................<<0, <<1, A10 E$<?ou.............................../A2, /A<, /44, <04-<11 E;'eption..........................................<21, A<8, 410 E;pan"ableList.ie=.......................................20< *ake#layer........................................A<1, A4<, A4A *an'yListsQ.ie=+ol"er...................................144 *et'h*ore'ast5ask...........................................A<8 *iel"@emo.........................................................121 *ile.....................................................</3, <<0, A11 *ile>utput%tream...........................................<<0 *lo=Layout........................................................3<
6;'
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
9ey*or
*ont%ampler.....................................................414 *ore'ast.....................................A0<, A</-A<A, A<8 *ragment................../3A, /30-<00, <0<, <0A, 40/ *ragmentA'ti!ity...................../88, <0A, <1/, 402 *ragmentManager............................<0A, <00, <11 *ragment5ransa'tion....................../3A, <0A, <00 *rameLayout......................18<, 18A, 13A, 201, 40/ 8allery.........................................1//, 1/<, 1A2, 20< 8eo#oint..........................................................A34 8ra"ient@ra=able.........................................../<< 8ri".ie=..............................1/<, 1<<-1<4, 1<8, 1A2 +an"ler.......2<2, 248, 243, 201-20/, 281, 284, A/1, A/2, A/8 +an">&Car"sLayout......................................./</
"n ex
1n&lation@emo................................................../81 1nputMetho"Manager..............................1/1, /80 1nput%tream......................</1, </<, </A, A0<, A20 1nput%tream ea"er.........................................</A 1nteger...............................................................101 1ntent......<, 18/, 212, 21/, 2<8, 2<3, 231, 23/, 23A, 233, /0/-/0A, <12, <21, <43, A13, A20, A28, A/0, A/1, A/4-A/8, A<0, A<2, AA0, A84, A80, 408, 411 1ntent%er!i'e.............A2<, A/<, A/4, A/0, A/3, A<0 1nterpreter.......................................................<32 1temiLe">!erlay..............................A34-A38, 40/ C2utton.........................................................4A, 44 CChe'k2o;.........................................................1/A CCombo2o;.......................................................1<1 CLabel................................................................1/A
+elpA'ti!ity....................................................233 CList...................................................................1/< +oney'omb+elper..................................<2A, <24 C5abbe"#ane....................................................18< +oriLontal%'roll.ie=.......................120, 183, 130 C5able................................................................1/< +ttpClient.........................A01, A02, A0A, A04, A13 Layout1n&later............................141, 142, 130, <00 +ttpConte;t....................................................A04 +ttp8et.....................................A01, A02, A/4, A<8 +ttp#ost...........................................................A01 +ttp eBuest.....................................................A01 +ttp esponse...................................................A01 +ttp$rlConne'tion.........................................A13 +ttp$ LConne'tion...............<33, A00, A13, A20 1'oni'A"apter...........................................1A8, 1A3 1mage2utton.................................03, 80, /14, /A1 1mage%=it'her.................................................20A 1mage.ie= 03, 80, 1A3, 142, 14A, 140, 148, 201, /14 1ME@emo1........................................................123 1ME@emo2.......................................................123 LinearLayout3/-30, 33, 100, 102, 10<, 10A, 111, 11A, 1A4, 142, 101, 18A, 201, 2A0, 2A8, //A, /84, /3/, <08 List.............................................................221, A8/ ListA'ti!ity..1/4-1/8, 18A, 22A, 204, /A2, /33, <0A, <1/, A32 ListA"apter......................................14<, 20<, /33 ListCell en"erer..............................................1/A List*ragment..................../3A, /33, <02, <0A, <21 List#re&eren'e..................................................<41 List.ie=.. .120, 1/1, 1/<, 1/4, 1/8-1<2, 1<8, 1A2, 1AA1A8, 140, 14/, 14<, 140, 148, 13<, 221, 22/, 224, /A1/A/, /3<, /33, <02, <8/, <8<, A01, A32 Lo'ation....................A02, A</, A<A, A<3, A8/, A8< Lo'ationListener.....................................A8<, A8A
6;1
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
9ey*or
Lo'ationManager.....................A82-A8<, A84, 43A Lo'ation#ro!i"er.............................A82-A8<, 423 Map..........................................................<<3, <80 MapA'ti!ity.....................A83, A32, A3<, 402-40< MapController.................................................A3A Map*ragment..........................................40/, 40< Map.ie=. .A00, A83, A31, A32, A3A, A34, A33, 40140A Me"ia#layer.....................................................A<0 Menu..........................................218, 213, 228-2/0 Menu1n&later............................................223, 2/0 Menu1tem..........218-220, 22<, 224, 228, 223, /8A Message......................248, 243, 201, 202, A/2, A/0 Messenger..........................A/1, A/2, A/<, A/0, A/8 MultiAutoComplete5e;t.ie=........................20A MyLo'ation>!erlay................................A3/, A33 -oo?a=k..........A3/, A34, A30, A33, 401, 40<, 40A -otAll5hat%tri't.....................................<<A, <<4 -oti&i'ation.......2<0, AA4-AA8, A40, A4/-A44, A43 -oti&i'ationManager........................AA4, A41, A4< -oti&y@emo.....................................................AA8
"n ex
>n1tem%ele'te"Listener...........................1<1, 1</ >n5imeChange"Listener................................104 >n5ime%etListener..................................104, 108 >utput%tream.................................................</A >utput%treamWriter......................................</A >!erlay....................................................A34, A38 >!erlay1tem.............................................A30-A33 #a'kageManager.....................................43/, 43< #ar'elable.........................................................A/1 #en"ing1ntent...A/1, AA0, A40, A40, A43, A8A, A84 #layer%er!i'e.............................A/3-A<1, A4<, A4A #layingCar"Layout........................................../</ #re&eren'e................................................<A2, <43 #re&eren'eA'ti!ity. .<0A, <A0, <A1, <AA, <A8, <4<<40, <00, <01 #re&eren'eCategory.................................<A0, <A8 #re&eren'e*ragment.......................<0A, <44-<48 #re&eren'eManager.........................................<A0 #re&eren'e%'reen....<A2, <A0, <A8, <4<, <4A, <43 #rogress2ar10A, 240, 243, 201, 202, 20A, 204, 203, 281, 28A, 280, //1, //4-//8, A1< #rogress@ialog................................................240
-oti&yMessage.................................................A40 Kui'kConta't2a"ge........................................20A -o=..............................................................0/, 0< a"io2utton..............88, 83, 31, 3/, 100, 102, <02 -o= e"u;.........................................................0/ a"io8roup.....................88, 83, 3/, 100, 102, 10/ >bHe't...............................................................2A/ an"omA''ess*ile..........................................<<0 >nChe'ke"ChangeListener..........8/, 8<, 80, 102 atingA"apter..................................................100 >nCli'kListener..................................4A, 44, 2/4 ating2ar............................................148, 101, 18/ >n@ateChange"Listener................................104 elati!eLayout.3/, 104-112, 114, 201, /<2, /</, /3/ >n@ate%etListener...................................104, 108 emote>bHe'tE;'eption.................................A/0 >nE"itorA'tionListener................./84, /80, <2A esour'es........................................../18, </1, <48 >n1temCli'kListener...............................1<0, 1<8
6;3
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
9ey*or
esponse+an"ler............................................A/4 ingtone#re&eren'e........................................<A2 otationAsyn'.................................282, 28<, 28A otationA=are5ask.........................282, 28<, 28A o=Mo"el..................................................100, 101 unnable...................................248, 202-20<, 204 %'roll.ie=..............................3/, 110-120, 123, 1/0 %e'urityE;'eption............................................A0/ %eek2ar.............................................................182 %ensorManager................................................<0/ %er!i'e..............................A2<, A2A, A/3, A<0, A4< %er!i'eConne'tion...................A28, A23, A<<, AA2 %hare"#re&eren'es....................<<4, <A0, <A1, <41 %impleCursorA"apter.....................................<8/ %imple#re&s@emo....................................<A/, <AA %ites>!erlay.............................................A34-A38 %li"ing@ra=er..........................................200-20< %o&t e&eren'e...................................................A/0 %panne"............................................................/12 %pinner...1/<, 1<1-1</, 1<8, 1A2, 1A8, /0A, /80, /34, 440, 44A %KLite@atabase...............................<04, <08-<80 %KLite@atabase.Cursor*a'tory......................<8A %KLite>pen+elper.................................<04, <08 %KLiteKuery2uil"er........................................<81 %ta'k>!er&lo=E;'eption.................................<14 %tate..........................................................AA2-AA< %tati'................................................................./18 %tati'@emo.......................................................1A3 %to'k#re&eren'e*ragment......................<40-<43 %tri't*or ealL..........................................<<A, <<4
"n ex
%tri'tMo"e........................................<<2-<<A, A13 %tri'tWrapper..........................................<<<-<<4 %tring...100, 22/, 2/<, 2/A, 208, /00, /12, /1<, <<3, <48, A01, A/4, AA2, AA/ %=it'h..............................................................20A %ystem.%ettings.............................................../<< 5abA'ti!ity................................18A, 184, /0/, /0A 5ab+ost...............18<-180, /0A, /04, /A1, /A2, /34 5ab+ost.5abContent*a'tory...................188, 130 5ab+ost.5ab%pe'.............................................130 5ableLayout.............3/, 11/-114, 12<, 123, /3<, <AA 5able o=.....................................................11/-11A 5ab%pe'..............................................184, 180, 130 5ab.ie=....................................................138, /0< 5abWi"get............18<, 18A, 188-130, 13A, 138, /0A 5elephonyManager.........................................408 5e;t%=it'her....................................................20A 5e;t.ie=.02, 00-03, 81, 8/, 88, 31, 32, 34, 33, 110, 128, 1/A, 1A0, 1A3, 142, 14A, 148, 101, 108, 131, 132, 134, 130, 20<, 210, 24A, 281, /23, /8<, 414, 418 5e;tWat'her.............................................1<3, 1A0 5hrea".............................................................244 5ime#i'ker................................................10A, 104 5ime#i'ker@ialog..............................10A, 104, 108 5oast. .2//, 2/<, 2/4, 203, 280, /82, <3<, A02, A1A, A14, A13, A/8, A33 5oggle2utton...............................................84, 80 5ype&a'e...........................................................414 $ri......2<8, 2<3, 2A1, 2AA, 230, 231, 23/, 230, 233, /01, /0<, <21, <22, A11, AA4, 408 .eri&yError................................<20, <21, <2<, <<A .ie=.43, 0/, 03, 30, 11A, 113, 1</, 1AA, 1A8-14/, 14A, 144, 101, 188, 130, 13<, 220, 224, 220, 2/<, 20/, /0<, /30, /38, <2/, <2A, <8<, 42/
6;6
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
9ey*or
.ie=.>nCli'kListener......................................03 .ie=Animator.................................................134 .ie=*lipper........................13A, 134, 138-200, 20A .ie=8roup....................................................../3< .ie=+ol"er........................................144, 140, 101 .ie=+ol"er@emo............................................144 .ie=%=it'her...................................................20A .oi"..........................................................208-280 Weak e&eren'e................................................A/0 Weather2in"er........................A<<, A<A, A<8, A<3 Weather@emo.........................A0/, A<8, A<3, AA< WeatherListener..............................A<<, A<A, A<8 Weather%er!i'e.......................................A<<, A<8 WebDit......................................................A01, A02 Web%ettings.....................................................21< Web.ie=...200-21<, /0<, /4<, /44, /3<, /3A, /38, <0A-<00, A00, A<3, AA/, A02, 48/ Web.ie=Client.........................................212, 21/ Web.ie=*ragment.........................................<0A Fml#ull#arser.........................................../18, /20
"n ex
an"roi"....................................................10, 1<, A/ an"roi" 'reate proHe't................../0, /8, 232, /1< an"roi" list targets............................................/0 an"roi" up"ate proHe't -p ..........................;;!iii ant................................................................/8, <0 ant -!ersion...................................................1/, 1< ant 'lean "ebug install.............................44, 448 ant Har'ore........................................................<31 ""ms................................................................42< hierar'hy!ie=er........................................<14, 413 Harsigner............................................................A31 keytool......................................................A31, A32 p"&tk `.p"& 'at output 'ombine".p"&............;;i! sBlite/..............................................................<84 su"o ser!i'e u"e! reloa"..................................2< Lipalign..............................................................<0
Constant.........................................
ACCE%%]C>A %E]L>CA51>-.....................A82 ACCE%%]*1-E]L>CA51>-............................A82 AC51>-]E@15................................................230 AC51>-]#1CD........................................230, /00 AC51>-].1EW......................................230, 233 AL5E -A51.E.................................................231 @E*A$L5..........................................................231 @ELE5E....................................................<80, <81 E-@]@>C$ME-5........................................../18 E-@]5A8........................................................./18 8E5...................................................................A01 +> 1R>-5AL..................................................3<
Command......................................
a"b............................................................4/A, 4/4 a"b "e!i'es................................................2/, 4/4 a"b install........................................................4/4 a"b kill-ser!er.................................................4/4 a"b log'at.........................................A10, 424, 4/4 a"b pull............................................<84, 420, 4/4 a"b push..........................................<80, 420, 4/4 a"b shell..........................................<84, 428, 4/4 a"b start-ser!er...............................................4/4
6;8
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
9ey*or
1-%E 5.............................................<0A, <80, <81 1-5E8E .........................................................<0A LA 8E ............................................................21A LA$-C+E ..............................................231, 23/ LE-85+]L>-8..............................................2/< LE-85+]%+> 5...........................................2/< MA1-...............................................................23/ -$LL...............................................................<80 #E M1%%1>-]@E-1E@..................................A0A #E M1%%1>-]8 A-5E@...............................A0A #>%5.................................................................A01 ......................................................................... 0/ E%$L5]CA-CELE@....................................../00 E%$L5]*1 %5]$%E ..................................../00 E%$L5]>D..................................................../00 %ELEC5.....................................................<0A, <81 %MALLE%5........................................................21A %5A 5]5A8............................................../18, /20 5EF5................................................................./18 $#@A5E...................................................<80, <81 .E 51CAL.........................................................3< W+E E....................................................<80-<82 ]i"....................................................................<03
"n ex
a""%ubMenu().................................................213 a""5ab()....................................................180, 130 a""Wor"().............................................../84, /80 a&ter5e;tChange"()..........................................1A0 animateClose()................................................20/ animate>pen()................................................20/ animate5oggle()..............................................20/ apply().............................................................<A0 apply*ormat()................................................../1< atta'h()....................................................28<, 28A be&ore5e;tChange"().......................................1A0 bin"%er!i'e().............................A2A, A28, A23, A/1 bin".ie=()......................................................<8< boun"Center2ottom()....................................A30 buil"*ore'asts()...............................................A0/ buil"5ab1n"i'ator().........................................130 'an'el()............................................................AA4 'an'elAll().......................................................AA4 'an8o2a'k().....................................................211 'an8o2a'k>r*or=ar"()..................................212 'an8o*or=ar"()................................................211 'he'k()........................................................88, 83 'he'kCalling#ermission()...............................A0A 'hoose@ate()....................................................108
3ethod...........................................
a""()..................................218, 22<, 22A, /80, A34 a""E!entListener().........................................404 a""Menu().......................................................213 a""#re&eren'es*rom esour'e()....<A/, <44-<43, <01 a""#ro;imityAlert().......................................A84
'hoose5ime()...................................................108 'lear().......................................................<A0, 4A/ 'learCa'he().....................................................212 'learChe'k()......................................................88 'lear+istory()...................................................212 'lose()...............................20/, </A, <<0, <08, <8/
6;:
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
9ey*or
'ommit()..........................................................<A0 'reate().............................................................2/A 'reate@atabase().............................................<84 'reate*romAsset()...........................................414 'reate*rom*ile()..............................................414 'reate1tem().....................................................A30 'reate#en"ing esult().....................................A/1 'reate5abContent().........................................188 "elete().....................................................<80, <81 "eta'h()...................................................28<, 28A "o1n2a'kgroun"(). . .20A, 204, 208, 280, 28A, 284 "o5he@o=nloa"()...........................................A/0 e"it()................................................................<A0 enable@e&aults().............................................<<2 enable#ersistent%ele'tion()...........................<0< enBueue()...................................................A10, A11 e;e'%KL()................................................<08-<80 e;e'ute()...........................................20<, 280, A01 &in"*ragment2y1"().........................................<11 &in".ie=2y1"()..0/, 0<, 31, 14<-144, 18A, 180, /8A, /84, </1, A3A &inish()..............................................2<1, 2<<, 2<3 &ormat@ate5ime()...........................................108 &rom()..............................................................<00 &syn'()......................................................<<4, <<0 generate#age()................................................A0< get().................................................................<80 getA'tion.ie=()............................../8A, /88, <2< getA'ti!ity().............................................<00, AA0 getA""A'tion.ie=().......................................<2A getAltitu"e()....................................................A8<
"n ex
getAppli'ationConte;t().........................A23, A</ getArguments()..............................................<48 getAs1nteger().................................................<80 getAssets().......................................................414 getAs%tring()...................................................<80 getAttributeCount()......................................../20 getAttribute-ame()......................................../20 get2earing().....................................................A8< get2est#ro!i"er()............................................A8/ get2oolean()....................................................<A0 get2roa"'ast(..................................................A8A get2roa"'ast().................................................AA0 getCall%tate()..................................................408 getChe'ke"1tem#ositions()............................1<0 getChe'ke" a"io2utton1"()............................88 getColumn1n"e;()..........................................<8/ getColumn-ames()........................................<8/ getContentLength()........................................A20 getController()................................................A3A getCount().......................................................<8/ get@ata()..................................................2<3, A/4 get@e&ault%hare"#re&eren'es()...............<A0, <A1 getE;ternal*iles@ir()......................................<<0 getE;ternal%torage@ire'tory()......................<<0 getE;ternal%torage#ubli'@ire'tory()....<<0, A10, A11 getE;ternal%torage%tate()..............................<<0 get*iles@ir()....................................................</3 get*ore'ast()............................................A</, A<A get*ragmentManager()....................................<11 get1"enti&ier().........................................<48, <43
6+;
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
9ey*or
get1nput%tream()............................................A20 get1nt().............................................................<8/ get1tem()..........................................................4A/ get1tem1"()......................................................22< getLastDno=n#osition().................................A8/ getLast-onCon&iguration1nstan'e().....2AA, 28A, AA/, AA< getLatitu"e()...................................................A02 getLayout1n&later()..................................142, <00 getList.ie=()....................................................1/8 getLongitu"e()................................................A02 getMeMyCurrentLo'ation-o=()...................A8< getMenu1n&o().........................................220, 224 get-et=ork5ype()...........................................408 get>!erlays()...................................................A34 get#a'kage-ame()..........................................<48 get#arent().........................................................31 get#hone5ype()..............................................408 get#re&eren'es()......................................<<3, <A0 get#rogress()............................................18/, 240 get#ro!i"ers()..................................................A8/ get ea"able@atabase()...................................<08 get esour'es().........................................</1, <48 get oot.ie=()....................................................31 get%ettings().....................................................21< get%hare"#re&eren'es()..........................<<3, <A0 get%pee"().......................................................A8< get%tring()........................................../11, /1<, <8/ get%tringArray()............................................../2/ get%ubs'riber1"()............................................408 get%upport*ragmentManager()......................<11
"n ex
get%ystemA!ailable*eatures()........................43< get%ystem%er!i'e().........................................A03 get5ag()...............................................144, 140, 101 get5e;t().........................................................../12 get.ie=().....1A8, 1A3, 14/-144, 100, /38, <43, <8< getWriteable@atabase().................................<08 getFml().........................................................../18 go2a'k()............................................................211 go2a'k>r*or=ar"().........................................212 go*or=ar"()......................................................211 han"leError()..................................................A<8 han"leMessage()..............................243, 201, A/2 hasAltitu"e()...................................................A8< has2earing()....................................................A8< has%pee"().......................................................A8< has%ystem*eature()........................................43/ hi"e%o&t1nput*romWin"o=()..........................1/1 in'rement#rogress2y()...................................240 init().........................................................<<<, <<A initA"apter()............................................22/, 22A insert().....................................................<08, <80 isA&terLast()....................................................<8/ isChangingCon&igurations()...........................AA< isChe'ke"().................................................8/, 88 isCon&igurationChanging...............................AA< isEnable"().........................................................31 is*inishing()....................................................AA< is*o'use"().........................................................31 is oute@isplaye"().........................................A3< key().................................................................4A/
6++
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
9ey*or
length()............................................................4A/ loa"@ata()........................................................210 loa"+ea"ers*rom esour'e().................<44, <40 loa"5ime()........................................................21/ loa"$rl()...................................208, 210, /38, 40/ lo'k()................................................................20/ make5e;t().......................................................2/< MenuGset8roupChe'kable()..........................213 Menu1temGsetChe'kable().............................213 mk"irs().............................................................A11 mo!e5o*irst()..................................................<8/ mo!e5o-e;t().................................................<8/ ne=Cursor()....................................................<8A ne=1nstan'e().................................................A04 ne=5ab%pe'()...........................................184, 180 ne=.ie=().......................................................<8< ne;t()................................................................/18 noti&y().....................................................AA4, A4< noti&yMe().......................................................A40 obtainMessage().....................................248, 243 onA'ti!ityCreate"()........................./33, <12, 40< onA'ti!ity esult()....................2<3, 233, /00, A/1 on2in"()...................................A2A, A28, A<0, A<8 on2uil"+ea"ers()...........................................<40 onChe'ke"Change"()...............................8<, 102 onCli'k()...................................................44, 244 onCon&igurationChange"().............2AA, 2A8, 2A3 onConte;t1tem%ele'te"().......................220, 2/0 onConte;tMenu%ele'te"().............................224 onCountry%ele'te"().......................<0<, <03, <11
"n ex
onCreate()...4A, 44, 02, 0/, 83, 102, 130, 208, 218, 22/, 2<0-2</, 2A1, 2A2, 244, 28A, 284, /1<, /8A, /34, /33, <10, <12, </<, <<2, <<<, <<A, <A4, <40, <04, <08, <03, A02, A10, A2A, A23, A/4, A/0, A<0, A<2, A<8, AA/, AA<, A41, A4<, 40<, 448, 48A onCreateConte;tMenu().................220, 22A, 2/0 onCreate>ptionsMenu(). .218, 213, 22/, 2/0, /81, /8A, /34, <2<, <24 onCreate#anelMenu().....................................213 onCreate.ie=().............................../30, /38, 40/ on@estroy()......2<1, 2<<, /33, A02, A2A, A23, A/4, A<0, A<3, AA< on@e!i'e ea"y().....................................404, 400 on@o=ngra"e().......................................<08, <03 on+an"le1ntent()....................................A/4, A/0 on1tem%ele'te"()..............................................1<1 onList1temCli'k().....1/0, 1<0, 100, 244, /33, <0<, <03, <1/, <8/ onLoa"()..........................................................404 on>pen().........................................................<08 on>ptions1tem%ele'te"().218, 213, 221, 22<, 2/0, /81, /34 on#age%tarte"()...............................................212 on#ause()...2<2, 2<<, 201, 23A, /33, </0, A2A, A33 on#ostE;e'ute()......................204, 203, 284, A<8 on#reE;e'ute()................................................20A on#repare>ptionsMenu()...............................218 on#rogress$p"ate()........................204, 208, 203 on atingChange"()..........................................101 on e'ei!e().....................................................23< on e'ei!e"+ttpAuth eBuest()......................212 on estart().......................................................2<1 on estore1nstan'e%tate()........................2</, <12 on esume()......2<2, 201, 23<, /33, </0, <A4, A02, A2A, A33
6+(
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
9ey*or
on etain-onCon&iguration1nstan'e(). .2AA, 242, 28A, 284, <1/, A23, A</, A<<, AA/, AA< on%a!e1nstan'e%tate().....2<1, 2</, 2A0, 2A1, 242, <12 on%er!i'eConne'te"()....................................A28 on%er!i'e@is'onne'te"()...............................A23 on%tart()...................................................2<1, /33 on%tartComman"().........................A2A, A20, A<0 on%top()...........................................2<1, 2<<, /33 on5ap()............................................................A38 on5e;tChange"().............................................1A0 on5ooMany e"ire'ts()....................................212 on$pgra"e()....................................<04, <08, <03 open()..............................................................20/ open*ile1nput()...............................</A, </0, </3 open*ile>uptut()............................................</3 open*ile>utput()............................</A, </0, </3 open a= esour'e().........................................</1 play()........................................................A<0, A4A populate()........................................................A30 post()........................................................202, 20/ post@elaye"()...........................................202, 20/ publish#rogress()............................204, 208, 203 Buery()........................................<81, <82, A11, A12 BueryWith*a'tory()........................................<8A ra=Kuery().......................................................<81 ra=KueryWith*a'tory().................................<8A register*orConte;tMenu().............................220 register e'ei!er().....................................23<, A/1 reloa"()..............................................................211 remo!e()..........................................................<A0
"n ex
remo!e1tem()...................................................4A/ remo!e#ro;imityAlert().................................A84 remo!e$p"ates()............................................A8A reBuery()..........................................................<8/ reBuest*o'us()...................................................31 reBuestLo'ation$p"ates()......................A8<, A8A restoreMe().......................................2A1, 2A2, 2AA run>n$i5hrea"()............................................20/ sen"()........................................................A/1, A/2 sen"2roa"'ast().......................................A/0, A0A sen"EmptyMessage().....................................243 sen"Message()................................................248 sen"MessageAt*ront>&Kueue()....................248 sen"MessageAt5ime()....................................248 sen"Message@elaye"()...................................243 set()..................................................................<3< setA''ura'y()...................................................A8/ setA"apter()................................1/4, 1<1, 1<A, 1<3 setAllo=e"-et=ork5ypes()..............................A11 setAllo=e">!er oaming()..............................A11 setAlphabeti'%hort'ut()..................................213 setAltitu"e eBuire"().....................................A8/ setCell en"erer().............................................1/A setCenter().......................................................A3A setChe'ke"()...............................................8/, 83 setChoi'eMo"e().............................................1/8 setColumnCollapse"().....................................114 setColumn%hrinkable()....................................114 setColumn%tret'hable()...................................114 setContent()..............................................184-188
6+.
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
9ey*or
setContent.ie=()...................4A, 0/, 31, <10, 448 setCostAllo=e"().............................................A8/ setCurrent5ab()...............................................180 set@e&ault*ont%iLe()........................................21A set@es'ription()................................................A11 set@estination1nE;ternal#ubli'@ir()..............A11 set@rop@o=n.ie= esour'e().........................1<1 set@uration()...................................................2/< setEnable"()...............................................31, 223 set*antasy*ont*amily()...................................21< set*oregroun"()..............................................A4< set8roupChe'kable()......................................218 set8roupEnable"()..........................................223 set8roup.isible()............................................223 set+as>ptionsMenu()..................................../34 set1'on()...........................................................2/A set1n"eterminate()..........................................240 set1n"i'ator()....................................184, 180, 130 set1tem()..........................................................4A/ set1temChe'ke"()............................................1<0 setCa!a%'riptCan>penWin"o=sAutomati'ally( )......................................................................... 21A setCa!a%'riptEnable"()....................................21A setLatestE!ent1n&o()...............................AA0, A40 setListA"apter().......................................1/0, /33 setMa;().............................................18/, 240, 201 setMessage()....................................................2/A set-egati!e2utton()........................................2/A set-eutral2utton()..........................................2/A set-umeri'%hort'ut().....................................213 set>nCli'kListener()........................................4A
"n ex
set>nE"itorA'tionListener()..................128, /84 set>n1tem%ele'te"Listener()............1/4, 1<1, 1<A set>n%eek2arChangeListener().....................18/ set>rientation()................................................3< set#a""ing()......................................................30 set#ositi!e2utton()..........................................2/A set#rogress()....................................................240 setK=ertyMo"e()............................................213 set esult()................................................./00, A/1 set5ag()...............................................144, 140, 101 set5e;t().....................................................44, 24A set5e;tColor()....................................................31 set5e;t%iLe().....................................................21A set5itle()....................................................2/A, A11 set5ype&a'e()..............................................00, 414 setup()........................................................18A-180 set$serAgent().................................................21A set.ie=()..........................................................2/< set.isible()......................................................223 set.isible1n@o=nloa"s$i().............................A13 setWeb.ie=Client()........................................212 setRoom()........................................................A3A shoul">!erri"e$rlLoa"ing()...................212, 21/ sho=().......................................................2/<-2/4 sho=Me()........................................................./01 sho=-e;t()......................................................134 siLe()................................................................A30 start()................................................................181 startA'ti!ity()..2<8, 2<3, 233, <1/, <43, A20, 408, 411 startA'ti!ity*or esult()....2<8-2A0, 233, /00, A/1
6+'
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
9ey*or
start@o=nloa"()..............................................A10 start*oregroun"()............................A<0, A4<, A4A start#layer().....................................................A<2 start%er!i'e()......A2A-A28, A/1, A/<, A/4, A/0, A/3, A<0, A<2 stop().................................................181, A<0, A4A stop*oregroun"()....................................A4<-A44 stop#layer().....................................................A<2 stop%el&().........................................................A28 stop%er!i'e().....................................A20-A23, A<2 s=it'h()............................................................213 toggle().................................................8/, 88, 20/ toggle%atellite()...............................................401 to%tring()..........................................................1/A unbin"%er!i'e()...............................................A23 unlo'k()...........................................................20/ unregister e'ei!er().......................................23A up"ate()...................................................<80, <81 up"ate*ore'ast().....................................A02, A<8 up"ateLabel()...................................................108 up"ate5ime()..............................................4A, 44 !alue>&()...........................................................32
"n ex
an"roi",horiLontal%pa'ing.............................1<< an"roi",i".........................01, 02, 88, 100, 18A, 184 an"roi",label.....................................................</ an"roi",layout]abo!e......................................108 an"roi",layout]align2aseline.........................103 an"roi",layout]align2ottom..........................108 an"roi",layout]alignLe&t................................108 an"roi",layout]align#arent2ottom................100 an"roi",layout]align#arentLe&t......................100 an"roi",layout]align#arent ight...................100 an"roi",layout]align#arent5op......................100 an"roi",layout]align ight..............................103 an"roi",layout]align5op.........................108, 103 an"roi",layout]belo=.....................................108 an"roi",layout]'enter+oriLontal...................100 an"roi",layout]'enter1n#arent......................100 an"roi",layout]'enter.erti'al........................100 an"roi",layout]'olumn...................................11< an"roi",layout]height.................................01, 3A an"roi",layout]span........................................11< an"roi",layout]toLe&t>&.................................108 an"roi",layout]to ight>&..............................108
Property.........................................
an"roi",auto5e;t...............................................81 an"roi",'apitaliLe..............................................81 an"roi",'ollapseColumns................................114 an"roi",'olumnWi"th....................................1<< an"roi",'ompletion5hreshol".......................1<3 an"roi","igits.....................................................81 an"roi","ra=%ele'tor>n5op....................1<2, 1A/
an"roi",layout]=eight.....................................3A an"roi",layout]=i"th...........................01, 3A, 101 an"roi",mani&est...............................................<1 an"roi",name.....................................</, A2A, A02 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
6+1
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition
9ey*or
an"roi",numColumns..............................1<<, 1<A an"roi",orientation..........................................3< an"roi",permission.................................A24, A0< an"roi",shrinkColumns...................................114 an"roi",singleLine.............................................81 an"roi",spa'ing................................................1A/ an"roi",spinner%ele'tor..................................1A/ an"roi",sr'........................................................80
"n ex
an"roi",stret'hColumns..................................11A an"roi",stret'hMo"e.......................................1<A an"roi",te;t..................................................01, 00 an"roi",te;tColor........................................08, 8/ an"roi",te;t%tyle..........................................00, 81 an"roi",type&a'e................................................00 an"roi",!erti'al%pa'ing..................................1<< an"roi",!isibility...............................................30
6+3
Subscribe to updates at http://commonsware.com Special Creative Commons BY-NC-SA 3.0 License Edition