Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android中ContentProvider組件詳解

Android中ContentProvider組件詳解

編輯:關於Android編程

一.Android四大組件

Android四大組件是Activity, Service, Content Provider,Broadcast Receiver。

Activity作為程序界面,直接與用戶交互

Service運行在後台,沒有界面,完成特定的功能

ContentProvider維護應用數據,方便應用本身或其它應用訪問

Broadcast Receiver提供異步廣播消息接收機制,便於各應用/組件進行交互

二.什麼是ContentProvider

ContentProvider(內容提供者)是Android中的四大組件之一。主要用於對外共享數據,也就是通過ContentProvider把應用中的數據共享給其他應用訪問,其他應用可以通過ContentProvider對指定應用中的數據進行操作。ContentProvider分為系統的和自定義的,系統的也就是例如聯系人,圖片等數據。

1.ContentProvider
Android提供了一些主要數據類型的ContentProvider,比如音頻、視頻、圖片和私人通訊錄等。可在android.provider包下面找到一些Android提供的ContentProvider。通過獲得這些ContentProvider可以查詢它們包含的數據,當然前提是已獲得適當的讀取權限。
主要方法:

public boolean onCreate() 在創建ContentProvider時調用
public Cursor query(Uri, String[], String, String[], String) 用於查詢指定Uri的ContentProvider,返回一個Cursor
public Uri insert(Uri, ContentValues) 用於添加數據到指定Uri的ContentProvider中
public int update(Uri, ContentValues, String, String[]) 用於更新指定Uri的ContentProvider中的數據
public int delete(Uri, String, String[]) 用於從指定Uri的ContentProvider中刪除數據
public String getType(Uri) 用於返回指定的Uri中的數據的MIME類型
*如果操作的數據屬於集合類型,那麼MIME類型字符串應該以vnd.android.cursor.dir/開頭。
例如:要得到所有person記錄的Uri為content://contacts/person,那麼返回的MIME類型字符串為"vnd.android.cursor.dir/person"。
*如果要操作的數據屬於非集合類型數據,那麼MIME類型字符串應該以vnd.android.cursor.item/開頭。
例如:要得到id為10的person記錄的Uri為content://contacts/person/10,那麼返回的MIME類型字符串應為"vnd.android.cursor.item/person"。

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

ContentResolver cr = getContentResolver();  
ContentResolver提供的方法和ContentProvider提供的方法對應的有以下幾個方法。
public Uri insert(Uri uri, ContentValues values) 用於添加數據到指定Uri的ContentProvider中。
public int delete(Uri uri, String selection, String[] selectionArgs) 用於從指定Uri的ContentProvider中刪除數據。
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) 用於更新指定Uri的ContentProvider中的數據。
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) 用於查詢指定Uri的ContentProvider。
3.Uri

Uri 代表了要操作的數據,Uri 主要包含了兩部分信息:1、需要操作的
ContentProvider;2、對ContentProvider中的什麼數據進行操作。一個Uri由以
下幾部分組成:
\

ContentProvider的scheme已經由Android所規定,scheme為content://。
主機名(authorities)用於唯一標識這個ContentProvider,外部調用者可以根據
它找到對應的內容提供者(ContentProvider)。
路徑(Path)可以用來表示我們要操作的數據,路徑的構建應該根據業務而定,
如下:
要操作Person表中ID 為10的記錄,可以構建這樣的路徑:/person/id/10,也
可以為/prson/10,構建什麼樣的路徑需要與UriMatcher中注冊的匹配Uri相一
致。例如:/person/id/10,那麼匹配Uri需要也需要帶id 為/preson/id/#,否則
可以寫成/person/10.
要操作person表中的所有記錄,可以這樣構建路徑:/person
如果要把一個字符串轉換成Uri,可以使用Uri類中的parse()方法。如下:
Uri uri = Uri.parse("content://com.ljq.provider.personprovider/person")

三、UriMatcher類使用介紹

因為Uri代表了要操作的數據,所以我們經常需要解析Uri,並從Uri中獲取數據。Android系統提供了兩個用於操作Uri的工具類,分別為UriMatcher和ContentUris 。掌握它們的使用,會便於我們的開發工作。
UriMatcher類用於匹配Uri,它的用法如下:
首先第一步把你需要匹配Uri路徑全部給注冊上,如下:

