You are on page 1of 161

Gio

trnh Android

Table of Contents
1. Gii thiu
2. Nhng kin thc c bn v thit b di ng v lp trnh cho thit b di ng
i. Cc thit b di ng
ii. Tng quan v lp trnh cho thit b di ng
3. Nhp mn lp trnh Android
i. Thit b Android - h iu hnh v my o Dalvik
ii. Lp trnh cho thit b Android
4. Cc Activity, Fragment v Intent
i. Activity
ii. Intent v vic tng tc gia cc Activity
iii. Fragment
5. Giao din ngi dng ca ng dng Android
i. View v ViewGroup
ii. B cc giao din thch nghi vi hng mn hnh
iii. S dng trnh n (Menu)
iv. S dng thanh tc v (Action Bar)
v. X l s kin tng tc vi cc thnh phn ha
6. Thit k giao din ngi dng vi cc View c bn
i. S dng cc View c bn trong Android
ii. TimePicker v DatePicker
iii. Hin th nh vi ImageView v Gallery
iv. S dng ListView hin th danh sch di
v. Hin th ni dung trang web vi WebView
7. Lu tr d liu
i. Lu tr d liu c nh vi shared preferences
ii. Lu tr d liu vi file trn b nh trong v b nh ngoi
iii. CSDL SQLite trong ng dng Android
8. Lp trnh mng vi Android
i. S dng web services thng qua giao thc HTTP
ii. Ti d liu nh phn thng qua HTTP
iii. Ti d liu dng text thng qua HTTP
iv. Web service vi d liu XML
v. Web service vi d liu JSON
9. Google Play Store v vic phn phi ng dng
i. Chun b ng dng trc khi phn phi
ii. Phn phi ng dng

2
Gio trnh Android

Gio trnh Android


Gio trnh dng cho sinh vin khoa Cng Ngh Thng Tin, i hc M a Cht, H Ni

H Th Tho Trang thaotrang1011@gmail.com

B mn Cng Ngh Phn Mm

Khoa Cng Ngh Thng Tin

i hc M a Cht

Gii thiu 3
Gio trnh Android

Nhng kin thc c bn v thit b di ng v lp trnh


cho thit b di ng

Nhng kin thc c bn v thit b di ng v lp trnh cho thit b di ng 4


Gio trnh Android

Cc thit b di ng

Phn loi cc thit b di ng

Cc thit b di ng tri qua rt nhiu nm pht trin vi rt nhiu loi thit b khc nhau, c th k n nh my nhn
tin di ng, in thoi di ng, thit b tr gip c nhn (PDA, Palm...), in thoi thng minh, my tnh bng... Cc thit b
nghe nhn khc nh my nh, my quay k thut s, my nghe nhc... cng c th c xp vo "thit b di ng". Gio
trnh ny s khng cp n cc thit b l lch s (khng cn hoc gn nh khng cn c s dng trong thc t)
v cc thit b nghe nhn v ch cp n cc loi thit b in ton cm tay hin ang ph bin trn th trng tiu dng.
Cc thit b ny thng c phn thnh cc loi nh sau:

in thoi di ng c bn (basic phones v featured phones) - l cc in thoi di ng vi cc tnh nng c bn nh


nghe, gi, danh b... v mt s ng dng dng sn n gin. Cc thit b ny thng c kch thc nh, mn hnh
phn gii thp, c hoc khng c bn phm, pin dng c lu, t kh nng kt ni, kh nng pht trin cng nh ci t
thm phn mm ca nh pht trin l (gn nh) khng c.

in thoi di ng thng minh (smartphones) - l cc in thoi c trang b cu hnh tt hn, chy h iu hnh
thng minh vi cc b cng c pht trin phn mm (Software Development Kit - SDK) cho php lp trnh vin pht trin
a dng cc ng dng phc v mi mc ch ca cuc sng v cng vic. Cc thit b ny thng c kch thc v mn
hnh ln hn nhiu so vi featured phones, cu hnh phn cng (CPU, RAM, GPU, camera...) cao, a dng cc kt ni
(Wifi, Bluetooth, 3G/4G, GPS, Glonass, NFC...), c th c mt s loi cm bin (cm bin gia tc, la bn, cm bin tim
cn, cm bin nh sng, con quay hi chuyn, cm bin p sut...). Vi tnh nng a dng nh vy nn d thng c
trang b thi pin ln hn so vi cc my in thoi c bn, thi lng pin ca in thoi thng minh thng hn ch hn
so vi featured phones.

My tnh bng (tablets) - l cc thit b thng minh, tng t nh smartphones nhng c kch thc mn hnh ln hn
rt nhiu (thng thng t 7"-13"), c th c khe cm th SIM (phc v vic nhn tin, gi in hoc truy cp Internet qua
mng 3G).

in thoi thng minh lai my tnh bng (phablet) - l loi thit b lai gia smartphone v my tnh bng, v tnh nng
n l mt smartphone, nhng c trang b mn hnh c ln hn smartphone thng thng v nh hn kch thc ph
bin ca mn hnh tablet. Mn hnh ca phablet thng c kch thc 5.0"-6.9". Trong lp trnh, cc phablet thng c
xp cng vi vi cc smartphones.

Do kh nng lp trnh cho cc in thoi c bn rt hn ch (thng phi lm vic vi mc thp hn, khng c b cng c
pht trin tin dng) nn mc d in thoi c bn vn chim th phn ln, gio trnh ch tp trung vo vic pht trin ng
dng cho cc thit b thng minh (in thoi thng minh, my tnh bng v in thoi lai). V mt phn mm, cc thit b
ny hu nh ging nhau nn c th gi chung l in thoi thng minh.

Biu di y th hin t l th phn gia Smart Phones v Featured Phones trong 3 nm gn y, d liu kho st
trn tp ngi trng thnh ti Hoa K (theo s liu ca PewSearchCenter, thng 6 nm 2013):

Cc thit b di ng 5
Gio trnh Android

Hnh: Th phn cc loi in thoi ti Hoa K 2011-203

Cc h iu hnh thit b di ng thng minh

Nhng h iu hnh di ng ph bin nht hin nay gm c:

Android

