Đối với Window Mobile là một công nghệ của Microsoft và hoàn toàn đóng đối với người dùng, nhà phát triển ứng dụng chỉ dựa hoàn toàn vào công nghệ mà Microsoft cung cấp, còn Symbian thì
Trang 1NHẬN XÉT CỦA GIẢNG VIÊN HƯỚNG DẪN
Ngày Tháng Năm
Giảng Viên Hướng Dẫn
(Ký và ghi rõ họ tên)
Trang 2NHẬN XÉT CỦA GIẢNG VIÊN PHẢN BIỆN
Ngày Tháng Năm
Giảng Viên Phản Biện
(Ký và ghi rõ họ tên)
Trang 3LỜI CẢM ƠN
Chúng em xin chân thành cảm ơn các thầy cô trong khoa Công Nghệ Thông Tin cùng toàn thể các thầy cô trường Đại Học Sư Phạm Kỹ Thuật Tp.HCM đã truyền đạt cho chúng em những kiến thức quý giá trong suốt những năm học vừa qua
Chúng em xin chân thành cảm ơn Thầy Nguyễn Minh Đạo đã tận tình hướng dẫn, chỉ bảo chúng em trong suốt quá trình thực hiện đề tài
Cuối cùng tôi xin cảm ơn các bạn trong khoa Công Nghệ Thông Tin, những người
đã giúp đỡ, chia sẽ kiến thức, tài liệu trong suốt quá trình thực hiện nghiên cứu đề tài.Trong phạm vi khả năng cho phép, chúng em đã rất cố gắng để hoàn thành đề tài một cách tốt nhất Song, chắc chắn sẽ không tránh khỏi những thiếu sót Chúng em kính mong nhận được sự cảm thông và những ý kiến đóng góp của quý thầy cô và các bạn
Nhóm sinh viên thực hiện Nguyễn Chí Tâm
Nguyễn Phi Cường
MỤC LỤC
Trang 4DANH MỤC HÌNH
Mở đầu
Hiện nay ngành công nghiệp phần mềm đang rất phát triển và ngành công nghiệp phần mềm trên điện thoại di động cũng không nằm ngoài xu thế đó Tuy còn nhiều hạn chế trong phần cứng của điện thoại di động nhưng nó đã thể hiện được sức mạnh của
Trang 5mình trong rất nhiều các lĩnh vực khác nhau như giải trí, các tiện ích, thanh toán điện
tử v.v… Ngành công nghệ phần mềm di động vẫn còn khá non trẻ ở Việt Nam vì vậy việc nghiên cứu và phát triển các ứng dụng trên di động là rất cần thiết
Các hệ điều hành như Window Mobile, Symbian… phần nào cũng gây ít nhiều khó khăn cho những ai có ý định xây dựng các ứng dụng trên nó Đối với Window Mobile là một công nghệ của Microsoft và hoàn toàn đóng đối với người dùng, nhà phát triển ứng dụng chỉ dựa hoàn toàn vào công nghệ mà Microsoft cung cấp, còn Symbian thì việc cấu hình để có thể lập trình trên nó cũng vô vàn khó khăn, đặc biệt là
nó sử dụng ngôn ngữ C/C++ để làm nền tảng lập trình rõ ràng là không thuận tiện trong việc phát triển ứng dụng
Xuất phát từ nhu cầu thực tế đó, Google đã mạnh dạn nghiên cứu và đưa ra một nền tảng hệ điều hành mới, đó chính là Android Một nền tảng hệ điều hành mã nguồn
mở hoàn toàn và dựa vào một ngôn ngữ lập trình rất mạnh là Java để phát triển ứng dụng Chính vì Android hỗ trợ Java ngay từ trong nền tảng của nó, nên việc viết ứng dụng, ngay cả sử dụng các chức năng của phần cứng là hoàn toàn dễ dàng thông qua việc sử dụng bộ công cụ hỗ trợ lập trình được cung cấp hoàn toàn miễn phí, là Android SDK
Nhóm thực hiện nhận thấy nhu cầu của con người trong lĩnh vực giải trí trên di động ngày càng cao và Android chính là nền tảng ứng dụng có thể phát triển trong
tương lai Chính vì vậy nhóm thực hiện chọn đề tài “Xây dựng ứng dụng 3D với Android” nhằm hiểu rõ về các kĩ thuật lập trình trên thiết bị động, đặc biệt là các kĩ
thuật xây dựng đồ họa 3D trên di động để có thể tạo nên một game 3D hoàn chỉnh.Nhưng vì thời gian, cũng như năng lực của nhóm có hạn, cho nên chỉ giới hạn ở việc tìm hiểu cách thức hoạt động, nghiên cứu cơ bản các chức năng, sử dụng bộ công
cụ Android SDK và một số hàm chức năng của OpenGL ES để vẽ một số hình ảnh 3D
cơ bản mục đích nghiệm thu quá trình tìm hiểu
Trang 6Đề tài bao gồm:
Phần A: Xây dựng ứng dụng 3D với Android
Chương 1: Tổng quan về ứng dụng trên Android
Chương 2: Các thành phần cơ bản của một ứng dụng trên Android
Chương 3: Thiết kế giao diện
Tài liệu tham khảo
PHẦN A: XÂY DỰNG ỨNG DỤNG 3D VỚI ANDROID
Chương 1: Tổng quan về ứng dụng trên android
1.1Lược sử về Android:
Android được phát hành phiên bản đầu tiên 11/11/2007, là một môi trường hệ điều hành hoàn chỉnh dựa trên hệ điều hành nhân Linux V2.6 Lúc đầu, đích triển khai đối với Android là lĩnh vực điện thoại di động, gồm các loại điện thoại thông minh và các loại thiết bị điện thoại kiểu gập chi phí thấp Tuy nhiên, phạm vi đầy đủ các dịch vụ điện toán của Android và sự hỗ trợ chức năng phong phú của nó có tiềm năng mở rộng
Trang 7ra ngoài thị trường điện thoại di động Android còn có thể hữu ích đối với các nền tảng
và ứng dụng khác
Nền Android là sản phẩm của Open Handset Alliance (Liên minh thiết bị cầm tay mở), một tập đoàn các tổ chức cùng hợp tác với nhau để xây dựng nên một loại điện thoại di động tốt hơn Tập đoàn do Google đứng đầu này gồm các nhà vận hành (điện thoại) di động, các nhà sản xuất thiết bị cầm tay, sản xuất linh kiện, các nhà cung cấp nền và giải pháp phần mềm và các công ty tiếp thị Từ một quan điểm phát triển phần mềm, Android trở thành trung tâm của thế giới mã nguồn mở và rất có tiềm năng phát triển
Thiết bị cầm tay có khả năng Android đầu tiên trên thị trường là thiết bị G1 do HTC sản xuất và được bán trên T-Mobile Nó trở nên sẵn có sau gần một năm đồn đại, khi mà các công cụ phát triển phần mềm sẵn có duy nhất chỉ là một số bản phát hành
Bộ công cụ phát triển phần mềm (SDK) được cải tiến dần từng bước Khi ngày phát hành G1 gần đến, nhóm Android đã phát hành SDK V1.0 và các ứng dụng bắt đầu vượt lên nhằm hướng tới nền tảng mới này
Để kích thích đổi mới và phát triển các ứng dụng của Android, Google đã tài trợ hai vòng cuộc thi “Các thách thức nhà phát triển Android”, và hàng triệu đô la đã được
đổ vào các ứng dụng dự thi hàng đầu Vài tháng sau G1, Android Market được phát hành, cho phép người sử dụng duyệt và tải về các ứng dụng trực tiếp vào điện thoại của
họ Trong vòng 18 tháng, một nền di động mới đã chính thức có mặt trên thị trường và
sẽ là đối thủ cạnh tranh nặng ký của các nền di động phổ biến trước đó như Symbian hay Window Mobile
Android cung cấp khá đầy đủ các công cụ cơ bản và được thiết kế sao cho các nhà phát triển có thể tận dụng tối đa lợi thế của thiết bị cầm tay để xây dựng nên các ứng dụng thực sự thuyết phục Họ có thể tạo một ứng dụng có thể gọi thực hiện các chức năng lõi trong điện thoại như thực hiện cuộc gọi, gửi tin nhắn SMS, dùng camera
… hay chia sẻ thông tin cá nhân lên trang web chẳn hạn như thông tin liên lạc, vị trí địa lí, lịch biểu… Các nhà phát triển còn có thể làm bất cứ việc gì trên thiết bị Android
Trang 8bởi vì hệ thống Android giao tiếp thông qua các Intents – nó đơn giản là một chuỗi mô
tả một hành động nào đó – ví dụ: “android.provider.Telephony.SMS_RECEIVED” Android còn cung cấp sẵn các dịch vụ định vị (và đây là một thế mạnh của Google) cùng với một tập các ứng dụng về “Map” với các tính năng rất ấn tượng như dò đường, tính khoảng cách địa điểm, tìm bạn … Ngoài ra còn có một số tính năng nổi bật khác như Animation và đồng thời cũng hỗ trợ media-playback.
Android đã dần hoàn thiện qua các phiên bản, mà phiên bản mới nhất hiện nay
là Android 3.1
1.2Nền tảng Android:
Với khả năng rộng rãi của Android, sẽ rất dễ dàng nhầm lẫn nó với một hệ điều hành máy tính để bàn Android là một môi trường phân tầng, xây dựng trên nền của hệ điều hành nhân Linux, và nó bao hàm nhiều chức năng phong phú Hệ thống giao diện người sử dụng gồm có:
Android khoe ra một mảng dồi dào nhiều tùy chọn kết nối, gồm WiFi, Bluetooth
và dữ liệu không dây qua một kết nối di động (như GPRS, EDGE và 3G) Một kỹ thuật phổ biến trong các ứng dụng Android là liên kết tới Google Maps để hiển thị một địa chỉ trực tiếp trong một ứng dụng Việc hỗ trợ cho các dịch vụ dựa trên địa điểm (chẳng hạn như GPS) và các dụng cụ đo gia tốc cũng có sẵn trong gói phần mềm Android, mặc dù không phải tất cả các thiết bị Android được trang bị với các phần cứng cần thiết Ngoài ra còn có cả hỗ trợ máy ảnh nữa (camera)
Trang 9Về mặt lịch sử, có hai lĩnh vực mà các ứng dụng di động đã gắng sức theo kịp các đối tác máy tính để bàn là đồ họa/đa phương tiện và phương thức lưu trữ dữ liệu Android giải quyết thách thức về đồ họa bằng sự hỗ trợ dựng sẵn cho đồ họa 2D và 3D, gồm cả thư viện OpenGL Gánh nặng lưu trữ dữ liệu được giảm nhẹ vì nền Android có gồm cả cơ sở dữ liệu SQLite mã nguồn mở phổ biến Hình 1 cho thấy một khung hình đơn giản hóa về các tầng phần mềm Android.
Hình 1 – Cấu trúc Android
1.3Kiến trúc ứng dụng Android:
1.3.1 Máy ảo Dalvik:
Các ứng dụng Android được viết bằng ngôn ngữ lập trình Java và chúng chạy trong một máy ảo (VM) Điều quan trọng phải lưu ý rằng VM không phải là một máy
ảo Java mà là máy ảo Dalvik (Dalvik Virtual Machine), một công nghệ mã nguồn mở Chiếc máy ảo này dựa trên việc đăng kí (register-based) và được thiết kế bởi Dan
Trang 10Bornstein và một vài kĩ sư của Google Thuật ngữ “register-based” đã nói lên sự khác biệt giữa máy ảo Android với máy ảo JAVA thông thường Tương tự như máy ảo JAVA, đây cũng chỉ là một máy ảo thông dịch, nhưng thông dịch các file có định dạng dex (Dalvik Execute) – một định dạng giúp tối ưu bộ nhớ và khả năng lưu trữ của máy ảo – Các máy ảo JAVA ngày nay chủ yếu dựa trên ngăn xếp (Stack-based), với tính chất này cho phép rút ngắn thời gian thực thi chương trình Mỗi ứng dụng Android chạy trong một cá thể của máy ảo Dalvik, khi đến lượt, cá thể máy ảo này nằm trong một tiến trình
do nhân Linux quản lý, như trình bày dưới đây
Hình 2 – Máy ảo Dalvik
1.3.2Các thành phần của một ứng dụng Android:
Một ứng dụng Android gồm 4 thành phần chính sau:
Hoạt động (Activity): một ứng dụng có một giao diện người dùng nhìn
thấy được, sẽ được thực hiện bằng một Activity Activity dùng Views để tạo nên giao diện đồ họa người dùng, để hiển thị thông tin và đáp lại các hành động của người dùng Khi người dùng chọn một ứng dụng từ màn
Trang 11hình chủ hoặc trình khởi chạy ứng dụng thì một Activity được khởi động Activity trong Android cũng tương tự như một Form trong các ứng dụng desktop truyền thống.
Dịch vụ (Services): các service làm việc ẩn dưới ứng dụng, được sử dụng
để thực hiện các xử lý thông thường khi cần và thậm chí ngay cả lúc các Activity không hoạt động hoặc ẩn đi.Một dịch vụ nên được sử dụng đối với bất kì ứng dụng nào cần tồn tại trong một thời gian dài, chẳng hạn như một trình giám sát mạng hoặc ứng dụng kiểm tra cập nhật
Trình cung cấp nội dung (Content Providers): có thể coi như là một máy
chủ cơ sở dữ liệu Công việc của nó là quản lý truy cập và chia sẻ dữ liệu đang tồn tại, chẳng hạn như một cơ sở dữ liệu SQLite Nó có thể được cấu hình để cho phép các ứng dụng khác truy xuất và ngược lại Nếu ứng dụng rất đơn giản thì không nhất thiết phải tạo ra một trình cung cấp nội dung
Trình thu phát (Broadcast Receivers): bằng cách tạo và đăng ký một
Broadcast Receiver, ứng dụng Android có thể lắng nghe toàn bộ các Intent theo một chuẩn cụ thể được chỉ định Các Broadcast Receiver sẽ chạy ứng dụng một cách tự động để đáp ứng một Intent gửi đến, hay xử
lý một phần tử dữ liệu hoặc đáp ứng một sự kiện, chẳng hạn như nhận một văn bản thông báo
Việc tách rời sự phụ thuộc giữa các thành phần trong ứng dụng giúp việc chia sẽ cũng như trao đổi giữa các ứng dụng khác trở nên dễ dàng hơn
1.4 Vòng đời của ứng dụng Android:
Không giống như các ứng dụng trên các nền tảng khác, các ứng dụng Android không có một điều khiển đến vòng đời của chúng Thay vào đó, các thành phần ứng dụng phải lắng nghe việc thay đổi trạng thái bên trong của ứng dụng đó và tác động trở lại một cách hợp lý Mỗi một ứng dụng Android ở trong chính tiến trình của nó,
Trang 12chạy một thể hiện riêng biệt của Dalvik Việc quản lý bộ nhớ và tiến trình của mỗi ứng dụng Android được điều khiển một cách riêng trong lúc runtime.
Android quản lý tài nguyên một cách chặt chẽ, nó sẽ làm bất cứ việc gì để đảm bảo cho thiết bị duy trì đáp ứng Điều này có nghĩa là các tiến trình sẽ bị hủy đi mà không có một cảnh báo nào nếu cần giải phóng tài nguyên cho các ứng dụng có độ ưu tiên cao
1.5Các công cụ để tạo một ứng dụng Android:
Để bắt đầu phát triển các ứng dụng Android, chúng ta cần có Bộ công cụ phát triển phần mềm Android (SDK) và môi trường phát triền tích hợp Eclipse (Eclipse IDE) Việc phát triển Android có thể diễn ra trên Microsoft Window, Mac OS X hoặc Linux Trong tiểu luận này, nhóm thực hiện sẽ phát triển ứng dụng Android bằng Microsoft Window
1.5.1 Eclipse IDE:
Các ứng dụng Android được viết bằng ngôn ngữ Java, nhưng biên dịch và thi hành bằng máy ảo Dalvik Viết mã bằng ngôn ngữ Java trong Eclipse là rất trực quan Eclipse cung cấp một môi trường Java phong phú, gồm cả việc trợ giúp theo ngữ cảnh
và các mách nước gợi ý về mã Khi bộ mã Java được biên dịch thành công, Android Developer Tools sẽ đảm bảo rằng ứng dụng đó được đóng gói một cách đúng đắn, gồm
cả tập tin AndroidManifest.xml
1.5.2 Android SDK:
Bộ công cụ phát triển ứng dụng Android SDK là công cụ giả lập thiết bị ảo trên máy tính để phát triển ứng dụng với các hàm API hỗ trợ cho những lập trình viên lập trình trên các thiết bị di động sử dụng nền tảng Android thông qua ngôn ngữ lập trình Java SDK gồm có:
Trang 13 android.jar : tập tin lưu trữ Java chứa toàn bộ các lớp SDK Android cần
thiết để xây dựng ứng dụng
documention.html và thư mục docs: tài liệu SDK được cung cấp tại chỗ
và trên web, chủ yếu nó ở dạng JavaDocs, tạo điều kiện dễ dàng cho việc hướng dẫn trong nhiều gói SDK Tài liệu cũng gồm cả hướng dẫn phát triển mức cao và các liên kết đến cộng đồng Android rộng rãi
Thư mục sample (các ví dụ mẫu): thư mục con samples chứa bộ mã nguồn
đầy đủ dùng cho một loạt các ứng dụng, gồm cả ApiDemo, nó sử dụng nhiều API Ứng dụng mẫu là một nơi khám phá tuyệt vời khi bắt đầu phát triển ứng dụng Android
Thư mục tools (các công cụ): chứa toàn bộ các công cụ dòng lệnh để xây
dựng nên các ứng dụng Android Công cụ được dùng phổ biến và hữu ích nhất là tiện ích adb (Android Debug Bridge)
Usb_driver: thư mục chứa các trình điều khiển cần thiết để kết nối môi
trường phát triển với một thiết bị có khả năng chạy Android, chẳng hạn như G1 hay điện thoại đã được phát triển Android Dev 1 Các tập tin này là đòi hỏi duy nhất đối với các nhà phát triển đang sử dụng nền Windows
1.5.3 Cài đặt công cụ:
Chuẩn bị:
o Phần mềm Eclipse IDE (phiên bản 3.2 trở lên), có thể tải trực tiếp
từ trang web http://www.eclipse.org/downloads/
o Bộ công cụ Android SDK phiên bản mới nhất, tại thời điềm thực hiện tiểu luận này là phiên bản r11, có thể tải từ trang web http://developer.android.com/sdk/index.html
Bắt đầu việc cài đặt:
o Giải nén chương trình Eclipse vào một thư mục nào đó (ví dụ:
D:\eclipse\)
Trang 14o Giải nén bộ Android SDK vào một thư mục bất kỳ (ví dụ:
D:\Android_SDK_r11\)
o Chạy chương trình Eclipse.
o Vào menu Help – Software Updates …
o Chọn tab Available Software
o Chọn Add Site, nhập vào đường dẫn sau:
http://dl-ssl.google.com/android/eclipse/
o Chọn OK
o Chờ cho chương trình được cài đặt
o Sau khi cài xong, tiếp tục vào menu Window – Preferences
o Chọn tab Android, chỉ đường dẫn đến thư mục đã giải nén Android SDK ở trên (ở đây là D:\Android_SDK_r11\)
o Hoàn tất
Lưu ý : Cách cài đặt ở trên đòi hỏi máy tính phải được nối mạng Internet.
1.6 Thiết bị Android ảo (Android Virtual Device - AVD):
Các ứng dụng Android có thể được chạy trên một thiết bị thật sự hoặc trên trình
mô phỏng Android (Android Emulator) kèm với SDK Android
Từ phiên bản SDK 1.5, Google đã giới thiệu khái niệm về thiết bị Android ảo Một thiết bị Android ảo chỉ đơn giản là một tập các thuộc tính cấu hình được áp dụng cho hình ảnh của một thiết bị mô phỏng để hiển thị ứng dụng lên nó
Cách tạo một thiết bị Android ảo như sau:
- Trong Eclipse à window à Android SDK and AVD manager
- Ở cửa sổ mới hiện ra, chọn mục Virtual devices à bấm nút New, hiện ra một cửa sổ mới như hình sau đây:
Trang 15Hình 3– Tạo một AVD
- Mục Name: đặt tên cho thiết bị, tên gì cũng được, cốt là dễ nhớ và để phân biệt, không chứa khoản trắng và các ký tự đặc biệt
- Mục Target: chọn phiên bản hệ điều hành Android
- Mục SD Card: điền kích thước bộ nhớ của thiết bị hoặc lấy một file SD Card
có sẵn
- Nhấn nút Create AVD
Trang 16Hình 4 – Trình mô phỏng thiết bị Android.
1.7 Android project:
1.7.1 Tạo một Android project mới:
- Trong Eclipse, chọn File à New à Android Project
- Một cửa sổ mới hiện ra, điền các thông tin tương ứng vào cửa sổ
- Project name: tên project
- Chọn phiên bản Android
- Application name: tên ứng dụng
- Package name: tên gói
- Create activity: tên hoạt động
- Min SDK Version: API Level tương ứng với phiên bản Android
Trang 17- Nhấn nút Finish.
Hình 5 – Tạo một Android project
1.7.2 Cấu trúc một project:
Một Android project gồm các thư mục sau:
• Thư mục src chứa source code ứng dụng Gồm các package và các class.
• Thư mục gen chứa các file tự động phát sinh (mà thường gặp nhất là
R.class)
Trang 18• Thư mục res để chứa các resource dùng trong ứng dụng (thông qua ID).
• Thư mục assets chứa các resource file mà ứng dụng cần dùng (dưới dạng
file)
• File Manifest là file khai báo thông tin về ứng với hệ thống (như ứng
dụng gồm những màn hình nào, có service nào… xin các quyền gì, phiên bản bao nhiêu, dùng từ SDK phiên bản nào…)
• File thư viện
Chương 2: Các thành phần cơ bản của một ứng dụng trên Android
Trang 192.1.1 Tạo một Activity:
Để tạo một Activity mới, cần thừa kế từ lớp Activity, sử dụng các View để cung cấp các tương tác với người dùng, khai báo các thành phần giao diện và thực thi các chức năng của ứng dụng
package com.paad.myapplication;
import android.app.Activity;
import android.os.Bundle;
public class MyActivity extends Activity {
/** Called when the activity is first created */
@Override public void onCreate(Bundle icicle) { super.onCreate(icicle);
} }
Một lớp Activity cơ bản đưa ra một màn hình rỗng chứa cửa sổ hiển thị Vì vậy việc cần thực hiện đầu tiên là khai báo bố cục cho nó bằng cách sử dụng các View và layout Activity UI được tạo thành bởi các View View là các điều khiển giao diện người dùng, hiển thị dữ liệu và cung cấp tương tác đến người dùng
Để gắn một giao diện cho một Activity, sử dụng phương thức setContentView
trong lớp Activity được kế thừa
Trang 20Có 2 cách để thiết lập giao diện cho Activity: bằng code hoặc thông qua file định nghĩa layout Ở trên là cách tạo giao diện bằng code, sau đây là cách tạo giao diện
người thông qua layout, truyền tham số vào cho phương thức setContentView là một
Để dùng một Activity cần khai báo bên trong file manifest Thêm vào một thẻ
activity mới bên trong nút application Thẻ activity này bao gồm các thuộc tính cho siêu dữ liệu (label, icon,…) Một Activity mà không được khai báo một thẻ activity
tương ứng sẽ không được khởi chạy
Ví dụ sau mô tả cách làm thế nào để khai báo Activity đã được tạo ở phần trên:
</activity>
2.1.2 Vòng đời của Activity:
Trang 21Hình 6 – Vòng đời của Activity2.1.3 Khởi động một Activity:
Để khởi động một Activity, chúng ta dùng Intent:
o Khai báo tường minh: cung cấp chính xác thông tin của activity cần gọi (nếu cùng ứng dụng chỉ cần cung cấp tên class, nếu ứng dụng khác nhau thì cung cấp tên package, tên class) Ví dụ: đoạn code bên dưới sẽ khởi động activity tên là TargetActivity
Intent intent = new Intent(getApplicationContext(),TargetActivity.class); startActivity(intent);
o Khai báo không tường minh: cung cấp thao tác cần làm gì, với loại dữ liệu nào, thao tác thuộc nhóm nào… hệ thống sẽ tìm activity tương ứng
để khởi động Ví dụ: đoạn code bên dưới sẽ khởi động một activity nào
đó đăng có khả năng xem ảnh
Trang 22Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(MediaStore.Images.Media.EXTERNAL_CONTENT_URI); startActivity(intent);
Với cách khởi động activity không tường minh, chúng ta cần phải biết một chút
về Intent-filter Intent-filter sẽ giúp một activity đăng ký với hệ thống mình có thể làm được thao tác gì, trong nhóm nào, với loại dữ liệu nào Như vậy khi intent và intent-filter khớp nhau, activity sẽ được hệ thống khởi động
2.1.4 Liên lạc giữa 2 activity:
Có thể khởi động một activity với một yêu cầu nào đó và activity kia khi làm xong công việc sẽ trả lại kết quả cho activity trước Ví dụ activity A yêu cầu một activity làm giúp việc chụp ảnh, activity B đáp ứng được việc này, sau khi user chụp ảnh xong sẽ trả lại file ảnh cho activity A Để liên lạc 2 activity chúng ta làm nhu sau:
– Khi khởi động một activity, ta có thể gửi kèm dữ liệu trong intent như ví
dụ sau:
intent.putExtra("value1", new String("Hello"));
intent.putExtra(“value2", new Long(100));
– Bên phía activity được khởi động, có thể lấy dữ liệu được gửi như sau:
Trang 23– Khi có sự kiện mà BroadcastReceiver đã đăng ký nhận được phát đi, thì phương thức onReceive() của BroadcastReceiver đó sẽ được gọi.
– Sau khi thực thi xong phương thức này, vòng đời của BroadcastReceiver kết thúc
Lưu ý khi sử dụng: Ngay khi onReceive() kết thúc, hệ thống coi như receiver đã không còn hoạt động và có thể giải phóng tiến trình chứa receiver này bất cứ lúc nào
àTránh xử lý các code quá lâu trong onReceive()
à Không có xử lý bất đồng bộ, chờ callback… trong Receiver (cụ thể như hiển thị Dialog, kết nối service…)
2.2.2 Một số broadcast thông dụng:
o Báo hệ thống khởi động xong
o Báo pin có sự thay đổi
o Báo có package mới cài vào hoặc xóa đi
o Báo tắt máy
o Báo cắm sạc, rút sạc
o Thông báo tin nhắn tới
o Thông báo cắm, rút thẻ nhớ
o Thông báo có cuộc gọi đi
o Broadcast do người phát triển ứng dụng tự định nghĩa (giúp liên lạc hoặc thông báo một sự kiện giữa các ứng dụng)
Trang 24o intent: intent được truyền vào sẽ có đầy đủ thông tin như sự kiện nào mà receiver này đăng ký đã xảy ra dẫn đến onReceive() được gọi, có gửi kèm thông tin gì hoặc dữ liệu gì hay không Xem các api:
public void onStart(Intent intent, int startId) {
// TODO: Actions to perform when service is started.
}
Trang 25@Override
public void onCreate() {
// TODO: Actions to perform when service is created.
}
@Override
public IBinder onBind(Intent intent) {
// TODO: Replace with service binding implementation.
return null;
} }
Để bắt đầu một Service, sử dụng phương thức startService Nếu Service yêu cầu
quyền truy cập không tồn tại trong ứng dụng thì một ngoại lệ SecurityException sẽ được đưa ra Có 2 cách để bắt đầu một Service mới
+ Cách 1: khởi động ngầm Ví dụ:
startService(new Intent(MyService.MY_ACTION));
+ Cách 2: khởi động tường minh Ví dụ:
startService(new Intent(this, MyService.class));
Để dừng một Serivce, sử dùng phương thức stopService, truyền vào Intent xác
định Service cần ngưng hoạt động Ví dụ:
ComponentName service = startService(new Intent(this, BaseballWatch.class)); // ngừng dịch vụ bằng cách xác định tên dịch vụ
stopService(new Intent(this, service.getClass()));
// ngừng dịch vụ bằng cách tường minh
Trang 26try {
Class serviceClass = Class.forName(service.getClassName());
stopService(new Intent(this, serviceClass));
} catch (ClassNotFoundException e) {}
2.3.2 Vòng đời của Services:
Hình 7 – Vòng đời của service
o Khi có một context nào đó gọi startService() để khởi động một dịch vụ mong muốn Nếu dịch vụ đó chưa được tạo thì sẽ gọi onCreate() rồi gọi tiếp onStart() và khi đó dịch vụ chạy nền bên dưới
o Nếu sau đó lại có một context muốn khởi động dịch vụ này mà dịch vụ
đã đang chạy thì chỉ có phương thức onStart() của dịch vụ được gọi
o Dù dịch vụ có được gọi khởi động bao nhiêu lần thì cũng chỉ có thể hiện của dịch vụ và chỉ cần gọi stopService() một lần để kết thúc dịch vụ
2.3.3 Kết nối dịch vụ:
Khi một Activity được kết nối tới một Service, nó duy trì một tham chiếu đến
một thực thể Service Để kết nối đến thực thể này, thực thi phương thức onBind như
Trang 27-public class MyBinder extends Binder {
private MyService serviceBinder;
// xử lý kết nồi giữa service và activity
private ServiceConnection mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder
service) { // được gọi khi liên kết được thực hiện
Trang 28super.onCreate(icicle);
// kết nối dịch vụ
Intent bindIntent = new Intent(MyActivity.this, MyService.class);
}
Hoạt động của bindService(): kết nối dịch vụ
Hình 8 – Hoạt động kết nối dịch vụThông thường, vòng đời của dịch vụ khi có client kết nối từ đầu như sau:
o Cũng bắt đầu bằng onCreate() rồi đến onBind() và dịch vụ chạy dưới nền
o Khi không còn client kết nối tới thì dịch vụ gọi onUnbind() rồi onDestroy()
Có một số trường hợp không thông thường, ví dụ như:
o Có một context khởi động một dịch vụ, sau đó có một số client kết nối (bind) tới service
o Có nhiều client cùng lúc kết nối tới dịch vụ
o Một activity vừa gọi startService() vừa gọi bindService()
2.4Trình cung cấp nội dung (Content Providers):
2.4.1 Giới thiệu:
Có thể coi trình cung cấp nội dung như là một máy chủ cơ sở dữ liệu Công việc
của nó là quản lý truy cập và chia sẻ dữ liệu đang tồn tại, chẳng hạn như một cơ sở dữ liệu SQLite Nó có thể được cấu hình để cho phép các ứng dụng khác truy xuất và
Trang 29ngược lại Nếu ứng dụng rất đơn giản thì không nhất thiết phải tạo ra một trình cung cấp nội dung.
Content Provider giúp tách biệt tầng ứng dụng ra khỏi tầng dữ liệu Nó có đầy đủ các quyền điều khiển và được truy xuất thông qua mô hình URI đơn giản như là có thể thêm, xóa, cập nhật dữ liệu của các ứng dụng
2.4.2 Tạo một Content Provider mới:
2.4.2.1 Tạo Content Provider:
Để tạo một Content Provider cần thừa kế lại từ lớp trừu tượng ContentProvide, override lại phương thức onCreate.
public boolean onCreate() {
// TODO: Construct the underlying database.
return true;
} }
Nên cung cấp một biến static CONTENT_URI trả về một URI của provider này Content URI phải là duy nhất giữa các provider, vì thế nên dựa vào tên package để xác định URI, hình thức chung cho việc định nghĩa một Content Provider URI là:
content://com.<CompanyName>.provider.<ApplicationName>/<DataPath>
Trang 30Ví dụ:
content://com.paad.provider.myapp/items
Content URI có thể ở 2 dạng thể hiện Ví dụ trên là URI ở dạng request tất cả các
giá trị Việc thêm vào cuối /<rownumber>, sẽ request một record đơn.
content://com.paad.provider.myapp/items/5
Các đơn giản nhất để làm việc này là sử dụng URIMatcher Cấu hình UriMatcher để phân tích hình thức của nó khi provider đang được truy xuất đến thông
qua một Content Resolver Xét ví dụ sau:
public class MyProvider extends ContentProvider {
private static final String myURI =
“content://com.paad.provider.myapp/items”;
public static final Uri CONTENT_URI = Uri.parse(myURI);
@Override
public boolean onCreate() {
// TODO: Construct the underlying database.
return true;
}
// tạo các hằng số được dùng để phân biệt các yêu cấu URI khác nhau
private static final int ALLROWS = 1;
private static final int SINGLE_ROW = 2;
private static final UriMatcher uriMatcher;
// thông thường đối tượng UriMatcher, nơi mà một URI kết thúc bằng ‘items’ sẽ
Trang 31// tương ứng với một yêu cầu tất cả item, và ‘items/[rowID]’ sẽ tương ứng với một
// hàng đơn
static {
uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
uriMatcher.addURI(“com.paad.provider.myApp”, “items”, ALLROWS);
uriMatcher.addURI(“com.paad.provider.myApp”, “items/#”,
SINGLE_ROW);
}
}
2.4.2.2 Đưa ra truy xuất Data Source:
Có thể cung cấp các truy vấn và thực thi với Content Provdier bằng cách thực
hiện các phương thức delete, insert, update và query Các phương thức này hoạt động
như các giao tiếp chung đến nguồn dữ liệu bên dưới, chúng cho phép các ứng Android chia sẽ dữ liệu với nhau mà không phải tạo một giao tiếp riêng cho mỗi ứng dụng
Ví dụ: một đối tượng UriMatcher được sử dụng để lọc các thực thi và các câu
truy vấn
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sort) {
// nếu là truy vấn 1 hàng thì hạn chế kết quả
switch (uriMatcher.match(uri)) {
case SINGLE_ROW : // TODO: Modify selection based on row id, where:
// rowNumber = uri.getPathSegments().get(1));
Trang 32} return null;
}
@Override
public Uri insert(Uri _uri, ContentValues _initialValues) {
long rowID = [ Add a new item ]
case SINGLE_ROW:
default: throw new IllegalArgumentException(“Unsupported
URI:” + uri);
} }
@Override
public int update(Uri uri, ContentValues values, String where,
String[] whereArgs) {
Trang 33switch (uriMatcher.match(uri)) { case ALLROWS:
Bước cuối cùng trong quá trình tạo một Content Provider là định nghĩa kiểu
MIME là kiểu dữ liệu mà Provider trả về, override phương thức getType để trả về một
kiểu String mô tả cho kiểu dữ liệu Kiểu trả về bao gồm cả 2 hình thức: trường đơn và tất cả dữ liệu
Trang 34default: throw new IllegalArgumentException(“Unsupported URI:
2.4.3 Truy vấn, thêm, cập nhật và xóa nội dung trong Content Provide:
Content Provider được truy xuất thông qua lớp Content Resolver Mỗi một Context của ứng dụng có một đối tượng ContentResolver, có thể được truy xuất thông
qua phương thức getContentResolver.
ContentResolver cr = getContentResolver();
Content Resolver bao gồm một vài phương thức để thực thi và truy vấn đến Content Providers Một URI dùng để chỉ định Content Provider nào được cung cấp bởi các quyền được định nghĩa trong manifest của ứng dụng URI là một chuỗi tùy ý, vì thế hầu hết các provider đều đưa ra thuộc tính CONTENT_URI Content Provider thường đưa ra 2 hình thức URI, một là đựa tất cả các dữ liệu được yêu cầu trên cùng một dòng
đơn lẻ, hoặc là thêm vào /<rowID> vào phía sau CONTENT_URI.
Trang 352.4.3.1 Truy vấn:
Việc truy vấn trên Content Provider có hình thức tương tự như khi truy vấn trong
database, dùng phương thức query của đối tượng ContentResolver với các tham số
truyền vào gồm:
• Một URI của Content Provider muốn truy vấn
• Một ánh xạ đại diện cho các cột muốn chứa trong tập kết quả
• Một mệnh đề where chỉ định các dòng nào được trả về Có thể đưa vào ký tự đại
diện ? và sẽ được thay thế bởi các giá trị được lưu bên trong các tham số được chọn
• Một mảng các đối số kiểu String thay thế cho các ký tự đại diện ? trong mệnh đề where
String where = KEY_COL3 + “=” + requiredValue;
String order = KEY_COL5;
Cursor someRows = getContentResolver().query(MyProvider.CONTENT_URI, null, where, null, order);
2.4.3.2 Thêm:
Content Resolver cung cấp 2 phương thức để chèn một record mới vào trong
Content Provider, đó là insert và bulkInsert Phương thức insert trả về một URI đến
Trang 36record mới được thêm vào, trong khi bulkInsert trả về số thành phần thêm vào thành công
Đoạn code sau mô tả cách sử dụng 2 phương thức trên:
// tạo một dòng mới cho các giá trị muốn chèn.
ContentValues newValues = new ContentValues();
// gán giá trị cho mỗi hàng
newValues.put(COLUMN_NAME, newValue);
[ lặp lại cho mỗi cột ]
Uri myRowUri = getContentResolver().insert(MyProvider.CONTENT_URI,
newValues);
// tạo một dòng mới cho các giá trị muốn chèn.
ContentValues[] valueArray = new ContentValues[5];
// tạo một mảng các dòng mới và trả về số thành phần thêm thành công
int count = getContentResolver().bulkInsert(MyProvider.CONTENT_URI,
valueArray);
2.4.3.3 Xóa:
Để xóa một record khi sử dụng Content Resolver, sử dụng phương thức delete,
truyền vào URI cho dòng muốn xóa Đồng thời, cũng có thể dùng mênh đề điều kiện
where để xóa nhiều dòng
Ví dụ:
// xóa một dòng được chỉ định
getContentResolver().delete(myRowUri, null, null);
Trang 37// xóa 5 dòng đầu tiên.
String where = “_id < 5”;
getContentResolver().delete(MyProvider.CONTENT_URI, where, null)
2.4.3.4 Cập nhật:
Việc cập nhật cho một Content Provider được điều khiển bởi phương thức update cùa Content Resolver Phương thức update nhận URI của Content Provider đích, một đối tượng ContentValues chứa tập giá trị được ánh xạ đến các cột cần cập nhật, và một mệnh đề where để chỉ định dòng nào được cập nhật.
Khi thực thi, mỗi dòng phù hợp với điều kiện trong mệnh đề where sẽ được cập
nhật và trả về số dòng được cập nhật giá trị thành công
Ví dụ:
// tạo một dòng mới cho các giá trị muốn chèn.
ContentValues newValues = new ContentValues();
// tạo ánh xạ thay thế các cột muốn cập nhật và những giá trị gì để gán cho mỗi cột
newValues.put(COLUMN_NAME, newValue);
// áp dụng cho 5 hàng đầu tiên
String where = “_id < 5”;
getContentResolver().update(MyProvider.CONTENT_URI, newValues, where, null);
2.4.4 Native Android Content Provider:
Android đưa ra nhiều Content Provider hỗ trợ truy xuất đến các ứng dụng native
Có thể dùng một trong các Content Provider native này để sử dụng các kỹ thuật được
mô tả ở trên Như một sự thay thế, gói android.provider chứa các lớp thuận tiện để truy
xuất một cách đơn giản đến nhiểu provider bao gồm:
Trang 38• Browser: Dùng browser Content Provider để đọc và điều chỉnh bookmarks,
browser history, hoặc web searches
• CallLog: Hiển thị hoặc cập nhật các cuộc gọi (cuộc gọi đến, cuộc gọi đi, các
cuộc gọi nhỡ, và chi tiết cuộc gọi
• Contacts: dùng để rút trích, chình sữa, hoặc lưu trữ chi tiết danh bạ.
• MediaStore: cung cấp sự kiểm soát, quản lý truy xuất đa phương tiện trên thiết
bị (audio, video, và hình ảnh)
• Settings: Truy xuất đến các thiết lập cài đặc của thiết bị, Settings cho phép hiển
thị và điều chỉnh các thiết lập Bluetooth, ring tone và nhiều cài đặt khác
Nên sử dụng các Content Providers native này bất cứ khi nào có thể, bởi vì khi sử dụng chúng sẽ bảo đảm cho ứng dụng được kết hợp với các ứng dụng native hoặc third-party khác một cách liên tục
2.4.4.1 Media Store Provider:
Android Media Store cung cấp một kho lưu trữ các tập tin audio, video, và hình ảnh Mỗi khi thêm một tập tin đa phương tiện nào vào Android filesystem, nó sẽ được thêm vào Media Store để cho các ứng dụng khác nhìn thấy nó
Một lớp MediaStore bao gồm một số các phương thức tiện lợi để thêm các tập tin
vào Media Store một cách đơn giản Ví dụ sau đây sẽ mô tả việc thêm vào một tập tin hình ảnh vào trong Media Store
Trang 39Trong ví dụ sau đây, một Activity nhận một Cursor đến mỗi người trong cơ sở dữ liệu contact, tạo một mảng kiểu String với mỗi thành phần chứa tên người và số điện thoại của người đó
// lấy một con trỏ của mỗi liên hệ
Cursor cursor = getContentResolver().query(People.CONTENT_URI,
null, null, null, null);
// quản lý vòng đời con trỏ.
startManagingCursor(cursor);
// các thuộc tính để lấy chì số cột
int nameIdx = cursor.getColumnIndexOrThrow(People.NAME);
int phoneIdx = cursor getColumnIndexOrThrow(People.NUMBER);
String[] result = new String[cursor.getCount()];
if (cursor.moveToFirst())
do {
// trích xuất tên
String name = cursor.getString(nameIdx);
// trích xuất số điện thoại
String phone = cursor.getString(phoneIdx);
result[cursor.getPosition()] = name + “ (“ + phone + “)”;
} while(cursor.moveToNext());
Trang 40Chương 3: Thiết kế giao diện
3.1 Một số lớp hỗ trợ thiết kế giao diện cho ứng dụng Android:
Android cung cấp một số công cụ thiết kế giao diện:
Views: là lớp UI cơ bản cho các control giao diện Tất cả các control giao diện người dùng, các lớp layout đều được dẫn xuất từ lớp Views
ViewGroups: được mở rộng từ lớp View và có thể chứa nhiều Views ViewGroups cũng được kế thừa để cung cấp các lớp quản lý bố cục như LinearLayout ViewGroup được dùng để xây dựng nên các component có thể dùng lại (widget) hoặc để quản lý bố cục cho các control
Activity: dùng để hiển thị giao diện người dùng Lớp này do người phát triển ứng dụng viết