tìm hiểu hệ điều hành android

75
1 Trường Đại học Bách Khoa Tp. HCM Khoa Điện- Điện tử Bộ môn Điện Tử ---o0o--- Cộng Hoà Xã Hội Chủ Nghĩa Việt Nam Độc lập – Tự do – Hạnh phúc ---o0o--- THỰC TẬP TỐT NGHIỆP Họ và tên: Nguyễn Hoàng Sang MSSV: 40902228 Nông Văn Hiếu MSSV: 40900822 Lớp DD09KSVT Ngành: Điện tử- Viễn thông 1.1. ĐẦU ĐỀ ĐỒ ÁN TÌM HỆ ĐIỀU HÀNH ANDROID TẠI CÔNG TY TNHH KIẾN VIỆT 1.2. NHIỆM VỤ. - Tìm hiểu kiến trúc HDH Android, môi trường hoạt động - Lập trình Android trên thiết bị di động - Giao tiếp giữa thiết bị Android và MCU định hướng phát triển luận văn 1. Ngày giao nhiệm vụ : ................................................................................... 2. Ngày hoàn thành nhiệm vụ: ......................................................................... 3. Họ và tên giáo viên hướng dẫn: ThS. BÙI QUỐC BẢO 4. Tên công ty thực tập: CÔNG TY TNHH KIẾN VIỆT Nội dung và yêu cầu ĐA đã thông qua Bộ môn. Ngày ..... tháng ........ năm .......... CHỦ NHIỆM BỘ MÔN GIÁO VIÊN HƯỚNG DẪN PHẦN DÀNH CHO KHOA, BỘ MÔN Người duyệt (chấm sơ bộ): ........................... Đơn vị: .......................................................... Ngày bảo vệ: ................................................. Điểm tổng kết: ..............................................

Upload: dai-gia-nha-ngheo

Post on 28-Oct-2015

174 views

Category:

Documents


7 download

DESCRIPTION

1/ mô tả về Android2/ tạo giao diện GUI

TRANSCRIPT

1

Trường Đại học Bách Khoa Tp. HCM Khoa Điện- Điện tử

Bộ môn Điện Tử ---o0o---

Cộng Hoà Xã Hội Chủ Nghĩa Việt Nam Độc lập – Tự do – Hạnh phúc

---o0o---

THỰC TẬP TỐT NGHIỆP

Họ và tên: Nguyễn Hoàng Sang MSSV: 40902228

Nông Văn Hiếu MSSV: 40900822

Lớp DD09KSVT Ngành: Điện tử- Viễn thông

1.1. ĐẦU ĐỀ ĐỒ ÁN

TÌM HỆ ĐIỀU HÀNH ANDROID TẠI CÔNG TY TNHH KIẾN VIỆT

1.2. NHIỆM VỤ.

- Tìm hiểu kiến trúc HDH Android, môi trường hoạt động

- Lập trình Android trên thiết bị di động

- Giao tiếp giữa thiết bị Android và MCU định hướng phát triển luận văn

1. Ngày giao nhiệm vụ : ...................................................................................

2. Ngày hoàn thành nhiệm vụ: .........................................................................

3. Họ và tên giáo viên hướng dẫn: ThS. BÙI QUỐC BẢO

4. Tên công ty thực tập: CÔNG TY TNHH KIẾN VIỆT

Nội dung và yêu cầu ĐA đã thông qua Bộ môn.

Ngày ..... tháng ........ năm ..........

CHỦ NHIỆM BỘ MÔN GIÁO VIÊN HƯỚNG DẪN

PHẦN DÀNH CHO KHOA, BỘ MÔN

Người duyệt (chấm sơ bộ): ...........................

Đơn vị: ..........................................................

Ngày bảo vệ: .................................................

Điểm tổng kết: ..............................................

2

NHẬN XÉT CỦA CÔNG TY THỰC TẬP

..........................................................................................................................................

..........................................................................................................................................

..........................................................................................................................................

..........................................................................................................................................

..........................................................................................................................................

..........................................................................................................................................

..........................................................................................................................................

..........................................................................................................................................

..........................................................................................................................................

..........................................................................................................................................

..........................................................................................................................................

..........................................................................................................................................

..........................................................................................................................................

..........................................................................................................................................

..........................................................................................................................................

..........................................................................................................................................

..........................................................................................................................................

..........................................................................................................................................

..........................................................................................................................................

..........................................................................................................................................

..........................................................................................................................................

..........................................................................................................................................

..........................................................................................................................................

..........................................................................................................................................

............................

Ngày........tháng.......năm........

Giám đốc (đại diện)

3

NHẬN XÉT CỦA GIÁO VIÊN HƯỚNG DẪN

..........................................................................................................................................

..........................................................................................................................................

..........................................................................................................................................

..........................................................................................................................................

..........................................................................................................................................

..........................................................................................................................................

..........................................................................................................................................

..........................................................................................................................................

..........................................................................................................................................

..........................................................................................................................................

..........................................................................................................................................

..........................................................................................................................................

..........................................................................................................................................

..........................................................................................................................................

..........................................................................................................................................

..........................................................................................................................................

..........................................................................................................................................

..........................................................................................................................................

..........................................................................................................................................

..........................................................................................................................................

..........................................................................................................................................

..........................................................................................................................................

..........................................................................................................................................

..........................................................................................................................................

........................

Ngày .........tháng..........năm........

Giáo viên phản biện

4

LỜI CẢM ƠN

Qua một thời gian nghiên cứu và thực hiện, đến nay chúng em đã hoàn thành

chương trình thực tập với đề tài: “Tìm hiểu HDH Android tại công ty Kiến Việt” do

thầy Bùi Quốc Bảo hướng dẫn. Trong suốt thời gian nghiên cứu và thực hiện đề tài, em

đã gặp không ít khó khăn và đã nhận được sự giúp đỡ nhiệt tình và quý báu của thầy và

các kĩ sư bên công ty Kiến Việt.

Trước tiên, chúng em gửi lời cảm ơn sâu sắc tới thầy Bùi Quốc Bảo đã tin tưởng

giới thiệu em với CTY KIẾN VIỆT để thực tập. Chúng em cũng xin được gửi lời cảm

ơn chân thành tới các các anh kĩ sư bên CTY KIẾN VIỆT đã tạo điều kiện thuận lợi để

chúng em hoàn thành đúng tiến độ chương trình thực tập.

Do năng lực và thời gian còn hạn chế nên việc tìm thêm nhiều tài liệu cho quá

trình tìm hiểu và nghiên cứu còn thiếu sót. Em rất mong nhận được nhiều hơn nữa ý

kiến đóng góp của các thầy, sự chia sẻ tài liệu của các bạn sinh viên để chúng em có thể

hoàn thiện kiến thức của mình hơn.

Em xin chân thành cảm ơn!

5

Mục Lục

Mục Lục ..................................................................................................................................... 5

Danh sách hình vẽ ...................................................................................................................... 8

1. CHƯƠNG 1: TỔNG QUAN ............................................................................................. 9

1.1 Lịch sử hình thành .................................................................................................... 9

1.1.1 Lịch sử hình thành ............................................................................................... 9

1.1.2 Hướng phát triển trong tương lai ....................................................................... 11

1.2 Môi trường cài đặt ................................................................................................... 12

1.2.1 Giới thiệu một số gói cần thiết ........................................................................... 12

1.2.2 Làm quen với IDE.............................................................................................. 15

1.3 Các thành phần cơ bản của một ứng dụng Android ............................................ 18

1.3.1 Activity .............................................................................................................. 18

1.3.2 Service................................................................................................................ 20

1.3.3 ContentProvider ................................................................................................. 20

1.3.4 Broadcast Receiver ............................................................................................ 20

2. CHƯƠNG 2: XÂY DỰNG GUI ...................................................................................... 22

2.1 Layouts ..................................................................................................................... 24

2.1.1 FrameLayout ...................................................................................................... 25

2.1.2 LinearLayout ...................................................................................................... 26

2.1.3 RelativeLayout ................................................................................................... 27

2.1.4 TableLayout ....................................................................................................... 28

2.1.5 AbsoluteLayout .................................................................................................. 28

2.2 Các control cơ bản................................................................................................... 29

2.2.1 Button ................................................................................................................. 30

2.2.2 EditText và TextView ........................................................................................ 31

2.2.3 Checkboxes ........................................................................................................ 32

6

2.2.4 Radio Button ...................................................................................................... 33

2.2.5 Toast Notification và Alert Dialog .................................................................... 34

2.3 ListView.................................................................................................................... 35

2.3.1 ListView với mảng dữ liệu định sẵn .................................................................. 35

2.3.2 ListView với ArrayList ...................................................................................... 37

2.3.3 CustomListview ................................................................................................. 39

3. CHƯƠNG 3: XÂY DỰNG ỨNG DỤNG GTALK ......................................................... 42

3.1 Giới thiệu .................................................................................................................. 42

3.1.1 Kiến trúc XMPP(Extensible Messaging and Presence Protocol) ...................... 42

3.1.2 Address trong XMPP ......................................................................................... 43

3.1.3 XMPP protocol .................................................................................................. 43

3.1.4 Giới thiệu về gói thư viện asmack.jar ................................................................ 44

3.2 Xây dựng project XMPPChatDemo ...................................................................... 44

3.2.1 Code ................................................................................................................... 44

3.2.2 Demo .................................................................................................................. 50

4. CHƯƠNG 4: XÂY DỰNG ỨNG DỤNG STREAM AUDIO VÀ VIDEO .................... 54

4.1 Giới thiệu về Audio trên Android .......................................................................... 54

4.1.1 Định dạng hỗ trợ Audio ..................................................................................... 54

4.1.2 Khởi chạy Audio thông qua Intent ..................................................................... 54

4.1.3 Xây dựng một ứng dụng Audio ......................................................................... 56

4.2 Background and Networked Audio ....................................................................... 59

4.2.1 Background Audio Playback ............................................................................. 59

4.2.2 Networked Audio ............................................................................................... 59

4.3 Giới thiệu về Video playback ................................................................................. 66

4.3.1 Định dạng hỗ trợ của Android ........................................................................... 66

4.3.2 Cách mở một tập tin video lưu trữ trong SD card.............................................. 66

7

4.3.3 Network video .................................................................................................... 66

4.3.4 Giao thức hỗ trợ HTTP và RTSP ....................................................................... 67

4.3.5 Giao thức hỗ trợ HTTP và RTSP ....................................................................... 68

5. CHƯƠNG 5: KẾT QUẢ ĐẠT ĐƯỢC VÀ ĐÁNH GIÁ HƯỚNG LUẬN VĂN ........... 75

5.1 Kết quả đạt được ..................................................................................................... 75

5.2 Hướng phát triển luận văn ..................................................................................... 75

8

Danh sách hình vẽ

Hình 1.1.1 Tỉ lệ sử dụng các phiên bản Android ..................................................................... 11

