Your SlideShare is downloading. ×
0
Android Nâng cao-Bài 4: Content Provider
Android Nâng cao-Bài 4: Content Provider
Android Nâng cao-Bài 4: Content Provider
Android Nâng cao-Bài 4: Content Provider
Android Nâng cao-Bài 4: Content Provider
Android Nâng cao-Bài 4: Content Provider
Android Nâng cao-Bài 4: Content Provider
Android Nâng cao-Bài 4: Content Provider
Android Nâng cao-Bài 4: Content Provider
Android Nâng cao-Bài 4: Content Provider
Android Nâng cao-Bài 4: Content Provider
Android Nâng cao-Bài 4: Content Provider
Android Nâng cao-Bài 4: Content Provider
Android Nâng cao-Bài 4: Content Provider
Android Nâng cao-Bài 4: Content Provider
Android Nâng cao-Bài 4: Content Provider
Android Nâng cao-Bài 4: Content Provider
Android Nâng cao-Bài 4: Content Provider
Android Nâng cao-Bài 4: Content Provider
Android Nâng cao-Bài 4: Content Provider
Android Nâng cao-Bài 4: Content Provider
Android Nâng cao-Bài 4: Content Provider
Android Nâng cao-Bài 4: Content Provider
Android Nâng cao-Bài 4: Content Provider
Android Nâng cao-Bài 4: Content Provider
Android Nâng cao-Bài 4: Content Provider
Android Nâng cao-Bài 4: Content Provider
Android Nâng cao-Bài 4: Content Provider
Android Nâng cao-Bài 4: Content Provider
Android Nâng cao-Bài 4: Content Provider
Android Nâng cao-Bài 4: Content Provider
Android Nâng cao-Bài 4: Content Provider
Android Nâng cao-Bài 4: Content Provider
Android Nâng cao-Bài 4: Content Provider
Android Nâng cao-Bài 4: Content Provider
Android Nâng cao-Bài 4: Content Provider
Android Nâng cao-Bài 4: Content Provider
Android Nâng cao-Bài 4: Content Provider
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

Android Nâng cao-Bài 4: Content Provider

3,199

Published on

Khoá học: Android Nâng cao (9 bài) …

Khoá học: Android Nâng cao (9 bài)
Bài học: Content Provider

