Tim hieu lap trinh Android.pdf
description
Transcript of Tim hieu lap trinh Android.pdf
1
TRƯỜNG ĐẠI HỌC BÁCH KHOA HÀ NỘI
Viện Công nghệ Thông tin và Truyền thông
BÁO CÁO ĐỒ ÁN 2
Đề tài:
Tìm hiểu hệ điều hành Android và xây dựng ứng dụng
minh họa
Giáo viên hướng dẫn: ThS. Lương Mạnh Bá
Sinh viên thực hiện:
1. Lê Đức Anh SHSV: 20109202
2. Nguyễn Văn Bảo SHSV: 20109209
3. Bùi Văn Chiến SHSV: 20109214
HÀ NỘI – 11/2012
2
MỤC LỤC I- MỞ ĐẦU .......................................................................................................................................... 4
II- HỆ ĐIỀU HÀNH ANDROID. .......................................................................................................... 4
1. Giới thiệu chung ................................................................................................................................ 4
2. Kiến trúc hệ điều hành Android ........................................................................................................ 4
III- PHÁT TRIỂN ỨNG DỤNG CHO HỆ ĐIỀU HÀNH ANDROID. .............................................. 6
1. Tổng quan ứng dụng Android ........................................................................................................... 6
2. Môi trường, công cụ hỗ trợ phát triển ............................................................................................... 6
2.1. Môi trường phát triển .................................................................................................................... 6
2.2. Cài đặt plugin ADT cho Eclipse ................................................................................................... 7
2.3. Cài đặt Android SDK .................................................................................................................... 8
2.4. Cài đặt SDK APIs ......................................................................................................................... 9
2.5. Cài đặt AVD sử dụng AVD Manager ......................................................................................... 10
2.6. Công cụ gỡ rối DDMS (Dalvik Debug Monitor Server) ............................................................ 12
2.7. Cài đặt AVD sử dụng dòng lệnh ................................................................................................. 13
2.8. Sử dụng Android Emulator ......................................................................................................... 14
2.8.1. Cài đặt ứng dụng vào Emulator .............................................................................................. 14
2.8.2. Làm việc với Disk images trong Emulator .............................................................................. 16
2.8.3. Emulator Networking .............................................................................................................. 16
2.8.4. Sử dụng Emulator Console ..................................................................................................... 18
3. Phát triển ứng dụng trên Android.................................................................................................... 23
3.1. Tạo chương trình Hello World .................................................................................................... 24
3.2. Thành phần giao diện trong Android .......................................................................................... 30
3.2.1. View: ....................................................................................................................................... 30
3.2.2. ViewGroup : ............................................................................................................................ 30
3.2.3. Một số thành phần giao diện thông dụng ................................................................................ 30
3.2.3.1. Button: ................................................................................................................................. 30
3.2.3.2. ImageButton: ....................................................................................................................... 31
3.2.3.3. ImageView: ......................................................................................................................... 31
3.2.3.4. TextView: ............................................................................................................................ 31
3.2.3.5. EditText: .............................................................................................................................. 32
3.2.3.6. CheckBox: ........................................................................................................................... 32
3.2.3.7. RadioButton và RadioGroup: ............................................................................................. 33
3
3.2.3.8. ListView: ............................................................................................................................. 34
3.2.3.9. AutoCompleteTextView: ...................................................................................................... 35
3.2.3.10. Menu Options: .................................................................................................................... 36
3.2.3.11. ProgressBar: ....................................................................................................................... 37
3.3. Thao tác với luồng ...................................................................................................................... 39
3.4. Thao tác cơ sở dữ liệu sử dụng SQLite ....................................................................................... 41
3.5. Activity và Intent ........................................................................................................................ 43
3.6. Bộ nhớ chia sẻ ............................................................................................................................. 45
3.6.1. Shared Preferences ................................................................................................................. 45
3.6.2. Internal Storeage: ................................................................................................................... 47
3.6.3. External Storeage .................................................................................................................... 48
IV- ỨNG DỤNG MINH HỌA .......................................................................................................... 49
V- KẾT LUẬN ................................................................................................................................. 55
VI- TÀI LIỆU THAM KHẢO........................................................................................................... 56
4
I- MỞ ĐẦU
Hiện nay, nhu cầu sử dụng các thiết bị di động ngày càng lớn, kéo theo sự phát triển của các
nền tảng di động. Trên thị trường đã có rất nhiều hệ điều hành di động như iOS, Window
Phone, BlackBerry, Symbian, LiMo, ... Trong đó, nổi bật phải kể đến là hệ điều hành
Android. Với đặc tính là nền tảng mã nguồn mở và hoàn toàn miễn phí, Android tạo nhiều
thuận lợi cho các nhà phát triển thiết kế ứng dụng di động của mình, giúp nền tảng này ngày
càng phát triển hơn nữa..
II- HỆ ĐIỀU HÀNH ANDROID.
1. Giới thiệu chung
Android là bộ công cụ phần mềm mã nguồn mở dựa trên nhân Linux 2.6 dành cho nền
tảng di động được phát triển bởi Google và Open Handset Alliance (tổ chức đa quốc gia
do Google lập, nhằm xây dựng một chiếc điện thoại tốt hơn dựa trên Android). Hàng
trăm triệu thiết bị Android trên toàn cầu hiện nay đã minh chứng cho sự phát triển mạnh
mẽ của nền tảng này.
Những đặc tính nổi trội của hệ điều hành Android so với các hệ điều hành di động khác:
Android thực sự mở, một nền tảng phát triển dựa trên Linux và mã nguồn mở:
Các nhà sản xuất thiết bị và các nhà phát triển yêu thích Android do họ có thể sử
dụng và tùy chỉnh nó mà không phải trả tiền bản quyền.
Cung cấp các dịch vụ nền tảng phát triển ứng dụng.
Hỗ trợ ngôn ngữ lập trình Java, C/C++.
Dễ dạng xây dựng, chỉnh sửa, nâng cấp ứng dụng.
Tối ưu hóa cho các thiết bị với nguồn năng lượng thấp và bộ nhớ hạn chế.
Đồ họa và âm thanh chất lương cao.
Tương thích với nhiều kiến trúc phần cứng khác nhau.
Được hỗ trợ mạnh mẽ từ Google..
2. Kiến trúc hệ điều hành Android
5
Linux Kernel: Android được xây dựng dựa trên nhân Linux và là một hệ điều hành đa nhiệm
thực sự. Nhân Linux cung cấp tầng ảo hóa phần cứng cho Android, giúp Android có thể
thích hợp với đa dạng nền tảng phần cứng.
Libraries: Các thư viện chia sẻ toàn bộ được viết bằng C/C++, được biên dịch phù hợp với
đặc thù kiến trúc phần cứng sử dụng bởi các thiết bị di động, được cài đặt sẵn bởi nhà sản
xuất. Một số thư viện quan trọng như:
Surface Manager: Quản lý cửa sổ, hiển thị, hiệu ứng.
2D, 3D Graphics: Thư viện đồ họa sử dụng phần cứng 3D (nếu có) và công cụ hỗ trợ
nhanh (nếu không).
Media codecs: Android chơi được nhiều định dạng video và âm thanh như: AAC,
AVC, H.263, MP3, MP4...
SQLite database: Công cụ cơ sở dữ liệu gọn nhẹ.
Browser engine: để hỗ trợ xây dựng ứng dụng duyệt web, Android sử dụng Webkit
libraries.
Android Runtime: gồm thư viện lõi Java, máy ảo Dalvik (tối ưu hóa cho bộ nhớ hạn chế, cho
phép nhiều VM chạy đồng thời và tạo thuận lợi cho hệ điều hành lõi (Linux) trong bảo mật
và độc lập giữa các tiến trình)
Application Framework: tầng này cung cấp thành phần cấp cao để tạo ứng dụng, mặc định
được cài sẵn, nhưng nhà phát triển có thể kế thừa bằng những thành phần của mình. Một số
thành phần quan trọng:
6
Activity manager: điều khiển vòng đời ứng dụng.
Content providers: những đối tượng dữ liệu được đóng gói cần thiết để chia sẻ giữa
các ứng dụng (ví dụ như là danh bạ)
Resource manager: quản lý tài nguyên của ứng dụng (những thứ không phải là code
như xâu kí tự, hình ảnh, âm thanh...)
Location manager: cho phép xác định vị trí thiết bị dựa vào GPS và Google Maps.
Notification manager: quản lý thông báo đến người dùng (ví dụ như: có tin nhắn, lịch,
cảnh báo...)
Application: Android cung cấp một số các ứng dụng tiêu chuẩn đi kèm thiết bị như: ứng
dụng gọi điện, danh bạ, SMS, Email, bản đồ, trình duyệt, danh bạ, ... cho nhà phát triển.
III- PHÁT TRIỂN ỨNG DỤNG CHO HỆ ĐIỀU HÀNH ANDROID.
1. Tổng quan ứng dụng Android
Trong Android, chỉ có một ứng dụng tiền cảnh (foreground application) chiếm toàn bộ màn
hình và chờ đợi để người dùng tương tác (ví dụ như ứng dụng Home mỗi khi người dùng mở
máy).
Khi người dùng chạy một ứng dụng, Android khởi động và đưa nó ra tiền cảnh. Từ ứng dụng
này, người dùng có thể đi đến ứng dụng khác, màn hình khác v.v. Tất cả chương trình và
màn hình được ghi vào application stack bởi Activity manager. Người dùng có thể dùng nút
Back để trở lại màn hình trước đó.
Một ứng dụng là một hoặc nhiều activity cộng thêm một tiến trình Linux chứa nó.
Các ứng dụng được quản lý chặt chẽ việc sử dụng tài nguyên nhằm tránh lãng phí, xung đột,
đảm bảo hiệu năng hệ thống.
Ứng dụng Android có phần mở rộng là Apk
Thành phần chính được dùng trong ứng dụng Android
Activities: một Activity thể hiện một màn hình giao diện người dùng
Services: Thành phần chạy ngầm, không có giao diện, dùng để chạy các tác vụ lâu
dài.
Content providers: quản lý dữ liệu chia sẻ, truy vẫn dữ liệu. Ví dụ việc lấy dữ liệu
trong danh bạ
Broadcast receiver: thành phần thông báo của hệ thống, đón bắt các sự kiện.
2. Môi trường, công cụ hỗ trợ phát triển
2.1.Môi trường phát triển
- Eclipse IDE
- Plugin cho Eclipse – ADT
7
- Android SDK
2.2.Cài đặt plugin ADT cho Eclipse
Cách 1:
1. Mở Eclipse, vào help > Install New Software… > chọn Add và điền https://dl-
ssl.google.com/android/eclipse/ vào ô Location
2. Chọn thành phần Deverloper Tool và cài đặt
Cách 2:
1. Tải ADT-20.0.3.zip mới nhất trên http://developer.android.com/tools/sdk/eclipse-adt.html
2. Giải nén, copy toàn bộ file trong thư mục features và plugins vào thư mục tương ứng của
thư mục cài đặt Eclipse
8
2.3.Cài đặt Android SDK
1. Tải Android SDK dạng file zip tại http://developer.android.com/sdk/index.html
2. Giải nén ra thư mục bất kỳ
3. Mở Eclipse, chọn Window > Preferences, chọn mục Android
4. Tại SDK Location, điền đường dẫn đến thư mục Android SDK vừa giải nén, chọn
OK
9
2.4.Cài đặt SDK APIs
1. Trong Eclipse, vào Window > Android SDK Manager
2. Chọn nền tảng API và tiến hành cài đặt
10
2.5.Cài đặt AVD sử dụng AVD Manager
1. Trong Eclipse, vào Window > AVD Manager > New…
2. Điền tên máy tại ô Name, chọn nền tảng tại Target, dung lượng thẻ nhớ tại SD
Card, kích thước màn hình tại Skin, cấu hình chi tiết tại Hardware,… sau đó ấn
Create AVD.
3. Để khởi động AVD, chọn AVD trong list > Start…
11
Figure 1: Giao diện Emulator khi khởi động xong
12
2.6.Công cụ gỡ rối DDMS (Dalvik Debug Monitor Server)
DDMS cho phép theo dõi hoạt động trong Emulator, hỗ trợ sửa lỗi, xem, dừng các tiến trình, truy
cập hệ thống file, giả lập gửi tin nhắn, gọi điện, GPS, …
13
2.7.Cài đặt AVD sử dụng dòng lệnh
Từ cửa sổ dòng lệnh đi vào <sdk>/tools
Hiển thị Target đã được cài đặt, sử dụng lệnh: “android list targets” . Nó sẽ quét trong 2 thư mục
<sdk>/platforms/ và <sdk>/add-ons/ và hiển thị kết quả. Ví dụ:
Để tạo AVD mới, sử dụng lệnh:
android create avd -n <name> -t <targetID> [-<option> <value>]
name : tên AVD
targetID: id của target trong hệ thống (như ví dụ trên)
[-<option> <value>]: các tùy chọn khác
Ví dụ: android create avd –n my_android –t 2 --skin WXGA800
Các file AVD sẽ được chứa mặc định ở ~/.android/avd/ (với Linux/Mac), <user>\.android\avd
(với Window). Để tùy biến ta có thể thêm tùy chọn –p <đường dẫn>
Để tạo SD Card thêm tùy chọn -c <size>[K|M]
Để xóa AVD, sử dụng lệnh: android delete avd -n <name>
Khởi động AVD: sử dụng lệnh emulator -avd <avd_name> [<options>]
14
2.8.Sử dụng Android Emulator
Android Emulator để thiết kế, phát triển, thử nghiệm, sửa lỗi ứng dụng Android mà không cần sử
dụng thiết bị thật. Nó mô phỏng hầu hết phần cứng cũng như phần mềm giống thiết bị thật ngoại
trừ việc không thể gọi điện như máy thật.
2.8.1. Cài đặt ứng dụng vào Emulator
Đối với môi trường Eclipse + ADT ứng dụng tự động được cài khi Build
Nếu không sử dụng môi trường Eclipse + ADT, ta dùng công cụ adb với cú pháp như sau:
adb install <đường dẫn đến file .apk>
Trong trường hợp có nhiều Emulator đang chạy ta xác định Emulator thông qua số hiệu cổng của
nó. Ví dụ để cài ứng dụng cho Emulator có số hiệu cổng 5554 ta làm như sau:
adb –s emulator-5554 install <đường dẫn đến file .apk>
Nói thêm về quá trình tạo ra file .apk
15
Figure 2: Quá trình tạo file apk
Công cụ đóng gói aapt (Android Asset Packaging Tool) thu thập các file tài nguyên
(như là các file .xml), biên dịch chúng và đồng thời tạo ra file R.java (dùng để quản lý
các thuộc tính được khai báo trong file xml).
16
Công cụ aidl (Android Interface Definition Language) chuyển đổi .aidl interfaces (nếu
có) vào trong Java interfaces.
R.java, mã nguồn, cùng với file aidl được biên dịch bởi Java complier cho ra .class file
Dex tools sẽ chuyển các file class (kể cả của bên thứ 3) thành Dalvik bytecode
Các tài nguyên không được biên dịch (ví dụ: hình ảnh), các tài nguyên đã được biên dịch,
cùng với .dex file được đóng gói thành file apk sử dụng apkbuilder
File apk được đăng ký dạng Debug hoặc Release, nếu ứng dụng được đăng ký dạng
Release cần qua bộ zipalign giúp giảm bộ nhớ sử dụng khi chạy trên thiết bị.
2.8.2. Làm việc với Disk images trong Emulator
++File ảnh mặc định (Default image files):
Nếu khi Emulator khởi động mà không tìm thấy file ảnh dữ liệu người dùng (user data image),
nó sẽ tạo mới từ một phiên bản mặc định trong SDK và file ảnh là file chỉ đọc.
Có thể thay đổi đường dẫn đến user data image (file userdata.img) bằng cách thêm tùy chọn lúc
khởi động là –system <đường dẫn>. Ta cũng có thể thay đổi tên của user data image bằng cách
thêm tùy chọn khởi động –initdata <file>
++File ảnh khi chạy (Runtime images):
Tại thời điểm chạy, Emulator đọc và ghi dữ liệu vào hai đĩa ảnh userdata-qenu.img và
sdcard.img – mô phỏng phân vùng dữ liệu người dùng và thiết bị lưu trữ gắn ngoài (như SD
Card) trên máy thật. Như file ảnh mặc định ở trên, ta cũng có thể thay đổi đường dẫn đến hai đĩa
ảnh này với tùy chọn khởi động –data <đường dẫn> và –sdcard <đường dẫn>, nếu đường dẫn
chỉ có tên file, Emulator sẽ tìm trong thư mục làm việc hiện tại.
++File ảnh tạm (Temporary Images):
Emulator tạo hai file ảnh có thể ghi và xóa chúng khi tắt máy đó là:
Bản sao có thể ghi của hệ thống Android
Phân vùng /cache
Phân vùng /cache được khởi tạo rỗng sử dụng bởi trình duyệt để lưu trang web và ảnh. Emulator
cung cấp tùy chọn –cache <file> để lưu trữ /cache khi tắt máy.
2.8.3. Emulator Networking
++Không gian địa chỉ:
Mỗi thực thể Emulator chạy sau một router/firewall ảo, cô lập với giao diện mạng của máy phát
triển và với internet; nó không thể nhìn thấy máy của nhà phát triển và các Emulator khác. Nó
chỉ nhìn thấy các kết nối thông qua router/firewall.
17
Router ảo của mỗi thực thể quản lý không gian địa chỉ 10.0.2/24. Địa chỉ trong không gian nay
đã được đặt trước bởi Emulator/router như sau:
Địa chỉ Mô tả
10.0.2.1 Router/gateway address
10.0.2.2 Địa chỉ loopback gán với 127.0.0.1 trên máy
tính nhà phát triển
10.0.2.3 DNS server đầu tiên
10.0.2.4/ 10.0.2.5/10.0.2.6 DNS server thứ 2, 3, 4 (nếu cần)
10.0.2.15 Địa chỉ Emulator trong mạng của nó
127.0.0.1 Địa chỉ loopback Emulator trong mang của nó
Tất cả thực thể Emulator đều được gán giống nhau và giống như trên.
++Sử dụng Network Redirection:
Để giao tiếp với Emulator cần phải thiết lập network redirection cho router của nó.
Cài đặt sử dụng Emulator console:
1. telnet localhost <port number> : port number là số hiệu cổng của Emulator (thường thấy
trên góc trái cửa sổ Emulator), khi đã kết nối thành công thì đến bước 2.
2. add <protocol> : <host-port> : <guest-port> (protocol có thể là TCP hoặc UDP, host-
port là cổng tại máy nhà phát triển, guest-port là cổng của hệ thống mô phỏng)
Ví dụ: redir add tcp:8080:80 sẽ tạo network redirection để mỗi khi thông tin TCP đến
127.0.0.1:8080 tại máy nhà phát triển nó sẽ tự động chuyển tiếp đến hệ thống mô phỏng tại địa
chỉ 10.0.2.15:80;
Cài đặt sử dụng ADB
ADB (Android Debug Bridge) tool cung cấp việc chuyển tiếp cổng.
Với ví dụ trên, cú pháp là: adb forward tcp:8080 tcp:80
++Cấu hình cài đặt Emulator DNS:
Lúc khởi động, Emulator đọc danh sách DNS server mà hệ thống của nhà phát triển đang dùng,
sau đó ánh xạ tối đa 4 địa chỉ DNS server vào trong địa chỉ mô phỏng 10.0.2.3, 10.0.2.4,
10.0.2.5, 10.0.2.6.
18
Nếu khởi động từ dòng lệnh, ta có thể thêm tùy chọn –dns-server <danh sách địa chỉ ngăn cách
bởi dấu phẩy> để thiết lập DNS cho Emulator.
++Kết nối giữa các Emulator:
Để làm được điều này, chúng ta sẽ sử dụng network redirection
Giả sử hai Emulator A và B cùng chạy trên máy nhà phát triển, giả sử A là server, B kết nối đến
A, ta sẽ làm như sau:
1. A sẽ nghe tại 10.0.2.15:<server_port>
2. redir add <protocol> : <local_port> : <server_port>
3. B sẽ kết nối đến 10.0.2.2:<local_port>
++Gọi điện, gửi tin SMS đến Emulator khác:
Emulator tự đông chuyển tiếp cuộc gọi hay SMS bằng số hiệu cổng. Để gọi điện hay gửi SMS
đến Emulator khác, ta bật ứng dụng gọi điên hoặc nhắn tin lên, thay số máy thật bằng số hiệu
cổng của Emulator cần kết nối đến.
2.8.4. Sử dụng Emulator Console
Mỗi thực thể Emulator đang hoạt động cung cấp một Console cho phép truy vấn, điều khiển môi
trường thiết bị mô phỏng. Ví dụ: dùng Console để quản lý port redirection (đã nói đến ở phần
trước), các sự kiện, … khi ứng dụng chạy trên Emulator. Để truy cập Console ta dùng telnet để
kết nối tới cổng của Emulator
Cú pháp: telnet localhost <console-port>
Minh họa:
19
Một thực thể Emulator có một cặp cổng kề nhau: console port và adb port, adb port sẽ lớn hơn.
Ví dụ console port là 5554 thì adb port là 5555
20
Lưu ý: Emulator nghe kết nối từ cổng trong khoảng từ 5554-5587, và chỉ chấp nhận kết nối tư
local host
++Post Redirection:
Cú pháp: redir <list | add | del>
Chi tiết:
Lệnh con Mô tả
list Hiển thị port redirection
add <protocol> : <host_port> : <guest_port> Thêm mới một port redirection
del <protocol> : <host_port> Xóa một port redirection
++Geo Location Provider Emulation (giả lập cung cấp vị trí):
Chúng ta có thể sử dụng Console để thiết lập vị trí địa lý cung cấp cho ứng dụng chạy trong
Emulator sử dụng lệnh geo. Lệnh này gửi một thông số vị trí GPS đến Emulator có thể kèm hoặc
không định dạng NMEA 0183 (chuẩn để truyền dữ liệu giữa các thiết bị điện tử trong đó có
GPS).
Cú pháp geo <fix | nmea>
21
Chi tiết:
Lệnh con Mô tả
fix <longitude> <latitude> [<altitude>] Cung cấp kinh độ, vĩ độ [độ cao (theo mét)]
nmea <một câu> Gửi câu NMEA 0183 đến Emulator nếu như nó
được gửi từ một GPS modem mô phỏng (câu
phải bắt đầu bằng ‘$GP’, hiện tại chỉ hỗ trợ
‘GPGGA’ và ‘$GPRCM’)
++ Device Power Characteristics (Mô phỏng tính chất nguồn của thiết bị)
Cú pháp: power <display|ac|status|present|health|capacity>
Chi tiết:
Lệnh con Mô tả
display Hiển thị pin và trạng thái nạp điện
ac <on|off> Thiết lập trạng thái nạp AC
status <unknown|charging|discharging|not-
charging|full>
Thay đổi trạng thái của pin
present <true|false> Thiết lập có pin hoặc không
health
<unknown|good|overheat|dead|overvoltage|failure>
Thiết lập sức khỏe pin
capacity <percent> Thiết lập dung lượng pin còn lại (0-100)
++ Network Status (trạng thái mạng)
Cú pháp: network status
++ Network Delay Emulation (mô phỏng trễ mạng)
Cú pháp tùy chọn khi khởi động:
emulator -netdelay <giá trị>
Khi Emulator đang chạy, kết nối vào Console và dùng lệnh: network delay <giá trị>
Ví dụ: network delay gprs
Chi tiết:
22
Giá trị Mô tả (đơn vị mili giây)
gprs GPRS (min 150, max 550)
edge EDGE/EGPRS (min 80, max 400)
umts UMTS/3G (min 35, max 200)
none (min 0, max 0)
<num> Số chính xác
<min> : <max> Khoảng tự đặt
++ Network Speed Emulation (mô phỏng tốc độ mạng)
Cú pháp tùy chọn khi khởi động:
emulator -netspeed <giá trị>
Khi Emulator đang chạy, kết nối vào Console và dùng lệnh: network speed <giá trị>
Chi tiết:
Giá trị Mô tả (đơn vị kilobits/giây)
gsm GSM/CSD (Up: 14.4, down: 14.4)
hscsd HSCSD (Up: 14.4, down: 43.2)
gprs GPRS (Up: 40.0, down: 80.0)
edge EDGE/EGPRS (Up: 118.4, down: 236.8)
umts UMTS/3G (Up: 128.0, down: 1920.0)
hsdpa HSDPA (Up: 348.0, down: 14400.0)
full Không giới hạn (Up: 0.0, down: 0.0)
<num> Up = down = number
<up>:<down> Sô chính xác
++Telephony Emulation (mô phỏng thoại)
Cú pháp: gsm <call|accept|busy|cancel|data|hold|list|voice|status>
Lệnh con Mô tả
call <phonenumber> Cuộc gọi đến từ phonenumber
23
accept <phonenumber> Chấp nhận cuộc gọi từ phonenumber thay đổi
trạng thái sang “active” (nếu trạng thái hiện tại
là “waiting” hoặc “held”)
busy <phonenumber> Đóng cuộc gọi đi đến phonenumber, thay đổi
trạng thái thành “busy” (nếu trạng thái hiện tại
là “waiting”)
cancel <phonenumber> Kết thúc gọi đi hoặc đến phonenumber
data <state> Thay đổi trạng thái kết nối dữ liệu GPRS về
state:
unregistered – Không có mạng
home – Trong mạng chủ
roaming – Đang roaming
searching – Đang tìm mạng
denied – Chỉ gọi khẩn cấp
off – giống 'unregistered'
on – giống 'home'
hold Thay đổi trang thái thành “held” <nếu trạng
thái hiện tại là “active” hoặc “waiting”>
list Hiển thị danh sách các cuộc gọi + trạng thái
của nó
voice <state> Thay đổi trạng thái kết nối GPRS voice về
state:
unregistered – Không có mạng
home – Trong mạng chủ
roaming – Đang roaming
searching – Đang tìm mạng
denied – Chỉ gọi khẩn cấp
off – giống 'unregistered'
on – giống 'home'
status Báo cáo trạng thái hiện tại của GSM voice/data
++ SMS Emulation (mô phỏng tin nhắn SMS)
Cú pháp: sms send <senderPhoneNumber> <textmessage>
++ VM State (thay đổi trạng thái máy ảo trên Emulator)
Cú pháp: vm <start|stop|status>
3. Phát triển ứng dụng trên Android
24
3.1.Tạo chương trình Hello World
1. Mở Eclipse > File > New > Project chọn Android Application Project
2. Điền tên ứng dụng…
3. Ấn next liên tiếp, đến phần đặt tên cho Activity, và Layout sau đó Finish
25
Cấu trúc chương trình Hello World
26
Các thư mục:
Src: chứa toàn bộ mã nguồn chương trình
Gen: chứa file R.java khi biên dịch
Assets: chứa các file âm thanh streaming…
Res: chứa các tài nguyên của chương trình
Drawable: các file ảnh
Layout: chứa file xml, quyết định giao diện chương
trình
Menu: chứa file xml thiết kế cho menu
Values: chứa các tài nguyên khác như xâu kí tự,
theme style …
File Manifest: định nghĩa cấu trúc, các thành phần
yêu cầu của ứng dụng
27
Ví dụ file manifest:
Một số thành phần trong file manifest:
Uses-sdk: xác định SDK version min, max mà ứng dụng hỗ trợ
Uses-feature: đặc tả thành phần phần cứng nào yêu cầu bởi ứng dụng (ví dụ: Audio,
Bluetooth, Camera, Location, …)
Support-screens: kích thước màn hình ứng dụng
Uses-permission: định nghĩa quyền người dùng với các thành phần ứng dụng yêu cầu (ví
dụ: <uses-permission android:name=”android.permission. BLUETOOTH”/>)
Applicaton: đặc tả dữ liệu cho ứng dụng (ví dụ: tiêu đề, icon, theme…)
Activity: mô tả cho Activity chính và các Activity khác
Hình ảnh file main.xml
28
File HelloWorld.java
29
Kết quả chạy chương trình HelloWorld
30
3.2.Thành phần giao diện trong Android
3.2.1. View:
Giao diện người dùng trong ứng dụng Android được cấu thành từ các đối tượng gọi là View và
View Group. Các thành phần này đều được xuất phát từ lớp view cơ sở gọi và được gọi là
widget.
Để hiển thị giao diện thì trong hàm onCreate của Activity cần gọi hàm
setContentView(R.laylout.main) để tải giao diện từ file main.xml.
3.2.2. ViewGroup :
Để tạo các giao diện phức tạp cần dùng ViewGroup để nhóm các View theo ý nhà phát triển và
được khai báo trong các file XML.
Một số ViewGroup thông dụng
++LinearLayout: sắp xếp các thành phần theo dòng hoặc theo cột
++RelativeLayout: sắp xếp bằng cách mô tả vị trí giữa thành phần này so với thành phần khác
++TableLayout: sắp xếp các thành phần giống như lưới gồm có các hàng, các cột
3.2.3. Một số thành phần giao diện thông dụng
3.2.3.1.Button:
Nút bấm được khai báo trong file XML bằng thẻ <Button>. Ví dụ:
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="hello"
android:onClick="click"/>
khai báo một nút bấm có ID là button, chiều rộng, chiều cao vừa với nội dung, chữ hiển thị trên
nút là hello, phương thức xử lý sự kiện ấn nút là phương thức click() (được định nghĩa trong mã
nguồn)
Cấu trúc phương thức click():
public void click(View button)
31
{
// lam viec gi do
}
Nếu không dùng android:onClick ta sẽ khai báo trong mã nguồn như sau:
Button myButton = (Button)findViewById(R.id.button);
myButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
// lam viec gi do
}
});
3.2.3.2.ImageButton:
Giống như Button, ta chỉ thay tên thẻ là <ImageButton> và khai thêm trong file XML nguồn ảnh
và không có phần text, ảnh được chứa trong thư mục res/drawable:
android:src="@drawable/icon"
3.2.3.3.ImageView:
Dùng để hiển thị ảnh, ví dụ khai báo trong file XML:
<ImageView
android:id="@+id/image"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:src="@drawable/image"/>
Ảnh có ID là image, chiều rộng, chiều cao vừa màn hình, nguồn là image.png
3.2.3.4.TextView:
Dùng để hiển thị văn bản, ví dụ:
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
32
android:text="@string/hello_world"/>
sẽ hiển thị nội dung nằm trong "@string/hello_world"
3.2.3.5.EditText:
Hiển thị ô nhập liệu, ví dụ:
<EditText
android:id="@+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
3.2.3.6.CheckBox:
Hiển thị ô chọn, ví dụ:
<CheckBox
android:id="@+id/check"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="unChecked"/>
để xử lí sự kiện CheckBox này được chọn hay bỏ chọn trong mã nguồn ta làm như sau:
CheckBox cb = (CheckBox)findViewById(R.id.check);
cb.setOnCheckedChangeListener(new OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
// làm gì đó
}
});
33
Một số phương thức khác như: isChecked(), setChecked(boolean) …
3.2.3.7.RadioButton và RadioGroup:
Các nút chọn, ví dụ:
<RadioGroup
android:id="@+id/group"
android:layout_height="wrap_content"
android:layout_width="wrap_content">
<RadioButton
android:id="@+id/radio1"
android:text="radio1"
/>
<RadioButton
android:id="@+id/radio2"
android:text="radio2"
/>
</RadioGroup>
Để xử lý sự kiện trên RadioGroup ta làm như sau, ví dụ:
RadioGroup r = (RadioGroup)findViewById(R.id.group);
switch (r.getCheckedRadioButtonId()) {
case R.id.radio1:
// làm gì đó
break;
case R.id.radio2:
// làm gì đó
break;
}
34
3.2.3.8.ListView:
Hiển thị danh sách, ví dụ:
<ListView
android:id="@+id/list"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
/>
Ví dụ thêm phần tử vào danh sách:
String[] data = {"1", "2", "3", "4"};
List<String> model = new ArrayList<String>();
ListView list = (ListView)findViewById(R.id.list);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, model);;
list.setAdapter(adapter);
adapter.add(data[0]);
adapter.add(data[1]);
adapter.add(data[2]);
adapter.add(data[3]);
Đầu tiên ta lấy gán ListView vào biến list sau đó tạo đối tượng thuộc kiểu List<kiểu dữ liệu của
List> ví dụ là model, khởi tạo một đối tượng ArrayAdapter (ví dụ là adapter) làm cầu nối
chuyển dữ liệu vào list, dùng câu lệnh list.setAdapter(adapter) để nối. Để thêm dữ liệu vào list ta
dùng câu lệnh adapter.add(dữ liệu).
Kết quả minh họa:
35
Để xử lý sự kiện click vào các dòng trong ListView ta làm như sau:
list.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
// làm gì đó (arg2 là vị trí click trong list)
}
});
3.2.3.9.AutoCompleteTextView:
Ví dụ trong file XML:
<AutoCompleteTextView
android:id="@+id/edit"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:completionThreshold="3" />
Trong mã nguồn:
String[] data = {"Dai hoc BKHN", "Dai hoc KTQD"};
36
AutoCompleteTextView a = (AutoCompleteTextView)findViewById(R.id.edit);
a.setAdapter(new ArrayAdapter<String>
(this, android.R.layout.simple_dropdown_item_1line, data));
Kết quả minh họa:
3.2.3.10. Menu Options:
Để tạo menu option ta khai báo file XML trong thư mục res > menu. Ví dụ my_menu.xml:
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/abc"
android:title="My Menu"
/>
</menu>
Trong mã nguồn:
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.my_menu, menu);
return true;
}
37
Kết quả minh họa:
Để xử lí sự kiện click vào menu item ta làm như sau:
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if(item.getItemId() == R.id.abc)
{
// làm gì đó
}
return super.onOptionsItemSelected(item);
}
3.2.3.11. ProgressBar:
++ProgressBar ngầm định của Activity
Cách tạo:
38
Trong hàm onCreate() khai báo requestWindowFeature(Window.FEATURE_PROGRESS); trước
hàm setContentView(R.layout.main)
Để hiển thị ProgressBar dùng lệnh: setProgressBarVisibility(true);
Để thiết lập giá trị cho ProgressBar dùng lệnh: setProgress(int giá trị); (Tối đa 10000)
Minh họa:
++ProgressBar sử dụng khai báo trong file XML
<ProgressBar
android:id="@+id/progress"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
Minh họa:
Để ProgressBar ở dạng ngang ta thêm:
style="@android:style/Widget.ProgressBar.Horizontal"
39
Trong mã nguồn ta làm như sau:
ProgressBar pg = (ProgressBar)findViewById(R.id.progress);
pg.setProgress(giá trị); // tối đa 100
Hình minh họa:
3.3.Thao tác với luồng
Trong Android có luồng chính cập nhật giao diện là UI Thread và các luồng phụ Background
Để tạo một luồng Background ta làm như sau:
Khai báo lớp luồng với Runable:
private Runnable MyTask = new Runnable() {
public void run() {
// làm gì đó
}
};
Tạo đối tượng luồng:
Thread my_thread = new Thread(MyTask);
Để khởi động luồng dùng lệnh: my_thread.start();
Để trao đổi dữ liệu giữa UI Thread và luồng Background ta có các cách sau:
++Dùng phương thức runOnUiThread()
40
Ví dụ:
runOnUiThread(new Runnable() {
public void run() {
// thao tác có thể sử dụng dữ liệu của UI Thread
}
});
++Sử dụng Handler:
Đối tượng Handler sẽ bắt các thông điệp từ luồng Background cho vào hàng đợi thông điệp, và
có thể thao tác với dữ liệu UI Thread bất cứ lúc nào.
Ví dụ:
Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
super.handleMessage(msg);
//làm gì đó với msg, có thể lấy dữ liệu bằng msg.getData()
}
};
Trong luồng Background ta có thể làm như sau:
Message msg = handler.obtainMessage();
// msg có thể chứa nhiều loại dữ liệu ví dụ: msg.setData(Data Object)
handler.sendMessage(msg);
++Sử dụng AsyncTask:
AsyncTask có các phương thức làm việc với luồng Background và UI Thread
Phương thức doInBackground(): thực hiện các công việc trong luồng Background, để truyền dữ
liệu nó dùng hàm publishProgress(dữ liệu).
Phương thức onProgressUpdate(Kiểu dữ liệu … values);
41
Trong đó kiểu dữ liệu trùng với kiểu của dữ liệu trong publishProgress(), phương thức có thể
dùng values để cập nhật UI Thread.
Ngoài ra còn có hai phương thức là: onPreExecute() thực hiện với dữ liệu trên UI Thread, được
gọi trước khi thực hiện doInBackground() và phương thức onPostExecute() thực hiện với dữ
liệu trên UI Thread sau khi thực hiện doInBackground().
Ví dụ:
Tạo lớp MyAsyncTask kế thừa từ AsyncTask < ? ,? , ? > ? tương ứng các kiểu dữ liệu trong các
phương thức
class MyAsyncTask extends AsyncTask<Void, Integer, Void> {
int progress = 0;
@Override
protected Void doInBackground(Void... params) {
// làm gì đó
publishProgress(Kiểu Integer);
}
return null;
}
@Override
protected void onPostExecute(Void result) {
// làm gì đó
super.onPostExecute(result);
}
@Override
protected void onProgressUpdate(Integer... values) {
// làm gì đó với values
super.onProgressUpdate(values);
}
}
Để thực hiện ta gọi: new MyAsyncTask().execute();
3.4.Thao tác cơ sở dữ liệu sử dụng SQLite
Ta sẽ sử dụng lớp SQLiteOpenHelper để tạo, kết nối đến cơ sở dữ liệu:
Tạo một lớp kế thừa từ SQLiteOpenHelper ví dụ:
42
class MyHelper extends SQLiteOpenHelper {
public MyHelper(Context context) {
super(context, TÊN CSDL, null, PHIÊN BẢN CSDL BẮT ĐẦU TỪ 1);
// TODO Auto-generated constructor stub
}
@Override
public void onCreate(SQLiteDatabase db) {
// TODO Auto-generated method stub
db.execSQL(CÂU LỆNH TẠO BẢNG DỮ LIỆU);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
{
// TODO Auto-generated method stub
}
}
Tạo đối tượng thuộc lớp MyHelper kết nối CSDL: MyHelper helper = new MyHelper(this);
Mở CSDL để ghi ta tạo một đối tượng SQLiteDatabase ví dụ:
SQLiteDatabase db = helper.getWritableDatabase();
Mở CSDL để đọc: db = helper.getReadableDatabase();
Đóng cơ sở dữ liệu dùng: helper.close();
++Để chèn dữ liệu vào bảng ta làm như sau:
Tạo một đối tượng ContentValues ví dụ: ContentValues cv = new ContentValues();
Sau đó dùng lệnh put đưa dữ liệu vào cv, ví dụ: cv.put(tên cột, dữ liệu);
43
Dùng lệnh insert để đưa dữ liệu vào CSDL ví dụ:
db.insert(tên bảng, String nullColumnHack, cv);
nullColumnHack có thể là null, do SQL không cho phép chèn một dòng trống hoàn toàn nên nếu
để là null mà cv cũng null thì không được, cần cung cấp một tên cột được phép null là
nullColumnHack (được thay bởi tên cột nào đó trong bảng).
++Để xóa dữ liệu trong bảng ta dùng lệnh:
public int delete (String table, String whereClause, String[] whereArgs)
table là tên bảng
whereClause: mệnh đề WHERE
whereArgs: các tham số cho whereClause
++Để xóa database ta dùng lệnh:
public static boolean deleteDatabase (File file)
3.5.Activity và Intent
Trong một ứng dụng Android sẽ bao gồm nhiều Activity, mỗi Activity sử dụng câu lệnh
setContentView() để hiển thị ra một giao diện. Để từ một Activity này gọi đến Activity khác ta
sử dụng Intent. Intent bao gồm các thông số chính là Action (hành động mà Activity sẽ thực
hiện) và Data (dữ liệu cho việc thực thi Action).
Để khởi động Activity mới ta dùng lệnh:
Intent i = new Intent (action, data);
startActivity(i);
ví dụ một số action:
ACTION_CALL (gọi điện) sử dụng data là tel:số điện thoại
ACTION_VIEW (hiển thị nội dung, có thể là hình ảnh, âm thanh, web, bản đồ ..) với data là
đường dẫn đến nội dung cần hiển thị.
Chương trình có thể yêu cầu cần phải khai báo quyền trong file Android Manifest
Ví dụ data xem toàn bộ danh bạ: “content://contacts/people/”
44
Data xem bản đồ tại một vị trí tọa độ xác định: “geo: kinh độ, vĩ độ”
Minh họa việc gọi điện:
Intent i = new Intent(Intent.ACTION_CALL, Uri.parse("tel:1234"));
startActivity(i);
Để thực hiện được việc này, ta cần khai báo quyền trong AndroidManifest
<uses-permission android:name="android.permission.CALL_PHONE"/>
Minh họa xem bản đồ
Intent i = new Intent(Intent.ACTION_VIEW, Uri.parse("geo:21.007599,105.842929"));
startActivity(i);
Ngoài cách cung cấp Data như trên có thể còn có cách để truyền dữ liệu giữa các Activity:
45
Activity1.putExtra(“key”, Giá trị), Activity1.putExtra(Bundle data) … (Bundle là kiểu dữ liệu
gói có thể chứa được nhiều kiểu dữ liệu khác)
Activity được gọi sẽ lấy thông tin bằng lệnh:
getIntent().getExtra(), getIntent.getAction(), …
Một cách khai báo Intent khác là new Intent(context, <?>.class)
Context là ngữ cảnh của ứng dụng
<?>.class là lớp Activity người dùng tự định nghĩa
Trong trường hợp này ta phải khai báo thêm Activity trong file Manifest
Nếu chúng ta muốn nhận một kết quả trả về nào đó từ một Activity được gọi, ta không dùng lệnh
startActivity(Intent) mà dùng lệnh
startActivityForResult(Intent, requestCodeID)
khi đó ta phải override phương thức
onActivityResult(int requestCode, int resultCode, Intent data)
Nếu Activity được gọi thực hiện thành công resultCode sẽ là Activity.RESULT_OK, nếu thất bại
sẽ là activity.RESULT_CANCEL, tùy từng trường hợp ta có hành động tương ứng.
3.6.Bộ nhớ chia sẻ
Để lưu trữ dữ liệu trong Android ngoài cách sử dụng SQLite Database như đã nói ở trên, còn có
các cách sau:
3.6.1. Shared Preferences: Lưu trữ dữ liệu nguyên thủy bằng cặp key-value
Trong trường hợp này ta sẽ sử dụng lớp Shared Preferences, có hai phương thức để lấy đối tượng
Shared Preferences là:
getSharePreferences(): nếu có nhiều file preference, tham số đầu tiên là tên file
getPrefernces(): nếu chỉ có một file preference
Để ghi vào ta mở Shared Preferences.Editor bằng lệnh edit(), thêm vào bằng lệnh putBoolean(),
putString(), … sau đó gọi lệnh commit() để hoàn tất.
46
Đọc dữ liệu dùng lệnh getBoolean(), getString(), …
Ví dụ minh họa:
TextView text;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.ducanh);
text = (TextView)findViewById(R.id.text);
SharedPreferences sp = getSharedPreferences("demo", 0);
Editor editor = sp.edit();
editor.putString("color", "green");
editor.commit();
Button btnGetColor = (Button)findViewById(R.id.btnGetColor);
btnGetColor.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
// TODO Auto-generated method stub
SharedPreferences sp = getSharedPreferences("demo", 0);
text.setText("Color: "+ sp.getString("color", null));
}
});
}
47
File demo.xml được lưu trong thư mục Data > data > ứng dụng > shared_prefs
Nôi dung file demo.xml
3.6.2. Internal Storeage:
Lưu trữ dùng bộ nhớ trong, chỉ có thể dùng bởi ứng dụng tạo ra nó, khi hủy cài đặt ứng dụng nó
sẽ bị xóa theo.
Để tạo file dùng lệnh openFileOutput(FILENAME, MODE), câu lệnh trả về đối tượng
FileOutputStream
Để ghi ta dùng lệnh write() sau đó close() để hoàn tất.
Để đọc ta dùng lệnh openFileInput() tham số là tên file nó sẽ trả lại đối tượng FileInputStream,
sau đó ta dùng lệnh read(), dùng lệnh close() để đóng.
Ta có thể thêm file trong thời điểm đang tạo ứng dụng bằng cách copy vào thư mục res/raw/
Mở dùng lệnh openRawResourcce(R.id.<fileID>) nó sẽ trả về đối tượng InputStream
Một số câu lệnh khác:
48
getFileDir(): đường dẫn đến file đã lưu.
deleteFile(): xóa file.
fileList(): trả về mảng các file được lưu trữ
3.6.3. External Storeage: Lưu trữ sử dụng bộ nhớ mở rộng
Để kiểm tra tình trạng xem bộ nhớ mở rộng có thể đọc ghi ta dùng lệnh
getExternalStorageState()
Với API >= 8 ta dùng lệnh getExternalFileDir() để mở file, có tham số type là loại thư mục con
trong bộ nhớ mở rộng, ví dụ : DIRECTORY_MUSIC.
Với API <=7 ta dùng lệnh getExternalStorageDirectory() để mở file. File được lưu trong thư mục
/Android/data/<package_name>/files/, thư mục này bị xóa với API >=8;
Để tạo ra file không bị xóa khi hủy cài ứng dụng ta có thể dùng
getExternalStoragePublicDirectory() với API >=8 và getExternalStorageDirectory() với API <=
7 (lưu vào các thư mục như là Music, Ringtone, …)
49
IV- ỨNG DỤNG MINH HỌA
1. Giới thiệu ứng dụng
Bài báo cáo xin trình bày minh họa ứng dụng học từ mới với các chức năng:
Thêm, sửa xóa, tìm kiếm từ mới
Tạo một bài kiểm tra nhỏ với số câu được nhập bởi người dùng, có thể chọn chế
độ có giới hạn thời gian hoặc là không.
2. Thiết kế ứng dụng
Ứng dụng Android được tạo thành từ các Activity (các màn hình tương tác với người
dùng), các lớp giao diện sẽ được kế thừa từ lớp Activity gốc, giao diện được định nghĩa
trong các file XML riêng biệt.
Đầu tiên là giao diện màn hình chính của ứng dụng như sau:
Màn hình có TextView “Xin chào”, hình chào mừng và các nút (Button) để thêm, tìm
kiếm từ mới, vào mục tạo bài kiểm tra, một nút trợ giúp cho biết số từ có trong ứng dụng
và một nút thoát khỏi ứng dụng.
Trong file XML ta khai báo một Linearlayout với thuộc tính Vertical xếp các nội dung
theo chiều dọc. Để tiện lợi, ta sẽ chỉ định phương thức sẽ thực hiện khi nhấn nút ngay
trong file XML (main.xml) chi tiết như sau:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="Xin chào !" android:background="#1589FF" android:textColor="#FFFC17" android:textSize="20dp"/>
50
<ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/welcome"/> <Button android:id="@+id/home_add" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="Thêm từ mới" android:textColor="#0000FF" android:onClick="clickAdd"/> <Button android:id="@+id/home_search" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="Tìm kiếm" android:textColor="#0000FF" android:onClick="clickSearch"/> <Button android:id="@+id/home_test" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="Bài kiểm tra" android:textColor="#0000FF" android:onClick="clickTest"/> <Button android:id="@+id/home_help" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="Trợ giúp" android:textColor="#0000FF" android:onClick="clickHelp"/> <Button android:id="@+id/home_quit" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="Thoát" android:textColor="#0000FF" android:onClick="clickQuit"/> </LinearLayout>
File java chính sẽ có nội dụng như sau: package apt.tutorial.newword;
import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.view.View;
51
public class NewWord extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
public void clickAdd(View v)
{
Intent add_word = new Intent(this, Add_Word.class);
startActivity(add_word);
}
public void clickSearch(View v)
{
Intent search_word = new Intent(this, Search_Word.class);
startActivity(search_word);
}
public void clickTest(View v)
{
Intent test = new Intent(this, Test_Word.class);
startActivity(test);
}
public void clickHelp(View v)
{
Intent help = new Intent(this, Help.class);
startActivity(help);
}
public void clickQuit(View v)
{
finish();
}
}
Phương thức clickAdd(View v) được gọi khi nhấn nút “Thêm từ mới” khi đó nó sẽ khởi
tạo một đối tượng Intent gọi đến class Add_Word tức là gọi màn hình thêm từ mới và
thực hiện bằng phương thức startActivity().
Bằng các kĩ thuật tương tự ta có được các màn hình như sau:
52
53
Trong ứng dụng minh họa này ta sẽ sử dụng SQLite để lưu trữ từ mới làm nguồn từ cho bài kiểm
tra và lưu trữ kết quả kiểm tra.
Ta tạo một lớp ví dụ là MyDBHelper kế thừa từ lớp SQLiteOpenHelper. Lớp này sẽ cho phép
thao tác chèn, sửa, xóa, truy vấn bảng dữ liệu. Bảng dữ liệu được tạo trong hàm
onCreate(SqliteDatabase db) bằng câu lệnh db.execSQL(“chuỗi lệnh tạo bảng”). Ta cũng viết
trong lớp này các hàm chèn, sửa, xóa, các câu lệnh truy vấn, cập nhật từ mới. Thao tác sử dụng
phương thức getReadableDatabase(), hoặc getWriteableDatabase() (trả lại đối tượng thuộc lớp
SqliteDatabase ). Ví dụ phương thức thêm từ mới: public boolean insert(String word, String description) { if(!isExist(word)) { ContentValues cv = new ContentValues(); cv.put(COL1_TABLE1, word); cv.put(COL2_TABLE1, description); getWritableDatabase().insert(TABLE1, COL2_TABLE1, cv); updateTotal(true); return true; } return false;
}
Phương thức xóa từ: public void delete(String word) { getWritableDatabase().delete(TABLE1, COL1_TABLE1+ " =?", new String[] { word }); updateTotal(false);
}
54
Phương thức cập nhật từ: public void update(String word, String new_description) { ContentValues cv = new ContentValues(); cv.put(COL2_TABLE1, new_description); getWritableDatabase().update(TABLE1, cv, COL1_TABLE1 + " =? ", new String [] {word});
}
Lấy toàn bộ dữ liệu trong bảng trả về dạng con trỏ: public Cursor fetchAll(String table) { Cursor c = null; String query = null; if(table.equalsIgnoreCase(TABLE2)) { query = "SELECT * FROM " + table +";"; c = getReadableDatabase().rawQuery(query, null); } else if(table.equalsIgnoreCase(TABLE1)) { query = "SELECT * FROM " + table + " WHERE "+ COL1_TABLE1+ " <>?"; c = getReadableDatabase().rawQuery(query, new String [] {"__"}); } return c;
}
Với chức năng tạo một bài kiểm tra có giới hạn thời gian, để cập nhật thời gian trên màn hình ta
sẽ tạo luồng mới để đếm thời gian. Trong bài báo cáo này minh họa sử dụng lớp AsyncTask để
tạo luồng Background và thao tác với giao diện chính như sau: class MyAsyncTask extends AsyncTask<Void, Integer, Void> { int time_update = 0; @Override protected Void doInBackground(Void... params) { // TODO Auto-generated method stub while(time_update > 0) { SystemClock.sleep(1000); time_update--; publishProgress(time_update); } return null; } @Override protected void onProgressUpdate(Integer... values) { // TODO Auto-generated method stub super.onProgressUpdate(values); time_view.setText("Time "+ second2minute(values[0])); }
55
@Override protected void onPreExecute() { // TODO Auto-generated method stub super.onPreExecute(); time_update = TIME_PER_TASK*numberTask; } @Override protected void onPostExecute(Void result) { // TODO Auto-generated method stub super.onPostExecute(result); flag = false; task.setText("Hết giờ ! Ấn kết thúc để xem kết quả !"); answer.setEnabled(false); btn.setText("Kết thúc"); }
}
Hàm onPreExecute() thực hiện các công việc trước khi chạy luồng background và có thể thao tác
với dữ liệu trên luồng chính, trong trường hợp này là gán giá trị cho biến time_update.
Hàm doInBackground() làm các công việc của luồng Background và gửi dữ liệu đến giao diện
bằng phương thức publishProgress(), trong ví dụ này là gửi biến đếm đến giao diện.
Hàm onProgressUpdate() nhận dữ liệu từ luồng background và cập nhật lên giao diện, trong
trường hợp ví dụ là cập nhật thời gian lên giao diện.
Hàm onPostExecute() thực hiện các công việc sau khi luồng background thực hiện xong, trong ví
dụ thì nó đưa ra thông báo hết giờ và khóa các giao diện không cho người dùng nhập câu trả lời.
56
V- KẾT LUẬN
Với đặc tính mạnh mẽ là một nền tảng mở, lại được Google hỗ trợ cùng các công cụ tiện lợi,
việc phát triển ứng dụng trên hệ điều hành Android có rất nhiều thuận lợi cho các nhà phát
triển thỏa sức sáng tạo những ứng dụng phục vụ nhu cầu đa dạng của cuộc sống.
VI- TÀI LIỆU THAM KHẢO
1. Pramatic - Hello Android – 2008
2. Beginning Android 2 - Mark L.Murphy – 2010
3. Android Deverloper Website : developer.android.com