Hình 1.1.2 Biểu đồ thể hiện thị phần của Android .................................................................. 11

Hình 1.2.1 Download JDK....................................................................................................... 12

Hình 1.2.2 Download ADT cho windown ............................................................................... 13

Hình 1.2.3 Install Android SDK .............................................................................................. 14

Hình 1.2.4 Cấu trúc cây thư mục của một ứng dụng ............................................................... 15

Hình 1.2.5 Vùng thao tác với layout ........................................................................................ 15

Hình 1.2.6 Tạo máy ảo AVD device ........................................................................................ 16

Hình 1.2.7 Máy ảo AVD bản 4.2.2 .......................................................................................... 17

Hình 1.2.8 Giao diện DDMS ................................................................................................... 17

Hình 1.2.9 Activity lifecycle .................................................................................................... 19

9

1. CHƯƠNG 1: TỔNG QUAN

1.1 Lịch sử hình thành

1.1.1 Lịch sử hình thành

Android là hệ điều hành trên điện thoại di động (và hiện nay là cả trên một số

đầu phát HD, HD Player) phát triển bởi Google và dựa trên nền tảng Linux.

Trước đây, Android được phát triển bởi công ty liên hợp Android ( sau đó được

Google mua lại vào năm 2005). Theo NPD, thiết bị di động sử dụng hệ điều hành

Android bán được tại Mỹ trong quý II năm 2010 xếp vị trí đầu tiên với 33%, thứ

2 là BB os với 28% và iOS ở vị trí thứ 3 với 22%. Android có một cộng đồng

những nhà phát triển rất lớn viết các ứng dụng cho hệ điều hành của mình. Hiện

tại có khoảng 1000,000 ứng dụng cho Android OS và vào khoảng 1000,000

ứng dụng đã được đệ trình, điều này khiến Android trở thành hệ điều hành di

động có môi trƣờng phát triển lớn thứ 2. Các nhà phát triển viết ứng dụng cho

Android dựa trên ngôn ngữ Java. Sự ra mắt của Android vào ngày 5 tháng 11

năm 2007 gắn với sự thành lập của liên minh thiết bị cầm tay mã nguồn mở, bao

gồm 78 công ty phần cứng, phần mềm và viễn thông nhằm mục đính tạo nên một

chuẩn mở cho điện thoại di động trong tương lai. Google công bố hầu hết các mã

nguồn của Android theo bản cấp phép Apache. Hệ điều hành Android bao gồm

12 triệu dòng mã; 3 triệu dòng XML, 2.8 triệu dòng mã C, 2.1 triệu mã JAVA và

1.75 triệu dòng mã C++.Chi tiết lịch sử phát triển như sau:

Tháng 7 năm 2005, Google mua lại Android, Inc., một công ty nhỏ mới thành

lập có trụ sở ở Palo Alto , California , Mỹ. Những nhà đồng sáng lập của Android

chuyển sang làm việc tại Google gồm có Andy Rubin (đồng sáng lập công ty

Danger), Rich

Miner (đồng sáng lập công ty Wildfire Communications), Nick Sears (từng là

phó chủ tịch của T-Mobile ), và Chris White (trƣởng nhóm thiết kế và phát

triển giao diện tại WebTV). Khi đó, có rất ít thông tin về các công việc của

Android, ngoại trừ việc họ đang phát triển phần mềm cho điện thoại di động. Điều

này tạo những tin đồn về việc Google có ý định bước vào thị trường điện thoại di

động.Tại Google, nhóm do Rubin đứng đầu đã phát triển một nền tảng thiết bị di

10

động dựa trên hạt nhân Linux, được họ tiếp thị đến các nhà sản xuất thiết

bị cầm tay và các nhà mạng trên những tiền đề về việc cung cấp một hệ thống

mềm dẻo, có khả năng nâng cấp mở rộng cao. Một số nguồn tin cho biết trước đó

Google đã lên danh sách các thành phần phần cứng và các đối tác phần mềm,

đồng thời ra hiệu với các nhà mạng rằng họ sẵn sàng hợp tác ở nhiều cấp độ

khác nhau. Ngày càng nhiều suy đoán rằng Google sẽ tham gia thị trƣờng điện

thoại di động xuất hiện trong tháng 12 năm 2006. Tin tức của BBC và Nhật

Báo Phố Wall chú thích rằng Google muốn đưa công nghệ tìm kiếm và các ứng

dụng của họ vào điện thoại di động và họ đang nỗ lực làm việc để thực hiện điều

này. Các phƣơng tiện truyền thông in và online cũng sớm có bài viết về những tin

đồn cho rằng Google đang phát triển một thiết bị cầm tay mang thương hiệu

Google. Và lại càng có nhiều suy đoán sau bài viết về việc Google đang định nghĩa

các đặc tả công nghệ và trình diễn các mẫu thử với các nhà sản xuất điện thoại di

động và nhà mạng.Tháng 9 năm 2007, Information Week đăng tải một nghiên cứu

của Evalueserve cho biết Google đã nộp một số đơn xin cấp bằng sáng chế

trong lĩnh vực điện thoại di động

11

Hình 1.1.1 Tỉ lệ sử dụng các phiên bản Android

Hình 1.1.2 Biểu đồ thể hiện thị phần của Android

1.1.2 Hướng phát triển trong tương lai

Hiện tại thì Android đang rất phát triển, là Google sẽ tích hợp điện toán đám

mây trên hệ điều hành Android và bảo mật dữ liệu. Là mã nguồn mở nên việc

bảo mật dữ liệu là rất khó nên google sẽ dành nhiều thời gian cho vấn đề này

12

1.2 Môi trường cài đặt

1.2.1 Giới thiệu một số gói cần thiết

1.2.1.1 Java SE Development Kit(JDK)

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

để tiện lợi cho các nhà lập trình tiến hành phát triển các ứng dụng có nền tảng java.

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

Java SE JDK phiên bản 5 hay cao hơn. Hiệp hội các thiết bị cầm tay mở và Google

chọn Java là nền tảng để xây dụng Android không chỉ có lí do là nó là mã nguồn

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

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

Hình 1.2.1 Download JDK

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

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

13

1.2.1.2 Giới thiệu về plugin ADT(Android Development Tools)

ADT là plugin mở rộng được tích hợp vào môi trường phát triển phần mềm

Eclipse. Nó cho phép ta tạo và kiểm lỗi ứng dụng Android dễ dàng hơn và nhanh

chóng hơn. Cho phép ta thực hiện các công việc sau:

Truy xuất trực tiếp đến các công cụ phát triển Android khác bên trong Eclipse. Ví dụ, ADT cho phép truy xuất đến chức năng của công cụ DDMS

như: chụp màn hình, quản lý liên kết với thiết bị, đặt điểm dừng để kiểm lỗi, và

xem thông tin các luồng và tiến trình trự tiếp từ Eclipse.

Nó cung cấp New Project Wizard, mà giúp ta tạo và thiết lập tất cả các tập tin cơ bản cần thiết cho một ứng dụng Android mới.

Nó tự động hóa và làm đơn giản hóa tiến trình xây dựng ứng dụng Android.

Nó cung cấp trình biên tập mã lệnh Android mà giúp ta viết lệnh XML cho tập tin AndroidManifest và các tập tin tài nguyên khác.

Xuất ra tập tin .apk “đã đăng ký” (signed) hoặc “chưa đăng ký”

(unsigned) để mà phân phối ứng dụng cho người dùng cuối.

1.2.1.3 Sử dụng ADK

Sau khi cài đặt xong nền tảng JDK ta tải về Eclipse ADT. ADT tích hợp sẵn

trong phiên bản này tại địa chỉ : http://developer.android.com/sdk/index.html

Hình 1.2.2 Download ADT cho windown

14

Chọn đúng hệ điều hành và tải về, sau đó giải nén chạy eclipse.exe. Sau đó ta

tiến hành install Android SDK cho eclipse. Chú ý chỉ cài những version cần thiết.

Hình 1.2.3 Install Android SDK

Như vậy ta đã thiết lập đầy đủ điều kiện để tiến hành lập trình ứng Android

15

1.2.2 Làm quen với IDE

1.2.2.1 Project explorer

MainActivity.java và main.xml: Khi một ứng dụng được tao ra thì thông thường sẽ có một Activity để khởi chạy

ứng dụng. Ta hiểu rằng MainActivity.java chính là class chứa toàn bộ source code,

còn main.xml chính là phần giao diện. Đối với Android khi một Activity tạo ra thì

thường nó đi kèm với một layout riêng.

Bất kì một Activity nào muốn được triệu gọi thành công trong Android

Project thì bắt buộc nó phải được khai báo trong tập tin AndroidManifest.xml. Nếu như không khai báo Activity mà gọi đến nó thì chương trình sẽ bị lỗi và tắt.

Mở thư mục R.java. Thư mục gen

là thư mục do Android tự động tạo ra. Tất cả những giao diện hay thiết lập string.xml, menu. Mọi thứ liên quan tới resource đều

được sinh ra trong R.java. Dựa vào đây để ta có thể truy xuất các đối tượng trong

coding

Thư mục Drawable : chứa các tài nguyên mà ta đưa vào project ví dụ như file nhạc, file hình ảnh

Outline : vùng này nằm bên góc phải màn hình chứa các tiêu đề hay các tên hàm một cách gọn nhất để dễ dàng quan sát và quản lí code

Quan sát file main.xml :

Hình 1.2.5 Vùng thao tác với layout

Hình 1.2.4 Cấu trúc cây thư mục của một ứng dụng

16

Vùng này bao gồm:

o Chứa các control, layout, componet…muốn sử dụng thì kéo và thả vào vùng giao diện

o Vùng giao diện chính là vùng mà ta cần thiết kế o Các tùy chọn chế độ hiện thị cho layout đang làm việc như đứng hay

ngang, zoom in hoặc zoom out o Vùng properties :Vùng này thiết lập các thuộc tính cho các control được

kéo thả vào giao diện

1.2.2.2 DDMS và máy ảo AVD (Android Virtual Device)

Chọn Window=> Android virtual Device Manager => new và thiết lập các

thông số như hình sau:

Hình 1.2.6 Tạo máy ảo AVD device

Chọn start để khởi động máy ảo :

17

Hình 1.2.7 Máy ảo AVD bản 4.2.2

Vào window => open perspective => DDMS

Hình 1.2.8 Giao diện DDMS

18

o Cửa sổ device bên trái cho biết thiết bị thật hay ảo này đang kết nối với

ADT và nhưng app nào đang chạy trên thiết bị

o Cửa sổ bên phải là File Explorer cho thấy hệ thống các file trong thiết bị

bao gồm cả Sdcard ta có thể nạp file vào sdcard hay lấy file dữ liệu ra thông qua

màn hình này

o Dưới cùng là màn hình longcat cho phép ta theo dõi tiến trình nào đang

chạy hoặc lỗi xảy ra, rất tiện dụng cho việc phát hiện và kiểm tra code

