日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
AndroidContentProvider詳解

Android中的Contentprovider機(jī)制可支持在多個(gè)應(yīng)用中存儲(chǔ)和讀取數(shù)據(jù)。這也是跨應(yīng)用共享數(shù)據(jù)的唯一方式。在android系統(tǒng)中,沒(méi)有一個(gè)公共的內(nèi)存區(qū)域,供多個(gè)應(yīng)用共享存儲(chǔ)數(shù)據(jù)。

我們提供的服務(wù)有:網(wǎng)站制作、成都網(wǎng)站制作、微信公眾號(hào)開(kāi)發(fā)、網(wǎng)站優(yōu)化、網(wǎng)站認(rèn)證、獨(dú)山子ssl等。為上1000+企事業(yè)單位解決了網(wǎng)站和推廣的問(wèn)題。提供周到的售前咨詢和貼心的售后服務(wù),是有科學(xué)管理、有技術(shù)的獨(dú)山子網(wǎng)站制作公司

Android提供了一些主要數(shù)據(jù)類型的ContentProvider,比如音頻、視頻、圖片和私人通訊錄等??稍赼ndroid.provider包下面找到一些android提供的Contentprovider??梢垣@得這些Contentprovider,查詢它們包含的數(shù)據(jù),當(dāng)然前提是已獲得適當(dāng)?shù)淖x取權(quán)限。

如果想公開(kāi)自己的數(shù)據(jù),那么可有兩種辦法:

創(chuàng)建自己的Contentprovider,需要繼承ContentProvider類; 如果你的數(shù)據(jù)和已存在的Contentprovider數(shù)據(jù)結(jié)構(gòu)一致,可以將數(shù)據(jù)寫(xiě)到已存在的Contentprovider中,當(dāng)然前提是獲取寫(xiě)該Contentprovider的權(quán)限。比如把OA中的成員通訊信息加入到系統(tǒng)的聯(lián)系人Contentprovider中。

所有Contentprovider都需要實(shí)現(xiàn)相同的接口用于查詢Contentprovider并返回?cái)?shù)據(jù),也包括增加、修改和刪除數(shù)據(jù)。

首先需要獲得一個(gè)ContentResolver的實(shí)例,可通過(guò)Activity的成員方法getContentResovler()方法:

 
 
 
  1. ContentResolver cr = getContentResolver(); 

ContentResolver實(shí)例帶的方法可實(shí)現(xiàn)找到指定的Contentprovider并獲取到Contentprovider的數(shù)據(jù)。

ContentResolver的查詢過(guò)程開(kāi)始,Android系統(tǒng)將確定查詢所需的具體Contentprovider,確認(rèn)它是否啟動(dòng)并運(yùn)行它。android系統(tǒng)負(fù)責(zé)初始化所有的Contentprovider,不需要用戶自己去創(chuàng)建。實(shí)際上,contentprovider的用戶都不可能直接訪問(wèn)到contentprovider實(shí)例,只能通過(guò)ContentResolver在中間代理。

數(shù)據(jù)模型

Contentprovider展示數(shù)據(jù)類似一個(gè)單個(gè)數(shù)據(jù)庫(kù)表。其中:

每行有個(gè)帶唯一值的數(shù)字字段,名為_(kāi)ID,可用于對(duì)表中指定記錄的定位;Contentprovider返回的數(shù)據(jù)結(jié)構(gòu),是類似JDBC的ResultSet,在android中,是Cursor對(duì)象。 URI

每個(gè)contentprovider定義一個(gè)唯一的公開(kāi)的URI,用于指定到它的數(shù)據(jù)集。一個(gè)contentprovider可以包含多個(gè)數(shù)據(jù)集(可以看作多張表),這樣,就需要有多個(gè)URI與每個(gè)數(shù)據(jù)集對(duì)應(yīng)。這些URI要以這樣的格式開(kāi)頭:

content://

表示這個(gè)uri指定一個(gè)contentprovider。

