text:
Mở đầu
Android là một hệ điều hành di động, tương tự như Symbian, iOS, Windows® Mobile, và những hệ điều hành khác. Ban đầu Android do công ty Android Inc. phát triển, về sau Google đã mua lại công ty này. Android bây giờ thuộc quyền sở hữu của Open Handset Alliance (Liên minh mở về thiết bị cầm tay) và hoàn toàn là nguồn mở, đó là lý do làm nó ngày càng phổ biến. Google đã phát hành hầu hết các mã Android theo Giấy phép của Apache. Với giấy phép này, các nhà cung cấp có thể thêm phần mở rộng độc quyền mà không cần đệ trình chúng lại cho cộng đồng nguồn mở. Nhiều phiên bản Android đã ra thị trường kể từ lúc khởi đầu (gần đây nhất là quý 3 năm 2010), bao gồm power-packed Froyo (Froyo được đóng gói mạnh) (phiên bản V2.2). Android đã vượt ra ngoài, không còn chỉ là một nền tảng cho các thiết bị di động; hệ thống truyền hình mới của Google cũng chạy trên Android.
Android sử dụng một nhân (kernel) Linux® đã cải biên và cho phép ứng dụng được phát triển bằng công nghệ Java™, sử dụng các thư viện Java (một số trong các thư viện đó được Google phát triển cho Android). Mặc dù các ứng dụng Android được viết bằng ngôn ngữ Java, không có Máy ảo Java (Java Virtual Machine) nào chạy trong nền tảng này và mã byte Java không được thi hành ở đây. Các lớp Java được biên dịch lại thành mã Dalvik thi hành được và chạy trên một máy ảo Dalvik. Dalvik là một máy ảo Android đã cải biên và tối ưu hóa cho các thiết bị chạy bằng nguồn pin và có CPU thấp.
Đối với các nhà phát triển, Android SDK (Bộ công cụ phát triển phần mềm của Android) cung cấp một tập hợp các công cụ phong phú, bao gồm trình gỡ rối, các thư viện, trình mô phỏng thiết bị cầm tay, tài liệu, mã mẫu và các hướng dẫn. Các ứng dụng Android có thể dễ dàng được phát triển khi sử dụng Eclipse (nền tảng phát triển chính thức của Android) với sự trợ giúp của một trình cắm thêm được gọi là ADT (Android Development Tools – Các công cụ phát triển Android). Điều này giúp tận dụng các tính năng phong phú của Eclipse, như là hỗ trợ nội dung, tìm kiếm Java, các tài nguyên mở, tích hợp JUnit và các khung nhìn và các ảnh phối cảnh khác nhau để phát triển một ứng dụng Android. Một mảng rộng rãi các widget (tiện ích), tương tự như các widget swing của Java, tạo điều kiện thuận lợi trong việc tạo một giao diện người dùng phong phú cho các ứng dụng. Một công cụ Javadoc chi tiết giúp cho quá trình phát triển này khá dễ dàng.
Ở đây, chúng ta bắt đầu với một hướng dẫn để chuẩn bị hệ thống cho việc
phát triển Android. Sau đó chúng ta đề cập ngắn đến các tính năng quan
trọng nhất của một ứng dụng Android bằng cách sử dụng một ứng dụng
Hello World (Chào thế giới) cơ bản của Android. Chúng ta cũng bàn về
các tệp tạo nên một ứng dụng Android và cách thức giao diện người dùng
được tách khỏi việc triển khai thực hiện như thế nào. Sau khi trình
bày xong quá trình tạo, phát triển và khởi chạy một ứng dụng Android
từ Eclipse, chúng ta chuyển sang thảo luận về một vài widget của
Android giúp cho việc xây dựng một giao diện người dùng phong phú (một
phần rất quan trọng của các ứng dụng di động). Chúng ta trình bày một
số widget cơ bản với sự trợ giúp của một ứng dụng mẫu. Chúng ta cũng
bàn về cách sử dụng widget
listView trong
một ứng dụng giống như danh bạ điện thoại và những cách triển khai
thực hiện nó. Trong lúc đó, chúng ta cũng bàn về các quyền hạn cần
phải được thiết lập để có thể cho phép một ứng dụng truy cập một số dữ
liệu từ hệ điều hành. Nhìn chung, vài giờ học theo bài viết này sẽ
giúp bạn tạo một ứng dụng triển khai thực hiện những chức năng cơ bản
và có một giao diện người dùng hấp dẫn.
Các yêu cầu hệ thống
Trước khi bắt đầu phát triển Android, hãy chắc chắn rằng bạn đã cài đặt các phần mềm sau:
- Eclipse SDK (Bộ công cụ phát triển phần mềm Eclipe)— phiên bản V3.5 được đề xuất sử dụng với Android SDK mới nhất. Có thể tải phần mềm này từ trang tải Galileo.
- Android SDK (Bộ công cụ phát triển phần mềm Android).
- Android Development Tools (ADT - Các công cụ phát triển Android)— Đây là một trình cắm thêm Eclipse. Nó tương đương với JDT (Các công cụ phát triển Java) để phát triển Android. Hãy làm theo các hướng dẫn chi tiết để cài đặt trình cắm thêm ADT cũng như thiết lập vị trí của Android SDK trong Eclipse.
Thuật ngữ Android
Một ứng dụng Android điển hình có các thành phần sau. Dưới đây cũng trình bày các định nghĩa do trang Web của nhà phát triển Android cung cấp:
- Activity (Hoạt động) — Một hoạt động biểu thị một giao diện người dùng trực quan của một nỗ lực tập trung có chủ hướng mà người dùng có thể thực hiện. Ví dụ, một hoạt động có thể biểu thị một danh sách các mục trình đơn mà người dùng có thể lựa chọn từ đó hoặc nó có thể hiển thị các hình ảnh cùng với lời chú thích của chúng. Một ứng dụng tin nhắn văn bản có thể có một hoạt động để hiển thị một danh sách các địa chỉ liên lạc để gửi tin nhắn đến, có một hoạt động thứ hai để viết tin nhắn cho địa chỉ liên lạc đã chọn và các hoạt động khác để xem lại tin nhắn cũ hoặc thay đổi các giá trị cài đặt. Mặc dù các hoạt động này làm việc cùng nhau để tạo thành một giao diện người dùng gắn kết, nhưng mỗi hoạt động độc lập với các hoạt động khác.
- Content providers (Những nhà cung cấp nội dung) — Một nhà cung cấp nội dung tạo ra một tập hợp cụ thể các dữ liệu của ứng dụng, sẵn có cho các ứng dụng khác. Các dữ liệu có thể được lưu trữ trong hệ thống tệp, trong một cơ sở dữ liệu SQLite hoặc theo cách hợp lý bất kỳ khác.
- Service (Dịch vụ) — Một dịch vụ không có một giao diện người dùng trực quan mà chạy ở nền sau, trong một khoảng thời gian không xác định. Ví dụ, một dịch vụ có thể chơi nhạc nền khi người dùng tham dự vào các vấn đề khác hoặc nó có thể tìm nạp dữ liệu qua mạng hoặc tính toán một cái gì đó và cung cấp kết quả cho các hoạt động cần nó.
- Broadcast receivers (Các bộ thu quảng bá) — Một bộ thu quảng bá là một thành phần không làm gì khác ngoài thu nhận và phản ứng lại với các thông báo quảng bá. Nhiều thông báo quảng bá bắt nguồn từ mã hệ thống — các thông báo thay đổi-múi giờ, các thông báo pin sắp hết pin, thay đổi ngôn ngữ-ưa thích, v.v.
Một số thuật ngữ khác cần biết:
- Intent (Ý định) — Các hoạt động, các dịch vụ và các bộ thu
quảng bá được kích hoạt bằng các thông báo không đồng bộ được gọi
là các ý định. Một ý định là một đối tượng
Intentđể lưu giữ các nội dung của thông báo. Ví dụ, nó có thể truyền đạt yêu cầu một hoạt động để hiển thị một hình ảnh cho người sử dụng hoặc cho phép người dùng chỉnh sửa một số văn bản.
- Intent filter (Bộ lọc ý định) — Một đối tượng Intent có thể gọi tên rõ ràng một thành phần đích. Nếu nó làm như vậy thì Android sẽ tìm thấy thành phần đó (dựa vào các khai báo trong tệp bản kê) và kích hoạt thành phần này. Tuy nhiên, nếu đích không được gọi tên rõ ràng, thì Android phải định vị thành phần tốt nhất để đáp ứng ý định đó. Nó làm như vậy bằng cách so sánh đối tượng Intent với các bộ lọc ý định của các đích có tiềm năng. Bộ lọc ý định của một thành phần thông báo cho Android về các loại ý định mà thành phần đó có khả năng xử lý.
Để hiểu về các thành phần này, hãy tham khảo "Phát triển các ứng dụng Android với Eclipse" và hướng dẫn Hello, World của Android.
Tạo một Thiết bị ảo Android
Bước này cần thiết để tạo một trình mô phỏng điện thoại Android/AVD (Android Virtual Device - Thiết bị ảo của Android ) trên đó các ứng dụng có thể chạy và được thử nghiệm. Lưu ý rằng để khởi động cho một AVD phải mất một chút thời gian. Tin vui là không cần các AVD riêng biệt cho mỗi ứng dụng được triển khai và thử nghiệm. Một khi AVD được khởi chạy, có thể triển khai một số lượng ứng dụng bất kỳ trong khi nó vẫn còn đang chạy và thậm chí có thể sử dụng nó để gỡ rối ứng dụng. Để tạo một AVD:
- Trong Eclipse, chọn Window > Android SDK và AVD Manager (Trình quản lý AVD).
- Chọn Virtual Devices (Các thiết bị ảo) ở khung bên trái.
- Nhấn New. Hộp thoại Create New AVD (Tạo AVD mới) xuất hiện.
- Gõ tên của AVD vào, ví dụ như "myPhone."
- Chọn một đích. Đích là một nền tảng (đó là một phiên bản Android SDK, ví dụ như 2.1) để chạy trên trình mô phỏng . Bạn cũng sẽ nhận được một tùy chọn để chọn các API của Google, nhưng việc đó là không cần thiết trừ khi chúng ta đặc biệt muốn có một số API của Google trong ứng dụng. Các trường còn lại tạm thời có thể bỏ qua vào lúc này.
- Nhấn Create AVD (Tạo AVD).
Một khi AVD này được khởi chạy, bạn có thể thấy nó mang lại dáng vẻ và cảm nhận đầy đủ của một điện thoại di động dựa trên Android thực, có đủ bàn phím và hỗ trợ đa chạm. Nó cũng có thể được sử dụng trong một loạt các cấu hình để thử nghiệm ứng dụng của bạn, như là chế độ hướng trang nằm ngang/thẳng đứng, cường độ mạng và mạng chuyển vùng , v.v. Tất cả những tùy chọn này có thể được cấu hình khi sử dụng trình quản lý AVD. AVD hoàn toàn độc lập để mô phỏng các thiết bị khác nhau sẵn có. Bạn có thể tạo các AVD khác nhau theo các cấu hình khác nhau và thử nghiệm ứng dụng của bạn trên từng AVD để chắc chắn rằng nó tương thích với mọi loại thiết bị.
Tạo một dự án Android
Đây là cách tạo một dự án Android mới trong Eclipse (xem Hình 1):
- Từ Eclipse, chọn File > New > Project. Một thư mục có tên là Android sẽ có mặt trong hộp thoại nếu trình cắm thêm ADT cho Eclipse đã được cài đặt thành công. Mở rộng thư mục đó sẽ cung cấp tùy chọn cho một dự án Android mới. Chọn nó và nhấn Next.
- Bạn sẽ được nhắc điền các chi tiết sau đây vào trong một biểu mẫu:
- Project name (Tên dự án)— Đây là tên của dự án của bạn và có thể là cái tên nào đó như "HelloWorld" chẳng hạn.
- Application name (Tên ứng dụng)— Đây là tên sẽ xuất hiện ở khắp mọi nơi trong thiết bị Android của bạn, cùng với các biểu tượng trong trình đơn, trong các phím tắt và trên thanh tiêu đề khi bạn chạy ứng dụng của mình. Đây cũng có thể là cái tên nào đó như là "Hello Android."
- Package name (Tên gói)—
com.example.helloandroidhoặc vùng tên riêng của bạn. Tên gói theo cùng các quy tắc như các tên gói trong ngôn ngữ Java.
- Create activity (Tạo hoạt động)— Ở đây, với mục đích minh họa, ta có thể gọi nó là
SaySomething (Nói gì đó). Đây là tên cho lớp sẽ được ADT (Các công
cụ phát triển Android) tạo ra. Đây sẽ là một lớp con của lớp
Activitycủa Android. Một hoạt động đơn giản là một lớp có thể chạy và thực hiện một số công việc. Nó có thể có một giao diện người dùng. Một ứng dụng có thể chứa một hoặc nhiều hoạt động. Thông thường chúng có mối quan hệ 1:1 với các màn hình có trong một ứng dụng. Một ứng dụng di chuyển từ một hoạt động này sang một hoạt động khác bằng cách gọi một phương thức có tên là
startActivity()hay
startSubActivity().
- Min SDK version (Phiên bản SDK tối thiểu)— Điều này quy định mức API tối thiểu theo yêu cầu của ứng dụng của bạn. Phiên bản mới nhất là 7.
Hình 1. Tạo một dự án Android mới
Các chi tiết của dự án Hello Android (Chào Android)
Hello Android là một dự án Android cơ bản, chỉ đơn giản in Hello World trên màn hình. Nó có vai trò sau trong bài viết này:
- Để trình diễn quá trình tạo một dự án Android mới.
- Để đưa ra một tổng quan về các tệp trong một dự án Android và mục đích của chúng.
- Để trình diễn cách triển khai một ứng dụng trên AVD và thử nghiệm nó.
Để xem các tệp và phần tài nguyên khác của dự án Android hãy sử dụng khung nhìn Package Explorer (Trình thám hiểm gói) trong Eclipse (Window > Show View > Package Explorer). Dự án Android vừa được tạo ra sẽ bao gồm các thứ sau (xem Hình 2):
- Có hai thư mục chứa mã nguồn:
- src chứa tất cả các lớp do người dùng xác định, bao gồm lớp hoạt động mặc định.
- gen chứa các tệp do ADT tạo tự động. Tệp R.java bên trong thư mục này chứa các tham chiếu tĩnh tới tất cả tài nguyên hiện có trong thư mục res để cho chúng có thể được tham khảo dễ dàng và động từ mã Java. Không nên sửa đổi thủ công các nội dung của R.java.
Hình 2. Các nội dung của dự án Hello Android
- Một thư mục res chứa tất cả các tài nguyên cho dự án: các biểu tượng, các hình ảnh, các chuỗi ký tự và các bố trí. Việc có một thư mục tài nguyên tách riêng giữ cho các tài nguyên không phải mã nguồn ở ngoài mã nguồn và các tài nguyên có thể được lựa chọn động dựa trên phần cứng, ngôn ngữ, hướng trang và vị trí.
Nó bao gồm:
- (Các) thư mục drawable— dành cho tất cả các tệp hình ảnh.
- Thư mục layout (bố trí) — dành cho các bố trí quy định các màn hình giao diện người dùng cho các hoạt động, dưới dạng mã XML. Tệp Main.xml được tự động tạo ra. Thư mục này gắn liền với cách bố trí thẳng đứng mặc định. Để biểu diễn một số giao diện người dùng theo bố trí nằm ngang (khi một thiết bị Android xoay 90 độ), tạo một thư mục layout-land (vùng bố trí) và đặt tệp XML bố trí của bạn ở đó. Tệp main.xml có một biểu diễn giao diện người dùng hấp dẫn, như trong Hình 3. Bạn có thể kéo và thả các bố trí khác nhau và các khung nhìn trên một màn hình trống để xây dựng các thành phần giao diện người dùng cho hoạt động này.
- Thư mục values (các giá trị) — dành cho tất cả các cặp tên-giá trị (các chuỗi ký tự mà ứng dụng của bạn sẽ xác định).
- Tệp AndroidManifest.xml cũng là một phần quan trọng của dự án. Nó tương đương với tệp plugin.xml cho các trình cắm thêm. Về cơ bản nó định nghĩa các hoạt động trong các ứng dụng và quy định các hành động đã được chỉ rõ cho mỗi hoạt động. Nó cũng liệt kê ra các quyền hạn mà ứng dụng yêu cầu để thực hiện các hành động khác nhau. Một lần nữa, tệp này có một giao diện người dùng đẹp.
Hình 3. Giao diện người dùng cho tệp main.xml
Hãy xem xét các nội dung thực tế của thư mục project (dự án) trên đĩa. Mở Navigator View (Khung nhìn của dẫn hướng) trong Eclipse (Window > Show View > Navigator). Bạn sẽ nhận được cấu trúc cho dự án HelloWorld như trong Hình 4. Ngoài các tệp class được biên dịch, bạn nhận được ba tệp sau đây trong thư mục bin:
- Tệp classes.dex — Tệp có thể thực thi được tạo ra từ các lớp biên dịch.
- Tệp HelloWorld.apk — Tệp lưu trữ nén sẽ được chuyển đến thiết bị Android. Ứng dụng này có thể được cài đặt trên thiết bị Android bất kỳ thông qua tệp lưu trữ này.
- Tệp resources.ap_ — Tệp các tài nguyên ứng dụng nén.
Cấu trúc thư mục của dự án Android
'Hoạt động' chính của ứng dụng
Chúng ta hãy xem xét
MainActivity.java.
Liệt kê 1. Tệp MainActivity.java
package com.example.helloandroid; import android.app.Activity; import android.os.Bundle; public class MainActivity extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); } }
Những điều cần lưu ý về tệp này là:
- Tệp
MainActivitymở rộng một lớp Android cơ bản có tên là
Activity, nằm trong gói
android.app.
- Phương thức
onCreate()là điểm nhập mặc định cho hoạt động này và phải được triển khai thực hiện cho từng hoạt động mới. Nó nhận một đối số kiểu
Bundle(bó). Các tùy chọn và các tham số cần thiết cho việc tạo hoạt động này được chuyển vào tham số này.
- Phương thức
setContentView()có trách nhiệm tạo giao diện người dùng chính sử dụng đối số
R.layout.main. Đây là một hằng số được định nghĩa trong R.java và biểu diễn cách bố trí chủ yếu có trong các tài nguyên của ứng dụng đó.
Tệp Main.xml
Tệp XML này mô tả giao diện người dùng (UI) của ứng dụng. Một hoạt động
có thể tham chiếu đến UI này. Tuy nhiên, UI này không tự ràng buộc nó
vào bất kỳ hoạt động nào. Một UI được xây dựng bằng cách sử dụng các
bố trí và các widget. Tệp
main.xml mà
Eclipse xây dựng theo mặc định gồm có một LinearLayout duy nhất, có
nghĩa là tất cả các phần tử được sắp xếp trong một cột duy nhất. Rồi
nó định nghĩa một
textView, được dùng để
hiển thị văn bản tĩnh không chỉnh sửa được. Trong trường hợp này,
chuỗi "hello" được định nghĩa trong tệp strings.xml (ký hiệu '@' dùng
để chỉ một tệp được định nghĩa trong thư mục res).
Mỗi phần tử khung nhìn bổ sung có các thuộc tính, như là
layout_height (độ cao_ bố trí) và
layout_width (độ rộng_bố trí), v.v.
Hình 5. Tệp Main.xml và khung nhìn properties (các đặc tính)
Một cách dễ dàng để làm việc với tệp
main.xml là thông qua khung nhìn các đặc
tính (Window > Show View > Other > General >
Properties). Khi chọn một khung nhìn cụ thể trong khung
nhìn phác thảo, tab các đặc tính được điền đủ tất cả các thuộc tính có
khả năng của khung nhìn đó, như trong Hình 5. Hầu hết các thuộc tính
này chỉ có thể chọn một số giá trị cố định, và các giá trị cố định này
lại có thể được chọn từ một trình đơn thả xuống bên cạnh mỗi thuộc
tính trong tab các đặc tính. Ví dụ, để thiết lập thuộc tính
layout_height, bạn có thể nhìn thấy hộp thả
xuống và nhận ra rằng nó chỉ có hai giá trị được phép:
wrap_content và
fill_parent.
(
wrap_content sẽ chỉ dựng lên khung nhìn
theo kích thước ban đầu của nó, trong khi
fill_parent sẽ co giãn nó để bao trùm toàn
bộ chiều cao hoặc chiều rộng hoặc cả hai).
Lưu ý: Với các thuộc tính
layout_height và
layout_width, bạn cũng có thể xác định kích
thước theo hai đơn vị sau: (a) Các điểm ảnh độc lập với mật độ (dp)
— Kích thước này cho phép bố trí giống nhau khi được xem trên
các thiết bị có các kích thước màn hình khác nhau. Ví dụ:
layout_width = 10dp; (b) Các điểm ảnh độc
lập co giãn được (sp) — Tương tự như dp, nhưng đây là tiêu
chuẩn được khuyến nghị dành cho các máy điện thoại di động. Ví dụ:
layout_width = 10sp.) Một điều quan trọng
khác cần lưu ý là nếu bạn muốn tham khảo một số khung nhìn/widget nào
đó từ trong mã Java, thì cần phải có một mã định danh (ID) duy nhất.
Nếu bạn sử dụng tab bố trí của tệp
main.xml
để kéo và thả một widget, thì ADT sẽ tự động tạo một ID cho widget đó,
có dạng sau "@+id/someView." Sau đó, trong mã Java, sau đó bạn có thể
tham chiếu nó như
R.id.someView.
Chạy ứng dụng trên trình mô phỏng thiết bị
Để triển khai và chạy ứng dụng này, bạn cần phải xác định một cấu hình chạy. Chọn Open > Run > Dialog hoặc phím tắt trên thanh công cụ trong Eclipse và chọn ứng dụng Android. Nhấn New và điền vào tên của cấu hình chạy này. Chỉ rõ tên dự án của bạn và hoạt động mặc định. Sau đó trong tab đích, chọn một số giá trị cài đặt trình mô phỏng mong muốn và xác định một AVD mà bạn muốn khởi động. Nhấn vào Run (Chạy). Bạn sẽ nhận được một AVD như trong Hình 6. Màn hình của thiết bị được hiển thị bên trái, cùng với một bàn phím QWERTY ở dưới cùng bên trái và các nút di động thông thường như quay số, ngắt kết nối, tắt tiếng, âm lượng và trang chủ ở trên cùng bên trái.
Hình 6. Thiết bị ảo Android (AVD)
Các widget Android
Bây giờ chúng ta biết cách tạo và chạy một ứng dụng Android cơ bản, chúng ta hãy làm đẹp mọi thứ bằng các widget (xem Hình 7):
textViewbao gồm các widget như
editText, nút ấn (Button), v.v. Các nút ấn có thể được được phân loại thêm nữa:
- CheckBox (Hộp kiểm tra).
- RadioButton (Nút ấn tròn).
- ToggleButton (Nút ấn đảo chiều), v.v.
- ImageView bao gồm các widget như ImageButton.
- ViewGroup bao gồm các bố trí như:
- Relative Layout (Bố trí tương đối).
- Table Layout (Bố trí bảng).
- Frame Layout (Bố trí khung).
- Adapter View (Khung nhìn của bộ tiếp hợp).
- Linear Layout (Khung nhìn tuyến tính).
Để biết thông tin về các widgetHướng dẫn trực quan về các widget Giao
diện đồ họa người dùng của Android (GUI Android Widget) là hướng dẫn
tốt nhất. Tuy nhiên, hãy thận trọng với các sai lệch có thể xuất hiện
ở đó do những thay đổi nhanh chóng của nền tảng Android. Một ví dụ rõ
ràng là việc sử dụng
id như là một thuộc
tính của trình định danh cho một widget trong tệp
main.xml trong hướng dẫn nêu trên. Trong nền tảng Android
mới nhất, nên sử dụng tên phân biệt đầy đủ
android:id.
Hình 7. Hệ thống phân cấp các widget của Android
Một ứng dụng mẫu có sử dụng widget
Bây giờ chúng ta sẽ thay đổi ứng dụng hiện có của mình để trông giống
như Hình 8. Mục đích của ví dụ này là làm cho độc giả quen thuộc với
việc sử dụng của một số widget cơ bản như
textView,
editText, Button, và Toast trong một ứng
dụng thực tế.
Ứng dụng của chúng ta sẽ bao gồm một thanh tiêu đề với thông điệp
"WELCOME!!!" Nó sẽ có ba widget
textView
bắt đầu từ trên xuống, sắp xếp theo chiều dọc: widget thứ nhất nói
"Hello World, how're you (Chào thế giới, Bạn thế nào)?" theo phông chữ
mặc định, widget tiếp theo là "Welcome to my first Android app (Chào
mừng đến với ứng dụng Android đầu tiên của tôi)" với chữ serif
nghiêng, canh chính giữa, có nền trắng; và widget thứ ba nói "Type
anything and press the button (Gõ vào gì đó và nhấn nút)" với chữ đậm,
độ rộng bằng nhau, có nền màu đỏ. Sau ba widget này là widget
editText để lấy đầu vào từ người dùng, theo
sau là một widget nút nhấn, nút này đi cùng với thông điệp "Click Me!"
(Nhấn vào tôi). Mọi thứ bạn gõ vào trong widget
editText sẽ xuất hiện trong một widget Toast ở dưới đáy
giữa màn hình khi nhấn vào nút này.
Không có nhiều mã triển khai thực hiện liên quan ở đây. Độc giả nên chú ý rằng các widget có thể được đưa vào trong ứng dụng dễ dàng như thế nào khi sử dụng trình soạn thảo GUI của ADT cho các tệp XML và các đặc tính của widget được thiết lập thuận tiện như thế nào khi sử dụng khung nhìn "properties" (các thuộc tính) do Eclipse cung cấp. Ví dụ này cũng sẽ cho thấy giao diện người dùng và các phần triển khai thực hiện có thể được mã hoá độc lập như thế nào.
Hình 8. Thiết bị ảo Android với các widget
Tệp string.xml
Hãy thêm một số chuỗi mới vào tệp string.xml, thay đổi chuỗi chào mừng
hiện có và cuối cùng là chuỗi tiêu đề. Chúng ta cũng xác định các màu
trắng và màu đỏ ở đây để làm nền cho hai widget
textView.
Liệt kê 2. Tệp string.xml
<?xml version="1.0" encoding="utf-8"?> <resources> <string name="hello">Hello World, how\'re you?</string> <string name="app_name">Hello Android</string> <string name="title">WELCOME!!!</string> <string name="mainText">Welcome to my first android app</string> <string name="subText">Type anything and press the button</string> <color name="White">#FFFFFF</color> <color name="Red">#FF0000</color> </resources>
Chúng ta thay đổi chuỗi ký tự "hello" để chứa "Hello World, how're
you?" Lưu ý ở đây phải có ký tự thoát (
'\')
đối với dấu nháy đơn. Chúng ta cũng định nghĩa hai chuỗi mới:
mainText và
subText, và các màu trắng và đỏ.
Tệp main.xml
Hãy sử dụng tab bố trí của tệp main.xml để kéo và thả hai widget
textView: một widget
editText và một widget nút ấn. Sau đó chúng
ta sẽ sử dụng tab các thuộc tính trong tệp main.xml để chỉnh sửa các
thuộc tính cho mỗi widget.
Liệt kê 3. Tệp main.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/hello" /> <TextView android:layout_height="wrap_content" android:layout_width="fill_parent" android:id="@+id/mainTextView" android:gravity="center" android:text="@string/mainText" android:textStyle="italic" android:typeface="serif" android:background="@color/White"> </TextView> <TextView android:layout_height="wrap_content" android:layout_width="fill_parent" android:layout_margin="20sp" android:gravity="left" android:id="@+id/subTextView" android:padding="10sp" android:text="@string/subText" android:textStyle="bold" android:typeface="monospace" android:background="@color/Red"> </TextView> <EditText android:text="Enter text here" android:id="@+id/EditText01" android:layout_width="wrap_content" android:layout_height="wrap_content"> </EditText> <Button android:text="Click me!" android:id="@+id/Button01" android:layout_width="wrap_content" android:layout_height="wrap_content"> </Button> </LinearLayout>
Với tệp này, chúng ta đã xác định giao diện giao diện người dùng của mình. Bây giờ chúng ta phải liên kết mã hành động của mình với nó.
Tệp MainActivity.java
Đây là tệp thực sự liên kết giao diện người dùng với mã triển khai thực
hiện. Cũng giống như ứng dụng HelloWorld, chúng ta sử dụng phương thức
Activity.onCreate(Bundle) để trang trí tất
cả các phần tử UI trên màn hình. Phương thức
onClick(View) bị ghi đè này sẽ chứa chức
năng nhấn nút, nơi văn bản đầu vào của người dùng sẽ được đọc và được
hiển thị trên màn hình trong một widget toast.
Liệt kê 4. Tệp MainActivity.java
package com.example.helloandroid; import android.app.Activity; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.Toast; public class MainActivity extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); String title = getString(R.string.title); setTitle(title); // done so that we can change the default title //get handles to editText and button widgets final EditText eText = (EditText) findViewById(R.id.EditText01); final Button button = (Button) findViewById(R.id.Button01); button.setOnClickListener(new Button.OnClickListener(){ @Override public void onClick(View v) { //get the String entered into the editText widget CharSequence editText = eText.getText(); //display the toast Toast.makeText(MainActivity.this, editText, Toast.LENGTH_LONG).show(); } }); } }
Khi sử dụng mã này, chúng ta nhận được các ứng dụng như trong Hình 8.
Sử dụng widget
listView: Một ứng dụng
mẫu
Trong phần này, chúng ta sẽ tạo một ứng dụng mẫu (xem hình 9a, 9b) để
hiển thị tất cả các địa chỉ liên lạc trong danh bạ điện thoại bằng
cách sử dụng widget
listView. Mục đích của
ví dụ này là để giới thiệu không chỉ là việc sử dụng widget
listView mà còn cho thấy dữ liệu điện thoại
có thể được tìm nạp như thế nào khi sử dụng các lớp ContentProvider và
ContentResolver. Hãy chú ý đến các tệp XML của giao diện người dùng vì
có hai cách bố trí giao diện người dùng: một để xác định cách widget
listView sẽ hiển thị danh sách khít với
giao với giao diện người dùng chính và cái kia để xác định cách hiển
thị từng phần tử của danh sách đó. Một điểm quan trọng là thiết lập
các quyền hạn cho các ứng dụng có thể đọc dữ liệu điện thoại. Ví dụ
này là bước đầu tiên để hiểu được cách có thể kết hợp các ý định
(intent) và các bộ lọc ý định trong một ứng dụng. Mặc dù các intent
nằm ngoài phạm vi của bài viết này, nhưng độc giả cũng nên lưu ý rằng
để chuyển ứng dụng của ví dụ này thành một ứng dụng danh bạ điện thoại
trong thế giới thực, chỉ cần triển khai thực hiện các thao tác nhấn
vào các mục của danh sách và tạo một ý định (intent) cuộc gọi và bộ
lọc ý định để bắt đầu một cuộc gọi đến địa chỉ liên lạc được chọn.
Trong ví dụ này, các địa chỉ liên lạc sẽ được hiển thị theo mẫu thẳng
theo chiều dọc và địa chỉ liên lạc được chọn sẽ xuất hiện ở đầu danh
sách với một phông chữ in nghiêng lớn và một nền màu xanh dương. Chúng
ta cũng có một hộp kiểm tra ở phía dưới cùng bên trái của màn hình, mà
khi được đánh dấu chọn, sẽ hiển thị chỉ các địa chỉ liên lạc được đánh
dấu sao (hoặc các địa chỉ liên lạc ưa thích). Tiêu đề của ứng dụng
trong trường hợp này là "Contact Manager (Trình quản lý các địa chỉ
liên lạc). Ở đây chúng ta sử dụng ba loại widget:
textView,
listView và
checkBox. Chúng ta sử dụng widget
textView để hiển thị địa chỉ liên lạc hiện
đang được chọn. Bạn có thể đoán ngay rằng widget
listView là một danh sách các widget
textView. Widget
listView sử dụng các mẫu thiết kế của bộ
tiếp hợp để kết nối dữ liệu (trong trường hợp này là các địa chỉ liên
lạc) và một khung nhìn dữ liệu (trong trường hợp này là một
textView cho
listView này. Mọi thao tác nhấn trên
listView có thể được bắt giữ lại bằng cách
thực hiện phương thức
AdapterView.OnItemClickListener().
Trước khi tiếp tục, chúng ta nên có một số các địa chỉ liên lạc được lưu trong phần các địa chỉ liên lạc của trình mô phỏng thiết bị của Android (AVD). Điều này có thể được thực hiện bằng cách nhấn vào Contacts (Các địa chỉ liên lạc) trên màn hình chủ của AVD, sau đó nhấn vào Menu để có tùy chọn Add Contacts (Thêm các địa chỉ liên lạc). Phần Favorites (Các địa chỉ liên lạc ưa thích) cho biết cách đánh dấu một địa chỉ liên lạc như là ưa thích/được đánh dấu sao.
Hình 9a. Ứng dụng
các địa chỉ liên lạc hiển thị tất cả các địa chỉ liên lạc trong
một widget
listView
Hình 9b. Ứng dụng
các địa chỉ liên lạc hiển thị tất cả các địa chỉ liên lạc được
đánh dấu sao trong một widget
listView
khi đánh dấu chọn vào hộp kiểm tra hiển thị các địa chỉ liên lạc
có đánh dấu sao
Bây giờ chúng ta sẽ định nghĩa một vài chuỗi.
Liệt kê 5. Các chuỗi được định nghĩa trong tệp strings.xml
<?xml version="1.0" encoding="utf-8"?> <resources> <string name="hello">Hello World, Manager!</string> <string name="app_name">Contact Manager</string> <string name="selectedEntry" /> <color name="White">#FFFFFF</color> <color name="Black">#000000</color> <color name="Blue">#0000FF</color> <string name="showStarred">Show starred contacts only</string> </resources>
Tệp main.xml
Chúng ta hãy định nghĩa cách bố trí chính cho ứng dụng của mình. Widget
listView sẽ cung cấp danh sách tất cả các
địa chỉ liên lạc trong danh bạ điện thoại.
listView hiển thị từng mục bên trong một
widget
textView, mà chúng ta sẽ định nghĩa
tiếp sau.
Liệt kê 6. Tệp main.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:gravity="center" android:id="@+id/selectedContact" android:padding="10dp" android:textSize="20sp" android:textStyle="italic" android:typeface="serif" android:background="@color/Blue" android:textColor="@color/White" android:text="@string/selectedEntry"/> <ListView android:id="@+id/contactsListView" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_weight="1"> </ListView> <CheckBox android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/showStarred" android:text="@string/showStarred"/> </LinearLayout>
Lưu ý rằng việc gán cho thuộc tính layout_weight giá trị bằng 1 trong
listView bảo đảm chắc chắn rằng danh sách
phủ hết vùng màn hình càng lớn càng tốt cho đến khi một widget mới
được định nghĩa.
Tệp contactItem.xml
Bên cạnh bố trí chính, chúng ta cần phải xác định một cách bố trí khác
ở đây. Việc này là để thể hiện từng phần tử trong
listView này. Ở đây, ta sử dụng một
textView đơn giản.
Liệt kê 7. Mã cho widget
textView, thiết lập từng phần tử của widget
listView
<?xml version="1.0" encoding="utf-8"?> <TextView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="wrap_content" android:padding="5dp" android:textStyle="bold" android:id="@+id/contactItem"> </TextView>
Lưu ý rằng theo mặc định Android cung cấp một cách bố trí đơn giản, có
thể được sử dụng thay cho định nghĩa riêng của bạn. Điều này có thể
được tham chiếu qua
android.R.layout.simple_list_item_1.
Tệp ManageContacts.java
Liệt kê 8 cho thấy hoạt động chính được triển khai thực hiện như thế
nào. Phương thức
populateContactList() là
một phương thức mà chúng ta sử dụng để truy vấn cơ sở dữ liệu các địa
chỉ liên lạc và hiển thị chúng trong
listView này.
Liệt kê 8. Triển khai thực hiện của hoạt động chính
public class ManageContacts extends Activity { private ListView mContactList; private CheckBox mCheckBox; private boolean mShowStarred; private TextView selectedText; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); mContactList = (ListView) findViewById(R.id.contactsListView); mCheckBox = (CheckBox) findViewById(R.id.showStarred); selectedText = (TextView) findViewById(R.id.selectedContact); mShowStarred = false; mCheckBox.setOnCheckedChangeListener(new CheckChangedListener()); mContactList.setOnItemClickListener(new ClickListener()); populateContactList(); } public void populateContactList() { Uri uri = ContactsContract.Contacts.CONTENT_URI; String[] projection = new String[] { ContactsContract.Contacts._ID, ContactsContract.Contacts.DISPLAY_NAME, }; String[] selectionArgs = null; String sortOrder = ContactsContract.Contacts.DISPLAY_NAME + " COLLATE LOCALIZED ASC"; String selection = mShowStarred? ContactsContract.Contacts.STARRED + " ='1'" : null; Cursor c = getContentResolver().query(uri, projection, selection, selectionArgs, sortOrder); String[] fields = new String[] { ContactsContract.Data.DISPLAY_NAME }; SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, R.layout.contactitem, c, fields, new int[] {R.id.contactItem}); mContactList.setAdapter(adapter); } private class ClickListener implements OnItemClickListener { @Override public void onItemClick(AdapterView<?> arg0, View textView, int pos, long arg3) { if(textView instanceof TextView) selectedText.setText(((TextView) textView).getText()); } } private class CheckChangedListener implements OnCheckedChangeListener { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { mShowStarred = isChecked; selectedText.setText(""); populateContactList(); } } }
Những điều cần lưu ý:
- Chúng ta có hai trình lắng nghe — một trình lắng nghe để xử
lý các lần nhấn vào một mục của danh sách và cái kia để xử lý các
lần nhấn vào hộp kiểm tra. Trình lắng nghe đầu tiên chỉ đơn giản
đặt văn bản trong hộp
textViewmàu xanh dương với tên hiển thị của địa chỉ liên lạc hiện đang được chọn. Trình lắng nghe sau là để thiết lập trường
mShowStarredvà điền lại danh sách.
- Để đọc các địa chỉ liên lạc từ cơ sở dữ liệu điện thoại, chúng ta
cần phải truy vấn nó để có được một con trỏ. Truy vấn này có các
tham số sau:
- uri— URI sử dụng content:// scheme để lấy ra nội dung.
- projection (hình chiếu)— Một danh sách các cột nào sẽ được trả về. Nếu cho bằng null sẽ trả về tất cả các cột; điều này không nên làm để tránh đọc nhiều dữ liệu từ bộ nhớ mà sẽ không dùng hết.
- selection (lựa chọn)— Một bộ lọc khai báo sẽ trả về hàng nào, được định
dạng như là một mệnh đề
WHEREcủa SQL (ngoại trừ chính từ khóa
WHERE). Cho bằng null sẽ trả về tất cả các hàng có trong URI đã cho.
- selectionArgs— Bạn có thể bao gồm các dấu hỏi
?, chúng sẽ được thay thế bằng các giá trị từ
selectionArgs, theo đúng trình tự mà chúng xuất hiện trong selection. Các giá trị này sẽ bị buộc như là kiểu chuỗi ký tự (String).
- sortOrder— sắp xếp các hàng như thế nào, được định dạng
như là một mệnh đề SQL
ORDER BYcủa SQL (ngoài trừ chính từ khóa
ORDER BY). Cho bằng null sẽ sử dụng thứ tự sắp xếp mặc định, mà theo mặc định có thể là không theo thứ tự nào cả.
Con trỏ của tập hợp kết quả đã thu được phải được liên kết với giao
diện người dùng qua một bộ tiếp hợp (adapter). Chúng ta sử dụng một
SimpleCursorAdapter ở đây, mặc dù Android
cũng cung cấp một
ListAdapter. Khi nhận
được bộ tiếp hợp chúng ta cần phải gắn nó kèm theo vào
listView và thế là xong.
Các quyền hạn
Một bước cuối cùng trước khi ứng dụng của chúng ta sẽ chạy thành công trên một thiết bị Android là thiết lập các quyền hạn. Không có các quyền hạn để có thể đọc cơ sở dữ liệu các địa chỉ liên lạc, nhân (kernel) Linux trong thiết bị đó sẽ không cho phép các ứng dụng làm như vậy. Vì vậy, hãy vào AndroidManifest.xml>Permissions tab và thiết lập các quyền hạn sau:
android.permission.GET_ACCOUNTS
android.permission.READ_CONTACTS
Các quyền hạn này có thể được thiết lập bằng cách nhấn vào biểu tượng U và định nghĩa quyền hạn. Hình 10 cho thấy tab permissions trông như thế nào.
Hình 10. Bản kê các quyền hạn của Android
Widget
listView khi sử dụng
ListActivity
Ví dụ này được dùng để trình bày một cách khác để triển khai thực hiện
một
listView. Trong ứng dụng trên, lưu ý
rằng hoạt động chính của chúng ta triển khai thực hiện lớp hoạt động.
Khi đề cập đến các widget
listView, đôi khi
lớp
ListActivity tỏ ra rất tiện lợi vì nó
có các API công cộng để xử lý các lần nhấn vào các mục danh sách,
thiết lập các bộ tiếp hợp của danh sách, lấy vị trí nơi nhấn vào, v.v.
Chúng ta có thể sửa đổi (mã lệnh của) hoạt động của mình để triển khai
thực hiện lớp
ListActivity như trong Liệt
kê 9.
Liệt kê 9. Triển khai thực hiện bằng cách sử dụng lớp
ListActivity
public class ManageContacts extends ListActivity { @Override protected void onListItemClick(ListView l, View v, int position, long id) { // TODO Auto-generated method stub super.onListItemClick(l, v, position, id); if(v instanceof TextView) selectedText.setText(((TextView) v).getText()); } private CheckBox mCheckBox; private boolean mShowStarred; private TextView selectedText; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); mCheckBox = (CheckBox) findViewById(R.id.showStarred); selectedText = (TextView) findViewById(R.id.selectedContact); mShowStarred = false; mCheckBox.setOnCheckedChangeListener(new CheckChangedListener()); populateContactList(); } public void populateContactList() { Uri uri = ContactsContract.Contacts.CONTENT_URI; String[] projection = new String[] { ContactsContract.Contacts._ID, ContactsContract.Contacts.DISPLAY_NAME, }; String[] selectionArgs = null; String sortOrder = ContactsContract.Contacts.DISPLAY_NAME + " COLLATE LOCALIZED ASC"; String selection = mShowStarred? ContactsContract.Contacts.STARRED + " ='1'" : null; Cursor c = getContentResolver().query(uri, projection, selection, selectionArgs, sortOrder); String[] fields = new String[] { ContactsContract.Data.DISPLAY_NAME }; ListAdapter adapter = new SimpleCursorAdapter(this, R.layout.contactitem, c, fields, new int[]{R.id.contactItem}); setListAdapter(adapter); } private class CheckChangedListener implements OnCheckedChangeListener { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { mShowStarred = isChecked; selectedText.setText(""); populateContactList(); } } }
Lưu ý rằng ở đây chúng ta chỉ cần triển khai thực hiện phương thức
onListItemClick của lớp
ListActivity, thay vì khai báo một lớp ẩn
danh để xử lý các lần nhấn. Ở đây, chúng ta cũng không cần phải tham
chiếu đến widget
listView được xác định
trong tệp main.xml vì lớp
ListActivity giả
định rằng widget
listView được định nghĩa
với mã định danh là
@android:id/list. Đây
là lưu ý quan trọng. Bất cứ khi nào chúng ta sử dụng lớp
ListActivity, chúng ta phải định nghĩa widget
listView trong tệp main.xml để có một
mã định danh @android:id/list; nếu không, lớp
ListActivity sẽ không biết tham chiếu đến
listView nào.
Kết luận
Trong hướng dẫn này, chúng ta đã tìm hiểu cách thiết lập Eclipse để phát triển cho Android và các tính năng phong phú của Eclipse hỗ trợ từng bước để viết các ứng dụng Android như thế nào. Chúng ta cũng đã tìm hiểu các ứng dụng có thể dễ dàng được triển khai và thử nghiệm trên trình phỏng theo thiết bị Android — AVD như thế nào. Chúng ta trình bày các tính năng nổi bật của một ứng dụng Android bằng cách sử dụng một ví dụ Hello World và đã tìm hiểu về các tệp tạo ra một ứng dụng Android. Chúng ta đã đề cập đến một số các widget do Android cung cấp và đã biết cách sử dụng chúng trong một số ví dụ thực tế. Bây giờ bạn sẽ có thể bắt đầu tạo một ứng dụng thú vị với một giao diện người dùng gọn gàng. Bước đầu tiên, hãy mở rộng ứng dụng các địa chỉ liên lạc để triển khai thực hiện hành động nhấn vào một mục của danh sách để hiển thị các số điện thoại và các chi tiết liên hệ và một nút để gọi địa chỉ liên lạc được chọn. Cũng cần xác định một ý định (intent) cuộc gọi, cùng với một bộ lọc ý định, sẽ triển khai thực hiện chức năng tạo cuộc gọi.
Android là một nền tảng mạnh mẽ cho các ứng dụng di động và việc mã hóa bằng công nghệ Java, cùng với Các công cụ phát triển Android cho Eclipse, làm cho những người bắt đầu dễ dàng chấp nhận nó. Mảng các widget rộng lớn của nó, cùng với khả năng gắn kết (bind) động các phần tử giao diện người dùng tới phần triển khai thực hiện, cung cấp nhiều tính linh hoạt và làm cho các ứng dụng gọn nhẹ hơn, mặc dù vẫn có giao diện người dùng phong phú. Các khái niệm về các hoạt động, các ý định, các nhà cung cấp nội dung, v.v, làm dễ dàng việc quản lý giao diện người dùng và các phần tử dữ liệu và kiểm soát việc gắn kết giữa chúng. Cũng có một mảng rộng lớn các API nối mạng để khám phá. Ngoài ra, các API của Google cung cấp chức năng về các bản đồ, tìm kiếm và thư điện tử, và nhiều thứ khác nữa, tất cả có thể dễ dàng được chấp nhận trong một ứng dụng Android. Vì vậy, hãy đi sâu vào thế giới tuyệt vời này của Android và hãy để cho trí tưởng tượng của bạn phát triển thoải mái.
Tài nguyên
Học tập
- Hướng dẫn của nhà phát triển là một mở đầu thiết thực để phát triển các ứng dụng cho Android.
- Đọc "Phát triển các ứng dụng Android với Eclipse" để nhận được một bài học nhập môn về phát triển Android với một giới thiệu nhanh cho nền tảng này.
- Chắc chắn đọc hướng dẫn Hello, World.
- "Một hướng dẫn trực quan về Các Widget GUI của Android" cung cấp thêm nhiều thông tin.
- Đọc Ngày Eclipse tại Googleplex: Phát triển Android bằng Eclipse.
- Đừng bỏ lỡ Hướng dẫn phát triển Android của Lars Vogella.
- Xem một loạt các video hướng dẫn cho Android Phòng nghiên cứu khoa học điện toán Elon.
- Xem "Danh sách khuyến khích đọc Eclipse."
- Duyệt tất cả nội dung Eclipse trên developerWorks.
- Theo dõi developerWorks trên Twitter.
- Mới đến với Eclipse? Đọc bài viết "Hãy bắt đầu với Nền tảng Eclipse" để tìm hiểu nguồn gốc và kiến trúc của nó và cách mở rộng Eclipse bằng các trình cắm thêm.
- Mở rộng các kỹ năng Eclipse của bạn bằng cách xem Tài nguyên dự án Eclipse của developerWorks IBM.
- Để nghe các cuộc phỏng vấn và các cuộc thảo luận thú vị dành cho các nhà phát triển phần mềm, hãy xem developerWorks podcasts.
- Cộng đồng My developerWorks là một ví dụ về một cộng đồng rộng rãi thành công bao trùm nhiều chủ đề rộng lớn.
- Theo sát các sự kiện kỹ thuật và Webcast của developerWorks.
- Xem và tìm hiểu về IBM và các công nghệ mã nguồn mở và các chức năng sản phẩm với chương trình trình diễn miễn phí theo yêu cầu của developerWorks.
- Xem các hội nghị, triển lãm thương mại, Webcast sắp tới và Các sự kiện khác trên thế giới được các nhà phát triển nguồn mở của IBM quan tâm.
- Truy cập vào Vùng mã nguồn mở của developerWorks với các thông tin hướng dẫn rộng lớn, các công cụ và các bản cập nhật dự án để giúp bạn phát triển bằng các công nghệ mã nguồn mở và sử dụng chúng với các sản phẩm của IBM, cũng như hầu hết các bài viết và các hướng dẫn phổ biến của chúng tôi.
Lấy sản phẩm và công nghệ
- Hãy chắc chắn tải về Eclipse cho RCP/Plug-in.
- Tải về Android SDK.
- Nhận lấy Trình cắm thêm ADT cho Eclipse.
- Xem Các bản tải về công nghệ Eclipse mới nhất tại alphaWorks của IBM.
- Tải về Nền tảng Eclipse và các dự án khác từ Quỹ Eclipse.
- Tải về các phiên bản đánh giá sản phẩm của IBM hoặc khám phá các thử nghiệm trực tuyến trong SOA Sandbox của IBM và nhận các công cụ phát triển ứng dụng thực hành của bạn và các sản phẩm phần mềm trung gian từ DB2®, Lotus®, Rational®, Tivoli® và WebSphere®.
- Đổi mới dự án phát triển nguồn mở tiếp theo của bạn bằng phần mềm dùng thử IBM, có sẵn để tải xuống hoặc trên đĩa DVD.
Thảo luận
- Các nhóm tin Nền tảng Eclipse là nơi dừng chân đầu tiên của bạn để thảo luận các câu hỏi về Eclipse. (Việc chọn mục này sẽ khởi chạy ứng dụng đọc tin Usenet mặc định của bạn và mở eclipse.platform).
- Các nhóm tin Eclipse có nhiều tài nguyên cho những người quan tâm đến việc sử dụng và mở rộng Eclipse.
- Tham gia vào các blog developerWorks và dành tâm trí cho cộng đồng developerWork.
Bình luận
-
Vùng dữ liệu trên developerWorks
Khám phá các bài viết xoay quanh lĩnh vực dữ liệu, Quản lý hệ thống thông tin
-
Vùng mã nguồn mở trên developerWorks
Xem các bài viết về HTML, CSS, JavaScript,...
-
Điện toán đám mây
Tìm hiểu về điện toán đám mây

markdown:
## Mở đầu
Android là một hệ điều hành di động, tương tự như Symbian, iOS, Windows® Mobile, và những hệ điều hành khác. Ban đầu Android do công ty Android Inc. phát triển, về sau Google đã mua lại công ty này. Android bây giờ thuộc quyền sở hữu của Open Handset Alliance (Liên minh mở về thiết bị cầm tay) và hoàn toàn là nguồn mở, đó là lý do làm nó ngày càng phổ biến. Google đã phát hành hầu hết các mã Android theo Giấy phép của Apache. Với giấy phép này, các nhà cung cấp có thể thêm phần mở rộng độc quyền mà không cần đệ trình chúng lại cho cộng đồng nguồn mở. Nhiều phiên bản Android đã ra thị trường kể từ lúc khởi đầu (gần đây nhất là quý 3 năm 2010), bao gồm power-packed Froyo (Froyo được đóng gói mạnh) (phiên bản V2.2). Android đã vượt ra ngoài, không còn chỉ là một nền tảng cho các thiết bị di động; hệ thống truyền hình mới của Google cũng chạy trên Android.
Android sử dụng một nhân (kernel) Linux® đã cải biên và cho phép ứng dụng được phát triển bằng công nghệ Java™, sử dụng các thư viện Java (một số trong các thư viện đó được Google phát triển cho Android). Mặc dù các ứng dụng Android được viết bằng ngôn ngữ Java, không có Máy ảo Java (Java Virtual Machine) nào chạy trong nền tảng này và mã byte Java không được thi hành ở đây. Các lớp Java được biên dịch lại thành mã Dalvik thi hành được và chạy trên một máy ảo Dalvik. Dalvik là một máy ảo Android đã cải biên và tối ưu hóa cho các thiết bị chạy bằng nguồn pin và có CPU thấp.
Đối với các nhà phát triển, Android SDK (Bộ công cụ phát triển phần mềm của Android) cung cấp một tập hợp các công cụ phong phú, bao gồm trình gỡ rối, các thư viện, trình mô phỏng thiết bị cầm tay, tài liệu, mã mẫu và các hướng dẫn. Các ứng dụng Android có thể dễ dàng được phát triển khi sử dụng Eclipse (nền tảng phát triển chính thức của Android) với sự trợ giúp của một trình cắm thêm được gọi là ADT (Android Development Tools – Các công cụ phát triển Android). Điều này giúp tận dụng các tính năng phong phú của Eclipse, như là hỗ trợ nội dung, tìm kiếm Java, các tài nguyên mở, tích hợp JUnit và các khung nhìn và các ảnh phối cảnh khác nhau để phát triển một ứng dụng Android. Một mảng rộng rãi các widget (tiện ích), tương tự như các widget swing của Java, tạo điều kiện thuận lợi trong việc tạo một giao diện người dùng phong phú cho các ứng dụng. Một công cụ Javadoc chi tiết giúp cho quá trình phát triển này khá dễ dàng.
Ở đây, chúng ta bắt đầu với một hướng dẫn để chuẩn bị hệ thống cho việc
phát triển Android. Sau đó chúng ta đề cập ngắn đến các tính năng quan
trọng nhất của một ứng dụng Android bằng cách sử dụng một ứng dụng
Hello World (Chào thế giới) cơ bản của Android. Chúng ta cũng bàn về
các tệp tạo nên một ứng dụng Android và cách thức giao diện người dùng
được tách khỏi việc triển khai thực hiện như thế nào. Sau khi trình
bày xong quá trình tạo, phát triển và khởi chạy một ứng dụng Android
từ Eclipse, chúng ta chuyển sang thảo luận về một vài widget của
Android giúp cho việc xây dựng một giao diện người dùng phong phú (một
phần rất quan trọng của các ứng dụng di động). Chúng ta trình bày một
số widget cơ bản với sự trợ giúp của một ứng dụng mẫu. Chúng ta cũng
bàn về cách sử dụng widget
listView trong
một ứng dụng giống như danh bạ điện thoại và những cách triển khai
thực hiện nó. Trong lúc đó, chúng ta cũng bàn về các quyền hạn cần
phải được thiết lập để có thể cho phép một ứng dụng truy cập một số dữ
liệu từ hệ điều hành. Nhìn chung, vài giờ học theo bài viết này sẽ
giúp bạn tạo một ứng dụng triển khai thực hiện những chức năng cơ bản
và có một giao diện người dùng hấp dẫn.
### Các yêu cầu hệ thống
Trước khi bắt đầu phát triển Android, hãy chắc chắn rằng bạn đã cài đặt các phần mềm sau:
[Eclipse SDK (Bộ công cụ phát triển phần mềm Eclipe)](http://www.eclipse.org/downloads/packages/eclipse-rcpplug-developers/galileosr2)— phiên bản V3.5 được đề xuất sử dụng với Android SDK mới nhất. Có thể tải phần mềm này từ trang tải Galileo. [Android SDK (Bộ công cụ phát triển phần mềm Android)](http://developer.android.com/sdk/index.html). [Android Development Tools (ADT - Các công cụ phát triển Android)](http://developer.android.com/sdk/eclipse-adt.html)— Đây là một trình cắm thêm Eclipse. Nó tương đương với JDT (Các công cụ phát triển Java) để phát triển Android. Hãy làm theo các hướng dẫn chi tiết để cài đặt trình cắm thêm ADT cũng như thiết lập vị trí của Android SDK trong Eclipse.
## Thuật ngữ Android
Một ứng dụng Android điển hình có các thành phần sau. Dưới đây cũng
trình bày các định nghĩa do
[trang Web của nhà phát
triển Android](http://developer.android.com/guide) cung cấp:
- Activity (Hoạt động) — Một
*hoạt động*biểu thị một giao diện người dùng trực quan của một nỗ lực tập trung có chủ hướng mà người dùng có thể thực hiện. Ví dụ, một hoạt động có thể biểu thị một danh sách các mục trình đơn mà người dùng có thể lựa chọn từ đó hoặc nó có thể hiển thị các hình ảnh cùng với lời chú thích của chúng. Một ứng dụng tin nhắn văn bản có thể có một hoạt động để hiển thị một danh sách các địa chỉ liên lạc để gửi tin nhắn đến, có một hoạt động thứ hai để viết tin nhắn cho địa chỉ liên lạc đã chọn và các hoạt động khác để xem lại tin nhắn cũ hoặc thay đổi các giá trị cài đặt. Mặc dù các hoạt động này làm việc cùng nhau để tạo thành một giao diện người dùng gắn kết, nhưng mỗi hoạt động độc lập với các hoạt động khác.
- Content providers (Những nhà cung cấp nội dung) — Một
*nhà cung cấp nội dung*tạo ra một tập hợp cụ thể các dữ liệu của ứng dụng, sẵn có cho các ứng dụng khác. Các dữ liệu có thể được lưu trữ trong hệ thống tệp, trong một cơ sở dữ liệu SQLite hoặc theo cách hợp lý bất kỳ khác.
- Service (Dịch vụ) — Một
*dịch vụ*không có một giao diện người dùng trực quan mà chạy ở nền sau, trong một khoảng thời gian không xác định. Ví dụ, một dịch vụ có thể chơi nhạc nền khi người dùng tham dự vào các vấn đề khác hoặc nó có thể tìm nạp dữ liệu qua mạng hoặc tính toán một cái gì đó và cung cấp kết quả cho các hoạt động cần nó.
- Broadcast receivers (Các bộ thu quảng bá) — Một
*bộ thu quảng bá*là một thành phần không làm gì khác ngoài thu nhận và phản ứng lại với các thông báo quảng bá. Nhiều thông báo quảng bá bắt nguồn từ mã hệ thống — các thông báo thay đổi-múi giờ, các thông báo pin sắp hết pin, thay đổi ngôn ngữ-ưa thích, v.v.
Một số thuật ngữ khác cần biết:
- Intent (Ý định) — Các hoạt động, các dịch vụ và các bộ thu
quảng bá được kích hoạt bằng các thông báo không đồng bộ được gọi
là
*các ý định*. Một ý định là một đối tượng
Intentđể lưu giữ các nội dung của thông báo. Ví dụ, nó có thể truyền đạt yêu cầu một hoạt động để hiển thị một hình ảnh cho người sử dụng hoặc cho phép người dùng chỉnh sửa một số văn bản.
- Intent filter (Bộ lọc ý định) — Một đối tượng Intent có
thể gọi tên rõ ràng một thành phần đích. Nếu nó làm như vậy thì
Android sẽ tìm thấy thành phần đó (dựa vào các khai báo trong tệp
bản kê) và kích hoạt thành phần này. Tuy nhiên, nếu đích không
được gọi tên rõ ràng, thì Android phải định vị thành phần tốt nhất
để đáp ứng ý định đó. Nó làm như vậy bằng cách so sánh đối tượng
Intent với
*các bộ lọc ý định*của các đích có tiềm năng. Bộ lọc ý định của một thành phần thông báo cho Android về các loại ý định mà thành phần đó có khả năng xử lý.
Để hiểu về các thành phần này, hãy tham khảo "
[Phát triển các ứng dụng Android với Eclipse](http://www.ibm.com/developerworks/opensource/tutorials/os-eclipse-android/index.html?S_TACT=105AGY75)" và [hướng dẫn Hello, World](http://developer.android.com/resources/tutorials/hello-world.html) của Android.
## Tạo một Thiết bị ảo Android
Bước này cần thiết để tạo một trình mô phỏng điện thoại Android/AVD (Android Virtual Device - Thiết bị ảo của Android ) trên đó các ứng dụng có thể chạy và được thử nghiệm. Lưu ý rằng để khởi động cho một AVD phải mất một chút thời gian. Tin vui là không cần các AVD riêng biệt cho mỗi ứng dụng được triển khai và thử nghiệm. Một khi AVD được khởi chạy, có thể triển khai một số lượng ứng dụng bất kỳ trong khi nó vẫn còn đang chạy và thậm chí có thể sử dụng nó để gỡ rối ứng dụng. Để tạo một AVD:
- Trong Eclipse, chọn
**Window > Android SDK**và **AVD Manager**(Trình quản lý AVD).
- Chọn
**Virtual Devices**(Các thiết bị ảo) ở khung bên trái.
- Nhấn
**New**. Hộp thoại **Create New AVD**(Tạo AVD mới) xuất hiện.
- Gõ tên của AVD vào, ví dụ như "myPhone."
- Chọn một đích. Đích là một nền tảng (đó là một phiên bản Android SDK, ví dụ như 2.1) để chạy trên trình mô phỏng . Bạn cũng sẽ nhận được một tùy chọn để chọn các API của Google, nhưng việc đó là không cần thiết trừ khi chúng ta đặc biệt muốn có một số API của Google trong ứng dụng. Các trường còn lại tạm thời có thể bỏ qua vào lúc này.
- Nhấn
**Create AVD**(Tạo AVD).
Một khi AVD này được khởi chạy, bạn có thể thấy nó mang lại dáng vẻ và cảm nhận đầy đủ của một điện thoại di động dựa trên Android thực, có đủ bàn phím và hỗ trợ đa chạm. Nó cũng có thể được sử dụng trong một loạt các cấu hình để thử nghiệm ứng dụng của bạn, như là chế độ hướng trang nằm ngang/thẳng đứng, cường độ mạng và mạng chuyển vùng , v.v. Tất cả những tùy chọn này có thể được cấu hình khi sử dụng trình quản lý AVD. AVD hoàn toàn độc lập để mô phỏng các thiết bị khác nhau sẵn có. Bạn có thể tạo các AVD khác nhau theo các cấu hình khác nhau và thử nghiệm ứng dụng của bạn trên từng AVD để chắc chắn rằng nó tương thích với mọi loại thiết bị.
## Tạo một dự án Android
Đây là cách tạo một dự án Android mới trong Eclipse (xem Hình 1):
- Từ Eclipse, chọn
**File > New > Project**. Một thư mục có tên là **Android**sẽ có mặt trong hộp thoại nếu trình cắm thêm ADT cho Eclipse đã được cài đặt thành công. Mở rộng thư mục đó sẽ cung cấp tùy chọn cho **một dự án Android**mới. Chọn nó và nhấn **Next**.
- Bạn sẽ được nhắc điền các chi tiết sau đây vào trong một biểu mẫu:
*Project name (Tên dự án)*— Đây là tên của dự án của bạn và có thể là cái tên nào đó như "HelloWorld" chẳng hạn. *Application name (Tên ứng dụng)*— Đây là tên sẽ xuất hiện ở khắp mọi nơi trong thiết bị Android của bạn, cùng với các biểu tượng trong trình đơn, trong các phím tắt và trên thanh tiêu đề khi bạn chạy ứng dụng của mình. Đây cũng có thể là cái tên nào đó như là "Hello Android." *Package name (Tên gói)*—
com.example.helloandroidhoặc vùng tên riêng của bạn. Tên gói theo cùng các quy tắc như các tên gói trong ngôn ngữ Java.
*Create activity (Tạo hoạt động)*— Ở đây, với mục đích minh họa, ta có thể gọi nó là SaySomething (Nói gì đó). Đây là tên cho lớp sẽ được ADT (Các công cụ phát triển Android) tạo ra. Đây sẽ là một lớp con của lớp
Activitycủa Android. Một hoạt động đơn giản là một lớp có thể chạy và thực hiện một số công việc. Nó có thể có một giao diện người dùng. Một ứng dụng có thể chứa một hoặc nhiều hoạt động. Thông thường chúng có mối quan hệ 1:1 với các màn hình có trong một ứng dụng. Một ứng dụng di chuyển từ một hoạt động này sang một hoạt động khác bằng cách gọi một phương thức có tên là
startActivity()hay
startSubActivity().
*Min SDK version (Phiên bản SDK tối thiểu)*— Điều này quy định mức API tối thiểu theo yêu cầu của ứng dụng của bạn. Phiên bản mới nhất là 7.
##### Hình 1. Tạo một dự án Android mới
![ Ảnh chụp màn hình việc tạo dự án HelloWorld trong Eclipse với bộ đích xây dựng cho Android 2.1](figure01.jpg)
## Các chi tiết của dự án Hello Android (Chào Android)
Hello Android là một dự án Android cơ bản, chỉ đơn giản in Hello World trên màn hình. Nó có vai trò sau trong bài viết này:
- Để trình diễn quá trình tạo một dự án Android mới.
- Để đưa ra một tổng quan về các tệp trong một dự án Android và mục đích của chúng.
- Để trình diễn cách triển khai một ứng dụng trên AVD và thử nghiệm nó.
Để xem các tệp và phần tài nguyên khác của dự án Android hãy sử dụng
khung nhìn Package Explorer (Trình thám hiểm gói) trong Eclipse
(
**Window > Show View > Package Explorer**). Dự
án Android vừa được tạo ra sẽ bao gồm các thứ sau (xem Hình 2):
- Có hai thư mục chứa mã nguồn:
**src**chứa tất cả các lớp do người dùng xác định, bao gồm lớp hoạt động mặc định. **gen**chứa các tệp do ADT tạo tự động. Tệp R.java bên trong thư mục này chứa các tham chiếu tĩnh tới tất cả tài nguyên hiện có trong thư mục **res**để cho chúng có thể được tham khảo dễ dàng và động từ mã Java. Không nên sửa đổi thủ công các nội dung của R.java.
##### Hình 2. Các nội dung của dự án Hello Android
![ Ảnh chụp màn hình bố trí dự án Hello của Android trong Eclipse](figure02.jpg)
- Một thư mục
**res**chứa tất cả các tài nguyên cho dự án: các biểu tượng, các hình ảnh, các chuỗi ký tự và các bố trí. Việc có một thư mục tài nguyên tách riêng giữ cho các tài nguyên không phải mã nguồn ở ngoài mã nguồn và các tài nguyên có thể được lựa chọn động dựa trên phần cứng, ngôn ngữ, hướng trang và vị trí.
Nó bao gồm:
- (Các) thư mục
**drawable**— dành cho tất cả các tệp hình ảnh.
- Thư mục
**layout**(bố trí) — dành cho các bố trí quy định các màn hình giao diện người dùng cho các hoạt động, dưới dạng mã XML. Tệp Main.xml được tự động tạo ra. Thư mục này gắn liền với cách bố trí thẳng đứng mặc định. Để biểu diễn một số giao diện người dùng theo bố trí nằm ngang (khi một thiết bị Android xoay 90 độ), tạo một thư mục layout-land (vùng bố trí) và đặt tệp XML bố trí của bạn ở đó. Tệp main.xml có một biểu diễn giao diện người dùng hấp dẫn, như trong Hình 3. Bạn có thể kéo và thả các bố trí khác nhau và các khung nhìn trên một màn hình trống để xây dựng các thành phần giao diện người dùng cho hoạt động này.
- Thư mục
**values**(các giá trị) — dành cho tất cả các cặp tên-giá trị (các chuỗi ký tự mà ứng dụng của bạn sẽ xác định).
- Tệp
**AndroidManifest.xml**cũng là một phần quan trọng của dự án. Nó tương đương với tệp plugin.xml cho các trình cắm thêm. Về cơ bản nó định nghĩa các hoạt động trong các ứng dụng và quy định các hành động đã được chỉ rõ cho mỗi hoạt động. Nó cũng liệt kê ra các quyền hạn mà ứng dụng yêu cầu để thực hiện các hành động khác nhau. Một lần nữa, tệp này có một giao diện người dùng đẹp.
##### Hình 3. Giao diện người dùng cho tệp main.xml
![ Ảnh chụp màn hình UI do tệp main.xml tạo ra, cho thấy một màn hình đen và một đoạn văn bản](figure03.jpg)
Hãy xem xét các nội dung thực tế của thư mục project (dự án) trên đĩa.
Mở Navigator View (Khung nhìn của dẫn hướng) trong Eclipse
(
**Window > Show View > Navigator**). Bạn sẽ
nhận được cấu trúc cho dự án HelloWorld như trong Hình 4. Ngoài các
tệp class được biên dịch, bạn nhận được ba tệp sau đây trong thư mục
bin:
- Tệp classes.dex — Tệp có thể thực thi được tạo ra từ các lớp biên dịch.
- Tệp HelloWorld.apk — Tệp lưu trữ nén sẽ được chuyển đến thiết bị Android. Ứng dụng này có thể được cài đặt trên thiết bị Android bất kỳ thông qua tệp lưu trữ này.
- Tệp resources.ap_ — Tệp các tài nguyên ứng dụng nén.
##### Cấu trúc thư mục của dự án Android
![ Ảnh chụp màn hình cấu trúc dự án cho biết các vị trí của các tệp classes.dex, HellowWorld.apk và resources.ap_ trong thư mục bin/com với các nhãn làm nổi mục đích của chúng như đã xác định trong phần trước](figure04.jpg)
### 'Hoạt động' chính của ứng dụng
Chúng ta hãy xem xét
MainActivity.java.
##### Liệt kê 1. Tệp MainActivity.java
package com.example.helloandroid; import android.app.Activity; import android.os.Bundle; public class MainActivity extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); } }
Những điều cần lưu ý về tệp này là:
- Tệp
MainActivitymở rộng một lớp Android cơ bản có tên là
Activity, nằm trong gói
android.app.
- Phương thức
onCreate()là điểm nhập mặc định cho hoạt động này và phải được triển khai thực hiện cho từng hoạt động mới. Nó nhận một đối số kiểu
Bundle(bó). Các tùy chọn và các tham số cần thiết cho việc tạo hoạt động này được chuyển vào tham số này.
- Phương thức
setContentView()có trách nhiệm tạo giao diện người dùng chính sử dụng đối số
R.layout.main. Đây là một hằng số được định nghĩa trong R.java và biểu diễn cách bố trí chủ yếu có trong các tài nguyên của ứng dụng đó.
#### Tệp Main.xml
Tệp XML này mô tả giao diện người dùng (UI) của ứng dụng. Một hoạt động
có thể tham chiếu đến UI này. Tuy nhiên, UI này không tự ràng buộc nó
vào bất kỳ hoạt động nào. Một UI được xây dựng bằng cách sử dụng các
bố trí và các widget. Tệp
main.xml mà
Eclipse xây dựng theo mặc định gồm có một LinearLayout duy nhất, có
nghĩa là tất cả các phần tử được sắp xếp trong một cột duy nhất. Rồi
nó định nghĩa một
textView, được dùng để
hiển thị văn bản tĩnh không chỉnh sửa được. Trong trường hợp này,
chuỗi "hello" được định nghĩa trong tệp strings.xml (ký hiệu '@' dùng
để chỉ một tệp được định nghĩa trong thư mục
**res**).
Mỗi phần tử khung nhìn bổ sung có các thuộc tính, như là
layout_height (độ cao_ bố trí) và
layout_width (độ rộng_bố trí), v.v.
##### Hình 5. Tệp Main.xml và khung nhìn properties (các đặc tính)
![ Ảnh chụp màn hình của Eclipse có tệp main.xml trong khung nhìn phối cảnh, cho biết mã trong phần trên bên trái, một phác thảo ở phần trên bên phải và một hệ thống phân cấp các đặc tính ở phần dưới cùng](figure05.jpg)
Một cách dễ dàng để làm việc với tệp
main.xml là thông qua khung nhìn các đặc
tính (
**Window > Show View > Other > General >
Properties**). Khi chọn một khung nhìn cụ thể trong khung
nhìn phác thảo, tab các đặc tính được điền đủ tất cả các thuộc tính có
khả năng của khung nhìn đó, như trong Hình 5. Hầu hết các thuộc tính
này chỉ có thể chọn một số giá trị cố định, và các giá trị cố định này
lại có thể được chọn từ một trình đơn thả xuống bên cạnh mỗi thuộc
tính trong tab các đặc tính. Ví dụ, để thiết lập thuộc tính
layout_height, bạn có thể nhìn thấy hộp thả
xuống và nhận ra rằng nó chỉ có hai giá trị được phép:
wrap_content và
fill_parent.
(
wrap_content sẽ chỉ dựng lên khung nhìn
theo kích thước ban đầu của nó, trong khi
fill_parent sẽ co giãn nó để bao trùm toàn
bộ chiều cao hoặc chiều rộng hoặc cả hai).
*Lưu ý:* Với các thuộc tính
layout_height và
layout_width, bạn cũng có thể xác định kích
thước theo hai đơn vị sau: (a) Các điểm ảnh độc lập với mật độ (dp)
— Kích thước này cho phép bố trí giống nhau khi được xem trên
các thiết bị có các kích thước màn hình khác nhau. Ví dụ:
layout_width = 10dp; (b) Các điểm ảnh độc
lập co giãn được (sp) — Tương tự như dp, nhưng đây là tiêu
chuẩn được khuyến nghị dành cho các máy điện thoại di động. Ví dụ:
layout_width = 10sp.) Một điều quan trọng
khác cần lưu ý là nếu bạn muốn tham khảo một số khung nhìn/widget nào
đó từ trong mã Java, thì cần phải có một mã định danh (ID) duy nhất.
Nếu bạn sử dụng tab bố trí của tệp
main.xml
để kéo và thả một widget, thì ADT sẽ tự động tạo một ID cho widget đó,
có dạng sau "@+id/someView." Sau đó, trong mã Java, sau đó bạn có thể
tham chiếu nó như
R.id.someView.
## Chạy ứng dụng trên trình mô phỏng thiết bị
Để triển khai và chạy ứng dụng này, bạn cần phải xác định một cấu hình
chạy. Chọn
**Open > Run > Dialog** hoặc phím tắt
trên thanh công cụ trong Eclipse và chọn **ứng dụng
Android**. Nhấn **New** và điền vào tên của
cấu hình chạy này. Chỉ rõ tên dự án của bạn và hoạt động mặc định. Sau
đó trong tab đích, chọn một số giá trị cài đặt trình mô phỏng mong
muốn và xác định một AVD mà bạn muốn khởi động. Nhấn vào
**Run** (Chạy). Bạn sẽ nhận được một AVD như trong
Hình 6. Màn hình của thiết bị được hiển thị bên trái, cùng với một bàn
phím QWERTY ở dưới cùng bên trái và các nút di động thông thường như
quay số, ngắt kết nối, tắt tiếng, âm lượng và trang chủ ở trên cùng
bên trái.
##### Hình 6. Thiết bị ảo Android (AVD)
![ Ảnh chụp màn hình Thiết bị ảo Android, cho biết hiển thị điện thoại mô phỏng ở bên trái và các phím ảo cho tất cả các nút ấn điện thoại ở bên phải](figure06.jpg)
## Các widget Android
Bây giờ chúng ta biết cách tạo và chạy một ứng dụng Android cơ bản, chúng ta hãy làm đẹp mọi thứ bằng các widget (xem Hình 7):
textViewbao gồm các widget như
editText, nút ấn (Button), v.v. Các nút ấn có thể được được phân loại thêm nữa:
- CheckBox (Hộp kiểm tra).
- RadioButton (Nút ấn tròn).
- ToggleButton (Nút ấn đảo chiều), v.v.
- ImageView bao gồm các widget như ImageButton.
- ViewGroup bao gồm các bố trí như:
- Relative Layout (Bố trí tương đối).
- Table Layout (Bố trí bảng).
- Frame Layout (Bố trí khung).
- Adapter View (Khung nhìn của bộ tiếp hợp).
- Linear Layout (Khung nhìn tuyến tính).
Để biết thông tin về các widgetHướng dẫn trực quan về các widget Giao
diện đồ họa người dùng của Android (GUI Android Widget) là hướng dẫn
tốt nhất. Tuy nhiên, hãy thận trọng với các sai lệch có thể xuất hiện
ở đó do những thay đổi nhanh chóng của nền tảng Android. Một ví dụ rõ
ràng là việc sử dụng
id như là một thuộc
tính của trình định danh cho một widget trong tệp
main.xml trong hướng dẫn nêu trên. Trong nền tảng Android
mới nhất, nên sử dụng tên phân biệt đầy đủ
android:id.
##### Hình 7. Hệ thống phân cấp các widget của Android
![ Hình này cho biết hệ thống phân cấp của mỗi widget trong Android, có một khung nhình ở trên đỉnh, tiếp theo là các kiểu khung nhìn và các widget khác nhau để áp dụng cho từng khung nhìn](figure07.gif)
## Một ứng dụng mẫu có sử dụng widget
Bây giờ chúng ta sẽ thay đổi ứng dụng hiện có của mình để trông giống
như Hình 8. Mục đích của ví dụ này là làm cho độc giả quen thuộc với
việc sử dụng của một số widget cơ bản như
textView,
editText, Button, và Toast trong một ứng
dụng thực tế.
Ứng dụng của chúng ta sẽ bao gồm một thanh tiêu đề với thông điệp
"WELCOME!!!" Nó sẽ có ba widget
textView
bắt đầu từ trên xuống, sắp xếp theo chiều dọc: widget thứ nhất nói
"Hello World, how're you (Chào thế giới, Bạn thế nào)?" theo phông chữ
mặc định, widget tiếp theo là "Welcome to my first Android app (Chào
mừng đến với ứng dụng Android đầu tiên của tôi)" với chữ serif
nghiêng, canh chính giữa, có nền trắng; và widget thứ ba nói "Type
anything and press the button (Gõ vào gì đó và nhấn nút)" với chữ đậm,
độ rộng bằng nhau, có nền màu đỏ. Sau ba widget này là widget
editText để lấy đầu vào từ người dùng, theo
sau là một widget nút nhấn, nút này đi cùng với thông điệp "Click Me!"
(Nhấn vào tôi). Mọi thứ bạn gõ vào trong widget
editText sẽ xuất hiện trong một widget Toast ở dưới đáy
giữa màn hình khi nhấn vào nút này.
Không có nhiều mã triển khai thực hiện liên quan ở đây. Độc giả nên chú ý rằng các widget có thể được đưa vào trong ứng dụng dễ dàng như thế nào khi sử dụng trình soạn thảo GUI của ADT cho các tệp XML và các đặc tính của widget được thiết lập thuận tiện như thế nào khi sử dụng khung nhìn "properties" (các thuộc tính) do Eclipse cung cấp. Ví dụ này cũng sẽ cho thấy giao diện người dùng và các phần triển khai thực hiện có thể được mã hoá độc lập như thế nào.
##### Hình 8. Thiết bị ảo Android với các widget
![ Ảnh chụp màn hình cho biết Thiết bị ảo Android đang chạy một ứng cụng với các widget khác nhau, bao gồm văn bản và các nút ấn](figure08.jpg)
#### Tệp string.xml
Hãy thêm một số chuỗi mới vào tệp string.xml, thay đổi chuỗi chào mừng
hiện có và cuối cùng là chuỗi tiêu đề. Chúng ta cũng xác định các màu
trắng và màu đỏ ở đây để làm nền cho hai widget
textView.
##### Liệt kê 2. Tệp string.xml
<?xml version="1.0" encoding="utf-8"?> <resources> <string name="hello">Hello World, how\'re you?</string> <string name="app_name">Hello Android</string> <string name="title">WELCOME!!!</string> <string name="mainText">Welcome to my first android app</string> <string name="subText">Type anything and press the button</string> <color name="White">#FFFFFF</color> <color name="Red">#FF0000</color> </resources>
Chúng ta thay đổi chuỗi ký tự "hello" để chứa "Hello World, how're
you?" Lưu ý ở đây phải có ký tự thoát (
'\')
đối với dấu nháy đơn. Chúng ta cũng định nghĩa hai chuỗi mới:
mainText và
subText, và các màu trắng và đỏ.
#### Tệp main.xml
Hãy sử dụng tab bố trí của tệp main.xml để kéo và thả hai widget
textView: một widget
editText và một widget nút ấn. Sau đó chúng
ta sẽ sử dụng tab các thuộc tính trong tệp main.xml để chỉnh sửa các
thuộc tính cho mỗi widget.
##### Liệt kê 3. Tệp main.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/hello" /> <TextView android:layout_height="wrap_content" android:layout_width="fill_parent" android:id="@+id/mainTextView" android:gravity="center" android:text="@string/mainText" android:textStyle="italic" android:typeface="serif" android:background="@color/White"> </TextView> <TextView android:layout_height="wrap_content" android:layout_width="fill_parent" android:layout_margin="20sp" android:gravity="left" android:id="@+id/subTextView" android:padding="10sp" android:text="@string/subText" android:textStyle="bold" android:typeface="monospace" android:background="@color/Red"> </TextView> <EditText android:text="Enter text here" android:id="@+id/EditText01" android:layout_width="wrap_content" android:layout_height="wrap_content"> </EditText> <Button android:text="Click me!" android:id="@+id/Button01" android:layout_width="wrap_content" android:layout_height="wrap_content"> </Button> </LinearLayout>
Với tệp này, chúng ta đã xác định giao diện giao diện người dùng của mình. Bây giờ chúng ta phải liên kết mã hành động của mình với nó.
#### Tệp MainActivity.java
Đây là tệp thực sự liên kết giao diện người dùng với mã triển khai thực
hiện. Cũng giống như ứng dụng HelloWorld, chúng ta sử dụng phương thức
Activity.onCreate(Bundle) để trang trí tất
cả các phần tử UI trên màn hình. Phương thức
onClick(View) bị ghi đè này sẽ chứa chức
năng nhấn nút, nơi văn bản đầu vào của người dùng sẽ được đọc và được
hiển thị trên màn hình trong một widget toast.
##### Liệt kê 4. Tệp MainActivity.java
package com.example.helloandroid; import android.app.Activity; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.Toast; public class MainActivity extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); String title = getString(R.string.title); setTitle(title); // done so that we can change the default title //get handles to editText and button widgets final EditText eText = (EditText) findViewById(R.id.EditText01); final Button button = (Button) findViewById(R.id.Button01); button.setOnClickListener(new Button.OnClickListener(){ @Override public void onClick(View v) { //get the String entered into the editText widget CharSequence editText = eText.getText(); //display the toast Toast.makeText(MainActivity.this, editText, Toast.LENGTH_LONG).show(); } }); } }
Khi sử dụng mã này, chúng ta nhận được các ứng dụng như trong Hình 8.
## Sử dụng widget
listView: Một ứng dụng
mẫu
Trong phần này, chúng ta sẽ tạo một ứng dụng mẫu (xem hình 9a, 9b) để
hiển thị tất cả các địa chỉ liên lạc trong danh bạ điện thoại bằng
cách sử dụng widget
listView. Mục đích của
ví dụ này là để giới thiệu không chỉ là việc sử dụng widget
listView mà còn cho thấy dữ liệu điện thoại
có thể được tìm nạp như thế nào khi sử dụng các lớp ContentProvider và
ContentResolver. Hãy chú ý đến các tệp XML của giao diện người dùng vì
có hai cách bố trí giao diện người dùng: một để xác định cách widget
listView sẽ hiển thị danh sách khít với
giao với giao diện người dùng chính và cái kia để xác định cách hiển
thị từng phần tử của danh sách đó. Một điểm quan trọng là thiết lập
các quyền hạn cho các ứng dụng có thể đọc dữ liệu điện thoại. Ví dụ
này là bước đầu tiên để hiểu được cách có thể kết hợp các ý định
(intent) và các bộ lọc ý định trong một ứng dụng. Mặc dù các intent
nằm ngoài phạm vi của bài viết này, nhưng độc giả cũng nên lưu ý rằng
để chuyển ứng dụng của ví dụ này thành một ứng dụng danh bạ điện thoại
trong thế giới thực, chỉ cần triển khai thực hiện các thao tác nhấn
vào các mục của danh sách và tạo một ý định (intent) cuộc gọi và bộ
lọc ý định để bắt đầu một cuộc gọi đến địa chỉ liên lạc được chọn.
Trong ví dụ này, các địa chỉ liên lạc sẽ được hiển thị theo mẫu thẳng
theo chiều dọc và địa chỉ liên lạc được chọn sẽ xuất hiện ở đầu danh
sách với một phông chữ in nghiêng lớn và một nền màu xanh dương. Chúng
ta cũng có một hộp kiểm tra ở phía dưới cùng bên trái của màn hình, mà
khi được đánh dấu chọn, sẽ hiển thị chỉ các địa chỉ liên lạc được đánh
dấu sao (hoặc các địa chỉ liên lạc ưa thích). Tiêu đề của ứng dụng
trong trường hợp này là "Contact Manager (Trình quản lý các địa chỉ
liên lạc). Ở đây chúng ta sử dụng ba loại widget:
textView,
listView và
checkBox. Chúng ta sử dụng widget
textView để hiển thị địa chỉ liên lạc hiện
đang được chọn. Bạn có thể đoán ngay rằng widget
listView là một danh sách các widget
textView. Widget
listView sử dụng các mẫu thiết kế của bộ
tiếp hợp để kết nối dữ liệu (trong trường hợp này là các địa chỉ liên
lạc) và một khung nhìn dữ liệu (trong trường hợp này là một
textView cho
listView này. Mọi thao tác nhấn trên
listView có thể được bắt giữ lại bằng cách
thực hiện phương thức
AdapterView.OnItemClickListener().
Trước khi tiếp tục, chúng ta nên có một số các địa chỉ liên lạc được
lưu trong phần các địa chỉ liên lạc của trình mô phỏng thiết bị của
Android (AVD). Điều này có thể được thực hiện bằng cách nhấn vào
**Contacts** (Các địa chỉ liên lạc) trên màn hình chủ
của AVD, sau đó nhấn vào **Menu** để có tùy chọn
**Add Contacts** (Thêm các địa chỉ liên lạc). Phần
**Favorites** (Các địa chỉ liên lạc ưa thích) cho
biết cách đánh dấu một địa chỉ liên lạc như là ưa thích/được đánh dấu
sao.
##### Hình 9a. Ứng dụng
các địa chỉ liên lạc hiển thị tất cả các địa chỉ liên lạc trong
một widget
listView
![ Ảnh chụp màn hình của một ứng dụng các địa chỉ liên lạc đang chạy trong một thiết bị ảo Android đang hiển thị một danh sách các địa chỉ liên lạc có mục của người tạo được tô sáng](figure09a.jpg)
##### Hình 9b. Ứng dụng
các địa chỉ liên lạc hiển thị tất cả các địa chỉ liên lạc được
đánh dấu sao trong một widget
listView
khi đánh dấu chọn vào hộp kiểm tra hiển thị các địa chỉ liên lạc
có đánh dấu sao
![ Ảnh chụp màn hình của một ứng dụng các địa chỉ liên lạc đang chạy trong một thiết bị ảo Android với tùy chọn chỉ hiển thị các địa chỉ liên lạc được đánh dấu sao được chọn và một tập các mục nhập rút gọn](figure09b.jpg)
Bây giờ chúng ta sẽ định nghĩa một vài chuỗi.
##### Liệt kê 5. Các chuỗi được định nghĩa trong tệp strings.xml
<?xml version="1.0" encoding="utf-8"?> <resources> <string name="hello">Hello World, Manager!</string> <string name="app_name">Contact Manager</string> <string name="selectedEntry" /> <color name="White">#FFFFFF</color> <color name="Black">#000000</color> <color name="Blue">#0000FF</color> <string name="showStarred">Show starred contacts only</string> </resources>
#### Tệp main.xml
Chúng ta hãy định nghĩa cách bố trí chính cho ứng dụng của mình. Widget
listView sẽ cung cấp danh sách tất cả các
địa chỉ liên lạc trong danh bạ điện thoại.
listView hiển thị từng mục bên trong một
widget
textView, mà chúng ta sẽ định nghĩa
tiếp sau.
##### Liệt kê 6. Tệp main.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:gravity="center" android:id="@+id/selectedContact" android:padding="10dp" android:textSize="20sp" android:textStyle="italic" android:typeface="serif" android:background="@color/Blue" android:textColor="@color/White" android:text="@string/selectedEntry"/> <ListView android:id="@+id/contactsListView" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_weight="1"> </ListView> <CheckBox android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/showStarred" android:text="@string/showStarred"/> </LinearLayout>
Lưu ý rằng việc gán cho thuộc tính layout_weight giá trị bằng 1 trong
listView bảo đảm chắc chắn rằng danh sách
phủ hết vùng màn hình càng lớn càng tốt cho đến khi một widget mới
được định nghĩa.
#### Tệp contactItem.xml
Bên cạnh bố trí chính, chúng ta cần phải xác định một cách bố trí khác
ở đây. Việc này là để thể hiện từng phần tử trong
listView này. Ở đây, ta sử dụng một
textView đơn giản.
##### Liệt kê 7. Mã cho widget
textView, thiết lập từng phần tử của widget
listView
<?xml version="1.0" encoding="utf-8"?> <TextView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="wrap_content" android:padding="5dp" android:textStyle="bold" android:id="@+id/contactItem"> </TextView>
Lưu ý rằng theo mặc định Android cung cấp một cách bố trí đơn giản, có
thể được sử dụng thay cho định nghĩa riêng của bạn. Điều này có thể
được tham chiếu qua
android.R.layout.simple_list_item_1.
#### Tệp ManageContacts.java
Liệt kê 8 cho thấy hoạt động chính được triển khai thực hiện như thế
nào. Phương thức
populateContactList() là
một phương thức mà chúng ta sử dụng để truy vấn cơ sở dữ liệu các địa
chỉ liên lạc và hiển thị chúng trong
listView này.
##### Liệt kê 8. Triển khai thực hiện của hoạt động chính
public class ManageContacts extends Activity { private ListView mContactList; private CheckBox mCheckBox; private boolean mShowStarred; private TextView selectedText; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); mContactList = (ListView) findViewById(R.id.contactsListView); mCheckBox = (CheckBox) findViewById(R.id.showStarred); selectedText = (TextView) findViewById(R.id.selectedContact); mShowStarred = false; mCheckBox.setOnCheckedChangeListener(new CheckChangedListener()); mContactList.setOnItemClickListener(new ClickListener()); populateContactList(); } public void populateContactList() { Uri uri = ContactsContract.Contacts.CONTENT_URI; String[] projection = new String[] { ContactsContract.Contacts._ID, ContactsContract.Contacts.DISPLAY_NAME, }; String[] selectionArgs = null; String sortOrder = ContactsContract.Contacts.DISPLAY_NAME + " COLLATE LOCALIZED ASC"; String selection = mShowStarred? ContactsContract.Contacts.STARRED + " ='1'" : null; Cursor c = getContentResolver().query(uri, projection, selection, selectionArgs, sortOrder); String[] fields = new String[] { ContactsContract.Data.DISPLAY_NAME }; SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, R.layout.contactitem, c, fields, new int[] {R.id.contactItem}); mContactList.setAdapter(adapter); } private class ClickListener implements OnItemClickListener { @Override public void onItemClick(AdapterView<?> arg0, View textView, int pos, long arg3) { if(textView instanceof TextView) selectedText.setText(((TextView) textView).getText()); } } private class CheckChangedListener implements OnCheckedChangeListener { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { mShowStarred = isChecked; selectedText.setText(""); populateContactList(); } } }
Những điều cần lưu ý:
- Chúng ta có hai trình lắng nghe — một trình lắng nghe để xử
lý các lần nhấn vào một mục của danh sách và cái kia để xử lý các
lần nhấn vào hộp kiểm tra. Trình lắng nghe đầu tiên chỉ đơn giản
đặt văn bản trong hộp
textViewmàu xanh dương với tên hiển thị của địa chỉ liên lạc hiện đang được chọn. Trình lắng nghe sau là để thiết lập trường
mShowStarredvà điền lại danh sách.
- Để đọc các địa chỉ liên lạc từ cơ sở dữ liệu điện thoại, chúng ta
cần phải truy vấn nó để có được một con trỏ. Truy vấn này có các
tham số sau:
**uri**— URI sử dụng content:// scheme để lấy ra nội dung. **projection (hình chiếu)**— Một danh sách các cột nào sẽ được trả về. Nếu cho bằng null sẽ trả về tất cả các cột; điều này không nên làm để tránh đọc nhiều dữ liệu từ bộ nhớ mà sẽ không dùng hết. **selection (lựa chọn)**— Một bộ lọc khai báo sẽ trả về hàng nào, được định dạng như là một mệnh đề
WHEREcủa SQL (ngoại trừ chính từ khóa
WHERE). Cho bằng null sẽ trả về tất cả các hàng có trong URI đã cho.
**selectionArgs**— Bạn có thể bao gồm các dấu hỏi
?, chúng sẽ được thay thế bằng các giá trị từ
selectionArgs, theo đúng trình tự mà chúng xuất hiện trong selection. Các giá trị này sẽ bị buộc như là kiểu chuỗi ký tự (String).
**sortOrder**— sắp xếp các hàng như thế nào, được định dạng như là một mệnh đề SQL
ORDER BYcủa SQL (ngoài trừ chính từ khóa
ORDER BY). Cho bằng null sẽ sử dụng thứ tự sắp xếp mặc định, mà theo mặc định có thể là không theo thứ tự nào cả.
Con trỏ của tập hợp kết quả đã thu được phải được liên kết với giao
diện người dùng qua một bộ tiếp hợp (adapter). Chúng ta sử dụng một
SimpleCursorAdapter ở đây, mặc dù Android
cũng cung cấp một
ListAdapter. Khi nhận
được bộ tiếp hợp chúng ta cần phải gắn nó kèm theo vào
listView và thế là xong.
### Các quyền hạn
Một bước cuối cùng trước khi ứng dụng của chúng ta sẽ chạy thành công
trên một thiết bị Android là thiết lập các quyền hạn. Không có các
quyền hạn để có thể đọc cơ sở dữ liệu các địa chỉ liên lạc, nhân
(kernel) Linux trong thiết bị đó sẽ không cho phép các ứng dụng làm
như vậy. Vì vậy, hãy vào
**AndroidManifest.xml>Permissions** tab và thiết
lập các quyền hạn sau:
android.permission.GET_ACCOUNTS
android.permission.READ_CONTACTS
Các quyền hạn này có thể được thiết lập bằng cách nhấn vào biểu tượng U và định nghĩa quyền hạn. Hình 10 cho thấy tab permissions trông như thế nào.
##### Hình 10. Bản kê các quyền hạn của Android
![ Ảnh chụp màn hình cho biết tab các quyền hạn với các mục nhập cho android.permission.GET_ACCOUNTS(Uses Permission) và android.permission.READ_CONTACTS (Uses Permission)](figure10.jpg)
#### Widget
listView khi sử dụng
ListActivity
Ví dụ này được dùng để trình bày một cách khác để triển khai thực hiện
một
listView. Trong ứng dụng trên, lưu ý
rằng hoạt động chính của chúng ta triển khai thực hiện lớp hoạt động.
Khi đề cập đến các widget
listView, đôi khi
lớp
ListActivity tỏ ra rất tiện lợi vì nó
có các API công cộng để xử lý các lần nhấn vào các mục danh sách,
thiết lập các bộ tiếp hợp của danh sách, lấy vị trí nơi nhấn vào, v.v.
Chúng ta có thể sửa đổi (mã lệnh của) hoạt động của mình để triển khai
thực hiện lớp
ListActivity như trong Liệt
kê 9.
##### Liệt kê 9. Triển khai thực hiện bằng cách sử dụng lớp
ListActivity
public class ManageContacts extends ListActivity { @Override protected void onListItemClick(ListView l, View v, int position, long id) { // TODO Auto-generated method stub super.onListItemClick(l, v, position, id); if(v instanceof TextView) selectedText.setText(((TextView) v).getText()); } private CheckBox mCheckBox; private boolean mShowStarred; private TextView selectedText; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); mCheckBox = (CheckBox) findViewById(R.id.showStarred); selectedText = (TextView) findViewById(R.id.selectedContact); mShowStarred = false; mCheckBox.setOnCheckedChangeListener(new CheckChangedListener()); populateContactList(); } public void populateContactList() { Uri uri = ContactsContract.Contacts.CONTENT_URI; String[] projection = new String[] { ContactsContract.Contacts._ID, ContactsContract.Contacts.DISPLAY_NAME, }; String[] selectionArgs = null; String sortOrder = ContactsContract.Contacts.DISPLAY_NAME + " COLLATE LOCALIZED ASC"; String selection = mShowStarred? ContactsContract.Contacts.STARRED + " ='1'" : null; Cursor c = getContentResolver().query(uri, projection, selection, selectionArgs, sortOrder); String[] fields = new String[] { ContactsContract.Data.DISPLAY_NAME }; ListAdapter adapter = new SimpleCursorAdapter(this, R.layout.contactitem, c, fields, new int[]{R.id.contactItem}); setListAdapter(adapter); } private class CheckChangedListener implements OnCheckedChangeListener { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { mShowStarred = isChecked; selectedText.setText(""); populateContactList(); } } }
Lưu ý rằng ở đây chúng ta chỉ cần triển khai thực hiện phương thức
onListItemClick của lớp
ListActivity, thay vì khai báo một lớp ẩn
danh để xử lý các lần nhấn. Ở đây, chúng ta cũng không cần phải tham
chiếu đến widget
listView được xác định
trong tệp main.xml vì lớp
ListActivity giả
định rằng widget
listView được định nghĩa
với mã định danh là
@android:id/list. Đây
là lưu ý quan trọng. Bất cứ khi nào chúng ta sử dụng lớp
ListActivity, chúng ta phải định nghĩa widget
listView trong tệp main.xml để có một
mã định danh @android:id/list; nếu không, lớp
ListActivity sẽ không biết tham chiếu đến
listView nào.
## Kết luận
Trong hướng dẫn này, chúng ta đã tìm hiểu cách thiết lập Eclipse để phát triển cho Android và các tính năng phong phú của Eclipse hỗ trợ từng bước để viết các ứng dụng Android như thế nào. Chúng ta cũng đã tìm hiểu các ứng dụng có thể dễ dàng được triển khai và thử nghiệm trên trình phỏng theo thiết bị Android — AVD như thế nào. Chúng ta trình bày các tính năng nổi bật của một ứng dụng Android bằng cách sử dụng một ví dụ Hello World và đã tìm hiểu về các tệp tạo ra một ứng dụng Android. Chúng ta đã đề cập đến một số các widget do Android cung cấp và đã biết cách sử dụng chúng trong một số ví dụ thực tế. Bây giờ bạn sẽ có thể bắt đầu tạo một ứng dụng thú vị với một giao diện người dùng gọn gàng. Bước đầu tiên, hãy mở rộng ứng dụng các địa chỉ liên lạc để triển khai thực hiện hành động nhấn vào một mục của danh sách để hiển thị các số điện thoại và các chi tiết liên hệ và một nút để gọi địa chỉ liên lạc được chọn. Cũng cần xác định một ý định (intent) cuộc gọi, cùng với một bộ lọc ý định, sẽ triển khai thực hiện chức năng tạo cuộc gọi.
Android là một nền tảng mạnh mẽ cho các ứng dụng di động và việc mã hóa bằng công nghệ Java, cùng với Các công cụ phát triển Android cho Eclipse, làm cho những người bắt đầu dễ dàng chấp nhận nó. Mảng các widget rộng lớn của nó, cùng với khả năng gắn kết (bind) động các phần tử giao diện người dùng tới phần triển khai thực hiện, cung cấp nhiều tính linh hoạt và làm cho các ứng dụng gọn nhẹ hơn, mặc dù vẫn có giao diện người dùng phong phú. Các khái niệm về các hoạt động, các ý định, các nhà cung cấp nội dung, v.v, làm dễ dàng việc quản lý giao diện người dùng và các phần tử dữ liệu và kiểm soát việc gắn kết giữa chúng. Cũng có một mảng rộng lớn các API nối mạng để khám phá. Ngoài ra, các API của Google cung cấp chức năng về các bản đồ, tìm kiếm và thư điện tử, và nhiều thứ khác nữa, tất cả có thể dễ dàng được chấp nhận trong một ứng dụng Android. Vì vậy, hãy đi sâu vào thế giới tuyệt vời này của Android và hãy để cho trí tưởng tượng của bạn phát triển thoải mái.
## Tài nguyên
### Học tập
[Hướng dẫn của nhà phát triển](http://developer.android.com/guide)là một mở đầu thiết thực để phát triển các ứng dụng cho Android.
- Đọc "
[Phát triển các ứng dụng Android với Eclipse](http://www.ibm.com/developerworks/opensource/tutorials/os-eclipse-android/?S_TACT=105AGY75)" để nhận được một bài học nhập môn về phát triển Android với một giới thiệu nhanh cho nền tảng này.
- Chắc chắn đọc hướng dẫn
[Hello, World](http://developer.android.com/resources/tutorials/hello-world.html).
- "
[Một hướng dẫn trực quan về Các Widget GUI của Android](http://droiddraw.org/widgetguide.html)" cung cấp thêm nhiều thông tin.
- Đọc
[Ngày Eclipse tại Googleplex: Phát triển Android bằng Eclipse](http://live.eclipse.org/node/804).
- Đừng bỏ lỡ
[Hướng dẫn phát triển Android](http://www.vogella.de/articles/Android/article.html)của Lars Vogella.
- Xem một loạt
[các video hướng dẫn cho Android](http://jonah.cs.elon.edu/dpowell2/android_tutorial.htm)Phòng nghiên cứu khoa học điện toán Elon.
- Xem "
[Danh sách khuyến khích đọc Eclipse](http://www.ibm.com/developerworks/library/os-ecl-read/index.html?S_TACT=105AGY75)."
- Duyệt tất cả
[nội dung Eclipse](http://www.ibm.com/developerworks/views/opensource/libraryview.jsp?search_by=eclipse&S_TACT=105AGY75)trên developerWorks.
- Theo dõi
[developerWorks trên Twitter](http://twitter.com/developerworks).
- Mới đến với Eclipse? Đọc bài viết "
[Hãy bắt đầu với Nền tảng Eclipse](http://www.ibm.com/developerworks/vn/library/os-eclipse-platform/index.html)" để tìm hiểu nguồn gốc và kiến trúc của nó và cách mở rộng Eclipse bằng các trình cắm thêm.
- Mở rộng các kỹ năng Eclipse của bạn bằng
cách xem
[Tài nguyên dự án Eclipse](http://www.ibm.com/developerworks/opensource/top-projects/eclipse.html?S_TACT=105AGY75)của developerWorks IBM.
- Để nghe các cuộc phỏng vấn và các cuộc
thảo luận thú vị dành cho các nhà phát triển phần mềm, hãy xem
[developerWorks podcasts](http://www.ibm.com/developerworks/podcast/?S_TACT=105AGY75).
- Cộng đồng
[My developerWorks](http://www.ibm.com/developerworks/community?S_TACT=105AGY75)là một ví dụ về một cộng đồng rộng rãi thành công bao trùm nhiều chủ đề rộng lớn.
- Theo sát
[các sự kiện kỹ thuật và Webcast](http://www.ibm.com/developerworks/offers/techbriefings/?S_TACT=105AGY75)của developerWorks.
- Xem và tìm hiểu về IBM và các công nghệ
mã nguồn mở và các chức năng sản phẩm với
[chương trình trình diễn miễn phí theo yêu cầu của developerWorks](http://www.ibm.com/developerworks/offers/lp/demos/?S_TACT=105AGY75).
- Xem các hội nghị, triển lãm thương mại,
Webcast sắp tới và
[Các sự kiện](http://www.ibm.com/developerworks/views/opensource/events.jsp?S_TACT=105AGY75)khác trên thế giới được các nhà phát triển nguồn mở của IBM quan tâm.
- Truy cập vào
[Vùng mã nguồn mở](http://www.ibm.com/developerworks/opensource?S_TACT=105AGY75)của developerWorks với các thông tin hướng dẫn rộng lớn, các công cụ và các bản cập nhật dự án để giúp bạn phát triển bằng các công nghệ mã nguồn mở và sử dụng chúng với các sản phẩm của IBM, cũng như [hầu hết các bài viết và các hướng dẫn phổ biến](http://www.ibm.com/developerworks/opensource/library/os-top10.html?S_TACT=105AGY75)của chúng tôi.
### Lấy sản phẩm và công nghệ
- Hãy chắc chắn tải
về
[Eclipse cho RCP/Plug-in](http://www.eclipse.org/downloads/packages/eclipse-rcpplug-developers/galileosr2).
- Tải về
[Android SDK](http://developer.android.com/sdk/index.html).
- Nhận lấy
[Trình cắm thêm ADT cho Eclipse](http://developer.android.com/sdk/eclipse-adt.html).
- Xem
[Các bản tải về công nghệ Eclipse](http://www.alphaworks.ibm.com/eclipse)mới nhất tại [alphaWorks](http://www.alphaworks.ibm.com/)của IBM.
- Tải về
[Nền tảng Eclipse và các dự án khác](http://www.eclipse.org/downloads/)từ Quỹ Eclipse.
- Tải về
[các phiên bản đánh giá sản phẩm của IBM](http://www.ibm.com/developerworks/downloads/?S_TACT=105AGY75)hoặc [khám phá các thử nghiệm trực tuyến trong SOA Sandbox của IBM](http://www.ibm.com/developerworks/downloads/soasandbox/?S_TACT=105AGY75)và nhận các công cụ phát triển ứng dụng thực hành của bạn và các sản phẩm phần mềm trung gian từ DB2®, Lotus®, Rational®, Tivoli® và WebSphere®.
- Đổi mới dự án
phát triển nguồn mở tiếp theo của bạn bằng
[phần mềm dùng thử IBM](http://www.ibm.com/developerworks/downloads/?S_TACT=105AGY75), có sẵn để tải xuống hoặc trên đĩa DVD.
### Thảo luận
[Các nhóm tin Nền tảng Eclipse](news://news.eclipse.org/eclipse.platform)là nơi dừng chân đầu tiên của bạn để thảo luận các câu hỏi về Eclipse. (Việc chọn mục này sẽ khởi chạy ứng dụng đọc tin Usenet mặc định của bạn và mở eclipse.platform). [Các nhóm tin Eclipse](http://www.eclipse.org/newsgroups/)có nhiều tài nguyên cho những người quan tâm đến việc sử dụng và mở rộng Eclipse.
- Tham gia vào
[các blog developerWorks](http://www.ibm.com/developerworks/blogs?S_TACT=105AGY75)và dành tâm trí cho cộng đồng developerWork.
## Bình luận
[Vùng dữ liệu trên developerWorks](http://www.ibm.com/developerworks/vn/views/data/libraryview.jsp)
Khám phá các bài viết xoay quanh lĩnh vực dữ liệu, Quản lý hệ thống thông tin
[Vùng mã nguồn mở trên developerWorks](http://www.ibm.com/developerworks/vn/views/opensource/libraryview.jsp)
Xem các bài viết về HTML, CSS, JavaScript,...
[Điện toán đám mây](http://www.ibm.com/developerworks/vn/views/cloud/libraryview.jsp)
Tìm hiểu về điện toán đám mây

Content-Language: en-US

Kp-eeAlive: timeout=10, max=82


text:
Jose Graziano da Silva, Tổng giám đốc của Tổ chức Nông Lương của Liên Hợp Quốc (FAO), cho biết tại một hội nghị ở Hà Nội rằng hiện nay giá lương thực toàn cầu đang giảm dần.
Sự phát triển của kinh tế thế giới sẽ giảm đi 3,3% trong năm nay từ 3,8% trong năm 2011. Ở Trung Quốc, Thủ tướng Ôn Gia Bảo đã công bố mục tiêu tăng trưởng trong năm 2012 là 7,5%, giảm từ 8% trong vòng bảy năm qua. Thu hoạch luá gạo và luá mì toàn cầu đã đạt mức cao kỷ lục do nông dân đẩy mạnh gieo trồng để được hưởng lợi từ giá cả tăng cao.
Giá lúa mì, gạo và bắp đã tăng vọt đáng kể từ 2008 do tình trạng thiếu hụt sản lượng trên toàn cầu, điều này hạn chết xuất khẩu lương thực, và gây ra khủng hoảng lương thực trên diện rộng.
Giá lúa mì đã giảm 29% từ tháng 2/2011. Giá gạo giảm 25% so với đỉnh điểm vào tháng 9/2011 xuống còn 13,94 USD cho mỗi 100 pounds.
Ở khu vực châu Á-Thái Bình Dương, biến động giá lương thực vẫn còn là một "mối đe dọa" với việc giá bán lẻ ở nhiều nước cao hơn từ 10% - 30% so với năm 2011. Một số quốc gia đã đạt đến ngưỡng để mở rộng nông nghiệp khi đất nông nghiệp bị sụt giảm làm ảnh hưởng đến năng suất cũng như bị đe dọa bởi sự khan hiếm nước."
Sản lượng lương thực toàn cầu phải tăng lên 70% vào năm 2050 để nuôi dân số thế giới dự kiến sẽ tăng lên 9 tỷ và người tiêu dùng ngày càng giàu có ở các nền kinh tế phát triển ăn nhiều thịt hơn.
(theo Bloomberg – TL, ITPC)

markdown:
|
|
|
Bạn đang ở:
|
|
|![]()
|
|
|
|
|
|![]()
|
|![]()
|
|![]()
|
|
|
|![]()
|© Copyright ITPC 2008. All Rights Reserved|

WARC-Type: response

Content-Type: application/http; msgtype=response

Server: Zope/(Zope 2.7.6-final, python 2.3.5, win32) ZServer/1.1 Plone/2.0.5

Content-Encoding: gzip

Cache-Control: public, must-revalidate

Connection: close


text:
Ngày cập nhật: 2010-11-10 13:51:03
Ngày áp dụng: 0000-00-00 00:00:00
Số điểm của file này: 20
hoặc nhắn tin theo cú pháp: KHOGIA AAEE7 Email gửi tới 8585 (trong đấy Email là email của bạn, và chúng tôi sẽ gửi file giá vào email này chi tiết xem TẠI ĐÂY)
Mô tả: giá ca máy

markdown:
Ngày cập nhật: 2010-11-10 13:51:03
Ngày áp dụng: 0000-00-00 00:00:00
Số điểm của file này:
** 20**
hoặc
**nhắn tin theo cú pháp:** **KHOGIA AAEE7 Email** gửi tới **8585**
(trong đấy Email là email của bạn, và chúng tôi sẽ gửi file giá vào email này chi tiết xem [)
TẠI ĐÂY](/index/terms) **Mô tả:** *giá ca máy*

WARC-Truncated: length

Server: Apache/2.2.26 (CentOS)

Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0

Pragma: no-cache

Content-Type: text/html; charset=UTF-8