1.3 Các thành phần cơ bản của một ứng dụng Android

1.3.1 Activity

Hiểu một cách đơn giản thì Activity là nền của 1 ứng dụng. Khi khởi động 1

ứng dụng Android nào đó thì bao giờ cũng có 1 main Activity được gọi, hiển thị

màn hình giao diện của ứng dụng cho phép người dùng tương tác. Để hiểu được

cách thức hoạt động của một Activity ta quan sát vòng đời của nó

19

Hình 1.2.9 Activity lifecycle

20

1.3.2 Service

Một service là một thành phần chạy ẩn (runs in the background) để thực hiện các

thao tác chạy lâu dài hoặc điều khiển các tiến trình. Service thì không có giao

diện người dùng.

Ví dụ: Một service phát nhạc (không cần giao diện ) trong khi người dùng đang

sử dụng một ứng dụng khác, hoặc nó trao đổi dữ liệu qua mạng mà không làm

ngăn cản sự tương tác của người dùng với một activity. Một thành phần khác,

chẳng hạn như một activity, có thể start service và tương tác với nó.

Một service được implement như là một subclass của lớp Service

1.3.3 ContentProvider

Một content provider quản lý một tập hợp dữ liệu chia sẻ của ứng dụng. Ta có

thể lưu trữ dữ liệu trong file hệ thống, một cơ sở dữ liệu SQLite, trên web hay bất

kỳ nơi lưu trữ nào khác mà ứng dụng của bạn có thể truy cập. Thông qua content

providers, các ứng dụng khác có thể truy vấn hoặc thậm chí sửa đổi dữ liệu ( nếu

content provider cho phép điều đó ).Ví dụ, hệ thống Android cung cấp một content

provider quản lý các thông tin liên hệ của người dùng. Như vậy, bất kỳ ứng dụng

nào được cấp quyền truy vấn đến một phần của content provider ( chẳng hạn như

ContactsContract.Data) có thể đọc và ghi thông tin về một người cụ thể.Content

providers cũng rất hữu ích trong việc đọc và ghi dữ liệu riêng tư cho ứng dụng và

không chia sẻ nó. Một content provider được implement như là một subclass của

ContentProvider và phải implement một tập hợp chuẩn các APIs cho phép ứng

dụng khác có thể thực hiện giao dịch.

1.3.4 Broadcast Receiver

Một broadcast receiver là một thành phần phản ứng với các thông báo từ bên

ngoài gửi tới hệ thống. Nhiều broadcasts có nguồn gốc từ hệ thống chẳng hạn, một

broadcast thông báo các màn hình đã tắt, pin yếu, hoặc chụp hình. Các ứng dụng

cũng có thể khởi tạo các broadcast ví dụ, để cho các ứng dụng khác biết được rằng

một số dữ liệu đã được tải về thiết bị và sẵn sàng để sử dụng. Mặc dù broadcast

không hiển thị 1 giao diện người dùng, chúng có thể tạo một thông báo trên thanh

trạng thái để cảnh báo người dùng khi có một sự kiện broadcast xảy ra. Thông

21

thường hơn, một broadcast receiver là một “cửa ngõ” (gateway) cho các thành

phần khác và được dự định để làm một số lượng tối thiểu các công việc. Ví dụ nó

có thể khởi tạo một service để thực hiện một vài công việc dựa trên các sự kiện.Một

broadcast receiver được implement như là một subclass của BroadcastReceiver và

mỗi broadcast được dẫn xuất như là một đối tượng Intent

22

2. CHƯƠNG 2: XÂY DỰNG GUI

Có thể nói hầu hết mọi ứng dụng trên thiết bị di động đều cần phải có một giao

diện người dùng (GUI) để cho phép người sử dụng có thể tương tác với thiết bị.

Cho nên đây là một phần quan trọng và căn bản để bắt đầu xây dựng một ứng

dụng Android. Trong phần này ta sẽ lần lượt tìm hiểu các thành phần giao diện

căn bản như: Layout, Button, TextView, EditText… Ta cũng sẽ tìm

hiểu các giao diện điều khiển nâng cao như ListView…

Tất cả các giao diện người dùng được thực thi trong Android app đều được xây dựng

lên từ dối tượng View và ViewGroup.Một View là một đối tượng xuất hiện trên màn

hình mà người dùng có thể tương tác với nó. Một ViewGroup là đối tượng mà bao gồm

các View hoặc ViewGroup khác để định nghĩa lớp giao tiếp.

Giao diện người dùng được xây dựng theo kiểu cây phân cấp, cấu tạo nên từ các đối

tượng View và ViewGroup được chỉ ra trong hình vẽ. Mỗi ViewGroup xem như một

nhóm các View và ViewGroup con. Trong khi View và ViewGroup con có thể là

điểu khiển đầu vào (Input control) hoặc đơn giản chỉ là một phần của giao diện hiện thị.

23

Ví dụ: Bố trí đơn giản của một layout cơ bản

<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <TextView android:id="@+id/text" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello, I am a TextView" /> <Button android:id="@+id/button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello, I am a Button" /> </LinearLayout>

Đây là outline:

Đây là phần hiện thị người dùng:

24

2.1 Layouts

Layout xác định cách bố trí hình ảnh cho một giao diện người dùng trên screen,

Chẳng hạn như giao diện cho một activity hoặc app widget. Chúng ta có thể khai báo

layout theo 2 cách:

Khai báo thành phần giao diện người dùng trong XML.

Khai báo layout trong thời gian chạy ứng dụng.

Trong Android chúng ta có thể sự dụng linh hoạt một hoặc cả hai cả hai phương pháp

để khai báo bố trí và quản lí các thành phần lauout. Ví dụ, chúng ta có thể khai báo các

thành phần giao diện mặc định của ứng dụng trong XML, bao gồm các thành phần màn

hình sẽ xuất hiện trong nó và thuộc tính của nó. Sau đó chúng ta có thể thêm mã trong

ứng dụng của mình có thể sẽ thay đổi trạng thái của các đối tượng màn hình, bao gồm

cả những khai báo trong XML trong khi ứng dụng đang chạy.

Một điều nữa là bản thân layout chỉ là một thành phần giao diện hiện thị, tự nó không

thể load lên sceen cũng như không thể tiếp nhận các tương tác với người dùng nên để

nó có thể hoạt động thì bắt buộc phải có một file Activity.Java điều khiển nó. Thông

thường một file layout.xml thường sẽ đi kèm với một file Activity.java để điều khiển

nó. Ví dụ: chúng ta tạo một main_layout.xml với nội dung giống như trong ví dụ

trên. Để lauout đó xuất hiện trên screen thi trong file Activity.java ta phải gọi

setContentView(R.layout. main_layout.xml) để load layout lên screen.

public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main_layout); }

Layout cũng có nhiều loại như: LinearLayout, TableLayout, FrameLayout,

RelativeLayout, AbsoluteLayout. Trong một ứng dụng ta thường phải kết hợp

các loại layout nay lại với nhau.

25

2.1.1 FrameLayout

Là loại Layout cơ bản nhất, đặc điểm của nó là khi gắn các control lên giao diện

thì các control này sẽ luôn được “Neo” ở góc trái trên cùng màn hình, nó không

cho phép chúng ta thay đổi vị trí của các control theo một Location nào đó. Các

control đưa vào sau nó sẽ đè lên trên và che khuất control trước đó (trừ khi ta thiết

lập transparent cho control sau).

Ví dụ: chúng ta có đoạn xml sau.

<?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/mainlayout" android:layout_width="fill_parent" android:layout_height="fill_parent" gt="" android:orientation="vertical" > <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:padding="5px" android:src="@drawable/blue" /> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:padding="5px" android:src="@drawable/red" />

</FrameLayout>

Ta thấy, hình màu đỏ và màu xanh luôn được

“neo” ở góc trái màn hình. Hình màu đỏ đưa vào

sau sẽ đè lên trên hình màu xanh.

26

2.1.2 LinearLayout

Đây là layout được dùng rất phổ biến cùng với TableLayout và RelativeLayout. Layout này cho phép các control sắp xếp theo 2 hướng giao diện không chồng lắp

lên nhau: hướng từ trái sang phải(horiental) và từ trên xuống dưới (vertical).

Ví dụ:

<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:paddingLeft="16dp" android:paddingRight="16dp" android:orientation="vertical" > <EditText android:layout_width="fill_parent" android:layout_height="wrap_content" android:hint="@string/to" /> <EditText android:layout_width="fill_parent" android:layout_height="wrap_content" android:hint="@string/subject" /> <EditText android:layout_width="fill_parent" android:layout_height="0dp" android:layout_weight="1" android:gravity="top" android:hint="@string/message" /> <Button android:layout_width="100dp" android:layout_height="wrap_content" android:layout_gravity="right" android:text="@string/send" /> </LinearLayout>

27

2.1.3 RelativeLayout

RelativeLayout cho phép sắp xếp các control theo vị trí tương đối giữa các

control khác trên giao diện (kể cả control chứa nó). Thường nó dựa vào Id của các

control khác để sắp xếp theo vị trí tương đối. Do đó khi làm RelativeLayout

ta phải chú ý là đặt Id control cho chuẩn xác, nếu sau khi Layout xong mà bạn lại

đổi Id của các control thì giao diện sẽ bị xáo trộn (do đó nếu đổi ID thì phải đổi

luôn các tham chiếu khác sao cho khớp với Id bạn mới đổi).

Ví dụ:

<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:paddingLeft="16dp" android:paddingRight="16dp" > <EditText android:id="@+id/name" android:layout_width="fill_parent" android:layout_height="wrap_content" android:hint="@string/reminder" /> <Spinner android:id="@+id/dates" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_below="@id/name" android:layout_alignParentLeft="true" android:layout_toLeftOf="@+id/times" /> <Spinner android:id="@id/times" android:layout_width="96dp" android:layout_height="wrap_content" android:layout_below="@id/name" android:layout_alignParentRight="true" /> <Button android:layout_width="96dp" android:layout_height="wrap_content" android:layout_below="@id/times" android:layout_alignParentRight="true" android:text="@string/done" /> </RelativeLayout>

28

2.1.4 TableLayout

Đây là một dạng control cũng rất hay sử dụng. Nó cho phép sắp xếp các control

theo dạng dòng và cột.

TableLayout sẽ xem xét dòng nào có nhiều control nhất để xác định số lượng

cột. Nó sẽ lấy dòng có số cột nhiều nhất để lấy làm số cột.

Theo như hình trên thì TableLayout này có 3 dòng 4 cột.

2.1.5 AbsoluteLayout

Cho phép thiết lập các control giao diện theo vị trí tùy thích. Tuy nhiên loại

control này lại khó sử dụng vì bản chất hệ điều hành Android chạy trên nhiều dòng

máy khác nhau nên có rât nhiều loại screen với các kích thước khác nhau. Do đó

các phiên bản android về sau google không khuyến khích các lập trình viên sử

