– Bài tập này Tôi sẽ hướng dẫn các bạn cách sử dụng ContentProvider. Cụ thể là cách đọc danh bạ, cách đọc lịch sử cuộc gọi, cách đọc Media và bookmark.
– Phần này rất nhiều và phong phú, bạn cần khám phá nó trên mạng nhiều hơn.
– Thời gian không cho phép do đó Tôi chỉ hướng dẫn những tính năng mà ta thường xuyên sử dụng nhất.
– Tôi có giao diện chính sau:
– Ta có cú pháp tổng quát:
<standard_prefix>://<authority>/<data_path>/<id>
– Ví dụ để lấy tất cả các bookmark trong trình duyệt ta dùng cú pháp:
content://browser/bookmarks
– Để lấy toàn bộ danh bạ trong điện thoại ta dùng cú pháp:
content://contacts/people
– Để lấy 1 contact theo 1 định danh nào đó:
content://contacts/people/3
– Để lấy các kết quả trả về ta cũng dùng Cursor để quản lý.
– Có 2 cách sử dụng hàm lấy kết quả ở đây:
Cách 1:
CursorLoader loader=new CursorLoader(context, uri, null, null, null, null);
Cursor c=loader.loadInBackground();
cách 2:
Cursor c = getContentResolver() .query(uri, null, null, null, null);
– Ta sẽ làm cụ thể từng chức năng trong ví dụ trên
– Bạn xem cấu trúc của bài tập này:
– Bạn xem XML Resource của màn hình chính (activity_main.xml):
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/LinearLayout1" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=".MainActivity" > <Button android:id="@+id/btnshowallcontact" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Show All Contact" /> <Button android:id="@+id/btnaccesscalllog" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Access The Call Log" /> <Button android:id="@+id/btnmediastore" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Access Media Store" /> <Button android:id="@+id/btnaccessbookmarks" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Access Bookmarks" /> </LinearLayout>
– Source code xử lý MainActivity.java:
package tranduythanh.com; import android.os.Bundle; import android.provider.Browser; import android.provider.CallLog; import android.provider.CallLog.Calls; import android.provider.MediaStore; import android.provider.MediaStore.Audio.Media; import android.app.Activity; import android.content.CursorLoader; import android.content.Intent; import android.database.Cursor; import android.view.Menu; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.Toast; public class MainActivity extends Activity implements OnClickListener{ Button btnshowallcontact; Button btnaccesscalllog; Button btnaccessmediastore; Button btnaccessbookmarks; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); btnshowallcontact=(Button) findViewById(R.id.btnshowallcontact); btnshowallcontact.setOnClickListener(this); btnaccesscalllog=(Button) findViewById(R.id.btnaccesscalllog); btnaccesscalllog.setOnClickListener(this); btnaccessmediastore=(Button) findViewById(R.id.btnmediastore); btnaccessmediastore.setOnClickListener(this); btnaccessbookmarks=(Button) findViewById(R.id.btnaccessbookmarks); btnaccessbookmarks.setOnClickListener(this); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.activity_main, menu); return true; } @Override public void onClick(View v) { Intent intent=null; if(v==btnshowallcontact) { intent=new Intent(this, ShowAllContactActivity.class); startActivity(intent); } else if(v==btnaccesscalllog) { accessTheCallLog(); } else if(v==btnaccessmediastore) { accessMediaStore(); } else if(v==btnaccessbookmarks) { accessBookmarks(); } } /** * hàm lấy danh sách lịch sử cuộc gọi * với thời gian nhỏ hơn 30 giây và sắp xếp theo ngày gọi */ public void accessTheCallLog() { String [] projection=new String[]{ Calls.DATE, Calls.NUMBER, Calls.DURATION }; Cursor c=getContentResolver().query( CallLog.Calls.CONTENT_URI, projection, Calls.DURATION+"<?",new String[]{"30"}, Calls.DATE +" Asc"); c.moveToFirst(); String s=""; while(c.isAfterLast()==false){ for(int i=0;i<c.getColumnCount();i++){ s+=c.getString(i)+" - "; } s+="\n"; c.moveToNext(); } c.close(); Toast.makeText(this, s, Toast.LENGTH_LONG).show(); } /** * hàm đọc danh sách các Media trong SD CARD */ public void accessMediaStore() { String []projection={ MediaStore.MediaColumns.DISPLAY_NAME, MediaStore.MediaColumns.DATE_ADDED, MediaStore.MediaColumns.MIME_TYPE }; CursorLoader loader=new CursorLoader (this, Media.EXTERNAL_CONTENT_URI, projection, null, null, null); Cursor c=loader.loadInBackground(); c.moveToFirst(); String s=""; while(!c.isAfterLast()){ for(int i=0;i<c.getColumnCount();i++){ s+=c.getString(i)+" - "; } s+="\n"; c.moveToNext(); } Toast.makeText(this, s, Toast.LENGTH_LONG).show(); c.close(); } /** * hàm đọc danh sách Bookmark trong trình duyệt */ public void accessBookmarks() { String []projection={ Browser.BookmarkColumns.TITLE, Browser.BookmarkColumns.URL, }; Cursor c=getContentResolver() .query(Browser.BOOKMARKS_URI, projection, null, null, null); c.moveToFirst(); String s=""; int titleIndex=c.getColumnIndex (Browser.BookmarkColumns.TITLE); int urlIndex=c.getColumnIndex (Browser.BookmarkColumns.URL); while(!c.isAfterLast()) { s+=c.getString(titleIndex)+" - "+ c.getString(urlIndex); c.moveToNext(); } c.close(); Toast.makeText(this, s, Toast.LENGTH_LONG).show(); } }
– Source XML xử lý xem danh bạn (activity_show_all_contact.xml):
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/LinearLayout1" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=".ShowAllContactActivity" > <ListView android:id="@+id/listView1" android:layout_width="match_parent" android:layout_height="wrap_content" > </ListView> <Button android:id="@+id/btnback" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Back" /> </LinearLayout>
– Source code xử lý xem danh bạ ( ShowAllContactActivity.java):
– Tôi viết theo 2 cách : Dùng CursorLoader và getContentResolver
package tranduythanh.com; import java.util.ArrayList; import android.net.Uri; import android.os.Bundle; import android.provider.ContactsContract; import android.app.Activity; import android.content.CursorLoader; import android.database.Cursor; import android.view.Menu; import android.view.View; import android.view.View.OnClickListener; import android.widget.ArrayAdapter; import android.widget.Button; import android.widget.ListView; public class ShowAllContactActivity extends Activity { Button btnback; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_show_all_contact); btnback=(Button) findViewById(R.id.btnback); btnback.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub finish(); } }); showAllContacts1(); } /** * hàm danh toàn bộ danh bạ * dùng CursorLoader */ public void showAllContacts1() { Uri uri=Uri.parse("content://contacts/people"); ArrayList<String> list=new ArrayList<String>(); CursorLoader loader=new CursorLoader(this, uri, null, null, null, null); Cursor c1=loader.loadInBackground(); c1.moveToFirst(); while(c1.isAfterLast()==false){ String s=""; String idColumnName=ContactsContract.Contacts._ID; int idIndex=c1.getColumnIndex(idColumnName); s=c1.getString(idIndex)+" - "; String nameColumnName=ContactsContract.Contacts.DISPLAY_NAME; int nameIndex=c1.getColumnIndex(nameColumnName); s+=c1.getString(nameIndex); c1.moveToNext(); list.add(s); } c1.close(); ListView lv=(ListView) findViewById(R.id.listView1); ArrayAdapter<String>adapter=new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, list); lv.setAdapter(adapter); } /** * hàm danh toàn bộ danh bạ * dùng getContentResolver */ public void showAllContacts2() { Uri uri=Uri.parse("content://contacts/people"); ArrayList<String> list=new ArrayList<String>(); Cursor c1=getContentResolver() .query(uri, null, null, null, null); c1.moveToFirst(); while(c1.isAfterLast()==false) { String s=""; String idColumnName=ContactsContract.Contacts._ID; int idIndex=c1.getColumnIndex(idColumnName); s=c1.getString(idIndex)+" - "; String nameColumnName=ContactsContract.Contacts.DISPLAY_NAME; int nameIndex=c1.getColumnIndex(nameColumnName); s+=c1.getString(nameIndex); c1.moveToNext(); list.add(s); } c1.close(); ListView lv=(ListView) findViewById(R.id.listView1); ArrayAdapter<String>adapter=new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, list); lv.setAdapter(adapter); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.activity_show_all_contact, menu); return true; } }
– Lưu ý cấp quyền cho ứng dụng:
AndroidManifest.xml:
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="tranduythanh.com" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="14" android:targetSdkVersion="17" /> <uses-permission android:name="android.permission.READ_CONTACTS" /> <uses-permission android:name="android.permission.READ_CALL_LOG" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="com.android.browser.permission.READ_HISTORY_BOOKMARKS" /> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name="tranduythanh.com.MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name="tranduythanh.com.ShowAllContactActivity" android:label="@string/title_activity_show_all_contact" > </activity> </application> </manifest>
– Dòng 11, 12, 13, 14 là cấp quyền cho ứng dụng có thể truy suất các chức năng mong muốn.
– Bây giờ bạn thực hiện ứng dụng và quan sát, giờ Tôi chạy lên và dùng chức năng xem toàn bộ danh bạ:
– Tương tự như vậy bản thử các chức năng còn lại trong ứng dụng.
– Bạn có thể tải coding mẫu đầy đủ ở đây: http://www.mediafire.com/download/kaac7d36ocvr8ba/LearnContentProvider.rar
– Bài tập kế tiếp các bạn sẽ được học về một kỹ thuật hoàn toàn mới trong Android và rất khó và rất hữu dụng, đó là kỹ thuật xử lý Đa Tiến Trình trong Android. Các bạn phải chú ý theo dõi vì nó vô cùng quan trọng, nó cũng giống như Intent là huyết mạch trong các ứng dụng của Android.
– Chúc các bạn thành công.
Cho em hỏi xíu! Tại sao nó cứ bị báo lỗi ở Cursorloader vậy ạ
test
Url
Lỗi Cursor do Android 6.0 nó cảnh báo , cần thêm checkSelfPermission trong hàm