Android多媒體圖片音頻視頻可限制大小時(shí)間自定義選擇器庫

項(xiàng)目中許多時(shí)候需要選擇圖片、音視頻送爸,并有大小和時(shí)間限制铛嘱,沒有找到合適的庫,所以自己提供一個(gè)滿足需求的基礎(chǔ)版本袭厂。
一.可以選擇圖片墨吓、音頻、視頻
二.可以限制選擇數(shù)量纹磺、音視頻大小帖烘、時(shí)長
三.可以進(jìn)行圖片、音視頻的預(yù)覽播放橄杨,指定每列顯示item個(gè)數(shù)
四.可以自定義過濾條件秘症,只顯示符合要求item

最新0.1.6版本:
1.優(yōu)化完善自定義過濾器

一.實(shí)現(xiàn)效果

在這里插入圖片描述

在這里插入圖片描述

在這里插入圖片描述

在這里插入圖片描述

可以設(shè)置顯示主題,默認(rèn)為深色主題

二.引用

1.Add it in your root build.gradle at the end of repositories

allprojects {
        repositories {
            ...
            maven { url 'https://jitpack.io' }
        }
    }

2.Add the dependency

dependencies {
            implementation 'com.github.MingYueChunQiu:MediaPicker:0.1.6'
    }

三.使用

1.基礎(chǔ)使用

最簡單的使用式矫,全部為默認(rèn)配置選擇圖片

        final ArrayList<String> list = new ArrayList<>();
        list.add(MediaSuffixType.VideoSuffixType.TYPE_MP4);
        tvTest.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                MediaPicker.init(MainActivity.this)
//                        .setMediaPickerConfig(new MediaPickerConfig.Builder()
//                                .setThemeConfig(new MediaPickerThemeConfig.Builder()
//                                        .buildDarkTheme())
//                                .setMediaPickerType(MediaPickerType.TYPE_VIDEO)
//                                .setLimitDuration(10 * 1000)
//                                .setLimitSize(10 * 1024 * 1024L)
//                                .setMaxSelectMediaCount(3)
//                                .setStartPreviewByThird(true)
//                                .setColumnCount(3)
//                                .setLimitSuffixTypeList(list)
//                                .setMediaPickerFilter(new MediaPickerFilter() {
//                                    @Override
//                                    public boolean filter(MediaInfo info) {
//                                        if (info.getSize() > 10 * 1024 * 1024L) {
//                                            return true;
//                                        }
//                                        return false;
//                                    }
//
//                                    @Override
//                                    public String getFilteredHint() {
//                                        return "測試";
//                                    }
//
//                                    @Override
//                                    public boolean hideFiltered() {
//                                        return false;
//                                    }
//                                })
//                                .setFilterLimitSuffixType(true)
//                                .setFilterLimitMedia(true)
//                                .build())
                        .pick();

獲取到的結(jié)果在

@Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (data != null && requestCode == MP_REQUEST_START_MEDIA_PICKER && resultCode == RESULT_OK) {
            ArrayList<MediaInfo> list = data.getParcelableArrayListExtra(EXTRA_PICKED_MEDIA_LIST);
            for (MediaInfo info : list) {
                Log.d("份", info.getTitle() + "   fds    " + info.getName() + " " + info.getFilePath() + " " +
                        info.getSize() + " " + info.getDuration() + " " + info.getBucketId() + " "
                        + info.getBucketName());
            }
        }
    }

結(jié)果存儲在MediaInfo中

public class MediaInfo:
    private String title;//標(biāo)題
    private String name;//名稱(帶擴(kuò)展名)
    private MediaPickerType type;//多媒體類型
    private String suffixType;//后綴名類型(例如:.mp4)
    private String filePath;//視頻路徑
    private String thumbnail;//縮略圖
    private long addDate;//添加到Media Provider的時(shí)間
    private long duration;//時(shí)長
    private long size;//大小
    private String bucketId;//多媒體所屬文件夾ID
    private String bucketName;//多媒體所屬文件夾名稱

在MediaPicker主要是提供MediaPickerControlable接口實(shí)例乡摹,默認(rèn)提供的是MediaPickerControl子類

public class MediaPicker {

 private static final MediaPicker INSTANCE;//單例
    private MediaPickerControlable mControl;

    private MediaPicker() {
    }

    static {
        INSTANCE = new MediaPicker();
    }