dụng loại lauout này.

Như vậy ta đa đi qua đặc điểm cơ bản của các loại layout. Trong thực tế ta

thường phải sử dụng kết hợp các loại layout này với nhau để tạo giao diện màn

hình.

29

2.2 Các control cơ bản

Trong phần trước ta đã hiểu về layout, tiếp phần này ta sẽ tìm hiểu về cách sử

dụng các control cơ bản như :Button, TextView, EditText… Bảng dưới mô tả các

loại control thường sử dụng trong android.

Control Type Description Related Classes

Button A push-button that can be pressed, or

clicked, by the user to perform an action.

Button

Text field An editable text field. You can use

theAutoCompleteTextView widget to

create a text entry widget that provides

auto-complete suggestions

EditText,AutoComple

teTextView

Checkbox An on/off switch that can be toggled by the

user. You should use checkboxes when

presenting users with a group of

selectable options that are not mutually

exclusive.

CheckBox

Radio button Similar to checkboxes, except that only

one option can be selected in the group.

RadioGroup

RadioButton

Toggle

button

An on/off button with a light indicator. ToggleButton

Spinner A drop-down list that allows users to select

one value from a set.

Spinner

Pickers A dialog for users to select a single value

for a set by using up/down buttons or via a

swipe gesture. Use aDatePickercode>

widget to enter the values for the date

(month, day, year) or a TimePicker widget to enter the values

for a time (hour, minute, AM/PM), which

will be formatted automatically for the

user's locale.

DatePicker,TimePick

er

30

2.2.1 Button

Một Button bao gồm một text

hoặc một icon (hoặc cả text và

icon) mà đáp ứng lại những hành

động xẩy ra khi người dùng chạm vào nó. Tùy thuộc vào mục đích của mình mà

ta có thể tạo ra một button trong layout theo một trong 3 cách.

Với text, sử dụng lớp button:

<Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/button_text" ... />

Với icon, sử dụng lớp button:

<ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/button_icon" ... />

Với text và icon sử dụng lớp button với thuộc tính android:drawableLeft

<Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/button_text" android:drawableLeft="@drawable/button_icon" ... />

Đáp ứng sử kiện OnClick trên button:

Button button = (Button) findViewById(R.id.button_send); button.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { // Do something in response to button click } });

31

2.2.2 EditText và TextView

Trong android đối trượng EditText được sự dụng như một TextView hoặc một

TextBox. Giá trị thuộc tính singleLine bằng false, EditText sẽ là một TextBox

ngược lại là một TextView

<EditText Android:id="@+id/EditText01" Android:layout_width="wrap_content" Android:layout_height="wrap_content" Android:inputType="textCapWords" Android:singleLine="true" Android:text="Hello Android!" Android:textColor="#000000" Android:textSize="20dip" Android:textStyle="bold" />

TextView là một đối tượng để hiện thị văn bản. Ta cũng có thể thay đổi cũng

như lấy thuộc tính của hai đối tượng này trong mã code java. Để làm được điều

này thì đầu tiên ta phải dùng hàm

TextView button = (TextView) findViewById(R.id.ten_doi_tuong);

Để lấy id của đối tượng tương ứng.

32

2.2.3 Checkboxes

Checkboxes cho phép người

dùng lựa chọn một hoặc nhiều

option từ một GroupCheckboxes.

Thông thường Checkboxes được

sắp xếp thành một list hướng dọc.

Ví dụ:

<?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"> <CheckBox android:id="@+id/checkbox_meat" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/meat" android:onClick="onCheckboxClicked"/> <CheckBox android:id="@+id/checkbox_cheese" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/cheese" android:onClick="onCheckboxClicked"/> </LinearLayout>

public void onCheckboxClicked(View view) { // Is the view now checked? boolean checked = ((CheckBox) view).isChecked(); // Check which checkbox was clicked switch(view.getId()) { case R.id.checkbox_meat: if (checked) // Put some meat on the sandwich else // Remove the meat break; case R.id.checkbox_cheese: if (checked) // Cheese me else // I'm lactose intolerant break; // TODO: Veggie sandwich } }

33

2.2.4 Radio Button

Tương tự như Checkboxes nhưng Radio Button chỉ cho phép người dùng nhập

lựa chọn một option duy nhất một Group

Ví dụ:

<?xml version="1.0" encoding="utf-8"?> <RadioGroup xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="vertical"> <RadioButton android:id="@+id/radio_pirates" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/pirates" android:onClick="onRadioButtonClicked"/> <RadioButton android:id="@+id/radio_ninjas" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/ninjas" android:onClick="onRadioButtonClicked"/> </RadioGroup>

sdsfdfd

a

file.java

public void onRadioButtonClicked(View view) { // Is the button now checked? boolean checked = ((RadioButton) view).isChecked(); // Check which radio button was clicked switch(view.getId()) { case R.id.radio_pirates: if (checked) // Pirates are the best break; case R.id.radio_ninjas: if (checked) // Ninjas rule break; } }

34

2.2.5 Toast Notification và Alert Dialog

Trong nhiều ứng dụng chúng ta phải đưa ra thông báo hay là để đưa ra một cảnh

báo để người dùng xác nhận thì lúc này Toast Notification và Alert Dialog là hai đối

tượng rất hữu dụng. Toast Notification chỉ đơn thuần đưa ra thông báo cho người dùng

trong khoản thời gian từ 1-3s rồi tự động tắt trong khi Alert Dialog cho phép người dùng

tương tác vói nó.

Để hiện thị một Toast Notification ta tạo một đối tượng thuộc Toast và cho hiện thị

chúng.

// example toast Toast toast =

Toast.makeText(MainActivity.this, "Vi du ve toast",

Toast.LENGTH_LONG); toast.show(); /* * or Toast.makeText(MainActivity.this, "Vi du ve toast", * Toast.LENGTH_LONG).show(); */

Phức tạp hơn Toast Notification, Alert Dialog sử dụng phức tạp hơn một chút vì có

thêm các thành phần điều khiển.

// example alert dialog AlertDialog.Builder alertdialog = new AlertDialog.Builder( MainActivity.this); alertdialog.setTitle("Question"); alertdialog.setMessage("Are you sure you want to exit?"); alertdialog.setPositiveButton("Yes", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { finish(); } }); alertdialog.setNegativeButton("No", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { dialog.cancel(); } }); alertdialog.create().show();

35

2.3 ListView

Trong phần trước ta đã biết cách sử

dụng các control cơ bản, trong phần

này ta tiếp tục sử dụng các control

nâng cao hơn, cụ thể là ListView.

Trong các ứng dụng cần lưu trữ và hiện

thị danh sách các thông tin đa thành

phần thì chúng ta sài ListView. Đây là

một công cụ khó sử dụng nhưng lại

hay được dùng. Khi đã sử dụng ListView nhần nhuyễn rồi thì các control nâng cao

khác chúng ta cũng sẽ sử dụng dễ dàng.

Vì ListView được sử dụng theo nhiều cách khác nhau, và rất tùy biến nên

trong phần này ta sẽ lần lượt đi qua từng cách sử dụng ListView và cuối cùng là

Custom lại ListView.

2.3.1 ListView với mảng dữ liệu định sẵn

Là Đây là outline để ta tiện thiết kế giao diện xml.

36

Đây là phần xử lí gán data vào ListView :

package hoangsang.android.basiclistview;

import android.app.Activity; import android.os.Bundle; import android.view.View; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.ListView; import android.widget.TextView; public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // khoi tao du lieu cho mang array final String arr[] = { "Cao Văn Hoàn", "Nguyễn Hoàng Trung", "Nông văn hiếu", "Nguyễn Hoàn Sang", "Hồ thị Kỷ", "Trần thị Liên" }; // lay doi tuong listview dua vao id ListView lvPerson = (ListView) findViewById(R.id.lvPerson); // Gan data source vao array adapter ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, arr); // gan adapter vao Listview lvPerson.setAdapter(adapter); // thiet lap su kien cho listview // khi chon phan tu nao thi hien thi phan tu do len textview

final TextView tvSelect = (TextView) findViewById(R.id.etSelect);

// 5. Thiết lập sự kiện cho Listview, khi chọn phần tử nào thì hiển thị

// lên TextView lvPerson.setOnItemClickListener(new

AdapterView.OnItemClickListener() { public void onItemClick(AdapterView<?> arg0, View arg1,

int arg2,long arg3) { // đối số arg2 là vị trí phần tử trong Data Source (arr)

tvSelect.setText("position :" + arg2 + " ; value =" + arr[arg2]);

} }); } }

Như vậy để gán data vào ListView ta phải sử dụng một adapter. Đầu tiên ta gán

mảng arr vao ArrayAdapter sau do gán tiếp ArrayAdapter vào ListView để hiện

thị. Trong code trên ta có sử dụng phương thức setOnItemClickListener()

để lắng nghe sự kiện click trên phần tử bất kì của ListView

37

2.3.2 ListView với ArrayList

Ở đây thay vì gán một mảng dữ liệu vào ArrayAdapter thì ta tạo một đối tượng arrayList để gán vào ArrayAdapter.

package hoangsang.android.listviewcontrol; import java.util.ArrayList; import android.app.Activity; import android.os.Bundle; import android.view.View; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.Button; import android.widget.EditText; import android.widget.ListView; import android.widget.TextView; public class MainActivity extends Activity { EditText etName; TextView tvChon; Button btNhap; ListView lvName; ArrayList<String> arrList = null; ArrayAdapter<String> adapter = null; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); etName = (EditText) findViewById(R.id.etName); tvChon = (TextView) findViewById(R.id.tvChon);

38

lvName = (ListView) findViewById(R.id.lvName); // 1. Tạo ArrayList object arrList = new ArrayList<String>(); // arrList.add("Nguyen Hoang sang"); // adapter.notifyDataSetChanged(); // 2. Gán Data Source (ArrayList object) vào ArrayAdapter adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, arrList); arrList.add("Nguyen Hoang sang"); adapter.notifyDataSetChanged(); // 3. gán Adapter vào ListView lvName.setAdapter(adapter); // 4. Xử lý sự kiện nhấn nút Nhập btNhap = (Button) findViewById(R.id.btNhap); btNhap.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub arrList.add(etName.getText().toString()); adapter.notifyDataSetChanged(); } }); // 5. Xử lý sự kiện chọn một phần tử trong ListView

lvName.setOnItemClickListener(new AdapterView.OnItemClickListener() {

public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,long arg3) {

tvChon.setText("position : " + arg2 + "; value =" + arrList.get(arg2)); } }); // 6. xử lý sự kiện Long click

