Professional Documents
Culture Documents
Tai Lieu Giao Trinh Lap Trinh Android Co Ban
Tai Lieu Giao Trinh Lap Trinh Android Co Ban
Mc lc
Mc lc
1. Android, nn tng di ng ph bin nht th gii ...................................................3
2. Intent v b lc Intent ..............................................................................................7
3. Kin thc c bn v ng dng .............................................................................22
4. File AndroidManifest.xml ......................................................................................30
5. Giao din ngi dng trn mobile ........................................................................38
5.1 Tng quan v giao din ngi dng ..............................................................38
5.2 Layout ............................................................................................................40
5.2.1 Layout tuyn tnh .................................................................................50
5.2.2 Layout tng i .................................................................................52
5.2.3 List View ..............................................................................................55
5.2.4 Grid View ............................................................................................58
5.3 Cc s kin u vo .....................................................................................62
5.4 Menu ..............................................................................................................68
5.5 Thng bo ......................................................................................................88
5.5.1 To thng bo ......................................................................................91
5.5.2 Qun l thng bo ................................................................................95
5.5.3 Bo ton tri nghim iu hng khi khi ng Activity ......................96
5.5.4 Hin th tin trnh trong thng bo ......................................................100
5.6 Thnh phn ty chnh ..................................................................................104
6. X l u vo t bn phm ..................................................................................112
6.1 Xc nh kiu phng tin nhp liu ...........................................................113
6.2 X l trng thi hin th ca phng tin nhp liu .....................................116
6.3 H tr iu hng qua bn phm ................................................................118
6.4 X l cc action t bn phm .......................................................................121
7. Widget ca ng dng .........................................................................................123
8. Activity ................................................................................................................148
9. Ty chn lu tr .................................................................................................162
10. Content Provider ................................................................................................170
10.1 C bn v content provider ........................................................................170
10.2 To content provider ..................................................................................188
10.3 Provider Calendar ......................................................................................205
10.4 Provider Contacts ......................................................................................224
11. Thit k sao cho ng dng c th phn hi tt ..................................................265
12. Service ...............................................................................................................269
13. Lp BroadcastReceiver ......................................................................................284
14. Mo bo mt .......................................................................................................295
15. WebView ............................................................................................................307
Mc lc
15.1 Tng quan v lp WebView .......................................................................307
15.2 Xy dng ng dng Web trong WebView .................................................310
Lp trnh Android c bn
Lp trnh Android c bn
(1)
Lp trnh Android c bn
Lp trnh Android c bn
KHI NG
Tt c nhng g bn cn bt u pht trin ng dng cho Android u c y, trn
trang developer.android.com. Bn s tm thy mi th trn trang Web ny, t nhng
SDK (b cng c pht trin phn mm - Software Developement Kit), ti liu hng
dn API, ch dn thit k, thng tin v chiu xoay (landscape) ca thit b hin ti cho
ti cch bn c th phn phi v thu li nhun t cc ng dng.
Cc ng dng u c xy dng theo nhng cch khc nhau, nhng chng ti
cu trc nhng thng tin cn thit gip bn xy dng mt ng dng thnh ba mc chnh
di y, i din cho quy trnh pht trin ng dng chung:
Thit k
Trc khi vit mt dng m, bn cn thit k giao din ngi dng v lm cho n ph
hp vi tri nghim ngi dng trn Android. Mc d bn c th bit ngi dng s
lm g vi ng dng ca mnh, song bn vn nn dng li tp trung vo cch ngi
dng s tng tc vi n. Thit k ca bn nn c style p, n gin, mnh m v
c iu chnh hng ti tri nghim trn Android.
V vy, bt k bn l mt ca hng nh ch c mt ngi hay l mt nhm ln nhiu
ngi th cng nn nghin cu cc ch dn Design (Thit k) trc tin.
Pht trin
Mt khi thit k ca bn hon thin, tt c nhng g bn cn l cc cng c bin
tng thit k ng dng thnh hin thc. Framework ca Android cung cp cho
bn cc giao din lp trnh ng dng (Application Programming Interface - API) xy
dng nhng ng dng c th khai thc ton b li th ca phn cng thit b, thit b
ph kin kt ni (connected accessory device), mng Internet, cc tnh nng phn mm
v nhiu hn na. Vi sc mnh ca Android, sc mnh m ng dng ca bn c th
em li l khng gii hn.
Mi kin thc bn cn hc v framework v cc cng c pht trin ng dng u c
trong mc (Develop) (Pht trin) ca ti liu hng dn.
Phn phi
Hin gi, ng dng ca bn hon tt. Chng ta xy dng ng dng h
tr nhiu kch c v mt mn hnh, ng thi kim th (test) n trn trnh gi lp
(emulator) Android cng nh trn cc thit b tht. Bn sn sng em ng dng
ca mnh i phn phi.
Bc tip theo ph thuc vo nhiu yu t, chng hn nh chin lc tin t v loi
thit b h tr ng dng ca bn. Mi thng tin bn cn bt u qu trnh ny u c
trong mc (Distribute) (Phn phi).
Lp trnh Android c bn
2. Intent v b lc Intent
B ba trong cc thnh phn chnh (core component) ca mt ng dng - activity (mt
thnh phn ca ng dng cung cp giao din ngi dng tng tc nhm thc hin
mt cng vic no ), service (lung dch v chy ngm trong Android) v broadcast
receiver (trnh thu nhn cc thng tin bn ngoi gi ti) - c kch hot thng qua bn
tin (message), gi l cc intent. Vic gi v nhn intent l c s cho vic lin kt khi
chy v sau ny gia nhng thnh phn trong cng mt hoc cc ng dng khc nhau.
Bn thn i tng Intent l mt cu trc d liu th ng cha m t tru tng
v mt activity c thc hin - hoc, trong trng hp ca broadcast th thng l
m t v iu g xy ra v c cng b. C nhiu c ch ring bit gi Intent
cho mi loi thnh phn ca h thng:
Cc i tng Intent
Mt i tng Intent l mt tp thng tin. i tng ny cha thng tin v c im
ca thnh phn nhn intent (nh action c thc hin v d liu thc hin action
), cng vi l thng tin v c im ca h thng Android (nh danh mc ca
thnh phn x l intent v cc lnh khi chy mt activity ch). Phn ln i tng
Intent c th bao gm:
Lp trnh Android c bn
Tn thnh phn
Tn ca thnh phn x l intent. Trng ny l mt i tng ComponentName
- mt s kt hp tn lp (class) y ca thnh phn ch (chng hn nh
com.example.project.app.FreneticActivity) vi tn gi (package)
t trong file k khai (manifest file) ca ng dng, ni cha cc thnh phn (v d
nh com.example.project). Phn thng tin tn gi trong ComponentName
v tn gi c thit lp trong file k khai khng nht thit phi trng nhau.
Tn thnh phn l khng bt buc. Nu c thit lp, i tng Intent c
gi ti mt th hin (instance) ca lp ch nh. Cn nu cha c thit lp,
Android s dng thng tin khc trong i tng Intent t thnh phn ch thch
hp - xem mc Phn tch Intent (Intent Resolution) s c trnh by phn
sau ca ti liu ny.
Tn thnh phn c thit lp bng cch s dng setComponent(),
setClass() hoc setClassName() v c c bi getComponent().
Action
Mt chui (string) cha tn ca action c thc hin - hoc, trong trng hp cc
intent broadcast, y s l action xy ra v ang c bo co. Lp Intent nh
ngha mt vi hng s action, gm:
Hng s
Thnh phn ch
Action
ACTION_CALL
activity
ACTION_EDIT
activity
ACTION_MAIN
activity
Bt u vi activity khi to
ca mt nhim v v khng c
d liu u vo (input), ng
thi khng tr v d liu u ra
(output).
ACTION_SYNC
activity
ng b d liu trn my ch
(server) vi d liu trn thit b
di ng.
ACTION_BATTERY_LOW
broadcast receiver
ACTION_HEADSET_PLUG
broadcast receiver
Mt b tai nghe c gn
vo thit b, hoc c rt ra t
thit b.
ACTION_SCREEN_ON
broadcast receiver
Mn hnh c bt ln.
ACTION_TIMEZONE_
CHANGED
broadcast receiver
Lp trnh Android c bn
Xem m t lp Intent tm hiu danh sch cc hng s c sn cho nhng
action chung. Cc action khc c nh ngha u trong Android API. Bn
cng c th t nh ngha cc chui action kch hot nhng thnh phn c mt
trong ng dng ca mnh. Cc chui m bn to ra nn bao gm tn gi ng dng
nh mt tin t - v d: com.example.project.SHOW_COLOR.
Action quyt nh phn ln cch m cc thng tin cn li ca intent c cu trc ngoi tr cc trng data v extras - cng nhiu nh vic mt tn phng thc
(method) quyt nh tp cc tham s v gi tr tr v. Do vy, nn s dng nhng
tn action c th nht trong kh nng, ng thi kt hp cht ch chng vi cc
trng khc ca intent. Ni cch khc, thay v nh ngha mt action ring l, hy
nh ngha c mt giao thc (protocol) cho nhng i tng intent m cc thnh
phn trong ng dng ca bn c th x l.
Action trong mt i tng Intent c phng thc setAction() thit lp v
c c bi getAction().
D liu
Thnh phn URI (Uniform Resource Identifier - nh dng ti nguyn thng nht)
ca d liu c thc thi v loi MIME (Multipurpose internet mail extension - M
rng th tn Internet a nng) ca d liu . Nhng action khc nhau c kt
hp vi cc loi c t d liu khc nhau thnh tng cp. V d, nu trng action
l ACTION_EDIT, trng d liu s cha URI ca ti liu c hin th chnh
sa. Nu hnh ng l ACTION_CALL, trng d liu s l tel: URI vi s in
thoi gi. Tng t, nu action l ACTION_VIEW v trng d liu l http: URI,
activity nhn c s c gi ti v, ng thi hin th bt c d liu no m
URI tr ti.
Khi khp mt intent vi mt thnh phn c kh nng x l d liu, iu quan
trng cn bit l loi ca d liu (loi MIME) cng vi URI ca d liu y. V d,
khng nn gi mt thnh phn c kh nng hin th d liu hnh nh chy mt
file m thanh.
Trong nhiu trng hp, loi d liu c th c suy on t URI - ngoi tr cc
content: URI cho thy rng d liu c nh v trn thit b v do mt Content
Provider (trnh cung cp ni dung) kim sot (xem mc Content provider bn
di)). Tuy nhin, loi d liu c th c thit lp mt cch tng minh trong
i tng Intent. Phng thc setData() nh r rng d liu ch nh mt URI,
setType() nh r rng n ch nh mt loi MIME, cn setDataAndType()
cho bit n va l mt URI va l mt loi MIME. c URI s dng getData(),
c loi d liu s dng getType().
Hng mc
Mt chui cha thng tin b sung v nhng loi thnh phn x l intent. i tng
intent c th cha mt s lng khng gii hn cc m t hng mc (category).
Tng t nh cch lm vi action, lp Intent nh ngha mt vi hng s hng
mc, bao gm:
Lp trnh Android c bn
Hng s
ngha
CATEGORY_BROWSABLE
CATEGORY_GADGET
CATEGORY_HOME
CATEGORY_LAUNCHER
CATEGORY_PREFERENCE
10
Lp trnh Android c bn
H thng Android v nhng ng dng i km nn tng dng cc i tng Intent
va gi i cc tin broadcast ca h thng ban u va kch hot nhng thnh phn
xc nh trong h thng. Mun bit cch cu trc mt intent kch hot mt thnh
phn h thng, mi bn tham kho mc List of intents (Danh sch intent).
Phn tch Intent
Cc Intent c th c chia thnh hai nhm:
Intent tng minh (explicit intent) quy nh thnh phn ch bng tn ca n (trng
tn thnh phn - Component Name cp trn, c mt gi tr thit lp). Do
cc nh pht trin ca nhng ng dng khc khng bit tn thnh phn ng dng
ca nhau, nn cc intent tng minh thng c dng cho nhng thng ip ni
b trong ng dng - v d, mt activity khi chy mt service cp con hay thc thi
mt activity anh em ca n.
B lc intent
thng bo cho h thng bit chng c th x l nhng intent ngm nh no, cc
activity, service v broadcast receiver c th c mt hay nhiu b lc intent. Mi b lc
m t mt kh nng ca mt thnh phn, mt tp intent m thnh phn sn sng nhn.
Kt qu l, n lc ra cc intent mong mun v loi b nhng intent khng mong mun -
11
Lp trnh Android c bn
ch gm cc intent ngm nh (nhng intent ny khng t tn cho lp ch). Mt intent
tng minh lun c gi ti ch ca n, bt k n cha ni dung g; b lc khng lm
nhim v tra cu ni dung. Tuy nhin, mt intent ngm nh ch c gi ti mt thnh
phn khi n c th vt qua c cc b lc ca thnh phn .
Mt thnh phn c nhiu b lc ring bit cho tng vic n c th lm, cho mi giao
din m n biu din ti ngi dng. V d, activity c tn NoteEditor ca ng dng
Note Pad c hai b lc - mt khi ng vi mt ghi ch c th gip ngi dung c
th xem hoc chnh sa, mt b lc khc bt u vi mt ghi ch mi, trng hon
ton ngi dng c th in vo ri lu li. (Tt c cc b lc ca Note Pad u
c miu t trong mc V d v Note Pad s trnh by v sau).
B lc v bo mt
Mt b lc intent khng th dng cho mc ch bo mt (security). Trong khi m mt
thnh phn ch nhn nhng dng intent ngm nh nht nh, b lc khng lm g
ngn nga cc intent tng minh nhm ti thnh phn . Mc d mt b lc c th
hn ch cc intent, song mt thnh phn s c yu cu x l mt s action v ngun
d liu nht nh. Tuy nhin, ai vn c th t mt intent tng minh cnh mt action
v ngun d liu khc ri t tn thnh phn ging vi thnh phn ch.
B lc intent l mt th hin ca lp IntentFilter. Tuy nhin, do h thng Android
phi bit v kh nng ca mt thnh phn trc khi thc thi thnh phn , nn cc
b lc intent thng khng c thit lp trong m Java m ch ng vai tr l cc
phn t (element) <intent-filter> trong file k khai (AndroidManifest.xml)
ca ng dng. (Mt ngoi l l nhng b lc cho broadcast receiver c ng k ng
l gi Context.registerReceiver(); chng c to trc tip di dng cc
i tng IntentFilter).
Mt b lc c cc trng song song vi cc trng action, d liu v hng mc ca
mt i tng Intent. Mt intent ngm nh c kim th bng b lc c ba trng.
c chuyn ti thnh phn s hu b lc, n phi vt qua c ba kim th. Nu
tht bi cho d ch trong mt kim th, h thng Android s khng gi n ti thnh phn
- t nht l khng da trn c s ca b lc . Tuy nhin, do mi thnh phn c th c
nhiu b lc intent, nn mt intent khng vt qua mt trong cc b lc ca thnh phn
li c th vt qua b lc khc.
Mi kim th c m t chi tit di y:
Kim th action
Mt phn t <intent-filter> trong file k khai lit k cc action di dng nhng
phn t con <action>. V d:
<intent-filter . . . >
<action android:name=com.example.project.SHOW_CURRENT />
<action android:name=com.example.project.SHOW_RECENT />
<action android:name=com.example.project.SHOW_PENDING />
. . .
</intent-filter>
12
Lp trnh Android c bn
V d trn cho thy, trong khi mt i tng Intent ch t tn cho mt action th mt b
lc c th lit k nhiu hn th. Danh sch khng th trng; mt b lc phi cha t
nht mt phn t <action>, hoc n s chn (block) tt c cc intent.
vt qua kim th ny, action c n nh trong i tng Intent phi khp
vi mt trong cc action c lit k trong b lc. Nu i tng hoc b lc khng ch
nh mt action, kt qu s nh sau:
Kim th hng mc
Mt phn t <intent-filter> lit k cc hng mc di dng nhng phn t con.
V d:
<intent-filter . . . >
<category android:name=android.intent.category.DEFAULT />
<category android:name=android.intent.category.BROWSABLE />
. . .
</intent-filter>
13
Lp trnh Android c bn
Kim th d liu
Tng t action v hng mc, c t d liu (data specification) ca mt b lc intent
c bao gm trong mt phn t con. V, vi nhng trng hp nh vy, phn t con
c th xut hin nhiu ln, hoc khng ln no. V d:
<intent-filter . . . >
<data android:mimeType=video/mpeg android:scheme=http . . . />
<data android:mimeType=audio/mpeg android:scheme=http . . . />
. . .
</intent-filter>
V d, trong URI di y,
content://com.example.project:200/folder/subfolder/etc
14
Lp trnh Android c bn
trng hp duy nht cho cc URI nh mailto: v tel: m khng cp
n d liu thc t.
c. Mt i tng Intent cha mt kiu d liu nhng khng c URI s vt qua
kim th ch khi b lc lit k cng kiu d liu v tng t vy, khng xc
nh URI no.
d. Mt i tng Intent cha c URI ln kiu d liu (hoc c th suy ra kiu d
liu t URI) vt qua phn kim th kiu d liu ch khi kiu ca n khp vi
mt kiu c lit k trong b lc. N vt qua phn kim th URI khi URI
ca n khp vi mt URI trong b lc, hoc nu n cha content: URI hay
file: URI v b lc khng xc nh URI no. Ni cch khc, mt thnh phn
c coi l h tr d liu content: v file:, nu b lc ca n ch lit k
kiu d liu.
Nu mt intent c th vt qua cc b lc ca nhiu activity hoc service, ngi dng
s c hi thnh phn no c kch hot. Mt ngoi l xy ra khi khng c thnh
phn ch no c tm thy.
Cc trng hp ph bin
Nguyn tc cui cng trnh by trn dnh cho vic kim th d liu, nguyn tc (d),
phn nh mong mun rng cc thnh phn c th ly d liu ni b t mt file hoc
Content Provider. Do , b lc ca chng c th lit k ch mt kiu d liu m khng
cn xc nh tng minh tn lc content: v file:. y l mt trng hp in
hnh. V d, mt phn t <data> nh sau cho Android bit thnh phn c th ly d
liu hnh nh t Content Provider v hin th n:
<data android:mimeType="image/*" />
15
Lp trnh Android c bn
Hu ht ng dng u c mt cch lm mi li m khng cn tham chiu ti
bt k d liu c th no. Nhng activity c th khi to cc ng dng c b lc
vi android.intent.action.MAIN c xc nh di dng action. Nu c
hin th trong mn hnh chnh (laucher) ca ng dng, chng cng xc nh hng mc
android.intent.category.LAUNCHER:
<intent-filter . . . >
<action android:name=android.intent.action.MAIN />
V d v Note Pad
ng dng Note Pad cho php ngi dng c th duyt qua mt danh sch cc ghi ch
(note), xem chi tit tng mc trong danh sch, chnh sa cc mc v thm mc mi vo
danh sch. Phn ny xem xt cc b lc intent c khai bo (declared) trong file k khai.
(Nu ang lm vic ngoi tuyn trong SDK (Software Developement Kit - B cng c pht
trin phn mm), bn c th tm thy ton b file ngun cho ng dng v d ny, bao gm
c file k khai ca n ti <sdk>/samples/NotePad/index.html. Nu bn ang
xem ti liu trc tuyn, cc file ngun u c mc Tutorials and Sample (V d mu v
ti liu hng dn ging dy) ti y).
Trong file k khai ca n, ng dng Note Pad khai bo ba activity, mi activity ng vi
t nht mt b lc intent. N cng khai bo mt Content Provider qun l d liu ghi
ch. y l ni dung file k khai:
16
Lp trnh Android c bn
<manifest xmlns:android=http://schemas.android.com/apk/res/android
package=com.example.android.notepad>
<application android:icon=@drawable/app_notes
android:label=@string/app_name >
<provider android:name=NotePadProvider
android:authorities=com.google.provider.NotePad />
<activity android:name=NotesList android:label=@string/title_notes_list>
<intent-filter>
<action android:name=android.intent.action.MAIN />
<category android:name=android.intent.category.LAUNCHER />
</intent-filter>
<intent-filter>
<action android:name=android.intent.action.VIEW />
<action android:name=android.intent.action.EDIT />
<action android:name=android.intent.action.PICK />
<category android:name=android.intent.category.DEFAULT />
<data android:mimeType=vnd.android.cursor.dir/vnd.google.note />
</intent-filter>
<intent-filter>
<action android:name=android.intent.action.GET_CONTENT />
<category android:name=android.intent.category.DEFAULT />
<data android:mimeType=vnd.android.cursor.item/vnd.google.note />
</intent-filter>
</activity>
<activity android:name=NoteEditor
android:theme=@android:style/Theme.Light
android:label=@string/title_note >
<intent-filter android:label=@string/resolve_edit>
<action android:name=android.intent.action.VIEW />
<action android:name=android.intent.action.EDIT />
<action android:name=com.android.notepad.action.EDIT_NOTE />
<category android:name=android.intent.category.DEFAULT />
<data android:mimeType=vnd.android.cursor.item/vnd.google.note />
</intent-filter>
<intent-filter>
<action android:name=android.intent.action.INSERT />
<category android:name=android.intent.category.DEFAULT />
<data android:mimeType=vnd.android.cursor.dir/vnd.google.note />
</intent-filter>
</activity>
<activity android:name=TitleEditor
android:label=@string/title_edit_title
android:theme=@android:style/Theme.Dialog>
<intent-filter android:label=@string/resolve_title>
<action android:name=com.android.notepad.action.EDIT_TITLE />
<category android:name=android.intent.category.DEFAULT />
17
Lp trnh Android c bn
<category android:name=android.intent.category.ALTERNATIVE />
<category android:name=android.intent.category.SELECTED_ALTERNATIVE />
<data android:mimeType=vnd.android.cursor.item/vnd.google.note />
</intent-filter>
</activity>
</application>
</manifest>
Activity u tin, NotesList, khc bit vi nhng activity khc v thc t, n hot
ng trn mt danh mc ghi ch (danh sch ghi ch) thay v trn mt ghi ch n l.
NotesList thng c dng lm giao din ngi dng u tin, khi mi truy cp
ng dng. N c th lm ba vic c m t bng ba b lc intent:
<intent-filter>
<action android:name=android.intent.action.MAIN />
<category android:name=android.intent.category.LAUNCHER />
</intent-filter>
18
oo
oo
Lp trnh Android c bn
Do , hng mc DEFAULT l cn thit cho tt c cc b lc - ngoi tr nhng b lc
vi action MAIN v hng mc LAUNCHER. (Cc b lc intent khng cn quan tm n
nhng intent tng minh).
<intent-filter>
<action android:name=android.intent.action.GET_CONTENT />
<category android:name=android.intent.category.DEFAULT />
<data android:mimeType=vnd.android.cursor.item/vnd.google.note />
</intent-filter>
19
Lp trnh Android c bn
chn mt ghi ch t danh sch, v activity s tr URI cho mc v activity
khi ng activity NoteList.
action: android.intent.action.GET_CONTENT
kiu d liu: vnd.android.cursor.item/vnd.google.note
Ra lnh cho activity cung cp mt mc n trong d liu Note Pad.
Activity th hai, NoteEditor, cho ngi dng thy mt mc ghi ch n, ng thi cho
php h chnh sa n. N c th lm hai iu c m t bng hai b lc intent di y:
<intent-filter android:label=@string/resolve_edit>
<action android:name=android.intent.action.VIEW />
<action android:name=android.intent.action.EDIT />
<action android:name=com.android.notepad.action.EDIT_NOTE />
<category android:name=android.intent.category.DEFAULT />
<data android:mimeType=vnd.android.cursor.item/vnd.google.note />
</intent-filter>
20
Lp trnh Android c bn
Ra lnh cho activity hin th ni dung ca ghi ch xc nh bi ID, ng thi
cho php ngi dng chnh sa n. Nu ngi dung lu cc thay i, activity
s cp nht d liu cho ghi ch trong Content Provider.
action: android.intent.action.INSERT
d liu: content://com.google.provider.NotePad/notes
Ra lnh cho activity to mt ghi ch mi trong danh sch ghi ch mi, rng ti
content://com.google.provider.notepad/notes, ng thi cho
php ngi dng chnh sa n. Nu ngi dung lu ghi ch, URI ca n c
tr v cho i tng gi.
Activity cui cng, TitleEditor, cho php ngi dng chnh sa tiu (title) ca
ghi ch. Vic ny c th c thc thi bng cch trc tip kch hot activity (nh thit
lp tn thnh phn ca n trong Intent mt cch tng minh), m khng cn s dng
b lc intent no. Nhng y, chng ta cn bt ly c hi ch ra cch trin khai nhng
activity thay th trn d liu c sn:
<intent-filter android:label=@string/resolve_title>
<action android:name=com.android.notepad.action.EDIT_TITLE />
<category android:name=android.intent.category.DEFAULT />
<category android:name=android.intent.category.ALTERNATIVE />
<category android:name=android.intent.category.SELECTED_ALTERNATIVE />
<data android:mimeType=vnd.android.cursor.item/vnd.google.note />
</intent-filter>
21
Lp trnh Android c bn
Theo mc nh, h thng gn (assign) cho mi ng dng mt user ID duy nht (ID
ny ch c h thng dng v ng dng khng bit ti n). H thng thit lp
quyn (permission) cho tt c cc file trong ng dng, sao cho ch duy nht user
ID c gn cho ng dng mi c th truy cp (access) vo nhng file ny.
Theo mc nh, mi ng dng s chy trong tin trnh Linux ca ring mnh. Android
khi ng tin trnh khi c bt c thnh phn no ca ng dng cn c thc thi,
sau tt tin trnh khi n khng cn cn thit hoc khi h thng phi khi phc
(recover) b nh (memory) cho cc ng dng khc.
Bng cch ny, h thng Android p dng nguyn l c quyn ti thiu (principle of
least privelege). l: Theo mc nh, mi ng dng ch c quyn truy cp ti nhng
thnh phn m ng dng yu cu phi lm vic cho n v khng th hn na. iu
ny to ra mt mi trng rt an ton, trong mt ng dng khng th truy cp vo
nhng phn thuc h thng m n khng c cp quyn.
Tuy nhin, c nhiu cch mt ng dng chia s d liu vi nhng ng dng khc
v mt ng dng truy cp vo cc dch v ca h thng:
File k khai, trong bn khai bo nhng thnh phn v tnh nng thit b cn thit
cho ng dng.
22
Lp trnh Android c bn
23
Lp trnh Android c bn
qun l thng tin lin lc ca ngi dung. Nh vy, mt ng dng bt k vi
quyn ph hp c th truy vn mt phn ca Content Provider (chng hn nh
ContactsContract.Data) c v ghi thng tin v mt ngi c th no ).
Cc Content Provider cng rt hu ch trong vic c, ghi d liu ring t i vi
ng dng ca bn v khng chia s i. V d, ng dng mu Note Pad dng mt
Content Provider lu cc ghi ch.
Content Provider c ci t l mt lp con ca ContentProvider v phi
ci t mt tp cc API chun cho php nhng ng dng khc thc hin cc giao
dch (transaction). bit thm thng tin, xem hng dn cho nh pht trin
Content Providers (Trnh cung cp ni dung)..
Broadcast receiver
Broadcast receiver l thnh phn phn hi li cc thng bo qung b ca ton h
thng. Nhiu broadcast xut pht t h thng - v d, mt broadcast thng bo rng
mn hnh tt, pin sp ht hoc mt bc nh ang c chp. Cc ng dng
cng c th khi to broadcast - v d, cho nhng ng dng khc bit rng mt
s d liu c ti v thit b v sn sng cho ngi dng s dng. Mc d cc
broadcast receiver khng hin th giao din ngi dng, song chng c th to mt
thng bo qua thanh trng thi (create a status bar notification) bo cho ngi
dung khi xy ra mt s kin broadcast. Mc d thng th mt broadcast receiver
ch l mt cng ra (gateway) ti cc thnh phn khc v dng thc hin mt
khi lng cng vic rt nh. V d, broadcast receiver c th khi to mt service
thc hin mt s vic da trn s kin.
Broadcast receiver c ci t l mt lp con ca BroadcastReceiver v mi
broadcast c gi di dng mt i tng Intent. bit thm thng tin, xem
lp BroadcastReceiver.
Mt kha cnh c o trong thit k h thng Android l bt c ng dng no cng c
th khi ng thnh phn ca ng dng khc. V d, nu bn mun chp mt bc nh
bng camera ca thit b, c th mt ng dng khc s lm iu v ng dng ca
bn s s dng n, thay v bn phi t pht trin mt activity chp nh. Bn khng
phi kt hp cht ch hoc thm ch lin kt ti ma ngun t ng dng camera. Thay
vo , bn ch cn lm mt vic n gin l khi ng activity c chc nng chp nh
trong ng dng camera. Khi hon thnh, bc nh c tr v cho ng dng ca
bn bn c th s dng n. i vi ngi dng, c v nh camera thc s l mt
phn trong ng dng ca bn.
Khi h thng khi ng mt thnh phn, n khi ng tin trnh cho ng dng (nu
n cha chy sn) v khi to cc lp cn thit cho thnh phn. V d, nu ng dng
ca bn khi ng activity trong ng dng camera chp mt bc nh, activity s
chy trong tin trnh thuc v ng dng camera ch khng phi trong tin trnh thuc
v ng dng ca bn. Do , khng ging nh cc ng dng trn hu ht nhng h
thng khc, cc ng dng Android khng c im bt u n l (v d nh khng c
hm (function) main()).
Do h thng chy tng ng dng trong mt tin trnh ring, vi quyn file hn ch truy
cp vo cc ng dng khc, nn ng dng ca bn khng th trc tip kch hot mt
thnh phn t ng dng khc. Tuy nhin, h thng Android li c kh nng thc hin
24
Lp trnh Android c bn
iu . V vy, kch hot mt thnh phn trong ng dng khc, bn phi gi mt
thng ip ti h thng xc nh intent ca mnh khi ng mt thnh phn c th.
Sau , h thng s kch hot thnh phn cho bn.
25
Lp trnh Android c bn
bit thm thng tin v cch s dng intent, xem ti liu Intents and Intent Filters
(Intent v b lc intent). Thng tin tham kho v vic kch hot cc thnh phn
c th cng c cung cp trong nhng ti liu sau: Activity, Service, Broadcast
Receiver v Content Providers.
File k khai
Trc khi h thng Android c th khi ng mt thnh phn ca ng dng, h thng
phi bit thnh phn tn ti hay cha bng cch c file AndroidManifest.
xml ca ng dng (file k khai). ng dng ca bn phi khai bo tt c cc thnh
phn ca n trong file k khai v file ny phi lu th mc gc (root) ca project (d
n) ng dng.
Ngoi vic khai bo cc thnh phn ca ng dng, file k khai c th thc hin mt s
vic khc nh:
Khai bo API Level (Cp API) ti thiu cn thit cho ng dng, da vo vic ng
dng s dng nhng API no.
26
Lp trnh Android c bn
Trong phn t <activity>, thuc tnh android:name xc nh tn lp y ca
lp con Activity, cn cc thuc tnh android:label ch nh mt chui s dng
nh l nhn m ngi dung c th thy c (user-visible label) cho activity.
Bn cn khai bo tt c cc thnh phn ca ng dng theo cch sau:
27
Lp trnh Android c bn
Khai bo cc yu cu ca ng dng
C rt nhiu thit b vn hnh bng Android v khng phi tt c trong s chng u
cung cp cc tnh nng v kh nng nh nhau. trnh cho ng dng ca bn khi
b ci t trn cc thit b thiu tnh nng cn thit vn hnh, mt iu quan trng l
bn phi nh ngha r rng mt profile cho nhng loi thit b m ng dng ca mnh
h tr, bng cch khai bo thit b cng cc yu cu phn mm trong file k khai. Hu
ht nhng khai bo ny u ch mang tnh thng tin v h thng khng c chng, song
cc service ngoi nh Google Play li c chng cung cp tnh nng lc tm kim
ng dng t thit b ca h.
V d, nu ng dng ca bn yu cu mt camera v s dng nhng API c gii thiu
trong Android 2.1 (API Cp 7), bn nn khai bo nhng yu cu ny trong file k khai.
Theo cch ny, nhng thit b khng c camera v c phin bn Android thp hn bn
2.1 s khng th ci t ng dng ca bn t Google Play.
Tuy nhin, bn cng c th khai bo rng ng dng ca mnh s dng camera, nhng
iu ny l khng bt buc. Vi trng hp ny, ng dng ca bn phi thc hin mt
thao tc kim tra trong thi gian chy xc nh xem thit b c camera khng v tt
cc tnh nng s dng camera i nu camera khng sn sng.
Sau y l mt s c tnh quan trng ca thit b m bn nn xem xt khi thit k v
pht trin ng dng ca mnh.
Kch thc mn hnh (screen size) v mt (density)
phn loi thit b theo kch thc mn hnh, Android nh ngha hai c tnh
cho mi thit b: Kch thc mn hnh (kch thc vt l ca mn hnh) v mt
mn hnh (mt cc pixel - im nh trn mn hnh, hay cn gi l dpi - dots per
inch). n gin ha tt c cc dng khc nhau ca cu hnh mn hnh, h thng
Android phn chng thnh cc nhm d dng la chn hn.
Cc kch thc mn hnh l: Nh (small), va (normal), ln (large) v rt ln
(extra large).
Cc mt mn hnh l: Thp (low), va (medium), cao (high) v rt cao (extra high).
Theo mc nh, ng dng ca bn s tng thch vi tt c cc kch thc v mt
mn hnh, v h thng Android s thc hin tinh chnh ph hp vi layout ca
giao din ngi dng v ti nguyn nh. Tuy nhin, bn nn to ra cc layout (b
cc) chuyn bit cho mt s kch thc mn hnh nht nh v cung cp cc nh
chuyn dng cho nhng mt nht nh, s dng cc ti nguyn layout thay th,
v bng cch khai bo chnh xc trong file k khai v kch thc mn hnh c
ng dng ca bn h tr vi phn t <supports-screens>.
tham kho thm thng tin, xem ti liu Supporting Multiple Screens (H
tr a mn hnh).
Cu hnh u vo
Nhiu thit b cung cp mt loi c ch nhp u vo khc bit, chng hn nh
bn phm phn cng (hardware keyboard), mt bi ln (trackball), hoc bn di chut
5 chiu (five-way navigation pad). Nu ng dng ca bn i hi mt phn cng
c th dng nhp u vo, bn nn khai bo n trong file k khai vi phn t
28
Lp trnh Android c bn
<uses-configuration>. Tuy nhin, rt him khi mt ng dng yu cu cu hnh
nhp nh vy.
Cc c im ca thit b
C nhiu c im phn cng v phn mm c th hoc khng th tn ti trn
mt thit b chy Android, chng hn camera, cm bin nh sng (light sensor),
bluetooth, mt phin bn nht nh ca OpenGL, hoc mn hnh cm ng trung
thc. Bn khng nn cho rng mt c im nht nh l c sn trn mi thit b
chy Android (ngoi th vin chun ca Android). Do , bn nn khai bo bt k
c im no c ng dng ca mnh s dng vi phn t <uses-feature>.
Phin bn nn tng
Cc thit b chy Android thng chy nhng phin bn khc nhau ca nn
tng Android, chng hn nh Android 1.6 hay Android 2.3. Mi phin bn thnh
cng thng bao gm thm cc API m cha tn ti trong nhng phin bn
trc . ch ra rng tp cc API sn sng, mi phin bn nn tng xc
nh mt Cp API (v d nh Android 1.0 l API Cp 1 (API Level 1) v Android
2.3 l API Cp 9). Nu s dng bt c API no c thm vo nn tng sau
phin bn 1.0, bn nn khai bo Cp API ti thiu c cha nhng API bng
cch s dng phn t <uses-sdk>.
iu quan trng l bn cn khai bo tt c cc yu cu cho ng dng ca mnh,
bi v khi bn phn phi ng dng trn Google Play, ca hng s s dng nhng khai
bo ny lc cc ng dng ph hp cho mi thit b. Nh vy, ng dng ca bn ch
nn hin th sn sng i vi nhng thit b p ng c mi yu cu m n a ra.
bit thm thng tin v cch Google Play lc cc ng dng da trn nhng yu
cu trn (hoc cc yu cu khc), xem ti liu Lc trn Google Play (Filters on
Google Play).
Ti nguyn ca ng dng
Mt ng dng Android khng ch bao gm m ngun - n i hi nhng ti nguyn khc
nm tch bit vi m ngun (source code), chng hn nh hnh nh, file m thanh v
bt c th g lin quan ti hnh thc trnh by trc quan ca ng dng. V d, bn nn
nh ngha cc hot cnh (animation), menu, style, mu sc v layout ca cc giao din
ngi dng activity vi file XML. S dng ti nguyn ca ng dng lm cho vic cp
nht nhiu c im khc nhau trong ng dng ca bn tr nn d dng m khng phi
chnh sa m ngun. Bn cnh , bng cch cung cp tp cc ti nguyn thay th,
bn c th ti u ha ng dng ca mnh cho nhiu loi cu hnh thit b (chng hn
nh nhng ngn ng v kch thc mn hnh khc nhau).
i vi mi ti nguyn bao gm trong d n Android, cc cng c SDK (SDK build toos)
xc nh mt ID duy nht c dng s nguyn (integer), v bn c th dng ID ny
tham chiu ti ti nguyn t m ngun ca ng dng hoc t cc ti nguyn khc c
nh ngha trong XML. V d, nu ng dng ca bn cha mt file nh tn l logo.png
(lu trong th mc res/drawable/directory), cc cng c SDK s to mt ID ti
nguyn c tn l R.drawable.logo, bn c th dng cho vic tham chiu ti file
nh v chn n vo giao din ngi dng ca mnh.
29
Lp trnh Android c bn
Mt trong nhng kha cnh quan trng nht ca vic cung cp ti nguyn tch bit khi ma
ngun l bn c th cung cp cc ti nguyn thay th cho nhng cu hnh thit b khc. V
d, bng vic nh ngha cc chui (t ,cm t, hoc cu) xut hin trn giao din ngi
dng (UI) trong XML, bn c th dch (translate) nhng chui ny sang loi ngn ng khc
v lu chng trong cc file ring bit. Sau , da vo mt b nh x ngn ng (language
qualifier) m bn thm vo tn th mc ti nguyn (chng hn nh res/values-fr/
i vi cc gi tr chui ting Php) v thit lp ngn ng ngi dung, h thng Android s
p dng nhng chui ngn ng ph hp cho giao din ngi dng ca bn.
Android h tr nhiu b nh x khc nhau cho cc ti nguyn thay th ca bn. B nh
x l mt chui ngn c bao gm trong tn ca th mc ti nguyn, xc nh loi
cu hnh thit b m ti , nhng ti nguyn trn nn c s dng. Mt v d khc,
bn nn thng xuyn to cc layout khc nhau cho nhng activity ca mnh, da vo
vo chiu xoay v kch thc mn hnh ca thit b. V d, khi mn hnh thit b ang
dng ng (portrait orientation, cn gi l tall), bn mun mt layout vi nhng button
nm dc. Tuy nhin, khi mn hnh dng nm ngang (landscapte orientation, cn gi
l wide), cc button nn c cn chnh theo chiu ngang. thay i layout da trn
chiu xoay mn hnh, bn c th nh ngha hai layout khc nhau v p dng b nh
x thch hp i vi tng tn th mc ca layout. Sau , h thng s t ng p dng
layout thch hp da vo chiu xoay hin ti ca thit b.
bit thm thng tin v nhng loi ti nguyn khc nhau m bn c th bao gm trong
ng dng ca mnh v cch to cc ti nguyn thay th cho nhiu loi cu hnh thit
b, xem hng dn dnh cho cc nh pht trin ti mc Ti nguyn ca ng dng.
4. File AndroidManifest.xml
Mi ng dng u phi c mt file AndroidManifest.xml (vi chnh xc tn gi )
trong th mc gc ca n. File k khai ny trnh by nhng thng tin cn thit v ng
dng cho h thng Android, l thng tin m h thng bt buc phi c trc khi n
c th chy bt c dng ma ngun no ca ng dng. Mt s nhim v m file k khai
c th thc hin bao gm:
M t cc thnh phn ca ng dng - activity, service, broadcast receiver v Content Provider cu thnh nn ng dng. File AndroidManifest.xml ch ra tn
cc lp thc thi mi thnh phn v a ra nhng kh nng ca chng (v d, cc
loi thng ip Intent m chng c th x l). Nhng khai bo nh vy cho h
thng Android bit cc thnh phn no c khi ng v chng c thc thi
di nhng iu kin no.
30
Lp trnh Android c bn
<permission-tree />
<permission-group />
<instrumentation />
<uses-sdk />
<uses-configuration />
<uses-feature />
<supports-screens />
<compatible-screens />
<supports-gl-texture />
<application>
<activity>
<intent-filter>
<action />
<category />
<data />
</intent-filter>
<meta-data />
</activity>
<activity-alias>
<intent-filter> . . . </intent-filter>
<meta-data />
</activity-alias>
31
Lp trnh Android c bn
<service>
<intent-filter> . . . </intent-filter>
<meta-data/>
</service>
<receiver>
<intent-filter> . . . </intent-filter>
<meta-data />
</receiver>
<provider>
<grant-uri-permission />
<meta-data />
<path-permission />
</provider>
<uses-library />
</application>
</manifest>
Tt c cc phn t c th xut hin trong file k khai u c lit k trong danh sch
bn di theo trnh t ABC. y ch l nhng phn t hp l; bn khng th t thm
cc phn t hoc thuc tnh ca ring mnh c.
<action>
<activity>
<activity-alias>
<application>
<category>
<data>
<grant-uri-permission>
<instrumentation>
<intent-filter>
<manifest>
<meta-data>
<permission>
<permission-group>
<permission-tree>
<provider>
<receiver>
<service>
32
Lp trnh Android c bn
<supports-screens>
<uses-configuration>
<uses-feature>
<uses-library>
<uses-permission>
<uses-sdk>
Cc quy c v file
Mt s quy c v quy tc p dng chung cho tt c cc phn t cng nh thuc tnh
trong file k khai:
Cc phn t
Ch c cc phn t <manifest> v <application> mi l phn t bt buc,
chng phi tn ti v c th ch duy nht mt ln. Hu ht cc phn t khc u c
th xut hin nhiu ln hoc khng - mc d t nht mt vi trong s chng phi c
mt trong file k khai c ngha.
Nu mt phn t cha bt k th g, n s cha c nhng phn t khc. Mi gi
tr u c thit lp thng qua thuc tnh, ch khng phi di dng d liu trong
mt phn t.
Cc phn t ng cp thng khng c cng th t. V d, cc phn t
<activity>, <provider> v <service> c th c trn ln theo bt c
trt t no. (Phn t <activity-alias> l ngoi l ca nguyn tc ny: N
phi theo sau <activity> m n l b danh (alias)).
Cc thuc tnh
Theo ngha chnh thc th tt c cc thuc tnh l ty chn (khng bt buc). Tuy
nhin, c mt s thuc tnh phi c ch nh cho mt phn t phc v mc
ch no . Hy s dng ti liu ny nh mt hng dn. i vi nhng thuc
tnh thc s khng bt buc, ti liu ny cp ti mt gi tr mc nh hoc trng
thi xy ra khi khng c s n nh gi tr no.
Ngoi tr mt s thuc tnh ca phn t gc <manifest>, cn li
mi tn thuc tnh u bt u vi tin t android: - v d nh
android:alwaysRetainTaskState. Do tin t mang tnh ton cc, nn cc
ti liu thng b qua n khi tham chiu n cc thuc tnh qua tn ca chng.
Khai bo tn lp
Nhiu phn t tng ng vi cc i tng Java, bao gm cc phn t cho bn
thn ng dng (phn t <application>) v nhng thnh phn chnh - activitiy
(<activity>), service (<service>), broadcast receiver (<receiver>),
Content Provider (<provider>).
Nu bn nh ngha mt lp con, hu ht l cho cc lp thnh phn (Activity,
Service, BroadcastReceiver v ContentProvider), lp con s c
33
Lp trnh Android c bn
khai bo thng qua thuc tnh name. Tn phi bao gm tn y ca gi. V d,
mt lp con Service c th c khai bo nh sau:
<manifest . . . >
<application . . . >
</service>
. . .
</application>
</manifest>
</service>
. . .
</application>
</manifest>
</intent-filter>
Gi tr ti nguyn
Mt s thuc tnh c gi tr c th c hin th i vi ngi dung - v d, label
(nhn) v icon (biu tng) cho mt activity. Cc gi tr ca nhng thuc tnh ny
34
Lp trnh Android c bn
nn c nh v t mt ti nguyn hoc theme. Cc gi tr ti nguyn c th
hin di nh dng sau:
@[package:]type:name
@:
?[package:]type:name
Gi tr chui
Trong khi mt gi tr thuc tnh l mt chui, hai du cho ngc (\\) phi c dng
cho cc k t thot (escape character) - v d, \\n cho mt dng mi hoc \\uxxxx
cho mt k t Unicode.
Cc tnh nng ca file
Mc di y s m t cch mt s tnh nng ca Android c phn nh trong file
k khai.
B lc intent
Cc thnh phn ct li ca mt ng dng (activity, service v broadcast receiver) u
c intent kch hot. Intent l mt bundle thng tin (i tng Intent) m t mt
action mong mun - bao gm d liu cn gii quyt, hng mc ca thnh phn nn
thc hin action cng nhng ch dn khc. Android nh v mt thnh phn thch hp
phn hi intent, khi ng mt th hin mi ca thnh phn nu cn thit v truyn
cho n mt i tng Intent.
Cc thnh phn ch ra kh nng ca chng - nhng loi intent m chng c th phn
hi - thng qua cc b lc intent. Do h thng Android phi bit nhng intent no m
mt thnh phn c th x l trc khi khi ng mt thnh phn, nn cc b lc intent
s c xc nh trong file k khai di dng cc phn t <intent-filter>. Mt
thnh phn c th c s lng b lc ty , nhng mi b lc li m t mt kh nng
khc nhau.
Mt intent ch nh r rng tn ca thnh phn ch s kch hot thnh phn ; b lc
khng lm vic ny. Tuy nhin, mt intent khng ch nh c th tn thnh phn ch li
c th kch hot mt thnh phn ch khi intent c th vt qua mt trong nhng b lc
ca thnh phn y.
bit thm thng tin v cch cc i tng Intent c kim th qua b lc intent,
xem ti liu Intents and Intent Filters (Intent v b lc intent) .
35
Lp trnh Android c bn
Quyn
Quyn (permission) l kh nng hn ch truy cp vo mt phn m ngun hoc d liu
trn thit b. S hn ch c p t bo v d liu v m ngun quan trng khi
vic b lm dng bp mo hoc gy hu qu ti tri nghim ngi dng.
Mi quyn c xc nh bng mt nhn duy nht. Thng th nhn ch ra action b hn
ch. V d, di y l mt s quyn nh ngha bi Android:
android.permission.CALL_EMERGENCY_NUMBERS
android.permission.READ_OWNER_DATA
android.permission.SET_WALLPAPER
android.permission.DEVICE_POWER
36
Lp trnh Android c bn
Mt ng dng cng c th bo v cc thnh phn ca n (activity, service, broadcast
receiver v Content Provider) vi quyn. ng dng c th s dng bt c quyn no
do Android nh ngha (c lit k trong android.Manifest.permission), hoc
do nhng ng dng khc khai bo, hoc t nh ngha. Mt quyn mi c khai bo
vi phn t <permission>. V d, mt activity c th c bo v nh sau:
<manifest . . . >
<permission android:name=com.example.project.DEBIT_ACCT . . . />
<uses-permission android:name=com.example.project.DEBIT_ACCT />
. . .
<application . . .>
<activity android:name=com.example.project.FreneticActivity
android:permission=com.example.project.DEBIT_ACCT
. . . >
. . .
</activity>
</application>
</manifest>
Cc th vin
Mi ng dng c lin kt ti th vin mc nh ca Android, bao gm cc gi c
bn xy dng ng dng (vi nhng lp thng dng nh Activity, Service,
Intent, View, Button, Application, ContentProvider,).
Tuy nhin, mt s gi li nm trong th vin ring ca chng. Nu ng dng ca bn
dng m t bt k gi no trong s nhng gi ny, ng dng phi c lin kt r rng
ti chng. File k khai phi cha mt phn t <uses-library> ring bit t tn
cho mi th vin. (C th tm thy tn th vin trong ti liu ca gi ).
37
Lp trnh Android c bn
38
Lp trnh Android c bn
view con, trong khi view con c th l nhng iu khin u vo hoc cc widget(2)
khc to thnh mt s phn ca giao din ngi dng. Cy phn cp c th dng
n gin hoc phc tp, tuy theo nhu cu (nhng s n gin vn l cch tt nht
gia tng hiu nng).
<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:id=@+id/text
android:layout_width=wrap_content
android:layout_height=wrap_content
<Button android:id=@+id/button
android:layout_width=wrap_content
android:layout_height=wrap_content
android:text=y l mt Button />
</LinearLayout>
L cc tin ch nh, thng dng cung cp thng tin hoc tng tc vi user dng n gin khi user khng mun mt thi
gian vo phn mm chnh.
(2)
39
Lp trnh Android c bn
Khi bn np mt ti nguyn layout trong ng dng, Android s khi to mi nt
(node) ca layout thnh mt i tng ang trong thi gian chy, bn c th
dng i tng nh ngha thm cc hnh vi, truy vn trng thi i tng hoc
chnh sa layout.
xem hng dn hon chnh v cch to mt layout giao din ngi dng, mi bn tham
kho XML Layouts.
5.2 Layout
Layout nh ngha cu trc trc quan cho giao din ngi dng, chng hn nh giao din
ngi dng cho mt activity hoc widget ca ng dng (app widget). Bn c th khai bo
layout theo hai cch:
Khai bo cc phn t giao din ngi dng trong XML. Android cung cp mt
b t vng XML n gin tng ng vi cc lp View v lp con, v d nh cho
widget v layout.
Framework Android cho bn kh nng s dng linh hot mt hoc c hai phng thc
ny khai bo v qun l giao din ngi dng ca ng dng. V d, bn c th khai
bo layout mc nh cho ng dng trong XML, bao gm nhng phn t mn hnh s
xut hin trong v cc thuc tnh ca chng. Sau , bn c th thm m trong ng
dng thay i trng thi ca cc i tng mn hnh, bao gm nhng i tng
c khai bo trong XML ti thi im chy ng dng.
u im ca vic khai bo giao din ngi dng trong XML l cho php bn tch bit
tt hn m trnh by (giao din) ca ng dng khi phn m iu khin hnh vi ca
n. Cc m t giao din ngi dng c t bn ngoi ma ngun, c ngha l bn
c th sa i hoc ty chnh giao din m khng phi sa m ngun v bin dch li
(recompile). V d, bn c th to layout XML cho cc chiu xoay mn hnh khc nhau,
kch thc mn hnh khc nhau v ngn ng khc nhau. Ngoi ra, vic khai bo layout
trong XML gip cho vic hnh dung cu trc ca giao din ngi dng tr nn d dng
hn, dn ti vic g li (debug) cng d hn. Nh vy, ti liu ny tp trung vo vic
hng dn bn cch khai bo layout trong XML. Nu bn quan tm n cch khi to
cc i tng View vo thi im chy, hy tham kho lp ViewGroup v View.
40
Lp trnh Android c bn
Thng thng, b t vng XML khai bo cc phn t cho giao din ngi dng s
tun theo cu trc cng nh cch t tn ca lp v phng thc, trong tn phn t
tng ng vi tn lp v tn thuc tnh tng ng vi phng thc. Thc t, s tng
ng xy ra thng xuyn, nn bn c th on thuc tnh XML no s tng ng vi
phng thc lp no, hoc bit c lp no s ng vi mt phn t XML cho. Tuy
nhin, lu rng khng phi tt c b t vng u ging nhau. Trong vi trng hp,
nhng khc bit nh trong cch t tn vn tn ti. V d, phn t EditText c mt thuc
tnh text tng ng vi EditText.setText().
Mch nh: Tm hiu thm v cc loi layout khc nhau trong mc Common Layout
Objects (Cc i tng layout thng thng). Ngoi ra cn c mt b hng dn v
vic xy dng cc layout khc nhau trong ti liu hng dn Hello Views.
Plugin ADT cho Eclipse h tr bn xem trc layout ca file XML - sau khi m
file XML, chn tab Layout.
<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:id=@+id/text
android:layout_width=wrap_content
android:layout_height=wrap_content
<Button android:id=@+id/button
41
Lp trnh Android c bn
android:layout_width=wrap_content
android:layout_height=wrap_content
</LinearLayout>
Sau khi khai bo layout ca mnh trong XML, bn lu file li vi ui .xml trong th
mc res/layout/ ca d n Android, layout c bin dch.
bit thm thng tin v c php cho file layout XML, xem ti liu Layout Resources
(Cc ti nguyn layout).
Np ti nguyn XML
Khi bn bin dch ng dng, mi file layout XML c bin dch thnh mt ti nguyn
View. Bn nn np (load) ti nguyn layout t m ngun ca ng dng, trong phn
thc thi callback (gi tr li) Activity.onCreate(). thc hin iu , bn
gi setContentView(), sau truyn cho phng thc ny mt tham chiu ti ti
nguyn layout ca bn theo mu: R.layout.ten_file_layout. V d, nu layout XML
c lu thnh main_layout.xml, bn c th np layout ny cho Activity nh sau:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_layout);
Cc thuc tnh
Mi i tng View v ViewGroup h tr cc thuc tnh XML khc nhau ca chng.
Mt s thuc tnh l chuyn bit i vi mt i tng View (v d, TextView h tr
thuc tnh textSize), nhng nhng thuc tnh ny cn c bt c i tng View
no c th m rng t lp ny k tha. Mt s thuc tnh l thuc tnh chung i vi
tt c cc i tng View, bi v chng c k tha t lp View gc (nh thuc tnh
id chng hn). V, cc thuc tnh khc c coi nh l tham s ca layout (layout
parameter), l nhng thuc tnh m t hng layout ca i tng View, nh
c i tng cha l ViewGroup nh ngha.
ID
Bt k i tng View no cng c th s hu mt ID dng s nguyn (integer ID) lin
kt vi n ch xc nh View trong cy phn cp. Khi ng dng c bin dch, ID
42
Lp trnh Android c bn
ny c tham chiu di dng s nguyn, nhng trong file XML ca layout, ID c
gn di dng chui, trong thuc tnh id. y l mt thuc tnh XML thng xut hin
tt c cc i tng View (nh ngha bi lp View) v bn s thng xuyn s
dng n. C php ca ID bn trong th XML l:
android:id=@+id/my_button
Biu tng (@) phn u chui ch ra rng b phn tch XML (XML parser) nn phn
tch, m rng phn cn li ca chui ID v nhn bit n nh l mt ti nguyn ID. Biu
tng du cng (+) c ngha y l mt tn ti nguyn mi c to v thm vo kho
ti nguyn (trong file R.java). C mt s ti nguyn ID khc c cung cp bi framework Android. Khi tham chiu mt ID ca ti nguyn Android, bn khng cn biu tng
du cng, nhng phi thm vo namespace ca gi android nh sau:
android:id=@android:id/empty
android:layout_width=wrap_content
android:layout_height=wrap_content
android:text=@string/my_button_text/>
Cc thng s layout
Cc thuc tnh layout XML c t tn di dng layout_<ten thuoc tinh> nh ngha
cc tham s layout cho View ph hp vi ViewGroup cha n.
Mi lp ViewGroup ci t di dng mt lp lng, m rng t lp ViewGroup.
LayoutParams. Lp con ny cha cc loi thuc tnh xc nh kch c v v tr cho
43
Lp trnh Android c bn
tng view con (child view) sao cho ph hp vi nhm view. Nh bn c th thy Hnh
1, nhm view cha (parent view) xc nh cc thng s layout cho mi view con (bao
gm c nhm view con).
Nhn chung, vic xc nh mt chiu rng v chiu cao layout s dng cc n v tuyt
i nh pixel (im nh) khng c khuyn khch. Thay vo , s dng cc kch
thc tng i nh l nhng n v pixel c lp vi mt (density-independent
pixel - dp), wrap_content hoc fill_parent, l phng php tt hn, v n m bo rng
ng dng ca bn s hin th ng nhng kch thc mn hnh thit b khc nhau. Cc
loi kch thc c chp nhn c trnh by trong ti liu Available Resources
(Cc ti nguyn c sn).
44
Lp trnh Android c bn
V tr layout
Dng hnh hc ca view l hnh ch nht. Mi view c mt v tr, c th hin bng
mt cp ta left (bn tri), top (bn trn) cng hai thng s kch thc l chiu rng
v chiu cao. n v cho v tr v kch thc l pixel.
Chng ta c th ly thng s v tr ca mt view bng cch kch hot cc phng thc
getLeft() v getTop(). Phng thc getLeft() tr v thng s left, hay ta
X ca hnh ch nht i din cho view. Phng thc getTop() tr v thng s top,
hay ta Y ca hnh ch nht i din cho view. Cc phng thc ny u tr v v
tr tng i ca view so vi cha ca n. V d, khi getLeft() tr v 20, c ngha l
view c v tr cch cnh tri ca view cha ca n 20 pixel.
Ngoi ra, c mt vi phng thc tin li c cung cp trnh cc php tnh khng
cn thit, l getRight() v getBottom(). Nhng phng thc ny tr v
ta ca cnh phi v y ca hnh ch nht i din cho view. Chng hn, gi
getRight() s tng ng vi php tnh sau: getLeft() + getWidth().
45
Lp trnh Android c bn
Layout t chc cc con ca n thnh mt hng ngang hoc dc. N to mt thanh cun
dc (scrollbar) nu chiu di ca s vt qu chiu di mn hnh.
Layout tng i
46
Lp trnh Android c bn
Web View
List View
47
Lp trnh Android c bn
Grid View
ArrayAdapter
S dng adapter ny khi ngun d liu ca bn l mt mng. Mc nh,
ArrayAdapter to mt view cho tng phn t mng bng cch gi phng thc
toString() trn mi thnh vin v t ni dung vo mt TextView.
V d, nu bn c mt mng cc chui mun hin th trong mt ListView, hy
khi to mt ArrayAdapter mi bng cch s dng mt phng thc khi to
(constructor) xc nh layout cho tng chui v mng chui:
ArrayAdapter adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, myStringArray);
Mng cc chui.
48
Lp trnh Android c bn
ty chnh hnh thc hin th ca mi mc, bn c th ghi (override) phng
thc toString() cho cc i tng trong mng. Hoc, to mt view cho mi
mc khc TextView (v d nu bn mun mt ImageView cho tng mc), hy
m rng lp ArrayAdapter v ghi phng thc getView() tr v loi ca
view bn mun cho mi mc.
SimpleCursorAdapter
S dng adapter ny khi d liu ca bn ti t mt i tng Cursor (con tr).
Khi s dng SimpleCursorAdapter, bn phi ch nh mt layout s dng
cho mi dng trong Cursor v cc ct trong Cursor nn c chn vo nhng
view tng ng ca layout. V d, nu mun to mt danh sch tn mi ngi
km theo s in thoi, bn c th thc thi mt truy vn tr v mt Cursor cha
mt dng cho tng ngi v cc ct cho tn cng s in thoi. Sau , bn to
mt mng chui xc nh cc ct t Cursor m bn mun trong layout cho tng
kt qu v mt mng s nguyn xc nh nhng view tng ng m mi ct nn
c t vo :
String[] fromColumns = {ContactsContract.Data.DISPLAY_NAME,
ContactsContract.CommonDataKinds.Phone.NUMBER};
X l cc s kin click
Bn c th phn hi cc s kin Click trn tng mc trong mt AdapterView bng
cch thc thi giao din (interface) AdapterView.OnItemClickListener.
V d:
49
Lp trnh Android c bn
// To mt thng ip x l i tng di dng mt lp n danh
// (anonymous class).
private OnItemClickListener mMessageClickedHandler =
new OnItemClickListener() {
};
listView.setOnItemClickListener(mMessageClickedHandler);
Trng s ca layout
LinearLayout cng h tr vic gn mt trng s (weight) cho ring tng view con
vi thuc tnh android:layout_weight. Thuc tnh ny gn mt gi tr tm quan
50
Lp trnh Android c bn
trng (importance) cho mt view theo ngha l n s chim bao nhiu khng gian trn
mn hnh. Mt gi tr trng s ln hn s cho php n m rng lp y bt k khng
gian cn li no trong view cha. Cc view con c th xc nh mt gi tr trng s, sau
bt c khng gian cn li no trong nhm view cng c gn cho cc con theo t
l khai bo. Trng s mc nh l 0.
V d, nu c ba trng vn bn v hai trong s khai bo mt trng s l 1, trong khi
trng khc khng c trng s, trng vn bn th ba khng c trng s s khng
tng di v s ch chim vng khng gian nht nh theo ni dung m n yu cu.
Hai trng kia s cng m rng lp y khng gian cn li sau khi c ba trng
c o lng. Nu, trng th ba c thit lp trng s l 2 (thay v 0), tc hin ti
trng th ba c khai bo l quan trng hn hai trng kia, trng ny s ly mt
na trong tng khng gian cn li, trong khi hai trng kia chia u khong khng gian
tha ra cho nhau.
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:paddingLeft=16dp
android:paddingRight=16dp
android:orientation=vertical >
<EditText
android:layout_width=fill_parent
android:layout_height=wrap_content
android:hint=@string/to />
<EditText
android:layout_width=fill_parent
android:layout_height=wrap_content
android:hint=@string/subject />
<EditText
android:layout_width=fill_parent
android:layout_height=0dp
android:layout_weight=1
android:gravity=top
51
Lp trnh Android c bn
<Button
android:hint=@string/message />
android:layout_width=100dp
android:layout_height=wrap_content
android:layout_gravity=right
android:text=@string/send />
</LinearLayout>
bit thm chi tit v cc thuc tnh cho tng view con ca mt LinearLayout,
xem LinearLayout.LayoutParams.
52
Lp trnh Android c bn
nh v cc view
RelativeLayout cho php cc view con n nh v tr tng i ca chng so
vi view cha hoc vi mt view khc (c xc nh bng ID). Do vy, bn c th
cn chnh hai phn t bng vin phi, hoc lm cho view n bn di view kia, nm
gia mn hnh, nm gia theo chiu dc v bn tri theo chiu ngang,... Theo
mc nh, tt c view con u c v gc trn bn tri ca layout, nn bn phi
nh ngha v tr ca tng view, s dng nhiu thuc tnh ca layout c sn trong
RelativeLayout.LayoutParams.
Mt s thuc tnh layout dng cho cc view trong mt RelativeLayout bao gm:
android:layout_alignParentTop
Nu true: Lm cho gc trn ca view ny khp vi gc trn ca view cha.
android:layout_centerVertical
Nu true: Cn gia view con ny theo chiu dc trong phm vi view cha.
android:layout_below
Cc v tr cnh trn ca view ny nm di view c ID c ch nh.
android:layout_toRightOf
Cc v tr cnh tri ca view ny nm v bn phi ca view c ID c ch nh.
53
Lp trnh Android c bn
Trn y ch l mt s v d. Tt c thuc tnh ca layout c ghi ti
RelativeLayout.LayoutParams.
Gi tr cho mi thuc tnh layout c th l boolean (true/false) cho php mt v tr
layout tng i vi cha RelativeLayout, hoc mt ID tham chiu ti mt view
khc trong layout, ni view ny c nh v.
Trong layout XML, cc i tng ph thuc vo nhng view khc c th khai bo theo
th t bt k. V d, bn c th khai bo rng view1 nm bn di view2 ngay c
nu khi view2 l view cui cng c khai bo trong cy phn cp. V d di y
minh ha mt trng hp nh vy.
V d
Trong on m di y, mi thuc tnh kim sot v tr tng i ca tng view c
in m.
54
Lp trnh Android c bn
<?xml version=1.0 encoding=utf-8?>
<RelativeLayout xmlns:android=http://schemas.android.com/apk/res/android
android:layout_width=fill_parent
android:layout_height=fill_parent
android:paddingLeft=16dp
android:paddingRight=16dp >
<EditText
android:id=@+id/name
android:layout_width=fill_parent
android:layout_height=wrap_content
android:hint=@string/reminder />
<Spinner
android:id=@+id/dates
android:layout_width=0dp
android:layout_height=wrap_content
android:layout_below=@id/name
android:layout_alignParentLeft=true
android:layout_toLeftOf=@+id/times />
<Spinner
android:id=@id/times
android:layout_width=96dp
android:layout_height=wrap_content
android:layout_below=@id/name
android:layout_alignParentRight=true />
<Button
android:layout_width=96dp
android:layout_height=wrap_content
android:layout_below=@id/times
android:layout_alignParentRight=true
android:text=@string/done />
</RelativeLayout>
bit thm chi tit v tt c cc thuc tnh ca layout cho tng view con ca mt
RelativeLayout, xem RelativeLayout.LayoutParams.
55
Lp trnh Android c bn
S dng Loader
S dng CursorLoader l phng php chun truy vn mt Cursor (con
tr) di dng mt tc v khng ng b (asynchronous task) trnh chn lung
(thread) chnh ca ng dng khi truy vn. Khi CursorLoader nhn kt qu Cursor,
LoaderCallbacks nhn mt phng thc callback ti onLoadFinished(),
l ni bn cp nht Adapter vi Cursor mi v list view hin th kt qu v sau.
Mc d cc API CursorLoader c gii thiu ln u trong Android 3.0 (API Cp
11), song chng u c mt trong Support Library (th vin h tr) nn ng dng ca
bn c th s dng chng nu n h tr cc thit b chy Android 1.6 hoc cao hn.
Mun bit thm thng tin v cch s dng Loader np d liu theo cch khng
ng b, hy xem hng dn v Loaders (Cc trnh Loader).
V d
V d sau y s dng ListActivity, l activity cha mt ListView vi t
cch l phn t layout duy nht theo mc nh. N thc thi mt truy vn ti Contacts
Provider yu cu danh sch cc tn v s in thoi.
Activity thi hnh giao din LoaderCallbacks s dng CursorLoader nhm
np ng d liu cho list view.
56
Lp trnh Android c bn
public class ListViewLoader extends ListActivity
implements LoaderManager.LoaderCallbacks<Cursor> {
SimpleCursorAdapter mAdapter;
ContactsContract.Data.DISPLAY_NAME};
// y l iu kin chn
@Override
super.onCreate(savedInstanceState);
progressBar.setLayoutParams(new
LayoutParams(LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT, Gravity.CENTER));
progressBar.setIndeterminate(true);
getListView().setEmptyView(progressBar);
// Phi thm thanh tin trnh vo gc ca layout
ViewGroup root = (ViewGroup) findViewById(android.R.id.content);
root.addView(progressBar);
//simple_list_item_1
//
//
//
//
android.R.layout.simple_list_item_1, null,
setListAdapter(mAdapter);
57
Lp trnh Android c bn
mAdapter.swapCursor(data);
}
mAdapter.swapCursor(null);
}
@Override
58
Lp trnh Android c bn
V d
Trong hng dn ny, bn s to mt li gm cc mu nh (image thumbnail - dng
hnh nh thu nh ca mt bc nh). Khi mt mc c chn, mt thng ip tc thi
(toast message) s hin th v tr ca nh.
1. Bt u mt d n mi c tn HelloGridView.
2. Tm mt s tm nh bn mun s dng, hoc ti v cc nh mu ny. Lu cc file
nh vo th mc res/drawable/ ca d n.
3. M file res/layout/main.xml v thm on m sau vo:
<?xml version=1.0 encoding=utf-8?>
<GridView xmlns:android=http://schemas.android.com/apk/res/android
android:id=@+id/gridview
android:layout_width=fill_parent
android:layout_height=fill_parent
android:columnWidth=90dp
android:numColumns=auto_fit
android:verticalSpacing=10dp
android:horizontalSpacing=10dp
android:stretchMode=columnWidth
android:gravity=center
/>
59
Lp trnh Android c bn
GridView ny s lp y ton b mn hnh. Hu ht cc thuc tnh u kh d
hiu. bit thm thng tin v nhng thuc tnh hp l, mi bn xem phn tham
kho GridView.
gridview.setOnItemClickListener(new OnItemClickListener() {
gridview.setAdapter(new ImageAdapter(this));
}
});
}
public ImageAdapter(Context c) {
mContext = c;
return mThumbIds.length;
}
60
Lp trnh Android c bn
}
return 0;
ImageView imageView;
if (convertView == null) { // nu convertView cha b hy, hy khi
// to mt s thuc tnh
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageView.setPadding(8, 8, 8, 8);
} else {
imageView.setImageResource(mThumbIds[position]);
return imageView;
}
// tham chiu ti cc nh
R.drawable.sample_2, R.drawable.sample_3,
R.drawable.sample_6, R.drawable.sample_7,
};
R.drawable.sample_4, R.drawable.sample_5,
R.drawable.sample_0, R.drawable.sample_1,
R.drawable.sample_2, R.drawable.sample_3,
R.drawable.sample_4, R.drawable.sample_5,
R.drawable.sample_6, R.drawable.sample_7,
R.drawable.sample_0, R.drawable.sample_1,
R.drawable.sample_2, R.drawable.sample_3,
R.drawable.sample_4, R.drawable.sample_5,
R.drawable.sample_6, R.drawable.sample_7
61
Lp trnh Android c bn
Phng thc cn thit u tin l getView(). Phng thc ny to mt View mi
cho mi nh c thm vo ImageAdapter. Khi getView() c gi, mt View
c truyn vo, thng l mt i tng c kh nng b thu hi b nh (t nht l
sau khi phng thc ny c gi mt ln), nn y s c mt bc kim tra xem
i tng ny c bng null khng. Nu i tng l null, mt i tng ImageView
s c khi to v cu hnh vi cc thuc tnh mong mun cho vic trnh by nh:
oo
oo
oo
5.3 Cc s kin u vo
Trn Android, c nhiu cch chn (intercept) cc s kin t mt action tng
tc ca ngi dng vi ng dng ca bn. Khi xem xt cc s kin trong giao din
ngi dng, bn nn p dng phng php bt cc s kin t i tng View c
th m ngi dung tng tc cng. Lp View cung cp phng tin thc hin
iu ny.
Trong nhng lp View khc nhau dng to layout, hy lu rng c vi phng
thc callback dng public hu ch cho cc s kin giao din ngi dng. Nhng
phng thc ny c framework Android gi khi action tng ng xy ra trn i
tng . V d, khi nhn vo mt View (chng hn nh mt Button), phng thc
onTouchEvent() s c gi trn i tng . Tuy nhin, ngn chn iu ny,
bn phi m rng lp v ghi ln phng thc . Nhng vic m rng mi i
tng View x l s kin nh vy s khng thit thc. l l do ti sao lp View
cn cha mt tp cc giao din lng nhau vi nhng callback m bn c th d nh
62
Lp trnh Android c bn
ngha hn nhiu. Cc giao din nh vy gi l trnh lng nghe s kin (event listener),
l cha kha bt nhng tng tc ca ngi dng vi giao din.
Trong khi bn s dng trnh lng nghe s kin lng nghe tng tc ca ngi dung,
c th s n lc no bn mun m rng mt lp View xy dng mt thnh phn
ty chnh. C th bn mun m rng lp Button to ra ci g hay hn chng hn.
Trong trng hp ny, bn c th nh ngha cc hnh vi s kin mc nh cho lp
bng cch s dng trnh x l s kin (event handler) cho lp.
onClick()
T View.OnClickListener. Phng thc ny c gi khi ngi dung chm
vo mc ( ch cm ng), hoc chuyn focus(3) vo mc bng cch s dng
cc phm iu hng (nevigation key) hay bi ln v nhn phm enter hoc nhn
bi ln xung.
onLongClick()
T View.OnLongClickListener. Phng thc ny c gi khi ngi dung
chm ri gi vo mc ( ch cm ng), hoc focus vo mc vi cc phm
iu hng hay bi ln v nhn gi phm enter ph hp hoc nhn gi bi ln (trong
mt giy).
onFocusChange()
T View.OnFocusChangeListener. Phng thc ny c gi khi ngi
dung di chuyn n hoc ri khi mt mc bng cch s dng cc phm iu
hng hoc bi ln.
onKey()
T View.OnKeyListener. Phng thc ny c gi khi ngi dung focus
vo mt mc v nhn hoc th mt phm cng trn thit b.
onTouch()
T View.OnTouchListener. Phng thc ny c gi khi ngi dung thc
hin mt action, chng hn nh mt s kin chm (touch event), bao gm nhn, th
hay bt c ng tc di chuyn no trn mn hinh (trong phm vi ca mc).
onCreateContextMenu()
T View.OnCreateContextMenuListener. Phng thc ny c gi khi
mt menu ng cnh (context menu) ang c dng (kt qu ca vic nhn lu
(long click). Xem tho lun v menu ng cnh trong phn hng dn cho nh
pht trin Menu ca sch ny.
(3)
Trng thi ca iu khin ang c kch hot hay c chn ngi dng c th thao tc hoc nhp liu vi n.
63
Lp trnh Android c bn
Mi phng thc ny l thnh phn duy nht ca giao din tng ng. nh ngha
mt trong nhng phng thc ny v x l cc s kin, hy thc thi giao din lng
(nested interface) trong Activity hoc nh ngha n nh l mt lp n danh. Sau ,
hy truyn mt th hin ca lp ny ti phng thc View.set...Listener()
tng ng. (V d, hy gi setOnClickListener() v truyn cho n th hin ca
OnClickListener).
V d bn di ch r cch ng k mt trnh lng nghe s kin on-click cho mt Button.
// To mt lp n danh ca OnClickListener
};
// Ly v button t layout
button.setOnClickListener(mCorkyListener);
...
}
...
button.setOnClickListener(this);
}
}
}
...
64
Lp trnh Android c bn
onKey() - tr v mt boolean cho bit liu bn s dng xong s kin hay cha
onTouch() - tr v mt boolean cho bit liu trnh lng nghe s kin x l xong
65
Lp trnh Android c bn
chuyn bi ln.
ViewParent.requestDisallowInterceptTouchEvent(boolean) - Gi
phng thc ny trn View cha ch ra rng view cha khng chn cc s kin
chm mn hnh vi onInterceptTouchEvent(MotionEvent).
Ch cm ng
Khi ngi dung thc hin iu hng trn giao din vi cc phm iu hng (directional
key) hoc bi ln, iu cn thit l phi focus vo nhng mc c kh nng tng tc
(nh button), gip ngi dng bit c ci g s tip nhn u vo. Tuy nhin, nu
thit b c tnh nng cm ng v ngi dung bt u tng tc vi giao din bng cch
chm ln mn hnh th khng nht th it phi nh du cc mc hoc focus vo mt
View c th. Do , c mt ch tng tc gi l ch cm ng (touch mode).
i vi mt thit b c kh nng cm ng, mt khi ngi dng chm vo mn hnh,
thit b s chuyn sang ch cm ng. T lc ny tr i, ch nhng View m ti ,
isFocusableInTouchMode() c gi tr true s c focus vo, chng hn nh cc
widget chnh sa vn bn. Nhng View khc cng c kh nng cm ng, nh cc button,
s khng c focus khi ngi dng chm vo; thay v vy chng l kch hot cc trnh
lng nghe s kin on-click khi bn nhn vo.
66
Lp trnh Android c bn
Bt c thi im no ngi dung nhn phm iu hng hoc ln bi ln, thit b s
thot khi ch cm ng v tm mt view focus vo. Lc ny, ngi dng c th
tip tc tng tc vi giao din ngi dng m khng phi chm vo mn hnh.
Ch cm ng c duy tr trn ton h thng (tt c window v activity). truy vn
trng thi hin thi, bn c th gi isInTouchMode() xem thit b c ang ch
cm ng hay khng.
X l s kin focus
Framework s nh k x l thay i v focus p ng thao tc nhp liu t
ngi dng. iu ny bao gm vic thay i focus khi mt s View b xa hoc n
i, hay khi View mi to ra. Cc view cho bit chng sn sng nhn focus
thng qua phng thc isFocusable(). di chuyn focus vo mt View, hy gi
setFocusable(). Khi ch cm ng, bn c th truy vn xem mt View c cho
php focus hay khng vi isFocusableInTouchMode(). Bn c th thay i iu
ny vi setFocusableInTouchMode().
Vic di chuyn focus c da vo thut ton tm hng xm gn nht theo hng
cho. Trong mt s trng hp him gp, thut ton mc nh c th khng khp
vi hnh vi d nh ca lp trnh vin. Trong nhng tnh hung , bn c th cung
cp cc thuc tnh ghi tng minh ln nhng thuc tnh XML trong file layout l
nextFocusDown, nextFocusLeft,nextFocusRight v nextFocusUp. Hy thm mt trong
cc thuc tnh ny vo View s mt focus, ng thi nh ngha gi tr thuc tnh bng
gi tr id ca View s nhn focus. V d:
<LinearLayout
android:orientation=vertical
... >
<Button android:id=@+id/top
android:nextFocusUp=@+id/bottom
... />
<Button android:id=@+id/bottom
android:nextFocusDown=@+id/top
... />
</LinearLayout>
67
Lp trnh Android c bn
yu cu mt View nhn focus, gi requestFocus().
lng nghe cc s kin focus (khi mt View c focus hoc mt focus), s dng
onFocusChange(), nh tho lun trong mc Trnh lng nghe s kin trn.
5.4 Menu
Menu l thnh phn giao din ngi dng thng dng trong nhiu loi ng dng.
cung cp tri nghim ngi dung quen thuc v nht qun, bn nn s dng cc API
Menu biu din action ca ngi dng v nhng ty chn khc trong cc activity
ca mnh.
K t Android 3.0 (API Cp 11), cc thit b nn Android khng cn bt buc phi c
mt button Menu na. Vi s thay i ny, cc ng dng Android nn thot khi s
ph thuc vo bng menu 6 mc m thay vo cung cp mt action bar th hin
nhng action thng thng ca ngi dung.
Mc d thit k v tri nghim ngi dng cho cc mc ca menu thay i, nhng
nhng yu t cn bn nh ngha mt tp action v ty chn vn da trn cc API
Menu. Hng dn ny ch ra cch to ba loi menu c bn hoc biu din cc action
trn mi phin bn ca Android:
Menu ty chn v action bar
Menu ty chn (Options menu) l tp cc mc menu chnh cho mt activity. y
l ni bn nn t cc action c nh hng trn ton ng dng, chng hn nh
Search (tm kim), Compose email (son tho e-mail) v Settings (chnh sa
cc thit lp).
Nu bn ang pht trin cho Android 2.3 hay cp thp hn, ngi dng c th hin
th bng menu ty chn ty chn bng cch nhn button Menu.
T phin bn 3.0 tr i, cc mc trn menu ty chn c hin th trn action bar
bao gm cc action trn mn hnh v cc hnh ng n (overflow option - ngi
dng chm vo mt biu tng cui action bar hin th nhng action n ny).
K t Android 3.0, button Menu dn b loi b (mt s thit b khng c button ny).
Do vy, bn nn hng ti s dng action bar cung cp cch thc truy cp ti
nhng action v ty chn khc.
Xem mc To mt menu ty chn.
Menu ng cnh v ch contextual action
Menu ng cnh (context menu) l mt menu ng (floating menu) xut hin khi
ngi dung nhn lu trn trn mt phn t. Menu ny cung cp cc action nh
hng ti ni dung hoc khung ng cnh c chn.
Khi pht trin ng dng cho Android 3.0 v cp cao hn, bn nn s dng ch
contextual action (contextual action mode) kch hot cc action trn phn ni
dung c chn. Ch ny hin th nhng mc action nh hng ti ni dung
c chn trong mt thanh pha trn mn hnh v cho php ngi dung chn
cng lc nhiu mc.
Xem mc To menu ng cnh.
68
Lp trnh Android c bn
Menu popup
Menu popup hin th mt danh sch cc mc theo dng dc ngay trn view kch
hot menu . Menu cung cp dng cung cp nhiu action lin quan ti ni
dung c th hoc cung cp thm ty chn cho mt lnh. Cc action trong mt
menu popup khng nh hng trc tip ti ni dung tng ng - ging nh cc
action trn menu ng cnh. Thay vo , menu popup cung cp nhng action m
rng lin quan ti cc vng ni dung trong activity ca bn.
Xem mc To menu popup.
Ti nguyn menu gip bn d hnh dung cu trc menu trong XML hn.
Ti nguyn menu cho php bn to cc cu hnh menu thay i cho nhng phin
bn nn tng, cc kch thc mn hnh v cu hnh khc nhau bng cch s dng
framework ti nguyn ng dng (app resources).
<menu>
nh ngha mt Menu l i tng cha cho cc mc menu. Mt phn t <menu>
nn l nt gc cho file, c th cha mt hoc nhiu phn t <item> v <group>.
<item>
To mt MenuItem i din cho mt mc n trong menu. Phn t ny c th
cha mt phn t <menu> lng to mt menu con (submenu).
<group>
L phn t khng bt buc, nh ngha mt vt cha n (v hnh) cho cc phn t
<item>. N cho php bn phn loi cc mc menu chng c th chia s thuc
tnh, chng hn nh trng thi active v trng thi hin th (visibility). tham kho
thm thng tin, xem mc To nhm menu.
y l mt menu v d c tn game_menu.xml:
69
Lp trnh Android c bn
<?xml version=1.0 encoding=utf-8?>
<menu xmlns:android=http://schemas.android.com/apk/res/android>
<item android:id=@+id/new_game
android:icon=@drawable/ic_new_game
android:title=@string/new_game
android:showAsAction=ifRoom/>
<item android:id=@+id/help
android:icon=@drawable/ic_help
android:title=@string/help />
</menu>
android:id
ID ti nguyn duy nht i vi mt mc, cho php ng dng nhn din mc khi
ngi dung chn n.
android:icon
Tham chiu ti mt drawable s dng biu tng cho mc.
android:title
Tham chiu ti mt chui s dng lm tiu cho mc.
android:showAsAction
Xc nh thi im v cch thc m mc ny xut hin di dng mt mc action
trong action bar.
y l nhng thuc tnh quan trng nht m bn nn s dng, nhng ngoi ra cn
c sn nhiu thuc tnh khc. bit thm thng tin v tt c cc thuc tnh c
h tr, xem ti liu Menu Resource (Ti nguyn menu).
Bn c th thm mt menu con vo mt mc trong bt c menu no (ngoi tr trong
mt menu con) bng cch thm mt phn t <menu> di dng l con ca <item>.
Cc menu con rt hu ch khi ng dng c nhiu chc nng c th c t chc theo
ch nh cc mc trong thanh menu ca ng dng my tnh (File, Edit, View,...).
V d:
<?xml version=1.0 encoding=utf-8?>
<menu xmlns:android=http://schemas.android.com/apk/res/android>
<item android:id=@+id/file
android:title=@string/file >
<item android:id=@+id/create_new
70
android:title=@string/create_new />
Lp trnh Android c bn
<item android:id=@+id/open
</menu>
android:title=@string/open />
</item>
</menu>
To mt menu ty chn
Nu bn pht trin ng dng cho Android 2.3.x (API Cp 10) hay cp thp hn,
ni dung ca menu ty chn s xut hin phn di mn hnh khi ngi dung
nhn button Menu, nh minh ha Hnh 1. Khi menu ty chn c m ra, u
tin menu cha biu tng ca su mc menu. Nu menu cha qu su mc,
71
Lp trnh Android c bn
Android s t mc th sau v nhng mc menu cn li vo menu trn (overflow
menu) m ti , ngi dng c th m bng cch chn More.
Nu bn pht trin ng dng cho Android 3.0 (API Cp 11) v cp cao hn, cc
mc t menu ty chn u sn c trong action bar. Theo mc nh, h thng t tt
c cc action u b n trong mt biu tng bn phi ca action bar v ngi
dng c th hin th chng bng cch bm vo biu tng ny (hoc bng cch
nhn button Menu ca thit b, nu c). cho php truy cp nhanh vo nhng
action quan trng, bn c th tng cp vi mc xut hin trong action bar bng
cch thm android:showAsAction=ifRoom vo cc phn t <item>
tng ng (xem Hnh 2).
bit thm thng tin v cc mc action v nhng hnh vi khc ca action bar,
xem hng dn Action Bar.
Ghi ch: Ngay c khi khng pht trin ng dng cho Android 3.0 v cp cao hn,
bn cng c th xy dng layout cho action bar ca mnh vi hiu ng tng t.
tm hiu v d v cch bn c th h tr cc phin bn c hn ca Android vi
action bar, xem v d mu trong ti liu mu Action Bar Compatibility (Tng thch
Action Bar).
72
Lp trnh Android c bn
@Override
return true;
inflater.inflate(R.menu.game_menu, menu);
X l cc s kin click
Khi ngi dung chn mt mc t menu ty chn (gm cc mc action trong action bar),
h thng s gi phng thc onOptionsItemSelected() ca activity. Phng thc
ny truyn MenuItem chn. Bn c th nhn din mc bng cch gi phng thc
getItemId() tr v ID duy nht cho mc menu (xc nh bi thuc tnh android:id
trong ti nguyn menu hoc vi mt s nguyn c truyn cho phng thc add()).
Bn c th khp ID ny vi cc mc menu c thc hin action thch hp. V d:
@Override
case R.id.new_game:
newGame();
return true;
case R.id.help:
showHelp();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
73
Lp trnh Android c bn
mi phn vng c thm vo) ti khi c mt gi tr true c tr v hoc tt c cc
phn vng u c gi.
Mch nh: Android 3.0 b sung kh nng cho php bn nh ngha hnh vi on-click
cho mt mc menu trong XML, s dng thuc tnh android:onClick. Gi tr cho
thuc tnh phi l tn phng thc do activity s dng menu ny nh ngha. Phng
thc phi l public v chp nhn mt tham s MenuItem n - khi h thng gi
phng thc ny, n s truyn mc menu chn. tham kho thm thng tin v
v d, xem ti liu Menu Resource (Ti nguyn menu).
Mch nh: Nu ng dng cha nhiu activity v mt vi trong s chng cung cp menu
ty chn ging nhau, hy cn nhc vic to mt activity khng thc thi g, ngoi tr
cc phng thc onCreateOptionsMenu() v onOptionsItemSelected().
Sau , hy m rng lp ny cho mi activity m c menu ty chn ging nhau .
Bng cch ny, bn c th qun l mt tp m ngun cho vic x l nhng action
menu v mi lp con chu k tha cc hnh vi menu. Nu bn mun thm cc mc
menu vo mt trong nhng activity con chu, hy ghi onCreateOptionsMenu()
trong activity . Gi super.onCreateOptionsMenu(menu) cc mc menu
gc (ca lp cha) c to, ri thm nhng mc menu mi vi menu.add(). Bn
cng c th ghi hnh vi ca lp cha cho tng mc menu ring l.
74
Lp trnh Android c bn
To menu ng cnh
75
Lp trnh Android c bn
Ghi ch: Ch action ng cnh c trn Android 3.0 (API Cp 11) v cp cao hn.
K thut ny thng c dng hin th cc action ng cnh khi sn sng.
Nu ng dng ca bn h tr cc phin bn cp thp hn 3.0, bn nn quay li vi
menu ng cnh ng trn nhng thit b .
To menu ng cnh ng
to mt menu ng cnh ng:
1. ng k View vi i tng m menu ng cnh nn c lin kt bng cch gi
registerForContextMenu() v truyn View cho phng thc.
@Override
ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
inflater.inflate(R.menu.context_menu, menu);
AdapterContextMenuInfo info =
switch (item.getItemId()) {
(AdapterContextMenuInfo) item.getMenuInfo();
case R.id.edit:
76
Lp trnh Android c bn
editNote(info.id);
return true;
case R.id.delete:
deleteNote(info.id);
return true;
default:
return super.onContextItemSelected(item);
}
}
Ngi dng chn mt checkbox hoc thnh phn giao din tng t bn
trong view.
77
Lp trnh Android c bn
Cch ng dng kch hot ch action ng cnh v xc nh hnh vi cho mi action
ty thuc vo thit k ca bn. C hai thit k c bn:
@Override
inflater.inflate(R.menu.context_menu, menu);
return true;
}
@Override
@Override
78
Lp trnh Android c bn
{
switch (item.getItemId()) {
case R.id.menu_share:
shareCurrentItem();
return true;
default:
return false;
}
}
@Override
mActionMode = null;
};
if (mActionMode != null) {
return false;
}
view.setSelected(true);
return true;
}
});
79
Lp trnh Android c bn
Khi bn gi phng thc startActionMode(), h thng tr v ActionMode
c to. Bng cch lu n trong mt bin thnh vin (member variable), bn c th
thay i action bar ng cnh phn hi li nhng s kin khc. Trong v d trn,
ActionMode c s dng m bo rng th hin ActionMode khng c ti
to nu n hot ng bng cch kim tra xem bin thnh vin c null khng trc
khi bt u ch action .
V d:
ListView listView = getListView();
listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
listView.setMultiChoiceModeListener(new MultiChoiceModeListener() {
@Override
@Override
{
case R.id.menu_delete:
deleteSelectedItems();
return true;
default:
return false;
}
}
@Override
80
Lp trnh Android c bn
inflater.inflate(R.menu.context, menu);
return true;
}
@Override
@Override
return false;
}
});
To menu popup
81
Lp trnh Android c bn
PopupMenu l menu c neo vo mt View. Loi menu ny xut hin bn di
view neo nu cn ch, hoc bn trn view nu ngc li. PopupMenu rt hu ch
trong vic:
android:layout_width=wrap_content
android:layout_height=wrap_content
android:src=@drawable/ic_overflow_holo_dark
android:onClick=showPopup />
android:contentDescription=@string/descr_overflow_button
inflater.inflate(R.menu.actions, popup.getMenu());
popup.show();
}
82
Lp trnh Android c bn
Menu b hy (dismiss) khi ngi dung chn mt mc hoc chm vo bn ngoi khu
vc menu. Bn c th lng nghe s kin hy menu bng cch s dng PopupMenu.
OnDismissListener.
X l cc s kin click
thc hin mt action khi ngi dung chn mt mc menu, bn phi thc thi giao
din PopupMenu.OnMenuItemClickListener v ng k n vi PopupMenu
bng cch gi setOnMenuItemclickListener(). Khi ngi dng chn mt
mc, h thng gi phng thc callback onMenuItemClick() trong giao din
ca bn.
V d:
public void showMenu(View v) {
popup.inflate(R.menu.actions);
popup.setOnMenuItemClickListener(this);
popup.show();
}
@Override
switch (item.getItemId()) {
case R.id.archive:
archive(item);
return true;
case R.id.delete:
delete(item);
return true;
default:
return false;
}
}
To nhm menu
Nhm menu l tp cc mc menu c chung mt s c im nht nh. Vi mt nhm
menu, bn c th:
83
Lp trnh Android c bn
Bn c th to mt nhm bng cch lng cc phn t <item> bn trong mt phn t
<group> trong ti nguyn menu, hoc bng cch n nh mt ID nhm vi phng
thc add().
Di y l v d v ti nguyn menu c cha mt nhm:
<?xml version=1.0 encoding=utf-8?>
<menu xmlns:android=http://schemas.android.com/apk/res/android>
<item android:id=@+id/menu_save
android:icon=@drawable/menu_save
android:title=@string/menu_save />
<group android:id=@+id/group_delete>
<item android:id=@+id/menu_archive
android:title=@string/menu_archive />
<item android:id=@+id/menu_delete
</group>
android:title=@string/menu_delete />
</menu>
S dng cc mc menu c th nh du
84
Lp trnh Android c bn
i khi, vic mt menu c giao din h tr kh nng la chn mc menu bng cch bt
hoc tt s rt hu ch, bn hy s dng checkbox khi mi mc c la chn c lp
vi nhau hoc dng cc radio button khi cc mc thuc mt nhm v ch cho php la
chn mt mc. Hnh 5 minh ha mt menu con vi nhng mc c th nh du c
vi cc radio button.
Ghi ch: Cc mc menu trong Icon Menu (t menu ty chn) khng th hin th mt
checkbox hoc radio button. Nu chn cch to cc mc trong Icon Menu l c th nh
du, bn phi t biu th trng thi chn bng cch hon i biu tng v/hoc vn
bn mi ln trng thi thay i.
Bn c th nh ngha kh nng c th nh du cho tng mc menu ring bng cch
s dng thuc tnh android:checkable trong phn t <item>, hoc cho c nhm
vi thuc tnh android:checkableBehavior trong phn t <group>. V d, tt
c cc mc trong nhm menu ca on m di y u c th nh du c vi
mt radio button:
<?xml version=1.0 encoding=utf-8?>
<menu xmlns:android=http://schemas.android.com/apk/res/android>
<group android:checkableBehavior=single>
<item android:id=@+id/red
android:title=@string/red />
<item android:id=@+id/blue
</group>
android:title=@string/blue />
</menu>
single
Ch mt mc ca nhm c th c chn (button radio).
all
Tt c cc mc c th c chn (checkbox).
none
Khng th chn bt c mc no.
Bn c th p dng trng thi chn mc nh cho mt mc bng cch s dng thuc
tnh android:checked trong phn t <item>, ng thi thay i trng thi ny
trong m ngun vi phng thc setChecked().
Khi mt mc c th nh du c chn, h thng s gi phng thc callback tng
ng vi mc (chng hn nh onOptionsItemSelected()). Phng thc ny
l ni bn phi thit lp trng thi ca checkbox, do checkbox hoc radio button khng
t ng thay i trng thi ca n c. Bn c th truy vn trng thi hin ti ca mc
(nh trc khi ngi dng chn n) vi isChecked() v thit lp trng thi chn
vi setChecked(). V d:
85
Lp trnh Android c bn
@Override
switch (item.getItemId()) {
case R.id.vibrate:
case R.id.dont_vibrate:
if (item.isChecked()) item.setChecked(false);
else item.setChecked(true);
return true;
default:
return super.onOptionsItemSelected(item);
}
}
Nu bn khng thit lp trng thi chn bng cch ny th, trng thi hin th ca
mc (checkbox hoc button radio) s khng i khi ngi dung chn n. Khi bn thit
lp trng thi, activity s bo ton trng thi chn ca mc; do , khi ngi dung
m menu ln sau, trng thi chn m bn thit lp s hin th.
Ghi ch: Cc mc menu c th nh du thng c s dng ch da trn c s theo
phin (session) v khng c lu sau khi tt ng dng. Nu c cc thit lp ng dng
mun lu cho ngi dng, bn nn lu tr d liu bng cch dng Cc thit lp chia s
(Shared Preferences).
86
Lp trnh Android c bn
Ghi ch: CATEGORY_SELECTED_ALTERNATIVE c dng x l phn t ang
c chn trn mn hnh. V vy, ch nn s dng hng mc ny khi to mt Menu trong
onCreateContextMenu().
V d:
@Override
// mt gi tr hng mc ca Intent.CATEGORY_ALTERNATIVE.
Intent intent = new Intent(null, dataUri);
intent.addCategory(Intent.CATEGORY_ALTERNATIVE);
menu.addIntentOptions(
0,
0,
this.getComponentName(),
return true;
87
Lp trnh Android c bn
<intent-filter label=@string/resize_image>
...
...
</intent-filter>
tham kho thng tin v cch to cc b lc intent, xem mc Intents and Intent Filters (Intent v b lc intent).
xem mt ng dng mu s dng k thut ny, hy tm trong v d mu Note Pad.
5.5 Thng bo
Thng bo (notification) l mt thng ip m bn c th hin th cho ngi dng
ngoi giao din ngi dung thng thng ca ng dng. Khi bn ra lnh cho h thng
a ra mt thng bo, trc ht thng bo s xut hin di dng mt biu tng trong
vng thng bo (notification area). xem chi tit v thng bo, ngi dung cn m
ngn thng bo (notification drawer). C vng thng bo ln ngn thng bo u l
cc khu vc c h thng kim sot m ngi dung c th xem vo mi thi im.
88
Lp trnh Android c bn
Thit k ca thng bo
L mt b phn quan trng ca giao din ngi dng Android, thng bo c nhng quy
tc thit k ring ca chng. bit cch thit k thng bo v tng tc vi chng,
hy c ch Hng dn Thit k Notifications ca Android.
Ghi ch: Ngoi tr ni c ghi ch, hng dn ny cp ti lp
NotificationCompat.Builder trong Support Library (th vin h tr) phin bn
4. Lp Notification.Builder c thm vo trong Android 3.0.
89
Lp trnh Android c bn
5. Biu tng nh (small icon).
6. Thi gian thng bo xut hin. Bn c th thit lp mt gi tr c th vi setWhen();
nu bn khng lm nh vy th gi tr mc nh s l thi gian h thng nhn c
thng bo.
View ln
Mt thng bo ca view ln ch xut hin khi thng bo c m rng, iu ny xy ra
khi thng bo nm u ngn thng bo, hoc khi ngi dung thao tc m rng ngn
thng bo. Cc thng bo m rng l tnh nng sn c vi Android 4.1.
nh chp mn hnh di y hin th mt thng bo dng hp th n (inbox):
90
Lp trnh Android c bn
Cho php bn thm mt dng vn bn di vng chi tit.
Vic p dng mt kiu view ln cho mt thng bo c m t trong mc p dng kiu
view ln cho mt thng bo.
5.5.1 To thng bo
Bn c th xc nh thng tin giao din ngi dng v cc action cho mt thng bo
trong mt i tng NotificationCompat.Builder. t to mt thng bo,
bn gi NotificationCompat.Builder.build(), n tr v mt i tng
Notification cha cc thng s k thut cho bn. a ra thng bo, bn truyn
i tng Notification cho h thng bng cch gi NotificationManager.
notify().
Cc action ca thng bo
Mc d chng l ty chn, song bn vn nn thm t nht mt action cho thng bo
ca mnh. Mt action cho php ngi dung i trc tip t thng bo ti mt Activity
trong ng dng, y cng l ni h c th nhn vo mt hay nhiu s kin hoc lm
nhng vic khc.
Mt thng bo c th cung cp nhiu action. iu bn nn lm l lun nh ngha
action kch hot khi ngi dung nhn vo thng bo; thng th action ny m mt
Activity trong ng dng ca bn. Bn cng c th thm cc button vo thng bo
thc hin cc action b sung nh tng thi gian cho mt bo thc (alarm) hoc phn
hi lp tc mt tin nhn vn bn (text message); tnh nng ny c sn phin bn
Android 4.1. Nu s dng thm cc button action, bn phi lm cho chc nng ca
chng sn sng trong mt Activity ca ng dng; xem mc Handling compatibility
(X l vn tng thch) bit thm thng tin chi tit.
Trong mt Notification, bn thn action do mt PendingIntent nh ngha cha
mt Intent khi ng Activity ca ng dng. lin kt PendingIntent vi
mt thao tc ca ngi dng, gi phng thc thch hp ca NotificationCompat.
Builder. V d, nu bn mun khi ng Activity khi ngi dung nhn vo
dng thng bo trong ngn thng bo, hy thm PendingIntent bng cch gi
setContentIntent().
91
Lp trnh Android c bn
Khi ng mt Activity khi ngi dung nhn vo thng bo l kch bn action
ph bin nht. Bn cng c th khi ng mt Activity khi ngi dng tt mt
thng bo. Trong Android 4.1 v cc phin bn mi hn, bn c th khi ng mt
Activity t mt button action. tm hiu su hn, hy c hng dn tham kho
cho NotificationCompat.Builder.
To mt thng bo n gin
on m nh di y minh ha mt thng bo n gin, xc nh mt activity s
m khi ngi dng nhn vo thng bo. Ch rng, on m to mt i tng
TaskStackBuilder v dng n to PendingIntent cho action. M hnh ny
c gii thch chi tit hn mc Preserving Navigation when Starting an Activity
(Bo ton iu hng khi khi ng mt Activity):
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(this)
.setContentTitle(My notification)
.setSmallIcon(R.drawable.notification_icon)
.setContentText(Hello World!);
stackBuilder.getPendingIntent(
0,
PendingIntent.FLAG_UPDATE_CURRENT
);
mBuilder.setContentIntent(resultPendingIntent);
NotificationManager mNotificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(mId, mBuilder.build());
92
Lp trnh Android c bn
.setSmallIcon(R.drawable.notification_icon)
.setContentText(Events received)
.setContentTitle(Event tracker)
NotificationCompat.InboxStyle inboxStyle =
new NotificationCompat.InboxStyle();
// a ra thng bo y.
X l vn tng thch
Khng phi mi tnh nng thng bo u sn sng cho phin bn c th trc ,
bt k cc phng thc dng thit lp chng u nm trong lp th vin h tr
NotificationCompat.Builder. V d, button action ph thuc vo thng bo m
rng ch xut hin trn Android 4.1 v cp cao hn, bi bn thn nhng thng bo m
rng u ch sn sng trn Android 4.1 v cp cao hn.
m bo tng thch tt nht, hy to thng bo vi NotificationCompat v cc
lp con ca n, c bit l NotificationCompat.Builder. Ngoi ra, bn hy tun
theo quy trnh sau khi thc thi mt thng bo:
1. Cung cp tt c cc chc nng ca thng bo cho mi ngi dng, bt k h ang
dng phin bn no. lm iu ny, hy m bo rng tt c cc chc nng u
93
Lp trnh Android c bn
c sn t mt Activity trong ng dng ca bn. C th bn s mun thm mt
Activity mi lm vic ny.
V d, nu mun s dng addAction() nhm cung cp mt iu khin dng
v bt u pht a phng tin (media playback), trc ht, hy thc thi iu
khin ny trong mt Activity thuc ng dng ca bn.
2. m bo mi ngi dng u c th s dng tnh nng trong Activity, bng
cch khi ng n khi ngi dung nhn vo thng bo. lm iu ny, hy to
mt PendingIntent cho Activity. Gi setContentIntent() thm
PendingIntent vo thng bo.
3. Lc ny, hy thm cc tnh nng ca thng bo m rng bn mun dng vo
thng bo. Cn nh rng, bt c chc nng no bn thm cng sn sng trong
Activity khi ng khi ngi dung nhn vo thng bo.
Cp nht thng bo
thit lp mt thng bo c kh nng cp nht, hy cp cho n mt ID thng
bo bng cch gi NotificationManager.notify(ID,
notification).
cp nht thng bo khi bn hin th n, hy cp nht hoc to mt i tng
NotificationCompat.Builder, xy dng mt i tng Notification t i
tng v hin th Notification vi cng ID m bn s dng trc . Nu
thng bo trc vn hin hu, h thng s cp nht n t ni dung ca i tng
Notification. Nu thng bo trc b tt, mt thng bo mi s c to
thay th.
on m di y m t mt thng bo c cp nht phn nh s lng s kin
xy ra. N xp chng (stack) thng bo, a ra bn tm lc:
94
Lp trnh Android c bn
mNotificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
.setContentTitle(New Message)
.setSmallIcon(R.drawable.ic_notify_status)
numMessages = 0;
mNotifyBuilder.setContentText(currentText)
.setNumber(++numMessages);
notifyID,
mNotifyBuilder.build());
...
G b thng bo
Cc thng bo s cn hin hu cho n khi mt trong nhng iu di y xy ra:
Ngi dng tt tng thng bo hoc s dng Clear All (nu thng bo c th b
xa b).
95
Lp trnh Android c bn
phn
ny,
PARENT_ACTIVITY .
96
t android:name=android.support.
Thit lp android:value=<parent_
Lp trnh Android c bn
activity_name>, trong <parent_activity_name> l gi
tr ca android:name i vi phn t <activity> cha. Xem mt v
d file XML sau.
android:name=.MainActivity
android:label=@string/app_name >
<intent-filter>
</intent-filter>
</activity>
<activity
android:name=.ResultActivity
android:parentActivityName=.MainActivity>
<meta-data
android:name=android.support.PARENT_ACTIVITY
android:value=.MainActivity/>
</activity>
97
Lp trnh Android c bn
f.
stackBuilder.addParentStack(ResultActivity.class);
// Thm Intent vo nh ca ngn xp
stackBuilder.addNextIntent(resultIntent);
...
stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(id, builder.build());
android:name=activityclass
Tn lp y ca activity.
android:taskAffinity=
android:excludeFromRecents=true
98
Lp trnh Android c bn
on m nh di y hin th phn t:
<activity
android:name=.ResultActivity
...
android:launchMode=singleTask
android:taskAffinity=
android:excludeFromRecents=true>
</activity>
...
notifyIntent.setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK);
// To PendingIntent
PendingIntent notifyIntent =
PendingIntent.getActivity(
this,
0,
notifyIntent
PendingIntent.FLAG_UPDATE_CURRENT
);
99
Lp trnh Android c bn
NotificationManager mNotificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(id, builder.build());
100
Lp trnh Android c bn
...
mNotifyManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
.setContentText(Download in progress)
.setSmallIcon(R.drawable.ic_notification);
new Runnable() {
@Override
int incr;
mNotifyManager.notify(0, mBuilder.build());
try {
Thread.sleep(5*1000);
} catch (InterruptedException e) {
// Hy progress bar
mNotifyManager.notify(ID, mBuilder.build());
mBuilder.setContentText(Download complete)
}
.setProgress(0,0,false);
101
Lp trnh Android c bn
mNotifyManager.notify(0, mBuilder.build());
mNotifyManager.notify(0, mBuilder.build());
102
Lp trnh Android c bn
103
Lp trnh Android c bn
Phng php c bn
Di y l kin thc tng quan mc nng cao v nhng iu bn cn bit bt
u to thnh phn View ca ring mnh:
1. M rng mt lpViewhin c hoc lp con cha lp ca bn.
2. Ghi mt s phng thc t lp cha. Cc phng thc ca lp cha b ghi s
bt u vi on, v d nh onDraw(), onMeasure() v onKeyDown(). Thao
104
Lp trnh Android c bn
tc tng t vi cc s kin on...trong Activityhoc ListActivitym
bn ghi cho ton vng i v cc hm khc.
3. S dng lp m rng mi ca bn. Mt khi hon tt, bn c th s dng lp
m rng mi ny.
Mch nh:Lp m rng c th c nh ngha di dng lp ni b (inner class)
trong activity s dng chng. iu ny thc s hu ch, bi n kim sot cc truy
cp khng cn thit ti lp m rng (c th bn mun to mt View dng public
cho nhng mc ch s dng rng hn trong ng dng ca mnh).
105
Lp trnh Android c bn
Ghi ch:iu ny khng p dng cho ha 3D. Nu mun s dng ha 3D, bn
phi m rngSurfaceView thay v View, ng thi v t mt lung (thread) ring
bit khc. Xem v d v GLSurfaceViewActivity c thm thng tin chi tit.
phn quan trng trong mi lin h gia thnh phn ca bn v i tng cha ca
n.onMeasure()c ghi bo co mt cch hiu qu v chnh xc kt qu o
ca nhng thnh phn m n cha. Vic ny c thc hin phc tp hn mt cht
bi cc yu cu v gii hn t cha (c truyn vo qua phng thconMeasure())
cng nh bi yu cu gi phng thc setMeasuredDimension()vi chiu di
v chiu cao o lng khi chng c tnh ton. Nu bn khng gi c phng
thc ny t mt phng thc onMeasure()ghi , kt qu s l mt ngoi l ti thi
im .
mc cao, thc thionMeasure()s nh sau:
6. Phng thc onMeasure()b ghi s c gi vi nhng thng s o lng v chiu
rng v chiu cao (cc tham s widthMeasureSpecvheightMeasureSpec,
c hai u l m dng s nguyn biu din di). Cc thng s o lng trn
nn c coi l yu cu v gii hn chiu rng v chiu di o lng m bn nn
a ra. Bn c th tm thy ngun tham kho y v cc loi hn ch m nhng
thng s ny c th i hi trong ti liu tham chiu diView.onMeasure(int,
int)(ti liu ny lm rt tt vic gii thch ton b hot ng o lng).
7. Phng thc onMeasure()trong thnh phn ca bn nn tnh ton mt chiu
rng v chiu cao o lng s c yu cu dng thnh phn . Phng
thc ny nn th lm vic vi cc thng s c truyn vo, mc d n c th la
chn b qua chng (trong trng hp ny, i tng cha c th chn vic lm,
bao gm ct (clipping), cun (scrolling), nm ra (throwing) mt ngoi l (exception),
hoc yu cuonMeasure()th li ln na vi nhng thng s o lng khc).
8. Khi
tnh
xong
chiu
rng
chiu
cao,
phng
thc
106
Lp trnh Android c bn
Hng mc
Phng thc
M t
To
Gm c mt dng
phng thc khi
to c gi khi view
c to ra t m
ngun v mt dng
c gi khi view
c to t mt file
layout. Dng th hai
nn phn tch v p
dng bt c thuc
tnh no xc nh
trong file layout.
onFinishInflate()
c gi sau khi
mt view v tt c
con ca n c to
t XML.
onMeasure(int, int)
c gi xc
nh yu cu v
kch thc cho view
ny cng tt c con
ca n.
Layout
(b cc)
thc v v tr cho tt
c con ca n.
Dng hnh
(drawing)
onDraw(Canvas)
c gi khi view
sp dng ni dung
ca n.
107
Lp trnh Android c bn
Hng mc
Phng thc
M t
X l s kin
onKeyDown(int, KeyEvent)
c gi khi mt s
kin bn phm mi
xy ra.
onKeyUp(int, KeyEvent)
c gi khi mt s
kin th phm xy ra.
onTrackballEvent(MotionEvent)
c gi khi mt s
kin chuyn ng bi
ln xy ra.
onTouchEvent(MotionEvent)
c gi khi mt s
kin chuyn ng
trn mn hnh cm
ng xy ra.
Focus
Gn
(attach)
hoc
onWindowFocusChanged(boolean)
c gi khi ca
s cha view c
focus hoc mt focus.
onAttachedToWindow()
c gi khi view
c gn vo mt
ca s.
onDetachedFromWindow()
c gi khi view
c g khi ca
s gn vi n.
onWindowVisibilityChanged(int)
c gi khi trng
thi hin th (visibility)
ca ca s cha view
thay i.
V d v View ty chnh
V d mu CustomView trongti liu API Demos (Cc bn demo API)cung cp v d
v mt View c ty chnh. View ty chnh c nh ngha trong lpLabelView.
LabelView minh ha mt s kha cnh khc nhau ca cc thnh phn ty chnh:
108
Lp trnh Android c bn
Phng thc onDraw() ghi v nn nhn trn khung canvas c cung cp.
Cc iu khin hn hp
Nu khng mun to mt thnh phn ty chnh hon ton, bn hy tm cch t mt
thnh phn c th ti s dng cha nhm iu khin tn ti, sau to mt thnh
phn hn hp (Compound Component), hay cn gi l iu khin hn hp (Compound
Control) tha mn yu cu bn a ra. Ni ngn gn, iu ny nhm mt lot iu
khin (hoc view) n nguyn hn thnh mt nhm mc c lin quan lgc vi nhau v
nhm ny c th c coi l mt phn t n l. V d, mt Combo Box c th c
coi nh mt s kt hp ca trng EditText mt dng v mt button iu chnh vi mt
PopupList gn vo. Nu bn nhn button v chn th g t danh sch, n s in
vo trng EditText. Bn cnh , nu mun, ngi dng cng c th g trc tip ci
g vo bn trong trng EditText.
Trong Android, thc ra c hai View khc sn sng lm vic ny: Spinner v
AutoCompleteTextView, nhng d sao th khi nim v Combo Box cng l mt
v d d hiu.
to mt thnh phn hn hp:
1. Xut pht im thng l mt loi layout no ; v vy, hy to mt lp m rng
layout. Trong v d ny v Combo box, chng ta s s dng LinearLayout (layout
tuyn tnh) vi hng thit b xoay theo chiu ngang. Cn nh rng, cc layout
khc c th c lng bn trong, nn thnh phn hn hp c th c cu trc v
mc phc tp ty . Lu , tng t mt Activity, bn c th s dng phng
php khai bo (da trn XML) to cc thnh phn cha trong , hoc bn cng
c th lng chng bng cch lp trnh t m ngun.
2. Trong phng thc khi to ca lp mi, hy cung cp bt c tham s no lp cha
mun, ri truyn chng qua phng thc khi to ca lp cha trc tin. Sau ,
bn c th thit lp cc view khc s dng trong thnh phn mi ca mnh; y
l ni bn s to trng EditText v PopupList. Lu , bn cng c th a cc
thuc tnh v tham s ca mnh vo trong XML, v XML c th c phng thc
khi to ca bn ly ra v s dng.
3. Bn cng c th to nhng trnh lng nghe s kin m cc view cha trong c
th to ra, v d nh mt phng thc lng nghe cho trnh lng nghe s kin click
109
Lp trnh Android c bn
vo mt mc trong danh sch (List Item Click Listener) cp nht ni dung ca
EditText nu ngi dng chn mt mc trong danh sch .
4. Bn cng c th t to thuc tnh cng vi cc phng thc truy cp v chnh sa
chng, v d nh cho php gi tr EditText c khi to trong thnh phn, cng
nh truy vn ni dung ca n khi cn.
5. Trong trng hp m rng mt layout, bn khng cn ghi ln cc phng thc
onDraw() v onMeasure(), v layout s c hnh vi mc nh c kh nng lm
tt vic ny. Tuy nhin, nu cn, bn vn c th ghi chng.
6. Bn c th ghi nhng phng thc on... khc, v d nh onKeyDown(),
chn nhng gi tr mc nh t danh sch popup ca mt combo box khi mt phm
no c nhn.
Tm li, vic s dng mt layout lm c s cho mt iu khin ty chnh em li rt
nhiu li ch, bao gm:
Cc v d v iu khin hn hp
Trong d n API Demos i km SDK, c hai v d v danh sch - V d 4 (Example
4) v V d 6 (Example 6) bn di Views/Lists biu din mt SpeechView m rng
LinearLayout to mt thnh phn hin th cc trch dn pht biu. Cc lp tng ng
trong m mu l List4.java v List6.java.
110
Lp trnh Android c bn
Nu bn cha hon thnh n, hy nhp m ngun mu ca NotePad vo Eclipse (hoc
xem m ngun trc tip trn lin kt c cung cp). C th l, hy xem nh ngha
ca MyEditText trong file NoteEditor.java ti a ch: http://developer.android.com/
samples/index.html.
y, c mt s im cn lu .
1. nh ngha
Lp c nh ngha vi dng sau:
oo
oo
2. Khi to lp
Nh mi khi, lp cha c gi trc. Hn na, y khng phi phng thc khi
to mc nh m l mt phng thc khi to c tham s ha. EditText c
to vi nhng tham s khi n c to t mt file layout XML; do , phng
thc khi to va phi ly chng v va phi truyn cho phng thc khi to
ca lp cha.
3. Cc phng thc ghi
Trong v d ny, ch c mt phng thc ghi : onDraw() - tuy nhin, c th c
nhiu phng thc khc khi bn to thnh phn ty chnh ca mnh.
i vi v d NotePad, vic ghi ln phng thc onDraw() cho php chng ta
v nhng dng mu xanh ln khung canvas ca view EditText (khung canvas
c truyn ti phng thc onDraw() ghi ). Phng thc cha .onDraw()
c gi trc khi phng thc con kt thc. Phng thc ca lp cha nn c
kch hot, nhng trong trng hp ny, chng ta lm iu bc cui cng sau
khi v cc dng mnh mun bao gm.
4. S dng thnh phn ty chnh
By gi, chng ta c thnh phn ty chnh ca mnh, nhng lm sao c th
s dng n? Trong v d NotePad, thnh phn ty chnh c s dng trc tip
t layout khai bo; vy nn, hy nhn vo note_editor.xml trong th mc
res/layout.
111
Lp trnh Android c bn
<view
class=com.android.notepad.NoteEditor$MyEditText
id=@+id/note
android:layout_width=fill_parent
android:layout_height=fill_parent
android:background=@android:drawable/empty
android:padding=10dip
android:scrollbars=vertical
android:fadingEdge=vertical />
oo
6. X l u vo t bn phm
H thng Android a ra mt bn phm trn mn hnh (on-screen keyboard) - c bit
n nh mt phng tin nhp liu mm (soft input method) - khi mt trng vn bn
trong giao din ngi dng c focus. cung cp tri nghim tt nht cho ngi
dng, bn c th xc nh cc c im v loi u vo mnh mun (chng hn nh
n l s in thoi hay a ch e-mail) v hnh vi ca phng tin nhp liu (chng hn
nh n c thc hin hnh vi t sa li v ng php hay khng).
112
Lp trnh Android c bn
Ngoi cc phng tin nhp liu trn mn hnh, Android cn h tr bn phm cng, nn
iu quan trng l ng dng ca bn phi ti u tri nghim ngi dng tng tc
c th xy ra, cho d l bn phm gn km.
Nhng ch ny c bn lun cc mc di y.
Xc nh kiu bn phm
Bn hy lun khai bo phng tin nhp liu cho trng vn bn ca mnh bng cch
thm thuc tnh android:inputType vo phn t <EditText>.
113
Lp trnh Android c bn
114
Lp trnh Android c bn
Thuc tnh android:inputType cho php bn xc nh nhiu hnh vi cho phng
tin nhp liu. Quan trng nht, nu trng vn bn ca bn c dnh cho u vo
dng vn bn c bn (chng hn nh cho mt tin nhn vn bn), bn nn bt tnh nng
t sa chnh t vi gi tr textAutoCorrect.
Bn c th kt hp cc hnh vi v kiu phng tin nhp liu khc nhau vi thuc tnh
android:inputType. V d, y l cch to mt trng vn bn c chc nng
vit hoa t u tin ca mt cu v t sa li chnh t:
<EditText
android:id=@+id/message
android:layout_width=wrap_content
android:layout_height=wrap_content
android:inputType=
textCapSentences|textAutoCorrect
.../>
Sau , bn c th lng nghe phm c nhn trn button action bng cch xc nh
mt TextView.OnEditorActionListener cho phn t EditText. Trong trnh
115
Lp trnh Android c bn
lng nghe, hy phn hi ID ca action IME (input method editor - trnh chnh sa
phng tin nhp liu) ph hp xc nh trong lp EditorInfo, chng hn nh
IME_ACTION_SEND. V d:
EditText editText = (EditText) findViewById(R.id.search);
editText.setOnEditorActionListener(new OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
boolean handled = false;
if (actionId == EditorInfo.IME_ACTION_SEND) {
sendMessage();
handled = true;
}
return handled;
}
});
116
Lp trnh Android c bn
<application ... >
<activity
android:windowSoftInputMode=stateVisible ... >
...
</activity>
...
</application>
Ghi ch: Nu thit b ca ngi dng c bn phm cng i km, phng tin nhp
liu mm s khng xut hin.
Ghi ch: Mt khi phng tin nhp liu hin th, bn khng nn n n bng cch
lp trnh m ngun na. H thng n phng tin nhp liu khi ngi dung hon
thnh tc v trong trng vn bn, hoc ngi dng c th n n vi mt iu khin
ca h thng (chng hn nh vi button Back).
117
Lp trnh Android c bn
V d, nhm m bo h thng thay i kch thc layout cho phn khng gian hin
ti - iu ny m bo rng mi ni dung ca layout u c th c truy cp - s dng
adjustResize:
<application ... >
<activity
android:windowSoftInputMode=adjustResize ... >
...
</activity>
...
</application>
118
Lp trnh Android c bn
Kim th ng dng
Ngi dng c th duyt ng dng ca bn bng bn phm, bi v h thng Android
bt hu ht cc hnh vi cn thit theo mc nh.
Tt c cc widget tng tc cung cp bi framework Android (chng hn nh Button
v EditText) u c th nhn focus. iu ny c ngha rng, ngi dng c th iu
hng vi cc thit b iu khin nh D-pad hoc bn phm v mi widget s sng ln
hoc ngc li, thay i giao din ca n khi n c focus vo.
kim th ng dng ca bn, hy:
1. Ci t ng dng trn mt thit b c sn bn phm phn cng.
Nu thit b phn cng ca bn khng c bn phm, hy kt ni bn phm Bluetooth
hoc mt bn phm USB (mc d khng phi mi thit b u h tr ph kin USB).
Bn cng c th s dng trnh gi lp (emulator) Android:
1. Trong AVD Manager, nhn vo New Device (thit b mi) hoc chn mt profile
c sn v nhn Clone (to bn sao).
2. Trong ca s hin ra, hy m bo rng Keyboard v DPad c bt.
2. kim th ng dng, hy ch dng phm Tab iu hng trn giao din ngi
dng, m bo rng mi iu khin trong u nhn c focus khi cn.
Tm xem c thc th no c focus khng nh bn mun khng.
3. Bt u t khi ng dng khi ng v thay vo , hy dng cc phm iu hng
(phm mi tn trn bn phm) duyt ng dng.
T mi phn t c th c focus trong giao din ngi dng, nhn Up (ln),
Down (xung), Left (tri), Right (phi).
Tm xem c thc th no c focus khng nh bn mun khng.
Nu bn gp bt c thc th no m ti khi bn ang iu hng vi phm Tab hoc
iu khin iu hng khng nh mun, hy xc nh v tr nn c focus trong
layout. iu ny s c bn lun mc sau.
119
Lp trnh Android c bn
<RelativeLayout ...>
<Button
android:id=@+id/button1
android:layout_alignParentTop=true
android:layout_alignParentRight=true
android:nextFocusForward=@+id/editText1
... />
<Button
android:id=@+id/button2
android:layout_below=@id/button1
android:nextFocusForward=@+id/button1
... />
<EditText
android:id=@id/editText1
android:layout_alignBottom=@+id/button2
android:layout_toLeftOf=@id/button2
android:nextFocusForward=@+id/button2
... />
...
</RelativeLayout>
android:nextFocusUp.
android:nextFocusDown.
android:nextFocusLeft.
android:nextFocusRight.
Mi thuc tnh ch nh view k tip nhn focus khi ngi dung thc hin iu hng
theo hng bng cch s dng ID ca view. V d:
120
Lp trnh Android c bn
<Button
android:id=@+id/button1
android:nextFocusRight=@+id/button2
android:nextFocusDown=@+id/editText1
... />
<Button
android:id=@id/button2
android:nextFocusLeft=@id/button1
android:nextFocusDown=@id/editText1
... />
<EditText
android:id=@id/editText1
android:nextFocusUp=@id/button1
... />
X l cc s kin phm n
x l mt phm n c nhn, hy thc thi onKeyDown() hoc onKeyUp() nu
thch hp. Thng th bn nn s dng onKeyUp() nu mun m bo ch nhn mt
s kin. Nu ngi dung nhn v gi button, onKeyDown() s c gi nhiu ln.
V d, phng thc sau s phn hi mt s phm iu khin mt tr chi:
@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
switch (keyCode) {
case KeyEvent.KEYCODE_D:
moveShip(MOVE_LEFT);
return true;
case KeyEvent.KEYCODE_F:
121
Lp trnh Android c bn
moveShip(MOVE_RIGHT);
return true;
case KeyEvent.KEYCODE_J:
fireMachineGun();
return true;
case KeyEvent.KEYCODE_K:
fireMissile();
return true;
default:
return super.onKeyUp(keyCode, event);
}
}
X l cc phm b tr
phn hi cc s kin t phm b tr (modifier key), chng hn nh khi mt phm
c kt hp vi Shift hay Ctrl (Control), bn c th truy vn (query) KeyEvent c
truyn ti phng thc callback. Mt vi phng thc cung cp thng tin v phm b
tr, chng hn nh getModifiers() v getMetaState(). Tuy nhin, gii php n
gin nht l kim tra xem liu c ng phm b tr m bn ang quan tm c nhn
hay khng vi cc phng thc nh isShiftPressed() v isCtrlPressed().
V d, sau y l bi tp thc thi onKeyDown() cng vi mt s x l b sung khi phm
Shift c nhn cng vi mt trong s cc phm:
@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
switch (keyCode) {
...
case KeyEvent.KEYCODE_J:
if (event.isShiftPressed()) {
fireLaser();
} else {
fireMachineGun();
}
return true;
case KeyEvent.KEYCODE_K:
if (event.isShiftPressed()) {
fireSeekingMissle();
} else {
fireMissile();
}
return true;
default:
122
Lp trnh Android c bn
}
}
7. Widget ca ng dng
Widget ca ng dng l cc view loi nh trong ng dng , c th c nhng vo
nhng ng dng khc (chng hn nh mn hnh Home) v nhn cp nht theo chu k.
Nhng view ny c gi l cc Widget trong giao din ngi dng, bn c th pht
hnh chng vi mt Widget provider (Widget provider). Thnh phn ng dng c th
cha cc Widget khc c gi l Widget ch cho Widget ca ng dng (App Widget
host). nh chp mn hnh bn di biu din Widget ca ng dng Music.
Kin thc c bn
to Widget cho ng dng, bn cn c:
i tng AppWidgetProviderInfo
M t siu d liu (metadata) cho mt Widget, chng hn nh layout ca Widget,
tn sut cp nht v lp AppWidgetProvider. C th xc nh iu ny trong XML.
123
Lp trnh Android c bn
cho php ngi chnh sa cc thit lp trong Widget ca ng dng vo thi im
khi to.
Mc di y m t cch thit lp mi thnh phn .
124
Lp trnh Android c bn
V d:
<appwidget-provider xmlns:android=http://schemas.android.com/apk/
res/android
android:minWidth=40dp
android:minHeight=40dp
android:updatePeriodMillis=86400000
android:previewImage=@drawable/preview
android:initialLayout=@layout/example_appwidget
android:configure=com.example.android.ExampleAppWidgetConfigure
android:resizeMode=horizontal|vertical
android:widgetCategory=home_screen|keyguard
android:initialKeyguardLayout=@layout/example_keyguard>
</appwidget-provider>
Xem mc App Widget Design Guidelines (Hng dn thit k Widget cho ng dng)
bit thm thng tin v vic thay i kch thc ca Widget trong ng dng.
Ghi ch: gip cho Widget trong ng dng ca bn c th dng vi nhiu loi thit
b, kch thc ti thiu ca n khng nn ln hn 4 x 4 .
Xem phn Hng dn thit k Widget cho ng dng (App Widget Design Guidelines)
bit thm thng tin v vic thay i kch thc Widget trong ng dng.
Thuc tnh updatePeriodMillis xc nh tn sut framework Widget trong ng
dng nn yu cu mt cp nht (update) t AppWidgetProvider bng cch gi
phng thc callback onUpdate(). Cp nht thc s khng m bo xy ra chnh
xc ti thi im c gi tr ny; do , chng ti khuyn bn nn cp nht t thng
xuyn nht nu c th - c th l khng qu mt gi mi ln tit kim pin. Bn cng
c th cho php ngi dung iu chnh tn sut bng cch cu hnh - mt s ngi
mun b m thi gian cho c phiu (stock ticker) phi cp nht 15 pht mt ln, hoc
c th ch l bn ln mi ngy.
125
Lp trnh Android c bn
Ghi ch: Nu thit b ang ch ng khi n thi im cp nht (c xc
nh bi updatePeriodMillis), thit b s thc dy thc hin cp nht. Nu
bn cp nht khng qu mt ln mi gi, iu ny s khng gy vn ng k i
vi thi lng pin. Tuy nhin, nu cn cp nht vi tn sut cao hn v/hoc khng
cn cp nht khi thit b ch ng, bn c th thc hin cp nht da trn bo
thc (alarm), n s khng nh thc thit b. lm vic ny, hy t bo thc vi
mt Intent m AppWidgetProvider s nhn, bng cch s dng AlarmManager.
Thit lp loi bo thc thnh ELAPSED_REALTIME hoc RTC, tc l n s ch gi
bo thc khi thit b ang ch thc. Sau , thit lp updatePeriodMillis
thnh 0.
Thuc tnh configure xc nh Activity chy khi ngi dung thm Widget
ng dng, nhm gip h cu hnh cc thuc tnh ca Widget. Vic ny l ty chn
(c mc To activity cu hnh cho Widget trong ng dng bn di).
126
Lp trnh Android c bn
FrameLayout.
LinearLayout.
RelativeLayout.
GridLayout.
v cc lp Widget di y:
AnalogClock.
Button.
Chronometer.
ImageButton.
ImageView.
ProgressBar.
TextView.
ViewFlipper.
ListView.
127
Lp trnh Android c bn
GridView.
StackView.
AdapterViewFlipper.
128
Lp trnh Android c bn
res/values-v14/dimens.xml:
<dimen name=widget_margin>0dp</dimen>
S dng lp AppWidgetProvider
Lp AppWidgetProvider m rng BroadcastReceiver di dng mt lp thch hp
x l cc broadcast ca Widget trong ng dng. AppWidgetProvider ch nhn cc s
kin broadcast c lin quan ti Widget trong ng dng, chng hn nh khi Widget c
cp nht, b xa, c bt v b v hiu ha. Khi nhng s kin broadcast ny xy ra,
AppWidgetProvider nhn cc li gi phng thc sau:
Bn phi khai bo thc thi lp AppWidgetProvider di dng mt broadcast receiver
s dng phn t <receiver> trong AndroidManifest (xem mc Khai bo Widget ca
ng dng trong file k khai bn trn).
onUpdate()
129
Lp trnh Android c bn
Callback ny c gii thiu trong API Cp 16 (Android 4.1). Nu bn thc thi callback
ny, hy chc chn rng ng dng ca bn khng ph thuc vo n, bi callback s
khng c gi trn nhng thit b c hn.
onDeleted(Context, int[])
c gi mi khi mt Widget trong ng dng b xa t host Widget ca ng dng.
onEnabled(Context)
c gi khi mt th hin Widget trong ng dng c to ln u tin.
V d, nu ngi dung thm hai th hin ca Widget trong ng dng,
onEnabled(Context) ch c gi vo ln u tin. Nu bn cn m mt c
s d liu mi hoc thc hin ci t khc ch cn xy ra mt ln trn tt c cc
th hin Widget ca ng dng, y l ni thch hp lm iu ny.
onDisabled(Context)
c gi khi th hin cui cng ca Widget ng dng b xa t host Widget ng
dng. y l ni bn nn dn dp bt c cng vic no hon thnh trong
onEnabled(Context), chng hn nh xa mt c s d liu tm thi.
onReceive(Context, Intent)
c gi cho mi broadcast v trc mi phng thc callback bn trn.
Thng thng, bn khng phi thc thi phng thc ny bi khi thc thi,
AppWidgetProvider s mc nh lc tt c cc broadcast Widget trong ng dng
v gi nhng phng thc trn nu ph hp.
AppWidgetProvider quan trng nht l onUpdate(), v callback ny c gi khi
mi Widget trong ng dng c thm vo mt host (tr phi bn s dng mt activity
cu hnh). Nu Widget trong ng dng ca bn chp nhn bt c s kin tng tc
vi ngi dng no, bn phi ng k cc trnh x l s kin trong callback ny. Nu
Widget trong ng dng khng to cc file hoc c s d liu tm thi hoc thc hin
cng vic khc i hi phi dn dp (clean-up), onUpdate() c th l phng thc
callback duy nht bn cn xc nh. V d, nu mun mt Widget trong ng dng vi
mt button khi ng activity khi nhn vo, bn c th s dng thc thi di y ca
AppWidgetProvider:
public class ExampleAppWidgetProvider extends AppWidgetProvider {
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds) {
130
Lp trnh Android c bn
PendingIntent pendingIntent =
views.setOnClickPendingIntent(R.id.button, pendingIntent);
appWidgetManager.updateAppWidget(appWidgetId, views);
}
}
131
Lp trnh Android c bn
ACTION_APPWIDGET_UPDATE.
ACTION_APPWIDGET_DELETED.
ACTION_APPWIDGET_ENABLED.
ACTION_APPWIDGET_DISABLED.
ACTION_APPWIDGET_OPTIONS_CHANGED.
132
Lp trnh Android c bn
133
Lp trnh Android c bn
Intent resultValue = new Intent();
resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId);
setResult(RESULT_OK, resultValue);
finish();
xmlns:android=http://schemas.android.com/apk/res/android
...
android:previewImage=@drawable/preview>
</appwidget-provider>
134
Lp trnh Android c bn
<appwidget-provider
xmlns:android=http://schemas.android.com/apk/res/android
...
android:widgetCategory=keyguard|home_screen>
</appwidget-provider>
135
Lp trnh Android c bn
Chiu rng ca mt Widget cho mn hnh kha lun lp y khng gian c cp. i
vi chiu cao ca mt Widget cho mn hnh kha, bn c cc ty chn sau:
oo
136
Lp trnh Android c bn
thay th bi RemoteViewsFactory, y n gin l i tng bao mt lp
mng quanh giao din Adapter. Khi yu cu mt mc c th trong collection,
RemoteViewsFactory to v tr v mc cho collection di dng mt i tng
RemoteViews. bao gm mt collection view trong Widget ng dng ca mnh,
bn phi thc thi RemoteViewsService v RemoteViewsFactory.
RemoteViewsService l mt service cho php mt adapter t xa yu cu cc i
tng RemoteViews. RemoteViewsFactory l mt giao din cho adapter
gia mt collection view (chng hn nh ListView, GridView,) v d liu
bn di view . T mu Widget StackView, sau y l mt v d v on m mu
c sn m bn dng thc thi service v giao din ny:
public class StackWidgetService extends RemoteViewsService {
@Override
public RemoteViewsFactory onGetViewFactory(Intent intent)
{
return new
StackRemoteViewsFactory(this.getApplicationContext(), intent);
}
}
ng dng mu
M ngun trch on trong mc ny c ly t ng dng mu Widget StackView:
137
Lp trnh Android c bn
Nu ngi dng chm vo view trn cng, Widget ca ng dng s hin th thng
ip Toast Touched view n ( chm view n), trong n l ch s (v tr) ca
view c chm. tham kho thm phn tho lun v cch thc thi iu ny,
xem mc Thm hnh vi cho cc mc ring.
android:permission=android.permission.BIND_REMOTEVIEWS />
android:layout_height=match_parent>
<StackView xmlns:android=http://schemas.android.com/apk/res/android
android:id=@+id/stack_view
138
Lp trnh Android c bn
android:layout_width=match_parent
android:layout_height=match_parent
android:gravity=center
android:loopViews=true />
<TextView xmlns:android=http://schemas.android.com/apk/res/android
android:id=@+id/empty_view
android:layout_width=match_parent
android:layout_height=match_parent
android:gravity=center
android:background=@drawable/widget_item_background
android:textColor=#ffffff
android:textStyle=bold
android:text=@string/empty_view_text
android:textSize=20sp />
</FrameLayout>
139
Lp trnh Android c bn
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds) {
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID,
appWidgetIds[i]);
intent.setData(Uri.parse(intent.toUri
(Intent.URI_INTENT_SCHEME)));
rv.setEmptyView(R.id.stack_view, R.id.empty_view);
//
appWidgetManager.updateAppWidget(appWidgetIds[i], rv);
//
}
Lp RemoteViewsService
D liu lu tr lu di
V lu di, bn khng th trng cy vo mt th hin ca service hoc bt c d
liu no m th hin ny cha. V vy, bn ng nn cha bt k d liu no trong
RemoteViewsService (tr phi n dng tnh). Nu bn mun d liu trong Widget
ca ng dng c lu tr lu di, cch tt nht l dng mt ContentProvider m
d liu ca n c lu tr trong ton b vng i ca tin trnh.
140
Lp trnh Android c bn
Nh m t trn, lp con RemoteViewsService cung cp RemoteViewsFactory
c dng to collection view t xa.
C th, bn cn thc hin nhng bc sau:
To lp con RemoteViewsService. RemoteViewsService l service m qua ,
mt adapter t xa c th yu cu RemoteViews.
Trong lp con RemoteViewsService ca bn, hy bao gm mt lp c th thc
thi giao din RemoteViewsFactory. RemoteViewsFactory l mt giao din cho
adapter gia mt collection view t xa (chng hn nh ListView, GridView,)
v d liu bn di view . Vic thc thi ca bn c trch nhim phi to ra mt i
tng RemoteViews cho tng mc trong tp d liu. Giao din ny l mt lp mng
bao bn ngoi Adapter.
Ni dung chnh ca vic thc thi RemoteViewsService l RemoteViewsFactory
ca n, nh m t di y.
mContext = context;
mAppWidgetId =
intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID,
141
Lp trnh Android c bn
AppWidgetManager.INVALID_APPWIDGET_ID);
// nn c truyn ti onDataSetChanged()
// li gi ny s tr v trong mt ANR.
for (int i = 0; i < mCount; i++) {
...
}
...
rv.setTextViewText(R.id.widget_item, mWidgetItems.get(position).text);
RemoteViews rv = new RemoteViews(mContext.getPackageName(),
R.layout.widget_item);
...
}
142
Lp trnh Android c bn
setOnClickFillInIntent(). iu ny s thit lp mt Intent mu cho Intent
trng thi ch (pending Intent) cho collection view ca bn, sau thit lp mt Intent
trn mi mc trong collection thng qua RemoteViewsFactory.
Mc ny s dng ng dng mu Widget StackView m t cch thm hnh vi cho
tng mc n l. Trong mu Widget StackView, nu ngi dung chm vo view trn
cng, Widget ca ng dng s hin th thng ip Toast nh sau Touched view n,
trong n l ch s (v tr) ca view c chm . y l cch n lm vic:
...
//
//
//
//
@Override
if (intent.getAction().equals(TOAST_ACTION)) {
143
Lp trnh Android c bn
int appWidgetId =
intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID,
AppWidgetManager.INVALID_APPWIDGET_ID);
super.onReceive(context, intent);
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds) {
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID,
appWidgetIds[i]);
// View trng c hin th khi collection khng c mc no
// N nn l anh em ca collection view.
intent.setData(Uri.parse(intent.toUri
(Intent.URI_INTENT_SCHEME)));
rv.setEmptyView(R.id.stack_view, R.id.empty_view);
// Phn ny cho php cc mc c hnh vi c lp. N lm vic
// ny bng cch thit lp mt mu Intent trng thi ch.
// Cc mc c lp ca mt collection khng th t thit
// lp cc Intent trng thi ch ca chng. Thay vo ,
// collection s thit lp mt mu Intent trng thi ch,
// v cc mu c lp s thit lp mt fillInIntent to
// hnh vi duy nht trn c s tng mc mt.
Intent toastIntent = new Intent(context, StackWidgetProvider.class);
// Thit lp action cho Intent. Khi ngi dung chm vo
// mt view c th, n s c hiu ng ca
// TOAST_ACTION broadcast.
144
toastIntent.setAction(StackWidgetProvider.TOAST_ACTION);
Lp trnh Android c bn
toastIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID,
appWidgetIds[i]);
intent.setData(Uri.parse(intent.toUri
(Intent.URI_INTENT_SCHEME)));
PendingIntent toastPendingIntent =
PendingIntent.getBroadcast(context, 0, toastIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
rv.setPendingIntentTemplate
(R.id.stack_view, toastPendingIntent);
appWidgetManager.updatesAppWidget(appWidgetIds[i], rv);
}
}
mContext = context;
// Khi to tp d liu.
mAppWidgetId =
intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID,
}
AppWidgetManager.INVALID_APPWIDGET_ID);
145
Lp trnh Android c bn
//
//
//
//
//
...
}
...
extras.putInt(StackWidgetProvider.EXTRA_ITEM, position);
fillInIntent.putExtras(extras);
rv.setOnClickFillInIntent(R.id.widget_item, fillInIntent);
...
}
...
}
146
// Tr v i tng RemoteViews.
return rv;
Lp trnh Android c bn
Mt tnh nng ca nhng Widget ng dng dng cc collection l cung cp cho ngi
dng ni dung mi nht. V d, hy xem xt Widget ng dng ca Gmail trong Android
3.0, cung cp cho ngi dng mt nh chp nhanh ca hp th n. lm iu ny,
bn cn kch hot RemoteViewsFactory v collection view ly v cng nh
hin th d liu mi. Bn thc hin iu ny vi AppWidgetManager bng cch
gi notifyAppWidgetViewDataChanged(). Li gi ny tr v kt qu trong mt
callback ti phng thc onDataSetChanged()ca RemoteViewsFactory, cho
php bn ly bt k d liu mi no. Lu , bn c th thc hin cc hot ng
x l phc tp (processing-intensive operation) mt cch ng b trong callback
onDataSetChanged(). Bn c bo m rng li gi ny s hon tt trc
147
Lp trnh Android c bn
khi siu d liu hoc d liu ca view c ly t RemoteViewsFactory. Ngoi
ra, bn c th thc hin nhng hot ng c x l c bit trong phng thc
getViewAt(). Nu li gi ny tn nhiu thi gian, view ang np (xc nh bi
phng thc getLoadingView()ca RemoteViewsFactory) s c hin th ti
v tr tng ng ca collection view cho ti khi n tr v.
8. Activity
Activity l thnh phn ca ng dng cung cp mt mn hnh cho ngi dng c th
To activity
to mt activity, bn phi to mt lp con mi (hoc mt lp con tn ti) ca
Activity . Trong lp con ca mnh, bn cn thc thi nhng phng thc callback do
h thng gi trong khi chuyn i gia cc trng thi ca vng i activity , chng
hn nh khi activity c to, b dng, phc hi hoc b ph hy. Hai phng thc
callback quan trng nht l:
148
Lp trnh Android c bn
onCreate()
Bn phi thc thi phng thc ny. H thng gi n khi to activity. Trong lc thc
thi, bn nn khi to nhng thnh phn cn thit ca activity. Quan trng nht, y
chnh l ni bn phi gi setContentView() xc nh layout cho giao din
ngi dng ca activity.
onPause()
H thng gi phng thc ny di dng du hiu u tin cho thy ngi dng
ang ri khi activity ca bn (d khng phi lc no n cng truyn ti ngha l
hot ng b hy). y thng l ni bn nn xc nhn (commit) bt c thay i
no l ra nn c lu tr lu di ngoi phin hin ti ca ngi dung (bi ngi
dng c th s khng tr li).
Bn nn s dng vi phng thc callback khc cung cp mt tri nghim ngi
dng a dng gia cc activity, ng thi x l cc ln ngt (interuption) bt thng
khin activity b dng li, thm ch b hy b. Tt c cc phng thc callback trn
ton vng i ca activity u c tho lun mc Qun l vng i ca activity
bn di.
149
Lp trnh Android c bn
din ngi dng.
...
...
</manifest >
S dng b lc intent
Mt phn t <activity> cng c th xc nh nhiu b lc intent - bng cch dng
phn t <intent-filter> - khai bo cch m cc thnh phn ca ng dng khc
c th kch hot n.
Khi bn to mt ng dng mi s dng cc cng c SDK ca Android, activity gc c
to t ng bao gm mt b lc intent khai bo activity tng ng vi action chnh v
nn t hng mc l launcher (mn hnh chnh). B lc intent trng nh sau:
<activity android:name=.ExampleActivity android:icon=@drawable/app_icon>
<intent-filter>
</intent-filter>
</activity>
150
Lp trnh Android c bn
ca h thng ( cho php ngi dng kch hot activity ny).
Nu d nh cho ng dng ca mnh c th t kim sot v khng cho php cc ng
dng khc kch hot activity ca n, bn khng cn bt k b lc intent no khc. Ch
duy nht mt activity nn c action main v hng mc launcher, nh v d trc.
Nhng activity bn khng mun c mt trong cc ng dng khc th khng nn c b
lc intent v bn c th t khi ng chng bng cch dng cc intent tng minh
(explicit intent), nh tho lun mc di y.
Tuy nhin, nu mun activity ca mnh phn hi cc intent ngm nh (implicit intent)
c gi t nhng ng dng khc (v c ng dng ca bn), bn phi xc nh thm
cc b lc intent cho activity ca mnh. i vi mi loi intent bn mun phn hi ti,
bn phi bao gm mt <intent-filter> cha mt phn t <action>, ng thi c
th ty chn thm mt phn t <category> v/hoc <data>. Nhng phn t ny xc
nh kiu intent m activity ca bn c th phn hi ti.
bit thm thng tin v cch activity ca bn phn hi li intent, tham kho ti liu
Intent v b lc Intent ti a ch:
http://developer.android.com/guide/components/intents-filters.html.
Khi ng activity
Bn c th khi ng mt activity khc bng cch gi startActivity(), truyn cho
n mt Intent m t activity m bn mun khi ng. Intent hoc xc nh chnh xc
activity bn mun khi ng, hoc m t kiu action bn mun thc hin (v h thng
s chn activity ph hp cho bn, activity c th ti t ng dng khc). Mi intent
cng c th cha mt lng nh d liu c activity s dng khi n khi ng.
Khi lm vic trong ng dng ca mnh, bn s phi thng xuyn kch hot mt activity
bit. Bn c th lm vy bng cch to mt intent xc nh r rng activity mnh
mun khi ng qua vic s dng tn lp. V d, y l cch mt activity khi ng
activity khc c tn SignInActivity:
Intent intent = new Intent(this, SignInActivity.class);
startActivity(intent);
151
Lp trnh Android c bn
Phn ph EXTRA_EMAIL c thm vo intent l mt mng cc chui a ch e-mail
m mail ny s c gi ti. Khi mt ng dng e-mail phn hi intent ny, n c mng
chui cung cp trong phn ph trn v t chng trong trng to (gi n) ca form
son tho e-mail. Trong trng hp ny, activity ca ng dng e-mail khi ng v khi
ngi dung hon tt, activity s phc hi.
Khi ng activity tr v kt qu
i khi, bn mun nhn mt kt qu t activity m mnh khi ng. Trong trng
hp , hy khi ng activity bng cch gi startActivityForResult() (thay
v startActivity()). Sau , nhn kt qu t activity tip theo, hy thc thi
phng thc callback onActivityResult(). Khi activity tip theo hon tt, n tr
v kt qu trong mt Intent ti phng thc onActivityResult().
V d, c th bn mun ngi dung chn mt trong cc thng tin lin lc ca mnh; t
, activity ca bn c th lm vic g vi thng tin y. y l cch bn c th to
intent nh vy v x l kt qu:
private void pickContact() {
}
@Override
// Lm g vi tn danh b chn...
}
}
152
Lp trnh Android c bn
requestCode khp vi tham s th hai gi bi startActivityForResult().
T y, m ngun x l kt qu activity bng cch truy vn d liu tr v trong mt
Intent (tham s data).
Tt activity
Bn c th tt mt activity bng cch gi phng thc finish() ca activity
ny. Bn cng c th tt mt activity ring khi ng trc bng cch gi
finishActivity().
Ghi ch: Trong hu ht trng hp, bn khng nn tt mt activity mt cch tng
minh bng cch s dng cc phng thc trn. Nh ni dung tho lun mc sau
v vng i ca activity, h thng Android qun l vng i ca mt activity cho bn,
do bn khng cn tt cc activity. Vic gi cc phng thc trn c th nh hng
khng tt n tri nghim ngi dung d kin v ch nn c s dng khi bn hon
ton khng mun ngi dng quay v th hin ny ca activity.
153
Lp trnh Android c bn
c gn vi trnh qun l ca s). Tuy nhin, activity b dng khng cn hin th
i vi ngi dng v c th b h thng hy khi b nh cn cho vic khc.
Nu mt activity b tm dng hoc dng, h thng c th loi b activity ny khi b
nh bng cch yu cu activity kt thc (gi phng thc finish() ca activity), hoc
n gin l hy tin trnh ca n. Khi activity c m li (sau khi b kt thc hoc hy),
n phi c to t u.
@Override
super.onStop();
@Override
154
super.onDestroy();
// Activity sp b hy b.
Lp trnh Android c bn
}
}
Ghi ch: Thc thi ca cc phng thc vng i ny phi lun gi phng thc ca
lp cha trc khi lm bt c vic g, nh nu trong v d trn.
Cc phng thc cng nhau xc nh ton b vng i ca mt activity. Bng vic
thc thi nhng phng thc ny, bn c th theo di ba vng lp lng nhau trong vng
i activity:
155
Lp trnh Android c bn
Activity c
khi ng
onCreate()
onStart()
Ngi dng
duyt ti activity
onResume()
Tin trnh ca ng
dng b hy
Activity
ang chy
Activity khc
chuyn v chy
tin cnh
Cc ng dng c
u tin cao hn cn
ti b nh
onRestart()
Ngi dng
quay v activity
onPause()
Activity khng
cn hin th na
Ngi dng
duyt ti activity
onSop()
Activity ang hon
thnh hoc b h
thng hy
onDestroy()
Activity b tt
Hnh 1. Vng i activity.
Cc phng thc callback ca vng i activity ging nhau c lit k Bng 1, m
156
Lp trnh Android c bn
t chi tit hn v tng phng thc callback v xc nh v tr ca chng trong ton b
vng i ca activity, bao gm h thng c th hy activity hay khng sau khi phng
thc callback hon tt.
Bng 1. Tng quan v cc phng thc callback ca vng i activity.
C th
b hy
sau
khng?
Phng thc
M t
onCreate()
Phng
thc c
gi tip
theo
onStart()
onRestart()
onStart()
onStart()
onResume()
hoc
onStop()
onPause()
157
Lp trnh Android c bn
Phng thc
M t
C th
b hy
sau
khng?
Tip theo
onResume()
hoc
onStop()
onStop()
onRestart()
hoc
onDestroy()
onDestroy()
158
khng c g
Lp trnh Android c bn
Ct c nhn "C th b hy sau khng?" cho ta thy h thng c th hy tin trnh
qun l activity vo bt c thi im nosau khi phng thc tr v, m khng cn
thc thi dng m no khc ca activity hay khng. Ba phng thc c nh du
"C" l (onPause(), onStop() v onDestroy()). Do onPause()ng u tin
trong ba phng thc ny, nn sau khi activity c to, onPause()s l phng
thc cui cng bo m c gi trc khi tin trnhc thb hy - nu h thng phi
phc hi b nh trong trng hp khn cp, onStop() v onDestroy() c th
khng c gi. Do , bn nn s dng onPause() ghi d liu quan trng cn
lu tr lu di (chng hn nh cc chnh sa ca ngi dung) thc hin vic lu.
Tuy nhin, bn nn la chn thng tin phi gi li trongonPause(), bi bt c th tc
chn no trong phng thc ny cng ngn chn vic chuyn tip ti activity tip theo
v lm chm tri nghim ngi dung.
Cc phng thc c nh du "Khng" trong ct C th b hy sau khngbo
v tin trnh host activity khi b hy t thi im chng c gi. V vy, mt activity
c th b hy t lconPause()tr v cho ti lc onResume()c gi. N s khng
th b hy ln na cho ti khionPause()c gi v tr v ln na.
Ghi ch: Mt activity khng th b hy theo nh ngha Bng 1 vn c th b h
thng loi b - tuy nhin, iu ny ch xy ra trong cc hon cnh khng cn ti
nguyn no khc. Thi im mt activity c th b hy c tho lun k hn trong ti
liuProcesses and Threads (Tin trnh v lung).
159
Lp trnh Android c bn
Activity
ang chy
Activity khc chuyn v
chy mn hnh chnh
onCreate()
onRestoreInstanceState()
Phc hi trng thi activity
onSaveInstanceState()
Lu trng thi activity
onRestart()
Ngi dng
duyt ti activity
Ngi dng
duyt ti activity
Tin trnh ca ng
dng b hy
Th hin ca
activity cn nguyn
vn; khng cn
phc hi trng thi
Nhng ng
dng c u
tin cao hn
cn ti b nh
Activity
khng hin th
160
Lp trnh Android c bn
gi phng thc setSaveEnabled(). Thng thng, bn khng nn v hiu ha
n, song bn c th lm vy nu mun phc hi trng thi ca giao din ngi dng
activity theo cch khc.
Mc d thc thi mc nh caonSaveInstanceState() lu thng tin hu ch v
giao din ngi dng ca activity, song bn vn phi ghi n lu thm thng tin.
V d, bn c th phi lu cc gi tr thnh vin c thay i trong sut vng i
ca activity (iu ny c th lin quan ti nhng gi tr c phc hi trong giao din
ngi dng; tuy nhin, theo mc nh th cc thnh vin nm gi gi tr u khng
c phc hi).
Do thc thi mc nh caonSaveInstanceState() gip lu trng thi ca giao din
ngi dng, nn nu mun ghi phng thc ny lu thm thng tin th bn nn lun
gi phng thc onSaveInstanceState()ca lp cha trc khi lm bt c vic
g. Tng t, bn cng nn gi phng thc onRestoreInstanceState()ca
lp cha nu bn ghi phng thc ny; v vy, thc thi mc nh c th phc hi cc
trng thi view.
Ghi ch:VonSaveInstanceState()khng bo m c gi, bn ch nn dng
n ghi li nhng s chuyn i trng thi ca activity (trng thi ca giao din ngi
dng) - ng bao gi dng phng thc ny lu tr d liu lu di. Thay vo ,
hy s dng onPause() lm vic ny (chng hn nh d liu nn c lu vo
c s d liu) khi ngi dung ri khi activity.
Mt cch hay kim th tnh nng ca ng dng trong vic phc hi trng thi ca
n l bn ch cn xoay thit b sao cho hng ca mn hnh thay i. Khi hng mn
hnh thay i, h thng s hy v to li activity p dng ti nguyn thay th sn
sng c mt cho cu hnh mn hnh mi. Do vy, iu quan trng l activity ca bn
phc hi hon ton trng thi khi activity c to li, v ngi dng thng xoay mn
hnh khi dng cc ng dng.
X l cc thay i cu hnh
Mt s cu hnh thit b c th thay i trong lc chy (chng hn nh chiu xoay mn
hnh, bn phm c sn, ngn ng). Khi thay i xy ra, Android s to li activity
ang chy (h thng gi onDestroy(), sau lp tc gi onCreate()). Hnh vi
ny c thit k nhm gip ng dng ca bn thch nghi vi cc cu hnh mi bng
cch t ng np li ng dng vi nhng ti nguyn thay th m bn cung cp
(chng hn nh cc layout khc nhau i vi nhng chiu xoay v kch thc mn
hnh khc nhau).
Nu bn thng thit k activity x l vic khi ng li do chiu xoay mn hnh thay
i v phc hi trng thi ca activity nh m t trn, ng dng ca bn s vng hn
trc cc s kin ngoi mong mun trong sut vng i ca activity.
Cch tt nht x l vic khi ng li l lu, sau phc hi trng thi ca activity
bng cch s dng onSaveInstanceState() v onRestoreInstanceState() (hoc
onCreate()), nh tho lun mc trc.
bit thm thng tin v cu hnh thay i xy ra vo thi im chy v cch x l
chng, hy c hng dnHandling Runtime Changes (X l cc thay i khi chy).
161
Lp trnh Android c bn
Phi hp cc activity
Khi mt activity khi ng activity khc, chng u tri qua cc chuyn tip vng i.
Activity u tin tm dng v dng (d n s khng dng nu vn hin th trong hu
cnh), trong khi activity khc c to. Trong trng hp cc activity chia s d liu
lu vo a hoc ni no , iu quan trng l activity th nht khng hon ton b
dng khi activity th hai c to. Thay vo , tin trnh khi ng activity th hai s
xy ra cng lc dng activity th nht.
Th t ca cc phng thc callback trong vng i c xc nh, c bit l khi
hai activity u trong cng tin trnh v mt ci khi ng ci cn li. Di y l th
t ca cc hot ng xy ra khi Activity A khi ng Activity B:
Phng thconPause()ca Activity A c thc thi.
Cc phng thconCreate(),onStart() vonResume()ca Activity B thc thi
theo th t. (Activity B gi c ngi dng focus vo).
Sau , nu Activity A khng cn hin th trn mn hnh, phng thconStop()ca
n s thc thi.
Vic tin on trnh t ca cc callback cho php bn qun l vic chuyn i thng tin
t activity ny sang activity khc. V d, nu phi ghi vo mt c s d liu khi activity
th nht dng li activity sau c th c n, bn nn ghi vo c s d liu trong sut
thi im chyonPause()thay v onStop().
9. Ty chn lu tr
Android cung cp mt s ty chn bn c th lu tr d liu lu di cho ng dng.
Gii php bn chn ph thuc vo tng nhu cu c th, chng hn nh d liu l ca
ring ng dng ny hay cn cho php ng dng (v ngi dng) khc truy cp vo,
dung lng cn dng l bao nhiu.
Bn c th chn mt trong nhng ty chn lu tr d liu sau:
Ty chnh chia s (Shared Preferences)
Lu d liu ring kiu c s di dng cp kha-gi tr.
B nh trong (Internal Storage)
Lu d liu ring trn b nh thit b.
B nh ngoi (External Storage)
Lu d liu cng cng (public data) trn b nh ngoi cng chia s.
C s d liu SQLite (SQLite Databases)
Lu d liu c cu trc (structured data) trong c s d liu ring.
Kt ni mng (Network Connection)
Lu d liu trn Web bng network server ca bn.
162
Lp trnh Android c bn
Android cung cp cho bn mt cch hin th d liu ring cho cc ng dng khc vi mt Content Provider. Content provider l mt thnh phn ty chn, dng cung
cp quyn c/ghi (read/write) i vi d liu ca ng dng, ty thuc vo gii hn
quyn bn mun cp. tm hiu thm v cch s dng content provider, hy tham
kho ti liu Content Providers.
Ty chnh c nhn
Ty chnh chia s khng ch dng lu ty chnh c nhn (user preference), chng
hn nh nhc chung (ringtone) m ngi dng la chn. Nu bn mun to phn ty
chnh c nhn cho ng dng, hy tm hiu thm v PreferenceActivity, lp ny
s cung cp mt framework Activity bn to phn ty chnh c nhn, phn ny s t
ng c lu li (bng cch s dng ty chnh chia s).
to mt i tng SharedPreferences trong ng dng, hy dng mt trong hai
phng thc sau:
lu cc gi tr:
1. Gi edit() ly mt i tng SharedPreferences.Editor.
2. Thm cc gi tr vi nhng phng thc nh putBoolean() v
putString().
3. Gi commit() cp nht cc chnh sa .
c gi tr, s dng phng thc SharedPreferences, chng hn nh
getBoolean() v getString().
Sau y l mt v d v vic lu ty chn cho ch nhn phm im lng trong ng dng
my tnh c nhn (calculator):
163
Lp trnh Android c bn
public class Calc extends Activity{
@Override
super.onCreate(state);
// Lu ty chnh
...
@Override
super.onStop();
}
}
S dng b nh trong
Bn c th trc tip lu file vo b nh trong ca thit b. Mc nh, cc file c lu
vo b nh trong l ca ring ng dng , nn cc ng dng (hay ngi dng) khc
khng th truy cp vo. Khi ngi dng g ng dng, nhng file ny s b xa b.
to v ghi mt file ring vo b nh trong:
1. Gi phng thc openFileOutput() vi tn file v ch hot ng. Kt qu
tr v s l mt FileOutputStream.
2. Ghi vo file vi phng thc write().
3. ng lung d liu bng phng thc close().
164
Lp trnh Android c bn
V d:
String FILENAME =hello_file;
Stringstring=hello world!;
Lu file cache
Nu ch mun lu cache (nh tm) thay v lu lu di mt vi d liu, bn nn dng
phng thc getCacheDir() m mt File i din cho th mc ni b, y
chnh l ni ng dng ca bn tm lu cc file cache.
Khi thiu dung lng b nh trong ca thit b, Android c th xa nhng file cache ny
khi phc khng gian b nh. Tuy nhin, bn khng nn cho h thng t ng
xa cc file ca bn. Hy qun l cc file cache ca mnh v t vo mt khng gian
nh c dung lng hp l, chng hn nh 1MB. Khi ngi dng g ng dng ca bn,
nhng file ny s b xa b.
getDir()
To th mc mi (hoc m th mc c) nm trong b nh trong.
deleteFile()
Xa mt file lu b nh trong.
165
Lp trnh Android c bn
fileList()
Tr v mt mng cc file ang c lu trong ng dng ca bn.
S dng b nh ngoi
Mi thit b tng thch vi Android u h tr mt b nh ngoi (external storage)
cng chia s cho bn lu file. B nh ngoi ny c th l mt thit b lu tr c th tho
ri (removable storage media) (chng hn nh mt th nh SD) hoc mt b nh trong
(khng th tho ri). Ngi dng c th c c v c th chnh sa cc file c
lu vo b nh ngoi khi s dng ch lu tr b nh USB (USB mass storage)
a file vo mt my tnh.
Mt thit b c th dng mt phn vng ca b nh trong lm b nh ngoi c th vn
cung cp mt khe cm th SD (SD card slot). Trong trng hp ny, th SD khng phi
l mt phn ca b nh ngoi v ng dng ca bn khng th truy cp vo (phn
lu tr b sung ny ch dnh cho cc file a phng tin m ngi dng cung cp v
h thng c th qut c).
Lu : B nh ngoi c th mt tc dng nu ngi dng gn (mount) b nh ny vo
mt my tnh hoc tho ri th nh; bi khi , nhng file bn lu vo b nh ngoi
s khng c bo mt. Tt c cc ng dng c th c v ghi file t trong b nh
ngoi v ngi dng c th xa chng.
// Chng ta c th c v ghi th nh
} else if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)){
// Chng ta ch c th c th nh
mExternalStorageWriteable =false;
mExternalStorageAvailable =true;
} else {
166
Lp trnh Android c bn
V d trn nhm kim tra xem b nh ngoi c sn sng c v ghi hay khng.
Phng thc getExternalStorageState() tr v mt s trng thi m bn c
th mun kim tra, chng hn nh th nh c ang b chia s hay khng (ang c
kt ni vi my tnh), ang b li, hoc b tho ri,... Bn c th s dng nhng
thng tin ny thng bo chi tit cho ngi dng bit khi ng dng ca bn cn truy
cp th nh.
167
Lp trnh Android c bn
Nu bn s dng API Cp 7 hoc cp thp hn, hy dng phng thc
getExternalStorageDirectory() m file i din cho th mc gc ca
b nh ngoi, sau lu cc file chia s ny vo mt trong nhng th mc di y:
Download/ - Cc file hn hp ti v.
tion sound).
chp nh).
Lu file cache
Nu bn s dng API Cp 8 hoc cp cao hn, hy dng getExternalCacheDir()
m mt File i din cho th mc b nh ngoi - l ni dng lu cc file cache.
Nu ngi dng g b ng dng ca bn, nhng file ny s t ng b xa. Tuy nhin,
trong sut vng i ca ng dng, bn nn qun l cc file cache ny v loi b nhng
file khng cn thit tit kim khng gian nh.
Nu bn dng API Cp 7 hoc cp thp hn, hy s dng phng thc
getExternalStorageDirectory() m mt File i din cho th mc gc
ca b nh ngoi, sau ghi d liu cache vo th mc di y:
/Android/data/<package_name>/cache/
S dng c s d liu
H iu hnh Android h tr y cho c s d liu SQLite. Bt c c s d liu no
bn to u c th truy cp c theo tn t bt k lp no trong ng dng, nhng
khng th truy cp c t bn ngoi ng dng.
Phng php c khuyn dng to c s d liu SQLite mi l to mt lp con
ca SQLiteOpenHelper v ghi ln phng thc onCreate(), ti y bn c
th thc thi lnh SQLite to bng cho c s d liu. V d:
168
Lp trnh Android c bn
public class DictionaryOpenHelper extends SQLiteOpenHelper {
KEY_DEFINITION + TEXT);;
KEY_WORD + TEXT, +
DictionaryOpenHelper(Context context){
@Override
db.execSQL(DICTIONARY_TABLE_CREATE);
169
Lp trnh Android c bn
G li c s d liu
Android SDK bao gm cng c c s d liu sqlite3 cho php bn tm duyt ni
dung bng, chy lnh SQL v thc hin mt s chc nng hu ch khc trn c s
d liu SQLite. Xem mc Examining sqlite3 databases from a remote shell (Tm
hiu v c s d liu sqlite3 t chng trnh dng lnh xa) hc thm v cch
chy cng c ny.
S dng kt ni mng
Bn c th s dng mng (khi mng sn sng) lu tr v truy xut d liu trn
cc dch v da trn Web ca ring bn. thao tc trn mng, s dng cc lp trong
cc gi sau y:
java.net.*
android.net.*
170
Lp trnh Android c bn
chun, nht qun cho d liu cng nh qu trnh giao tip ca cc tin trnh bn trong
(inter-process) v bo mt vic truy cp d liu.
Mc ny s gii thiu nhng khi nim c bn sau y:
Cc tnh nng API khc khin vic thao tc vi content provider tr nn d dng hn.
Tng quan
Content provider biu din d liu vi cc ng dng bn ngoi di dng mt hoc
mt vi bng tng t vi bng thng thy trong c s d liu quan h (relational
database - RDB). Mi hng i din cho mt th hin ca mt kiu d liu bt k m
content provider thu thp; mi ct trong hng th hin mt phn d liu thu thp c
ca th hin.
V d, mt content provider c sn trong nn tng Android l user dictionary (t in
ngi dng), ni lu tr cch vit ca mt s t c bit m ngi dng mun lu li.
Bng 1 gii thiu cch biu din d liu trong content provider ny.
Bng 1: V d v bng t in ca ngi dng
word
Mapreduce
Precompiler
Applet
Const
Int
app id
user1
user14
user2
user1
user5
frequency
100
200
225
255
100
locale
en_US
fr_FR
fr_CA
pt_BR
en_UK
_ID
1
2
3
4
5
171
Lp trnh Android c bn
172
Lp trnh Android c bn
Bng 2: So snh lnh Query() vi truy vn trong SQL.
i s ca lnh
query()
T kha/tham s ca cu lnh
SELECT
Ghi ch
Uri
FROMten_bang
Projection
cot,cot,cot,...
Selection
WHEREcot=gia_tri
selectionArgs
sortOrder
ORDER BY cot,cot,...
projection l mt mng
cc ct nn c bao gm
trong mi hng kt qu
truy vn.
selection xc nh iu
kin chn hng.
sortOrderxc nh th t
cc hng xut hin trong con
tr (cursor) c tr v.
Content URI
Content URI l nh danh ti nguyn thng nht (uniform resource identifier - URI) xc
nh d liu trong content provider. Content URI bao gm chui nh danh (tn tng
trng cho ton b provider) v mt ng dn (mt tn tr ti mt bng). Khi bn gi
mt phng thc client truy cp vo bng trong content provider, content URI ca
bng chnh l mt trong cc i s.
cc dng m trn, hng CONTENT_URI cha content URI ca bng words trong
t user dictionary. i tng ContentResolver phn tch ly ra chui nh danh
(authority) ca URI, ng thi s dng chui ny phn gii content provider bng
cch so snh chui nh danh vi bng ca h thng cha nhng content provider
khai bo. Sau , ContentResolver c th gi cc i s ca truy vn n ng
provider.
173
Lp trnh Android c bn
Trong , chui user_dictionary l chui nh danh ca provider, cn chui words
l ng dn ca bng. Chui content:// l scheme (thng tin cung cp cho
Content Provider) lun tn ti, xc nh y l mt content URI.
Nhiu content provider cho php bn truy cp vo mt hng n ca mt bng bng
cch gn thm mt gi tr ID vo cui URI. V d, truy xut mt hng c _ID l 4
trong user dictionary, bn c th s dng content URI sau:
Uri singleUri =ContentUris.withAppendedId(UserDictionary.Words.CONTENT_URI,4);
Yu cu quyn truy cp c
truy xut d liu trong mt trnh cung cp, ng dng ca bn cn quyn truy cp
c (read) cho content provider. Bn khng th yu cu quyn ny trong lc chy
chng trnh; thay vo , bn phi ch ra l cn quyn ny trong file k khai bng cch
s dng phn t <uses-permission> v tn chnh xc ca quyn c nh ngha
trong content provider. Khi s dng phn t ny trong file k khai, c ngha l bn ang
yu cu quyn ny cho ng dng ca mnh. Nu ngi dng ci ng dng ca bn,
ngm hiu l h ng vi yu cu ny.
tm ng tn ca quyn truy cp c cho content provider bn dng cng nh
cc tn quyn truy cp khc, hy tm trong ti liu hng dn s dng ca content
provider .
174
Lp trnh Android c bn
Cc vai tr (role) ca quyn truy cp content provider c miu t chi tit trong mc
Quyn i vi content provider bn di.
Content provider user dictionary nh ngha quyn android.permission.READ_
USER_DICTIONARY trong file k khai; do , nu mun c content provider ny, ng
dng phi yu cu vi tn quyn nh vy.
Xy dng truy vn
Bc tip theo trong vic truy xut d liu t mt content provider l xy dng truy
vn. on m nh u tin nh ngha mt s bin dng truy cp content provider
user dictionary:
// Mt mng chui nh ngha cc ct s c tr v cho mi hng (hay
// Projection)
String[] mProjection =
{
UserDictionary.Words._ID, // Hng thuc lp Contract tng
// ng vi tn ct _ID
UserDictionary.Words.WORD, // Hng thuc lp Contract vi tn
// ct word
};
// vi tn ct locale
175
Lp trnh Android c bn
UserDictionary.Words.WORD + = ? v phn t u tin ca mng
i s chn c thit lp bng t m ngi dng nhp vo.
/*
mSearchString = mSearchWord.getText().toString();
// Hy nh chn thm m vo y kim tra u vo khng hp l v
// m c (malicious) lm hng chng trnh.
// Nu t do ngi dng nhp vo l chui rng, ly ra ton b t in
if(TextUtils.isEmpty(mSearchString)){
// Vic thit lp mnh chn l null s tr v ton b t trong
// t in
mSelectionClause = null;
mSelectionArgs[0]= ;
} else {
mSelectionClause =UserDictionary.Words.WORD + = ?;
mSelectionArgs[0]= mSearchString;
}
// Thc hin truy vn trn bng d liu v tr v mt i tng
// Cursor (con tr)
mCursor = getContentResolver().query(
mSortOrder); // Th t sp xp ca cc hng c tr v
176
Lp trnh Android c bn
*/
*/
} else {
Cu lnh SQL ny s dng trc tip tn ct thc th thay v cc hng nh ngha trong
lp contract.
Nu thc hin iu ny, v hnh trung bn ang cho php ngi dng ghp m SQL
c vo cu lnh SQL. V d, ngi dng c th nhp nothing; DROP TABLE *; cho
mUserInput, kt qu c mnh chn var = nothing; DROP TABLE *;. Nu mnh
chn ny c coi nh mt cu lnh SQL, n c th khin content provider xa ton
b bng trong c s d liu do SQLite qun l, tr phi content provider c thit lp
bt cc cu lnh SQL gy hi (SQL injection).
trnh vn ny, s dng mnh chn c dng du ? lm tham s thay th v mt
mng ring bao gm cc i s chn. Khi thc hin iu ny, d liu ngi dng nhp
vo c gn trc tip vi truy vn thay v c bin dch di dng cu lnh SQL.
Do khng c x l di dng cu lnh SQL, nn d liu ngi dng nhp khng th
a m SQL c vo. Thay v ghp trc tip d liu ngi dng nhp vo, c th s
dng mnh chn sau:
177
Lp trnh Android c bn
// To mnh chn vi i s c th thay th
String mSelectionClause = var = ?;
Hin th kt qu truy vn
Mt phng thc client ContentResolver.query() lun tr v i tng Cursor
cha cc hng ph hp vi iu kin chn ca truy vn, v mi hng li bao gm cc
ct do i s projection ch nh. Mt i tng Cursor cung cp kh nng truy cp
ngu nhin ti hng v ct n cha. Bng cch s dng cc phng thc ca Cursor,
bn c th duyt qua cc hng kt qu, xc nh kiu d liu ca tng ct, ly d liu
ra khi mt ct, ng thi kim tra cc thuc tnh khc ca kt qu. Mt s Cursor
c ci t t ng cp nht i tng khi d liu ca content provider thay i,
hoc s dng phng thc trigger bn trong mt i tng gim st (observer) mi khi
Cursor thay i, hoc c hai.
Ghi ch: Mt s content provider c th hn ch vic truy cp ti cc ct da trn
c tnh t nhin ca i tng thc hin truy vn. V d, Provider Contacts gii hn
vic truy cp trn mt s ct ng b cc adapter; do , provider ny s khng
tr v nhng ct b gii hn cho mt activity hay service.
Nu khng c hng no ph hp vi iu kin chn, content provider s tr v mt i
tng Cursor vi phng thc Cursor.getCount() cho kt qu l 0 (mt con tr
rng).
Nu xy ra li ni b, kt qu ca truy vn s ty thuc vo tng provider c th: C th
tr v null, hoc nm ra mt ngoi l (Exception).
V i tng Cursor l mt danh sch cc hng, nn cch tt nht hin th
ni dung ca Cursor l lin kt n vi mt ListView thng qua mt i tng
SimpleCursorAdapter.
on m nh di y l phn tip theo ca on m nh trc. Phn ny s to mt
i tng SimpleCursorAdapter cha Cursor l kt qu ca truy vn, ng thi
t i tng SimpleCursorAdapter ny lm adapter ca ListView:
178
Lp trnh Android c bn
// nh ngha mt danh sch ct truy xut d liu t Cursor v a
// vo mt hng u ra
String[] mWordListColumns =
{
};
mCursor, // Kt qu ca truy vn
mWordListItems, // Mt mng s nguyn cha cc ID hin th trong
// layout hng
mWordList.setAdapter(mCursorAdapter);
Ly d liu t kt qu truy vn
Thay v ch hin th kt qu truy vn, bn c th s dng kt qu ny cho cc mc ch
khc. V d, bn c th truy xut spelling (cch vit t/nh vn) trong user dictionary,
sau tm kim chng trong content provider khc. thc hin iu ny, bn duyt
qua cc hng trong Cursor:
// Xc nh ch s ct cho ct c tn word
if(mCursor != null){
/*
179
Lp trnh Android c bn
* u tin, con tr ch hng l -1, v nu c gng truy xut d
* liu ti v tr ny, bn s nhn c mt ngoi l.
*/
while(mCursor.moveToNext()){
// Ly gi tr t ct.
newWord = mCursor.getString(index);
...
} else {
i tng Cursor thc thi cha mt s phng thc get dng cho vi kiu truy xut
d liu khc nhau. V d, on m nh trc s dng getString(). Chng ta cng
c th dng phng thc getType() tr v gi tr cho bit kiu d liu ca ct.
180
Lp trnh Android c bn
Phn t <uses-permission> di y yu cu quyn c i vi content provider user
dictionary:
<uses-permissionandroid:name=android.permission.READ_USER_DICTIONARY>
Tc dng ca quyn i vi vic truy cp content provider c gii thch chi tit hn
trong ti liu hng dn Security and Permissions (Quyn v bo mt).
Chn d liu
chn d liu vo mt content provider, bn gi phng thc ContentResolver.
insert(). Phng thc ny s chn mt hng mi vo content provider v tr v
mt content URI (nh danh ti nguyn thng nht ca ni dung) ca hng . on m
nh di y minh ha cch chn mt hng mi vo content provider user dictionary:
// nh ngha mt i tng Uri mi s nhn kt qu tr v khi chn
// d liu
Uri mNewUri;
...
// nh ngha mt i tng cha gi tr mi s c chn thm
ContentValues mNewValues = new ContentValues();
/*
mNewValues.put(UserDictionary.Words.APP_ID,example.user);
mNewValues.put(UserDictionary.Words.LOCALE,en_US);
mNewValues.put(UserDictionary.Words.WORD,insert);
mNewValues.put(UserDictionary.Words.FREQUENCY,100);
mNewUri = getContentResolver().insert(
mNewValues // cc gi tr chn
);
181
Lp trnh Android c bn
thit phi cng kiu d liu; nu khng mun xc nh gi tr no, bn c th thit lp
ct l null bng cch s dng phng thc ContentValues.putNull().
on m nh trn khng thm ct _ID, bi ct ny c duy tr t ng. Content
provider gn mt gi tr ID duy nht cho mi hng mi c thm vo. Cc content
provider thng dng gi tr ny lm kha chnh ca bng.
Content URI tr v mt URI mi xc nh hng mi thm vo, di dng sau:
content://user_dictionary/words/<id_value>
Cp nht d liu
cp nht mt hng, bn s dng i tng ContentValues() vi cc gi tr cp nht
nh lm vi thao tc chn, v iu kin chn ging nh khi bn thc hin mt truy
vn. Phng thc client nn dng l ContentResolver.update(). Bn ch cn thm cc
gi tr vo i tng ContentValues cho nhng ct cn cp nht. Nu mun xa ni
dung mt ct, hy thit lp gi tr l null.
on m nh di y s thay i tt c cc hng c ct locale l en thnh locale l
null. Gi tr tr v l s lng hng c cp nht:
// To mt i tng cha cc gi tr c cp nht
ContentValues mUpdateValues = new ContentValues();
mUpdateValues.putNull(UserDictionary.Words.LOCALE);
mRowsUpdated = getContentResolver().update(
mUpdateValues // Cc ct cp nht
mSelectionClause // ct c chn
182
Lp trnh Android c bn
mSelectionArgs // gi tr so snh
);
Xa d liu
Xa hng tng t nh vic truy xut hng d liu: Bn xc nh iu kin chn cho
cc hng mun xa v phng thc client s tr v s lng hng xa. on m
nh di y s xa nhng hng c ct app id bng user. Phng thc xa tr v
s lng hng c xa.
// Xc nh iu kin chn cho cc hng mun xa
mRowsDeleted = getContentResolver().delete(
mSelectionArgs // gi tr so snh
);
mSelectionClause // ct chn
integer.
floating point.
183
Lp trnh Android c bn
Kiu d liu ca mi ct trong content provider thng c lit k trong ti liu hng
dn ca trnh . Cc kiu d liu ca content provider user dictionary c lit k
trong ti liu tham kho v lp contract UserDictionary.Words ca trnh ny (cc
lp contract s c gii thiu trong mc Lp contract bn di). Bn cng c th
xc nh kiu d liu bng cch gi phng thc Cursor.getType().
Content provider cng lu gi thng tin v kiu d liu MIME cho mi content URI m
trnh nh ngha. Bn c th s dng thng tin v kiu MIME khm ph xem liu
ng dng ca bn c th x l d liu m content provider dng hay khng, hoc
chn mt kiu x l da trn kiu MIME. Bn thng cn kiu MIME khi lm vic vi
content provider cha cu trc hoc file d liu phc tp. V d, bng ContactsContract.
Data trong Content Provider Contacts s dng kiu MIME dn nhn kiu d liu
lin lc c lu mi hng. ly kiu MIME tng ng vi tng content URI, gi
phng thc ContentResolver.getType().
Mc Ti liu tham kho v kiu MIME bn di s gii thiu c php ca c kiu
MIME chun ln kiu MIME ty chnh.
Hai cch truy cp v chnh sa hng lot v thng qua intent s c miu t trong
cc mc di y.
184
Lp trnh Android c bn
bng khc nhau. Mt li gi ti phng thc ContentResolver.applyBatch()
tr v mt mng cha cc kt qu.
Phn gii thiu v lp contract ContactsContract.RawContacts cha mt on
m nh minh ha cho vic chn hng lot. ng dng mu Contact Manager cha mt
v d v vic truy cp hng lot trong file ngun ContactAdder.java.
Quyn c: FLAG_GRANT_READ_URI_PERMISSION
Content provider nh ngha cc quyn URI cho content URI trong file k khai ca
n, s dng thuc tnh android:grantUriPermission ca phn t <provider>,
c chc nng tng t nh phn t con <grant-uri-permission> ca phn
t <provider>. C ch quyn URI c gii thch chi tit hn ti ti liu hng
dn Security and Permissions (Quyn v bo mt), trong mc URI permissions
(Quyn URI).
185
Lp trnh Android c bn
V d, ngay c khi khng c quyn READ_CONTACTS, bn vn c th truy xut d liu
mt lin lc trong Content Provider Contacts. C th bn mun thc hin iu ny trong
mt ng dng gi li chc in t ti ngi bn mun lin lc trong ngy sinh nht ca
anh/c y. Thay v yu cu quyn READ_CONTACTS, c th truy cp vo tt c cc
lin lc ca ngi dng v ton b thng tin ca h, bn mun ngi dng qun l
nhng lin lc c ng dng ca bn dng. thc hin iu ny, bn s dng tin
trnh x l sau:
1. ng dng ca bn gi i mt intent cha action ACTION_PICK v
kiu MIME cha lin lc CONTENT_ITEM_TYPE, dng phng thc
startActivityForResult().
2. Do intent trn ph hp vi b lc intent ca activity la chn (selection) trong ng
dng ca ngi dng (People), nn activity ny s hin th mn hnh chnh.
3. Trong activity la chn (selection) ny, ngi dng chn mt lin lc cp
nht. Khi , activity la chn s gi phng thc setResult(resultcode,
intent) to mt intent tr v cho ng dng ca bn. Intent mi ny cha
content URI ca lin lc m ngi dng chn, ng thi thm c FLAG_GRANT_
READ_URI_PERMISSION. Cc c ny s gn quyn URI cho ng dng ca bn
c d liu trong lin lc c content URI tr ti. Sau , activity la chn s
gi phng thc finish() tr iu khin v cho ng dng ca bn.
4. Activity ca bn tr li mn hnh chnh, v h thng gi phng thc
onActivityResult() trong activity ca bn. Phng thc ny s nhn intent
kt qu c activity la chn to ra trong ng dng People.
5. Vi content URI trong intent kt qu, bn c th c d liu lin lc ca Content
Provider Contacts, ngay c khi khng yu cu quyn c lu di trong file k khai.
Sau , bn c th ly thng tin v sinh nht ca lin lc hoc a ch e-mail ca
ngi mun lin lc gi li chc in t.
Lp contract
Lp contract nh ngha cc hng s gip ng dng lm vic vi content URI, tn ct,
action ca intent v nhng tnh nng khc ca content provider. Lp contract khng
t ng c trong content provider, nn nh pht trin content provider phi nh ngha
chng, sau x l nhng nh pht trin chng trnh khc c th s dng c.
186
Lp trnh Android c bn
Nhiu nh pht trin tch hp vi nn tng Android c cc lp contract tng ng trong
gi android.provider.
V d, content provider user dictionary c lp contract UserDictionary cha cc
hng content URI v tn ct. Content URI ca bng words c nh ngha trong
hng UserDictionary.Words.CONTENT_URI. Lp UserDictionary.Words
cng cha hng tn ct, c s dng trong on m nh minh ha di y. Chng
hn, chng ta c th nh ngha mt php chiu truy vn nh sau:
String[] mProjection =
{
UserDictionary.Words._ID,
UserDictionary.Words.WORD,
UserDictionary.Words.LOCALE
};
187
Lp trnh Android c bn
mi cho mt s in thoi, ng dng ny s thit lp kiu MIME di y cho hng
mi :
vnd.android.cursor.item/phone_v2
kiu con, gi tr subtype ch n gin l phone_v2.
Cc nh pht trin content provider khc c th to nhng mu kiu con ca ring
h da vo chui nh danh v tn bng. V d, gi s mt content provider c bng
lu thng tin thi gian cc chuyn tu (train time). Chui nh danh ca trnh ny l
com.example.trains, ng thi cha cc bng Line1, Line2 v Line3.
p ng content URI
content://com.example.trains/Line1
cho bng Line1, content provider tr v kiu MIME
vnd.android.cursor.dir/vnd.example.line1
p ng content URI
content://com.example.trains/Line2/5
cho hng 5 trong bng Line2, content provider tr v kiu MIME
vnd.android.cursor.item/vnd.example.line2
Hu ht content provider u nh ngha hng cho cc kiu MIME m trnh ny s dng
trong lp contract. V d, lp contract ca Provider Contacts l ContactsContract.
RawContacts, nh ngha hng CONTENT_ITEM_TYPE cho kiu MIME ca mt
hng lin lc n.
Content URI ca hng n c miu t trong mc Content URIs.
188
Lp trnh Android c bn
oo
Mun cho php ngi dng sao chp d liu phc tp t ng dng ca bn
vo nhng ng dng khc.
oo
189
Lp trnh Android c bn
nh pht trin ng dng khc. tm hiu thm v content URI, xem mc Thit
k content URI. tm hiu thm v intent, xem mc Intent v truy cp d liu.
4. Thm vo cc ty chn khc, chng hn nh d liu mu hoc phn ci t ca
lp AbstractThreadedSyncAdapter c th ng b d liu gia content
provider v d liu trn m my (cloud-based data).
Thit k b lu tr d liu
Content provider l giao din lu d liu di nh dng c cu trc. Trc khi to
giao din ny, bn phi quyt nh cch lu tr d liu. Bn c th lu d liu di
bt k dng no mnh mun, sau thit k giao din c v ghi d liu, nu cn.
Trong Android c sn mt s k thut lu tr d liu:
lu tr d liu dng file, h iu hnh Android c nhiu API hng file (fileoriented data). tm hiu thm v vic lu tr file, tham kho mc Lu tr
d liu. Nu ang thit k content provider chia s d liu lin quan n a
phng tin (media-related data) nh m nhc hoc video, bn c th xy dng
content provider kt hp gia d liu bng v file.
190
D liu bng phi lun c mt ct kha chnh l trng m content provider duy
tr nh mt gi tr s duy nht cho mi hng. Bn c th dng gi tr trn lin
kt hng ny vi cc hng c lin quan trong bng khc (ly trng ny lm kha
ngoi - foreign key). Mc d bn c th t mt tn bt k cho ct ny, nhng
s dng tn BaseColumns._ID l la chn tt nht, bi v vic lin kt kt qu
ca mt truy vn trn provider vi ListView yu cu mt trong cc ct c truy
xut phi c tn l _ID.
Lp trnh Android c bn
S dng kiu d liu BLOB lu d liu c kch thc bin i hoc c cu trc
bin i. V d, bn c th s dng mt ct BLOB lu JSON structure (cu trc
JSON).
Bn cng c th s dng kiu d liu BLOB ci t bng schema-independent
(khng ph thuc cu trc). Trong kiu bng ny, bn xc nh mt ct kha chnh,
mt ct c kiu MIME v mt hoc nhiu ct thng kiu BLOB. ngha ca
d liu trong cc ct BLOB ph thuc vo gi tr trong ct kiu MIME. iu ny
cho php bn lu cc kiu hng khc nhau trong cng mt bng. Bng d liu
ContactsContract.Data ca Provider Contacts l mt v d v bng khng
ph thuc cu trc.
dng>.provider.
Thit k cu trc ng dn
Cc nh pht trin thng to content URI t chui nh danh bng cch gn thm
ng dn tr ti nhng bng c th. Chng hn, nu c hai bng l table1 v table2,
bn kt hp vi chui nh danh trong v d trc to thnh content URI l com.
example.<tn ng dng>.provider/table1 v com.example.<tn
ng dng>.provider/table2. Cc ng dn ny khng hn ch trong mt
phn on (segment) n, khng bt buc phi l bng tng ng vi mi mc ca
ng dn.
191
Lp trnh Android c bn
X l cc ID ca content URI
Theo quy c, content provider cung cp truy cp ti mt hng n trong bng bng
cch chp nhn mt content URI vi mt gi tr ID tng ng cho mi hng nm cui
URI. Cng theo quy c, content provider i chiu gi tr ID vi ct _ID ca bng ,
ng thi thc hin truy cp c yu cu trn hng tng ng.
Cc quy c ny to iu kin thun li cho kiu mu thit k chung truy cp vo
content provider. ng dng thc hin truy vn trn provider v hin th Cursor kt
qu qua ListView bng cch s dng CursorAdapter. Trong nh ngha ca lp
CursorAdapter yu cu mt trong cc ct ca Cursor l _ID.
Sau , ngi dng ly ra mt trong cc hng hin th t giao din ngi dng theo th
t sp xp xem hoc chnh sa d liu. ng dng ly hng tng ng t Cursor
quay tr li ListView, ly ra gi tr _ID cho hng , gn gi tr ny vo content URI,
ri gi yu cu truy cp ti content provider. T , content provider c th thc hin
truy vn hoc chnh sa trn ng hng m ngi dng chn.
content://com.example.app.provider/table1: Mt bng
ltable1.
content://com.example.app.provider/table2/dataset1: Mt bng
c tn ldataset1.
content://com.example.app.provider/table2/dataset2: Mt bng
c tn l dataset2.
content://com.example.app.provider/table3: Mt bng c tn l
table3.
c tn
192
Lp trnh Android c bn
Cc mu content URI di y c th kh thi:
content://com.example.app.provider/*:
...
// To i tng UriMatcher.
/*
*/
...
/*
sUriMatcher.addURI(com.example.app.provider,table3,1);
*/
/*
*
*
*
*
*/
193
Lp trnh Android c bn
sUriMatcher.addURI(com.example.app.provider,table3/#,2);
Uri uri,
String selection,
...
publicCursor query(
String[] projection,
String[] selectionArgs,
String sortOrder){
...
/*
*/
switch(sUriMatcher.match(uri)){
// Nu URI ti l ca mt hng n
case1:
case2:
/*
*
*
*
*
*/
default:
...
194
Lp trnh Android c bn
Ci t lp ContentProvider
Th hin ca lp ContentProvider qun l vic truy cp ti b d liu c cu trc
bng cch x l yu cu t cc ng dng khc. Cui cng th tt c cc dng truy cp
u gi n i tng ContentResolver, sau i tng ny gi ti mt phng
thc c th ca content provider thc hin truy cp.
Phng thc yu cu
Lp tru tng (abstract class) ContentProvider nh ngha su phng thc tru
tng m bn phi ci t thnh mt phn trong cc lp con c th ca chnh bn. Tt
c cc phng thc ny, ngoi tr phng thc onCreate(), c gi bi ng dng
client ang truy cp vo content provider ca bn:
query()
Truy xut d liu t content provider. S dng cc i s chn bng truy vn,
cc hng v ct tr v, cng nh th t sp xp ca kt qu. Tr v d liu di
dng i tng Cursor.
insert()
Khi to content provider. H thng Android gi phng thc ny ngay sau khi
Android to content provider ca bn. Lu , content provider ca bn khng c
to ra cho n khi i tng ContentResolver c gng truy cp vo trnh ny.
Lu , cc phng thc ny c cng ch k (signature) vi nhng phng thc
ContentResolver c tn tng t.
Vic ci t cc phng thc ny nn tun theo nhng phn tch di y:
195
Lp trnh Android c bn
NullPointerException.
196
Lp trnh Android c bn
*/
// nh ngha tn c s d liu
/*
*/
197
Lp trnh Android c bn
);
DBNAME, // tn c s d liu
return true;
...
*/
db = mOpenHelper.getWritableDatabase();
main + // Tn bng
...
(+ // Cc ct ca bng
WORD TEXT
FREQUENCY INTEGER +
LOCALE TEXT );
/**
198
Lp trnh Android c bn
/*
*/
MainDatabaseHelper(Context context){
super(context, DBNAME,null,1);
/*
*/
// To bng chnh
db.execSQL(SQL_CREATE_MAIN);
199
Lp trnh Android c bn
oo
oo
Nu provider bn pht trin khng chia s kiu MIME no do chui lc yu cu, phng
thc getStreamTypes() nn tr v null.
200
Lp trnh Android c bn
Ci t lp contract
Lp contract l lp c khai bo public final cha cc nh ngha hng cho URI,
tn ct, kiu MIME v siu d liu (meta-data) khc gn lin vi provider. Lp ny thit
lp mt giao kt (contract) gia provider v cc ng dng khc bng cch m bo
rng provider c th c truy cp ng, ngay c khi cc gi tr thc s ca URI, tn
ct, thay i.
Lp contract cng gip ch cho nh pht trin ng dng, bi chng thng c cc tn
hng d nh; do , nh pht trin t dng tn ct hoc URI khng chnh xc. V l mt
lp, nn Lp contract c th cung cp ti liu Javadoc. Cc mi trng pht trin tch
hp (integrated development environment- IDE) nh Eclipse c th a ra danh sch
gi cho php ngi dng chn t ng in cc tn hng ny t Lp contract v
hin th Javadoc ca hng .
Nh pht trin ng dng khng cn truy cp vo file lp ca Lp contract t ng dng
ca bn, nhng h c th bin dch tnh lp ny trong ng dng ca mnh t file .jar
bn cung cp.
Lp ContactsContract v cc lp lng (nested class) ca n l nhng v d v
Lp contract.
201
Lp trnh Android c bn
d nh trn mt server xa), ng thi nn gi cho cc file v c s d liu l dnh
ring cho ng dng ca bn.
Ci t quyn
Mi ng dng u c th c hoc ghi vo provider ca bn, ngay c khi d liu bn
di l ring t, bi theo mc nh th provider ca bn khng c tp cc quyn truy
cp. thay i iu ny, hy thit lp quyn cho provider ca bn trong file k khai,
s dng thuc tnh hoc phn t con ca phn t <provider>. Bn c th thit lp
quyn p dng cho ton b provider, cho bng c th, hay thm ch cho mt s bn
ghi nht nh, hoc c ba.
Bn nh ngha cc quyn cho content provider ang pht trin vi mt hoc nhiu
phn t <permission> trong file k khai. m bo nhng quyn ny l duy
nht i vi ng dng ca bn, s dng kiu phm vi theo nh dng Java cho thuc
tnh android:name. V d, tn ca quyn c l com.example.app.provider.
permission.READ_PROVIDER.
Danh sch di y m t phm vi ca cc quyn ca provider, bt u vi quyn p
dng cho ton b provider, sau i vo cc quyn chi tit hn. Quyn cng chi tit
cng c u tin cao hn quyn c phm vi cao hn:
Quyn c-ghi kt hp mc provider
Mt quyn kim sot c quyn c ln quyn ghi trn ton provider, c xc nh
vi thuc tnh android:permission ca phn t <provider>.
Quyn c v ghi ring mc provider
Mt quyn c v mt quyn ghi cho ton provider. Bn xc nh nhng quyn ny bng
cc thuc tnh android:readPermission v android:writePermission
ca phn t <provider>. Cc quyn ny c u tin hn quyn c thuc tnh
android:permission xc nh.
Quyn ti mc ng dn (path-level)
Quyn c, ghi hoc c/ghi cho mt content URI trong provider m bn pht trin.
Bn ch r mi URI mnh mun qun l vi mt phn t con <path-permission>
ca phn t <provider>. Vi mi content URI bn ch ra, bn c th xc nh
quyn c/ghi, mt quyn c, hay mt quyn ghi, hoc c ba. Quyn c v ghi
ny c quyn u tin hn quyn c/ghi. Quyn ti mc ng dn cng c u
tin hn quyn mc provider.
Quyn tm (temporary permission)
Mt mc quyn m s trao quyn truy cp tm thi cho mt ng dng, ngay c khi
ng dng khng yu cu cc quyn thng thng. c tnh ca quyn tm l lm
gim s quyn m mt ng dng phi yu cu trong file k khai ca n. Khi bn bt
quyn tm, ch nhng ng dng cn quyn lu di trn provider mi c th lin
tc truy cp ton b d liu ca bn.
Gi s c cc quyn bn cn ci t mt ng dng v email provider (trnh cung
cp e-mail), khi mun cho php ng dng hin th nh bn ngoi (outside image
viewer) hin th cc nh nh km trong provider. cp cho ng dng hin th nh
202
Lp trnh Android c bn
cc quyn truy cp cn thit m khng phi yu cu quyn, hy thit lp quyn tm
cho cc content URI ca nh. Thit k ng dng e-mail ca bn khi ngi dng
mun hin th nh, ng dng s gi mt intent cha content URI ca nh v cc
c quyn ti ng dng hin th nh. Sau , ng dng hin th nh c th truy vn
email provider bn pht trin ly nh ra, ngay c khi ng dng hin th khng c
quyn c thng thng trn provider .
bt quyn tm, hoc l thit lp thuc tnh
android:grantUriPermissions ca phn t <provider> , hoc
thm mt hoc nhiu phn t con <grant-uri-permission> vo
phn t <provider> . Nu dng quyn tm, bn phi gi phng thc
Context.revokeUriPermission() mi khi xa s h tr trn mt
content URI khi provider v content URI c gn vi quyn tm.
Gi tr ca thuc tnh xc nh mc truy cp c ca provider do bn pht trin.
Nu thuc tnh ny c thit lp l true, h thng ca bn s gn quyn tm cho
ton b provider, che khut cc quyn c yu cu ti mc ng dn v mc
provider.
N u c n y c t hit lp l f alse, b n p h i th m p h n t co n
<grant-uri-permission> cho phn t <provider> . Mi phn t
con xc nh content URI hoc cc URI c gn quyn truy cp tm.
gn quyn tm cho mt ng dng, mt intent phi cha c FLAG_GRANT_
READ_URI_PERMISSION hoc FLAG_GRANT_WRITE_URI_PERMISSION,
hay c hai. Nhng quyn ny c thit lp bng phng thc setFlags().
Nu khng c thuc tnh android:grantUriPermissions, thuc tnh ny
c coi l false.
Phn t <provider>
Tng t phn t Activity v Service, lp con ca ContentProvider phi
c nh ngha trong file k khai ca ng dng provider, bng cch s dng phn t
<provider>. H iu hnh Android ly cc thng tin sau t phn t ny:
Chui nh danh (android:authorities)
Tn c tnh biu tng xc nh ton b provider bn trong h thng. Thuc tnh
ny c m t chi tit mc Thit k Content URI.
Tn lp provider (android:name)
L lp ci t ContentProvider. Lp ny c m t chi tit mc
Ci t lp ContentProvider.
Quyn
Cc thuc tnh xc nh quyn m nhng ng dng khc phi c truy cp vo
d liu ca provider:
203
Lp trnh Android c bn
Biu tng ny xut hin bn cnh nhn ca provider trong danh sch cc
ng dng nm Settings > Apps > All.
hoc c hai. Nhn ny xut hin trong danh sch cc ng dng nm Settings
> Apps > All.
204
Lp trnh Android c bn
C th bn mun s dng vic truy cp thng qua intent m bo tnh ton vn
(integrity) ca d liu. Content provider ca bn c th ph thuc vo vic d liu c
chn thm, cp nht v xa theo cc lgc nghip v c nh ngha cht ch. Nu
gp trng hp nh vy, hy cho php ng dng khc c sa trc tip trn d liu
ca bn, iu ny c th dn n d liu khng hp l. Nu mun cc nh pht trin
s dng truy cp thng qua intent, bn cn m bo rng vic ny phi c hng
dn mt cch r rng. Hy gii thch vi cc nh pht trin ng dng rng ti sao vic
truy cp thng qua intent bng cch dng giao din ngi dng ca ng dng bn pht
trin li tt hn vic c gng chnh sa d liu bng m do h pht trin.
Vic x l cc intent n, tc intent mun chnh sa d liu ca provider do bn pht
trin, khng khc bit so vi vic x l nhng intent khc. Bn c th tm hiu thm
v vic s dng intent qua ch Intents and Intent Filters (Intent v b lc intent).
Cc khi nim c bn
Content provider lu tr d liu v gip cc ng dng khc c th truy cp c vo
nhng d liu ny. Cc content provider c nn tng Android cung cp (bao gm
Provider Calendar) thng xut d liu di dng tp bng da trn m hnh c s
d liu quan h; trong , mi hng l mt bn ghi v mi ct l d liu ca mt kiu
v ngha c th. Thng qua API ca Provider Calendar, ng dng v adapter c chc
nng ng b c th c/ghi trn cc bng c s d liu lu tr d liu lp lch ca
ngi dng.
Mi content provider cung cp ra bn ngoi mt URI cng khai (nm trong mt i
tng Uri), y l nh danh duy nht cho mi tp d liu ca provider. Content
provider qun l nhiu tp d liu (nhiu bng) xut ra mt URI cho mi tp. Tt c
cc URI ca provider bt u bng chui content://. nh dng ny nh danh
205
Lp trnh Android c bn
d liu do provider qun l. Provider Calendar nh ngha hng cho URI ca mi lp
(bng) trong trnh ny. Cc URI ny c nh dng l <class>.CONTENT_URI. V d,
Events.CONTENT_URI.
Hnh 1 minh ha mt m hnh d liu ca Provider Calendar. M hnh ny ch biu din
cc bng chnh v nhng trng c chc nng lin kt bng.
Calendars
Events
S kin
Attendee
Reminder
Li nhc nh
Instances
Th hin
206
Lp trnh Android c bn
Bng (Lp)
M t
CalendarContract.Calendars
CalendarContract.Events
CalendarContract.Instances
CalendarContract.Attendees
CalendarContract.Reminders
API ca Provider Calendar c thit k linh hot v mnh m. Cng lc, trnh ny
c th cung cp nhng tri nghim tt cho ngi dng cui cng nh m bo tnh
ton vn ca lch v d liu bn trong. Phn cui s tm tt mt s lu khi s dng
API ny:
207
Lp trnh Android c bn
<manifest xmlns:android=http://schemas.android.com/apk/res/android...>
<uses-sdkandroid:minSdkVersion=14/>
<uses-permissionandroid:name=android.permission.WRITE_CALENDAR/>
<uses-permissionandroid:name=android.permission.READ_CALENDAR/>
...
</manifest>
Bng Calendars
Bng CalendarContract.Calendars cha thng tin chi tit v cc lch c nhn.
Cc ct ca bng Calendars di y cung cp quyn ghi cho ng dng hoc adapter
c chc nng ng b. xem danh sch y cc trng c h tr, tham kho
CalendarContract.Calendars.
208
Lp trnh Android c bn
Hng
M t
NAME
Tn lch.
CALENDAR_DISPLAY_NAME
VISIBLE
CalendarContract.Instances.
SYNC_EVENTS
Truy vn lch
Sau y l mt v d minh ha cch ly lch do mt ngi dng c th qun l. n
gin, trong v d ny, hot ng truy vn c hin th trong lung giao din ngi dng
(lung chnh - main thread). Trong thc t, cc truy vn ny nn c thc hin
trong lung khng ng b (asynchronous thread) thay v trn lung chnh. tho
lun thm v iu ny, xem mc Loaders (Cc trnh loader). Nu bn ch c d liu
m khng chnh sa, xem phn AsyncQueryHandler.
// Mng i s projection. To ch s cho mng ny thay v thc hin
// tm kim ng (dynamic lookup) nng cao hiu sut.
Calendars._ID, // 0
Calendars.CALENDAR_DISPLAY_NAME, // 2
};
Calendars.ACCOUNT_NAME, // 1
Calendars.OWNER_ACCOUNT // 3
209
Lp trnh Android c bn
ContentResolver cr = getContentResolver();
Uri uri = Calendars.CONTENT_URI;
+Calendars.ACCOUNT_TYPE + = ?) AND (
+Calendars.OWNER_ACCOUNT + = ?));
Phn tip theo s dng con tr duyt qua tp kt qu. Phn ny s dng cc hng
thit lp u v d tr v gi tr ca mi trng.
// S dng con tr duyt qua cc bn ghi kt qu c tr li
while (cur.moveToNext()) {
// Ly ra gi tr ca cc trng
displayName = cur.getString(PROJECTION_DISPLAY_NAME_INDEX);
210
calID = cur.getLong(PROJECTION_ID_INDEX);
accountName = cur.getString(PROJECTION_ACCOUNT_NAME_INDEX);
Lp trnh Android c bn
ownerName = cur.getString(PROJECTION_OWNER_ACCOUNT_INDEX);
Chnh sa lch
thc hin cp nht trn lch, bn c th cung cp _ID ca lch bng cch gn thm
ID vo Uri (vi phng thc withAppendedId()), hoc ly mc chn u tin.
Mnh chn s bt u vi _id=?, v selectionArg (i s chn) u tin s
l _ID ca lch. Bn cng c th cp nht bng cch m ha (encode) ID trong URI. V
d ny s thay i tn hin th ca lch, s dng phng thc withAppendedId():
private static final String DEBUG_TAG =MyActivity;
...
values.put(Calendars.CALENDAR_DISPLAY_NAME,Trevors Calendar);
Chn lch
Lch c thit k c qun l ch yu bi adapter c chc nng ng b. Do
, bn ch nn thm cc lch mi di dng adapter c chc nng ng b. im
quan trng nht l ng dng ch c th thc hin cc thay i b ngoi, chng
hn nh thay i tn hin th. Nu mt ng dng cn to mt lch cc b (local
calendar), bn c th chn lch di dng mt adapter ng b, s dng ACCOUNT_TYPE l ACCOUNT_TYPE_LOCAL .ACCOUNT_TYPE_LOCAL l mt loi
ti khon c bit ca lch, khng c mi lin kt vi ti khon trn thit b. Lch
ca ti khon ny khng c ng b vi server. tho lun thm v adapter
c chc nng ng b, xem mc Adapter c chc nng ng b.
Bng Events
Bng CalendarContract.Events bao gm thng tin chi tit cho tng s
kin ring. thm, cp nht hoc xa s kin, mt ng dng phi thm quyn
WRITE_CALENDAR vo file file k khai ca n.
Cc ct di y ca bng Events c th c ng dng v adapter c chc nng
ng b chnh sa. c danh sch y cc trng c h tr ny, xem phn
tham kho ca CalendarContract.Events.
211
Lp trnh Android c bn
Hng
M t
CALENDAR_ID
ORGANIZER
TITLE
Tiu ca s kin.
EVENT_LOCATION
a im din ra s kin.
DESCRIPTION
Phn m t s kin.
DTSTART
DTEND
EVENT_TIMEZONE
Mi gi ca s kin.
EVENT_END_TIMEZONE
DURATION
ALL_DAY
RRULE
"FREQ=WEEKLY;COUNT=10;WKST=SU".
Bn c th tham kho thm v d ti y.
RDATE
AVAILABILITY
GUESTS_CAN_MODIFY
GUESTS_CAN_INVITE_OTHERS
212
Lp trnh Android c bn
Hng
M t
GUESTS_CAN_SEE_GUESTS
Thm s kin
Khi ng dng ca bn chn thm s kin mi, chng ti khuyn ngh bn nn s dng
Intent INSERT, nh m t trong mc S dng intent chn thm s kin. Tuy nhin,
nu cn, bn c th trc tip chn s kin. Phn ny s hng dn cch lm.
Sau y l cc quy tc chn thm s kin mi:
startMillis = beginTime.getTimeInMillis();
Calendar endTime =Calendar.getInstance();
endTime.set(2012, 9, 14, 8, 45);
endMillis = endTime.getTimeInMillis();
...
ContentResolver cr = getContentResolver();
213
Lp trnh Android c bn
values.put(Events.TITLE,Jazzercise);
values.put(Events.DESCRIPTION,Group workout);
values.put(Events.CALENDAR_ID, calID);
values.put(Events.EVENT_TIMEZONE,America/Los_Angeles);
Uri uri = cr.insert(Events.CONTENT_URI, values);
Cp nht s kin
Khi ng dng ca bn mun cho php ngi dng chnh sa mt s kin, chng ti
khuyn ngh bn nn dng intent EDIT, nh m t trong mc S dng intent chnh
sa s kin. Tuy nhin, nu cn, bn c th trc tip chnh sa s kin. thc hin
cp nht trn mt s kin, bn c th cung cp _ID ca s kin thng qua vic ghp
thm ID vo Uri (bng phng thc withAppendedId()), hoc ly mc chn u
tin. Mnh chn phi bt u vi _id=?, cn i s chn selectionArg u
tin phi l _ID ca s kin. Bn cng c th cp nht bng cch s dng mnh
chn khng c ID. Sau y l mt v d v cp nht s kin. V d ny s thay i tiu
(title) ca s kin, s dng withAppendedId():
private static final String DEBUG_TAG = MyActivity;
...
long eventID =188;
...
ContentResolver cr = getContentResolver();
ContentValues values =newContentValues();
Uri updateUri = null;
// Tiu mi ca s kin
values.put(Events.TITLE,Kickboxing);
updateUri =ContentUris.withAppendedId(Events.CONTENT_URI, eventID);
int rows = getContentResolver().update(updateUri, values, null, null);
Log.i(DEBUG_TAG,Rows updated: + rows);
214
Lp trnh Android c bn
Xa s kin
Bn c th xa s kin bng _ID ca s kin ny di dng ghp thm ID vo URI,
hoc bng cch s dng mnh chn chun. Nu s dng cch gn thm ID, bn
khng phi thc hin php chn. C hai kiu xa: Dng ng dng v dng adapter c
chc nng cp nht. ng dng xa cc bn ghi c ct deleted bng 1. C ny bo vi
adapter c chc nng ng b l hng b xa v vic xa ny phi c p dng
vo server. Adapter c chc nng ng b loi b hon ton s kin khi c s d liu
cng vi nhng d liu lin quan ti s kin ny. Sau y l v d dng ng dng
xa mt s kin thng qua _ID ca s kin :
private static final String DEBUG_TAG = MyActivity;
...
long eventID = 201;
...
ContentResolver cr = getContentResolver();
ContentValues values = new ContentValues();
Uri deleteUri = null;
deleteUri =ContentUris.withAppendedId(Events.CONTENT_URI, eventID);
int rows = getContentResolver().delete(deleteUri,null,null);
Log.i(DEBUG_TAG,Rows deleted: + rows);
Bng Attendees
Mi hng ca bng CalendarContract.Attendees i din cho mt ngi tham
d hoc khch mi ca s kin. Gi phng thc query() tr v danh sch khch
tham d s kin vi EVENT_ID cho trc. EVENT_ID ny phi ph hp vi _ID ca
mt s kin c th.
Bng di y lit k cc trng c th ghi c. Khi chn thm khch mi mi, bn
phi cung cp gi tr cho tt c cc trng ny, ngoi tr ATTENDEE_NAME.
Hng
M t
EVENT_ID
ID s kin.
ATTENDEE_NAME
Tn ngi tham d.
ATTENDEE_EMAIL
215
Lp trnh Android c bn
Hng
M t
ATTENDEE_RELATIONSHIP
ATTENDEE_TYPE
ATTENDEE_STATUS
216
Lp trnh Android c bn
values.put(Attendees.ATTENDEE_EMAIL,trevor@example.com);
values.put(Attendees.ATTENDEE_RELATIONSHIP,Attendees.RELATIONSHIP_ATTENDEE);
values.put(Attendees.ATTENDEE_TYPE,Attendees.TYPE_OPTIONAL);
values.put(Attendees.ATTENDEE_STATUS,Attendees.ATTENDEE_STATUS_INVITED);
values.put(Attendees.EVENT_ID, eventID);
Uri uri = cr.insert(Attendees.CONTENT_URI, values);
Bng Reminders
Mi hng ca bng CalendarContract.Reminders tng ng vi mt li nhc
nh ca s kin. Li gi phng thc query() tr v danh sch cc li nhc nh ca
s kin c EVENT_ID cho trc.
Bng di y lit k cc trng c th ghi c ca bng nhc nh. Khi thm
mt li nhc mi, bn phi cung cp gi tr cho tt c cc trng ny. Lu , cc
adapter c chc nng ng b xc nh kiu nhc nh m chng h tr trong bng
CalendarContract.Calendars. Xem mc ALLOWED REMINDERS (Cc kiu
nhc nh c cho php) bit thm chi tit.
Hng
M t
EVENT_ID
ID ca s kin.
MINUTES
METHOD
Thm li nhc nh
V d sau thm mt li nhc nh vo s kin. Li nhc nh c khi ng trc s
kin 15 pht.
217
Lp trnh Android c bn
long eventID = 221;
...
ContentResolver cr = getContentResolver();
ContentValues values = new ContentValues();
values.put(Reminders.MINUTES,15);
values.put(Reminders.EVENT_ID, eventID);
values.put(Reminders.METHOD, Reminders.METHOD_ALERT);
Uri uri = cr.insert(Reminders.CONTENT_URI, values);
Bng Instances
Bng CalendarContract.Instances qun l thi im bt u v kt thc mi
ln din ra mt s kin. Mi hng trong bng i din cho mt ln s kin din ra. Bng
Instances khng cho quyn ghi v ch cung cp mt cch truy vn cc ln din ra
s kin.
Bng sau lit k mt s trng bn c th dng truy vn cho mt th hin. Lu ,
mi gi l do KEY_TIMEZONE_TYPE v KEY_TIMEZONE_INSTANCES xc nh.
Hng
M t
BEGIN
END
END_DAY
END_MINUTE
EVENT_ID
START_DAY
START_MINUTE
218
Lp trnh Android c bn
private static final String DEBUG_TAG = MyActivity;
Instances.EVENT_ID, // 0
Instances.TITLE // 2
};
Instances.BEGIN, // 1
ContentResolver cr = getContentResolver();
// ID ca s kin m bn ang tm kim cc th hin ca n trn bng
// Instances
cur = cr.query(builder.build(),
INSTANCE_PROJECTION,
selectionArgs,
selection,
null);
while(cur.moveToNext()){
219
Lp trnh Android c bn
// Ly gi tr ca cc trng
eventID = cur.getLong(PROJECTION_ID_INDEX);
beginVal = cur.getLong(PROJECTION_BEGIN_INDEX);
title = cur.getString(PROJECTION_TITLE_INDEX);
Log.i(DEBUG_TAG,Event: + title);
calendar.setTimeInMillis(beginVal);
Log.i(DEBUG_TAG,Date: + formatter.format(calendar.getTime()));
}
}
Cc intent ca Calendar
ng dng ca bn khng cn phi c quyn c v ghi d liu lch. Thay vo
, ng dng do bn pht trin c th dng cc intent c ng dng Calendar ca
Android h tr thc hin nhng thao tc c v ghi vi ng dng ny. Bng sau y
lit k cc intent c Provider Calendar h tr:
Cc trng ph h tr
(extra)
Action
URI
M t
VIEW
content://com.
android.calendar/
time/<ms_since_
epoch>
M
lch
vi Khng c.
thi gian c
xc nh bi
<ms_since_
epoch>.
Bn cng c th tr ti
URI ny thng qua hng
CalendarContract.
CONTENT_URI. V v d
s dng intent, xem mc
S dng intent hin th
d liu lch.
VIEW
c o n t e n t : / / c o m . Hin th s kin
android.calendar/ c xc nh
events/<event_id>
bi
<event_id>
.
Bn cng c th tr ti URI
220
CalendarContract.
EXTRA_EVENT_BEGIN_
TIME
CalendarContract.
EXTRA_EVENT_END_
TIME
Lp trnh Android c bn
Action
URI
M t
EDIT
c o n t e n t : / / c o m . Chnh sa s
android.calendar/ kin c xc
events/<event_id>
nh bi
<event_id>.
Bn cng c th tr ti URI
EDIT
c o n t e n t : / / c o m . To mt
android.calendar/ s kin.
INSERT
events
Cc trng ph h tr
(extra)
CalendarContract.
EXTRA_EVENT_BEGIN_
TIME
CalendarContract.
EXTRA_EVENT_END_
TIME
Bt c trng ph h tr
no c lit k bng bn
di.
Bn c th tr ti URI
ny bng hng Events.
CONTENT_URI. V v d
s dng intent ny, xem
mc S dng intent
chn thm s kin.
Bng sau lit k mt s trng ph h tr intent (extra) c Provider Calendar
cung cp:
Trng ph h tr intent (extra)
M t
Events.TITLE
Tn s kin.
CalendarContract.EXTRA_
EVENT_BEGIN_TIME
CalendarContract.EXTRA_
EVENT_END_TIME
CalendarContract.EXTRA_
EVENT_ALL_DAY
Events.EVENT_LOCATION
a im t chc s kin.
Events.DESCRIPTION
M t v s kin.
Intent.EXTRA_EMAIL
Cc a ch e-mail ca khch mi di
dng mt danh sch phn cch nhau bi
du phy.
Events.RRULE
Quy tc lp s kin.
Events.ACCESS_LEVEL
221
Lp trnh Android c bn
Trng ph h tr intent (extra)
M t
Events.AVAILABILITY
.setData(Events.CONTENT_URI)
.putExtra(CalendarContract.EXTRA_EVENT_END_TIME,
222
.putExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME,
beginTime.getTimeInMillis())
endTime.getTimeInMillis())
.putExtra(Events.TITLE,Yoga)
.putExtra(Events.DESCRIPTION,Group class)
.putExtra(Events.EVENT_LOCATION,The gym)
.putExtra(Events.AVAILABILITY,Events.AVAILABILITY_BUSY)
Lp trnh Android c bn
.putExtra(Intent.EXTRA_EMAIL,rowan@example.com,
trevor@example.com);
startActivity(intent);
startActivity(intent);
Xem mt s kin.
ContentUris.appendId(builder, startMillis);
.setData(builder.build());
startActivity(intent);
223
Lp trnh Android c bn
Sau y l v d minh ha cch m mt s kin xem:
long eventID =208;
...
.setData(uri);
startActivity(intent);
return uri.buildUpon()
.appendQueryParameter(Calendars.ACCOUNT_NAME, account)
.appendQueryParameter(android.provider.CalendarContract.
CALLER_IS_SYNCADAPTER,true)
.appendQueryParameter(Calendars.ACCOUNT_TYPE, accountType).build();
224
Lp trnh Android c bn
d liu gia thit b v cc service trc tuyn. Provider ny ly thng tin t nhiu ngun
d liu v c gng qun l nhiu d liu nht c th cho tng c nhn (contact), nn kt
qu kh phc tp. Do vy, API ca provider ny cha mt tp lp contract ln, cng vi
l nhng giao din h tr c lc cho vic truy xut v chnh sa d liu.
Phn ny s gii thiu cc ni dung sau:
Cu trc c bn ca provider.
Raw Contact
(Thng tin lin
lc th)
Data
(D liu)
Raw Contact
(Thng tin lin
lc th)
Data
(D liu)
Raw Contact
(Thng tin lin
lc th)
Data
(D liu)
225
Lp trnh Android c bn
Ba bng ny thng c tham chiu bng tn cc lp contract ca chng. Nhng lp
ny nh ngha cc hng cho cc content URI, tn ct v gi tr ca ct c s dng
trong bng:
Bng ContactsContract.Contacts
Mi hng i din cho mt ngi, da trn s kt hp ca cc hng d liu lin
lc th.
Bng ContactsContract.RawContacts
Cc hng ny lu bn tm tt d liu ca mt ngi, c trng cho loi v ti
khon ca ngi dng.
Bng ContactsContract.Data
Hng cha thng tin chi tit v d liu lin lc th, chng hn nh a ch e-mail
hoc s in thoi.
Nhng bng cn li c i din bng cc lp contract trong ContactsContract
l nhng bng b tr m Provider Contacts dng qun l cc thao tc v h tr
nhng chc nng c th trong thng tin lin lc ca thit b hoc ng dng in thoi.
226
Lp trnh Android c bn
Bng 1. Cc ct d liu th quan trng.
Tn ct
Mc ch s dng
Ch thch
ACCOUNT_NAME
Tn ti khon ca loi ti
khon lm ngun cho thng tin
lin lc th ny. V d, tn ti
khon ca ti khon Google
l mt trong cc a ch Gmail
ca ch thit b. Xem mc tip
theo v ACCOUNT_TYPE
tm hiu thm.
nh dng ca tn ny c
trng cho loi ti khon ca n.
Khng nht thit phi l a ch
e-mail.
ACCOUNT_TYPE
DELETED
C xa ca mt lin lc th.
Ghi ch
Sau y l mt s lu quan trng v bng ContactsContract.RawContacts:
227
Lp trnh Android c bn
tn ti khon (becky.sharp@dataservice.example.com) ng dng
ca bn c th thm cc hng thng tin lin lc th. Bn c th gii thch yu cu
ny vi ngi dng trong ti liu hng dn, hoc c th nhc nh h thm loi v
tn, hay c hai. Mc tip theo m t chi tit hn v loi ti khon v tn ti khon.
emily.dickinson@gmail.com.
emilyd@gmail.com.
Ngi dng ny bt chc nng Sync Contacts (ng b thng tin lin lc) cho c ba ti
khon trong phn ci t Accounts (ti khon).
Gi s Emily Dickinson m mt ca s trnh duyt, ng nhp vo Gmail bng
ti khon emily.dickinson@gmail.com, m phn Contacts v thm vo
lin lc Thomas Higginson. Sau , c y ng nhp vo Gmail bng ti khon
emilyd@gmail.com v gi e-mail cho Thomas Higginson, vic ny s t ng
thm Thomas thnh mt lin lc. Emily cng a ti khon colonel_tom (ID
Twitter ca Thomas Higginson) vo Twitter.
Sau cc thao tc trn, Provider Contacts to ra ba d liu lin lc dng th:
1. Mt d liu lin lc dng th ca Thomas Higginson lin kt vi ti khon
emily.dickinson@gmail.com. Loi ti khon ca ngi dng l Google.
2. D liu lin lc th th hai ca Thomas Higginson lin kt vi ti khon emilyd@
gmail.com. Loi ti khon ca ngi dng ny cng l Google. Thm ch, c d
liu lin lc th th hai ging ht tn trong d liu lin lc th th nht, bi v ngi
ny c thm vo trong mt ti khon ngi dng khc.
3. D liu lin lc th th ba ca Thomas Higginson lin kt vi ti khon
belle_of_amherst. Ti khon ngi dng loi ny l Twitter.
D liu
Nh ghi ch mc trc, d liu ca lin lc th ban u c lu trong hng
ContactsContract.Data lin kt vi gi tr _ID ca d liu lin lc th. iu ny
cho php mt d liu th c nhiu th hin thuc cng mt loi d liu nh a ch
e-mail hoc s in thoi. V d, nu Thomas Higginson ca ti khon emilyd@
gmail.com (hng d liu lin lc th ca Thomas Higginson lin kt vi ti khon
Google emilyd@gmail.com) c mt a ch e-mail nh thigg@gmail.com v
mt e-mail cng vic thomas.higginson@gmail.com, Provider Contacts s lu
hai hng a ch e-mail v lin kt c hai vi d liu lin lc th.
Lu , cc loi d liu khc nhau u c lu trong bng ny. Tn hin th, s in
thoi, e-mail, a ch bu in, nh v cc hng chi tit v Website u c lu
trong bng ContactsContract.Data. gip qun l cc thng tin ny, bng
ContactsContract.Data cha vi ct c tn m t (descriptive name) v nhng
228
Lp trnh Android c bn
ct khc c tn chung chung (generic name). Ni dung ca ct tn m t c cng
ngha vi kiu d liu trong hng, trong khi ni dung ca ct tn chung chung c cc
ngha khc nhau ty theo kiu d liu.
Tn ct m t
Mt s v d v tn ct m t l:
RAW_CONTACT_ID
L gi tr ct _ID cho thng tin lin lc th ca d liu ny.
MIMETYPE
Loi d liu c lu trong hng ny l kiu MIME ty chnh. Provider
Contacts s dng nhng kiu MIME c nh ngha trong cc lp con ca
ContactsContract.CommonDataKinds. Nhng kiu MIME ny l m ngun
m (open source), c th c bt c ng dng hay adapter c chc nng ng
b no lm vic vi Provider Contacts s dng.
IS_PRIMARY
Nu c nhiu kiu hng d liu ny trong bng d liu cho mt thng tin lin lc
th, ct IS_PRIMARY t c vo hng d liu cha d liu chnh ca loi ny. V
d, nu ngi dng nhp s in thoi cho mt lin lc v chn Set default (thit
lp mc nh), hng ContactsContract.Data cha s in thoi ny c ct
IS_PRIMARY c t mt gi tr khc 0 (non-zero value).
Tn ct chung chung
C 15 ct chung chung c tn t DATA1 n DATA15 lun sn sng s dng v
bn ct chung chung b sung t SYNC1 n SYNC4 s c cc adapter c chc nng
ng b s dng. Cc hng tn ct chung chung lun c tc dng, bt k kiu d liu
trong hng l g.
Ct DATA1 l ct c nh ch mc. Provider Contacts lun s dng ct DATA1 cho
d liu m trnh ny mong mun cc truy vn s thng xuyn hng ti nht. V d,
trong hng e-mail, ct ny s cha a ch e-mail thc.
Theo quy c, ct DATA15 c dnh lu tr d liu BLOB, chng hn nh hnh
phc tho nh ca nh chp.
Tn ct c kiu xc nh
d lm vic vi cc ct c kiu d liu c th trn hng, Provider Contacts cng
cung cp hng tn ct c kiu xc nh (type-specific name), c nh ngha trong
lp con ContactsContract.CommonDataKinds. Nhng hng ny ch cung cp
cc tn hng khc nhau cho cng tn ct, gip bn truy cp d liu trong mt hng ca
mt kiu c th.
V d, lp ContactsContract.CommonDataKinds.Email nh ngha cc hng
tn ct c kiu xc nh cho mt hng ContactsContract.Data c kiu MIME l
229
Lp trnh Android c bn
Email.CONTENT_ITEM_TYPE. Lp ny c hng ADDRESS tng ng vi ct a ch
e-mail. Gi tr thc s ca ADDRESS l data1, chnh l tn chung chung ca ct.
Lu : Khng a thm d liu ty chnh ca bn vo bng ContactsContract.
Data bng cch s dng mt hng c mt trong cc kiu MIME nh ngha trc
ca content provider. Nu thc hin iu ny, bn c th lm mt d liu hoc khin
content provider b li. V d, bn khng nn thm hng vi kiu MIME l Email.
CONTENT_ITEM_TYPE cha tn ngi dng thay v a ch e-mail trong ct DATA1.
Nu s dng kiu MIME ty chnh ca mnh cho hng ny, bn c th thoi mi nh
ngha tn ct c kiu xc nh v s dng cc ct ny theo mun.
Hnh 2 minh ha cch b tr cc ct miu t v ct d liu trong hng
ContactsContract.Data, cng vi l cch tn ct c kiu xc nh ph ln
tn ct chung chung.
Address
a ch
Type
Loi
Lable
Nhn
Lp tn ct c kiu xc nh
Bng 2 di y lit k cc lp tn ct c kiu xc nh thng dng:
230
Lp trnh Android c bn
Bng 2. Cc lp tn ct c kiu xc nh.
Lp nh x
Kiu d liu
Ch thch
ContactsContract.
CommonDataKinds.
StructuredName
D liu tn ca lin lc
th c lin kt vi hng
d liu ny.
Mi d liu lin lc th
ch c duy nht mt
hng ny.
ContactsContract.
CommonDataKinds.
Photo
nh chnh ca d liu
lin lc th c lin kt vi
hng d liu ny.
Mi d liu lin lc th
ch c duy nht mt
hng ny.
ContactsContract.
CommonDataKinds.
Email
a ch e-mail ca d liu
lin lc th c lin kt vi
hng d liu ny.
Mt d liu th c th c
nhiu a ch e-mail.
ContactsContract.
CommonDataKinds.
StructuredPostal
a ch bu in ca d
liu th c lin kt vi
hng d liu ny.
Mt d liu th c th c
nhiu a ch bu in.
ContactsContract.
CommonDataKinds.
GroupMembership
Mt nh danh lin kt
d liu lin lc th vi
mt trong cc nhm ca
Provider Contacts.
Lin lc
Provider Contacts kt hp cc hng d liu lin lc th thng qua tt c cc loi ti
khon v tn ti khon to thnh mt lin lc (contact). iu ny gip hin th
v chnh sa d dng mi d liu m ngi dng c th thu thp cho mt ngi.
Provider Contacts qun l vic to cc hng lin lc mi, ng thi tng hp nhng
d liu lin lc th vi hng lin lc c. C ng dng ln adapter c chc nng
ng b u khng c php thm lin lc, v mt s ct ch c c (read-only)
trong hng lin lc.
Ghi ch: Nu c gng thm mt lin lc vo Provider Contacts bng phng thc
insert(), bn s nhn c ngoi l UnsupportedOperationException.
Nu bn c gng cp nht mt ct c thit lp l ch c, thao tc cp nht s
b b qua.
Provider Contacts to mt lin lc mi phn hi vic thm mt d liu lin lc th
mi khng trng vi bt k lin lc no hin c. Provider cng thc hin iu ny nu
d liu lin lc th c thay i da trn vic d liu ny khng cn khp vi lin lc
c thm vo trc . Nu mt ng dng hoc adapter c chc nng ng b
to mt d liu lin lc th mi trng vi lin lc hin c, d liu lin lc mi s c
kt hp vi lin lc hin c.
Provider Contacts lin kt mt hng lin lc vi cc hng d liu lin lc th ca n
bng ct _ID ca hng lin lc trong bng Contacts. Ct CONTACT_ID ca bng
231
Lp trnh Android c bn
d liu th ContactsContract.RawContacts cha gi tr _ID ca hng lin lc
c lin kt vi mi hng d liu lin lc th.
Bng ContactsContract.Contacts cng c ct LOOKUP_KEY l ct lin kt lu
di vi hng lin lc. Do Provider Contacts t ng qun l cc lin lc, nn trnh ny
c th thay i gi tr _ID ca mt hng lin lc phn hi mt s kt hp hoc ng
b. Thm ch, nu nhng thay i ny xy ra, content URI CONTENT_LOOKUP_URI
kt hp vi LOOKUP_KEY ca lin lc vn tr ti hng lin lc ny, nn bn c th s
dng gi tr LOOKUP_KEY duy tr lin kt ti nhng lin lc a thch, Ct ny c
nh dng ring khng lin quan ti nh dng ca ct _ID.
Hnh 3 minh ha cch ba bng chnh lin kt vi nhau.
Contacts
Lin lc
Rawcontacts
Lin lc th
StructuredName
Tn c cu trc
Data
D liu
232
Lp trnh Android c bn
233
Lp trnh Android c bn
People app
ng dng ca mi ngi
App
ng dng
Contacts provider
Provider Contacts
Sync adapters
Cc quyn bt buc
ng dng mun truy cp Provider Contacts phi yu cu cc quyn sau:
Quyn c ti mt hoc nhiu bng
Quyn READ_CONTACTS, c xc nh trong file AndroidManifest.
xml vi phn t <use-permission> v d <uses-permission
android:name=android.permission.READ_CONTACTS>.
Quyn ghi ti mt hoc nhiu bng
Quyn WRITE_CONTACTS, c xc nh trong file AndroidManifest.
xml bng phn t <uses-permission> nh l <uses-permission
android:name=android.permission.WRITE_CONTACTS>.
Nhng quyn ny khng p dng cho user profile (h s thng tin ngi dng).
User profile v cc quyn bt buc ca n c miu t chi tit mc bn di,
User Profile.
Hy nh rng, d liu lin lc ca ngi dng l thng tin c nhn, c tnh cht nhy
cm. Ngi dng lo ngi v tnh ring t, nn h khng mun cc ng dng thu thp
d liu v nhng thng tin ny hay cc lin lc ca h. Nu khng a ra l do r rng
v vic ti sao bn cn quyn truy cp vo d liu lin lc ca ngi dng, h s nh
gi thp ng dng ca bn hoc n gin l t chi ci t ng dng ny.
234
Lp trnh Android c bn
User Profile
Bng ContactsContract.Contacts c mt hng cha d liu v profile cho
ngi dng thit b. D liu ny m t ngi dng thit b, ch khng phi l mt trong
nhng lin lc ca h. Hng profile c lin kt vi hng d liu th tng ng ca
tng h thng s dng profile. Mi profile th c th cha nhiu hng d liu. Cc hng
truy cp user profile nm trong lp ContactsContract.Profile.
Truy cp vo user profile cn cc quyn c bit. Ngoi quyn READ_CONTACTS
v WRITE_CONTACTS c v ghi, bn cn cn thm quyn READ_PROFILE v
WRITE_PROFILE truy cp c v ghi vo user profile.
Hy nh rng, bn phi tnh n thc t rng user profile l d liu nhy cm. Quyn
READ_PROFILE cho php bn truy cp d liu c nhn ca ngi dng thit b. Hy
m bo bn thng bo y ti ngi dng v l do bn cn quyn truy cp vo
user profile trong phn m t ca ng dng m bn pht trin.
truy xut vo hng cha user profile trong bng ContactsContract.
Contacts, gi phng thc ContentResolver.query(). Thit lp content URI
l CONTENT_URI v khng cung cp bt c iu kin chn no. Bn cng c th s
dng content URI lm URI c s truy xut d liu lin lc th hoc d liu cho user
profile. V d, on m nh di y truy xut d liu profile:
// Thit lp cc ct truy xut ly user profile
mProjection =newString[]
{
Profile._ID,
Profile.LOOKUP_KEY,
};
Profile.DISPLAY_NAME_PRIMARY,
Profile.PHOTO_THUMBNAIL_URI
getContentResolver().query(
Profile.CONTENT_URI,
null,
mProjection ,
null,
null);
235
Lp trnh Android c bn
Ct
ContactsContract. DIRTY
RawContacts
Gi tr
ngha
0 - khng
thay i k
t ln ng
b cui.
nh du d liu lin lc th c
thay i trn thit b v cn c
ng b tr li server. Gi tr ny
c Provider Contacts thit lp t
ng khi ng dng Android cp nht
mt hng.
Adapter c chc nng ng b
chnh sa d liu lin lc th hoc
bng d liu lun phi gn chui
CALLER_IS_SYNCADAPTER vo
content URI m adapter ny s
dng. iu ny trnh cho provider
khi vic nh du hng l dirty
(cha c cp nht). Nu khng,
vic chnh sa ca adapter c chc
nng ng b ch mang ngha l
thay i cc b v c gi ti
server, ngay c khi server l ngun
chnh sa.
1 - thay
i k t
ln ng b
cui,
cn
c ng
b tr li
server.
ContactsContract. VERSION
RawContacts
236
Lp trnh Android c bn
Bng
Ct
Gi tr
ngha
n nh (stable): Cc id ngun
l phn bn vng ca d liu
service trc tuyn cho d liu lin
lc th. V d, nu ngi dng
xa b nh lu tr thng tin lin
lc (Contacts Storage) t ni ci
t ng dng, sau ti ng b,
d liu lin lc th c khi phc
li s c cng id ngun nh trc
. Nu bn khng tun theo tnh
cht ny, biu tng shortcut s
ngng hot ng.
237
Lp trnh Android c bn
Bng
Ct
Gi tr
ngha
ContactsContract. U
N
- 0 - Vi Mc nh, cc lin lc b n nu
Settings
GROUPED_ ti
khon khng c lin lc th no ca
VISIBLE
v loi ti chng thuc v mt nhm (thng
khon ny,
cc lin lc
khng nm
trong nhm
s ch
n (invisible)
vi giao din
ngi dng
ng
dng
Android.
1 - Vi
ti
khon
v loi ti
khon ny,
cc lin lc
khng nm
trong nhm
c hin
th
trong
giao
din
ngi dng
ng dng.
238
CommonDataKinds.
GroupMembership trong bng
ContactsContract.Data ch ra).
Bng cch thit lp c ny trong hng
ca bng ContactsContract.
Settings cho mt ti khon v mt
loi ti khon, bn c th quy c
nhng lin lc khng cn nhm c
hin th. Mt tc dng ca c ny l
hin th lin lc t server m khng
cn s dng nhm.
Lp trnh Android c bn
Bng
Ct
ContactsContract. (tt c
SyncState
cc
ct)
Gi tr
ngha
S
dng
bng
ny
lu siu
d liu cho
adapter c
chc nng
ng b.
Vi bng ny, bn c th lu li
trng thi ng b v cc d liu lin
quan n ng b khc mt cch
lu di trn thit b.
Vic thc hin chnh sa t adapter c chc nng ng b s c gii thiu chi tit
hn trong mc Adapter c chc nng ng b ca Provider Contacts.
Cc thc th truy vn
Do cc bng ca Provider Contacts c t chc trong mt h thng phn cp,
nn vic truy vn mt hng v tt c cc hng con c lin kt vi n rt thun
li. V d, hin th ton b thng tin v mt ngi, bn c th mun truy xut
tt c cc hng ca bng ContactsContract.RawContacts c lin quan n
mt hng trong bng ContactsContract.Contacts, hoc tt c cc hng trong bng
ContactsContract.CommonDataKinds.Email c lin quan n mt hng
trong bng ContactsContract.RawContacts. thc hin iu ny mt cch
d dng, Provider Contacts cung cp cu trc thc th (entity), ng vai tr tng t
nhng lin kt c s d liu gia cc bng.
Mt thc th ging nh mt bng cha cc ct c chn t bng cha v bng con ca n.
Khi truy vn mt thc th, bn cung cp mt php chiu v iu kin chn da trn nhng
ct c sn trong thc th. Kt qu s l mt Cursor cha mt hng cho mi hng ca bng
con c truy xut. V d, nu truy vn ContactsContract.Contacts.Entity
ly mt tn lin lc v tt c hng ContactsContract.CommonDataKinds.Email
ca ton b d liu lin lc th c tn ny, bn s nhn v mt Cursor cha mt hng cho
mi hng trong bng ContactsContract.CommonDataKinds.Email.
Cc thc th gip n gin ha truy vn. S dng mt thc th, bn c th cng lc
truy xut tt c d liu lin lc ca mt lin lc hoc d liu lin lc th, thay v phi truy
vn trn bng cha trc ly ID, sau thc hin truy vn bng con bng ID ny.
Ngoi ra, Provider Contacts thc hin truy vn trn mt thc th trong mt giao dch
(transaction) n, iu ny m bo d liu truy xut c cu trc n nh.
239
Lp trnh Android c bn
Ghi ch: Mt thc th thng khng cha tt c cc ct ca bng cha v bng con.
Nu th lm vic vi mt tn ct khng nm trong danh sch hng tn ct ca thc
th, bn s nhn v mt Exception (ngoi l).
on m nh sau minh ha cch truy xut tt c cc hng d liu th ca mt lin lc.
on m nh ny l mt phn trong mt ng dng ln hn, ng dng gm hai activity
l activity chnh v activity chi tit. Activity chnh hin th danh sch cc hng lin lc;
khi ngi dng chn mt hng, activity ny s gi li ID ca hng ti activity chi tit.
Activity chi tit s dng ContactsContract.Contacts.Entity hin th tt c
cc hng d liu t nhng lin lc th tng ng vi lin lc chn.
on m nh di y minh ha activity chi tit:
...
/*
* content://com.google.contacts/#/entity (# l gi tr ID).
*/
mContactUri =Uri.withAppendedPath(
mContactUri,
ContactsContract.Contacts.Entity.CONTENT_DIRECTORY);
LOADER_ID,
null,
this);
this,
// ng cnh ca activity
mCursor,
mToViews,
0);
240
// cc ct trong con tr s
// cung cp d liu
// cc view ca mc view
// hin th d liu
// c
mRawContactList.setAdapter(mCursorAdapter);
Lp trnh Android c bn
...
@Override
* Thit lp ct ly d liu.
* RAW_CONTACT_ID c a vo xc nh d liu
* lin lc th lin kt vi hng d liu.
* DATA1 cha ct u tin ca hng d liu
* (thng l ct quan trng nht).
*/
String[] projection =
ContactsContract.Contacts.Entity.RAW_CONTACT_ID,
ContactsContract.Contacts.Entity.MIMETYPE
};
ContactsContract.Contacts.Entity.DATA1,
/*
*/
String sortOrder =
ContactsContract.Contacts.Entity.RAW_CONTACT_ID +
ASC;
/*
*/
projection,
// Cc ct ly gi tr
null,
null,
sortOrder);
// lin lc n
// Sp xp theo ID ca d liu
// lin lc th.
241
Lp trnh Android c bn
Khi hon thnh vic np d liu, LoaderManager (trnh qun l vic np) gi
phng thc callback onLoadFinished(). Mt trong nhng i s ca phng
thc ny l mt Cursor kt qu ca truy vn. Trong ng dng ca mnh, bn c th
ly d liu t Cursor ny hin th n hoc thc hin cc thao tc khc.
Cc im trung chuyn
Chnh sa hng lot cha s lng thao tc ln c th chn cc tin trnh khc, v ton
cc s khin ngi dng khng thoi mi. t chc tt c cc chnh sa bn mun
thnh mt vi danh sch tch bit, ng thi trnh lm chm h thng, bn nn t mt
vi im trung chuyn (yield point) cho mt hoc nhiu thao tc. im trung chuyn
l i tng ContentProviderOperation c gi tr isYieldAllowed() thit
lp l true. Khi Provider Contacts gp mt im trung chuyn, n dng thao tc
cc tin trnh khc chy v ng giao dch hin ti li. Khi content provider khi ng
tr li, provider ny s tip tc vi thao tc tip theo trong ArrayList v bt u tin
hnh mt giao dch mi.
im trung chuyn to ra nhiu giao dch trn mi li gi phng thc applyBatch().
Do vy, bn nn thit lp im trung chuyn cho thao tc cui ca tp cc hng lin kt.
V d, bn nn thit lp cho thao tc cui mt im trung chuyn cho tp lnh thm cc
hng d liu lin lc th v nhng hng d liu lin quan ca n, hoc thao tc cui
cho tp cc hng lin h vi mt lin lc n.
im trung chuyn cng l mt n v thao tc n. Tt c cc truy cp gia hai im
trung chuyn s thnh cng hoc tht bi ging nh mt n v n. Nu bn khng thit
lp bt c im trung chuyn no, thao tc n nh nht s l ton b thao tc ca nhm
lnh (batch). Nu s dng im trung chuyn, bn s trnh c cc thao tc lm gim
hiu sut ca h thng, trong khi vn m bo c rng tp con ca cc thao tc l n.
242
Lp trnh Android c bn
iu ny, lp ContentProviderOperation.Builder cung cp phng thc
withValueBackReference(). Phng thc ny cho php bn chn hoc chnh
sa mt ct trn kt qu ca thao tc trc .
Phng thc withValueBackReference() c hai i s:
key
Kha ca cp kha-gi tr. Gi tr ca i s ny phi l tn mt ct trong bng bn
ang chnh sa.
previousResult
Ch s bt u t 0 ca mt gi tr trong mng cc i tng
ContentProviderResult tr v t phng thc applyBatch(). Khi cc
thao tc ca nhm c p dng, kt qu ca mi thao tc c lu trong mt
mng kt qu trung gian. Gi tr previousResult l ch s ca mt trong
nhng kt qu ny, c truy xut v lu tr bng gi tr key. iu ny cho php
bn chn mt bn ghi lin lc th mi v ly v gi tr _ID ca bn ghi ny, sau
thc hin mt tham chiu li (back reference) gi tr khi bn thm hng
ContactsContract.Data.
Mng cha ton b kt qu c to ra khi bn gi phng thc applyBatch()
ln u, vi kch thc bng kch thc ArrayList ca cc i tng
ContentProviderOperation m bn cung cp. Tuy nhin, tt c cc phn t ca
mng kt qu c thit lp l null, v nu bn c gng lm mt tham chiu li ti kt qu
ca mt thao tc cha c p dng, phng thc withValueBackReference()
nm ra mt ngoi l Exception.
on m nh sau minh ha cch chn mt d liu lin lc th mi v d liu trong nhm.
on m ny bao gm m thit lp mt im trung chuyn v s dng mt tham chiu
li. on m sau l phin bn m rng ca phng thc createContactEntry(),
l mt phn ca lp ContactAdder trong ng dng mu Contact Manager.
on m u truy xut d liu lin lc t giao din ngi dng. Lc ny, ngi dng
chn mt ti khon thm d liu th mi vo.
// To mt mc lin lc t cc gi tr trn giao din ngi dng
// hin ti, s dng ti khon ang c chn.
protected void createContactEntry() {
/*
*/
mContactPhoneTypeSpinner.getSelectedItemPosition());
mContactEmailTypeSpinner.getSelectedItemPosition());
243
Lp trnh Android c bn
on m nh tip theo s to mt thao tc chn hng d liu lin lc th vo bng
ContactsContract.RawContacts:
/*
*
*
*
*
*
*
*/
new ArrayList<ContentProviderOperation>();
/*
*
*
*
*
*/
ContentProviderOperation.Builder op =
ContentProviderOperation.newInsert(ContactsContract.
RawContacts.CONTENT_URI)
.withValue(ContactsContract.RawContacts.ACCOUNT_TYPE,
mSelectedAccount.getType())
.withValue(ContactsContract.RawContacts.ACCOUNT_NAME,
mSelectedAccount.getName());
244
Lp trnh Android c bn
op = ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
/*
*/
.withValueBackReference(ContactsContract.Data.RAW_
CONTACT_ID,0)
ContactsContract.CommonDataKinds.StructuredName.
CONTENT_ITEM_TYPE)
.withValue(ContactsContract.CommonDataKinds.
StructuredName.DISPLAY_NAME, name);
op = ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
/*
* Thit lp gi tr ca ct id lin lc th l gi tr ID
lin lc th c thao tc u tin ca nhm tr v.
*/
.withValueBackReference(ContactsContract.Data.RAW_
CONTACT_ID,0)
ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE)
.withValue(ContactsContract.CommonDataKinds.Phone.NUMBER, phone)
.withValue(ContactsContract.CommonDataKinds.Phone.TYPE, phoneType);
245
Lp trnh Android c bn
op = ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
/*
.withValueBackReference(ContactsContract.Data.RAW_
CONTACT_ID,0)
ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE)
.withValue(ContactsContract.Data.MIMETYPE,
// Thit lp a ch e-mail v kiu
.withValue(ContactsContract.CommonDataKinds.Email.
ADDRESS, email)
.withValue(ContactsContract.CommonDataKinds.Email.TYPE,
emailType);
/*
*/
op.withYieldAllowed(true);
ops.add(op.build());
mSelectedAccount.getType()+));
/*
*/
try {
getContentResolver().applyBatch(ContactsContract.
AUTHORITY, ops);
246
}catch(Exception e){
Lp trnh Android c bn
CharSequence txt =
toast.show();
getString(R.string.contactCreationFailure);
247
Lp trnh Android c bn
Nu hng d liu lin lc th c mt thao tc khc cp nht trong thi
gian bn c hng ny v thi im bn th chnh sa hng, vic xc nhn
ContentProviderOperation s b li, ton b nhm thao tc s b li li. Sau ,
bn c th chn th li nhm hoc thc hin mt s thao tc khc.
on m nh di y minh ha cch to xc nhn ContentProviderOperation
sau khi truy vn mt d liu lin lc th n bng cch s dng CursorLoader:
/*
mRawContactID = cursor.getLong(cursor.getColumnIndex(BaseColumns._ID));
mVersion = cursor.getInt(cursor.getColumnIndex(SyncColumns.
VERSION));
}
...
// Thit lp Uri cho thao tc xc nhn
assertOp.withValue(SyncColumns.VERSION, mVersion);
assertOp.withExpectedCount(1);
248
Lp trnh Android c bn
try
ContentProviderResult[] results =
getContentResolver().applyBatch(AUTHORITY, ops);
}catch(OperationApplicationException e){
Nu ngi dng ang chn hoc cp nht d liu, bn c th thu thp d liu ny
trc, sau gi chng i nh mt phn ca intent.
Khi s dng intent truy cp Provider Contactsthng qua ng dng lin lc ca thit
b, bn khng phi xy dng giao din ngi dng ca mnh v m truy cp provider
ny. Bn cng khng phi yu cu quyn c v ghi vo provider. ng dng lin lc
ca thit b c th cp quyn c mt lin lc cho bn, v do ang thc hin chnh sa
provider thng qua ng dng khc, nn bn khng cn ti quyn ghi.
Tin trnh chung gi mt intent nhm truy cp provider c m t chi tit trong mc
hng dn C bn v content provider, phn Truy cp d liu thng qua intent. Action,
kiu MIME v gi tr d liu bn s dng cho cc tc v c bn c tng kt trong Bng
4. Ngoi ra, cc gi tr ph tr m bn c th s dng vi phng thc putExtra() c
lit k trong ti liu tham kho ca ContactsContract.Intents.Insert:
249
Lp trnh Android c bn
Bng 4. Cc intent ca Provider Contacts.
Thao
tc
Hnh ng
D liu
Kiu MIME
Ly ra
mt lin
lc t
danh
sch
ACTION_PICK
Khng s dng.
Contacts.CONTENT_URI,
hin th danh sch cc lin
lc.
P h o n e . C O N T E N T _ U R I ,
hin th danh sch cc s
in thoi ca mt d liu
lin lc th.
S t r u c t u r e d P o s t a l .
CONTENT_URI, hin th
danh sch cc a ch bu
in ca mt d liu lin lc
th.
E m a i l . C O N T E N T _ U R I ,
hin th danh sch cc a ch
e-mail ca mt d liu lin lc
th.
Chn
mt d
liu lin
lc th
mi
Insert.ACTION
Chnh
sa mt
lin lc
ACTION_EDIT
Hin th
mt View
cho php
ngi
dng
chn
thng tin
(c th
thm
thng
tin vo
View)
A C T I O N _
INSERT_OR_
EDIT
250
Khng c.
RawContacts.
CONTENT_TYPE,
kiu MIME ca
tp d liu lin
lc th.
ca
lin lc ny. Activity chnh sa
s cho php ngi dng sa
bt k d liu no lin kt vi
lin lc ny.
Contacts.
CONTENT_
ITEM_TYPE,
Khng c.
CONTENT_
ITEM_TYPE
CONTENT_LOOKUP_URI
mt lin lc n.
Lp trnh Android c bn
ng dng lin lc ca thit b khng cho php bn xa mt d liu lin lc th hay
bt k d liu no ca lin lc ny bng intent. Thay vo , ng dng cho php bn
xa d liu lin lc th bng cch s dng ContentResolver.delete() hoc
ContentProviderOperation.newDelete().
on m nh di y minh ha cch xy dng v gi mt intent c chc nng chn
d liu lin lc th v d liu mi:
// Ly gi tr t giao din ngi dng
insertIntent.setType(ContactsContract.RawContacts.CONTENT_TYPE);
// Thit lp tn lin lc mi
insertIntent.putExtra(ContactsContract.Intents.Insert.NAME, name);
// Thit lp tn cng ty v ngh nghip mi
insertIntent.putExtra(ContactsContract.Intents.Insert.COMPANY,
company);
insertIntent.putExtra(ContactsContract.Intents.Insert.JOB_TITLE,
jobtitle);
/*
251
Lp trnh Android c bn
rawContactRow.put(ContactsContract.RawContacts.ACCOUNT_TYPE,
mSelectedAccount.getType());
rawContactRow.put(ContactsContract.RawContacts.ACCOUNT_NAME,
mSelectedAccount.getName());
// a hng vo mng
contactData.add(rawContactRow);
/*
ContactsContract.Data.MIMETYPE,
);
ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE
phoneRow.put(ContactsContract.CommonDataKinds.Phone.NUMBER, phone);
// a hng ny vo mng
contactData.add(phoneRow);
/*
ContactsContract.Data.MIMETYPE,
);
ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE
emailRow.put(ContactsContract.CommonDataKinds.Email.ADDRESS, email);
// a hng vo mng
contactData.add(emailRow);
252
Lp trnh Android c bn
/*
insertIntent.putParcelableArrayListExtra(ContactsContract.Intents.
Insert.DATA, contactData);
// Gi intent i khi ng ng dng lin lc ca
253
Lp trnh Android c bn
254
Lp trnh Android c bn
trc tuyn v chui nh danh cho content provider ny, hai thng tin trn cng xc nh
duy nht mt adapter. Adapter c chc nng ng b ch c kch hot cho n khi
ngi dng thm mt ti khon vo loi ti khon ca adapter ny v cho php ng
b content provider. Ti im ny, h thng khi ng vic qun l adapter, gi phn
ny khi cn thit ng b gia providerv server.
Ghi ch: S dng loi ti khon lm mt phn nhn din adapter c chc nng
ng b cho php h thng pht hin v nhm nhng adapter truy cp cc service
khc nhau t cng mt t chc. V d, cc ti khon ca cc adapterr c chc nng
ng b ca service trc tuyn Google c cng loi ti khon l com.google. Khi
ngi dng thm mt ti khon Google vo thit b ca h, tt c cc adapter c chc
nng ng b ci t ca service Google c lit k cng nhau; trong , mi
adapter c chc nng ng b c lit k cng vi mt content provider trn thit b.
Do hu ht service u yu cu ngui dng phai xc thc nhn dang cua ho truc
khi truy cp d liu, nn h thng Android cung cp framework xc thc tng t nh
vy v cung thung uc s dung kt hp cng framework adapter c chc nang
ng b. Framework xc thc s dung trnh xc thc plug-in, cung l lp con cua
lp AbstractAccountAuthenticator. Trnh xc thc kim tra nhn dang ngui
dng theo cc buc sau:
1. Thu thp tn v mt khu ngi dng hoc thng tin tng t thng tin c nhn
ca ngi dng.
2. Gi thng tin c nhn ti service.
3. Kim tra hi p ca service.
Nu service chp nhn thng tin ny, trnh xc thc c th lu thng tin ny li s
dng v sau. Nh plug-in framework xc thc, AccountManager c th cung cp
truy cp ti bt k m thng bo xc thc (authtoken) no m trnh xc thc h tr v
chn cung cp, chng hn nh m thng bo xc thc OAuth2.
Mc d vic xc thc khng bt buc, nhng hu ht service lin lc u s dng yu
cu ny. Tuy nhin, bn khng bt buc phi s dng framework xc thc ca Android
tin hnh xc thc.
com.example.android.samplesync.syncadapter.SyncService.
255
Lp trnh Android c bn
Adapter c chc nng ng b thc s, c ci t nh mt lp con c th ca lp
AbstractThreadedSyncAdapter.
Lp ny thc hin ti d liu t server, y d liu t thit b ln server v gii
quyt xung t. Cng vic chnh ca adapter c thc hin trong phng thc
onPerformSync(). Lp ny phi c khi to di dng mt Singleton (lp
ch c duy nht mt i tng).
Trong ng dng mu Sample Sync Adapter, adapter c chc nng
ng b c nh ngha ti lp com.example.android.samplesync.
syncadapter.SyncAdapter.
Mt lp con ca lp Application.
Lp ny hot ng ging nhnh my cho ch mt adapter duy nht c chc nng
ng b. S dng phng thc onCreate() khi to adapter, ng thi cung
cp phng thc truy cp get tnh (phng thc c ci t tr v thuc tnh
ca i tng) tr v singleton cho phng thc onBind() ca service adapter c
chc nng ng b.
Ty chn: Thnh phn Service phn hi yu cu t h thng xc thc
ngi dng.
com.example.android.samplesync.authenticator.
AuthenticationService.
Ty chn: Mt lp con c th ca lp AbstractAccountAuthenticator
x l yu cu xc thc.
Lp ny cung cp cc phng thc m AccountManager s dng xc thc
thng tin c nhn ca ngi dng vi server. Chi tit v tin trnh x l xc thc
mi ni mt khc, ph thuc vo k thut m server s dng. Bn nn tham kho
ti liu v phn mm server ca mnh tm hiu thm v xc thc.
Trong ng dng mu Sample Sync Adapter, trnh xc thc c nh ngha trong lp
com.example.android.samplesync.authenticator.Authenticator.
256
Lp trnh Android c bn
ACCOUNT_TYPE
Bt buc. Loi ti khon ngi dng ca d liu lin lc th lin kt vi hng mc
lung ny. Hy nh thit lp gi tr ny khi bn chn mt hng mc lung.
ACCOUNT_NAME
Bt buc. Tn ti khon ngi dng ca lin lc th lin kt vi hng mc lung
ny. Bn nh thit lp gi tr ny khi chn mt hng mc lung.
Cc ct nh danh
Bt buc. Bn phi chn cc ct nh danh (identifier column) khi chn mt hng
mc lung mi:
COMMENTS
Ty chn (khng bt buc). Lu thng tin tng kt m bn c th hin th u
mt hng mc lung.
257
Lp trnh Android c bn
TEXT
Vn bn ca hng mc lung, hoc l ni dung c ngun hng mc ng, hoc
m t mt vi hot ng to ra hng mc lung ny. y l ct c th cha bt
c nh dng v cc hnh nh ngun c nhng vo no, sao cho phng thc
fromHtml() c th hin th c. Provider c th ct bt (truncate) hoc ellipsize
(ct bt ni dung v du chm lng) ni dung di, nhng s c gng trnh lm
v cc th (tag).
TIMESTAMP
Chui vn bn cha thi gian m hng mc lung c chn hoc cp nht, thi
gian c biu din di dng mili giy tnh t epoch. ng dng chn hoc cp
nht cc hng mc lung c trch nhim to v cp nht ct ny; y cng l ct
khng c Provider Contactsduy tr t ng.
hin th thng tin nhn dng cho cc hng mc lung ca bn, s dng
RES_ICON, RES_LABEL v RES_PACKAGE lin kt cc ngun d liu
trong ng dng ca bn.
Bng ContactsContract.StreamItems cng cha cc ct t SYNC1 n
SYNC4 dnh ring cho nhng adapter c chc nng ng b.
PHOTO_FILE_ID
L mt con s, nh danh nh ca mt d liu lin lc th. Gn gi tr ny vo
hng DisplayPhoto.CONTENT_URI c content URI tr ti mt file
nh n, sau gi phng thc openAssetFileDescriptor() ly
x l trn file nh.
PHOTO_URI
Mt content URI trc tip tr ti file nh ca nh m hng ny i din. Gi phng
thc openAssetFileDescriptor() vi URI ny ly x l trn file nh.
258
Lp trnh Android c bn
Lp ContactsContract.StreamItems.StreamItemPhotos nh ngha mt
bng con ca ContactsContract.StreamItemPhotos cha cc hng nh cho
mt hng mc lung n.
259
Lp trnh Android c bn
Vic ng b nh k cc hng mc lung vi Provider Contactscng ging nh nhng
ng b khc. tm hiu thm v ng b, xem mc Adapter c chc nng ng b
ca Provider Contacts. Cch ng k thng bo v tnh nng invite contact c gii
thiu trong hai mc tip theo.
android=http://schemas.android.com/apk/res/android>.
Nu c phn t trn, hy b qua bc ny.
3. ng k service nhn thng bo khi ngi dng m trang thng tin chi tit
ca lin lc trn ng dng lin lc ca thit b, thm thuc tnh viewContact
NotifyService=serviceclass vo phn t trn, vi serviceclass
l tn lp y ca service nhn intent t ng dng lin lc ca thit b. Vi
service thng bo ny, hy s dng lp m rng IntentService, nhm cho
php service nhn intent. D liu trong intent ti cha content URI ca d liu
lin lc th m ngi dng nhn vo. Nh service thng bo, bn c th lin
kt vi adapter c chc nng ng b, sau gi adapter ny cp nht d
liu cho d liu lin lc th.
ng k activity c gi khi ngi dng nhn vo hng mc lung hay nh, hoc
c hai:
1. To mt file c tn contacts.xml trong th mc res/xml/ ca d n. Nu
c file trn, hy b qua bc ny.
2. Trong file ny, thm vo phn t <ContactsAccountType xmlns:
android=http://schemas.android.com/apk/res/android>.
Nu c phn t trn, hy b qua bc ny.
260
Lp trnh Android c bn
Intent ti cha content URI ca hng mc hoc nh m ngi dng nhn vo.
c cc activity ring bit cho hng mc vn bn v nh, hy s dng cc thuc tnh
trong cng mt file.
xmlns:android=http://schemas.android.com/apk/res/android>.
Nu c phn t trn, hy b qua bc ny.
inviteContactActivity=activityclass
oo
inviteContactActionLabel=@string/invite_action_label
Phn t <ContactsAccountType>
Phn t <ContactsAccountType> iu khin vic tng tc ca ng dng bn
pht trin vi ng dng lin lc. C php ca phn t ny nh sau:
<ContactsAccountType
xmlns:android=http://schemas.android.com/apk/res/android
inviteContactActionLabel=invite_command_text
inviteContactActivity=activity_name
viewContactNotifyService=view_notify_service
viewGroupActivity=group_view_activity
viewStreamItemActivity=viewstream_activity_name
viewGroupActionLabel=group_action_text
viewStreamItemPhotoActivity=viewphotostream_activity_name>
261
Lp trnh Android c bn
c lu trong:
res/xml/contacts.xml
C th bao gm phn t:
<ContactsDataKind>
M t:
Khai bo cc thnh phn ca Android v cc nhn trn giao din ngi dng cho php
ngi dng mi mt trong cc lin lc ca h vo mng x hi, thng bo vi ngi
dng khi mt trong nhng lung mng x hi ca h c cp nht,
Lu , khng cn s dng tin t thuc tnh android: cho thuc tnh
<ContactsAccountType>.
Thuc tnh:
inviteContactActivity
Tn lp y ca activity trong ng dng ca bn, l activity bn mun kch hot
khi ngi dng chn mc Add connection t ng dng lin lc ca thit b.
inviteContactActionLabel
Chui vn bn hin th cho activity, c xc nh trong thuc tnh
inviteContactActivity, trn menu Add connection. V d, bn c th s
dng chui Follow in my network (Theo di trong mng ca ti). Bn c th s
dng mt nh danh ti nguyn dng chui cho nhn ny.
viewContactNotifyService
Tn lp y ca mt service trong ng dng ca bn, l service s nhn thng
bo khi ngi dng hin th lin lc. Thng bo ny c ng dng lin lc ca
thit b gi i; vic ny cho php ng dng ca bn c th hon cc thao tc cn
nhiu d liu cho n khi cn thit. V d, ng dng ca bn c th phn hi thng
bo ny bng vic c cng nh hin th nh c phn gii cao v hng mc
lung mng x hi gn y nht ca lin lc. Mc Tng tc vi lung mng x
hi m t chi tit hn v tnh nng ny. Bn c th xem mt v d v service thng
bo trong file NotifierService.java ca ng dng mu SampleSyncAdapter.
viewGroupActivity
viewGroupActionLabel
Nhn m ng dng lin lc hin th cho iu khin giao din ngi dng, l iu
khin cho php ngi dng xem cc nhm trong ng dng ca bn.
262
Lp trnh Android c bn
vng hin th cc lin lc Google+, s xut hin mt biu tng ca Google+; nu
bn nhn vo biu tng ny, iu khin s c chuyn hng sang ng dng
Google+. ng dng lin lc lm c iu ny thng qua viewGroupActivity,
s dng biu tng Google+ lm gi tr cho viewGroupActionLabel.
Thuc tnh ny cng c th s dng mt nh danh ti nguyn dng chui.
viewStreamItemActivity
Tn lp y ca activity trong ng dng ca bn m ng dng lin lc khi ng
khi ngi dng nhn vo mt hng mc lung ca d liu lin lc th.
viewStreamItemPhotoActivity
Tn lp y ca activity trong ng dng m ng dng lin lc khi ng khi
ngi dng nhn vo mt nh trong hng mc lung ca d liu lin lc th.
Phn t <ContactsDataKind>
Phn t <ContactsDataKind> iu khin vic hin th cc hng d liu ty chnh
cho ng dng bn pht trin trong giao din ngi dng ca ng dng lin lc. Phn
t ny c c php nh sau:
<ContactsDataKind
android:mimeType=MIMEtype
android:icon=icon_resources
android:summaryColumn=column_name
android:detailColumn=column_name>
nm trong:
<ContactsAccountType>
M t:
S dng phn t ny ng dng lin lc hin th ni dung ca hng d liu ty
chnh lm mt phn trong cc thng tin chi tit ca d liu lin lc th. Mi phn t
con <ContactsDataKind> ca <ContactsAccountType> i din cho mt kiu
hng d liu ty chnh m adapter c chc nng ng b ca bn thm vo bng
ContactsContract.Data. Thm mt phn t <ContactsDataKind> vo mi
kiu MIME ty chnh bn s dng. Bn khng phi thm phn t ny nu y l hng
d liu ty chnh m bn khng mun hin th d liu.
Thuc tnh:
android:mimeType
Kiu MIME ty chnh m bn nh ngha cho mt trong nhng kiu hng d
liu ty chnh ca mnh ti bng ContactsContract.Data . V d, gi tr
vnd.android.cursor.item/vnd.example.locationstatus c th l
kiu MIME ty chnh cho hng d liu ghi li v tr mi nht ca lin lc.
263
Lp trnh Android c bn
android:icon
Mt ti nguyn drawable (drawable resource) ca Android m ng dng lin lc
hin th bn cnh d liu ca bn. S dng thuc tnh ny ch cho ngi dng
bit rng d liu n t service ca bn.
android:summaryColumn
Tn ct ca gi tr u tin trong hai gi tr c truy xut t hng d liu. Gi tr
ny khi c hin th l dng u tin ca mc cho hng d liu ny. Hng u tin
c mc ch s dng l thng tin tng kt ca d liu, nhng l d liu ty chn (c
th c hoc khng). Xem thm thuc tnh android:detailColumn.
Android:detailColumn
Tn ct ca gi tr th hai trong hai gi tr c truy xut t hng d liu. Gi tr
ny c hin th l dng th hai ca mc cho hng d liu ny. Xem thm thuc
tnh android:summaryColumn.
Nhm lin lc
Provider Contactsc th gn nhn ty chn cho tp cc lin lc lin quan thnh d liu
nhm (group). Nu server lin kt vi ti khon ngi dng mun duy tr cc nhm,
adapter c chc nng ng b ca loi ti khon ny phi truyn d liu nhm gia
Provider Contactsv server. Khi ngi dng thm mt lin lc mi vo server, sau
a lin lc ny vo mt nhm mi, adapter c chc nng ng b phi thm nhm
mi vo bng ContactsContract.Groups. Nhm hoc cc nhm cha mt d
liu lin lc th c lu trong bng ContactsContract.Data, s dng kiu MIME
ContactsContract.CommonDataKinds.GroupMembership.
Nu bn ang thit k mt adapter c chc nng ng b thm d liu lin lc
th t server vo Provider Contacts, ng thi ang khng s dng nhm, bn
cn yu cu provider hin th d liu ny. Trong m thc thi khi ngi dng thm
ti khon vo thit b, cp nht hng ContactsContract.Setting m
Provider Contacts thm vo ti khon ny. Trong hng ny, thit lp gi tr ca ct
Settings.UNGROUPED_VISIBLE l 1. Khi thc hin iu ny, Provider Contactslun
hin th d liu lin lc , ngay c khi bn khng s dng nhm.
nh ca lin lc
Bng ContactsContract.Data lu tr nh di dng cc hng c kiu MIME l
Photo.CONTENT_ITEM_TYPE. Ct CONTACT_ID ca hng ny c lin kt vi ct
_ID ca d liu lin lc th cha nh ny. Lp ContactsContract.Contacts.Photo
264
Lp trnh Android c bn
nh ngha mt bng con ca bng ContactsContract.Contacts cha thng tin
nh cho nh chnh ca mt lin lc, y cng l nh chnh cho d liu lin lc th chnh
ca lin lc. Tng t, lp ContactsContract.RawContacts.DisplayPhoto
nh ngha mt bng con ca bng ContactsContract.RawContacts cha thng
tin nh cho nh chnh ca d liu lin lc th.
Ti liu tham kho ca ContactsContract.Contacts.Photo v
ContactsContract.RawContacts.DisplayPhoto cha cc v d minh ha
v truy xut thng tin nh. Khng c lp no tin cho vic truy xut nh i din chnh cho mt
d liu lin lc th, nhng bn c th gi mt truy vn ti bng ContactsContract.Data,
chn _ID ca d liu lin lc th, Photo.CONTENT_ITEM_TYPE v ct IS_PRIMARY
tm hng nh chnh ca d liu lin lc th.
D liu lung t mng x hi ca mt ngi cng c th bao gm nh. Cc nh ny
c lu tr ti bng ContactsContract.StreamItemPhotos, c m t chi
tit hn trong mc D liu nh trn lung t mng x hi.
Ch thch
Hello World isnt responding:
ng dng Hello World khng
phn hi
Do you want to close it? :
Bn c mun dng ng dng?
Wait:
Tip tc i phn hi
265
Lp trnh Android c bn
Trigger ANR l g?
Nhn chung, h thng s hin th mt ANR nu ng dng khng th phn hi u vo
ca ngi dng. V d, nu mt ng dng chn (block) mt s thao tc I/O (Input/Output
- Nhp/Xut) (thng l truy cp mng) trn lung giao din ngi dng (UI thread),
h thng s khng th x l s kin nhp liu ca ngi dng khi n xy ra. Hoc, ng
dng c th mt qu nhiu thi gian xy dng mt cu trc phc tp trong b nh,
hoc tnh ton bc di chuyn tip theo trong mt tr chi trn lung giao din ngi
dng. Bi vy, iu quan trng l cn m bo rng nhng tnh ton ny thc s em
li hiu qu; th nhng, m hiu qu nht vn gy tn thi gian cho vic chy.
Trong mt tnh hung bt k m ti , ng dng ca bn thc hin mt thao tc tn
thi gian ng k, bn khng nn thc hin hot ng ny trn lung giao din
ngi dng. Thay vo , hy to mt lung cng vic (worker thread) v thc hin
hu ht cc vic ti y. iu ny gi cho lung giao din ngi dng - lung iu khin
vng lp s kin giao din ngi dng - chy v trnh cho h thng khi kt lun rng
m ca bn b ng bng (ngng hot ng). Do vic chy lung nh vy thng c
tin hnh ti mc lp, nn bn c th ngh ti vic phn hi nh mt vn v lp. (So
snh vi hiu sut m c bn, vic ny phi x l mc phng thc).
Trong Android, phn hi ca ng dng c cc service ca h thng, bao gm Activity
Manager (trnh qun l activity) v Window Manager (trnh qun l Window) iu khin.
Android lun hin th hp thoi ANR cho mt ng dng c th khi h iu hnh ny pht
hin mt trong nhng trng hp sau:
266
Lp trnh Android c bn
Cch hiu qu nht to lung cng vic cho cc thao tc di l to bng lp
AsyncTask. n gin l m rng (extend) lp AsyncTask v ci t phng thc
doInBackground() thc hin vic ny. chuyn cc thay i ca tin trnh
ti ngi dng, bn c th gi phng thc publishProgress(), l phng thc
gi phng thc callback onProgressUpdate(). Trong bn ci t phng thc
onProgressUpdate() ca mnh (phng thc chy trn lung giao din ngi
dng), bn c th thng bo cho ngi dng thng tin h cn bit. V d:
private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
totalSize +=Downloader.downloadFile(urls[i]);
break;
return totalSize;
// publishProgress()
setProgressPercent(progress[0]);
// thnh
267
Lp trnh Android c bn
mc u tin thp theo cch ny, c th lung vn lm chm ng dng ca bn, do mc
nh lung c to ra hot ng mc u tin ging vi lung giao din ngi dng.
Nu ci t lp Thread hoc HandlerThread, cn m bo lung giao din ngi
dng ca bn khng b chn trong khi ch lung cng vic hon thnh - khng gi
phng thc Thread.wait() hay Thread.sleep(). Thay v chn chng trnh
trong khi ch lung cng vic hon thnh, lung chnh ca bn nn cung cp mt i
tng Handler cho cc lung khc gi tr li iu khin sau khi hon thnh. Thit
k ng dng ca bn theo cch ny s cho php lung giao din ngi dng ca ng
dng duy tr vic phn hi cho hot ng u vo, t trnh c hp thoi ANR khi
khng kp phn hi hot ng u vo trong vng 5 giy.
Rng buc c th v thi gian thc thi BroadcastReceiver nhn mnh vo nhng g
broadcast receiver phi lm: Thc hin s lng thao tc nh, ri rc trong lung chy
ngm, chng hn nh lu mt thit lp hoc ng k mt thng bo Notification.
Do , vi cc phng thc khc c gi trong lung giao din ngi dng, ng
dng phi trnh nhng thao tc hoc tnh ton tn nhiu thi gian trong broadcast
receiver. Tuy nhin, thay v thc hin cc tc v chuyn su thng qua lung cng vic,
bn nn pht trin ng dng theo hng khi ng mt IntentService nu cn
thc hin mt action mt nhiu thi gian phn hi mt intent broadcast.
Mch nh: Bn c th s dng StrictMode tm cc thao tc tn nhiu thi
gian, chng hn nh thao tc vi mng hoc trn c s d liu m bn v tnh thc
hin trong lung chnh ca mnh.
Ring vi game, hy tnh ton cc bc di chuyn trong tin trnh worker (hay cn
gi l lung cng vic).
268
Lp trnh Android c bn
12. Service
Service (dch v) l mt thnh phn ca ng dng, c th thc hin cc thao tc tn
thi gian chy ngm v khng cung cp giao din ngi dng. Cc thnh phn khc
ca ng dng c th khi ng mt service v service s tip tc chy ngm ngay c
khi ngi dng chuyn sang ng dng khc. Ngoi ra, mi thnh phn c th lin kt
vi mt service tng tc vi service , thm ch thc hin cc giao tip lin tin
trnh (interprocess communication - IPC). V d, mt service c th x l cc giao dch
mng, pht nhc, thc hin nhp/xut file hoc tng tc vi mt content provider, tt
c u chy ngm.
V c bn, mt service c th nhn hai dng sau:
Khi ng
Mt service c gi l service khi ng (started) khi mt thnh phn ca ng
dng (chng hn nh mt activity) khi ng service bng cch gi phng
thc startService(). Khi c khi ng, mt service c th chy ngm v
hn nh, thm ch ngay c khi thnh phn khi ng service b hy. Mt service
c khi to thng thc hin mt thao tc n v khng tr li kt qu cho
thnh phn gi. V d, service ny c th ti v hoc y mt file ln trn mng. Khi
thao tc ny hon thnh, service ny nn t dng li.
C lin kt
Mt service c gi l c lin kt (bound) khi mt thnh phn ca ng dng
gn vi service ny bng cch gi phng thc bindService(). Service c lin
kt cung cp giao din client-server cho php cc thnh phn tng tc vi service
ny, gi yu cu, nhn kt qu, thm ch l thc hin cc tin trnh cho (across
process) vi cc giao tip lin tin trnh. Mt service c lin kt ch chy vi lng
thi gian tng t thnh phn ng dng khc c gn vi service ny. Nhiu
thnh phn c th gn cng lc vi mt service kiu ny, nhng khi tt c trong s
chng khng cn lin kt, service b hy.
Nhn chung, ti liu ny s tho lun ring v hai kiu service trn, nhng service ca
bn c th thc hin theo c hai cch - c th c khi ng (chy v hn nh) v
cng cho php vic lin kt. Bn c th d dng thc hin iu ny bng cch ci t
c hai phng thc callback: Phng thc onStartCommand() cho php cc thnh
phn khi ng service v phng thc onBind() to lin kt.
Bt k ng dng ca bn khi ng, c lin kt hay c hai, bt c thnh phn ng
dng no cng c th dng service ny (thm ch t mt ng dng khc), ging nh
cch thnh phn bt k c th s dng mt activity - bng cch khi ng service vi
cng mt Intent. Tuy nhin, bn c th khai bo service ny l private (ring t), trong
file k khai, ng thi kha vic truy cp t cc ng dng khc. Mc Khai bo service
trong file k khai bn di s c tho lun chi tit hn v ni dung ny.
Ch : Service s chy trong lung chnh ca tin trnh cha n - service khng to
lung ring v khng chy trong tin trnh ring (tr phi bn quy nh kiu khc). iu
ny c ngha l, nu service s thc hin cng vic chim nhiu b x l trung tm
(Central Processing Unit - CPU) hoc chn cc thao tc (chng hn nh pht nhc
MP3 hoc kt ni mng), bn nn to mt lung mi bn trong service thc hin
269
Lp trnh Android c bn
cng vic ny. Bng cch s dng mt lung ring, bn s lm gim ri ro xut hin li
ANR (Application Not Responding - ng dng khng phn hi) v lung chnh ca ng
dng c th vn dnh ngi dng tng tc vi activity ca bn.
C bn v service
Bn nn s dng service hay lung?
Service ch n gin l mt thnh phn c th chy ngm ngay c khi ngi dng
khng tng tc vi ng dng. Do vy, bn ch nn to mt service nu l nhng
g bn cn.
Nu cn thc hin cng vic bn ngoi lung chnh (main thread), nhng ch trong khi
ngi dng ang tng tc vi ng dng, bn nn to mt lung mi, khng phi l
service. V d, nu mun pht nhc, nhng ch trong lc activity ca mnh ang chy,
bn c th to mt lung trong phng thc onCreate(), chy lung ny bng
phng thc onStart(), sau dng bng phng thc onStop(). Ngoi ra,
bn nn cn nhc s dng AsyncTask hay HandlerThread, thay v s dng lp
Thread truyn thng. Xem ti liu hng dn Processes and Threads (Tin trnh v
lung) tm hiu thm thng tin v lung.
Cn nh rng, nu bn s dng mt service, th mc nh service s chy trong
lung chnh ca ng dng. Do , bn vn nn to mt lung mi bn trong service nu
service ny thc hin cc thao tc chim nhiu b x l hoc thao tc chn.
to mt service, bn phi to mt lp con ca lp Service (hoc mt trong nhng
lp con c ca lp ny). Trong phn ci t, bn nn ghi (override) mt vi
phng thc callback x l cc cng vic chnh trong vng i ca service, ng
thi cung cp mt c ch cho cc thnh phn lin kt vi service ny, nu thch hp.
Cc phng thc callback quan trng nht cn ghi l:
onStartCommand()
H thng s gi phng thc ny khi mt thnh phn khc, chng hn nh mt activity, yu cu khi ng mt service bng cch gi startService(). Khi phng
thc ny thc thi, service c khi to v c th chy ngm v hn nh. Nu ci t
phng thc ny, nhim v ca bn l dng service khi hon thnh cng vic, bng
cch gi phng thc stopSelf() hoc stopService(). (Nu ch mun cung cp
lin kt, bn khng cn ci t phng thc ny).
onBind()
H thng gi phng thc ny khi thnh phn khc mun lin kt vi service, chng
hn nh thc hin RPC (Remote Procedure Call - Th tc gi hm t xa), bng cch
gi phng thc bindService(). Khi ci t phng thc ny, bn phi cung
cp giao din cho nhng client dng giao tip vi service, bng cch tr v mt
IBinder. Bn lun phi ci t phng thc ny, nhng nu khng mun to lin kt,
bn nn tr v null.
onCreate()
H thng gi phng thc ny khi service c to ln u, nhm thc hin cc th
tc thit lp mt ln (trc khi h thng gi phng thc onStartCommand() hoc
270
Lp trnh Android c bn
onBind()). Nu service chy, phng thc ny khng c gi.
onDestroy()
H thng gi phng thc ny khi service khng cn c s dng v s b hy b.
Service ca bn nn ci t phng thc ny dn sch bt c ti nguyn no ang
s dng, chng hn nh lung, trnh lng nghe ng k (registered listener), trnh
nhn (receiver),... y l li gi cui cng service nhn c.
Nu mt thnh phn khi ng service bng cch gi phng thc startService()
(dn n vic gi phng thc onStartCommand()), service vn chy cho n khi
t dng bng phng thc stopSelf(), hoc khi thnh phn khc dng service ny
bng cch gi phng thc stopService().
Nu mt thnh phn gi phng thc bindService() to mt service (v phng
thc onStartCommand() khng c gi), service ny ch chy vi lng thi gian
tng t thnh phn gn vi n. Khi mt service khng c gn vo bt k client no,
h thng s hy service .
H thng Android ch p mt service dng khi sp ht b nh v h iu hnh phi
khi phc ti nguyn h thng cho activity c ngi dng ang focus. Nu service ny
c gn vi mt activity m ngi dng ang focus th t c kh nng b p dng. Nu
service c khai bo chy trn ch mn hnh chnh (s c tho lun sau),
hu nh service s khng bao gi b p dng. Mt khc, nu service c khi
to v s chy trong thi gian di, h thng s gim v tr ca service ny trong danh
sch cc tc v chy ngm qu hn v service s c kh nng cao b p dng - nu
l service khi ng, bn phi thit k sao cho h thng c th khi ng li service
ny. Khi , nu h thng p service dng, n s khi ng li service ny ngay khi
c ti nguyn (mc d vic ny cn ph thuc vo gi tr bn tr v t phng thc
onStartCommand(), s c bn lun sau). tm hiu thm v thi im h thng
c th hy b mt service, xem mc hng dn v Tin trnh v lung.
Trong cc mc di y, bn s tm hiu cch thc to mi loi service trn v s dng
tng loi service ny t cc thnh phn khc ca ng dng.
<serviceandroid:name=.ExampleService/>
...
</application>
</manifest>
271
Lp trnh Android c bn
Bn c th thm vo phn t <service> cc thuc tnh khc nh ngha nhng
tnh cht nh cc quyn cn thit khi ng service v tin trnh chy service ny.
Thuc tnh android:name l thuc tnh bt buc duy nht, xc nh tn lp cho service. Khi pht hnh ng dng, bn khng nn thay i tn ny bi nu thay i, bn
c th ph hng mt s chc nng cha cc intent tng minh (explicit intent) c
dng tham chiu n service ca bn (c bi ng trn blog, Things That Cannot
Change - tm dch: Nhng th khng th thay i).
Xem ti liu tham kho v phn t <service> tm hiu thm v cch khai bo
service trong file k khai (manifest file) .
Tng t activity, service c th nh ngha b lc intent cho php nhng thnh
phn khc gi service ny thng qua cc intent ngm nh (implicit intent). Bng cch
khai bo cc b lc intent, nhng thnh phn t mt ng dng bt k c ci t trn
thit b ngi dng c th khi ng service ca bn, nu service miu t mt b lc
intent ph hp vi intent m ng dng truyn vo phng thc startService().
Nu ln k hoch ch s dng service do mnh pht trin mt cch cc b (cc ng
dng khc khng c dng service ny), bn khng cn (v cng khng nn) cung
cp bt c b lc intent no. Khng c b lc intent, bn phi khi ng service bng
cch s dng mt intent xc nh r tn cho lp service. Chi tit v vic khi ng mt
service s c tho lun sau.
Ngoi ra, bn c th m bo service l dnh ring cho ng dng mnh ang pht trin
ch bng cch thm thuc tnh android:exported v thit lp l false. y l
tnh nng hiu qu ngay c khi service c cung cp b lc intent.
tm hiu thm v cch to b lc intent cho service ca bn, xem ti liu hng dn
v Intent v b lc intent.
272
Lp trnh Android c bn
Ch : Mt service s chy trong cng tin trnh vi ng dng khai bo n v mc nh
l trong lung chnh ca ng dng. Do vy, nu service ca bn thc hin cc thao
tc s dng nhiu b x l hoc thao tc chn trong khi ngi dng tng tc vi mt
activity cng ng dng, service ny s lm chm hiu sut ca activity. Nhm trnh
lm nh hng n hiu sut ng dng, bn nn khi ng mt lung mi bn trong
service.
V c bn, bn cn m rng hai lp sau to mt service dng khi ng:
Service
y l lp c bn ca mi service. Khi m rng lp ny, quan trng l bn cn to
mt lung mi trong lp thc hin tt c cc cng vic ca service. V mc nh
l service s dng lung chnh ca ng dng, nn c th lm chm hiu sut ca
bt c activity no m ng dng ang chy.
IntentService
y l lp con ca Service s s dng lung cng vic (worker thread) x l
ton b yu cu khi ng, mi yu cu c x l ti mt thi im. y l la
chn tt nht nu bn khng yu cu service ca mnh x l cng lc nhiu yu
cu. Tt c nhng g bn cn lm l ci t onHandleIntent(), l phng
thc s nhn intent cho mi yu cu khi ng bn c th thc hin cng vic
chy ngm.
Cc mc di y s hng dn ci t service ca bn bng cch s dng mt trong
nhng lp trn.
M rng lp IntentService
Do hu ht service dng khi ng khng cn x l cng lc nhiu yu cu (y
thc s l mt kch bn a lung (multi-threading) nguy him), nn vic s dng lp
IntentService ci t service ca bn c th l s la chn tt nht.
Lp IntentService thc hin cc cng vic sau:
To mt hng i (queue) cng vic, truyn tng intent theo tng thi im
ti phn ci t onHandleIntent() , bn khng bao gi phi lo lng v
a lung.
273
Lp trnh Android c bn
Sau y l mt v d v ci t IntentService:
public class HelloIntentService extends IntentService {
/**
*/
public HelloIntentService() {
super(HelloIntentService);
/**
*/
@Override
protected void
onHandleIntent(Intent intent){
synchronized(this){
try {
} catch(Exception e) {
wait(endTime -System.currentTimeMillis());
}
}
}
}
}
274
Lp trnh Android c bn
@Override
Toast.makeText(this,service starting,Toast.LENGTH_SHORT).show();
return super.onStartCommand(intent, flags, startId);
M rng lp Service
Nh bn thy mc trc, s dng IntentService ci t mt service
dng khi ng l vic rt n gin. Tuy nhin, nu cn service x l a lung (thay v
x l yu cu khi ng thng qua mt hng i cng vic), bn c th m rng lp
Service x l tng intent.
so snh, m v d di y ci t lp Service thc hin cng vic hon ton
ging v d trn (s dng IntentService). C th, vi mi yu cu khi ng,
chng trnh s s dng mt lung cng vic thc hin cng vic v ch x l mt
yu cu vo mt thi im:
public classHelloService extends Service {
private Looper mServiceLooper;
super(looper);
@Override
275
Lp trnh Android c bn
wait(endTime -System.currentTimeMillis());
} catch(Exception e) {
stopSelf(msg.arg1);
@Override
// cn nhiu CPU s khng ngt giao din ngi dng ca chng ta.
thread.start();
@Override
Toast.makeText(this,service starting,Toast.LENGTH_SHORT).show();
// Vi mi yu cu khi ng, gi thng ip khi ng
mServiceHandler.sendMessage(msg);
276
return START_STICKY;
Lp trnh Android c bn
@Override
return null;
@Override
Toast.makeText(this,service done,Toast.LENGTH_SHORT).show();
START_NOT_STICKY
Nu h thng dng service sau khi phng thc onStartCommand() tr v,
khng to li service, tr phi c intent trng thi ch gi i. y l la chn an
ton nht trnh chy service khi khng cn thit, cng nh khi ng dng ca
bn c th khi ng li bt c cng vic no cha hon thnh.
START_STICKY
Nu h thng dng service sau khi phng thc onStartCommand() tr v,
hy to li service v gi onStartCommand(), nhng khng gi li intent
cui cng. Thay vo , h thng s gi phng thc onStartCommand() vi
mt intent c gi tr null, tr phi c intent trng thi ch khi ng service ny;
trong trng hp , nhng intent ny s c gi i. Cch x l ny ph hp vi
cc trnh pht a phng tin (media player), hoc nhng service tng t, l cc
service khng thc thi lnh, nhng chy v hn nh v ch thc hin cng vic.
START_REDELIVER_INTENT
Nu h thng dng service sau khi phng thc onStartCommand() tr v,
hy to li service v gi phng thc onStartCommand() vi intent cui cng
c gi ti service. Bt c intent trng thi ch no cng s ln lt c gi
i. Cch x l ny ph hp vi cc service ang ch ng thc hin cng vic cn
c khi phc li ngay lp tc, chng hn nh vic ti file v.
277
Lp trnh Android c bn
tm hiu thm v cc hng tr v ny, xem ti liu tham kho tng ng vi
mi hng.
Khi ng service
Bn c th khi ng mt service t activity hoc thnh phn khc cu thnh ng
dng bng vic truyn mt Intent (xc nh service khi ng) vo phng thc
startService(). H thng Android gi phng thc onStartCommand() ca
service ny v truyn Intent trn cho service . (Li khuyn cho bn l ng bao
gi gi trc tip phng thc onStartCommand()).
V d, mt activity c th khi ng service v d trong mc trc (HelloService) bng
cch s dng mt intent tng minh vi phng thc startService():
Intent intent == new Intent(this, HelloService.class);
startService(intent);
Dng service
Mt service dng khi ng phi qun l vng i ca chnh n. Ngha l, h thng s
khng dng hoc hy service ny, tr phi h thng cn khi phc b nh v service
tip tc chy sau khi phng thc onStartCommand() tr v. Do , service phi
t dng bng cch gi phng thc stopSelf(), hoc gi thnh phn khc c th
dng service ny bng cch gi phng thc stopService().
Khi c yu cu dng vi phng thc stopSelf() hoc stopService(), h
thng s hy service ngay khi c th.
Tuy nhin, nu service ca bn x l nhiu yu cu onStartCommand() cng lc,
bn khng nn dng service khi ang thc hin x k mt yu cu khi ng, bi v
bn c th nhn mt yu cu khi ng mi (vic dng service cui yu cu u
tin c th s kt thc yu cu th hai). trnh vn ny, bn c th s dng
phng thc stopSelf(int) m bo rng yu cu dng service lun da
trn yu cu khi ng mi nht. C th, khi gi phng thc stopSelf(int),
bn truyn vo ID ca yu cu khi ng (cng chnh l startId c gi ti phng
278
Lp trnh Android c bn
thc onStartCommand()) tng ng vi yu cu dng service ca bn. Sau ,
nu service nhn mt yu cu khi ng mi trc khi bn c th gi phng thc
stopSelf(int), ID s khng ph hp v service s khng dng.
Ch : Vic ng dng ca bn dng service ca n khi hon thnh cng vic l rt
quan trng, nhm trnh lng ph ti nguyn h thng v tiu tn in nng. Nu cn, cc
thnh phn khc c th dng service bng cch gi phng thc stopService().
Thm ch, nu c th kch hot lin kt cho service ny, bn phi lun t dng service
nu tng nhn c li gi ti onStartCommand().
tm hiu thm v vng i ca mt service, xem mc Qun l vng i ca service
bn di.
To service c lin kt
Service c lin kt (bound service) l thnh phn cho php cc thnh phn ng dng
khc lin kt vi n bng cch gi phng thc bindService() tng ng to
mt kt ni lu di (v nhn chung l khng cho php cc thnh phn khc khi ng
n bng li gi phng thc startService()).
Bn nn to mt service lin kt khi mun tng tc vi service kiu ny t activity
v cc thnh phn khc trong ng dng, hoc cung cp mt s chc nng ca ng
dng cho nhng ng dng khc, thng qua vic giao tip lin tin trnh (interprocess
communication - IPC).
Mun to mt service lin kt, bn phi ci t phng thc callback onBind() tr
v mt IBinder nh ngha giao din dng cho vic kt ni vi service. Sau , cc
thnh phn ng dng khc c th gi phng thc bindService() truy xut vo
giao din ny v bt u gi cc phng thc trn service. Service ch tn ti phc
v thnh phn ng dng c gn vi n; do , khi khng cn thnh phn gn vi
service na, h thng s hy service (bn khng cn dng service lin kt nh cch phi
thc hin vi service dng khi ng thng qua phng thc onStartCommand()).
to mt service lin kt, vic cn lm trc tin l bn phi nh ngha giao din
xc nh cch mt client giao tip vi service ny. Giao din gia service v client phi
l mt bn ci t ca IBinder v cng l kt qu m service ca bn phi tr v
t phng thc callback onBind(). Khi client nhn IBinder, client c th bt u
tng tc vi service thng qua giao din ny.
Cng lc, nhiu client c th gn vi mt service. Khi ang tng tc vi service, client
gi phng thc unbindService() ngt lin kt. Khi khng cn client lin kt vi
service, h thng s hy service.
C nhiu cch ci t mt service c lin kt v bn ci t service ny phc tp
hn so vi service dng khi ng. Do , phn tho lun v service c lin kt nm
trong mt ti liu ring v Bound Services (Service c lin kt).
279
Lp trnh Android c bn
Thng bo nhanh l thng ip xut hin tm thi trn mt ca s hin ti, sau bin
mt. Trong khi , mt thng bo qua thanh trng thi cung cp mt biu tng trn
thanh trng thi cng vi mt thng ip, t ngi dng c th chn thc hin
mt hot ng (chng hn nh khi ng mt activity).
Thng thng, thng bo qua thanh trng thi l k thut tt nht khi hon thnh
mt s cng vic chy ngm (chng hn nh hon thnh ti file v) v gi th ngi
dng c th thao tc trn . Khi ngi dng chn thng bo t view m rng, thng
bo c th khi ng mt activity (chng hn nh hin th file va ti v).
Xem phn hng dn lp trnh v Toast Notifications hoc Status Bar Notifications
tm hiu thm thng tin.
280
Lp trnh Android c bn
@Override
public void onCreate() {
// Service ang c to
}
281
Lp trnh Android c bn
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// Service ang c khi ng, do mt li gi
// ti phng thc startService()
return mStartMode;
}
@Override
public IBinder onBind(Intent intent) {
// Mt client ang lin kt vi service
// qua phng thc bindService()
return mBinder;
}
@Override
public boolean onUnbind(Intent intent) {
// Tt c cc client ngt lin kt bng phng thc unbindService()
return mAllowRebind;
}
@Override
public void onRebind(Intent intent) {
// Mt client s c lin kt vi service
// bng phng thc bindService(),
// sau khi phng thc onUnbind() c gi
}
@Override
public void onDestroy() {
// Service khng cn c s dng v ang b hy
}
Ghi ch: Khng ging nh cc phng thc callback lin quan n vng i ca
activity, bn khng cn gi bn ci t lp cha ca nhng phng thc callback ny.
282
Lp trnh Android c bn
Call to startService()
Call to bindService()
Service running
Active Lifetime
Vng i sng
The service is stopped by itself or a client Service t dng hoc mt client dng n
All clients unbind by calling unbindService() Tt c client u ngt lin kt bng cch
gi phng thc unbindService()
Service shut down
Unbounded service
Bound service
Service c lin kt
283
Lp trnh Android c bn
Bng cch ci t nhng phng thc ny, bn c th iu khin hai vng lp lng
nhau ca vng i service:
Ton b vng i (entire lifetime) ca mt service l khong thi gian gia thi
im gi phng thc onCreate() v thi im phng thc onDestroy()
tr v kt qu. Tng t activity, mt service thc hin cc thit lp ban u ca
n trong phng thc onCreate() v gii phng tt c ti nguyn ang gi trong
phng thc onDestroy(). V d, mt service nghe nhc c th to lung pht
nhc trong phng thc onCreate(), sau dng lung ny trong phng thc
onDestroy().
Tt c cc service u gi hai phng thc onCreate() v onDestroy(), bt
k chng c to bng phng thc startService() hay bindService().
tm hiu thm v cch to service cung cp lin kt, xem ti liu Bound
Services (Service c lin kt). Chi tit v phng thc callback onRebind()
c trnh by trong mc Managing the Lifecycle of a Bound Service (Qun l
vng i ca service c lin kt) ca ti liu trn.
13. Lp BroadcastReceiver
Tng quan v lp BroadcastReceiver
BroadcastReceiver l lp c s cha m dng nhn intent do phng thc
sendBroadcast() gi ti.
284
Lp trnh Android c bn
Nu bn khng cn gi broadcast trn nhiu ng dng, hy cn nhc dng lp ny vi
lp LocalBroadcastManager thay v thm nhiu chc nng chung s c m t
sau y. Vic ny s gip bn ci t hiu qu hn nhiu (khng cn cc giao tip tin
trnh cho), ng thi cho php bn trnh phi bn tm n nhng vn bo mt
lin quan ti vic cc ng dng khc c th nhn hoc gi tn hiu broadcast ca bn.
Bn c th ng k ng mt th hin ca lp ny bng phng thc
Context.registerReceiver() , hoc pht hnh tnh mt bn ci t
thng qua th <receiver> trong file AndroidManifest.xml .
Ghi ch: Nu ng k mt trnh nhn trong bn ci t phng thc
Activity.onResume() , bn nn hy ng k phng thc Activity.
onPause(). (Bn s khng nhn intent khi dng trnh nhn, v iu ny
s lm gim nhng ph ti (overhead) khng cn thit). ng hy ng
k trong Activity.onSaveInstanceState() , v phng thc ny s
khng c gi nu ngi dng quay li ngn xp history (lch s).
C hai lp broadcast chnh c th c nhn:
Broadcast thng (normal broadcast) (c gi i bng cch dng phng thc
Context.sendBroadcast) l kiu broadcast khng ng b hon ton. Tt c
cc trnh nhn broadcast chy u theo th t khng xc nh, thng l cng lc.
Cch truyn ny hiu qu hn, nhng cng c ngha l trnh nhn khng th s dng
kt qu hoc ngng API (Application Programming Interface - Giao din lp trnh ng
dng) ti y.
Broadcast theo th t (ordered broadcast) (c gi i bng cch dng phng
thc Context.sendOrderedBroadcast) c gi ti mt trnh nhn ti mt thi
im. Khi mi trnh nhn thc thi theo th t, trnh ny c th nhn bn kt qu cho
trnh nhn tip theo, hoc c th ngng hon ton broadcast khng chuyn broadcast ny ti trnh nhn khc. Th t chy ca cc trnh nhn c th c qun l bng
thuc tnh android:priority ca b lc intent ph hp; nhng trnh nhn c cng
mc u tin s chy theo th t bt k.
Thm ch, trong trng hp broadcast thng, h thng c th ri vo mt s tnh th
c th khi phc vic broadcast ti mt trnh nhn ring. C th, cc trnh nhn c th
yu cu to mt tin trnh, ch mt trnh nhn chy ring nhm trnh cc tin trnh
mi lm qu ti h thng. Tuy nhin, trong tnh hung ny, vic x l v ngha vn l
khng theo th t: Cc trnh nhn ny vn khng th tr v kt qu hoc ngng vic
broadcast ca chng.
Lu , mc d lp Intent c dng gi v nhn cc tn hiu broadcast, nhng
c ch Intent broadcast y hon ton khc so vi nhng Intent c s dng
khi ng cc Activity thng qua phng thc Context.startActivity().
Khng c c ch i tng BroadcastReceiver thy hoc bt Intent c
dng vi phng thc startActivity(); tng t, khi broadcast mt Intent, bn
s khng bao gi tm thy hoc khi ng mt Activity. V mt ng ngha, y l hai
thao tc rt khc nhau: Vic khi ng mt Activity bng Intent l mt thao tc chy
trn mn hnh chnh (foreground), lm thay i nhng g ngi dng hin ang tng
tc; vic broadcast mt Intent l mt hot ng chy ngm m ngi dng thng
khng nhn thy.
285
Lp trnh Android c bn
Lp BroadcastReceiver (khi khi ng ging nh mt thnh phn thng qua th
<receiver> trong file k khai) l mt thnh phn quan trng trong ton b vng i
ca ng dng. Xem thm v ton b vng i ca ng dng ti mc Kin thc c bn
v ng dng.
Ch ny s tho lun v cc ni dung:
1. Bo mt.
2. Vng i ca trnh nhn.
3. Vng i ca tin trnh.
Bo mt
Cc trnh nhn c s dng vi cc API (giao din lp trnh ng dng) Context
bng tnh nng a ng dng (cross-application) t nhin ca chng, nn bn phi tnh
n kh nng nhng ng dng khc c th lm dng vic s dng ca bn trn cc
trnh nhn ny. Mt s vn cn cn nhc sau:
Intent.setPackage.
286
Lp trnh Android c bn
p buc mt quyn khi gi, bn cung cp mt i s permission khc null cho phng thc
sendBroadcast(Intent, String) hoc sendOrderedBroadcast(Intent,
287
Lp trnh Android c bn
iu ny c ngha l, i vi nhng thao tc tn thi gian, bn thng s dng
Service kt hp vi BroadcastReceiver gi tin trnh cha tn ti trong sut
thi gian din ra thao tc ca bn.
Tng kt
Lp lng nhau (nested class)
Lp
BroadcastReceiver.PendingResult
Trng thi ca kt qu
c gi li cho broadcast
receiver.
final void
abortBroadcast()
Thit lp c (flag) cho bit trnh nhn ny nn hy broadcast
hin ti; phng thc ny ch lm vic vi nhng tn hiu
broadcast c gi thng qua phng thc
Context.sendOrderedBroadcast.
clearAbortBroadcast()
getAbortBroadcast()
Tr v c cho bit liu trnh nhn ny c nn hy broadcast
hin ti hay khng.
final boolean
final int
getDebugUnregister()
Tr v gi tr cui cng nhn c t phng thc
setDebugUnregister(boolean).
getResultCode()
getResultData()
Truy xut d liu kt qu hin ti, do trnh nhn trc thit lp.
final Bundle
final
goAsync()
BroadcastReceiver.
Phng thc ny c th c ng dng gi trong phng
PendingResult
thc onReceive(Context, Intent) cho php gi tn
hiu broadcast hot ng sau khi c tr v t phng thc
onReceive(Context, Intent).
288
Lp trnh Android c bn
final boolean
isInitialStickyBroadcast()
Tr v true nu trnh nhn ang x l gi tr khi to ca tn
hiu broadcast kiu sticky (dnh) - gi tr ny c broadcast
sau cng v hin ang c lu gi trong cache sticky; bi
vy; ti thi im , gi tr ny khng phi l kt qu trc tip
ca mt broadcast.
final boolean
isOrderedBroadcast()
Tr v gi tr true nu trnh nhn ang x l mt broadcast c
th t.
abstract void
IBinder
final void
final void
setDebugUnregister(boolean debug)
Cung cp tp cc iu khin tr gip g li cho nhng li gi khng
ph hp vi phng thc Context.registerReceiver().
setOrderedHint(boolean isOrdered)
final void
final void
final void
[M rng]
289
Lp trnh Android c bn
290
Lp trnh Android c bn
Truy xut d liu kt qu hin ti, do trnh nhn trc thit lp. Thng l null.
Kt qu tr v
makeMap
Nu true th s thit lp cho bn mt Map rng mi khi Map hin ti l null; Nu
false, bn c chun b nhn mt Map null.
Kt qu tr v
Bn nh x ph tr hin ti kiu Map.
public final BroadcastReceiver.PendingResultgoAsync()
c a vo API cp 11 (API level 11)
Phng thc ny c th c mt ng dng gi trong phng thc
onReceive(Context, Intent) cho php ng dng gi vic broadcast
ny vn hot ng sau khi phng thc onReceive(Context, Intent) tr
v kt qu. Khng thay i thi gian ch phn hi tn hiu broadcast mong mun
(hon thnh trong vng 10 giy), nhng cho php ci t chuyn nhng cng
vic lin quan sang lung khc, nhm trnh nh hng ti lung giao din ngi
dng chnh do IO (u vo/u ra) ca a.
Kt qu tr v
Tr v BroadcastReceiver.PendingResult i din cho kt qu ca
tn hiu broadcast ang hot ng. Bn thn i tng BroadcastRecord
khng cn hot ng na; tt c cc d liu v tng tc khc phi i
qua API ca BroadcastReceiver.PendingResult. Phng thc
PendingResult.finish() phi c gi khi tin trnh x l broadcast
hon thnh.
public final boolean isInitialStrickyBroadcast()
c a vo API cp 5 (API level 5)
Tr v true, nu trnh nhn ang x l gi tr khi to ca tn hiu broadcast kiu
sticky - gi tr ny c broadcast sau cng v hin ang c lu gi trong cache
sticky; do vy, ti thi im , gi tr ny khng phi l kt qu trc tip ca mt
broadcast.
public final boolean isOrderedBroadcast()
c a vo API cp 5 (API level 5)
Tr v true, nu trnh nhn ang x l mt broadcast c th t.
291
Lp trnh Android c bn
public abstract void onReceive (Context context, Intent intent)
c a vo API cp 1 (API level 1)
Phng thc ny c gi khi i tng BroadcastReceiver ang nhn mt
Intent broadcast. Sut thi gian ny, bn c th s dng cc phng thc khc
trong BroadcastReceiver hin th/chnh sa gi tr kt qu hin ti. y l
phng thc lun c gi trong lung chnh ca tin trnh x l phng thc,
tr phi bn yu cu c th phng thc ny c a vo lung khc bng
cch s dng phng thc registerReceiver(BroadcastReceiver,
IntentFilter, String, android.os.Handler). Khi phng thc ny
chy trn lung chnh, li khuyn cho bn l ng bao gi thc hin cc thao tc
tn thi gian trong phng thc (thi gian ch (timeout) l 10 giy; qu thi gian
ny, h thng s cho rng trnh nhn b chn v mt ng c vin b hy). Bn
khng nn ci t bt hp thoi popup trong phng thc onReceive().
Nu i tng BroadcastReceiver c pht i thng qua th <receiver>,
i tng ny s khng hot ng sau khi c tr v t hm ny. iu
ny c ngha rng, bn khng nn thc hin bt k thao tc no tr v kt qu
mt cch khng ng b - c th, tng tc vi service, bn nn s dng
phng thc startService(Intent) thay v bindService(Intent,
ServiceConnection, int). Nu mun tng tc vi mt service ang chy,
bn c th s dng phng thc peekService(Context, Intent).
B lc Intent c dng trong phng thc registerReceiver(Broadcast
Receiver, IntentFilter) v trong file k khai, ng dng khng m bo
vic broadcast c s dng ring. B lc intent l gi h iu hnh bit cch
tm trnh nhn ph hp. Chng ta c th thit k trnh gi c kh nng chn
broadcast ti cc trnh nhn c th, b qua vic dng b lc. Do vy, bn nn ci
t sao cho phng thc onReceive() ch phn hi nhng hot ng bit,
b qua nhng Intent khng mun nhn v.
Tham s
context
292
Lp trnh Android c bn
Context truyn vo phng thc onReceive(Context, Intent).
service
L Intent ch ra service bn mun s dng. Xem thm phng thc
startService(Intent) tm hiu k hn.
public final void setDebugUnregister (boolean debug)
c a vo API cp 1 (API level 1)
Cung cp tp cc iu khin tr gip g li cho nhng li gi khng ph hp
vi phng thc Context.registerReceiver(). Nu phng thc
ny c gi vi gi tr true, trc khi nhn kt qu tr v t phng thc
registerReceiver(), callstack (ngn xp li gi) cho phng thc Context.
unregisterReceiver() sau s tip tc c s dng, c in ra nu sau
c mt li gi cha ng k khng hp l c thc hin. Lu , phng thc
ny cn duy tr thng tin v BroadcastReceiver trong sut thi gian chy ng
dng, tr v vt li (leak) - ch dng g li.
public final void setOrderedHint(boolean isOrdered)
c a vo API cp 1 (API level 1)
Phng thc ny c s dng bn trong, thit lp gi v vic i tng
BroadcastReceiver ny c ang chy trong ch c th t hay khng.
public final void setResult (int code, String data, Bundle extras)
c a vo API cp 1 (API level 1)
Thay i tt c cc d liu kt qu tr v t vic broadcast ny; ch lm vic vi tn
hiu broadcast c gi thng qua Context.sendOrderedBroadcast. Ton
b d liu kt qu hin ti c thay th bng gi tr nhn v t phng thc ny.
Phng thc ny khng lm vic vi cc tn hiu broadcast khng theo th t,
chng hn nh nhng tn hiu c gi ti t Context.sendBroadcast.
Tham s
code
M kt qu mi. Thng s dng cc hng Activity RESULT_CANCELED v
RESULT_OK, mc d ngha thc s ca gi tr ny lin quan ti i tng
broadcast.
data
D liu kt qu mi. y l mt chui bt k gii thch cho i tng broadcast; c th l null.
extras
Bn nh x d liu ph tr mi. y l i tng Bundle lu d liu bt k,
lin quan n i tng broadcast. C th c thit lp l null. D liu ny
gp phn thay th hon ton bn nh x hin ti (nu c).
293
Lp trnh Android c bn
public final void setResultCode (int code)
c a vo API cp 1 (API level 1)
Thay i m kt qu hin ti ca tn hiu broadcast ny; phng thc
setResultCode() ch lm vic vi cc tn hiu broadcast c gi ti thng
qua Context.sendOrderedBroadcast. Phng thc ny thng s dng
cc hng Activity RESULT_CANCELED v RESULT_OK, mc d ngha thc s
ca gi tr ny lin quan n i tng broadcast.
Phng thc setResultCode() khng lm vic vi cc tn hiu broadcast khng
theo th t, chng hn nh nhng tn hiu c gi ti t Context.
sendBroadcast.
Tham s
code
M kt qu mi.
294
Lp trnh Android c bn
Tham s
Extras
14. Mo bo mt
Android c nhng tnh nng bo mt c xy dng bn trong h iu hnh ny, gip
gim thiu ng k tn sut v nh hng ca cc vn bo mt (security) ng dng.
H thng ny c thit k bn c th xy dng ng dng ca mnh mt cch c
th vi h iu hnh mc nh v cc quyn trn file, gip trnh c nhng quyt nh
kh khn v bo mt.
Mt s tnh nng bo mt ct li gip bn xy dng ng dng an ton, bao gm:
Cng ngh Sandbox (mi trng o chy ng dng) dnh cho ng dng Android,
gip cch ly d liu ng dng ca bn vi vic thc thi m t cc ng dng khc.
Lu tr d liu
Mi lo ngi ln nht v bo mt i vi mt ng dng Android l xem xt liu d liu
bn lu trn thit b c th c cc ng dng khc truy cp hay khng. C ba cch c
bn lu d liu trn thit b:
S dng b nh trong
Mc nh, cc file bn to ra trn b nh trong ch c ng dng ca bn truy cp.
Tnh nng bo v ny c Android thit lp v c p dng cho hu ht ng dng.
295
Lp trnh Android c bn
Thng th bn nn trnh s dng ch MODE_WORLD_WRITEABLE hoc
MODE_WORLD_READABLE cho cc file IPC, bi nhng quyn ny khng cung cp
kh nng gii hn truy cp ln cc ng dng c th, cng nh khng cung cp
bt c iu khin no nh dng d liu. Nu mun chia s d liu ca bn vi
cc tin trnh x l ng dng khc, bn c th ngh n vic dng mt content
provider. Provider ny s cung cp quyn c v ghi cho cc ng dng khc v
c th s dng quyn ng (dynamic permission) trong tng trng hp c th.
cung cp thm tnh nng bo v cho d liu nhy cm, bn c th chn m ha
cc file cc b (local file) bng cch dng mt kha (key) ng dng khng trc tip
truy cp c. V d, kha c th c t trong mt KeyStore v c bo v bng
password (mt khu) ca ngi dng, password ny khng c lu tr trn thit b.
iu ny khng th bo v d liu khi quyn qun tr (root) c th theo di ngi dng
nhp password, nhng cng gip bo v trong trng hp mt thit b v cha m ha
file h thng.
S dng b nh ngoi
Cc file c to trn b nh ngoi, chng hn nh th SD, c th c c v ghi
tng th. B nh ngoi c th c ngi dng di chuyn v cng c th c mt
ng dng bt k chnh sa; do , bn khng nn lu nhng thng tin nhy cm vo
b nh ny.
Cng nh d liu t cc ngun khng ng tin khc, bn nn thc hin kim tra tnh
hp l ca d liu u vo khi x l d liu lu trong b nh ngoi. Chng ti nhn
mnh rng, bn khng nn lu tr cc file c th thc thi hoc file lp vo b nh ngoi
trc khi tin hnh np ng (dynamic loading). Nu ng dng ca bn thc hin truy
xut file c th thc thi t b nh ngoi, cc file ny nn c nh du v kim nh
m ha trc khi np ng.
296
Lp trnh Android c bn
c kim sot hn cho d liu content provider khi vic truy cp d liu ca cc ng
dng c k vi cng mt kha.
Content provider cng c th cung cp thm truy cp chi tit (granular access) bng
cch khai bo thuc tnh android:grantUriPermissions v s dng cc c
FLAG_GRANT_READ_URI_PERMISSION cng nh FLAG_GRANT_WRITE_URI_
PERMISSION trong i tng Intent kch hot thnh phn. Phm vi ca nhng quyn
ny c th c gii hn c th hn bi phn t <grant-uri-permission>.
Khi truy cp mt content provider, bn cn s dng cc phng thc truy vn tham
s ha (parameterized query method) nh query(), update() v delete()
trnh s can thip ca cc l hng SQL injection (l l hng an ninh nh hng trc
tip n c s d liu v ti nguyn ca mt h thng Website) tim tng t nhng
ngun khng ng tin. Lu , vic s dng cc phng thc truy vn tham s ha l
cha nu i s selection c xy dng da trn s ghp ni vi d liu ngi
dng trc khi gi ti phng thc ny.
ng nh gi sai vic bo mt i vi quyn ghi. Lu , quyn ghi cng vi cu lnh
SQL cho php xc nhn mt s d liu bng cch s dng sng to mnh WHERE
v phn tch kt qu tr v. V d, k tn cng (attacker) c th s d c mt s in
thoi c th c mt trong bn nht k ghi li cc cuc gi bng cch chnh sa mt
hng ch khi s in thoi ny thc s tn ti. Nu d liu content provider c cu trc
d pht hin, quyn ghi c th tng ng vi vic cung cp c quyn c v ghi.
S dng quyn
Do h thng sandbox Android bo v ng dng khi cc ng dng khc, nn cc ng
dng phi chia s ti nguyn v d liu mt cch tng minh. ng dng thc hin vic
ny bng cch khai bo quyn chng cn dng cho nhng tnh nng b sung khng
c sandbox c bn cung cp, bao gm quyn truy cp ti cc tnh nng ca thit b
nh camera.
Yu cu quyn
Chng ti khuyn ngh nn ti thiu ha s quyn m ng dng ca bn yu cu. Vic
khng truy cp vo quyn nhy cm gip gim thiu ri ro c th v tnh lm dng
nhng quyn ny, tng kh nng ngi dng chp nhn ng dng v cng khin ng
dng t b tn cng hn. Thng thng, nu khng cn quyn thc hin chc nng
no trong chng trnh ca mnh, bn ng yu cu quyn .
Nu c th thit k ng dng ca bn theo cch khng cn yu cu quyn th tt hn.
V d, thay v yu cu truy cp ti thng tin thit b to mt nh danh duy nht, hy
to mt GUID (Globally unique identifier - nh danh duy nht ton cu) cho ng dng
ca bn (xem mc X l d liu ngi dng bn di). Hoc, thay v s dng b nh
ngoi (phi yu cu quyn), hy lu tr d liu b nh trong.
Ngoi vic yu cu quyn, ng dng ca bn c th s dng <permissions> bo
v IPC rt cn bo mt cc d liu nhy cm v s c xut ra cho nhng ng dng
khc, chng hn nh mt ContentProvider. Nhn chung, chng ti khuyn bn nn
297
Lp trnh Android c bn
s dng cc iu khin truy cp (access control) thay v quyn cn xc nhn ca ngi
dng (user confirmed permission) nhng v tr kh thi, v cc quyn ny c th khin
ngi dng bi ri. V d, hy xt ti vic s dng mc bo v xc nhn bng ch k
(signature protection level) cho nhng quyn ca giao tip IPC gia cc ng dng ca
cng mt nh pht trin chng trnh.
Trnh r r d liu c quyn bo v. iu ny c th xy ra khi ng dng ca bn
xut d liu thng qua IPC duy nht c sn v IPC ny c mt quyn xc nh, nhng
khng yu cu quyn cho client no trong giao din IPC ny.
To quyn
Thng thng, bn nn c gng nh ngha t quyn nht c th trong khi vn p ng
c yu cu v bo mt. Vic to quyn mi thng khng ph bin i vi a s
ng dng, do cc quyn c h thng nh ngha thng bao ph rt nhiu tnh
hung. Ti v tr thch hp, hy thc hin kim tra truy cp bng cch s dng nhng
quyn c.
Nu phi to mt quyn mi, hy cn nhc xem liu bn c th hon thnh tc v ny
vi mc bo v signature hay khng. Ngi dng s khng nhn thy s c mt ca
quyn xc nhn bng ch k v khi ng dng thc hin kim tra quyn, ch cho php
cc ng dng c xc nhn ch k l ca cng mt nh pht trin chng trnh th
mi c th truy cp c.
Nu mun to mt quyn vi mc bo v dangerous (nguy him), bn phi tnh n
mt s vn phc tp sau:
Quyn phi l mt chui din t ngn gn cho ngi dng bit v quyt nh bo
mt m h c yu cu thc hin.
S dng kt ni mng
Cc giao dch mng vn tim n nhiu ri ro v bo mt, v chng bao gm vic truyn
d liu thng l thng tin ring t ca ngi dng. Mi ngi ngy cng cnh gic vi
cc mi lo ngi v bo mt trn thit b di ng, c bit l khi thit b thc hin giao dch
mng. Do , y l yu t quan trng khi ng dng ca bn thc hin cc bin php
ci t tt nht, hng ti bo v d liu ngi dng trong mi hon cnh.
298
Lp trnh Android c bn
S dng kt ni mng IP
Kt ni mng trn h iu hnh Android khng khc nhiu so vi cc mi trng Linux
khc. Mi bn tm chnh l m bo s dng giao thc (protocol) ph hp vi d liu
nhy cm, chng hn nh HttpsURLConnection i vi cc lu lng truy cp
Web an ton (secure web traffic). Chng ti khuyn bn nn s dng giao thc HTTPS
thay v HTTP mi ni m HTTPS c server h tr, bi v thit b di ng thng
kt ni ti mt mng khng an ton, chng hn nh im truy cp Wi-Fi cng cng.
C th d dng ci t giao tip mc cng m ha, c xc thc bng cch s
dng lp SSLSocket. Cc thit b Android thng xuyn kt ni vi nhng mng
khng dy thiu an ton thng qua Wi-Fi, nn vic s dng kt ni mng an ton cho
tt c cc ng dng kt ni qua mng rt c khuyn khch.
Chng ti cng nhn thy rng mt s ng dng dng cng mng (network port)
localhost x l cc IPC nhy cm. Chng ti phn i cch tip cn nh vy, v
cc ng dng khc trn thit b c th truy cp giao din ny. Thay vo , bn nn
s dng mt c ch IPC ca Android; nh c ch ny, vic xc thc c th thc hin
c, chng hn nh khi dng mt Service. (Thm ch iu ny cn khng tt bng
s dng vng lp ngc (loopback) lin kt vi INADDR_ANY, bi v sau ng
dng ca bn c th nhn yu cu t mi ni).
Mt vn chung nhm bo v vic lp l m bo rng bn khng tin vo nhng
d liu c ti v t HTTP hoc cc giao thc khng an ton khc. iu ny bao
gm vic kim tra u vo trn WebView v bt c phn hi intent no c pht
ra t HTTP.
299
Lp trnh Android c bn
ng dng v bn nn s dng cc tnh nng ny bt c ni no c th. Cng cn lu
rng, vic chn cc ngn ng an ton c th lm gim thiu kh nng xy ra nhng
vn v kim tra u vo.
Nu bn ang s dng m my (native code), bt c d liu no c c t file, c
nhn thng qua mng hoc t IPC u c th tim n nguy c gy ra cc vn v
bo mt. Vn ph bin nht l trn b m (buffer overflow), s dng sau khi gii
phng (use after free) v li lgc off-by-one error (li b st iu kin bin). Android
cung cp mt s k thut nh ASLR v DEP, gip gim thiu kh nng xy ra cc li
ny, nhng khng gii quyt c tn gc vn . Bn c th trnh nhng sai st ny
bng cch x l con tr v qun l b m mt cch cn thn.
Cc ngn ng ng da trn chui, chng hn nh JavaScript v SQL, cng l i
tng cn kim tra u vo do thot ra k t v cho php chn script (script injection).
Nu bn ang s dng d liu bn trong truy vn s c gi ti c s d liu SQL
hoc content provider, SQL Injection l mt vn . Cch bo v tt nht l s dng
truy vn tham s ha, nh tho lun mc trc v content provider. Gii hn cc
quyn l ch c (only-read) hoc ch ghi (only-write) cng lm gim kh nng gy hi
lin quan n SQL Injection.
Nu khng th s dng nhng tnh nng bo mt trn, chng ti rt khuyn khch bn
dng cc nh dng cu trc d liu tt v kim tra xem d liu c ph hp vi nh
dng mong mun hay khng. Vic lp danh sch en cc k t hoc k t thay th
khng c s dng c th l mt chin lc hiu qu, song bn nn trnh nhng k
thut ny v chng d pht sinh li trong thc t.
300
Lp trnh Android c bn
Nu buc phi truy cp d liu nhy cm, hy c tnh xem liu cc thng tin ny
c cn truyn ti server khng, hoc liu thao tc c th thc hin trn client hay
khng. Bn cng cn cn nhc v vic chy bt c m no s dng d liu nhy cm
trn client trnh truyn i d liu ngi dng.
Ngoi ra, cng cn m bo rng bn khng v tnh l d liu ngi dng cho ng
dng khc trn thit b khi qu d di vi IPC, cc file c th ghi c (world writable
file) hoc cng mng. y l mt trng hp c bit lm r r d liu c bo v
bi quyn, nh tho lun mc Yu cu quyn.
Nu bn cn mt GUID, hy to mt s ln, duy nht v lu tr n. Khng s dng
nh danh in thoi, chng hn nh s in thoi hoc IMEI (International Mobile
Equipment Identity - S nhn dng thit b di ng trn ton th gii) c th lin h vi
thng tin c nhn. Ch ny s c tho lun chi tit ti Android Developer Blog
(Blog dnh cho nh pht trin Android).
Hy cn thn khi ghi nht k (log) trn thit b. Trong Android, nht k l ti nguyn
c chia s, c th c mt ng dng c quyn READ_LOGS d dng truy cp. Mc
d d liu nht k in thoi l tm thi v c th xa c ghi li, nhng nht k
khng thch hp cha thng tin ngi dng c th v tnh lm r r d liu ngi dng
cho cc ng dng khc.
S dng WebView
Do WebView s dng ni dung Web c th bao gm HTML v JavaScript, nn nu s
dng khng ng c th gp phi nhng vn bo mt thng thng, chng hn nh
cross-site-scripting (cn gi l XSS hoc CSS, thng c cho l mt trong nhng
lp ng dng ph bin nht cc k thut hacking. Ni chung, cross-site scripting cho
thy rng k thut hacking thc y nhng l hng trong m ca mt ng dng Web
cho php mt k tn cng gi ni dung c hi t mt ngi dng cui v thu thp
mt s loi d liu t cc nn nhn). Android cha mt s c ch gip gim thiu phm
vi nh hng ca nhng vn ny bng cch gii hn kh nng ca WebView cho
mt s chc nng nh ca ng dng.
Nu ng dng ca bn khng trc tip s dng JavaScript bn trong WebView, ng
gi phng thc setJavaScriptEnable(). Mt s m mu s dng phng thc
ny, v c th bn s dng li vi cng mc ch trong ng dng sn phm. Do , hy
loi b li gi phng thc ny nu khng cn thit. Mc nh, WebView khng thc
hin JavaScript, nn khng th xy ra cross-site-scripting.
S dng phng thc addJavaScriptInterface() trong cc x l c th, v
phng thc ny cho php m JavaScript thc hin thao tc thng ch dnh cho ng
dng Android. Nu s dng phng thc ny, ch cho php tc ng trn nhng trang
Web m tt c d liu u vo u ng tin. Nu cho php u vo khng ng tin, m
JavaScript c c th x l cc phng thc Android trong ng dng ca bn. Ni chung,
chng ti khuyn khch ch s dng phng thc addJavaScriptInterface()
cho m JavaScript bn trong APK ng dng ca bn.
Nu ng dng truy cp d liu nhy cm bng mt WebView, c th bn mun dng
phng thc clearCache() xa nhng file c lu tr cc b. Phn header
301
Lp trnh Android c bn
pha server kiu nh no-cache (khng lu cache) c th c dng quy nh rng
mt ng dng khng nn lu cache ni dung c th.
X l chng thc
Nhn chung, chng ti khuyn ngh bn nn hn ch ti a vic yu cu chng thc
ngi dng (user credential) - d nhn ra cc v tn cng gi mo (phising attack),
v nhng v ny cng t c kh nng thnh cng. Thay vo , hy s dng token xc
thc (authorization token) v lm mi token ny.
Nu c th, bn khng nn lu tr username (tn ngi dng) v password (mt
khu) trn thit b. Thay vo , hy thc hin xc thc khi to bng cch s dng
username v password c ngi dng cung cp, sau s dng token xc thc i
vi service c th trong thi gian ngn.
Cc service m nhiu ng dng nn c truy cp s dng AccountManager. Nu
c th, hy dng lp AccountManager x l nhng service da trn m my
v khng lu tr password trn thit b.
Sau khi dng AccountManager truy xut mt Account, CREATOR trc khi
truyn i trong chng thc bt k, bn s khng b ri vo tnh trng v tnh truyn sai
chng thc ti ng dng.
Nu chng thc ch c dng trong nhng ng dng do bn pht trin, bn c th
kim tra ng dng truy cp vo AccountManager bng cch s dng phng thc
checkSignature(). Mt khc, nu ch c mt ng dng dng chng thc ny, bn
c th s dng mt KeyStore (i tng lu kha) lu tr.
S dng k thut m ha
Ngoi vic cung cp c ch cch ly d liu, h tr m ha ton b file h thng v cung
cp knh giao tip an ton, Android cn cung cp rt nhiu thut ton bo v d liu
nh s dng k thut m ha (cryptography).
Nhn chung, hy c gng s dng mc thc thi cao nht ca framework c t trc
h tr trng hp s dng ca bn. Nu cn truy xut an ton mt file t ni bit,
mt URI HTTPS n gin c th ph hp v khng cn n k thut m ha. Nu cn
mt ng bo mt (secure tunnel), hy xem xt s dng HttpsURLConnection hoc
SSLSocket thay v vit giao thc ca chnh bn.
Nu bn ang cn ci t giao thc ring, chng ti rt khuyn ngh rng bn khng
nn ci t thut ton m ha ca ring mnh. Hy s dng cc thut ton m ha
(cryptographic algorithm) c nh thut ton m ha AES hoc RSA c cung cp
trong lp Cipher.
S dng c ch sinh ngu nhin s bo mt (secure random number generator),
SecureRandom, khi to kha m ha bt k, KeyGenerator. S dng mt
kha khng c to t c ch sinh ngu nhin s bo mt thng lm gim ng
k kh nng bo mt ca thut ton, to iu kin cho tn cng offline (ngoi tuyn).
Nu bn cn lu tr mt kha ti s dng, hy dng c ch ging nh KeyStore
cung cp mt c ch lu tr lu di v truy xut kha m ha (cryptographic key).
302
Lp trnh Android c bn
android:protectionLevel.
S dng intent
Intent l c ch c a dng cho IPC khng ng b trong Android. Ty
thuc vo yu cu ca ng dng, bn c th s dng sendBroadcast(),
sendOrderedBroadcast(), hoc mt intent tng minh cho mt thnh phn ng
dng xc nh.
Lu , vic broadcast theo th t c th b mt i tng nhn tiu th, nn c th
chng khng c gi ti tt c ng dng. Nu ang gi mt intent cn chuyn ti
mt trnh nhn xc nh, bn phi s dng mt intent tng minh khai bo trnh nhn
bng intent tn.
Trnh gi intent c th kim nh trnh nhn c mt quyn xc nh quyn khc null gi
cng li gi phng thc. Ch nhng ng dng c quyn ny mi c nhn intent.
Nu d liu bn trong intent broadcast c tnh cht nhy cm, bn nn cn nhc p
dng quyn m bo rng nhng ng dng xu khng th ng k nhn cc thng
ip ny nu thiu quyn thch hp. Trong nhng hon cnh ny, bn cng c th cn
nhc ti vic trc tip ch ra trnh nhn thay v gi broadcast.
Ghi ch: Khng nn cn nhc b lc intent cho tnh nng bo mt - cc thnh phn
c th c dn ra bng nhng intent tng minh v c th khng cha d liu
ph hp vi b lc intent. Bn nn thc hin xc thc u vo bn trong trnh nhn
intent chc chn d liu ny c nh dng ph hp vi trnh nhn, service hoc
activity c dn ra.
303
Lp trnh Android c bn
S dng service
Service thng c dng cung cp tnh nng s dng cho ng dng khc. Mi
lp service phi c khai bo tng ng trong file k khai ca lp ny.
304
Lp trnh Android c bn
Np m ng
Chng ti khuyn co bn khng c np m t bn ngoi APK ng dng. Vic lm
ny s gia tng ng k kh nng ng dng tha hip vi vic chn m (code injection)
hoc can thip m (code tampering). Lm nh vy cng khin vic qun l phin bn
v kim th ng dng tr nn phc tp hn. Cui cng, vic np m t bn ngoi APK
ng dng khin chng ta khng th kim tra hnh vi ca ng dng; do , hot ng
ny c th b cm trong mt s mi trng.
Nu ng dng ca bn np m ng, iu quan trng nht nn nh l m c np
ng chy cng quyn bo mt vi APK ca ng dng. Ngi dng quyt nh ci t
ng dng da trn danh tnh ca bn, v h mong mun c cung cp bt c m no
chy bn trong ng dng, bao gm c m np ng.
Ri ro bo mt ch yu lin quan ti m np ng l m ny cn c ly t mt ngun
c th xc minh c. Nu cc m un ny c thm trc tip vo APK ca bn, th
ng dng khc khng th chnh sa c. iu ny lun ng, bt k m ca ca bn
l th vin m my (native library) hay mt lp c np bng DexClassLoader.
Chng ta tng thy rt nhiu ng dng c gng np m t nhng a im khng an
ton, nh ti v t mng thng qua giao thc khng m ha, hoc t a im c th
ghi c nh b nh ngoi. Nhng ni a im c th cho php i tng tn cng
trn mng chnh sa ni dung trong khi truyn, hoc cho php ng dng khc trong
thit b ngi dng chnh sa ni dung.
Bo mt trn my o
Dalvik l my o (VM - Virtual Machine) chy trn h thng Android. Dalvik c xy
dng dnh ring cho Android, nhng nhiu mi quan ngi lin quan n m bo mt
trong cc my o khc cng tn ti Android. Ni chung, bn khng cn bn tm
n vn bo mt lin quan n my o. ng dng ca bn chy trong mi trng
sandbox an ton, nn cc tin trnh khc trong h thng khng th truy cp vo m
hoc d liu ring ca bn.
Nu bn quan tm ti ch bo mt trn my o, chng ti khuyn ngh bn nn lm
quen dn vi cc ti liu hin c v ch ny. Hai ngun ti liu ph bin hn l:
305
Lp trnh Android c bn
http://www.securingjava.com/toc.html.
https://www.owasp.org/index.php/Java_Security_Resources.
Nhn mt khng gian lu tr gii hn trn thit b di ng, vic ny vn quen thuc
vi nhng nh pht trin mun xy dng ng dng kiu m un v s dng vic
np lp ng. Khi lm vy, hy xt ti c ngun bn truy xut lgc ng dng v
v tr lu tr ng dng cc b. Khng nn np lp ng t ngun cha c kim
nh, chng hn nh nhng ngun mng khng c bo mt hoc b nh ngoi,
v m c th b chnh sa cha cc hnh vi c hi.
Bo mt trong m my
Nhn chung, chng ti khuyn khch cc lp trnh vin dng Android SDK (Software
development kit - B pht trin phn mm) pht trin ng dng thay v dng m my
i km Android NDK (Native Development Kit - B pht trin m my). Cc ng dng
c xy dng vi m my phc tp hn, t linh ng hn v thng bao gm nhiu
li b nh hn, chng hn nh trn b m.
Android c xy dng da trn nhn (kernel) Linux; bi vy, nm r vic pht trin
bo mt trn Linux s c bit c ch trong trng hp bn mun s dng m my.
Hng dn v bo mt trn Linux l ni dung nm ngoi phm vi ca ti liu ny,
nhng c bn lun trong mt ti liu vo loi ph bin nht l Programming for
Linux and Unix HOWTO, ti a ch http://www.dwheeler.com/secure-programs.
Mt khc bit quan trng gia Android v mi trng Linux l Sandbox ca ng dng.
Trn Android, tt c cc ng dng u chy trong Sandbox ca ng dng, bao gm c
cc ng dng c vit bng m my. mc c bn nht, mt cch hay m cc lp
trnh vin quen vi Linux ngh v Sandbox ca Andorid l mi ng dng u nhn
mt UID duy nht vi cc quyn c gii hn. iu ny c tho lun chi tit hn
trong mc Android Security Overview (Tng quan v bo mt trong Android). Ngoi
ra, bn nn lm quen vi quyn ca ng dng ngay c khi ang s dng m my.
306
Lp trnh Android c bn
15. WebView
15.1 Tng quan v lp WebView
WebView l mt View dng hin th trang Web. y l lp c bn m bn c th
da vo cun trnh duyt Web, hoc ch n gin l hin th mt s ni dung trc
tuyn bn trong Activity ca bn. Lp ny s dng WebKit rendering engine hin
th trang Web v bao gm cc phng thc iu hng tin v li thng qua mt
history (lch s), phng to v thu nh, thc hin tm kim vn bn,
Lu , Activity ca bn truy cp Internet v np trang Web trong mt WebView, bn
phi thm quyn Internet vo file k khai ca Android:
<uses-permission android:name="android.permission.INTERNET" />
Cc trng hp s dng c bn
Mc nh, mt WebView khng cung cp widget ging nh trnh duyt, khng cho php
m JavaScript v b qua li Web. Nu mc ch ch l hin th mt s HTML l mt
phn trong giao din ngi dng ca bn th s dng WebView c v n; ngi dng
khng cn tng tc vi trang Web, ngoi tr vic c n v trang Web cng khng
cn tng tc vi ngi dng. Nu thc s mun mt trnh duyt Web ang pht trin
mnh, c th bn s mun gi ti ng dng Browser vi mt intent URL hn l hin th
trang Web bng WebView. V d:
Uri uri = Uri.parse("http://www.example.com");
307
Lp trnh Android c bn
// Cch s dng n gin nht: Lu , nu c li khi np trang ny
// th s KHNG c ngoi l no c nm ra (xem bn di).
webview.loadUrl(http://slashdot.org/);
getWindow().requestFeature(Window.FEATURE_PROGRESS);
webview.getSettings().setJavaScriptEnabled(true);
final Activity activity = this;
webview.setWebChromeClient(new WebChromeClient() {
308
Lp trnh Android c bn
}
});
webview.setWebViewClient(new WebViewClient() {
Toast.LENGTH_SHORT).show();
});
webview.loadUrl(http://developer.android.com/);
Qun l cookie v ca s
V l do bo mt c gii thch r phn trc, nn ng dng ca bn c cache
ring, lu tr cookie,... - cache ny khng chia s vi d liu ng dng trnh duyt.
Mc nh, yu cu m ca s mi ca HTML b b qua. iu ny ng trong c trng
hp ca s c m bng m JavaScript ln bng thuc tnh ch trn lin kt (link).
Bn c th ty chnh phng thc WebChromeClient cung cp hnh vi ca chnh
mnh nhm m nhiu ca s, ng thi hin th chng theo cch bn mun.
Hnh vi chun ca Activity b hy v c to li khi hng ca thit b thay i, hoc
khi c bt c cu hnh no khc thay i. iu ny cng lm cho WebView np li trang
hin ti. Nu khng thch cch x l trn, bn c th thit lp Activity ca mnh x
l thay i trong orientation v keyboardHidden, sau ch li mt mnh
WebView. Khi , WebView s t ng nh hng li cho ph hp. c mc Handling
Runtime Changes (X l cc thay i trong thi gian chy) tm hiu thm v cch
x l vic thay i cu hnh trong thi gian chy.
309
Lp trnh Android c bn
mt cao hn. n gin, Android chia tt c cc mt mn hnh thc thnh ba
mt chung: Cao, trung bnh v thp.
Mc nh, WebView s cn t l mt trang Web trang ny c v kch thc
ph hp vi vic hin th mc nh trn mn hnh mt trung bnh. Do , Android p
dng t l 1,5x trn mn hnh mt cao (do s pixel ca mn hnh ny nh hn) v t
l 0,75 trn mn hnh mt thp (do s pixel ln hn). Bt u vi API cp ECLAIR,
WebView h tr DOM, CSS v cc tnh nng ca th meta gip bn (trong vai tr
mt nh lp trnh Web) x l mn hnh vi nhng mt khc nhau.
Sau y l phn tng kt nhng tnh nng bn c th dng x l cc mt mn
hnh khc nhau:
Thuc tnh DOM window.devicePixelRatio. Gi tr ca thuc tnh
ny xc nh yu t t l mc nh dng cho thit b hin ti. V d, nu gi tr
window.devicePixelRatio l 1,0, thit b c xem l c mt trung bnh
(medium density - mdpi) v vic iu chnh kch thc mc nh s khng c
p dng cho trang Web ny; nu gi tr ny l 1,5, thit b ny c xem l thit
b mt cao (high density device - hdpi) v ni dung trang Web s c ko vi
t l 1,5x; nu gi tr ny l 0,75, thit b c xem l thit b c mt thp (low
density device - ldpi) v ni dung c ko vi t l 0,75x.
310
Lp trnh Android c bn
Mt kch bn ph bin cho thy vic s dng WebView rt c ch l khi bn mun cung
cp thng tin trong ng dng c th cn cp nht, chng hn nh mt tha thun vi
ngi dng cui hoc hng dn ngi dng. Bn trong ng dng Android, bn c
th to mt Activity cha WebView, sau dng Activity ny hin th vn bn
c host trc tuyn.
Kch bn khc m trong , WebView c th h tr l khi ng dng ca bn cung cp
d liu cho ngi dng, nhng ngi lun mun yu cu kt ni Internet truy xut
d liu, chng hn nh e-mail. Trong trng hp ny, bn c th thy tht d dng
xy dng mt WebView trong ng dng Android ca mnh nhm hin th trang Web vi
ton b d liu ngi dng thay v thc hin mt yu cu mng, sau phn tch v
hin th d liu trn mn hnh Android. Thay v th, bn c th thit k mt trang Web
ph hp vi thit b Android, sau ci t WebView trong ng dng Android np
trang Web.
Ti liu ny s hng dn bn cch khi ng vi WebView cng nh cch b sung
thm mt s tnh nng, chng hn nh x l iu hng trang v lin kt JavaScript t
trang Web ti m pha client (client-side code) trong ng dng Android.
Tuy nhin, trc khi thc hin m trn, ng dng ca bn phi c truy cp vo Internet.
ly truy cp vo Internet, hy yu cu quyn INTERNET trong file k khai. V d:
<manifest ... >
<uses-permissionandroid:name=android.permission.INTERNET/>
...
</manifest>
311
Lp trnh Android c bn
312
Lp trnh Android c bn
313
Lp trnh Android c bn
Ch S dng phng thc addJavascriptInterface() cho php JavaScript
iu khin ng dng Android ca bn. y c th l mt tnh nng hu dng, hoc
l mt vn bo mt nguy him. Khi HTML trong WebView c ngun gc khng
ng tin (v d, mt phn hoc tt c HTML c mt ngi hoc tin trnh khng
xc nh cung cp), i tng tn cng c th a vo m HTML thc thi m pha
client ca bn v a vo bt c m no m i tng tn cng mun. Nh vy, bn
khng nn s dng phng thc addJavascriptInterface(), tr phi mun
ghi c m HTML ln JavaScript vo WebView ca bn. Bn cng khng nn cho
php ngi dng iu hng sang trang Web khc khng phi ca mnh, bn trong
i tng WebView (thay vo , hy cho php ng dng trnh duyt mc nh m
lin kt ngoi (foreign link) - mc nh, trnh duyt Web ca ngi dng m tt c lin
kt URL, nn bn cn cn thn khi x l iu hng trang nh miu t mc sau).
X l iu hng trang
Khi ngi dng nhn vo lin kt t trang Web trong WebView ca bn, hnh vi mc
nh ca Android l khi chy mt ng dng x l URL. Thng th trnh duyt Web
mc nh m v np URL ch (destination URL). Tuy nhin, bn c th ghi hnh vi
ny cho WebView ca mnh; do , lin kt m bn trong WebView ca bn. Sau ,
bn c th cho php ngi dng iu hng li hoc tin thng qua history trang Web
ca h c lu trong WebView do bn pht trin.
m lin kt c ngi dng nhn vo, bn ch cn cung cp WebViewClient
cho WebView ca bn, bng cch s dng phng thc setWebViewClient().
V d:
WebView myWebView =(WebView) findViewById(R.id.webview);
myWebView.setWebViewClient(new WebViewClient());
// WebView ca ti np trang
return false;
}
// Ngc li, lin kt ny khng phi l mt trang trn min
314
Lp trnh Android c bn
315