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

216 763 3
Lập trình trên thiết bị di động

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

Thông tin tài liệu

BỘ GIÁO DỤC VÀ ĐÀO TẠO ĐẠI HỌC CÔNG NGHỆ TP.HCM LẬP TRÌNH TRÊN THIẾT BỊ DI ĐỘNG Biên Soạn: ThS Nguyễn Hà Giang www.hutech.edu.vn LẬP TRÌNH TRÊN THIẾT BỊ DI ĐỘNG Ấn 2014 MỤC LỤC I MỤC LỤC MỤC LỤC I HƯỚNG DẪN V BÀI 1: TỔNG QUAN VỀ LẬP TRÌNH TRÊN THIẾT BỊ DI ĐỘNG 1.1 THIẾT BỊ DI ĐỘNG 1.1.1 Nền tảng Android 1.1.2 Nền tảng iOS 1.1.3 Nền tảng Windows Phone 2.2 ỨNG DỤNG TRÊN THIẾT BỊ DI ĐỘNG 1.1.4 Native Application 1.1.5 Mobile Web Application 1.1.6 Hybrid Application 1.1.7 Chọn lựa Native, Web hay Hybrid TÓM TẮT BÀI TẬP BÀI 2: PHÁT TRIỂN ỨNG DỤNG TRÊN ANDROID 10 2.1 HỆ ĐIỀU HÀNH ANDROID 10 2.1.1 Đặc điểm 10 2.1.2 Giao diện 11 2.1.3 Ứng dụng 12 2.1.4 Kiến trúc 13 2.1.5 Quản lý nhớ 15 2.1.6 Các phiên Android 15 2.1.7 Các thiết bị khác dùng Android 16 2.2 PHÁT TRIỂN ỨNG DỤNG TRÊN ANDROID 17 2.2.1 Nền tảng xây dựng phát triển ứng dụng Android 18 2.2.2 Công cụ môi trường để phát triển ứng dụng Android 19 2.2.3 Các bước chuẩn bị môi trường phát triển ứng dụng 20 2.3 QUY TRÌNH PHÁT TRIỂN ỨNG DỤNG ANDROID 23 2.3.1 Giai đoạn phát triển 25 2.3.2 Giai đoạn build & run ứng dụng Android 27 2.3.3 Giai đoạn publish 30 2.4 CÁC THÀNH PHẦN TRONG ỨNG DỤNG ANDROID 31 2.4.1 Activity 31 2.4.2 Service 31 2.4.3 Content provider 32 2.4.4 Broadcast receiver 32 2.4.5 Đối tượng Intent 33 TÓM TẮT 35 II MỤC LỤC BÀI TẬP 35 BÀI 3: XÂY DỰNG ACTIVITY 36 3.1 ĐẶC ĐIỂM ACTIVITY 36 3.2 VÒNG ĐỜI HOẠT ĐỘNG 36 3.2.1 Tiến trình hoạt động ứng dụng Android .36 3.2.2 Activity stack 38 3.2.3 Vòng đời hoạt động Activity .39 3.3 XÂY DỰNG ACTIVITY 40 3.3.1 Tạo ứng dụng Android với Activity 40 3.3.2 Các thành phần cấu trúc project Android 44 3.3.3 Làm việc với resource .50 3.4 XỬ LÝ SỰ KIỆN 55 3.4.1 Đăng ký xử lý kiện thông qua anonymous inner class .57 3.4.2 Đăng ký thông qua lớp Activity thực thi giao diện Listener 61 3.4.3 Đăng ký thông qua XML Layout 62 TÓM TẮT 65 BÀI TẬP 66 BÀI 4: THIẾT KẾ GIAO DIỆN 67 4.1 TỔ CHỨC GIAO DIỆN 67 4.2 THIẾT KẾ GIAO DIỆN QUA XML 70 4.3 CÁC THUỘC TÍNH XML CƠ BẢN 72 4.4 ANDROIDMANIFEST.XML 76 4.5 RESOURCE VÀ R.JAVA 77 4.5.1 Resource .77 4.5.2 Sử dụng resource mã chương trình (java code) 78 4.5.3 Tham chiếu resource resource khác 79 4.5.4 Nhiều phiên resource tính localization .80 4.5.5 Tập tin R.java 80 4.6 LINEARLAYOUT 82 4.7 ABSOLUTELAYOUT 85 4.8 RELATIVELAYOUT 87 4.9 TABLELAYOUT 89 4.10 FRAMELAYOUT 93 4.11 SCROLLVIEW 95 4.12 GRIDLAYOUT 97 TÓM TẮT 105 BÀI TẬP 106 BÀI 5: THÀNH PHẦN VIEW - WIDGET 109 5.1 VIEW CƠ BẢN 109 5.2 VIEW NÂNG CAO 121 MỤC LỤC III 5.3 TOAST VÀ DIALOG 138 TÓM TẮT 142 BÀI TẬP 142 BÀI 6: THÀNH PHẦN INTENT 146 6.1 CƠ CHẾ INTENT 146 6.2 ĐỐI TƯỢNG INTENT 147 6.3 PHÂN LOẠI INTENT 149 6.3.1 Intent Filter 150 6.3.2 Cách thức xác định thành phần phù hợp với Intent 151 6.4 SỬ DỤNG CÁC INTENT 152 6.4.1 Explicit Intent thực thi Activity 153 6.4.2 Implicit Intent thực thi Activity 153 6.5 GỌI HIỂN THỊ ACTIVITY 154 6.5.1 Gọi hiển thị trau đổi liệu 154 6.5.2 Gọi hiển thị truyền liệu cho Activity 155 6.5.3 Gọi hiển thị truyền/nhận liệu với Activity 156 TÓM TẮT 159 BÀI TẬP 160 BÀI 7: LẬP TRÌNH SQLITE 161 7.1 CƠ SỞ DỮ LIỆU SQLITE 161 7.1.1 Đặc trưng SQLite 162 7.1.2 Lập trình với SQLite 162 7.1.3 Kiểu liệu lưu trữ 163 7.1.4 Các lớp gói SQLite 164 7.1.5 Thư mục lưu trữ 165 7.2 ỨNG DỤNG MINH HỌA 166 7.2.1 Tạo lớp kế thừa từ SQLiteOpenHelper 166 7.2.2 Tạo lớp chứa liệu DTO Student 167 7.2.3 Tạo lớp truy cập liệu 168 7.2.4 Thao tác insert liệu 171 7.2.5 Hiển thị danh sách sinh viên 172 TÓM TẮT 173 BÀI TẬP 173 BÀI 8: ỨNG DỤNG SERVICE 175 8.1 THÀNH PHẦN SERVICE 175 8.1.1 Vòng đời Service 176 8.1.2 Khuôn mẫu chung lớp thực thi Service 177 8.2 ỨNG DỤNG CHƠI NHẠC 179 TÓM TẮT 184 BÀI TẬP 185 IV MỤC LỤC BÀI 9: BROADCAST RECEIVER 186 9.1 CƠ CHẾ BROADCAST RECEIVER 186 9.1.1 Phân loại Broadcast 187 9.1.2 Tạo broadcast receiver 187 9.1.3 Đăng ký xử lý Broadcast Intent 187 9.1.4 Một số Broadcast Intent 188 9.1.5 Phát sinh Custome Broadcast Intent 189 9.2 MINH HỌA BẮT VÀ HIỂN THỊ SMS 190 9.2.1 Cách thức bắt xử lý SMS 190 TÓM TẮT 195 BÀI TẬP 196 BÀI 10: THÀNH PHẦN NOTIFICATION 197 10.1 THÀNH PHẦN NOTIFICATION 197 10.2 THỂ HIỆN THÔNG ĐIỆP 198 10.2.1 Dạng bình thường 198 10.2.2 Dạng lớn 199 10.3 TẠO THÔNG ĐIỆP 200 10.3.1 Các nội dung thông điệp bắt buộc 200 10.3.2 Hành động thông điệp 201 10.3.3 Tạo thông điệp đơn giản 201 10.4 SỬ DỤNG THANH TIẾN ĐỘ 202 10.4.1 Thanh tiến độ với thời gian xác định 202 10.4.2 Thanh dẫn liên tục 203 TÓM TẮT 205 BÀI TẬP 205 TÀI LIỆU THAM KHẢO 206 HƯỚNG DẪN V HƯỚNG DẪN MÔ TẢ MÔN HỌC Môn học trang bị kiến thức cách thức phát triển ứng dụng tảng thiết bị di động Bao gồm nhóm kiến thức: giới thiệu tảng hay hệ điều hành thiết bị di động, công cụ môi trường để phát triển ứng dụng thiết bị di động thông minh NỘI DUNG MÔN HỌC - Bài Tổng quan lập trình thiết bị di động: Kiến thức thiết bị di động khái niệm môi trường cách thức lập trình thiết bị di động - Bài Phát triển ứng dụng Android: Cung cấp kiến thức hệ điều hành Android Trình bày mô hình quy trình phát triển ứng dụng thiết bị di động hỗ trợ Android Ngoài giới thiệu thành phần ứng dụng Android điển hình - Bài Xây dựng Activity ứng dụng Android: Bài học cung cấp kiến thức để xây dựng ứng dụng có giao diện tương tác với người dùng; cách thức hoạt động thành phần Activity ứng dụng Android Làm quen với cách thức sử dụng layout XML để khởi tạo giao diện Activity - Bài Thiết kế giao diện: Trong trình bày loại layout nâng cao để tạo giao diện cho Activity - Bài Thành phần View-Widget: Cung cấp loại widget từ đến nâng cao, bao gồm chức năng, cách sử dụng thiết kế giao diện cách tham chiếu để lập trình mã nguồn Java - Bài Thành phần Intent: Bài cung cấp kỹ thuật để truyền thông giao tiếp thành phần ứng dụng Android Cách thức gọi hiển thị Activity ứng dụng gọi ứng dụng hệ thống trình bày chi tiết học VI - HƯỚNG DẪN Bài Lập trình với SQLite: Kỹ thuật để tạo sử dụng sở liệu SQLite ứng dụng Android - Bài Xây dựng ứng dụng Service: Cung cấp mô hình tổng quát để tạo ứng dụng Android chạy background, dạng ứng dụng hoạt động giao diện tương tác với người dùng - Bài Lập trình Broadcast Receiver: Cung cấp kỹ thuật đăng ký xử lý thông điệp hệ thống hay ứng dụng - Bài 10 Thành phần Notification: Cách thức sử dụng Notification ứng dụng Android KIẾN THỨC TIỀN ĐỀ Sinh viên có kiến thức lập trình hướng đối tượng, lập trình có giao diện tương tác với người dùng Ngoài có kiến thức sở liệu quan hệ lập trình sở liệu YÊU CẦU MÔN HỌC Người học phải tham dự đầy đủ buổi lên lớp làm tập đầy đủ nhà Ngoài trước buổi học, người học phải đọc trước học giảng để nắm nội dung Sau lên lớp, người học cần đọc thêm tài liệu giảng viên trực tiếp đứng lớp yêu cầu Do giới hạn giảng cung cấp hết chi tiết thành phần lập trình Android, yêu cầu người học cần phải đọc thêm tài liệu tham khảo liệt kê phần cuối giảng CÁCH TIẾP NHẬN NỘI DUNG MÔN HỌC Để học tốt môn này, người học cần ôn tập học, trả lời câu hỏi làm đầy đủ tập; đọc trước tìm thêm thông tin liên quan đến học Đối với học, người học đọc trước mục tiêu tóm tắt học, sau đọc nội dung học Kết thúc học người đọc cần phải làm tối thiểu tập yêu cầu HƯỚNG DẪN VII Ngoài môn học có số có phần thực hành viết chương trình, người học cần phải làm tập phần thực hành tương ứng với học PHƯƠNG PHÁP ĐÁNH GIÁ MÔN HỌC Môn học đánh giá gồm:  Điểm trình: 30% Hình thức nội dung giảng viên định, phù hợp với quy chế đào tạo tình hình thực tế nơi tổ chức học tập Điểm thi: 70% Hình thức thi báo cáo đồ án môn học 192 BÀI 9: BROADCAST RECEIVER for (int i = 0; i < pdusObj.length; i++) { SmsMessage currentMessage = SmsMessage.createFromPdu((byte[]) pdusObj[i]); String phoneNumber = currentMessage.getDisplayOriginatingAddress(); String senderNum = phoneNumber; String message = currentMessage.getDisplayMessageBody(); Log.i("SmsReceiver", "senderNum: "+ senderNum + "; message: " + message); int duration = Toast.LENGTH_LONG; Toast toast = Toast.makeText(context, "senderNum: "+ senderNum + ", message: " + message, duration); toast.show(); } // end for loop } // bundle is null } catch (Exception e) { Log.e("SmsReceiver", "Exception smsReceiver" +e); } } } Phần khai báo AndroidManifest.xml, khai báo Activity xem ứng dụng có giao diện thêm phần khai báo Receiver xử lý kiện tin nhắn SMS đến Ngoài ra, bổ sung thêm permission liên quan đến truy cập tin nhắn SMS 194 BÀI 9: BROADCAST RECEIVER BÀI 9: BROADCAST RECEIVER 195 TÓM TẮT Broadcast Receiver thành phần quan trọng ứng dụng Android, cho phép bắt xử lý kiện phát sinh từ hệ thống Android hay kiện phát sinh từ ứng dụng Thông qua học người học hiểu chế phát sinh kiện hệ thống Android, hiểu cách chặn xử lý kiện 196 BÀI 9: BROADCAST RECEIVER BÀI TẬP Câu 1: Viết ứng dụng Android cho phép lưu tin nhắn SMS mà máy nhận Các tin nhắn gởi đến máy lưu CSDL SQLite riêng ứng dụng Ứng dụng cho phép người dùng thêm, xóa, gởi nội dung tin nhắn vào địa email xác định Câu 2: Viết ứng dụng Android lưu số điện thoại gọi đến máy, thông tin lưu trữ gồm: {số điện thoại, thời gian gọi} lưu CSDL SQLite Ứng dụng cho phép quản lý gọi lưu CSDL riêng Câu 3: Viết hai ứng dụng Android thực yêu cầu sau: Ứng dụng Android A: giả lập máy rút tiền ATM, cho phép user xem thông tin tài khoản, xem số dư, xem lịch sử giao dịch, cho phép rút tiền Trong chức rút tiền sau thực xong phát sinh Broadcast lên hệ thống Ứng dụng Android B: đăng ký xử lý kiện A có giao dịch rút tiền hoàn tất, B lấy thông tin {mã tài khoản, tên tài khoản, số tiền rút, số dư cuối} B kiểm tra CSDL khách hàng để lấy số điện thoại khách hàng Cuối B thực nhắn tin cho khách hàng biết giao dịch vừa diễn với số tiền rút số dư cuối Câu 4: Bổ sung thêm dựa ứng dụng câu theo yêu cầu sau: Bổ sung thêm chức chuyển khoản cho ứng dụng A, cho người dùng chuyển vào tài khoản khác số tiền nhỏ số dư Khi A phát sinh kiện lên hệ thống: Sự kiện rút tiền tài khoản làm việc (sự kiện xử lý câu 3) Sự kiện chuyển khoản Sự kiện chuyển khoản xử lý ứng dụng B (phần viết bổ sung) B thực chức nhắn tin cho khách hàng chuyển khoản BÀI 10: THÀNH PHẦN NOTIFICATION 197 BÀI 10: THÀNH PHẦN NOTIFICATION Học xong này, người học cần nắm nội dung sau - Cơ chế Notification ứng dụng Android, thành phần cần thiết hệ điều hành dành cho thiết bị di động - Các dạng thông điệp hiển thị tảng Android - Hiểu cách thức tạo phát sinh thông điệp lập trình Android - Làm việc với chức nâng cao thể dạng progress ứng dụng Android 10.1 THÀNH PHẦN NOTIFICATION Notification dạng thông điệp đặc biệt để hiển thị thông tin cho người dùng, thông điệp xuất bên giao diện thông thường ứng dụng Khi ứng dụng báo với hệ thống phát sinh Notification, hình xuất biểu tượng vùng Notification Để nhìn thấy chi tiết Notification, người dùng mở Notification Drawer Cả hai thành phần vùng quản lý hệ thống người dùng mở lúc Hình 10.1: Các thông điệp Notification Area 198 BÀI 10: THÀNH PHẦN NOTIFICATION Hình 10.2: Các Notification Notification Drawer Trong tảng Android thành phần Notification hữu dụng quen thuộc với người dùng, cho phép người dùng biết mà ứng dụng hay hệ thống muốn thông báo Ví dụ như: có sms nhận, có gọi nhỡ, mạng Wi-Fi, Bluetooth… 10.2 THỂ HIỆN THÔNG ĐIỆP Các thông điệp vùng Notification Area xuất theo hai dạng sau, điều tùy thuộc vào phiên trạng thái Drawer - Dạng bình thường (normal view): giao diện chuẩn thông điệp hiển thị Notification Drawer - Dạng lớn (big view): dạng xuất thông điệp mở Cách thể đặc tính xuất Android 4.1 10.2.1 Dạng bình thường Một thông điệp chế độ xuất vùng có kích thước khoảng 64 dp chiều cao Thậm chí tạo thông điệp với dạng lớn, xuất dạng bình thường mở Hình 10.3 bên minh họa cho dạng thể BÀI 10: THÀNH PHẦN NOTIFICATION 199 Hình 10.3: Các thông điệp dạng bình thường Các thành phần theo nhãn hình 10-3 sau: Nội dung tiêu đề Icon lớn Nội dung thông điệp Thông tin nội dung Icon nhỏ Thời gian mà thông điệp đưa 10.2.2 Dạng lớn Dạng thông điệp lớn hiển thị thông điệp mở rộng, điều xuất thông điệp Notification Drawer, người dùng mở rộng Chức xuất từ phiên 4.1 Hình 10-4 minh họa phần thể dạng Hình 10.4: Dạng thể lớn 200 BÀI 10: THÀNH PHẦN NOTIFICATION Như ta thấy hình 10-4, hầu hết chúng giống thành phần dạng bình thường, khác thành phần có nhãn số 7, vùng chi tiết Có số kiểu thể khác dạng view này: Dạng ảnh lớn (big picture style): vùng chi tiết chứa ảnh bitmap có kích thước đến 256 chiều cao Dạng văn lớn (big text style): hiển thị khối văn lớn vùng chi tiết Dạng inbox (inbox style): hiển thị dòng văn vùng chi tiết Ngoài dạng view cho phép nội dung tùy chọn sau, nội dung view bình thường Dạng tiêu đề nội dung lớn: cho phép ta viết lại tiêu đề nội dung xuất view bình thường Văn tóm tắt: cho phép thêm dòng văn bên vùng chi tiết 10.3 TẠO THÔNG ĐIỆP Người lập trình thiết lập thông tin giao diện hành động cho thông điệp thông qua đối tượng NotificationCompat.Builder Để tạo thông điệp phải gọi phương thức NotificationCompat.Builder.build(), phương thức trả đối tượng Notification chứa phần mô tả chương trình Sau thiết lập xong thông số cho thông điệp phát sinh thông điệp truyền đối tượng Notification cho hệ thống cách gọi phương thức NotificationManager.notify() 10.3.1 Các nội dung thông điệp bắt buộc Một đối tượng notification phải chứa thông tin sau: Icon nhỏ: dùng phương thức setSmallIcon() Tiêu đề: thiết lập với setContentTitle() Nội dung chi tiết: setContentText() Các thông tin lại tùy chọn, tùy theo yêu cầu cụ thể mà thông điệp có thiết lập hay không thiết lập BÀI 10: THÀNH PHẦN NOTIFICATION 201 10.3.2 Hành động thông điệp Mặc dù thành phần tùy chọn, ta nên thêm tối thiểu hành động cho thông điệp Một hành động cho phép người dùng từ thông điệp đến Activity ứng dụng Một thông điệp cung cấp nhiều hành động, thông thường định nghĩa hành động ràng buộc người dùng chạm vào thông điệp, phổ biến mở Activity ứng dụng Ngoài ta thêm button vào thông điệp để thực thi hành động thêm vào tắt alarm hay trả lời tin nhắn (từ phiên 4.1) 10.3.3 Tạo thông điệp đơn giản Đoạn code sau minh họa cách tạo thông điệp đơn giản cho phép user mở Activity chạm hay kích vào thông điệp NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this) setSmallIcon(R.drawable.notification_icon) setContentTitle("My notification") setContentText("Hello World!"); Intent resultIntent = new Intent(this, ResultActivity.class); TaskStackBuilder stackBuilder = TaskStackBuilder.create(this); stackBuilder.addParentStack(ResultActivity.class); stackBuilder.addNextIntent(resultIntent); PendingIntent resultPendingIntent = stackBuilder.getPendingIntent( 0, PendingIntent.FLAG_UPDATE_CURRENT ); mBuilder.setContentIntent(resultPendingIntent); NotificationManager mNotificationManager = 202 BÀI 10: THÀNH PHẦN NOTIFICATION (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); mNotificationManager.notify(mId, mBuilder.build()); 10.4 SỬ DỤNG THANH TIẾN ĐỘ Thông điệp chứa dẫn tiến độ dạng animation cho người dùng biết tình trạng hoạt động chức Nếu ước lượng thời gian mà hoạt động diễn thời gian để hoàn thành dùng hình thức xác định tiến độ (progress bar) Nếu không xác định thời gian hoàn thành hoạt động dùng hình thức không xác định (dạng minh họa hoạt động liên tục) Từ phiên Android 4.0 để sử dụng tiến độ gọi phương thức setProgress() Trong phiên trước phải tạo layout thông điệp chứa ProgressBar 10.4.1 Thanh tiến độ với thời gian xác định Để hiển thị tiến độ với thời gian xác định, gọi phương thức setProgress() theo tham số setProgress(max, progress, false) phát sinh thông điệp Khi hoạt động diễn giá trị progress gia tăng cập nhật thông điệp Khi hoạt động hoàn thành giá trị progress với max Cách thực chung gọi setProgress() với max 100 gia tăng progress mức độ hoàn thành công việc Sau công việc hoàn thành cập nhật lại nội dung thông điêp để báo hoàn thành xóa tiến độ cách gọi setProgress(0, 0, false) Đoạn code sau minh họa việc tạo tiến độ: mNotifyManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); mBuilder = new NotificationCompat.Builder(this); mBuilder.setContentTitle("Picture Download") setContentText("Download in progress") setSmallIcon(R.drawable.ic_notification); BÀI 10: THÀNH PHẦN NOTIFICATION 203 new Thread( new Runnable() { @Override public void run() { int incr; for (incr = 0; incr

