如何通過contentprovider構(gòu)建媒體文件數(shù)據(jù)庫(doc7頁)正式版_第1頁
如何通過contentprovider構(gòu)建媒體文件數(shù)據(jù)庫(doc7頁)正式版_第2頁
如何通過contentprovider構(gòu)建媒體文件數(shù)據(jù)庫(doc7頁)正式版_第3頁
如何通過contentprovider構(gòu)建媒體文件數(shù)據(jù)庫(doc7頁)正式版_第4頁
如何通過contentprovider構(gòu)建媒體文件數(shù)據(jù)庫(doc7頁)正式版_第5頁
已閱讀5頁,還剩2頁未讀 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

1、Android 如何通過 content provider 構(gòu)建媒體文件數(shù)據(jù)庫Android 為 Camera, Audio , Video 等媒體文件提供MediaProvider 用于數(shù)據(jù)的保存, 刪除, 檢索等。 MediaProvider 實現(xiàn)了 ContentProvider 類的幾個操作SQL的重要方法如 insert ,delete, updata, query 。 MediaProvider 中 Databa seHelper 類用于獲取與創(chuàng)建 Database。private static final class DatabaseHelper extends SQLiteOp

2、enHelpe r final Context mContext;final boolean mInternal; / True if this is the internal database/ In memory caches of artist and album data.HashMap mArtistCache = new HashMap ();HashMap mAlbumCache = new HashMap ();public DatabaseHelper(Context context, String name, boolean inter nal) super(context

3、, name, null, DATABASE_VERSION);mContext = context;mInternal = internal;/* Creates database the first time we try to open it.*/Override / 第一次打開數(shù)據(jù)庫時創(chuàng)建Tablepublic void onCreate(final SQLiteDatabase db) updateDatabase(db, mInternal, 0, DATABASE_VERSION);以Camera的image文件文件為例,數(shù)據(jù)庫在第一次使用的時候被創(chuàng)建,對 于 image 文件,

4、SQL updateDatabase 為其創(chuàng)建一個 table :db.execSQL(CREATE TABLE IF NOT EXISTS images ( +_id INTEGER PRIMARY KEY, + / 文件保存的序號_data TEXT, + / 記錄 image 文件保存路徑_size INTEGER, + / 文件大小_display_name TEXT, + / 圖片名稱mime_type TEXT, + / 文件類型title TEXT, +date_added INTEGER, +date_modified INTEGER, +description TEXT, +

5、picasa_id TEXT, +isprivate INTEGER, +latitude DOUBLE, +longitude DOUBLE, +datetaken INTEGER, +orientation INTEGER, +mini_thumb_magic INTEGER, +bucket_id TEXT, +bucket_display_name TEXT +););添加URI到match這個也很重要,因為不同類型的文件會保存在不同的 tab le 中,如果我們得到一個 URI 為:content:media/external/images/media/1 通過 UriMatcher

