Content provider作為資訊的讀出,比較常見的還有檔案的讀寫,最基礎的就是二進位檔案的的讀寫,例如img檔案,音頻檔案的讀寫。在資料庫中存放了該檔案的路徑,我們可以通過ContentProvider獲得InputSream和OutputStream,實現對檔案的操作。Pro Android 4.0提及有關內容,但語焉不詳,可同時參考http://www.grokkingandroid.com/handling-binary-data-with-contentproviders/,也可同時參考閱讀的原始碼,通過eclipse下載原始碼,具體是sdk\sources\android-17\android\content\ContentProvider.java。
本筆記仍以BookProvider為例。
在資料庫中存放檔案路徑
從ContentProvider的原始碼注釋中可知:Android會自動從uri的一個名為_data的列中擷取檔案路徑。也就是Android在資料庫表格中預留了列名_data,專門用於存放檔案路徑。和_id不同,_data不屬於處理SQLite資料庫表格BaseColumns類,也就是系統不會預留_data列,需要我們進行人工處理。
處理包括在provider描述中,為該表格增加_data的列:
public class BookProviderMetaData {......//由於我們要更新資料庫,所以資料庫的版本需要提升public static final int DATABASE_VERSION = 3;public static final class BookTableMetaData implements BaseColumns{......public static final String FILE_NAME = "_data";}}
處理還包括在BookProvider中projectMap的映射關係:
sBooksProjectionMap.put(BookTableMetaData.FILE_NAME, BookTableMetaData.FILE_NAME);
還有所涉及的增改查等內容。如果檔案位於外接SD卡,還需要在AndriodManifest.xml中聲明對SD卡具備讀寫權限。
重寫openFile()方法
在原始碼中,openFile()如下:
public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException { throw new FileNotFoundException("No files supported by provider at " + uri); }
即永遠會拋出一個異常:FileNotFoundException,必須對之重寫。
@Overridepublic ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException {if(sUriMatch.match(uri) != BOOK_ITEM_URI_INDICATION)throw new IllegalArgumentException ("URI invalid. Use an id-based URI only."); /* 在代碼或者reference,清晰寫明:Convenience for subclasses that wish to implement openFile(Uri, String) by looking up * a column named "_data" at the given URI. * 簡單地,在進行了uri的合法判斷後,只需返回openFileHelper就可以。*/return openFileHelper(uri, mode);}
如何通過Content Provider進行檔案讀寫
對於某個已的item的uri,擷取二進位檔案讀寫非常方便,如下所示
try{OutputStream file = getContentResolver().openOutputStream(uri);... ... //寫處理file.close();}catch (Exception e){Log.e(“pro”,e.toString());}try{InputStream in = getContentResolver().openInputStream(uri);... ... //讀處理in.close();}catch (Exception e){Log.e(“pro”,e.toString());}
相關連結:
我的Android開發相關文章