Android中ContentProvider簡介【安卓進化二十七】

來源:互聯網
上載者:User

          對做應用的來說,資料存放區很重要,在【安卓進化十三】中有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>

 

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.