如果你想創(chuàng)建自己的contentprovider,***把自定義的URI設(shè)置為類的常量,這樣簡(jiǎn)化別人的調(diào)用,并且以后如果更新URI也很容易。android定義了CONTENT_URI常量用于URI,比如:

android.provider.Contacts.Phones.CONTENT_URI
android.provider.Contacts.Photos.CONTENT_URI

要注意的是上面例子中的Contacts,已經(jīng)在android 2.0及以上版本不贊成使用。

查詢Contentprovider

要想使用一個(gè)contentprovider,需要以下信息:

定義這個(gè)contentprovider的URI 返回結(jié)果的字段名稱 這些字段的數(shù)據(jù)類型

如果需要查詢contentprovider數(shù)據(jù)集的特定記錄(行),還需要知道該記錄的ID的值。

構(gòu)建查詢

查詢就是輸入U(xiǎn)RI等參數(shù),其中URI是必須的,其他是可選的,如果系統(tǒng)能找到URI對(duì)應(yīng)的contentprovider將返回一個(gè)Cursor對(duì)象。

可以通過(guò)ContentResolver.query()或者Activity.managedQuery()方法。兩者的方法參數(shù)完全一樣,查詢過(guò)程和返 回值也是相同的。區(qū)別是,通過(guò)Activity.managedQuery()方法,不但獲取到Cursor對(duì)象,而且能夠管理Cursor對(duì)象的生命周 期,比如當(dāng)Activity暫停(pause)的時(shí)候,卸載該Cursor對(duì)象,當(dāng)Activity restart的時(shí)候重新查詢。另外,也可以對(duì)一個(gè)沒(méi)有處于Activity管理的Cursor對(duì)象做成被Activity管理的,通過(guò)調(diào)用 Activity.startManaginCursor()方法。

類似這樣:

 
 
 
  1. Cursor cur = managedQuery(myPerson, null, null, null, null); 

其中***個(gè)參數(shù)myPerson是Uri類型實(shí)例。

如果需要查詢的是指定行的記錄,需要用_ID值,比如ID值為23,URI將是類似:

content://. . . ./23

android提供了方便的方法,讓開(kāi)發(fā)者不需要自己拼接上面這樣的URI,比如類似:

 
 
 
  1. Uri myPerson = ContentUris.withAppendedId(People.CONTENT_URI, 23); 

或者:

 
 
 
  1. Uri myPerson = Uri.withAppendedPath(People.CONTENT_URI, "23"); 

二者的區(qū)別是一個(gè)接收整數(shù)類型的ID值,一個(gè)接收字符串類型。

其他幾個(gè)參數(shù):

names,可以為null,表示取數(shù)據(jù)集的全部列,或者聲明一個(gè)String數(shù)組,數(shù)組中存放列名稱,比如:People._ID。一般列名都在該Contentprovider中有常量對(duì)應(yīng); 針對(duì)返回結(jié)果的過(guò)濾器,格式類似于SQL中的WHERE子句,區(qū)別是不帶WHERE關(guān)鍵字,如果返回null表示不過(guò)濾,比如name=?; 前面過(guò)濾器的參數(shù),是String數(shù)組,是針對(duì)前面條件中?占位符的值; 排序參數(shù),類似SQL的ORDER BY字句,不過(guò)不需要寫(xiě)ORDER BY部分,比如name desc,如果不排序,可輸入null。

返回值是Cursor對(duì)象,游標(biāo)位置在***條記錄之前。

下面實(shí)例適用于android 2.0及以上版本,從android通訊錄中得到姓名字段:

 
 
 
  1. Cursor cursor = getContentResolver().query( 
  2.         ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null,null,null); 

返回值的內(nèi)容

返回值的內(nèi)容類似上圖,不同的contentprovider會(huì)有不同的列和名稱,但是會(huì)有兩個(gè)相同的列,上面提到過(guò)的一個(gè)是_ID,用于唯一標(biāo)識(shí)記錄,還有一個(gè)_COUNT,用于記錄整個(gè)結(jié)果集的大小,可以看到上面圖中的_COUNT的值是相同的。

讀取返回的數(shù)據(jù)