Android l h iu hnh min ph, m ngun m, c pht trin bi "g khng l" Google. Android da trn nn tng
Linux, c thit k dnh cho cc thit b di ng c mn hnh cm ng nh in thoi thng minh v my tnh bng.
Phin bn mi nht ca Android c h tr thm cc thit b khc nh -t, ng h thng minh v TV. Ban u, Android
c pht trin bi Android Corporation, vi s h tr ti chnh t Google v sau ny c chnh Google mua li vo nm
2005. Android ra mt vo nm 2007 cng vi tuyn b thnh lp Lin minh thit b cm tay m (Open Handset Alliance -
http://www.openhandsetalliance.com/), mt hip hi gm cc cng ty phn cng, phn mm, v vin thng vi mc tiu
y mnh cc tiu chun m cho cc thit b di ng. Chic in thoi u tin chy Android c bn vo thng 10 nm
2008.

Android c m ngun m v Google pht hnh m ngun theo Giy php Apache. Chnh m ngun m cng vi mt
giy php khng c nhiu rng buc cho php cc nh pht trin thit b, mng di ng v cc lp trnh vin nhit huyt
c ty bin v phn phi Android mt cch t do. Ngoi ra, Android cn c mt cng ng lp trnh vin ng o,
chuyn vit cc ng dng m rng chc nng ca thit b bng ngn ng lp trnh Java c sa i. Vo thng 7 nm
2013, c hn mt triu ng dng cho thit b Android c cng b, v s lt ti ng dng t Google Play, ca hng ng
dng chnh ca Android, c tnh t khong 50 t. Mt cuc kho st cc nh pht trin vo thng 4 - 5 nm 2013 cho
thy hn 71% lp trnh vin cho di ng pht trin ng dng cho Android. Ti s kin Google I/O 2014
(https://www.google.com/events/io), "g khng l" cng b c hn mt t ngi dng Android hng thng, trong khi con
s ny vo thng 6 nm 2013 mi ch l 538 triu.

Nhng yu t trn gip Android tr thnh nn tng in thoi thng minh ph bin nht th gii, vt qua Symbian vo
qu 4 nm 2010 (chim 33%), v c cc cng ty cng ngh la chn khi h cn mt h iu hnh khng nng n, c

Cc thit b di ng 6
Gio trnh Android

kh nng tinh chnh, gi r chy trn cc thit b cng ngh cao thay v xy dng t u. Kt qu l mc d c thit
k chy trn in thoi v my tnh bng, Android xut hin trn TV, my chi game, ng h thng minh, -t v
cc thit b in t khc. Bn cht m ca Android cng khch l mt i ng ng o lp trnh vin v nhng ngi am
m s dng m ngun m to ra nhng d n do cng ng qun l. Nhng d n ny b sung cc tnh nng cao cp
cho nhng ngi dng thch tm ti hoc a Android vo cc thit b ban u chy h iu hnh khc.

Android chim 75% th phn in thoi thng minh trn ton th gii vo thi im qu 3 nm 2012, vi tng cng 750
triu thit b c kch hot. Vo thng 4 nm 2013 c 1,5 triu lt kch hot mi ngy v tng s thit b Android
c kch hot ln n 1 t vo thng 9 nm 2013. S thnh cng ca h iu hnh ny cng khin n tr thnh mc tiu
trong cc v kin lin quan n bng pht minh, gp mt trong ci gi l "cuc chin in thoi thng minh" gia cc cng
ty cng ngh.

iOS

iOS l h iu hnh trn cc thit b di ng ca Apple. Ban u h iu hnh ny ch c pht trin chy trn iPhone
(gi l iPhone OS), nhng sau n c m rng chy trn cc thit b ca Apple nh iPod touch, iPad v Apple
TV. Ngy 31 thng 5, 2011, App Store ca Apple cha khong 500 000 ng dng chy trn iOS, v c ti v tng cng
khong 15 t lt. Trong qu 4 nm 2010, c khong 26% in thoi thng minh chy h iu hnh iOS, ng sau h iu
hnh Android ca Google v Symbian ca Nokia.

Giao din ngi dng ca iOS da trn c s thao tc bng tay. Ngi dng c th tng tc vi h iu hnh ny thng
qua rt nhiu ng tc bng tay trn mn hnh cm ng ca cc thit b ca Apple.

Phin bn mi nht l iOS 8.1 (ra ngy 20/10/2014) dnh ring cho cc thit b iPhone, iPad, iPad Mini v iPod Touch v
iOS 7.0.1 (ra ngy 20/10/2014) cho cc thit b Apple TV th h 3.

Blackberry

BlackBerry OS l nn tng phn mm t hu do RIM (Research In Motion) pht trin cho dng sn phm cm tay
BlackBerry. BlackBerry OS cung cp kh nng a nhim v c thit k cho cc thit b s dng phng php nhp
thng tin c bit, thng l bi iu khin trackball hoc mn hnh cm ng. H iu hnh ny h tr MIDP 1.0 v WAP
1.2. Cc phin bn trc cho php ng b ha khng dy th in t v lch vi Microsoft Exchange Server , v vi
c Lotus Domino. Phin bn OS 4 hin ti h tr MIDP 2.0, c kh nng kch hot khng dy hon ton v ng b th
in t, lch cng vic, ghi ch v danh b vi Exchange, v h tr Novell GroupWise, Lotus Notes khi kt hp vi
BlackBerry Enterprise Server.

Cc bn cp nht cho BlackBerry OS c th c ti v thng qua dch v BlackBerry OTASL.

Cc bn th ba c th pht trin ng dng s dng cc API t hu ca BlackBerry, nhng bt k ng dng no s dng


cc chc nng ny u cn phi chng thc trc khi ci t. Vic chng thc ny xc nhn tc gi ca phn mm,
nhng khng bo m tnh an ton v bo mt ca ng dng.

BlackBerry 10

L th h tip theo ca h iu hnh BlackBerry OS, c pht trin bi BlackBerry Limited (Research In Motion i tn),
dnh cho c in thoi ln my tnh bng. Thit b gn y nht s dng h iu hnh l smartphone cao cp BlackBerry
Q10.

Windows phone

Windows Phone l h iu hnh ca Microsoft dnh cho smartphone k tc nn tng Windows Mobile, mc d chng
khng tng thch vi nhau. Khc vi Windows Mobile, Windows Phone tp trung vo s pht trin ca Marketplace - ni
cc nh pht trin c th cung cp sn phm (min ph hoc c ph) ti ngi dng. Windows Phone c bn vo thng
10 nm 2010 v u nm 2011 ti Chu .

Cc thit b di ng 7
Gio trnh Android

Phin bn mi nht hin ti l Windows Phone 8. Microsoft cn ang pht trin bn Windows Phone Apollo Plus, v trong
tng lai c th cn c Windows Blue (hay c th l Windows 9) gip tng thch vi h iu hnh Windows trn my
tnh. Vi Windows Phone , Microsoft pht trin giao din ngi dng mi mang tn Modern (trc y gi l Metro) -
tch hp kh nng lin kt vi cc phn cng v phn mm ca hng th ba mt cch d dng.

Ngy 11 thng 2 nm 2011, trc mt bo gii, CEO Microsoft Steve Balmer v CEO Nokia Stephen Elop cng b tr
thnh i tc ca nhau, ng ngha vi vic Windows Phone tr thnh h iu hnh chnh ca Nokia, thay th Symbian
gi ci. S kin ny cng nh du mt mc quan trng trong cuc chin vi Android v iOS, c v nh l "cuc ua
gia 3 con nga". Theo , cng ty ny s hp tc vi Microsoft trong vic sn xut nhng in thoi Windows Phone 7
(hin ti l Windows Phone 8). Nokia ha hn s:

Tp trung vo Windows Phone 7/8: a ra nhng thit k mi, b sung nhng gi ngn ng v ph bin chng
nhiu hn cho ngi tiu dng thng qua nhng thit k mi v phn cng, nhiu phn khc gi v th trng hn

Hp tc trong lnh vc marketing, pht trin phn mm cho in thoi di ng. Bing s tr thnh nn tng tm kim
trong cc thit b v dch v ca Nokia. Kho ng dng ring ca Nokia s c tch hp chung vi Marketplace.

Ngoi cc h iu hnh trn, trn th trng hin nay cn c cc thit b chy cc h iu hnh khc vi th phn khng
ng k nh: Bada (ca Samsung), BlackBerry Tablet OS (cho my tnh bng BlackBerry PlayBook), GridOS (do Fusion
Garage pht trin da trn Android), Linux, Brew (ca Qualcomm), webOS (ca Palm, sau HP mua li, ri li bn li cho
LG hi thng 2 nm 2013), Tizen (do Samsung v Intel phi hp h tr, da trn LiMo - Linux for Mobile), Windows RT
(ca Microsoft cho cc thit b s dng chip kin trc ARM). Mt s t chc, cng ty cng ang n lc pht trin cc h
iu hnh di ng mi, c nhc n nhiu nht trong s c th k n:

Aliyun OS

Aliyun OS ra i thng 7 nm 2011, l h iu hnh da trn Linux, c pht trin bi AliClound, mt cng ty con ca
Alibaba Group, Trung Quc. tng chung ca h iu hnh Aliyun l "m my ha" cc tnh nng ca thit b di ng
(clound functionality). Theo Google, Aliyun c pht trin t h iu hnh m ngun m Android ca mnh, Alibaba th
ph nhn iu ny, tuy nhin h iu hnh ny c th chy c hu ht cc ng dng ca Android. Trn ch ng dng
ca Aliyun thm ch cn cha rt nhiu ng dng Android vi phm bn quyn. Thit b u tin chy h iu hnh ny l
in thoi K-Touch W700.

FireFox OS

L h iu hnh cho in thoi di ng v my tnh bng, c pht trin da trn nn Linux, c pht trin bi t chc
phi li nhun Mozilla Foundation (t chc lm ra trnh duyt FireFox ni ting). c thit k cung cp mt h thng
ton din cho thit b di ng, s dng cc cng ngh m v ph bin nh HTML5, Javascript, web API... vi kh nng
truy cp trc tip vo phn cng thit b, FireFox OS nhm n cnh tranh vi cc ng ln khc nh Apple's iOS, Google's
Android, Microsoft's Windows Phone, cng nh cc h iu hnh mi xut hin nh Ubuntu Touch OS. FireFox OS c
gii thiu thng 2 nm 2012 trn vi in thoi chy Android, v trn b kit Raspberry Pi vo nm 2013. Thng 1 nm
2013, ti trin lm thit b in t tiu dng quc t CES 2013, hng ZTE xc nhn s sn xut in thoi chy h iu
hnh ny v n 2 thng 7 nm 2013, Telefnica chnh thc gii thiu in thoi thng mi u tin chy FireFox OS ti
Ty Ban Nha: in thoi ZTE Open.

Ubuntu Touch OS

L giao din di ng ca h iu hnh m ngun m ni ting - Ubuntu ca Canonical Ltd., c thit k dnh cho cc
thit b di ng vi mn hnh cm ng nh in thoi thng minh v my tnh bng. im mnh ca Ubuntu Touch l vic
da trn cng mt cng ngh li nh h iu hnh Ubuntu cho my tnh, gip cc ng dng dnh cho Ubuntu v Ubuntu
Touch c th chy ln nhau m khng cn pht trin li phin bn ring. Ngoi ra, thit b chy Ubuntu Touch c th bin
thnh Ubuntu bn cho my tnh vi y tnh nng ca my tnh c nhn khi kt ni vo mn hnh ngoi hoc kt ni
qua b (dock). Vi s ph bin ca h iu hnh Ubuntu v kh nng tng thch ca Ubuntu Touch, y c th s tr
thnh mt trong nhng h iu hnh ph bin trong tng lai.

Cc thit b di ng 8
Gio trnh Android

Bng di y th hin tng quan th phn gia cc h iu hnh di ng thng minh ph bin t nm 2012-2013, theo
s liu ngy 16/05/2013 ca IDC Worldwide Quarterly Mobile Phone Tracker - http://www.idc.com/prodserv/smartphone-os-
market-share.jsp (n v: triu thit b).

S lng Q1- Th phn Q1- S lng Q1- Th phn Q1- T l tng


HH
2013 2013 2012 2012 trng

Android 162.1 75.00% 90.3 59.10% 79.50%

iOS 37.4 17.30% 35.1 23.00% 6.60%

Windows
7 3.20% 3 2.00% 133.30%
Phone

BlackBerry
6.3 2.90% 9.7 6.40% -35.10%
OS

Linux 2.1 1.00% 3.6 2.40% -41.70%

Symbian 1.2 0.60% 10.4 6.80% -88.50%

Others 0.1 0.00% 0.6 0.40% -83.30%

Total 216.2 100.00% 152.7 100.00% 41.60%

Bng: Th phn gia cc h iu hnh di ng thng minh ph bin t nm 2012-2013

Biu di y cho thy s thay i v sn lng cng nh th phn ca cc h iu hnh di ng t nm 2007 n nay
(ngun wikipedia.org)

Hnh: Th phn (phn trm) in thoi ton cu theo h iu hnh

Cc thit b di ng 9
Gio trnh Android

Hnh: Th phn (sn lng) in thoi ton cu theo h iu hnh

Xu hng di ng ha

Cc thit b di ng 10
Gio trnh Android

Tng quan v lp trnh cho thit b di ng


Ngi lp trnh ng dng cho thit b di ng truyn thng lun lun phi nh trong u nguyn tc "tit kim ti a ti
nguyn" ca thit b, dng mi cch ti u ha phc tp tnh ton cng nh lng b nh cn s dng. Tuy nhin,
cng vi s pht trin nhanh chng ca phn cng, cc thit b di ng hin i thng c cu hnh rt tt, vi chip x l
mnh m, b nh (RAM) ln, khin vic lp trnh cho thit b di dng tr nn d dng hn bao gi ht. Cc b kit pht trin
ca cc hng sn xut h iu hnh di ng hin nay cng thng lm trong sut hu ht cc tc v lin quan n qun l
b nh, qun l tin trnh... Lp trnh vin c th t quan tm hn n vic ti u ha s dng ti nguyn v tp trung vo
vic "lp trnh", pht trin tnh nng cho ng dng nh khi lp trnh cho my tnh c nhn.

Tuy nhin, c trng di ng ca cc thit b ny cng em n nhiu vn m ngi lp trnh cn phi quan tm nh:

Tnh "di ng" ca cc thit b ny khin kt ni mng tr nn rt bt n nh v kh kim sot. Cc ng dng ph


thuc nhiu vo kt ni Internet cn ch im ny.
Lu lng Internet trn thit b di ng thng c chi ph cao hn so vi Internet c nh. iu ny cng cn lu khi
pht trin cc ng dng s dng nhiu ti nguyn Internet nh phim trc tuyn, nhc trc tuyn...
So vi my tnh c nhn, cc thit b di ng hin i c trang b thm rt nhiu tnh nng gip vic tng tc vi
ngi dng tr nn thun tin (mn hnh cm ng a im, tng tc ging ni, c ch...), cc loi kt ni a dng
(NFC, GPS, 3G, 4G, bluetooth, IR...), cc cm bin phong ph gip tri nghim rt a dng (cm bin nh sng, cm
bin tim cn, la bn, cm bin chuyn ng, gia tc k...). Ngi lp trnh, ty thuc vo ng dng c th, c th s
dng n cc tnh nng c bit ny em n cho ngi dng tri nghim tt nht trn thit b di ng ca mnh.

Ngoi ra cc hng pht trin h iu hnh di ng u lm ra b cng c pht trin (SDK) v mi trng pht trin tch
hp (IDE) rt thun tin cho vic vit m ngun, bin dch, g ri, kim th cng nh xut bn phn mm.

Xt theo th phn trn th trng, ba h iu hnh ph bin nht cho thit b di ng hin nay l Google's Android, Apple's
iOS v Microsoft's Windows Phone. Mi ng dng thnh cng thng c pht trin cho c 3 h nn ny. Mi h nn
u c mt ch ng dng chnh hng (Google c Google Play Store, Apple c Apple AppStore, Microsoft c Windows
Phone Store) vi rt nhiu khch hng tim nng, gip ngi pht trin c th phn phi ng dng min ph hoc c ph
vi chi ph nht nh.

Bng di y lit k cc h iu hnh cng vi ngn ng lp trnh v IDE ph bin nht ca n.

HH Ngn ng lp trnh IDE

Android Java IBM's Eclipse vi Google's ADT plugins

iOS Objective-C Apple' Xcode

Windows Phone C# Microsoft's Visual Studio cho Windows phone

Ngoi vic pht trin ng dng cho tng h iu hnh nh k trn, lp trnh vin c th la chn cc th vin lp trnh a
nn tng pht trin ng dng, ph bin nht trong cc ng dng a nn l cc ng dng vit bng ngn ng Web
(HTML5, CSS & Javascript). Trnh duyt web ca cc thit b di ng hin nay c y tnh nng ln hiu nng chy
tt cc ng dng web hin i. Mt ng dng Web c th c t trn my ch hoc c ng gi thnh native app
(ng dng cho tng h iu hnh) qua mt s cng c ng gi ca cc hng th ba.

Cng c ng gi ng dng Web cho thit b di ng ph bin nht hin nay l PhoneGap (http://phonegap.com/), c
pht trin bi Nitobi, sau c Adobe mua li. PhoneGap cho php lp trnh vin pht trin ng dng di ng s dng
ngn ng Web ph bin (HTML5, CSS3 v Javascript), vi cc tnh nng b sung, cho php ng dng truy cp vo phn
cng ca thit b nh gia tc k, my nh, GPS... v ng gi thnh ng dng cho nhiu h iu hnh khc nhau, bao
gm Android, iOS, Blackberry, BlackBerry 10, Windows Phone, Windows 8, Tizen, Bada. Tuy nhin, nhc im ca cc
ng dng loi ny l hiu sut thp (chy khng c "mt m" nh ng dng native) v khng ng nht gia tt c
cc trnh duyt Web di ng (c th chy hoc hin th khc nhau trn cc h iu hnh vi cc trnh duyt khc nhau).

Tng quan v lp trnh cho thit b di ng 11


Gio trnh Android

Vic chn h iu hnh/th vin no pht trin ty thuc vo nhiu yu t khc nhau nh mc ch ca ng dng, i
tng s dng, tim nng ca h iu hnh, cc yu cu k thut c th cng nh thi quen v k nng ca lp trnh vin.
Trong khun kh gio trnh ny, chng ti tp trung i su vo vic pht trin ng dng cho h iu hnh di ng ph bin
nht hin nay - Google's Android.

Tng quan v lp trnh cho thit b di ng 12


Gio trnh Android

Nhp mn lp trnh Android

Nhp mn lp trnh Android 13


Gio trnh Android

Thit b Android - h iu hnh v my o Dalvik


Ngy 5 thng 11 nm 2007, Lin minh thit b cm tay m (Open Handset Alliance), mt hip hi bao gm nhiu cng ty
trong c Texas Instruments, Tp on Broadcom, Google, HTC, Intel, LG, Tp on Marvell Technology, Motorola,
Nvidia, Qualcomm, Samsung Electronics, Sprint Nextel v T-Mobile c thnh lp vi mc ch pht trin cc chun m
cho thit b di ng. Cng ngy, Android cng c ra mt vi vai tr l sn phm u tin ca Lin minh, mt nn tng
thit b di ng c xy dng trn nhn Linux phin bn 2.6. Chic in thoi chy Android u tin c bn ra l HTC
Dream, pht hnh ngy 22 thng 10 nm 2008. Biu trng ca h iu hnh Android mi l mt con r-bt mu xanh l
cy do hng thit k Irina Blok ti California v.

T nm 2008, Android tri qua nhiu ln cp nht dn dn ci tin h iu hnh, b sung cc tnh nng mi v sa
cc li trong nhng ln pht hnh trc. Mi bn nng cp c t tn ln lt theo th t bng ch ci, theo tn ca
mt mn n trng ming; v d nh phin bn 1.5 Cupcake (bnh bng lan nh c kem) tip ni bng phin bn 1.6 Donut
(bnh vng). Phin bn mi nht cho n thi im cui nm 2014 l Android 5.0 Lollipop (ko mt). Vo nm 2010,
Google ra mt lot thit b Nexusmt dng sn phm bao gm in thoi thng minh v my tnh bng chy h iu
hnh Android, do cc i tc phn cng sn xut. HTC hp tc vi Google trong chic in thoi thng minh Nexus
u tin, Nexus One. K t nhiu thit b mi hn gia nhp vo dng sn phm ny, nh in thoi Nexus 4 v my
tnh bng Nexus 10, ln lt do LG v Samsung sn xut, k tip l Nexus 5 cng do LG sn xut, v mi nht l Nexus 6
(Motorolla) v Nexus 9 (HTC) va c ra mt ngy 03/11/2014 va qua. Google xem in thoi v my tnh bng Nexus
l nhng thit b Android ch lc ca mnh, vi nhng tnh nng phn cng v phn mm mi nht ca Android.

Bng di y th hin t l s dng cc phin bn Android tnh n ngy 09/09/2014 (cc phin bn c th phn di
0.1% khng c lit k ti y).

Phin bn Tn M API T l

2.2 Froyo 8 0.7%

2.3.3 -2.3.7 Gingerbread 10 11.4%

4.0.3 -4.0.4 Ice Cream Sandwich 15 9.6%

4.1.x Jelly Bean 16 25.1%

4.2.x Jelly Bean 17 20.7%

4.3 Jelly Bean 18 8.0%

4.4 KitKat 19 24.5%

Giao din v ng dng

Thit b Android - h iu hnh v my o Dalvik 14


Gio trnh Android

Giao din

Giao din ngi dng ca Android da trn nguyn tc tc ng trc tip, s dng cm ng chm tng t nh nhng
ng tc ngoi i thc nh vut, chm, ko dn v thu li x l cc i tng trn mn hnh. S phn ng vi tc
ng ca ngi dng din ra gn nh ngay lp tc, nhm to ra giao din cm ng mt m, thng dng tnh nng rung
ca thit b to phn hi rung cho ngi dng. Nhng thit b phn cng bn trong nh gia tc k, con quay hi chuyn
v cm bin khong cch c mt s ng dng s dng phn hi mt s hnh ng khc ca ngi dng, v d nh
iu chnh mn hnh t ch hin th dc sang ch hin th ngang ty theo v tr ca thit b, hoc cho php ngi
dng li xe ua bng xoay thit b, ging nh ang iu khin v-lng.

Cc thit b Android sau khi khi ng s hin th mn hnh chnh, im khi u vi cc thng tin chnh trn thit b, tng
t nh khi nim desktop (bn lm vic) trn my tnh bn. Mn hnh chnh ca Android thng gm nhiu biu tng
(icon) v tin ch (widget); biu tng ng dng s m ng dng tng ng, cn tin ch hin th nhng ni dung sng
ng, cp nht t ng nh d bo thi tit, hp th ca ngi dng, hoc nhng mu tin thi s ngay trn mn hnh
chnh. Mn hnh chnh c th gm nhiu trang c chuyn bng cch vut ra trc hoc sau. Giao din mn hnh chnh
ca Android c th ty chnh mc cao, cho php ngi dng t do sp t hnh dng cng nh hnh vi ca thit b theo
s thch. Nhng ng dng do cc hng th ba c trn Google Play v cc kho ng dng khc cn cho php ngi dng
thay i "ch " ca mn hnh chnh, thm ch bt chc hnh dng ca h iu hnh khc nh Windows Phone chng
hn. Phn ln nhng nh sn xut, v mt s nh mng, thc hin thay i hnh dng v hnh vi ca cc thit b Android
ca h phn bit vi cc hng cnh tranh.

Hnh . Mn hnh chnh vi cc biu tng (icon) v tin ch (widget)

pha trn cng mn hnh l thanh trng thi, hin th thng tin v thit b v tnh trng kt ni. Thanh trng thi ny c th

Thit b Android - h iu hnh v my o Dalvik 15


Gio trnh Android

"ko" xung xem mn hnh thng bo gm thng tin quan trng hoc cp nht ca cc ng dng, nh email hay tin
nhn SMS mi nhn, m khng lm gin on hoc khin ngi dng cm thy bt tin. Trong cc phin bn i u,
ngi dng c th nhn vo thng bo m ra ng dng tng ng, v sau ny cc thng tin cp nht c b sung
theo tnh nng, nh c kh nng lp tc gi ngc li khi c cuc gi nh m khng cn phi m ng dng gi in ra.
Thng bo s lun nm cho n khi ngi dng c hoc xa chng i.

Hnh . Thanh trng thi ang c "ko" xung vi cc thng bo bn trong

Mt im mnh ca h iu hnh Android l cho php ngi dng chy nhiu ng dng cng lc (a nhim - multi-
tasking). Vic chuyn qua chuyn li gia cc ng dng c thc hin mt cch d dng bng cch bm v gi phm
Home hin th danh sch ng dng ang chy.

Thit b Android - h iu hnh v my o Dalvik 16


Gio trnh Android

Hnh . Danh sch ng dng ang chy trn thit b (a nhim)

ng dng

Android c lng ng dng ca bn th ba ngy cng nhiu, c chn lc v t trn mt ca hng ng dng nh
Google Play hay Amazon Appstore ngi dng ly v, hoc bng cch ti xung ri ci t tp tin APK t trang web
khc. Cc ng dng trn Ca hng Google Play cho php ngi dng duyt, ti v v cp nht cc ng dng do Google
v cc nh pht trin th ba pht hnh. Google Play c ci t sn trn cc thit b tha mn iu kin tng thch ca
Google. Google Play s t ng lc ra mt danh sch cc ng dng tng thch vi thit b ca ngi dng, v nh pht
trin c th gii hn ng dng ca h ch dnh cho nhng nh mng c nh hoc nhng quc gia c nh v l do kinh
doanh. Nu ngi dng mua mt ng dng m h cm thy khng thch, h c th c hon tr tin sau 15 pht k t
lc ti v. Mt vi nh mng cn c kh nng mua gip cc ng dng trn Google Play, sau tnh tin vo trong ha n
s dng hng thng ca ngi dng. Tnh n thng 8 nm 2013, c hn 975.000 ng dng dnh cho Android trn ca
hng Google Play, v s lt ng dng ti v t Ca hng Play c tnh t gn 30 t.

Hnh: Giao din ca hng Google Play trn in thoi Google Nexus 4

Cc ng dng cho Android c pht trin bng ngn ng Java s dng B pht trin phn mm Android (Android SDK).
Android SDK bao gm mt b y cc cng c dng pht trin, bao gm cng c g li, th vin phn mm, b gi
lp in thoi da trn QEMU, ti liu hng dn, m ngun mu, v hng dn tng bc. Mi trng pht trin tch
hp (IDE) c h tr chnh thc l Eclipse s dng phn b sung Android Development Tools (ADT). Cc cng c pht
trin khc cng c sn, gm c B pht trin gc dnh cho cc ng dng hoc phn m rng vit bng C hoc C++,
Google App Inventor, mt mi trng ha cho nhng ngi mi bt u lp trnh, v nhiu nn tng ng dng Web di
ng a nn tng phong ph.

Pht trin

Thit b Android - h iu hnh v my o Dalvik 17


Gio trnh Android

Android c Google t pht trin ring cho n khi nhng thay i v cp nht hon thin, khi m ngun mi c
cng khai. M ngun ny, nu khng sa i, ch chy c trn mt s thit b, thng l thit b thuc dng Nexus. C
nhiu thit b c cha nhng thnh phn c gi bn quyn do nh sn xut t vo thit b Android ca h.

Ht nhn Linux

Android c ht nhn da trn nhn Linux phin bn 2.6. K t Android 4.0 Ice Cream Sandwich (bnh ngt kp kem) tr
v sau, l phin bn 3.x, vi middleware, th vin v API vit bng C, cn phn mm ng dng chy trn mt nn tng
ng dng gm cc th vin tng thch vi Java da trn Apache Harmony. Android s dng my o Dalvik vi mt trnh
bin dch ng chy 'm dex' (Dalvik Executable) ca Dalvik, thng c bin dch sang Java bytecode. Nn tng
phn cng chnh ca Android l kin trc ARM. Ngi ta cng h tr x86 thng qua d n Android x86 (chip Intel Atom),
v Google TV cng s dng mt phin bn x86 c bit ca Android.

Nhn Linux dng cho Android c Google thc hin nhiu thay i v kin trc so vi nhn Linux gc. Android khng
c sn X Window System cng nh khng h tr cc th vin GNU chun, nn vic chuyn cc ng dng hoc th vin
Linux c sn sang Android rt kh khn. Cc ng dng C n gin v SDL cng c h tr bng cch chn nhng on
shim Java v s dng tng t nh nn tng lp trnh JNI, nh khi ngi ta chuyn tr chi Jagged Alliance 2 sang
Android.

Mt s tnh nng cng c Google ng gp ngc vo nhn Linux, ng ch l tnh nng qun l ngun in c tn
wakelock, nhng b nhng ngi lp trnh chnh cho nhn t chi v h cm thy Google khng c nh s tip tc bo tr
on m do h vit. Google thng bo vo thng 4 nm 2010 rng h s thu hai nhn vin lm vic vi cng ng
nhn Linux, nhng Greg Kroah-Hartman, ngi bo tr nhn Linux hin ti ca nhnh n nh, ni vo thng 12 nm
2010 rng ng lo ngi Google khng cn mun a nhng thay i ca mnh vo Linux dng chnh na. Mt s lp trnh
vin Android ca Google t rng "nhm Android thy chn vi quy trnh ," v nhm h khng c nhiu ngi v c
nhiu vic khn cp cn lm vi Android hn.

Vo thng 8 nm 2011, Linus Torvalds pht biu rng "rt cuc th Android v Linux cng s tr li vi mt b nhn chung,
nhng iu c th s khng xy ra trong 4 hoc 5 nm na". Vo thng 12 nm 2011, Greg Kroah-Hartman thng bo
kch hot D n Dng chnh Android, nhm ti vic a mt s driver, bn v v tnh nng ca Android ngc vo nhn
Linux, bt u t Linux 3.3. Linux cng a tnh nng autosleep (t ng ngh) v wakelocks vo nhn 3.5, sau nhiu n
lc phi trn trc . Tng tc th vn vy nhng bn hin thc trn Linux dng chnh cho php hai ch ngh: b
nh (dng ngh truyn thng m Android s dng), v a (dng ng ng - hibernate trn my tnh bn). Vic trn s
hon tt k t nhn 3.8. Google cng khai kho m ngun trong c nhng on th nghim a Android v li nhn
3.8.

B lu tr flash trn cc thit b Android c chia thnh nhiu phn vng, nh "/system" dnh cho h iu hnh v
"/data" dnh cho d liu ngi dng v ci t ng dng. Khc vi cc bn phn phi Linux cho my tnh bn, ngi
s hu thit b Android khng c trao quyn truy cp root vo h iu hnh v cc phn vng nhy cm nh /system
c thit lp ch c. Tuy nhin, quyn truy cp root c th chim c bng cch tn dng nhng l hng bo mt trong
Android, iu m cng ng m ngun m thng xuyn s dng nng cao tnh nng thit b ca h, k c b nhng
ngi c s dng ci virus v phn mm gin ip.

Vic Android c c xem l mt bn phn phi Linux hay khng vn cn l vn gy tranh ci, tuy c Linux
Foundation v Chris DiBona, trng nhm m ngun m Google, ng h. Mt s khc, nh linux-magazine.com th khng
ng , do Android khng h tr nhiu cng c GNU, trong c glibc.

Qun l b nh

V cc thit b Android ch yu chy bng pin, nn Android c thit k qun l b nh (RAM) nhm gim ti a tiu
th in nng, tri vi h iu hnh my tnh bn lun cho rng my tnh s c ngun in khng gii hn. Khi mt ng
dng Android khng cn c s dng, h thng s t ng ngng n trong b nh, trong khi ng dng v mt k thut
vn "m", nhng ng dng ny s khng tiu th bt c ti nguyn no (nh nng lng pin hay nng lng x l) v
nm cho n khi n c cn n. Cch lm nh vy c li kp l va lm tng kh nng phn hi ni chung ca thit

Thit b Android - h iu hnh v my o Dalvik 18


Gio trnh Android

b Android, v ng dng khng nht thit phi ng ri m li t u, va m bo cc ng dng nn khng lm tiu hao
nng lng mt cch khng cn thit.

Android qun l cc ng dng trong b nh mt cch t ng: khi b nh thp, h thng s bt u dit ng dng v tin
trnh khng hot ng trong mt thi gian, sp theo thi im cui m chng c s dng (ci c nht s b tt trc).
Qu trnh ny c thit k n i vi ngi dng, ngi dng khng cn phi qun l b nh hoc t tay tt cc ng
dng. Tuy nhin, s che giu ny ca h thng qun l b nh Android dn n s thnh hnh ca cc ng dng tt
chng trnh ca bn th ba trn ca hng Google Play; nhng ng dng kiu nh vy c cho l c hi nhiu hn c
li.

Cng ng m ngun m

Android c mt cng ng cc lp trnh vin v nhng ngi am m rt nng ng. H s dng m ngun Android
pht trin v phn phi nhng phin bn chnh sa ca h iu hnh. Cc bn Android do cng ng pht trin thng
em nhng tnh nng v cp nht mi vo nhanh hn cc knh chnh thc ca nh sn xut/nh mng, tuy khng c
kim th k lng cng nh khng c m bo cht lng; cung cp s h tr lin tc cho cc thit b c khng cn nhn
c bn cp nht chnh thc; hoc mang Android vo nhng thit b ban u chy mt h iu hnh khc, nh HP
Touchpad. Cc bn Android ca cng ng thng c root (m quyn truy cp ton h thng) sn v c nhng iu
chnh khng ph hp vi nhng ngi dng khng rnh, nh kh nng p xung hoc tng/gim p b x l ca thit b.
CyanogenMod l firmware ca cng ng c s dng ph bin nht v l c s cho rt nhiu firmware khc pht trin
da trn bn firmware ny.

Trc y, nh sn xut thit b v nh mng t ra thiu thin ch vi vic pht trin firmware ca bn th ba. Nhng nh
sn xut cn th hin lo ngi rng cc thit b chy phn mm khng chnh thc s hot ng khng tt v dn n tn
tin h tr. Hn na, cc firmware thay i nh CyanogenMod i khi cn cung cp nhng tnh nng, nh truyn ti
mng (tethering), m ngi dng bnh thng phi tr tin nh mng mi c s dng. Kt qu l nhiu thit b bt u
t ra hng ro k thut nh kha bootloader hay hn ch quyn truy cp root. Tuy nhin, khi phn mm do cng ng
pht trin ngy cng tr nn ph bin, v sau mt thng co ca Th vin Quc hi Hoa K cho php "jailbreak" (vt
ngc) thit b di ng, cc nh sn xut v nh mng t ra mm mng hn vi cc nh pht trin th ba, thm ch mt
s hng nh HTC, Motorola, Samsung v Sony, cn h tr v khuyn khch pht trin. Kt qu ca vic ny l dn dn
nhu cu tm ra cc hn ch phn cng ci t c firmware khng chnh thc bt i do ngy cng nhiu thit b
c pht hnh vi bootloader m kha sn hoc c th m kha, nh in thoi dng Nexus, tuy rng thng thng
h s yu cu ngi dng t b ch bo hnh nu h lm nh vy. Tuy nhin, d c s chp thun ca nh sn
xut, mt s nh mng ti M vn bt buc in thoi phi b kha.

Bo mt v tnh ring t

Cc ng dng Android chy trong mt "hp ct" (sandboxed applications), l mt khu vc ring r vi h thng v khng
c tip cn n phn cn li ca ti nguyn h thng, tr khi n c ngi dng trao quyn truy cp mt cch cng
khai khi ci t. Trc khi ci t ng dng, Ca hng Play s hin th tt c cc quyn m ng dng i hi: v d nh
mt tr chi cn phi kch hot b rung hoc lu d liu vo th nh SD, nhng n khng nn cn quyn c tin nhn
SMS hoc tip cn danh b in thoi. Sau khi xem xt cc quyn ny, ngi dng c th chn ng hoc t chi
chng, ng dng ch c ci t khi ngi dng ng .

Thit b Android - h iu hnh v my o Dalvik 19


Gio trnh Android

Hnh . Yu cu chp nhn cc quyn ng dng c php s dng trc khi ci t

H thng hp ct v hi quyn lm gim bt nh hng ca li bo mt hoc li chng trnh c trong ng dng, nhng
s thiu kinh nghim ca lp trnh vin v ti liu hng dn cn hn ch dn ti nhng ng dng hay i hi nhng
quyn khng cn thit, do lm gim i hiu qu ca h thng ny. Mt s cng ty bo mt, nh Lookout Mobile
Security, AVG Technologies, v McAfee, pht hnh nhng phn mm dit virus cho cc thit b Android. Phn mm ny
khng c hiu qu v c ch hp ct vn p dng vo cc ng dng ny, do vy lm hn ch kh nng qut su vo h
thng tm nguy c.

Mt nghin cu ca cng ty bo mt Trend Micro lit k tnh trng lm dng dch v phi tr tin l hnh thc phn mm
c ph bin nht trn Android, trong tin nhn SMS s b gi i t in thoi b nhim n mt s in thoi tr tin m
ngi dng khng h hay bit. Loi phn mm c khc hin th nhng qung co khng mong mun v gy kh chu
trn thit b, hoc gi thng tin c nhn n bn th ba khi cha c php. e da bo mt trn Android c cho l
tng rt nhanh theo cp s m; tuy nhin, cc k s Google phn bc rng him ha t phn mm c v virus b thi
phng bi cc cng ty bo mt nhm mc ch thng mi, v buc ti ngnh cng nghip bo mt ang li dng s s
hi bn phn mm dit virus cho ngi dng. Google vn gi quan im rng phn mm c tht s nguy him l cc
k him, v mt cuc iu tra do F-Secure thc hin cho thy ch c 0,5% s phn mm c trn Android l len vo c
ca hng Google Play.

Google hin ang s dng b qut phn mm c Google Bouncer theo di v qut cc ng dng trn Ca hng
Google Play. N s nh du cc phn mm b nghi ng v cnh bo ngi dng v nhng vn c th xy ra trc khi

Thit b Android - h iu hnh v my o Dalvik 20


Gio trnh Android

h ti n v my. Android phin bn 4.2 Jelly Bean c pht hnh vo nm 2012 cng vi cc tnh nng bo mt c
ci thin, bao gm mt b qut phn mm c c ci sn trong h thng, hot ng cng vi Google Play nhng cng
c th qut cc ng dng c ci t t ngun th ba, v mt h thng cnh bo s thng bo cho ngi dng khi mt
ng dng c gng gi mt tin nhn vo s tnh tin, chn tin nhn li tr khi ngi dng cng khai cho php n.

in thoi thng minh Android c kh nng bo co v tr ca im truy cp Wi-Fi, pht hin ra vic di chuyn ca ngi
dng in thoi, xy dng nhng c s d liu c cha v tr ca hng trm triu im truy cp. Nhng c s d liu
ny to nn mt bn in t tm v tr in thoi thng minh, cho php chng chy cc ng dng nh Foursquare,
Google Latitude, Facebook Places, v gi nhng on qung co da trn v tr. Phn mm theo di ca bn th ba nh
TaintDroid, mt d n nghin cu trong trng i hc, i khi c th bit c khi no thng tin c nhn b gi i t ng
dng n cc my ch t xa.

My o Dalvik

Java c bit n vi khu hiu "vit mt ln, chy mi ni" (write once, run anywhere). Tnh nng ny ca h sinh thi
Java c c nh mt tng my o ng gia tng ng dng (vit bng Java) v tng h iu hnh (nhiu loi khc
nhau), gi l my o Java - JVM (Java Virtual Machine). My o Java chy rt n nh v ng nht trn cc mi trng
my tnh c nhn (JSE) v my ch (JEE), tuy nhin trong mi trng di ng (JME) th my o Java b phn mnh tng
i nhiu vi cc gi (pakages), cu hnh (configurations) v cc mu (profiles) khc nhau.

Google chn Java lm ngn ng pht trin ng dng cho h iu hnh Android, tuy nhin li t b c phin bn Java di
ng (JME) ln my o Java (JVM) pht trin mt my o ring - my o Dalvik v tp th vin Java chun c vit
li v thu gn hn.

ng dng Android c pht trin bng ngn ng Java, sau c bin dch thnh dng m nh phn Java (Java
bytecode). Cc file nh phn .class (tng thch vi JVM) ny s c chuyn i thnh 1 file nh phn dng cho my o
Dalvik - .dex (Dalvik EXecutable) trc khi c ci ln thit b. Cc tp tin .dex c thit k ph hp hn vi cc
thit b hn ch v b nh cng nh hiu nng x l.

Dalvik l mt phn mm m ngun m, ban u c pht trin bi Dan Bornstein, v c ng t tn theo tn ngi lng
Dalvk ti Eyjafjrur, Iceland, qu hng ca ng.

Kin trc

Thit b Android - h iu hnh v my o Dalvik 21


Gio trnh Android

H iu hnh Android c thit k hng n rt nhiu cc loi thit b khc nhau, t nhng thit b gi r, cu hnh thp
(low-end) n nhng siu phm t tin (high-end). Bn cnh , cc ng dng Android phi c chy trong "hp ct"
vi bo mt cao, hiu nng tt v n nh, v vy vic s dng mt my o lm mi trng thc thi l iu tt yu. Tuy
nhin vic s dng my o thng s lm gim hiu nng ca h thng. Gii php my o Dalvik ca Google c a
ra nhm cn bng gia 2 im ny:

Mi ng dng Android c chy trong tin trnh ring, vi mt thc th (instance) ca my o Dalvik ring. Dalvik
c thit k h iu hnh c th chy nhiu thc th ca my o mt cch hiu qu vi file thc thi Dalvik (.dek
file) c thit k ti u ha b nh cn s dng. My o Dalvik l my o da trn thanh ghi (register-based),
khc vi my o Java chy da trn cu trc ngn xp (stack-based).
My o Dalvik s dng ht nhn Linux cho cc vic lin quan n lp di ca h thng nh qun l tiu trnh
(threading), qun l b nh cp thp... Do mi ng dng chy trn mt thc th my o ring, h thng Android khng
nhng cn ti u vic chy nhiu my o v cn phi gim ti a thi gian khi to my o mi. Phn di y s
xem xt 4 im chnh trong thit k my o m Google chn la t c hiu nng v bo mt cn thit:
cu trc file .dex, Zygote, cu trc da trn thanh ghi v bo mt.

nh dng file .dex

Trong mi trng Java truyn thng, m ngun Java c bin dch thnh dng bytecode, mi class trong m ngun
c bin dch thnh mt file .class ring. Trong h thng Android, m ngun Java cng c bin dch thnh cc file
.class ring. Tuy nhin trc khi c th c ci t ln thit b, cc file ny phi c chuyn i thnh file thc thi Dalvik
(.dex) bng cng c "dx" c trong Android SDK. File thc thi Dalvik c th cha nhiu class bn trong v mi ng dng
Android ch cha mt file .dex duy nht.

File thc thi Dalvik c thit k nhm n vic ti u b nh trn c s chia s (dng chung) d liu. Biu di y
phn bit cu trc file .dex vi file .class truyn thng.

Thit b Android - h iu hnh v my o Dalvik 22


Gio trnh Android

Hnh . Cu trc file class ca Java v file thc thi Dalvik

C ch chnh ca file .dex cho vic tit kim b nh l dng chung cc vng nh cha hng s cho tt c cc class. Cc
vng nh cho hng s ny c chia theo tng loi d liu (hng s chui, tn trng, tn class, tn method...). Trong m
lnh ca cc class bn di s khng cn ghi li cc tn/hng s ny m ch cha ch s (s nguyn) ca n trong vng
hng s.

i vi cc file .class truyn thng, mi class file cha vng nh ring cho cc hng s ca class . Vng nh ny khng
ng nht v n cha tt c cc loi hng s, khng phn bit theo loi nh trong trng hp ca .dex file. Vic lp li khai
bo cc hng s ny nhiu file .class khin tng kch thc cc file .class ln hn nhiu so vi file thc thi Dalvik.

Theo s liu thng k, trung bnh trong mi file .class, 61% kch thc ca file l cc hng s (!!!), m ca cc phng
thc (method) ch cha khong 33%, cn li 5% cho cc phn khc ca class. Nh vy vic tit kim vng nh cho hng
s dn n vic tit kim ng k kch thc file thc thi (thng thng l khong 50%), t tit kim c lng b
nh cn cp pht lc thc thi ng dng.

Zygote

Cc ng dng Android c chy trong cc thc th my o ring, v vy my o phi c "khi ng" nhanh v s

Thit b Android - h iu hnh v my o Dalvik 23


Gio trnh Android

dng ti thiu b nh cn thit. t c iu ny, h thng Android a ra mt c ch gip cc thc th my o c


th chia s m lnh dng chung v "khi ng" nhanh, gi l Zygote.

Hu ht cc ng dng Android u dng chung mt s th vin li v cu trc b nh heap km theo n. Thm vo ,


vng nh heap ca cc th vin li ny thng ch c truy xut ch c (read-only). Li dng im ny, Zygote, mt tin
trnh my o Dalvik c khi chy lc khi ng thit b, np sn cc th vin li ca h iu hnh m cc ng dng
thng xuyn s dng, sn sng cho cc my o s dng. Mi ln mt ng dng c chy, h thng s khi ng
mt my o mi, tuy nhin my o ny s khng cn cha nhng th vin li, m s dng lun th vin li trong Zygote,
khin thi gian khi to my o l ti thiu.

Cc th vin li trong hu ht cc trng hp l "ch c" ch khng b ghi bi ng dng. Trong trng hp ng dng
c nhu cu ghi vo vng nh heap ca cc th vin li ny, mt bn sao ca vng nh Zygote s c to ra ring cho
tin trnh ca ng dng . C ch "sao chp khi ghi" (copy-on-write) ny gip ti u ha vic s dng chung m lnh ca
th vin li m vn m bo tnh bo mt gia cc ng dng: vic thay i d liu trong b nh ca ng dng ny khng
nh hng n cc ng dng khc.

Trong JVM truyn thng, mi thc th ca my o Java s c mt tp cc th vin li ring cng vng nh tng ng cho
chng, khng c s chia s b nh gia cc thc th ca my o.

Kin trc my o da trn thanh ghi

Theo truyn thng, cc nh pht trin my o thng la chn kin trc da trn ngn xp (stack-based architecture) hn
l kin trc da trn thanh ghi (register-based architecture) do vic thit k my o v trnh bin dch cho kin trc ngn
xp n gin hn so vi trng hp ca kin trc thanh ghi. B li cho s n gin l hiu sut gim i.

Cc nghin cu ch ra rng, kin trc da trn thanh ghi thng i hi s lng m lnh thc thi cho ng dng t hn
trung bnh l 47% so vi trng hp dng ngn xp. B li, kch thc m lnh thng ln hn khong 25%. Tuy nhin
s gia tng v kch thc m lnh ny ch pht sinh thm khong 1.07% ti ca CPU. Cc trnh nh gi tiu chun cho
thy hiu sut tng th ca my o da trn kin trc thanh ghi cao hn khong 32.3% so vi kin trc ngn xp.

Vi yu cu chy trn cc thit b vi hiu nng tnh ton thp, vic my o Dalvik la chn kin trc thanh ghi l hon
ton hp l. Mc d kch thc m lnh ln hn trung bnh 25%, vic s dng vng nh chung cho hng s ca file .dex
gip kch thc m lnh gim i n 50% khin file thc thi Dalvik vn hiu qu hn ng k v mt b nh so vi cc file
.class truyn thng.

Bo mt

Mc nh theo kin trc bo mt ca h iu hnh Android, mi ng dng khng c quyn thc thi bt c thao tc no nh
hng n cc ng dng khc, n h iu hnh hay ngi dng, bao gm: c/ghi d liu c nhn (nh danh b,
email...), c/ghi file d liu ca ng dng khc, thc hin kt ni mng, gi mn hnh lun sng...

Tnh nng ny c thc hin t tng h iu hnh v tng khung ng dng (application framework) ch khng phi bn
trong my o Dalvik. Mi ng dng c chy trong mt my o ring, my o ny li c chy trong mt tin trnh
ring. Mi tin trnh c chy di mt m ngi dng (user ID) ring, c sinh ra lc ci t v c phn quyn ch
c truy cp mt s tnh nng nht nh ca h iu hnh v cc tp tin ring ca mnh. Nu ng dng c cc yu cu
c bit n cc tnh nng khc ca h thng th phi khai bo cc quyn tng ng trong file m t ng dng
(AndroidManifest.xml) v s c cp cc quyn ny lc ci t nu c s ng t ngi dng.

Thit b Android - h iu hnh v my o Dalvik 24


Gio trnh Android

Lp trnh cho thit b Android

B pht trin phn mm Android (Android SDK)

H sinh thi Android c cu thnh t 3 thnh phn tng quan nh sau:

H iu hnh m ngun m cho thit b nhng


B cng c pht trin phn mm (m ngun m) - Android SDK
Cc thit b (ch yu l in thoi thng minh) chy h iu hnh Android vi cc ng dng c pht trin cho
chng. Trong Android SDK l b pht trin phn mm Android c Google a ra di dng m ngun m, gip
ngi lp trnh c th d dng truy xut vo cc tnh nng ca h iu hnh nh:
Mng in thoi cho vic nghe gi/SMS cng nh truy cp Internet: GSM/GRPS, EGDE, 3G, 4G, LTE...
Tp APIs cho cc ng dng hng v tr (GPS, v tr da trn kt ni mng)
Tch hp ng dng bn thnh 1 thnh phn ca ng dng
Kt ni mng WiFi v kt ni im-ti-im (peer-to-peer)
Cc ng dng a phng tin: ghi hnh, ghi m vi camera v microphone, pht nhc, pht video...
Th vin a phng tin vi kh nng thu v pht nhiu loi audio v video, cng nh cc nh tnh
API truy cp n cc cm bin: cm bin gia tc, tim cn, la bn...
Th vin cho vic s dng Bluetooth v NFC cho kt ni im-ti-im
Chia s v trao i d liu gia cc ng dng
API cho cc kho d liu chia s nh danh b, lch, mng x hi, a phng tin...
Cc ng dng/tc v chy ngm
Cc tin ch (widget) trn mn hnh chnh v hnh nn ng
Tch hp kh nng tm kim ca ng dng vo cng c tm kim ca h thng
Trnh duyt HTML5 m ngun m, da trn Webkit
B tng tc ha bng phn cng (GPU) cho vic ti u hiu nng hin th, bao gm nhng khng gii hn
ha 2D v 3D vi OpenGL ES 2.0
H tr a ngn ng vi c ch cung cp ti nguyn c trng
C ch s dng li cc thnh phn ca ng dng cng nh thay th cc ng dng sn c
Lu tr v truy xut d liu vi CSDL Sqlite 3.0
Google Cloud Message: cho qun l vic y thng bo xung thanh h thng
...

B SDK y sau khi ti v s bao gm tt c cc thnh phn cn thit cho vic vit code, g li, kim th, bin dch v
xut bn phn mm nh:

Android API - l cc th vin li ca b SDK, gip ngi lp trnh truy xut cc thnh phn ca h iu hnh. Cc ng
dng ca Google ci sn trn thit b cng c pht trin da trn cc API ny.
Cng c pht trin: bao gm cc cng c dng cho vic bin dch v g li ng dng
B qun l cc thit b o v b gi lp thit b: cho php ngi lp trnh chy th ng dng trn mt hoc nhiu thit
b o thng qua b gi lp trn my tnh c nhn m khng cn thit b di ng tht.
B ti liu tra cu rt chi tit v m t v cch s dng cho tt c cc gi v cc lp, cng nh cc bi vit hu ch
khc.
Cc m ngun mu: b SDK cng i km vi nhng ng dng mu, nhm biu din cc tnh nng ca Android vi
cc v d chi tit v vic s dng cc API

i vi nhng ngi dng Eclipse lm mi trng pht trin tch hp, Google cng pht trin mt trnh cm thm (Plugin)
cho IDE ny gi l Android Developer Tools (ADT), gip vic pht trin ng dng Android tr nn d dng hn rt nhiu.
Bn cnh , Google cng pht trin song song v dn chuyn trng tm qua mt mi trng pht trin mi cho ng dng
Android, tn l Android Studio, da trn phin bn m ngun m ca IDE ni ting IntelliJ IDEA ca JetBrains. Ta s lm
quen vi trnh cm thm ADT cc phn sau ca gio trnh. Android Studio ang dn tr nn ph bin v h tr tt hn
ADT v nhiu mt. Tuy nhin, n thi im hin ti, bn mi nht vn ang trng thi Beta 0.8 nn gio trnh s gii

Lp trnh cho thit b Android 25


Gio trnh Android

thiu mi trng pht trin tch hp ny vo ln ti bn sau.

Cc tng phn mm Android (software stack)

m bo s n gin, tnh dng chung v bo mt trong cc ng dng trn h thng Android, cc th vin cho ng
dng Android c chia ra thnh cc phn tng t thp n cao, cc thnh phn tng trn ch yu s dng cc dch v
do cc tng ngay bn di cung cp m t khi phi dng n cc API ca cc tng thp hn. Kin trc ny c chia ra
thnh cc tng chnh nh trong hnh v di y.

Hnh: Cc lp phn mm trong Android

Nhn Linux (Linux kernel) - bao gm cc dch v li (trnh iu khin phn cng, qun l tin trnh, b nh, mng, ngun
in v bo mt...). Nhn ny l lp tru tng gia phn cng ca thit b v cc lp pha trn.

Cc th vin (libraries) - chy bn trn lp ht nhn, bao gm cc cc th vin li vit bng C/C++ nh libc v SSL, cng
nh cc th vin sau:

Th vin cho vic pht cc loi d liu m thanh v hnh nh

Lp trnh cho thit b Android 26


Gio trnh Android

B qun l b mt (surface manager) cho vic hin th ha trn mn hnh


Cc th vin ha bao gm SGL v OpenGL cho ha 2D v 3D
SQLite cho cc ng dng s dng CSDL
SSL v WebKit cho vic tch hp trnh duyt v bo mt Internet

B thc thi Android (Android runtime) - l mi trng cho cc ng dng Android c th chy c, bao gm cc th
vin li Android (gn nh tng ng vi cc th vin li ca ngn ng Java), cc th vin dnh ring cho Android, v
my o Dalvik nh m t phn trc.

B khung ng dng (Application framework) - cung cp tp cc class pht trin cc ng dng Android. Tng ny
cung cp kh nng giao tip vi phn cng thng qua cc tng bn di cng nh qun l giao din v cc ti nguyn
ca ng dng

Tng ng dng (Application layer) - hu ht cc ng dng (bao gm c ng dng ci sn trong h iu hnh v cc


ng dng ca cc bn th 3) u c pht trin da trn tng ny (dng chung tp API). Tng ng dng c chy
trong b thc thi Android (vi cc th vin li v my o Dalvik), s dng cc lp v cc dch v cung cp bi tng
Application Framework.

Mi trng pht trin

c th bt u lp trnh ng dng cho h iu hnh Android, chng ta cn t nht cc th sau:

B pht trin phn mm Android (Android SDK) nh m t trn, bao gm cc cng c pht trin do Google pht trin
v cc Android API (cc API c download ring bi cng c

Mi trng pht trin tch hp (IDE) dng cho vic vit m ngun vi cc tnh nng nh t ng nh dng m ngun,
t ng hon thin m ngun (gi )... Cc mi trng IDE thng t ng kt ni n Android SDK gip cc thao tc
bin dch, g li, kim th v xut bn ng dng tr nn d dng hn rt nhiu. Cc IDE ph bin cho lp trnh Android c
th k n nh Eclipse (vi plugin ADT ca Google), IntelliJ IDEA, Android Studio...

Thit b chy Android, thng thng l in thoi thng minh chy h iu hnh Android, dng chy th ng dng
trong qu trnh pht trin. Bn cng c th dng trnh gi lp thit b (Android emulator) i km theo b kit pht trin nu
khng c thit b tht, tuy nhin hiu nng ca trnh gi lp thit b Android tng i thp, v mt s tc v c bit lin
quan n phn cng nh lp trnh a phng tin hay truy xut n mt s cm bin s khng chy c trn trnh gi
lp. Hu ht cc v d trong gio trnh ny s chy c tt trn c thit b tht ln trnh gi lp, trong trng hp m
ngun khng chy c trn trnh gi lp s c ch thch ring.

Bn cnh trnh gi lp thit b mc nh i km vi b kit pht trin, bn c c th s dng mt loi my o Android


khc l GenyMotion (http://www.genymotion.com/) vi hiu nng tt hn rt nhiu so vi Android Emulator mc
nh.

Ti v ci t mi trng SDK, IDE

Cch thc n gin nht c c b cng c y , cu hnh sn sng cho vic pht trin l ti gi Eclipse c ng
gi sn trnh cm ADT (Android Developer Tool) ca Google ti a ch http://developer.android.com/sdk/index.html, chn
Download the SDK (ADT Bundle for {OS}).

Lp trnh cho thit b Android 27


Gio trnh Android

Sau khi ti xong Eclipse + ADT (b ng gi sn ca Google), g nn v chy file eclipse.exe, giao din mn hnh ang
khi ng ca IDE ny nh sau:

Hnh: Eclipse vi ADT ang khi ng

Hello Android (Android Hello world)

to d n (project) Android mi, chng ta lm theo cc bc sau:

Bc 1. T Eclipse, chn File > New > Project

Lp trnh cho thit b Android 28


Gio trnh Android

Bc 2. Trong mc Android, chn Android project

Bc 3. t tn cho d n l HelloWorld

Lp trnh cho thit b Android 29


Gio trnh Android

Bc 4. in thng tin cho ng dng cn to:

Tn ng dng (s hin th trn thit b Android)


Package name: chui nh danh duy nht cho ng dng, thng c t c nh dng ging vi nh dng package
ca Java
Chn Create Activity v t tn Activity mc nh ca ng dng. Khi nim activity trong Android ta s tm hiu trong
chng ti, y tm hiu activity l mt mn hnh hay form ca ng dng
Chn mc SDK (tng ng vi phin bn Android) thp nht m ng dng c th h tr
Chn Finish

Lp trnh cho thit b Android 30


Gio trnh Android

Bc 5. Sau khi to xong, project mi s xut hin trong khung Package Explorer ca Android nh hnh di:

Lp trnh cho thit b Android 31


Gio trnh Android

Bc 6. Trong th mc res/layout , ta thy c file main.xml . y l file m t giao din ca ng dng HelloWorld ca
chng ta. Kch p vo file ny, ca s son tho giao din s c m ra nh hnh di. thay i giao din bng tay
(XML code), ta chuyn sang tab main.xml

Lp trnh cho thit b Android 32


Gio trnh Android

Bc 7. Thm on code di y vo file main.xml:

<?xml version="1.0" encoding="utf-8"?>


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >

<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello" />

<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="This is my first Android Application!" />

<Button
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="And this is a clickable button!" />

</LinearLayout>

Bc 8. Ghi file (Ctrl+S) v chy ng dng trn thit b o bng cch nhy phi chut vo project, chn Run As >
Android Application

Lp trnh cho thit b Android 33


Gio trnh Android

Bc 9. ng dng sau khi chy s c hnh nh sau:

Lp trnh cho thit b Android 34


Gio trnh Android

Bc 10. Click vo nt Home (biu tng ngi nh trong cc phm o bn phi mn hnh emulator) n ng dng v
hin th mn hnh ch ca h iu hnh Android. Sau bm nt danh sch ng dng , ta s thy ng dng HelloWorld
ca chng ta xut hin trong danh sch cc ng dng c ci t:

Lp trnh cho thit b Android 35


Gio trnh Android

Nh vy ng dng HelloWorld c bin dch v chy thnh cng trn thit b o (i vi thit b tht cng vy).
hiu c ng dng chy nh th no, trc tin ta s tm hiu cu trc ca mt ng dng Android v cc khi nim c
bn s dng trong d n ny.

Cu trc ca mt d n Android

Mt b m ngun ca ng dng Android thng bao gm cc thnh phn nh sau:

src th mc cha cc file m ngun Java, cc file m ngun ny c t trong cc th mc con ca th mc

src , tng ng vi package cha n. Trong v d trn, ta ch c 1 file m ngun l HelloWorldActivity.java , nm

trong package vn.edu.humg.android_course.HelloWorld .


gen th mc cha file R.java , file ny c trnh bin dch t ng sinh ra, cha tham chiu n tt c cc ti

nguyn (nh, chui, mu sc, kch thc, layout) s dng trong d n. y l file t sinh ra, ta khng cn t chnh
sa file ny trong mi trng hp.
Android x.x cha file android.jar , bao gm tt c cc lp trong th vin Android cn thit cho ng dng, file ny

cng t ng c gn vo d n, ty thuc vo mc API bn chn trc .


assets th mc cha cc ti nguyn tnh khc c s dng trong ng dung, nh HTML, font, file CSDL

bin cha cc file tm trong qu trnh bin dch, trong c file .apk , l file nh phn ca ng dng Android. File

.apk l file ng gi ton b mi th cn thit chy ng dng. Ni dung th mc ny cng do trnh bin dch t

ng sinh ra, ta khng cn can thip bng tay.


res th mc cha tt c cc ti nguyn c s dng trong ng dng nh: hnh nh (drawable), b cc giao din

(layout), cc chui, mu sc, kch thc (values). Chng ta s xem chi tit v cc loi ti nguyn ny trong cc
chng k tip.
AndroidManifest.xml l file c t ng dng. Mi ng dng Android u cn c file ny. H thng s c file ny lc

ci t xc nh cc quyn cn cp cho ng dng, cc activity c trong ng dng, v nhiu tnh nng khc. Chi tit

Lp trnh cho thit b Android 36


Gio trnh Android

v file c t ny s c cp n phn di.

File m ngun duy nht chng ta s dng trong d n HelloWorld l HelloWorldActivity.java . Ni dung file ny nh sau:

package vn.edu.humg.android_course.HelloWorld;

import android.app.Activity;
import android.os.Bundle;

public class HelloWorldActivity extends Activity {


/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
}

Lp HelloWorldActivity k tha t lp android.app.Activity vi ci t hm onCreate (hm ny c gi khi Acticity


c khi to). Trong thn hm ngoi vic gi hm dng (hm khi to) ca lp cha, ch cha mt dng duy nht
setContentView(R.layout.main); dng ny ch ra activity hin ti s s dng giao din khai bo trong file main.xml nm

trong th mc res/layout . File ny c bin dch v tham chiu n trong file R.java di tn R.layout.main .

Activity ny c th c s dng v m ra u tin khi ng dng c chy trn thit b, n cn phi c khai bo
trong file AndroidManifest.xml nh sau:

<?xml version="1.0" encoding="utf-8"?>


<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="vn.edu.humg.android_course.HelloWorld"
android:versionCode="1"
android:versionName="1.0" >

<uses-sdk android:minSdkVersion="13" />

<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name" >
<activity
android:label="@string/app_name"
android:name=".HelloWorldActivity" >
<intent-filter >
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>

Cc thnh phn chnh ca file AndroidManifest.xml :

Khai bo package name nh danh duy nht ca ng dng trn h thng Android
( vn.edu.humg.android_course.HelloWorld )
Phin bn ca ng dng (tn m v tn hin th ca phin bn): android:versionCode , android:versionName . Trong
versionCode l s nguyn, c s dng cho h thng, nhm xc nh khi no ng dng c phin bn mi hn, cn

versionName l chui cha tn ca phin bn hin th ln cho ngi dng.

android:minSdkVersion khai bo mc API thp nht m ng dng cn chy, thit b chy Android vi phin bn

thp hn mc API ny s khng ci t c ng dng ang pht trin.


android:icon="@drawable/ic_launcher" khai bo s dng file nh ic_launcher.png trong th mc res/drawable

lm biu tng cho ng dng


android:label="@string/app_name" khai bo s dng chui c tn l app_name trong file string.xml lm tn ca ng

dng (chui ny c gi tr l HelloWorld)

Lp trnh cho thit b Android 37


Gio trnh Android

File manifest ny cng khai bo cc activity c trong ng dng, trong v d ca chng ta ch c 1 activity l
.HelloWorldActivity , du chm ( . ) u tn Activity ch ra rng activity ny nm trong package cng tn vi

package name ca ng dng ( vn.edu.humg.android_course.HelloWorld.HelloWorldActivity ). Bn trong khai bo Activity


ny c thm mc intent-filter vi <action android:name= "android.intent.action.MAIN"/> ch ra rng y l Activity
cn m ra u tin khi chy ng dng, v <category android:name= "android.intent.category.LAUNCHER"/> ch ra rng
Activity ny s c to biu tng (shortcut) trn mn hnh ch ca Android.

File main.xml trong th mc res/layout (nh m t trn) cha m t giao din ca activity HelloWorldActivity , bao
gm khai bo 2 on ch ( TextView ) ( @string/hello v "This is my first Android Application!") v mt nt bm vi ni
dung "And this is a clickable button!". Ba thnh phn ny c sp xp th t t trn xung di do chng c t trong
mt LinearLayout vi tham s hng l theo chiu dc ( android:orientation="vertical" ).

Ta c th thy TextView th 2 c khai bo ni dung dng ch mt cch tng minh ("This is my first Android
Application!"), trong khi TextView u tin c khai bo bng tn ca hng s chui nm trong th mc ti nguyn ca
ng dng ( res/values/string.xml ) xem hnh di. y l cch cung cp ti nguyn ph bin trong Android, gip cho
vic qun l cc hng s mt cch tp trung v d dng cho vic a phng ha (localization) cc chui (a ngn ng).
Chng ta s tm hiu thm v vn ny cc chng sau.

Chng ta kt thc d n HelloWorld y. Chng tip theo s tm hiu su hn v thnh phn quan trng nht ca ng
dng Android l cc Activity v mt s khi nim lin quan.

Lp trnh cho thit b Android 38


Gio trnh Android

Cc Activity, Fragment v Intent


Trong chng trc, chng ta bit Activity l mt ca s (hay mn hnh, form) cha giao din ca ng dng Android.
y l thnh phn ph bin v quan trng nht trong mi ng dng Android. Thng thng mi ng dng c th c t nht
mt hoc nhiu activity, l ni ngi dng tng tc vi ng dng (tuy nhin c nhng ng dng c bit khng cha mt
activity no, nh nhng ng dng chy ngm khng c giao din). Trong qu trnh thc thi ng dng, k t khi c khi
to n lc bin mt khi mn hnh in thoi, mi activity s tri qua mt s cc trng thi nht nh, gi l vng i ca
Activity. Mi lp trnh vin Android cn phi nm vng cc trng thi trong vng i ca cc Activity c nhng x l ph
hp nh lu li trng thi d liu trc khi Activity bin mt hay khi phc li trng thi d liu khi Activity c khi
phc

Ngoi Activity, Android t phin bn 3.0 (API mc 11) tr ln c gii thiu thm khi nim mnh giao din, hay fragment.
Fragment c th c hiu nh cc mnh ghp ca giao din ng dng l mt phn ca Activity. Mi Activity c th
cha mt hoc nhiu mnh ghp ny trong giao din ca mnh v mi mnh ghp li c th c chn vo nhiu
Activity khc nhau. iu ny cho php gim thiu ti a s trng lp v m ngun trong vic to giao din ng dng thch
nghi c vi nhiu loi kch c v hng mn hnh. Cc ng dng vit cho cc phin bn h iu hnh thp hn cng c
th s dng Fragment bng cch s dng th vin h tr ca Android (Android Support Library). Th vin ny cung cp
cc tnh nng ca cc API mi cho cc ng dng vit cho API mc thp hn, trong Android Support Library v4 cho
php cc ng dng vit cho API 4 (Android 1.6) tr ln s dng c Fragment v nhiu tnh nng khc ca cc API mc
cao hn.

Chng ta s tm hiu k hn v Activity v Fragment trong phn tip theo ca chng ny. Mt khi nim quan trng khc
ca h iu hnh Android l Intent. Intent c hiu mt cch nm na ging nh keo dn gia cc thnh phn ca h
iu hnh, gip cc activity ca cng mt ng dng hoc cc ng dng khc nhau c th tng tc vi nhau thc hin
cng vic mt cch tri chy, ging nh cc activity cng thuc mt ng dng. Ngi lp trnh cng c th s dng
Intent gi cc ng dng c sn ca h iu hnh nh trnh duyt, trnh gi in, gi tin nhn, bn Chng ta s tm
hiu k hn v cc Activty v Intent trong phn tip theo ca gio trnh.

Cc Activity, Fragment v Intent 39


Gio trnh Android

Activity

Vng i ca Activity

Mi activity l mt lp (class) k tha t lp android.app.Activity hoc cc lp k tha t n. Ta xem li Activity trong v


d chng trc:

package vn.edu.humg.android_course.HelloWorld;
import android.app.Activity;
import android.os.Bundle;

public class HelloWorldActivity extends Activity {


/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
}

Activity ny s dng giao din c khai bo trong file b cc main.xml , trong th mc res/layout bng cch gi lnh:
setContentView(R.layout.main) ;

Cng nhc li l mi Activity cn c khai bo trong file c t ng dng ( AndroidManifest.xml ) nh cp trong


chng trc.

Vng i ca mi Activity tri qua cc trng thi nht nh. Ti mi trng thi s c s kin tng ng c gi n. Cc
s kin ny c khai bo trong lp c s ( android.app.Activity ). Chng ta c th np chng cc s kin ny theo
di vng i ca Activity v c nhng tc ng thch hp. Cc s kin nh vy bao gm:

onCreate() c gi khi Activity c khi to

onStart() c gi khi Activity bt u hin ra (chng ta bt u nhn thy giao din)

onResume() bt u nhn cc tng tc vi ngi dng

onPause() c gi khi activity bi dng li chuyn qua activity khc

onStop() c gi khi activity bin mt khi mn hnh

onDestroy() c gi khi activity b hy (hy ch ng hoc b hy bi h thng trong trng hp h iu hnh xc

nhn thiu RAM)


onRestart() c gi khi activity c khi ng li sau khi b dng

Theo mc nh, Eclipse ADT s to sn hm onCreate() cho mi Activity mi c to ra. Thng thng ngi lp trnh
s vit m ngun (code) lin quan n vic khi to giao din ha trong thn hm ny.

Vng i ca mt Activity c m t trong s di y:

Activity 40
Gio trnh Android

Hnh: Vng i ca mt Activity

hiu r hn vng i ca mt Activity, chng ta vit mt Activity n gin, np chng tt c cc hm s kin k trn v
ghi ra log tng ng:

public class Activity101Activity extends Activity {


String tag = "Lifecycle";

/** Called when the activity is first created. */


@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//---hides the title bar---
requestWindowFeature(Window.FEATURE_NO_TITLE);

setContentView(R.layout.main);
Log.d(tag, "In the onCreate() event");
}

public void onStart()


{
super.onStart();
Log.d(tag, "In the onStart() event");
}

public void onRestart()

Activity 41
Gio trnh Android

{
super.onRestart();
Log.d(tag, "In the onRestart() event");
}

public void onResume()


{
super.onResume();
Log.d(tag, "In the onResume() event");
}

public void onPause()


{
super.onPause();
Log.d(tag, "In the onPause() event");
}

public void onStop()


{
super.onStop();
Log.d(tag, "In the onStop() event");
}

public void onDestroy()


{
super.onDestroy();
Log.d(tag, "In the onDestroy() event");
}
}

Chy ng dng ny trn thit b Android, thc hin cc thao tc bm phm Home, Back, m activity khc v theo di th
t ca cc s kin trn trong ca s LogCat s cho ta khi nim chnh xc nht v vng i ca cc Activity. Phn ny coi
nh bi tp.

Ca s hp thoi (Dialog)

Trong rt nhiu trng hp chng ta cn hin th thng bo, hi xc nhn ca ngi dng, hin th trng thi ch dng
hp thoi nhanh hin ln trn Activity hin ti m khng cn m ra Activity mi, khi ta np chng hm onCreateDialog
ca lp c s android.app.Activity .

V d di y m t cch to mt hp thoi c bn:

Bc 1. To project mi trong Eclipse, t tn l Dialog

Bc 2. Thm mt nt bm vo file main.xml vi on m sau:

<?xml version="1.0" encoding="utf-8"?>


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >

<Button
android:id="@+id/btn_dialog"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Click to display a dialog"
android:onClick="onClick" />
</LinearLayout>

Bc 3. tham s android:onClick="onClick" ca nt bm btn_dialog . Tham s ny ch ra rng bn cn khai vo mt


phng thc tn l onClick trong Activity x l s kin khi nt bm ny c chn.

Bc 4. Thm on m sau vo DialogActivity.java :

Activity 42
Gio trnh Android

public class DialogActivity extends Activity {


CharSequence[] items = { "Google", "Apple", "Microsoft" };
boolean[] itemsChecked = new boolean [items.length];

ProgressDialog progressDialog;

/** Called when the activity is first created. */


@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}

public void onClick(View v) {


showDialog(0);
}

@Override
protected Dialog onCreateDialog(int id) {
switch (id) {
case 0:
return new AlertDialog.Builder(this)
.setIcon(R.drawable.ic_launcher)
.setTitle("This is a dialog with some simple text...")
.setPositiveButton("OK",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
Toast.makeText(getBaseContext(), "OK clicked!", Toast.LENGTH_SHORT).show();
}
})
.setNegativeButton("Cancel",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
Toast.makeText(getBaseContext(), "Cancel clicked!", Toast.LENGTH_SHORT).show();
}
})
.setMultiChoiceItems(items, itemsChecked,
new DialogInterface.OnMultiChoiceClickListener() { public void onClick(DialogInterface dialog,
Toast.makeText(getBaseContext(), items[which] + (isChecked ? " checked!":" unchecked!"), Toast.LENGTH_SHORT).show()
}
}).create();
}
return null;
}
}

