286
TRƯỜNG ĐẠI HC KHOA HC TNHIÊN KHOA CÔNG NGHTHÔNG TIN VÕ THÀNH NHT PHAN THÀNH TRUNG TÌM HIU HĐIỀU HÀNH ANDROID VÀ XÂY DNG NG DNG MINH HA - PHLC - KHÓA LUN TT NGHIP CNHÂN CNTT TP.HCM, 2010

Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

Embed Size (px)

DESCRIPTION

xxx

Citation preview

Page 1: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

TRƯỜNG ĐẠI HỌC KHOA HỌC TỰ NHIÊN

KHOA CÔNG NGHỆ THÔNG TIN

VÕ THÀNH NHẬT – PHAN THÀNH TRUNG

TÌM HIỂU HỆ ĐIỀU HÀNH ANDROID VÀ

XÂY DỰNG ỨNG DỤNG MINH HỌA

- PHỤ LỤC -

KHÓA LUẬN TỐT NGHIỆP CỬ NHÂN CNTT

TP.HCM, 2010

Page 2: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

2

LỜI GIỚI THIỆU

Android là một hệ điều hành mã nguồn mở được phát triển dựa trên nhân

Linux. Trong một hai năm trở lại đây, sự phát triển của Android đã có những bước

phát triển mạnh mẽ và dần chiếm cảm tình của người dùng. Do có lợi thế là được

xây dựng theo tiêu chí mở nên việc phát triển ứng dụng trên Android được cho là

khá dễ dàng. Tuy nhiên, nguồn tài liệu để lập trình được ứng dụng chạy trên

Android khá là rời rạc và chưa có sự sắp xếp và tổ chức tốt. Chính vì thế mà cuốn

Phụ lục này được viết ngoài mục đích hỗ trợ cho Khóa luận “Tìm hiểu Hệ điều

hành Android và xây dựng ứng dụng minh họa” còn có mục đích cao hơn đó là

cung cấp những cái nhìn cơ bản nhất, chung nhất giúp cho người đọc có thể dễ dàng

nắm bắt, học hỏi cách thức vận hành cũng như phát triển ứng dụng trên hệ điều

hành nhiều tiềm năng này.

Do thời gian thực hiện đề tài khá ngắn cho nên việc thiếu sót trong khi viết

phần Phụ lục này là một điều không thể tránh khỏi. Nhóm chúng em rất mong được

sự góp ý từ Thầy Cô và các Bạn. Nhóm chúng em xin chân thành cảm ơn.

Tp. Hồ Chí Minh, tháng 03 năm 2010

Nhóm sinh viên thực hiện

Võ Thành Nhật – Phan Thành Trung

Page 3: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

3

MỤC LỤC

MỤC LỤC .............................................................................................................. 3

DANH MỤC CÁC HÌNH ...................................................................................... 9

Phụ lục A Cuộc thăm dò hệ điều hành Android khuấy động thị trường

smart phone 19

Phụ lục B Những thống kê thú vị về Google Android trong những năm gần

đây (theo iTech.vn ngày 25/01/2010)....................................................................24

B.1 Những thống kê từ Google ...................................................................... 24

B.2 Những thông tin đáng chú ý .................................................................... 26

B.3 Báo cáo của Admob ................................................................................ 26

B.4 Báo cáo của Myxer ................................................................................. 28

Phụ lục C Danh sách các công ty trong Hiệp hội các thiết bị cầm tay mở .....29

Phụ lục D Các smart phone dùng hệ điều hành Android ...............................32

Phụ lục E So sánh các hệ điều hành hiện có trên smart phone ......................35

Phụ lục F Hai HĐH smartphone Android và iPhone tăng trưởng nhanh

nhất 39

Phụ lục G Lập trình trên Android ...................................................................41

G.1 Tổng quan Android ................................................................................. 41

G.1.1 Định nghĩa Android ......................................................................... 41

G.1.2 Tính năng và kiến trúc Android ........................................................ 41

G.2 Giới thiệu Java SE JDK, Android SDK , ADT, Eclipse và các bước cài đặt

44

G.2.1 Giới thiệu Java SE JDK, Android SDK, ADT, DDMS, Eclipse và mối

liên hệ giữa chúng .......................................................................................... 44

G.2.2 Các bước cài đặt để lập trình Android .............................................. 50

G.2.3 Các điều lưu ý sau khi cài đặt ........................................................... 64

G.3 Bước đầu làm quen với Android qua project HelloNhatTrungApp .......... 67

Page 4: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

4

G.3.1 Các bước tạo project HelloNhatTrungApp ...................................... 67

G.3.2 Cấu trúc của một project Android .................................................... 85

G.4 Làm quen với các khung nhìn trên Eclipse qua cái nhìn trên Android

project ................................................................................................................ 87

G.4.1 Khung nhìn Java .............................................................................. 87

G.4.2 Khung nhìn DDMS .......................................................................... 99

G.4.3 Tìm hiểu Debug ............................................................................. 104

G.5 Làm quen với nền tảng ứng dụng Android ............................................ 108

G.5.1 Các thành phần ứng dụng ............................................................... 109

G.5.2 Activities và Tasks ......................................................................... 114

G.5.3 Tiến trình và luồng ......................................................................... 115

G.5.4 Vòng đời các thành phần ứng dụng Android .................................. 115

G.6 Làm quen với các công cụ hỗ trợ sẵn có của Android SDK ................... 125

G.6.1 Android Development Tools Plugin (ADT) ................................... 125

G.6.2 Dalvik Debug Monitor Service (DDMS) ........................................ 126

G.6.3 Hierarchy Viewer ........................................................................... 128

G.6.4 Draw 9-patch ................................................................................. 130

G.6.5 Android Debug Bridge (ADB) ....................................................... 134

G.6.6 Các công cụ hỗ trợ khác ................................................................. 136

Phụ lục H Các vấn đề cơ bản trong lập trình Android ................................. 137

H.1 Các vấn đề và khái niệm cơ bản trong lập trình giao diện ...................... 137

H.1.1 Giới thiệu lập trình giao diện trên Android và các tính năng của nó 137

H.1.2 Các từ khóa thường gặp trong lập trình giao diện ........................... 141

H.1.3 Các đơn vị tính trên giao diện ........................................................ 142

H.1.4 Các thuộc tính thường gặp trên các View ....................................... 143

H.1.5 Tổng quát các View dưới cái nhìn hướng đối tượng ....................... 144

H.1.6 Cách thức xây dựng và thiết kế giao diện ....................................... 149

H.1.7 Cách thao tác control trên Java code .............................................. 152

H.2 Lập trình với giao diện cơ bản ............................................................... 153

Page 5: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

5

H.2.1 Các điều khiển chứa điều khiển khác (layout) ................................ 153

H.2.2 Các điều khiển thông dụng ............................................................. 164

H.3 Các chú ý khi lập trình giao diện ........................................................... 166

Phụ lục I Lập trình theo từng chủ đề ........................................................... 167

I.1 Lập trình giao diện tùy biến với Adapter ............................................... 167

I.1.1 Giới thiệu sơ lược BaseAdapter và các lớp con của nó ....................... 167

I.1.2 Dùng Adapter trên Spinner ................................................................ 168

I.1.3 Dùng Adapter trên Gallery................................................................. 170

I.1.4 Dùng Adapter trên ListView cơ bản .................................................. 173

I.1.5 Dùng Adapter trên ListView nâng cao ............................................... 175

I.1.6 Dùng Adapter trên GridView cơ bản ................................................. 177

I.1.7 Dùng Adapter trên GridView nâng cao .............................................. 179

I.1.8 Kinh nghiệm lập trình với Adapter .................................................... 182

I.2 Lập trình với hoạt cảnh chuyển động (Animation)................................. 183

I.2.1 Giới thiệu lập trình với Animation ..................................................... 183

I.2.2 Lập trình với TweenAnimation .......................................................... 184

I.2.3 Lập trình với FrameByFrameAnimation ............................................ 189

I.3 Lập trình với Media............................................................................... 191

I.3.1 Giới thiệu .......................................................................................... 191

I.3.2 Lập trình phát âm thanh trên Android ................................................ 193

I.3.3 Lập trình phát Video trên Android ..................................................... 193

I.3.4 Nhận xét ............................................................................................ 194

I.4 Lập trình với thao tác Telephony ........................................................... 195

I.4.1 Giới thiệu .......................................................................................... 195

I.4.2 Thực hiện gọi điện thoại tới một số cho trước .................................... 195

I.4.3 Thực hiện gửi tin nhắn SMS .............................................................. 197

I.4.4 Thực hiện chức năng rung điện thoại ................................................. 198

I.5 Lập trình với luồng (Thread) ................................................................. 198

I.5.1 Giới thiệu luồng ................................................................................. 198

Page 6: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

6

I.5.2 Các đặc tính và cách thức vận hành luồng ......................................... 199

I.5.3 Lập trình luồng .................................................................................. 200

I.6 Lập trình với thực đơn (Menu) .............................................................. 202

I.6.1 Giới thiệu thực đơn ............................................................................ 202

I.6.2 Cách thức lập trình ............................................................................ 203

I.6.3 Nhận xét ............................................................................................ 212

I.7 Lập trình với kiểu chữ (Font) ................................................................ 212

I.7.1 Giới thiệu .......................................................................................... 212

I.7.2 Cách lập trình .................................................................................... 213

I.7.3 Nhận xét ............................................................................................ 214

I.8 Lập trình với khung thoại (Dialog) ........................................................ 214

I.8.1 Giới thiệu .......................................................................................... 214

I.8.2 Cách thức lập trình ............................................................................ 215

I.9 Lập trình với nhập xuất tập tin............................................................... 220

I.9.1 Giới thiệu .......................................................................................... 220

I.9.2 Preferences ........................................................................................ 221

I.9.3 Files ................................................................................................... 222

I.9.4 Databases .......................................................................................... 226

I.9.5 Network............................................................................................. 231

I.10 Lập trình với MapView ......................................................................... 233

I.10.1 Giới thiệu ....................................................................................... 233

I.10.2 Cách thức lập trình ......................................................................... 235

I.10.3 Nhận xét ........................................................................................ 239

I.11 Lập trình thao tác WebKit ..................................................................... 239

I.11.1 Giới thiệu ....................................................................................... 239

I.11.2 Cách thức lập trình ......................................................................... 240

I.11.3 Nhận xét ........................................................................................ 241

I.12 Lập trình với các widget khác ............................................................... 241

I.12.1 Widget Date/Time .......................................................................... 241

Page 7: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

7

I.12.2 Widget Tab .................................................................................... 242

Phụ lục J Lập trình với EndlessList ............................................................. 245

J.1 Giới thiệu .............................................................................................. 245

J.2 Cách thức tạo EndlessList ..................................................................... 246

J.2.1 Cách thức vận hành của EndlessList: ................................................. 246

J.2.2 Cách thức lập trình tạo EndlessList .................................................... 247

J.3 Nhận xét ................................................................................................ 250

Phụ lục K Cấu trúc và ý nghĩa các thành phần của một project Android ... 251

Phụ lục L Hướng dẫn sử dụng, thao tác chính trên chương trình

eSaleShopping ..................................................................................................... 253

L.1 Sơ đồ liên kết các màn hình chức năng trong ứng dụng eSaleShopping . 253

L.2 Giới thiệu chức năng của màn hình chính .............................................. 254

L.2.1 Các chức năng trên màn hình chính ................................................ 254

L.2.2 Thực đơn (menu) chức năng của màn hình chính ........................... 255

L.3 Thao tác trên màn hình chụp mã vạch ................................................... 256

L.3.1 Sử dụng chức năng chụp mã vạch .................................................. 256

L.3.2 Các chức năng thực hiện sau khi chụp được mã vạch hàng hóa ...... 259

L.4 Thao tác trên màn hình tìm theo danh mục hàng hóa ............................. 262

L.5 Thao tác trên màn hình tìm theo chuỗi .................................................. 264

L.6 Thao tác trên màn hình tìm theo hệ thống siêu thị ................................. 265

L.6.1 Thao tác chính................................................................................ 265

L.6.2 Thao tác trên các chức năng trên một siêu thị được chọn ................ 267

L.6.3 Tìm hàng hóa siêu thị theo chuỗi .................................................... 269

L.6.4 Tìm hàng hóa siêu thị theo mã vạch ............................................... 269

L.6.5 Tìm hàng hóa siêu thị theo danh mục ............................................. 270

L.7 Thao tác quản lý danh sách hàng hóa ưa thích ....................................... 270

L.8 Thao tác quản lý danh sách hàng hóa cần mua ...................................... 271

L.8.1 Thao tác thêm hàng cần mua .......................................................... 272

Page 8: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

8

L.8.2 Thao tác xóa hàng cần mua ............................................................ 272

L.8.3 Thao tác gửi tin nhắn hàng cần mua ............................................... 273

Phụ lục M Các cấu trúc, mã lệnh, ứng dụng tham khảo được sử dụng

trong ứng dụng eSaleShopping .......................................................................... 275

M.1 Bộ gõ Tiếng Việt IME ........................................................................... 275

M.2 Chụp mã vạch hàng hóa (barcode)......................................................... 276

M.3 Ứng dụng bản đồ và vị trí ...................................................................... 279

M.3.1 Các tham số Google Map hỗ trợ tìm kiếm đường đi ....................... 279

M.3.2 Thể hiện đường đi trên bản đồ Google Map ................................... 280

M.3.3 Cách thức tìm vị trí thiết bị thông qua GPS hoặc mạng .................. 281

M.4 Ứng dụng EndlessList ........................................................................... 282

M.4.1 Giải pháp của M.Murphy ............................................................... 282

M.4.2 Giải pháp của Evan Charlton .......................................................... 283

M.5 Mã nguồn android-misc-widgets ........................................................... 284

M.5.1 Hiệu ứng hoạt cảnh ........................................................................ 285

M.5.2 Các widget mới .............................................................................. 285

Page 9: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

9

DANH MỤC CÁC HÌNH

Hình phụ lục 1 Hệ Điều Hành Android Của Google - Phần trăm người dự định mua

smart phone dùng hệ điều hành Android trong vòng 90 ngày tới (theo

ChangeWave) ................................................................................................. 19

Hình phụ lục 2 Ứng Tỉ lệ số người dùng dự định mua smart phone dùng hệ điều

hành giữa đợt thăm dò 09/2009 và 12/2009 (theo ChangeWave) .................... 20

Hình phụ lục 3 Tỉ lệ người dùng smart phone trong đợt thăm dò tháng 12/2009

(theo ChangeWave) ........................................................................................ 21

Hình phụ lục 4 Biểu đồ số người mua smart phone trong vòng 90 ngày tới thì nhà

sản xuất smart phone nào dự định mua giữa đợt thăm dò tháng 9/2009 và

12/2009 (theo ChangeWave) .......................................................................... 22

Hình phụ lục 5 Mức Độ Hài Lòng Dựa Trên Hệ Điều Hành Trong Đợt Thăm Dò

Tháng 12/2009 (theo ChangeWave) ............................................................... 23

Hình phụ lục 6 Dữ liệu thống kê trong 2 tuần cuối từ ngày 4/1/2010 ..................... 25

Hình phụ lục 7 Thống kê so sánh ba phiên bản hệ điều Android giữa hai thời điểm

17/12/2009 và 04/01/2010 .............................................................................. 25

Hình phụ lục 8 Thị phần các hệ điều hành trên smart phone theo từng khu vực ..... 26

Hình phụ lục 9 Thị phần hệ điều hành trên toàn thế giới ........................................ 27

Hình phụ lục 10 Biểu đồ cạnh tranh giữa iPhone và Android từ 01/01/2009 đến

01/12/2009 ..................................................................................................... 28

Hình phụ lục 11 Kiến trúc Android theo từng tầng (nguồn developer.Android.com)

....................................................................................................................... 42

Hình phụ lục 12 Trang web tải về Java SE trên Windows ...................................... 46

Hình phụ lục 13 Mục Eclipse cần tải về để làm IDE cho phát triển Android .......... 47

Hình phụ lục 14 Mục cần tải về ADT (nguồn developer.Android.com) ................. 49

Hình phụ lục 15 Biểu diễn trình tự và quan hệ giữa Java SE, Android SDK, ADT và

Eclipse. .......................................................................................................... 49

Hình phụ lục 16 Mục Android SDK cần tải về để dùng trên Windows .................. 50

Hình phụ lục 17 Lựa chọn mục Java SE (JDK) 6 ................................................... 51

Page 10: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

10

Hình phụ lục 18 Lựa chọn tải về bản JDK mới nhất............................................... 51

Hình phụ lục 19 Chọn lựa phiên bản JDK phù hợp với máy trạm .......................... 52

Hình phụ lục 20 Lựa chọn nơi lưu trữ tập tin JDK về máy ..................................... 52

Hình phụ lục 21 Chấp nhận điều khoản sử dụng JDK và tiến hành cài đặt ............. 53

Hình phụ lục 22 Lựa chọn đường dẫn để cài đặt bộ JDK ....................................... 53

Hình phụ lục 23 Mục lựa chọn bản Eclipse phù hợp với hệ thống .......................... 54

Hình phụ lục 24 Lựa chọn thư mục lưu trữ bộ Eclipse ........................................... 54

Hình phụ lục 25 Giải nén bộ IDE Eclipse .............................................................. 55

Hình phụ lục 26 Chọn Work space để làm việc khi khởi động Eclipse................... 55

Hình phụ lục 27 Mục chọn để cập nhật thêm phần mềm mới vào Eclipse .............. 56

Hình phụ lục 28 Chọn đường dẫn để đồng bộ bản ADT từ Google ........................ 56

Hình phụ lục 20 Lựa chọn các plug-in cần cài đặt vào Eclipse ............................... 57

Hình phụ lục 30 Lựa chọn tập tin ADT.zip để cập nhật vào Eclipse ...................... 58

Hình phụ lục 31 Chọn đường dẫn tới tập tin ADT.zip ............................................ 58

Hình phụ lục 32 Chọn cập nhật đường dẫn tới bộ Android SDK trên Eclipse ........ 59

Hình phụ lục 33 Trình đơn quản lý các bộ Android SDK và máy ảo ...................... 60

Hình phụ lục 34 Mục quản lý các thiết bị Android ảo ............................................ 61

Hình phụ lục 35 Mục cập nhật các gói hỗ trợ lập trình Android mới nhất từ Google

....................................................................................................................... 61

Hình phụ lục 36 Hình minh họa cho việc cập nhật một gói hỗ trợ mới nhất từ

Google ........................................................................................................... 62

Hình phụ lục 37 Mục tạo mới một diện thoại Android ảo ...................................... 63

Hình phụ lục 38 Thư mục chứa bộ Android SDK .................................................. 65

Hình phụ lục 39 Các thư mục bên trong bộ Android SDK ..................................... 66

Hình phụ lục 40 Mục tạo mới một project Android................................................ 67

Hình phụ lục 41 Các thông số cần quan tâm khi thiết lập một project Android mới

....................................................................................................................... 68

Hình phụ lục 42 Khung ứng dụng của HelloNhatTrungApp .................................. 71

Hình phụ lục 43 Màn hình thiết kế giao diện cho Android ..................................... 72

Page 11: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

11

Hình phụ lục 44 Màn hình hiện nút nhấn xóa TextViews ...................................... 73

Hình phụ lục 45 Màn hình hiện nút thêm TextView .............................................. 73

Hình phụ lục 46 Màn hình thêm mới một widget vào giao diện ............................. 74

Hình phụ lục 47 Màn hình chọn thêm mới một EditText ....................................... 75

Hình phụ lục 48 Màn hình thêm mới một LinearLayout ........................................ 75

Hình phụ lục 49 Màn hình thêm một Button .......................................................... 76

Hình phụ lục 50 Màn hình giao diện hoàn chỉnh .................................................... 77

Hình phụ lục 51 Các thẻ XML tạo nên giao diện ứng dụng HelloNhatTrungApp .. 77

Hình phụ lục 52 Màn hình thông báo lỗi mã hóa chuỗi khi lưu Tiếng Việt ............ 79

Hình phụ lục 53 Màn hình chọn thuộc tính của một project ................................... 80

Hình phụ lục 54 Màn hình lựa chọn thuộc tính mã hóa ký tự ................................. 81

Hình phụ lục 55 Màn hình chạy một ứng dụng Android từ Eclipse ........................ 82

Hình phụ lục 56 Màn hình minh họa trạng thái chạy cũa một ứng dụng ................. 83

Hình phụ lục 57 Màn hình đợi ứng dụng xử lý xong .............................................. 83

Hình phụ lục 58 Màn hình thao tác xử dụng ứng dụng HelloNhatTrungApp ......... 84

Hình phụ lục 59 Màn hình giao diện chính của Android 2.1 .................................. 84

Hình phụ lục 60 câu trúc ứng dụng Android trên Eclipse ....................................... 85

Hình phụ lục 61 Cấu trúc thư mục của một project Android trên bộ nhớ ............... 87

Hình phụ lục 62 Mành hình khung nhìn Java ......................................................... 88

Hình phụ lục 63 Cửa sổ Package Explorer ............................................................. 89

Hình phụ lục 64 Thực đơn ngữ cảnh của một project Android ............................... 90

Hình phụ lục 65 Hộp thoại Properties/Resource của một project Android ............. 91

Hình phụ lục 66 Hộp thoại Properties/Android của một project Android .............. 92

Hình phụ lục 67 Hộp thoại Properties/Java Build Path của một project Android ... 93

Hình phụ lục 68 Thực đơn ngữ cảnh của một tập tin .Java ..................................... 94

Hình phụ lục 69 Thực đơn ngữ cảnh Source trên một tập tin .Java......................... 95

Hình phụ lục 70 Hình minh họa cho một ghi chú mã lệnh của một phương thức ... 96

Hình phụ lục 71 Thực đơn ngữ cảnh Refactor trên một tập tin .Java ...................... 97

Hình phụ lục 72 Màn hình Outline ........................................................................ 98

Page 12: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

12

Hình phụ lục 73 Màn hình Outline ........................................................................ 99

Hình phụ lục 74 Khung nhìn DDMS ..................................................................... 99

Hình phụ lục 75 Khung nhìn của File Explorer .................................................... 100

Hình phụ lục 76 Khung nhìn của Devices ............................................................ 101

Hình phụ lục 77 Khung nhìn của Emulator Control ............................................. 101

Hình phụ lục 78 Màn hình Development Settings hỗ trợ lập trình cài sẵn trên điện

thoại Android ảo ........................................................................................... 102

Hình phụ lục 79 Khung nhìn Debug .................................................................... 103

Hình phụ lục 80 Màn hình thể hiện công đoạn debug .......................................... 104

Hình phụ lục 81 Tab Debug trong khung nhìn Debug .......................................... 105

Hình phụ lục 82 Tab Variables trong khung nhìn Debug ..................................... 106

Hình phụ lục 83 Tab Breakpoints trong khung nhìn Debug ................................. 106

Hình phụ lục 84 Tab Expressions trong khung nhìn Debug ................................. 107

Hình phụ lục 85 Tab thể hiện dòng hiện hành đang kiểm lỗi................................ 107

Hình phụ lục 86 Tab LogCat, Progress, Search, ErrorLog ................................... 108

Hình phụ lục 87 Vòng đời của một Activity ........................................................ 118

Hình phụ lục 88 Vòng đời của một Service ......................................................... 123

Hình phụ lục 89 Hình minh họa mối quan hệ giữ Eclipse, ADT và Android SDK 126

Hình phụ lục 90 Hình minh họa công cụ DDMS.................................................. 127

Hình phụ lục 91 Hình minh họa công cụ Hierarrchy Viewer ................................ 128

Hình phụ lục 92 Cấu trúc dạng cây khi phân tích một khung giao diện đang được

thực thi trên màn hình .................................................................................. 129

Hình phụ lục 93 Hình minh họa công cụ Pixel Perfect View ............................... 130

Hình phụ lục 94 Định nghĩa dạng hình NinePatch (Google) ................................ 130

Hình phụ lục 95 Hình minh họa cho việc thiết kế một ảnh nền của một nút nhấn

dùng định dạng hình NinePatch .................................................................... 131

Hình phụ lục 96 Hình nhận định về thuộc tính Strecthable của ảnh Nine Patch ... 132

Hình phụ lục 97 Hình nhận định về thuộc tính Padding của ảnh Nine Patch ........ 133

Hình phụ lục 98 Hình minh họa công cụ Draw 9-patch........................................ 134

Page 13: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

13

Hình phụ lục 99 Hình minh họa cách thức dùng dòng lệnh để thực thi công cụ adb

..................................................................................................................... 135

Hình phụ lục 100 Hình minh họa cách thức tạo biến môi trường (Windows XP) . 135

Hình phụ lục 101 Hình minh họa giao diện ứng dụng NhatTrungHelloAndroid .. 138

Hình phụ lục 102 Đoạn mã lệnh XML tạo giao diện cho ứng dụng

NhatTrungHelloAndroid .............................................................................. 138

Hình phụ lục 103 Hình minh họa cho việc kéo thả giao diện từ khung Layouts và

Views ........................................................................................................... 139

Hình phụ lục 104 Hình minh họa cho việc tạo giao diện từ khung Outline........... 139

Hình phụ lục 105 Hình minh họa việc thêm một phần tử mới từ khung Outline ... 140

Hình phụ lục 106 Các công cụ hỗ trợ bên trong thư mục Android SDK ............... 141

Hình phụ lục 107 Giao diện công cụ Hierarchy Viewer ....................................... 141

Hình phụ lục 108 Nhóm thuộc tính thường gặp trên một TextView ..................... 143

Hình phụ lục 109 Nhóm thuộc tính thường gặp trên một LinearLayout ............... 143

Hình phụ lục 110 Hình ảnh các View dưới góc nhìn hướng đối tượng ................. 144

Hình phụ lục 111 Hình ảnh minh họa của một Linear Layout .............................. 145

Hình phụ lục 112 Hình ảnh minh họa của một Relative Layout ........................... 146

Hình phụ lục 113 Hình ảnh minh họa của một Absolute Layout .......................... 147

Hình phụ lục 114 Hỉnh ảnh một số View thông dụng........................................... 148

Hình phụ lục 115 Hình ảnh minh họa cấu trúc dạng cây của một giao diện bất kỳ

..................................................................................................................... 148

Hình phụ lục 116 Hình minh họa tạo giao diện bằng mã lệnh XML .................... 149

Hình phụ lục 117Hình minh họa tạo giao diện bằng Java..................................... 149

Hình phụ lục 118 Cấu trúc xây dựng giao diện bằng XML .................................. 150

Hình phụ lục 119 Hình minh họa việc quản lý các View thông qua định danh ID 152

Hình phụ lục 120 Hình minh họa một Linear Layout ........................................... 154

Hình phụ lục 121 Hình minh họa cho thuộc Layout_weight ................................ 157

Hình phụ lục 122 Hình minh họa cho một Table Layout ..................................... 158

Hình phụ lục 123 Hình minh họa cho một Frame Layout..................................... 160

Page 14: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

14

Hình phụ lục 124 Hình minh họa cho một Absolute layout .................................. 162

Hình phụ lục 125 Hình minh họa Relative Layout ............................................... 163

Hình phụ lục 126 Hình minh họa các điều khiển khác ......................................... 165

Hình phụ lục 127 Hình minh họa các điều khiển khác ......................................... 165

Hình phụ lục 128 Hình minh họa cho một Spinner trong Android ....................... 168

Hình phụ lục 129 Danh sách lựa chọn khi nhấn vào Spinner ............................... 169

Hình phụ lục 130 Hình minh họa việc tạo Giao diện có chứa Spinner.................. 169

Hình phụ lục 131 Hình minh họa Gallery ............................................................ 171

Hình phụ lục 132 Hình ảnh minh họa của một ListView...................................... 174

Hình phụ lục 133 Minh họa việc tạo một List View ............................................. 174

Hình phụ lục 134 Hình minh họa một Custom ListView ..................................... 175

Hình phụ lục 135 Hình minh họa cách thức làm một custom row cho một ListView

..................................................................................................................... 176

Hình phụ lục 136 Hình minh họa cách thức làm một ListView ............................ 176

Hình phụ lục 137 Hình ảnh minh họa một GridView đơn giản ............................ 178

Hình phụ lục 138 Cách thưc tạo một GridView .................................................. 178

Hình phụ lục 139 Hình ảnh minh họa một Custom GridView .............................. 180

Hình phụ lục 140 Cách thức tạo một Custom Item cho một Grid View ................ 180

Hình phụ lục 141 Hình minh họa cách thức tạo một GridView ............................ 180

Hình phụ lục 142 Tập tin quy định hoạt cảnh chuyển động .................................. 183

Hình phụ lục 143 Hình ảnh minh họa sự hỗ trợ của Eclipse giúp tạo hiệu ứng hoạt

cảnh.............................................................................................................. 184

Hình phụ lục 144 Hình minh họa cho Tweened Animation .................................. 185

Hình phụ lục 145 Công cụ hỗ trợ thiết kế hoạt cảnh từ Eclipse ............................ 186

Hình phụ lục 146 Hình minh họa một Frame-by-frame animation đơn giản......... 190

Hình phụ lục 147 Hình ảnh một bộ MediaController hỗ trợ việc phát Video tốt hơn

..................................................................................................................... 194

Hình phụ lục 148 Hình minh họa việc gọi điện dùng ACTION.CALL................. 196

Hình phụ lục 149 Hình minh họa việc gọi điện dùng ACTION.DIAL ................. 196

Page 15: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

15

Hình phụ lục 150 Hình minh họa tiến trình và luồng ........................................... 199

Hình phụ lục 151 Lập trình luồng dùng Message ................................................. 200

Hình phụ lục 152 Hình minh họa lập trình luồng ................................................. 201

Hình phụ lục 153 Lập trình luồng dùng Post ........................................................ 202

Hình phụ lục 154 Hình minh họa thực đơn của hệ thống ..................................... 203

Hình phụ lục 155 Hình minh họa thực đơn ngữ cảnh ........................................... 203

Hình phụ lục 156 Hình minh họa tạo menu bằng mã lệnh Java ............................ 204

Hình phụ lục 157 Hình minh họa tạo menu bằng XML........................................ 204

Hình phụ lục 158 Hình minh họa thao tác tạo menu thông qua công cụ hỗ trợ được

tích hợp bên trong Eclipse (ADT) ................................................................. 207

Hình phụ lục 159 Hình minh họa tạo thực đơn ngữ cảnh ..................................... 212

Hình phụ lục 160 Hình minh họa dùng font chữ khác trong Android ................... 213

Hình phụ lục 161 Hình minh họa các thức chọn font chữ thông thường mà Android

hỗ trợ ............................................................................................................ 213

Hình phụ lục 162 Hình minh họa thư mục chứa tập tin font chữ (.ttf) trong một

project Android ............................................................................................ 214

Hình phụ lục 163 Hình minh họa hộp thoại có nút nhấn ...................................... 217

Hình phụ lục 164 Hình minh họa hộp thoại dạng danh sách chọn ........................ 217

Hình phụ lục 165Hình minh họa hộp thoại dạng danh sách lựa chọn RadioButton

..................................................................................................................... 218

Hình phụ lục 166 Hình minh họa hộp thoại dạng ProgressDialog ........................ 219

Hình phụ lục 167 Hình minh họa ProgressDialog dạng thanh trượt ngang ........... 219

Hình phụ lục 168 Hình minh họa tạo hộp thoại từ một gioa diện ......................... 220

Hình phụ lục 169 Hình minh họa thư mục chứa các lưu trữ Preferences nằm trong

hệ thống của điện thoại ................................................................................. 221

Hình phụ lục 170 Hinh minh họa thư mục mặc định lưu trữ tập tin SQLite của một

ứng dụng trên hệ thống Android ................................................................... 228

Hình phụ lục 171 Hình minh họa thư mục chứa tập tin debug.keystore (Windows 7)

..................................................................................................................... 236

Page 16: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

16

Hình phụ lục 172 Hình minh họa trang web lấy mã đăng ý Google Maps ApiKey từ

Google ......................................................................................................... 238

Hình phụ lục 173 Hình minh họa Date widget ..................................................... 241

Hình phụ lục 174 Hình minh họa Time widget .................................................... 241

Hình phụ lục 175 Hình minh họa giao diện dạng Tab trong Android ................... 242

Hình phụ lục 176 Mã XML minh họa cho việc tạo một khung ứng dụng Tab đơn

giản .............................................................................................................. 243

Hình phụ lục 177 Hình minh họa cấu trúc của một Tab widget ............................ 243

Hình phụ lục 178 Hình minh họa cho một EndlessList được áp dụng vào

eSaleShopping .............................................................................................. 247

Hình phụ lục 179 Sơ đồ liên kết các màn hình của ứng dụng eSaleShopping ...... 253

Hình phụ lục 180 Sơ đồ liên kết các màn hình của ứng dụng eSaleShopping (tiếp)

..................................................................................................................... 254

Hình phụ lục 181 Màn hình chính của ứng dụng eSaleShopping ......................... 254

Hình phụ lục 182 Menu chức năng của màn hình chính ....................................... 256

Hình phụ lục 183 Màn hình chụp và tìm kiếm hàng hóa dựa theo mã vạch .......... 256

Hình phụ lục 184 Các bước tiến hành tải về ứng dụng Barcode Scanner .............. 257

Hình phụ lục 185 Màn hình chụp thông tin của một mã vạch hàng hóa ............... 258

Hình phụ lục 186 Màn hình hiển thị kết quả đọc được từ quá trình chụp mã vạch 258

Hình phụ lục 187 Màn hình gợi ý tìm hàng hóa theo chuỗi .................................. 259

Hình phụ lục 188 Màn hình danh sách hàng hóa ứng với một mã vạch nào đó .... 260

Hình phụ lục 189 Màn hình thêm thông tin của một hàng hóa vào danh sách hàng

hóa cần mua ................................................................................................. 261

Hình phụ lục 190 Màn hình danh sách các hàng hóa ưa thích .............................. 261

Hình phụ lục 191 Màn hình thông tin chi tiết của một hàng hóa .......................... 262

Hình phụ lục 192 Màn hình tìm kiếm theo danh mục hàng hóa và loại hàng hóa

tương ứng ..................................................................................................... 262

Hình phụ lục 193 Màn hình danh sách hàng hóa .................................................. 263

Hình phụ lục 194 Màn hình tìm kiếm hàng hóa theo chuỗi .................................. 264

Page 17: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

17

Hình phụ lục 195 Menu của màn hình tìm kiếm hàng hóa theo chuỗi .................. 264

Hình phụ lục 196 Màn hình trợ giúp người dùng tìm kiếm hiệu quả hơn ............. 265

Hình phụ lục 197 Màn hình tìm theo danh sách hệ thống các siêu thị .................. 266

Hình phụ lục 198 Màn hình danh sách siêu thị con của hệ thống siêu thị ............. 266

Hình phụ lục 199 Các chức năng khi chọn vào một siêu thị trong một hệ thống siêu

thị ................................................................................................................. 267

Hình phụ lục 200 Màn hình thông tin chi tiết của một siêu thị ............................. 268

Hình phụ lục 201 Màn hình thông tin bản đồ đường đi đến siêu thị ..................... 269

Hình phụ lục 202 Menu của ứng dụng bản đồ đường đi đến siêu thị .................... 269

Hình phụ lục 203 Màn hình tìm kiếm theo danh mục hàng hóa và loại hàng hóa

tương ứng ..................................................................................................... 270

Hình phụ lục 204 Màn hình danh sách các mặt hàng ưa thích .............................. 271

Hình phụ lục 205 Màn hình danh sách hàng hóa cần mua .................................... 271

Hình phụ lục 206 Menu của màn hình danh sách hàng cần mua .......................... 272

Hình phụ lục 207 Màn hình thêm hàng hóa cần mua ........................................... 272

Hình phụ lục 208 Màn hình xóa hàng cần mua .................................................... 273

Hình phụ lục 209 Hộp thoại hỏi người dùng có thực sự muốn xóa một mặt hàng nào

đó hay không ................................................................................................ 273

Hình phụ lục 210 Màn hình gửi tin nhắn hàng cần mua ....................................... 274

Hình phụ lục 211 Màn hình sử dụng bộ gõ Tiếng Việt IME trên Android 1.5 và 2.1

..................................................................................................................... 276

Hình phụ lục 212 Nội dung của một gói mã nguồn ZXing ................................... 277

Hình phụ lục 213 Mã nguồn ZXing dành cho HĐH Android ............................... 277

Hình phụ lục 214 Ứng dụng vẽ đường đi trên bản đồ Google Map trong

eSaleShopping .............................................................................................. 281

Hình phụ lục 215 Hình minh họa và bug lỗi cũa EndlessAdapter ......................... 283

Hình phụ lục 216 Hình minh họa của ứng dụng Magnatune ................................ 284

Hình phụ lục 217 Các lớp tạo hiệu ứng chuyển động được dùng lại trong ứng dụng

eSaleShopping .............................................................................................. 285

Page 18: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

18

Hình phụ lục 218 Ứng dụng Panel tạo khung chỉ đường đi trên bản đồ trong

eSaleShopping .............................................................................................. 286

Hình phụ lục 219 Ứng dụng Switcher tạo lựa chọn hình thức bán hàng trong

eSaleShopping .............................................................................................. 286

Page 19: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

19

Phụ lục A Cuộc thăm dò hệ điều hành Android khuấy

động thị trường smart phone

Tác giả Paul Carton và Jean Crumrine

Ngày 04 tháng 01 năm 2010

Hệ điều hành Android của Google ra đời cách đây hơn một năm và nó được

mong đợi là hệ điều hành có thể thay đổi được thị trường smart phone trên toàn thế

giới.

Theo đợt thăm dò 4068 khách hàng từ ngày 9 đến ngày 14 tháng 12 của

ChangeWave với chủ đề hệ điều hành Android ảnh hưởng đến thị trường smart

phone, thì trong thời điểm đó có 4% nói là họ đang dùng hệ điều hành Android có

nghĩa là tăng 3% so với đợt thăm dò của ChangeWave trong tháng 9.

Nhưng quan trọng hơn, 21% trong những người nói dự định mua smart

phone dùng hệ điều hành Android trong vòng 90 ngày tới.

Hình phụ lục 1 Hệ Điều Hành Android Của Google - Phần trăm người dự định mua smart phone dùng

hệ điều hành Android trong vòng 90 ngày tới (theo ChangeWave)

Trong đợt thăm dò trước đó tức là tháng 09/2009, chỉ có 6% số người được

hỏi trả lời là sẽ mua smatphone dùng hệ điều hành Android trong vòng 90 ngày tới

1% 2% 2%4% 4% 3%

6%

21%

0%

5%

10%

15%

20%

25%

Hệ Điều Hành Android Của GooglePhần trăm người dự định mua smartphone dùng hệ điều

hành Android trong vòng 90 ngày tới

Phần trăm người dự định mua smartphone dùng hệ điều hành Android trong vòng 90 ngày tới

Page 20: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

20

nhưng trong thời điểm tháng 12/2009 thì con số đó đã tiến lên 21% giành vị trí thứ

2 sau hệ điều hành iPhone OS X chiếm 28% mặc dù đã giảm 4% so với đợt thăm dò

trước đó.

Hình phụ lục 2 Ứng Tỉ lệ số người dùng dự định mua smart phone dùng hệ điều hành giữa đợt thăm

dò 09/2009 và 12/2009 (theo ChangeWave)

Trái lại với sự tăng vọt của Google Android, RIM OS chỉ tăng nhẹ 1%, còn

Windows Mobile và Palm OS/Web OS giảm 3% từ đợt thăm dò tháng 9/2009.

Những con số rút ra từ những đợt thăm dò ấy có ảnh hưởng lớn đối với các nhà sản

xuất smart phone. Nhưng đáng ghi nhận là sự tăng tưởng này diễn ra ngay tại thời

điểm mà nghành công nghiệp sản xuất smart phone nhìn chung lớn mạnh.

Hơn nữa, 42% trong số người tham gia đợt thăm dò nói là họ đang dùng

smart phone, tăng 3% so với đợt thăm dò tháng 09/2009. Thêm vào đó, 12,8%

người trong đợt thăm dò nói là họ dự định mua smart phone trong vòng 90 ngày tới,

đây là con số lớn nhất từ trước tới nay trong các đợt thăm dò ý kiến người dùng của

ChangeWave.

32%

6%

17%

9%

6%

28%

21%

18%

6%

3%

0%

5%

10%

15%

20%

25%

30%

35%

iPhone OS X Google Android

BlackBerry RIM OS

Windows Mobile

Palm OS/Web OS

Đợt thăm dò (09/2009)

Đợt thăm dò (12/2009)

Page 21: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

21

Hình phụ lục 3 Tỉ lệ người dùng smart phone trong đợt thăm dò tháng 12/2009 (theo ChangeWave)

Trong đợt thăm dò này, khi ChangeWave đưa ra câu hỏi là nếu bạn muốn

mua smart phone trong 90 ngày tới thì nhà sản xuất smart phone nào mà bạn chọn

để mua với kết quả là biểu đồ sau:

15% 16% 17%20% 21% 22% 23%

27%

32% 32%34%

37%39%

42%

0%

5%

10%

15%

20%

25%

30%

35%

40%

45%

Tỉ lệ số người dùng smartphone trong đợt thăm dò tháng 12/2009

Tỉ lệ số người dùng smartphone

Page 22: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

22

Hình phụ lục 4 Biểu đồ số người mua smart phone trong vòng 90 ngày tới thì nhà sản xuất smart

phone nào dự định mua giữa đợt thăm dò tháng 9/2009 và 12/2009 (theo ChangeWave)

Mặc dù thị phần sức mua iPhone của Apple giảm từ 36% còn 32% kể từ đợt

thăm dò tháng 09/2009 nhưng nó vẫn tiếp tục đứng đầu trong thị trường smart

phone. Trong đợt thăm dò này cho thấy iPhone vẫn đứng vị trí độc tôn đối với thị

trường smart phone trong thời gian sắp tới.

Không giống như cách đây một năm khi mà những sản phẩm mới của

Blackberry đã tạo ra sự đẩy mạnh cho RIM, số lượng người dùng dự định mua

RIM giảm 6 điểm còn 21%. Nhưng mà chúng ta ghi nhận rằng trong nửa đầu năm

2010 RIM đưa ra một vài mẫu Backberry với các phiên bản Tour, Pearl, Bold, và

Curve – và điều đó có nghĩa là giúp ngăn chặn sự lớn mạnh của Android và sự

thống trị của iPhone trong lòng khách hàng.

Còn về Palm, 6 tháng sau khi Palm Pre phát hành, tỉ lệ số người dùng dự

định mua máy Palm giảm từ 8% trong đợt thăm dò 9/2009 còn 4% trong đợt thăm

dò 12/2009. Rõ ràng là Palm bị mắt kẹt giữa hệ điều Android đang lên và hai nhà

cạnh tranh smart phone hùng mạnh là RIM và Apple. Biện pháp đối phó lớn nhất

của Palm là phát hành nhiều mẫu điện thoại mới dựa trên hai nhà phân phối mạng

lớn là Verizon và AT&T, hứa hẹn sự khởi sắc trong tương lai.

36%

27%

1%

5%8%

32%

21%

13%

9%

4%

0%

5%

10%

15%

20%

25%

30%

35%

40%

Đợt thăm dò 09/2009

Đợt thăm dò 12/2009

Page 23: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

23

Xét góc độ mức độ thỏa mãn người dùng di động, thì iPhone OS X tiếp tục

dẫn đầu trong tất cả các nhà sản xuất điện thoại di động với 77% số người nói là họ

rất hài lòng với iPhone. Với chi tiết theo biểu đồ sau:

Hình phụ lục 5 Mức Độ Hài Lòng Dựa Trên Hệ Điều Hành Trong Đợt Thăm Dò Tháng 12/2009 (theo

ChangeWave)

Trên là những tổng hợp từ bài báo cáo của ChangeWave do 2 tác giả Paul

Carton và Jean Crumrine đưa ra vào ngày 04/01/2010. So với thời điểm mà khóa

luận này báo cáo thì con số có thể khác đi đôi chút vì thị trường điện thoại smart

phone dần khởi sắc sau đợt khủng hoảng kinh tế thế giới trong năm 2009.

Như đã phân tích trong chương 1 của cuốn khóa luận thì Android đang vươn

lên là hệ điều hành tiềm năng trong tương lai và có thể vươn lên đứng vị trí dẫn đầu

trong nhiều khía cạnh và để làm được chuyện đó thì cần sự hợp tác của các bên

trong Hiệp hội các thiết bị cầm tay mở (OHA).

77%72%

41%33%

25%

0%

10%

20%

30%

40%

50%

60%

70%

80%

90%

iPhone OS X Google Android

Blackberry RIM OS

Palm OS/ Web OS

Windows Mobile

Mức Độ Hài Lòng Dựa Trên Hệ Điều Hành

Trong Đợt Thăm Dò Tháng 12/2009Tỉ lệ người dùng nói là họ rất hài lòng với hệ điều hành trên

smart phone của họ đang dùng

Tỉ lệ người dùng nói là họ rất hài lòng với hệ điều hành trên smart phone của họ đang dùng

Page 24: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

24

Phụ lục B Những thống kê thú vị về Google Android

trong những năm gần đây (theo iTech.vn ngày

25/01/2010)

Hệ điều hành “non trẻ” của Google đã có một năm 2009 rất thành công, nhất

là trong 2 quý cuối năm ngoái. Đây được xem là bước đệm vững chắc để Google

Android tiếp tục gặt hái được những thành công trong năm 2010:

Được sự hậu thuẫn to lớn từ Google và các nhà sản xuất di động hàng đầu

hiện nay như HTC, Motorola, Sony Ericsson, Samsung, Acer, hệ điều hành Google

Android đang dần được nhiều người biết đến và trở thành một đối thủ đáng gờm

cho các hệ điều hành di động khác như Windows Mobile, Symbian và đặc biệt là

RIM OS, WebOS và iPhone OS trong phân khúc điện thoại thông minh.

Dưới đây là những thống kê mới nhất liên quan đến nền tảng di động linh

hoạt và mạnh mẽ này:

B.1 Những thống kê từ Google

Giống như tháng trước, Google cũng đưa ra các số liệu mới nhất về thị phần

các thiết bị chạy trên các phiên bản Android khác nhau. Đây là các số liệu rất cần

thiết và rất quan trọng dành cho các nhà phát triển phần mềm, giúp họ có một cái

nhìn tổng quát hơn về các phiên bản hệ điều hành Android.

Theo số liệu từ Google, phiên bản Android 1.6 là nền tảng phổ biến nhất hiện

nay trong các nền tảng Android, với 47.6%. Tiếp theo sau là phiên bản Android 1.5

và Android 2.0.1 (phiên bản Android mới nhất, đang được sử dụng trên Motorola

Droid).

Page 25: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

25

Hình phụ lục 6 Dữ liệu thống kê trong 2 tuần cuối từ ngày 4/1/2010

So sánh từ 17/12/2009 đến 4/1/2010, các dòng điện thoại sử dụng phiên bản

Android 1.5 và Android 2.x đều tăng, trong khi các thiết bị sử dụng Android 1.6 lại

giảm, nhưng trong khoảng thời gian này, không có di động nào cập nhật lên các nền

tảng Android 2.x. Điều này có thể lý giải là số lượng bán ra của các dòng di động sử

dụng Android 1.5 và Android 2.x tăng cao, kéo theo thị phần của 2 nền tảng này

được tăng thêm.

Hình phụ lục 7 Thống kê so sánh ba phiên bản hệ điều Android giữa hai thời điểm 17/12/2009 và

04/01/2010

Trong số liệu thống kê mới nhất này, không có sự đóng góp từ Google Nexus

One, di động mới nhất của Google đang sử dụng Android 2.1.

Page 26: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

26

B.2 Những thông tin đáng chú ý

78.9% các thiết bị đang chạy trên nền tảng cũ kĩ là Android 1.5, 1.6 đều được

trông đợi là sẽ nâng cấp lên phiên bản mới nhất vào quý 2/2010

Có 31% các di động không sử dụng những ứng dụng mới nhất từ Google như

chức năng chỉ đường miễn phí Google Maps Navigation, phiên bản Android Market

mới, hay ứng dụng Goggles … (các ứng dụng này đòi hỏi phải sử dụng phiên bản

Android 1.6 trở lên)

21.1% các di động hỗ trợ cảm ứng đa chạm tích hợp sẵn vào hệ điều hành

(Android 2.x).

B.3 Báo cáo của Admob

Công ty quảng cáo trên di động Admob vừa mới đưa ra các thống kê mới

nhất về thị phần các hệ điều hành di động trên các dòng smart phone trong quý

4/2009.

Theo thị phần hệ điều hành phân chia theo từng khu vực, Android là hệ điều

hành phổ biến tại khu vực Bắc Mỹ với 43% và Tây Âu với 8%. Về thị phần smart

phone tính trên toàn thế giới, Android đạt được 16%, đứng ở vị trí thứ 3, sau iPhone

với 51% và Symbian với 21%.

Hình phụ lục 8 Thị phần các hệ điều hành trên smart phone theo từng khu vực

Page 27: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

27

Hình phụ lục 9 Thị phần hệ điều hành trên toàn thế giới

Tại thị trường Mỹ, thị phần của Android đang tăng rất ấn tượng và đang lấy

đi một phần thị phần từ iPhone OS. Trong tháng 12, thị phần của iPhone đạt 46%

trong khi thị phần của Android đã tăng lên 36%.

Theo nhiều chuyên gia dự đoán có nhiều khả năng thị phần của Android sẽ

vượt qua iPhone trong năm nay, khi số lượng các dòng smart phone chạy Android

đang tăng lên rất nhanh. Mới đây nhà mạng AT&T cũng đã cam kết sẽ gắn bó với

Android khi có kế hoạch phân phối 5 mẫu smart phone mới chạy Android trong

năm nay (bao gồm các dòng smart phone của Motorola, Dell và HTC). Như vậy là

sắp tới đây thị trường Mỹ sẽ có đến 4 nhà mạng không dây lớn nhất phân phối các

dòng di động chạy Android, bao gồm Verizon, Sprint, T-Mobile và mới nhất là

AT&T.

Page 28: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

28

Hình phụ lục 10 Biểu đồ cạnh tranh giữa iPhone và Android từ 01/01/2009 đến 01/12/2009

Lưu ý: Báo cáo của Admob được thống kê qua những hoạt động trên các ứng

dụng và mobile sites nằm trong mạng quảng cáo của Admob.

B.4 Báo cáo của Myxer

Báo cáo của Myxer, công ty giải trí trên di động với hơn 30 triệu thành viên

cho thấy lượng người dùng truy cập vào website của công ty qua di động sử dụng

Android tăng đến 350% trong năm 2009, vượt qua độ tăng trưởng của iPhone với

170%.

Phúc Trần (Theo AndroidAndMe- ReadWriteWeb - Gigaom)

Page 29: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

29

Phụ lục C Danh sách các công ty trong Hiệp hội các

thiết bị cầm tay mở

Các nhà

điều

hành

mạng

Viễn thông

Bouyguee

Tập đoàn

truyền thông

di động Trung

Quốc

Tập đoàn

truyền thông

Trung Quốc

Viễn thông

mạng liên hiệp

Trung quốc

Tập đoàn

KDDI

Công ty NTT

DoCoMo

Tập đoàn di

động

SOFTBANK

Truyền thông

Ý

Sprint Nextel

Telefonica

T-mobile

Vodafone

Công ty

phần

mềm

Tập đoàn

Ascender

eBay

Google

KivingImage

LTD

Myriad

Công ty truyền

thông Nuance

Công ty phần

mềm OMRON

PacketVideo

SkyPop

SONiVOX

Page 30: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

30

SVOX

Công ty

bán dẫn

Công ty bán

dẫn AKM

Audience

ARM

Truyền thông

Atheros

Tập đoàn

Broadcom

CSR Plc

Tập đoàn bán

dẫn Cypress

Công ty bán

dẫn Freescale

Tập đoàn Intel

Công ty bán

dẫn Marvell

Công ty công

nghệ MIPS

Tập đoàn

NVIDIA

Qualcomm

Công nghệ

Renesas

ST-Ericsson

Công ty

Synaptics

Texas

Instruments

Incoporated

Via Telecom

Các nhà

sản

xuất di

động

Acer

Điện thoại di

động Alcatel

Công ty máy

tính AsusTek

Foxconn

International

Holdings

Limited

Page 31: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

31

Công ty quốc

tế Garmin

Tập đoàn HTC

Công nghệ

Huawei

Kyocera

Lenovo

LG

Motorola

Samsung

Sony Ericsson

Toshiba

Tập đoàn ZTE

Page 32: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

32

Phụ lục D Các smart phone dùng hệ điều hành

Android

HTC

Dòng điện

thoại

Ngày ra mắt Hình ảnh

HTC Bravo Sắp ra mắt

Android 2.0

NexusOne 05/01/2010

Android 2.1

HTC Tattoo 07/09/2009

Android 1.5

HTC Hero 24/06/2009

Android 1.5

HTC Magic 30/04/2009

Android 1.5

Page 33: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

33

HTC

Dream(G1)

05/02/2009

Android 1.5

SAMSUNG

Galaxy i7500 Quý 2 năm 2009

Android 1.5

MOTOROLA

Motorola

Milestone

Quý 1 năm 2010

Android 2.0

Motorola

BackFlip

Quý 1 năm 2010

Android 1.5

Motorola Cliq

(DEXT

MB220)

Quý 4 năm 2009

Android 1.5

ACER

Page 34: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

34

Acer Liquid Quý 4 năm 2009

Android 1.6

SONY ERICSSION

Sony Ericsson

XPERIA X10

Quý 1 năm 2010

Androi 1.6

Page 35: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

35

Phụ lục E So sánh các hệ điều hành hiện có trên

smart phone

Android

Cupcake

Blackberry

OS 4.7

iPhone

OS 3.0

S60 5th

Edition

Palm

WebOS

Windows

Mobile 6.5

Các thông số cơ bản

Loại

nhân

Linux Sở hữu

riêng

OS X Symbian Linux Windows

CE

Độ khả

mở của

nền tảng

Xuất sắc Tốt Kém Xuất sắc Xuất sắc Xuất sắc

Tuổi đời

của nền

tảng

Mới “Trưởng

thành”

Lâu năm “Trưởng

thành”

Mới “Trưởng

thành”

Doanh

nghiệp

đối tác

hỗ trợ

đầu tiên

Không BlackBerr

y

- Exchange,

Domino,

blakcBerr

y

Exchange Exchange,

Domino,

BlackBerry

Công

nghệ kết

nối

không

dây

GSM,

WiFi

GSM,

CDMA,

WiFi

GSM,

WiFi

GSM,

WiFi

GSM,

CDMA,

WiFi

GSM,

CDMA,

WiFi

Giao diện người dùng

Page 36: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

36

Android

Cupcake

Blackberry

OS 4.7

iPhone

OS 3.0

S60 5th

Edition

Palm

WebOS

Windows

Mobile 6.5

Ra hiệu

trên màn

hình

Có Có Có Hạn chế Có Hạn chế

Công

nghệ

màn

hình

Điện dung Điện dung Điện dung Điện trở /

Điện dung

Điện dung Điện dung

Đa cảm

ứng

(không

chính

thức)

Có Có Không Có Không

Lớp bao

giao

diện

Có Có Không Có Không Có

Phương

thức

nhập

liệu

Bàn phím

ảo, bàn

phím vật

Bàn phím

ảo

Bàn phím

ảo

Bàn phím

ảo, bàn

phím vật

lý, khả

năng nhận

diện ký tự,

T9

Bàn phím

vật lý

Bàn phím

ảo, bàn

phím vật

lý, nhận

diện ký tự

Tính năng chính

Android

Cupcake

Blackberry

OS 4.7

iPhone

OS 3.0

S60 5th

Edition

Palm

WebOS

Windows

Mobile 6.5

Kiểu

thông

báo

Khay Pop-up,

nền

Pop-up Pop-up Khay Khay, Pop-

up

Công cụ Google BES, BIS Exchange, Exchange, Synergy Exchange,

Page 37: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

37

quản lý /

Danh bạ

tương

thích

ActiveSyn

c, Mac OS

Address

Book

Domino,

BlackBerr

y, iSync

Domino,

BlackBerry

,

ActiveSync

Xử lý đa

nhiệm

Có Có Không Có Có Có

Cắt /

dán

Có Có Có Có Có Có

Hỗ trợ

đa

phương

tiện

Amazon Non-DRM

iTunes

iTunes Ovi Amazon Windows

Media

Player

Global

Search

Không Không Có Có Có Không

Cập

nhật

firmwar

e

OTA Tethered,

OTA

Tethered Tethered,

OTA

Không rõ Tethered,

OTA

Trình

duyệt

Webkit Sở hữu

riêng

Webkit Webkit Webkit Internet

Eplorer

Tetherin

g

(không

chính

thức)

Có Có Có Có Có

Stereo

Bluetoot

h

Có Có Có Có Có Có

Khả năng hỗ trợ các nhà phát triển

Android

Cupcake

Blackberry

OS 4.7

iPhone

OS 3.0

S60 5th

Edition

Palm

WebOS

Windows

Mobile 6.5

Page 38: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

38

SDK Có Có Có Có Có Có

Cửa

hàng

ứng

dụng

trực

tuyến

Có Có Có có Có Có

Ứng

dụng bổ

sung

Trung

bình

Trung

bình

Cao Trung

bình

Thấp Cao

Các ứng

dụng

ban đầu

Không Không Có Có Không Có

Khả

năng

quản lý

ứng

dụng

trên

thiết bị

Xuất sắc Tốt Xuất sắc Tốt Xuất sắc Tốt

Page 39: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

39

Phụ lục F Hai HĐH smartphone Android và iPhone

tăng trưởng nhanh nhất

Ngày đăng: 25/2/2010 lúc 9h20

Theo nghiên cứu của Gartner, HĐH iPhone đã qua mặt Windows Mobile,

chiếm hạng 3 sau Symbian và BlackBerry.

Hãng nghiên cứu Gartner hôm thứ Ba cho biết, trong năm 2009, Android và

iPhone là 2 HĐH tăng trưởng nhanh nhất, doanh số của HĐH iPhone của Apple đã

qua mặt Windows Mobile. Hai HĐH Symbian và BlackBerry (RIM – Research In

Motion) vẫn dẫn đầu thị trường.

Số ĐTDĐ thông minh (smartphone)

chạy HĐH Symbian bán ra trên thế giới đạt

80,9 triệu máy trong năm 2009, tăng so với

72,9 triệu trong năm trước. Gartner cho biết,

vì tổng số smartphone bán ra tăng trưởng

nhanh hơn, từ 139,3 triệu máy năm trước lên

đến 172,4 triệu, thị phần của Symbian đã

giảm 46,9%. Thị phần đứng hạng nhì của

RIM tăng lên 19,9% so với 16,6% của năm

2008.

HĐH smartphone của Apple đứng hạng 3 với số iPhone bán ra trong năm

2009 là 24,9 triệu máy, so với 11,4 triệu của năm 2008, đạt 14,4% thị phần.

HĐH smartphone của Windows rớt xuống hạng 4 khi thị phần giảm từ

11,8% xuống 8,7% và số bán giảm 1,5 triệu máy. Theo Roberta Cozza, nhà phân

tích nghiên cứu chính của Gartner, phiên bản Windows Phones 7 Series mới tung ra

có vẻ là một HĐH cạnh tranh hơn, nhưng vì ĐTDĐ dùng HĐH mới này đến cuối

Page 40: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

40

năm nay mới được trình làng nên doanh số vẫn sẽ phải cố vươn lên trong suốt năm

2010.

Linux, trong đó có LiMo nhưng không bao gồm Android, sẽ còn phải lận đận

trong thị trường smartphone. Thị phần của Linux giảm từ 7,6% xuống còn 4,7%

trong năm 2009.

Android chỉ đứng hạng 6 trong năm 2009 với thị phần 3,9%. Tuy nhiên, con

số này sẽ sớm thay đổi. Doanh số ĐTDĐ Android thật sự bắt đầu tăng trong quý

4/2009. Bốn triệu trong tổng số 6,8 triệu máy được bán ra trong quý cuối năm 2009.

Theo Cozza, 69% trong số này được bán ở Bắc Mỹ nhờ chương trình khuyến mãi

ĐTDĐ Motorola Droid của hãng Verizon Wireless.

WebOS của Palm mới xuất hiện trên danh sách của Gartner với hạng 7, thị

phần là 0,7%.

Trong khi thị trường smartphone bùng nổ thì tổng doanh số ĐTDĐ trên thế

giới là 1,2 tỷ máy, giảm khoảng 1% so với năm 2008, Gartner cho biết.

Huy Thắng

Theo InfoWorld, 23/2/2010

Page 41: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

41

Phụ lục G Lập trình trên Android

G.1 Tổng quan Android

G.1.1 Định nghĩa Android

Android là hệ thống tuần tự các phần mềm cho thiết bị di động bao gồm hệ

điều hành, các trình điều khiển phần cứng và các ứng dụng cơ bản.

G.1.2 Tính năng và kiến trúc Android

G.1.2.1 Tính năng

Android gồm các tính năng như sau:

Khung ứng dụng: cho phép tái sử dụng lại các ứng dụng đã có sẵn.

Máy ảo Dalvik: là máy ảo được tinh chỉnh dành riêng cho thiết bị di

động chạy trên nền Android. Các chương trình Java đa phần chạy trên máy

ảo Java; trong khi đó, Dalvik là máy ảo dùng để chạy ứng dụng Java trên di

động Android.

Trình duyệt web được tích hợp sẵn: được dựa trên bộ mã nguồn mở

Webkit.

Hệ thống xử lý đồ họa được tối ưu hóa: gồm thư viện đồ họa 2D, thư

viện đồ họa 3D dựa trên nền OpenGL (tùy theo từng loại phần cứng đồ họa

của di động).

SQLite: dùng cho lưu trữ cơ sở dữ liệu cục bộ.

Media: hỗ trợ định dạng các tập tin âm thanh, video, và hình ảnh

thông thường như: MPEG4, H.264, MP3, AAC, AMR, JPG, PNG và GIF.

Điện thoại GSM với các chức năng nghe gọi, tin nhắn.

Hỗ trợ hầu hết các phương thức kết nối Bluetooth, EDGE, 3G, và

Wifi (tùy thuộc theo phần cứng điện thoại) .

Hỗ trợ các phần cứng: Camera, GPS, la bàn số, vả cảm nhận gia tốc

(tùy thuộc theo phần cứng điện thoại).

Page 42: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

42

Môi trường phát triển đa dạng: bao gồm thiết bị máy ảo, công cụ để

kiểm lỗi (debug), bộ nhớ và công cụ cung cấp thông tin giả lập và plugin cho

Eclipse.

G.1.2.2 Kiến trúc Android

Hình phụ lục 11 Kiến trúc Android theo từng tầng (nguồn developer.Android.com)

Hình phụ lục G. -1 trình bày các thành phần lớn trong hệ điều hành Android.

Mỗi phần được trình bày chi tiết trong các mục bên dưới.

G.1.2.3 Ứng dụng (Application)

Android đã bao gồm một bộ các ứng dụng chính như trình nhận email, trình

nhận tin SMS, lịch, bản đồ, trình duyệt web, danh bạ và các chương trình phụ trợ

khác. Tất cả các ứng dụng sử dụng ngôn ngữ lập trình Java.

G.1.2.4 Khung ứng dụng

Nhờ Android cung cấp nền tảng phát triển mở, các nhà phát triển có thể xây

dựng các ứng dụng đa dạng và sáng tạo. Các nhà phát triển có thể dùng các phần

Page 43: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

43

cứng thiết bị, lấy thông tin vị trí, chạy ngầm các dịch vụ, thiết lập cảnh báo, thêm

thông báo vào thanh trạng thái và nhiều cái khác nữa.

Các nhà phát triển có thể tác động sâu vào khung API mà các ứng dụng

chính đang dùng. Kiến trúc ứng dụng được thiết kế đơn giản để tái sử dụng lại các

thành phần trong ứng dụng đó. Như ứng dụng mua sắm xem giá cả có thể sử dụng

lại ứng dụng chụp mã vạch BarcodeZXing.

Tất cả các ứng dụng nền là một bộ các dịch vụ và hệ thống, bao gồm:

Bộ các View đa dạng và có thể tùy biến bao gồm: danh sách

(listView), lưới (gridView), textbox, nút (Button), và các View khác.

Content Provider: cho phép ứng dụng lấy dữ liệu từ ứng dụng khác (ví

dụ danh bạ) hoặc chúng chia sẽ dữ liệu với nhau..v .v . . .

Resource Manager: cho phép truy xuất các nguồn tài nguyên cục bộ

như chuỗi tĩnh, hình ảnh và tập tin khai báo giao diện, .v. v…

Notification Manager: cho phép ứng dụng trình bày cảnh báo tùy biến

trên thanh trạng thái.

Activity Manager: quản lý vòng đời ứng dụng.

Để hiểu thêm về khung ứng dụng, các bạn có thể tìm hiểu thêm trong project

Notepad.

G.1.2.5 Thư viện

Android bao gồm bộ thư viện C/C++ được dùng bởi ứng dụng chính của hệ

thống Android. Thông qua khung ứng dụng (Application framework), các nhà phát

triển có thể tiếp cận sâu vào lõi thư viện bao gồm:

Thư viện hệ thống C: được rút ra từ thư viện hệ thống C chuẩn (libc).

Thư viện media: dựa tên OpenCORE của PacketVideo, một bộ thư

viện hỗ trợ đọc, ghi lại nhiều định dạng âm thanh, video, hình ảnh như:

MPEG4, H.264, MP3, AAC, AMR, JPG, và PNG.

Surface Manager: quản lí giao diện bao gồm lớp giao diện 2D và 3D.

Page 44: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

44

LibWebCore: là bộ thư viện trình duyệt web mới hỗ trợ trình duyệt

Android và WebView.

SGL: hệ thống đồ họa 2D cơ sở.

Thư viện 3D: dựa trên OpenGL ES 1.0 API; thư viện gồm phần cứng

hỗ trợ 3D và phần mềm hỗ trợ tối ưu 3D.

FreeType: trình bày kiểu chữ và hình ảnh.

SQLite: hệ thống cơ sở dữ liệu có kích thước nhỏ nhưng mạnh mẽ cho

tất cả ứng dụng.

G.1.2.6 Android Runtime

Android bao gồm bộ thư viện chính, cung cấp hầu hết các tính năng cho bộ

thư viện kể trên và dùng ngôn ngữ Java.

Mỗi ứng dụng Android chạy trên tiến trình riêng của nó với một thể hiện

(instance) riêng của nó trên máy ảo Dalvik. Dalvik giúp thiết bị chạy nhiều máy ảo

cùng lúc. Máy ảo Dalvik chạy nhiều tập tin định dạng .dex được tối ưu hóa cho máy

có bộ nhớ thấp. Máy ảo được khai báo và chạy các lớp được biên dịch bởi trình biên

dịch ngôn ngữ Java mà mới vừa được chuyển sang định dạng .dex bởi công cụ có

sẵn “dx”.

Máy ảo Dalvik lệ thuộc vào lõi Linux cho các tính năng cơ bản như là luồng

và quản lý bộ nhớ mức độ thấp.

G.1.2.7 Lõi Linux

Android dựa trên nền Linux phiên bản 2.6 cho các chương trình hệ thống

chính như an ninh, quản lý bộ nhớ, quản lý tiến trình, mạng và mẫu trình điều khiển

thiết bị. Nhân Linux cũng đóng vai trò như là lớp ảo giữa phần cứng và phần còn lại

của kiến trúc Android.

G.2 Giới thiệu Java SE JDK, Android SDK , ADT, Eclipse và các

bước cài đặt

G.2.1 Giới thiệu Java SE JDK, Android SDK, ADT, DDMS, Eclipse và

mối liên hệ giữa chúng

Page 45: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

45

G.2.1.1 Giới thiệu chung

Để viết ứng dụng Android, chúng ta cần Java SE Development Kit (JDK),

Android SDK, môi trường phát triển phần mềm (IDE) và các công cụ hỗ trợ phát

triển phần mềm Android trên IDE đó.

Một cách “ngông cuồng” mà nói, ta có thể lập trình trên bất cứ trình soạn

thảo văn bản nào nhưng làm vậy sẽ mất rất nhiều thời gian trong khi lập trình ứng

dụng Android với IDE và các công cụ đi kèm có sự hỗ trợ cao về các công cụ hỗ trợ

lập trình giao diện, kiểm lỗi, hỗ trợ biên dịch chương trình,…

Kể từ các mục sau trở đi ta đi sâu vào tính năng từng thành phần và cách thức tải về

đối từng thành phần.

G.2.1.2 Giới thiệu Java SE Development Kit (JDK)

Java SE là hệ thống nền tảng Java và thường được cài đặt lên các máy trạm,

máy PC hay laptop để tiện lợi cho các nhà lập trình tiến hành phát triển các ứng

dụng có nền tảng Java. Cho nên dù muốn dù không thì khi lập trình với ứng dụng

Java trên máy trạm hay laptop hay PC thì trên máy phải có Java SE Development

Kit (JDK).

Android SDK là bộ phát triển ứng dụng Android trên nền Java và nó đòi hỏi

Java SE JDK phiên bản 5 hay cao hơn. Ta có thể tải về Java SE JDK tại địa chỉ sau:

http://Java.sun.com/Javase/downloads/widget/jdk6.jsp. Hiệp hội các thiết bị cầm tay

mở và Google chọn Java là nền tảng để xây dựng Android không chỉ có lí do là nó

là mã nguồn mở mà còn lí do quan trọng không kém là nó được hỗ trợ trên nhiều hệ

điều hành khác nhau từ Windows, Macintosh (x86), Solaris cho đến Linux.

Page 46: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

46

Hình phụ lục 12 Trang web tải về Java SE trên Windows

Trên là Java SE JDK là nền tảng, còn để lập trình trên Java thì có nhiều môi

trường phát triển phần mềm (IDE) chẳng hạn như Eclipse, Netbean, … Phần sau ta

sẽ tìm hiểu kĩ hơn về IDE Eclipse.

G.2.1.3 Giới thiệu Eclipse IDE

Về nguyên tắc mà nói, bạn có thể dùng bất kì môi trường phát triển phần

mềm Java nào mà bạn thích để phát triển ứng dụng. Thậm chí bạn có thể dùng

NotePad của Windows để viết các mã lệnh nhưng làm thế sẽ tốn rất nhiều thời gian

và khá phức tạp. Đối với Android, thì theo như Google khuyến cáo dùng Eclipse để

có sự hỗ trợ tối đa từ các công cụ lập trình Android mà Google cung cấp. Theo

chúng tôi biết, Netbean cũng có thể lập trình được ứng dụng Android nhưng về mặt

ổn định và hỗ trợ thì chúng tôi chưa phân tích kĩ và dùng thử. Tổ chức OHA và

Google khuyến cáo dùng Eclipse vì Eclipse có thể thực thi trên nhiều hệ điều hành

khác nhau mà không cần cài đặt trên chúng. Toàn bộ gói ứng dụng Eclipse có thể

tải về tại địa chi sau: http://www.eclipse.org/downloads/ . Phiên bản Eclipse IDE tối

Page 47: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

47

thiểu là 3.4 (Ganymede) hay 3.5 (Galileo) nhưng theo chúng tôi nên chọn phiên bản

Eclipse mới nhất trên địa chỉ tải về Eclipse bên trên để đạt được sự hỗ trợ tối đa từ

Eclipse IDE.

Hình phụ lục 13 Mục Eclipse cần tải về để làm IDE cho phát triển Android

Như vậy có Elipse và JDK ta có thể lập trình ứng dụng Java ngay trên các

máy trạm được. Do chúng ta lập trình ứng dụng Android nên cần JDK để có nền

tảng để lập trình Java, có IDE Eclipse để lập trình ứng dụng trên đó, bây giờ ta cần

thêm một Android SDK để hỗ trợ viết ứng dụng đặc thù Android với những công cụ

hỗ trợ của nó cùng với Eclipse có thể viết ứng dụng Android hoàn chỉnh. Để Eclipse

và Android SDK hiểu nhau thì ta cần có công cụ phát triển phần mềm Android có

tác “mồi” để Eclipse và Android SDK hiểu nhau. Mặc dù theo lí thuyết mà nói,

ADT là những công cụ nằm trong Android SDK nhưng ADT phải được cài đặt hay

đồng bộ hóa trước với Eclipse để “tạo đà” để lấy tất cả các bảng cập nhật nền tảng

Android về cho Android SDK.

G.2.1.4 Giới thiệu plugin ADT

Page 48: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

48

ADT là plugin mở rộng được tích hợp vào môi trường phát triển phần mềm

Eclipse. Nó cho phép ta tạo và kiểm lỗi ứng dụng Android dễ dàng hơn và nhanh

chóng hơn. Nếu bạn dùng Eclipse. Plugin ADT sẽ giúp bạn được các công việc sau:

Truy xuất trực tiếp đến các công cụ phát triển Android khác bên trong

Eclipse. Ví dụ, ADT cho phép truy xuất đến chức năng của công cụ DDMS

như: chụp màn hình, quản lý liên kết với thiết bị, đặt điểm dừng để kiểm lỗi,

và xem thông tin các luồng và tiến trình trự tiếp từ Eclipse.

Nó cung cấp New Project Wizard, mà giúp ta tạo và thiết lập tất cả

các tập tin cơ bản cần thiết cho một ứng dụng Android mới.

Nó tự động hóa và làm đơn giản hóa tiến trình xây dựng ứng dụng

Android.

Nó cung cấp trình biên tập mã lệnh Android mà giúp bạn viết lệnh

XML cho tập tin AndroidManifest và các tập tin tài nguyên khác.

Xuất ra tập tin .apk “đã đăng ký” (signed) hoặc “chưa đăng ký”

(unsigned) để mà phân phối ứng dụng cho người dùng cuối.

Nói chung, dùng Eclipse với plugin ADT, chúng ta có thể lợi dụng tính năng

cập nhật từ xa của Eclipse. Bằng cách thiết lập một trang cập nhật từ xa, bạn có thể

dễ dàng tải về, cài đặt, và kiểm tra những cập nhật ADT. Thật chất ADT không cài

đặt riêng lẻ hay chạy trên tập tin thực thi mà nó được “đính vào” Eclipse dưới dạng

plugin.Ta tải về ADT dưới dạng plugin dành cho Eclipse thông qua 2 hình thức là:

Cập nhật về 2 công cụ thông dụng là DDMS và ADT lên Eclipse qua

đường liên kết https://dl-ssl.google.com/android/eclipse/ thì sẽ có mục chọn

như đã nói là DDMS và ADT. Hai phần này sẽ được đính kèm vào Android

và đây là hai plugin mồi để tải về nền tảng Android dựa trên thư mục

Android SDK mà ta thiết lập sau đó.

Hay tải về tập tin ADT tại http://developer.Android.com/SDK/eclipse-

adt.html và sau đó đính kèm nó vào Eclipse cũng qua đường Help/Install

New Software có mục Add trên khung thoại Install thì ta sẽ Add achive cho

Page 49: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

49

nó. Ngay lập tức Eclipse sẽ hỗ trợ các công cụ và trình đơn cần thiết để thiết

lập Android SDK với nền tảng hệ điều hành các các công cụ khác của

Android SDK.

Hình phụ lục 14 Mục cần tải về ADT (nguồn developer.Android.com)

ADT là công cụ hỗ trợ lập trình đắc lực được gắn thêm trên Eclipse để các

nhà phát triển Android làm việc tốt hơn. Ta cũng có thể nhận định ADT như là

chiếc cầu nối giữa Eclipse và Android SDK. Ta tóm tắt lại theo mô hình sau:

Hình phụ lục 15 Biểu diễn trình tự và quan hệ giữa Java SE, Android SDK, ADT và Eclipse.

Một khi thiết lập ADT xong, ta sẽ tải về tập tin Android SDK để nhờ ADT

trên Eclipse để thiết lập giữa Eclipse IDE và Android SDK.

G.2.1.5 Giới thiệu Android SDK

Android SDK là nền tảng xây dựng ứng dụng Android trên nền Java và được

cung cấp trực tiếp trên trang web: http://developer.Android.com/SDK/index.html

với 3 phiên bản dành cho ba hệ điều hành khác nhau gồm Windows, Mac và Linux.

Eclipse

ADT

Android SDK

Java SE JDK

Page 50: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

50

Hình phụ lục 16 Mục Android SDK cần tải về để dùng trên Windows

Android SDK là một tập tin dạng nén .zip và khi giải nén ra thì ta sẽ có một

thư mục /android-sdk-windows cùng với các thư mục /tools với các công cụ đi kèm

phía bên trong nhưng thư mục /platform thì vẫn còn trống chưa có gì. Nhiệm vụ duy

nhất của ta hiện giờ là kết nối Eclipse và Android SDK hiểu nhau sau đó cập nhật

lại nền tảng và các công cụ cho Android SDK.

Một khi thiết lập tham chiếu đến thư mục Android SDK cho Eclipse thì trên

Eclipse có mục Android SDK and AVD Manager để tải về các thành phần nền tảng

mà chúng ta cần như là nền tảng Android, các SDK add-on, các công cụ, và tài liệu

hướng dẫn.

G.2.2 Các bước cài đặt để lập trình Android

G.2.2.1 Cài đặt Java (JDK)

Vào trang http://developers.sun.com/downloads/ để tải bộ JDK mới

nhất về máy tính.

Tiến hành theo các bước sau để cài đặt JDK.

Chọn mục Java SE Java SE (JDK) 6

Page 51: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

51

Hình phụ lục 17 Lựa chọn mục Java SE (JDK) 6

Tải về phiên bản JDK 6 update 18

Hình phụ lục 18 Lựa chọn tải về bản JDK mới nhất

Chọn hệ thống cài đặt là Windows và tiến hành tải JDK về

Page 52: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

52

Hình phụ lục 19 Chọn lựa phiên bản JDK phù hợp với máy trạm

Chọn nơi lưu trữ

Hình phụ lục 20 Lựa chọn nơi lưu trữ tập tin JDK về máy

Tiến hành cài đặt JDK

Page 53: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

53

Hình phụ lục 21 Chấp nhận điều khoản sử dụng JDK và tiến hành cài đặt

Hình phụ lục 22 Lựa chọn đường dẫn để cài đặt bộ JDK

Chờ trong ít phút để quá trình cài đặt hoàn tất.

G.2.2.2 Cài đặt Eclipse

Vào trang http://www.eclipse.org/downloads/ để tải về bộ Eclipse

phục vụ việc phát triển ứng dụng Android.

Tiến hành theo các bước sau để cài đặt Eclipse.

Chọn bản Eclipse IDE for Java Developer (92MB), phiên bản

dành cho Windows 32bit.

Page 54: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

54

Hình phụ lục 23 Mục lựa chọn bản Eclipse phù hợp với hệ thống

Chọn nơi lưu trữ bộ Eclipse. Ta chọn ổ đĩa C để lưu trữ.

Hình phụ lục 24 Lựa chọn thư mục lưu trữ bộ Eclipse

Sau khi đã tải về toàn bộ file nén tại ổ đĩa C, ta tiến hành giải nén.

Page 55: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

55

Hình phụ lục 25 Giải nén bộ IDE Eclipse

Sau khi giải nén ta thu được thư mục tương ứng là c:\eclipse. Bên

trong thư mục sẽ có file thực thi để chạy chương trình Eclipse, để tiện lợi

hơn ta nên tạo Shortcut cho Eclipse ngoài màn hình Desktop.

Quá trình thiết lập Eclipse hoàn tất.

G.2.2.3 Thiết lập ADT (Android Development Tools)

Khởi động Eclipse

Chọn Workspace thích hợp(đường dẫn tới thư mục sẽ chứa toàn bộ

các project Android, ví dụ: C:\Documents and Settings\Admin\workspace).

Hình phụ lục 26 Chọn Work space để làm việc khi khởi động Eclipse

Thiết lập thông số để cập nhật ADT vào Eclipse.

Chọn HelpInstall New Software.

Page 56: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

56

Hình phụ lục 27 Mục chọn để cập nhật thêm phần mềm mới vào Eclipse

Ta sẽ có 2 cách thức để cập nhật plugin ADT vào Eclipse và tùy

theo hoàn cảnh sẽ dùng cách 1 hoặc cách 2 .

Cách 1: cài đặt plugin ADT thông qua đồng bộ hóa với

thư mục Eclipse trên Google khi ta chưa có tập tin

ADT.zip.

o Sau khi nhấn nút Add, ta sẽ nhập địa chỉ http://dl-

ssl.google.com/android/eclipse/ vào ô Location

và nhấn OK

Hình phụ lục 28 Chọn đường dẫn để đồng bộ bản ADT từ Google

Page 57: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

57

o Chương trình sẽ kiểm tra phiên bản ADT mới

nhất và thông báo lại cho người dùng chọn như

trong hình minh họa bên dưới.

Hình phụ lục 29 Lựa chọn các plug-in cần cài đặt vào Eclipse

o Chọn vào tất cả các mục và nhấn Next. Chương

trình sẽ tiến hành việc cập nhật plugin ADT.

Cách 2: cài đặt plugin ADT thông qua file zip. Cách

này tiện lợi hơn so với cách 1 ở trên do tiết kiệm được

thời gian và nhanh chóng.

o Tải về bộ plugin ADT mới nhất (tại thời điểm

của bài viết là phiên bản plugin ADT 0.9.5)

thông qua địa chỉ

http://dl.google.com/android/ADT-0.9.5.zip. Lưu

tập tin này vào ổ đĩa C của máy tính, lưu ý là

không giải nén.

Page 58: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

58

o Chọn nút Add, sau đó chọn nút Archive…

Hình phụ lục 30 Lựa chọn tập tin ADT.zip để cập nhật vào Eclipse

o Chọn file ADT-0.9.5.zip ở ổ đĩa chứa (ví dụ ổ đĩa

C) và nhấn Open

Hình phụ lục 31 Chọn đường dẫn tới tập tin ADT.zip

Page 59: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

59

o Chờ trong ít phút để chương trình Eclipse cập

nhật thông tin từ bản ADT-0.9.5.zip này.

Khởi động lại Eclipse để hoàn tất việc cập nhật ADT Plugin cho

Eclipse.

G.2.2.4 Sử dụng plugin ADT để thiết lập, cập nhật Android SDK và

thiết lập điện thoại ảo Android.

Cập nhật Android SDK vào Eclipse

Sau khi cài đặt ADT thành công, ta tiến hành thiết lập Android

SDK cho Eclipse. Chọn Windows/Preferences, tiếp theo chọn mục

Android và chỉ ra đường dẫn tới thư mục đang chứa bộ Android SDK (ví

dụ c:\android-sdk-windows\), sau đó nhấn chọn OK. Lưu ý, nên tải về và

giải nén Android SDK trước khi cài đặt ADT cho Eclipse.

Hình phụ lục 32 Chọn cập nhật đường dẫn tới bộ Android SDK trên Eclipse

Page 60: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

60

Chọn thực đơn Windows/ Android SDK and AVD Manager (mục

này chỉ xuất hiện khi cài đặt plugin ADT thành công).

Hình phụ lục 33 Trình đơn quản lý các bộ Android SDK và máy ảo

Ta sẽ thấy cửa sổ Android SDK and AVD Manager xuất hiện.

Trong đó có 3 chức năng chính:

Virtual Devices: Quản lý điện thoại Android ảo.

Installed Packages: Quản lý các gói hỗ trợ Android đã

được cài đặt vào Eclipse.

Available Packages: Thông tin các gói hỗ trợ Android

mới (SDK, tài liệu hướng dẫn, công cụ.v.v…) từ

Google.

Page 61: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

61

Hình phụ lục 34 Mục quản lý các thiết bị Android ảo

Cài đặt Android SDK:

Chọn mục Available Packages ở phía bên trái của Android SDK

and AVD Manager và chờ chương trình cập nhật thông tin các gói hỗ trợ

Android mới nhất.

Hình phụ lục 35 Mục cập nhật các gói hỗ trợ lập trình Android mới nhất từ Google

Page 62: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

62

Hình phụ lục 36 Hình minh họa cho việc cập nhật một gói hỗ trợ mới nhất từ Google

Nhấn chọn vào các gói SDK mà ta mong muốn (hình minh họa

đang chọn bộ Android SDK 1.6 dành cho Windows), nhấn nút Install

Selected để tiến hành tải và cập nhật.

Thiết lập điện thoại Android ảo để hỗ trợ phát triển ứng dụng.

Chọn mục Virtual Devices ở phía bên trái của Android SDK and

AVD Manager, chọn New.

Page 63: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

63

Hình phụ lục 37 Mục tạo mới một diện thoại Android ảo

Các mục sau cần quan tâm khi tạo một điện thoại Android ảo:

Name: tên điện thoại Android ảo cần tạo.

Target: chọn phiên bản Android SDK mà ta muốn phát

triển ứng dụng.

SD Card: mô phỏng thẻ nhớ cho điện thoại. Ta có thể

chọn kích thước cho thẻ nhớ ảo (đơn vị tính là MiB hay

KiB) hoặc tìm chọn thẻ nhớ ảo đã được thiết lập sẵn từ

trước (là một tập tin có phần mở rộng là .iso được tạo

sẵn từ trước. Bạn có thể tham khảo việc tạo tập tin iso

trên Internet hay lệnh mksdcard có trong thư mục

\android-sdk-windows\tools).

Page 64: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

64

Ngoài ra, còn có các mục để chọn như: thay đổi skin, thêm sự hỗ

trợ phần cứng ảo cho điện thoại Android ảo và tùy theo mục đích sử dụng

mà các phần này được tùy chỉnh lại theo ý muốn.

Nhấn nút Create AVD để tạo điện thoại ảo Android.

Tất cả các thiết lập, tập tin để tạo điện thoại Android ảo, thẻ nhớ

ảo (file .iso) mà ta tạo bằng mục chọn Size đều tập trung tại thư mục

C:\Documents and Settings\<UserName>\.android\avd (Windows XP)

hay tương tự tại các hệ điều hành khác.

G.2.2.5 Nhận xét:

Với sự hỗ trợ của bộ ADT mới nhất từ Google (plugin ADT 0.9.5) việc lập

trình phát triển ứng dụng trên nền hệ điều hành Android đã thuận tiện hơn rất nhiều

như là ta có thể tải về các bộ Android SDK mới nhất từ Google hoặc tạo và quản lý

tốt hơn các điện thoại Android ảo thông qua giao diện người dùng trực quan (hộp

thoại Android SDK and AVD Manager) và các bước tiến hành đơn giản mà điều

này gần như là khó khăn đối với các phiên bản ADT trở về trước (mọi thứ đều phải

thiết lập bằng dòng lệnh gây khó khăn cho các lập trình viên khi mới tiếp cận

Android).

G.2.3 Các điều lưu ý sau khi cài đặt

G.2.3.1 Chú ý việc tạo máy ảo

Trong khi tạo máy ảo thì bạn chú ý việc chọn SD Card. Có 2 cách chọn SD

Card:

Size: nhập vào kích thước và tạo mới một SD Card đi kèm chung với

máy ảo đó.

File: cho chon một tập tin .iso để làm SD Card của máy ảo như vậy thì

máy ảo và SD Card tách rời nhau.

Giữa 2 cách trên thì mỗi cách có mặt lợi và hại riêng của nó. Theo kinh

nghiệm chúng tôi thì nếu:

Page 65: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

65

Chọn Size: thì bạn sẽ ít gặp lỗi hơn khi bị đứt kết nối giữa Eclipse và

máy ảo hoặc ta tắt ngang máy ảo trong khi đang kiểm lỗi (debug), ... Ví dụ

như, khi đang debug ứng dụng trên thiết bị ảo mà bạn tắt máy ảo “thô bạo”

thì lần sau, ta khởi động máy ảo lại và chạy bình thường. Nhưng nếu một khi

ta xóa máy ảo đi thì tập tin SD Card trong máy ảo cũng bị mất đi.

Chọn File: thì sẽ thường xuyên bị lỗi hơn khi bị vướng phải các vấn

đề trên mục chọn Size. Do mỗi một tập tin .iso chỉ được dùng bởi một máy

ảo, khi máy ảo chạy thì nó tạo ra tập tin “khóa” ngay bên cạnh tập tin iso đó,

khi chúng ta tắt ngang hay có lỗi xảy ra thì tập tin khóa đó chưa được xóa đi

nên những lần sau ta khởi động sẽ bị lỗi khi khởi động máy áo. Nhưng bù lại,

tập tin iso đó vẫn còn “y nguyên” khi ta xóa máy ảo đó đi trên hộp thoại

AVD Manager.

G.2.3.2 Chú ý đến các thư mục phát sinh và nhiệm vụ tiềm năng

của chúng

Như đã nói trong các phần trước của chương này, trong thư mục Android

SDK chứa các công cụ và tài liệu cho việc lập trình Android. Ta chú ý vào hình sau:

Hình phụ lục 38 Thư mục chứa bộ Android SDK

Nhấp vào android-sdk-windows ta chú ý hình sau:

Page 66: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

66

Hình phụ lục 39 Các thư mục bên trong bộ Android SDK

Ta cần chú ý các thư mục sau:

Add-ons: chứa các bộ APIs cho bộ thư viện của Google như Google

Maps chẳng hạn. Trong đó chứa các phương thức cùng với tài liệu hướng

dẫn cho từ bộ API.

Docs: chứa tài liệu hướng dẫn các bộ hàm cho toàn Android.

Platform: chứa các nền tảng Android tương ứng với từng máy ảo chạy

trên từng hệ điều hành Android tương ứng.

Tools: Trong này chứa tất cả các công cụ hỗ trợ lập trình Android.

SDK Setup: đây là tập tin khởi động hộp thoại tương ứng với hộp

thoại được mở bởi trình đơn Android SDK và AVD Manager.

Ngoài ra, khi tạo máy ảo, bạn để ý trong thư mục C:\Users\<user>\.android

(Windows 7) có tập tin debug.keystore. Hãy nhớ tập tin debug.keystore này vì sau

này nhờ tập tin này mà ta có thể lập trình với bản đồ Google Map.

G.2.3.3 Tham khảo sâu vào các tập tin hệ thống nền tảng

Bạn có thể vào thư mục ..\android-sdk-windows\platforms\android-2.1 và

tìm tòi trong đó. Có rất nhiều thành phần mà có có thể “vọc” như data, images,

samples, skins, templates và tools. Những thư mục này chứa các ví dụ và các tập tin

hệ thống về giao diện cũng như các tài nguyên mà ta có thể tham khảo rất tốt. Theo

kinh nghiệm chúng tôi, trong thư mục \sample và thư mục \data có rất nhiều tài

nguyên cho các bạn tham khảo.

Page 67: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

67

G.3 Bước đầu làm quen với Android qua project

HelloNhatTrungApp

G.3.1 Các bước tạo project HelloNhatTrungApp

G.3.1.1 Bước 1: Tạo project mới

Chọn File/New/ Android Project

Hình phụ lục 40 Mục tạo mới một project Android

Bạn sẽ thấy khung thoại sau:

Page 68: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

68

Hình phụ lục 41 Các thông số cần quan tâm khi thiết lập một project Android mới

Error! No text of specified style in document.-1 Khung thoại thiết lập Android projet mới

Các bạn đã quen với lập trình ứng dụng Java trên Eclipse sẽ làm quen rất

nhanh với khung thoại này, nhưng còn với các bạn chưa quen với lập trình ứng

Page 69: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

69

dụng Java trên Eclipse thì sẽ mất khoảng thời gian để hiểu các khái niệm cơ bản

như Package name hay Contents với các tùy chọn khác nhau. Từ màn hình này,

chúng tôi sẽ giải thích sơ lược mỗi mục chúng tôi chọn là gì để chúng ta có thể làm

quen với ứng dụng “đầu tay” của các bạn.

Điền vào tên ứng dụng Project name: HelloNhatTrungApp. Do chúng ta tạo

ứng dụng mới từ đầu cho nên ta chọn mục Create new project in workspace trong

phần Contents. Nếu tạo ứng dụng mới từ nguồn code có sẵn thì ta chọn mục Create

project from existing source. Còn nếu không thì chọn Create project from existing

sample nếu muốn chạy thử các ví dụ có sẵn có trong thư mục ../Android-SDK-

windows/add-ons/. Chúng ta tạm tóm gọn các mục trong Contents như sau:

Create new project in workspace: Tạo ứng dụng Android hoàn toàn

mới.

Create project from existing source: Tạo ứng dụng Android từ nguồn

có sẵn.

Use default location: chọn nơi lưu ứng dụng Android mặc định.

Create project from existing sample: Tạo ứng dụng Android từ ví dụ

sẵn có của Android SDK.

Phần Build target cho ta chọn các phiên bản hệ điều hành mà ứng dụng sẽ

được cài lên để nhận được sự hỗ trợ từ hệ điều hành. Ví dụ như nếu ta viết ứng

dụng có nhận biết giọng nói thì phải chọn Android 2.1 với API mức độ 7 để nhận sự

hỗ trợ từ hệ điều hành. Ngoài ra, nếu ứng dụng có sử dụng các hàm hỗ trợ bản đồ

hay các dịch vụ khác từ Google thì ta chọn Google API 2.1 mức độ 7. Nhìn chung,

về cơ bản Google API 2.1 cũng giống như Android 2.1 nhưng có thêm các hỗ trợ

bản đồ và các hàm dịch vụ khác từ Google cung cấp. Tạm tóm gọn các mục trong

Build target như sau:

Android 1.1: Ứng dụng sẽ được cài đặt trên thiết bị di động có hệ điều

hành Android 1.1. Tương tự cho các Android 1.5, 1.6, 1.6, 2.0, 2.01, 2.1.

Page 70: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

70

Google APIs 1.5, 1.6, 2.0, 2.01, 2.1: ứng dụng sẽ được hỗ trợ trên các

hệ điều hành tương ứng như Android 1.5, 1.6, 2.0, 2.01, 2.1 và thêm vào đó

nó hỗ trợ các hàm APIs cùa các dịch vụ do Google đưa ra như bản đồ chẳng

hạn.

Application name là tên chính thức của ứng dụng. Ở đây chúng tôi nhập tên

HelloNhatTrungApp.

Ta chú ý kĩ hơn phần Package name là tên gói Package. Ở đây, các bạn đã

quen với lập trình ứng dụng trên Eclipse thì đã quen với Package vì theo nguyên tắc

package thường bắt đầu bằng com và tiếp theo sau đó là các tên nối tiếp sau bởi các

dấu chấm thì tương ứng với từng tên nằm giữa các dấu chấm thì sẽ tạo ra các thư

mục tương ứng. Ví dụ như com.hellonhattrung.nhat.trung thì nó sẽ tạo ra thư mục

/com/hellonhattrung/nhat/trung để chứa các lớp ứng dụng.

Mục chọn Create Activity: tạo ra Activity “mở hàng” cho ứng dụng.

Min SDK Version: chọn phiên bản SDK nhỏ nhất mà ứng dụng muốn được

hỗ trợ.

Cuối cùng là chọn Finish để bắt đầu project.

Bạn sẽ thấy project nằm bên trái màn hình trong mục Package Explorer với

tên là HelloNhatTrungApp trùng khớp với tên Project name như trên.

Page 71: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

71

Hình phụ lục 42 Khung ứng dụng của HelloNhatTrungApp

Ta sẽ tạo chương trình “đầu tay” của các bạn với kịch bản sau: Ở màn hình

có ô nhập liệu cho bạn nhập tên vào; sau đó nhấn chọn nút Chào Android thì sẽ hiện

khung thoại Chào mừng bạn đến với Android.

Chúng ta bắt đầu qua bước 2 tạo giao diện cho màn hình

G.3.1.2 Bước 2 Lập trình giao diện

Màn hình giao diện nằm trong file main.xml trong thư mục ../res/layout của

ứng dụng. Ta nhấp đúp vào main.xml thì màn hình thiết kế giao diện sẽ hiện ra ở

giữa màn hình cùng với các control.

Page 72: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

72

Hình phụ lục 43 Màn hình thiết kế giao diện cho Android

Ta thiết lập lại Config đóng khung hồng nhạt là Potrait

để thiết kế màn hình đứng thay vì nằm ngang như hiện tại. Bên trái phần Layout và

View lần lượt giúp bạn tạo khung chứa để chứa các Views trong phần Views mà

các bạn kéo vào từ bên trái. Một cách khác để thêm giao diện vào màn hình là dùng

các nút lệnh bên tay phải được bao bởi màu vàng . Phần

Outlines này được thiết kế để giúp nhà phát triển nhìn rõ được giao diện chương

trình theo dạng cây với các thuộc tính được biểu thị ngay dưới Tab Properties được

bao bởi màu vàng ngay bên dưới màn hình. Ta có thể thay đổi thuộc tính các

Layout và Views ngay đây. Các nút mũi tên xanh lên xuống dùng để di

chuyển layout và View lên xuống trong từng cấp bậc thứ tự còn nút cộng và

trừ giúp ta thêm hay xóa các Views ngay trên màn hình.

Ta tạo giao diện màn hình theo trình tự sau:

Chỉnh lại Config là Portrait

Page 73: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

73

Trên Outlines, nhấp chọn TextView và nhấn vào dấu trừ màu đỏ

để xóa TextViews đó đi.

Hình phụ lục 44 Màn hình hiện nút nhấn xóa TextViews

Dùng chuột kéo rê layout LinearLayout trong Layouts vào màn hình

thiết kế.

Nhấp chọn LinearLayout mới vừa kéo vào trên Outlines và nhấp vào

dấu cộng màu xanh để thêm vào một TextView và EditViews tương ứng

với Label và TextBox bên C#.

Hình phụ lục 45 Màn hình hiện nút thêm TextView

Ta sẽ thấy hộp thoại:

Page 74: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

74

Hình phụ lục 46 Màn hình thêm mới một widget vào giao diện

Ta thêm vào TextView và vào thuộc tính Text ở tab Properties đổi

thành chuỗi Mời bạn nhập tên. Chú ý: tùy thuộc vào từng hệ điều hành của

máy trạm bạn đang dùng cho nên tốt nhất bạn nên chạy chương trình gõ

tiếng Việt với quyền Administrator mới có thể gõ tiếng Việt có dấu trên

Eclipse.

Page 75: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

75

Hình phụ lục 47 Màn hình chọn thêm mới một EditText

Tiếp tục nhấp chọn LinearLayout01 và nhấp chọn nút dấu cộng màu

xanh và tiếp tục thêm vào một EditText. Ta nhấp chọn EditText mới vừa

thêm và xóa các chuỗi ở thuộc tính Text của nó ở dưới tab Properties. Sửa

thuộc tính Single line thành false, và thuộc tính Width thành 200 dip (với dip

là đơn vị kích thước).

Hình phụ lục 48 Màn hình thêm mới một LinearLayout

Nhấp chọn vào LinearLayout trên cùng của cây giao diện trên

Outline, kế tiếp nhấp vào dấu cộng để hiện khung thoại và thêm vào một

LinearLayout thứ 2. Cũng nhấp chọn vào LinearLayout02 mới vừa thêm vào

và nhấp chọn dấu cộng để thêm vào Button.

Page 76: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

76

Hình phụ lục 49 Màn hình thêm một Button

Nhấp chọn Button và vào thuộc tính Text và sửa thành Chào Android.

Ta cần chú ý thêm là các đối tượng nào sẽ được thiết lập lại các thuộc

tính hay các hành động thì ta nên sửa lại thuộc tính ID cho dễ nhớ. Do

TextView01 không thay đổi thuộc tính hay phương thức nên ta để nguyên

ID, còn EditText01 và Button01 sẽ thay đổi thuộc tính và sự kiện nhấp chọn

nên ta lần lượt sửa lại thuộc tính ID trong tab Properties của chúng cho dễ

nhớ.

Nhấp chọn TextView01 vào thuộc tính ID sửa lại thành

@+id/EditTextTenCuaBan và tương tự cho Button01 thành

@+id/ButtonChaoAndroid. Những ID này sẽ là định danh cho các đối tượng

trong lập trình các sự kiện và thuộc tính của chúng trong Android.

Ta “điệu đàng” tí xíu như canh chỉnh thuộc tính Layout gravity của

LinearLayout02 thành center để canh giữa ButtonChaoAndroid.

Page 77: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

77

Hình phụ lục 50 Màn hình giao diện hoàn chỉnh

Các bạn có thể xem tập tin giao diện của chúng ta mới vừa tạo lập dưới hình

thức “xương xẩu” .xml bằng cách click vào tab main.xml ngay dưới tay trái của

màn hình hiệu chỉnh.

Hình phụ lục 51 Các thẻ XML tạo nên giao diện ứng dụng HelloNhatTrungApp

Các bạn có thể lập trình trực tiếp bằng dòng lệnh xml nhưng chúng tôi e rằng

nó sẽ khó khăn hơn nhiều so với việc kéo thả hay cách thêm vào như chúng tôi đề

nghị.

Như vậy, tạo màn hình giao diện bước đầu đã hoàn thành xong.

G.3.1.3 Bước 3 Lập trình xử lý

Khác so với C#, ta lập trình sự kiện bằng cách nhấp đúp vào đối tượng ngay

trên màn hình thì sẽ phát sinh hàm sự kiện cho đối tượng. Ở đây, trong ứng dụng

Page 78: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

78

Android này thì lớp giao diện được tách bạch khỏi lập trình bằng tập tin XML và

việc lập trình nhờ vào ID để định danh từng đối tượng.

Nhấp đúp vào HelloNhatTrungApp.Java để lập trình cho các sự kiện.

Lớp HelloNhatTrungApp “mở rộng” hay “kế thừa” từ lớp Activity để quản

lý các tương tác của người dùng trên màn hình. Lớp này có màn hình chính là main

với setContentView(R.layout.main). Công việc của chúng ta là thiết lập việc người

dùng nhập tên vào EditText và nhấp chọn bút Chào Android thì hiện khung thoại có

nội dung Chào mừng Nguyễn Văn A với Nguyễn Văn A là tên người dùng nhập

vào.

Có hai công việc chính cần làm là khai báo thực thể instance cho 2 định danh

quan trọng là EditText và Button với các thuộc tính và phương thức tùy mỗi đối

tượng.

Đối với EditText thì ta chỉ cần lấy giá trị mà người dùng đưa vào nên rất đơn

giản chỉ có vài dòng và Button có thêm phương thức bắt sự kiện click cho nút

ButtonChaoAndroid:

EditText edtTextTenNguoiDung =

(EditText)findViewById(R.id.EditTextTenCuaBan);

Button btnChaoAndroid = (Button)findViewById(R.id.ButtonChaoAndroid);

btnChaoAndroid.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

// TODO Auto-generated method stub

}

});

Thế là khung xử lý đã xong, bây giờ là thêm các phương thức để hiện khung

thoại chào mừng. Trong mục // TODO Auto-generated method stub ta thêm vào các

phương thức có nhiệm vụ hiện khung thoại.

btnChaoAndroid.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

Page 79: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

79

// TODO Auto-generated method stub

// Khai báo instance builder chào mừng

AlertDialog.Builder builder = new

AlertDialog.Builder(HelloNhatTrungApp.this);

builder.setTitle("Chào Mừng");

builder.setMessage(edtTextTenNguoiDung.getText());

builder.setPositiveButton("Đồng Ý", null);

// Khai báo khung thoại để hiện thực hóa builder

AlertDialog dlgChaoMung = builder.create();

// Hiện khung thoại

dlgChaoMung.show();

}

});

Hình phụ lục 52 Màn hình thông báo lỗi mã hóa chuỗi khi lưu Tiếng Việt

Khi bạn gõ tiếng Việt vào tập tin HelloNhatTrungApp.Java và khi lưu vào sẽ

xuất hiện lỗi như trên hình trên do ta chưa chọn mã kí tự thích hợp cho tập tin. Để

giải quyết vấn đề này, ta nhấp phải chuột vào tên ứng dụng Android

HelloNhatTrungApp và chọn Properties.

Page 80: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

80

Hình phụ lục 53 Màn hình chọn thuộc tính của một project

Ta sẽ thấy khung thoại như sau:

Page 81: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

81

Hình phụ lục 54 Màn hình lựa chọn thuộc tính mã hóa ký tự

Trong mục Text file encoding ta nhấp chọn vào Other và chọn UTF-8 để

định dạng kí tự cho các tập tin có chứa chuỗi kí tự trong chương trình.

Đến đây, chương trình chúng ta đã xong, bây giờ chỉ cần ngồi châm tí xíu trà

và vài mẫu bánh nhỏ và nhịp chân chờ máy ảo “lết” sau khi kích hoạt chương trình

chạy bằng cách nhấp huột phải vào tên ứng dụng Android HelloNhatTrungApp

chọn Run as/ 1 Android Application. Tùy theo, tốc độ xử lí và bộ nhớ của máy trạm

mà máy ảo chạy nhanh hay chậm tùy theo.

Page 82: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

82

Hình phụ lục 55 Màn hình chạy một ứng dụng Android từ Eclipse

Khi chương trình chạy, bạn để ý bên dưới thẻ Console sẽ có hiệu lực và thể

hiện từng bước mà Eclipse chạy như kiểm lỗi chương trình, khởi động máy ảo, cài

đặt chương trình lên máy ảo và cuối cùng là chương trình đã sẵn sàng thực thi trên

máy ảo. Chú ý khi máy ảo khởi động và khi chương trình đang cài thì bạn không

nên “quậy quọ” bất cứ nút gì hay nhấp chọn bất cứ gì trên màn hình máy ảo nếu

trên màn hình Console chưa tới trạng thái Starting: Intent {

cmp=com.hellonhattrungapp/.HelloNhatTrungApp } để tránh các lỗi có thể gặp

phải.

Page 83: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

83

Hình phụ lục 56 Màn hình minh họa trạng thái chạy cũa một ứng dụng

Khi trên Console chạy tới Starting: Intent thì ta qua bên màn hình Emulator.

Nếu bạn thấy xuất hiện bất kì hộp thoại nào thì đều chọn Wait để tránh các lỗi xảy

ra.

Hình phụ lục 57 Màn hình đợi ứng dụng xử lý xong

Sau cùng, chào mừng bạn đến chương trình “đầu tay” Android mới vừa tạo

được qua vài bước đơn giản. Và thử trải nghiệm chương trình này bằng kịch bản

ban đầu là nhập chuỗi vào EditText và nhấn nút Chào Android để hiện khung thoại

Chào Mừng.

Page 84: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

84

Hình phụ lục 58 Màn hình thao tác xử dụng ứng dụng HelloNhatTrungApp

Lần lượt nhấp chọn Đồng Ý và nút Home trên màn hình để ra màn hình

chính của Emulator. Và đây, chào mừng bạn đến màn hình giao diện chính của

Android 2.1.

Hình phụ lục 59 Màn hình giao diện chính của Android 2.1

Đầu tiên, bạn có thể thử dùng các chương trình sẵn có trên hệ điều hành

Android 2.1 mà trong phần giới thiệu Android ta gọi chúng là ứng dụng chính có

Page 85: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

85

nghĩa là ứng dụng ban đầu đi kèm với hệ điều hành Android. Nói một cách dễ hiểu

chúng như là những ứng dụng di kèm như NotePad hay Calculator đi kèm với các

hệ điều hành Windows của Microsoft vậy.

G.3.2 Cấu trúc của một project Android

G.3.2.1 Cấu trúc cây trên Eclipse

Đây là cấu trúc của ứng dụng Android trên Eclipse:

Hình phụ lục 60 câu trúc ứng dụng Android trên Eclipse

Ta thấy rằng cấu trúc ứng dụng gồm các thành phần chính như sau:

/src: chứa các package gồm các lớp ứng dụng và xử lí liên quan đến

Activity, các xử lý.

/gen: chứa các tập tin Java được phát sinh tự động. Tốt nhất là không

được thêm hay sửa đổi bất kì giá trị gì của các tập tin nằm trong gen; nếu

không tất cả các giá trị vừa thêm hay sửa đổi đó sẽ được phục hồi về giá trị

ban đầu. Trong tập tin R.Java của thư mục /gen chứa các định danh cho tất

Page 86: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

86

các đối tượng trên giao diện của tất cả màn hình, của tất cả các nguồn tài

nguyên gồm hình ảnh, giá trị, layout, màu sắc,... trong thư mục /res.

/Google APIs [Android 2.1] nếu bạn chọn Target name là Android 2.1

thì thư mụ sẽ trở thành /Android 2.1. Trong đây chứa các tập tin .jar là bộ các

hàm APIs của Android và Google là Android.jar và maps.jar. Ngoài ra, nếu

chương trình của bạn cần sự hỗ trợ các hàm do bên thứ 3 cung cấp thì ta có

thể thêm tham chiếu và chúng ta sẽ có thêm thư mục Referenced Libraries

chứa các tập tin .jar gồm các bộ hàm hỗ trợ của bên thứ 3. Ví dụ như, trong

chương trình demo của khóa luận này có dùng thêm 2 tập tin jar của bên thứ

3 cho việc truy dùng hàm đọc dữ liệu thông qua service và dùng hàm để

dùng cho danh sách tải về dạng tuần tự.

/asset: các tài nguyên trong thư mục này sẽ không được Android đánh

định danh ID cho nó.

/res: chứa các nguồn tài nguyên có trong chương trình như thư mục

/drawable chứa các hình ảnh hay hình nền chương trình gồm các tập tin hình

ảnh hoặc xml; thư mục layout chứa các khung giao diện chương trình; và thư

mục values chứa các giá trị như chuỗi, màu sắc, … Tập tin

AndroidManifest.xml: chứa các thiết lập cho chương trình như các quyền

cho phép truy cập vào phần cứng, thiết lập màn hình chính và các thuộc tính

của chúng, và còn rất nhiều thiết lập khác.

Trên là các thành phần cơ bản nhất của một ứng dụng Android. Ngoài ra còn

một số thành phần sau:

G.3.2.2 Cấu trúc của project Android trên bộ nhớ

Tương ứng với cấu trúc ứng dụng Android trên Eclipse thì cấu trúc của nó sẽ

tương tự trên ổ đĩa.

Page 87: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

87

Hình phụ lục 61 Cấu trúc thư mục của một project Android trên bộ nhớ

Tương ứng với từng package thì sẽ tạo thành từng cấp thư mục tương ứng

trong thư mục \src như com.hellonhattrung trở thành \src\com\hellonhattrung. Ở đây

ta chú ý đến thư mục \bin chứa tập tin thực thi .apk để cài vào thiết bị chạy Android

và thư mục \.settings chứa các thiết lập ứng dụng Android mà ta không nhìn thấy

trên Package Explorer.

Tiếp theo ta làm quen với các khung nhìn trên Eclipse để thấy rõ hơn về từng

khung nhìn lập trình Android trên Eclipse.

G.4 Làm quen với các khung nhìn trên Eclipse qua cái nhìn trên

Android project

G.4.1 Khung nhìn Java

G.4.1.1 Giới thiệu sơ lược về khung nhìn Java

Page 88: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

88

Hình phụ lục 62 Mành hình khung nhìn Java

Nếu bạn muốn khung nhìn Java thì nhấn vào nút nhấn Java màu cam nằm

bên phải phía trên màn hình. Trong khung nhìn Java cho phép các bạn lập trình giao

diện và xử lí cho các thành phần trong ứng dụng Android. Ngay cả thao tác thêm

hay xóa các tập tin âm thanh, hình ảnh, video cho chương trình của bạn.

Trên hình, ta thấy rõ 3 thành phần chính của khung nhìn Java là Package

Explorer với màu cam, khu vực để thao tác lập trình giao diện và xử lí với màu tím

và phần xem tổng thể lớp Java đang thao tác với cấu trúc cây dễ nhìn qua khung

Outline với màu nâu. Đây là các đối tượng chính mà chúng ta cần quan tâm trong

mục này.

Trong mục này, có nhiều thao tác nhưng chúng tôi giới thiệu đến các bạn các

thao tác cơ bản mà chúng tôi đã trải nghiệm như kinh nghiệm thao tác các thành

phần trên Package Explorer, thao tác trên thực đơn ngữ cảnh của các tập tin *.Java

và cách dùng Outline.

G.4.1.2 Thao tác với các thành phần trên Package Explorer

Page 89: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

89

Hình phụ lục 63 Cửa sổ Package Explorer

Ở đây, ta sẽ từ từ đi qua các thành phần trên cửa sổ Package explorer và tìm

hiểu chức năng cùng với thao tác lên trên các thành phần đó.

Trước tiên là thao tác lên tên project Android HelloNhatTrungApp bằng cách

nhấp chuột phải lên tên project. Trên thực đơn ngữ cảnh đó, ta quan tâm đến các

mục sau:

Page 90: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

90

Hình phụ lục 64 Thực đơn ngữ cảnh của một project Android

Ta thống kê chức năng theo từng mục như sau:

New: giúp ta thêm các tập tin XML, Java, … mới vào ứng dụng.

Go into: cho ta chỉ xem cấu trúc project Android và giấu đi hết tất cả

các project Android khác.

Refresh: làm mới lại toàn bộ project Android khi ta vừa thao tác ảnh

hưởng đến ứng dụng chẳng hạn như thêm tài nguyên âm thanh, hình ảnh hay

video mới.

Close project: đóng project hiện hành. Khi Eclipse khởi động hay có

sự kiện chạy một ứng dụng Android nào đó trên workspace – tên gọi khác

Page 91: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

91

của Package explorer – thì Eclipse sẽ quét và duyệt tài nguyên và lỗi cú pháp

trên tất cả các project Android nào đang mở. Nếu chỉ có vài project thì bạn

không thấy rõ, nhưng nếu có vài trăm project trong workspace thì việc chờ

“dài cổ” là không tránh khỏi cho nên ta tránh bằng cách đóng project không

liên quan với project hiện tại để tiết kiệm được thời gian khi Eclipse khởi

động hay chạy một ứng dụng.

Close unrelated project: đóng tất cả các project không liên quan với

project hiện tại. Cũng với mục đích tiết kiệm thời gian như đã nói ở trên,

project Android có thể dùng các project khác có trên workspace làm tham

chiếu nên an toàn nhất là chỉ đóng các project không liên quan với project

hiện hành mà thôi.

Run as và Debug as: chạy và kiểm lỗi project hiện tại.

Properties: kiểm soát thuộc tính của project. Phần này ta cần tìm hiểu

hơn các thành phần có trên hộp thoại Properties của project. Ta nhìn

Properties dưới đây:

Hình phụ lục 65 Hộp thoại Properties/Resource của một project Android

Ta thấy trên mục Resource bao bởi màu cam thì bên phải có mục Text file

encoding bao bởi mục xanh lá cây giúp ta qui định mã chuỗi cho toàn các tập tin có

Page 92: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

92

chứa chuỗi. Theo như chúng tôi, nếu các đoạn code hay các ghi chú của bạn có

tiếng Việt thì tốt hơn là bạn thiết lập ngay từ ban đầu cho thuộc tính Other của Text

file encoding là UTF-8 để có thể lưu được tiếng Việt.

Ta qua mục tiếp theo là Android. Như đã trình bày trong mục viết chương

trình “đầu tay” HelloNhatTrungApp ở mục Build Target ở phần G.3.1. có phần

chọn hệ điều hành hỗ trợ.

Ngay từ ban đầu ta đã chọn phiên bản hệ điều hành hỗ trợ nhưng ta có thể

thay đổi điều đó bằng cách vào mục Android của hộp thoại Properties để thay đổi.

Hình phụ lục 66 Hộp thoại Properties/Android của một project Android

Cũng như các chương trình trên C#, bạn muốn Add Reference như DLL để

dùng lại các phương thức sẵn có thì bạn vào mục Java Build Path để thêm các tham

chiếu để dùng các bộ hàm có sẵn. Bạn nhâp chọn nút Add External Jars để thêm vào

các tập tin *.jar để ta có thể dùng lại các hàm được cung cấp trong tập tin jar đó. Ví

dụ như chúng ta thấy trên Hình phụ lục G. -57 thì chúng tôi đã thêm tập tin ksoap2-

Android-full-2.1.2.jar để dùng lại các hàm đọc và lấy thông tin từ server.

Page 93: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

93

Hình phụ lục 67 Hộp thoại Properties/Java Build Path của một project Android

G.4.1.3 Thao tác trên thực đơn ngữ cảnh của các tập tin *.Java

Page 94: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

94

Hình phụ lục 68 Thực đơn ngữ cảnh của một tập tin .Java

Ta cần quan tâm rõ hơn các mục được bao bởi màu như sau:

Quick outline: hiện trình đơn ngữ cảnh để xem nhanh cấu trúc của tập

tin .Java.

Page 95: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

95

Cut, Copy, Paste các thành phần mã lệnh trên tập tin Java.

Surround With: thêm vào đoạn mã try/catch cho phần mã lệnh mình

chọn nếu đoạn mã đó bắt buộc dùng try/catch hay nhà phát triển cẩn thận

muốn xem xét lỗi cho từng thành phần.

Reference: xem vị trí của một đối tượng nằm đâu trên project hoặc

trên toàn workspace nếu project đó dùng biến giá trị của project khác.

Source: trình đơn nhanh cho bạn thao tác nhanh trên các mã lệnh.

Hình phụ lục 69 Thực đơn ngữ cảnh Source trên một tập tin .Java

Như nhóm Comment bao bởi màu cam cho phép bạn thao tác trên các

ghi chú dành cho các mục mã lệnh. Chú ý nếu chúng ta muốn ghi chú bình

thường thì chỉ cần đặt hai dấu // trước các dòng ghi chú để trình biên dịch

loại bỏ chúng ra khi biên dịch. Còn dạng ghi chú đặc biệt khác là ghi chú

trước các lớp đối tượng hay trước các phương thức mà các ghi chú này sẽ

Page 96: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

96

hiển thị trên các hộp thoại ngữ cảnh thuyết minh khi ta dùng đến các lớp hay

các phương thức đó.

Ta xem minh họa sau:

Ghi chú trước dòng lệnh

// Khai báo khung thoại để hiện thực hóa builder

AlertDialog dlgChaoMung = builder.create();

Ghi chú trước thân hàm.

/**

* <strong> getResult(int value)</strong>

* </br>

* </br>

* Hàm có nhiệm vụ làm demo thử ghi chú sẽ hiện lên khi hàm này

được gọi đến

* value:

*

* @param value giá trị đầu vào

* @return Giá trị đầu ra lớn hơn giá trị đầu vào 1 đơn vị

*/

int getResult(int value)

{

value= value+1;

return value;

}

Kết quả của ghi chú trên sẽ hiển thị như sau khi ta gọi hàm này

trong các phương thức khác như sau:

Hình phụ lục 70 Hình minh họa cho một ghi chú mã lệnh của một phương thức

Page 97: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

97

Format: định dạng lại các dòng lệnh có trên tập tin .Java để nhà

phát triển có thể nhìn dễ hơn các đoạn mã.

Các phương thức phát sinh Generate rất hữu dụng khi bạn lập trình

các lớp đối tượng như phát sinh các Constructor, các hàm Get hay Set

cho các thuộc tính có trong lớp đối tượng.

Refactor: cũng như bên C# thì Refactor là công cụ cực kì hữu ích khi

có vấn đề muốn thay đổi hàng loạt các mã lệnh cũng như tách các đoạn mã

trong một thân hàm ra làm phương thức mới hay sát nhập các đoạn mã trong

trong các phương thức bên ngoài vào phương thức hiện hành.

Hình phụ lục 71 Thực đơn ngữ cảnh Refactor trên một tập tin .Java

Mục Rename có tác dụng đổi tên một đối tượng lại hàng loạt trên

tất cả các tập tin Java có liên quan mà không tốn công lần hồi tìm đối

tượng đó tại các hàm hay các tập tin Java khác.

Các phương thức Extract: có tác dụng tách các đoạn mã đang chọn

trong thân hàm ra làm một phương thức mới và được gọi bởi phương

thức hiện hành.

Incline: sát nhập các mã lệnh của phương thức bên ngoài vào trong

phương thức hiện hành.

Page 98: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

98

Như đã nói, các phương thức trong phần Refactor là công cụ rất

mạnh và hữu ích cho các nhà phát triển khi muốn điều chỉnh mã lệnh và

tách hay gộp các phương thức trên Eclipse IDE.

Ta để ý bên tay phải màn hình viết mã lệnh có thanh scroll bar có

các thành phần màu nằm ngang và thông thường có 3 dạng:

Thanh ngang màu xanh: khi nhấp vào sẽ đi đến các mục đánh

dấu ghi chú dạng 1.

Thanh ngang màu vàng: khi nhấp vào sẽ đi đến các biến đối

tượng khai báo dư thừa và không sử dụng.

Thanh ngang màu đỏ: khi nhấp vào sẽ đi tới các dòng mã lệnh

bị lỗi.

G.4.1.4 Cách dùng Outline

Hình phụ lục 72 Màn hình Outline

Page 99: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

99

Hình phụ lục 73 Màn hình Outline

Phần Outline giúp ta xem tổng quát được các phương thức và các biến nếu là

tập tin .Java và xem được cấu trúc giao diện nếu là tập tin .xml định nghĩa giao

diện. Ngoài ra, còn giúp ta định vị nhanh chóng đến các thành phần có trên tập tin

mà không cần lần hồi khi giao diện xml hay tập tin .Java có khá nhiều dòng lệnh.

G.4.2 Khung nhìn DDMS

Hình phụ lục 74 Khung nhìn DDMS

Chúng ta chuyển qua khung nhìn DDMS bằng cách nhấp vào nút >> bên tay

phải phía trên màn hình rồi nhấp chọn DDMS hay nhấp chọn trực tiếp nút DDMS.

Trên khung nhìn DDMS ta thấy rõ 3 thành phần chính là Device, Emulator Control

và File Explorer.

Bây giờ ta đi qua các thành phần ấy, trước tiên là File Explorer.

Page 100: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

100

G.4.2.1 Tìm hiểu File Explorer

Trong mục File Explorer, chúng ta chú ý đến các thành phần chính được bao

khung.

Nút “Pull a file from the device” giúp ta lấy một tập tin từ trong

thiết bị máy ảo hay thiết bị hệ chạy Android hiện hành kết nối với Eclipse

IDE.

Tương tự, nút “Push a file onto the device” giúp ta đưa một tập

tin trên laptop hay PC bất kì vào thiết bị máy ảo hay thiết bị Android.

Nút “Delete the selection” giúp ta xóa các thư mục hay tập tin mà

ta chọn ở cửa sổ File Explorer.

Trên cửa sổ File Explorer ta có thể thao tác trên

các tập tin nằm trên thiết bị bao gồm các tập tin hệ thống trong thư mục

/system, các tập tin trên thẻ nhớ trong thư mục /sdcard và các tập tin dữ liệu

trong thư mục /data.

Hình phụ lục 75 Khung nhìn của File Explorer

G.4.2.2 Tìm hiểu Device

Page 101: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

101

Hình phụ lục 76 Khung nhìn của Devices

Trong mục này, thể hiện các chương trình hiện đã được cài trên máy ảo hiện

hành. Các chương trình được cài đặt trên hệ điều hành Android dược định bằng các

Package bắt đầu bằng com.*. Như trên hình trên thể hiện ứng dụng

com.hellonhattrung đã được cài vào máy ảo.

G.4.2.3 Tìm hiểu Emulator Control

Hình phụ lục 77 Khung nhìn của Emulator Control

Page 102: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

102

Trong mục này giúp ta giả lập trạng thái điện thoại, giả lập hành động gọi

hay nhắn tin của điện thoại, giả lập vị trí của điện thoại và giả lập lộ trình đường đi

bằng tập tin KML. KML là tập tin qui định định tuyến đường đi từ điểm A đến

điểm B của Google và tập tin này là cấu trúc chung để các hàm APIs của Google

Map có thể trích xuất dữ liệu và thê hiện lên bản đồ.

Telephone status: giả lập trạng thái của điện thoại như dùng mạng 2G

hay 3G, tình trạng điện thoại đang roaming, …

Telephone Actions: giả lập việc gửi tin nhắn hay gọi điện thoại tới

máy ảo.

Location Controls: giả lập liên quan tới vị trí và bản đồ trên Google

Map. Với Manual giúp ta giả lập máy ảo nhận vị trí hiện tại thông qua phần

cứng và với KML giúp ta có thể đưa vào tập tin KML để giả lập định tuyến

đường đi giữa 2 điểm trong chương trình có dùng bản đồ.

Bên cạnh đó Android còn hỗ trợ thêm một số công cụ để hỗ trợ tốt hơn cho

các nhà lập trình và các công cụ này được cài sẵn trong điện thoại ảo Android. Bật

điện thoại Android, mở ứng dụng hỗ trợ có tên là Dev Tools, chọn mục

Development Settings ta sẽ thấy được các chức năng mà Android hỗ trợ nhà lập

trình như hình bên dưới:

Hình phụ lục 78 Màn hình Development Settings hỗ trợ lập trình cài sẵn trên điện thoại Android ảo

Page 103: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

103

Đây là các chức năng rất hay mà Android hỗ trợ cho việc lập trình trên

Android. Nhóm chúng tôi xin điểm qua một số chức năng đáng chú ý như sau:

Show running processes: hiện ra các tiến trình đang chạy giúp ta giám

sát hiện tại trên máy có bao nhiêu tiến trình hiện đang chạy.

Show screen update: chỉ ra các vùng nào trên màn hình đang được “vẽ

lại”. Đây là chức năng hữu ích giúp ta có thể tối ưu lại việc vẽ các đối tượng

lên màn hình.

Show CPU usage: giúp ta quan sát ngay trên màn hình trạng thái sử

dụng CPU của một ứng dụng đang chạy. Chức năng này giúp ta biết được

việc thiết kế chương trình có hiệu quả hay không, có tiêu tốn tài nguyên của

thiết bị hay không.

G.4.2.4 Khung nhìn Debug:

Hình phụ lục 79 Khung nhìn Debug

Ta thấy trong khung nhìn Debug ta thấy rõ bốn thành phần cơ bản đó là

Debug, khung tab Variables – Breakpoints – Expression, khung hiện đang kiểm lỗi

tới dòng nào bảo bởi màu xanh dương và các tab Logcat – Progress – Search –

Error Log. Sau đây, ta tìm hiểu phần đầu tiên Debug.

Page 104: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

104

G.4.3 Tìm hiểu Debug

Trong phần Debug này thể hiện các luồng hiện đang chạy có trên chương

trình. Chúng ta chú ý kĩ đến các nút lệnh sau:

Nút Resume (F8): hồi phục lại khi công việc kiểm lỗi bị gián

đoạn. Theo kinh nghiệm của chúng tôi, khi việc kiểm lỗi chạy một hồi lâu

nếu xuất hiện màn hình tập tin như hình bên dưới thì nên nhấn F8 để việc

kiểm lỗi đi tiếp.

Hình phụ lục 80 Màn hình thể hiện công đoạn debug

Nút Disconnect: ngắt kết nối với máy ảo

Nút Step Into (F5): đi vào thân hàm của hàm đang được gọi tại

dòng đang kiểm lỗi.

Nút Step Over (F6): tiếp tục đi qua các dòng lệnh mà không đi

vào thân hàm của các hàm được gọi.

Nút Step Return (F7): Lập tức “bay” ra khỏi thân hàm hiện đang

kiểm lỗi.

Page 105: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

105

Hình phụ lục 81 Tab Debug trong khung nhìn Debug

G.4.3.1 Tìm hiểu tab Variables – Breakpoints – Expression

Tab Vaviables: hiển thị tất cả các giá trị của các biến hiện hành xung

quanh có trong khu vực hiện đang kiểm lỗi.

Tab Breakpoints: cho phép quản lý chọn hay bỏ chọn các điểm dừng

một cách nhanh chóng mà không cần bỏ các điểm dừng trên màn hình đang

kiểm lỗi.

Tab Expressions: cho phép nhà lập trình quan sát giá trị của bất kì

biến nào, mục này có vẻ tiện lợi hơn cho các nhà lập trình khi cần xem

những giá trị của các biến hay đối tượng cần xem.

Page 106: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

106

Hình phụ lục 82 Tab Variables trong khung nhìn Debug

Hình phụ lục 83 Tab Breakpoints trong khung nhìn Debug

Page 107: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

107

Hình phụ lục 84 Tab Expressions trong khung nhìn Debug

G.4.3.2 Tìm hiểu khung thể hiện dòng hiện hành đang kiểm lỗi

Hình phụ lục 85 Tab thể hiện dòng hiện hành đang kiểm lỗi

Ở đây ta chú ý, dòng hiện hành là dòng được bao bởi màu cam và có nền

màu xanh. Các dấu chấm tròn bao bởi màu đỏ là các điểm dừng Breakpoint. Bạn có

thể thêm các điểm dừng mới hay bỏ các điểm dừng có sẵn trong khi kiểm lỗi bằng

cách để trỏ chuột tại dòng đó và nhấn tổ hợp phím Ctrl+Shift+B.

G.4.3.3 Tìm hiểu khung tab Logcat – Progress – Search – Error

Log

Page 108: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

108

Hình phụ lục 86 Tab LogCat, Progress, Search, ErrorLog

Hiện nhật kí quá trình kiểm lỗi và các trạng thái của chúng.

G.4.3.4 Các điều chú ý khi kiểm lỗi chương trình

Tuy Android có hỗ trợ cho việc kiểm lỗi chương trình nhưng thực sự công cụ

debug chưa thực sự làm hài lòng các nhà lập trình. Việc debug ứng dụng được tiến

hành rất chậm và khi có lỗi xảy ra ta không thể biết được thành phần nào đang gây

ra lỗi do Android chỉ báo lỗi chung chung như là source không tìm thấy… Theo

kinh nghiệm của một số nhà lập trình trên cộng đồng mạng, ta nên tận dụng việc

dùng khối hàm try{} catch{} để tránh lỗi đồng thời dùng thêm tính năng ghi chú lại

quá trình chạy bằng LogCat để biết được chính xác và nhanh chóng thành phần nào

gây lỗi cho chương trình.

G.5 Làm quen với nền tảng ứng dụng Android

Rõ ràng, ứng dụng Android dựa trên ngôn ngữ Java. Các mã lệnh Java đã

được biên dịch cùng với dữ liệu và các tài nguyên đi kèm được đóng gói lại thành

tập tin .apk duy nhất. Tập tin này được cài vào các thiết bị Android và tất cả mã

lệnh và tài nguyên trong tập tin .apk được xem như là một ứng dụng hoàn chỉnh.

Với nhiều cách khác nhau, ứng dụng Android chạy riêng biệt trong không

gian riêng của nó trên thiết bị Android:

Page 109: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

109

Mặc định, mỗi ứng dụng hạy trên tiến trình Linux riêng của nó.

Android khởi động tiến trình khi dòng lệnh của ứng dụng bắt đầu thực thi và

kết thúc tiến trình khi nó không còn chạy nữa hay không còn được được gọi

bởi ứng dụng khác.

Mỗi tiến trình có một máy ảo Java riêng (VM), vì thế ứng dụng chạy

độc lập với các ứng dụng khác.

Mặc định, mỗi ứng dụng có một định danh Linux duy nhất. Các quyền

thiết lập cho phép (Permission) được thiết lập cho mỗi ứng dụng (như cho

phép dùng GPS, dùng Internet, dùng thoại, …) thì chỉ có thể phát huy trong

mỗi ứng dụng đó mà thôi.

Ta đi sâu vào tìm hiểu các thành phần ứng dụng, Activities và Tasks, tiến

trình và luồng, vòng đời các thành phần ứng dụng Android.

G.5.1 Các thành phần ứng dụng

Tính năng hay nhất của Android là một ứng dụng có thể gọi, thực thi và lấy

kết quả trả về của một ứng dụng khác. Như chương trình BarcodeZxing là chương

trình chụp mã vạch và trả ra cho ta mã vạch mới vừa chụp; chương trình này do

Zxing Team viết ra. Chúng tôi chỉ cần dùng lại chương trình để lấy giá trị mã vạch

hơn là viết ra một chương trình mới hay sao chép đoạn mã lệnh đã công bố trên

Internet của nhóm Zxing rồi đính kèm vào chương trình như vậy sẽ tốn nhiều thời

gian.

Để làm được điều trên, hệ thống phải khởi động tiến trình ứng dụng và khởi

động đối tượng Java – tức là thực thể instance – cho tiến trình ứng dụng đó. Vì vậy,

không giống như những hệ điều hành khác, ứng dụng Android không có hàm

main() hay tương tự như bên C++. Mà thay vào đó, ứng dụng Android có 4 dạng

thành phần cốt yếu mà hệ thống khởi động và chạy khi cần đó là:

Activities: nói dễ hiểu một Activity là sự thể hiện một màn hình

(tương ứng với từng form khi lập trình trên Windows Form của C#). Ví dụ

như trong ứng dụng demo của chúng tôi có nhiều activites điển hình như từ

Page 110: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

110

Activity chính ta chuyển sang Activity tìm kiếm hàng hóa rồi từ đó qua

Activity danh sách hàng hóa và cuối cùng là chi tiết hàng hóa. Ta cần biết

thêm là có nhiều activites trong ứng dụng vậy Activity nào sẽ chạy đầu tiên

khi ứng dụng khởi động. Đây là nhiệm vụ của AndroidManifest.xml; nó qui

định Activity nào chạy trước bằng thuộc tính <category

Android:name="Android.intent.category.LAUNCHER" />. Như đã nói, mỗi

Activity là một màn hình có thể đầy màn hình (full screen) nhưng cũng có

thể nhỏ hơn màn hình thông thường như các hộp thoại chẳng hạn. Nội dung

trên một màn hình hay Activity mà người dùng thấy được được tổ chức bởi

hệ thống cấp bậc các Views – Views là các đối tượng trên màn hình. Mỗi

Views chiếm một vị trí trên màn hình; Views “cha” chứa các Views con, các

Views “lá” là các Views nằm cuối cùng trên cây cấp bậc các Views và chính

các Views này sẽ trực tiếp tiếp nhận các sự kiện mà người dùng tác động lên

màn hình. Android hỗ trợ một số Views có sẵn như nút lệnh, text fields,

thanh cuộn, thực đơn, check box và nhiều Views khác nữa. Ta thiết lập cây

cấp bậc giao diện cho cho một Activity bằng phương thức

Activity.setContentView().

Service: khác với Activity là một giao diện mà người dùng có thể nhìn

thấy, service chạy ngầm trong một khoảng thời gian không xác định. Các

dạng ví dụ cho một service có thể chơi nhạc nền khi nhấn nút, hay lấy dữ liệu

qua mạng, hay tính toán và cung cấp kết quả cho Activity nào đó đang cần.

Mỗi service thừa kế từ lớp Service cơ sở. Ta có thể đưa ví dụ rõ hơn cho một

service dạng chơi các bài nhạc từ một danh sách các bài hát. Ứng dụng có

nhiều Activity cho phép người dùng chọn và chơi các bài nhạc; tuy nhiên,

trong một Activity không thể chơi tiếp các bài nhạc khi người dùng chuyển

qua các ứng dụng khác hay làm việc gì khác trong khi vẫn muốn tiếp tục

nghe nhạc. Để làm được việc này, Activity chơi nhạc của ứng dụng khởi

động một service để chạy ngầm việc phát nhạc ngay khi nhấn vào nút chơi

Page 111: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

111

nhạc. Cũng như các activities và các thành phần khác, service chạy trong một

luồng chính của tiến trình ứng dụng.

Broadcast receivers: là thành phần nhận và hồi đáp các thông báo. Các

thông báo bắt nguồn từ mã hệ thống – như pin yếu, hay có một ảnh mới vừa

chụp, … Một ứng dụng thông thường cũng có thể phát ra các thông báo – ví

dụ như, nó để các ứng dụng khác biết là dữ liệu mới được tải về hay nó vừa

trả ra kết quả cho các ứng dụng khác. Một ứng dụng có nhiều broadcast

receivers. Tất cả các receivers thừa kế từ lớp BroadcastReceiver cơ sở.

Broadcast receiver không hiển thị trên giao diện. Tuy nhiên, chúng có thể

khởi động một Activity để thể hiện thông tin mà chúng nhận được hoặc

chúng có thể dùng NotificationManager để cảnh báo người dùng.

NotificationManager có thể cảnh báo bằng nhiều cách như chớp đèn, rung,

phát âm thanh hay đại loại như vậy.

Content provider: cung cấp bộ dữ liệu của ứng dụng này cho ứng

dụng khác. Dữ liệu có thể lưu trữ trong cơ sở dữ liệu SQLite hay các loại

khác. Content providers đựa trên lớp ContentProvider cơ sở để thực thi một

bộ phương thức làm cho ứng dụng khác để truy xuất và lưu trữ các loại dữ

liệu mà nó quản lý.

Cho dù là thành phần nào thì Android cũng tạo các thực thể của các thành

phần và khởi động chúng.

G.5.1.1 Kích hoạt thành phần : intents

Với các thành phần vừa nói ở trên thì Content providers được kích hoạt bởi

một yêu cầu từ ContentResolver. Còn activities, services và broadcast receivers

được kích hoạt bởi tin nhắn bất đồng bộ gọi là intents. Một intents có thể giữ nội

dung tin nhắn. Với mỗi loại thành phần có những phương thức kích hoạt khác nhau:

Activity: được kích hoạt bởi các phương thức Context.startActivity()

hoặc Activity.startActivityForResult(). Từ Activity này qua Activity khác sẽ

có thể mang theo giá trị và truyền qua Activity được khởi động giống như

truyền giá trị từ form hiện hành qua một form khác giống như trên C#. Bên

Page 112: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

112

Activity được khởi động có thể dùng hàm getIntent() để lấy giá trị. Nếu một

Activity khởi động một Activity khác và mong chờ nó trả về cho nó một kết

quả thì gọi hàm startAtivityForResult() thay vì gọi hàm startActivity(). Ví

dụ, một Activity đang cần một tấm hình là kết quả chọn lựa từ Activity khác

gồm danh sách các hình; kết quả trả về thông qua hàm onActivityResult().

Service: được khởi động thông qua hàm Context.startService().

Tương tự, trên một intents có thể dùng hàm Context.bindService() để thiết

lập một kết nối giữa các thành phần và service muốn gọi.

G.5.1.2 Tắt các thành phần

Một content provider còn hiện hành trong khi nó hồi đáp lại các yêu

cầu từ ContentResolver. Một broadcast receiver hiện hành chỉ khi nó hồi đáp

lại tin nhắn broadcast vì vậy không cần tắt chính thức các thành phần này.

Mặt khác, Activity cung cấp giao diện người dùng và giao tiếp với

người dùng trong khoảng thời gian dài. Tương tự, service có thể duy trì chạy

ngầm trong khoảng thời gian dài. Vì thế Android đưa ra phương thức để tắt

Activity và service như sau:

Một Activity có thể tắt bằng hàm finish(). Một Activity có thể tắt

một Activity khác bằng hàm finishActivity().

Một service dừng bằng cách gọi hàm stopSelf() hay hàm

Context.stopService().

Hệ thống tắt các thành phần khi chúng không còn được sử dụng nữa

hoặc khi bộ nhớ không còn đủ chỗ trống.

G.5.1.3 Tập tin AndroidManifest

Trước khi Android khởi động thành phần ứng dụng, nó phải biết thành phần

nào đang tồn tại. Vì thế, ứng dụng phải nêu rõ các thành phần trong tập tin

AndroidManifest.xml mà được gói trong tập tin .apk mà tập tin .apk này giữ mã

lệnh, tập tin, và các tài nguyên của ứng dụng.

Page 113: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

113

Manifest là một tập tin XML và luôn luôn được đặt tên là

AndroidManifest.xml cho ứng dụng. Trong tập tin manifest chứa các thành phần

sau:

Liệt kê các thành phần như Activity, service, . . . có trong ứng dụng.

Các permission cho phép dùng các phần cứng.

Thông số thiết lập SDK.

Ví dụ tập tin AndroidManifest.xml như sau:

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

<manifest . . . >

<application . . . >

<Activity Android:name="com.example.project.FreneticActivity"

Android:icon="@drawable/small_pic.png"

Android:label="@string/freneticLabel"

. . . >

</Activity>

. . .

</application>

</manifest>

G.5.1.4 Intent filters

Một đối tượng Intent có thể đặt tên cho một thành phần mà mình muốn mở

một cách rõ ràng. Nếu làm vậy, Android tìm thấy thành phần đó và kích hoạt nó.

Nhưng nếu lỡ thành phần không được đặt tên rõ ràng và có thể bị nhập nhằng tên,

Android phải chọn thành phần thích hợp nhất để trả về cho intents. Nó làm vậy

bằng cách so sánh đối tượng Intent với intent filters của thành phần sắp được mở.

Intent filters của thành phần sẽ thông báo cho Android các loại intents mà thành

phần có thể quản lý. Tất cả cả thông tin của thành phần được lưu trong tập tin

Android Manifest. Dưới đây là 2 ví dụ mở rộng có dùng intents filters so với ví dụ

trên:

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

<manifest . . . >

<application . . . >

<Activity Android:name="com.example.project.FreneticActivity"

Android:icon="@drawable/small_pic.png"

Android:label="@string/freneticLabel"

. . . >

<intent-filter . . . >

Page 114: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

114

<action Android:name="Android.intent.action.MAIN" />

<category Android:name="Android.intent.category.LAUNCHER"

/>

</intent-filter>

<intent-filter . . . >

<action Android:name="com.example.project.BOUNCE" />

<data Android:mimeType="image/jpeg" />

<category Android:name="Android.intent.category.DEFAULT"

/>

</intent-filter>

</Activity>

. . .

</application>

</manifest>

Ta thấy trong ví vụ trong thẻ intents filter đầu tiên có 2 thành phần là action

"Android.intent.action.MAIN" và category

"Android.intent.category.LAUNCHER". Nó đánh dấu Activity

FreneticActivity là màn hình đầu tiên khi người dùng khởi động ứng dụng

trên thiết bị Android. Nói cách khác, Activity đó là đầu vào của ứng dụng, nó là

màn hình đầu tiên mà người dùng nhìn thấy khi họ khởi động ứng dụng.

Trong thẻ intents filter thứ 2 mô tả tên action mà Activity có thể thực thi trên

một loại dữ liệu nào đó.

Một thành phần có thể có nhiều intents filter, mỗi cái mô tả bộ khả năng khác

nhau của Activity. Nếu nó không có bất kì filter nào, nó có thể chỉ được kích hoạt

bằng intents mà nó đặt tên rõ ràng như là một thành phần cần được mở.

Đối với broadcast receiver thì nó được tạo và khai báo bằng mã lệnh, intent

filter được khởi động trực tiếp như là đối tượng IntentFilter. Tất cả các filter khác

được thiết lập trong manifest.

G.5.2 Activities và Tasks

Như đã đề cập ở trên, một Activity có thể khởi động một Activity khác.

Trong một ứng dụng có nhiều activities và Task là một ngăn xếp (Stack) cho các

activities, và Task không phải là một lớp hay một phần tử trong tập tin manifest. Vì

thế, không có cách nào để thiết lập giá trị cho tác vụ một cách độc lập của các

activities của nó. Giá trị cho toàn bộ tác vụ được thiết lập ở Activity gốc. Tất cả các

activities trong một tác vụ tạo thành một đơn vị.

Page 115: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

115

<Chú ý 80 trang – So sánh và nói rõ Thread>

G.5.3 Tiến trình và luồng

Khi thành phần đầu tiên của ứng dụng cần chạy, Android khởi động tiến

trình Linux cho nó với một luồng thực thi. Mặc định, tất cả các thành phần của ứng

dụng chạy trong tiến trình và luồng.

G.5.3.1 Tiến trình

Tiến trình nơi mà một thành phần chạy được quản lý bởi tập tin manifest.

Các phần tử thường gặp của thành phần là <Activity>, <service>, <receiver>, và

<provider>, mỗi các phần tử có thuộc tính process mà có thể chỉ rõ tiến trình nơi mà

thành phần chạy. Nếu dùng các thuộc tính này các thành phần chạy trên tiến trình

của riêng nó vì vậy mà một số thành phần có thuộc tính đó thì chia sẻ tiến trình

trong khi các thành phần khác thì không.

Tất cả các thành phần được khởi động trong luồng chính của tiến trình và hệ

thống gọi đến các thành phần.

G.5.3.2 Luồng

Mặc dù bạn chứa ứng dụng của mình trong một tiến trình đơn, nhưng sẽ có

khả năng bạn cần tạo ra một luồng để làm một vài công việc ngầm. Bởi vì giao diện

người dùng phải luôn nhanh để đáp ứng lại hành động của người dùng, cho nên

không thể nào để màn hình dừng lại để chờ một hành động tải về dữ lệu từ mạng rồi

màn hình mới có thể làm công việc khác. Nói chung, bất cứ công việc gì mà không

thể làm nhanh được thì sẽ được chuyển thành luồng.

Những luồng được tạo trong mã lệnh và dùng đối tượng Thread của Java.

Android cung cấp một số lớp tiện lợi cho việc quản lí luồng – Looper cho việc chạy

một vòng lặp tin nhắn trong luồng, Handler cho việc xử lí tin nhắn và

HandlerThread cho việc thiết lập một luồng với vòng lặp tin nhắn.

G.5.4 Vòng đời các thành phần ứng dụng Android

Các thành phần ứng dụng có vòng đời – đó là sự bắt đầu khi Android khởi

động thành phần cho đến khi kết thúc ứng dụng khi thực thể ứng dụng bị hủy. Các

Page 116: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

116

trạng thái ứng dụng có thể có hiệu lực hay không có hiệu lực; đối với activities, thì

có tình trạng visible hoặc invisible. Trong mục này ta nói về vòng đời của activities,

services, và broadcast receiver.

G.5.4.1 Vòng đời của Activity

Một Activity có ba trạng thái:

Đang hiệu lực hoặc đang chạy: khi nó trực tiếp giao tác với người

dùng.

Tạm dừng: khi nó không còn được hiệu lực nhưng vẫn được nhìn thấy

bởi người dùng. Nói dễ hiểu hơn, có Activity này nằm trên một Activity khác

mà Activity này trong suốt hoặc không che phủ hết màn hình vì vậy Activity

khác được nhìn thấy. Một Activity đang dừng thì hoàn toàn “còn sống”

nhưng có thể bị “giết đi” bởi hệ thống trong trường hợp bộ nhớ thấp.

Dừng hẳn: nếu Activity bị che khỏa hoàn toàn bởi một Activity khác.

Nó vẫn còn duy trì tất cả trạng thái và thông tin thành viên. Tuy nhiên, người

dùng không còn thấy nó vì màn hình của nó ẩn đi và thường bị “giết” bởi hệ

thống khi không đủ bộ nhớ.

Nếu một Activity bị tạm dừng và dừng hẳn, hệ thống có thể loại bỏ nó ra

khỏi bộ nhớ bằng cách gọi hàm finish() hoặc loại bỏ nó ra khỏi tiến trình. Khi nó

thể hiện trước người dùng lần nữa, nó phải khởi động và khôi phục lại các trạng thái

trước đó.

Khi một Activity chuyển từ trạng thái này qua trạng thái khác, thì Activity đó

sẽ gọi các phương thức protected sau: void onCreate(Bundle savedInstanceState),

void onStart(), void onRestart(), void onResume(), void onPause(), void onStop(),

void onDestroy(). Tất cả các phương thức này có thể viết lại (override) để phù hợp

với từng công việc cụ thể đối với ứng dụng của bạn khi mà trạng thái ứng dụng thay

đổi. Tất cả các Activity phải thực thi lại hàm onCreate() để thiết lập lần đầu khi mà

các đối tượng trong ứng dụng được khởi động. Nhiều activy sẽ dùng hàm onPause()

để cập nhật lại dữ liệu đã thay đổi hoặc dừng hẵn việc giao tiếp với người dùng.

Page 117: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

117

Chú ý việc gọi siêu lớp (superclass): Việc thực thi bất kì phương thức vòng

đời ứng dụng nào thì nên luôn luôn gọi hàm tương ứng của siêu lớp. Ví dụ:

protected void onPause() {

super.onPause();

. . .

}

Với 7 phương thức định nghĩa cho toàn bộ vòng đời ứng dụng của Activity.

Nếu chú ý, ta thấy có những vòng khép kín như sau:

Vòng khép kín toàn bộ của ứng dụng: Activity bắt đầu từ lần gọi hàm

đầu tiên onCreate() đến hàm cuối cùng onDestroy(). Một Activity làm tất cả

các thiết lập đầu tiên cho chương trình trong hàm onCreate() và giải phóng

tất cả các tài nguyên trong hàm onDestroy(). Ví dụ như ứng dụng có 1 luồng

chạy ngầm để tải dữ liệu từ máy chủ về thì nó tạo luồng trong hàm

onCreate() và sau đó dừng hẵn luồng trong hàm OnDestroy().

Vòng đời nhìn thấy được bởi người dùng: trong Activity từ hàm

onStart() cho đến hàm onStop(). Trong suốt thời gian này, người dùng có thể

thấy Activity trên màn hình. Giữa 2 phương thức này, bạn có thể duy trì các

tài nguyên mà cần thiết để trình bày Activity cho người dùng. Ví dụ, bạn có

thể khai báo BroadcastReceiver trong hàm onStart() để giám sát tự thay đổi

ảnh hưởng đến giao diện và giải phóng nó trong hàm onStop() khi người

dùng không còn nhìn thấy những gì bạn đang trình bày. Hàm onStart() và

onStop() được gọi nhiều lần bởi vì acitivity thay đổi nhiều lần giữa trạng thái

nhìn thấy được và ẩn đi đối với người dùng.

Vòng đời chạy ngầm: từ hàm onResume() đến hàm onPause(). Trong

suốt thời gian này, Activity chuyển từ trạng thái resume sang pause hay

ngược lại. onPause() được gọi khi thiết bị “ngủ” hoặc khi Activity mới được

khởi động, hàm onResume() được gọi khi kết quả của một Activity hay một

intent mới được đưa ra. Vì thế mã lệnh trong hai phương thức này nên ít thôi.

Hình sau mô tả những vòng khép kín và con đường mà activty phải trải qua

giữa các trạng thái. Hình ô van thể hiện trạng thái của Activity, hình chữ nhật thể

Page 118: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

118

hiện các phương thức của vòng đời ứng dụng khi mà Activity có sự thay đổi trạng

thái:

Hình phụ lục 87 Vòng đời của một Activity

Bảng sau mô tả mỗi hàm chi tiết hơn về cách sử dụng và đặt nó ở trong vòng

đời ứng dụng của Activity:

Page 119: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

119

Phương

thức

Mô tả Có thể

hủy

(killable)

Theo sau

hàm

onCreate() Được gọi khi Activity lần đầu tiên được

tạo. Đây là nơi đầu tiên bạn nên làm tất cả

các thiết lập như tạo Views, gắn dữ liệu

vào danh sách hay đại loại vậy. Luôn theo

sau là hàm onStart()

Không onStart()

onRestart() Được gọi sau khi Activity đã bị dừng trước

đó và được được khởi động lại. Luôn theo

sau hàm onStart().

Không onStart()

onStart() Được gọi chỉ trước khi acitivity trở nên

nhìn thấy được với người dùng. Luôn theo

sau là hàm onResume() nếu Activity chạy

ngầm hoặc onStop() nếu nó bị ẩn đi.

Không onResume()

hoặc

onStop()

onResume() Chỉ được gọi trước Activity bắt đầu tương

tác với người dùng. Tại thời điểm này,

Activity nằm trên đầu của ngăn xếp

Activity và người dùng chuẩn bị tương tác

với chúng. Luôn theo sau là hàm

onPause().

Không onPause()

onPause() Được gọi khi hệ thống sắp bắt đầu hồi

phục lại một Activity khác. Phương thức

này được dùng để lưu những dữ liệu mới

vừa thay đổi, dừng hẳn hiệu ứng động và

và dừng hẳn những thứ khác có thể ngốn

tài nguyên CPU hay đại loại vậy. Ứng

dụng làm bất cứ cái gì để sao cho nó chạy

Có onResume()

hay

onStop()

Page 120: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

120

nhanh bởi vì Activity kế tiếp sẽ không hồi

phục lại cho đến khi acitvity hiện tại dừng

lại. Nó theo sau hàm onResume() nếu

Activity hiện tại sắp được thực thi hoặc

theo sau là hàm onStop() nếu nó trở nên ẩn

đi đối với người dùng.

onStop() Được gọi khi người dùng không nhìn thấy

được Activity nữa. Điều này có thể xảy ra

bởi vì nó đang được hủy hoặc một Activity

khác (có thể Activity đang tồn tại hoặc

Activity mới) được hồi phục lại và đang đè

lên Activity hiện tại. Vừa theo sau là hàm

onRestart() nếu Activity đang quay lại để

tương tác với người dùng hoặc hàm

onDestroy() nếu Activity dự định hủy đi.

Có onRestart()

hay

onDestroy()

onDestroy() Được gọi trước khi Activity bị hủy đi. Hàm

này được gọi lần cuối cùng khi mà một

ativity đang kết thúc hay hệ thống chỉ đang

hủy những thực thể của Activity để tiết

kiệm không gian. Có thể phân biệt 2 trạng

thái này bằng hàm isFinishing().

Yes không

Bảng 1 Bảng mô tả lại ý nghĩa các phương thức trong vòng đời của một Activity

Ghi chú cột Có thể hủy (Killable): Ý nghĩa của nó là dù muốn dù không thì

hệ thống có thể “giết” tiến trình đang giữ Activity tại thời điểm sau khi phương thức

kết thúc mà không thực thi dòng mã lệnh cũa một Activity khác. Ba phương thức

(onPause(), onStop(), onDestroy()) có giá trị là Có. Bởi vì onPause() là phương thức

đầu tiên của ba phương thức, nó là phương thức duy nhất bảo đảm được gọi trước

khi tiến trình kết thúc trong khi đó onStop() và onDestroy() thì không. Vì thế, bạn

nên dùng onPause() để cập nhật tất cả dữ liệu mới vừa được thay đổi.

Page 121: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

121

Còn những phương thức được đánh dấu là Không trong cột Có thể hủy

(Killable) bảo đảm tiến trình giữ acitivity khỏi bị “giết” khỏi thời điểm mà chúng

được gọi. Mặc dù vậy một ativity trong tình trạng có thể hủy bắt đầu từ khi

onPause() đến onResume(). Nó không thể bị hủy cho đến khi hàm onPause() kết

thúc.

Tiết kiệm tình trạng của Activity: Khi hệ thống tắt Activity để bảo

toàn bộ nhớ, người dùng mong muốn Activity giữ được trạng thái Activity

như lúc trước khi tắt. Để giữ lại trạng thái trước khi Activity bị tắt, bạn nên

dùng hàm onSaveInstanceState() cho Activity. Android gọi hàm này trước

khi hủy acvitity. Tiếp theo sau đó, để lấy lại trạng thái của Activity thì phải

thực thi hàm onRestoreInstanceState() sau hàm onStart() và hàm onCreate()

đã chạy trước đó. Vì thế ta có thể vừa tái tạo và lưu vết lại trạng thái

Activity. Không giống như hàm onPause() hay những hàm trong vòng đời

ứng dụng, hàm onSaveInstanceState() hay hàm onRestoreInstanceState()

không phải phương thức vòng đời của ứng dụng và không phải lúc nào cũng

được gọi vì không phải lúc nào người dùng cũng muốn lưu vết lại trạng thái

của Activity.

Phối hợp các activities: khi một Activity khởi động một Activity khác,

cả hai Activity sẽ thay đổi trạng thái của vòng đời của mình. Activity này

tạm dừng và có thể dừng hẳn trong khi cái khác thì mới khởi động. Trong

trường hợp bạn có thể cần phối hợp các Activity này khi mà 2 Activity cùng

nằm trong cùng một tiến trình.

G.5.4.2 Vòng đời Service

Một service có thể dùng trong 2 cách:

Nó có thể được khởi động và được cho phép dùng cho đến khi ai đó

dừng hẳn nó hoặc nó tự dừng hẳn. Để khởi động dùng hàm

Context.startService() và dừng hẳn bằng hàm Context.stopService() hoặc tự

dừng bằng hàm Service.stopSelf() hoặc Service.stopSelfResult(). Chú ý là

Page 122: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

122

hàm stopService() chỉ được gọi một lần duy nhất để dừng service trong khi

đó gọi hàm startService() bao nhiêu lần tùy thích.

Nó có thể được vận hành bằng mã lệnh dùng lớp interface mà nó đã

định nghĩa. Client thiết lập kết nối và dùng kết nối ấy để gọi dịch vụ. Kết nối

được thiết lập bằng cách gọi Context.bindService() và được đóng bởi hàm

Context.unbindService().

Giống như Activity, service có những phương ứng vòng đời của riêng mình

mà có thể thực thi để giám sát sự thay đổi trong trạng thái của nó. Nhưng service có

ít hơn và gồm có 3 phương thức public: void onCreate(), void onStart(Intent intent),

void onDestroy().

Bằng cách thực thi những phương thức này, bạn có thể giám sát vòng đời của

service:

Toàn bộ vòng đời của service xảy ra khi gọi hàm onCreate() và kết

thúc khi gọi hàm onDestroy(). Giống như một Activity, một service khởi

động trong hàm onCreate() và giải phóng mọi tài nguyên trong hàm

onDestroy().

Vòng đời “có hiệu lực” của service bắt đầu khi gọi hàm onStart(). Và

không được kết thúc bằng onStop() vì hàm này không có thực.

Phương thức onCreate() và onDestroy() được gọi cho tất cả dịch vụ cho dù

service khởi động bằng hàm Context.startService() hay hàm Context.bindService().

Tuy nhiên, onStart() được gọi khi service đã khởi động bằng hàm startService().

Nếu một service cho phép những service khác liên kết với nó thì phải dùng các

phương thức sau: IBinder onBind(Intent intent), boolean onUnbind(Intent intent),

void onRebind(Intent intent).

Hình sau mô tả các phương thức cho service, Mặc dù, hình chia ra 2 loại

service dựa trên tiêu chí khởi động bởi hàm startService (0 và hàm bindService().

Cho dù nó khởi động bằng cách nào đi chăng nữa, thì nó vẫn cho client kết nối tới

nó và bất kì service nào cũng có thể gọi 2 hàm onBind() và onUnbind().

Page 123: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

123

Hình phụ lục 88 Vòng đời của một Service

G.5.4.3 Vòng đời BroadcastReceiver

Broadcast receiver có một hàm cho phép người dùng viết lại là hàm void

onCreate(Context curContext, Intent broadcastMsg).

Khi một tin nhắn phát đi cho người nhận, Android gọi phương thức

onReceive và chuyển nó cho đối tượng Intent đang chứa tin nhắn. Broadcast

receiver được xem là có hiệu lực chỉ khi nào có đang thực thi phương thức này. Khi

phương thức onReceive() kết thúc thì broadcast receiver không còn hiệu lực nữa.

Page 124: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

124

Một tiến trình với một broadcast receiver thì được bảo vệ khỏi bị “giết”.

Nhưng một tiến trình với các thành phần không còn hiệu lực (Activity, service,…)

thì bị hệ thống “giết” bất kì lúc nào khi mà bộ nhớ không đủ cho các tiến trình khác.

G.5.4.4 Tiến trình và vòng đời ứng dụng

Hệ thống Android duy trì một tiến trình ứng dụng càng lâu càng tốt nhưng nó

sẽ loại bỏ các tiến trình cũ khi mà bộ nhớ thấp. Để quyết định tiến trình nào được

giữ lại, tiến trình nào bị “giết” đi, Android đặt mỗi tiến trình vào một “hệ thống cấp

bậc quan trọng” dựa trên các thành phần đang chạy trên nó và trạng thái của các

thành phần đó. Những tiến trình với độ quan trọng thấp bị loại bỏ đi đầu tiên, sau đó

tới lượt các tiến trình có độ ưu tiên thấp hơn và cứ như vậy. Có 5 cấp trong hệ thống

cấp bậc gồm các cấp bậc sau:

Tiến trình nền: là tiến trình người dùng đang làm việc. Một tiến trình

được xem là tiến trình nền nếu có bất kì điều kiện sau đây:

Nó đang chạy một activty mà người dùng đang tương tác.

Giữ một service mà được liên kết với Activity mà người dùng

đang tương tác.

Có đối tượng Service mà đang thực thi một trong những phương

thức onCreate(), onStart(), onDestroy().

Có đối tượng BroadcastReceiver mà đang thực thi hàm

onReceive().

Chỉ có một vài tiến trình ngầm sẽ tồn tại tại bất kì thời gian nào.

Chúng chỉ bị “giết đi” khi nằm cuối “bảng tổng sắp” nếu bộ nhớ quá thấp

đến nỗi chúng không thể tiếp tục chạy được nữa.

Tiến trình nhìn thấy được: là tiến trình không có các thành phần nền

nhưng vẫn có thể ảnh hưởng đến những gì mà người dùng thấy trên màn

hình. Một tiến trình được xem như là thấy nếu thỏa cả hai điều kiện sau:

Nó giữ một acitivity mà không phải acitivity nền nhưng vẫn nhìn

thấy được đối với người dùng. Điều này xảy ra khi Activity hiện tại là

Page 125: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

125

một hộp thoại và Activity trước đó có thể nhìn thấy được do hộp thoại

không che hết màn hình.

Nó giữ một service mà đang kết nối tới một Activity nhìn thấy

được.

Tiến trình dịch vụ: là tiến trình chạy một service mà được bắt đầu bởi

hàm startService() mà nó không rơi vào 2 trạng thái trên. Mặc dù tiến trình

dịch vụ không liên quan gì tới bất kì cái gì mà người dùng thấy, nhưng nó

làm những thứ mà người dùng quan tâm đến chẳng hạn chơi nhạc mp3

ngầm, và vì thế hệ thống giữ cho chúng chạy nếu đủ bộ nhớ để duy trì 2 tiến

trình trên.

Tiến trình ngầm: là tiến trình giữ một Activity mà người dùng không

nhìn thấy được. Những tiến trình này không ảnh hưởng trực tiếp lên người

dùng, nó có thể bị “giết” bất kì lúc nào để dành bộ nhớ cho 3 dạng tiến trình

trên.

Tiến trình rỗng là tiến trình không giữ bất cứ một ứng dụng nào cả.

Chỉ có một lí do để giữ những tiến trình như vậy là xem nó như là một vùng

đệm để cải thiện tốc độ thời gian khởi động vào lần tới khi mà các thành

phần cần nó để chạy nhanh hơn. Hệ thống thường “giết” các tiến trình này để

mà cân bằng tài nguyên hệ thống giữa vùng đệm tiến trình và vùng đệm lõi

bên dưới thiết bị.

Android xếp hạng các tiến trình từ cao đến thấp dựa trên mức độ quan trọng

của các thành phần hiện đang có hiệu lực trong tiến trình. Thêm vào đó, thứ hạng

các tiến trình có thể tăng lên bởi vì các tiến trình khác phụ thuộc vào nó. Một tiến

trình mà phục vụ cho tiến trình khác có thể không bao giờ được sắp thấp hơn tiến

trình mà nó đang phục vụ. Ví dụ tiến trình A đang phục vụ cho B thì thứ hạng A

luôn cao hơn B.

G.6 Làm quen với các công cụ hỗ trợ sẵn có của Android SDK

G.6.1 Android Development Tools Plugin (ADT)

Page 126: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

126

Hình phụ lục 89 Hình minh họa mối quan hệ giữ Eclipse, ADT và Android SDK

ADT là một plugin bổ sung tích hợp mạnh vào Eclipse. Nó cho phép tạo và

kiểm lỗi ứng dụng Android một cách dễ dàng và thuận tiện.

Plugin ADT khi kết hợp với Eclipse sẽ hỗ trợ rất tốt cho các lập trình viên

phát triển ứng dụng chạy trên Android một cách nhanh chóng, điển hình là:

Truy cập các công cụ phát triển ứng dụng Android ngay trong Eclipse.

Ví dụ như là công cụ DDMS: chụp màn hình ứng dụng, đặt các breakpoint,

xem các luồng (thread) và thông tin tiến trình (process)…

Cung cấp “New Project Wizard” giúp cho việc tạo và thiết lập các tập

tin cơ bản cho ứng dụng Android mới một cách thuận tiện và nhanh chóng.

Tự động và đơn giản hóa quá trình xây dựng ứng dụng Android.

Cung cấp trình biên tập thuận tiện cho việc xây dựng, chỉnh sửa file

XML (Android manifest, và các nguồn tài nguyên khác như layout,

animation…)

G.6.2 Dalvik Debug Monitor Service (DDMS)

DDMS cung cấp nhiều công cụ hữu ích cho việc phát triển ứng dụng

Android và được tích hợp vào bên trong Eclipse, giúp lập trình viên theo dõi các

ADT Plugin

Eclipse IDEAndroid

SDK

Page 127: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

127

luồng, giả lập tổng đài điện thoại (cuộc gọi và SMS), giả lập vị trí (location), quản

lý file trong điện thoại Android ảo…

Hình phụ lục 90 Hình minh họa công cụ DDMS

Một số công cụ hữu ích trong DDMS:

Quản lý thiết bị (1): giúp ta quản lý điện thoại Android nào đang kết

nối và xem danh sách các máy ảo (virtual machine) đang chạy bên trong điện

thoại Android nào đó, các máy ảo này được đặt tên theo tên của các gói ứng

dụng (ví dụ com.android.mms). Ngoài ra còn có các công cụ bên phía trên

giúp cho ta có thể debug, theo dõi, dừng một máy ảo…

Giả lập điện thoại (2): đây là chức năng thú vị và hữu ích khi lập trình

ứng dụng Android. Nó giúp ta giả lập mạng điện thoại (UTMS, GSM,

GPRS…), giả lập cuộc gọi, giả lập tin nhắn, giả lập thông tin vị trí (kinh độ,

vĩ độ), hay nạp vào các file hướng dẫn phục vụ cho việc giả lập bản đồ

(KML, GPX )…

Page 128: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

128

Theo dõi các ghi vết của điện thoại- Logcat (3): mục này giúp ta thấy

được các ghi vết (log) mong muốn khi chạy ứng dụng nào đó, điều này thực

sự hữu ích khi kiểm lỗi một ứng dụng Android.

Quản lý tập tin trong điện thoại (4): mục này giúp ta có thể thao tác

với các tập tin nằm trong điện thoại (chép file từ máy tính vào điện thoại hay

lấy file ra để dùng)

G.6.3 Hierarchy Viewer

Ứng dụng Hierarchy Viewer giúp ta kiểm lỗi và tối ưu lại giao diện.

Cách thức chạy ứng dụng:

Kết nối điện thoại hoặc chạy điện thoại ảo.

Từ dòng lệnh hoặc trong thư mục chứa SDK /tool tìm và chạy

hierarchyViewer.

Khi ứng dụng vừa chạy ta sẽ thấy danh sách các điện thoại đang kết

nối. Lựa chọn điện thoại mong muốn và nhấn vào nút Load View Hierarchy

để thấy cấu trúc cây của giao diện ứng dụng đang chạy trên điện thoại.

Hình phụ lục 91 Hình minh họa công cụ Hierarrchy Viewer

Khi chuyển sang ứng dụng khác trên điện thoại mà ta mong muốn

xem cấu trúc cây của giao diện đó thì nhấn nút Refresh Windows.

Phân tích một mẫu giao diện.

Hình bên dưới là kết quả phân tích mẫu giao diện (1), (2) là kết quả

cây phân cấp giao diện được phân tích. Theo một số thông tin không chính

Page 129: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

129

thức từ cộng đồng phát triển Androi thì giao diện sẽ tối ưu nhất khi các tầng

của cây là ít nhất.

Hình phụ lục 92 Cấu trúc dạng cây khi phân tích một khung giao diện đang được thực thi trên màn

hình

Ngoài ra, ta còn có thể khảo sát được sự phóng to, thu nhỏ của màn hình

(Pixel Perfect View) như hình minh họa bên dưới. Công cụ này có ích trong việc

phát triển giao diện ứng dụng dòi hỏi độ chính xác cao về hình ảnh hay tinh chỉnh

lại hình ảnh, màu sắc, độ trong suốt cho hợp lý hơn. Bên cạnh đó còn có các công

cụ hữu ích khác như:

Overlay: nạp chồng vào một hình khác và điều chỉnh độ trong suốt

của hình đó so với màn hình hiện tại, điều này rất hữu ích khi thiết kế game

hay ứng dụng nhiều hình ảnh phong phú.

Refresh rate: điều chỉnh tốc độ làm tươi của hình ảnh.

Zoom: phóng to hay thu nhỏ hình ảnh.

Page 130: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

130

Hình phụ lục 93 Hình minh họa công cụ Pixel Perfect View

G.6.4 Draw 9-patch

G.6.4.1 Định dạng hình NinePatch

Hình phụ lục 94 Định nghĩa dạng hình NinePatch (Google)

Page 131: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

131

NinePatch cho phép chia một tấm ảnh thành 9 phần với 4 góc không co giãn,

4 cạnh co giãn về một hướng, phần nội dung chính giữa được co giãn theo hai

hướng. Thông thường phần nội dung chính giữa trong suốt, vì vậy phần chính giữa

có thể đẩy nội dung như chuỗi vào trong nó. Nó cho phép tạo các bức ảnh mà có thể

co giãn theo cách bạn muốn khi mà nội dung vượt khỏi kích thước của hình ảnh.

Đối với NinePatch bạn có thể lập trình bằng 2 cách: mã lệnh Java với lớp NinePatch

và tạo ra một bức ảnh NinePatch sử dụng công cụ Draw 9-patch. Trong phần này

chúng tôi nói rõ cách tạo một hình ảnh theo định dạng NinePatch.

Ảnh NinePatch là một bức ảnh có thể co giãn một cách tự động tùy thuộc

vào kích thước nội dung bên trong nó.

Một ví dụ sử dụng NinePatch là các hình nền sử dụng cho nút nhấn chuẩn

của Android. Như các bạn thấy, khi tạo một nút nhấn, nếu nội dung chuỗi hay hình

ảnh trong một nút nhấn quá lớn hay quá nhiều thì nút nhấn sẽ bự dần ra tùy thuộc

vào kích thước của hình hay chuỗi đó. Nhưng chung quy lại, cho dù lớn bao nhiêu

thì nút nhấn vẫn có hình nền đồng bộ với nhau và không bị bể ảnh như trong 5 trạng

thái hình bên dưới:

Nút nhấn bình thường

Nút nhấn không được kích hoạt

Nút nhấn không được kích hoạt khi được chọn

Nút nhấn bình thường khi được chọn

Nút nhấn bình thường khi được nhấn

Hình phụ lục 95 Hình minh họa cho việc thiết kế một ảnh nền của một nút nhấn dùng định dạng hình

NinePatch

Hình ảnh dạng NinePatch phải là hình ảnh PNG chuẩn mà bao gồm hình ảnh

chính phía bên trong và một đến bốn đường viền ở ngoài cùng có kích thước bề

rộng là 1 pixel và ảnh phải lưu với phần mở rộng là .9.png; đương nhiên là ảnh sẽ

Page 132: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

132

được lưu trữ trong thư mục \res\raw trong thư mục của một project Android. Ý

nghĩa các đường viền như sau:

Đường viền trên và đường viền trái của hình NinePatch: quy định độ

giãn của tấm hình theo chiều dọc và chiều ngang khi View chứa nó co giãn.

Chú ý, bất kể một hình kiểu NinePatch nào đều phải có viền trên và viền trái;

nếu thiếu một trong trong hai đường thì chương trình sẽ không chấp nhận

ảnh này.

Hình phụ lục 96 Hình nhận định về thuộc tính Strecthable của ảnh Nine Patch

Đường viền dưới và đường viền phải của hình NinePatch: quy định

khoảng cách tối thiểu giữa phần nội dung của View chứa nó với đường viền

của nó. Nói một cách dễ hiểu, nếu chiều cao và chiều rộng của phần nội dung

quá lớn thì kích thước chiều cao và chiều rộng của hình sẽ giãn nở phù hợp

với nội dung và khoảng cách tối thiểu giữa phần nội dung và đường viền sẽ

được quy định bởi hình vẽ sau:

Page 133: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

133

Hình phụ lục 97 Hình nhận định về thuộc tính Padding của ảnh Nine Patch

Ghi chú: nếu kích thước của View chứa nó nhỏ hơn kích

thước chiều rộng của hình ảnh thì một nửa bên phải và một nửa

bên trái của hình ảnh sẽ giao thoa nhau (tương tự cho chiều cao)

như hình bên:

Nhận xét: Ý nghĩa và cách dùng của NinePatch được nói rõ trên trang

http://developer.android.com/guide/developing/tools/draw9patch.html và

http://developer.android.com/guide/topics/graphics/2d-graphics.html#nine-patch

nhưng không rõ ràng, dễ gây sự khó hiểu cho các nhà phát triển. Chúng tôi đã thử

sử dụng NinePatch và áp dụng hình ảnh NinePatch vào chương trình cho nên chúng

tôi mới có nhận định lại về cách hiệu chỉnh hình ảnh NinePatch như trên.

G.6.4.2 Công cụ Draw 9-patch

Draw 9-patch là công cụ tạo ảnh thuộc kiểu NinePatch dễ dàng nhất.

Cách thức sử dụng công cụ:

Page 134: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

134

Hình phụ lục 98 Hình minh họa công cụ Draw 9-patch

Từ dòng lệnh commanline hoặc trong thư mục chứa SDK \tool tìm và

chạy draw9patch.

Kéo và thả một tấm hình (chỉ hỗ trợ định dạng PNG) vào trong cửa sổ

ứng dụng Draw 9-patch (như hình minh họa bên trên).

Nhấn chuột vào một trong 4 cạnh của tấm hình (mỗi lần nhấp chuột sẽ

tạo 1 pixel màu đen, đây chính là phần quy định độ giãn của tấm hình) và

quan sát độ co giãn của hình ảnh ở khung bên phải của ứng dụng Draw 9-

patch.

Sau khi chỉnh sửa tạo được hình ảnh như ý, ta tiến hành chọn File/

Save 9 patch để lưu lại hình đã chỉnh sửa thành định dạng NinePatch.

G.6.5 Android Debug Bridge (ADB)

Đây là công cụ giúp ta có thể cài đặt một ứng dụng (ten_ung_dung.apk) từ

bên ngoài vào bên trong điện thoại Android.

Page 135: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

135

Hình phụ lục 99 Hình minh họa cách thức dùng dòng lệnh để thực thi công cụ adb

Mở chương trình dòng lệnh Prompt và đi đến thư mục android-sdk-windows

trên ổ đĩa. Ví dụ: C:\android-sdk-windows\tools\. Tại đây chạy tập tin adb.exe với

tham số theo cú pháp sau: adb install <đường dẫn tới file ứng dụng Android>.

Còn cách thứ 2 là các bạn có thể sử dụng biến môi trường (Environment

Variable) để chạy tham số dòng lệnh adb bất kì trên ổ đĩa và thư mục nào mà không

cần vào đúng thư mục chứa nó. Ta có thể thiết lập biến môi trường bằng cách sau:

Vào System Properties/Chọn thẻ Advanced/ Chọn nút Environment Variable. Tiếp

đó là hộp thoại Environment Variables hiện lên, sau đó ta vào System variables/

Chọn Path/ Nhấn Edit. Sau đó đến cuối ô giá trị Variable value và thêm vào đường

dẫn đến tập tin adb. Nhấn Ok và quay trở ra. Thế là xong. Kể từ đây ta ó thể gọi

lệnh adb ở bất kì thư mục nào mà không nhất thiết vào thư mục chứa nó.

Hình phụ lục 100 Hình minh họa cách thức tạo biến môi trường (Windows XP)

Page 136: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

136

G.6.6 Các công cụ hỗ trợ khác

Android Emulator: công cụ tạo điện thoại ảo giúp các nhà lập trình có

thể thiết kế, kiểm lỗi, kiểm tra ứng dụng.

Android Virtual Devices (AVDs): các thiết lập thiết bị ảo. Với mỗi sự

thiết lập ta có thể chỉ định nền Android để thực thi, tùy chọn phần cứng, giao

diện máy ảo. Mỗi chức năng AVD có vai trò như một thiết bị độc lập có lưu

trữ dữ liệu người dùng, có thẻ nhớ…

Layoutopt: công cụ giúp phân tích cách xắp xếp khung giao diện ứng

dụng (application’s layouts) sao cho hiệu quả.

Android Asset Packaging Tool (aapt): công cụ giúp tạo tập tin .apk

chứa các mã nhị phân và các tài nguyên của ứng dụng Android.

Sqlite3: công cụ giúp truy cập tập tin cơ sở dữ liệu SQLite được tạo

và sử dụng bởi ứng dụng Android.

TraceView: công cụ đưa ra sự phân tích bằng đồ họa của các lưu vết

dữ liệu (trace log data) tạo ra từ ứng dụng Android.

Mksdcard: công cụ tạo ảnh đĩa có thể dùng với điện thoại ảo để giả

lập một thẻ lưu trữ bên ngoài (thẻ nhớ SD).

Dx: công cụ chuyễn mã Java bytecode (.class) sang mã Android

bytecode (.dex).

Android: là một tập lệnh (script) giúp quản lý các AVD và tạo các tập

tin xây dựng Ant để có thể biên dịch ứng dụng Android.

Zipalign: một công cụ quan trọng để tối ưu tập tin .apk.

Page 137: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

137

Phụ lục H Các vấn đề cơ bản trong lập trình Android

H.1 Các vấn đề và khái niệm cơ bản trong lập trình giao diện

H.1.1 Giới thiệu lập trình giao diện trên Android và các tính năng của

H.1.1.1 Giới thiệu bản chất tập tin giao diện trên Android

Các tập tin giao diện của ứng dụng Android được qui định bằng XML bao

gồm khung chứa (layout), các điều khiển (widget) trong khung chứa đó và mối quan

hệ giữa chúng. Android xem các tập tin giao diện XML này là tài nguyên và được

lưu trong thư mục /res/layout bên trong project Android.

Các thuộc tính của các layout và widget được thể hiện bằng các thuộc tính

nằm trong thẻ đối tượng của XML. Nếu muốn đối tượng nào được quản lí hay sẽ

thao tác, ta đặt thêm giá trị cho thuộc tính ID của đối tượng ấy. Phần này tương ứng

như trên C#, các đối tượng phải thông qua một định danh ID cho trước.

H.1.1.2 Phân tích mặt mạnh yếu khi dùng XML để làm giao diện

Chúng ta thấy giao diện web hiện nay được định dạng ở 2 dạng là HTML và

Flash. Nếu hùng HTML thì trang web rất “nhẹ” do nội dung giao diện được qui

định bởi các thẻ HTML và các hình ảnh hay phim ảnh sẽ dược tải về ngay sau đó.

Các tập tin giao diện của Android cũng “tưa tựa” như thế. Nội dung được qui định

bằng tập tin XML còn hình ảnh nằm trong thư mục khác. Khi vận hành chúng sẽ kết

hợp lại với nhau tạo nên giao diện màn hình. Nói chung, XML dài dòng nhưng ta

còn có thể đọc được chúng. Nhưng khi biên dịch chương trình và đóng gói thành

tập tin .apk thì các tập tin giao diện sẽ được biên dịch thành mã nhị phân bởi plugin

biên dịch tài nguyên aapt.

Ta dễ thấy mặt mạnh của tập tin XML là làm nhẹ hẳn đi việc định nghĩa giao

diện của một chương trình nhưng ngược lại nó làm cho việc phát triển giao diện trở

nên dài dòng và luộm thuộm khi mới bắt đầu làm quen với nó. Người lập trình sẽ

kết hợp khá nhiều layout và widget để lập nên một giao diện tương đối phức tạp

Page 138: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

138

trong khi đó cũng với giao diện đó nếu làm trên Windows Form của Windows

Mobile thì chỉ cần vài thao tác đơn giản.

Hình phụ lục 101 Hình minh họa giao diện ứng dụng NhatTrungHelloAndroid

Hình phụ lục 102 Đoạn mã lệnh XML tạo giao diện cho ứng dụng NhatTrungHelloAndroid

Trên giao diện chỉ có 3 đối tượng gồm Text View, Edit View và Button

nhưng lượng mã lệnh XML qui định cho chúng khá nhiều.

H.1.1.3 Các cách thêm giao diện

Có 2 cách chính để thêm giao diện là:

Cách 1: kéo thả đối tượng giao diện trên khung Layout, Views bên tay

trái .

Page 139: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

139

Hình phụ lục 103 Hình minh họa cho việc kéo thả giao diện từ khung Layouts và Views

Ta kéo thả khung chứa (layout) và các widget (Views) vào giao

diện kế bên sau đó tinh chỉnh các thuộc tính để chúng thể hiện như ý

muốn.

Cách 2: thêm trực tiếp trên khung Outline thông qua nút .

Hình phụ lục 104 Hình minh họa cho việc tạo giao diện từ khung Outline

Page 140: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

140

Với các Layout, chúng ta có thể thêm các widget cho nó bằng cách

nhấp chọn vào layout và chọn dấu cộng để hiện khung thoại sau để

thêm vào layout con hoặc widget mà bạn cần:

Hình phụ lục 105 Hình minh họa việc thêm một phần tử mới từ khung Outline

Ngoài ra còn cách “pro” hơn là gõ dòng lệnh XML trực tiếp lên tập tin XML.

Nhưng nếu làm vậy thì việc lập trình sẽ dài dòng và khó khăn vì ta phải đảm bảo cú

pháp XML và khó quản lý khi giao diện bắt đầu phức tạp dần.

H.1.1.4 Thứ tự cấp bậc giao diện

Thông thường, một tập tin giao diện nên có một khung chứa nếu không có

khung chứa thì tập tin giao diện ấy chỉ chứa được duy nhất một widget mà thôi.

Chúng ta kết hợp nhiều khung chứa để tạo nên một giao diện hoàn chỉnh.

Bằng cách chạy tập tin hierarchyViewer.bat trong thư mục /android-sdk-

windows/tool ta sẽ xem được cấu trúc giao diện hiện tại của một acitivity hiện hành

của một ứng dụng hiện đang chạy trên một máy ảo. Lưu ý là plugin này có thể liên

kết với nhiều máy ảo khác nhau.

Page 141: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

141

Hình phụ lục 106 Các công cụ hỗ trợ bên trong thư mục Android SDK

Đây là giao diện của công cụ trên:

Hình phụ lục 107 Giao diện công cụ Hierarchy Viewer

Dựa theo cây trên, ta có thể nhìn tổng quát hơn về hệ thống cấp bậc của giao

diện và các phương thức và thuộc tính của nó khi ứng dụng đang thực thi.

H.1.2 Các từ khóa thường gặp trong lập trình giao diện

Chúng tôi tìm hiểu lập trình giao diện trên nhiều nguồn như tài liệu, các

website hướng dẫn lập trình Android thì có nhiều từ được lặp đi lặp lại như sau:

View, Widget, Control: là các đối tượng trực tiếp nhận được sự tương

tác với người dùng. Ví dụ như nút nhấn, edit text,.v.v…

Page 142: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

142

Container: đây là một View mà chứa các View khác. Ví dụ như một

lưới có thể xem là một container bởi vì nó chứa các ô và đương nhiên mỗi ô

là một View.

Layout: là một tập tin XML để mô tả một màn hình giao diện nhưng

đôi khi lại được dùng để mô tả khung chứa như LinearLayout, FrameLayout,

TableLayout, …

H.1.3 Các đơn vị tính trên giao diện

Lúc trước, các nhà lập trình dùng đơn vị pixel để để định kích thước cho các

phần tử trên giao diện bởi vì kích thước màn hình theo đơn vị pixel; ví dụ như

320x480 pixel. Vấn đề xảy ra với pixel đó là nếu chúng ta chạy ứng dụng trên màn

hình có độ phân giải cao hơn thì giao diện trở nên nhỏ hơn và thậm chí rất khó thấy.

Chính vì lí do trên, để giải quyết vấn đề này ta phải có giải pháp làm sao cho kích

thước các phần tử phải độc lập với độ phân giải. Android đưa ra nhiều đơn vị để lựa

chọn tùy thuộc vào nhu cầu nhà phát triển:

px (pixel): số lượng điểm ảnh trên màn hình.

In(inches): kích thước được tính bằng đơn vị inches.

Mm(milimeters): kích thước được tính bằng đơn vị milimet.

Pt (points): có kích thước 1/72 inch.

Dp (density-independent pixels): đơn vị ảo dựa trên độ dày đặc của

màn hình. Trên màn hình có 160 điểm ảnh trên 1 inch thì 1dp=1px.

Dip: gần nghĩa giống dp, được dùng nhiều trong các ví dụ ứng dụ mẫu

của Google.

Sp (scale-independent pixels): tương tự như dp nhưng áp dụng cho

kích tước các font chữ.

Riêng về kinh nghiệm của chúng tôi, thì chúng ta nên dùng đơn vị dip làm độ

đo cho kích thước các đối tượng widget trên màn hình vì nói chung nó được Google

dùng nhiều trên các ví dụ. Ngoài ra, như đã nói, dip cũng như dp nó sẽ có độ co

Page 143: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

143

giãn tùy thuộc theo từng màn hình cho nên đã giải quyết được vấn đề đã nêu ở ban

đầu mục này. Tương tự cho font chữ cũng thế, ta nên dùng đơn vị sp cho chúng.

H.1.4 Các thuộc tính thường gặp trên các View

Thông thường, các thuộc tính các View bao gồm cả 2 dạng khung chứa

(layout) và widget thì sẽ tùy thuộc vào từng hoàn cảnh mà gồm 3 nhóm thuộc tính

sau:

Nhóm thuộc tính nội tại của View: nhóm thuộc tính này qui định lên

các giá trị và thành phần bên trong View đó, nó không hoàn toàn ảnh hưởng

bởi thuộc tính các View bên ngoài.

Nhóm thuộc tính Misc: qui định sự tương quan giữa View hiện tại với

cha của nó.

Nhóm thuộc tính Deprecate: Qui định thuộc tính chuỗi thuộc đối

tượng (Nếu View này là đối tượng có chứa chuỗi trong đó).

Hình phụ lục 108 Nhóm thuộc tính thường gặp

trên một TextView

Hình phụ lục 109 Nhóm thuộc tính thường gặp

trên một LinearLayout

Page 144: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

144

H.1.5 Tổng quát các View dưới cái nhìn hướng đối tượng

Hình phụ lục 110 Hình ảnh các View dưới góc nhìn hướng đối tượng

Sau đây, ta đi vào hiểu thêm về các lớp đối tượng có trên mô hình kế thừa

trên:

H.1.5.1 Lớp View

ViewAnalogClock

ProgressBar

ImageView

ImageButton

SurfaceView

VideoView

ViewGroup

ViewStub

TextView

Button

CompoundButton

CheckBox

EditText

DigitalClock

CheckedTextViewMapView

AdapterView

Gallery

GridView

ListView

RelativeLayout LinearLayout FrameLayout AbsoluteLayout

WebView

ViewAnimation

ZoomControls

TwoLineListItem

DialerFilter

TableLayout

TableRow

TabWidget

RadioGroup

Spinner

Chronometer

ScrollView

TimePicker

DatePicker

AppWidgetHostView

TabHost

SlidingDrawer

RadioButton

KeyboardView

ToggleButton

Page 145: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

145

Lớp View là lớp đại diện tiêu biểu cho việc xây dựng giao diện người dùng

(UI). Một View chiếm một vùng hình chữ nhật trên màn hình, chịu trách nhiệm vẽ

và quản lý sự kiện trên đó.

View là lớp cơ sở cho các widget (widget dùng để tạo các thành phần giao

diện tương tác người dùng như các nút nhấn, vùng nhập liệu…)

H.1.5.2 Viewgroup

ViewGroup là một View đặc biệt có thể chứa các View. ViewGroup là lớp

cơ sở cho các khung chứa.

Một số lớp con tiêu biểu của ViewGroup:

LinearLayout:

Hình phụ lục 111 Hình ảnh minh họa của một Linear Layout

Đây là một khung chứa mà các thành phần bên trong nó được sắp

xếp trên một dòng đơn hay cột đơn.Có 2 hướng để sắp xếp các thành

phần con bên trong là hướng ngang hoặc hướng dọc, hướng mặc định là

xắp xếp theo chiều ngang.

LinearLayout là khung chứa đơn giản, dễ hiệu chỉnhvà được dùng

nhiều trong việc tạo giao diện người dùng.

Page 146: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

146

RelativeLayout:

Hình phụ lục 112 Hình ảnh minh họa của một Relative Layout

Đây là một khung chứa mà vị trí của các thành phần bên trong

được sắp xếp có sự tương quan so với các thành phần khác hay so với cha

của nó.

Ví dụ:

A nằm bên trên (so với khung chứa nó).

B nằm bên dưới so với A, và về phía phải so với

chính nó.

C nằm bên dưới so với A, và về phía bên trái so với

B.

AbsoluteLayout:

Page 147: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

147

Hình phụ lục 113 Hình ảnh minh họa của một Absolute Layout

Đây là khung chứa cho phép ta định nghĩa chính xác vị trí (tọa độ)

đặt các thành phần bên trong nó hay nói cách khác là các thành phần bên

trong khung chứa này được đặt vào một vị trí tuyệt đối và không dịch

chuyển được. Chính vì vậy mà AbsoluteLayout kém mềm dẻo hơn so với

các khung chứa còn lại và khó khăn trong việc chỉnh sửa nâng cấp giao

diện.

H.1.5.3 Các View ở nút lá

Các View ở nút là View trực tiếp thao tác với người sử dụng. Ở đây, chúng

tôi liệt kê ra một số các View thông dụng:

Page 148: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

148

Hình phụ lục 114 Hỉnh ảnh một số View thông dụng

Ngoài ra còn rất nhiều View khác còn chờ bạn khám phá và áp dụng theo

từng nhu cầu riêng của mình trong ứng dụng.

H.1.5.4 Nhận xét

Việc xây dựng giao diện người dùng trong Android rất linh hoạt và uyển

chuyển.

Hình phụ lục 115 Hình ảnh minh họa cấu trúc dạng cây của một giao diện bất kỳ

Ta có thể kết hợp ViewGroup và View lại với nhau để tạo ra giao diện người

dùng đơn giản hoặc phức tạp tùy theo nhu cầu sử dụng. Chẳng hạn như một

ViewGroup có thể chứa nhiều View và cũng có thể chứa ViewGroup khác. Chính vì

sự kết hợp này mà cấu trúc của giao diện người dùng trong Android thường có cấu

trúc dạng cây và gốc của cây thường là một ViewGroup.

Page 149: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

149

H.1.6 Cách thức xây dựng và thiết kế giao diện

H.1.6.1 Giới thiệu

Cũng như C#, Android đưa ra 2 phương pháp lập trình giao diện uyển

chuyển là bằng tập tin giao diện XML và bằng mã lệnh Java. Đối với bằng tập tin

giao diện XML thì đã rõ, còn đối với việc bằng mã lệnh Java thì ta sẽ tìm hiểu sâu

hơn để đưa ra so sánh tương ứng giữa 2 phần này.

Trong những phần tiếp theo của mục này, chúng tôi tạo một ứng dụng mẫu

để mô tả cách lập trình thiết kế giao diện bằng cả 2 cách để các bạn tham khảo. Ứng

dụng đó có tên là HelloAndroidUI đi kèm với đĩa DVD của tài liệu này gồm 2 cách

với cấu trúc giao diện giống nhau để cho các bạn tiện so sánh.

Hình phụ lục 116 Hình minh họa tạo giao diện

bằng mã lệnh XML

Hình phụ lục 117Hình minh họa tạo giao diện

bằng Java

Hai hình trên thể hiện cùng một cấu trúc giao diện nhưng bản chất hình đầu

lập trình bằng XML hình 2 thì bằng mã lệnh Java.

H.1.6.2 Lập trình giao diện bằng XML

Cách thức thao tác kéo thả hay dùng các nút bên Outline của giao diện cho

đến “ngông cuồng” gõ trực tiếp dòng lệnh XML để tạo thành tập tin giao diện XML

Page 150: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

150

trên Android ta không bàn nhiều ở đây. Ta xem như đã có sẵn tập tin giao diện

XML có tên là using_xml.xml trong thư mục /res/layout/ như sau:

Hình phụ lục 118 Cấu trúc xây dựng giao diện bằng XML

Ta thiết lập tập tin giao diện này cho một Activity bằng đoạn mã sau:

public class AndroidUI_UsingXML extends Activity {

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

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

// nạp giao diện từ tập tin XML

setContentView(R.layout.using_xml);

}

}

Để thiết lập tập tin giao diện XML cho một Activity thì ta dùng hàm

setContentView(R.layout.xxx) với xxx là tên tập tin. Phương thức này được thiết

lập trong những dòng mã lệnh đầu tiên của phương thức onCreate().

H.1.6.3 Lập trình giao diện bằng mã lệnh Java

Khác với phương pháp trên, lập trình giao diện bằng mã lệnh Java là ánh xạ

các phần tử giao diện XML thành mã Java tương ứng. Nói chung, việc làm này rất

dễ và gần giống như lập trình XmlDocument trên C# vậy.

Sau đây là toàn bộ đoạn mã lệnh:

public class AndroidUI_UsingJava extends Activity {

private LinearLayout parentContainer;

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

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

Page 151: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

151

// phần này tương ứng như khung LinearLayout trong tập tin

using_xml

parentContainer = new LinearLayout(this);

parentContainer.setLayoutParams(new LayoutParams(

LayoutParams.FILL_PARENT,

LayoutParams.FILL_PARENT));

parentContainer.setOrientation(LinearLayout.VERTICAL);

// phần này ứng với TextView trong tập tin using_xml

TextView myTextView = new TextView(this);

myTextView.setText("Hello Android UI (Using Java Code)");

parentContainer.addView(myTextView);

// phần này ứng với EditText có ID @+id/edt_TestEditText

trong tập tin using_xml

EditText nameLbl = new EditText(this);

nameLbl.setHint("EditText using code");

parentContainer.addView(nameLbl);

// phần này ứng với Button có ID @+id/btn_TestButton trong

tập tin using_xml

Button btn = new Button(this);

btn.setText("Button Using Code");

parentContainer.addView(btn);

// nạp giao diện tạo bằng Java code lên màn hình

setContentView(parentContainer);

}

}

Bạn nhìn thấy trên mã lệnh có phần đầu là tạo thực thể Layout và thiết lập

các thuộc tính riêng cho nó. Sau đó lần lượt tạo thực thể các View và thêm vào thực

thể layout đó. Công đoạn này xem chừng rất tỉ mĩ và tốn nhiều thời gian và cuối

cùng cũng thông qua hàm setContentView(thực thể layout gốc) để thiết lập thực thể

giao diện đó cho màn hình Android.

H.1.6.4 Nhận xét

Page 152: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

152

Giữa 2 phương pháp lập trình giao diện trên đều ra một kết quả như nhau.

Nhưng mỗi phương pháp có mặt mạnh yếu như sau:

Bằng XML: giúp nhà lập trình thiết kế giao diện nhanh hơn so với

bằng mã lệnh Java do có công cụ hỗ trợ lập trình giao diện ADT. Nhưng nó

chưa đáp ứng được nhu cầu khi giao diện có sự thay đổi linh hoạt hơn tùy

thuộc theo từng điều kiện mà giao diện XML không thể đáp ứng được.

Bằng mã lệnh Java: rất khó để lập trình một giao diện phức tạp vì nó

rất khó quản lí theo từng dòng mã lệnh nhưng bù lại nó uyển chuyển và linh

hoạt khi mà giao diện bằng XML không đáp ứng được.

H.1.7 Cách thao tác control trên Java code

Tất cả các khung chứa (layout) và các View đều có thể khai báo thành một

thực thể bằng mã lệnh Java. Nếu chúng ta có nhu cầu thiết lập lại thuộc tính hay

kiểm soát các hành động của đối tượng thì phải tại một định danh trong thuộc tính

ID để ta có thể gán đối tượng đó cho một thực thể thông qua phương thức

findViewByID(R.id.yyy) với yyy là tên ID của nút nhấn. Ví dụ như giá trị thuộc

tính ID trên nút như sau:

Hình phụ lục 119 Hình minh họa việc quản lý các View thông qua định danh ID

Chúng ta xem lại tập tin HelloNhatTrungApp.Java trong project đầu tay

HelloNhatTrungApp. Trong tập tin này có đoạn mã lệnh tạo thực thể cho nút nhấn

Chào Android như sau:

Page 153: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

153

Button btnChaoAndroid = (Button) findViewById(R.id.ButtonChaoAndroid);

Ta thấy rất dễ, để khai báo thực thể cho một đối tượng bất kì trên màn hình

giao diện thì ta dùng phương thức findViewById(R.id.yyy) và sau đó ép về kiểu dữ

liệu thật của nó. Tương tự cho tất cả các đối tượng còn lại như EditText chẳng hạn:

// Khai báo thực thể (instance) ánh xạ qua bên EditTextTenCuaBan trên

final EditText edtTextTenNguoiDung = (EditText)

findViewById(R.id.EditTextTenCuaBan);

Cũng với từng đối tượng, chúng ta có thể thay đổi thuộc tính của chúng,

dùng các phương thức thiết lập “lắng nghe” người dùng tác động lên nó bằng các

phương thức thuộc kiểu onXXXListener với XXX là tùy theo từng kiểu khác nhau.

Trong những phần tiếp theo, chúng tôi sẽ nói rõ hơn về cách lập trình đối với khung

chứa (layout) và các widget cơ bản trong lập trình giao diện.

H.2 Lập trình với giao diện cơ bản

H.2.1 Các điều khiển chứa điều khiển khác (layout)

Các layout rất quan trọng trên màn hình giao diện Android và nó là khung

chứa các điều khiển của ứng dụng. Mỗi layout có cách dùng khác nhau và thuộc

tính khác nhau và giúp cho nhà lập trình rất nhiều khi các nhà lập trình biết uyển

chuyển kết hợp chúng lại với nhau tạo nên màn hình giao diện mong muốn.

Có 5 layout chính là LinearLayout, TableLayout, FrameLayout, AbsoluteLayout, và

RelativeLayout. Tiếp theo sau đây, ta sẽ đi qua ý nghĩa và cách sử dụng từng layout

cùng với kinh nghiệm của chúng tôi khi làm trên chúng.

H.2.1.1 Khung chứa Linear Layout

Linear là “tuyến tính” và nói một cách dễ hiểu về LinearLayout là vị trí các

đối tượng con của LinearLayout đi theo tuần tự từ trên xuống hay từ trái sang phải.

Đó là nguyên tắc nhất quán của LinearLayout. Nếu thiết lập thuộc tính Orientation

là Vertical thì các đối tượng con của nó theo từ trên xuống, và nếu là Horizontal thì

các đối tượng thêm vào sẽ được xếp theo chiều ngang.

Ví dụ, ta có hình minh họa như sau:

Page 154: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

154

Hình phụ lục 120 Hình minh họa một Linear Layout

Như chúng ta thấy, hinh trên có một LinearLayout “cha” có 2 LinearLayout

“con” là linear layout đóng khung màu vàng ở trên và phần đóng khung màu đỏ ở

dưới.

Phần LinearLayout được bao bởi khung vàng có Orientation là Horizontal

nên các TextView được xếp ngang. Còn LinearLayout được bao bởi màu đỏ thì có

TextView được xếp theo chiều dọc.

Ta chú ý kĩ các thuộc tính có trong LinearLayout trên và dưới trong đoạn

XML sau:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

android:orientation="vertical" android:layout_width="fill_parent"

android:layout_height="fill_parent">

<LinearLayout android:orientation="horizontal"

android:layout_width="fill_parent"

android:layout_height="fill_parent"

Page 155: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

155

android:layout_weight="1">

<TextView android:text="red"

android:gravity="center_horizontal"

android:background="#aa0000"

android:layout_width="wrap_content"

android:layout_height="fill_parent"

android:layout_weight="1" />

<TextView android:text="green"

android:gravity="center_horizontal"

android:background="#00aa00"

android:layout_width="wrap_content"

android:layout_height="fill_parent"

android:layout_weight="1" />

<TextView android:text="blue"

android:gravity="center_horizontal"

android:background="#0000aa"

android:layout_width="wrap_content"

android:layout_height="fill_parent"

android:layout_weight="1" />

<TextView android:text="yellow"

android:gravity="center_horizontal"

android:background="#aaaa00"

android:layout_width="wrap_content"

android:layout_height="fill_parent"

android:layout_weight="1" />

</LinearLayout>

<LinearLayout android:orientation="vertical"

android:layout_width="fill_parent"

android:layout_height="fill_parent"

android:layout_weight="1">

<TextView android:text="row one" android:textSize="15pt"

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:layout_weight="1" />

<TextView android:text="row two" android:textSize="15pt"

Page 156: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

156

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:layout_weight="1" />

<TextView android:text="row three" android:textSize="15pt"

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:layout_weight="1" />

<TextView android:text="row four" android:textSize="15pt"

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:layout_weight="1" />

</LinearLayout>

</LinearLayout>

Đối với các thuộc tính LinearLayout thì ta cần chú ý các thuộc tính sau:

Orientation: hướng của layout có 2 giá trị là Horizontal và Vertical.

Như đoạn cho ví dụ ở trên.

Layout_width và layout_height: lần lượt là chiều rộng và chiều cao

của layout. Ta có thể điền vào kích thước như ý muốn bằng đơn vị dip – 110

dip – hay dùng 2 dạng có sẵn là wrap_content và fill_parent lần lượt là bao

theo chiều dài của nội dung và phủ đầy theo chiều dọc hay ngang tùy theo là

layout_width hay layout_height.

Layout_weight: dùng thuộc tính này để ta thiết lập mức độ quan trọng

và “giành giật” không gian theo hướng mà thuộc tính Orientation mà cha nó

qui định. Layout_weight được áp dụng cho các layout mà còn cho các

widget. Ở đây, chúng tôi lấy ví dụ Button như hình sau:

Page 157: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

157

Hình phụ lục 121 Hình minh họa cho thuộc Layout_weight

Nút 1 có layout_wight là 0 còn nút còn lại có giá trị là 1 cho nên

nút còn lại sẽ chiếm dụng hết phần còn lại theo hướng của cha qui định

cho các con.

Layout_gravity: là sự canh lề cho các đối tượng bên trong layout hay

widget.

Gravity: là sự canh lề trái, phải, trên, dưới so với cha của nó.

Ta có thể lập trình giao diện LinearLayout bằng XML và bằng mã lệnh Java

như đã hướng dẫn ở trên.

Page 158: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

158

Theo như kinh nghiệm của chúng tôi, bạn nên dùng LinearLayout để làm

Layout thiết kế chính cho toàn chương trình của mình và tùy theo từng hoàn cảnh

mà sẽ kết hợp thêm các Layout còn lại. Bởi vì LinearLayout được dùng thuần thục

thì sẽ tác dụng cao trong việc phân chia khung hệ thống giao diện trong ứng dụng.

H.2.1.2 Khung chứa Table Layout

Table là “bảng”, nói dễ hiểu TableLayout là khung được thiết kế theo dạng

bảng có nhiều dòng và nhiều cột và mỗi ô có thể chứa một widget con hay chứa một

layout khác.

Hình phụ lục 122 Hình minh họa cho một Table Layout

Chúng ta thấy TableLayout để tạo tạo thành bảng thì ta dùng Thẻ TableRow

để qui định bảng có bao nhiêu dòng. Còn việc có bao nhiêu cột là do bên trong dòng

đó có bao nhiêu phần tử; số lượng phần tử qui định số cột cho dòng đó. Chúng tôi

Page 159: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

159

đã tạo 4 TableLayout với việc thêm từng thuộc tính thì bảng sẽ khác nhau với

những thuộc tính sau:

Android:layout_span: là thuộc tính của một đối tượng bên trong

TableRow. Ví dụ như:

<TextView android:text="red" android:gravity="center_horizontal"

android:background="#aa0000"

android:layout_height="fill_parent"

android:layout_width="fill_parent"

android:layout_span="3" />

Như bạn thấy do layout_span là 3 nên nó mở rộng ra mà trộn 3 cột

lại trong bàng thứ 2 từ trên xuống trên hình trên.

Android:stretchcolumns chỉ định kéo giãn cột nào trong bảng theo chỉ

số từ 0. Ví dụ như bạn đặt thuộc tính android:stretchColumns="0,1,2" nằm

bên trong thẻ TableLayout thì nó sẽ qui định cột thứ 1, thứ 2 và thứ 3 dãn

đầy màn hình và lấp phần trống còn lại của cha. Ví dụ như sau:

<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:stretchColumns="0,1,2">

Android:layout_weight: sẽ giúp cho các đối tượng bên trong

TextView sẽ giản hết và chiếm phần trống còn lại của cha nó theo chiều

Orientation mà cha nó qui định.

<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"

android:layout_width="fill_parent"

android:background="#fffff0"

android:layout_height="wrap_content">

<TableRow android:layout_width="fill_parent"

android:layout_height="wrap_content">

<TextView android:text="red"

android:gravity="center_horizontal"

android:background="#aa0000"

android:layout_height="fill_parent"

android:layout_width="fill_parent"

android:layout_weight="1" />

Page 160: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

160

</TableRow>

Theo kinh nghiệm chúng tôi, bạn nên dùng TableLayout khi thiết kế màn

hình kiểu nhập liệu nhiều giá tri6 như tìm kiếm nâng cao hay thông tin khách

hàng,… Khi đó cần canh chỉnh TextView bên trái và các EditText bên phải cho dễ

nhìn.

H.2.1.3 Khung chứa Frame Layout

Frame là “khung ảnh”; nói dễ hiểu FrameLayout giống như trò chơi ghép

nhiều tấm phim lên với nhau để tạo thành một bức ảnh hoàn chỉnh. Ví dụ như bạn

có 5 tấm hình: 1 tấm có khuôn mặt, 1 tấm có 1 cái mũi, 1 tấm có 2 con mắt, 1 tấm

có miệng, 1 tấm có mái tóc và 2 lổ tay; sau đó ta ghép các tấm phim lại thành 1 hình

ảnh hoàn chỉnh. FrameLayout tương tự như thế.

Hình phụ lục 123 Hình minh họa cho một Frame Layout

Đoạn mã lệnh tương ứng với hình trên bằng XML:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"

android:layout_width="fill_parent"

android:layout_height="fill_parent"

android:background="#ffffff">

<Button android:id="@+id/Button01"

android:layout_width="wrap_content"

android:layout_height="wrap_content" android:text="Hello

Button"></Button>

<FrameLayout android:id="@+id/FrameLayout01"

android:background="#000000" android:layout_gravity="left"

Page 161: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

161

android:layout_marginTop="50dip"

android:layout_width="fill_parent"

android:layout_height="fill_parent">

<TextView android:id="@+id/TextView01"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="Hello FrameLayout 2"></TextView>

</FrameLayout>

<FrameLayout android:id="@+id/FrameLayout02"

android:layout_width="wrap_content"

android:layout_height="wrap_content">

<AnalogClock android:id="@+id/AnalogClock01"

android:layout_width="wrap_content"

android:layout_height="wrap_content"></AnalogClock>

</FrameLayout>

</FrameLayout>

Như đã nói, các FrameLayout nằm chồng đè lên nhau cho nên ta nên canh

chỉnh lề cho từng đối tượng con của nó để chúng sắp xếp đè lên nhau một cách có

trật tự.

Theo chúng tôi dùng FrameLayout cho trường hợp muốn các đối tượng nằm

những nơi mà mình thích không bị chi phối bởi sự tương quan giữa chúng như các

đối tượng trên LinearLayout bị ảnh hưởng đến nhau.

H.2.1.4 Khung chứa Absolute Layout

Absolute là “xác thực”; AbsoluteLayout có nghĩa là các điều khiển được kéo

vào thì nó sẽ để điều khiển đó đúng như vị trí mà đối tượng đó được kéo vào. Nếu

bạn nào lập trình giao diện trên C# thì nó sẽ đúng y chang như vậy. Nhưng nó bị

một hạn chế là khi màn hình quay ngang hoặc đứng thì nó sẽ bị mất đi như hình

dưới.

Page 162: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

162

Hình phụ lục 124 Hình minh họa cho một Absolute layout

Đoạn mã XML sau thể hiện giao diện trên:

<AbsoluteLayout

xmlns:android="http://schemas.android.com/apk/res/android"

android:layout_width="fill_parent"

android:layout_height="fill_parent">

<Button android:layout_width="wrap_content"

android:layout_y="200dip"

android:layout_x="100dip"

android:layout_height="wrap_content"

android:id="@+id/Button01" android:text="Hello

Button"></Button>

<Button android:layout_width="wrap_content" android:text="Hello

Button"

android:layout_y="200dip" android:layout_x="240dip"

android:id="@+id/Button02"

android:layout_height="wrap_content"></Button>

Page 163: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

163

</AbsoluteLayout>

Theo như kinh nghiệm chúng tôi, dùng AbsoluteLayout trong hoàn cảnh ta

muốn để “cứng” kiến trúc giao diện.

H.2.1.5 Khung chứa Relative Layout

Relative là “quan hệ”; Relative Layout có nghĩa là các đối tượng bên trong

nó sẽ có vị trí tương quan và ảnh hưởng dây chuyền với nhau, khi một đối tượng

gốc bị thay đổi thì tất cả các đối tượng còn lại bị thay đổi theo.

Hình phụ lục 125 Hình minh họa Relative Layout

Đoạn mã XML tương ứng:

<RelativeLayout

xmlns:android="http://schemas.android.com/apk/res/android"

android:layout_width="fill_parent"

android:layout_height="fill_parent"

android:padding="10dip">

Page 164: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

164

<TextView android:id="@+id/label"

android:layout_width="fill_parent"

android:layout_height="wrap_content" android:text="Type

here:" />

<EditText android:id="@+id/entry"

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:layout_below="@id/label" />

<Button android:id="@+id/ok" android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_below="@id/entry"

android:layout_alignParentRight="true"

android:layout_marginLeft="10dip"

android:text="OK" />

<Button android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_toLeftOf="@id/ok"

android:layout_alignTop="@id/ok" android:text="Cancel" />

</RelativeLayout>

Như ta thấy thẻ Button của nút nhấn Ok có thuộc tính

android:layout_below="@id/entry" với @id/entry là EditText của màn hình; như

vậy nó có vị trí tương đối với EditText và các đối tượng còn lại đều tương tự như

vậy khi ta thiết lập các thuộc tính android:layout_below, android:layout_above,

android:layout_toLeftOf, android:layout_toRightOf,

android:layout_alignTop, android:layout_alignBottom,

android:layout_alignRight, android:layout_alignLeft,… có giá trị là các ID

của các đối tượng mà nó đang canh chỉnh theo tên của thuộc tính.

Theo chúng tôi, RelativeLayout là layout gần giống như LinearLayout về

mặt thể hiện nhưng bản chất lại khác nhau. Chúng tôi đọc 1 số cuốn sách hướng dẫn

lập trình Android thì một số tác giả có khuynh hướng dùng RelativeLayout do nó có

tính tối ưu hơn LinearLayout về mặt phân cấp giao diện. Nhưng sử dụng ra sao thì

còn tùy thuộc vào từng hoàn cảnh của thể của từng giao diện bài toán.

H.2.2 Các điều khiển thông dụng

Page 165: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

165

Các điều khiển thông dụng trên màn hình đủ để cho ta lập trình giao diện

phục vụ cho các công việc riêng ứng với từng nhu cầu trong thực tế gồm những

giao diện thông dụng sau:

Hình phụ lục 126 Hình minh họa các điều khiển khác

Trên các các đối tượng cơ bản thuộc nhóm các nút nhấn như Button,

ImageButton, ToggleButton, CheckBox, Option, …

Hình phụ lục 127 Hình minh họa các điều khiển khác

Page 166: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

166

Các điều khiển khác như RatingBar, Clock, ZoomImage, ImageView,

ProgressBar, SeekBar, ... có các thuộc tính và phương thức khác nhau.

Trong phần này, tùy theo từng điều khiển mà thuộc tính và phương thức sẽ

khác nhau. Cho nên trong phần này nếu trình bày thì sẽ rất nhiều nhưng bù lại các

thuộc tính và phương thức rất dễ. Theo kinh nghiệm chúng tôi, thuộc tính và

phương thức thì có nhiều nhưng quanh đi quẩn lại chỉ tập trung vào thuộc tính chỉnh

sửa thuộc tính nội dung của nó và các phương thức Listener mà thôi. Những phần

này, bạn nào có tí kiến thức về lập trình trên C# thì làm quen sẽ rất nhanh.

H.3 Các chú ý khi lập trình giao diện

Khi muốn chọn nhiều đối tượng không liên tục nhau, ta cần dùng tổ hợp

phím Ctrl + nhấp chọn vào đối tượng cần chọn.

Khi bước vào lập trình giao diện, sau khi tìm hiểu xong các thao tác cơ bản

thì bạn cần bắt tay vào ngay để “vọc” thử như thiết lập giao diện cho các ý tưởng

màn hình mà bạn đề ra, thử quay dọc hay quay ngang màn hình để xem các đối

tượng được bố trí lại ra làm sao và có phù hợp chưa. Khi làm vậy, bạn sẽ có kinh

nghiệm lập trình giao diện để hiện thực hóa ý tưởng của mình rất nhanh.

Theo kinh nghiệm chúng tôi, bạn nên dùng công cụ thao tác trên Outline để

chỉnh sửa nội dung giao diện như tạo mới, xóa hay di chuyển các layout và View

khi mà chúng đặt không đúng vị trí.

Một số thuộc tính của điều khiển và layout không nằm trên tab Properties

của đối tượng đó mà ta sẽ thêm “nóng” vào trong tập tin giao diện bằng XML. Phần

này, chỉ trong những cuốn sách lớn viết về Android nằm trong phần tài liệu tham

khảo của khóa luận sẽ “lâu lâu” nói thêm về các thuộc tính bất chợt đó. Ví dụ như,

thuộc tính android:layout_span là thuộc tính không sẵn có trên tab Properties của

các điều khiển nhưng thuộc tính ấy khi được thêm vào các widget là con của

TableLayout thì nó sẽ trộn với các cột phía sau còn trống của TableLayout đó. Bản

chất thuộc tính này không trực thuộc TextView nhưng ta thêm “cứng” hay “nóng”

bằng cách gõ trực tiếp vào tập tin XML.

Page 167: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

167

Phụ lục I Lập trình theo từng chủ đề

Trong phần phụ lục này, chúng tôi nói về cách thức lập trình theo từng chủ

đề mà chúng tôi tìm hiểu để phục vụ cho ứng dụng thực tế của chúng tôi. Mỗi phần

chúng tôi nêu ra cách dùng đơn giản nhất ở mức có thể để có thể làm quen với chủ

đề ấy. Trong mỗi chủ đề sẽ có rất nhiều tài liệu và code mẫu trên các diễn đàn

Android mà các bạn có thể tham khảo thêm.

I.1 Lập trình giao diện tùy biến với Adapter

Thực chất khái niệm lập trình với Adapter là chúng tôi đã tham khảo trên

một số tài liệu nói về Android khi lập trình với một số đối tượng giao diện mà cần

một Adapter làm trung gian liên kết giữa giao diện màn hình và nguồn dữ liệu sẵn

có. Nói dễ hiểu, nó đóng vai trò gắn kết từng thành phần dữ liệu vào từng đối tượng

thành phần giao diện và tạo nên một danh sách hay một hệ thống các phần tử giao

diện hoàn chỉnh.

I.1.1 Giới thiệu sơ lược BaseAdapter và các lớp con của nó

I.1.1.1 Giới thiệu Base Adapter

BaseAdpater là lớp adpater cơ sở cho các Adapter thường dùng khác như

ArrayAdapter<T>, CursorAdapter, SimpleAdapter. BaseAdapter thường đóng vai

trò Adapter cho các ListView và Spinner sẽ được tìm hiểu trong các phần tiếp theo.

Chú ý: có thể dùng lớp ListAdapter hoặc lớp SpinnerAdapter làm Adapter lần lượt

cho ListView và Spinner. Nhưng 2 lớp này chỉ là lớp ảo xây dựng trên lớp

BaseAdapter mà thôi.

I.1.1.2 Giới thiệu ArrayAdapter

Một ListAdapter có thể quản lí một ListView chứa danh sách các phần tử có

kiểu bất kì. Việc rất đơn giản, bạn chỉ cần “móc nối” dữ liệu với TextView thông

qua ID của nó với mỗi dòng trong ListView là một TextView – ví dụ như ListView

gồm danh sách tên sinh viên mà thôi. Nếu bạn muốn mỗi dòng ListView phức tạp

Page 168: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

168

hơn tức là gồm nhiều thành phần hơn thì nên dùng một mảng để giữ tất cả các ID

của các TextView trong. Từng cách làm sẽ được nói trong các phần sau.

I.1.1.3 Giới thiệu CursorAdapter

CursorAdapter là lớp Adapter lấy dữ liệu từ một Cursor ra một ListView.

Cursor phải có chứa tên định danh cho cột, bằng không nó sẽ không chạy.

I.1.1.4 Giới thiệu Simple Adapter

SimpleAdapter thì đúng như chữ simple – tức đơn giản. Nó là một Adapter

đơn giản và dễ hiểu để ánh xạ dữ liệu vào những View được định nghĩa trong một

tập tin XML. Bạn có thể chỉ rõ dữ liệu sẽ được đóng gói trong một danh sách như là

một ArrayList của việc ánh xạ. Mỗi phần tử trong ArrayList là một thể hiện của một

dòng trên ListView. Công việc ánh xạ này nó chứa dữ liệu cho mỗi dòng. Bạn cũng

có thể chỉ rõ một tập tin XML chứa nhiều điều khiển (widget) mà được dùng để thể

hiện một dòng và ta sẽ ánh xạ từng giá trị trong từng phần tử trong ArrayList sang

từng widget nằm trên từng dòng. Gắn dữ liệu vào các Views xảy ra trong 2 giao

đoạn. Sẽ được trình bày trong các phần sau.

Trong các phần tiếp theo của mục này, chúng tôi sẽ đi vào cách lập trình cho

Spinner, Gallery, ListView, GridView.

I.1.2 Dùng Adapter trên Spinner

I.1.2.1 Hình ảnh giới thiệu

Đây là một Spinner, so với bên C# nó gần giống như là một DropDownList

vậy.

Hình phụ lục 128 Hình minh họa cho một Spinner trong Android

Nhấp chọn vào thì sẽ hiện danh sách các phần tử cần thể hiện :

Page 169: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

169

Hình phụ lục 129 Danh sách lựa chọn khi nhấn vào Spinner

Hình ảnh và project mẫu có tên là HelloAdapter mà bạn có thể tham khảo

thêm.

I.1.2.2 Từng bước lập trình

Đương nhiên là phải có một Spinner trên giao diện rồi:

Hình phụ lục 130 Hình minh họa việc tạo Giao diện có chứa Spinner

Thiết lập mã lệnh Java theo từng bước sau:

Spinner s = (Spinner) findViewById(R.id.mySpinner);

ArrayAdapter Adapter = ArrayAdapter.createFromResource(this,

R.array.planets,

android.R.layout.simple_spinner_item);

Page 170: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

170

Adapter

.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_i

tem);

s.setAdapter(Adapter);

Có 3 bước chính là

Tạo thực thể Spinner.

Khai báo và thiết lập Adapter.

Gán Adapter vào spinner.

Đối với Spinner có thể dùng ArrayAdapter thì đủ để thể hiện dữ liệu lên

Spinner vì Spinner chỉ cho phép ta thể hiện chuỗi lên từng dòng của Spinner.

Ở đây, ta chú ý tới cách lập trình có phần “là lạ” ở đây là:

ArrayAdapter.createFromResource(this,

R.array.planets,

android.R.layout.simple_spinner_item);

Thay vì đưa vào một mảng chuỗi giá trị thì ta có thể dùng mảng giá trị đã

định nghĩa trong thư mục /values. Bạn có thể tham khảo thêm trong project mẫu

như đã nêu. Ngoài ra còn có android.R.layout.simple_spinner_item là một mẫu

giao diện spinner đã có sẵn của android và ta chỉ cần dùng lại. Bạn chú ý nếu tài

nguyên nào nằm trong thư mục /res của ứng dụng thì khi dùng chỉ cần R.xxx.yyy;

ngược lại nếu dùng tài nguyên sẵn có hệ điều hành android thì theo mô típ sau:

android.R.xxx.yyy.

I.1.2.3 Nhận xét

Về lí thuyết mà nói ta có thể dùng nhiều loại Adapter để phục vụ cho Spinner

nhưng theo kinh nghiệm chúng tôi thì ArrayAdapter thì thích hợp cho Spinner hơn.

I.1.3 Dùng Adapter trên Gallery

I.1.3.1 Hình ảnh giới thiệu

Đây là hình ảnh của một Gallery thể hiện danh sách hình ảnh:

Page 171: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

171

Hình phụ lục 131 Hình minh họa Gallery

Bạn có thể tham khảo thêm trong project mẫu HelloAdapter mục

HelloGallery.

I.1.3.2 Từng bước lập trình

Tạo giao diện như hình trên với mã lệnh XML:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

android:layout_width="fill_parent"

android:layout_height="fill_parent"

android:background="#ffffff">

<Gallery android:id="@+id/gallery"

android:layout_width="fill_parent"

android:layout_height="wrap_content" />

</LinearLayout>

Đơn giản ta chỉ cần một Gallery trên giao diện.

Sau đây là đoạn mã lệnh trên Java:

// tạo đối tượng gallery

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

// gắn gallery với một BaseAdapter

g.setAdapter(new ImageAdapter(this));

Page 172: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

172

Adapter ở đây là ImageAdapter do ta tạo thêm phục vụ nhu cầu Adapter cho

Gallery bởi vì chúng ta muốn làm cho Gallery đẹp hơn bởi các đường viền và mỗi

hình cách nhau nên ta viết lớp ImageAdapter từ BaseAdpter với hàm getView để

phục vụ cho việc thiết kế giao diện lại. Với đoạn mã lệnh như sau:

public Integer[] imageIDs = { R.drawable.gallery_photo_1,

R.drawable.gallery_photo_2, R.drawable.gallery_photo_3,

R.drawable.gallery_photo_4, R.drawable.gallery_photo_4,

R.drawable.gallery_photo_6, R.drawable.gallery_photo_7,

R.drawable.gallery_photo_8, };

public class ImageAdapter extends BaseAdapter {

int mGalleryItemBackground;

private Context mContext;

public ImageAdapter(Context c) {

mContext = c;

// See res/values/attrs.xml for the <declare-styleable>

that defines

// Gallery1.

TypedArray a =

obtainStyledAttributes(R.styleable.Gallery1);

mGalleryItemBackground = a.getResourceId(

R.styleable.Gallery1_android_galleryItemBackground, 0);

a.recycle();

}

public int getCount() {

return imageIDs.length;

}

public Object getItem(int position) {

return position;

}

public long getItemId(int position) {

return position;

Page 173: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

173

}

// set image and style for each item of the gallery

public View getView(int position, View convertView, ViewGroup

parent) {

ImageView i = new ImageView(mContext);

i.setImageResource(imageIDs[position]);

i.setLayoutParams(new Gallery.LayoutParams(150, 100));

i.setScaleType(ImageView.ScaleType.FIT_XY);

i.setBackgroundResource(mGalleryItemBackground);

return i;

}

}

Ta thấy trong lớp ImageAdapter có hàm getView, hàm này có công dụng

thiết kế tại phần giao diện theo ý chúng ta mà không dùng cái có sẵn từ android như

sửa màu sắc, canh lề, đường viền, …

I.1.3.3 Nhận xét

Với Gallery là do nhu cầu ta chỉnh sửa giao diện từng hình ảnh trên galery

theo ý mình như thay màu đường viền từng tấm hình, hay làm sáng tấm hình, …

nên ta sẽ dùng BaseAdapter cho nó để lợi dụng hàm getView để có thể làm chuyện

đó.

I.1.4 Dùng Adapter trên ListView cơ bản

I.1.4.1 Hình ảnh giới thiệu

Đây là hình giới thiệu màn hình ListView

Page 174: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

174

Hình phụ lục 132 Hình ảnh minh họa của một ListView

Với mỗi phần tử là một chuổi và đây là ListView dạng đơn giản.

I.1.4.2 Từng bước lập trình

Đầu tiên ta kéo vào một ListView vào giao diện với hình như sau:

Hình phụ lục 133 Minh họa việc tạo một List View

Mã lệnh trên Java như sau:

ListView myList = (ListView) findViewById(R.id.lv_myListView);

String[] listItems = new String[] { "List Item 1", "List Item 2",

"List Item 3", "List Item 4", "List Item 5", };

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

android.R.layout.simple_list_item_1, listItems);

myList.setAdapter(listItemAdapter);

Tương tự như Spinner ta dùng ArrayAdapter do nhìn chung danh sách thể

hiện giữa Spinner và ListView đơn giản thì gần như là giống nhau và chỉ khác nhau

về mặt thể hiện mà thôi. Cho nên nó cũng trải qua 3 bước:

Page 175: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

175

Tạo thực thể listView.

Khai báo và thiết lập dữ liệu và Adapter cho ListView.

Thiết lập Adapter cho ListView.

Để tận dụng lại phần giao diện layout sẵn có của android ta dùng

android.R.layout.simple_list_item_1 để định nghĩa giao diện thể hiện cho từng

dòng trên ListView.

I.1.4.3 Nhận xét

Đối với ListView đơn giản thì ta chỉ cần dùng ArrayAdapter mà thôi vì nó có

danh sách các giá trị cần thể hiện lên màn hình với mỗi phần tử là một giá trị dạng

số và chữ.

I.1.5 Dùng Adapter trên ListView nâng cao

I.1.5.1 Hình ảnh giới thiệu

Hình ảnh ListView nâng cao:

Hình phụ lục 134 Hình minh họa một Custom ListView

Trên mỗi dòng có nhiều TextView thể hiện chuỗi kí tự.

I.1.5.2 Từng bước lập trình

Page 176: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

176

Đầu tiên ta phải tạo khung mẫu giao diện cho từng dòng trong listView.

Từng mẫu có nhiều TextView sẽ là nơi thể hiện thông tin lên ListView.

Hình phụ lục 135 Hình minh họa cách thức làm một custom row cho một ListView

Sau đó cũng như ListView đơn giản là cũng cần có một ListView trên giao

diện chính:

Hình phụ lục 136 Hình minh họa cách thức làm một ListView

Sau đây là đoạn mã lệnh Java:

ListView myList = (ListView)

findViewById(R.id.lv_myListView);

// tạo liên kết với custom row

String[] mFrom = { "Chuoi_1", "Chuoi_2" };

int[] mTo = { R.id.tv_myTextView_row1,

R.id.tv_myTextView_row2 };

List<HashMap<String, String>> mAdapterData = new

ArrayList<HashMap<String, String>>();

// tạo dữ liệu

HashMap<String, String> item = new HashMap<String, String>();

item.put("Chuoi_1", "Custom Row 1");

item.put("Chuoi_2", "Custom Row 1.1");

mAdapterData.add(item);

item = new HashMap<String, String>();

item.put("Chuoi_1", "Custom Row 2");

item.put("Chuoi_2", "Custom Row 2.1");

Page 177: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

177

mAdapterData.add(item);

item = new HashMap<String, String>();

item.put("Chuoi_1", "Custom Row 3");

item.put("Chuoi_2", "Custom Row 3.1");

mAdapterData.add(item);

// gắn dữ liệu vào list

SimpleAdapter simpleAdapter = new SimpleAdapter(this,

mAdapterData,

R.layout.hello_customlistView_row, mFrom, mTo);

myList.setAdapter(simpleAdapter);

Ta để ý ở đây là cũng có 3 giao đoạn chính:

Tạo thực thể ListView để dễ quản lí là ListView myList.

Thiết lập chế độ ánh xạ bằng tên đại diện bằng 2 mảng 1 chiều

String[] mFrom và int[] mTo . Bằng cơ chế ánh xạ tên đó ta tạo dữ liệu

thông qua một HashMap<String,String> và thêm HashMap đó vào một danh

sách dữ liệu List<HashMap<String,String>>.

Gắn danh sách đó vào trong setAdapter.

I.1.5.3 Nhận xét

Theo như trong tài liệu của developer.android.com hướng dẫn nói là

SimpleAdapter có thể để từng hình ảnh lên SimpleAdapter được nhưng theo

chúng tôi tìm hiểu thì chúng ta phải tạo một lớp mà dẫn xuất từ lớp

SimpleAdapter để tái sử dụng lại hàm setViewImage của nó. Trong bài demo

chính thức của chúng tôi thì chúng tôi có sử dụng lớp dẫn xuất từ lớp

SimpleAdapter trong Activity ManHinhDanhSachHangHoa.Java và trong đó có đối

tượng thuộc kiểu HangHoasimpleAdapter.Java trong com.Adapter.

I.1.6 Dùng Adapter trên GridView cơ bản

I.1.6.1 Hình ảnh giới thiệu

Đây là một GridView cơ bản:

Page 178: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

178

Hình phụ lục 137 Hình ảnh minh họa một GridView đơn giản

Ta thấy chỉ đơn giản là hiện một tập hợp các giá trị trên màn hình.

I.1.6.2 Từng bước lập trình

Ta thiết kế màn hình giao diện thể hiện như sau:

Hình phụ lục 138 Cách thưc tạo một GridView

Kế đến thiết kế mã lệnh Java như sau:

public class Adapter_BasicGridView extends Activity {

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

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.hello_basicgridView);

Page 179: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

179

GridView myGrid = (GridView)

findViewById(R.id.grv_myGridView);

String[] gridItems = new String[] { "Grid Item 1", "Grid Item

2",

"Grid Item 3", "Grid Item 4", "Grid Item 5", };

ArrayAdapter<String> listItemAdapter = new

ArrayAdapter<String>(this,

android.R.layout.simple_list_item_1, gridItems);

myGrid.setAdapter(listItemAdapter);

}

}

Ta chú ý ở đây do các phần tử thể hiện khá đơn giản là chỉ đơn thuần là các

chuỗi dữ liệu nên ta chỉ cần dùng ArrayAdapter thôi là đủ cho nên cách thức thiết

lập gần như giống Spinner và ListView cơ bản.

I.1.6.3 Nhận xét

Nếu GridView thể hiện dạng các mục chọn chỉ có chuỗi thông thường thì

nhìn chung nó rất dễ. Nhưng thông thường GridView không chỉ đơn giản thể hiện

như vậy mà còn có thêm hình ảnh và chuỗi đi kèm thì lúc đó GridView đã có phần

phức tạp. Hay chỉ đơn giản như là một nhóm TextView trên 1 phần tử của

GridView như ListView dạng nâng cao chẳng hạn. Chúng tôi sẽ trình bày trong

phần sau với GridView có mỗi phần tử là một nhóm các chuỗi riêng biệt.

I.1.7 Dùng Adapter trên GridView nâng cao

I.1.7.1 Hình ảnh giới thiệu

Hình ảnh của GridView nâng cao cũng như ListView về mặt bản chất từng

phần tử:

Page 180: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

180

Hình phụ lục 139 Hình ảnh minh họa một Custom GridView

I.1.7.2 Từng bước lập trình

Tạo một tập tin XML để qui định giao diện của từng phần tử nằm trong

GridView:

Hình phụ lục 140 Cách thức tạo một Custom Item cho một Grid View

Sau đó thiết kế một giao diện chứa GridView như GridView cơ bản:

Hình phụ lục 141 Hình minh họa cách thức tạo một GridView

Page 181: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

181

Tiếp đến là thiết kế mã lệnh Java, nếu tinh ý ta sẽ suy luận rằng mã lệnh Java

của GridView nâng cao này sẽ gần giống như ListView nâng cao như đã trình bày ở

trên vậy vì bản chất là nó giống nhau trên từng phần tử:

public class Adapter_CustomGridView extends Activity {

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

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.hello_customgridView);

GridView myGrid = (GridView)

findViewById(R.id.grv_myGridView);

// tạo liên kết với custom row

String[] mFrom = { "Chuoi_1", "Chuoi_2" };

int[] mTo = { R.id.tv_myTextView_row1,

R.id.tv_myTextView_row2 };

List<HashMap<String, String>> mAdapterData = new

ArrayList<HashMap<String, String>>();

// tạo dữ liệu

HashMap<String, String> item = new HashMap<String, String>();

item.put("Chuoi_1", "Custom Row 1");

item.put("Chuoi_2", "Custom Row 1.1");

mAdapterData.add(item);

item = new HashMap<String, String>();

item.put("Chuoi_1", "Custom Row 2");

item.put("Chuoi_2", "Custom Row 2.1");

mAdapterData.add(item);

item = new HashMap<String, String>();

item.put("Chuoi_1", "Custom Row 3");

item.put("Chuoi_2", "Custom Row 3.1");

mAdapterData.add(item);

Page 182: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

182

// gắn dữ liệu vào list

SimpleAdapter simpleAdapter = new SimpleAdapter(this,

mAdapterData,

R.layout.hello_customgridView_row, mFrom, mTo);

myGrid.setAdapter(simpleAdapter);

}

}

I.1.7.3 Nhận xét

Thực tế mà nói, nhu cầu GridView thật tế rất phong phú và đa dạng, trên chỉ

là nâng cao dạng cơ bản mà thôi, thực tế, GridView đòi hỏi cao như từng phần tử là

một tấm hình và bên dưới có một chuỗi mô tả tên tấm hình và có một hình nền đẹp

khi người dùng tác động vào, … Với mô típ đó, chúng tôi đã làm trong chương

trình ứng dụng thực tế ở Activity ManHinhHeThongSieuThi.Java mà trong đó có

thực thể viết từ lớp HeThongSieuThiAdapter.Java mà dẫn xuất từ lớp BaseAdapter.

Các bạn có thể tham khảo thêm trong chương trình đó.

I.1.8 Kinh nghiệm lập trình với Adapter

Theo kinh nghiệm chúng tôi, việc chọn kiểu Adapter nào cho Spinner,

Gallery, ListView và GridView thì tùy thuộc vào thực tế bài toán của các bạn.

Nhưng chung qui lại chúng tôi có những nhận xét đơn giản như sau:

Đối với Spinner, ListView đơn giản, GridView đơn giản: dữ liệu trên

từng phần tử dạng đơn giản thì chỉ cần ArrayAdapter<T> là đủ để lập trình

thể hiện nội dung với chúng.

ListView nâng cao và GridView nâng cao chỉ chứa nhiều hơn một

TextView thì ta có thể dùng SimpleAdapter để ánh xạ từ dữ liệu thật qua

giao diện.

ListView và GridView có chứa hình ảnh trong đó thì ta nên dùng

SimpleAdapter nhưng phải viết lại một lớp dẫn xuất từ SimpleAdapter và

thiết kế lại hàm public void setViewImage(final ImageView image, final

String value) để gán hình vào từng phần tử trên giao diện.

Page 183: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

183

Cũng như trên, nếu với hình ảnh phức tạp hơn thì ta cũng có thể dùng

BaseAdapter để viết lại thiết kế Adapter phù hợp cho riêng nhu cầu của

mình. Việc dùng BaseAdapter sẽ phức tạp hơn so với SimpleAdapter nhưng

nếu sử dụng quen thì nó sẽ không còn là vấn đề khó khăn nữa. Nói hung,

BaseAdapter là lớp Adapter cơ sở có thể tùy biến theo nhiều loại giao diện

mà các Adapter kia không đáp ứng được.

I.2 Lập trình với hoạt cảnh chuyển động (Animation)

I.2.1 Giới thiệu lập trình với Animation

Nhìn chung, lập trình Animation trên Android có hai hướng đi là:

Hướng 1: Tạo và qui định sẵn hoạt cảnh chuyển động trong tập tin

XML và áp dụng tập tin XML đó vào đối tượng cần được thực thi hoạt cảnh.

Hướng 2: Dùng mã lệnh Java qui định hoạt cảnh chuyển động của đối

tượng. Tùy theo từng hoàn cảnh mà ta áp dụng.

Theo chúng tôi, nếu thuần thục với XML thì nên dùng cách 1 để tạo sẵn hoạt

cảnh chuyển động, vả lại tất cả đều có công cụ hỗ trợ khi lập trình hoạt cảnh chuyển

động cho XML:

Hình phụ lục 142 Tập tin quy định hoạt cảnh chuyển động

Page 184: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

184

Hình phụ lục 143 Hình ảnh minh họa sự hỗ trợ của Eclipse giúp tạo hiệu ứng hoạt cảnh

Ta có thể thêm, xóa và hiệu đính lại thuộc tính chuyển động nhờ vào ADT

hỗ trợ. Trong khi đó, theo hướng 2 thì ta phải dùng các đoạn mã lệnh Java và theo

một mặt nào đó nó sẽ chiếm bộ nhớ nhiều hơn do nó phải tạo ra các thực thể để

quản lí việc chuyển động trên mã lệnh Java.

Đi theo 2 hướng là vậy; thêm vào đó lập trình hoạt cảnh chuyển động phân

làm 2 dạng gọi là TweenedAnimation và FrameByFrameAnimation. Hai dạng này

sử dụng trong những hoàn cảnh khác nhau. Ta sẽ đi qua từng dạng trong các mục

tiếp theo.

I.2.2 Lập trình với TweenAnimation

Đầu tiên, ta thiết kế một màn hình chung để áp dụng hoạt cảnh chuyển động

lần lượt theo từng cách XML và Java như sau:

Page 185: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

185

Hình phụ lục 144 Hình minh họa cho Tweened Animation

I.2.2.1 Lập trình bằng XML

Ta thiết kế tập tin Java scaler.xml trong thư mục /res/anim như sau:

<set xmlns:android="http://schemas.android.com/apk/res/android"

android:interpolator="@android:anim/accelerate_interpolator">

<scale android:fromXScale="0.5" android:toXScale="2.0"

android:fromYScale="0.5" android:toYScale="2.0"

android:pivotX="50%"

android:pivotY="50%" android:startOffset="700"

android:duration="400"

android:fillBefore="false" />

</set>

Hay chúng ta dùng công cụ hỗ trợ sẵn có để thiết kế hoạt cảnh chuyển động

như sau:

Page 186: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

186

Hình phụ lục 145 Công cụ hỗ trợ thiết kế hoạt cảnh từ Eclipse

Bạn có thể tìm hiểu cách thức hiệu chỉnh trong các tập tin hướng dẫn android

trong phần tài liệu tham khảo của chúng tôi hoặc có thể tìm hiểu trên các diễn đàn

Android.

Sau đó áp dụng tập tin trên vào đối tượng cần thể hiện:

// ====================================

// nạp animation từ XML

// ====================================

AnalogClock testAnalogClockAnim = (AnalogClock)

findViewById(R.id.AnalogClock);

testAnalogClockAnim.setAnimation(AnimationUtils.loadAnimation(this,

R.anim.scaler));

Theo như chúng tôi, nếu hiệu ứng hoạt cảnh chuyển động quá phức tạp và

cần đi theo một trình tự với một luật cho trước bởi một hàm số hay đại loại vậy thì

mới cần thiết lập chúng bằng mã lệnh Java còn nếu không thì một tập tin XML qui

định hoạt cảnh chuyển động thông thường thì đã là đủ.

I.2.2.2 Lập trình bằng mã lệnh Java

Khác với phần trên, tất cả các qui định chuyển động được viết bằng mã lệnh

Java như sau:

Page 187: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

187

// ====================================

// nạp animation thông qua code Java

// ====================================

// Create root AnimationSet

AnalogClock testAnalogClockAnim = (AnalogClock)

findViewById(R.id.AnalogClock);

AnimationSet rootSet = new AnimationSet(true);

rootSet.setInterpolator(new AccelerateInterpolator());

// Create ScaleAnimation

ScaleAnimation scaleAnim = new ScaleAnimation(0.5F, 2.0F,

0.5F, 2.0F,

0.5F, 0.5F);

rootSet.setDuration(400);

rootSet.setFillBefore(false);

rootSet.setStartOffset(700);

rootSet.addAnimation(scaleAnim);

// gán Animation

testAnalogClockAnim.startAnimation(rootSet);

Bạn có thể tìm hiểu thêm về các phương thức thiết lập hoạt cảnh chuyển

động trong các tài liệu Android đi kèm với phụ lục này. Nhưng nhìn chung nó theo

mô típ như sau:

Tạo một thực thể hoạt cảnh chuyển động gốc. Thực thể này là trung

tâm của mọi hoạt cảnh chuyển động.

Thiết lập các thuộc tính cần thiết như thời lượng, vị trí, …

Ngoài ra, ta có thể thêm các dạng hoạt cảnh khác vào hoạt cảnh gốc

để thực thi trên cùng 1 đối tượng như ScaleAnimation là hoạt cảnh phóng to

chẳng hạn. Nó được thêm vào thực thể hoạt cảnh gốc.

Sau cùng là khởi động hoạt cảnh chuyển động cho đối tượng bằng

phương thức startAnimation với tham số đầu vào là thực thể hoạt cảnh

chuyển động gốc.

I.2.2.3 Kinh nghiệm lập trình với TweenedAnimation

Tweened animation thường được dùng phổ biến cho:

Page 188: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

188

Sự chuyển tiếp giữa các Activity.

Sự chuyển tiếp giữa các khung chứa (layout) bên trong một Activity.

Cung cấp lại sự phản hồi cho người dùng như “rung” một ô nhập liệu

để báo cho người dùng biết dữ liệu nhập sai.

Tweened animation được tạo bằng cách sử dụng lớp Animation. Và có các

loại lớp animation sau:

Lớp AlphaAnimation: điều chỉnh mức độmàu alpha của một đối

tượng.

Lớp RotateAnimation: điều chỉnhhoạt cảnh xoay của một đối tượng.

Lớp ScaleAnimation: điều chỉnh sự phóng to hay thu nhỏ của một đối

tượng.

Lớp TranslateAnimation: điều chỉnh vị trí của một đối tượng.

Tweened animation thường được định nghĩa trong một tập tin XML và được

đặt trong thư mục /res/anim của một project Android và được gọi thông qua

AnimationUtils. Ta có thể gán Tweened animation cho các View thông qua

setAnimation(). Trong khi đó, Tweened animation cũng được thiết lập bằng mã

lệnh Java. Trong bảng so sánh dưới đây, chúng tôi so sánh sự tương quan giữa lập

trình bằng mã lệnh XML với lập trình bằng Java.

Tên Thuộc tính

xml

Hàm Java Mô tả

Start time android:

startOffset

Animation.

setStartOffset()

(hoặc

setStartTime())

Thời gian bắt đầu một

Animation, tính bằng mili

giây. 0 mili giây là chế độ

mặc định.

Duration android:

Duration

Animation.

setDuration() Khoảng thời gian thực hiên

của Animation.

Fill before android:

fillBefore

Animation.

setFillBefore() True nếu muốn Animation

Page 189: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

189

thực hiên đầu tiên.

Fill after android:

fillAfter

Animation.

SetFillAfter() True nếu muốn Animation

thực hiện sau 1 Animation

khác.

Interpolator android:

interpolator

Animation.

SetInterpolator() Gồm :

AccelerateInterpolator :

Animation bắt đầu với tốc

độ chậm và nhanh dần lên.

DecelerateInterpolator :

Animation bắt đầu với tộc

độ nhanh và chậm dần.

Bảng 2 Bảng so sánh thuộc tính tạo hiệu ứng chuyển động bằng XMl so với Java

(Bảng tham khảo từ Khóa luận 2008 “Nghiên cứu và xây dựng từ điển trên G-Phone” của Tô

Xuân Khôi Nguyên và Đoàn Chánh Thức)

I.2.3 Lập trình với FrameByFrameAnimation

Trong Android không hỗ trợ hình ảnh động dạng GIF, vì vậy việc thể hiện

hình ảnh theo dạng nối tiếp từng ảnh liên tục là một điều khó khăn. Frame-by-frame

animation có thể giải quyết được khó khăn trên bằng cách nạp tuần tự một chuỗi

hình ảnh lên trên nền một View (thông thường ứng dụng trên ImageView). Việc tạo

frame-by-frame animation có thể được thực hiện dễ dàng thông qua một tập tin

XML (tập tin này được đặt trong thư mục /res/anim của một project Android).

Frame-by-frame animation được tạo và quản lý bởi lớp AnimationDrawable, một

AnimationDrawable được định nghĩa trong tập tin XML chứa một phần tử

<animation-list>và một loạt các thành phần con được định nghĩa bằng thẻ <item>,

mỗi thành phần con này định nghĩa một khung ảnh cho frame animation như ví dụ

bên dưới.

<animation-listandroid:id="selected"android:oneshot="false">

<itemandroid:drawable="@drawable/wheel"android:duration="50"/>

Page 190: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

190

<itemandroid:drawable="@drawable/whee2"android:duration="50"/>

</animation-list>

Các thuộc tính trên tập tin XML cần quan tâm khi tạo animation dạng frame-

by-frame:

Tên Ý nghĩa

android:drawable Chỉ tới một ảnh nằm trong tài nguyên

của chương trình.

android:duration Khoảng thời gian (tính bằng mili giây)

dành cho việc hiển thị một khung ảnh.

android:oneshot Nếu thiết lậptrue, hiệu ứng hình ảnh sẽ

được thực hiện một lần rồi thôi và

ngược lại.

android:visible Quy định trạng thái nhìn thấy ban đầu

của một ảnh(initial visibility state), giá

trị mặc định là false.

Bảng 3 Các thuộc tính cần quan tâm khi tạo hiệu ứng Frame-by-frame animation

Ví dụ minh họa hình ảnh một thước phim về một quả banh nẩy lên nẩy

xuống dùng Frame-by-frame animation

Hình phụ lục 146 Hình minh họa một Frame-by-frame animation đơn giản

Page 191: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

191

Tạo animation (tập tin framebyframe.xml được đặt trong thư mục

/res/anim của project Android)

<?xmlversion="1.0"encoding="utf-8"?>

<animation-listxmlns:android="http://schemas.android.com/apk/res/android"

id="selected"android:oneshot="false">

<itemandroid:drawable="@drawable/ball1"android:duration="50"/>

<itemandroid:drawable="@drawable/ball2"android:duration="50"/>

<itemandroid:drawable="@drawable/ball3"android:duration="50"/>

<itemandroid:drawable="@drawable/ball4"android:duration="50"/>

<itemandroid:drawable="@drawable/ball5"android:duration="50"/>

<itemandroid:drawable="@drawable/ball6"android:duration="50"/>

</animation-list>

Gọi thực thi animation

// Load the ImageView that will host the animation and

// set its background to our AnimationDrawable XML resource.

ImageView imvHinhDong = (ImageView)

findViewById(R.id.imv_HinhDong);

imvHinhDong.setBackgroundResource(R.anim.framebyframe);

// Get the background, which has been compiled to an

// AnimationDrawable object.

AnimationDrawableballAnimation = (AnimationDrawable)

imvHinhDong.getBackground();

// Start animation

ballAnimation.start();

Một điều lưu ý quan trọng là phương thức start() được gọi trong

AnimationDrawable sẽ không được thực hiện trong suốt phương thức onCreate()

của Activity, bởi vì AnimationDrawable chưa thực sự được nạp đầy đủ.

I.3 Lập trình với Media

I.3.1 Giới thiệu

Việc hỗ trợ và phát media là một điều hết sức thiết yếu trên một chiếc điện

thoại thông minh và Android không thể thiếu đi phần hỗ trợ media này. Chính vì

Page 192: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

192

vậy mà Android được tích hợp sẵn bộ đọc và ghi cho nhiều loại định dạng media

(xem bảng liệt kê bên dưới), vì thế mà ta có thể dễ dàng tích hợp âm thanh, hình

ảnh, video vào trong ứng dụng một cách dễ dàng.

Kiểu Định dạng Ghi Đọc Loại tập tin hỗ trợ

Audio

AAC LC/LTP

x 3GPP (.3gp) và MPEG-4

(.mp4, .m4a). Không hỗ trợ

AAC (.aac)

HE-AACv1

(AAC+) x

HE-AACv2

(enhanced

AAC+)

x

AMR-NB x x 3GPP (.3gp)

AMR-WB

x 3GPP (.3gp)

MP3

x MP3 (.mp3)

MIDI

x .mid

Ogg Vorbis

x Ogg (.ogg)

PCM/WAVE

x WAVE (.wav)

Image

JPEG x x JPEG (.jpg)

GIF

x GIF (.gif)

PNG

x PNG (.png)

BMP

x BMP (.bmp)

Video

H.263 x x

3GPP (.3gp) và MPEG-4

(.mp4)

H.264 AVC

x

3GPP (.3gp) và MPEG-4

(.mp4)

MPEG-4 SP

x 3GPP (.3gp)

Bảng 4 Các loại định dạng media mà Android hỗ trợ

Android hỗ trợ việc phát âm thanh, video từ nhiều nguồn khác nhau chẳng

hạn như tập tin âm thanh nằm trong tài nguyên của chương trình (trong thư mục

/res/raw), tập tin nằm trong hệ thống (thẻ nhớ) hay tập tin trên mạng. Để nắm bắt

Page 193: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

193

được cách phát media trên Android ta tiến hành tìm hiểu các ví dụ đơn giản ở các

phần sẽ đề cập ngay sau đây.

I.3.2 Lập trình phát âm thanh trên Android

Việc phát âm thanh trên Android được thực hiện thông qua ngõ ra tiêu chuẩn

của thiết bị (loa hoặc tai nghe Bluetooth). Một lưu ý là Android không hỗ trợ phát

âm thanh trong lúc gọi điện đàm thoại.

Cách thức phát âm thanh từ tài nguyên của chương trình:

Chép âm thanh vào trong thư mục /res/raw của project.

Tạo một thể hiện của lớp MediaPlayer, chỉ dẫn đến tập tin âm thanh

thông qua MediaPlayer.create(…). Dùng start() để bắt đầu phát âm thanh.

Đoạn mã minh họa cho việc phát âm thanh:

MediaPlayer mp = MediaPlayer.create(context, R.raw.sound_file_1);

mp.start();

Cách thức phát âm thanh từ file bên ngoài:

Tạo một thể hiện của lớp MediaPlayer dùng new.

Gọi setDataSource(duong_dan_den_file).

Lưu ý là phải thực thi prepare() trước khi chạy start()

Đoạn mã minh họa:

MediaPlayer mp = new MediaPlayer();

mp.setDataSource(DUONG_DAN_TOI_FILE);

mp.prepare();

mp.start();

DUONG_DAN_TOI_FILE có thể là đường dẫn tới tập tin nằm trong tài

nguyên chương trình hoặc tập tin nằm trong thẻ nhớ hoặc tập tin nằm trên mạng.

I.3.3 Lập trình phát Video trên Android

Việc phát video có phần phức tạp hơn việc phát âm thanh trên Android, ta có

thể dùng lớp MediaPlayer để phát video trong Android tuy nhiênviệc dùng lớp này

không được thuận tiện và có phần khó khăn. Bên cạnh đó Android hỗ trợ một View

Page 194: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

194

đặc biệt để phát video được gọi là VideoView nên ta sẽ dùng VideoView này để

phát video.

Để phát video, điều trước tiên phải làm là thêm vào widget VideoView vào

trong ứng dụng, sau đó chỉ ra đường dẫn tới tập tin video mà Android hỗ trợ và cuối

dùng là phát video thông qua phương thức start()

VideoView videoView = (VideoView) findViewById(R.id.testVideoView);

videoView.setVideoURI(Uri.parse("file:///sdcard/test.mp4"));

videoView.start();

Khi gán đường dẫn tới tập tin video ta dùng setVideoPath() cho các tập tin

nằm trên máy (đường dẫn vật lý) và dùng setVideoURI() cho các tập tin nằm trên

mạng.

Ngoài ra ta cũng có thể thêm vào ứng dụng một bộ MediaController (như

hình minh họa bên dưới) để thuận tiện hơn cho việc phát video.

Hình phụ lục 147 Hình ảnh một bộ MediaController hỗ trợ việc phát Video tốt hơn

// add media controller to your app

MediaController mc = new MediaController(this);

videoView.setMediaController(mc);

I.3.4 Nhận xét

Khi phát một tập tin âm thanh hoặc video nằm trên mạng ta cần gán quyền

truy cập được mạng Internet cho ứng dụng nằm trong tập tin AndroidManifest.xml

như sau <uses-permissionandroid:name="android.permission.INTERNET"/> và tập

tin âm thanh, video này có khả năng tải về được.

Khi lập trình phát media ta nên dùng các bẫy lỗi như

IllegalArgumentException và IOException để tránh các lỗi không mong muốn như

không tồn tại tập tin…

Page 195: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

195

Một khi đã gán nguồn dữ liệu cho lớp MediaPlayer, ta không thể tự động

thay đổi sang một nguồn dữ liệu khác. Để làm được điều này ta phải tạo một lớp

MediaPlayer mới hoặc gọi phương thức reset() để khởi chạy lại chương trình phát.

Mỗi một lớp MediaPlayer khi chạy đều chạy trên một luồng (thread) do thế lời

khuyên khi dùng lớp này là nên gọi phương thức release() khi đã hoàn tất việc phát

âm thanh hoặc video. Nếu dùng VideoView để phát video thì ta không cần quan

tâm đến điều này do VideoView có cơ chế tự thực hiện khi phát xong.

I.4 Lập trình với thao tác Telephony

I.4.1 Giới thiệu

Một trong những thành phần cơ bản mà không kém phần quan trọng trong

Android là điện thoại (mobile phone). Các chức năng quay số điện thoại, nhận cuộc

gọi, gửi và nhận tin nhắn… đều có thể dễ dàng sử dụng, kết hợp các chức năng lại

với nhau và cũng có thể nhúng chúng vào trong ứng dụng một cách linh hoạt.

Để có thể dùng được các chức năng điện thoại của Android, hầu hết ta đều

phải thực hiện xin quyền truy cập đến các chức năng của điện thoại như gọi điện,

gửi tin nhắn… thông qua AndroidManifest.xml. Và để nắm bắt được các thao tác

đơn giản với điện thoại, ta tiến hành tìm hiểu và phân tích các ví dụ bên dưới như

gọi điện thoại tới một số cho trước, gửi tin nhắn SMS, rung điện thoại.

I.4.2 Thực hiện gọi điện thoại tới một số cho trước

Để thực hiện gọi điện thoại tới một số điện thoại cho trước ta có hai cách

dùng thông qua cách gọi Intent:

Intent.ACTION_CALL: tự động bắt đầu cuộc gọi và hiển thị quá trình

gọi điện thoại. Và ứng dụng gọi Intent loại này sẽ phải thực hiện xin phép

thực hiện cuộc gọi trong AndroidManifest.xml

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

Page 196: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

196

Hình phụ lục 148 Hình minh họa việc gọi điện dùng ACTION.CALL

Intent.ACTION_DIAL: hành động này sẽ trực tiếp gọi ứng dụng quay

số điện thoại và số điện thoại cần gọi sẽ được gán lên trên ứng dụng quay số.

Người dùng muốn thực hiện cuộc gọi thì phải nhấn nút gọi điện thoại. Ứng

dụng gọi Intent loại này không yêu cầu phải thực hiện xin phép gọi điện

thoại.

Hình phụ lục 149 Hình minh họa việc gọi điện dùng ACTION.DIAL

Cả hai cách gọi Intent trên đều yêu cầu đầu vào là một số điện thoại theo

định dạng là "tel:1234567". Sau đây là mã lệnh Java để thực hiện gọi điện thoại:

Intent intent = new Intent(Intent.ACTION_CALL, Uri

Page 197: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

197

.parse("tel:1234567"));

startActivity(intent);

hoặc

Intent intent = new Intent(Intent.ACTION_DIAL, Uri

.parse("tel:1234567"));

startActivity(intent);

I.4.3 Thực hiện gửi tin nhắn SMS

Tin nhắn SMS (Short Message Service) rất đỗi phổ biến và có tầm quan

trọng trong sự truyền thông giữa các thiết bị mobile.

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

Ta thiết lập permission trong Androidmanifest.xml để qui định chương trình

có được phép dùng tính năng SMS.

SMS cũng gần giống như phần gọi điện thoại ở trên có 2 hình thức là gửi

thẳng đến số chỉ định mà không cần thông qua màn hình gửi tin nhắn và mở màn

hình gửi tin nhắn với số và nội dung đầu vào.

I.4.3.1 Gửi SMS thẳng và không cần màn hình

sendSmsMessage(phoneNum.getText().toString(),// số điện thoại cần gửi

textMess.getText().toString() // nội dung cần gửi

);

Ta chỉ cần một phương thức sendSmsMessage thôi thế là đủ

I.4.3.2 Gửi tin nhắn với màn hình SMS

Có 2 cách mở màn hình sendSMS như sau:

Cách 1:

Intent sendIntent = new Intent(Intent.ACTION_VIEW);

sendIntent.putExtra("address", "0976188622");

sendIntent.putExtra("sms_body", "Võ Thành Nhật (07HC102) – Phan Thành

Trung (07HC167)");

sendIntent.setType("vnd.android-dir/mms-sms");

startActivity(sendIntent);

Cách 2: cũng tương tự như trên nhưng với ACTION khác

Page 198: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

198

Intent sendIntent = new Intent(Intent.ACTION_SENDTO,

Uri.parse("sms://"));

sendIntent.putExtra("address", "0919816456");

sendIntent.putExtra("sms_body", "Nhật – Trung");

startActivity(sendIntent);

Nói chung, 2 cách tương tự nhau nhưng phần đầu ta qui định Intent bằng

setType là mms và sms có nghĩa là có thể gửi bằng tin nhắn đa phương tiện hoặc tin

nhắn dạng chuỗi thông thường. Còn cách 2 thì chỉ có thể gửi bằng SMS mà thôi.

I.4.4 Thực hiện chức năng rung điện thoại

Thực hiện chức năng rung điện thoại cũng phải cần permission trong

AndroidManifest.xml:

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

Ta ghi đoạn mã lệnh Java sau để thực hiện việc rung điện thoại:

Vibrator vibarte = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);

// 1. Cho rung khoảng 1 giây

long milliseconds = 1000;

vibarte.vibrate(milliseconds);

Ngoài ra, ta có thể kết hợp hài hỏa khoảng thời gian cho rung và hàm rung

vibrate có thể tạo ra các nhịp điệu rung lạ và phù hợp với từng ngữ cảnh và thời

điểm khác nhau. Ví dụ như tùy theo từng người khác nhau mà có cách run khác

nhau.

I.5 Lập trình với luồng (Thread)

I.5.1 Giới thiệu luồng

Luồng là đơn vị nhỏ nhất của xử lí đồng thời. Nhiều luồng có thể chạy trong

cùng một tiến trình và chia sẻ tài nguyên bộ nhớ mà tiến trình đó có. Trên một tiến

trình của một ứng dụng có một luồng chính (main thread) và nhiều luồng khác

(thread-xx). Tất cả chúng chạy song hành với nhau và thực thi những nhiệm vụ

khác nhau và có thể liên lạc với nhau.

Page 199: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

199

Hình phụ lục 150 Hình minh họa tiến trình và luồng

Các mặt mạnh của luồng:

Luồng chia sẻ tài nguyên tiến trình với nhau nhưng chúng chạy độc

lập.

Nói chung, ứng dụng luôn chạy để hồi đáp lại những thao tác của

người dùng, cho nên những hành động nào tốn thời gian thì sẽ được tách ra

thành một luồng và chạy ngầm phía bên dưới.

Các mặt yếu của luồng:

Việc lập trình cho nó gần như là hơi phức tạp.

Cần được xác nhận, tránh và giải quyết hiện tượng Deadlock. Ví dụ

như 2 luồng cùng chạy và cùng thao tác thay đổi giá trị một biến toàn cục thì

lúc đó có thể Deadlock sẽ xảy ra.

I.5.2 Các đặc tính và cách thức vận hành luồng

Trong một chương trình, luôn có một luồng chính và nhiều luồng chạy ngầm

khác. Các luồng này sẽ giao tiếp với nhau thông qua một Handler để quản lí danh

sách các tin nhắn yêu cầu xử lí những hành động được nạp sẵn trong Handler mà

với mỗi tin nhắn là một luồng nào đó gửi tới.

Page 200: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

200

Handler là lớp trung gian đứng chính giữa để quản lí các hành động mà các

luồng yêu cầu xử lí. Có nhiều Handler trong một ứng dụng, và một khi khai báo một

thực thể Handler trong ứng dụng thì nó sẽ đóng vai trò làm trung gian giữa luồng

chính (main thread) và các luồng phụ khác. Ví dụ dễ hiểu nhất là chúng ta không

thể sử dụng các thực thể giao diện như EditView, TextView, Button, … trong luồng

mà chỉ thao tác chúng trong Handler mà thôi.

I.5.3 Lập trình luồng

Lập trình luồng có 2 phương pháp: dùng Message và dùng Post.

I.5.3.1 Lập trình luồng dùng Messages

Hình phụ lục 151 Lập trình luồng dùng Message

Thông thường ta tạo một Thread đi kèm với một Handler. Thread sẽ gửi tin

nhắn lên Handler và Handler đóng vai trò kiểm tra tin nhắn là gì và làm những việc

tương ứng. Trong nội tại Thread không thể gọi và xử lí các đối tượng thuộc giao

diện cho nên ta phải thông qua một Handler để xử lí các đối tượng giao diện.

Trong một chương trình có nhiều Handler và có nhiều luồng, mỗi một luồng

có thể gửi tin nhắn đến nhiều Handler. Trong các Handler là nơi để xử lí các tác vụ

mà chúng ta cần.

Để gửi một Mesaage đến một Handler thì thông qua hàm obtainMessage() để

lấy nội dung tin nhắn và thông qua hàm sendMessage() để gửi tin nhắn đó đi đến

một Handler mà chạy hàm sendMeassage đó.

Page 201: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

201

Ta chú ý các phương thức sendMessage sau:

sendMessage(): gửi tin nhắn lên Handler ngay lập tức

sendMessageAtFrontOfQueue(): gửi tin nhắn lên Handler và tin nhắn

đó sẽ ưu tiên giải quyết trước.

sendMessageAtTime(): gửi tin nhắn vào thời điểm chỉ định trước.

sendMessageDelayed(): gửi tin nhắn vào Handler sau một khoảng thời

gian nhất định.

Chúng tôi đã làm một luồng với 2 Handler. Trong luồng ấy gửi tin nhắn đến

2 Handler và 2 Handler ấy sẽ xử lí các hành động trên giao diện mà luồng mong

muốn. Project mẫu đó lên là HelloThread với kịch bản là 1 Handler sẽ hiện cho

thanh chạy ngầm nhanh và một Handler cho thanh chạy nổi phía trên chậm để thấy

rõ một luồng qui định 2 Handler chạy với 2 dạng hành động khác nhau. Ví dụ như

hình sau:

Hình phụ lục 152 Hình minh họa lập trình luồng

Các bạn có thể tham khảo thêm.

I.5.3.2 Lập trình luồng dùng Post

Page 202: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

202

Hình phụ lục 153 Lập trình luồng dùng Post

Lập trình luồng với Post cũng gần giống như bằng Message. Trong chương

trình chính, ta tạo một luồng trong onCreate() và khởi động luồng đó. Ngoài ra tạo

thêm 3 biến private lần lượt là Handler myHandler, Runnable foregroundTask và

Runnable backgroundTask. Với foregroundTask là nơi thực thi các hành động chính

cần xử lí và backgroundTask là nơi kiểm tra các hành động nên dừng lúc nào.

I.6 Lập trình với thực đơn (Menu)

I.6.1 Giới thiệu thực đơn

Thực đơn có hai dạng trên Android là thực đơn thông thường xuất hiện khi ta

nhấn nút Menu trên điện thoại và thực đơn ngữ cảnh khi ta nhấn cà chọn lâu một

đối tượng nào đó.

Trên thực đơn thông thường và thực đơn ngữ cảnh ta thường thấy các đối

tượng sau:

Chuỗi

Biểu tượng.

Nút chọn Radio Button.

Nút chọn CheckBox.

Menu con.

Các phím short-cut.

Page 203: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

203

Hình phụ lục 154 Hình minh họa thực đơn của hệ thống

Còn phần thực đơn ngữ cảnh thì không đưa hình ảnh lên được như sau:

Hình phụ lục 155 Hình minh họa thực đơn ngữ cảnh

I.6.2 Cách thức lập trình

Page 204: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

204

Thực đơn có 2 cách thức lập trình bằng XML và bằng mã lệnh Java cũng

tương tự cách thức lập trình giao diện trong project HelloUI như đã trình bày trong

các phần trước. Sau đây là cách thức lập trình theo từng hướng theo 2 chủ đề.

I.6.2.1 Lập trình thực đơn lựa chọn chính

Thực đơn lựa chọn xuất hiện khi ta nhấn vào nút Menu trên thiết bị. Ta có

thể dùng 2 phương pháp là XML hoặc bằng mã lệnh Java.

Trong project HelloMenu có 2 phương pháp mã lệnh Java và bằng XML cho

một menu thông thường.

Hình phụ lục 156 Hình minh họa tạo menu bằng

mã lệnh Java

Hình phụ lục 157 Hình minh họa tạo menu bằng

XML

Với cách tạo menu bằng mã lệnh Java ta làm như đoạn mã lệnh sau:

// tạo menu cho chương trình

@Override

public boolean onCreateOptionsMenu(Menu menu) {

super.onCreateOptionsMenu(menu);

MenuItem mMenuItem;

// tạo menu item

mMenuItem = menu.add(Menu.NONE, // group

Page 205: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

205

0, // item ID

Menu.NONE, // order

"Menu 1"); // title

// gán icon cho một menu item

mMenuItem.setIcon(R.drawable.icon);

mMenuItem = menu.add(Menu.NONE, 1, Menu.NONE, "Menu 2");

mMenuItem.setIcon(R.drawable.exit);

mMenuItem = menu.add(Menu.NONE, 2, Menu.NONE, "Menu 3");

mMenuItem.setIcon(R.drawable.icon);

// // tạo sub menu

// SubMenu subMenu = menu.addSubMenu("Test SubMenu");

// subMenu.add(Menu.NONE, 3, Menu.NONE, "Sub Menu Item 1");

// subMenu.add(Menu.NONE, 4, Menu.NONE, "Sub Menu Item 2");

return true;

}

// gán sự kiện khi nhấn menu

@Override

public boolean onOptionsItemSelected(MenuItem item) {

super.onOptionsItemSelected(item);

switch (item.getItemId()) {

case 0:

Toast.makeText(this, "Menu 1 Clicked!",

Toast.LENGTH_SHORT).show();

break;

case 1:

Toast.makeText(this, "Menu 2 Clicked!",

Toast.LENGTH_SHORT).show();

break;

case 2:

Toast.makeText(this, "Menu 3 Clicked!",

Toast.LENGTH_SHORT).show();

break;

case 3:

Page 206: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

206

Toast.makeText(this, "Sub MenuItem 1 Clicked!",

Toast.LENGTH_SHORT)

.show();

break;

case 4:

Toast.makeText(this, "Sub MenuItem 2 Clicked!",

Toast.LENGTH_SHORT)

.show();

break;

default:

break;

}

return true;

}

Đầu tiên ta tạo menu bằng cách viết lại hàm onCreateOptionMenu(Menu

menu) hàm này giúp ta tạo lại toàn bộ menu và viết lại hàm

onOptionItemSelected(MenuItem item) để giúp việc bắt sự kiện khi ta nhấn chọn

từng thành phần trên menu.

Đối với hàm onCreateOptionMenu(Menu menu) thì tạo từng MenuItem và

thêm nó vào menu chính. Sau đó, thiết lập hình ảnh cho từng menu.

Cách thứ 2 là làm bằng tập tin XML. Với cách thức dùng XML thì dĩ nhiên

đầu tiên ta tạo một tập tin XML để qui định cho thực đơn chính với tên menu1.xml

trong thư mục /res/menu như sau:

<menu xmlns:android="http://schemas.android.com/apk/res/android">

<!-- This group uses the default category. -->

<group android:id="@+id/menuGroup_Main">

<item android:orderInCategory="5" android:title="Test Sub

Menu"

android:icon="@drawable/icon"

android:id="@+id/testsubmenu">

<menu>

<item android:title="Item 1"

android:id="@+id/menu_subitem01"></item>

<item android:title="Item 2"

android:id="@+id/menu_subitem02"></item>

</menu>

</item>

Page 207: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

207

<item android:id="@+id/menu1" android:icon="@drawable/icon"

android:title="Menu Item 1"></item>

<item android:id="@+id/menu2" android:icon="@drawable/icon"

android:title="Menu Item 2"></item>

</group>

</menu>

Hoặc thao tác thông qua công cụ hổ trợ sẵn có của ADT:

Hình phụ lục 158 Hình minh họa thao tác tạo menu thông qua công cụ hỗ trợ được tích hợp bên trong

Eclipse (ADT)

Sau đó vào lớp giao diện Activity thực thi đoạn mã lệnh sau:

// tạo menu

@Override

public boolean onCreateOptionsMenu(Menu menu) {

super.onCreateOptionsMenu(menu);

MenuInflater inflater = getMenuInflater(); // from Activity

// nạp menu từ tập tin XML nằm trong thư mục

/res/menu/menu1.xml

inflater.inflate(R.menu.menu1, menu);

return true;

}

Page 208: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

208

// xử lý sự kiện nhấn menu

@Override

public boolean onOptionsItemSelected(MenuItem item) {

super.onOptionsItemSelected(item);

switch (item.getItemId()) {

case R.id.menu1:

Toast.makeText(this, "Menu 1 Clicked!",

Toast.LENGTH_SHORT).show();

break;

case R.id.menu2:

Toast.makeText(this, "Menu 2 Clicked!",

Toast.LENGTH_SHORT).show();

break;

case R.id.menu_subitem01:

Toast.makeText(this, "Menu SubItem 1 Clicked!",

Toast.LENGTH_SHORT)

.show();

break;

case R.id.menu_subitem02:

Toast.makeText(this, "Menu SubItem 2 Clicked!",

Toast.LENGTH_SHORT)

.show();

break;

default:

break;

}

return true;

}

Ta dễ dàng thấy về cấu trúc chung thì giữa XML và mã lệnh Java thì gần như

giống nhau là tạo và thiết lập thực đơn; kế tiếp là viết hàm sự kiện cho nó khi có sự

kiện nhấn chọn thực đơn. Trong tập tin XML ta thấy ta thiết lập chuỗi, hình ảnh cho

từng thực đơn.

Trong hàm onCreate() ta thiết lập như sau:

Page 209: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

209

MenuInflater inflater = getMenuInflater(); // from Activity

// nạp menu từ tập tin XML nằm trong thư mục /res/menu/menu1.xml

inflater.inflate(R.menu.menu1, menu);

Ta thấy rằng nó đã tiến hành gán menu XML vào thực thể menu của chương

trình. Còn phần còn lại thiết lập sự kiện nhấp chọn thì giống như làm bằng Java.

I.6.2.2 Lập trình thực đơn ngữ cảnh

Thực đơn ngữ cảnh phải đi chung với một widget nào đó như Button,

editText, … mà khi ta nhấn và giữ lâu thì thực đơn ngữ cảnh xuất hiện cho phép ta

chọn những hành động xử lí liên quan đến thuộc tính, chức năng và nhiệm vụ riêng

của thực đơn ngữ cảnh ấy.

Trong ví dụ chúng tôi tạm thời tạo một nút nhấn và cho người dùng nhấn lâu

thì sẽ hiện thực đơn ngữ ảnh với 2 kiểu cách là XML và bằng mã lệnh Java.

Đầu tiên, ta khai báo thực đơn ngữ cảnh trong phương thức

setOnCreateContextMenuListener(new OnCreateContextMenuListener(). Phương

thức này có thể được gọi từ hầu hết các widget trên Android. Ta tiến hành thiết lập

thực đơn ngữ cảnh như sau bằng mã lệnh Java:

Button btnMenu = (Button)findViewById(R.id.Button01);

btnMenu.setOnCreateContextMenuListener(new

OnCreateContextMenuListener() {

@Override

public void onCreateContextMenu(ContextMenu menu, View

v,

ContextMenuInfo menuInfo) {

// TODO Auto-generated method stub

MenuItem mMenuItem;

// tạo menu item

mMenuItem = menu.add(Menu.NONE, // group

0, // item ID

Menu.NONE, // order

"Menu 1"); // title

// gán icon cho một menu item

mMenuItem.setIcon(R.drawable.icon);

Page 210: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

210

mMenuItem = menu.add(Menu.NONE, 1, Menu.NONE,

"Menu 2");

mMenuItem.setIcon(R.drawable.exit);

mMenuItem = menu.add(Menu.NONE, 2, Menu.NONE,

"Menu 3");

mMenuItem.setIcon(R.drawable.icon);

}

});

Hoặc bằng mã lệnh Java nhưng thực đơn đã tạo thành tập tin menu1.xml

trước trong thư mục /res/menu và ta thiết lập ghép tập tin menu1.xml vào thực đơn

ngữ cảnh như sau:

Button btnMenu = (Button)findViewById(R.id.Button01);

btnMenu.setOnCreateContextMenuListener(new

OnCreateContextMenuListener() {

@Override

public void onCreateContextMenu(ContextMenu menu, View

v,

ContextMenuInfo menuInfo) {

// TODO Auto-generated method stub

MenuInflater inflater = getMenuInflater(); //

from Activity

// nạp menu từ tập tin XML nằm trong thư mục

/res/menu/menu1.xml

menu.setHeaderTitle("Thực đơn ngữ cảnh");

inflater.inflate(R.menu.menu1, menu);

}

});

Trên là hai cách thiết lập menu ngữ cảnh cho nút nhấn cho trước trên màn

hình. Tương tự như thực đơn ngữ cảnh thông thường ta cũng phải thiết lập sự kiện

nhấp chọn thực đơn như sau:

@Override

Page 211: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

211

public boolean onContextItemSelected(MenuItem item) {

switch (item.getItemId()) {

case R.id.menu1:

Toast.makeText(this, "Menu 1 Clicked!",

Toast.LENGTH_SHORT).show();

break;

case R.id.menu2:

Toast.makeText(this, "Menu 2 Clicked!",

Toast.LENGTH_SHORT).show();

break;

case R.id.menu_subitem01:

Toast.makeText(this, "Menu SubItem 1 Clicked!",

Toast.LENGTH_SHORT)

.show();

break;

case R.id.menu_subitem02:

Toast.makeText(this, "Menu SubItem 2 Clicked!",

Toast.LENGTH_SHORT)

.show();

break;

default:

break;

}

return false;

}

Và đây là kết quả giao diện thể hiện của thực đơn ngữ cảnh:

Page 212: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

212

Hình phụ lục 159 Hình minh họa tạo thực đơn ngữ cảnh

I.6.3 Nhận xét

Tùy theo từng hoàn cảnh mà ta sẽ dùng hai loại thực đơn kể trên. Nếu muốn

làm thực đơn thao tác có ảnh hưởng đến phạm vi ứng dụng hay Activity hiện tại thì

ta nên dùng thực đơn thông thường làm Menu cho Activity hiện tại. Còn nếu muốn

gây tác động và ảnh hưởng lên một đối tượng cho trước sau khi nhấn và chọn lâu

đối tượng đó.

I.7 Lập trình với kiểu chữ (Font)

I.7.1 Giới thiệu

Mặc định trên Android có 4 loại kiểu chữ là Normal, Sans, Serif và

Monospace. Nhưng không vì thế mà giao diện bị nhàm chán bằng cách ta áp dụng

nhiều kiểu chữ khác nhau từ những tập tin kiểu chữ .ttf sẵn có.

Page 213: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

213

Hình phụ lục 160 Hình minh họa dùng font chữ khác trong Android

Hình trên có kiểu chữ là tubes.ttf cho chữ Hello Custom Font.

I.7.2 Cách lập trình

Để chọn kiểu chữ cho các đối tượng chứa chuỗi trên Android thì ta chỉ cần

thay đổi giá trị trong thuộc tính TypeFace thành giá trị kiểu chữ mình muốn như

hình sau:

Hình phụ lục 161 Hình minh họa các thức chọn font chữ thông thường mà Android hỗ trợ

Còn đối với lập trình áp dụng những kiểu chữ ngoài 4 kiểu chữ chuẩn của

Android thì ta chỉ cần có tập tin kiểu chữ .ttf được lưu trong thư mục /asset/font.

Page 214: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

214

Hình phụ lục 162 Hình minh họa thư mục chứa tập tin font chữ (.ttf) trong một project Android

Sau đó ta khai báo thực thể kiểu TypeFace có tham số đầu vào là tập tin kiểu

chữ. Và công đoạn cuối là thiết lập TypeFace đó cho đối tượng cần thiết. Đoạn mã

Java như sau:

// bind the "custom" textView with chosen font

TextView tvCustom = (TextView) findViewById(R.id.tv_TestFont);

Typeface myNewFace = Typeface.createFromAsset(getAssets(),

"fonts/tubes.ttf");

tvCustom.setTypeface(myNewFace);

I.7.3 Nhận xét

Thông thường đối với các trò chơi hay các chương trình cần nhiều kiểu chữ

với nhiều mục đích đồ họa khác nhau thì mới đưa nhiều kiểu chữ vào chương trình.

Nhưng với những chương trình thông thường thì 4 kiểu chữ sẵn có của Android đã

đủ để lập trình kiểu chữ cho giao diện. Vì nếu áp dụng nhiều kiểu chữ quá thì giao

diện sẽ rất rối.

I.8 Lập trình với khung thoại (Dialog)

I.8.1 Giới thiệu

Page 215: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

215

Một hộp thoại thường là một màn hình nhỏ mà xuất hiện đè lên các Activity

hiện tại. Activity nằm dưới sẽ không tương tác được với người dùng mà thay vào đó

là hộp thoại sẽ đóng vai trò đó. Hộp thoại thông thường dùng để thông báo hay đại

loại vậy. Thông thường có các loại hộp thoại sau:

AlertDialog: là dạng hộp thoại có nhiều nhất 3 nút nhấn hoặc có thêm

danh sách các mục lựa chọn có thêm checkbox hay radio button. AlertDialog

thích hợp làm hộp thoại trong các chương trình Android và được khuyến

khích dùng.

ProgressDialog: là hộp thoại có vòng xoay hay thanh thể hiện tiến

trình đang chạy. Bởi vì nó là dạng AlertDialog mở rộng cho nên nó cũng có

nút nhấn.

DatePickerDialog: là hộp thoại cho phép người dùng chọn ngày.

TimePickerDialog: là hộp thoại cho phép người dùng chọn giờ.

Trong hoàn cảnh, muốn thiết kế lại các hộp thoại thì có thể viết lại lớp

Dialog hay định nghĩa lại giao diện cho các lớp hộp thoại trên.

I.8.2 Cách thức lập trình

I.8.2.1 Tạo AlertDialog

Khi tạo một AlertDialog thì ta có thể thiết lập các giá trị sau: tựa đề, nội

dung tin nhắn, các nút (dưới 3 nút) và danh sách các mục chọn (có hoặc không có

checkbox và radio button). Để tạo một AlertDialog ta sử dụng lớp con

AlertDialog.Builder. Lớp này có nhiệm vụ tạo và thiết lập nút nhấn, giá trị thường

hay một danh sách, biểu tượng, và checkbox hay radio button để hình thành một

hộp thoại.

AlertDialog.Builder alertDialog;

// tạo một AlertDialog

alertDialog = new AlertDialog.Builder(this);

// gán title cho alertDialog

alertDialog.setTitle("Xin chào AlertDialog");

Page 216: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

216

// gán icon cho alertDialog

alertDialog.setIcon(R.drawable.icon);

// gán thông tin cho một alertDialog

alertDialog.setMessage("Nội dung thông báo!");

// tạo và gán sự kiện cho nút nhấn Positive

alertDialog.setPositiveButton("Yes",

new DialogInterface.OnClickListener() {

@Override

public void onClick(DialogInterface dialog,

int which) {

// Do something

}

});

// tạo và gán sự kiện cho nút nhấn Neutral

alertDialog.setNeutralButton("Cancel",

new DialogInterface.OnClickListener() {

@Override

public void onClick(DialogInterface dialog,

int which) {

// Do something

}

});

// tạo và gán sự kiện cho nút nhấn Negative

alertDialog.setNegativeButton("No",

new DialogInterface.OnClickListener() {

@Override

public void onClick(DialogInterface dialog,

int which) {

// Do something

Page 217: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

217

}

});

alertDialog.show();

Ta dễ thấy có 3 bước chính để tạo một AlertDialog là tạo thực thể hộp thoại

bằng lớp AlertDialog.Builder alertDialog; và sau đó thiết lập tiêu đề, nội dung,

tin nhắn và các nút cho hộp thoại như đoạn mã lệnh nêu ở trên. Cuối cùng là hộp

thoại phải show() để hiện hộp thoại trên màn hình giao diện với giao diện sau:

Hình phụ lục 163 Hình minh họa hộp thoại có nút nhấn

Ngoài ra, ta có thể tạo hộp thoại với dạng danh sách lựa chọn như sau:

Hình phụ lục 164 Hình minh họa hộp thoại dạng danh sách chọn

Để làm hộp thoại dạng danh sách như trên ta dùng đoạn mẽ lệnh Java như

sau:

Page 218: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

218

final CharSequence[] items = {"Red", "Green", "Blue"};

AlertDialog.Builder builder = new AlertDialog.Builder(this);

builder.setTitle("Pick a color");

builder.setItems(items, new DialogInterface.OnClickListener() {

public void onClick(DialogInterface dialog, int item) {

Toast.makeText(getApplicationContext(), items[item],

Toast.LENGTH_SHORT).show();

}

});

AlertDialog alert = builder.create();

Nếu muốn giao diện hộp thoại dạng danh sách có các mục chọn dạng radio

button thì dùng đoạn mã lệnh sau:

final CharSequence[] items = {"Red", "Green", "Blue"};

AlertDialog.Builder builder = new AlertDialog.Builder(this);

builder.setTitle("Pick a color");

builder.setSingleChoiceItems(items, -1, new

DialogInterface.OnClickListener() {

public void onClick(DialogInterface dialog, int item) {

Toast.makeText(getApplicationContext(), items[item],

Toast.LENGTH_SHORT).show();

}

});

AlertDialog alert = builder.create();

Với hình mô phỏng như sau:

Hình phụ lục 165Hình minh họa hộp thoại dạng danh sách lựa chọn RadioButton

I.8.2.2 Tạo ProgressDialog

ProgressDialog được mở rộng từ lớp AlertDialog mà có hình dạng là bánh xe

quay quay hay là thanh chạy thể hiện quá trình đang chạy ngầm hay quá trình đã xử

lí được bao nhiêu phần trăm để người dùng có thể biết được với hình như sau:

Page 219: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

219

Hình phụ lục 166 Hình minh họa hộp thoại dạng ProgressDialog

Hình phụ lục 167 Hình minh họa ProgressDialog dạng thanh trượt ngang

Với hình bánh xe quay thì ta dùng đoạn mã lệnh sau:

ProgressDialog dialog = ProgressDialog.show(MyActivity.this, "",

"Loading. Please wait...", true);

Với thanh tiến trình thì ta dùng đoạn mã lệnh sau:

ProgressDialog progressDialog;

progressDialog = new ProgressDialog(mContext);

progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);

progressDialog.setMessage("Loading...");

progressDialog.setCancelable(false);

I.8.2.3 Tạo hộp thoại có hiệu chỉnh lại

Trên là các hộp thoại có kiểu giao diện được qui định sẵn nhưng ta có thể qui

định lại các giao diện hộp thoại bằng tập tin giao diện riêng và áp dụng tập tin giao

diện đó cho hộp thoại theo trình tự sau:

Tạo tập tin giao diện. Ví dụ như :

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

android:id="@+id/layout_root"

android:orientation="horizontal"

android:layout_width="fill_parent"

android:layout_height="fill_parent"

android:padding="10dp"

>

<ImageView android:id="@+id/image"

android:layout_width="wrap_content"

android:layout_height="fill_parent"

android:layout_marginRight="10dp"

/>

<TextView android:id="@+id/text"

Page 220: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

220

android:layout_width="wrap_content"

android:layout_height="fill_parent"

android:textColor="#FFF"

/>

</LinearLayout>

Sau đó thiết lập đoạn mã lệnh Java để áp dụng giao diện đó lên hộp thoại và

thiết lập các thuộc tính cho hộp thoại

Context mContext = getApplicationContext();

Dialog dialog = new Dialog(mContext);

dialog.setContentView(R.layout.custom_dialog);

dialog.setTitle("Custom Dialog");

TextView text = (TextView) dialog.findViewById(R.id.text);

text.setText("Hello, this is a custom dialog!");

ImageView image = (ImageView) dialog.findViewById(R.id.image);

image.setImageResource(R.drawable.android);

Và đây là giao diện ứng với phần trên:

Hình phụ lục 168 Hình minh họa tạo hộp thoại từ một gioa diện

Ngoài ra, theo nguyên tắc lập trình giao diện, ta có thể tạo giao diện trực tiếp

bằng mã lệnh Java cho hộp thoại mà không cần thông qua tập tin XML như trên. Ta

dùng cách nào còn tùy theo từng hoàn cảnh và trường hợp.

I.9 Lập trình với nhập xuất tập tin

I.9.1 Giới thiệu

Bất kì hệ điều hành thông thường trên máy vi tính đều có những ứng dụng

mà có khả năng lưu, xóa, sửa các tập tin mà các tập tin đó điều được truy xuất bởi

các ứng dụng khác. Android sử dụng cơ chế khác, tất cả dữ liệu trong một ứng dụng

chỉ được dùng cho ứng dụng đó mà thôi.

Tuy nhiên, Android cũng cung cấp một cách để đưa những tập tin của ứng

dụng này sang ứng dụng khác thông qua một dạng là ContentProvider.

ContentProvider là thành phần của ứng dụng mà nó đọc dữ liệu từ tập tin bên trong

Page 221: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

221

ra cho các ứng dụng khác và ghi dữ liệu từ các ứng dụng khác vào tập tin bên trong.

Android hỗ trợ một số ContentProvider chuẩn cho các dạng tập tin như hình ảnh,

âm thanh, tập tin video và tập tin thông tin liên lạc cá nhân.

Cho dù chúng ta có muốn xuất dữ liệu sang các ứng dụng khác hay không thì

chúng ta phải cần biết cách thức để lưu trữ nó. Android có nhiều cách thức lưu trữ

dữ liệu và truy xuất nó là : Preferences, files, Databases và Network.

I.9.2 Preferences

I.9.2.1 Giới thiệu

Preferences là cách lưu trữ và truy xuất các thiết lập của ứng dụng Android.

Ví dụ như các thiết lập rung hay không rung khi ấn phím, bật/tắt GPS… Ta gọi hàm

Context.getSharedPreferences() để đọc và ghi giá trị. Gán tên cho bộ Preferences

nếu bạn muốn chia sẻ chúng với các thành phần khác trong cùng một ứng dụng hay

sử dụng hàm Activity.getPreferences() và không gán tên để dùng nó trong nội tại

Activity đó mà thôi. Bạn không thể chia sẻ Preference cho các ứng dụng khác;

ngoại trừ dùng ContentProvider.

Các giá trị thiết lập của Preferences được lưu thành một tập tin XML trong

thư mục ứng dụng của hệ thống /com.<ten_ung_dung>/shared_prefs.

Hình phụ lục 169 Hình minh họa thư mục chứa các lưu trữ Preferences nằm trong hệ thống của điện

thoại

Page 222: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

222

Sau đây là nội dung của một tập tin mẫu lưu vết Preferences:

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

<map>

<boolean name="default_toggle" value="true" />

<string name="default_edittext">Default value</string>

<string name="default_list">beta</string>

</map>

I.9.2.2 Cách thức lập trình

Đây là ví dụ đoạn mã lệnh Preferences:

import android.app.Activity;

import android.content.SharedPreferences;

public class Calc extends Activity {

public static final String PREFS_NAME = "MyPrefsFile";

. . .

@Override

protected void onCreate(Bundle state){

super.onCreate(state);

. . .

// Restore preferences

SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);

boolean silent = settings.getBoolean("silentMode", false);

setSilent(silent);

}

@Override

protected void onStop(){

super.onStop();

// Save user preferences. We need an Editor object to

// make changes. All objects are from android.context.Context

SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);

SharedPreferences.Editor editor = settings.edit();

editor.putBoolean("silentMode", mSilentMode);

// Don't forget to commit your edits!!!

editor.commit();

}

I.9.3 Files

I.9.3.1 Giới thiệu

Page 223: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

223

Ta có thể lưu trữ tập tin trên bộ nhớ trong của thiết bị di động hay trên bộ

nhớ ngoài (SD Card). Mặc định, các ứng dụng khác không thể truy xuất đến các tập

tin nằm trong bộ nhớ trong của ứng dụng.

Để đọc dữ liệu từ tập tin, gọi hàm Context.openFileInput() và tham số đầu

vào là đường dẫn và tên tập tin. Nó sẽ trả ra một đối tượng tập tin để ta dễ dàng

quản lí. Để ghi một tập tin thì dùng hàm Context.openFileOutput() với tham số là

tên và đường dẫn. Nó sẽ trả về đối tượng FileOutputSream. Gọi những phương thức

này với tham số đầu vào là đường dẫn và tên tập tin từ các ứng dụng khác sẽ không

được; lúc ấy, bạn có thể chỉ truy xuất đến các tập tin của ứng dụng của mình mà

thôi.

Nếu bạn có sẵn một tập tin được đóng gói cùng với ứng dụng lúc biên dịch

ứng dụng, bạn có thể lưu tập tin này trong project trong thư mục

/res/raw/myDataFile, và sau đó mở nó bằng hàm

Resources.openRawResource(R.raw.myDataFile). Nó sẽ trả về đối tượng

InputStream mà bạn có thể dùng để đọc tập tin.

Các bạn tham khảo thêm trong project mẫu đi kèm với tên là HelloIO.

I.9.3.2 Cách thức lập trình

Có 3 cách thức cần bàn tới trong mục này là ghi tập tin vào SDCard, đọc tập

tin từ SDCard và đọc tập tin trong thư mục chương trình – tập tin hệ thống.

Đọc tập tin từ thư mục chương trình:

Khi lập trình với việc đọc ghi tập tin thì Java khuyến cáo và đôi

khi bắt buộc nhà lập trình phải để các đoạn mã lệnh đọc ghi tập tin trong

try/catch để có thể bắt các lỗi xảy ra vì khả năng lỗi rất cao khi mà tập tin

không còn tồn tại trong bộ nhớ.

Nội dung chính như sau:

try {

// hàm đọc tập tin my_base_data.txt từ thư mục

// res/drawable/

PlayWithRawFiles();

Page 224: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

224

} catch (IOException e) {

Toast.makeText(getApplicationContext(),

"Problems: " + e.getMessage(), 1).show();

}

Nội dung hàm PlayWithRawFiles() như sau:

public void PlayWithRawFiles() throws IOException {

String str = "";

StringBuffer buf = new StringBuffer();

InputStream is = this.getResources().openRawResource(

R.drawable.my_base_data);

BufferedReader reader = new BufferedReader(new

InputStreamReader(is));

if (is != null) {

while ((str = reader.readLine()) != null) {

buf.append(str + "\n");

}

}

is.close();

Toast.makeText(getBaseContext(), buf.toString(), Toast.LENGTH_LONG)

.show();

}

Như chúng ta thấy cho dù tách hàm hay để cùng nhau thì phải có

try/catch.

Ta nên theo các bước chính là đọc tập tin cần đọc đưa vào

InputStream. Kế đến, tạo BufferReader để đọc tuần tự từ đầu đến cuối

InputStream đó. Trong khi đọc ta tiến hành lấy giá trị ra ngoài để vào

chuỗi tương ứng.

Đọc tập tin từ thư mục SDCard

Cũng như trên là phải cần có try/catch:

try {

// read an SD-file

Scanner infile = new Scanner(new FileReader(

"/sdcard/mysdfile.txt"));

String inString = "";

Page 225: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

225

while (infile.hasNextLine()) {

inString += infile.nextLine() + "\n";

}

// show result

Toast.makeText(getBaseContext(), inString,

Toast.LENGTH_LONG).show();

infile.close();

} catch (Exception e) {

Toast.makeText(getBaseContext(), e.toString(),

Toast.LENGTH_LONG).show();

}

Ta có nhiều cách đọc tập tin như ta thấy ở trên có cách thứ 2 là

dùng lớp Scanner. Nhưng lớp scanner thì chỉ có thể đọc theo từng dòng

mà thôi. Nếu tập tin chúng ta quản lí theo dòng thì lớp này sẽ tiện hơn.

Còn lớp InputStream và BufferReader thì đọc theo từng kí tự.

Ghi tập tin vào SDCard

try {

File myFile = new File("/sdcard/mysdfile.txt");

myFile.createNewFile();

FileOutputStream fOut = new FileOutputStream(myFile);

OutputStreamWriter myOutWriter = new OutputStreamWriter(

fOut);

myOutWriter.append("Phan Thanh Trung – Vo Thanh Nhat");

myOutWriter.close();

fOut.close();

// thông báo ghi file thành công

Toast.makeText(getBaseContext(),

"Done writing SD 'mysdfile.txt'",

Toast.LENGTH_SHORT).show();

// xóa khung nhập liệu

Page 226: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

226

txtData.setText("");

} catch (Exception e) {

Toast.makeText(getBaseContext(), e.getMessage(),

Toast.LENGTH_SHORT).show();

}

Để tạo tập tin mới gồm các bước tạo thực thể File để bắt đầu thao

tác; sau đó kích hoạt bằng hàm createNewFile(). Tiếp đến, tiến hành ghi

nội dung lên tập tin bằng 2 lớp FileOutputStream và OutputStreamWriter

để tiến hành ghi dữ liệu vào tập tin.

Chú ý: khi tiến hành đọc tập tin hoặc ghi tập tin thì sau khi thao tác ta

phải đóng tập tin lại bằng phương thức FileOutputStream.close() hoặc

InputStream.close().

I.9.3.3 Nhận xét

Nếu có nhu cầu ghi dữ liệu dạng đơn giản thì ta chỉ cần thao tác trên tập tin

thông thường. Còn nếu quản lí theo mối quan hệ dữ liệu quan hệ với nhau thì cần

quản lí chúng thành cơ sở dữ liệu để tiện theo dõi và quản lí.

I.9.4 Databases

I.9.4.1 Giới thiệu

Android cung cấp cho ta cách tạo và lưu trữ dữ liệu bằng cơ sở dữ liệu

(CSDL) SQLite. Mỗi CSDL chỉ được dùng trong ứng dụng đó mà thôi.

Đối tượng SQLiteDatabase thể hiện một CSDL và có các phương thức giao

tác với CSDL như thêm, xóa, sửa và truy vấn dữ liệu. Để tạo CSDL, gọi hàm

SQLiteDatabase.create() và cũng có thể dùng lớp SQLiteOpenHelper.

Android đưa ra các tính năng quản lí cho phép ta lưu trữ các dữ liệu từ đơn

giản đến phức tạp. Ví dụ như ta có thể lưu chuỗi, số, hình ảnh, …

Android có công cụ hỗ trợ CSDL SQL là sqlite3 giúp ta có thể truy xuất đến

nội dung các bảng, chạy dòng lệnh SQL và thực thi các tính năng hữu dụng khác

trên CSDL SQLite.

Page 227: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

227

Tất cả CSDL – gồm CSDL SQLite và các CSDL khác – được lưu trữ trong

thiết bị trong thư mục /data/data/package_name/databases.

Chuyện có bao nhiêu bảng trong CSDL SQLite, các cột chứa dữ liệu gì,

chúng liên kết với nhau ra sao thì đó là nhiệm vụ của việc quản lí cơ sở dữ liệu

thuần túy. Trong phần SQLite này chúng tôi chỉ giới thiệu từng bước và cách thức

lập trình để thao tác trên dữ liệu mà thôi.

Bạn có thể tham khảo thêm trên project mẫu phần SQLite có tên project là

HelloSQLite.

I.9.4.2 Cách thức lập trình

Cũng như các công cụ thao tác trên cơ sỡ dữ liệu Access hay MDF của

MSSQL, SQLite cung cấp các phương thức cần thiết để thao tác cơ sở dữ liệu.

Nhìn chung, có mở kết nối đến CSDL, thao tác và đóng kết nối CSDL. Đầu

tiên, chúng tôi nói về mở kết nối:

SQLiteDatabase db;

// tạo một SQLite database

db =

SQLiteDatabase.openDatabase("data/data/com.hellosqlite/testDB",

null, SQLiteDatabase.CREATE_IF_NECESSARY);

và đóng kết nối:

db.close();

Ta chú ý đến đường dẫn CSDL. Nếu CSDL đã tồn tại thì openDatabase sẽ

mở nó lên còn nếu không thì sẽ tạo CSDL mới do thuộc tính

SQLiteDatabase.CREATE_IF_NECESSARY đã qui định.

Khi chúng tôi lập trình phần này, thì chúng tôi thấy nếu để tên CSDL thôi thì

openDatabase sẽ tìm hoặc tạo CSDL trong thư mục mặc định của ứng dụng android

là data/com.<tên ứng dụng>/lib/<tên CSDL> như sau:

Page 228: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

228

Hình phụ lục 170 Hinh minh họa thư mục mặc định lưu trữ tập tin SQLite của một ứng dụng trên hệ

thống Android

Còn nếu chỉ rõ vị trí trên thẻ nhớ gắn ngoài thì nó sẽ đọc hoặc ghi CSDL lên

thẻ nhớ ngoài đó.

Có 2 kiểu chính thao tác lên CSDL là thực thi câu lệnh SQL execSQL hay sử

dụng các phương thức sẵn có của đối tượng SQLiteDatabase như query, insert,

update, delete. Ngoài ra, nó còn hỗ trợ tính toàn vẹn của giao tác bằng các bộ hàm

beginTransaction(), setTransactionSuccessful() và endTransaction(). Ta đặt các câu

lệnh SQL giữa beginTransaction() và endTransaction(). Và trong Android có hỗ trợ

các cách để thực hiện câu truy vấn như sau:

Thực thi truy vấn bằng câu lệnh SQL

Cursor c=null;

try {

c = db.rawQuery(sql, null);

} catch (SQLException e) {

Toast.makeText(mContext,

"Loi khi truy van du lieu:" + e.toString(),

4000).show();

}

Page 229: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

229

Thực thi câu lệnh truy vấn SQL và kết quả trả được chứa trong

biến con trỏ Cursor. Sau đó, ta duyệt biến con trỏ để lấy ra từng giá trị ta

cần bằng hàm movetoNext().

Thực thi truy vấn bằng phương thức sẵn có

Cursor c = null;

try {

c = db.query(tablename, columns, selection,

selectionArgs, groupBy,

having, orderBy);

} catch (SQLException e) {

Toast.makeText(mContext,

"Loi khi truy van du lieu:" + e.toString(),

4000).show();

}

Android đưa ra cách thứ 2 là dùng hàm có sẵn để thực hiện truy

vấn. Giúp nhà lập trình giải phóng khỏi vấn đề là phải biết ngôn ngữ truy

vấn SQL. Việc lập trình bằng hàm query thì phải theo khuôn khổ và theo

từng tham số đầu vào ứng với từng đối tượng trên câu truy vấn. Đối

tượng nào không có thì ta để NULL. Bạn có thể tham khảo toàn diện

trong chương trình ứng dụng thực tế eSaleShopping trong Package

com.DataProvider.

Thực thi hành động thêm/ xóa/ sửa bằng câu lệnh SQL

try {

db.execSQL(sql);

result = 1;

} catch (SQLException e) {

Toast.makeText(mContext, "Thuc thi khong thanh cong: "

+ e.toString(), 3000);

}

Ta đưa vào câu sql chứa câu lệnh SQL thêm, xóa, hoặc sửa và

thực thi.

Thực thi hành động thêm/ xóa/ sửa bằng phương thức sẵn có

Page 230: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

230

Thêm

int result = 0;

try {

result = (int) db.insert(table, null, values);

} catch (SQLException e) {

Toast.makeText(mContext, "Thuc thi khong thanh cong: "

+ e.toString(), 3000);

}

Cập nhật

int result = 0;

try {

result = (int) db.update(table, values, whereClause, whereArgs);

} catch (SQLException e) {

// TODO: handle exception

Toast.makeText(mContext, "Thuc thi khong thanh cong: "

+ e.toString(), 3000);

}

Xóa

int result = 0;

try {

result = (int) db.delete(table, whereClause, whereArgs);

} catch (SQLException e) {

// TODO: handle exception

Toast.makeText(mContext, "Thuc thi khong thanh cong: "

+ e.toString(), 3000);

}

I.9.4.3 Nhận xét

Tùy theo từng trường hợp và hoàn cảnh mà ta dùng các cách khác nhau.

Theo kinh nghiệm chúng tôi thì nếu các bạn có học mô hình 3 lớp viết cho

ứng dụng cục bộ truy vấn dữ liệu MSSQL thì ắt hẳn biết lớp DataProvider là lớp

nền tảng để thực thi các truy vấn CSDL. Cho nên, khi làm việc với SQLite thì ta

Page 231: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

231

cũng nên tạo lớp DataProvider cung cấp tập trung hầu hết các phương thức cơ bản

cho việc thao tác lên CSDL cho dễ dàng và dễ quản lí.

I.9.5 Network

I.9.5.1 Giới thiệu

Theo như xu hướng ngày nay, các máy di động và các thiết bị máy tính trở

thành thiết bị đầu cuối – là nơi thể hiện dữ liệu và xử lí đầu vào. Do sự lớn mạnh

của các máy chủ có khả năng lưu trữ lượng dữ liệu khổng lồ và khả năng xử lí cực

nhanh nên hầu như tất cả dữ liệu được lưu trên một máy chủ và tất cả thiết bị có thể

truy xuất để lấy dữ liệu về và hiển thị cho người dùng.

Lập trình dạng thức này là dạng lập trình theo từng tầng và ta phát lệnh truy

xuất dữ liệu từ di động cho máy chủ, máy chủ trả về kết quả tương ứng cho di động.

Vấn đề lớn ở đây là nếu lượng dữ liệu trả về quá lớn thì trong một lần không thể trả

về hết cho nên phải có cơ chế giao tiếp thích hợp giữa máy chủ và thiết bị di động.

Hiện nay có nhiều máy chủ chạy các nền tảng khác nhau, chúng tôi chỉ đề

cập đến 2 nền tảng chính là Java và .Net. Các máy chủ dạng webservice là nơi cung

cấp dữ liệu mà nó được cập nhật liên tục cho các thiết bị đầu cuối. Các webservice

được xây dựng trên nền Java hay .Net thì sẽ có cơ chế truyền và nhận dữ liệu khác

nhau từ phía client – client là thiết bị đầu cuối nhận và yêu cầu dữ liệu từ

webservice. Dot Net thì dùng cơ chế XML với định dạng của riêng mình và client

phải biết cơ chế định dạng đó mà làm theo để webservice và client có thể hiểu nhau

mà truyền cho nhau thông điệp yêu cầu và hồi đáp.

Hiện nay, theo chúng tôi biết thì Android hỗ trợ truy xuất thông tin từ

webservice trên nền ASP lẫn PHP với sự hỗ trợ từ kSOAP. Nhưng trong phần này,

chúng tôi sẽ nói nhiều về cơ chế giao tiếp với webservice viết trên nền .Net vì

chúng tôi chưa có cơ hội làm quen với PHP nên đã hiện thực hóa ứng dụng thực tế

với phần webservice trên nền .Net.

I.9.5.2 Cách thức lập trình

String SOAP_ACTION = "http://tempuri.org/HelloArr";

String METHOD_NAME = "HelloArr";// = "GetHS";

Page 232: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

232

String NAMESPACE = "http://tempuri.org/";

String URL = "http://192.168.200.85/HelloWebservice/Service.asmx";

SoapSerializationEnvelope envelope;

// khởi tạo môi trường, đường dẫn kết nối với webservice

envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);

envelope.dotNet = true;

SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);

envelope.setOutputSoapObject(request);

// xử lý kết nối webservice (ASP.NET) để lấy kết quả thông

qua sự kiện

// nhấn nút

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

btn.setOnClickListener(new OnClickListener() {

@Override

public void onClick(View v) {

SoapObject result = null;

try {

// gọi lấy kết quả từ webservice thông qua

đối tượng

// SoapObject result

HttpTransportSE androidHttpTransport = new

HttpTransportSE(URL);

androidHttpTransport.call(SOAP_ACTION,

envelope);

result = (SoapObject)

envelope.getResponse();

result.toString();

// xử lý kết quả nhận được từ webservice

String resultFromWebservice = "";

for (int i = 0; i <

result.getPropertyCount(); i++) {

resultFromWebservice += "\n"

+

result.getProperty(i).toString();

}

Toast.makeText(getBaseContext(),

Page 233: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

233

"Result From Server: \n" +

resultFromWebservice,

Toast.LENGTH_LONG).show();

} catch (Exception e) {

Toast.makeText(getBaseContext(), "" +

e.toString(),

Toast.LENGTH_LONG).show();

}

}

});

Hoàn cảnh ở đây là ta cần phát lệnh yêu cầu máy chủ webservice trả về cho

chúng ta tập giá trị ứng với yêu cầu mà ta đã gửi lên trước đó.

Trên là đoạn mã lệnh thực hiện đọc dữ liệu webservice và thể hiện lên màn

hình Android. Trong project mẫu hướng dẫn có tên là HelloWebservice có một

webservice đã viết sẵn. Bạn chạy webservice đó lên máy của bạn; sau đó thiết lập IP

thích hợp cho máy của bạn. Ở đây, chúng tôi tạm thiết lập IP như trên và từ đây

máy tính của bạn trở thành một server có webservice cung cấp thông tin cho ứng

dụng Android.

Đầu tiên ta phải thiết lập các thông số SOAP_ACTION, METHOD_NAME,

NAMESPACE, URL. Sau đó khởi tạo môi trường kết nối tới webservice thông qua

SoapSerializationEnvelope và SoapObject để gửi yêu cầu lên webservice. Tiếp

theo gọi và lấy kết quả về thông qua HttpTransportSE . Tùy theo từng hoàn cảnh

mà ta phân giải giá trị tương ứng thông qua phương thức getProperty().

I.9.5.3 Nhận xét

Cũng như SQLite, ta nên tạo một lớp để chuyên thực thi kết nối tới

webservice và lấy dữ liệu về từ máy chủ. Trong ứng dụng eSaleShopping, chúng tôi

đã tạo ra lớp ServiceProvider bao gồm các phương thức cơ bản để kết nối và yêu

cầu dữ liệu từ máy chủ.

I.10 Lập trình với MapView

I.10.1 Giới thiệu

Page 234: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

234

Lập trình bản đồ là thế mạnh của Android do nó được sự hậu thuẫn tối đa từ

Google. Ứng dụng bản đồ và vị trí dùng các lớp trong gói android.location và các

thư viện mở rộng của Google.

Android cho phép ứng dụng truy xuất đến các dịch vụ vị trí (có một phần cần

phải có sự hỗ trợ của thiết bị) thông qua gói android.location. Thành phần chính

của android.location là LocationManager sẽ cung cấp các hàm API để xác định vị

trí nếu có sự hỗ trợ của thiết bị (như GPS hay vị trí thông qua trạm thu phát sóng

điện thoại).

Cũng như các dịch vụ hệ thống khác, ta không khởi động thực thể

LocationManager trực tiếp mà phải nhờ hệ thống gọi hàm

getSystemService(Context.LOCATION_MANAGER). Hàm này sẽ trả ra một thực

thể LocationManager để quản lí bản đồ và vị trí.

Một khi có thực thể LocationManager thì ứng dụng có thể làm những việc

sau:

Tìm lại danh sách các LocationProvider để tìm giá trị vị trí lần cuối

cùng mà LocationProvider có (LocationProvider là các thiết bị nhận tín hiệu

vị trí thông qua GPS, Wifi, Mạng điện thoại).

Thiết lập hay gỡ bỏ thiết lập cho khoảng thời gian nhận giá trị cập

nhật cho LocationProvider.

Tuy nhiên, khi dùng máy ảo để chạy ứng dụng bản đồ thì ta không thể nhận

giá trị vị trí thật từ LocationPrivider (như mạng hay GPS). Trong hoàn cảnh này, ta

có thể dùng DDMS để gửi tín hiệu giả lập cho máy ảo.

Google cung cấp cho ta thư viện mở rộng gồm gói

com,google.android.maps. Các lớp con của gói này cung cấp cho ta bản đồ, canh

chỉnh bản đồ, lưu vết bản đồ và nhiều sự hỗ trợ khác nữa.

Lớp quan trọng của gói Maps là MapView, là một lớp con của ViewGroup.

MapView hiển thị bản đồ với dữ liệu có được từ dịch vụ Google Map. Tùy theo

người dùng thao tác lên màn hình mapView mà nó sẽ phóng to, thu nhỏ bản đồ. Nó

cung cấp các phần tử giao diện cần thiết để quản lí bản đồ như la bàn đi kèm chẳng

Page 235: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

235

hạn. Ngoài ra, MapView có chứa các lớp để quản lí và vẽ các loại hình ảnh “đè” lên

bản đồ chẳng hạn như các nút ghim, các chú thích ...

Gói thư viện Maps không phải là phần thư viện chính thức từ thư viện

Android, vì thế nếu bạn muốn lập trình ứng dụng có sự hỗ trợ của Google Maps thì

phải dùng thêm thư viện và thêm vào reference của ứng dụng như là phần KSOAP

của Webservice.

I.10.2 Cách thức lập trình

Chúng tôi hướng dẫn bạn theo từng bước để tạo một ứng dụng có áp dụng

bản đồ.

I.10.2.1 Bước 1:

Dĩ nhiên là tạo project. Tạm đặt tên là HelloOtherWidget.

I.10.2.2 Bước 2:

Khai báo là ta có sử dụng bản đồ trong AndroidManifest.xml với giá trị qui

định nằm trong thẻ <application> như sau:

<uses-library android:name="com.google.android.maps" />

I.10.2.3 Bước 3:

Do ta cần truy xuất Internet để truy xuất bản đồ của Google; vì thế ta cần cấp

phép dùng Internet. Trong tập tin AndroidManifest.xml, thì thêm vào giá trị bên

trong thẻ <manifest> như sau:

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

I.10.2.4 Bước 4:

Cũng trong tập tin AndroidManifest.xml ta thiết lập thuộc tính không thể

hiện tiêu đề cho Activity bản đồ như sau:

<Activity android:name=".HelloMapView" android:label="@string/app_name"

android:theme="@android:style/Theme.NoTitleBar">

<intent-filter>

<action android:name="android.intent.action.MAIN"

/>

<category

android:name="android.intent.category.SAMPLE_CODE" />

Page 236: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

236

</intent-filter>

</Activity>

Thuộc tính qui định không có tiêu đề có hay không có đều được.

I.10.2.5 Bước 5:

Mở tập tin qui định giao diện, chúng tôi tạo một tập tin giao diện XML mới

có tên là hello_mapView.xml và thiết kế như sau:

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

<RelativeLayout

xmlns:android="http://schemas.android.com/apk/res/android"

android:id="@+id/mainlayout" android:orientation="vertical"

android:layout_width="fill_parent"

android:layout_height="fill_parent">

<com.google.android.maps.MapView

android:id="@+id/mapView" android:layout_width="fill_parent"

android:layout_height="fill_parent" android:clickable="true"

android:apiKey="0zAN4n_WR-D5XultBqPDnHAv2g_krHVOK8m4D3g" />

</RelativeLayout>

Ta lưu ý ở trên có mục apiKey. Mục này là khóa mà Google Maps đưa cho

mỗi người khác nhau với từng debug.keystore khác nhau.

Trong tài liệu phụ lục này có mục trình bày cài đặt máy ảo và có phần yêu

cầu các bạn chú ý đến phần debug.keystore để sau này lập trình bản đồ. Google

Maps yêu cầu với mỗi nhà lập trình trên mỗi máy khác nhau thì cần có một apiKey

khác nhau. Để lấy được apiKey ta theo các bước sau:

Vào thư mục chứa máy ảo để lấy đường dẫn debug.keystore. Ở đây

tôi có đường dẫn sau: C:\Users\ThanhTrung\.android\debug.keystore.

Hình phụ lục 171 Hình minh họa thư mục chứa tập tin debug.keystore (Windows 7)

Page 237: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

237

Mở CommandPromt và vào đến thư mục và chạy dòng lệnh:

C:\Program Files\Java\jdk1.6.0_16\bin>keytool -list -keystore

"C:\Users\ThanhTrung\.android\debug.keystore"

Khi đó màn hình sẽ xuất hiện nội dung sau:

***************** WARNING WARNING WARNING

*****************

* The integrity of the information stored in your keystore *

* has NOT been verified! In order to verify its integrity, *

* you must provide your keystore password. *

***************** WARNING WARNING WARNING

*****************

Keystore type: JKS

Keystore provider: SUN

Your keystore contains 1 entry

androiddebugkey, 07-12-2009, PrivateKeyEntry,

Certificate fingerprint (MD5):

AD:35:5C:24:54:36:76:AB:42:7B:4F:2B:D4:D9:38:DB

Vào website http://code.google.com/intl/vi-VN/android/add-

ons/google-apis/maps-api-signup.html và nhập vào mã số Certificate

fingerprint (MD5) như hình sau:

Page 238: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

238

Hình phụ lục 172 Hình minh họa trang web lấy mã đăng ý Google Maps ApiKey từ Google

Cuối cùng Google yêu cầu ta đăng nhập với tài khoản của GoogleMail

vào và ta sẽ nhận được apiKey. Lúc đó, ta lưu lại apiKey để sử dụng cho các

chương trình sau.

Lúc này ta dùng apiKey đó cho phần apiKey ở mục trên.

Chú ý là không dùng apiKey như đã ví dụ ở trên vì chắc chắn màn hình bản

đồ sẽ không hiển thị được Google Map khi bạn dùng apiKey của máy khác.

I.10.2.6 Bước 6

Tạo tập tin Java có tên là HelloMapView.Java và thừa kế lớp MapActivity

public class HelloMapView extends MapActivity

I.10.2.7 Bước 7

Trong mỗi lớp nào kế thừa từ lớp MapActivity đề phải viết lại hàm

isRouteDisplayed().

@Override

protected boolean isRouteDisplayed() {

return false;

}

Page 239: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

239

I.10.2.8 Bước 8

Thiết kế nội dung hàm onCreate() như sau:

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.hello_mapView);

MapView mapView = (MapView) findViewById(R.id.mapView);

// chỉnh độ phóng to của bản đồ

mapView.getController().setZoom(17);

// gắn bộ ZoomController vào bản đồ

mapView.setBuiltInZoomControls(true);

}

Thế là xong ứng dụng có bản đồ.

I.10.3 Nhận xét

Trên là những bước cơ bản để tạo nên bản đồ có sử dụng tính năng của

Google Maps. Ngoài ra, việc khai thác bản đồ dường như là vô tận khi ta thêm các

đối tượng trên màn hình bản đồ để phục vụ cho từng ý tưởng liên quan đến bản đồ.

Cho nên việc vẽ các nút nhấn, các biểu tượng lên trên đó là điều rất cần thiết. Để

tìm hiểu kĩ hơn phần này ta vào mục Part 2: Adding Overlay Items trong trang

web: http://developer.android.com/resources/tutorials/Views/hello-mapView.html

để tìm hiểu thêm.

I.11 Lập trình thao tác WebKit

I.11.1 Giới thiệu

Android hỗ trợ ta mở trình duyệt web ngay trên phần mềm ứng dụng

Android. Chỉ cần vài thao tác đơn giản ta có thể mở các trang web ngay trên màn

hình thao tác của ứng dụng mà không cần tốn công mở trình duyệt web lên.

Page 240: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

240

Phần lập trình với Webkit chúng tôi đã làm trong project mẫu

HelloOtherWidget mục Webkit.

I.11.2 Cách thức lập trình

I.11.2.1 Tạo giao diện

Tạo tập tin giao diện XML với nội dung đơn giản như sau:

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

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

android:layout_width="fill_parent"

android:layout_height="fill_parent"

android:orientation="vertical">

<WebView android:id="@+id/webkit"

android:layout_height="fill_parent"

android:layout_width="fill_parent" />

</LinearLayout>

Các bạn không quên kiểm tra sự pho phép dùng Internet trong thẻ permission

thuộc tập tin AndroidManifest.xml có tồn tại chưa.

I.11.2.2 Mã lệnh Java

Thiết kế lớp Activity đơn giản như sau.

public class HelloWebKit extends Activity {

WebView browser;

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

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.hello_webkit);

// tạo một WebView

browser = (WebView) findViewById(R.id.webkit);

browser.getSettings().setJavaScriptEnabled(true);

// nạp vào WebView địa chỉ web

browser.loadUrl("http://google.com");

}

}

Page 241: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

241

Nó sẽ mở một trình duyệt web và vào thẳng trang web www.google.com .

Bạn chú ý, khi thiết kế bạn có thêm TextView hay các widget khác thì trình duyện

cũng che lấp hết các widget ấy.

I.11.3 Nhận xét

Cũng giống như các trình gọi điện thoại hay gửi tin nhắn, thì trình trình duyệt

web giúp nhà lập trình có thể gọi trực tiếp màn hình duyệt web ngay từ chương

trình và sẽ thuận tiện cho người dùng khi nhấp vào các đường liên kết thì nó sẽ mở

trang web ứng với đường liên kết ấy.

I.12 Lập trình với các widget khác

I.12.1 Widget Date/Time

I.12.1.1 Giới thiệu

Điều khiển này cho phép ta chọn ngày/ giờ hệ thống. Chúng có giao diện như

sau:

Hình phụ lục 173 Hình minh họa Date widget

Hình phụ lục 174 Hình minh họa Time widget

I.12.1.2 Cách thức lập trình

Page 242: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

242

Việc lập trình trên widget này tương đối dễ. Các bạn có thể tự tìm hiểu thêm

phần này trong ứng mẫu HelloOtherWidget với phần

HelloDateTimeSelectionWidget.Java.

I.12.2 Widget Tab

I.12.2.1 Giới thiệu

Phần tab giúp ta nhìn trên nhìn khung nhìn khác nhau. Tùy theo từng chương

trình ứng dụng mà ta có thể áp dụng chúng:

Hình phụ lục 175 Hình minh họa giao diện dạng Tab trong Android

I.12.2.2 Cách thức lập trình

Đầu tiên, tạo tập tin giao diện XML như sau:

Page 243: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

243

Hình phụ lục 176 Mã XML minh họa cho việc tạo một khung ứng dụng Tab đơn giản

Ta chú ý, giao diện tab có 3 thành phần chính:

Tabhost: là khung chứa chính cho nút lệnh tab và nội dung tab.

Tabwidget: là phần chứa số nút tab bao gồm chữ và biểu tượng.

FrameLayout: là nơi chứa nội dung tab.

Hình phụ lục 177 Hình minh họa cấu trúc của một Tab widget

Như trong phần mã lệnh XML ta có thể hiện từng TextView ứng với từng

Tab trong TabWidget.

Tiếp đến vào mã lệnh Java để thiết lập cho từng tab như sau:

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.hello_tabwidget);

TabHost mTabHost = getTabHost();

Page 244: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

244

mTabHost.addTab(mTabHost.newTabSpec("tab_test1").setIndicator("TAB

1")

.setContent(R.id.textView1));

mTabHost.addTab(mTabHost.newTabSpec("tab_test2").setIndicator("TAB

2")

.setContent(R.id.textView2));

mTabHost.addTab(mTabHost.newTabSpec("tab_test3").setIndicator("TAB

3")

.setContent(R.id.textView3));

mTabHost.setCurrentTab(0);

}

Lúc này, tab được hình thành theo ý muốn của chúng ta.

Page 245: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

245

Phụ lục J Lập trình với EndlessList

J.1 Giới thiệu

Việc tạo một danh sách trên Android như ta đã biết ở các phần phụ lục trước

là một việc hết sức dễ dàng và nhanh chóng. Ở đây, chúng ta chỉ cần tạo một

ListView trên màn hình giao diện và dùng bất kỳ một Adapter nào để gắn kết dữ

liệu vào ListView này. Việc lập trình như vậy nếu xét về khía cạnh cục bộ trên một

thiết bị di động thì không có gì phải bàn nhưng nếu xét trên ngữ cảnh thiết bị đó

hoạt động trên môi trường mạng thì đây lại là một vấn đề thách thức đối với các nhà

lập trình.

Việc hiển thị dữ liệu cục bộ (nguồn dữ liệu có thể là các mảng chuỗi lưu

trong tài nguyên chương trình hay lưu trong CSDL SQLite) được Android thực hiện

rất nhanh chóng và chính xác. Tuy nhiên việc lấy dữ liệu từ server về và hiển thị lên

ListView là một điều khó do nó phụ thuộc vào nhiều yếu tố như: chất lượng đường

truyền của mạng, độ lớn của dữ liệu... Ví dụ như việc hiển thị một list các bài nhạc

hay album từ một website âm nhạc nào đó lên màn hình cho người dùng xem và

nghe thử trước khi mua bài hát hay album nào đó. Có nhiều cách để thực hiện công

việc này. Cách đơn giản nhất là ta tải hết toàn bộ dữ liệu từ server về một lần sau đó

mới hiển thị lên cho người dùng xem và chọn. Cách này tuy đơn giản nhưng bộc lộ

không ít các nhược điểm đó là: nếu nguồn dữ liệu khá lớn thì người dùng sẽ đợi

“dài cổ” để cho dữ liệu được tải về hết và ngoài ra nó còn tiềm ẩn lỗi cho chương

trình nếu như đường truyền mạng bị trục trặc.

Để giải quyết bài toán nêu ra ở trên thì khái niệm EndlessList ra đời và được

các nhà lập trình áp dụng với nhiều cách thức khác nhau. Một bộ dữ liệu lớn trên

server sẽ được “chẻ” nhỏ và chương trình sẽ download tuần tự từng bộ dữ liệu được

“chẻ” nhỏ này và thể hiện lên trên một ListView lúc này ListView sẽ được gọi nôm

na là EndlessList.

Page 246: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

246

J.2 Cách thức tạo EndlessList

Việc lập trình tạo ra EndlessList tương đối là phức tạp, vì vậy để thực hiện

được một EndlessList điều đầu tiên là ta phải biết được cách gắn kết dữ liệu vào

ListView thông qua một SimleAdapter (phần này đã được trình bày kỹ ở phần phụ

lục I.1).

Điều tiên quyết tiếp theo là nguồn dữ liệu từ server trả ra cho client phải

được “chẻ” nhỏ ra để ta có thể lấy về từng bộ nhỏ này về hiển thị lên ListView của

chương trình (ví dụ trên server có 100 record thì bộ dữ liệu này phải được chia nhỏ

làm 10 phần, mỗi phần có 10 record đủ nhỏ để cho phù hợp với việc truyền tải dữ

liệu trên môi trường thiết bị di động).

J.2.1 Cách thức vận hành của EndlessList:

Chương trình sẽ download về trước phần dữ liệu nhỏ đầu tiên và hiển thị lên

trên ListView. Khi người dùng duyệt đến dòng cuối cùng của ListView, chương

trình sẽ bắt được sự kiện này và tiến hành gửi một yêu cầu lên server để yêu cầu

phần dữ liệu tiếp theo.

Nếu server báo không còn phần dữ liệu nào nữa thì ứng dụng sẽ hoàn tất và

không còn gửi yêu cầu lên server nữa. Lúc này danh sách đã được tải và thể hiện

đầy đủ lên trên màn hình.

Ngược lại thì chương trình sẽ tiếp tục download về phần dữ liệu tiếp theo.

Sau khi download xong chương trình sẽ thực hiện gắn nối tiếp phần dữ liệu này vào

ListView (tức là nối liền phần dữ liệu ban đầu với phần dữ liệu mới này và hiển thị

lên List). Tiến trình trên cứ được lặp đi lặp lại cho đến khi chương trình download

hết các phần dữ liệu về.

Người dùng sẽ tốn một khoảng thời gian nhỏ cho mỗi lần chờ một phần dữ

liệu được tải về. Tuy nhiên việc chờ đợi này là chấp nhận được hơn so với việc phải

ngồi chờ rất lâu để tải hết trọn bộ dữ liệu về máy rồi mới xem.

Hình ảnh minh họa cho một EndlessList được ứng dụng trong bài toán

eSaleShopping.

Page 247: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

247

Hình phụ lục 178 Hình minh họa cho một EndlessList được áp dụng vào eSaleShopping

J.2.2 Cách thức lập trình tạo EndlessList

Phần này chúng tôi sẽ không trình bày chi tiết các mã lệnh để tạo ra

EndlessList mà chỉ nêu vấn đề ở mức tổng quát nhất do từng hoàn cảnh thực tế mà

ta sẽ có cách áp dụng EndlessList khác nhau.

Theo như sự tìm hiểu của chúng tôi, ta sẽ tạo một lớp dẫn xuất từ lớp

SimpleAdapter và task không đồng bộ (AsyncTask) để có thể tạo một EndlessList.

Cách thức hoạt động và cơ chế sẽ được nêu rõ ở phần bên dưới.

Tạo một lớp mở rộng từ lớp SimpleAdapter như sau:

public class TestSimpleAdapter extends SimpleAdapter {

public TestSimpleAdapter(TestEndlessSlow context,

List<? extends Map<String, String>> data, int resource,

String[] from, int[] to) {

super(context, data, resource, from, to);

}

@Override

public View getView(int position, View convertView, ViewGroup

parent) {

Page 248: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

248

// kiểm tra xem có cần load thêm dữ liệu về từ server hay

không

if (!mDone && (getCount() - position) <= 1) {

if (mTestEndlessSlow.isAsyncTaskFinished()) {

mTestEndlessSlow.loadNextValues();

}

}

View ret = super.getView(position, convertView, parent);

if (ret != null) {

// Do something

}

return ret;

}

// ...

}

Lớp này có nhiệm vụ gắn kết dữ liệu với ListView (cách thức sử

dụng lớp dẫn xuất từ SimpleAdapter để gán dữ liệu vào ListView thông

qua phương thức setAdapter() như đã được trình bày ở phụ lục I.1),

đồng thời kiểm tra xem hiện thời ListView đã được cuộn tới cuối danh

sách chưa. Nếu đã tới cuối danh sách thì ta tạo một Task không đồng bộ

thực hiện việc tải tiếp phần dữ liệu mới về. Task không đồng bộ này sẽ

được trình bày kỹ hơn ở phần bên dưới.

Việc kiểm tra xem cuối danh sách của ListView hay chưa ta sẽ

thiết kế hàm đặt ở bên trong phương thức public View getView(int

position, View convertView, ViewGroup parent) {}

Gọi thực thi một AsyncTask để thực thi việc lấy dữ liệu ngầm từ

server về:

AsyncTask là một task không đồng bộ do Android hỗ trợ các nhà

lập trình thực hiện các hoạt động chạy nền bên dưới và đẩy kết quả thực

hiện được ra luồng UI (UI Thread) mà không cần thông qua Handler hay

Thread. Để hiểu rõ hơn ta có thể tham khảo thêm định nghĩa và cách

Page 249: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

249

dùng AsyncTask từ trang

http://developer.android.com/reference/android/os/AsyncTask.html

Khi một AsyncTask được gọi thực thi, nó phải trải qua 4 bước như

sau (và ta sẽ lợi dụng 4 bước này để thực hiện việc tải ngầm từng phần dữ

liệu từ server và sau khi tải xong phần nào sẽ “đẩy” phần đó lên trên giao

diện)

onPreExcute() phương thức này sẽ được gọi một lần khi

AsyncTask được kích hoạt. Ta sẽ khởi động các hiệu ứng của

progressBar lên trên màn hình để báo cho người dùng biết là phải chờ đợi

để tải thêm thông tin về từ server.

doInBackground() phương thức này là một thread chạy ngầm và

được chạy ngay sau khi hàm onPreExcute() được thực hiện xong. Ta sẽ

thiết kế các hàm đọc dữ liệu từ server ngay bên trong phương thức này.

Ngay khi đọc được bộ dữ liệu nào từ server ta có thể gửi kết quả này qua

hàm onProgressUpdate() để xử lý kết quả thông qua phương thức

publishProgress(ket_qua_doc_duoc).

onProgressUpdate() phương thức này được chạy trên UI Thread,

phương thức này được dùng để xử lý dữ liệu được gửi qua từ phương

thức doInBackground(). Từng record khi được gửi qua đây sẽ được thêm

vào một List<T>, List<T> này chính là nơi chứa dữ liệu cũ đang hiển thị

trên ListView và giờ sẽ chứa thêm dữ liệu mới vừa thêm vào. Mối liên hệ

giữa List<T> SimpleAdapter ListView đã được nói rõ trên phần phụ

lục I.1 nên phần này sẽ không được đề cập ở đây.

onPostExcute() phương thức này cũng được chạy trên UI Thread

và được gọi thực thi khi tác vụ tính toán chạy ngầm đã thực thi hoàn tất.

Ta sẽ gọi thực hiện tắt hiệu ứng progressBar đi và yêu cầu ListView cập

nhật thêm dữ liệu mới (thông qua việc dùng phương thức

notifyDataSetChanged()của lớp dẫn xuất từ SimpleAdapter được mô tả

như ở phần trên).

Page 250: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

250

J.3 Nhận xét

Việc lập trình với EndlessList tuy có phần phức tạp nhưng một khi đã nắm

vững được cách thức hoạt động của EndlessList thì việc áp dụng EndlessList vào

các ứng dụng có dạng kết nối dữ liệu với server sẽ nâng cao tính linh hoạt và uyển

chuyển cho ứng dụng khi hoạt động trên môi trường mạng, và người dùng không

phải tốn công chờ một lượng lớn dữ liệu tải về mà thay vào đó là “nhâm nhi” dần

dần dữ liệu.

Theo sự nhận xét của chúng tôi, EndlessList thường được dùng cho các ứng

dụng thương mại, tin tức và thường được dùng để liệt kê danh sách sản phẩm đang

bán hay quảng bá sản phẩm tới người dùng điển hình như ứng dụng Google Market

hay Magnatune (http://evancharlton.com/projects/magnatune)… và ứng dụng

eSaleShopping cũng đã có áp dụng EnlessList cho việc hiển thị danh sách hàng hóa

đang được bán từ các siêu thị khác nhau.

Page 251: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

251

Phụ lục K Cấu trúc và ý nghĩa các thành phần của

một project Android

MyApp/

AndroidManifest.xml (rất cần) Chứa các khai báo về một project

như tên project, tên gói package, các lớp

Activity, lớp Activity chính khi chương trình

được chạy…

src/

/myPackagePath/.../MyClass.Java

(rất cần) Thư mục này chứa tất cả các source

code của chương trình.

res/ (rất cần) Thư mục này chứa tất cả các

resource của chương trình

anim/

animation1.xml

...

(không bắt buộc) Chứa các file XML về khai

báo animation mà chương trình cần sử dụng

drawable/

some_picture.png

some_stretchable.9.png

some_background.xml

...

(không bắt buộc) Các files trong thư mục này

sẽ được biên dịch trong resources

Android.graphic.drawable. Các file này

thường là các file ảnh như PNG. JPG hay

GIF.

layout/

screen_1_layout.xml

...

(không bắt buộc) Chứa tất cả các file XML

mô tả về giao diện màn hình hay một phần

giao diện màn hình.

values/

arrays

classes.xml

colors.xml

dimens.xml

strings.xml

(không bắt buộc) Đây là các file XML chứa

các thông tin thêm như strings, color hay

styles.

Page 252: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

252

styles.xml

values.xml

xml/ Các file XML có thể được đọc trong thời gian

chạy trên thiết bị

raw/ (không bắt buộc) Tất cả các file trong thư mục

này sẽ được chép trực tiếp lên thiết bị.

Bảng B.1 Cấu trúc project Android

Bảng B-1 Cấu trúc project Android được tham khảo từ Khóa luận 2008

“Nghiên cứu và xây dựng từ điển trên G-Phone” của Tô Xuân Khôi Nguyên và

Đoàn Chánh Thức thực hiện.

Đối với các resource, bên cạnh những resource do người dùng tạo ra, Android

cũng hỗ trợ một số resource khác trong gói Android.R. (các resource do người dùng

thêm vào được sử dụng bằng cách gọi R.)

Page 253: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

253

Phụ lục L Hướng dẫn sử dụng, thao tác chính trên

chương trình eSaleShopping

L.1 Sơ đồ liên kết các màn hình chức năng trong ứng dụng

eSaleShopping

Để tiện việc trình bày phần hướng dẫn sử dụng các chức năng trong chương

trình eSaleShopping chúng tôi đưa ra sơ đồ liên kết các màn hình chức năng trong

ứng dụng như hình bên dưới.

Hình phụ lục 179 Sơ đồ liên kết các màn hình của ứng dụng eSaleShopping

Màn hình chính

MH tìm theo danh mục

MH tìm theo Loại hàng

hóa

MH danh sách hàng

hóa

MH chi tiết hàng hóa

MH tìm theo hệ thống siêu

thị

...

MH tìm theo chuỗi

MH danh sách hàng

hóa

MH chi tiết hàng hóa

MH tìm theo mã vạch

MH danh sách hàng

hóa

MH chi tiết hàng hóa

MH hàng hóa cần mua

MH hàng hóa ưu thích

MH tùy chọnMH thông tin chương trình

Page 254: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

254

Hình phụ lục 180 Sơ đồ liên kết các màn hình của ứng dụng eSaleShopping (tiếp)

L.2 Giới thiệu chức năng của màn hình chính

Hình phụ lục 181 Màn hình chính của ứng dụng eSaleShopping

L.2.1 Các chức năng trên màn hình chính

Tìm hàng hóa theo mã vạch: chọn chức năng này nếu chúng ta

muốn chụp thông tin của một mã vạch hàng hóa nào đó và tìm thông tin của

Màn hình tìm theo hệ thống

siêu thị

MH chỉ đường đi ngắn nhất

MH lựa chọn của một siêu thị trong hệ thống siêu thị

MH thông tin siêu thị

MH chỉ đường đến siêu thị

MH tìm hàng hóa theo chuỗi

MH tìm hàng hóa theo mã vạch

MH tìm hàng hóa theo danh mục

Page 255: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

255

hàng hóa đó hiện đang bán ở tại siêu thị nào, có giá cả là bao nhiêu, có

khuyến mãi hay không, .v.v…

Tìm hàng hóa theo siêu thị: chọn chức năng này nếu ta muốn

tìm các thông tin về hàng hóa hiện đang bán tại siêu thị của một hệ thống

siêu thị nào đó và các thông tin khác như bản đồ đường đi đến siêu thị hoặc

thông tin siêu thị, …

Tìm hàng hóa theo danh mục: chọn chức năng này nếu ta

muốn tìm thông tin hàng hóa theo các danh mục đã được chia sẵn theo nhiều

tiêu chí như: hàng gia dụng, thực phẩm đông lạnh… Khi chọn chức năng

này, chương trình sẽ hiển thị thông tin các hàng hóa được phân hoạch theo

danh mục hàng hóa, loại hàng hóa cho người dùng tiện theo dõi.

Tìm hàng hóa theo chuỗi: chọn chức năng này nếu người dùng

muốn tìm kiếm hàng hóa thông qua các từ khóa, các chuỗi … Ví dụ, khi

người dùng gõ vào từ khóa “trà xanh” và nhấn nút tìm kiếm thì chương trình

sẽ lấy dữ liệu danh sách những mặt hàng nào có chứa từ khóa “trà xanh” từ

server về và hiển thị chúng ra trên màn hình.

Quản lý danh sách hàng hóa ưu thích: chọn chức năng này nếu

ta muốn thêm, xóa, sửa hay xem thông tin của một hàng hóa ưu thích nào đó.

Quản lý danh sách hàng hóa cần mua: chọn chức năng này

nếu ta muốn thêm, xóa, sửa hay xem thông tin của một hàng cần mua.

L.2.2 Thực đơn (menu) chức năng của màn hình chính

Page 256: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

256

Hình phụ lục 182 Menu chức năng của màn hình chính

Menu chức năng trong màn hình chính gồm có 3 chức năng chính như sau:

Thiết lập chương trình: đây là chức năng mà người dùng có thể thiết

lập hay sử dụng các chức năng như: xóa rác hình ảnh, cập nhật lại toàn bộ dữ

liệu của chương trình.

Thông tin chương trình: chức năng này cho biết thông tin phiên bản

phần mềm cũng như thông tin tác giả thực hiện.

Thoát chương trình: chức năng thoát chương trình.

L.3 Thao tác trên màn hình chụp mã vạch

Hình phụ lục 183 Màn hình chụp và tìm kiếm hàng hóa dựa theo mã vạch

L.3.1 Sử dụng chức năng chụp mã vạch

Để tiện việc trình bày hướng dẫn sử dụng chức năng chụp mã vạch chúng tôi

sẽ tóm lược lại bằng một kịch bản sử dụng như sau:

Page 257: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

257

Người dùng thực hiện nhấn nút “Đọc Mã Vạch” . Chương trình

sẽ kiểm tra trên điện thoại có cài chương trình Barcode Scanner hay không.

Nếu không có chương trình Barcode Scanner để chụp mã vạch thì sẽ

hỏi xem người dùng có cần tải ứng dụng chụp mã vạch này về hay không.

Nếu cần thì chương trình sẽ dò tìm và tải về ứng dụng Barcode Scanner từ

Android Market về và cài đặt lên trên điện thoại theo trình tự sau:

Hình phụ lục 184 Các bước tiến hành tải về ứng dụng Barcode Scanner

Page 258: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

258

Nếu điện thoại đã có sẵn chương trình Barcode Scanner thì ứng dụng

này sẽ được kích hoạt để chụp mã vạch hàng hóa

Hình phụ lục 185 Màn hình chụp thông tin của một mã vạch hàng hóa

Nếu chụp được mã vạch của hàng hóa, kết quả sẽ được phân tích

thành chuỗi số gồm 13 ký tự và được hiển thị lại trên màn hình

chụp mã vạch như sau

Hình phụ lục 186 Màn hình hiển thị kết quả đọc được từ quá trình chụp mã vạch

Page 259: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

259

Nếu không chụp được mã vạch thì chương trình sẽ đưa ra gợi ý là

có tiếp tục tìm kiếm thông tin hàng hóa bằng cách sử dụng “Màn

hình tìm kiếm chuỗi” hay không.

Hình phụ lục 187 Màn hình gợi ý tìm hàng hóa theo chuỗi

L.3.2 Các chức năng thực hiện sau khi chụp được mã vạch hàng hóa

Sau khi chụp được mã vạch của hàng hóa, ta có 3 chức năng có thể thực hiện

được như sau: thêm vào danh sách mua hàng, thêm vào ưa thích và tìm hàng hóa.

Cả 3 chức năng trên đều có một kịch bản chung là khi nhấn chọn một trong ba chức

năng thì chương trình sẽ tiến hành gửi thông tin mã vạch vừa chụp được trên server,

yêu cầu server tìm các thông tin hàng hóa ứng với mã vạch đó. Sau khi xử lý yêu

cầu server sẽ trả kết quả này về cho client. Trên client sẽ hiển thị các thông tin này

dưới dạng một danh sách như hình phụ lục.

Page 260: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

260

Hình phụ lục 188 Màn hình danh sách hàng hóa ứng với một mã vạch nào đó

Khi nhấn chọn vào một dòng trên danh sách ta sẽ thực hiện chức năng ứng với chức

năng từ lần nhấn chọn bên ngoài màn hình chụp mã vạch như sau:

Ứng với chức năng thêm vào danh sách mua hàng: các thông tin của

một hàng hóa trên danh sách các hàng hóa ứng với mã vạch được chụp sẽ

được chuyển sang “Màn hình thêm hàng hóa cần mua”. Trong màn hình này

ta sẽ có 2 thao tác chính như sau:

Nhấn nút “Thêm” để tiến hành thêm thông tin này vào danh sách

hàng hóa cần mua. Sau khi chương trình xử lý thêm xong, ta có

thể nhập thêm thông tin của một hàng hóa khác nữa vào danh sách

hàng hóa cần mua.

Nếu chỉ muốn thêm một hàng hóa và xem liền danh sách cần mua

thì ta nhấn chọn “Thêm và Xem”.

Page 261: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

261

Hình phụ lục 189 Màn hình thêm thông tin của một hàng hóa vào danh sách hàng hóa cần mua

Ứng với chức năng thêm vào ưa thích: thông tin hàng hóa sẽ được lưu

thẳng vào danh sách các mặt hàng ưa thích và Màn hình danh sách các mặt

hàng ưa thích sẽ được hiển thị cho người dùng xem.

Hình phụ lục 190 Màn hình danh sách các hàng hóa ưa thích

Ứng với chức năng tìm hàng hóa: thông tin chi tiết của hàng hóa sẽ

được hiển thị ra cho người dùng xem.

Page 262: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

262

Hình phụ lục 191 Màn hình thông tin chi tiết của một hàng hóa

L.4 Thao tác trên màn hình tìm theo danh mục hàng hóa

Hình phụ lục 192 Màn hình tìm kiếm theo danh mục hàng hóa và loại hàng hóa tương ứng

Nhấn chọn icon trên màn hình chính để mở ra được màn hình lựa

chọn danh mục hàng hóa. Nhấn chọn một dòng trên Danh mục hàng hóa sẽ mở lên

Màn hình loại hàng hóa chứa tất cả danh sách của các loại hàng hóa ứng với một

danh mục hàng hóa nào đó. Ví dụ như trong danh mục hàng hóa là “Thực Phẩm

Page 263: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

263

Đông Lạnh” có các loại hàng hóa như “Các Loại Kem”, “Các Loại Lẩu Đông

Lạnh”…

Trên màn hình lựa chọn loại hàng hóa, khi nhấn chọn vào một dòng thì

chương trình sẽ mở ra màn hình danh sách hàng hóa nằm trong một loại hàng hóa

nào đó

Hình phụ lục 193 Màn hình danh sách hàng hóa

Và khi ta nhấn vào một dòng trên danh sách hàng hóa thì chương trình sẽ mở ra

màn hình chi tiết của hàng hóa đó.

Page 264: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

264

L.5 Thao tác trên màn hình tìm theo chuỗi

Hình phụ lục 194 Màn hình tìm kiếm hàng hóa theo chuỗi

Nhấn chọn icon trên màn hình chính, chương trình sẽ mở ra màn

hình tìm hàng hóa theo chuỗi để giúp người dùng có thể tìm thấy hàng hóa mà mình

cần tìm.

Trong màn hình này ngoài tìm kiếm bằng chuỗi ta còn có thể nhấn nút

để gọi màn hình chụp mã vạch để lấy chuỗi mã vạch qua bên màn hình tìm theo

chuỗi này để thực hiện việc tìm kiếm chính xác hơn.

Khi người dùng điền đầy đủ các thông tin cần tìm thì người dùng nhấn nút

để yêu cầu server tìm kiếm các mặt hàng nào thỏa mãn yêu cầu tìm

kiếm của người dùng và trả về danh sách kết quả cho người dùng.

Khi người dùng nhấn nút Menu trên máy sẽ có thêm 2 chức năng phụ đó là:

trợ giúp và thoát chương trình

Hình phụ lục 195 Menu của màn hình tìm kiếm hàng hóa theo chuỗi

Page 265: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

265

Khi ta nhấn chọn menu “Giúp Đỡ” chương trình sẽ mở ra màn hình

gợi ý giúp cho người dùng có thể thực hiện việc tìm kiếm chính xác hơn.

Hình phụ lục 196 Màn hình trợ giúp người dùng tìm kiếm hiệu quả hơn

Khi ta nhấn chọn menu “Thoát Chương Trình” thì sẽ thoát ứng dụng

eSaleShopping.

L.6 Thao tác trên màn hình tìm theo hệ thống siêu thị

Đây là chức năng hỗ trợ người dùng tìm kiếm các thông tin như:

Thông tin hệ thống siêu thị, siêu thị.

Bản đồ chỉ đường đến siêu thị nào đó hay đường đi đến siêu thị gần

nhất trong một hệ thống siêu thị.

Tìm kiếm hàng hóa đang được bán tại siêu thị theo các tiêu chí như:

tìm kiếm theo mã vạch, tìm kiếm theo chuỗi, tìm kiếm theo danh mục hàng

hóa.

L.6.1 Thao tác chính

Chọn biểu tượng từ màn hình chính ta sẽ tới được màn hình thể hiện

danh sách các hệ thống siêu thị như hình phụ lục 197

Page 266: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

266

Hình phụ lục 197 Màn hình tìm theo danh sách hệ thống các siêu thị

Tiếp tục ta chọn một logo của hệ thống siêu thị tương ứng, ví dụ như logo

của hệ thống siêu thị Metro ta sẽ được màn hình có thể hiện danh sách

các siêu thị con của hệ thống siêu thị Metro

Hình phụ lục 198 Màn hình danh sách siêu thị con của hệ thống siêu thị

Page 267: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

267

Khi nhấn chọn một siêu thị trong danh sách các siêu thị ta sẽ thấy các chức

năng như sau:

Thông tin của siêu thị được chọn.

Chỉ đường đi đến siêu thị.

Tìm hàng hóa của siêu thị đó theo chuỗi.

Tìm hàng hóa của siêu thị đó theo mã vạch.

Tìm hàng hóa của siêu thị đó theo danh mục.

Hình phụ lục 199 Các chức năng khi chọn vào một siêu thị trong một hệ thống siêu thị

L.6.2 Thao tác trên các chức năng trên một siêu thị được chọn

L.6.2.1 Thông tin siêu thị

Page 268: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

268

Hình phụ lục 200 Màn hình thông tin chi tiết của một siêu thị

Đây là chức năng thể hiện thông tin chi tiết của một siêu thị như tên, địa chỉ,

số điện thoại liên hệ, giờ mở cửa, chương trình của siêu thị, hay các thông tin hỗ trợ

vận chuyển lắp đặt, hỗ trợ thanh toán thẻ, thông tin các máy rút tiền có tại siêu thị.

Nhấn để xem thông tin bản đồ đường đi đến siêu thị.

Nhấn để thực hiện gọi điện thoại tới số điện thoại của siêu thị.

Nhấn vào vùng để hiển thị ra vùng thông tin khác chức

thông tin của siêu thị như: thông tin hỗ trợ vận chuyển lắp đặt…

L.6.2.2 Chỉ đường đến siêu thị

Page 269: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

269

Hình phụ lục 201 Màn hình thông tin bản đồ đường đi đến siêu thị

Đây là chức năng thể hiện bản đồ đường đi đến một siêu thị và có kết hợp

phần chỉ dẫn đường đi cụ thể.

Nhấn vào icon để mở ra vùng hướng dẫn chỉ dẫn đường đi cụ thể. Nhấn

lại icon một lần nữa để đóng lại vùng hiển thị này.

Nhấn Menu trên máy ta sẽ nhận được menu của ứng dụng bản đồ đường đi.

nhấn chọn “Chế Độ Xem” để hiển thị thêm 2 lựa chọn chế độ xem bản đồ là hình vẽ

hay hình vệ tinh.

Hình phụ lục 202 Menu của ứng dụng bản đồ đường đi đến siêu thị

L.6.3 Tìm hàng hóa siêu thị theo chuỗi

Đây là chức năng tìm kiếm hàng hóa theo một chuỗi nào đó. Hướng dẫn cách

thức thao tác trên màn hình tìm kiếm hàng hóa tìm theo chuỗi đã được chúng tôi

trình bày trong phần phụ lục L.5.

L.6.4 Tìm hàng hóa siêu thị theo mã vạch

Page 270: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

270

Khi chọn lựa chức năng này, chương trình sẽ chuyển sang Màn hình chụp mã

vạch như đã hướng dẫn ở phần phụ lục L.3.

L.6.5 Tìm hàng hóa siêu thị theo danh mục

Hình phụ lục 203 Màn hình tìm kiếm theo danh mục hàng hóa và loại hàng hóa tương ứng

Khi chọn chức năng này, chương trình sẽ chuyển sang Màn hình lựa chọn

danh mục hàng hóa để cho phép người dùng lựa chọn. Phần hướng dẫn thao tác với

Màn hình danh mục hàng hóa đã được trình bày trong phần phụ lục L.4.

L.7 Thao tác quản lý danh sách hàng hóa ưa thích

Người dùng nhấn chọn từ màn hình chính để mở màn hình danh sách

hàng hóa ưa thích. Đây là màn hình có chức năng xem danh sách các mặt hàng ưa

thích cũng như xem giá cả hiện thời của món hàng ưu thích nào đó hiện đang bán ở

siêu thị nào, giá cả bao nhiêu.

Khi người dùng nhấn chọn vào một dòng trong danh sách hàng hóa ưa thích,

một vùng hiển thị danh sách các hệ thống siêu thị hiện đang bán mặt hàng đó sẽ

được cập nhật từ server và mở ra như hình phụ lục 195. Để thu vùng này lại ta cần

nhấn nút .

Page 271: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

271

Hình phụ lục 204 Màn hình danh sách các mặt hàng ưa thích

L.8 Thao tác quản lý danh sách hàng hóa cần mua

Người dùng nhấn chọn từ màn hình chính để mở ra danh sách hàng

hóa cần mua. Đây là màn hình giúp ta quản lý được mặt hàng nào mua rồi, mặt

hàng nào cần mua thông qua 2 danh sách là Danh sách hàng hóa cần mua và Danh

sách hàng hóa đã được mua.

Hình phụ lục 205 Màn hình danh sách hàng hóa cần mua

Page 272: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

272

Khi người dùng đang đứng ở danh sách này mà nhấn chọn một hàng hóa nào

đó thì hàng hóa đó sẽ được di chuyển qua danh sách còn lại.

Người dùng nhấn nút Menu trên thiết bị sẽ thấy được 3 chức năng đó là:

Thêm hàng cần mua, Xóa hàng cần mua, Gửi tin hàng cần mua.

Hình phụ lục 206 Menu của màn hình danh sách hàng cần mua

L.8.1 Thao tác thêm hàng cần mua

Hình phụ lục 207 Màn hình thêm hàng hóa cần mua

Màn hình này giúp người dùng nhập các thông tin hàng hóa cần mua. Người

dùng nếu muốn chỉ thêm một hàng cần mua và xem danh sách hàng cần mua thì

nhấn nút “Thêm và Xem”, còn nếu muốn nhập nhiều lần thì nhấn nút “Thêm”.

L.8.2 Thao tác xóa hàng cần mua

Page 273: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

273

Hình phụ lục 208 Màn hình xóa hàng cần mua

Màn hình này giúp người dùng xóa một phần hoặc xóa hết danh sách hàng

hóa cần mua. Nếu muốn xóa một mặt hàng người dùng nhấn chọn vào một dòng,

chương trình sẽ hiện lên hộp thoại hỏi lại người dùng có thực sự muốn xóa mặt

hàng đó hay không. Còn người dùng nếu muốn xóa toàn bộ danh sách thì chỉ cần

nhấn nút “Xóa Hết”.

Hình phụ lục 209 Hộp thoại hỏi người dùng có thực sự muốn xóa một mặt hàng nào đó hay không

L.8.3 Thao tác gửi tin nhắn hàng cần mua

Page 274: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

274

Hình phụ lục 210 Màn hình gửi tin nhắn hàng cần mua

Đây là chức năng gửi tin nhắn SMS cho một người nào đó nhờ họ mua giùm

các mặt hàng có trong danh sách hàng hóa cần mua. Người dùng chỉ việc kiểm tra

lại nội dung tin nhắn lần cuối và nhấn nút gửi đi.

Page 275: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

275

Phụ lục M Các cấu trúc, mã lệnh, ứng dụng tham

khảo được sử dụng trong ứng dụng eSaleShopping

M.1 Bộ gõ Tiếng Việt IME

Đóng góp phần không nhỏ cho ứng dụng eSaleShopping đó chính là ứng

dụng bộ gõ Tiếng Việt để thực hiện tìm kiếm thông tin hàng hóa bằng Tiếng Việt.

Nhóm đã quyết định là dùng bộ gõ Tiếng Việt IME (đã được diễn đàn tinhte.com

giới thiệu gần đây - http://www.tinhte.com/threads/192466-Vietnamese-IME-bản-

1.9-bộ-gõ-tiếng-Việt-đầu-tiên-trên-Android) để có thể gõ được Tiếng Việt trên

Android và phục vụ cho chức năng tìm kiếm hàng hóa bằng Tiếng Việt.

Bộ gõ Tiếng Việt IME do tác giả Phạm Cao Trí phát triển và phát hành miễn

phí đối với người dùng tại địa chỉ http://code.google.com/p/vietnameseime/. Phiên

bản mới nhất là VietnameseIME-1.9.1 hỗ trợ 2 kiểu gõ Tiếng Việt là VNI và

TELEX rất tốt, giao diện đẹp. Ở phiên bản này tác giả đã cải tiến, thêm một số tính

năng mới như: hỗ trợ tốt cho các phiên bản Android (từ 1.5 đến 2.1), chỉnh độ rung

khi gõ phím, chỉnh âm lượng khi gõ phím, có tùy chọn màu sắc bàn phím, và chức

năng đặc sắc là hỗ trợ từ điển gợi ý Tiếng Việt kết hợp với chức năng tự tạo một từ

điển gợi ý cho riêng người dùng. Hình bên dưới là hình chụp màn hình gửi tin nhắn

SMS dùng bộ gõ Tiếng Việt IME để gõ tiếng Việt với 2 phiên bản Android là 1.5 và

2.1.

Page 276: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

276

Hình phụ lục 211 Màn hình sử dụng bộ gõ Tiếng Việt IME trên Android 1.5 và 2.1

M.2 Chụp mã vạch hàng hóa (barcode)

Trong ứng dụng eSaleShopping có chức năng chụp mã vạch của một hàng

hóa bất kỳ, sau đó lấy kết quả mã vạch phân tích được từ hình chụp gồm 13 chữ số

và tiến hành gửi mã vạch này lên server yêu cầu server trả về thông tin hàng hóa

ứng với mã vạch đó.

Trong quá trình tìm hiểu ý tưởng, công nghệ để hỗ trợ cho chức năng vừa

nêu, nhóm đã gặp nhiều khó khăn. Khó khăn lớn nhất là làm sao chụp được hình

ảnh của một mã vạch được in trên hàng hóa và phân tích hình ảnh này thành chuỗi

số để có thể gửi lên cho server yêu cầu tìm kiếm thông tin hàng hóa. Việc viết riêng

một chương trình chụp mã vạch là một điều không khả thi. Nhóm đã chuyển sang

tìm hiểu theo một hướng khác là tích hợp các module chụp mã vạch đã được công

bố trên mạng vào chương trình eSaleShopping. Sau nhiều lần tìm kiếm giải pháp

trên mạng, nhóm đã tìm thấy ZXing ("Zebra Crossing") một project mở với giấy

phép Apache License 2.0 (http://www.apache.org/licenses/LICENSE-2.0) được

công bố trên Google Code (http://code.google.com/p/zxing/). Khi tải về bộ mã

Page 277: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

277

nguồn của ZXing chúng tôi nhận thấy toàn bộ mã nguồn hỗ trợ cho nhiều nền tảng,

hệ điều hành khác nhau như RIM, iPhone, Android…

Hình phụ lục 212 Nội dung của một gói mã nguồn ZXing

Hình phụ lục 213 Mã nguồn ZXing dành cho HĐH Android

Tuy “gánh nặng” chụp mã vạch đã được giảm bớt nhưng việc áp dụng

project ZXing này vào ứng dụng cũng là một khó khăn không nhỏ do toàn bộ mã

nguồn được công bố hết sức “đồ sộ”. Để nắm bắt và ứng dụng được bộ mã nguồn

này thì lượng thời gian bỏ ra để tìm hiểu là không nhỏ. Sau một hồi lần tìm giải

pháp trên mạng, nhóm chúng tôi cũng tìm được một giải pháp thay thế đó chính là

nhờ chương trình Barcode Scanner chụp phân giải mã vạch và trả kết quả về cho

Page 278: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

278

ứng dụng eSaleShopping. Barcode Scanner cũng do nhóm ZXing phát triển (địa chỉ

tải về ứng dụng http://zxing.googlecode.com/files/BarcodeScanner3.1.apk). Việc

gọi thực thi Barcode Scanner để lấy kết quả mã vạch được thực hiện thông qua gọi

Intent cũng được nhóm ZXing hướng dẫn cụ thể tại:

http://code.google.com/p/zxing/wiki/ScanningViaIntent

public Button.OnClickListener mScan = new Button.OnClickListener() {

public void onClick(View v) {

Intent intent = new

Intent("com.google.zxing.client.android.SCAN");

intent.putExtra("SCAN_MODE", "QR_CODE_MODE");

startActivityForResult(intent, 0);

}

};

public void onActivityResult(int requestCode, int resultCode, Intent

intent) {

if (requestCode == 0) {

if (resultCode == RESULT_OK) {

String contents = intent.getStringExtra("SCAN_RESULT");

String format = intent.getStringExtra("SCAN_RESULT_FORMAT");

// Handle successful scan

} else if (resultCode == RESULT_CANCELED) {

// Handle cancel

}

}

}

Để tiện dụng hơn, nhóm chúng tôi đã dùng lớp IntentIntegrator.java và lớp

IntentResult.java (các lớp này được tiết kế bởi các tác giả: Sean Owen, Fred Lin,

Isaac Potoczny-Jones) để thực hiện việc gọi Intent kích hoạt chương trình Barcode

Scanner chụp ảnh mã vạch và yêu cầu lấy kết quả trả về thông qua các phương thức

initiateScan(…) và parseActivityResult(…) trên các Activity gọi và nhận kết

quả từ chương trình Barcode Scanner.

Cách gọi ứng dụng Barcode Scanner trên Activity ManHinhTimTheoMaVach:

việc gọi Intent được thực hiện thông qua sự kiện nhấn nút “Đọc Mã Vạch”

// button chụp barcode

btnReadBarcode.setOnClickListener(new OnClickListener() {

@Override

public void onClick(View v) {

IntentIntegrator.initiateScan(ManHinhTimTheoMaVach.this);

IntentIntegrator.initiateScan(ManHinhTimTheoMaVach.this,

Page 279: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

279

"Thông Báo",

"Đồng ý tải về chương trình Barcode Scanner không?",

"Đồng Ý", "Không");

}

});

Cách thức lấy kết quả trả về từ ứng dụng Barcode Scanner:

protected void onActivityResult(int requestCode, int resultCode, Intent

data) {

switch (requestCode) {

case IntentIntegrator.REQUEST_CODE: {

if (resultCode != RESULT_CANCELED) {

IntentResult scanResult =

IntentIntegrator.parseActivityResult(

requestCode, resultCode, data);

if (scanResult != null) {

String upc = scanResult.getContents();

TextView txtBarcodeResult = (TextView)

findViewById(R.id.TextViewBarcodeResult);

txtBarcodeResult.setText("" + upc);

// . . .

break;

}

}

Một điểm thú vị của 2 lớp IntentIntegrator.java và lớp IntentResult.java là

khi điện thoại không có sẵn chương trình đọc mã vạch là Barcode Scanner thì sẽ

xuất hiện thông báo và hỏi người dùng có muốn tải về ứng dụng Barcode Scanner

hay không. Nếu đồng ý tải về thì chương trình sẽ tìm kiếm ứng dụng Barcode

Scanner thông qua Android Market để tiến hành tải và cài đặt ứng dụng.

Nhóm chúng tôi rất hoan nghênh và cám ơn cộng đồng mã nguồn mở cũng

như các nhà lập trình đã phát triển và cung cấp những ứng dụng, project thật sự hay

và có chất lượng như bộ mã mở ZXing như đã đề cập ở trên.

M.3 Ứng dụng bản đồ và vị trí

M.3.1 Các tham số Google Map hỗ trợ tìm kiếm đường đi

Page 280: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

280

Việc Google mở rộng hỗ trợ chỉ đường đi cho Việt Nam là một điều thuận

lợi cho nhóm tích hợp phần chỉ đường đi này vào bản đồ và chỉ ra đường đi tới siêu

thị gần nhất. Thông tin yêu cầu đường đi sẽ được gửi lên Google với các tham số

theo quy định (http://mapki.com/wiki/Google_Map_Parameters). Sau khi tính toán

lộ trình đường đi, Google sẽ trả ra kết quả là một tập tin KML có cấu trúc dạng các

thẻ XML. Ta chỉ việc phân tích thông tin từ tập tin này để có được hướng dẫn chỉ

đường đi từ Google.

Sau đây là ví dụ mẫu về yêu cầu tìm đường đi từ 2 điểm có kinh độ và vĩ độ

biết trước và gửi yêu cầu lên Google tìm đường đi giữa 2 điểm ấy:

http://maps.google.com/maps?f=d&hl=en&saddr=10.75896,106.68257&daddr=10.

848731,106.773877&ie=UTF8&0&om=0&output=kml. Với saddr là thông tin

kinh độ, vĩ độ của điểm xuất phát; dsddr là thông tin kinh độ, vĩ độ của điểm cần

đến.

Nội dung của một tập tin KML được trả về từ Google

<?xml version="1.0" encoding="UTF-8"?><kml

xmlns="http://earth.google.com/kml/2.0"><Document><name>Nguyễn Trãi to

Unknown road</name><Style

id="roadStyle"><LineStyle><color>7fcf0064</color><width>6</width></LineSt

yle></Style><Snippet><![CDATA[<font size=+1><a

href="http://maps.google.com/maps?f=d&hl=en&saddr=10.75896,106.68257&dadd

r=10.848731,106.773877&ie=UTF8&om=0">Printable

view</a></font>]]></Snippet><Placemark><name>Head east on Nguyễn Trãi

toward Nguyen Bieu</name><description><![CDATA[go

0.2&#160;km]]></description><address>Nguyễn

Trãi</address><StyleMap><Pair><key>normal</key><Style><IconStyle><Icon><h

ref>http://maps.gstatic.com/intl/en_ALL/mapfiles/kml/paddle/go.png</href>

</Icon><hotSpot x="0.500000" y="0.000000" xunits="fraction"

yunits="fraction"

/></IconStyle><ListStyle><ItemIcon><href>http://maps.gstatic.com/intl/en_

ALL/mapfiles/kml/paddle/go-lv.png</href> . . .

M.3.2 Thể hiện đường đi trên bản đồ Google Map

Nhóm đã tham khảo và áp dụng bài viết chỉ dẫn vẽ đường đi lên bản đồ

GoogleMap là: Android - Driving Direction (Route Path) tại địa chỉ http://csie-

tw.blogspot.com/2009/06/android-driving-direction-route-path.html để hiện thực

hóa chức năng chỉ đường đi đến siêu thị.

Page 281: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

281

Hình phụ lục 214 Ứng dụng vẽ đường đi trên bản đồ Google Map trong eSaleShopping

Nhóm đã tham khảo 2 lớp là Direction.java (truyền tham số lên Google) và

MyOverlay.java (vẽ đường đi trên bản đồ) để áp dụng vào ứng dụng

eSaleShopping. Bên cạnh tham khảo 2 lớp này, nhóm đã tiến hành xử lý lại thuật

toán đọc tập tin KML để có thể lấy về cũng như tính toán ra đường đi ngắn nhất đến

một siêu thị gần nhất.

M.3.3 Cách thức tìm vị trí thiết bị thông qua GPS hoặc mạng

Để chương trình có thể xác định được vị trí hiện tại nhóm đã tham khảo bài

viết “Android Examples - Using Location API”, được viết bởi tác giả Marko

Gargenta tại địa chỉ http://marakana.com/forums/android/android_examples/42.html

và mã nguồn tham khảo của bài viết tại địa chỉ

http://marakana.com/static/tutorials/LocationDemo.zip

Đồng thời nhóm cũng có tham khảo bài viết của thành viên có nickname là

jagtap.jj1 trên diễn đàn anddev.org với phần bài viết là “app with GPS-enable but

the device is indoor” (http://www.anddev.org/app_with_gps-

enable_but_the_device_is_indoor-t8997.html) để tham khảo 2 phương:

Page 282: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

282

startLocationReceiving(), stopLocationReceiving() cho việc khởi động hay

dừng các thiết bị nhận tín hiệu xác định vị trí hiện tại.

M.4 Ứng dụng EndlessList

Khái niệm EndlessList đã được chúng tôi trình bày trong phụ lục J. Ở phần

này chúng tôi chỉ trình bày 2 giải pháp tiêu biểu mà chúng tôi có dịp tham khảo và

áp dụng vào ứng dụng eSaleShopping.

M.4.1 Giải pháp của M.Murphy

Mark Murphy hiện làm việc cho Commons Ware, email liên hệ:

[email protected]

Tác giả có cung cấp sẵn mã nguồn cũng như hướng dẫn sử dụng project

CWAC EndlessAdapter tại địa chỉ http://github.com/commonsguy/cwac-endless.

Nhóm đã có dịp dùng và ứng dụng EndlessAdapter của M.Murphy vào bài toán

EndlessList. Việc ứng dụng EndlessList vào tuy đã giải quyết được vấn dề của

EndlessList nhưng bên cạnh đó EndlessAdapter còn tồn tại một lỗi nhỏ đó là vòng

tròn xoay thể hiện tiến trình download dữ liệu mới từ server để gắn thêm vào

ListView hiển thị bị lỗi. Chúng hiển thị không có kiểm soát trên màn hình

ListView. Do mã nguồn của ứng dụng được tác giả đóng gói thành một tập tin .jar

nên nhóm chúng tôi không thể hiệu chỉnh lại lỗi này nên đã tiến hành tìm kiếm giải

pháp khác cho vấn đề EndlessList. Hình bên dưới thể hiện ứng dụng chạy của

EndlessAdapter và bug lỗi của nó.

Page 283: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

283

Hình phụ lục 215 Hình minh họa và bug lỗi cũa EndlessAdapter

M.4.2 Giải pháp của Evan Charlton

Tác giả Evan Charlton hiện là sinh viên năm 4 của học viện công nghệ

Rochester (http://evancharlton.com/about/). Trong bài viết công bố trên mạng của

tác giả (http://evancharlton.com/thoughts/lazy-loading-images-in-a-listview/) nhóm

thấy đây là một nguồn tham khảo rất hữu ích. Ứng dụng Magnatune

(http://evancharlton.com/projects/magnatune/downloads/) của tác giả không những

giải quyết rất tốt vấn đề của EndlessList đồng thời cũng có cách giải quyết việc

download hình ảnh minh họa về máy một cách linh hoạt và uyển chuyển. Ứng dụng

Magnatune sẽ tải về máy thông tin (chuỗi ký tự) tên các bài hát, album, thông tin

nhạc sĩ ca sĩ từ server về hiển thị trước trên ListView và hình ảnh sẽ được download

về tại thẻ nhớ và khi download được hình nào thì sẽ hiển thị lên trên ListView ngay

sau đó như hình minh họa bên dưới.

Nhóm chúng tôi đã dùng lại các hàm thiết kế của tác giả để phục vụ cho ứng

dụng eSaleShopping là:

Page 284: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

284

Dùng lại các lớp HTTPQueue.java, HTTPThread.java,

RemoteImageView.java: phục vụ cho việc chạy ngầm tải hình ảnh từ server

về dưới dạng danh sách hàng đợi dùng Thread.

Hiệu chỉnh lớp MagnatuneAPI.java nhưng có chỉnh sửa lại cho phù

hợp để phục vụ việc lưu vết thư mục tạm lưu trữ hình ảnh từ server về.

Hiệu chỉnh lớp LazyAdapter.java phục vụ hiển thị một item trên

ListView.

Hiệu chỉnh lớp LazyActivity.java, đây là lớp mà nhóm tham khảo kỹ

nhất và thực hiện viết lại một số tính năng cho phù hợp vì trong lớp này chứa

giải pháp giải quyết vấn đề của EndlessList cực kỳ hiệu quả đó là dùng Task

không đồng bộ. Vấn đề dùng Task không đồng bộ đã được nhóm trình bày

tại phụ lục J.

Hình phụ lục 216 Hình minh họa của ứng dụng Magnatune

M.5 Mã nguồn android-misc-widgets

Đây là một project được viết bởi tác giả có nickname là pskink

(http://code.google.com/u/pskink/) được đăng tải trên Google Code tại địa chỉ

Page 285: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

285

http://code.google.com/p/android-misc-widgets/. Đây là một project chứa một loạt

các hiệu ứng chuyển động (animation) và widget mới rất tiện dụng và hữu ích.

Nhóm chúng tôi đã áp dụng một số lớp, thiết kế trong projec android-misc-widget

để làm phong phú thêm cho ứng dụng eSaleShopping.

M.5.1 Hiệu ứng hoạt cảnh

Nhóm chúng tôi đã dùng lại hết các lớp tạo hiệu ứng chuyển động vào ứng

dụng eSaleShopping. Đó là các ứng với hình minh họa bên dưới.

Hình phụ lục 217 Các lớp tạo hiệu ứng chuyển động được dùng lại trong ứng dụng eSaleShopping

M.5.2 Các widget mới

Nhóm đã dùng lại 2 widget mới đó có tên là Panel và Switcher để làm cho

ứng dụng eSaleShopping thêm phần phong phú hơn.

Page 286: Tìm hiểu hệ điều hành android và xây dựng ứng dụng minh họa

286

Hình phụ lục 218 Ứng dụng Panel tạo khung chỉ đường đi trên bản đồ trong eSaleShopping

Hình phụ lục 219 Ứng dụng Switcher tạo lựa chọn hình thức bán hàng trong eSaleShopping