posts - 1, comments - 0, trackbacks - 0, articles - 0

          2009年7月20日

          創建Content Providers

          2009-07-03 IMTI Haerbin dg

          目標:

                 創建Content Providers ,讓自己的程序所收集的數據能夠被其他應用所訪問

          應用案例:

                 Service Http形式抓取網絡地震信息,存入本地SQLite3,供本地應用查詢,統計,同時以Content Providers形式對外提供數據,讓另一個基于google地圖的程序能夠根據經緯度在地圖上顯示地震區域,并且可以向Content Providers發起查詢得到經緯度

          問題:

          1, 怎么創建Content Providers

          2, 我們的程序怎么經由Content Providers訪問數據

          別人的程序怎么經由Content Providers查詢我們的數據

          關鍵角色:

          1, Content URI

          2, SQLiteOpenHelper

          3, ContentResolver

          4, SQLiteQueryBuilder

          5, Content Providers工作原理

          介紹 

                 Content Providers 是一種讓我們能夠在不同應用間共享數據 的唯一的 通用化接口機制,通過對底層的數據源進行抽象,Content Providers 解除了應用程序層和數據層的耦合,這樣應用程序可以輕便的在不同數據源之上切換(和DAO的理想相當一致)

                 Content Providers 使用 權限控制,通過URI模式訪問,讀寫雙向,由此,任何具有對應permissions(許可、權限)的應用程序都可以增刪查改 由另一個程序創建的數據---包括一些本地化Android數據庫(也就是說你的程序可以Happy的訪問通訊錄,瀏覽器歷史等

                 同樣,你可以把你自己的數據源(你開發的飯館評價系統的數據)發布成Content Providers ,這樣其他開發者就可以和你所開發的應用中的數據進行交互,甚至擴展(別人可以在你的數據基礎上挖掘開發出菜品評價系統)

          倒敘進行:如何調用Content Providers

                 我們可以使用ContentResoler訪問Content Providers,每一個應用上下文android.content.Context(Activity是他的子類)都持有一個ContentResolver引用,于是

                

          ContentResolver cr = getContentResolver();就很貼心的出現了

           

          ContentResolver我們拿到手后,可以使用query(),insert(),update()等方法,但是還有一個URI

                 備注:content URI             


          A.       標準的前綴,不可以修改

          B.       標識部分,對于第三方應用(用戶自己開發的應用),此處應該使用完整的包名類名來保證唯一性,其實是對應在manifest.xml<provider>節點的authorities屬性值<provider class="TransportationProvider" authorities="com.example.transportationprovider" />

          C.       content providers用來確定是何種數據請求的,這個可以沒有,也可以有多個,如果content provider僅提供一種類型的數據(只有trains,例如咱們這個例子),那么此段可以省略。如果可以提供幾種類型的數據,那么就可能形如: "land/bus, land/train, sea/ship, and sea/submarine" 。

          D.       被指定的記錄,一般是被請求記錄的id值,如果被申請使用指定類型的所有數據,那么形如content://com.example.transportationprovider/trains

          需要關心,作為ContentResolver,需要使用URI來告訴Android 想要和哪一個ContentProvider交互(調用)


          1 //返回所有的地震信息
          2 
          3     Cursor c = cr.query(EarthquakeProvider.CONTENT_URI, PROJECTION, null,         null, EarthquakeProvider.DEFAULT_SORT_ORDER);

          其中


          1 public staticfinal Uri CONTENT_URI = Uri
          2 
          3            .parse("content://com.paad.provider.Earthquake/earthquakes");
          4 
          5 Content Provider 的URI 是在AndroidManifest.xml 中聲明的,如下:
          6 
          7 <!-- 注冊ContentProvider -->
          8 
          9        <provider android:name=".earthquake.EarthquakeProvider" android:authorities="com.paad.provider.Earthquake" />

          可見,authorities是一個標識,是我們自定義的,大多Content Providers都定義一個CONTENT_URI屬性值存儲對應xml中聲明的authorities ,這樣方便我們隨時取用

           

          通常 Content Providers 展現兩種形式的URI入口,一個對應查詢所有的請求,另一個對應查詢單條記錄

          查詢所有記錄的URI:

              content://com.paad.provider.Earthquake/earthquakes

          查詢單條記錄的URI:

              content://com.paad.provider.Earthquake/earthquakes/#

          創建Content Providers 步驟

          繼承ContentProvider

              重寫onCreateupdate,query,insert,deletegetType回調方法,當應用程序用ContentResolver.insert()等操作時,此處的函數被調用

          定義public static final Uri  CONTENT_URI屬性,此變量代表你的ContentProvider能夠處理的 URI ,必須是唯一的,(實際是引用AndroidManifest.xml中的定義),

             

          1 public staticfinal Uri CONTENT_URI = Uri
          2 
          3        .parse("content://com.paad.provider.Earthquake/earthquakes");

          構建數據存儲系統,我們可以使用文件存儲或是SQLite數據庫,或其他

              針對SQLite3,我們的步驟如下:

          l         定義內部類earthquakeDatabaseHelper繼承SQLiteOpenHelper,并重寫onCreate(SQLiteDatabase db)     onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)方法   ,earthquakeDatabaseHelper的作用是封裝了創建數據庫、更新數據庫版本的操作

          l         對于query(),我們在其內部依賴Cursor SQLiteQueryBuilder.query()發送查詢,對于其他insert,update,delete我們直接借助SQLiteDatabase.insert等完成

          l         Content ProvideronCreate()中,我們做如下初始化

                 

          1 Context context = getContext();
          2 
          3        earthquakeDatabaseHelper dbHelper;
          4 
          5        dbHelper = new earthquakeDatabaseHelper(context, DATABASE_NAME,        null,DATABASE_VERSION);
          6 
          7        earthquakeDB = dbHelper.getWritableDatabase();
          8 
          9        return (earthquakeDB == null? false : true;

          定義我們的查詢時所會用到的列名,一般我們會把數據庫中表的所有列名都定義成常量,方便查詢時Cursor提取值

             

          // Column Names 表中列名
           
               
          public static final String KEY_ID = "_id";
           
               
          public static final String KEY_DATE = "date";
           
               
          public static final String KEY_DETAILS = "details";
           
               
          public static final String KEY_LOCATION_LAT = "latitude";//……

          URI 數據請求來了,作為Content Provider的開發者你需要告訴Conent Provider 怎么判斷URI想要哪種數據,這里需借助UriMatcher

             

          private static final UriMatcher uriMatcher;

              
          // Allocate the UriMatcher object, where a URI ending in ‘earthquakes’

              
          // will correspond to a request for all earthquakes, and ‘earthquakes’

              
          // with a trailing ‘/[rowID]’ will represent a single earthquake row.

              
          static {

                 uriMatcher 
          = new UriMatcher(UriMatcher.NO_MATCH);

                 
          // 匹配查詢所有com.paad.provider.Earthquake

                 uriMatcher.addURI(
          "com.paad.provider.Earthquake""earthquakes", QUAKES);

                 
          // 匹配查詢單個

                 uriMatcher.addURI(
          "com.paad.provider.Earthquake""earthquakes/#",QUAKE_ID);

              }

          這個變量Content Provider getType()中會使用進行URI匹配

          posted @ 2009-07-20 14:38 dgshine 閱讀(467) | 評論 (0)編輯 收藏

          主站蜘蛛池模板: 乌审旗| 个旧市| 龙岩市| 汤阴县| 吉林市| 佛冈县| 临洮县| 仁怀市| 汪清县| 拉萨市| 化隆| 来安县| 枣阳市| 湾仔区| 铜陵市| 黄山市| 姜堰市| 柘城县| 德兴市| 大丰市| 左权县| 海林市| 东丰县| 竹北市| 革吉县| 万盛区| 衡阳市| 穆棱市| 多伦县| 武定县| 临颍县| 东海县| 蓬溪县| 镶黄旗| 社旗县| 大邑县| 聂拉木县| 大余县| 德江县| 唐山市| 嘉鱼县|