Bc 5. Chy ng dng v bm vo nt Click to display a dialog. Ta s quan st thy hp thoi tng ng hin ra.

Trong v d trn ta np chng phng thc onCreateDialog(int id) hin th hp thoi khi c yu cu. Trong Activity
c th hin th nhiu hp thoi khc nhau ty vo tnh hung nh hp thoi thng bo, hp thoi xc nhn, hp thoi tin
trnh, tham s id trong phng thc onCreateDialog c dng phn bit hp thoi no cn c hin ln.

kch hot yu cu m hp thoi, ta gi phng thc showDialog(0) . Phng thc ny c gi khi ta bm vo nt


Click to display a dialog ,

Trong hm onCreateDialog , ty thuc vo id truyn vo m ta hin th hp thoi tng ng, trong v d trn l hp thoi
c id = 0 . Trong trng hp ny ta s dng loi hp thoi n gin nht l AlertDialog. to ra mt hp thoi loi ny,
ta to ra mt i tng (object) ca lp (class) AlertDialog.Builder v gi phng thc create() ca n. on code trn
thit lp 2 nt bm cho hp thoi cho hai trng hp: ng (nt OK setPositiveButton ) v hy b (nt Cancel
setNegativeButton ), cng nh thit lp cc hp ty chn (checkbox) bng setMultiChoiceItems .

Cc hm x l s kin ca Dialog trong v d ch n gin l hin th ln mn hnh dng thng bo dng text trong mt
khong thi gian ngn. Dng thng bo ny trong Android gi l Toast - l on ch hin th gia, pha di mn hnh
trong khong vi giy. Toast thng c dng hin th cc loi thng bo ngn, t quan trng nh thng bo SMS
c gi, thng bo mt tin trnh ngm hon thnh