Ngày đăng: 21/09/2017, 21:03

Mục lục

  • 1.1.3 Nền tảng Windows Phone

  • 1.1.7 Chọn lựa giữa Native, Web hay Hybrid

  • BÀI 2: PHÁT TRIỂN ỨNG DỤNG TRÊN ANDROID

    • 2.1 HỆ ĐIỀU HÀNH ANDROID

      • 2.1.1 Đặc điểm cơ bản

      • 2.1.5 Quản lý bộ nhớ

      • 2.1.6 Các phiên bản Android

      • 2.1.7 Các thiết bị khác dùng Android

      • 2.2 PHÁT TRIỂN ỨNG DỤNG TRÊN ANDROID

        • 2.2.1 Nền tảng xây dựng và phát triển ứng dụng Android

        • 2.2.2 Công cụ và môi trường để phát triển ứng dụng trên Android

        • 2.2.3 Các bước chuẩn bị môi trường phát triển ứng dụng

        • 2.3 QUY TRÌNH PHÁT TRIỂN ỨNG DỤNG ANDROID

          • 2.3.1 Giai đoạn phát triển

          • 2.3.2 Giai đoạn build & run ứng dụng Android

          • 3.2 VÒNG ĐỜI HOẠT ĐỘNG

            • 3.2.1 Tiến trình hoạt động của ứng dụng Android

            • 3.2.3 Vòng đời hoạt động của Activity

            • 3.3 XÂY DỰNG ACTIVITY

              • 3.3.1 Tạo ứng dụng Android với Activity

              • 3.3.2 Các thành phần trong cấu trúc project Android

              • 3.3.3 Làm việc với resource

              • 3.4 XỬ LÝ SỰ KIỆN

                • 3.4.1 Đăng ký xử lý sự kiện thông qua anonymous inner class

                • 3.4.2 Đăng ký thông qua lớp Activity thực thi giao diện Listener

                • 3.4.3 Đăng ký thông qua XML Layout

                • BÀI 4: THIẾT KẾ GIAO DIỆN

                  • 4.1 TỔ CHỨC GIAO DIỆN

Tài liệu cùng người dùng

Tài liệu liên quan