Bài giảng Android nâng cao - Bài 3: Telephony + Media Services
Bạn đang xem 20 trang mẫu của tài liệu "Bài giảng Android nâng cao - Bài 3: Telephony + Media Services", để 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:
- bai_giang_android_nang_cao_bai_3_telephony_media_services.pdf
Nội dung text: Bài giảng Android nâng cao - Bài 3: Telephony + Media Services
- M o b i P r o ANDROID NÂNG CAO BÀI 3: Telephony + Media Services
- M o b i P r o Nội dung 1. 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 2. Media Services (part I) 1. Media API 2. MediaStore 3. Audio TRƯƠNG XUÂN NAM 2
- M o b i P r o Phần 1.1 Làm việc với điện thoại TRƯƠNG XUÂN NAM 3
- M o b i P r o 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 4
- M o b i P r o 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: hony/TelephonyManager.html TRƯƠNG XUÂN NAM 5
- M o b i P r o Ví dụ về TelephonyManager TRƯƠNG XUÂN NAM 6
- M o b i P r o 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 7
- M o b i P r o Xử lý PHONE_STATE_CHANGE TRƯƠNG XUÂN NAM 8
- M o b i P r o Xử lý PHONE_STATE_CHANGE TRƯƠNG XUÂN NAM 9
- M o b i P r o Phần 1.2 SMS TRƯƠNG XUÂN NAM 10
- M o b i P r o 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ụngvẫn bị chặn nếu gửi nhiều SMS – Không cần quyền nếu sử dụngacvitity bên ngoài TRƯƠNG XUÂN NAM 11
- M o b i P r o 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 – sendMultipartTextMessage Delivery Pending Intent Send Pending Intent sms.sendTextMessage( "0912102165", null, "Hello!", null, null); TRƯƠNG XUÂN NAM 12
- M o b i P r o Gửi SMS – example TRƯƠNG XUÂN NAM 13
- M o b i P r o 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 14
- M o b i P r o Nhận SMS – example TRƯƠNG XUÂN NAM 15
- M o b i P r o Nhận SMS – PDU encode TRƯƠNG XUÂN NAM 16
- M o b i P r o Đọc SMS . Android OS cung cấp dữ liệu về SMS nhận được bằng ContentProvider “content://sms/inbox” – Sử dụngContentProvider để 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/dat abases/mmssms.db” TRƯƠNG XUÂN NAM 17
- M o b i P r o Đọc SMS – example TRƯƠNG XUÂN NAM 18
- M o b i P r o Phần 1.3 Tạo và nhận cuộc gọi TRƯƠNG XUÂN NAM 19
- M o b i P r o 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 20
- M o b i P r o 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 21
- M o b i P r o 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 22
- M o b i P r o Nhận Cuộc Gọi – example TRƯƠNG XUÂN NAM 23
- M o b i P r o Phần 2 Media Services (part I) TRƯƠNG XUÂN NAM 24
- M o b i P r o Media Services 1. Media API 2. MediaStore 3. Audio 4. Video 5. TTS 6. Camera TRƯƠNG XUÂN NAM 25
- M o b i P r o Phần 2.1 Media API TRƯƠNG XUÂN NAM 26
- M o b i P r o Media API . Android cung cấp tập hợp hỗ trợ media khá phong phú gồm cả âm thanh, hình ảnh và video . Chia làm 2 nhóm recorder và playback . Các lớp thư viện này đều dễ dàng sử dụng trong phát triển ứng dụng và hoàn toàn miễn phí (rất quan trọng) TRƯƠNG XUÂN NAM 27
- M o b i P r o Media API . Các tệp tin media có thể được sử dụng – thao tác bằng những cách sau: – Các tệp tin media được lưu trữ bên ngay bên trong ứng dụng (các file resources) – Các file media độc lập có trong bộ nhớ trong của máy hoặc trong thẻ nhớ SDCARD – Các tài nguyên trên mạng TRƯƠNG XUÂN NAM 28
- M o b i P r o Phần 2.2 MediaStore TRƯƠNG XUÂN NAM 29
- M o b i P r o MediaStore . Android OS có provider chuẩn chứa thông tin về các file media trong thiết bị . Các ứng dụng tạo media (chụp ảnh, quay video) nên chủ động thêm các file media vào provider này MediaStore.Audio MediaStore.Images MediaStore.Video TRƯƠNG XUÂN NAM 30
- M o b i P r o MediaStore Có thể xem cấu trúc của MediaStore bằng cách xem file CSDL sau /data/data/com.android.providers.media/databases/internal.db // Trường hợp muốn mở các file video thì dùng Uri: // android.provider.MediaStore.Video.Media.EXTERNAL_CONTENT_URI Uri p = android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI; Intent myIntent = new Intent(Intent.ACTION_VIEW, p); startActivity(myIntent); // Trường hợp muốn mở để chọn media thì sử dụng ACTION_PICK Uri x = android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI; Intent myIntent = new Intent(Intent.ACTION_PICK, x); startActivityForResult(myIntent); TRƯƠNG XUÂN NAM 31
- M o b i P r o Phần 2.3 Audio TRƯƠNG XUÂN NAM 32
- M o b i P r o MediaPlayer & MediaRecorder . Lớp MediaPlayer hỗ trợ việc playback các file audio và video . Lớp MediaRecorder hỗ trợ việc ghi âm (ghi hình) và chuyển thành các file audio (video) – Chú ý: việc record phụ thuộc và việc phần cứng được hỗ trợ hay không . Android OS chưa có cơ chế cài đặt thêm các codec mới cho audio và video, trường hợp ứng dụng muốn chạy format mới thì cần tự làm việc với i/o stream, surface view và audio stream TRƯƠNG XUÂN NAM 33
- M o b i P r o MediaPlayer . Được sử dụng cho việc playback audio/video file và stream . MediaPlayer hiểu cả các giao thức video internet . Có thể xem các protocol được hỗ trợ bởi MediaPlayer m/guide/appendix/media- formats.html TRƯƠNG XUÂN NAM 34
- M o b i P r o MediaPlayer – Useful Methods PublicMethods create(Context context,Uri uri) static Convenience method to create a MediaPlayer for a MediaPlayer given Uri. create(Context context,int resid) static Convenience method to create a Media Player for a MediaPlayer given resource id. boolean isPlaying() Checks whether the Media Player is playing. void pause() Pauses play back. void prepare() Prepares the player for play back ,synchronously. TRƯƠNG XUÂN NAM 35
- M o b i P r o MediaPlayer – Useful Methods PublicMethods void setLooping(boolean looping) Sets the player to be looping or non-looping. void setVolume(float leftVolume,float rightVolume) Sets the volume on this player. void start() Starts or resumes play back. void stop() Stops play back after playback has been stopped or paused. TRƯƠNG XUÂN NAM 36
- M o b i P r o Chơi audio từ resource . Tạo một file nhạc trong thư mục res/raw của dự án . Khởi tạo đối tượng MediaPlayer thông qua hàm static create, prepare để khởi tạo các thông số cần thiết và bắt đầu chơi nhạc bằng phương thức start . Gọi phương thức stop() để dừng lại . Tạm dừng sử dụng phương thức pause() . Chú ý: trong thử nghiệm thì chạy file từ resource không cần gọi prepare MediaPlayer mp = MediaPlayer.create(context, R.raw.sound_1); mp.prepare(); mp.start(); TRƯƠNG XUÂN NAM 37
- M o b i P r o MediaPlayer – example TRƯƠNG XUÂN NAM 38
- M o b i P r o MediaPlayer – example public class MyPlayer extends Activity { MediaPlayer mp = null; public void onCreate(Bundle icicle) { super.onCreate(icicle); setContentView(R.layout.main); } // xử lý button STOP public void btnStop(View v) { if (null == mp) return; if (mp.isPlaying()) { mp.stop(); mp = null; } } TRƯƠNG XUÂN NAM 39
- M o b i P r o MediaPlayer – example // xử lý button PLAY public void btnPlay(View v) { try { mp = MediaPlayer.create(MyPlayer.this, R.raw.kiss_the_rain); mp.start(); mp.setOnCompletionListener(new OnCompletionListener() { public void onCompletion(MediaPlayer arg0) { // xử lý khi đã chơi xong } }); } catch (Exception e) { } } } TRƯƠNG XUÂN NAM 40
- M o b i P r o Chơi audio từ File/Stream . Khởi tạo MediaPlayer thông qua hàm khởi tạo . Gọi phương thức setDataSource(string url) với url là địa chỉ file hay đường dẫn trên internet . Gọi phương thức prepare() để khởi tạo codec phù hợp . Gọi phương thức start() để bắt đầu chơi . Khi muốn tạm dừng hay dừng hẳn gọi các phương thức pause() hay stop() TRƯƠNG XUÂN NAM 41
- M o b i P r o MediaPlayer – example TRƯƠNG XUÂN NAM 42
- M o b i P r o Một số chú ý khi playback . MediaPlayer cần được reset hoặc release rồi mới được chơi lại nếu trước đó bạn stop . MediaPlayer chạy ngầm, vì thế nếu bạn đóng activity (finish) thì audio vẫn chạy ngầm (và không có cách nào dừng nó), vì thế nên dùng System.exit để kết thúc ứng dụng . Có thể chơi cùng lúc nhiều MediaPlayer và có thể thiết lập các mức volume khác nhau cũng như các nguồn ra khác nhau cho từng MediaPlayer (ví dụ chơi 2 file audio và mỗi file đổ âm thanh ra một phía của tai nghe) TRƯƠNG XUÂN NAM 43
- M o b i P r o Một số chú ý khi playback . Muốn ứng dụng chạy ngầm và sau khi ứng dụng quay trở lại vẫn tiếp tục điều khiển được Audio cũ, ta nên sử dụng service . Muốn tương tác với phím điều khiển âm lượng: – Đăng kí broadcast receiver: android.intent.action.MEDIA_BUTTON – Điều chỉnh âm thanh bằng phương thức setVolume(left, right), trong đó giá trị left/right là số thực nằm trong khoảng từ 0.0f đến 1.0f . Sử dụng AudioManager trong trường hợp muốn tương tác nhiều hơn với phần cứng audio TRƯƠNG XUÂN NAM 44
- M o b i P r o Audio Recording . Để ghi âm, sử dụng MediaRecorder 1. Khởi tạo đối tượng recorder thông qua hàm khởi tạo 2. Khởi tạo đối tượng android.content.ContentValues, truyền các giá trị TITLE, TIMESTAMP và MIME_TYPE để lưu trữ 3. Tạo đường dẫn đến file lưu trữ 4. Thiết lập audio source với MediaRecorder.setAudioSource() hoặc MediaRecorder.setAudioSource.MIC TRƯƠNG XUÂN NAM 45
- M o b i P r o Audio Recording 5. Cấu hình kiểu format MediaRecorder.setOutputFormat() 6. Kiểu mã hóa MediaRecorder.setAudioEncoder() 7. Gọi phương thức prepare() để chuẩn bị 8. Bắt đầu ghi âm với phương thức start() và dừng với stop() 9. Khi kết thúc gọi release() để giải phóng bộ nhớ TRƯƠNG XUÂN NAM 46
- M o b i P r o Audio Recording TRƯƠNG XUÂN NAM 47
- M o b i P r o Audio Recording – example TRƯƠNG XUÂN NAM 48
- M o b i P r o Audio Recording – example public class MyAudioRecorder extends Activity { MediaRecorder myRecorder; File mSampleFile = null; TextView txtMsg; static final String SAMPLE_PREFIX = "Recording"; static final String SAMPLE_EXTENSION = ".mp3"; private static final String TAG = " >"; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); txtMsg = (TextView)findViewById(R.id.txtMsg); myRecorder = new MediaRecorder(); TRƯƠNG XUÂN NAM 49
- M o b i P r o Audio Recording – example Button start = (Button) findViewById(R.id.startRecording); start.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { startRecording(); } }); Button stop = (Button) findViewById(R.id.stopRecording); stop.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { stopRecording(); addToMediaStoreDB(); } }); TRƯƠNG XUÂN NAM 50
- M o b i P r o Audio Recording – example Button play = (Button) findViewById(R.id.playRecording); play.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { try { String name = mSampleFile.getAbsolutePath(); txtMsg.setText("Now playing:\n " + name); MediaPlayer mp = new MediaPlayer(); mp.setDataSource( recordingName ); mp.prepare(); mp.start(); } catch (Exception e) {} } } } // onCreate TRƯƠNG XUÂN NAM 51
- M o b i P r o Audio Recording – example protected void startRecording() { try { if (this.mSampleFile == null) { File dir = Environment.getExternalStorageDirectory(); try { this.mSampleFile = File.createTempFile( MyAudioRecorder.SAMPLE_PREFIX, MyAudioRecorder.SAMPLE_EXTENSION, dir); } catch (IOException e) { return; } } txtMsg.setText("Recording: \n" + mSampleFile.getCanonicalPath()); TRƯƠNG XUÂN NAM 52
- M o b i P r o Audio Recording – example myRecorder = new MediaRecorder(); myRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); myRecorder.setOutputFormat(MediaRecorder.OutputFormat. THREE_GPP); myRecorder.setAudioEncoder(MediaRecorder.AudioEncoder. AMR_NB); myRecorder.setOutputFile(this.mSampleFile. getAbsolutePath()); myRecorder.prepare(); myRecorder.start(); } catch (Exception e) { } } // startRecording TRƯƠNG XUÂN NAM 53
- M o b i P r o Audio Recording – example protected void stopRecording() { try { myRecorder.stop(); myRecorder.release(); } catch (IllegalStateException e) {} } protected void addToMediaStoreDB() { try { int now = (int) (System.currentTimeMillis() / 1000); ContentValues newValues = new ContentValues(6); newValues.put(MediaColumns.TITLE, mSampleFile.getName()); newValues.put(MediaColumns.DATE_ADDED, now); TRƯƠNG XUÂN NAM 54
- M o b i P r o Audio Recording – example newValues.put(MediaColumns.MIME_TYPE, "audio/mpeg"); newValues.put(AudioColumns.IS_MUSIC, true); newValues.put(AudioColumns.ARTIST, "myself"); newValues.put(MediaColumns.DATA, mSampleFile.getAbsolutePath()); ContentResolver contentResolver = getContentResolver(); Uri base = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI; Uri nUri = contentResolver.insert(base, newValues); sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, nUri)); } catch (Exception e) { } } // addToMediaStoreDB TRƯƠNG XUÂN NAM 55