posts - 78, comments - 34, trackbacks - 0, articles - 1
            BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

                 早上我們簡要的對SQLite進行回顧,然后將SQLite的事務管理和SQLiteDataBase提供的InsertUpdateDeleteQuery方法進行了簡單的講解。

           

                 今日的重點內容是ContentProvider(內容提供者)和網絡存儲,我將對這兩大內容進行總結。關于SQLiteDataBase提供的便捷方法,它們會在ContentProvider被使用。SQLite的事務管理比較簡單,昨天有簡要介紹,今日就不做總結了。

           

                 ContentProvider和網絡存儲將分為兩篇日志,本篇總結ContentProvider

           

          一、ContentProvider簡介

                 當應用繼承ContentProvider類,并重寫該類用于提供數據和存儲數據的方法,就可以向其他應用共享其數據。雖然使用其他方法也可以對外共享數據,但數據訪問方式會因數據存儲的方式而不同,如:采用文件方式對外共享數據,需要進行文件操作讀寫數據;采用sharedpreferences共享數據,需要使用sharedpreferences API讀寫數據。而使用ContentProvider共享數據的好處是統一了數據訪問方式。

           

          二、Uri類簡介

                 Uri代表了要操作的數據,Uri主要包含了兩部分信息:1.需要操作的ContentProvider2.ContentProvider中的什么數據進行操作,一個Uri由以下幾部分組成:


                 1.schemeContentProvider(內容提供者)的scheme已經由Android所規定為:content://

                 2.主機名(或Authority):用于唯一標識這個ContentProvider,外部調用者可以根據這個標識來找到它。

                 3.路徑(path):可以用來表示我們要操作的數據,路徑的構建應根據業務而定,如下:

          ·         要操作contact表中id10的記錄,可以構建這樣的路徑:/contact/10

          ·         要操作contact表中id10的記錄的name字段, contact/10/name

          ·         要操作contact表中的所有記錄,可以構建這樣的路徑:/contact

           

                 要操作的數據不一定來自數據庫,也可以是文件等他存儲方式,如下:

          要操作xml文件中contact節點下的name節點,可以構建這樣的路徑:/contact/name

          如果要把一個字符串轉換成Uri,可以使用Uri類中的parse()方法,如下:

          Uri uri = Uri.parse("content://com.changcheng.provider.contactprovider/contact")

           

          三、UriMatcherContentUristContentResolver簡介

                 因為Uri代表了要操作的數據,所以我們很經常需要解析Uri,并從Uri中獲取數據。Android系統提供了兩個用于操作Uri的工具類,分別為UriMatcherContentUris 。掌握它們的使用,會便于我們的開發工作。

           

                 UriMatcher用于匹配Uri,它的用法如下:

                 1.首先把你需要匹配Uri路徑全部給注冊上,如下:

                 //常量UriMatcher.NO_MATCH表示不匹配任何路徑的返回碼(-1)

                 UriMatcher  uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);

                 //如果match()方法匹配content://com.changcheng.sqlite.provider.contactprovider/contact路徑,返回匹配碼為1

                 uriMatcher.addURI(“com.changcheng.sqlite.provider.contactprovider”, “contact”, 1);//添加需要匹配uri,如果匹配就會返回匹配碼

                 //如果match()方法匹配   content://com.changcheng.sqlite.provider.contactprovider/contact/230路徑,返回匹配碼為2

                 uriMatcher.addURI(“com.changcheng.sqlite.provider.contactprovider”, “contact/#”, 2);//#號為通配符

                

                 2.注冊完需要匹配的Uri后,就可以使用uriMatcher.match(uri)方法對輸入的Uri進行匹配,如果匹配就返回匹配碼,匹配碼是調用addURI()方法傳入的第三個參數,假設匹配content://com.changcheng.sqlite.provider.contactprovider/contact路徑,返回的匹配碼為1

           

                 ContentUris用于獲取Uri路徑后面的ID部分,它有兩個比較實用的方法:

          ·         withAppendedId(uri, id)用于為路徑加上ID部分

          ·         parseId(uri)方法用于從路徑中獲取ID部分

           

                 ContentResolver當外部應用需要對ContentProvider中的數據進行添加、刪除、修改和查詢操作時,可以使用ContentResolver 類來完成,要獲取ContentResolver 對象,可以使用Activity提供的getContentResolver()方法。 ContentResolver使用insertdeleteupdatequery方法,來操作數據。

           

          四、ContentProvider示例程序

                 我們為昨天的SQLite示例程序添加一個ContentProvider,供其他應用來訪問我們的數據。

           

                 1.SQLite示例程序添加ContentProvider

          package com.changcheng.sqlite.provider;

           

          import com.changcheng.sqlite.MyOpenHelper;

          import android.content.ContentProvider;

          import android.content.ContentUris;

          import android.content.ContentValues;

          import android.content.UriMatcher;

          import android.database.Cursor;

          import android.database.sqlite.SQLiteDatabase;

          import android.net.Uri;

           

          public class ContactContentProvider extends ContentProvider {

           

                   // 通過UriMatcher匹配外部請求

                   private static UriMatcher uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);

                   // 通過openHelper進行數據庫讀寫

                   private MyOpenHelper openHelper;

                   // 匹配狀態常量

                   private static final int CONTACT_LIST = 1;

                   private static final int CONTACT = 2;

                   // 表名

                   private static final String tableName = "contacts";

                   // 添加Uri

                   static {

                             uriMatcher.addURI("com.changcheng.sqlite.provider", "contact",

                                               CONTACT_LIST);

                             uriMatcher.addURI("com.changcheng.sqlite.provider", "contact/#",

                                               CONTACT);

                   }

           

                   @Override

                   public int delete(Uri uri, String selection, String[] selectionArgs) {

                             SQLiteDatabase db = this.openHelper.getWritableDatabase();

                            int result;

                             switch (uriMatcher.match(uri)) {

                             case CONTACT_LIST:

                                      result = db.delete(tableName, selection, selectionArgs);

                                      break;

                             case CONTACT:

                                      long id = ContentUris.parseId(uri);

                                      String where = "_id=" + id;

                                      if (selection != null && !"".equals(selection)) {

                                               where = where + " and " + selection;

                                      }

                                      result = db.delete(tableName, where, selectionArgs);

                                      break;

                             default:

                                      throw new IllegalArgumentException("Uri IllegalArgument:" + uri);

                             }

                             return result;

                   }

           

                   @Override

                   public String getType(Uri uri) {

                             switch (uriMatcher.match(uri)) {

                             case CONTACT_LIST:// 集合類型必須在前面加上vnd.android.cursor.dir/

                                      return "vnd.android.cursor.dir/contactlist";

                             case CONTACT:// 非集合類型必須在前面加上vnd.android.cursor.item/

                                      return "vnd.android.cursor.item/contact";

                             default:

                                      throw new IllegalArgumentException("Uri IllegalArgument:" + uri);

                             }

                   }

           

                   @Override

                   public Uri insert(Uri uri, ContentValues values) {

                             SQLiteDatabase db = this.openHelper.getWritableDatabase();

                             long id;

                             switch (uriMatcher.match(uri)) {

                             case CONTACT_LIST:

                                      // 因為后臺需要生成SQL語句,當valuesnull時,必須提第二個參數。生成的SQL語句才不會出錯!

                                      id = db.insert(tableName, "_id", values);

                                      return ContentUris.withAppendedId(uri, id);

                             case CONTACT:

                                      id = db.insert(tableName, "_id", values);

                                      String uriPath = uri.toString();

                                      String path = uriPath.substring(0, uriPath.lastIndexOf("/")) + id;

                                      return Uri.parse(path);

                             default:

                                      throw new IllegalArgumentException("Uri IllegalArgument:" + uri);

                             }

                   }

           

                   @Override

                   public boolean onCreate() {

                             this.openHelper = new MyOpenHelper(this.getContext());

                             return true;

                   }

           

                   @Override

                   public Cursor query(Uri uri, String[] projection, String selection,

                                      String[] selectionArgs, String sortOrder) {

                             SQLiteDatabase db = this.openHelper.getWritableDatabase();

                             switch (uriMatcher.match(uri)) {

                             case CONTACT_LIST:

                                      return db.query(tableName, projection, selection, selectionArgs,

                                                         null, null, sortOrder);

                             case CONTACT:

                                      long id = ContentUris.parseId(uri);

                                      String where = "_id=" + id;

                                      if (selection != null && !"".equals(selection)) {

                                               where = where + " and " + selection;

                                      }

                                      return db.query(tableName, projection, where, selectionArgs, null,

                                                         null, sortOrder);

                             default:

                                      throw new IllegalArgumentException("Uri IllegalArgument:" + uri);

                             }

                   }

           

                   @Override

                   public int update(Uri uri, ContentValues values, String selection,

                                      String[] selectionArgs) {

                             SQLiteDatabase db = this.openHelper.getWritableDatabase();

                             int result;

                             switch (uriMatcher.match(uri)) {

                             case CONTACT_LIST:

                                      result = db.update(selection, values, selection, selectionArgs);

                                      break;

                             case CONTACT:

                                      long id = ContentUris.parseId(uri);

                                      String where = "_id=" + id;

                                      if (selection != null && !"".equals(selection)) {

                                               where = where + " and " + selection;

                                      }

                                      result = db.update(tableName, values, where, selectionArgs);

                                      break;

                             default:

                                      throw new IllegalArgumentException("Uri IllegalArgument:" + uri);

                             }

                             return result;

                   }

           

          }

           

           

                 2.添加ContentProvider配置

          <provider android:name=".provider.ContactContentProvider" android:authorities="com.changcheng.sqlite.provider.contactprovider"/>

           

                 3.測試SQLite示例程序的ContentProvider

                 ContentProvider即然是提供給其他應用訪問本應用數據的,所以我們需要另創建一個Android應用,來測試SQLite示例程序的ContentProvider。我在此只列出query的測試方法testQuery

          public void testQuery() throws Throwable {

                   ContentResolver contentResolver = this.getContext()

                                      .getContentResolver();

                   Uri uri = Uri

                                      .parse("content://com.changcheng.sqlite.provider/contact");

                   Cursor cursor = contentResolver.query(uri, new String[] { "_id",

                                      "name", "phone" }, null, null, "_id desc");

                   while (cursor.moveToNext()) {

                             Log.i(TAG, "_id=" + cursor.getInt(0) + ",name="

                                               + cursor.getString(1) + ",phone=" + cursor.getString(2));

                   }

          }

           

                 下一篇:Android數據存儲之網絡

           


          評論

          # re: 2010-03-02 傳智播客—Android(四)數據存儲之四ContentProvider  回復  更多評論   

          2010-07-20 11:26 by Cangol
          你好!我有些疑問?
          在provider 類中我們寫注冊uri
          uriMatcher.addURI("com.changcheng.sqlite.provider", "contact",
          CONTACT_LIST);
          標示com.changcheng.sqlite.provider這個是在哪定義的,若是自定義的,將會在哪用到。
          以下在配置文件中的Authority 是否應該與Uri中的一致?

          <provider android:name=".provider.ContactContentProvider" android:authorities="com.changcheng.sqlite.provider.contactprovider"/>

          # re: 2010-03-02 傳智播客—Android(四)數據存儲之四ContentProvider  回復  更多評論   

          2010-07-20 13:11 by 長城
          @Cangol
          請仔細看文章中的例子代碼:
          // 添加Uri
          static {
          uriMatcher.addURI("com.changcheng.sqlite.provider", "contact",
          CONTACT_LIST);
          uriMatcher.addURI("com.changcheng.sqlite.provider", "contact/#",
          CONTACT);
          }

          # re: 2010-03-02 傳智播客—Android(四)數據存儲之四ContentProvider  回復  更多評論   

          2010-07-20 17:16 by Cangol
          @長城
          我還是不解 配置文件中的這個android:authorities做什么用?
          我寫的還是說failed not find provider info com.changcheng.sqlite.provider
          向您請教?

          # re: 2010-03-02 傳智播客—Android(四)數據存儲之四ContentProvider  回復  更多評論   

          2010-08-16 15:52 by 漂泊
          @Cangol
          com.changcheng.sqlite.provider就是你應用的包名、、。

          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          主站蜘蛛池模板: 石渠县| 保山市| 张家川| 茂名市| 祁连县| 瑞安市| 江安县| 江津市| 三台县| 丹寨县| 房产| 连平县| 金阳县| 梅州市| 会东县| 桂阳县| 增城市| 天峨县| 大悟县| 宜城市| 旌德县| 塔城市| 米林县| 新干县| 翁牛特旗| 海伦市| 思南县| 桐城市| 本溪| 泰和县| 房产| 象山县| 重庆市| 大丰市| 巩留县| 都安| 珲春市| 廉江市| 石阡县| 镇巴县| 浮山县|