lvName.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {

@Override public boolean onItemLongClick(AdapterView<?> arg0, View arg1,int arg2, long arg3) {

arrList.remove(arg2);// xóa phần tử thứ arg2 adapter.notifyDataSetChanged(); return false; } }); } }

39

2.3.3 CustomListview

Trong hai ví dụ trên, từng item của ListView chỉ có duy nhất một phần tử dạng

test. Nhưng trong các ứng dụng thực tế đòi hỏi chúng ta phải Custom lại ListView

theo đúng yêu cầu khách hàng. Custom lại ListView chăng qua là thiết kế lại

layout cho các item trên ListView. Như vậy từng item của ListView lúc này như

là một ViewGroup tức chúng có thể chứa các control.Để làm được điều này.

Bước 1: ta cần phải tạo một layout cho item của ListView.

<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/LinearLayout1" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal" > <ImageView android:id="@+id/imgItem" android:layout_width="22dip" android:layout_height="88dp" android:layout_gravity="center_vertical" android:layout_marginTop="4dp" android:layout_weight="0.50" android:contentDescription="here" android:paddingLeft="2dp" android:paddingRight="2dp" android:paddingTop="2dp" android:src="@drawable/ic_launcher" /> <TextView android:id="@+id/tvItem" android:layout_width="0dip" android:layout_height="wrap_content" android:layout_marginTop="4dp" android:layout_weight="2" android:paddingLeft="2dp" android:paddingRight="2dp" android:paddingTop="2dp" android:textSize="20sp" /> <CheckBox android:id="@+id/chkItem" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:focusable="false" android:focusableInTouchMode="false" />

</LinearLayout>

40

Bước 2: tạo một lớp MyarrayAdapter kế thừa từ arrayAdapter để gán vào

ListView.

package com.android.customlistview; import java.util.ArrayList; import android.app.Activity; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ArrayAdapter; import android.widget.ImageView; import android.widget.TextView; public class MyArrayAdapter extends ArrayAdapter<Employee> { Activity context = null; ArrayList<Employee> myArray = null; int layoutId; /** * Constructor này dùng để khởi tạo các giá trị từ MainActivity truyền vào * * @param context * : là Activity từ Main * @param layoutId * : Là layout custom do ta tạo (my_item_layout.xml) * @param arr * : Danh sách nhân viên truyền từ Main */ public MyArrayAdapter(Activity context, int layoutId, ArrayList<Employee> arr) { super(context, layoutId, arr); // TODO Auto-generated constructor stub this.context = context; this.layoutId = layoutId; this.myArray = arr; } /** * hàm dùng để custom layout, ta phải override lại hàm này từ MainActivity * truyền vào * * @param position * : là vị trí của phần tử trong danh sách nhân viên * @param convertView * : convertView, dùng nó để xử lý Item * @param parent * : Danh sách nhân viên truyền từ Main * @return View: trả về chính convertView */ @Override public View getView(int position, View convertView, ViewGroup parent) { // TODO Auto-generated method stub /**

41

* bạn chú ý là ở đây Tôi không làm: if(convertView==null) { * LayoutInflater inflater= context.getLayoutInflater(); * convertView=inflater.inflate(layoutId, null); } Lý do là ta phải xử * lý xóa phần tử Checked, nếu dùng If thì nó lại checked cho các phần * tử khác sau khi xóa vì convertView lưu lại trạng thái trước đó */ LayoutInflater inflater = context.getLayoutInflater(); convertView = inflater.inflate(layoutId, null); if (myArray.size() > 0 && position >= 0) { // dòng lệnh lấy TextView ra để hiển thị Mã và tên lên final TextView tvItem = (TextView) convertView .findViewById(R.id.tvItem); // lấy ra nhân viên thứ position final Employee emp = myArray.get(position); // đưa thông tin lên TextView // emp.toString() sẽ trả về Id và Name tvItem.setText(emp.toString()); // lấy ImageView ra để thiết lập hình ảnh cho đúng final ImageView imgItem = (ImageView) convertView .findViewById(R.id.imgItem); // nếu là Nữ thì lấy hình con gái if (emp.isGender()) imgItem.setImageResource(R.drawable.girlicon); else // nếu là Nam thì lấy hình con trai imgItem.setImageResource(R.drawable.boyicon); } // Vì View là Object là dạng tham chiếu đối tượng, nên // mọi sự thay đổi của các object bên trong convertView // thì nó cũng biết sự thay đổi đó return convertView; // trả về View này, tức là trả luôn // về các thông số mới mà ta vừa thay đổi }

}

Đến đây trong main_activity.java ta chỉ việc gán MyArrayAdapter vào ListView như trong ví dụ trước là được. chú ý là đối số truyền vào MyArrayAdapter là Employee nên lớp này ta phải tự thiết kế.

42

3. CHƯƠNG 3: XÂY DỰNG ỨNG DỤNG GTALK

3.1 Giới thiệu

Tin nhắn online(Instant messging) là một ứng dụng phổ biến giữa những người

dùng internet cũng như khách hàng thương mại trong truyền thông mobile. Nó

không những cung cấp cho người dùng kết nối với nhau trong thời gian thực, mà

còn có thể lưu trữ những thông tin gửi offline … Một trong những giao thức mã

nguồn mở sớm nhất là Jabber, là một giao thức được phát triển từ năm 1998 bởi

Jeremie Miler. XMMP không phải là giao thức duy nhất truyền tin nhắn. Những

giao thức thông dụng khác như XML-RPC và SOAP có thể cung cấp những

phương thức và thuộc tính tương tự.Giao thức mới hơn như là Representational

State Transfer(ReST) cung cấp việc quản lí truy cập file sử dụng URLs để xác định

vị trí, đối tượng, và phương thức …

3.1.1 Kiến trúc XMPP(Extensible Messaging and Presence Protocol)

XMMP cũng tương tự như giao thức lớp ứng dụng SMTP. Trong kiến trúc này

một client với một tên duy nhất sẽ kết nối với một client khác cũng có tên tương

tự thông qua 1 server. Mỗi client sẽ hiểu với nhau qua giao thức mà server cung

cấp quan sát hình minh họa sau :

Hình 3.1.1 XMPP server-client Servers chỉ đóng vai trò như một router giữa hai đối tượng. Hình dưới đây là

một ví dụ cho thấy một mạng XMPP với gateway đến một vùng Short Message

Service (SMS) và vùng SMTP Gateways thường được dùng trong trường hợp

chuyển đổi giữa hai giao thức IM(ví dụ XMPP sang Internet Relay Chat[IRC]).

Như một giao thức mở rộng, XMPP là một giao thức lý tưởng giữa các thiết bị đầu

cuối khác nhau

43

Hình 3.1.2 XMPP network 3.1.2 Address trong XMPP

Trong báo cáo thực tập này chúng em sẽ thực hiện và phân tích một ứng dụng

XMPP chat sử dụng server gmail.com và service gtalk.

3.1.3 XMPP protocol

XMPP là một giao thức quan hệ đơn giản dựa trên sockets sử dụng XML

messages. Giao tiếp bất đồng bộ với XML streams và XML stanzas.

44

Hình 3.1.3 XMPP protocol

3.1.4 Giới thiệu về gói thư viện asmack.jar

Có nhiều gói thư viện thứ 2 có sẵn để phát triển ứng dụng IM client. Một trong

số những thư viện được sử dụng nhiều nhất cho XMPP client libraries là Smack

API, đây là thư viện java thuần túy cho phép phát triển IM clients

Phiên bản được hỗ trợ mới nhất là aSmack 3.2.2 bởi nhà phát triển Samsum

3.2 Xây dựng project XMPPChatDemo

Ứng dụng này thực hiện các nhiệm vụ sau:

1. Kết nối đến Gtalk server

2. Đăng nhập vào Gtalk server

3. Thiết lập sự hiện diện của người dùng

4. Get Rosters

5. Gửi tin nhắn

6. Nhận tin nhắn

3.2.1 Code

45

Layout: Tạo layout như hình, ta có một đối tượng EditText để nhập địa chỉ

đích, một đối tượng EditText để nhập nội dung tin nhắn, một đối tượng Button để

gửi tin và một ListView để hiển thị nội dung. Trong phần thiết lập ListView đã

được trình bày ở phần trước

Hình 3.2.1 Layout ChatDemo

Activity

46

Hình 3.2.2 Cấu trúc MainActivity Những đoạn code chính cần quan tâm :

Khi sự kiện người dụng ấn vào nút nhấn ta tiến hành đọc nội dụng nhập vào để

lấy địa chỉ đích bằng phương thức getText() đối với đối tượng recipient mà ta đã

định nghĩa trong phần layout. Đưa nội dung tin nhắn vào đối tượng text. Đóng gói

dữ liệu thành đối tượng message. Đối tượng này sẽ được gửi đi bằng phương thức

sendPacke(). Thực hiện kết nối bằng phương thức connect().

String to = recipient.getText().toString();

String text = textMessage.getText().toString();

Message msg = new Message(to, Message.Type.chat);

msg.setBody(text);

if (connection != null) {

connection.sendPacket(msg);

messages.add(connection.getUser() + ":");

messages.add(text);

setListAdapter();

}

}

});

connect();

}

47

Kết nối đến server

Sử dụng aSmack SPI để kết nối đến server bằng đoạn code sau:Class XMPP

được sử dụng để tạo kết nối với server XMPP được xác định bằng

ConnectionConfiguration class, nó sẽ thiết lập bởi tham số truyền vào là tên server.

Để ngắt kết nối sử dụng phương thức disconnect().

Đăng nhập vào Server

Một khi đã thiết lập được kết nối, người dùng sẽ đăng nhập vào server với

username và password sử dụng phương thức login() của lớp Connection class

public static final String HOST = "talk.google.com";

public static final int PORT = 5222;

public static final String SERVICE = "gmail.com";

// Create a connection

ConnectionConfiguration connConfig = new ConnectionConfiguration(

HOST, PORT, SERVICE);

XMPPConnection connection = new XMPPConnection(connConfig);