Activity 43
Gio trnh Android

Ta c th to thm cc nt bm v hin th cc hp thoi khc tng ng bng cch truyn id khc nhau cho hm
showDialog() , v d: nt bm 1 showDialog(0) , nt bm 2 showDialog(1) C rt nhiu cc loi hp thoi khc nhau

trong h iu hnh Android nh hp thoi ch (vi biu tng quay quay) hay hp thoi th hin tin trnh (c thanh tin
trnh theo %), thm ch bn c th to ring mt b cc (layout) bng file .xml cho hp thoi. Bn c t tm hiu thm.
Phn ny coi nh bi tp.

i tng Context trong Android

Trong Android, rt nhiu phng thc ly mt trong nhng tham s l mt i tng ca lp Context. Trong v d trn,
hm dng ca lp AlertDialog.Builder v hm Toast.makeText u nhn tham s kiu Context. i tng kiu Context
ny thng dng ch ra phm vi, hay ng cnh ca phng thc c gi v thng tr n ng dng hoc activity
hin ti.

v d trn ta thy i tng ca lp AlertDialog.Builder c gi vi tham s this: new AlertDialog.Builder(this) . i


tng this y l Activity hin ti (Activity cng l lp con chu ca lp Context), trong khi hm Toast.makeText nhn
tham s Context l getBaseContext() ch khng c dng con tr this na, bi v phng thc ny c gi bn trong
i tng ca lp DialogInterface.OnClickListener() , con tr this y c kiu OnClickListener ch khng phi Activity,
nn khng phi l Context. V vy, ta dng hm getBaseContext() ly Context c s ca i tng hin ti. Mt cch
khc c th s dng l dng DialogActivity.this .

Activity 44
Gio trnh Android

Intent v vic tng tc gia cc Activity


Nh cp cc phn trn, mi ng dng Android c th khng c, c mt hoc nhiu Activity. Khi ng dng c nhiu
hn mt Activity th vic iu hng t Activity ny sang Activity khc v ngc li l vic rt cn thit v c thc hin
rt thng xuyn. Trong Android, vic iu hng ny c thc hin thng qua mt c ch rt c th, gi l Intent.

S dng Intent

Trc tin ta xem xt mt v d n gin nht s dng Intent m mt Activity khc t Activity hin ti. thc hin
iu ny ta to mt project cha 2 Activity, trong Activity th nht c mt nt bm, khi bm vo nt ny s m Activity th
2. Cc bc c th nh sau:

Bc 1. To project UsingIntent v to 2 Activity: UsingIntentActivity (Activity mc nh) v SencondActivity , 2 activity


ny c khai bo trong AndroidManifest.xml nh sau:

<activity
android:label="@string/app_name"
android:name=".UsingIntentActivity" >
<intent-filter >
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:label="Second Activity"
android:name=".SecondActivity" >
<intent-filter >
<action android:name="vn.edu.humg.android_course.SecondActivity" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>

Bc 2. To layout ring cho SecondActivity bng cch copy file main.xml thnh file secondactivity.xml v sa ni dung
TextView nh bn di. Sau trong hm onCreate ca SecondActivity, gi lnh
setContentView(R.layout.secondactivity); khai bo vic s dng file layout ny cho SecondActivity.

<?xml version="1.0" encoding="utf-8"?>


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >

<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="This is the Second Activity!" />
</LinearLayout>

Bc 3. To mt nt bm trong UsingIntentActivity v trong hm x l s kin onClick ca nt bm ny, ta gi lnh m


Activity th 2 nh sau:

startActivity(new Intent("vn.edu.humg.android_course.SecondActivity"));

Bc 4. Chy ng dng v bm vo nt bm duy nht trong UsingIntentActivity, ta s thy SecondActivity c m ra:

Intent v vic tng tc gia cc Activity 45


Gio trnh Android

Trong v v trn, ta thy dng lnh m ra Activity th 2 l startActivity(new


Intent("vn.edu.humg.android_course.SecondActivity")); . Trong tham s ca hm dng Intent khng h ch ra tn Class ca

SecondActivity m ch ra action cn thc hin, khi h iu hnh s qut ton b cc Activity ca ton b cc ng
dng c ci t trn thit b v lc ra Activity c khai bo action tng ng (vn.edu.humg.android_course.SecondActivity)
m n. Trong trng hp ca chng ta, action ca SecondActivity c khai bo trong phn intent-filter ca activity
trong file AndroidManifest.xml (<action android:name="vn.edu.humg.android_course.SecondActivity" />) nn s c m ra.
Ngoi ra cng phi ch l, activity c th c m ra bng phng thc startActivity nh trong v d, th trong
Manifest cng phi khai bo thm danh mc (category) android.intent.category.DEFAULT trong phn intent-filter (<category
android:name="android.intent.category.DEFAULT" />) . Trong trng hp Activity cn m nm trong cng ng dng vi

Activity m n (nh trong v d trn ca ta), ta c th gi startActivity vi Intent tng minh nh sau:

startActivity(new Intent(this, SecondActivity.class));

Gii quyt xung t Intent

Trong v d trn ta thy m mt Activity, ta ch cn truyn vo action ca Activity . H thng s qut tm kim Activity
c khai bo vi action nh vy m ra. Vy iu g s xy ra nu c nhiu hn 1 Activity khai bo vi cng mt action
nh vy?

Chng hn ta khai bo thm mt Activity th 3 vi cng intent-filter ging nh ca SecondActivity:

<activity
android:label="Third Activity"
android:name=".ThirdActivity" >

Intent v vic tng tc gia cc Activity 46


Gio trnh Android

<intent-filter >
<action android:name="vn.edu.humg.android_course.SecondActivity" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>

V gi nguyn li gi Activity nh c:

startActivity(new Intent("vn.edu.humg.android_course.SecondActivity"));

Khi c gi n, h thng s hin th danh sch cc Activity ph hp theo b lc Intent (trong trng hp ny l 02
Activity) ngi dng chn. Km theo ca s chn s l hp chn Use by default for this action. Nu bn chn hp
chn ny th h thng s ghi nh la chn ca bn v khng hi li cho cc ln sau na, nu khng ca s chn Activity
cn m s hin th mi ln bn gi hm startActivity k trn. Nu l chn ghi nh la chn mc nh ny, bn c th
xa ghi nh ny bng cch vo mc Settings ca h thng, chn Apps > Manage Applications, sau chn ng dng
ang dng (UsingIntent) v chn nt Clear defaults pha cui mn hnh. Cc hnh nh di y minh ha cc tnh
hung ni trn:

Cc ng dng mc nh sn c ca h iu hnh Android cng c m ra bng c ch Intent vi cc b lc nh vy. C


ch ny lm h iu hnh Android tr nn v cng mm do: mi thnh phn ca h iu hnh u c i x nh nhau
v u c kh nng thay th c. V d, bn c th vit mt ng dng x l tin nhn SMS thay cho ng dng Message
mc nh bng cch khai bo action cho Activity ca bn trng vi action ca ng dng tin nhn mc nh (cc intent
action ny c m t rt y trong cc ti liu tham kho ca Google). Nh vy, khi c yu cu gi tin nhn t mt
ng dng bt k, h thng s lit k ra cc ng dng c kh nng x l yu cu ny cho ngi dng la chn, bao gm
ng dng tin nhn mc nh v ng dng chng ta mi vit.

Ly kt qu tr v t Activity thng qua Intent

Trong rt nhiu trng hp, ta m Activty mi vi mc ch yu cu thm d liu t ngi dng, nh yu cu ngi dng
nhp vo tn truy cp v mt khu Trong trng hp , sau khi ngi dng kt thc nhp liu v quay tr li Activity
trc , d liu ngi dng va nhp vo cn phi c truyn v Activity ban u x l. lm c iu ny,
trong Activty th nht (UsingIntentActivity trn) thay v m Activity th 2 (SecondActivity) bng phng thc startActivity,
ta cn gi phng thc startActivityForResult v khai bo thm phng thc onActivityResult hng s kin khi
SecondActivity ng li v tr v d liu cho n. Bn cnh , trong SecondActivity cng phi cha on m tr v d liu
ngi dng nhp vo thng qua Intent. minh ha cho qu trnh trn, ta thc hin cc bc sau:

Intent v vic tng tc gia cc Activity 47


Gio trnh Android

Bc 1. Trong SecondActivity, thm mt nhp liu v mt nt bm nh sau:

<EditText
android:id="@+id/txt_username"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />

<Button
android:id="@+id/btn_OK"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="OK"
android:onClick="onClick"/>

Bc 2. Trong hm x l s kin click ca nt OK ca SecondActivity, ta thm on m cho Activity gc (Activity gi n,


trong v d l UsingIntentActivity) trc khi ng li:

Intent data = new Intent();


//---get the EditText view---
EditText txt_username = (EditText) findViewById(R.id.txt_username);

//---set the data to pass back---


data.setData(Uri.parse(txt_username.getText().toString()));
setResult(RESULT_OK, data);

//---closes the activity


finish();

Bc 3. Trong UsingIntentActivity, thay v m SecondActivity bng phng thc startActivity , ta dng


startActivityForResult km theo tham s th hai l mt m yu cu (request code) t quy nh (chn bng 1 chng hn):

startActivityForResult(new Intent("vn.edu.humg.android_course.SecondActivity"), 1);

Bc 4. V khai bo np chng hm hng s kin Activity tr kt qu v (onActivityResult) . Khi nhn c kt qu

Intent v vic tng tc gia cc Activity 48


Gio trnh Android

(dng chui) t SecondActivity, vi mc ch minh ha, ta ch hin th text ny ln mn hnh di dng Toast message :

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data)
{
if (requestCode == 1) {
if (resultCode == RESULT_OK) {
Toast.makeText(this,data.getData().toString(), Toast.LENGTH_SHORT).show();
}
}
}

Bc 5. Kt qu thu c khi chy ng dng s nh hnh bn di:

Truyn d liu gia cc Activity vi Intent

Ngoi vic ly d liu tr v ca Activity, mt thao tc ph bin khc l truyn d liu cho Activity mi c m ra. V d
trong trng hp trn, khi gi m SecondActivity ta c th truyn chui mc nh cn hin th sn trong nhp liu ca
Activity ny. lm c iu ny, trong UsingIntentActivity, trc khi gi startActivity , ta gn d liu cn truyn vo
i tng Intent dng m SecondActivity bng phng thc putExtra ca i tng Intent nh sau:

Intent i = new Intent("vn.edu.humg.android_course.PassingDataSecondActivity");

//---use putExtra() to add new key/value pairs---


i.putExtra("str1", "This is a string");

Intent v vic tng tc gia cc Activity 49


Gio trnh Android

i.putExtra("age1", 25);

//---use a Bundle object to add new key/values pairs---


Bundle extras = new Bundle();
extras.putString("str2", "This is another string");
extras.putInt("age2", 35);

//---attach the Bundle object to the Intent object---


i.putExtras(extras);

//---start the activity


startActivityForResult(i);

Khi , trong hm onCreate ca SecondActivity, ta c th ly d liu c truyn sang bng cch ly Intent qua hm
getIntent() v ln lt ly ra cc trng d liu tng ng bng cc phng thc getStringExtra , getIntExtra ,

getExtras nh sau:

//---get the data passed in using getStringExtra()---


Toast.makeText(this,getIntent().getStringExtra("str1"), Toast.LENGTH_SHORT).show();

//---get the data passed in using getIntExtra()---


Toast.makeText(this,Integer.toString(getIntent().getIntExtra("age1", 0)), Toast.LENGTH_SHORT).show();

//---get the Bundle object passed in---


Bundle bundle = getIntent().getExtras();

//---get the data using the getString()---


Toast.makeText(this, bundle.getString("str2"), Toast.LENGTH_SHORT).show();

//---get the data using the getInt() method---


Toast.makeText(this,Integer.toString(bundle.getInt("age2")),Toast.LENGTH_SHORT).show();

S dng Intent gi cc ng dng sn c ca h iu hnh

Nh ni trn, cc ng dng mc nh sn c ca h iu hnh Android cng c m ra bng c ch Intent nh cc


ng dng thng thng. T ng dng ca mnh, chng ta c th dng Intent m trnh duyt vi mt website chn,
hay m ng dng gi tin nhn vi s in thoi v ni dung tin nhn chn sn. Phn ny s a ra vi v d c th s
dng Intent trong cc vic nh vy.

M trnh duyt web:

Intent i = new Intent("android.intent.action.VIEW");


i.setData(Uri.parse("http://www.amazon.com"));
startActivity(i);

Kt qu:

Intent v vic tng tc gia cc Activity 50


Gio trnh Android

M ng dng gi in thoi:

Intent i = new Intent(android.content.Intent.ACTION_DIAL, Uri.parse("tel:+651234567"));


startActivity(i);

Intent v vic tng tc gia cc Activity 51


Gio trnh Android

M ng dng bn v iu hng n v tr nht nh:

Intent i = new Intent(android.content.Intent.ACTION_VIEW, Uri.parse("geo:37.827500,-122.481670"));


startActivity(i);

Intent v vic tng tc gia cc Activity 52


Gio trnh Android

i tng Intent

cc v d trn ta xem qua mt s cch s dng Intent khc nhau, phn ny s tng hp li m t chi tit hn v i
tng Intent.

Mi i tng Intent (Intent Object) c th cha cc thng tin sau:

Action (hnh ng)


Data (d liu)
Type (kiu d liu)
Category (loi)

Trong v d trn, ta thy m Activity khc, ta cn truyn Action ca activity trong hm dng ca i tng Intent
nh sau:

startActivity(new Intent(vn.edu.humg.android_course.SecondActivity));

Action y ( vn.edu.humg.android_course.SecondActivity) cn c gi l component name. Trong trng hp


Activity cn m nm cng d n (project) vi Activity hin ti, ta c th gi nh sau:

startActivity(newIntent(this, SecondActivity.class));

Intent v vic tng tc gia cc Activity 53


Gio trnh Android

Activity cng c th c gi bng cch truyn Action v d liu (Data) km theo nh trong trng hp m trnh duyt
trn:

Intent i = new Intent(android.content.Intent.ACTION_VIEW,


Uri.parse(http://www.amazon.com));
startActivity(i);

Phn hnh ng m t vic chng ta cn lm, cn phn d liu cha thng tin cn thit cho Activity sp c m ra x
l. Trong v d trn, ta to Intent vi yu cu cn hin th thng tin, vi d liu i km l a ch url ca mt website. H
thng Android s lc trong tt c cc ng dng c ci t trn h thng v lit k ra cc ng dng c th x l c
Intent ny ngi dng la chn.

Intent trn cng c th c truyn d liu tng minh hn nh sau:

Intent i = new Intent(android.intent.action.VIEW);


i.setData(Uri.parse(http://www.amazon.com));

Mt s Intent khng cn truyn d liu c th, m ch cn truyn theo kiu d liu. V d, ly mt bn ghi trong danh
sch danh b, ta c th dng Intent nh sau:

Intent i = new
Intent(android.content.Intent.ACTION_PICK);
i.setType(ContactsContract.Contacts.CONTENT_TYPE);

Hm setType() ch ra kiu d liu (MIME data type) ca thng tin tr v cho activity hin ti. Kiu d liu ca
ContactsContract.Contacts.CONTENT_TYPE l xu vnd.android.cursor.dir/contact .

Ngoi hnh ng, d liu v kiu d liu, mi i tng Intent c th c thm tham s loi (category) dng nhm cc
Activity li theo loi thun tin cho vic lc cc Activity theo nhu cu ca ng dng. bn c c th tm hiu k hn v
b lc Activity cc ti liu khc. Phn ny coi nh bi tp.

Intent v vic tng tc gia cc Activity 54


Gio trnh Android

Fragment
Trong phn trc ta tm hiu qua v Activty, l giao din ca mt mn hnh ng dng, mi mn hnh ch cha 01
Activity. Tuy nhin, khi cc my tnh bng ra i vi mn hnh ln hn rt nhiu so vi in thoi truyn thng, cho php
thit k vi nhiu loi view khc nhau, v pht sinh nhu cu dng li cc view ny trn cc mn hnh khc nhau (in thoi
v my tnh bng). Khi nim fragment (mnh) c sinh ra nhm phc v nhu cu . C th hiu fragment nh cc tiu
Activity, cha tp hp cc view khc bn trong n. Fragment lun lun c cha trong mt Activity hoc fragment khc,
mi Activity c th cha mt hoc nhiu fragment . Mt v d in hnh ca vic s dng fragment l trng hp thit k
master-detail, bao gm 2 view: view chnh (master) cha danh sch cc i tng (danh sch tiu cc bi bo chng
hn), v view chi tit (detail), hin th ni dung chi tit ca i tng (bi bo) ang c chn. Mi view nh vy c t
trong 1 fragement. Trn mn hnh in thoi, do kch thc hn ch, 2 fragement ny s nm trong 2 activity khc nhau,
trong khi i vi mn hnh my tnh bng, 2 fragment ny nm trn cng mt Activity (xem hnh di). Thit k ny gip
vic dng li m c ti a. Tng logic ca ng dng (nm trong 2 fragment), c dng li cho c in thoi v my
tnh bng, cn Activity ch l v cha ti thiu m ngun.

Khi nim fragment mi c a vo t phin bn Android 3.0 HoneyComb. Tuy nhin tnh nng ny cng c Google
b sung cho cc API thp hn (t Level 4) thng qua th vin h tr Android Support Library v4.

Fragment 55
Gio trnh Android

Sau y l mt v d v mt ng dng c 2 fragment ni trn.

Bc 1. To project mi, t tn l Fragments

Bc 2. To file fragment1.xml trong res/layout, y l file cha m t giao din ca fragment th nht, vi ni dung nh
sau:

<?xml version="1.0" encoding="utf-8"?>


<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#00FF00"
>
<TextView
android:id="@+id/lblFragment1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="This is fragment #1"
android:textColor="#000000"
android:textSize="25sp" />
</LinearLayout>

Bc 3. To file fragment2.xml trong res/layout, y l file cha m t giao din ca fragment th hai, vi ni dung nh
sau:

<?xml version="1.0" encoding="utf-8"?>


<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#FFFE00"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="This is fragment #2"
android:textColor="#000000"
android:textSize="25sp" />

<Button
android:id="@+id/btnGetText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Get text in Fragment #1"
android:textColor="#000000"
android:onClick="onClick" />

</LinearLayout>

Bc4. Sa ni dung file main.xml nh sau:

<?xml version="1.0" encoding="utf-8"?>


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal" >

<fragment
android:name="vn.edu.humg.android_course.Fragments.Fragment1"
android:id="@+id/fragment1"
android:layout_weight="1"
android:layout_width="0px"
android:layout_height="match_parent" />
<fragment

Fragment 56
Gio trnh Android

android:name="vn.edu.humg.android_course.Fragments.Fragment2"
android:id="@+id/fragment2"
android:layout_weight="1"
android:layout_width="0px"
android:layout_height="match_parent" />

</LinearLayout>

Bc 5. To file Fragment1.java v Fragment2.java trong namespace mc nh ca ng dng:

Bc 6. Ni dung file Fragment1.java:

public class Fragment1 extends Fragment {


@Override
public View onCreateView(LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {

Log.d("Fragment 1", "onCreateView");

//---Inflate the layout for this fragment---


return inflater.inflate(
R.layout.fragment1, container, false);
}
}

Bc7. Ni dung file Fragment2.java:

public class Fragment2 extends Fragment {


@Override
public View onCreateView(LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
//---Inflate the layout for this fragment---
return inflater.inflate(
R.layout.fragment2, container, false);
}

@Override

Fragment 57
Gio trnh Android

public void onStart() {


super.onStart();
//---Button view---
Button btnGetText = (Button)
getActivity().findViewById(R.id.btnGetText);
btnGetText.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
TextView lbl = (TextView)
getActivity().findViewById(R.id.lblFragment1);
Toast.makeText(getActivity(), lbl.getText(),
Toast.LENGTH_SHORT).show();
}
});
}
}

Bc 8. Sau khi chy:

Thm fragment trong thi gian thc thi

Bc 1. Sa li file main.xml , xa b khai bo 2 fragment trong ny:

<?xml version="1.0" encoding="utf-8"?>


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal" >

</LinearLayout>

Bc 2. Sa hm onCreate ca FramentActivity nh sau:

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction =

Fragment 58
Gio trnh Android

fragmentManager.beginTransaction();

//---get the current display info---


WindowManager wm = getWindowManager();
Display d = wm.getDefaultDisplay();
if (d.getWidth() > d.getHeight())
{
//---landscape mode---
Fragment1 fragment1 = new Fragment1();
// android.R.id.content refers to the content
// view of the activity
fragmentTransaction.replace(
android.R.id.content, fragment1);
}
else
{
//---portrait mode---
Fragment2 fragment2 = new Fragment2();
fragmentTransaction.replace(
android.R.id.content, fragment2);
}
//---add to the back stack---
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
}

Chy ng dng v thay i hng ca mn hnh (bt auto-rotate (t ng xoay) trn thit b v quay mn hnh theo hng
cn thit, hoc bm Ctrl+F11 nu ang chy trn emulator), ta s quan st thy 2 fragment khc nhau c gn vo
Activity khi thit b ang 2 hng khc nhau nh hnh di:

Fragment 59
Gio trnh Android

Fragment 60
Gio trnh Android

Vng i ca Fragment

Fragment 61
Gio trnh Android

hiu r hn vng i ca mt Frament, chng ta np chng tt c cc hm s kin v ghi ra log (nht k):

@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
Log.d("Fragment 1", "onAttach");
}

@Override

Fragment 62
Gio trnh Android

public void onCreate(Bundle savedInstanceState) {


super.onCreate(savedInstanceState);
Log.d("Fragment 1", "onCreate");
}

@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
Log.d("Fragment 1", "onActivityCreated");
}

@Override
public void onStart() {
super.onStart();
Log.d("Fragment 1", "onStart");
}

@Override
public void onResume() {
super.onResume();
Log.d("Fragment 1", "onResume");
}

@Override
public void onPause() {
super.onPause();
Log.d("Fragment 1", "onPause");
}

@Override
public void onStop() {
super.onStop();
Log.d("Fragment 1", "onStop");
}

@Override
public void onDestroyView() {
super.onDestroyView();
Log.d("Fragment 1", "onDestroyView");
}

@Override
public void onDestroy() {
super.onDestroy();
Log.d("Fragment 1", "onDestroy");
}

@Override
public void onDetach() {
super.onDetach();
Log.d("Fragment 1", "onDetach");
}

Chy ng dng ny trn thit b Android, thc hin cc thao tc bm phm Home, Back, m ng dng khc v theo di
th t ca cc s kin trn trong ca s LogCat s cho bn khi nim chc chn nht v vng i ca cc frament:

11-03 23:24:29.398: D/Fragment 1(11354): onAttach


11-03 23:24:29.398: D/Fragment 1(11354): onCreate
11-03 23:24:29.398: D/Fragment 1(11354): onCreateView
11-03 23:24:29.398: D/Fragment 1(11354): onActivityCreated
11-03 23:24:29.398: D/Fragment 1(11354): onStart
11-03 23:24:29.398: D/Fragment 1(11354): onResume
11-03 23:24:33.835: D/Fragment 1(11354): onPause
11-03 23:24:33.835: D/Fragment 1(11354): onStop
11-03 23:24:33.835: D/Fragment 1(11354): onDestroyView
11-03 23:24:33.835: D/Fragment 1(11354): onDestroy
11-03 23:24:33.835: D/Fragment 1(11354): onDetach
11-03 23:24:33.914: D/Fragment 1(11354): onAttach

Tng tc gia cc fragment

Fragment 63
Gio trnh Android

Trong v d trn, khi thc hin bm vo nt bm trong Fragment2, ta tin hnh ly v hin th xu k t cha trong
TextView ca Fragment1 di dng Toast:

@Override
public void onStart() {
super.onStart();
//---Button view---
Button btnGetText = (Button)
getActivity().findViewById(R.id.btnGetText);
btnGetText.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
TextView lbl = (TextView)
getActivity().findViewById(R.id.lblFragment1);
Toast.makeText(getActivity(), lbl.getText(),
Toast.LENGTH_SHORT).show();
}
});
}

Do 2 fragment thuc cng mt Activity, nn ta c th truy xut n View trong mi fragment thng qua Activity chung ny.
Activity cha fragment c ly thng qua phng thc getActivity() .

Fragment 64
Gio trnh Android

Giao din ngi dng ca ng dng Android


Trong cc chng trc ta lm quen vi thnh phn c bn ca giao din Android l Activity v vng i ca n. Tuy
nhin, bn thn Activity khng phi l th chng ta nhn thy trn mn hnh in thoi, thay vo Activity cn c cc
thnh phn ha khc bn trong n, l cc View v ViewGroup. Trong chng ny chng ta s tm hiu chi tit hn v
cc View v ViewGroup trong Android to nn giao din ha ca ng dng, cng nh cch thc tng tc vi
chng.

Giao din ngi dng ca ng dng Android 65


Gio trnh Android

View v ViewGroup
Nh cp trn, mi Activity mun hin th giao din ha cn cha cc thnh phn giao din khc nh nt bm,
cc nhn, cc nhp liu, checkbox, radio button Nhng thnh phn nh vy trong Android c gi chung l cc
View . Tt c cc View u c k tha t lp android.view.View .

Mt hoc nhiu View c th c nhm li vi nhau thnh mt ViewGroup . Mi ViewGroup cng l mt View , c dng
nhm cc View con bn trong n v hin th chng theo mt th t hay quy lut no . Mi ViewGroup u c k
tha t lp android.view.ViewGroup . Cc loi ViewGroup ph bin nht trong Android bao gm:

LinearLayout

AbsoluteLayout

TableLayout

RelativeLayout

FrameLayout

ScrollView

Cc View v ViewGroup to thnh giao din ca Activity v thng c m t ngay trong file layout ca Activity, nm
trong th mc res/layout (file main.xml trong cc v d trc). V d:

<?xml version="1.0" encoding="utf-8"?>


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >

<Button
android:layout_width="160dp"
android:layout_height="wrap_content"
android:text="Button"
android:layout_gravity="left"
android:layout_weight="1" />

<Button
android:layout_width="160dp"
android:layout_height="wrap_content"
android:text="Button"
android:layout_gravity="center"
android:layout_weight="2" />

<Button
android:layout_width="160dp"
android:layout_height="wrap_content"
android:text="Button"
android:layout_gravity="right"
android:layout_weight="3" />
</LinearLayout>

Mt s thuc tnh chung ca cc View v ViewGroup c k ra trong bng di y:

Thuc tnh M t

layout_width Chiu rng ca View/ViewGroup

layout_height Chiu cao ca View/ViewGroup

layout_marginTop Chiu rng khong trng (l) pha trn ca View

layout_marginBottom Chiu rng khong trng (l) pha di ca View

layout_marginLeft Chiu rng khong trng (l) pha bn tri ca View

View v ViewGroup 66
Gio trnh Android

layout_marginRight Chiu rng khong trng (l) pha bn phi ca View

layout_gravity Cch xp t View (tri, phi, trn, di, gia theo chiu dc, gia theo chiu ngang)