6、.match(uri) 將返回注冊的 IMAGES_MEDIAJD。URI_MATCHER.addURI(media, */images/media, IMAGES_MEDIA);URI_MATCHER.addURI(media, */images/media/#, IMAGES_MEDIA_ID);URI格式解析如下:URI格式中最重要的字段是authority , authority 確定了操作數(shù)據(jù)庫的Pr ovider是由誰提供的。MediaProvider在AndroidManifest.xml 中添加如下語句:Provider 力口載MediaProvider 安裝在手機中, Con

7、tentResolver 通過 acquireProvider 請 求加載 Provider 程序。 acquireProvider 正是通過解析URI 中的 authority 字段,在安裝的 package 中查找與此authority 相符的 Provider ,如果此 Provider 沒有被加載ActivityMangerService 將加載 Provider 程序, 這個過程可以參考我以前寫的 Activity 是如何加載的文章。 Provider 到底是加載到調(diào)用 Prov ider 的應(yīng)用程序還是將Provider 程序加載到 ActivityManagerService 中

8、作為system Provider 這個我不太確定是如何區(qū)分的,反正這兩種方式都是可行的, 總之按照 sdk help 文檔上的方式創(chuàng)建Provider 程序, android 會自動加載的。記錄的保存與獲取當(dāng)Camera拍照完成或者是media play文件需要保存的時候,首先要構(gòu)造保 存的數(shù)據(jù)結(jié)構(gòu)ContentValues values = new ContentValues(7);values.put(Images.Media.TITLE, imageName);values.put(Images.Media.DISPLAY_NAME, imageName);values.put(Ima

9、ges.Media.DESCRIPTION, description);values.put(Images.Media.DATE_TAKEN, dateTaken);values.put(Images.Media.MIME_TYPE, image/jpeg);values.put(Images.Media.ORIENTATION, orientation);Uri uri = cr.insert(sStorageURI, values); /保存到數(shù)據(jù)庫sStorageURI = content:/media/external/sdcard/media/Authority 是 media 所以

10、將調(diào)用 MediaProvider:insert ,在 insert 中生 成文件保存的路徑并放在 key為_data項數(shù)據(jù)區(qū)。再通過ContentResolver訪問 MediaProvider調(diào)用openFile打開文件并將Image或media數(shù)據(jù)寫入。Camera, Image gallery 應(yīng)用啟動后不會掃描文件系統(tǒng)而是根據(jù)數(shù)據(jù)庫的記 錄來進行列表并顯示。這樣做無疑效率比較高。文件的刪除數(shù)據(jù)庫中保存有文件的路徑名, 當(dāng)調(diào)用 delete 從數(shù)據(jù)庫中刪除一個記錄后,記錄中 _data 保存的文件名 (絕對路徑 )所指的文件也被刪除了。 而在應(yīng)用程序中 是找不到刪除文件的代碼,這個困擾

11、了我兩天,在程序中加 log ,分析源代碼, 最終屏蔽 MediaProvider 中的一段代碼找到了一點線索:public int delete(Uri uri, String userWhere, String whereArgs) int count;int match = URI_MATCHER.match(uri);if (match != VOLUMES_ID) DatabaseHelper database = getDatabaseForUri(uri);if (database = null) throw new UnsupportedOperationException(U

12、nknown URI: + uri);SQLiteDatabase db = database.getWritableDatabase();synchronized (sGetTableAndWhereParam) getTableAndWhere(uri, match, userWhere, sGetTableAndWhereParam);switch (match) case AUDIO_MEDIA:case AUDIO_MEDIA_ID:count = db.delete(audio_meta,sGetTableAndWhereParam.where, whereArgs);break;

13、default:/ count = db.delete(sGetTableAndWhereParam.table,/ sGetTableAndWhereParam.where, whereArgs);break;getContext().getContentResolver().notifyChange(uri, null);將上面紅色代碼注掉以后發(fā)現(xiàn)文件沒有被刪除, 而紅色代碼只是對數(shù)據(jù)庫進行操作,因而文件應(yīng)該是在清除數(shù)據(jù)庫的記錄時候被刪除的。仔細查看創(chuàng)建table 的代碼發(fā)現(xiàn)幾個語句很奇怪,由于沒有網(wǎng)絡(luò)去搜索一下關(guān)于 androidSQL的knowledge只能猜測這個語句的意思了當(dāng)然也怪

14、偶沒去學(xué)學(xué)SQLdb.execSQL(CREATE TRIGGER IF NOT EXISTS images_cleanup DELETE ON images +BEGIN +DELETE FROM thumbnails WHERE image_id = old._id; +SELECT _DELETE_FILE(old._data); +END);創(chuàng)建 table 為 images 的觸發(fā)器, DELETE FROM thumbnails WHERE image_i d = old._id正是刪除thumbnails的意思,對于 Camera&J建的Images會生成一個小圖片保存為 thu

15、mbnail ,這個記錄也是自動清除的。 SELECT _DELETE_F ILE(old._data); 應(yīng)該是刪除文件的意思。在 Sqlite3_android.cpp 文件中還真找到 delete_file 這個函數(shù), 加上 log , 進入 gallery 選擇一個文件刪除,打出了刪除文件名的全路徑。static void delete_file(sqlite3_context * context, int argc, sqli te3_value * argv)if (strncmp(/sdcard/, path, 8) != 0) /只能刪除 sdcard/ 路徑下的東西要刪除其他

16、路sqlite3_result_null(context); / 還需稍微改造一下return;如何將文件保存在手機上MediaProvider 中存在兩個數(shù)據(jù)庫一個是external 對應(yīng)文件系統(tǒng)為 SD Card, 一個是內(nèi)部數(shù)據(jù)庫internal 用于手機 flash 上的文件系統(tǒng)。 遺憾的是雖然MediaProvider 提供了操作內(nèi)外兩個數(shù)據(jù)庫的功能,但在發(fā)布的應(yīng)用中并沒有使 用這個內(nèi)部文件系統(tǒng)。 Android 默認狀態(tài)下 Image, audio 等文件是保存在SD card 上。 External, internal 數(shù)據(jù)庫都保存在手機文件系統(tǒng)上Path: /data/data

17、/viders.media/database/如果要使用內(nèi)部文件系統(tǒng)需要修改以下幾個地方1: MediaProvider generateFileName 函數(shù)private String generateFileName(boolean internal, String preferre dExtension, String directoryName)/ create a random fileString name = String.valueOf(System.currentTimeMillis();if (internal) throw new Unsu

18、pportedOperationException(Writing to internal stor age is not supported.);/ return Environment.getDataDirectory()/ + / + directoryName + / + name + preferredExtension; else return Environment.getExternalStorageDirectory()+ / + directoryName + / + name + preferredExtension;恢復(fù)紅色部分代碼,將路徑設(shè)置為手機內(nèi)部文件系統(tǒng)文件夾。

19、2:保存文件使用的URI 為 content:/media/internal/images/media/1紅色 internal 表名使用內(nèi)部文件系統(tǒng)數(shù)據(jù)庫3:修改Sqlite3_android.cpp 中 delete_file 函數(shù)static void delete_file(sqlite3_context * context, int argc, sqli te3_value * argv)if (strncmp(/sdcard/, path, 8) != 0 & strncmp(/data/media/, path, 12) sqlite3_result_null(context);return;添加紅色部分,文件位于手機上 /data/media 路徑時也進行刪除。這樣當(dāng)我們從數(shù)據(jù)庫里刪除一條記錄時, _data 數(shù)據(jù)區(qū)存取的文件路徑中的

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論