    public static MediaPickerControlable init(@NonNull Activity activity) {
        return init(activity, new MediaPickerStore(activity), null);
    }

    public static MediaPickerControlable init(@NonNull Activity activity, MediaPickerStoreable store,
                                              MediaPickerInterceptable intercept) {
        INSTANCE.mControl = new MediaPickerControl(activity, store, intercept);
        return INSTANCE.mControl;
    }

    public static MediaPickerControlable init(@NonNull Fragment fragment) {
        return init(fragment, new MediaPickerStore(fragment), null);
    }

    public static MediaPickerControlable init(@NonNull Fragment fragment, MediaPickerStoreable store,
                                              MediaPickerInterceptable intercept) {
        INSTANCE.mControl = new MediaPickerControl(fragment, store, intercept);
        return INSTANCE.mControl;
    }

    public static MediaPicker getInstance() {
        return INSTANCE;
    }

    public MediaPickerControlable getMediaPickerControl() {
        return INSTANCE.mControl;
    }

    public static ImageEngine getImageEngine() {
        return INSTANCE.mControl.getImageEngine();
    }

    public static MediaPickerFilter getMediaPickerFilter() {
        return INSTANCE.mControl.getMediaPickerStore().getMediaPickerConfig().getMediaPickerFilter();
    }
}

在拿到MediaPickerControlable后,設(shè)置相關(guān)配置采转,MediaPickerControlable里持有MediaPickerStoreable接口聪廉,默認(rèn)提供的子類實(shí)現(xiàn)是MediaPickerStore,MediaPickerStore主要是用來持有MediaPickerConfig,進(jìn)行配置設(shè)置板熊。

MediaPickerControlable包裹MediaPickerStoreable框全,使用與實(shí)現(xiàn)中間層攔截器,方便實(shí)現(xiàn)中間額外操作邻邮,所以提供MediaPickerInterceptable接口竣况,默認(rèn)提供了MediaPickerIntercept空實(shí)現(xiàn)子類,可以對所有方法進(jìn)行攔截監(jiān)聽

2.MediaPickerControlable

public interface MediaPickerControlable {

    MediaPickerControlable setMediaPickerConfig(MediaPickerConfig config);

    MediaPickerControlable setMediaPickerIntercept(MediaPickerInterceptable intercept);

    ImageEngine getImageEngine();

    MediaPickerFilter getMediaPickerFilter();

    MediaPickerStoreable getMediaPickerStore();

    void pick();

    void release();
}

3.MediaPickerStoreable

public interface MediaPickerStoreable {

    MediaPickerStoreable setMediaPickerConfig(MediaPickerConfig config);

    MediaPickerConfig getMediaPickerConfig();

    void pick();

    void release();
}

4.MediaPickerConfig

MediaPickerStore實(shí)現(xiàn)類里會持有MediaPickerConfig

private MediaPickerType mediaPickerType;//多媒體選擇類型

    private int maxSelectMediaCount;//最多可選擇多媒體個(gè)數(shù)

    private long limitSize;//限制大型惭稀(單位B)

    private long limitDuration;//限制時(shí)長(毫秒)

    private List<String> limitSuffixTypeList;//限制只能顯示的多媒體后綴類型列表

    private MediaPickerFilter mediaPickerFilter;//多媒體過濾器

    private boolean filterLimitSuffixType;//是否過濾超出后綴名類型限制的多媒體

    private boolean filterLimitMedia;//是否過濾超出限制的多媒體信息

    private int columnCount;//一行列數(shù)

    private int loadAnimation;//Item加載動畫

    private boolean startPreviewByThird;//以第三方應(yīng)用方式打開預(yù)覽多媒體

    private MediaPickerThemeConfig themeConfig;//主題配置

    private ImageEngine engine;//圖片加載引擎

可以通過startPreviewByThird來設(shè)置是否通過調(diào)用第三方應(yīng)用來預(yù)覽丹泉,默認(rèn)是庫自帶的預(yù)覽效果,目前設(shè)置后只有視頻可以打開調(diào)用其他第三方應(yīng)用預(yù)覽鸭蛙。

在MediaPickerConfig里可以配置界面主題深色和淺色摹恨,默認(rèn)為深色,同時(shí)也可以自定義設(shè)置

filterLimitSuffixType是和limitSuffixTypeList配合使用娶视,filterLimitMedia和時(shí)長晒哄、大小與自定義配合使用

