tìm hiểu hệ điều hành android
DESCRIPTION
1/ mô tả về Android2/ tạo giao diện GUITRANSCRIPT
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 :
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ó
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();
}
52
Như vậy máy A đang đang nhập với user 1:
Và máy B đang đăng nhập với user 2:
Đố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
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) {
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;
}
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