Phn tip theo s m t chi tit hn v mt s loi ViewGroup ph bin trn. Cn ch rng trong thc t s dng, giao
din ha ca ng dng thng c to thnh bi mt t hp phn cp gia cc loi ViewGroup khc nhau.

LinearLayout

LinearLayout sp xp cc view con bn trong n theo mt ct (t trn xung di) hoc theo mt hng (t tri qua phi).
Cc view con c xp dc hoc ngang ty thuc vo tham s android:orientation ca LinearLayout, gi tr ca tham s
ny c th l vertical (dc) hoc horizontal (ngang).

Xem v d sau:

<?xml version="1.0" encoding="utf-8"?>


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >

<TextView
android:layout_width="100dp"
android:layout_height="wrap_content"
android:text="@string/hello" />

<Button
android:layout_width="160dp"
android:layout_height="wrap_content"
android:onClick="onClick"
android:text="Button" />

</LinearLayout>

Giao din trn bao gm mt LinearLayout theo chiu dc, cha 1 view bn trong l on ch Hello world v nt bm
Button bn di n. Chiu rng v cao ca LinearLayout l fill_parent, tc l n s chim ht chiu rng, chiu di ca
view m (trong trng hp ny l Activity, tc l ton mn hnh). Chiu rng ca textview l 100dp (im nh khng ph
thuc vo mt mn hnh, chi tit xem bn di), chiu cao ca text ny l wrap_content tc l bng ng chiu cao ca
ni dung cha trong n (ph thuc vo s dng ch, kch thc ch, khong cch thc t).

Cc n v o kch thc trong Android bao gm:

dp (hoc dip) - Density-independent pixel (im nh khng ph thuc vo mt mn hnh). Mt dp tng ng vi


mt pixel trn mn hnh c mt 160 dpi (160 im nh trn mi inch mn hnh). y l n v c khuyn ngh
dng trong hu ht cc trng hp t kch thc ca view trong layout. Chi tit hn v mt mn hnh c
cp phn sau ca gio trnh.
sp - Scale-independent pixel, n v ny tng t dp, c dng khi m t kch thc font ch (font size)
pt - Point. 1 point = 1/72 inch, da trn kch thc vt l tht ca mn hnh.
px Pixel mt pixel vt l trn mn hnh, n v ny khng c khuyn dng trong thit k giao din ng dng v
giao din s hin th khng ng nht trn cc mn hnh c phn gii khc nhau.

Trong v d trn, nt bm c chiu rng l 160dp v textview l 100dp. hiu c kch thc ny, trc ht ta xem
khi nim kch thc v mt mn hnh trong Android. Ta xt trn v d c th: in thoi Nexus S ca Google. Thit b
ny c mn hnh 4 inch theo ng cho, 2.04 inch theo chiu ngang, vi phn gii 480x800 pixel. Chiu rng 2.04
inch vi 480 pixel cho ta mt im nh khong 235 dpi (dots per inch im nh mi inch) xem hnh bn di.

View v ViewGroup 67
Gio trnh Android

Android nh ngha 4 loi mt mn hnh nh sau:

Mt thp: Low density (ldpi) - 120 dpi


Mt trung bnh: Medium density (mdpi) - 160 dpi
Mt cao: High density (hdpi) - 240 dpi
Mt rt cao: Extra High density (xhdpi) - 320 dpi

Mi thit b s c xp vo mt trong cc loi mt trn. V d thit b Nexus S trn s c xp vo thit b mt


cao, do mt mn hnh (235dpi) gn nht vi mt hdpi 240dpi. Cn in thoi The HTC Hero, c mn hnh 3.2inch,
phn gii 320x480, c mt 180dpi s c xp vo in thoi mt trung bnh (mdpi) do gn nht vi con s
160dpi.

Di y l hnh nh ca layout trn chy trn 2 thit b c kch thc v phn gii khc nhau. Hnh bn tri l thit b 4
inch, phn gii 480x800 (mt 235dpi hdpi), hnh bn phi l thit b 3.2 inch, phn gii 320x480 (mt 180dpi).

View v ViewGroup 68
Gio trnh Android

C th thy mc d chy trn 2 thit b c phn gii, kch thc v mt khc nhau, nhng nt bm v text c kch
thc rt ng nht (nt bm chim khong 1/2 chiu ngang mn hnh). Kch thc thc t (tnh bng pixel vt l) c
tnh t kch thc dp nh sau: Kch thc pixel thc t = dp * (dpi / 160), trong dpi = 120, 160, 240, hoc 320 ty thuc
vo mn hnh thit b.

v d trn, nt bm trn mn hnh bn tri s c kch thc tht l: 160*(240/160) = 240 pixel, cn trn mn hnh bn
phi s l 160x(160/160) = 160 pixel.

Nu ta thay n v dp trong khai bo layout trn thnh n v px nh di y:

<TextView
android:layout_width="100px"
android:layout_height="wrap_content"
android:text="@string/hello" />

<Button
android:layout_width="160px"
android:layout_height="wrap_content"
android:onClick="onClick"
android:text="Button" />

th kt qu s l:

View v ViewGroup 69
Gio trnh Android

Nh vy c th thy vic s dng n v px trong thit k giao din l khng nn, m nn s dng n v dp, n v ny
bao gm vic thch nghi giao din vi cc kch thc mn hnh khc nhau. Nu thay tham s
android:orientation="vertical" ca linearlayout thnh android:orientation="horizontal" , s thu c:

View v ViewGroup 70
Gio trnh Android

AbsoluteLayout

AbsoluteLayout cho php t cc view con bn trong n ti v tr chnh xc, c nh, tnh theo px hoc dp. Layout loi ny
khng linh hot v khng thch nghi c vi s thay i ca phn gii mn hnh, v vy khng c khuyn dng
trong cc phin bn Android gn y. V vy cho n thi im hin ti, ta c th qun i loi layout ny.

TableLayout

Tablelayout cho php sp xp cc view con bn trong n theo dng v ct. Mi dng c t trong th <TableRow> , mi
view con trong TableRow c t trong mt ca dng, chiu rng ca mi ct c xc nh bng chiu rng ln nht
ca cc trong ct . Xt v d sau:

<TableLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="fill_parent"
android:layout_width="fill_parent"
>
<TableRow>
<TextView
android:text="User Name:"
android:width ="120dp"
/>
<EditText
android:id="@+id/txtUserName"
android:width="200dp" />
</TableRow>
<TableRow>
<TextView
android:text="Password:"
/>
<EditText
android:id="@+id/txtPassword"
android:password="true"
/>
</TableRow>
<TableRow>
<TextView />
<CheckBox android:id="@+id/chkRememberPassword"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Remember Password"
/>
</TableRow>
<TableRow>
<Button
android:id="@+id/buttonSignIn"
android:text="Log In" />
</TableRow>
</TableLayout>

Kt qu ca layout trn khi chy trn emulator vi mn hnh dc v ngang s nh sau:

View v ViewGroup 71
Gio trnh Android

RelativeLayout

RelativeLayout cho php cc view con bn trong c sp t tng i vi nhau v tng i so vi view m.

<RelativeLayout
android:id="@+id/RLayout"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
xmlns:android="http://schemas.android.com/apk/res/android" >

<TextView
android:id="@+id/lblComments"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Comments"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true" />

<EditText
android:id="@+id/txtComments"
android:layout_width="fill_parent"
android:layout_height="170px"
android:textSize="18sp"
android:layout_alignLeft="@+id/lblComments"
android:layout_below="@+id/lblComments"
android:layout_centerHorizontal="true" />

<Button
android:id="@+id/btnSave"
android:layout_width="125px"
android:layout_height="wrap_content"
android:text="Save"
android:layout_below="@+id/txtComments"
android:layout_alignRight="@+id/txtComments" />

<Button
android:id="@+id/btnCancel"
android:layout_width="124px"
android:layout_height="wrap_content"
android:text="Cancel"
android:layout_below="@+id/txtComments"
android:layout_alignLeft="@+id/txtComments" />
</RelativeLayout>

View v ViewGroup 72
Gio trnh Android

Kt qu ca layout trn nh sau:

Mi view con trong relativelayout c mt s thuc tnh nht nh gip chng cn chnh theo view m hoc theo cc view
khc cng cp. Ta c th thy cc thuc tnh ny trong v d trn nh:

layout_alignParentTop xp trn cng so vi layout m

layout_alignParentLeft cn tri so vi layout m

layout_alignLeft cn tri so vi layout khc (c id c ch ra trong gi tr ca thuc tnh ny)

layout_alignRight cn tri so vi layout khc (c id c ch ra trong gi tr ca thuc tnh ny)

layout_below t xung di layout khc (c id c ch ra trong gi tr ca thuc tnh ny)

layout_centerHorizontal cn gia theo chiu ngang so vi layout m (relativelayout hin ti)

FrameLayout

L layout c dng hin th mt view bn trong. View con ca Framelayout lun c cn pha trn, bn tri so vi
layout m ny. Nu bn thm nhiu hn 1 view vo bn trong FrameLayout, th cc view ny s nm chng ln nhau nh
v d di y.

<RelativeLayout
android:id="@+id/RLayout"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
xmlns:android="http://schemas.android.com/apk/res/android"
>
<TextView
android:id="@+id/lblComments"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello, Android!"

View v ViewGroup 73
Gio trnh Android

android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
/>
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/lblComments"
android:layout_below="@+id/lblComments"
android:layout_centerHorizontal="true"
>
<ImageView
android:src = "@drawable/droid"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<Button
android:layout_width="124dp"
android:layout_height="wrap_content"
android:text="Print Picture" />

</FrameLayout>
</RelativeLayout>

ScrollView

ScrollView l mt FrameLayout c bit, cho php ngi dng cun dc mn hnh khi ni dung bn trong ca ScrollView
chim nhiu din tch hn view m.

<ScrollView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
xmlns:android="http://schemas.android.com/apk/res/android" >

<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:focusable="true"
android:focusableInTouchMode="true" >
<Button
android:id="@+id/button1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Button 1" />
<Button
android:id="@+id/button2"

View v ViewGroup 74
Gio trnh Android

android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Button 2" />
<Button
android:id="@+id/button3"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Button 3" />
<EditText
android:id="@+id/txt"
android:layout_width="fill_parent"
android:layout_height="600dp" />
<Button
android:id="@+id/button4"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Button 4" />
<Button
android:id="@+id/button5"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Button 5" />
</LinearLayout>
</ScrollView>

Trong v d trn, EditText gia c t chiu cao ln n 600dp chc chn n vt qu chiu cao ca mn hnh
in thoi, khi khi chy trn in thoi/emulator, ta s thy view c th cun ln, cun xung nh hnh v sau:

Hnh: Scroll view ang c cun ln (tri) v cun xung (phi)

View v ViewGroup 75
Gio trnh Android

Thit k giao din thch nghi vi hng mn hnh


Mt tnh nng xut hin trn hu ht cc in thoi thng minh hin hnh l tnh nng t ng thay i hng hin th ca
mn hnh t dc sang ngang hoc ngc li khi ngi dng xoay in thoi theo hng tng ng. Khng ngoi l, khi
thit b Android thay i hng t dc sang ngang hoc ngc li, activity hin ti s v li cc view con ca mnh theo
hng mi, khi hm onCreate ca Activity s c gi li t u. Mt khc, do din tch v t l vng hin th theo
hng dc v hng ngang khc nhau tng i nhiu, nn khi thit k layout ta cn c bin php thch hp cho s thay
i ny.

C 2 phng php ph bin thit k layout thch nghi vi s thay i ny:

Neo neo (xp c nh) cc view con theo cc cnh ca mn hnh. y l cch d lm nht, khi kch thc mn hnh
thay i, v tr ca cc layout con s c xp li nhng vn cn theo cc cnh gn nht.
Thay i kch thc v v tr cch lm tn cng v linh hot hn v sp xp li ton b layout ca cc view con khi
c s thay i v mn hnh. Ngoi, ra cn c th thm/bt view con vi nhng hng nht nh.

Ta s xem v d c th cho 2 phng n trn.

Neo cc view con theo cc cnh mn hnh

<?xml version="1.0" encoding="utf-8"?>


<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
xmlns:android="http://schemas.android.com/apk/res/android">
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Top Left"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true" />
<Button
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Top Right"
android:layout_alignParentTop="true"
android:layout_alignParentRight="true" />
<Button
android:id="@+id/button3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Bottom Left"
android:layout_alignParentLeft="true"
android:layout_alignParentBottom="true" />
<Button
android:id="@+id/button4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Bottom Right"
android:layout_alignParentRight="true"
android:layout_alignParentBottom="true" />
<Button
android:id="@+id/button5"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Middle"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true" />
</RelativeLayout>

Trong v d trn button1 c neo theo gc trn bn tri, button2 gc trn bn phi, button3 gc di bn tri,

B cc giao din thch nghi vi hng mn hnh 76


Gio trnh Android

button4 gc di bn phi, button5 chnh gia mn hnh. Layout trn khi hin th trn mn hnh dc v ngang s nh

sau:

Hnh: Neo cc nt bm theo cnh mn hnh - mn hnh dc

Hnh: Neo cc nt bm theo cnh mn hnh - mn hnh ngang

B cc giao din thch nghi vi hng mn hnh 77


Gio trnh Android

Thay i kch thc v v tr

Trong phng php ny, thng thng mi hng mn hnh s c mt layout ring. Layout ny c th c cu hnh
trong code, hoc t file layout vo th mc cu hnh sn h thng t la chn trong qu trnh chy. to layout ring
cho Activity trn theo mn hnh ngang, ta to th mc layout-land trong th mc res, sau to file main.xml (trng tn vi
file layout trong th mc res/layout), vi ni dung nh sau:

<?xml version="1.0" encoding="utf-8"?>


<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
xmlns:android="http://schemas.android.com/apk/res/android">
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Top Left"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true" />
<Button
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Top Right"
android:layout_alignParentTop="true"
android:layout_alignParentRight="true" />
<Button
android:id="@+id/button3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Bottom Left"
android:layout_alignParentLeft="true"
android:layout_alignParentBottom="true" />
<Button
android:id="@+id/button4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Bottom Right"
android:layout_alignParentRight="true"
android:layout_alignParentBottom="true" />
<Button
android:id="@+id/button5"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Middle"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true" />
<Button
android:id="@+id/button6"
android:layout_width="180px"
android:layout_height="wrap_content"
android:text="Top Middle"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true"
android:layout_alignParentTop="true" />
<Button
android:id="@+id/button7"
android:layout_width="180px"
android:layout_height="wrap_content"
android:text="Bottom Middle"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true"
android:layout_alignParentBottom="true" />
</RelativeLayout>

ta thy layout ny c 7 nt thay v 5 nt nh layout mc nh (cho mn hnh dc). Kt qu hin th cho mn hnh
ngang s xut hin thm 2 nt bm trn v di mn hnh, cn gia theo chiu ngang nh hnh di:

B cc giao din thch nghi vi hng mn hnh 78


Gio trnh Android

Hnh: Giao din theo mn hnh ngang vi 2 nt mi xut hin (Top Middle v Bottom Middle)

Ngoi ra khi thay i hng mn hnh, Activity s c v li hon ton t u v trng thi hin ti s mt, bao gm gi
tr ca cc trng, ni dung ca cc view khng c t tn trong layout V vy, trong trng hp cn thit phi lu tr
trng thi hin ti ca Activity, vic ta cn lm l np chng 2 hm sau:

@Override
public void onSaveInstanceState(Bundle outState) {
//---save whatever you need to persist---
outState.putString("ID", "1234567890");
super.onSaveInstanceState(outState);
}

@Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
//---retrieve the information persisted earlier---
String ID = savedInstanceState.getString("ID");
}

D liu cn lu tr c cha trong mt i tng Bundle , chi tit v i tng ny v cc loi d liu c th lu tr
trong n bn c t tm hiu v phn ny c coi nh bi tp. Trong v d trn ta tin hnh lu v ly li gi tr ca
mt chui (0123456789) vo Bundle di tn l ID.

iu khin hng ca mn hnh

Trong mt s trng hp, ta cn thit k mt s Activity ch h tr mt loi hng mn hnh c th. V d, mn hnh xem
phim c th c thit lp ch c hng nm ngang, hay mn hnh gi in thoi c thit lp lun lun hin th theo
chiu dc.

lm vic ny, ta c th khai bo thuc tnh ca activity tng ng trong file Manifest hoc cu hnh trong m ngun ca
hm onCreate tng ng vi Activity cn thit lp.

V d v cu hnh hng mn hnh lun nm ngang trong m ngun:

B cc giao din thch nghi vi hng mn hnh 79


Gio trnh Android

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

//---change to landscape mode---


setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
}

V trong Manifest:

<activity
android:label="@string/app_name"
android:name=".OrientationsActivity"
android:screenOrientation="landscape" >
<intent-filter >
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />


</intent-filter>
</activity>

B cc giao din thch nghi vi hng mn hnh 80


Gio trnh Android

S dng trnh n (Menu)


Trnh n (bng chn, menu) dng hin th cc hnh ng thng t dng hn v khng hin th trc tip ln mn hnh.
Trong Android c 2 loi trnh n :

Trnh n chnh (Options menu) hin th cc hnh ng lin quan n ton b Activity hin ti. Trong Android,
kch hot trnh n ny, ta bm nt Menu ca thit b (phm cng hoc phm o trn mn hnh)
Trnh n ng cnh (Context Menu) hin th cc hnh ng lin quan n mt view c th trn mn hnh, trnh n
ny c kch hot bng cch bm v gi ngn tay (long tap) trn view tng ng.

Hnh di y minh ha trnh n chnh (bn tri) v trnh n ng cnh khi bm v gi tay trn nh (bn phi) ca ng
dng Browser (trnh duyt web):

Hnh: Trnh n chnh (tri) v trnh n ng cnh (phi)

V mt lp trnh, 2 loi menu ny s dng cng mt lp ( android.view.Menu ) v cha cc i tng ging nhau
( android.view.MenuItem ). V vy ta to sn 2 phng thc dng chung cho 2 loi menu ny to menu vi cc mc
(item) bn trong v x l s kin bm vo tng item nh di y:

Hm CreateMenu dng thm 7 mc vo menu c sn (c truyn vo di ng tham s):

private void CreateMenu(Menu menu)


{
menu.setQwertyMode(true);
MenuItem mnu1 = menu.add(0, 0, 0, "Item 1");
{
mnu1.setAlphabeticShortcut('a');
mnu1.setIcon(R.drawable.ic_launcher);
}
MenuItem mnu2 = menu.add(0, 1, 1, "Item 2");

S dng trnh n (Menu) 81


Gio trnh Android

{
mnu2.setAlphabeticShortcut('b');
mnu2.setIcon(R.drawable.ic_launcher);
}
MenuItem mnu3 = menu.add(0, 2, 2, "Item 3");
{
mnu3.setAlphabeticShortcut('c');
mnu3.setIcon(R.drawable.ic_launcher);
}
MenuItem mnu4 = menu.add(0, 3, 3, "Item 4");
{
mnu4.setAlphabeticShortcut('d');
}

menu.add(0, 4, 4, "Item 5");


menu.add(0, 5, 5, "Item 6");
menu.add(0, 6, 6, "Item 7");
}

Hm MenuChoice x l s kin tng ng vi tng mc c la chn (truyn vo dng tham s). Vi mc ch minh
ha, trong v d sau, khi mt mc c chn, ta ch n gin hin th tn ca mc bng thng bo dng Toast .

private boolean MenuChoice(MenuItem item)


{
switch (item.getItemId()) {
case 0:
Toast.makeText(this, "You clicked on Item 1",
Toast.LENGTH_LONG).show();
return true;
case 1:
Toast.makeText(this, "You clicked on Item 2",
Toast.LENGTH_LONG).show();
return true;
case 2:
Toast.makeText(this, "You clicked on Item 3",
Toast.LENGTH_LONG).show();
return true;
case 3:
Toast.makeText(this, "You clicked on Item 4",
Toast.LENGTH_LONG).show();
return true;
case 4:
Toast.makeText(this, "You clicked on Item 5",
Toast.LENGTH_LONG).show();
return true;
case 5:
Toast.makeText(this, "You clicked on Item 6",
Toast.LENGTH_LONG).show();
return true;
case 6:
Toast.makeText(this, "You clicked on Item 7",
Toast.LENGTH_LONG).show();
return true;
}
return false;
}

Trnh n chnh

hin th trnh n chnh, ta np chng hm onCreateOptionMenu(Menu menu) v thm cc mc vo i tng menu (trong
tham s ca hm):

@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
CreateMenu(menu);
return true;
}

S dng trnh n (Menu) 82


Gio trnh Android

hin th menu ny lc chy ng dng, ta bm phm MENU ca thit b.

x l s kin chn mt item trong menu hin ra, ta cn np chng hm onOptionsItemSelected(MenuItem item) :

@Override
public boolean onOptionsItemSelected(MenuItem item)
{
return MenuChoice(item);
}

Hnh bn di minh ha menu chnh c to trn trong trng hp thit lp SDK nh nht c h tr trong
AndroidManifest.xml >=10 ( <uses-sdkandroid:minSdkVersion=10 /> - hnh bn tri) v < 10 ( <uses-
sdkandroid:minSdkVersion=9 /> hnh bn phi).

Hnh: Trnh n chnh vi API mc 10 (tri) v API mc 9 (phi)

Trnh n ng cnh

hin th trnh n ng cnh, ta np chng hm onCreateContextMenu(Menu menu) v thm cc mc vo i tng menu


(l tham s ca hm):

@Override
public void onCreateContextMenu(ContextMenu menu, View view,
ContextMenuInfo menuInfo)
{
super.onCreateContextMenu(menu, view, menuInfo);
CreateMenu(menu);
}

S dng trnh n (Menu) 83


Gio trnh Android

x l s kin chn mt item trong menu hin ra, ta cn np chng hm onContextItemSelected (MenuItem item) :

@Override
public boolean onContextItemSelected (MenuItem item)
{
return MenuChoice(item);
}

gn menu ng cnh ny vo nt bm button1, ta thm on m sau vo hm onCreate ca activity:

Button btn = (Button) findViewById(R.id.button1);


btn.setOnCreateContextMenuListener(this);

hin th menu ny lc chy ng dng, ta bm v gi ngn tay ln trn nt bm button1, trnh n hin ra nh hnh
bn di:

Hnh: Trnh n ng cnh xut hin khi bm v gi ngn tay trn nt bm button1

S dng trnh n (Menu) 84


Gio trnh Android

S dng thanh tc v (Action Bar)


Cng vi Fragment, mt tnh nng mi c gii thiu t Android 3.0 HoneyComb l thanh tc v bn trong ng dng
(Action Bar) thay th cho thanh tiu c. Action bar bao gm icon ca ng dng v tiu ca Activity bn tri.
Ngoi ra, ngi dng c th t bn phi cc nt bm c bit, gi l action item. Hnh bn di minh ha action bar
ca ng dng email trong Android vi icon ng dng, tiu email v 4 action item bn phi:

Hnh: ActionBar vi tiu v cc nt bm

Action Bar dng chung menu chnh (option menu) nh m t trong phn trc. cc menu item trong menu chnh hin
th trn Action bar di dng cc action item, ta ch cn gi hm mnu1.setShowAsAction() ca mi menu item.

private void CreateMenu(Menu menu)


{
MenuItem mnu1 = menu.add(0, 0, 0, "Item 1");
{
mnu1.setIcon(R.drawable.ic_launcher);
mnu1.setShowAsAction(
MenuItem.SHOW_AS_ACTION_IF_ROOM |
MenuItem.SHOW_AS_ACTION_WITH_TEXT);
}
MenuItem mnu2 = menu.add(0, 1, 1, "Item 2");
{
mnu2.setIcon(R.drawable.ic_launcher);
mnu2.setShowAsAction(
MenuItem.SHOW_AS_ACTION_IF_ROOM |
MenuItem.SHOW_AS_ACTION_WITH_TEXT);
}
MenuItem mnu3 = menu.add(0, 2, 2, "Item 3");
{
mnu3.setIcon(R.drawable.ic_launcher);
mnu3.setShowAsAction(
MenuItem.SHOW_AS_ACTION_IF_ROOM |
MenuItem.SHOW_AS_ACTION_WITH_TEXT);

S dng thanh tc v (Action Bar) 85


Gio trnh Android

}
MenuItem mnu4 = menu.add(0, 3, 3, "Item 4");
{
mnu4.setShowAsAction(
MenuItem.SHOW_AS_ACTION_IF_ROOM |
MenuItem.SHOW_AS_ACTION_WITH_TEXT);
}
MenuItem mnu5 = menu.add(0, 4, 4, "Item 5");
{
mnu5.setShowAsAction(
MenuItem.SHOW_AS_ACTION_IF_ROOM |
MenuItem.SHOW_AS_ACTION_WITH_TEXT);
}
}

Kt qu khi chy trn thit b nh hnh bn di. i vi mn hnh dc, c t din tch hin th action item hn (2 ci), 3
item cn li s hin th di dng trnh n chnh nh bnh thng:

Hnh: Action Bar vi 2 nt bm khi mn hnh dc

i vi mn hnh ngang, nhiu item c hin th di dng action item hn (4 ci):

S dng thanh tc v (Action Bar) 86


Gio trnh Android

Hnh: Action Bar vi 4 nt bm khi mn hnh ngang

S dng thanh tc v (Action Bar) 87


Gio trnh Android

X l s kin tng tc vi cc thnh phn ha


Ngi dng tng tc vi giao din ha ca ng dng Android theo 2 mc: mc Activity v mc View. mc Activity,
lp Activity cn np chng cc phng thc tng ng c nh ngha sn. Mt s phng thc nh vy c th k n
nh:

onKeyDown c gi khi mt phm c nhn xung v s kin ny cha c x l bi bt c view con no trong

activty
onKeyUp c gi khi mt phm c nh ra v s kin ny cha c x l bi bt c view con no trong activty

onMenuItemSelected c gi khi ngi dng la chn mt item trong menu ang c m ra

onMenuOpened c gi khi mt trnh n c m ra.

Np chng hm x l s kin ca Activity

V d:

@Override
public boolean onKeyDown(int keyCode, KeyEvent event)
{
switch (keyCode)
{
case KeyEvent.KEYCODE_DPAD_CENTER:
Toast.makeText(getBaseContext(),
"Center was clicked",
Toast.LENGTH_LONG).show();
break;
case KeyEvent.KEYCODE_DPAD_LEFT:
Toast.makeText(getBaseContext(),
"Left arrow was clicked",
Toast.LENGTH_LONG).show();
break;
case KeyEvent.KEYCODE_DPAD_RIGHT:
Toast.makeText(getBaseContext(),
"Right arrow was clicked",
Toast.LENGTH_LONG).show();
break;
case KeyEvent.KEYCODE_DPAD_UP:
Toast.makeText(getBaseContext(),
"Up arrow was clicked",
Toast.LENGTH_LONG).show();
break;
case KeyEvent.KEYCODE_DPAD_DOWN:
Toast.makeText(getBaseContext(),
"Down arrow was clicked",
Toast.LENGTH_LONG).show();
break;
}
return false;
}

ng k s kin cho tng View

Mi view trong Android c th sinh ra cc s kin khi ngi dng tc ng ln n. V d nt bm sinh ra s kin onClick
khi ngi dng bm vo n, EditText sinh ra s kin onFocusChange khi nhn focus (ngi dng bm vo nhp liu ny)
hoc mt focus (khi view khc nhn focus).