try {

connection.connect();

Log.i("XMPPChatDemoActivity","Connected to " + connection.getHost());

} catch (XMPPException ex) {

Log.e("XMPPChatDemoActivity", "Failed to connect to "

+ connection.getHost());

Log.e("XMPPChatDemoActivity", ex.toString());

setConnection(null);

// SASLAuthentication.supportSASLMechanism("PLAIN", 0);

connection.login(USERNAME, PASSWORD);

Log.i("XMPPChatDemoActivity","Logged in as " + connection.getUser());

48

Thiết lập chế độ hiển thị

Sau khi đăng nhập, người dùng sẽ thiết lập trạng thái ẩn hiện với những người

khác trong chat list. Đoạn code dưới cho biết cách thiết lập sự hiện diện. Đối tượng

hiện diện được tạo với một trạng thái “available”. Trạng thái hiện diện này được

gửi bằng một gói dữ liệu sau đó bởi phương thức sendPacket() của Connection

class

Getting Roster

Class Roster thực hiện các công việc sau :

- Theo dõi sự hiện diện của người dùng khác

- Cho phép người dùng được tổ chức thành nhóm ví dụ như bạn bè hoặc

gia đình

- Tìm thấy tất cả nhưng danh mục và nhóm và ta có

- Lấy trạng thái hiện diện của mỗi người dùng

Đoạn code trước cho ta biết trạng thái của người dùng tại thời điểm đăng nhập,

nhưng khi có một người dùng khác đăng nhập tại thời điểm hiện tại thì ta cần phải

sử dụng bộ lắng nghe sự kiện RosterListener(interface) Phương thức sau sẽ được

gọi khi có bất kì sự thay đổi nào của roster.

// Set the status to available

Presence presence = new Presence(Presence.Type.available);

connection.sendPacket(presence);

setConnection(connection);

Roster roster = connection.getRoster();

Collection<RosterEntry> entries = roster.getEntries();

for (RosterEntry entry : entries) {

Presence entryPresence = roster.getPresence(entry.getUser());

Status:"+entryPresence.getStatus());

Presence.Type type = entryPresence.getType();

if (type == Presence.Type.available)

}

49

Gửi tin nhắn

Có 2 cách để gửi tin nhắn

- Sử dụng phương thức sendPacket(msg) của class XMPPconnection.

- Sử dụng class chatManager như đoạn code sau :

Đối tượng ChatManager được tạo ra từ XMPPConnection sử dụng phương

thức getChatManager(). Chatmanager theo dõi tất cả các cuộc chat hiện tại.

Nhận tin nhắn

Việc nhận tin nhắn từ người dùng khác được thực hiện bởi :

- Cơ chế thăm dò ý kiến được cung cấp thông qua việc sử dụng các lớp

PacketCollector.

Roster roster; roster.addRosterListener(new RosterListener() { @Override public void presenceChanged(Presence presence) { //Called when the presence of a roster entry is changed } @Override public void entriesUpdated(Collection<String> arg0) { // Called when a roster entries are updated. } @Override public void entriesDeleted(Collection<String> arg0) { // Called when a roster entries are removed. } @Override public void entriesAdded(Collection<String> arg0) { // TODO Auto-generated method stub

}

ChatManager chatmanager = connection.getChatManager(); Chat newChat = chatmanager.createChat("[email protected]", new MessageListener() { // Receiving Messages public void processMessage(Chat chat, Message message) { Message outMsg = new Message(message.getBody()); //Send Message object newChat.sendMessage(outMsg); //Send String as Message

newChat.sendMessage("How are you?");

50

- Cơ chế bất đồng bộ thông qua việc sử dụng bộ lắng nghe sự kiện

PacketListener()

Manifest: trong file manifest ngoài những thiết lập căn bản ta cẩn chắc chắn

rằng permission đã được add

3.2.2 Demo

Khởi động 2 máy ảo emulator chạy đồng thời máy A (5554) và máy B(5556)

Build và nạp ứng dụng vào máy A với username :[email protected]

Quan sát màn hình longcat cho ta thấy được các tài khoản trong danh mục và

tên users

public void setConnection(XMPPConnection connection) {

this.connection = connection;

if (connection != null) {

// Add a packet listener to get messages sent to us

PacketFilter filter = new MessageTypeFilter(Message.Type.chat);

connection.addPacketListener(new PacketListener() {

@Override

public void processPacket(Packet packet) {

Message message = (Message) packet;

if (message.getBody() != null) {

String fromName = StringUtils.parseBareAddress(message.getFrom());

Log.i("XMPPChatDemoActivity", "Text Recieved " + message.getBody()+ " from " + fromName );

messages.add(fromName + ":");

messages.add(message.getBody());

// Add the incoming message to the list view

mHandler.post(new Runnable() {

public void run() {

setListAdapter();

}

51

Buid và nạp ứng dụng cho máy B với username:[email protected]

Quan sát longcat thu được :

52

Như vậy máy A đang đang nhập với user 1:

[email protected]

Và máy B đang đăng nhập với user 2:

[email protected]

Đối với máy A nhập vào ô chat with là user 2

Đối với máy B nhập vào ô chat with là user 1

Thu được kết quả sau:

Hình 3.2.3Kết quả trên máy A

53

Hình 3.2.4 Kết quả trên máy B

54

4. CHƯƠNG 4: XÂY DỰNG ỨNG DỤNG STREAM AUDIO

VÀ VIDEO

4.1 Giới thiệu về Audio trên Android

Bất kì thiết bị smartphone nào ngày nay đều có khả năng chạy audio playback

tương tự như các thiết bị media hoặc MP3 player.Dĩ nhiên, thiết bị Android cũng

không ngoại lệ.Cho phép xây dựng các ứng dụng music player, audio book,

podcast, hoặc bất kì ứng dụng nào liên quan tới audio playback

4.1.1 Định dạng hỗ trợ Audio

Android hỗ trợ nhiều định dạng file audio và giải mã (codecs for playback) tuy

nhiên nó chỉ hỗ trợ vài định dạng recording .

AAC: Advanced Audio Coding codec là những định dạng như .m4a hoặc

3.gp. AAC là một chuẩn được sử dụng bở Ipod và các thiết bị chơi nhạc khác.

Android hỗ trợ định dạng audio là MPEG-4 files và 3GP files

MP3: MPEG-1 Audio Layer 3, .mp3 file. MP3, đây là dạng được dùng

phổ biến nhất được hỗ trợ trong Android cho phép đọc những file online trên

nhiều web sites và music stores

AMR: Adaptive Multi-Rate codec những định dạng như .3gp hoặc .amr .

AMR là chuẩn được sử dụng trong truyền thông và những ứng dụng voice

calling trên điện thoại và được hỗ trợ phát triển bởi nhà sản xuất.

Ogg: Ogg Vorbis, .ogg files. Là một dạng mã nguồn mở, chất lượng của

nó cũng giống như định dạng MP3 và ACC.

PCM:Pluse Code Modulation thông thường là những file .wav. PCM là

công nghệ sử dụng cho lưu trữ trên máy tính và thiết bị digital audio khác

4.1.2 Khởi chạy Audio thông qua Intent

Chúng ta sẽ xây dựng một ứng dụng Music đơn giản, có thể chạy tất cả các

files mà Android hỗ trợ. Đơn giản ta chỉ cần gọi chương trình có sẵn trong hệ điều

hành và sử dụng nó. Đầu tiên ta thiết lập giao diện cho ứng dụng là như sau:

55

Hình: 1Play audio layout

Trong Activity chính thiết lập sự kiện cho nút button

Khi button được nhấn sự kiện onClick sẽ xảy ra, trong hàm này ta sẽ gọi App

có sẵn để chạy file .Định danh ACTION_VIEW để gọi đến app có sẵn .Tạo đối

tượng sdcard để lấy đường dẫn các file trong sdcard sau đó lấy đường dẫn đến file

cần mở .Đối với đối tượng intent ta sử dụng phương thức để cài đặt đường dẫn Uri

và kiểu định dạng cho nó và cuối cùng kích hoạt Intent.

Trong file manifest ta phải khai báo để cho phép Activity gọi App khác

playButton = (Button) this.findViewById(R.id.Button01);

playButton.setOnClickListener(this);

Intent intent = new Intent(android.content.Intent.ACTION_VIEW);

File sdcard = Environment.getExternalStorageDirectory();

File audioFile =new File (sdcard.getPath()+ "/music/goodmorningandroid.mp3");

intent.setDataAndType(Uri.fromFile(audioFile), "audio/mp3");

startActivity(intent);

android:name="android.content.Intent.ACTION_VIEW"

56

Quan sát Emulator ta có kết quả :

Hình: 2Kết quả chạy audio

4.1.3 Xây dựng một ứng dụng Audio

Dĩ nhiên là ta có thể tự xây dụng một ứng dụng audio riêng, tạo giao diện theo

ý thích và lựa chọn các tính năng cần thiết cho ứng dụng. Để làm được điều này,

Android cung cấp một class là MediaPlayer. Class này được sử dụng cho playback

và điều khiển cho cả audio và video. Ví dụ đơn giản nhất về MediaPlayer là chạy

một file audio được đóng gói trong chính ứng dụng. Ta phải tạo một folder tài

nguyên tên là raw như sau :

Hình: 3Thư mục raw

57

Tạo một đối tượng MediaPlayer sử dụng phương thức create của class

MediaPlayer với tham số truyền vào là đường dãn tới thư mục chứa file cần mở :

Sau đó sử dụng phương thức start để mở :

Control playback

Class MediaPlayer chứa nhiều class để bắt sự kiện mà MediaPlayer gửi tới.Nó

sẽ gọi phương thức onCompletionListener và được cài đặt thông qua phương thức

setOnCompletionListener khi mà file audio được chạy xong.

Sau đây em xin trình bày một ví dụ về tạo giao diện điều khiển đơn giản để

chạy một file audio được đóng gói sẵn trong ứng dụng.

Tạo giao diện điều khiển như sau :

Hình: 4Layout audio custom

mediaPlayer = MediaPlayer.create(this, R.raw.goodmorningandroid);

mediaPlayer.start();

58

Sử dụng hàm findViewById , ta truy cập đến đối tượng nút nhấn được định

nghĩa trong file Layout XML

Để activity có thể đáp ứng được sự kiện click, ta phải khai báo bộ listener cho

2 nút này :

Tạo một đối tượng theView và khai báo sự kiện chạm tay vào màn hình:

Dưới đây là phương thức onComletion, được gọi khi MediaPlayer hoàn tất việc

chạy file audio. Ta sẽ gọi phương thức start để chạy audio sau đó gọi phương thức

seekTo đến vị trí đã lưu vào biến position :

Khi người dùng chạm vào màn hình cảm ứng , phương thức onTouch sẽ được

gọi. Trong phương thức này chúng ta chỉ quan tâm đến sự kiện ACTION_MOVE,

đây là sự kiện khi người dùng chạm và di chuyển ngón tay trên màn hình.

stopButton = (Button) this.findViewById(R.id.StopButton);

startButton.setOnClickListener(this);

stopButton.setOnClickListener(this);

theView = this.findViewById(R.id.theview);

theView.setOnTouchListener(this);

mediaPlayer.start();

@Override

public boolean onTouch(View v, MotionEvent me) {

if (me.getAction() == MotionEvent.ACTION_MOVE) {

if (mediaPlayer.isPlaying()) {

position = (int) (me.getX() * mediaPlayer.getDuration() / theView

.getWidth());

Log.v("SEEK", "" + position);

mediaPlayer.seekTo(position);

59

Cuối cùng, thiết lập sự kiện nút nhấn cho 2 Button :

4.2 Background and Networked Audio

4.2.1 Background Audio Playback

Nếu chúng ta muốn người dùng có thể làm những công việc khác trong khi

đang nghe nhạc ? Có một vấn đề gặp phải khi nó được xây dựng bằng activities.

Hệ điều hành Android sẽ có thể kill activities khi nó không tương tác với người

dùng. Nếu OS kill 1 activity đang chạy audio, thì điều này sẽ gây nên sự bất tiện

cho người dùng. Một giải pháp được đưa ra là thay vì sử dụng activities ta sẽ sử

dụng Service.

Service

Để chắc chắn rằng audio sẽ tiếp tục được chạy khi ứng dụng không còn tương

tác với người dùng nữa ta cần tạo một Service. Đó là một thành phần của các ứng

dụng Android mà các tác vụ được chạy ngầm và không tương tác và hiển thị với

người dùng.

Có 2 class Service khác nhau được dùng trong Android. Thứ nhất là Local

Service. Local Service tồn tại như một phần ứng dụng đặc biệt và được truy cập

chỉ bởi ứng dụng đó.Loại thứ 2 là Remote Service. Chúng có thể giao tiếp được

với nhau có thể được truy cập và điểu khiển bởi ứng dụng khác

Điều khiển một MediaPlayer trong Service

Để cho phép điều khiển một đối tượng MediaPlayer ta cần phải ràng buộc

Activity và Service với nhau. Một khi hoàn tất thì Activity và Service sẽ cùng chạy

song song với nhau

4.2.2 Networked Audio

Trong Android có hỗ trợ khá nhiều để chạy nhiều định dạng file audio có sẵn

trên network

@Override

public void onClick(View v) {

if (v == stopButton) {

mediaPlayer.pause();

} else if (v == startButton) {

60

Hình: 5Media LifeCycle

61

HTTP audio playback

Ta sẽ xây dựng một ví dụ đơn giản để chạy audio file và truy cập thông qua

HTTP, server có sẵn :

http://www.mobvcasting.com/android/audio/goodmorningandroid.mp3

Trong phương thức onCreate() tạo mới một đối tượng mediaplayer:

Với đối tượng này sử dụng phương thức SetDataSource() để link đến file cần

chạy trên server, sau đó là phương thức prepare() nó sẽ load dữ liệu từ server về

máy, chú ý là nó sẽ load toàn bộ file về máy trước khi thực hiện start().Sau đó file

này sẽ được chạy như ví dụ trước đã trình bày. Các phương thức này có thể ném

ra các ngoại lệ nên phải dùng cú pháp try catch :

Audio playback HTTP sử dụng prepareAsync()

Trong ví dụ trước, chỉ chạy được những file có dung lượng nhỏ, còn đối với

những file có dung lượng lớn thì thời gian load toàn bộ file về rất lớn, không đáp

ứng được nhu cầu chạy trực tuyến . Một giải pháp để khắc phục điều này là sử

dụng phương thức prepareAsync(). Phương thức này sẽ load dữ liệu vào một buffer

và khi đầy thì sẽ chuyển vào trạng thái prepared như trong sơ đồ Hình 4.5.

Dưới đây ta sẽ phân tích đoạn code để hiện thực hóa sơ đồ trên :

Tạo giao diện layout như sau:

mediaPlayer = new MediaPlayer();

mediaPlayer.setDataSource("http://www.mobvcasting.com/android/audio/goodmorningandroid.mp3");

mediaPlayer.prepare();

mediaPlayer.start();

62

Hình: 6Layout audio HTTP

Trong phương thức onCreate ta khai báo và thiết lập các đối tượng cần thiết:

Nút nhấn, textView, MediaPlayer…

Thiết lập bộ listener cho từng đối tượng:

Gọi phương thức :

stopButton.setOnClickListener(this);

startButton.setOnClickListener(this);

stopButton.setEnabled(false);

startButton.setEnabled(false);

mediaPlayer.setOnCompletionListener(this);

mediaPlayer.setDataSource("http://www.mobvcasting.com/android/audio/goodmorningandroid.mp3");

63

Xử lí các sự kiện. Khi có nút nhấn tương ứng, ta hiển thị lên màn hình phương

thức nào đã được gọi

Trong file manifest phải khai báo quyền sử dụng Internet :

Streaming Audio via HTTP

Phương thức streaming thông qua HTTP được phát triển từ năm 1999 do một

công ty tên là Nullsoft, Công ty này xây dựng một phần mềm gọi là WinAMP một

trình chơi MP3 thông dụng, và phát triển 1 server hỗ trợ audio streaming sử dụng

HTTP. Hiện tại một số lượng lớn các servers và phần mềm playback được tạo ra

đều hỗ trợ giao thức ICY, và là một chuẩn cho việc nghe radio online.

Ví dụ về sử dụng và chạy 1 file M3U chứa đường dẫn đến một trạm radio hoặc

bất kì M3U file chứa URL thích hợp:

Tạo layout như sau :

@Override

public void onClick(View v) {

if (v == stopButton) {

mediaPlayer.pause();

statusTextView.setText("pause called");

startButton.setEnabled(true);

}else if (v == startButton) {

mediaPlayer.start();

statusTextView.setText("start called");

startButton.setEnabled(false);

stopButton.setEnabled(true);

}

}

<uses-permission android:name="android.permission.INTERNET"/>

64

Trong phương thức onCreate để tạo các đối tượng sau :

Thiết lập các bộ Listener sự kiện cho các đối tượng:

Khi nút parseButton được nhấn, nó sẽ thực hiện phương thức

parsePlayListFile() mà chúng ta tự định nghĩa. Phương thức này tạo một đối tượng

HttpClient và gửi một yêu cầu đến server và ta sẽ nhân được một đối tượng trả về

là HttpResponse. Tiến hành lấy nội dung từ đối tượng này bằng các câu lệnh sau :

parseButton = (Button) this.findViewById(R.id.ButtonParse);

playButton = (Button) this.findViewById(R.id.PlayButton);

stopButton = (Button) this.findViewById(R.id.StopButton);

editTextUrl =(EditText)this.findViewById(R.id.EditTextURL);

Hiển thị đường link lên màn hình edittext:

parseButton.setOnClickListener(this);

playButton.setOnClickListener(this);

stopButton.setOnClickListener(this);

mediaPlayer = new MediaPlayer();

InputStream inputStream = httpResponse.getEntity().getContent();

BufferedReader bufferedReader =new BufferedReader(newInputStreamReader(inputStream));

65

Sử dụng phương thức readLine() cho đối tượng bufferedReader này ta sẽ thu

được dữ liệu dạng String. Nếu dữ liệu bắt đầu là kí tự # thì nó là metada và bỏ qua

nó, ta chỉ quan tâm đến dữ liệu bắt đầu là http:// mà thôi, cứ mỗi khi lấy được 1

đường dẫn url ta lại add nó vào một đối tượng là playListItems. Như vậy quá trình

phân tính file đã xong, ta cho phép nút nhấn playButton.

Khi người dùng nhấn playButton phương thức playPlaylistItems() được gọi.

Phương thức này sẽ chạy đường dẫn đầu tiên trong đối tượng playListItems. Lấy

đường dẫn lưu vào đối tượng path như sau:

Đến đây công việc còn lại đơn giản chỉ là tạo đối tượng MediaPlayer và sử dụng

các phương thức để chạy giống như ví dụ trước đã để cập:

String path = ((PlaylistFile) playlistItems

mediaPlayer.setDataSource(path);

66

4.3 Giới thiệu về Video playback

4.3.1 Định dạng hỗ trợ của Android

Thông thường định dạng mà Android hỗ trợ tương thích với nhiều loại thiết bị

mobile. Nó hỗ trợ 3GP(.3gp) và MPEG-4(.mp4) . 3GP là chuẩn được dẫn xuất từ

MPEG-4 được sử dụng cho mobile

Android hỗ trợ chuẩn mã hóa H.263 , được dùng cho ứng dụng video có bit

rate thấp và độ trễ thấp

4.3.2 Cách mở một tập tin video lưu trữ trong SD card

Có nhiều cách để mở một tập tin có sẵn trong máy, em xin giới thiệu 3 cách

như sau:

Ta có thể sử dụng Intent để khởi chạy một ứng dụng chạy video có sẵn của hệ

điều hành

Sử dụng class VideoView và các phương thức setVideoUri() và start() .Add

thêm các Widwet điều khiển bởi phương thức setMediaControler().

Sử dụng class MediaPlayer , cách này tương tự như đã trình bày ở phần audio.

Cách này đem lại sự linh động cho người lập trình hơn tuy nhiên phải viết code

dài và phức tạp

4.3.3 Network video

Có 2 phương pháp để xem video trên Internet thông dụng đó là downloading

và streaming

Downloading :khi tải về một tập tin thì toàn bộ tập tin sẽ được lưu trên thiết

bị, những tập tin này có thể mở và xem sau đó. Phương thức này có ưu điểm là

truy xuất nhanh đến các đoạn khác nhau trong tập tin nhưng có một nhược điểm

lớn là phải chờ cho toàn bộ tập tin được tải về trước khi nó có thể xem được. Nếu

như tệp có dung lượng nhỏ thì điều này không có quá nhiều bất tiện, nhưng với

tập tin lớn và nội dụng dài thì có thể gây ra nhiều khó chịu.

Streaming: Phương thức Streaming làm việc có một chút khác biệt- người

dùng cuối có thể bắt đầu xem tập tin ngay khi nó bắt đầu được tải .Tập tin được

gửi đến người dùng trong các chuỗi liên tiếp, và người dùng xem nội dung ngay

khi nó đến mà không phải chờ đợi.

Streaming video là gửi nội dung ở dạng nén trên internet và hiển thị bởi người

xem

ở thiết bị cuối theo thời gian thực. Hay nói một cách nôm na thì với streaming

video hoặc streaming phương tiện truyền thông thì một người sử dụng tại thiết bị

cuối không phải đợi để tải toàn bộ tập tin vềđểchạy nó. Thay vào đó các phương

tiện truyền thông như video, tập tin nhạc được gửi theo một luồng dữliệu liên tục

và được chạy ngay khi nó đến hoặc được lưu lại chờ đến lượt được chạy. Người

67

sử dụng sẽ cần một thiết bị mà nó được cài đặt sẵn chương trình phần mềm mà nó

liên tục tải dữ liệu theo luồng về thiết bị rồi ngay sau đó kết nối đến màn hình

hiển thị, loa… để chạy tập tin đó. Ngoài ra , Streaming video được thể hiện

dưới hai dạng: Video theo yêu câu (on demand) và Video th ời gian thực (live

event).

Video theo yêu cầu là các dữ liệu video được lưu trữ trên multimedia server

và được truyền đến người dùng khi có yêu cầu, người dùng có toàn quyền để hiển

thị cũng như thực hiện các thao tác (tua, dừng, nhẩy qua ..) với các đoạn dữ liệu

này.

Video thời gian thực là các dữliệu video được chuyển trực tiếp từcác nguồn

cung

cấp dữ liệu theo thời gian thực(máy camera, microphone, các thiết bị phát dữ

liệu video ...). Các dữ liệu này sẽ được multimedia phát quảng bá thành các kênh

người dùng sẽ chỉ có quyền truy nhập bất kỳ kênh ưa thích nào để hiển thị dữliệu

mà không được thực hiện các thao tác tua, dừngvv.. trên các dữ liệu đó (giống như

TV truyền thống).

Qui trình phát audio/video trực tuyến tiêu biểu bắt đầu với trang HTML trong

trình

duyệt. Khi người dùng nhấn liên kết nội dung hoặc chương trình player, trình

duyệt sẽ chuyển yêu cầu đến máy chủ web. Máy chủ web (web server) sẽchuyển

yêu cầu đến máy chủ dành riêng cho việc truyền phát nội dung, máy chủ này được

gọi là streaming server. Thực tế, có một số giải pháp sử dụng web server đảm

nhận vai trò truyền phát audio/video (dùng giao thức http), giải pháp này ít tốn

kém và đơn giản. Tuy nhiên, để cung cấp audio/video chất lượng cao cũng như

khả năng đáp ứng đồng thời nhiều luồng truyền, cần có phần mềm máy chủ chuyên

biệt (dùng giao thức truyền khác với máy chủ web).Ứng dụng phổ biến nhất của

hình thức Streaming video là dịch vụvideo theo yêu

cầu. Khách hàng có thể yêu cầu phim video đã được số hóa (và nén mã hóa)

lưu giữ tại server vào bất kỳ lúc nào. Nếu muốn, khách hàng có thể điều khiển

luồng nội dung tạm dừng, quay lại hay tới (nhờgiao thức RTSP hay MMS); nói

một cách khác, có thể thực hiện giống như với đầu máy tại nhà

4.3.4 Giao thức hỗ trợ HTTP và RTSP

HTTP : Chuẩn đầu tiên cần tìm hiểu là http. http được hỗ trợ một cách rộng rãi

để truy cập mạng và không có vấn đề xảy ra với tường lửa hoặc giao thức streaming

khác mà ta có. Media sử dụng HTTP là một chuẩn chung để xử lý dowload

Android cung cấp media theo yêu cầu với chuẩn MPEG-4 và 3GP file từ chuẩn

web server thông qua HTTP .Có nhiều tools miễn phí và thương mại có sẵn để xử

lý download với HTTP. Như là QuickTime X, Adobe Media Encoder, HanBrake,

và VLC.

68

Tiếp theo, ta quan tâm đến tốc độ bit của video. GPRS có băng thông thấp hơn

20 kbps, và do đó audio và video sẽ được mã hóa với tốc độ đó. Thông thường khi

dùng HTTP, media sẽ được buffered trên thiết bị , và playback sẽ được khởi chạy

khi đã được tải đầy đủ và sẽ không gây ra vẫn đề pause khi đang chạy. Nếu đường

truyền chỉ 20 kbps mà tốc độ encoded là 400 kbps thì trong mỗi giây của người

dùng xem phải đợi download trong 20 giây. Nếu sử dụng wifi, 400 kbps có thể

được đáp ứng

Thông thường tốc độ của mạng quyết định đến chất lượng của video.

RTSP :Chuẩn tiếp theo mà Android hỗ trợ là RTSP. RTSP là chuẩn cho Real

Time Streaming Protocol Dạng media mà được hỗ trợ kèm theo RTSP trong

Android là RTP (the Real time Transport Protocol), nhưng RTP chỉ hoạt động khi

có RTSP. Giao thức khác với HTTP về quá trình download. Nó cần phải có một

server đặc biệt để truyền video. Ví dụ ta có server có sẵn http://m.youtube.com

4.3.5 Giao thức hỗ trợ HTTP và RTSP

4.3.5.1 VideoView Network video player

Code:

Tạo một đối tượng VideoView được định nghĩa trong file layout :

Tạo đối tượng Uri chứa đường link đến server hỗ trợ streaming

Thiết lập giao diện điều khiển pause, seekto…

Thiết lập đường link với tham số truyền vào là đối tượng Uri vừa tạo :

Uri videoUri =

Uri.parse("http://channelz7.org.mp3.zdn.vn/zv/2d68e363c6fcc829d2faa

cbbe139b1fd/5209bd50/2012/06/06/4/0/40a2684713e84fc101ef7ca70279ae3

c.mp4?start=0");

vv = (VideoView) this.findViewById(R.id.VideoView);

vv.setMediaController(new MediaController(this));

vv.setVideoURI(videoUri);

69

Cuối cùng sau khi thiết lập xong ta khởi chạy và trước khi chạy phải chắc chắn

rằng add thêm permission cho INTERNET:

Demo

Để đơn giản ta truy cập để xem trực tuyến trên server zing.mp3

Truy cập vào video cần xem bằng chrome :

Hình: 7Zing server in Chrome

Kích download bằng IDM sau đó copy đường link ở URL:

Hình: 8URL in IDM

Và dán vào đối tượng Uri trong eclispe build và nạp qua emulator ta thu được

kết quả sau :

vv.start();

70

Hình: 9Kết quả xem Video trên zing server

4.3.5.2 Mediaplayer Network video player

Với lớp MediaPlayer ta có thể customize lại ứng dụng để linh động hơn trong

việc điều khiển cũng như thiết kế giao diện cân chỉnh kích thước hiển thị..

Sau đây em xin trình bày một ví dụ cụ thể sử dụng class MediaPlayer.

Code

Tạo main activiti có implement các class và interface để sử dụng các phương

thức của chúng :

Trong onCreate() tạo đối tượng surfaceView, đối tượng này là một lớp view

chứa toàn bộ những lớp view chồng lên nhau, chúng ta có thể thay đổi định dạng

public class CustomVideoPlayer extends Activity implements OnBufferingUpdateListener,

OnCompletionListener, OnErrorListener, OnInfoListener,

OnPreparedListener, OnSeekCompleteListener, OnVideoSizeChangedListener,

SurfaceHolder.Callback

71

và kích thước và vị trí của nó trên màn hình. SurfaceHolder là đối tượng hiển thị

trên cùng nhất mà ta nhìn thấy và tương tác với người dùng.

Tạo đối tượng mediaPlayer và thiết lập các bộ lắng nghe sự kiện

Thiết lập đường dẫn đến server như ví dụ trước đã trình bày vào đối tượng

filePath

Tạo thêm các đối tượng sau :statusView để hiện thị thông tin về quá trình nào

đang thực hiện, currentDisplay lưu giữ thông tin đang hiển thị ở màn hình, tạo đối

tượng điều khiển media.

Sau khi thiết lập xong các đối tượng thì đối tượng

surfaceView sẽ đi vào vòng đời của nó, đâu tiên ta override

phương thức surfaceCreate()

Tại đây ta sẽ sử dụng phương thức prepareAsync() cho đối tượng media:

Sau khi gọi phương thức trên đối tượng media sẽ bắt đầu load dữ liệu từ internet

về khi đầy buffer thì chuyển vào trạng thái prepared và phương thức onPrepare()

sẽ được gọi. (tham khảo thêm vòng đời của mediaplayer). Trong phương thức này

ta sẽ thực hiện điều chỉnh lại kích thước phân giải cho phù hợp với màn hình hiển

thị. Chúng ta không đi sâu vào vấn đề này.

surfaceView = (SurfaceView) this.findViewById(R.id.SurfaceView);

surfaceHolder = surfaceView.getHolder();

surfaceHolder.addCallback(this);

mediaPlayer = new MediaPlayer();

mediaPlayer.setOnCompletionListener(this);

mediaPlayer.setOnErrorListener(this);

mediaPlayer.setOnInfoListener(this);

mediaPlayer.setOnPreparedListener(this);

String filePath = "http://channelz7.org.mp3.zdn.vn/zv/c8026bfc894c49ed70e41e696519eb9c/5209bd50/2012/10/07/a/1/a178fd2f3b643435ab28f0049744776b.mp4?start=0";

statusView.setText("MediaPlayer DataSource Set");

currentDisplay = getWindowManager().getDefaultDisplay();

mediaPlayer.setDisplay(holder);

72

Tiếp theo để hiển thị lên giao diện điều khiển ta cần phải thực hiện các phương

thức sau đây cuối cùng hiển thị lên text view trạng thái hiện tại.

Ta cần xem tình trạng của buffered được điền đầy hay chưa thì cần phải

override phương thức onBufferingUpdate(). Phương thức này được gọi khi có bất

kì sự thay đổi nào của buffer

Cuối cùng ta quan tâm đến sự kiện chạm tay vào màn hình của người sử dụng,

khi chạm tay vào thì giao diện điều khiển media sẽ hiện ra và chạm tiếp thì ẩn đi.

Demo

Quan sát các phương thức và các biến trong outline trên màn hình của IDE để

có thể hình dung tổng quát được nội dung code

controller.setMediaPlayer(this); controller.setAnchorView(this.findViewById(R.id.MainView));

controller.setEnabled(true);

controller.show();

mp.start();

statusView.setText("MediaPlayer Started");

statusView.setText("MediaPlayer Buffering: " + bufferedPercent + "%");

@Override

public boolean onTouchEvent(MotionEvent ev) {

if (controller.isShowing()) {

controller.hide();

} else {

controller.show();

}

return false;

}

73

Hình: 10Outline

74

Thực hiện build và nạp lên emulator ta thu được kết quả sau

Hình: 11 Kết quả Streaming

75

5. CHƯƠNG 5: KẾT QUẢ ĐẠT ĐƯỢC VÀ ĐÁNH GIÁ

HƯỚNG LUẬN VĂN

5.1 Kết quả đạt được

Qua thời gian thực tập, chúng em tìm hiểu và nghiên cứu về HDH Android và

cũng đã nắm bắt được các vấn đề cơ bản của HDH Android, thực hiện lập trình một

số ứng dụng cơ bản như app chat gtalk Gmail, streaming video and audio, thực hiện

giao tiếp giữa thiết bị Android và Arduino. Tuy nhiên các ứng dụng đó chỉ mang

tính demo chứ chưa thể gửi lên app store của google. Để làm được điều này cần

phải nâng cấp thêm app.

5.2 Hướng phát triển luận văn

Hiện nay trào lưu SmartPhone đang phát triển mạnh mẽ, giá thành của chiếc

SmartPhone đang ngày càng giảm xuống nhờ nó đã được dân dụng hóa đồng thời

cung cấp thêm nhiều tính năng mới, nhiều chuẩn giao tiếp như 3G, wifi, GPRS…

Trong khi với một board mạch điều khiển mà có đầy những modul giao tiếp thì giá

thành rất đắt. Đổi lại các board mạch này có sẵn các chân I/O cho phép dễ dàng

điều khiển, thu thập tín hiệu càm biến. Chính vì vậy nếu ta có thể thực hiện giao

tiếp giữa MCU và smartphone thì ta có thể tận dụng được ưu điểm của hai thiết bị

này với nhau. MCU có thể tận dụng khả năng xử lí mạnh mẽ cũng như các modul

tích hợp giao tiếp 3G, wifi, camera, touchScreen… sẵn có trên SmartPhone với giá

thành rẻ, đồng thời vẫn có thể điều khiển, thu thập tín hiệu từ các sensor thông qua

các chân IO