Bài giảng Lập trình di động - Bài 8: Broadcast Receivers + Telephonyr - Trương Xuân Nam

pdf 40 trang ngocly 2440
Bạn đang xem 20 trang mẫu của tài liệu "Bài giảng Lập trình di động - Bài 8: Broadcast Receivers + Telephonyr - Trương Xuân Nam", để tải tài liệu gốc về máy bạn click vào nút DOWNLOAD ở trên

Tài liệu đính kèm:

  • pdfbai_giang_lap_trinh_di_dong_bai_8_broadcast_receivers_teleph.pdf

Nội dung text: Bài giảng Lập trình di động - Bài 8: Broadcast Receivers + Telephonyr - Trương Xuân Nam

  1. LẬP TRÌNH DI ĐỘNG Bài 8: Broadcast Receivers + Telephony
  2. Nhắc lại bài trước . Các API thông dụng nhất của SQLiteDatabase . Đóng/Tạo/Mở file cơ sở dữ liệu . Thực thi câu lệnh SQL . Làm việc với bản ghi: Tạo/Đọc/Xóa/Sửa . Duyệt kết quả trả về của truy vấn SELECT . Cách làm việc với SQLiteOpenHelper . Giới thiệu về content provider . Cách thức sử dụng content provider để khai thác các nguồn dữ liệu cung cấp bởi hệ thống hoặc nhà phát triển thứ 3 TRƯƠNG XUÂN NAM 2
  3. Nội dung 1. Broadcast Receiver 1. Vòng đời của boardcast receiver 2. Tự tạo một tín hiệu broadcast 3. Viết receiver xử lý tín hiệu broadcast 2. Telephony API 1. Làm việc với điện thoại 2. SMS • Gửi SMS • Nhận SMS • Đọc SMS 3. Tạo và nhận cuộc gọi TRƯƠNG XUÂN NAM 3
  4. Phần 1 Broadcast Receivers TRƯƠNG XUÂN NAM 4
  5. Broadcast Receiver . Broadcast receiver (gọi tắt là receiver): là một trong bốn loại thành phần cơ bản của ứng dụng android . Receiver là một class java nhận và xử lý các sự kiện mà hệ thống (hoặc ứng dụng nào đó) phát ra . VD: tín hiệu báo mất wifi, tín hiệu báo cuộc gọi đến, . Khi hệ thống phát đi sự kiện, có 2 cơ chế phát: . Không thứ tự: mọi receiver đủ điều kiện đều nhận được . Có thứ tự: receiver nào ưu tiên hơn thì nhận trước và có thể điều chỉnh thông tin tín hiệu đến các receiver sau • Cơ chế này khá giống xử lý ngắt (interrupt) trong HĐH TRƯƠNG XUÂN NAM 5
  6. Một số broadcast thông dụng . Báo hệ thống khởi động xong . Báo có package mới cài vào hoặc xóa đi . Báo tắt máy . Báo cắm sạc . Báo rút sạc . Thông báo cắm thẻ nhớ . Thông báo rút thẻ nhớ . Thông báo tin nhắn tới . Thông báo có cuộc gọi đi/đến TRƯƠNG XUÂN NAM 6
  7. Phần 2.1 Vòng đời của broadcast receiver TRƯƠNG XUÂN NAM 7
  8. Vòng đời của broadcast receiver 1. Khi ứng dụng được cài lên thiết bị: . Hệ thống đọc file AndroidManifest.xml để xem receiver đăng ký xử lý những sự kiện nào . Cho receiver vào danh sách các receiver cài trên thiết bị 2. Khi xảy ra sự kiện: . Hệ thống tạo một intent chứa thông tin về sự kiện . Gửi intent đó đến các receiver đăng ký xử lý sự kiện • Nếu sự kiện không thứ tự: gửi đồng loạt đến tất cả receiver • Nếu sự kiện có thứ tự: gửi lần lượt đến từng receiver . Khi intent được gửi đến receiver: hệ thống gọi hàm onReceive để xử lý intent đó TRƯƠNG XUÂN NAM 8
  9. Vòng đời của broadcast receiver . Broadcast receiver hoạt động vô cùng đơn giản . Chỉ cần viết duy nhất phương thức onReceive . Khi có sự kiện mà broadcast receiver đã đăng ký nhận được phát đi, thì phương thức onReceive của broadcast receiver đó sẽ được gọi . Sau khi thực thi xong phương thức này, lifecycle của receiver kết thúc . Trường hợp broadcast có thứ tự, ta có thể gọi hàm abortBroadcast trong khi onReceive đang chạy để ngăn không cho các receiver sau nhận broadcast TRƯƠNG XUÂN NAM 9
  10. Vòng đời của broadcast receiver . Ngay khi onReceive kết thúc, hệ thống coi như receiver đã không còn hoạt động và có thể hủy tiến trình chứa receiver này bất cứ lúc nào, vì thế: . Tránh xử lý các code quá lâu trong onReceive . Không có xử lý bất đồng bộ, chờ callback trong receiver (cụ thể như hiển thị Dialog, kết nối service ) . Nếu cứ cố dùng, hệ thống sẽ thông báo ứng dụng bị waiting quá lâu, có force close hay không, đây là lỗi nên tránh vì đa số người dùng sẽ chọn YES . Độ ưu tiên của receiver nên từ -1000 đến 1000 TRƯƠNG XUÂN NAM 10
  11. Phần 2.2 Tự tạo một tín hiệu broadcast TRƯƠNG XUÂN NAM 11
  12. Tự tạo một tín hiệu broadcast . Các tín hiệu broadcast thường do hệ thống sinh ra, nhưng LTV có thể tự tạo tín hiệu riêng 1. Tạo một intent chứa thông tin về tín hiệu 2. Yêu cầu hệ thống gửi broadcast phù hợp . Android có nhiều cơ chế phát tín hiệu khác nhau . Normal broadcast: gửi tín hiệu tới tất cả các receiver . Ordered broadcast: gửi lần lượt các broadcast, vào mỗi thời điểm chỉ gửi đến một receiver . Sticky broadcast: intent được giữ lại sau khi receiver xử lý xong (sử dụng trong một số tình huống ít gặp hơn, ví dụ như cảnh báo pin yếu) TRƯƠNG XUÂN NAM 12
  13. Ví dụ: gửi tín hiệu báo động đất // chuẩn bị một intent Intent intent = new Intent(NEW_EARTHQUAKE_FOUND); // nạp dữ liệu về broadcast vào intent intent.putExtra("date", "03/07/2016 07:00:00"); intent.putExtra("details", "London"); intent.putExtra("longitude", "-0.129098"); intent.putExtra("latitude", "51.535142"); intent.putExtra("magnitude", "3.0"); // chọn 1 trong 3 cách phát tín hiệu phù hợp sendBroadcast(intent); sendOrderedBroadcast(intent); sendStickyBroadcast(intent); TRƯƠNG XUÂN NAM 13
  14. Phần 2.3 Viết receiver xử lý tín hiệu broadcast TRƯƠNG XUÂN NAM 14
  15. Sử dụng BroadcastReceiver . Để đăng ký đối tượng receiver, có 2 cách: . Sử dụng Context.registerReceiver() để đăng ký và Context.unregisterReceiver() để hủy . Đăng ký trong file AndroidManifest.xml thông qua thẻ . Dùng cách thứ nhất nếu ta chỉ muốn chặn tín hiệu broadcast trong một khoảng thời gian nào đó . Ví dụ: khi chơi game, ta có thể chặn broadcast để biết có cuộc gọi đến hay không (để xử lý cho phù hợp) . Cách thứ hai sử dụng nếu muốn chặn tín hiệu broadcast bất kỳ khi nào nó được phát ra TRƯƠNG XUÂN NAM 15
  16. Ví dụ: viết ứng dụng auto start . Chọn sự kiện RECEIVE_BOOT_COMPLETED . Viết receiver tương ứng, trong onReceive chạy service ngầm hoặc khởi động activity . Chú ý: Nếu ứng dụng của bạn ở SD card, lúc này SD card chưa sẵn sàng, vì thế ứng dụng sẽ không chạy được, trường hợp này ta chọn sang sự kiện ACTION_EXTERNAL_APPLICATIONS_AVAILABLE . Một số điện thoại (HTC) không nhận sự kiện này . Từ Android 3.0, phải chạy ứng dụng ít nhất một lần thì ứng dụng mới nhận sự kiện này TRƯƠNG XUÂN NAM 16
  17. Ví dụ: viết ứng dụng auto start TRƯƠNG XUÂN NAM 17
  18. Ví dụ: viết ứng dụng auto start public class MyApp extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { // Trường hợp chạy activity Intent i = new Intent(context, MyActivity.class); i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); context.startActivity(i); // Trường hợp chạy service Intent service = new Intent(context, MyService.class); context.startService(service); } } TRƯƠNG XUÂN NAM 18
  19. Phần 2 Telephony API TRƯƠNG XUÂN NAM 19
  20. Phần 2.1 Làm việc với điện thoại TRƯƠNG XUÂN NAM 20
  21. Làm việc với điện thoại . Không phải thiết bị Android nào cũng có các tính năng thoại, nếu cần sử dùng một tính năng nào đó, ta cần thiết lập yêu cầu trong AndroidManifest.xml . Chú ý: khi thiết lập thuộc tính này thì ứng dụng sẽ không cài đặt được trên các thiết bị không có phần cứng hỗ trợ điện thoại TRƯƠNG XUÂN NAM 21
  22. Làm việc với điện thoại . Muốn đọc trạng thái phone, phải được cấp quyền . Android OS có service hệ thống để theo dõi trạng thái thoại, lấy service này bằng getSystemService . Dùng service này, ta có thể lấy thông tin của phone state, chẳng hạn như đọc số điện thoại gọi đến . Link API của TelephonyManager: elephony/TelephonyManager.html TRƯƠNG XUÂN NAM 22
  23. Ví dụ về TelephonyManager TRƯƠNG XUÂN NAM 23
  24. Làm việc với điện thoại . Việc lắng nghe các thay đổi trong trạng thái cuộc gọi giúp ứng dụng chúng ta có phù hợp với nhu cầu của người dùng. Ví dụ như: . Game có thể tự động tạm dừng và lưu thông tin trạng thái khi điện thoại đổ chuông để người dùng có thể trả lời cuộc gọi một cách an toàn . Ứng dụng chơi nhạc có thể vặn nhỏ hoặc tạm dừng âm thanh . Muốn tương tác tốt hơn, có thể chặn sự kiện CallStateChange của TelephonyManager và có cách xử lý phù hợp TRƯƠNG XUÂN NAM 24
  25. Xử lý PHONE_STATE_CHANGE TRƯƠNG XUÂN NAM 25
  26. Xử lý PHONE_STATE_CHANGE TRƯƠNG XUÂN NAM 26
  27. Phần 2.2 SMS TRƯƠNG XUÂN NAM 27
  28. SMS – Các quyền liên quan . Dịch vụ SMS khá đặc biệt vì liên quan tới chi phí và sự riêng tư, 3 quyền về SMS là Gửi, Nhận và Đọc . Chú ý: . Cấp quyền thì ứng dụng vẫn bị chặn nếu gửi nhiều SMS . Không cần quyền nếu sử dụng acvitity bên ngoài TRƯƠNG XUÂN NAM 28
  29. Gửi SMS – API . Muốn gửi SMS cần phải có ít nhất 1 đối tượng SmsManager SmsManager sms = SmsManager.getDefault(); . Các API gửi message . sendTextMessage . sendDataMessage Delivery Pending Intent . sendMultipartTextMessage Send Pending Intent sms.sendTextMessage( "0912102165", null, "Hello!", null, null); TRƯƠNG XUÂN NAM 29
  30. Gửi SMS – example TRƯƠNG XUÂN NAM 30
  31. Nhận SMS – Thiết lập Receiver . Để nhận SMS, sử dụng BroadcastReceiver để nhận thông báo có tin nhắn từ hệ thống . Gói dữ liệu mà receiver nhận được là dãy byte được mã hóa theo chuẩn SMS PDU, Android có những class hữu ích giúp làm việc với chuẩn này . Từ Android 1.6, broadcast SMS là loại ordered, vì thế có thể dùng abortBroadcast() để ngăn không cho SMS gửi tiếp tới các receiver khác Đăng kí receiver trong AndroidManifest.xml TRƯƠNG XUÂN NAM 31
  32. Nhận SMS – example TRƯƠNG XUÂN NAM 32
  33. Nhận SMS – PDU encode TRƯƠNG XUÂN NAM 33
  34. Đọc SMS . Android OS cung cấp dữ liệu về SMS nhận được bằng ContentProvider “content://sms/inbox” . Sử dụng ContentProvider để lấy dữ liệu, đọc SMS từ Cursor cần nắm được cấu trúc bảng SMS . Có thể “vọc” bằng cách lấy DB ra xem thử, trong DB có các bảng lưu dữ liệu (ví dụ bảng sms), vị trí DB: “//data/data/com.android.provider.telephony/datab ases/mmssms.db” TRƯƠNG XUÂN NAM 34
  35. Đọc SMS – example TRƯƠNG XUÂN NAM 35
  36. Phần 2.3 Tạo và nhận cuộc gọi TRƯƠNG XUÂN NAM 36
  37. Tạo Cuộc Gọi . Trong thiết kế của Android OS, cuộc gọi không thể thực hiện ở background và bắt buộc phải thông qua call activity . Cuộc gọi trong Android có thể theo 2 cách . Gọi gián tiếp: hiện call activity điền sẵn dữ liệu, người dùng phải bấm Send để thực hiện cuộc gọi . Gọi trực tiếp: hiện call activity và quay số luôn, người dùng có thể hủy cuộc gọi nếu muốn . Sự khác nhau: ứng dụng muốn gọi trực tiếp phải được cấp quyền android.permission.CALL_PHONE, gọi gián tiếp thì không cần quyền TRƯƠNG XUÂN NAM 37
  38. Tạo Cuộc Gọi – example . Gọi gián tiếp: Uri number = Uri.parse("tel:0912102165"); Intent dial = new Intent(Intent.ACTION_DIAL, number); startActivity(dial); . Gọi trực tiếp: Uri number = Uri.parse("tel:01699362020"); Intent call = new Intent(Intent. ACTION_CALL, number); startActivity(call); TRƯƠNG XUÂN NAM 38
  39. Nhận Cuộc Gọi . Tương tự như với SMS, để nhận cuộc gọi đến ứng dụng phải được cài đặt với BroadcastReceiver . Cần thiết lập quyền READ_PHONE_STATE và đặt receiver phù hợp TRƯƠNG XUÂN NAM 39
  40. Nhận Cuộc Gọi – example TRƯƠNG XUÂN NAM 40