ng k s kin tng tc vi cc view, ta c th s dng lp n danh (anonymous class) nh v d di y:

Button btn1 = (Button)findViewById(R.id.btn1);


btn1.setOnClickListener(btnListener);

X l s kin tng tc vi cc thnh phn ha 88


Gio trnh Android

v:

//---create an anonymous class to act as a button click listener---


private OnClickListener btnListener = new OnClickListener()
{
public void onClick(View v)
{
Toast.makeText(getBaseContext(),
((Button) v).getText() + " was clicked",
Toast.LENGTH_LONG).show();
}
};

Hoc s dng hm ni b n danh (anonymous inner class) nh sau:

//---create an anonymous inner class to act as an onfocus listener---


EditText txt1 = (EditText)findViewById(R.id.txt1);
txt1.setOnFocusChangeListener(new View.OnFocusChangeListener()
{
@Override
public void onFocusChange(View v, boolean hasFocus) {
Toast.makeText(getBaseContext(),
((EditText) v).getId() + " has focus - " + hasFocus,
Toast.LENGTH_LONG).show();
}
});

X l s kin tng tc vi cc thnh phn ha 89


Gio trnh Android

Thit k giao din ngi dng vi cc View c bn


Trong chng trc, chng ta lm quen vi cc loi viewgroup trong Android v cch s dng chng sp xp cc
view con trong activity. Trong chng ny, ta s lm quen vi cc loi view dng to nn giao din ha cho ng
dng: cc nt bm, ch, hnh nh, danh sch

Thit k giao din ngi dng vi cc View c bn 90


Gio trnh Android

S dng cc View c bn trong Android


Phn ny m t mt s View c bn nht thng c dng to nn giao din ha cho ng dng Android nh:

TextView
EditText
Button
ImageButton
CheckBox
ToggleButton
RadioButton
RadioGroup

TextView

Nh tn gi ca n, TextView dng hin th on vn bn (dng ch) ln mn hnh. y l view n gin nht v dng
rt nhiu trong Android. Ta gp view ny ngay t d n HelloAndroid trong nhng chng u tin:

<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content
android:text="@string/hello" />

Ngoi mt s thuc tnh chung nh layout_width, layout_height , ta c th la chn ty chnh kch thc font ch (thng
tnh bng sp scalable pixel), loi font ch, kiu ch (in m, in nghing), s dng ti a hin th on ch

Nu ta mun cho php ngi dng thay i/nhp ni dung ch th cn s dng mt view k tha t TextView l EditText
s c nhc n phn di.

Button v ImageButton

Dng hin th nt bm ln mn hnh. S kin ph bin nht ca nt bm l s kin onClick , c sinh ra khi ngi
dng bm ln nt bm. im khc nhau gia Button v ImageButton l Button dng ch (text) lm nhn, cn ImageButton
dng nh.

EditText

K tha t lp TextView , cho php ngi dng sa c ni dung ch trong n.

CheckBox

L mt loi nt bm c bit, c 2 trng thi: c chn ( checked ) v khng c chn ( unchecked )

RadioButton v RadioGroup

RadioButton c 2 trng thi l c chn v khng c chn, cn RadioGroup nhm cc RadioButton li vi nhau
m bo cng mt lc ch c ti a 01 RadioButton trong nhm c trng thi c chn.

ToggleButton

Tng t nh CheckBox, l mt loi nt bm c bit, c 2 trng thi l bt ( checked ) v tt ( unchecked ).

S dng cc View c bn trong Android 91


Gio trnh Android

Ta s xem cc view c bn trn trong cng mt v d di y:

<?xml version="1.0" encoding="utf-8"?>


<LinearLayout xmlns:andvroid="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >

<Button android:id="@+id/btnSave"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/save"
android:onClick="btnSaved_clicked"/>

<Button android:id="@+id/btnOpen"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Open" />

<ImageButton android:id="@+id/btnImg1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:src="@drawable/ic_launcher" />

<EditText android:id="@+id/txtName"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />

<CheckBox android:id="@+id/chkAutosave"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Autosave" />

<CheckBox android:id="@+id/star"
style="?android:attr/starStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />

<RadioGroup android:id="@+id/rdbGp1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<RadioButton android:id="@+id/rdb1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Option 1" />
<RadioButton android:id="@+id/rdb2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Option 2" />
</RadioGroup>

<ToggleButton android:id="@+id/toggle1"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />

</LinearLayout>

Chy ng dng vi activity c layout nh trn, ta s thy cc view c bn ny c xp t trn xung di theo th t ln
lt (do nm trong LinearLayout). Th thc hin cc thao tc chn trn cc nt ToggleButton , CheckBox v RadioButton ta
s thy trng thi chn ca chng nh hnh bn phi:

S dng cc View c bn trong Android 92


Gio trnh Android

Hnh: Cc view c bn v cc trng thi khng c chn (tri) v c chn (phi)

nhp liu (EditText) trn c thit lp chiu cao l wrap_content nn chiu cao ca n s c t ng iu chnh
khi ni dung bn trong thay i:

View RadioButton c thuc tnh orientation tng t nh LinearLayout, cho php xp cc RadionButton bn trong theo
chiu dc hoc chiu ngang.

Mi view trong v d trn u c t tn (dng thuc tnh android:id ), tn ny c s dng trong m ngun truy
cp n view tng ng thng qua cc hm View.findViewById() hoc Activity.findViewById() .

Sau khi xc nh c view ny theo id trong m ngun, ta c th thm cc hm x l s kin cho chng. Ta xt v d
di y:

S dng cc View c bn trong Android 93


Gio trnh Android

//---Button view---
Button btnOpen = (Button) findViewById(R.id.btnOpen);
btnOpen.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
DisplayToast("You have clicked the Open button");
}
});

//---CheckBox---
CheckBox checkBox = (CheckBox) findViewById(R.id.chkAutosave);
checkBox.setOnClickListener(new View.OnClickListener()
{
public void onClick(View v) {
if (((CheckBox)v).isChecked())
DisplayToast("CheckBox is checked");
else
DisplayToast("CheckBox is unchecked");
}
});

//---RadioButton---
RadioGroup radioGroup = (RadioGroup) findViewById(R.id.rdbGp1);
radioGroup.setOnCheckedChangeListener(new OnCheckedChangeListener()
{
public void onCheckedChanged(RadioGroup group, int checkedId) {
RadioButton rb1 = (RadioButton) findViewById(R.id.rdb1);
if (rb1.isChecked()) {
DisplayToast("Option 1 checked!");
} else {
DisplayToast("Option 2 checked!");
}
}
});

//---ToggleButton---
ToggleButton toggleButton =
(ToggleButton) findViewById(R.id.toggle1);
toggleButton.setOnClickListener(new View.OnClickListener()
{
public void onClick(View v) {
if (((ToggleButton)v).isChecked())
DisplayToast("Toggle button is On");
else
DisplayToast("Toggle button is Off");
}
});

Trong , hm DisplayToast n gin ch hin th thng bo dng Toast ln mn hnh:

private void DisplayToast(String msg)


{
Toast.makeText(getBaseContext(), msg,
Toast.LENGTH_SHORT).show();
}

Ring s kin onClick cho nt bm btnSave c khai bo ngay trong file layout:

android:onClick="btnSaved_clicked"

khi trong m ngun ca Activity cn khai bo hm tng ng:

public void btnSaved_clicked (View view) {


DisplayToast("You have clicked the Save button1");
}

ProgressBar

S dng cc View c bn trong Android 94


Gio trnh Android

ProgressBar cho php hin th thanh trng thi ch i khi c mt tc v g ang chy, nh khi c mt tc v ti mt
tp tin chy ngm pha di. V d di y minh ha cch s dng thanh tin trnh ny.

Trong layout ca Activity, thm view ProgressBar nh sau:

<?xml version="1.0" encoding="utf-8"?>


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >

<ProgressBar android:id="@+id/progressbar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>

</LinearLayout>

Trong m ngun ca Activity, ta to mt Thread ring gi lp thao tc di chy ngm v cp nht li trng thi ca
progressBar sau mi bc thc hin:

progress = 0;
progressBar = (ProgressBar) findViewById(R.id.progressbar);
progressBar.setMax(200);

//---do some work in background thread---


new Thread(new Runnable()
{
public void run()
{
//-do some work here-
while (progressStatus < 100)
{
progressStatus = doSomeWork();

//-Update the progress bar-


handler.post(new Runnable()
{
public void run() {
progressBar.setProgress(progressStatus);
}
});
}

//---hides the progress bar---


handler.post(new Runnable()
{
public void run()
{
progressBar.setVisibility(View.GONE);
}
});
}

//---do some long running work here---


private int doSomeWork()
{
try {
//---simulate doing some work---
Thread.sleep(50);
} catch (InterruptedException e)
{
e.printStackTrace();
}
return ++progress;
}
}).start();

Chy ng dng vi Activity nh trn, ta s thy ProgressBar nh hnh minh ha bn di:

S dng cc View c bn trong Android 95


Gio trnh Android

Hnh: Progress Bar khng xc nh tin trnh c th

Mc nh ProgressBar l thanh trng thi khng xc nh (khng c trng thi c th) nn ta s ch thy hnh trn xoay
xoay.

Ta c th thay i giao din ca thanh trng thi ny theo cc cch khc nhau. V d di y ta thm thuc tnh
style="@android:style/Widget.ProgressBar.Horizontal" bin thanh trng thi thnh dng thanh chy ngang c hin th

phn thc hin v phn cn li:

<ProgressBar android:id="@+id/progressbar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@android:style/Widget.ProgressBar.Horizontal" />

Hnh: Progress Bar c xc nh tin trnh chy xong

S dng cc View c bn trong Android 96


Gio trnh Android

TimePicker v DatePicker
Chn ngy thng, gi l thao tc tng i ph bin trong cc ng dng i ng. Android cng h tr sn thao tc ny
thng qua cc view TimePicker v DatePicker.

TimePicker

TimePicker cho php ngi dng chn thi gian trong ngy (gi, pht) theo c 2 ch 24 gi v 12 gi vi AM/PM.

<?xml version="1.0" encoding="utf-8"?>


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >

<TimePicker android:id="@+id/timePicker"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />

<Button android:id="@+id/btnSet"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="I am all set!"
android:onClick="onClick" />

</LinearLayout>

Giao din trn bao gm view chn thi gian v nt bm, trong hm onClick x l s kin bm ca nt bm ny. Ta s hin
th thi gian c chn trong TimePicker:

public void onClick(View view) {


Toast.makeText(getBaseContext(),
"Time selected:" + timePicker.getCurrentHour() +
":" + timePicker.getCurrentMinute(),
Toast.LENGTH_SHORT).show();
}

Giao din ng dng sau khi chy s nh sau:

TimePicker v DatePicker 97
Gio trnh Android

Hnh: TimePicker vi la chn AM/PM

Bm nt I am all set , thi gian va c chn s c in ra mn hnh di dng Toast.

Theo mc nh, TimePicker cho ta chn thi gian di dng 12 gi vi AM v PM. hin th thi gian di dng 24 gi,
ta gi hm setIs24HourView nh sau:

timePicker = (TimePicker) findViewById(R.id.timePicker);


timePicker.setIs24HourView(true);

Kt qu thu c:

TimePicker v DatePicker 98
Gio trnh Android

Hnh: TimePicker vi nh dng thi gian theo 24 gi

Tuy nhin TimePicker tng i tn din tch mn hnh, v vy thng thng ngi ta hay ngi dng la chn thi
gian trong mt ca s ring, sau cp nht thi gian va la chn vo giao din chnh di dng view khc (TextView
chng hn).

chn thi gian trong hp thoi, ta dng TimePickerDialog cho ngi dng chn thi gian v vit sn mt hm lng
nghe s kin khi ngi dng chn xong:

showDialog(TIME_DIALOG_ID);

v:

@Override
protected Dialog onCreateDialog(int id)
{
switch (id) {
case TIME_DIALOG_ID:
return new TimePickerDialog(
this, mTimeSetListener, hour, minute, false);
}
return null;
}

private TimePickerDialog.OnTimeSetListener mTimeSetListener =


new TimePickerDialog.OnTimeSetListener()
{
public void onTimeSet(
TimePicker view, int hourOfDay, int minuteOfHour)
{
hour = hourOfDay;
minute = minuteOfHour;

SimpleDateFormat timeFormat = new SimpleDateFormat("hh:mm aa");

TimePicker v DatePicker 99
Gio trnh Android

Date date = new Date(0,0,0, hour, minute);


String strDate = timeFormat.format(date);

Toast.makeText(getBaseContext(),
"You have selected " + strDate,
Toast.LENGTH_SHORT).show();
}
};

Kt qu ta thu c nh sau:

Hnh: TimePickerDialog c hin th di dng hp thoi

DatePicker

Tng t nh TimePicker chn thi gian, DatePicker c dng chn ngy thng vi cch s dng tng t.

S dng trong layout:

<?xml version="1.0" encoding="utf-8"?>


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >

<Button android:id="@+id/btnSet"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="I am all set!"
android:onClick="onClick" />

<DatePicker android:id="@+id/datePicker"
android:layout_width="wrap_content"

TimePicker v DatePicker 100


Gio trnh Android

android:layout_height="wrap_content" />

<TimePicker android:id="@+id/timePicker"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>

Hnh: TimePicker (tri) v DatePicker (phi)

Hoc s dng hp thoi thng qua

DatePickerDialog:
showDialog(DATE_DIALOG_ID);

v:

@Override
protected Dialog onCreateDialog(int id)
{
switch (id) {
case DATE_DIALOG_ID:
return new DatePickerDialog(
this, mDateSetListener, yr, month, day);

}
return null;
}

private DatePickerDialog.OnDateSetListener mDateSetListener =


new DatePickerDialog.OnDateSetListener()
{
public void onDateSet(
DatePicker view, int year, int monthOfYear, int dayOfMonth)
{
yr = year;

TimePicker v DatePicker 101


Gio trnh Android

month = monthOfYear;
day = dayOfMonth;
Toast.makeText(getBaseContext(),
"You have selected : " + (month + 1) +
"/" + day + "/" + year,
Toast.LENGTH_SHORT).show();
}
};

Hnh: DatePickerDialog c hin th trong hp thoi

TimePicker v DatePicker 102


Gio trnh Android

Hin th nh vi ImageView v Gallery


nh l i tng c s dng rt tch cc trong cc ng dng hin i. Trong phn ny ta s tm hiu cch hin th nh
trong Android vi ImageView v hin th danh sch nh vi Gallery view. Ta s xem xt 2 loi view ny trong mt v d
tng i in hnh: hin th danh sch nh cho php ngi dng cun v chn nh cn xem. nh c chn s c
hin th to hn bn di. Trc tin ta chun b mt s nh cho d n ny:

Cc nh ny ta s t vo th mc res/ drawable-mdpi:

Trong m ngun, cc nh ny s c truy cp thng qua id ca n trong lp R (resource):

R.drawable.pic1,
R.drawable.pic2,
R.drawable.pic3,
R.drawable.pic4,
R.drawable.pic5,
R.drawable.pic6,
R.drawable.pic7

Hin th nh vi ImageView v Gallery 103


Gio trnh Android

Layout ca activity cho v d ny nh sau:

<?xml version="1.0" encoding="utf-8"?>


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >

<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Images of San Francisco" />

<Gallery
android:id="@+id/gallery1"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />

<ImageView
android:id="@+id/image1"
android:layout_width="320dp"
android:layout_height="250dp"
android:scaleType="fitXY" />

</LinearLayout>

M ngun ca activity ny nh sau:

public class GalleryActivity extends Activity {


//---the images to display---
Integer[] imageIDs = {
R.drawable.pic1,
R.drawable.pic2,
R.drawable.pic3,
R.drawable.pic4,
R.drawable.pic5,
R.drawable.pic6,
R.drawable.pic7
};

/** Called when the activity is first created. */


@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

Gallery gallery = (Gallery) findViewById(R.id.gallery1);

gallery.setAdapter(new ImageAdapter(this));
gallery.setOnItemClickListener(new OnItemClickListener()
{
public void onItemClick(AdapterView<?> parent, View v,
int position, long id)
{
Toast.makeText(getBaseContext(),
"pic" + (position + 1) + " selected",
Toast.LENGTH_SHORT).show();

//---display the images selected---


ImageView imageView = (ImageView) findViewById(R.id.image1);
imageView.setImageResource(imageIDs[position]);
}
});
}

public class ImageAdapter extends BaseAdapter


{
Context context;
int itemBackground;

public ImageAdapter(Context c)
{

Hin th nh vi ImageView v Gallery 104


Gio trnh Android

context = c;
//---setting the style---
TypedArray a = obtainStyledAttributes(R.styleable.Gallery1);

itemBackground = a.getResourceId(
R.styleable.Gallery1_android_galleryItemBackground, 0);

a.recycle();
}

//---returns the number of images---


public int getCount() {
return imageIDs.length;
}

//---returns the item---


public Object getItem(int position) {
return position;
}

//---returns the ID of an item---


public long getItemId(int position) {
return position;
}

//---returns an ImageView view---


public View getView(int position, View convertView, ViewGroup parent) {
ImageView imageView;
if (convertView == null) {
imageView = new ImageView(context);
imageView.setImageResource(imageIDs[position]);
imageView.setScaleType(ImageView.ScaleType.FIT_XY);
imageView.setLayoutParams(new Gallery.LayoutParams(150, 120));
} else {
imageView = (ImageView) convertView;
}
imageView.setBackgroundResource(itemBackground);
return imageView;
}
}
}

Sau khi chy ng dng, ta s quan st thy danh sch cc nh nh pha trn cng ca activity, ta c th cun ngang
danh sch ny chn nh mun xem, nh c chn s lun c cn gia trong Gallery. Sau khi c chn, nh to s
c hin th bn di (xem hnh minh ha bn di).

Hin th nh vi ImageView v Gallery 105


Gio trnh Android

Hnh: Gallery

Ta cn gii thch thm mt cht v on m ngun ca Activity pha trn. u tin, ta lu danh sch ID ca cc nh cn
thm vo Gallery:

Integer[] imageIDs = {
R.drawable.pic1,
R.drawable.pic2,
R.drawable.pic3,
R.drawable.pic4,
R.drawable.pic5,
R.drawable.pic6,
R.drawable.pic7
};

Sau , thm cc nh ny vo Gallery, ta cn mt lp trung gian, gi l adapter. Adapter ny s cung cp ngun ni


dung cho cc i tng gm nhiu phn t nh Gallery hay cc danh sch. Ta s xem chi tit adapter ny pha di.
gn adapter ny vo gallery, ta dng hm

setAdapter:
gallery.setAdapter(new ImageAdapter(this));

Khi mt nh trong gallery c chn, ta s hin th nh to pha di. lm vic ny, ta cn thm hm x l s kin

Hin th nh vi ImageView v Gallery 106


Gio trnh Android

onItemClick ca gallery:

gallery.setOnItemClickListener(new OnItemClickListener()
{
public void onItemClick(AdapterView<?> parent, View v,
int position, long id)
{
Toast.makeText(getBaseContext(),
"pic" + (position + 1) + " selected",
Toast.LENGTH_SHORT).show();

//---display the images selected---


ImageView imageView = (ImageView) findViewById(R.id.image1);
imageView.setImageResource(imageIDs[position]);
}
});

Mi lp adapter cho cc view nhiu i tng (nh gallery) cn k tha t lp BaseAdapter v cn np chng cc
phng thc sau:

public class ImageAdapter extends BaseAdapter


{
public ImageAdapter(Context c){ }

public int getCount(){ }

public Object getItem(int position) { }

public long getItemId(int position) { }

public View getView(int position, View convertView, ViewGroup parent) {}


}

Trong hm getView tr v view ca i tng con (item) trong danh sch, ti v tr position.

Mt s view s dng Adapter lm ngun d liu trong Android c th k n nh:

ListView: danh sch cc i tng (theo chiu dc)


GridView: danh sch cc i tng dng bng (nhiu ct, cun theo chiu dc)
Spinner: danh sch x xung (ging khi nim combo box trong lp trnh web)
Gallery: th vin nh nh v d trn

Android cng nh ngha sn mt s lp con ca lp BasicAdapter nh:

ListAdapter
ArrayAdapter
CursorAdapter
SpinnerAdapter

Chng ta s tm hiu mt s lp trong s trong phn cn li ca gio trnh.

Hin th nh vi ImageView v Gallery 107


Gio trnh Android

S dng ListView hin th danh sch di


Trong Android hin th tp hp nhiu phn t cng loi, ta dng danh sch. C 2 loi danh sch c nh ngha sn l
ListView v SpinnerView . Trong phn ny ta s ln lt xem xt tng loi danh sch ny.

ListView

ListView hin th danh sch cc i tng con di dng danh sch dc, c kh nng cun khi chiu di danh sch vt
qu chiu cao ca view m. Ta s xem xt ListView trong trng hp n gin nht: hin th danh sch cc phn t dng
ch.

Trc tin, ta chun b mng d liu cc ch cn hin th trong danh sch. Ta c th nhp cng (hard code) danh sch
ny trong m ngun java ca Activity nh sau:

String[] presidents= {
"Dwight D. Eisenhower",
"John F. Kennedy",
"Lyndon B. Johnson",
"Richard Nixon",
"Gerald Ford",
"Jimmy Carter",
"Ronald Reagan",
"George H. W. Bush",
"Bill Clinton",
"George W. Bush",
"Barack Obama"
};

Tuy nhin cch lm ny lm cho m ngun ri hn, gy kh khn cho vic bo tr, cng nh hn ch kh nng a phng
ha (thay i ngn ng cho ng dng). V vy, trong lp trnh Android, phng php c khuyn dng l nh ngha cc
d liu tnh ny trong th mc res. C th, i vi mng ch nh trn, ta c th nh ngha trong file
res/values/string.xml nh sau:

<?xml version="1.0" encoding="utf-8"?>


<resources>
<string name="hello">Hello World, BasicViews5Activity!</string>
<string name="app_name">BasicViews5</string>
<string-array name="presidents_array">
<item>Dwight D. Eisenhower</item>
<item>John F. Kennedy</item>
<item>Lyndon B. Johnson</item>
<item>Richard Nixon</item>
<item>Gerald Ford</item>
<item>Jimmy Carter</item>
<item>Ronald Reagan</item>
<item>George H. W. Bush</item>
<item>Bill Clinton</item>
<item>George W. Bush</item>
<item>Barack Obama</item>
</string-array>
</resources>

Sau , trong m ngun Java, ta c th d dng ly ra mng ny bng cch nh sau:

String[] presidents;
presidents = getResources().getStringArray(R.array.presidents_array);

to mt danh sch, trc tin ta khai bo 1 ListView trong file layout ca Activity:

S dng ListView hin th danh sch di 108


Gio trnh Android

<?xml version="1.0" encoding="utf-8"?>


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >

<ListView
android:id="@+id/android:list"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />

</LinearLayout>

i vi Activity c mt ListView bn trong, Android nh ngha sn lp con ca Activity l ListActivity gip cho qu trnh lm
vic vi ListView tr n gin hn. c th dng c ListActivity ny, c 2 vic cn phi lm:

Activity phi k tha t lp android.app.ListActivity


ListView trong file layout ca Activity phi c id l "@+id/android:list"

M ngun ca Activity s nh sau:

public class BasicViews5Activity extends ListActivity {

String[] presidents;

/** Called when the activity is first created. */


@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

setContentView(R.layout.main);

presidents =
getResources().getStringArray(R.array.presidents_array);

setListAdapter(new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_checked, presidents));
}

@Override
public void onListItemClick(
ListView parent, View v, int position, long id)
{
Toast.makeText(this,
"You have selected " + presidents[position],
Toast.LENGTH_SHORT).show();
}
}

ListView trong Android cng ly ni dung t mt Adapter ging nh trng hp ca Gallery ta lm quen trc . i
vi ListActivity, ta khng cn ly tham chiu n ListView mt cch minh bch, m c th gi thng hm setListAdapter
t adapter cho listView trong Activity (c t id theo quy nh nh ni trn).

x l s kin ngi dng bm chn mt phn t trong ListView, ta ch cn np chng hm onListItemClick nh on


m trn. Trong v d ny ta ch n thun in ra ch ca phn t c chn.

Activity trn khi chy trn emulator s c dng nh sau:

S dng ListView hin th danh sch di 109


Gio trnh Android

Hnh: Hin th danh sch vi ListView

Ta c th vut ln/xung mn hnh xem ton b danh sch. C rt nhiu ty chn c th lm vi ListView. Bn c t
tm hiu coi nh bi tp. y ta ch ni thm mt tnh kh nng ca ListView cho php la chn nhiu phn t cng lc
(multi-item selection). bt tnh nng ny, ta ch cn gi hm setChoiceMode ca ListView nh sau:

ListView lstView = getListView();


lstView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);

ListView vi thuc tnh la chn nhiu phn t c bt s c dng nh sau:

S dng ListView hin th danh sch di 110


Gio trnh Android

Hnh: ListView cho php la chn nhiu phn t cng lc

SpinnerView

ListView rt tin dng cho vic hin th danh sch cc phn t ng dng. Tuy nhin, ListView chim tng i nhiu din
tch trn mn hnh. Trong thc t c nhiu trng hp ta ch cn hin th phn t ang chn ca danh sch, khi bm vo
phn t ny, s hin ra danh sch y cc phn t cn li ta la chn. lm c vic ny, ta dng SpinnerView.
d hnh dung, ta c th nhiu SpinnerView chnh l ComboBox trong lp trnh web v Windows Form.

Trong v d di y, ta vn hin th danh sch cc phn t dng ch nh v d trc, tuy nhin dng SpinerView thay
cho ListView.

Trc tin, ta thm khai bo mt SpinnerView trong file layout ca Activity:

<?xml version="1.0" encoding="utf-8"?>


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >

<Spinner
android:id="@+id/spinner1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:drawSelectorOnTop="true" />

</LinearLayout>

Sau , trong hm onCreate ca Activity, ta cn thm m ngun truy xut n SpinnerView ny, t adapter cho n v
thm hm x l s kin khi ta chn mt phn t ca spinner:

S dng ListView hin th danh sch di 111


Gio trnh Android

presidents =
getResources().getStringArray(R.array.presidents_array);
Spinner s1 = (Spinner) findViewById(R.id.spinner1);

ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,


android.R.layout.simple_spinner_item, presidents);
s1.setAdapter(adapter);
s1.setOnItemSelectedListener(new OnItemSelectedListener()
{
@Override
public void onItemSelected(AdapterView<?> arg0,
View arg1, int arg2, long arg3)
{
int index = arg0.getSelectedItemPosition();
Toast.makeText(getBaseContext(),
"You have selected item : " + presidents[index],
Toast.LENGTH_SHORT).show();
}

@Override
public void onNothingSelected(AdapterView<?> arg0) { }
});

Khi mt phn t ca SpinnerView c chn, ta ch n thun in ln mn hnh thng bo dng Toast. Chy ng dng va
to ln thit b hoc emulator, spinner view ca chng ta s c dng nh hnh di y:

Hnh: Spinner View

S dng ListView hin th danh sch di 112


Gio trnh Android

Hin th ni dung trang web vi WebView


