Android MediaScanner:(四)MediaScanner之scanSingleFile

來源:互聯網
上載者:User

田海立@csdn

2012-05-19

 

本文分析MediaScanner對單個檔案的掃描過程。單個檔案的掃描是MediaScanner的基礎,對路徑的掃描也要用到對Media檔案的掃描。本文從MediaScannerService的scanFile入口開始,詳細分析了MediaScanner和MediaScannerClient對單個媒體檔案的掃描處理過程。

 

一、MediaScannerService.scanFile()

上文對MediaScannerService的分析,知道對單個檔案的掃描是調用MediaScannerService.scanFile()完成的。下面看scanFile()的實現:

scanFile()中判斷如果是外部媒體檔案(只掃描外部媒體檔案),建立MediaScanner(定義在frameworks/base/media/java/android/media)執行個體,並設定locale資訊,然後調用MediaScanner的scanSingleFile()開始掃描。

二、MediaScanner.scanSingleFile()

 

MediaScanner.scanSingleFile()是具體的實現。看它完成的工作:

順序執行了

  •  initialize(); 3.1節中講解該方法的工作;
  •  prescan(); 3.2節中講解該方法的工作;
  •  MyMediaScannerClient.doScanFile() 3.3節中講解該方法的工作。

下面分章節著重講解這些方法裡面都做了哪些工作。

三、MediaScanner

位於/framework/base/media/java/android/media/。

3.1 MediaScanner.initialize(volumeName: String)

initialize()對MediaScanner的MediaProvider/Audio/Video/Image等媒體庫的URI進行初始化擷取,要擷取的屬性有下面這些:

另外,如果掃描的是外部volume,要處理playlist和genre,所以mProcessPlaylists和mProcessGenres被設定為true;建立mGenreCache;擷取Genres和playlists的URI。

3.2 MediaScanner.prescan()

  1. 從Audio、Video和Image各自的資料庫中分別讀取出這些媒體檔案資訊(ID,Path, Modified time),寫入mFileCache: HashMap<String,FileCacheEntry>中;
  2. 從Playlist資料庫中讀取出播放清單檔案資訊(ID,Path, Modified time),寫入mFileCache: HashMap<String,FileCacheEntry>中;

注意:新建立的FileCacheEntry的mSeenInFileSystem預設值為false。

3.3 MyMediaScannerClient.doScanFile()

MyMediaScannerClient是MediaScanner的內部類,實現了MediaScannerClient。

MyMediaScannerClient提供了doScanFile()方法供外部調用。另外實現了MediaScannerClient這個Interface,這個Interface在JNI實現中非常重要,講到那裡時再詳細闡述。

  •  doScanFile()中調用beginFile(),擷取FileType和MimeType資訊,並初始化內部結構;
  •  如果返回了FileCacheEntry,並且不是Image檔案,調用JNI方法processFile()解析到具體的檔案資訊在MyMediaScannerClient中;
  •  調用endFile()做後續的媒體庫更新等處理。

 

3.3.1 beginFile()

參數:path:String; mimeType: String; lastModified: long, fileSize: long

  1.  用MediaFile擷取FileType和MimeType,並分別賦值給mFileType和mMimeType;
  2.  從mFileCache中擷取(檔案已經在資料庫中了:3.2preScan()中已經把資料庫中的檔案都寫入到mFileCache),或產生新的entry:FileCacheEntry,加入到mFileCache中;
  3.  設定entry:FileCacheEntry的屬性mSeenInFileSystem為 true【掃描到了該檔案】;
  4.  如果是播放清單檔案,加入到mPlaylists:ArrayList<FileCacheEntry>中,並直接返回null;
  5.  為MyMediaScannerClient中的各個屬性(mArtist/ mAlbum / Artist / mAlbum / mTitle / mComposer / mGenre / mTrack / mYear /mDuration / mWriter / mCompliation)賦初值,為mPath / mLastModified賦值。返回 2)產生的FileCacheEntry的執行個體。
3.3.2 processFile()

JNI調用。詳細分析在文//TODO中。