Published in: Technology
0 Comments
10 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
3,199
On Slideshare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
0
Comments
0
Likes
10
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  1. 1 ANDROID NÂNG CAO Bài 4: Content Provider
  2. 2 Nội dung bài học ● SQLite & Android. ● Content Provider. ● System Preferences (*)
  3. 3 SQLite & Android ● Giới thiệu về SQLite. ● SQLite trong Android. ● Android SQLite API. ● Ví dụ. ● Truy xuất CSDL qua shell1. 1 Xem ở bài 6:”Multi theme, adb tool and JUnit”
  4. 4 Giới thiệu về SQLite ● SQLite là một thư viện hiện thực SQL Database Engine với các đặc điểm sau: ● Selft-contained → Phụ thuộc rất rất ít thư viện khác hay OS. ● Serverless → Không cần server. ● Zero-configuration → Không cần cài đặt, cấu hình. ● Transactional → ACID (Atomic, Consistent, Isolated, Durable) ● Mã nguồn của SQLite được công bố ở “public domain”. ● Hỗ trợ các kiểu dữ liệu TEXT, INTEGER, REAL ● ● ● Các kiểu dữ liệu khác phải chuyển sang 3 kiểu dữ liệu trên trước khi ghi vào cơ sở dữ liệu. SQLite không kiểm tra kiểu dữ liệu khi ghi. SQLite hỗ trợ ANSI SQL92. Tham khảo thêm thông tin tại: http://www.sqlite.org
  5. 5 SQLite & Android ● ● ● ● SQLite được phân phối cùng với Android. Để sử dụng SQLite chúng ta không cần cài đặt hay cấu hình thêm bất cứ điều gì. Sử dụng câu lệnh DDL để tạo cơ sở dữ liệu trong mã nguồn. Truy xuất cơ sở dữ liệu SQLite tức là truy xuất file. Để tránh block UI thread cần sử dụng các kỹ thuật “Background processing”. Mặc định tập tin cơ sở dữ liệu tạo ra tại: DATA/data/APP_NAME/databases/FILENAME ● DATA là đường dẫn Environment.getDataDirectory() ● APP_NAME tên của ứng dụng. ● FILENAME tên của cơ sở dữ liệu, chỉ định trong khi tạo cơ sở dữ liệu.
  6. 6 Android SQLite API ● Package: ● ● ● android.database → Các interface/class làm việc với database. android.database.sqlite → Các interface/class làm việc với SQLite. Class: ● SQLiteOpenHelper → Tạo/Nâng cấp cơ sở dữ liệu. ● SQLiteDatabase → Base class để làm việc với CSDL. ● SQLiteQueryBuilder → Tạo câu truy vấn SQL. ● Cursor → Chứa kết quả của câu truy vấn SQL.
  7. 7 SQLiteOpenHelper ● Tạo lớp kế thừa từ SQLiteOpenHelper để tạo hay nâng cấp CSDL. Các điểm cần quan tâm ở lớp kế thừa: ● ● ● ● ● Phương thức khởi tạo: Cần gọi super() và truyền hai tham số bắt buộc là tên của CSDL và phiên bản hiện tại. Override phương thức onCreate.Phương thức này được gọi khi CSDL chưa tồn tại. Override phương thức onUpgrade.Phương thức này được gọi khi phiên bản CSDL được tăng lên. Cả hai phương thức onCreate và onUpgrade đều truyền vào đối tượng SQLiteDatabase của CSDL hiện tại. Chúng ta dùng nó và các câu lệnh DDL để tạo/thay đổi schema của CSDL. Bảng trong CSDL phải có khoá chính tên _id.
  8. 8 SQLiteDatabase ● ● ● SQLiteDatabase là base class cho phép chúng ta làm việc với CSDL thông qua các phương thức insert, update, delete, executeSQL. Khi insert/update dữ liệu, chúng ta có thể dùng ContentValues class để định nghĩa dữ liệu theo dạng key/value. Trong đó “key” là tên của cột, “value” là giá trị của cột đó. SQLiteQueryBuilder class giúp ta xây dựng các query() hay rawQuery(). Cursor cursor = getReadableDatabase(). rawQuery("select * from employee where _id = ?", new String[] { id });
  9. 9 Cursor ● ● Kết quả trả về từ câu lệnh truy vấn là một Cursor. Cursor trỏ đến một dòng trong kết quả truy vấn. Phương pháp lưu trữ kết quả trả về sử dụng Cursor giúp Android tiết kiệm vùng nhớ vì nó không cần phải load tất cả dữ liệu lên bộ nhớ. Một số phương thức thường dùng trong lớp Cursor: ● ● ● ● getCount() → số lượng hàng trong kết quả truy vấn. moveToFirst(), moveToNext() → di chuyển con trỏ đến hàng đầu tiên hay hàng kế tiếp. isAfterLast() → kiểm tra xem đã đến cuối kết quả chưa. Các phương thức get như getLong(colidx), getString(colidx) → lấy giá trị của cột tương ứng colidx tại hàng hiện tại. ● getColumnIndexOrThrow(String) → lấy colidx từ tên cột. ● close() → close Cursor.
  10. 10 Ví dụ ● Viết chương trình có giao diện như trong hình (sử dụng CSDL để lưu trữ dữ liệu) ● ● Nếu nút “Thêm” được nhấn: Chọn 1 tên từ danh sách tên đã định trước thêm vào đầu danh sách. Nếu nút “Xoá” được nhấn: Xoá tên đang ở đầu danh sách.
  11. 11 Ví dụ ● Tạo lớp SampleDBOpenHelper: //Bỏ qua phần package & import public class SampleDBOpenHelper extends SQLiteOpenHelper { public static final String TABLE_EMPLOYEE_INFO = "employee_info"; public static final String COLUMN_EMPLOYEE_ID = "_id"; public static final String COLUMN_EMPLOYEE_NAME = "employee_name"; private static final String DATABASE_NAME = "employee.db"; private static final int DATABASE_VERSION = 1; //Câu truy vấn tạo bảng EMPLOYEE_INFO private static final String DATABASE_CREATE = "create table " + TABLE_EMPLOYEE_INFO + "(" + COLUMN_EMPLOYEE_ID + " integer primary key autoincrement, " + COLUMN_EMPLOYEE_NAME + " text not null);"; public SampleDBOpenHelper(Context context) { super(context, DATABASE_NAME, null, DATABASE_VERSION); } @Override public void onCreate(SQLiteDatabase database) { database.execSQL(DATABASE_CREATE); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { Log.w(SampleDBOpenHelper.class.getName(), "Upgrading database from version " + oldVersion + " to " +newVersion + ", which will destroy all old data"); db.execSQL("DROP TABLE IF EXISTS " + TABLE_EMPLOYEE_INFO); onCreate(db); } }
  12. 12 Ví dụ Tạo lớp model cho bảng employee_info: ● //Bỏ qua phần package public class EmployeeInfo { private long employee_id; private String employee_name; //Getter & setter sinh tự động bằng Eclipse public long getEmployee_id() { return employee_id; } public void setEmployee_id(long employee_id) { this.employee_id = employee_id; } public String getEmployee_name() { return employee_name; } public void setEmployee_name(String employee_name) { this.employee_name = employee_name; } // Sử dụng trong ArrayAdapter để trình bày lên ListView @Override public String toString() { return employee_name; } }
  13. 13 Ví dụ ● Hiện thực DAO (Data Access Object) lớp: //Bỏ qua package & import public class EmployeeDataSource { private SQLiteDatabase db; private SampleDBOpenHelper dbOpenHelper; private String[] allColumns = { SampleDBOpenHelper.COLUMN_EMPLOYEE_ID, SampleDBOpenHelper.COLUMN_EMPLOYEE_NAME }; public EmployeeDataSource(Context context) { dbOpenHelper = new SampleDBOpenHelper(context); } public void open() throws SQLException { db = dbOpenHelper.getWritableDatabase(); } public void close() { dbOpenHelper.close(); } public EmployeeInfo createEmployee(String name) { ContentValues values = new ContentValues(); values.put(SampleDBOpenHelper.COLUMN_EMPLOYEE_NAME, name); long insertId = db.insert(SampleDBOpenHelper.TABLE_EMPLOYEE_INFO, null, values); Cursor cursor = db.query(SampleDBOpenHelper.TABLE_EMPLOYEE_INFO,allColumns, SampleDBOpenHelper.COLUMN_EMPLOYEE_ID + " = " + insertId, null, null, null, null); cursor.moveToFirst(); EmployeeInfo newEmployee = cursorToEmployee(cursor); cursor.close(); return newEmployee; }
  14. 14 Ví dụ ● Hiện thực DAO lớp: public void deleteEmployee(EmployeeInfo employee) { long id = employee.getEmployee_id(); Log.d(this.getClass().getName(), "Employee deleted with id: " + id); db.delete(SampleDBOpenHelper.TABLE_EMPLOYEE_INFO, SampleDBOpenHelper.COLUMN_EMPLOYEE_ID + " = " + id, null); } public List<EmployeeInfo> getAllEmployees() { List<EmployeeInfo> employeeList = new ArrayList<EmployeeInfo>(); Cursor cursor = db.query(SampleDBOpenHelper.TABLE_EMPLOYEE_INFO, allColumns, null, null, null, null, null); cursor.moveToFirst(); while (!cursor.isAfterLast()) { EmployeeInfo employee = cursorToEmployee(cursor); employeeList.add(employee); cursor.moveToNext(); } //Nhớ close cursor!!! cursor.close(); return employeeList; } private EmployeeInfo cursorToEmployee(Cursor cursor) { EmployeeInfo employee = new EmployeeInfo(); employee.setEmployee_id(cursor.getLong(0)); employee.setEmployee_name(cursor.getString(1)); return employee; } }
  15. 15 Ví dụ ● Layout của Activity list_main.xml: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <LinearLayout android:id="@+id/group" android:layout_width="wrap_content" android:layout_height="wrap_content" > <Button android:id="@+id/add" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/btn_title_add_new" android:onClick="onClick"/> <Button android:id="@+id/delete" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/btn_title_del_first" android:onClick="onClick"/> </LinearLayout> <ListView android:id="@android:id/list" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@string/hello_world" /> </LinearLayout>
  16. 16 Ví dụ ● MainActivity: //Bỏ qua import & package public class MainActivity extends ListActivity { private EmployeeDataSource datasource; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.list_main); datasource = new EmployeeDataSource(this); datasource.open(); List<EmployeeInfo> values = datasource.getAllEmployees(); // Sử dụng SimpleCursorAdapter ArrayAdapter<EmployeeInfo> adapter = new ArrayAdapter<EmployeeInfo>(this, android.R.layout.simple_list_item_1, values); setListAdapter(adapter); } @Override protected void onResume() { datasource.open(); super.onResume(); } @Override protected void onPause() { datasource.close(); super.onPause(); } }
  17. 17 Ví dụ ● MainActivity: public void onClick(View view) { @SuppressWarnings("unchecked") ArrayAdapter<EmployeeInfo> adapter = (ArrayAdapter<EmployeeInfo>) getListAdapter(); EmployeeInfo employee = null; switch (view.getId()) { case R.id.add: String[] employees = new String[] { "Phước", "An", "Nguyên", "Sơn" }; int nextInt = new Random().nextInt(4); // Save the new comment to the database employee = datasource.createEmployee(employees[nextInt]); adapter.add(employee); break; case R.id.delete: if (getListAdapter().getCount() > 0) { employee = (EmployeeInfo) getListAdapter().getItem(0); datasource.deleteEmployee(employee); adapter.remove(employee); } break; } adapter.notifyDataSetChanged(); }
  18. 18 Content Provider ● Giới thiệu về Content Provider. ● Hiện thực Content Provider. ● Contract Class. ● Sử dụng Content Provider. ● Content Provider & Loader1. 1 Xem ở bài 2:”Background processing”
  19. 19 Giới thiệu Content Provider ● ● ● CSDL SQLite chỉ dùng trong ứng dụng. Để chia sẻ dữ liệu này có các ứng dụng khác cần dùng Content Provider. Content Provider là một cơ chế cho phép truy xuất (truy vấn, thêm, sửa, xoá) dữ liệu (tập tin, csdl) của một ứng dụng từ một ứng dụng khác. Ví dụ: ● Truy xuất lịch sử các cuộc gọi. ● Truy xuất bookmark của web browser. ● Truy xuất sổ địa chỉ. ● Truy xuất vào lịch.
  20. 20 Giới thiệu Content Provider STT Tên Mô tả 1 query Truy vấn dữ liệu, trả kết quả về qua Cursor. 2 insert Thêm dữ liệu 3 update Cập nhật dữ liệu 4 delete Xoá dữ liệu Application Content Provider CSDL Query Insert Update Delete External App
  21. 21 Hiện thực Content Provider ● Tạo lớp kế thừa lớp ContentProvider. ● Hiện thực các phương thức trừu tượng. ● Đăng ký provider vào AndroidManifest.
  22. 22 Hiện thực Content Provider ● Tạo lớp kế thừa lớp ContentProvider: ● Trong lớp ContentProvider có 6 phương thức trừa tượng cần được hiện thực: Tên Giá trị trả về Mô tả onCreate boolean ● Được gọi khi khởi động provider. ●Nếu quá trình khởi tạo thành công trả về true, ngược lại trả về false. getType String ● query Cursor ● insert int ● update int ● delete int ● Trả về MIME của URL được cung cấp. Truy vấn dữ liệu. ●Kết quả trả về là một Cursor. Thêm dữ liệu ●Trả về số lượng hàng dữ liệu thêm vào. Thay đổi dữ liệu. ●Trả về số lượng hàng thay đổi. Xoá dữ liệu. ●Trả về số lượng hàng bị xoá.
  23. 23 Hiện thực Content Provider import android.content.ContentProvider; import android.content.ContentValues; import android.database.Cursor; import android.net.Uri; public class SampleProvider extends ContentProvider { @Override public int delete(Uri uri, String selection, String[] selectionArgs) { return 0; } @Override public String getType(Uri uri) { return null; } @Override public Uri insert(Uri uri, ContentValues values) { return null; }
  24. 24 Hiện thực Content Provider @Override public boolean onCreate() { return false; } @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { return null; } @Override public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { return 0; } }
  25. 25 Hiện thực Content Provider ● Hiện thực các phương thức trừu tượng nếu cần thiết. ● ● ● Hiện thực phương thức onCreate: Tạo đối tượng của lớp con của lớp SQLiteOpenHelper và sử dụng phương thức getContext để lấy Context hiện tại. Lưu đối tượng này vào biến thành viên của lớp. Hiện thức 4 phương thức thao tác trên CSDL thì sử dụng đối tượng đã lưu ở trên để lấy đối tượng SQLiteDatabase. Sau đó sử dụng đối tượng SQLiteDatabase để thao tác trên CSDL. Hiện thực phương thức getType: Bình thường trả về null. Trong trường hợp phân chia ra nhiều thì nên trả về MIME cho từng trường hợp.
  26. 26 Hiện thực Content Provider ・・・ private SampleDBOpenHelper dbOpenHelper; private SQLiteDatabase db; @Override public boolean onCreate() {   dbOpenHelper = new SampleDBOpenHelper(getContext()); return true; } @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { db = dbOpenHelper.getReadableDatabase(); return db.query(SampleDBOpenHelper.TABLE_EMPLOYEE_INFO, projection, selection, selectionArgs, null, null, sortOrder); } ・・・
  27. 27 Bài tập 07 ● Hiện thực chức năng cho xoá một dòng trong bảng EMPLOYEE_INFO bằng ContentProvider trong phần ví dụ.
  28. 28 Hiện thực Content Provider ● Đăng ký provider vào AndroidManifest.xml: 1.Doubclick vào AndroidManifest, chọn “Application” tab. 2.Nhấn vào nút “Add” ở “Application Nodes” 2 1
  29. 29 Hiện thực Content Provider ● Đăng ký provider vào AndroidManifest.xml: 3.Chọn “Provider” và nhấn nút “OK”. Chọn lại chọn lựa 1 nếu màn hình bên trái hiện ra  3
  30. 30 Hiện thực Content Provider ● Đăng ký provider vào AndroidManifest.xml: 4.Nhập vào tên của provider ở ô “Name”. Có thể dùng nút “Browse” để tìm provider. 4
  31. 31 Hiện thực Content Provider ● Đăng ký provider vào AndroidManifest.xml: 5.Nhập một chuỗi vào “Authorities Tag”, thường dùng package name. 5
  32. 32 Hiện thực Content Provider ● Đăng ký provider vào AndroidManifest.xml: <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > ... <provider android:authorities="com.example.samplecontentprovider" android:name="SampleProvider"></provider> </application>
  33. 33 Contract Class ● ● ● Để cung cấp thông tin về provider như các URI, tên của các cột, intent action, ... người ta sử dụng các lớp đặc biệt gọi là Contract Class. Các provider được cung cấp sẵn trong Android thường cung cấp kèm theo Contract class trong package android.provider. Ví dụ: ● ● UserDictionary Provider cung cấp Contract class UserDictionary.Words. Contact Provider cung cấp Contract class ContactsContract.
  34. 34 Sử dụng Content Provider ● Để truy xuất dữ liệu cung cấp bởi provider chúng ta tiến hành các bước sau đây: 1. Xác định Uri của provider. 2. Sử dụng phương thức Context#getContentResolver để truy xuất đối tượng ContentResolver. 3. Sử dụng Uri và các phương thức cung cấp bởi ContentResolver để truy xuất đến provider. Tham khảo thêm lớp UriMatcher để theo tác với Uri.
  35. 35 Sử dụng Content Provider ● Định dạng của chuỗi Uri: content://<Authorities>/<Phần tuỳ chọn> ● “content://” → scheme: xác định đây là provider. ● Authorities → Phân biệt các provider với nhau. ● Phần tuỳ chọn: Xác định nội dung dữ liệu cần cung cấp.
  36. 36 Ví dụ Uri uri = Uri.parse("content://com.example.samplecontentprovider"); Cursor cursor = getContentResolver().query(uri,null,null,null,null); List<EmployeeInfo> values = new ArrayList<EmployeeInfo>(); cursor.moveToFirst(); EmployeeInfo employee = null; while (!cursor.isAfterLast()) { employee = new EmployeeInfo(); employee.setEmployee_id(cursor.getLong(0)); employee.setEmployee_name(cursor.getString(1)); values.add(employee); cursor.moveToNext(); } //Nhớ close cursor!!! cursor.close();
  37. 37 Ví dụ
  38. Nguyen Huu Phuoc, MEng. ●  Blog:http://folami.nghelong.com ●  Website http://phuocnh.nghelong.com

×