WebView cho php chng ta nhng trnh duyt web vo bn trong ng dng ca mnh. S dng web view rt hu dng
trong trng hp chng ta cn hin th ni dung mt trang web bn trong ng dng, cng nh khi chng ta mun thit k
mt phn hoc thm ch ton b giao din bng ngn ng web quen thuc (HTML5, Javascript, CSS).

Trong v d di y, ta s s dng web view hin th ni dung ca mt trang web trn Internet, c th ta s hin th
mt biu t dch v Chart ca Google.

Trc tin, ta cn thm mt WebView vo file layout ca Activity:

<?xml version="1.0" encoding="utf-8"?>


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >

<WebView android:id="@+id/webview1"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />

</LinearLayout>

Sau trong hm onCreate ca Activity, ta cn thm on m cu hnh webview ny hin th ni dung trang web t
Internet:

WebView wv = (WebView) findViewById(R.id.webview1);

WebSettings webSettings = wv.getSettings();


webSettings.setBuiltInZoomControls(true);
wv.loadUrl(
"http://chart.apis.google.com/chart" +
"?chs=300x225" +
"&cht=v" +
"&chco=FF6342,ADDE63,63C6DE" +
"&chd=t:100,80,60,30,30,30,10" +
"&chdl=A|B|C");

Ngoi ra, do ng dng mun truy cp vo Internet ly d liu t trang web ca Google Chart, ta cn khai bo quyn
truy cp Internet mt cch tng minh trong file AndroidManifest.xml nh sau:

<?xml version="1.0" encoding="utf-8"?>


<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="vn.edu.humg.android_course.WebView"
android:versionCode="1"
android:versionName="1.0" >

<uses-sdk android:minSdkVersion="14" />


<uses-permission android:name="android.permission.INTERNET"/>

<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name" >

</application>
</manifest>

Chy ng dng trn in thoi hoc Emulator, ta s thy mt th c v bi dch v Google Chart trn mn hnh:

Hin th ni dung trang web vi WebView 113


Gio trnh Android

Hnh: WebView hin th trang Web t Internet

Ngoi ra, WebView cng c th c dng hin th giao din bng HTML ta t khai bo trong m ngun nh v d di
y:

WebView wv = (WebView) findViewById(R.id.webview1);

WebSettings webSettings = wv.getSettings();


webSettings.setBuiltInZoomControls(true);

final String mimeType = "text/html";


final String encoding = "UTF-8";
String html = "<H1>A simple HTML page</H1><body>" +
"<p>The quick brown fox jumps over the lazy dog</p></body>";
wv.loadDataWithBaseURL("", html, mimeType, encoding, "");

Chy ng dng, ta s thy giao din tng t nh minh ha trong hnh sau:

Hin th ni dung trang web vi WebView 114


Gio trnh Android

Hnh: WebView hin th trc tip m HTML

Hin th ni dung trang web vi WebView 115


Gio trnh Android

Lu tr d liu
Trong chng ny chng ta s xem xt cch thc lu tr d liu trong Android. Lu tr d liu l tnh nng quan trng i
vi ng dng, gip cho ngi dng c th dng li c nhng d liu trc m khng cn nhp li. Trong Android c
3 cch lu li d liu:

C ch cu hnh chia s (shared preferences) c dng lu nhng d liu nh di dng key-value (tn kha
gi tr kha)
Lu d liu c nh vo tp tin trong b nh trong hoc b nh ngoi ca in thoi
Lu d liu s dng c s d liu quan h cc b SQLite

Chng ta s ln lt duyt qua cc phng php k trn trong chng ny.

Lu tr d liu 116
Gio trnh Android

Lu tr d liu c nh vi shared preferences


Android cung cp sn mt c ch n gin gip chng ta lu tr nhanh cc d liu ngn nh cu hnh ng dng, tn
ng nhp, email v ly li d liu ghi ny trong cc ln chy ng dng tip theo.

Cch thc thun tin nht l m t tp trung cc cu hnh ta cn lu li trong mt Activity (thng l mn hnh Settings
ca ng dng). Android cung cp sn mt loi Activity c bit l PreferenceActivity gip n gin ha qu trnh ny. V d
di y minh ha cch s dng Activity ny.

s dng c PreferenceActivity, trc ht ta m t cc thng tin cn lu li trong mt ti liu xml nm trong th mc


res/xml. Trong v d ny, ta to file res/xml/myapppreferences.xml vi ni dung nh sau:

<?xml version="1.0" encoding="utf-8"?>


<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android">
<PreferenceCategory android:title="Category 1">
<CheckBoxPreference
android:title="Checkbox"
android:defaultValue="false"
android:summary="True or False"
android:key="checkboxPref" />
</PreferenceCategory>
<PreferenceCategory android:title="Category 2">
<EditTextPreference
android:summary="Enter a string"
android:defaultValue="[Enter a string here]"
android:title="Edit Text"
android:key="editTextPref"
/>
<RingtonePreference
android:summary="Select a ringtone"
android:title="Ringtones"
android:key="ringtonePref"
/>
<PreferenceScreen
android:title="Second Preference Screen"
android:summary=
"Click here to go to the second Preference Screen"
android:key="secondPrefScreenPref" >
<EditTextPreference
android:summary="Enter a string"
android:title="Edit Text (second Screen)"
android:key="secondEditTextPref"
/>
</PreferenceScreen>
</PreferenceCategory>
</PreferenceScreen>

Sau , ta cn to mt Activity k tha t PreferenceActivity vi ni dung nh sau:

import android.os.Bundle;
import android.preference.PreferenceActivity;

public class AppPreferenceActivity extends PreferenceActivity {


@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
PreferenceManager prefMgr = getPreferenceManager();
prefMgr.setSharedPreferencesName("appPreferences");
//---load the preferences from an XML file---
addPreferencesFromResource(R.xml.myapppreferences);
}
}

Lu tr d liu c nh vi shared preferences 117


Gio trnh Android

Chy ng dng vi Activity nh trn, ta s c ngay mt mn hnh settings cho ng dng:

Ni dung ca mn hnh ny c m t hon ton trong file xml trn, trong chia cc cu hnh ny thnh 2 danh mc
(category 1 v category 2) v mt s loi cu hnh khc nhau nh checkbox, edittext, nhc chung v mt v d minh ha
cho vic m thm mn hnh cu hnh th 2 (khi mn hnh u c nhiu chi tit). Bm vo edittext, s c ca s popup cho
bn nhp gi tr cn lu li:

Lu tr d liu c nh vi shared preferences 118


Gio trnh Android

Hnh: Ca s popup cho php nhp cu hnh dng text (EditText)

Cu hnh nhc chung:

Lu tr d liu c nh vi shared preferences 119


Gio trnh Android

Hnh: Ca s popup cho php la chn cu hnh t danh sch cc RadioButton

Mn hnh preference th 2:

Lu tr d liu c nh vi shared preferences 120


Gio trnh Android

Hnh: Mn hnh cu hnh m rng

Sau khi bn thay i gi tr ca cc mc cu hnh trong Activity ny, h thng s t ng lu li gi tr ca chng c th


s dng c trong cc ln tip theo.

Vic lu tr d liu ny l trong sut vi ngi dng. Tuy nhin vi my o Android ta c th xem c c th cc gi tr
ny. Trn thc t, chng c lu trong 1 file xml nm trn b nh trong, trong vng nh ch c th truy cp c bi ng
dng to ra n (th mc /data/data/{package-name}/shared_prefs/appPreferences.xml):

Ni dung file ny c dng nh sau:

<?xml version='1.0' encoding='utf-8' standalone='yes' ?>

Lu tr d liu c nh vi shared preferences 121


Gio trnh Android

<map>
<string name="editTextPref">HUMG - Software engineer</string>
<string name="secondEditTextPref">HUMG - 2nd screen text</string>
<string name="ringtonePref">content://settings/system/ringtone</string>
<boolean name="checkboxPref" value="true" />
</map>

ly gi tr ca cc cu hnh ny trong code, ta lm nh sau:

SharedPreferences appPrefs = getSharedPreferences("appPreferences", MODE_PRIVATE);


Toast.makeText(this, appPrefs.getString("editTextPref", ""), Toast.LENGTH_LONG).show();

Trong , appPreferences l tn ca file cu hnh cn m (c t hm


prefMgr.setSharedPreferencesName("appPreferences") ; pha trn), cn editTextPref l tn ca thuc tnh cn ly gi tr

(c t trong file res/xml/myappprefererences.xml trn).

Ngoi ra, ta cng c th t li gi tr ca cc cu hnh ny bng tay m khng cn thng qua PreferenceActivity bng
cch s dng SharedPreferences.Editor nh sau:

SharedPreferences appPrefs =
getSharedPreferences("appPreferences", MODE_PRIVATE);

SharedPreferences.Editor prefsEditor = appPrefs.edit();


prefsEditor.putString("editTextPref",
((EditText) findViewById(R.id.txtString)).getText().toString());
prefsEditor.commit();

Sau khi thay i gi tr ca cc thuc tnh cn thay i, ta cn gi phng thc commit() ca lp Editor ny cc thay
i c hiu lc (tin hnh ghi vo file xml trong b nh trong nh m t trn).

Lu tr d liu c nh vi shared preferences 122


Gio trnh Android

Lu tr d liu bng file trn b nh trong v b nh ngoi


Trong trng hp cn lu li d liu phc tp hn (kh c th lu li dng key-value trong shared preference), ta c th
dng h thng file. Trong Android, lm vic (nhp/xut) vi file, ta c th dng cc lp ca gi java.io . Trong phn
ny, ta s xem cch lm vic vi file trong b nh trong ln b nh ngoi.

Lm vic vi file trong b nh trong

Ta s to mt Activity c mt nhp vn bn (EditText) v 2 nt bm cho php ghi v c vn bn ny vo file. Layout ca


Activity ny nh sau:

<?xml version="1.0" encoding="utf-8"?>


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >

<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Please enter some text" />

<EditText
android:id="@+id/txtText1"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />

<Button
android:id="@+id/btnSave"
android:text="Save"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:onClick="onClickSave" />

<Button
android:id="@+id/btnLoad"
android:text="Load"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:onClick="onClickLoad" />
</LinearLayout>

M ngun ca Activity vi 2 hm c ( onClickLoad ) v ghi ( onClickSave ) vo file nh sau:

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;

public class FilesActivity extends Activity {


EditText textBox;
static final int READ_BLOCK_SIZE = 100;

/** Called when the activity is first created. */


@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

Lu tr d liu vi file trn b nh trong v b nh ngoi 123


Gio trnh Android

textBox = (EditText) findViewById(R.id.txtText1);

public void onClickSave(View view) {


String str = textBox.getText().toString();
try
{
FileOutputStream fOut =
openFileOutput("textfile.txt",
MODE_PRIVATE);

OutputStreamWriter osw = new


OutputStreamWriter(fOut);

//---write the string to the file---


osw.write(str);
osw.flush();
osw.close();

//---display file saved message---


Toast.makeText(getBaseContext(),
"File saved successfully!",
Toast.LENGTH_SHORT).show();

//---clears the EditText---


textBox.setText("");
}
catch (IOException ioe)
{
ioe.printStackTrace();
}
}

public void onClickLoad(View view) {


try
{
FileInputStream fIn =
openFileInput("textfile.txt");
InputStreamReader isr = new
InputStreamReader(fIn);

char[] inputBuffer = new char[READ_BLOCK_SIZE];


String s = "";

int charRead;
while ((charRead = isr.read(inputBuffer))>0)
{
//---convert the chars to a String---
String readString =
String.copyValueOf(inputBuffer, 0,
charRead);
s += readString;

inputBuffer = new char[READ_BLOCK_SIZE];


}
//---set the EditText to the text that has been
// read---
textBox.setText(s);

Toast.makeText(getBaseContext(),
"File loaded successfully!",
Toast.LENGTH_SHORT).show();
}
catch (IOException ioe) {
ioe.printStackTrace();
}

}
}

Trong on m trn, ta thy vic c v ghi vo file tng i n gin v quen thuc. ghi d liu vo file, ta to mt
i tng OutputStreamWriter trn lung xut FileOutputStream v tin hnh ghi vo qua phng thc write. Sau , gi
flush y ht d liu trong b m vo file v ng lung li:

Lu tr d liu vi file trn b nh trong v b nh ngoi 124


Gio trnh Android

FileOutputStream fOut = openFileOutput("textfile.txt", MODE_PRIVATE);

OutputStreamWriter osw = new OutputStreamWriter(fOut);

//---write the string to the file---


osw.write(str);
osw.flush();
osw.close();

c ni dung file ny, ta cng thao tc tng t. To i tng InputStreamReader t lung nhp liu ( FileInputStream )
v tin hnh c d liu bng phng thc read() . Mi ln c s c READ_BLOCK_SIZE byte v lu vo b m (mng
byte). Ni dung ny s c chuyn thnh string v ni thm vo bin s . Qu trnh c lp li cho n khi ht ni dung
ca file:

FileInputStream fIn = openFileInput("textfile.txt");


InputStreamReader isr = new InputStreamReader(fIn);

char[] inputBuffer = new char[READ_BLOCK_SIZE];


String s = "";

int charRead;
while ((charRead = isr.read(inputBuffer))>0)
{
String readString = String.copyValueOf(inputBuffer, 0, charRead);
s += readString;
inputBuffer = new char[READ_BLOCK_SIZE];
}
textBox.setText(s);

Mt cu hi t ra l file "textfile.txt" trn c to ra u trong cy th mc. Cu tr li l n c to ra trong b nh


trong ca thit b, trong th mc dnh ring cho ng dng (/data/data/{package-name}/files)

Chy ng dng, nhp ni dung cho nhp liu v bm Save, ta s thy ni dung vn bn ny c ghi vo file trong b
nh trong.

Lu tr d liu vi file trn b nh trong v b nh ngoi 125


Gio trnh Android

Hnh: Giao din nhp/hin th d liu c v ghi file

Hnh: V tr file d liu va ghi trong b nh thit b

Ko file ny v my tnh xem ni dung file, ta s thy ni dung vn bn ta nhp vo trc

Lu tr d liu vi file trn b nh trong v b nh ngoi 126


Gio trnh Android

Hnh: Ni dung file d liu va ghi trong b nh thit b

Lm vic vi file trong b nh ngoi

File trong b nh trong ch c truy cp bi ng dng to ra n. Ngoi ra, dung lng lu tr ca b nh trong thng
hn ch hn b nh ngoi (SDCard). V vy, trong trng hp ta mun chia s thng tin lu tr vi cc ng dng khc, ta
nn s dng b nh ngoi. Lm vic vi file trong b nh ngoi hon ton tng t vi file trong b nh trong, ch khc
phn ly ra FileInputStream v FileOutputStream :

Thay v dng:

FileOutputStream fOut = openFileOutput("textfile.txt", MODE_PRIVATE);

Ta dng:

File sdCard = Environment.getExternalStorageDirectory();


File directory = new File(sdCard.getAbsolutePath() + "/MyFiles");
directory.mkdirs();
File file = new File(directory, "textfile.txt");
FileOutputStream fOut = new FileOutputStream(file);

V thay v:

FileInputStream fIn = openFileInput("textfile.txt");

Ta dng:

File sdCard = Environment.getExternalStorageDirectory();


File directory = new File (sdCard.getAbsolutePath() + "/MyFiles");
File file = new File(directory, "textfile.txt");
FileInputStream fIn = new FileInputStream(file);
InputStreamReader isr = new InputStreamReader(fIn);

Mi thao tc vn nh trng hp trc, ch khc b tr lu tr file trong cy th mc:

Lu tr d liu vi file trn b nh trong v b nh ngoi 127


Gio trnh Android

Hnh: V tr file d liu va ghi trn b nh ngoi ca thit b

Lu tr d liu vi file trn b nh trong v b nh ngoi 128


Gio trnh Android

C s d liu SQLite trong ng dng Android


Trong phn trc, ta tm hiu cch lu d liu vo file v vo shared preferences. Tuy nhin, vi loi d liu quan h
th vic s dng c s d liu quan h s thun tin hn rt nhiu. V d, ta cn lu tr kt qu kim tra ca cc sinh vin
trong trng hc. Dng c s d liu s cho php chng ta truy vn kt qu ca tp sinh vin nht nh theo cc tiu ch
khc nhau. Vic thm, bt, thay i thng tin thng qua cc cu truy vn SQL cng d dng hn nhiu so vi vic thao tc
trn file. Android s dng h c s d liu SQLite. CSDL do mt ng dng to ra s ch c truy xut bi ng dng ,
v file CSDL s nm trong b nh trong dnh ring cho ng dng (/data/data/{package-name}/databases/).

Mt thi quen tt thng c cc lp trnh vin kinh nghim s dng l tp trung tt c m lnh truy cp n CSDL vo
mt lp ring thao tc trn CSDL tr nn trong sut vi mi trng ngoi. Chng ta s to trc mt lp nh vy, gi l
DBAdapter.

To lp DBAdapter

Trong v d ny ta s to mt CSDL tn l MyDB, cha mt bng duy nht l contacts. Bng ny cha cc trng _id,
name v email. Lp DBAdapter c m ngun nh sau:

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;

public class DBAdapter {


static final String KEY_ROWID = "_id";
static final String KEY_NAME = "name";
static final String KEY_EMAIL = "email";
static final String TAG = "DBAdapter";

static final String DATABASE_NAME = "MyDB";


static final String DATABASE_TABLE = "contacts";
static final int DATABASE_VERSION = 2;

static final String DATABASE_CREATE =


"create table contacts (_id integer primary key autoincrement, "
+ "name text not null, email text not null);";

final Context context;

DatabaseHelper DBHelper;
SQLiteDatabase db;

public DBAdapter(Context ctx)


{
this.context = ctx;
DBHelper = new DatabaseHelper(context);
}

private static class DatabaseHelper extends SQLiteOpenHelper


{
DatabaseHelper(Context context)
{
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}

@Override
public void onCreate(SQLiteDatabase db)
{
try {
db.execSQL(DATABASE_CREATE);
} catch (SQLException e) {
e.printStackTrace();
}

CSDL SQLite trong ng dng Android 129


Gio trnh Android

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
{
Log.w(TAG, "Upgrading database from version " + oldVersion
+ " to " + newVersion + ", which will destroy all old data");
db.execSQL("DROP TABLE IF EXISTS contacts");
onCreate(db);
}
}

//---opens the database---


public DBAdapter open() throws SQLException
{
db = DBHelper.getWritableDatabase();
return this;
}

//---closes the database---


public void close()
{
DBHelper.close();
}

//---insert a contact into the database---


public long insertContact(String name, String email)
{
ContentValues initialValues = new ContentValues();
initialValues.put(KEY_NAME, name);
initialValues.put(KEY_EMAIL, email);
return db.insert(DATABASE_TABLE, null, initialValues);
}

//---deletes a particular contact---


public boolean deleteContact(long rowId)
{
return db.delete(DATABASE_TABLE, KEY_ROWID + "=" + rowId, null) > 0;
}

//---retrieves all the contacts---


public Cursor getAllContacts()
{
return db.query(DATABASE_TABLE, new String[] {KEY_ROWID, KEY_NAME,
KEY_EMAIL}, null, null, null, null, null);
}

//---retrieves a particular contact---


public Cursor getContact(long rowId) throws SQLException
{
Cursor mCursor =
db.query(true, DATABASE_TABLE, new String[] {KEY_ROWID,
KEY_NAME, KEY_EMAIL}, KEY_ROWID + "=" + rowId, null,
null, null, null, null);
if (mCursor != null) {
mCursor.moveToFirst();
}
return mCursor;
}

//---updates a contact---
public boolean updateContact(long rowId, String name, String email)
{
ContentValues args = new ContentValues();
args.put(KEY_NAME, name);
args.put(KEY_EMAIL, email);
return db.update(DATABASE_TABLE, args, KEY_ROWID + "=" + rowId, null) > 0;
}
}

Trc tin ta khai bo cc hng s nh: tn CSDL, tn bng, tn cc trng d dng truy xut v thay i trong qu
trnh pht trin. Ngoi ra, ta cng khai bo phin bn (do ta t nh s) ca CSDL trong ng dng v vit sn cu truy vn
dng to CSDL:

CSDL SQLite trong ng dng Android 130


Gio trnh Android

static final String KEY_ROWID = "_id";


static final String KEY_NAME = "name";
static final String KEY_EMAIL = "email";
static final String TAG = "DBAdapter";

static final String DATABASE_NAME = "MyDB";


static final String DATABASE_TABLE = "contacts";
static final int DATABASE_VERSION = 2;

static final String DATABASE_CREATE =


"create table contacts (_id integer primary key autoincrement, "
+ "name text not null, email text not null);";

Ta cng to thm mt lp cc b (lp DatabaseHelper trn) tr gip cho vic to CSDL v nng cp cu trc khi c
s thay i trong cc phin bn tip theo. Lp ny k tha t lp SQLiteOpenHelper . Hm dng ca lp ny s gi v hm
dng ca lp m vi tn v phin bn CSDL ca ng dng:

super(context, DATABASE_NAME, null, DATABASE_VERSION);

Ngoi ra, trong lp ny ta np chng 2 hm:

Hm onCreate() : c gi khi to CSDL trong ln u tin chy ng dng. Trong hm ny ta tin hnh thc thi
cu lnh to CSDL trn (DATABASE_CREATE)
Hm onUpgrade() : c gi khi ta nng cp ng dng v thay i gi tr ca phin bn CSDL (DATABASE_VERSION)
trn. Trong v d trn, khi c thay i phin bn ny, ta xa CSDL c v to li ci mi.

Ngoi ra, ta cng vit thm cc hm m CSDL, to mi bn ghi, cp nht bn ghi, ly tt c bn ghi, ly bn ghi theo
id (xem on m trn).

Sau khi c lp DBAdapter ny, vic truy xut CSDL tr nn tng i n gin, on m di y minh ha cc thao tc
thm, bt, truy vn CSDL:

DBAdapter db = new DBAdapter(this);

//--- thm mt bn ghi ---


db.open();
long id = db.insertContact("Wei-Meng Lee", "weimenglee@learn2develop.net");
id = db.insertContact("Mary Jackson", "mary@jackson.com");
db.close();

//-- ly danh sch tt c bn ghi ---


db.open();
Cursor c = db.getAllContacts();
if (c.moveToFirst())
{
do {
DisplayContact(c);
} while (c.moveToNext());
}
db.close();

//--- ly mt bn ghi theo id ---


db.open();
c = db.getContact(2);
if (c.moveToFirst())
DisplayContact(c);
else
Toast.makeText(this, "No contact found", Toast.LENGTH_LONG).show();
db.close();

//--- cp nht bn ghi ---


db.open();
if (db.updateContact(1, "Wei-Meng Lee", "weimenglee@gmail.com"))
Toast.makeText(this, "Update successful.", Toast.LENGTH_LONG).show();
else
Toast.makeText(this, "Update failed.", Toast.LENGTH_LONG).show();
db.close();

CSDL SQLite trong ng dng Android 131


Gio trnh Android

//--- xa bn ghi ---


db.open();
if (db.deleteContact(1))
Toast.makeText(this, "Delete successful.", Toast.LENGTH_LONG).show();
else
Toast.makeText(this, "Delete failed.", Toast.LENGTH_LONG).show();
db.close();

Trong hm DisplayContact(c) ch n gin hin th ln mn hnh ni dung bn ghi di dng Toast:

public void DisplayContact(Cursor c)


{
Toast.makeText(this,
"id: " + c.getString(0) + "\n" +
"Name: " + c.getString(1) + "\n" +
"Email: " + c.getString(2),
Toast.LENGTH_LONG).show();
}

Chy ng dng v dng trnh duyt file ca Emulator, ta c th thy file CSDL c to ra trong th mc
/data/data/{package-name}/databases/myDB:

Hnh: V tr file CSDL trong b nh ca thit b

Nu ta ly file ny v my tnh v c n bng cc phn mm h tr CSDL SQLite (nh NaviCat) ta s thy c ni dung
bng contacts bn trong.

CSDL SQLite trong ng dng Android 132


Gio trnh Android

Lp trnh mng vi Android


Trong cc ng dng hin i, nhu cu giao tip gia ng dng vi th gii bn ngoi (Internet) ht sc ph bin, t vic
ly v cp nht ni dung trc tuyn (t cc web site, cc web service), tng tc vi my ch, cho n lp trnh socket
m kt ni c nh n ng dng trn server.

Trong chng ny, ta s tm hiu cch thc ti d liu dng nh phn cng nh dng vn bn t my ch web thng qua
giao thc HTTP, cng nh vic phn tch c php d liu nhn v dng XML hoc JSON ly ra thng tin cn thit.

Vic lp trnh socket cn thm ng dng pha server, nm ngoi phm vi ca gio trnh, nn s khng c cp y,
bn c quan tm c th t tm hiu thm trong cc ti liu khc.

Lp trnh mng vi Android 133


Gio trnh Android

S dng cc dch v web services thng qua giao thc HTTP


Cch thc ph bin nht cp nht d liu trc tuyn l ly d liu t trang web trn Internet thng qua giao thc HTTP.
S dng giao thc ny, ta c th thc hin rt nhiu vic trao i d liu vi th gii bn ngoi, t vic ly ni dung trang
web, ti d liu nh phn (file nh phn, nh), ti d liu dng vn bn

V mt k thut, cc thao tc ny l nh nhau cho mi loi d liu ti v. V vy, trc tin ta to mt d n khung cho cc
ng dng s dng ti nguyn mng theo giao thc HTTP.

Trc ht, ta cn yu cu quyn truy cp Internet cho ng dng mt cch tng minh trong file AndroidManifest.xml nh
sau:

<?xml version="1.0" encoding="utf-8"?>


<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="vn.edu.humg.android_course.Networking"
android:versionCode="1"
android:versionName="1.0" >

<uses-sdk android:minSdkVersion="13" />


<uses-permission android:name="android.permission.INTERNET"/>

<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name" >
<activity
android:label="@string/app_name"
android:name=".NetworkingActivity" >
<intent-filter >
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />


</intent-filter>
</activity>
</application>
</manifest>

Sau , trong m ngun ca Activity chnh, ta vit thm mt hm ly d liu t trn mng v qua giao thc HTTP. Kt
qu ca vic ly d liu ny s cho ta mt lung nhp liu ( InputStream ) ta x l d liu (vic ly d liu ra loi g nh
phn hay vn bn s do lung nhp liu ny x l).

M ngun ca Activity ban u s nh sau:

public class NetworkingActivity extends Activity {

private InputStream OpenHttpConnection(String urlString)


throws IOException
{
InputStream in = null;
int response = -1;

URL url = new URL(urlString);


URLConnection conn = url.openConnection();

if (!(conn instanceof HttpURLConnection))


throw new IOException("Not an HTTP connection");
try{
HttpURLConnection httpConn = (HttpURLConnection) conn;
httpConn.setAllowUserInteraction(false);
httpConn.setInstanceFollowRedirects(true);
httpConn.setRequestMethod("GET");
httpConn.connect();
response = httpConn.getResponseCode();
if (response == HttpURLConnection.HTTP_OK) {
in = httpConn.getInputStream();

S dng web services thng qua giao thc HTTP 134


Gio trnh Android

}
}
catch (Exception ex)
{
Log.d("Networking", ex.getLocalizedMessage());
throw new IOException("Error connecting");
}
return in;
}

/** Called when the activity is first created. */


@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
}

Hm OpenHttpConnection trn nhn vo ng link n ti nguyn trn Internet, thc hin kt ni v tr d liu v vo
lung nhp liu ( InputStream ). Do vic lm vic vi ti nguyn mng thng xy ra li (khng kt ni c, link khng cn
tn ti...), ton b on m cho vic ny nm trong b x l nhn ngoi l try-catch bt cc li c th xy ra.

Lu l vic kt ni n my ch ly ti nguyn c th ko di, ty thuc vo kch thc ti nguyn, tc ng


truyn, kh nng x l ca thit b... V vy, hm trn thng c gi trong thread ring trnh vic kha cng giao
din ngi dng trong qu trnh x l. Ta s lm vic ny trong cc v d c th bn di vi vic ti d liu nh phn cng
nh ti d liu vn bn.

S dng web services thng qua giao thc HTTP 135


Gio trnh Android

Ti d liu nh phn thng qua HTTP


Trong phn ny, ta s minh ha mt trng hp ti d liu nh phn t my ch web thng qua giao thc HTTP. Ta s
dng ng dng khung v s dng ti nguyn qua HTTP trn ti mt nh (nh l d liu nh phn) t trn mng v v
hin th bn trong Activity. Trc tin, ta thm mt i tng ImageView vo file layout ca Activity hin th nh khi
c ti v:

<?xml version="1.0" encoding="utf-8"?>


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >

<ImageView
android:id="@+id/img"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center" />
</LinearLayout>

Nh ni trn, vic ti ti nguyn t mng phi nm trong thread ring, khc vi thread v giao din ng dng (UI
thread). y ta dng AsyncTask cho vic ny:

private Bitmap DownloadImage(String URL)


{
Bitmap bitmap = null;
InputStream in = null;
try {
in = OpenHttpConnection(URL);
bitmap = BitmapFactory.decodeStream(in);
in.close();
} catch (IOException e1) {
Log.d("NetworkingActivity", e1.getLocalizedMessage());
}
return bitmap;
}

private class DownloadImageTask extends AsyncTask<String, Void, Bitmap> {


protected Bitmap doInBackground(String... urls) {
return DownloadImage(urls[0]);
}

protected void onPostExecute(Bitmap result) {


ImageView img = (ImageView) findViewById(R.id.img);
img.setImageBitmap(result);
}
}

Hm DownloadImage thc hin ti nh t trn mng v v lu vo mt i tng Bitmap (i tng ny sn sng a


vo ImageView). Hm ny s dng hm OpenHttpConnection vit trn ly mt lung nhp liu cha d liu nh
ny, sau dng hm tnh decodeStream ca lp BitmapFactory gii m lung nhp liu ny v lu vo i tng
Bitmap.

Tuy nhin, hm DownloadImage ny cng s chim nhiu thi gian (bng thi gian ti nh v ca hm OpenHttpConnection
v thi gian gii m nh). V vy ta cn gi hm ny bn trong mt thread khc. Trong v d trn ta dng AsyncTask cho
vic ny. s dng AsyncTask , ta cn np chng ti thiu 2 hm:

doInBackground - hm ny c thc hin trong thread ring. Khi kt thc hm ny, n s t ng gi hm

onPostExecute trong UI thread. y l ni ta s thc hin cc thao tc tn thi gian.

onPostExecute hm ny c gi trong UI thread, sau khi cng vic ngm hm trn kt thc. y l ni ta cp

Ti d liu nh phn thng qua HTTP 136


Gio trnh Android

nht li UI t d liu c ti v.

Trong v d trn, ta tin hnh ti nh trong thread ring (trong hm doInBackground ) v tin hnh hin th nh mi c ti
v trong hm onPostExecute .

Cui cng, tin hnh ti nh, ta thm dng m gi n AsyncTask ny trong hm onCreate ca Activity:

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

new DownloadImageTask().execute("http://www.mayoff.com/5-01cablecarDCP01934.jpg");
}