public class MediaPickerThemeConfig:

    private int themeType;//主題類型(淺色或深色,請?jiān)O(shè)置此類時(shí)一定要配置涉及到狀態(tài)欄配置肪获,默認(rèn)為深色)

    private @ColorInt
    int topBackgroundColor;//頂部背景顏色

    private @ColorInt
    int bottomBackgroundColor;//底部背景顏色

    private @ColorInt
    int topTextColor;//頂部文字顏色

    private @ColorInt
    int bottomTextColor;//底部文字顏色

    private @DrawableRes
    int backIconResId;//返回Icon資源ID

    private @DrawableRes
    int upTriangleIconResId;//向上三角Icon資源ID

    private @DrawableRes
    int downTriangleIconResId;//向下三角Icon資源ID

MediaPickerThemeConfig默認(rèn)提供了buildLightTheme和buildDarkTheme

/**
         * 創(chuàng)建默認(rèn)淺色主題配置信息
         *
         * @return 返回淺色主題配置信息對象
         */
        public MediaPickerThemeConfig buildLightTheme() {
            mConfig.topBackgroundColor = Color.WHITE;
            mConfig.bottomBackgroundColor = Color.parseColor("#33000000");
            mConfig.topTextColor = Color.BLACK;
            mConfig.bottomTextColor = Color.BLACK;
            mConfig.backIconResId = R.drawable.mp_back_dark;
            mConfig.upTriangleIconResId = R.drawable.mp_up_triangle_dark;
            mConfig.downTriangleIconResId = R.drawable.mp_down_triangle_dark;
            mConfig.themeType = Constants.ThemeTypeConstants.TYPE_LIGHT;
            return mConfig;
        }

        /**
         * 創(chuàng)建默認(rèn)深色主題配置信息
         *
         * @return 返回深色主題配置信息對象
         */
        public MediaPickerThemeConfig buildDarkTheme() {
            mConfig.topBackgroundColor = Color.parseColor("#2C2C34");
            mConfig.bottomBackgroundColor = Color.parseColor("#2C2C34");
            mConfig.topTextColor = Color.WHITE;
            mConfig.bottomTextColor = Color.WHITE;
            mConfig.backIconResId = R.drawable.mp_back_light;
            mConfig.upTriangleIconResId = R.drawable.mp_up_triangle_light;
            mConfig.downTriangleIconResId = R.drawable.mp_down_triangle_light;
            mConfig.themeType = Constants.ThemeTypeConstants.TYPE_DARK;
            return mConfig;
        }

自定義過濾器MediaPickerFilter

public interface MediaPickerFilter {

    /**
     * 設(shè)置條件過濾多媒體Item
     *
     * @param info 多媒體信息對象
     * @return 滿足過濾條件的Item返回true寝凌,否則返回false
     */
    boolean filter(MediaInfo info);

    /**
     * 獲取選擇過濾Item時(shí)的提示文本(在hideFiltered為false時(shí),使用才有效)
     * 返回null或""無效孝赫,不設(shè)置時(shí)较木,默認(rèn)顯示"該項(xiàng)已被過濾,不能選擇"
     * 可以使用MediaPickerFilterAdapter青柄,提供了默認(rèn)實(shí)現(xiàn)伐债,只重新自己需要的方法
     *
     * @return 返回提示字符串
     */
    String getFilteredHint();

    /**
     * 隱藏被過濾的Item
     *
     * @return 返回true表示隱藏,否則返回false
     */
    boolean hideFiltered();
}

同時(shí)可以直接使用MediaPickerFilterAdapter致开,它實(shí)現(xiàn)了MediaPickerFilter峰锁,提供默認(rèn)實(shí)現(xiàn)

public class MediaPickerFilterAdapter implements MediaPickerFilter {

    @Override
    public boolean filter(MediaInfo info) {
        return false;
    }

    @Override
    public String getFilteredHint() {
        return null;
    }

    @Override
    public boolean hideFiltered() {
        return false;
    }
}

庫同時(shí)還提供了MediaUtils工具類,里面有許多工具方法双戳,可以直接在任何地方直接調(diào)用

/**
     * 啟動選擇本地圖片界面
     *
     * @param activity    啟動界面
     * @param requestCode 啟動請求碼
     */
    public static void startPickImage(@NonNull Activity activity, int requestCode) {
    }

    /**
     * 啟動選擇本地圖片界面
     *
     * @param fragment    啟動界面
     * @param requestCode 啟動請求碼
     */
    public static void startPickImage(@NonNull Fragment fragment, int requestCode) {
    }

    /**
     * 啟動選擇本地視頻界面
     *
     * @param activity    啟動界面
     * @param requestCode 啟動請求碼
     */
    public static void startPickVideo(@NonNull Activity activity, int requestCode) {
    }

    /**
     * 啟動選擇本地視頻界面
     *
     * @param fragment    啟動界面
     * @param requestCode 啟動請求碼
     */
    public static void startPickVideo(@NonNull Fragment fragment, int requestCode) {
    }

/**
     * 查詢系統(tǒng)數(shù)據(jù)庫地址中視頻信息
     *
     * @param resolver Android組件
     * @param uri      視頻本地地址
     * @return 如果成功獲取數(shù)據(jù)虹蒋,則返回MediaInfo,否則返回null
     */
    @Nullable
    public static MediaInfo queryVideoInfo(@NonNull ContentResolver resolver, @NonNull Uri uri) {
    }

    /**
     * 根據(jù)縮略圖路徑獲取縮略圖
     *
     * @param path 縮略圖路徑
     * @return 返回生成的縮略圖
     */
    public static Bitmap getThumbnail(String path) {
    }

    /**
     * 設(shè)置視頻播放聲音
     *
     * @param volume 聲音音量(0--1)
     * @param o      播放的對象
     */
    public static void setVolume(float volume, Object o) {
    }

    /**
     * 獲取圖片資源
     *
     * @param context  上下文
     * @param callback 瀏覽資源回調(diào)
     */
    public static void getImages(final Context context, BrowseMediaInfoCallback callback) {
    }

/**
     * 獲取音頻資源
     *
     * @param context  上下文
     * @param callback 瀏覽資源回調(diào)
     */
    public static void getAudios(final Context context, BrowseMediaInfoCallback callback) {
    }

/**
     * 獲取視頻資源
     *
     * @param context  上下文
     * @param callback 瀏覽資源回調(diào)
     */
    public static void getVideos(final Context context, BrowseMediaInfoCallback callback) {
    }

@NonNull
    private static Intent getPickImageIntent() {
    }

    /**
     * 獲取選擇視頻的啟動意圖
     *
     * @return 返回啟動意圖
     */
    @NonNull
    private static Intent getPickVideoIntent() {
    }

 /**
     * 瀏覽多媒體信息回調(diào)
     */
    public interface BrowseMediaInfoCallback {

        /**
         * 當(dāng)準(zhǔn)備瀏覽多媒體信息時(shí)調(diào)用
         */
        void onPrepareBrowseMediaInfo();

        /**
         * 當(dāng)開始瀏覽多媒體信息時(shí)調(diào)用
         *
         * @param count 多媒體總數(shù)
         */
        void onStartBrowseMediaInfo(int count);

        /**
         * 瀏覽多媒體資源信息時(shí)調(diào)用
         *
         * @param index 瀏覽的索引位置
         * @param info  多媒體信息數(shù)據(jù)
         */
        void onBrowseMediaInfo(int index, @NonNull MediaInfo info);

        /**
         * 當(dāng)結(jié)束瀏覽多媒體信息時(shí)回調(diào)
         */
        void onEndBrowseMediaInfo();
    }

5.圖片引擎

用戶可以設(shè)置ImageEngine

                MediaPicker.init(MainActivity.this)
                        .setMediaPickerConfig(new MediaPickerConfig.Builder()
                                .setImageEngine(new GlideEngine())
                                .build())
                        .pick();

ImageEngine 接口如下飒货,默認(rèn)提供了GlideEngine千诬,如果和項(xiàng)目有沖突,可以用自己的圖片引擎替換

public interface ImageEngine {

    /**
     * 顯示圖片
     *
     * @param context       上下文
     * @param file          顯示圖片
     * @param placeholderId 占位圖資源
     * @param errorId       錯(cuò)誤圖資源
     * @param imageView     顯示控件
     */
    void showImage(Context context, File file,
                   @DrawableRes int placeholderId, @DrawableRes int errorId, ImageView imageView);

    /**
     * 顯示圖片
     *
     * @param fragment      界面
     * @param file          顯示圖片
     * @param placeholderId 占位圖資源
     * @param errorId       錯(cuò)誤圖資源
     * @param imageView     顯示控件
     */
    void showImage(Fragment fragment, File file,
                   @DrawableRes int placeholderId, @DrawableRes int errorId, ImageView imageView);
}

四.總結(jié)

目前用戶所需要使用的源碼都在上面膏斤,其他預(yù)覽相關(guān)代碼就暫不介紹,庫剛出來邪驮,如果有什么疑問或建議歡迎提出莫辨,Github地址:https://github.com/MingYueChunQiu/MediaPicker.git , 碼云地址:https://gitee.com/MingYueChunQiu/MediaPicker.git ,感謝你的支持沮榜,如果不介意請Github點(diǎn)個(gè)star盘榨,謝謝。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末蟆融,一起剝皮案震驚了整個(gè)濱河市草巡,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌型酥,老刑警劉巖山憨,帶你破解...
    沈念sama閱讀 216,692評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異弥喉,居然都是意外死亡郁竟,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,482評論 3 392
  • 文/潘曉璐 我一進(jìn)店門由境,熙熙樓的掌柜王于貴愁眉苦臉地迎上來棚亩,“玉大人,你說我怎么就攤上這事虏杰〖ン。” “怎么了?”我有些...
    開封第一講書人閱讀 162,995評論 0 353
  • 文/不壞的土叔 我叫張陵纺阔,是天一觀的道長瘸彤。 經(jīng)常有香客問我,道長州弟,這世上最難降的妖魔是什么钧栖? 我笑而不...
    開封第一講書人閱讀 58,223評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮婆翔,結(jié)果婚禮上拯杠,老公的妹妹穿的比我還像新娘。我一直安慰自己啃奴,他們只是感情好潭陪,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,245評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著最蕾,像睡著了一般依溯。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上瘟则,一...
    開封第一講書人閱讀 51,208評論 1 299
  • 那天黎炉,我揣著相機(jī)與錄音,去河邊找鬼醋拧。 笑死慷嗜,一個(gè)胖子當(dāng)著我的面吹牛淀弹,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播庆械,決...
    沈念sama閱讀 40,091評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼薇溃,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了缭乘?” 一聲冷哼從身側(cè)響起沐序,我...
    開封第一講書人閱讀 38,929評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎堕绩,沒想到半個(gè)月后策幼,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,346評論 1 311
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡逛尚,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,570評論 2 333
  • 正文 我和宋清朗相戀三年垄惧,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片绰寞。...
    茶點(diǎn)故事閱讀 39,739評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡到逊,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出滤钱,到底是詐尸還是另有隱情觉壶,我是刑警寧澤,帶...
    沈念sama閱讀 35,437評論 5 344
  • 正文 年R本政府宣布件缸,位于F島的核電站铜靶,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏他炊。R本人自食惡果不足惜争剿,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,037評論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望痊末。 院中可真熱鬧蚕苇,春花似錦、人聲如沸凿叠。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,677評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽盒件。三九已至蹬碧,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間炒刁,已是汗流浹背恩沽。 一陣腳步聲響...
    開封第一講書人閱讀 32,833評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留翔始,地道東北人飒筑。 一個(gè)月前我還...
    沈念sama閱讀 47,760評論 2 369
  • 正文 我出身青樓片吊,卻偏偏與公主長得像,于是被迫代替她去往敵國和親协屡。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,647評論 2 354

推薦閱讀更多精彩內(nèi)容

  • Swift1> Swift和OC的區(qū)別1.1> Swift沒有地址/指針的概念1.2> 泛型1.3> 類型嚴(yán)謹(jǐn) 對...
    cosWriter閱讀 11,097評論 1 32
  • 走路去土馬會議的第二周全谤,路過海事大學(xué)肤晓,滿樹的櫻花都開了,粉粉的认然。 大連的春天還是有點(diǎn)冷补憾,粉粉的櫻花,讓傍晚的涼絲絲...
    Rose姚閱讀 395評論 1 0
  • 作者大前研一從前言“思考差距化”的時(shí)代作為導(dǎo)入卷员,解釋了此本書的創(chuàng)作背景盈匾。 “世界經(jīng)濟(jì)急劇變化,此次變化的本質(zhì)是新經(jīng)...
    桃白白ALEX閱讀 697評論 0 4
  • 總會有人說毕骡,要一直向前看削饵,往前走,不知你有沒有回過頭來未巫,一眼望去那一整個(gè)曾經(jīng)窿撬。 前兩天同學(xué)聚會,見到了以前的人叙凡,自...
    糖果糖糖閱讀 111評論 0 1