如 果在查詢的時(shí)候使用到ID,那么返回的數(shù)據(jù)只有一條記錄。在其他情況下,一般會(huì)有多條記錄。和JDBC的ResultSet類似,需要操作游標(biāo)遍歷結(jié)果 集,在每行,再通過(guò)列名獲取到列的值,可以通過(guò)getString()、getInt()、getFloat()等方法獲取值。比如類似下面:

 
 
 
  1. while (cursor.moveToNext()) { 
  2.     builder 
  3.             .append( 
  4.                     cursor 
  5.                             .getString(cursor 
  6.                                     .getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME))) 
  7.             .append("-"); 

和JDBC中不同,沒(méi)有直接通過(guò)列名獲取列值的方法,只能先列名獲取到列的整型索引值,然后再通過(guò)該索引值定位獲取列的值。

編輯數(shù)據(jù)

可以通過(guò)contentprovider實(shí)現(xiàn)以下編輯功能:

增加新的記錄; 在已經(jīng)存在的記錄中增加新的值; 批量更新已經(jīng)存在的多個(gè)記錄; 刪除記錄。

所有的編輯功能都是通過(guò)ContentResolver的方法實(shí)現(xiàn)。一些Contentprovider對(duì)權(quán)限要求更嚴(yán)格一些,需要寫(xiě)的權(quán)限,如果沒(méi)有會(huì)報(bào)錯(cuò)。

增加記錄

要想增加記錄到contentprovider,首先,要在ContentValues對(duì)象中設(shè)置類似map的鍵值對(duì),在這里,鍵的值對(duì)應(yīng)contentprovider中的列的名字,鍵值對(duì)的值,是對(duì)應(yīng)列希望的類型。然后,調(diào)用ContentResolver.insert()方法,傳入這個(gè)ContentValues對(duì)象,和對(duì)應(yīng)Contentprovider的URI即可。返回值是這個(gè)新記錄的URI對(duì)象。這樣你可以通過(guò)這個(gè)URI獲得包含這條記錄的Cursor對(duì)象。比如:

 
 
 
  1. ContentValues values = new ContentValues(); 
  2.  
  3. values.put(People.NAME, "Abraham Lincoln"); 
  4.  
  5. Uri uri = getContentResolver().insert(People.CONTENT_URI, values); 

在原有記錄上增加值

如果記錄已經(jīng)存在,可在記錄上增加新的值,或者編輯已經(jīng)存在的值。

首先要過(guò)去到原來(lái)的值對(duì)象,然后要清除原有的值,然后像上面增加記錄一樣即可:

 
 
 
  1. Uri uri=Uri.withAppendedPath(People.CONTENT_URI, "23"); 
  2.  
  3. Uri phoneUri = Uri.withAppendedPath(uri, People.Phones.CONTENT_DIRECTORY); 
  4.  
  5. values.clear(); 
  6. values.put(People.Phones.TYPE, People.Phones.TYPE_MOBILE); 
  7. values.put(People.Phones.NUMBER, "1233214567"); 
  8. getContentResolver().insert(phoneUri, values); 

批量更新值

批量更新一組記錄的值,比如NY改名為Eew York??烧{(diào)用ContenResolver.update()方法。

刪除記錄

如果是刪除單個(gè)記錄,調(diào)用ContentResolver.delete()方法,URI參數(shù),指定到具體行即可。

如果是刪除多個(gè)記錄,調(diào)用ContentResolver.delete()方法,URI參數(shù)指定Contentprovider即可,并帶一個(gè)類似SQL的WHERE子句條件。這里和上面類似,不帶WHERE關(guān)鍵字。

創(chuàng)建自己的Contentprovider

創(chuàng)建contentprovider,需要:

設(shè)置存儲(chǔ)系統(tǒng)。大多數(shù)contentprovider使 用文件或者SQLite數(shù)據(jù)庫(kù),不過(guò)你可以用任何方式存儲(chǔ)數(shù)據(jù)。android提供SQLiteoOpenHelper幫助開(kāi)發(fā)者創(chuàng)建和管理 SQLiteDatabase。 繼承ContentProvider,提供對(duì)數(shù)據(jù)的訪問(wèn)。 在manifest文件中聲明contentprovider。 繼承ContentProvider類

必須定義ContentProvider類的子類,需要實(shí)現(xiàn)如下方法:

query()
insert()
update()
delete()
getType()
onCreate()

query() 方法,返回值是Cursor實(shí)例,用于迭代請(qǐng)求的數(shù)據(jù)。Cursor是一個(gè)接口。android為該接口提供了一些只讀的(和JDBC的 ResultSet不一樣,后者還提供可寫(xiě)入的可選特性)Cursor實(shí)現(xiàn)。比如SQLiteCursor,可迭代SQLite數(shù)據(jù)庫(kù)中的數(shù)據(jù)。可以通過(guò) SQLiteDatabase類的query()方法獲取到該Cursor實(shí)例。還有其他的Cursor實(shí)現(xiàn),比如MatrixCursor,用于數(shù)據(jù)不 是存儲(chǔ)在數(shù)據(jù)庫(kù)的情況下。

因?yàn)镃ontentprovider可能被多個(gè)ContentResolver對(duì)象在不同的進(jìn)程和線程中調(diào)用,因此實(shí)現(xiàn)Contentprovider必須考慮線程安全問(wèn)題。

作為良好的習(xí)慣,在實(shí)現(xiàn)編輯數(shù)據(jù)的代碼中,要調(diào)用ContentResolver.notifyChange()方法,通知那些監(jiān)聽(tīng)數(shù)據(jù)變化的監(jiān)聽(tīng)器。

在實(shí)現(xiàn)子類的時(shí)候,還有一些步驟可以簡(jiǎn)化Contentprovider客戶端的使用:

定義public static final Uri常量,名稱為CONTENT_URI:

 
 
 
  1. public static final UriCONTENT_URI = 
  2.                Uri.parse("content://com.example.codelab.transportationprovider"); 

如果有多個(gè)表,它們也是使用相同的CONTENT_URI,只是它們的路徑部分不同。

也就是說(shuō)紅色框部分是一致的。

定義返回的列名,public static final,列名的值,比如使用SQLite數(shù)據(jù)庫(kù)作為存儲(chǔ),對(duì)應(yīng)表的列名。

在文檔中要寫(xiě)出各個(gè)列的數(shù)據(jù)類型,便于使用者讀取。

如果需要處理新的MIME數(shù)據(jù)類型,比如通過(guò)Intent的方式,并且?guī)ata的mimeType,那么需要在ContentProvider.getType()方法中進(jìn)行處理,參見(jiàn)編寫(xiě)完整的Contentprovider示例編寫(xiě)一個(gè)getType方法部分。

如果處理數(shù)據(jù)庫(kù)表中超大的數(shù)據(jù),比如很大的位圖文件,一般存在文件系統(tǒng)中,可以參照在contentprovider中使用大型二進(jìn)制文件,這樣第三方的contentprovider使用者,可以訪問(wèn)不屬于它權(quán)限的文件,通過(guò)contentprovider做代理。

聲明ContentProvider

創(chuàng)建ContentProvider后,需要在manifest文件中聲明,android系統(tǒng)才能知道它,當(dāng)其他應(yīng)用需要調(diào)用該ContentProvider時(shí)才能創(chuàng)建或者調(diào)用它。

語(yǔ)法類似:

 
 
 
  1.           android:authorities="com.easymorse.cp.mycp">  

android:name要寫(xiě)ContentProvider繼承類的全名。

android:authorities要寫(xiě)和CONTENT_URI常量的B部分(見(jiàn)上面圖)。

注意不要把上圖C和D部分加到authorities中去。authorities是用來(lái)識(shí)別ContentProvider的,C和D部分實(shí)際上是ContentProvider內(nèi)部使用的。


文章標(biāo)題:AndroidContentProvider詳解
網(wǎng)站URL:http://www.dlmjj.cn/article/cdhceeg.html