同步系統媒體庫到App 本地(AsyMediaLib)
簡介
AsyMediaLib
是一個可以將媒體資料庫中的圖片和視訊資訊同步到App本地的一個工具。當媒體庫中的圖片或視訊資訊發生變化,AsyMediaLib
會同步更新本地的媒體庫資訊。
特點
- 同步手機中媒體庫中的圖片到App本地
- 監聽並同步媒體庫中圖片和視訊的變化並同步本地
- 當媒體庫中圖片和視訊資訊非常龐大的時,同步不會造成OOM
- 可以設定同步圖片和視訊的大小範圍
AsyMediaLib Github 地址 (https://github.com/MrChao1991/AsyMediaDemo)
使用方法
將AsyMediaLib
新增到工程中
下載AsyMediaLib
, 依賴到專案中, 很簡單不介紹。
實現本地媒體資料表的對映類
實現本地媒體資料對映類一定要繼承MediaInfo
, 在MediaInfo
中封裝了系統媒體庫中圖片和視訊的所有資訊欄位。
MediaInfo
中包含的欄位:
public class MediaInfo implements Parcelable { private int id; private int mediaId; private String name; private String title; private String path; private String type; private long time; private long duration; private String resolution; private int width; private int height; private long size; private String album; private String folder; ........ }
既然MediaInfo
都有這些資訊為什麼還要繼承呢? 主要是為了擴充套件考慮, 比如Demo
中需要新增一個建立時間的欄位。
public class LocalMediaInfo extends MediaInfo { private long createTime; public long getCreateTime() { return createTime; } public void setCreateTime(long createTime) { this.createTime = createTime; } }
很容易就新增上。
CursorWrapper
這裡要先說一下CursorWrapper
,這個類包裝了Cursor
。
CursorWrapper
具體實現如下:
public class CursorWrapper { public Cursor cursor; public void close() { if (cursor != null) { cursor.close(); cursor = null; } } public CursorWrapper(Cursor cursor) { this.cursor = cursor; this.cursor.moveToFirst(); } public static CursorWrapper create(Cursor cursor) { return new CursorWrapper(cursor); } }
實現本地媒體資料表的控制類
實現本地媒體資料表的控制類要繼承AbsUDatabaseController<T>
, 這個控制類主要是負責給AsyMediaLib
庫提供對本地媒體資料操作具體實現。
必須實現下面幾個方法:
-
public T createMediaInfo()
建立本地資料表對映類
返回值:
T
對映物件 -
public T cursorToMediaBean(Cursor cursor, T t)
將
引數:Cursor
中的資料轉換成對映物件cursor
: 資料庫遊標t
:對映物件返回值:
T
: 對映物件。該對映物件最好使用引數中傳入的對映物件。 -
public int getMediaId(CursorWrapper cursorWrapper)
獲取當前
Cursor
中的MediaId
, 這個MediaId
, 必須和手機媒體庫中的_id
相對應。引數:
cursorWrapper
: 是包裝了Cursor
的實體物件。通過其中的Cursor
物件獲取本地資料庫中對應的Id
. -
public void insert(Context context, MediaInfo mediaInfo)
向App應用中插入媒體資料
MediaInfo
。引數:
MediaInfo
是從系統媒體庫中獲取的資料. -
public void deleteForList(Context context, List<MediaInfo> medias)
批量刪除媒體資料MediaInfo
, 本地資料庫中的資料和系統媒體資料庫中的資料不同步時,會呼叫這個方法刪除本地多餘的媒體資料。 -
public void updateForList(Context context, List<MediaInfo> medias)
批量修改媒體資料MediaInfo
,本地資料庫中的資料和系統媒體資料庫中的資料不同步時,會呼叫這個方修改本地變化的媒體資料。 -
public void insertForList(Context context, List<MediaInfo> medias)
批量插入媒體資料MediaInfo
,本地資料庫中的資料和系統媒體資料庫中的資料不同步時,會呼叫這個方法插入新的媒體資料。 -
public CursorWrapper queryImage(Context context, int startMediaId, int rowNum)
查詢同步的本地媒體庫中圖片資料。
引數:startMediaId
:每次查詢起始的MediaId
rowNum
:每次查詢的條數 -
public CursorWrapper queryVideo(Context context, int startMediaId, int rowNum)
查詢同步的本地媒體庫中視訊資料。
引數:startMediaId
:每次查詢起始的MediaId
rowNum
:每次查詢的條數 -
public CursorWrapper queryImageAndVideo(Context context, int startMediaId, int rowNum)
查詢同步的本地媒體庫中圖片和視訊資料。
引數:startMediaId
:每次查詢起始的MediaId
rowNum
:每次查詢的條數
上面的方法必須按照要求實現。如果有不清楚請參考Demo
下面介紹三個非必須實現的方法:
public CursorWrapper queryImageAndVideo(Context context, int imageMinSize, int imageMaxSize, int videoMinSize, int videMaxSzie, int startMediaId, int rowNum) public CursorWrapper queryImage(Context context, int minSuze, int maxSize, int startMediaId, int rowNum) public CursorWrapper queryVideo(Context context, int minSuze, int maxSize, int startMediaId, int rowNum)
這三個方法增加了對查詢媒體檔案資訊最大和最小的限制。
實現資料校驗規則類
校驗規則也要進行自定義,在實際開發中結合具體場景進行實現。
自定義校驗規則要實現CheckRule
介面,這個校驗規則要必須實現。
CheckRule
原始碼如下:
public interface CheckRule<T extends MediaInfo> { boolean checkUpdate(T localBean, MediaInfo mediaInfo); }
必要配置
AsyMediaLib
的配置也很簡單,下面看一下Demo
中的配置示例。
AsyMediaDatabase amd = AsyMediaDatabase .create(this) .setUDatabaseControl(new LocalDatabaseController()) .setCheckRule(new CheckRule<LocalMediaInfo>() { @Override public boolean checkUpdate(LocalMediaInfo localBean, MediaInfo mediaInfo) { Log.e(TAG, "checkUpdate: " + "local id:" + localBean.getMediaId() + "media id:" + mediaInfo.getMediaId() + "update: " + !localBean.getPath().equals(mediaInfo.getPath())); return !localBean.getPath().equals(mediaInfo.getPath()); } }) .setQueryOnceRowNumber(10) .setCacheSizeDelete(20) .setCacheSizeUpdate(30) .setCacheSizeInsert(40) .setFilterMinImageSize(39999) .setFilterMaxImageSize(500000) .setFilterMinVideoSize(1024) .setFilterMaxVideoSize(1024 * 100000) .build();
所有的配置都在一個Build
類中完成,AsyMediaDatabase.create(this)
建立一個Build
, 最後呼叫build()
方法進行配置。實現方法不多介紹,感興趣可以去看原始碼。
設定API介紹
-
setUDatabaseControl(AbsUDatabaseController UDatabaseControl)
設定本地對映實體類。 -
setCheckRule(CheckRule mCheckRule)
設定本地和手機系統媒體資訊校驗規則 -
setQueryOnceRowNumber(int mQueryOnceRowNumber)
設定每次查詢資料條數 -
setFilterMinImageSize(int mFilterMinImageSize)
設定查詢時圖片最小size -
setFilterMaxImageSize(int mFilterMaxImageSize)
設定查詢時圖片最大size -
setFilterMinVideoSize(int mFilterMinVideoSize)
設定查詢時視訊最小size -
setFilterMaxVideoSize(int mFilterMaxVideoSize)
設定查詢時視訊最大size -
setCacheSizeInsert(int mCacheSizeInsert)
,setCacheSizeUpdate(int mCacheSizeUpdate)
,setCacheSizeDelete(int mCacheSizeDelete)
設定在同步的時候,批量插入,修改,刪除快取的大小。設定的大小,為快取的條數。
為什麼會有這個快取,因為在同步的時候,可能有很多資料需要插入,刪除和修改的資料,不能發現一條,操作一條,所以,採用一個快取的方式,達到這個快取的極限後,會進行批量操作, 所以在實現本地資料庫控制類的時候,在多條資料操作的時候記得使用事務進行操作。 -
openDebug()
開啟debug。
註冊系統媒體庫變化監聽
註冊監聽非常簡單, 上面的配置完成後,register()
即可以啟動監聽。
AsyMediaDatabase amd = AsyMediaDatabase ..... // 省略配置程式碼 .build(); amd.register();
同步系統媒體庫到本地
同步系統媒體庫到本地非常簡單, 上面的配置完成後,asyMedia()
即可以啟動同步。
AsyMediaDatabase amd = AsyMediaDatabase ..... // 省略配置程式碼 .build(); amd.asyMedia();
上面是對AsyMediaLib
這個庫使用的簡單介紹,可能介紹不是很詳細,請參考Demo
以上內容如果發現有問題,歡迎指正,共同學習,共同進步