//常量UriMatcher.NO_MATCH表示不匹配任何路徑的返回碼   
UriMatcher  sMatcher = new UriMatcher(UriMatcher.NO_MATCH);   
//如果match()方法匹配content:  
//com.ljq.provider.personprovider/person路徑,返回匹配碼為1,匹配Uri注冊如下:   
sMatcher.addURI("com.ljq.provider.personprovider", person", 1);  
//添加需要匹配uri,如果匹配就會返回匹配碼   
//如果match()方法匹配content://com.ljq.provider.personprovider/person/230路徑,返回匹配碼為2,配Uri注冊如下:   
sMatcher.addURI("com.ljq.provider.personprovider", "person/#", 2);  
//#號為通配符   
//傳入Uri,進行匹配   
switch (sMatcher.match(Uri.parse("content://com.ljq.provider.personprovider/person/10"))) {    
     case 1   
       break;   
     case 2   
       break;   
     default://不匹配   
       break;   
 }   
注冊完需要匹配的Uri後,就可以使用sMatcher.match(uri)對輸入的uri進
匹配,如果匹配正確就返回匹配碼,匹配碼是addUri()方法傳入的第三個
數,假設匹配content://com.ljq.provider.personprovider/person 路徑,返回
匹配碼為1。

四、ContentUris介紹

ContentUris用於操作Uri後面的ID 部分,它有兩個實用的方法:
WithAppendedId(uri, id)用於為uri路徑加上id 部分,如下:
Uri uri = Uri.parse("content://com.ljq.provider.personprovider/person")   
Uri resultUri = ContentUris.withAppendedId(uri, 10);    
//生成後的Uri為:content://com.ljq.provider.personprovider/person/10   
parseId(uri)用於從路徑中獲取Id,如下:   
Uri uri = Uri.parse("content://com.ljq.provider.personprovider/person/10")   
long personid = ContentUris.parseId(uri);  
//獲取的結果為:10

五、監聽ContentProvider中數據的變化

如果ContentProvider的訪問者需要知道ContentProvider中數據發生變化,可以在ContentProvider中數據發生變化時調用getContentResovler().notifyChange(uri, null)來通知注冊在此uri上的訪問者,如下:
public class PersonContentProvider extends ContentProvider {   
     public Uri insert(Uri uri, ContentValues values) {   
        db.insert("person", "personid", values);   
        getContext().getContentResolver().notifyChange(uri, null);   
     }   
 }   
如果ContentProvider 的訪問者需要得到數據變化通知,必須使用ContentObserver對數據(數據采用Uri描述)進行監聽,當監聽到數據變化通知時,系統就會調用ContentObserver的onChange()方法,如下:
getContentResolver().registerContentObserver(Uri.parse("content://com.ljq.providers.personprovider/person"),   
       true, new PersonObserver(new Handler()));   
public class PersonObserver extends ContentObserver{   
   public PersonObserver(Handler handler) {   
      super(handler);   
   }   
   public void onChange(boolean selfChange) {   
      //此處可以進行相應的業務處理   
   }   
}   

六、具體實例
public class FirstContentProvider extends ContentProvider {  
      
        // UriMatcher類主要用來匹配Uri  
        private static final UriMatcher uriMatcher = new UriMatcher(  
                UriMatcher.NO_MATCH);  
        private MySqlite mysqlite;  
        static {  
            // 注冊向外部程序提供的Uri  
            uriMatcher.addURI(UserInfo.AUTOR, "userinfo", 1);  
            uriMatcher.addURI(UserInfo.AUTOR, "userinfoall", 2);  
        }  
        //刪除數據  
        @Override  
        public int delete(Uri uri, String selection, String[] selectionArgs) {  
            int number = 0;  
            if (uriMatcher.match(uri) == 1) {  
                // 根據條件刪除數據,並獲取刪除的行數  
                number = mysqlite.getReadableDatabase().delete("user_info",  
                        selection, selectionArgs);  
            }  
            // 通知數據已經改變  
            getContext().getContentResolver().notifyChange(uri, null);  
            return number;  
        }  
      
        @Override  
        public String getType(Uri uri) {  
      
            return null;  
        }  
        //插入數據  
        @Override  
        public Uri insert(Uri uri, ContentValues values) {  
            String name = values.getAsString(UserInfo.User.NAME).toString();  
            String age = values.getAsInteger(UserInfo.User.AGE).toString();  
            String maxId = "select max(id) id from user_info";  
            Cursor cursor = mysqlite.getReadableDatabase().rawQuery(maxId, null);  
            cursor.moveToFirst();  
            int userid = cursor.getInt(0) + 1;  
            if (uriMatcher.match(uri) == 1) {  
      
                mysqlite.getWritableDatabase().execSQL(  
                        "insert into user_info values(?,?,?)",  
                        new String[] { String.valueOf(userid), name, age });  
            }  
            return uri;  
        }  
      
        // 連接數據庫  
        @Override  
        public boolean onCreate() {  
            mysqlite = new MySqlite(getContext(), "userinfo.db", null, 1);  
            return true;  
        }  
        //查詢數據  
        @Override  
        public Cursor query(Uri uri, String[] projection, String selection,  
                String[] selectionArgs, String sortOrder) {  
            SQLiteDatabase sqlite = mysqlite.getReadableDatabase();  
            String str = "select name,age from user_info";  
            if (uriMatcher.match(uri) == 1) {  
                str += " where " + selection;  
            }  
            Cursor cursor = sqlite.rawQuery(str, selectionArgs);  
            return cursor;  
        }  
        //修改數據  
        @Override  
        public int update(Uri uri, ContentValues values, String selection,  
                String[] selectionArgs) {  
            SQLiteDatabase sqlite = mysqlite.getReadableDatabase();  
            int number = 0;  
            if (uriMatcher.match(uri) == 1) {  
                number = sqlite.update("user_info", values, selection,  
                        selectionArgs);  
            }  
            return number;  
        }  
      
    }  
  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved