android Content Provider詳解八-實現ContentProvider MIME 類型

來源:互聯網
上載者:User

(歡迎大家加入android技術交流QQ群:209796692)


實現ContentProvider MIME 類型

ContentProvider 有兩個方法返回MIME類型。 

getType() 

一個對任何provider都要實現的方法。 

getStreamTypes() 

如果你的provider提供的是檔案,此方法是期望被實現的。 

表的MIME類型們

getType()方法返回一個MIME格式的String ,此String描述了由content URI參數計算出的資料類型。Uri 可以是一個模式而不是一個具體的URI;此時,你應該返回對應於那些符合content URI模式的的資料的類型。

對於普通的資料類型,比如文本, HTML或 JPEG,getType()應該返回標準的MIME類型。關於標準MIME類型的一個完整的列表能在IANA MIME Media Types 網站上找到。 

對於指向表資料的一行或多行的content URI們,getType()應返回一個Android vendor-specific MIME 格式: 

· 類型部分:vnd 

· 子類型部分: 

· 如果URI指向單行:android.cursor.item/ 

· 如果URI 指向多行:android.cursor.dir/ 

· Provider-specific 部分:vnd.<name>.<type> 

你要提供 <name> 和 <type>。<name>的值應是一個全域唯一的,並且<type> 的值對於對應的URI模式也需是唯一的。對<name> 的一個好的選擇是用你公司的名字或你的應用的Android包名的一部分。對於<type>的一個好的選擇是使用標誌與URI相關連的表的字串。 

例如,如果一個provider的authority是com.example.app.provider,並且它曝露了一個叫做table1的表,那麼表示表中多行的MIME類型就是: 

vnd.android.cursor.dir/vnd.com.example.provider.table1

表示單行的MIME類型是: 

vnd.android.cursor.item/vnd.com.example.provider.table1

表示檔案的MIME 們

如果你的provider提供檔案,就要實現getStreamTypes()。這個方法對傳入的content URI返回一個由指向檔案們的MIME類型組成的String 數組,你應該跟據MIME類型過慮參數過慮MIME 類型們,所以你只返回那些用戶端真正相要的MIME類型們。 

例如,假設一個provider提供影像檔,有 .jpg, .png,和 .gif類型。如果一個應用使用過濾字串image/* (表示某些是"image"的東西)調用ContentResolver.getStreamTypes() ,那麼ContentProvider.getStreamTypes() 方法應返回數組: 

{ "image/jpeg", "image/png", "image/gif"}

如果應用只對.jpg 檔案感興趣,它應使用過濾字串 *\/jpeg 調用 ContentResolver.getStreamTypes(),並且 ContentProvider.getStreamTypes()應該返回: 

{"image/jpeg"}

如果你的provider沒有提供過濾字串中所請求的MIME, getStreamTypes() 應返回 null. 

實現一個Contract(契約)類

Contract class是一個public final 類,它包含有定義URI們的常量,列的名字,MIME類型們,以及其它用於provider的中繼資料。這個類建立了一個provider和其它應用之間的契約以保證在URI、列名等項的值發生變化時依然能被正確的操作。

一個契約類對開發人員有協助,因為它提供了一個好識別的名字,而不用直接使用數字,於是開發人員就不會為列名或URI們使用錯誤的值。因為它是一個類,它就可以包含Javadoc文檔。整合式開發環境,比如Eclipse可以跟據契約類自動完成常量名並為常量顯示Javadoc。 

開發人員不能從你的應用操作契約類的類檔案,但是他們可以從你提供的.jar檔案中靜態把它編譯到他們的應用中 。 

ContactsContract 類和它的嵌套類們就是契約類的例子。 

實現Content Provider 許可權

對android系統的所有方面的許可權在主題Security and Permissions中有詳細的描述。主題 Data Storage 中也描術了安全和許可權對各種儲存類型的影響。簡略的說,重要的幾點是: 

· 預設下,儲存在裝置的內部儲存空間上的資料檔案是你的應用和provider私人的。 

· 你建立的SQLiteDatabase 資料庫是你的應用和provider私人的。 

· 預設上,儲存到外部儲存空間上的資料檔案是公有的和全域可讀的。你不能使用一個content provider來限制外部儲存上的檔案的操作,因為其它應用可以使用其它API 來讀寫它們。 

· 那些用於在你的裝置內部儲存空間上開啟或建立檔案或SQLite資料的方法們可能會暗中給予其它應用讀寫的許可權。如果你使用一個內部檔案或資料庫作為你的provider的資料倉儲,並且你給予它們"world-readable" 或"world-writeable" 許可權,你在manifest中對你的provider的許可權聲明將不能保護你的資料。內部儲存上的檔案和資料庫的的預設許可權是"private",並且你也不應該改變你的provider的資料倉儲的許可權。 

如果你想使用content provider 的許可權來控制對你的資料的操作,那麼你應該儲存你的資料到內部檔案,SQLite 資料庫,或"cloud" (例如,在一個遠程服務上),並且你應該保持檔案和資料庫私屬於你的應用。 

實現許可權

所有的應用都可以從你的provider讀或寫你的provider寫,即使背景資料是私人的。因為預設下你的provider 沒有使用權限設定。要改變這種情況,可以在manifest檔案中設定你的provider的許可權,使用<provider> 元素的屬性或其兒子項目。你可以設定應用於整個provider的許可權,或只應用於特定表的,或特定記錄的,或所有三者的。 

你在manifest檔案中用一個或多個<permission> 元素定義你的provider的許可權。要使用於你的provider的許可權是唯一的,為使用android:name屬性使用Java風格的範圍限定。例如, 為讀許可權命名為com.example.app.provider.permission.READ_PROVIDER. 

下面所列的描述說明了provider許可權的範圍,開始是應用於整個provider的然後變成更細顆粒度。更細顆粒度的許可權優先順序高於大範圍的許可權: 

單一的read-write provider-level許可權 

一個許可權,它控制對整個provider的讀和寫入權限,用<provider> 元素的android:permission 屬性指定。 

分開的讀和寫provider-level許可權

控制整個provider的一個讀許可權和一個寫入權限。你用<provider> 元素的android:readPermission和android:writePermission屬性指定它們。它們的優先順序比android:permission更高。

Path-level 許可權

對你的provider中的content URI的讀、寫,或讀/寫入權限。你使用<provider> 元素<path-permission> 子項目指定的指定每個URI的許可權,你可以指定一個讀/寫入權限,一個讀許可權,或一個寫入權限,或所有三者。讀和寫入權限優先順序高於讀/寫入權限。並且,path-level許可權優先順序高於 provider-level許可權。

臨時許可權

也是一個權限等級,它代表了臨時擷取並賦於一個應用的許可權,即使這個應用不具有許可權。臨時許可權特性減少了一個應用需要在其mainifest中聲明的許可權的數量。當你開啟了臨時許可權,只有那些持續操作你的所有資料的應用們才需要對你的provider有“持久的”許可權. 

考慮一下你實現一個email provider和應用,當你想允許一個外部映像查看應用通過你的provider來顯示映像附件時所需的許可權。要想不用聲明許可權就給予映像查看應用所需的許可權,就需設定映像的content URI的臨時許可權。這樣設計你的email 應用:當使用者想要顯示一個映像,你的應用發送一個intent給映像查看應用,這個intent包含了映像的content URI 和許可權。映像查看應用之後可以請求你的email provider來擷取映像,即使映像查看應用對你的provider不具有普通的讀許可權。 

要開啟臨時許可權,既可以設定<provider>元素的android:grantUriPermissions 屬性,也可以添加一個或多個 <grant-uri-permission> 子項目到你的<provider> 元素。如果你使用臨時許可權,你必須在從你的provider刪除對一個content URI的支援時調用Context.revokeUriPermission() ,如果這個content URI關聯了一個臨時許可權的話。 

屬性的值決定了你的provider具有什麼操作的可操作性。如果屬性被設定為true,那麼系統將為你的整個provider擷取臨時許可權,覆蓋任何其它通過provider-level或path-level 擷取的許可權。 

如果這個flag 設定為false, 那麼你必須添加<grant-uri-permission> 子項目到你的<provider> 元素上。每個子項目指定了哪個content URI 或哪些URI們授予了臨時許可權。

要把臨時許可權委託給一個應用,intent必須包含FLAG_GRANT_READ_URI_PERMISSION 或FLAG_GRANT_WRITE_URI_PERMISSION 標誌,或兩者都有。它們可用setFlags() 方法設定。 

如果android:grantUriPermissions 屬性不存在,就被認為是false。 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.