Bài giảng Lập trình di động - Bài 7: SQLite và Content Provider - Trương Xuân Nam

pdf 42 trang ngocly 3430
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 7: SQLite và Content Provider - 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_7_sqlite_va_content_provider.pdf

Nội dung text: Bài giảng Lập trình di động - Bài 7: SQLite và Content Provider - Trương Xuân Nam

  1. LẬP TRÌNH DI ĐỘNG Bài 7: SQLite và Content Provider
  2. Nhắc lại bài trước . Nguyên tắc lưu trữ trong android: theo phân quyền của Linux, hỗ trợ nhiều loại lưu trữ với mục đích khác nhau . MODE_PRIVATE, MODE_WORLD_READABLE và MODE_WORLD_WRITEABLE . Các vùng lưu trữ được cấp cho ứng dụng . Shared preferences và PreferenceActivity . Các loại lưu trữ: internal, external, cached và trong file apk của ứng dụng . Làm việc với SQLite TRƯƠNG XUÂN NAM 2
  3. Nội dung 1. Làm việc với SQLite API . Tạo/Mở/Đóng CSDL . Thực thi câu lệnh SQL . CRDU . Duyệt các kết quả trả về bởi SELECT 2. SQLiteOpenHelper 3. Kinh nghiệm làm việc với CSDL 4. Content Providers . Giới thiệu . (tự học) Sử dụng content providers . (tự học) Tự viết content provider TRƯƠNG XUÂN NAM 3
  4. Phần 1 Làm việc với SQLite API TRƯƠNG XUÂN NAM 4
  5. SQLiteDatabase – Tạo/Mở CSDL public static SQLiteDatabase openDatabase(String path, CursorFactory factory, int flags) SQLiteDatabase db = SQLiteDatabase.openDatabase("/data/data/ /DB.db",null, SQLiteDatabase.CREATE_IF_NECESSARY); Flags: OPEN_READWRITE, OPEN_READONLY và CREATE_IF_NECESSARY TRƯƠNG XUÂN NAM 5
  6. SQLiteDatabase – Tạo/Mở CSDL TRƯƠNG XUÂN NAM 6
  7. SQLiteDatabase – Đóng CSDL public void close() . Sử dụng khi đóng kết nối với CSDL . CSDL tự đóng khi ứng dụng kết thúc . Nên đóng CSDL ngay khi không dùng nữa db = SQLiteDatabase.openDatabase( ); // thao tác với CSDL db.close(); TRƯƠNG XUÂN NAM 7
  8. SQLiteDatabase – Thực thi SQL . Sử dụng khi muốn thực thi một câu lệnh SQL và không quan tâm tới kết quả trả về . Không thực hiện được “multiple statements” SQL . Tài liệu của Google nói không thực hiện những câu SQL có trả về kết quả (SELECT, INSERT, UPDATE, ) db.execSQL("CREATE TABLE Book (BookID INTEGER PRIMARY KEY AUTOINCREMENT, BookName TEXT);"); db.execSQL("INSERT INTO Book(BookName) VALUES ('Test EXECSQL')"); TRƯƠNG XUÂN NAM 8
  9. SQLiteDatabase – Chèn public long insert(String table, String nullColumnHack, ContentValues values) . "table": tên bảng muốn insert dữ liệu . "nullColumnHack": tên cột nào đó nhận giá trị NULL (dùng trong trường hợp values = null) . "values": danh sách các cặp - sẽ chèn vào dòng mới . Chú ý: hàm trả về giá trị row ID của dòng vừa chèn vào, nếu không thành công sẽ trả về -1 TRƯƠNG XUÂN NAM 9
  10. SQLiteDatabase – Chèn ContentValues cv = new ContentValues(); cv.put("BookName", "SQLite"); cv.put("Price", "100"); db.insert("Book", null, cv); TRƯƠNG XUÂN NAM 10
  11. SQLiteDatabase – Cập nhật public int update(String table, ContentValues values, String whereClause, String[] whereArgs) . table: tên bảng muốn update . values: các cặp key/value – tên cột/giá trị mới muốn cập nhật . whereClause: điều kiện để dòng được chọn . whereArgs: mảng các giá trị ứng với whereClause . Giá trị trả về: số bản ghi được cập nhật TRƯƠNG XUÂN NAM 11
  12. SQLiteDatabase – Cập nhật String [] whereArgs = {"2"}; ContentValues updValues = new ContentValues(); updValues.put("BookName", "ANDROID"); updValues.put("Price", "200"); int recAffected = db.update("Book", updValues, "BookID=?", whereArgs); TRƯƠNG XUÂN NAM 12
  13. SQLiteDatabase - Xóa public int delete(String table, String whereClause, String[] whereArgs) . table: tên bảng muốn xóa . whereClause: điều kiện xóa . whereArgs: mảng giá trị ứng với whereClause String [] whereArgs = {"2"}; int recAffected = db.delete("Book", "BookID=?", whereArgs); // db.delete("Book", "BookID=2", null); TRƯƠNG XUÂN NAM 13
  14. SQLiteDatabase - SELECT public Cursor rawQuery(String sql, String[] selectionArgs) . sql: câu lệnh truy vấn . selectionArgs: mảng giá trị các tham số trong câu lệnh sql (nếu có) . Giá trị trả về: con trỏ đặc biệt hỗ trợ việc lấy dữ liệu và duyệt mảng các giá trị trả về TRƯƠNG XUÂN NAM 14
  15. SQLiteDatabase - SELECT // dạng đơn giản Cursor c = db.rawQuery("SELECT * FROM Book", null); // dạng có tham số String mySQL = "select count(*) as Total " + " from tblAmigo " + " where recID > ? " + " and name = ?"; String[] args = {"1", "BBB"}; Cursor c1 = db.rawQuery(mySQL, args); TRƯƠNG XUÂN NAM 15
  16. SQLiteDatabase - Cursor . Cursor trỏ tới 1 dòng trong kết quả trả về . Dùng cursor để đọc giá trị trên các cột của dòng đó . Khởi đầu cursor ở vị trí before-first . Cursor có nhiều phương thức hỗ trợ: . Kiểm tra vị trí hiện tại: isFirst(), isLast(), isBeforeFirst(), isAfterLast() . Dịch chuyển trong kết quả: moveToFirst(), moveToLast(), moveToNext(), moveToPrevious(), move(n) . Lấy dữ liệu: getInt, getString, getFloat, getBlob, getDate, . Lấy cấu trúc bảng: getCount, getColumnName, getColumnNames, getColumnIndex, getColumnCount, TRƯƠNG XUÂN NAM 16
  17. Mã chung khi sử dụng cursor // thực hiện truy vấn bằng SELECT, kết quả luôn là 1 mảng // lúc này cs trỏ tới trước dòng đầu tiên Cursor cs = db.rawQuery("SELECT * FROM Book", null); // dịch chuyển xuống dòng dưới while (cs.moveToNext()) { // đọc dữ liệu ở cột đầu tiên int id = cs.getInt(0); // đọc dữ liệu ở cột thứ hai String book = cs.getString(1); } // đóng kết quả truy vấn cs.close(); TRƯƠNG XUÂN NAM 17
  18. Phần 2 SQLiteOpenHelper TRƯƠNG XUÂN NAM 18
  19. SQLiteOpenHelper . SQLiteOpenHelper là phương pháp mà Google đề nghị để thống nhất việc quản lý, tạo, truy xuất và cập nhật cơ sở dữ liệu . SQLiteOpenHelper cần 3 phương thức cơ bản sau để làm việc hiệu quả . Constructor: cung cấp các tham số cần thiết để làm việc với cơ sở dữ liệu . onCreate(): phương thức được tự động gọi khi lần đầu tạo file CSDL và tạo các bảng trong CSDL cũng như khởi tạo dữ liệu ban đầu . onUpgrade(): phương thức được tự động gọi khi nâng cấp CSDL từ các phiên bản cũ TRƯƠNG XUÂN NAM 19
  20. SQLiteOpenHelper . Các phương thức hữu ích của SQLiteOpenHelper . SQLiteDatabase getReadableDatabase(): lấy về CSDL ở dạng “chỉ đọc” . SQLiteDatabase getWriteableDatabase(): lấy về CSDL ở dạng “đọc và ghi” . String getDatabaseName(): lấy tên CSDL . Không dùng SQLiteOpenHelper cũng không có vấn đề gì, nhưng sử dụng SQLiteOpenHelper thì ta sẽ đỡ công sức viết code hơn, đặc biệt khi cập nhật phiên bản ứng dụng kèm theo nâng cấp CSDL TRƯƠNG XUÂN NAM 20
  21. SQLiteOpenHelper . Code: kế thừa SQLiteOpenHelper và viết lại 3 phương thức cơ bản . Cách thức sử dụng SQLiteOpenHelper: . Thay vì mở CSDL trực tiếp, ta mở qua SQLiteOpenHelper . SQLiteOpenHelper kiểm tra xem CSDL đã có hay chưa, nếu chưa có thì sẽ tự động gọi onCreate để tạo . SQLiteOpenHelper kiểm tra phiên bản của CSDL hiện tại so với đề xuất có bằng nhau không, nếu không thì tự động gọi onUpgrade (hoặc onDowngrade, tùy tình huống) . LTV dùng getReadableDatabase / getWriteableDatabase để lấy về CSDL đã sẵn sàng hoạt động TRƯƠNG XUÂN NAM 21
  22. SQLiteOpenHelper - Sample TRƯƠNG XUÂN NAM 22
  23. SQLiteOpenHelper - Sample TRƯƠNG XUÂN NAM 23
  24. SQLiteOpenHelper - Sample TRƯƠNG XUÂN NAM 24
  25. Phần 3 Kinh nghiệm làm việc với CSDL TRƯƠNG XUÂN NAM 25
  26. Kinh nghiệm làm việc với CSDL . Viết class mô tả đối tượng cần thao tác (không liên quan gì tới database), tạm gọi là các model . Dùng SQLiteOpenHelper xử lý ở cấp độ database . Viết class bọc ngoài các table, cung cấp các thao tác làm việc giữa tables với model (data provider) . Sử dụng các data provider để làm việc bất kể khi nào dùng tới database, không trực tiếp làm việc với database trong mọi trường hợp . Các string SQL nên đặt ngoài resource hoặc có thể cập nhật online là tốt nhất TRƯƠNG XUÂN NAM 26
  27. Thực Hành . Xây dựng ứng dụng quản lý sách với CSDL Books trong bài học trước . Ứng dụng gồm các chức năng chính: . Thêm sách mới . Hiển thị danh sách các sách ra ListView . Sửa sách . Xóa sách . Tìm kiếm sách theo các trường hoặc theo các tiêu chuẩn . Upgrade lên DB lên phiên bản 2: bổ sung trường tags gồm danh sách các từ khóa mô tả về sách . Cập nhật chức năng tìm kiếm theo tags TRƯƠNG XUÂN NAM 27
  28. Phần 4 Content providers TRƯƠNG XUÂN NAM 28
  29. Content Providers . Là thành phần cơ bản của Android OS . Chuẩn chia sẻ dữ liệu cho các ứng dụng khác trên Android . Content Providers (thường gọi tắt là providers) là cách thức để chia sẻ dữ liệu . Không phải là nơi chứa dữ liệu . Nhiều dữ liệu hệ thống cung cấp providers để có thể truy xuất đến chúng như: Calendar, Contact, CallLog, MediaStore, . Ứng dụng của bên thứ 3 có thể tự viết provider để cung cấp dữ liệu cho các ứng dụng khác TRƯƠNG XUÂN NAM 29
  30. Content Providers . Content Providers cung cấp một đối tượng con trỏ (cursor) có thể dễ dàng lấy được bất cứ dữ liệu lưu trữ nào thông qua URI chính xác dữ liệu đó . URI: là quy tắc mô tả một đối tượng (bản thân các giao thức http, ftp, email, skype, torrent, cũng dùng URI để làm việc) URI TRƯƠNG XUÂN NAM 30
  31. Cấu trúc URI của providers . Phần A: chỉ ra URI được điều khiển bởi providers (luôn có dạng content://) . Phần B: chỉ đến nơi lưu trữ dữ liệu, là tên package + class cung cấp content . Phần C: chỉ ra loại dữ liệu. Chẳng hạn như dữ liệu contact, dữ liệu SMS, thường cũng là tên của một table trong CSDL của provider (không nhất thiết) . Phần D: tham số để thao tác dữ liệu, có thể coi phần này như là ID của row trong table hoặc một dữ liệu nào đó dùng để truy vấn TRƯƠNG XUÂN NAM 31
  32. Sử dụng providers . Phương thức getContentResolver() của context cho phép làm việc với với các provider . getContentResolver() trả về đối tượng ContentResolver . getContentResolver().query(Uri uri) trả về đối tượng Cursor . Android cung cấp sẵn nhiều providers về hệ thống . Tập hợp này nằm trong package android.provider . Cần khai báo permission trong AndroidManifest.xml trước khi muốn truy xuất đến những tài nguyên . Sử dụng CursorLoader trong tình huống truy vấn kéo dài TRƯƠNG XUÂN NAM 32
  33. Ví dụ . Bài tập: viết ứng dụng đọc contacts trong thiết bị . Kiến thức: . URI: “content://com.android.contacts/contacts/” . Hoặc hằng số: ContactsContract.Contacts.CONTENT_URI . Cách truy vấn thường: Cursor c = getContentResolver().query(uri, null, null, null, null); . Nếu provider hoạt động quá lâu, truy vấn ở background: CursorLoader loader = new CursorLoader(context, uri, null, null, null, null); Cursor c = loader.loadInBackground(); TRƯƠNG XUÂN NAM 33
  34. Đọc contacts – thiết lập quyền TRƯƠNG XUÂN NAM 34
  35. Đọc contacts – layout TRƯƠNG XUÂN NAM 35
  36. Đọc contacts – layout TRƯƠNG XUÂN NAM 36
  37. Xây dựng Content Providers . Lý do: khi chúng ta muốn chia sẻ dữ liệu của ứng dụng cho các ứng dụng khác (đặc biệt với các ứng dụng từ cùng một nhà phát triển) . Tạo class thừa kế lớp ContentProvider . Viết lại các phương thức: . onCreate() . query() . Các phương thức insert, delete, update (nếu cần) . Định nghĩa URI cho Content Provider trong AndroidManifest.xml TRƯƠNG XUÂN NAM 37
  38. Viết lớp kế thừa ContentProvider TRƯƠNG XUÂN NAM 38
  39. Viết lớp kế thừa ContentProvider TRƯƠNG XUÂN NAM 39
  40. Viết lớp kế thừa ContentProvider TRƯƠNG XUÂN NAM 40
  41. Đăng kí ở AndroidManifest.xml TRƯƠNG XUÂN NAM 41
  42. Khai thác provider mới TRƯƠNG XUÂN NAM 42