Chy ng dng trn in thoi hoc Android Emulator, ta thy nh t mng s c hin th trn mn hnh (c th phi
ch mt lc nu kt ni mng khng tt) nh hnh minh ha bn di:

Hnh: Hnh nh c ti t Internet thng qua HTTP

Ti d liu nh phn thng qua HTTP 137


Gio trnh Android

Ti d liu dng text thng qua HTTP


Tng t nh vic ti d liu nh phn trn, trong nhiu trng hp ta cn ti d liu dng vn bn t mng (ly d liu
t cc web service chng hn). Ta cng s thc hin thao tc ny trong thread ring, s dng AsyncTask v tr v d liu
dng String trc khi hin th ln mn hnh (dng Toast).

on m ti v hin d liu vn bn trong thread ring nh sau:

private String DownloadText(String URL)


{
int BUFFER_SIZE = 2000;
InputStream in = null;
try {
in = OpenHttpConnection(URL);
} catch (IOException e) {
Log.d("NetworkingActivity", e.getLocalizedMessage());
return "";
}

InputStreamReader isr = new InputStreamReader(in);


int charRead;
String str = "";
char[] inputBuffer = new char[BUFFER_SIZE];
try {
while ((charRead = isr.read(inputBuffer))>0) {
//---convert the chars to a String---
String readString =
String.copyValueOf(inputBuffer, 0, charRead);
str += readString;
inputBuffer = new char[BUFFER_SIZE];
}
in.close();
} catch (IOException e) {
Log.d("NetworkingActivity", e.getLocalizedMessage());
return "";
}
return str;
}

private class DownloadTextTask extends AsyncTask<String, Void, String> {


protected String doInBackground(String... urls) {
return DownloadText(urls[0]);
}

@Override
protected void onPostExecute(String result) {
Toast.makeText(getBaseContext(), result, Toast.LENGTH_LONG).show();
}
}

on m trn ch khc vi vic ti nh trong phn trc on c d liu t lung nhp liu tr v. Trong trng hp d
liu vn bn, ta dng lp InputStreamReader v hm read ca n c ln lt d liu dng char ra, sau gn thm
dn vo string kt qu. Cui cng, ta ch cn gi AsyncTask mi to ra ny trong hm onCreate ca Activity xem kt
qu:

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

//---download text---
new DownloadTextTask().execute(
"http://iheartquotes.com/api/v1/random?max_characters=256&max_lines=10");
}

Ti d liu dng text thng qua HTTP 138


Gio trnh Android

Chy ng dng, ta s thy d liu t web service trn c in ra mn hnh:

Hnh: D liu dng vn bn (XML) c ti t Internet qua HTTP

Ti d liu dng text thng qua HTTP 139


Gio trnh Android

Web service vi d liu XML


Trong phn trn ta tin hnh ly d liu vn bn t web service thng qua giao thc HTTP. Tuy nhin trong v d trc
ta cng thy d liu tr v c th dng XML. y l nh dng tng i ph bin ca cc web service hin nay (bn
cnh JSON), v c th s dng c d liu ny trong ng dng, ta cn phn tch c php (parsing) ca d liu XML
ny. Trong phn ny ta s xem xt cch thc phn tch ti liu XML trong Android.

Trong v d ny, ta s thc hin tra ngha ca mt t ting anh trn t in trc tuyn ca Aonaware qua web service.
thc hin tra t, ta gi API nh sau: http://services.aonaware.com/DictService/DictService.asmx/Define?word={t-cn-tra} .
V d tra ngha ca t apple, ta cn gi API nh sau:
http://services.aonaware.com/DictService/DictService.asmx/Define?word=apple Nu bn m link ny vo trnh duyt web,
ta s thy ni dung web service ny tr v di dng XML nh sau:

Nhim v ca chng ra l vit on m phn tch ti liu XML trn ly ra phn ngha ca t (trong th WordDefinition )
v hin th ln mn hnh.

thc hin vic ny, ta cng cn khai bo mt AsyncTask trnh kha cng UI thread:

private String WordDefinition(String word) {


InputStream in = null;
String strDefinition = "";

Web service vi d liu XML 140


Gio trnh Android

try {
in = OpenHttpConnection("http://services.aonaware.com/DictService/DictService.asmx/Define?word="
+ word);
Document doc = null;
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db;
try {
db = dbf.newDocumentBuilder();
doc = db.parse(in);
} catch (ParserConfigurationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
doc.getDocumentElement().normalize();

// ---retrieve all the <Definition> elements---


NodeList definitionElements = doc
.getElementsByTagName("Definition");

// ---iterate through each <Definition> elements---


for (int i = 0; i < definitionElements.getLength(); i++) {
Node itemNode = definitionElements.item(i);
if (itemNode.getNodeType() == Node.ELEMENT_NODE) {
// ---convert the Definition node into an Element---
Element definitionElement = (Element) itemNode;

// ---get all the <WordDefinition> elements under


// the <Definition> element---
NodeList wordDefinitionElements = (definitionElement)
.getElementsByTagName("WordDefinition");

strDefinition = "";
// ---iterate through each <WordDefinition> elements---
for (int j = 0; j < wordDefinitionElements.getLength(); j++) {
// ---convert a <WordDefinition> node into an Element---
Element wordDefinitionElement = (Element) wordDefinitionElements
.item(j);

// ---get all the child nodes under the


// <WordDefinition> element---
NodeList textNodes = ((Node) wordDefinitionElement)
.getChildNodes();

strDefinition += ((Node) textNodes.item(0))


.getNodeValue() + ". \n";
}

}
}
} catch (IOException e1) {
Log.d("NetworkingActivity", e1.getLocalizedMessage());
}
// ---return the definitions of the word---
return strDefinition;
}

private class AccessWebServiceTask extends AsyncTask<String, Void, String> {


protected String doInBackground(String... urls) {
return WordDefinition(urls[0]);
}

protected void onPostExecute(String result) {


Toast.makeText(getBaseContext(), result, Toast.LENGTH_LONG).show();
}
}

Trong hm WordDefinition s ti ni dung ca webservice v tin hnh phn tch c php ti liu XML tr v. Cng vic
ny tn thi gian nn ta cn lm trong thread ring, do ta cn vit thm lp AccessWebServiceTask nh trn.

Vic cui cng l gi AsyncTask ny trong hm onCreate ca Activity:

Web service vi d liu XML 141


Gio trnh Android

/** Called when the activity is first created. */


@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

// ---access a Web Service using GET---


new AccessWebServiceTask().execute("apple");
}

ng dng khi chy s c dng nh minh ha trong hnh bn di.

Hnh: D liu XML c phn tch

Ta s i chi tit hn mt cht v hm WordDefinition trn. Trc ht, ta vn s dng hm OpenHttpConnection vit
trn ly thng tin t mng v a vo lung nhp liu:

in = OpenHttpConnection(http://services.aonaware.com/DictService/DictService.asmx/Define?word= + word);

Sau ta dng lp javax.xml.parsers.DocumentBuilder phn tch ti liu XML trong lung nhp liu ny thnh cy i
tng ti liu (DOM Document object model):

Document doc = null;


DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db;

db = dbf.newDocumentBuilder();
doc = db.parse(in);
doc.getDocumentElement().normalize();

Web service vi d liu XML 142


Gio trnh Android

Lu : trong on code trn ta b qua phn bt ngoi l try-catch cho d quan st. Sau khi parsing nh trn, ta thu
c mt cy i tng trong trng doc (i tng ca lp org.w3c.dom.Document ). Ta c th duyt cy ti liu ny
ly ra cc trng mong mun. C th: ly danh sch cc node Definitions :

NodeList definitionElements = doc.getElementsByTagName("Definition");

Sau duyt tng phn t trong danh sch node trn ly ra WordDefinition ca tng node:

NodeList wordDefinitionElements = (definitionElement).getElementsByTagName("WordDefinition");

Vic duyt cy DOM trch xut ra d liu cn thit l cng vic kh in hnh v ph bin. Bn c quan tm c th
tham kho chi tit hn ti cc ti liu khc.

Web service vi d liu XML 143


Gio trnh Android

Web service vi d liu JSON


Ngoi XML, mt inh dng d liu vn bn c s dng rt ph bin hin nay trong cc web service l JSON (JavaScript
Object Notation). So vi XML, nh dng JSON c mt s u im:

Json c nn d liu tt hn: cng mt d liu, XML tn nhiu dung lng hn ng gi, do cc th (tag) trong
XML c di nht nh. Dung lng ln nh hng xu n tc truyn ti cng nh kh nng lu tr ti liu.
X l (phn tch) ti liu XML tn km hn so vi JSON c v b nh ln ti nguyn CPU.

V d v mt ti liu JSON ta s th phn tch trong phn tip theo c th ly c qua ng link sau:

http://extjs.org.cn/extjs/examples/grid/survey.html

Nu m link ny bng trnh duyt, ta s quan st c ni dung nh hnh bn di.

V d di y s phn tch ti liu JSON trn v in ra mn hnh appeId v inputTime cho tng i tng trong danh

Web service vi d liu JSON 144


Gio trnh Android

sch phn tch c.

Ton b m ngun ca Activity cho v d ny nh sau:

package vn.edu.humg.android_course.JSON;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.StatusLine;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONArray;
import org.json.JSONObject;

import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;

public class JSONActivity extends Activity {

public String readJSONFeed(String URL) {


StringBuilder stringBuilder = new StringBuilder();
HttpClient client = new DefaultHttpClient();
HttpGet httpGet = new HttpGet(URL);
try {
HttpResponse response = client.execute(httpGet);
StatusLine statusLine = response.getStatusLine();
int statusCode = statusLine.getStatusCode();
if (statusCode == 200) {
HttpEntity entity = response.getEntity();
InputStream content = entity.getContent();
BufferedReader reader = new BufferedReader(
new InputStreamReader(content));
String line;
while ((line = reader.readLine()) != null) {
stringBuilder.append(line);
}
} else {
Log.e("JSON", "Failed to download file");
}
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return stringBuilder.toString();
}

private class ReadJSONFeedTask extends AsyncTask<String, Void, String> {


protected String doInBackground(String... urls) {
return readJSONFeed(urls[0]);
}

protected void onPostExecute(String result) {


try {
JSONArray jsonArray = new JSONArray(result);
Log.i("JSON", "Number of surveys in feed: " +
jsonArray.length());

//---print out the content of the json feed---


for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jsonObject = jsonArray.getJSONObject(i);
Toast.makeText(getBaseContext(), jsonObject.getString("appeId") +
" - " + jsonObject.getString("inputTime"),
Toast.LENGTH_SHORT).show();

Web service vi d liu JSON 145


Gio trnh Android

}
} catch (Exception e) {
e.printStackTrace();
}
}
}

/** Called when the activity is first created. */


@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

new ReadJSONFeedTask().execute("http://extjs.org.cn/extjs/examples/grid/survey.html");
}
}

Lu : trong m ngun trn, ta dng lp org.apache.http.client.HttpClient ly ni dung web service thng qua HTTP
thay cho java.net.HttpURLConnection . Bn c quan tm c th t tm hiu v lp ny cc ti liu khc, y ta ch quan
tm n on m ngun phn tch ti liu JSON.

phn tch ti liu JSON v a vo mt mng cc JSONObject , ta ch cn gi mt lnh n gin: JSONArray jsonArray =
new JSONArray(result);

Vi result l d liu vn bn th (dng String ) ly c t webservice. Sau tin hnh duyt ln lt cc JSONObject
thu c bng hm getJSONObject(i) v ly ni dung ca tng trng d liu trong mi i tng JSON bng phng
thc getString ca lp JSONObject .

for (int i = 0; i < jsonArray.length(); i++) {


JSONObject jsonObject = jsonArray.getJSONObject(i);
Toast.makeText(getBaseContext(), jsonObject.getString("appeId") +
" - " + jsonObject.getString("inputTime"),
Toast.LENGTH_SHORT).show();
}

Web service vi d liu JSON 146


Gio trnh Android

Google Play Store v vic phn phi ng dng


Nh vy chng ta hc c rt nhiu th xuyn sut gio trnh gip chng ta c th pht trin mt ng dng Android
cht lng. Tuy nhin, ng dng c th c ci t ln thit b ca ngi dng, ta cn ng gi v phn phi. Trong
chng ny, chng ta s tm hiu cch thc ng gi ng dng Android v phn phi n my ngi dng qua cc cch
khc nhau, cng nh tm hiu cch phn phi ng dng Android ln ch ng dng chnh hng ca Google l Google Play
Store.

Google Play Store v vic phn phi ng dng 147


Gio trnh Android

Chun b ng dng trc khi phn phi


Google a ra quy trnh tng i n gin gip ngi dng ng gi v a ng dng ln Google Play Store phn
phi n ngi dng. Cc bc nh sau:

Xut ng dng ra file .apk (Android Package)


To chng thc ch k s v tin hnh k ln ng dng (file apk) trn theo chng thc mi c to ra
Xut bn ng dng c k ny. C nhiu cch xut bn nh: ci trc tip ln thit b, a ln web site, hoc phn
phi ln cc ch ng dng (c chnh hng ln khng chnh hng).

nh s phin bn phn mm

Phin bn phn mm c nh s trong file AndroidManifest.xml, di hai thuc tnh l android:versionCode v


android:versionName :

<?xml version="1.0" encoding="utf-8"?>


<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="vn.edu.humg.android_course.JSON"
android:versionCode="1"
android:versionName="1.0" >

<uses-sdk android:minSdkVersion="13" />


<uses-permission android:name="android.permission.INTERNET"/>

<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name" >

</application>
</manifest>

Trong versionCode l s hiu phin bn, c kiu s nguyn, dng cho h thng phn bit cc phin bn ca ng
dng c ci t. Mi khi bn nng cp phin bn ca ng dng, bn cn thay i (tng) s ny trc khi phn phi.
Cn tham s versionName l tn ca phin bn. Tham s ny khng c dng bi h thng, m ch l tn phin bn
ngi dng s nhn thy khi xut bn ln cc ch ng dng. VersionName c kiu chui v c th t ty , tuy nhin nh
dng thng c dng l <major> . <minor> . <point> . <major> l s hiu phin bn chnh, <minor> l phin bn
ph, <point> l s hiu cp nht nh trong phin bn ph, v d 1.0.1, 2.1.0

Trong nhiu trng hp, ta cn ly s hiu phin bn ng dng hin ti lc chy chng trnh. Khi , ta dng lp
PackageInfo ly thng tin nh sau:

PackageManager pm = getPackageManager();
try {
//---get the package info---
PackageInfo pi =
pm.getPackageInfo("vn.edu.humg.android_course.LBS", 0);
//---display the versioncode---
Toast.makeText(getBaseContext(),
"VersionCode: " +Integer.toString(pi.versionCode),
Toast.LENGTH_SHORT).show();
} catch (NameNotFoundException e) {
e.printStackTrace();
}

Ngoi ra, ng dng c th c phn phi trn ch ng dng, bn cn ch ra icon v tiu ca ng dng hin th
trong danh sch ng dng. lm iu ny, ta cn t gi tr cho tham s android:icon v android:label ca th
<application> (xem v d trn).

Chun b ng dng trc khi phn phi 148


Gio trnh Android

Chng thc s cho ng dng Android

Tt c ng dng Android u phi c k theo mt chng thc s trc khi c th ci t ln thit b hoc Android
Emulator. Khng nh mt s h nn khc yu cu bn phi mua chng ch s t mt hng chuyn cung cp chng thc,
h thng Android cho php chng ta t sinh ra chng thc s k ng dng. Eclipse v ADT cng cung cp sn cng c
gip ta to ra chng thc ny mt cch rt trc quan v d dng.

Trong qu trnh pht trin ng dng, bn vn c th chy ng dng ca mnh trn thit b hoc trnh gi lp. l do
Eclipse+ADT k sn ng dng ca bn theo mt chng thc mc nh trc khi chuyn ng dng ln thit b. Chng
thc mc nh ny cha trong file debug.keystore:

Tuy nhin, chng thc ny ch dng trong qu trnh pht trin. Trc khi bn xut bn ng dng, bn cn k ng dng
theo mt chng thc khc. Phn di y m t qu trnh sinh chng thc s v ng gi ng dng theo chng thc .

xut bn ng dng, t trnh n File ca Eclipse, chn Export..., trong ca s m ra, chn Export Android Application,
sau bm Next:

Chun b ng dng trc khi phn phi 149


Gio trnh Android

Hnh: Xut bn ng dng

Trong mn hnh tip theo, chn tn d n mun xut bn:

Chun b ng dng trc khi phn phi 150


Gio trnh Android

Hnh: Chn d n cn xut bn

Tip ta cn ch ra v tr ca file cha chng thc s cn dng k ng dng v nhp vo mt khu ca chng thc
ny (mt khu ny ta t lc to chng thc s). Trong trng hp cha c chng thc s, ta chn Create new keystore
to mi:

Chun b ng dng trc khi phn phi 151


Gio trnh Android

Hnh: Cu hnh ch k s dng cho vic xut bn ng dng

Trong trng hp to mi keystore, ta cn nhp thng tin to ra mt key (dng k ng dng), v d ta in thng tin
nh bn di:

Chun b ng dng trc khi phn phi 152


Gio trnh Android

Hnh: Thng tin to ch k s mi

Cui cng ta nhp tn file apk cn xut ra v bm Finish:

Khi qu trnh kt thc, ta s thu c ng dng di dng file apk ng gi, sn sng phn phi.

Chun b ng dng trc khi phn phi 153


Gio trnh Android

Phn phi ng dng


Sau khi ng gi v k theo chng thc s cn thit, file apk sn sng c phn phi ln cc ch ng dng. C
nhiu cch c th phn phi ng dng n ngi dng nh:

Ci t trc tip ln thit b u cui thng qua cng c adb.exe


t file ci t (.apk) ln web server v phn phi ng link ti xung cho ngi dng
Phn phi ng dng trn cc ch ng dng, in hnh l Google Play Store

S dng cng c adb

Cng c adb c th c s dng ci trc tip ng dng ln thit b u cui. dng c cng c ny, ta cn:

Kt ni thit b vi my tnh thng qua cng USB


Ci t driver cho thit b (nu cha c)
Bt ty chn USB debugging trong Developer options ca mc cu hnh (Settings) trn thit b Android.

kim tra thit b c kt ni thnh cng vi my tnh cha, ta c th g lnh adb devices t mn hnh console
(cmd.exe):

Hnh trn cho thy c 01 thit b vi m 05863c50 ang c kt ni vi my tnh. Lu : cng c adb.exe nm trong
th mc platform-tools ca Android SDK. Khi thit b c kt ni, ta c th dng lnh adb install <apk file>
ci t ng dng ln thit b:

Ch success bo hiu qu trnh ci t thnh cng, ta s thy ng dng xut hin trong danh sch ng dng ca thit
b v sn sng hot ng.

Phn phi trn web server

Cch th 2 l a ng dng ca bn ln mt web server v phn phi link ti (v d: http://myserver.com/app/LBS.apk )


n ngi dng. Ngi dng ch cn bm vo link ny t thit b android ca mnh, hoc g ng link ny vo thanh a
ch ca trnh duyt web trn thit b, ng dng s t ng c ti v.

Sau khi ti xong, bm chn file va ti thc hin ci t. Tuy nhin c th ci t ng dng t ngun ny (khng
phi t Google Play Store), bn cn bt ty chn Unknown source trong phn Settings > Security ca thit b:

Phn phi ng dng 154


Gio trnh Android

Hnh: Bt ty chn cho php ci t ng dng t xa khng thng qua Google Play

Phn phi trn Google Play Store

Knh phn phi chnh thng v tim nng nht cho ng dng Android l ch ng dng Google Play Store (ca hng Play)
ca Google. c th phn phi ng dng trn ca hng Play, ta cn ng k ti khon lp trnh vin Google Android. L
ph lp ti khon ny l $25 trn i ti khon. Bn c th thanh ton khon tin ny bng th thanh ton hoc th tn dng
quc t (Visa, Master, America Express, Discovery)

ng k ti khon lp trnh vin, ta truy cp https://play.google.com/apps/publish/signup/ v ng nhp bng ti khon


google ca bn (nu cha c ti khon google, bn cn to mi, min ph):

Phn phi ng dng 155


Gio trnh Android

Bm chp nhn iu khon v tip tc (Continue to payment). Trong mn hnh tip theo, nhp thng tin th quc t
thanh ton v bm ng v tip tc:

Phn phi ng dng 156


Gio trnh Android

Hnh: Thit lp thng tin thanh ton

Nu th ca bn c chp nhn, Google s a ti khon ca bn vo trng thi ch kim tra, sau khong vi ngy s
c phn hi t Google chp nhn ti khon ca bn hay khng. Trong trng hp khng c chp nhn, Google s yu
cu bn gi thm ti liu chng thc thng tin c nhn v ti khon ngn hng ca bn.

Trong thi gian ch i Google kim tra trng thi thanh ton, bn vn c th a ng dng ln server ca Google, tuy
nhin cha th phn phi n ngi dng.

Giao din ca Developer console sau khi ng k thnh cng s c dng nh sau:

Phn phi ng dng 157


Gio trnh Android

Hnh: Danh sch ng dng ang c xut bn trn Google Play

Ti khon trn c mt ng dng ang c phn phi n ngi dng, ng dng ny hin ang c 2071 ngi dng
trn tng s 15180 lt ti, c 93 ngi bnh chn v im trung bnh l 3.98/5 sao!!!!

phn phi ng dng khc, ta bm vo nt + Add new application pha trn ca trang (nt c bi vng trn hnh).
Bn cn cung cp y thng tin yu cu v ng dng trc khi c th phn phi n ngi dng nh: ti file ng dng
(apk) ca bn ln h thng, m t ng dng v chnh sch gi.

Phn phi ng dng 158


Gio trnh Android

Hnh: Ti file ng dng ng gi (apk file) ln Google Play

Cung cp tiu (tn ng dng), m t, ti ln file icon ln (512x512px) v t nht 02 hnh chp mn hnh ca ng dng,
chn loi ng dng, cu hnh website v email h tr:

Hnh: Thng tin m t ng dng Android trn Google Play

t gi bn ng dng (hin ti Vit Nam ta ch c php ng ng dng min ph) v cc quc gia mun phn phi
ng dng:

Phn phi ng dng 159


Gio trnh Android

Hnh: Cu hnh chnh sch gi cho ng dng trn Google Play

Cui cng bm Save and publish . ng dng ca bn s bt u c phn phi trn h thng Google Play. Ch : cn
phi mt t vi gi n vi ngy ng dng c th vt qua c h thng kim tra ca Google v phn phi khp
mng CDN ca Google.

Sau khi hon tt cc bc nh trn, ta hon thnh vic pht trin mt ng dng cho h iu hnh Android v phn phi
n ngi dng. Bn c th thng xuyn gh thm trang dnh cho developer ny xem cc thng k khc nhau lin
quan n vic ci t v s dng ng dng ca mnh nh: s lt ci t/g b theo ngy, t l cc phin bn Android
ang dng, cc li crash ng dng, nh gi, phn hi ca ngi dng Hnh di y minh ha mt trong nhng mn
hnh thng k nh vy. Phn ny cng kt thc gio trnh Lp trnh cho thit b di ng ca chng ta!.

Phn phi ng dng 160


Gio trnh Android

Hnh: Thng k cc thit b ci t ng dng t Google Play

Phn phi ng dng 161

You might also like