對做應用的來說,資料存放區很重要,在【安卓進化十三】中有SharedPreferences簡單KVStore for Redis形式,以xml格式儲存在手機中,這個是簡單,方便,好操作的資料存放區工具,只能存簡單的資料,如果儲存大量資料這個就不方便了。在【安卓進化十四】中,我寫了個sqlite的資料庫儲存資料的通訊錄的例子,sqlite對大量資料進行儲存,方便操作,是關係型資料庫的一種。資料存放區還有file檔案儲存體,network儲存,以後我會寫例子的。現在我要講一下自己對ContentProviders的理解,前面說的SharedPreferences,sqlite,等等,都是針對每個應用程式來說的,就是說你的不能跨越工程,只能這個工程能用,但是手機有些程式是需要資料共用的,不能只單獨讓一個工程用,(例如:android手機的簡訊和通訊錄等都是資料共用的,源碼寫了它們對應的ContentProvider提供給我們這個介面,我們就可以對其進行操作)這時候就需要ContentProviders了,它是多有應用程式之間資料存放區和檢索的一個橋樑,主要作用就是使得各個應用程式之間實現資料共用。系統提供了音頻、視頻、映像、個人聯絡資訊等幾個常用的ContentProviders。這就是泛講ContentProviders。
下面分步驟講解一下ContentsProviders:
一、建立ContentsProvider:
首先要在ContentsProviders類中定義一個公用的、靜態常量:CONTENT_URI來代表這個地址,該地址必須是唯一的:public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/notes");必須定義你要返回給用戶端的資料列名。如果你正在使用sqlite資料庫,則資料列的使用方式和你以往所熟悉的其他資料庫一樣。但是,你必須為其定義一個叫_id的列,它用來表示每條記錄的唯一性,模式使用“INTEGER
PRIMARY KEY AUTOINCREMENT”自動更新。
特別說明一下:如果你處理的資料類型是一種比較新的類型,你就必須定義一個新的MIME類型,以提供ContentProvider.getType(uri)來返回。MIME類型有兩種類型,一種是為指定的單個記錄的;另一種是為指定多條記錄的。
另外一定不要忘記在AndroidMenifest.xml中使用<provider>標籤來設定Content Provider。
<provider android:name="NotePadProvider"
android:authorities="com.cn.daming.proider.NotePad"/>
二、ContentResolver這個類,應用通過這個類來使用具體的某個ContentProvider,
ContentResolver crs = getContentResolver();得到一個ContentResolver對象,然後可以通過這個類的方法進行資料的增刪改查操作,具體方法參照sdk的api協助文檔。
三、講一下URI,每個ContentProvider都會對外提供一個公用的URI(封裝成Uri對象),資料共用的時候,就需要使用ContentProvider為這些資料定義的URI,然後其他的應用程式就可以通過ContentProvider傳入這個URI來對資料進行操作。URI由3部分組成:“content://”,資料的路徑,標示ID(可選),舉個系統的URI:
content://contacts/Mms/3(擷取簡訊表中ID為3的連絡人記錄)
content://contacts/Mms/(這個URI將返回裝置上的所有簡訊的資訊)
為了方便理解,在android.provider包下提供了一系列輔助類,其中包含了以類變數形式給出的查詢字串,上面的可以改為:
Uri person = ContentUris.withAppendedId(Mms.CONTENT_URI,3);
特別說明:在資料共用的查詢語句中:where ...And ...OR,可以同時使用,多個And,和一個或多個Or同時使用,或多個Or和一個And或多個And同時使用,使用的時候用小括弧括起來,這樣看的比較明了,注意:有Or和And同時使用的時候查詢的效率很低,速度有點慢。尤其再和like一起使用的情況下,效率會更慢。 有問題的,想要代碼的可以留言,轉載請標明出處:http://blog.csdn.net/wdaming1986/article/details/6820442
看例子:ContentProviderDemo 這個例子:
先看:讀取插入資料庫中的值:
代碼奉上,代碼說明一切:
在com.cn.daiming包下面的類
一、NotePad.java類中的代碼:
package com.cn.damingimport android.net.Uri;import android.provider.BaseColumns;public class NotePad {public static final String AUTHORITY = "com.cn.daming.proider.NotePad";private NotePad(){}public static final class Notes implements BaseColumns{private Notes(){}public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/notes");//new mime manypublic static final String CONTENT_TYPE = "daming.android.cursor.dir/cn.daming.note";//new mime onepublic static final String CONTENT_ITEM_TYPE = "daming.android.cursor.item/cn.daming.note";public static final String DEFAULT_SORT_ORDER = "modified DESC";//columnpublic static final String TITLE = "title";public static final String NOTE = "note";public static final String CREATEDDATE = "created";public static final String MODIFIEDDATE = "modified";}}二、NotePadProvider.java類中的代碼:
package com.cn.daming;import java.util.HashMap;import android.content.ContentProvider;import android.content.ContentUris;import android.content.ContentValues;import android.content.Context;import android.content.UriMatcher;import android.content.res.Resources;import android.database.Cursor;import android.database.SQLException;import android.database.sqlite.SQLiteDatabase;import android.database.sqlite.SQLiteOpenHelper;import android.database.sqlite.SQLiteQueryBuilder;import android.net.Uri;import android.text.TextUtils;import com.cn.daming.NotePad.Notes;public class NotePadProvider extends ContentProvider{private static final String TAG = "NotePadProvider";//database nameprivate static final String DATABASE_NAME = "notepad_db";private static final int DATABASE_VERSION = 2;//table nameprivate static final String NOTES_TABLE_NAME = "notes";private static HashMap<String, String> sNotesProjectionMap;private static final int NOTES = 1;private static final int NOTE_ID = 2;private static final UriMatcher sUriMatcher;private DatabaseHelper mOpenHelper; private static final String CREATE_TABLE = "CREATE TABLE " + NOTES_TABLE_NAME +" ("+Notes._ID +" INTEGER PRIMARY KEY, " +Notes.TITLE +" TEXT," +Notes.NOTE +" TEXT, " +Notes.CREATEDDATE +" INTEGER," +Notes.MODIFIEDDATE +" INTEGER" + ");"; static { sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH); sUriMatcher.addURI(NotePad.AUTHORITY, "notes", NOTES); sUriMatcher.addURI(NotePad.AUTHORITY, "notes/#", NOTE_ID); sNotesProjectionMap = new HashMap<String, String>(); sNotesProjectionMap.put(Notes._ID, Notes._ID); sNotesProjectionMap.put(Notes.TITLE, Notes.TITLE); sNotesProjectionMap.put(Notes.NOTE, Notes.NOTE); sNotesProjectionMap.put(Notes.CREATEDDATE, Notes.CREATEDDATE); sNotesProjectionMap.put(Notes.MODIFIEDDATE, Notes.MODIFIEDDATE); } private static class DatabaseHelper extends SQLiteOpenHelper { //create Database DatabaseHelper(Context context) { super(context, DATABASE_NAME, null, DATABASE_VERSION); } //create tables@Overridepublic void onCreate(SQLiteDatabase db) {db.execSQL(CREATE_TABLE);}//update Database@Overridepublic void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {db.execSQL("DROP TABLE IF EXISTS notes");onCreate(db);} } @Overridepublic boolean onCreate() {mOpenHelper = new DatabaseHelper(getContext()); return true;} @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { SQLiteQueryBuilder qb = new SQLiteQueryBuilder(); switch(sUriMatcher.match(uri)) { case NOTES: qb.setTables(NOTES_TABLE_NAME); qb.setProjectionMap(sNotesProjectionMap); break; case NOTE_ID: qb.setTables(NOTES_TABLE_NAME); qb.setProjectionMap(sNotesProjectionMap); qb.appendWhere(Notes._ID + "="+ uri.getPathSegments().get(1)); break; default: throw new IllegalArgumentException("Unknown URI"+uri); } String orderBy; if(TextUtils.isEmpty(sortOrder)) { orderBy = NotePad.Notes.DEFAULT_SORT_ORDER; } else { orderBy = sortOrder; } SQLiteDatabase db = mOpenHelper.getReadableDatabase(); Cursor cursor = qb.query(db, projection, selection, selectionArgs, null, null, orderBy); cursor.setNotificationUri(getContext().getContentResolver(), uri); return cursor; } //if you difine the class,must get the mothod @Override public String getType(Uri uri) { switch(sUriMatcher.match(uri)) { case NOTES: return Notes.CONTENT_TYPE; case NOTE_ID: return Notes.CONTENT_ITEM_TYPE; default: throw new IllegalArgumentException("Unknown URI "+uri); } } @Override public Uri insert(Uri uri, ContentValues initialValues) { if(sUriMatcher.match(uri) != NOTES) { throw new IllegalArgumentException("Unknown URI "+uri); } ContentValues values; if(initialValues != null) { values = new ContentValues(initialValues); } else { values = new ContentValues(); } Long now = Long.valueOf(System.currentTimeMillis()); if(values.containsKey(NotePad.Notes.CREATEDDATE) == false) { values.put(NotePad.Notes.CREATEDDATE, now); } if(values.containsKey(NotePad.Notes.MODIFIEDDATE) == false) { values.put(NotePad.Notes.MODIFIEDDATE, now); } if(values.containsKey(NotePad.Notes.TITLE) == false) { Resources recource = Resources.getSystem(); values.put(NotePad.Notes.TITLE, recource.getString(android.R.string.untitled)); } if(values.containsKey(NotePad.Notes.NOTE) == false) { values.put(NotePad.Notes.NOTE, ""); } SQLiteDatabase db = mOpenHelper.getWritableDatabase(); long rowId = db.insert(NOTES_TABLE_NAME, Notes.NOTE, values); if(rowId > 0) { Uri noteUri = ContentUris.withAppendedId(NotePad.Notes.CONTENT_URI, rowId); getContext().getContentResolver().notifyChange(noteUri, null); return noteUri; } throw new SQLException("Failed to insert row into "+uri); } @Overridepublic int delete(Uri uri, String where, String[] whereArgs) {SQLiteDatabase db = mOpenHelper.getWritableDatabase();int count;switch(sUriMatcher.match(uri)){case NOTES:count = db.delete(NOTES_TABLE_NAME, where, whereArgs);break;case NOTE_ID:String noteId = uri.getPathSegments().get(1);count = db.delete(NOTES_TABLE_NAME, Notes._ID +"=" + noteId + (!TextUtils.isEmpty(where) ? " " +" AND (" + where + ')' : ""), whereArgs);break;default:throw new IllegalArgumentException("Unknown URI "+uri);}getContext().getContentResolver().notifyChange(uri, null);return count;}@Overridepublic int update(Uri uri, ContentValues values, String where, String[] whereArgs) {SQLiteDatabase db = mOpenHelper.getWritableDatabase();int count;switch(sUriMatcher.match(uri)){case NOTES: count = db.update(NOTES_TABLE_NAME, values, where, whereArgs); break;case NOTE_ID: String noteId = uri.getPathSegments().get(1); count = db.update(NOTES_TABLE_NAME, values, Notes._ID + "=" + noteId + (!TextUtils.isEmpty(where)?"" + "AND(" + where + ')' : ""), whereArgs); break;default:throw new IllegalArgumentException("Unknown URI " + uri);}getContext().getContentResolver().notifyChange(uri, null);return count;}}三、MainActivity.java類中的代碼:
package com.cn.daming;import android.app.Activity;import android.content.ContentValues;import android.database.Cursor;import android.graphics.Color;import android.net.Uri;import android.os.Bundle;import android.widget.TextView;public class MainActivity extends Activity {private TextView show_text_view1;private TextView show_text_view2;@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); //insert value ContentValues values = new ContentValues(); values.put(NotePad.Notes.TITLE, "From Daming"); values.put(NotePad.Notes.NOTE, "This is Daming Make!"); getContentResolver().insert(NotePad.Notes.CONTENT_URI, values); values.clear(); values.put(NotePad.Notes.TITLE, "Daming blog"); values.put(NotePad.Notes.NOTE, "http://blog.csdn.net/wdaming1986/article/details/6820442!"); getContentResolver().insert(NotePad.Notes.CONTENT_URI, values); //show the display showDisplayNote(); } //show the display private void showDisplayNote() { String columns[] = new String[]{ NotePad.Notes._ID, NotePad.Notes.TITLE, NotePad.Notes.NOTE, NotePad.Notes.CREATEDDATE, NotePad.Notes.MODIFIEDDATE }; Uri myUri = NotePad.Notes.CONTENT_URI; show_text_view1 = (TextView)findViewById(R.id.show_textview1); show_text_view2 = (TextView)findViewById(R.id.show_textview2); Cursor cursor = managedQuery(myUri, columns, null, null, null); if(cursor.moveToFirst()) { String title = null; String note = null; for(int i=0;i<cursor.getCount();i++) { if(cursor.moveToPosition(i)) { title = cursor.getString(cursor.getColumnIndex(NotePad.Notes.TITLE)); note = cursor.getString(cursor.getColumnIndex(NotePad.Notes.NOTE)); if(i==0) { show_text_view2.setText("TITLE:"+title+"\n"+"NOTE:"+note); show_text_view2.setTextColor(Color.GREEN); } if(i==1) { show_text_view1.setText("TITLE:"+title+"\n"+"NOTE:"+note); show_text_view1.setTextColor(Color.BLUE); } } } } }}在layout下main.xml布局檔案下的代碼:
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" ><TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:gravity="center_vertical|center_horizontal" android:layout_marginTop="10dip" android:text="@string/hello" android:textSize="8pt" /><TextView android:id="@+id/show_textview1" android:layout_width="fill_parent" android:layout_height="wrap_content" android:gravity="center_vertical|center_horizontal" android:layout_marginTop="20dip" android:textSize="10pt"/><TextView android:id="@+id/show_textview2" android:layout_width="fill_parent" android:layout_height="wrap_content" android:gravity="center_vertical|center_horizontal" android:layout_marginTop="20dip" android:textSize="10pt"/></LinearLayout>
在Manifest.xml中的代碼:【一定注意要對ContentProvider進行聲明】
<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.cn.daming" android:versionCode="1" android:versionName="1.0"> <uses-sdk android:minSdkVersion="8" /> <application android:icon="@drawable/icon" android:label="@string/app_name"> <provider android:name="NotePadProvider" android:authorities="com.cn.daming.proider.NotePad"/> <activity android:name=".MainActivity" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> <intent-filter> <data android:mimeType="daming.android.cursor.dir/cn.daming.note"/> </intent-filter> <intent-filter> <data android:mimeType="daming.android.cursor.item/cn.daming.note"/> </intent-filter> </activity> </application></manifest>