3.3.3 endFile(entry: FileCacheEntry, …)

  • 1) 根據mFileType(Audio/Video/Images),選擇不同的資料庫,並把相應的URI賦值給entry.mTableUri;
  • 2) 寫入values:ContentValues資訊
    • ①分別用MediaScannerClient中的下面各個屬性值,初始化values:
    •  MediaStore.MediaColumns.DATA: mPath
    •  MediaStore.MediaColumns.TITLE: mTitle
    •  MediaStore.MediaColumns.DATE_MODIFIED: mLastModifed
    •  MediaStore.MediaColumns.SIZE: mFileSize
    •  MediaStore.MediaColumns.MIME_TYPE: mMimeType
    •  對於Video檔案

    o  MediaStore.MediaColumns.ARTIST: mArtist/MediaStore.UNKNOWN_STRING

    o  MediaStore.MediaColumns.ALBUM: mAlbum/ MediaStore.UNKNOWN_STRING

    o  MediaStore.MediaColumns.DURATION: mDuration

    •  對於Audio檔案

    o  MediaStore.MediaColumns.ARTIST: mArtist/MediaStore.UNKNOWN_STRING

    o  MediaStore.MediaColumns.ALBUM_ARTIST: mAlbumArtist/MediaStore.UNKNOWN_STRING

    o  MediaStore.MediaColumns.ALBUM: mAlbum/ MediaStore.UNKNOWN_STRING

    o  MediaStore.MediaColumns.COMPOSER: mComposer

    o  MediaStore.MediaColumns.YEAR: mYear

    o  MediaStore.MediaColumns.TRACK: mTrack

    o  MediaStore.MediaColumns.DURATION: mDuration

    o  MediaStore.MediaColumns.COMPILATION: mCompilation

      • ②對Title和Album做特殊處理
        •  如果Title為空白,從MediaStore.MediaColumns.DATA:mPath 中分離出檔案名稱(不含路徑和尾碼名),賦到value的MediaStore.MediaColumns.TITLE裡;
        •  如果Album為MediaStore.UNKNOWN_STRING也就是檔案中不含有Album資訊,把MediaStore.MediaColumns.DATA:mPath 的父目錄名賦到value的MediaStore.MediaColumns.ALBUM裡。

      • ③對於Audio和JPG檔案做一些特殊處理

      新加入的Audio,寫入下列資訊:

      •  MediaStore.Audio.Media.IS_RINGTONE: ringtones
      •  MediaStore.Audio.Media.IS_NOTIFICATION: notifications
      •  MediaStore.Audio.Media.IS_ALARM: alarms
      •  MediaStore.Audio.Media.IS_MUSIC: music
      •  MediaStore.Audio.Media.IS_PODCAST: podcasts

      對於JPG檔案,用android.media.ExifInterface獲得下列資訊:

      •  MediaStore.Images.Media.LATITUDE;
      •  MediaStore.Images.Media.LONGTITUDE;
      •  MediaStore.Images.Media.DATE_TAKEN: gps dateTime;
      •  MediaStore.Images.Media.ORIENTATION。
      • 3) 用2)中的values添加或更新1) 中URI指向的Audio/Video/Images資料庫
      • 4) 如果要處理Genres(判斷標誌mProcessGenres,外部媒體都要處理),
        1. 用Genre的名字mGenre查詢Genres的資料庫,更新或插入一條由把mGenre賦給MediaStore.Audio.Genres.NAME欄位組成的記錄到MediaStore.Audio.Genres資料庫中,並返回URI;
        2. 把 {genre, MediaStore.Audio.Genres.Members.CONTENT_DIRECTORY}加入mGenreCache:HashMap<String, Uri>中;
        3. 當前檔案所在媒體庫中的rowId賦值給MediaStore.Audio.Genres.Members.AUDIO_ID欄位,組成一條記錄插入到MediaStore.Audio.Genres.Members資料庫中。

      更新一個媒體檔案所屬的Genre,需要更新Genres資料庫,和Genres資料庫對應的記錄所在的Genres.Members資料庫。

      • 5) 對notification/ringtone/alarm進行處理
      • 如果是notification/ringtone/alarm,並且還未設定notification/ringtone/alarm,那麼設定Settings.System的Settings.System.NOTIFICATION_SOUND/ RINGTONE / ALARM_ALERT為媒體資料庫的Uri形式。

      • 6) 返回媒體資料庫的Uri。

       

      聯繫我們

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