Android如何通過content provider構(gòu)建媒體文件數(shù)據(jù)庫_第1頁
Android如何通過content provider構(gòu)建媒體文件數(shù)據(jù)庫_第2頁
Android如何通過content provider構(gòu)建媒體文件數(shù)據(jù)庫_第3頁
Android如何通過content provider構(gòu)建媒體文件數(shù)據(jù)庫_第4頁
Android如何通過content provider構(gòu)建媒體文件數(shù)據(jù)庫_第5頁
已閱讀5頁,還剩1頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

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

2、text 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 internal) super(context, name, null, DATABASE

3、_VERSION);mContext = context;mInternal = internal;/* Creates database the first time we try to open it.*/Override /第一次翻開數(shù)據(jù)庫時(shí)創(chuàng)建Tablepublic void onCreate(final SQLiteDatabase db) updateDatabase(db, mInternal, 0, DATABASE_VERSION);以Camera的image文件文件為例,數(shù)據(jù)庫在第一次運(yùn)用的時(shí)候被創(chuàng)建,對(duì)于image文件,SQL在updateDatabase為其創(chuàng)建一個(gè)ta

4、ble:db.execSQL(CREATE TABLE IF NOT EXISTS images ( +_id INTEGER PRIMARY KEY, + /文件保管的序號(hào)_data TEXT, + /記錄image 文件保管途徑_size INTEGER, + /文件大小_display_name TEXT, + /圖片稱號(hào)mime_type TEXT, + /文件類型title TEXT, +date_added INTEGER, +date_modified INTEGER, +description TEXT, +picasa_id TEXT, +isprivate INTEGER,

5、 +latitude DOUBLE, +longitude DOUBLE, +datetaken INTEGER, +orientation INTEGER, +mini_thumb_magic INTEGER, +bucket_id TEXT, +bucket_display_name TEXT +););添加URI到match這個(gè)也很重要,由于不同類型的文件會(huì)保管在不同的table中,假設(shè)我們得到一個(gè)URI為: contentmedia/external/images/media/1 經(jīng)過UriMatcher.match(uri)將前往注冊(cè)的IMAGES_MEDIA_ID值。URI_MAT

6、CHER.addURI(media, */images/media, IMAGES_MEDIA);URI_MATCHER.addURI(media, */images/media/#, IMAGES_MEDIA_ID);URI格式解析如下:URI格式中最重要的字段是authority,authority確定了操作數(shù)據(jù)庫的Provider是由誰提供的。MediaProvider在AndroidManifest.xml中添加如下語句:Provider加載MediaProvider安裝在手機(jī)中,ContentResolver經(jīng)過acquireProvider懇求加載Provider程序。acquir

7、eProvider正是經(jīng)過解析URI中的authority字段,在安裝的package中查找與此authority相符的Provider,假設(shè)此Provider沒有被加載ActivityMangerService將加載Provider程序,這個(gè)過程可以參考我以前寫的Activity是如何加載的文章。 Provider究竟是加載到調(diào)用Provider的運(yùn)用程序還是將Provider程序加載到ActivityManagerService中作為 system Provider這個(gè)我不太確定是如何區(qū)分的,反正這兩種方式都是可行的,總之按照sdk help 文檔上的方式創(chuàng)建Provider程序,andr

8、oid會(huì)自動(dòng)加載的。記錄的保管與獲取當(dāng)Camera拍照完成或者是media play文件需求保管的時(shí)候,首先要構(gòu)造保管的數(shù)據(jù)構(gòu)造ContentValues values = new ContentValues(7);values.put(Images.Media.TITLE, imageName);values.put(Images.Media.DISPLAY_NAME, imageName);values.put(Images.Media.DESCRIPTION, description);values.put(Images.Media.DATE_TAKEN, dateTaken);valu

9、es.put(Images.Media.MIME_TYPE, image/jpeg);values.put(Images.Media.ORIENTATION, orientation);Uri uri = cr.insert(sStorageURI, values); /保管到數(shù)據(jù)庫sStorageURI = contentmedia/external/sdcard/media/Authority是 media所以將調(diào)用MediaProvider:insert,在insert中生成文件保管的途徑并放在key為_data項(xiàng)數(shù)據(jù)區(qū)。再經(jīng)過 ContentResolver訪問MediaProvide

10、r調(diào)用openFile翻開文件并將Image或media數(shù)據(jù)寫入。Camera,Image gallery運(yùn)用啟動(dòng)后不會(huì)掃描文件系統(tǒng)而是根據(jù)數(shù)據(jù)庫的記錄來進(jìn)展列表并顯示。這樣做無疑效率比較高。文件的刪除數(shù)據(jù)庫中保管有文件的途徑名,當(dāng)調(diào)用delete從數(shù)據(jù)庫中刪除一個(gè)記錄后,記錄中_data保管的文件名(絕對(duì)途徑)所指的文件也被刪除了。而在運(yùn)用程序中是找不到刪除文件的代碼,這個(gè)困擾了我兩天,在程序中加log,分析源代碼,最終屏蔽MediaProvider中的一段代碼找到了一點(diǎn)線索:public int delete(Uri uri, String userWhere, String whereA

11、rgs) int count;int match = URI_MATCHER.match(uri);.if (match != VOLUMES_ID) DatabaseHelper database = getDatabaseForUri(uri);if (database = null) throw new UnsupportedOperationException(Unknown URI: + uri);SQLiteDatabase db = database.getWritableDatabase();synchronized (sGetTableAndWhereParam) getTa

12、bleAndWhere(uri, match, userWhere, sGetTableAndWhereParam);switch (match) case AUDIO_MEDIA:case AUDIO_MEDIA_ID:count = db.delete(audio_meta,sGetTableAndWhereParam.where, whereArgs);break;default:/ count = db.delete(sGetTableAndWhereParam.table,/ sGetTableAndWhereParam.where, whereArgs);break;getCont

13、ext().getContentResolver().notifyChange(uri, null);.將上面紅色代碼注掉以后發(fā)現(xiàn)文件沒有被刪除,而紅色代碼只是對(duì)數(shù)據(jù)庫進(jìn)展操作,因此文件應(yīng)該是在去除數(shù)據(jù)庫的記錄時(shí)候被刪除的。仔細(xì)查看創(chuàng)建table的代碼發(fā)現(xiàn)幾個(gè)語句很奇異,由于沒有網(wǎng)絡(luò)去搜索一下關(guān)于android SQL的knowledge 只能猜測(cè)這個(gè)語句的意思了當(dāng)然也怪偶沒去學(xué)學(xué)SQL。 db.execSQL(CREATE TRIGGER IF NOT EXISTS images_cleanup DELETE ON images +BEGIN +DELETE FROM thumbnails

14、WHERE image_id = old._id; +SELECT _DELETE_FILE(old._data); +END);創(chuàng)建table為 images的觸發(fā)器,DELETE FROM thumbnails WHERE image_id = old._id正是刪除thumbnails的意思,對(duì)于Camera創(chuàng)建的Images會(huì)生成一個(gè)小圖片保管為thumbnail,這個(gè)記錄也是自動(dòng)去除的。 SELECT _DELETE_FILE(old._data); 應(yīng)該是刪除文件的意思。在Sqlite3_android.cpp文件中還真找到delete_file這個(gè)函數(shù),加上log,進(jìn)入galle

15、ry選擇一個(gè)文件刪除,打出了刪除文件名的全途徑。static void delete_file(sqlite3_context * context, int argc, sqlite3_value * argv).if (strncmp(/sdcard/, path, 8) != 0) /只能刪除sdcard/途徑下的東西要?jiǎng)h除其他路sqlite3_result_null(context); /還需略微改造一下return;如何將文件保管在手機(jī)上MediaProvider中存在兩個(gè)數(shù)據(jù)庫一個(gè)是external對(duì)應(yīng)文件系統(tǒng)為SD Card, 一個(gè)是內(nèi)部數(shù)據(jù)庫internal用于手機(jī)flash上的

16、文件系統(tǒng)。遺憾的是雖然MediaProvider提供了操作內(nèi)外兩個(gè)數(shù)據(jù)庫的功能,但在發(fā)布的運(yùn)用中并沒有運(yùn)用這個(gè)內(nèi)部文件系統(tǒng)。Android 默許形狀下Image,audio等文件是保管在SD card上。External, internal 數(shù)據(jù)庫都保管在手機(jī)文件系統(tǒng)上Path: /data/data/viders.media/database/假設(shè)要運(yùn)用內(nèi)部文件系統(tǒng)需求修正以下幾個(gè)地方1:MediaProvider generateFileName函數(shù)private String generateFileName(boolean internal, String

17、 preferredExtension, String directoryName)/ create a random fileString name = String.valueOf(System.currentTimeMillis();if (internal) throw new UnsupportedOperationException(Writing to internal storage is not supported.);/ return Environment.getDataDirectory()/ + / + directoryName + / + name + preferredExtension; else return Environment.getExternalStorageDirectory()+ / + directoryName + / + name + preferredExtension;恢復(fù)紅色部分代碼,將途徑設(shè)置為手機(jī)內(nèi)部文件系統(tǒng)文件夾。2:保管文件運(yùn)用的URI為contentmedia/internal/images/media/1紅色internal表名運(yùn)用內(nèi)部文件系統(tǒng)數(shù)據(jù)庫3:修正Sqlite3_android.cpp

溫馨提示

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

最新文檔

評(píng)論

0/150

提交評(píng)論