Full Code of imLibo/FilePicker for AI

master fc3e85b07e3a cached
129 files
307.1 KB
77.0k tokens
532 symbols
1 requests
Download .txt
Showing preview only (351K chars total). Download the full file or copy to clipboard to get everything.
Repository: imLibo/FilePicker
Branch: master
Commit: fc3e85b07e3a
Files: 129
Total size: 307.1 KB

Directory structure:
gitextract_v173hlks/

├── .gitignore
├── .idea/
│   ├── caches/
│   │   └── build_file_checksums.ser
│   ├── codeStyles/
│   │   └── Project.xml
│   ├── copyright/
│   │   └── Ess.xml
│   ├── gradle.xml
│   ├── misc.xml
│   ├── modules.xml
│   ├── runConfigurations.xml
│   └── vcs.xml
├── APK/
│   └── release/
│       └── filepicker-demo.apk
├── LICENSE
├── README.md
├── app/
│   ├── .gitignore
│   ├── build.gradle
│   ├── proguard-rules.pro
│   └── src/
│       ├── androidTest/
│       │   └── java/
│       │       └── com/
│       │           └── ess/
│       │               └── essfilepicker/
│       │                   └── ExampleInstrumentedTest.java
│       ├── main/
│       │   ├── AndroidManifest.xml
│       │   ├── java/
│       │   │   └── com/
│       │   │       └── ess/
│       │   │           └── essfilepicker/
│       │   │               ├── FragmentTestActivity.java
│       │   │               ├── LApplication.java
│       │   │               ├── MainActivity.java
│       │   │               └── TestFragment.java
│       │   └── res/
│       │       ├── drawable/
│       │       │   └── ic_launcher_background.xml
│       │       ├── drawable-v24/
│       │       │   └── ic_launcher_foreground.xml
│       │       ├── layout/
│       │       │   ├── activity_fragment_test.xml
│       │       │   ├── activity_main.xml
│       │       │   └── fragment_test.xml
│       │       ├── mipmap-anydpi-v26/
│       │       │   ├── ic_launcher.xml
│       │       │   └── ic_launcher_round.xml
│       │       └── values/
│       │           ├── colors.xml
│       │           ├── strings.xml
│       │           └── styles.xml
│       └── test/
│           └── java/
│               └── com/
│                   └── ess/
│                       └── essfilepicker/
│                           └── ExampleUnitTest.java
├── build.gradle
├── filepicker/
│   ├── .gitignore
│   ├── build.gradle
│   ├── proguard-rules.pro
│   └── src/
│       ├── androidTest/
│       │   └── java/
│       │       └── com/
│       │           └── ess/
│       │               └── filepicker/
│       │                   └── ExampleInstrumentedTest.java
│       ├── main/
│       │   ├── AndroidManifest.xml
│       │   ├── java/
│       │   │   └── com/
│       │   │       └── ess/
│       │   │           └── filepicker/
│       │   │               ├── BaseFileFragment.java
│       │   │               ├── FilePicker.java
│       │   │               ├── SelectCreator.java
│       │   │               ├── SelectOptions.java
│       │   │               ├── activity/
│       │   │               │   ├── FileTypeListFragment.java
│       │   │               │   ├── PicturesViewActivity.java
│       │   │               │   ├── SelectFileByBrowserActivity.java
│       │   │               │   ├── SelectFileByScanActivity.java
│       │   │               │   └── SelectPictureActivity.java
│       │   │               ├── adapter/
│       │   │               │   ├── BreadAdapter.java
│       │   │               │   ├── BuketAdapter.java
│       │   │               │   ├── EssMediaAdapter.java
│       │   │               │   ├── FileListAdapter.java
│       │   │               │   ├── FragmentPagerAdapter.java
│       │   │               │   ├── OnFileSelectListener.java
│       │   │               │   └── SelectSdcardAdapter.java
│       │   │               ├── loader/
│       │   │               │   ├── EssAlbumCollection.java
│       │   │               │   ├── EssAlbumLoader.java
│       │   │               │   ├── EssMediaCollection.java
│       │   │               │   ├── EssMediaLoader.java
│       │   │               │   ├── EssMimeTypeCollection.java
│       │   │               │   └── EssMimeTypeLoader.java
│       │   │               ├── model/
│       │   │               │   ├── Album.java
│       │   │               │   ├── BreadModel.java
│       │   │               │   ├── CaptureStrategy.java
│       │   │               │   ├── EssFile.java
│       │   │               │   ├── EssFileCountCallBack.java
│       │   │               │   ├── EssFileFilter.java
│       │   │               │   ├── EssFileListCallBack.java
│       │   │               │   ├── EssFileProvider.java
│       │   │               │   ├── FileScanActEvent.java
│       │   │               │   ├── FileScanFragEvent.java
│       │   │               │   └── FileScanSortChangedEvent.java
│       │   │               ├── task/
│       │   │               │   ├── EssFileCountTask.java
│       │   │               │   └── EssFileListTask.java
│       │   │               ├── util/
│       │   │               │   ├── Const.java
│       │   │               │   ├── ConvertUtils.java
│       │   │               │   ├── DateUtils.java
│       │   │               │   ├── DialogUtil.java
│       │   │               │   ├── FileSizeUtil.java
│       │   │               │   ├── FileUtils.java
│       │   │               │   ├── LogUtils.java
│       │   │               │   ├── MediaStoreCompat.java
│       │   │               │   ├── MimeType.java
│       │   │               │   ├── PathUtils.java
│       │   │               │   ├── PhotoMetadataUtils.java
│       │   │               │   ├── Platform.java
│       │   │               │   └── UiUtils.java
│       │   │               └── widget/
│       │   │                   ├── MediaItemDecoration.java
│       │   │                   └── ToolbarSpinner.java
│       │   └── res/
│       │       ├── color/
│       │       │   ├── dracula_bottom_toolbar_apply.xml
│       │       │   ├── dracula_bottom_toolbar_preview.xml
│       │       │   ├── dracula_preview_bottom_toolbar_apply.xml
│       │       │   ├── elec_bottom_toolbar_apply.xml
│       │       │   ├── elec_bottom_toolbar_preview.xml
│       │       │   └── elec_preview_bottom_toolbar_apply.xml
│       │       ├── drawable/
│       │       │   └── bg_bottom_line_gray.xml
│       │       ├── layout/
│       │       │   ├── activity_pictures_detail.xml
│       │       │   ├── activity_select_file.xml
│       │       │   ├── activity_select_file_by_scan.xml
│       │       │   ├── activity_select_picture.xml
│       │       │   ├── bread_item.xml
│       │       │   ├── buket_list_item.xml
│       │       │   ├── empty_file_list.xml
│       │       │   ├── ess_media_item.xml
│       │       │   ├── fragment_file_type_list.xml
│       │       │   ├── item_capture.xml
│       │       │   ├── item_file_list.xml
│       │       │   ├── item_select_sdcard.xml
│       │       │   ├── loading_layout.xml
│       │       │   └── pop_select_sdcard.xml
│       │       ├── layout-v21/
│       │       │   ├── activity_select_file.xml
│       │       │   └── bread_item.xml
│       │       ├── menu/
│       │       │   ├── browse_menu.xml
│       │       │   └── media_menu.xml
│       │       ├── values/
│       │       │   ├── attrs.xml
│       │       │   ├── colors.xml
│       │       │   ├── colors_dracula.xml
│       │       │   ├── colors_zhihu.xml
│       │       │   ├── dimens.xml
│       │       │   ├── strings.xml
│       │       │   └── styles.xml
│       │       ├── values-v21/
│       │       │   └── styles.xml
│       │       └── xml/
│       │           └── provider_paths.xml
│       └── test/
│           └── java/
│               └── com/
│                   └── ess/
│                       └── filepicker/
│                           └── ExampleUnitTest.java
├── filepicker.jks
├── gradle/
│   └── wrapper/
│       ├── gradle-wrapper.jar
│       └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
└── settings.gradle

================================================
FILE CONTENTS
================================================

================================================
FILE: .gitignore
================================================
.gradle
/local.properties
/.idea/workspace.xml
/.idea/libraries
.DS_Store
/build
/captures
.externalNativeBuild
bintrayKey
gradle.properties
*.iml

================================================
FILE: .idea/codeStyles/Project.xml
================================================
<component name="ProjectCodeStyleConfiguration">
  <code_scheme name="Project" version="173">
    <Objective-C-extensions>
      <file>
        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Import" />
        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Macro" />
        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Typedef" />
        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Enum" />
        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Constant" />
        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Global" />
        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Struct" />
        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="FunctionPredecl" />
        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Function" />
      </file>
      <class>
        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Property" />
        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Synthesize" />
        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InitMethod" />
        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="StaticMethod" />
        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InstanceMethod" />
        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="DeallocMethod" />
      </class>
      <extensions>
        <pair source="cpp" header="h" fileNamingConvention="NONE" />
        <pair source="c" header="h" fileNamingConvention="NONE" />
      </extensions>
    </Objective-C-extensions>
  </code_scheme>
</component>

================================================
FILE: .idea/copyright/Ess.xml
================================================
<component name="CopyrightManager">
  <copyright>
    <option name="myName" value="Ess" />
  </copyright>
</component>

================================================
FILE: .idea/gradle.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
  <component name="GradleSettings">
    <option name="linkedExternalProjectsSettings">
      <GradleProjectSettings>
        <option name="distributionType" value="DEFAULT_WRAPPED" />
        <option name="externalProjectPath" value="$PROJECT_DIR$" />
        <option name="modules">
          <set>
            <option value="$PROJECT_DIR$" />
            <option value="$PROJECT_DIR$/app" />
            <option value="$PROJECT_DIR$/filepicker" />
          </set>
        </option>
        <option name="resolveModulePerSourceSet" value="false" />
      </GradleProjectSettings>
    </option>
  </component>
</project>

================================================
FILE: .idea/misc.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
  <component name="NullableNotNullManager">
    <option name="myDefaultNullable" value="android.support.annotation.Nullable" />
    <option name="myDefaultNotNull" value="android.support.annotation.NonNull" />
    <option name="myNullables">
      <value>
        <list size="4">
          <item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.Nullable" />
          <item index="1" class="java.lang.String" itemvalue="javax.annotation.Nullable" />
          <item index="2" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.Nullable" />
          <item index="3" class="java.lang.String" itemvalue="android.support.annotation.Nullable" />
        </list>
      </value>
    </option>
    <option name="myNotNulls">
      <value>
        <list size="4">
          <item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.NotNull" />
          <item index="1" class="java.lang.String" itemvalue="javax.annotation.Nonnull" />
          <item index="2" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.NonNull" />
          <item index="3" class="java.lang.String" itemvalue="android.support.annotation.NonNull" />
        </list>
      </value>
    </option>
  </component>
  <component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" project-jdk-name="1.8" project-jdk-type="JavaSDK">
    <output url="file://$PROJECT_DIR$/build/classes" />
  </component>
</project>

================================================
FILE: .idea/modules.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
  <component name="ProjectModuleManager">
    <modules>
      <module fileurl="file://$PROJECT_DIR$/FilePicker.iml" filepath="$PROJECT_DIR$/FilePicker.iml" />
      <module fileurl="file://$PROJECT_DIR$/app/app.iml" filepath="$PROJECT_DIR$/app/app.iml" />
      <module fileurl="file://$PROJECT_DIR$/filepicker/filepicker.iml" filepath="$PROJECT_DIR$/filepicker/filepicker.iml" />
    </modules>
  </component>
</project>

================================================
FILE: .idea/runConfigurations.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
  <component name="RunConfigurationProducerService">
    <option name="ignoredProducers">
      <set>
        <option value="org.jetbrains.plugins.gradle.execution.test.runner.AllInPackageGradleConfigurationProducer" />
        <option value="org.jetbrains.plugins.gradle.execution.test.runner.TestClassGradleConfigurationProducer" />
        <option value="org.jetbrains.plugins.gradle.execution.test.runner.TestMethodGradleConfigurationProducer" />
      </set>
    </option>
  </component>
</project>

================================================
FILE: .idea/vcs.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
  <component name="VcsDirectoryMappings">
    <mapping directory="$PROJECT_DIR$" vcs="Git" />
  </component>
</project>

================================================
FILE: LICENSE
================================================
MIT License

Copyright (c) 2018 aj

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.


================================================
FILE: README.md
================================================
### 介绍

# 由于暂时没有更多的精力在此项目上,现将此项目转让给其他人,谁来认领一下,一起把这个库搞下去,加我微信bo_744172447,谢谢!

---

1. 可在文件浏览器中选择指定后缀名文件
2. 可通过扫描全盘的方式,选择指定后缀名的文件
3. 类似微信图片选择器选择图片或视频
4. 图片选择页面可以自定义主题
5. 支持Activity、Fragment

### Example

---
![FilePicker](https://github.com/imLibo/FilePicker/blob/master/screenshot/Screenshot_20180307-124655.png)  ![FilePicker](https://github.com/imLibo/FilePicker/blob/master/screenshot/Screenshot_2018-03-07-13-51.png)  ![FilePicker](https://github.com/imLibo/FilePicker/blob/master/screenshot/Screenshot_20180307-124316.png)  
![FilePicker](https://github.com/imLibo/FilePicker/blob/master/screenshot/Screenshot_20180307-124556.png)  ![FilePicker](https://github.com/imLibo/FilePicker/blob/master/screenshot/Screenshot_20180307-124202.png)  ![FilePicker](https://github.com/imLibo/FilePicker/blob/master/screenshot/Screenshot_20180307-124213.png)

---

### 可下载APK直接体验
[Demo.apk](https://fir.im/filepicker)


---

### 用法


```
implementation 'cn.imlibo:FilePicker:v0.0.5_alpha'
```



##### 一、 在文件浏览器中选择指定文件
```
FilePicker.from(this)
                .chooseForBrowser()
                .setMaxCount(2)
                .setFileTypes("png", "doc","apk", "mp3", "gif", "txt", "mp4", "zip")
                .requestCode(REQUEST_CODE_CHOOSE)
                .start();
```

##### 二、 分类查找指定后缀名文件

```
FilePicker
                .from(this)
                .chooseForMimeType()
                .setMaxCount(10)
                .setFileTypes("png", "doc","apk", "mp3", "gif", "txt", "mp4", "zip")
                .requestCode(REQUEST_CODE_CHOOSE)
                .start();
```
##### 三、 在图片选择器中选择图片或视频

```
FilePicker
                .from(this)
                .chooseMedia()
                .enabledCapture(true)
                .setTheme(R.style.FilePicker_Dracula)
                .requestCode(REQUEST_CODE_CHOOSE)
                .start();
```

##### 四、 接收返回的文件数据,在 ++onActivityResult++ 方法中获取。选中文件以链表方式返回, ++EssFile++ 类为载体


```
@Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode != RESULT_OK) {
            return;
        }
        if (requestCode == REQUEST_CODE_CHOOSE) {
            ArrayList<EssFile> essFileList = data.getParcelableArrayListExtra(Const.EXTRA_RESULT_SELECTION);
            StringBuilder builder = new StringBuilder();
            for (EssFile file :
                    essFileList) {
                builder.append(file.getMimeType()).append(" | ").append(file.getName()).append("\n\n");
            }
            textView.setText(builder.toString());
        }
    }
```



### 属性列表

---

名称 | 描述 |  默认值
---|---|---
FileTypes | 需要显示的文件类型 | 无
SortType | 排序类型 | 按名字排序 BY_NAME_ASC
isSingle | 是否单选 |false
maxCount | 最大可选中数量 | 10
request_code | 请求码 | 无
onlyShowImages | 是否仅显示图片(仅当其实chooseMedia时有效) | false
onlyShowVideos | 是否仅显示视频(仅当其实chooseMedia时有效) | false
enabledCapture | chooseMedia时是否显示照相机 | false
placeHolder | 图片的PlaceHolder | png_holder
themeId | 主题ID | R.Style.FilePicker_Elec

### 自定义主题

---


```
<style name="FilePicker.Elec" parent="Theme.AppCompat.Light.NoActionBar">
		<item name="colorPrimary">@color/elec_primary</item>
		<item name="colorPrimaryDark">@color/elec_primary_dark</item>
		<item name="toolbar">@style/Toolbar.elec</item>
		<item name="album.dropdown.title.color">@color/elec_album_dropdown_title_text</item>
		<item name="album.dropdown.count.color">@color/elec_album_dropdown_count_text</item>
		<item name="album.element.color">@android:color/white</item>
		<item name="album.thumbnail.placeholder">@color/elec_album_dropdown_thumbnail_placeholder</item>
		<item name="album.emptyView">@drawable/ic_empty_elec</item>
		<item name="album.emptyView.textColor">@color/elec_album_empty_view</item>
		<item name="item.placeholder">@color/elec_item_placeholder</item>
		<item name="item.checkCircle.backgroundColor">@color/elec_item_checkCircle_backgroundColor</item>
		<item name="item.checkCircle.borderColor">@color/elec_item_checkCircle_borderColor</item>
		<item name="page.bg">@color/elec_page_bg</item>
		<item name="bottomToolbar.bg">@color/elec_bottom_toolbar_bg</item>
		<item name="bottomToolbar.preview.textColor">@color/elec_bottom_toolbar_preview</item>
		<item name="bottomToolbar.apply.textColor">@color/elec_bottom_toolbar_apply</item>
		<item name="preview.bottomToolbar.back.textColor">@color/elec_preview_bottom_toolbar_back_text</item>
		<item name="preview.bottomToolbar.apply.textColor">@color/elec_preview_bottom_toolbar_apply</item>
		<item name="listPopupWindowStyle">@style/Popup.elec</item>
		<item name="capture.textColor">@color/elec_capture</item>
	</style>
```


### Feature TODO

---

- [ ] 根据文件类型打开/预览文件
- [ ] 预览图片界面
- [ ] 压缩图片
- [ ] 裁剪图片
- [ ] 自定义相机拍照
- [ ] 去掉AndPermission依赖,用原生代码申请权限
- [ ] 增加多种图片加载框架支持
- [ ] 文件浏览器支持自定义主题
- [ ] 分类选择文件界面支持自定义主题


### THANKS

---

[陈宇明大师兄 BaseRecyclerViewAdapterHelper](https://github.com/CymChad/BaseRecyclerViewAdapterHelper)

[Android-FilePicker](https://github.com/DroidNinja/Android-FilePicker)

[Matisse](https://github.com/zhihu/Matisse)

[AndroidPicker](https://github.com/gzu-liyujiang/AndroidPicker)


## LICENSE

MIT License

Copyright (c) 2018

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.


================================================
FILE: app/.gitignore
================================================
/build


================================================
FILE: app/build.gradle
================================================
apply plugin: 'com.android.application'

android {
    compileSdkVersion 27
    defaultConfig {
        applicationId "com.imlibo.essfilepicker"
        minSdkVersion 17
        targetSdkVersion 26
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    signingConfigs {
        release {
            storeFile file("../filepicker.jks")
            storePassword "filepicker"
            keyAlias "filepicker"
            keyPassword "filepicker"
        }
    }
    buildTypes {
        release {
            minifyEnabled false
            signingConfig signingConfigs.release
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }

}

dependencies {
    implementation fileTree(include: ['*.jar'], dir: 'libs')
    implementation 'com.android.support:appcompat-v7:27.1.0'
    implementation 'com.android.support.constraint:constraint-layout:1.0.2'
    implementation 'com.android.support:support-v4:27.1.0'
    debugCompile 'com.squareup.leakcanary:leakcanary-android:1.5.4'
    releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.5.4'
    implementation 'com.jakewharton:butterknife:8.8.1'
    annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1'
    implementation 'com.yanzhenjie:permission:2.0.0-rc2'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.1'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
//    implementation 'cn.imlibo:FilePicker:v0.0.1_alpha'
    implementation project(':filepicker')
}


task copyApk(type: Copy) {
    include '**/*.apk'
    from '/build/outputs/release/apk'
    into '../APK/'
    rename { String fileName -> //在复制时重命名文件
        fileName = "filepicker-demo.apk" // 重命名
    }
}

//在task被添加的时候定义依赖关系
tasks.whenTaskAdded {
    task ->
        if (task.name.startsWith("assemble")) {
            task.finalizedBy copyApk
        }
}



================================================
FILE: app/proguard-rules.pro
================================================
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
#   http://developer.android.com/guide/developing/tools/proguard.html

# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
#   public *;
#}

# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable

# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile


================================================
FILE: app/src/androidTest/java/com/ess/essfilepicker/ExampleInstrumentedTest.java
================================================
package com.ess.essfilepicker;

import android.content.Context;
import android.support.test.InstrumentationRegistry;
import android.support.test.runner.AndroidJUnit4;

import org.junit.Test;
import org.junit.runner.RunWith;

import static org.junit.Assert.*;

/**
 * Instrumented test, which will execute on an Android device.
 *
 * @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
 */
@RunWith(AndroidJUnit4.class)
public class ExampleInstrumentedTest {
    @Test
    public void useAppContext() throws Exception {
        // Context of the app under test.
        Context appContext = InstrumentationRegistry.getTargetContext();

        assertEquals("com.imlibo.essfilepicker", appContext.getPackageName());
    }
}


================================================
FILE: app/src/main/AndroidManifest.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.ess.essfilepicker">

    <application
        android:name=".LApplication"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name=".FragmentTestActivity"></activity>
    </application>

</manifest>

================================================
FILE: app/src/main/java/com/ess/essfilepicker/FragmentTestActivity.java
================================================
package com.ess.essfilepicker;

import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.FrameLayout;

import butterknife.BindView;
import butterknife.ButterKnife;

public class FragmentTestActivity extends AppCompatActivity {

    @BindView(R.id.container_fragment)
    FrameLayout mFrameLayout;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_fragment_test);
        ButterKnife.bind(this);

        FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
        fragmentTransaction.add(R.id.container_fragment,TestFragment.newInstance());
        fragmentTransaction.commit();
    }
}


================================================
FILE: app/src/main/java/com/ess/essfilepicker/LApplication.java
================================================
/*
 * Copyright (c) 2018. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
 * Morbi non lorem porttitor neque feugiat blandit. Ut vitae ipsum eget quam lacinia accumsan.
 * Etiam sed turpis ac ipsum condimentum fringilla. Maecenas magna.
 * Proin dapibus sapien vel ante. Aliquam erat volutpat. Pellentesque sagittis ligula eget metus.
 * Vestibulum commodo. Ut rhoncus gravida arcu.
 */

package com.ess.essfilepicker;

import android.app.Application;

import com.squareup.leakcanary.LeakCanary;

/**
 * LApplication
 * Created by 李波 on 2018/2/22.
 */

public class LApplication extends Application{

    @Override
    public void onCreate() {
        super.onCreate();
        LeakCanary.install(this);
    }
}


================================================
FILE: app/src/main/java/com/ess/essfilepicker/MainActivity.java
================================================
package com.ess.essfilepicker;

import android.content.Intent;
import android.support.v4.app.Fragment;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;

import com.ess.filepicker.FilePicker;
import com.ess.filepicker.SelectCreator;
import com.ess.filepicker.SelectOptions;
import com.ess.filepicker.activity.SelectFileByBrowserActivity;
import com.ess.filepicker.activity.SelectFileByScanActivity;
import com.ess.filepicker.activity.SelectPictureActivity;
import com.ess.filepicker.model.EssFile;
import com.ess.filepicker.util.Const;
import com.ess.filepicker.util.DialogUtil;
import com.yanzhenjie.permission.Action;
import com.yanzhenjie.permission.AndPermission;
import com.yanzhenjie.permission.Permission;

import java.util.ArrayList;
import java.util.List;

import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;

public class MainActivity extends AppCompatActivity {

    @BindView(R.id.textView_filename)
    TextView textView;

    private static final int REQUEST_CODE_CHOOSE = 23;

    @OnClick(R.id.button_browse)
    public void onBrowse(View view) {
        FilePicker.from(this)
                .chooseForBrowser()
                .setMaxCount(2)
                .setFileTypes("png", "doc","apk", "mp3", "gif", "txt", "mp4", "zip")
                .requestCode(REQUEST_CODE_CHOOSE)
                .start();
    }

    @OnClick(R.id.button_scan)
    public void onScan(View view) {
        FilePicker
                .from(this)
                .chooseForMimeType()
                .setMaxCount(10)
                .setFileTypes("png", "doc","apk", "mp3", "gif", "txt", "mp4", "zip")
                .requestCode(REQUEST_CODE_CHOOSE)
                .start();
    }


    @OnClick(R.id.button_single_pick)
    public void onSinglePick(View view) {
        FilePicker
                .from(this)
                .chooseForBrowser()
                .isSingle()
                .setFileTypes("pdf")
                .requestCode(REQUEST_CODE_CHOOSE)
                .start();
    }

    @OnClick(R.id.button_select_pictures)
    public void onSelectPictures(View view){
        FilePicker
                .from(this)
                .chooseMedia()
                .enabledCapture(true)
                .setTheme(R.style.FilePicker_Dracula)
                .requestCode(REQUEST_CODE_CHOOSE)
                .start();
    }

    @OnClick(R.id.button_fragment)
    public void onFragment(View view){
        startActivity(new Intent(this,FragmentTestActivity.class));
    }


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ButterKnife.bind(this);
        AndPermission
                .with(this)
                .permission(Permission.READ_EXTERNAL_STORAGE,Permission.WRITE_EXTERNAL_STORAGE)
                .onDenied(new Action() {
                    @Override
                    public void onAction(List<String> permissions) {
                        //拒绝权限
                        DialogUtil.showPermissionDialog(MainActivity.this,Permission.transformText(MainActivity.this, permissions).get(0));
                    }
                })
                .start();

    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode != RESULT_OK) {
            return;
        }
        if (requestCode == REQUEST_CODE_CHOOSE) {
            ArrayList<EssFile> essFileList = data.getParcelableArrayListExtra(Const.EXTRA_RESULT_SELECTION);
            StringBuilder builder = new StringBuilder();
            for (EssFile file :
                    essFileList) {
                builder.append(file.getMimeType()).append(" | ").append(file.getName()).append("\n\n");
            }
            textView.setText(builder.toString());
        }
    }
}


================================================
FILE: app/src/main/java/com/ess/essfilepicker/TestFragment.java
================================================
package com.ess.essfilepicker;


import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;


import com.ess.filepicker.FilePicker;
import com.ess.filepicker.model.EssFile;
import com.ess.filepicker.util.Const;

import java.util.ArrayList;

import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;

import static android.app.Activity.RESULT_OK;

/**
 * TestFragment
 */
public class TestFragment extends Fragment {

    @BindView(R.id.textView_filename)
    TextView textView;

    private static final int REQUEST_CODE_CHOOSE = 23;

    @OnClick(R.id.button_browse)
    public void onBrowse(View view) {
        FilePicker.from(this)
                .chooseForBrowser()
                .setMaxCount(2)
                .setFileTypes("png", "doc","apk", "mp3", "gif", "txt", "mp4", "zip")
                .requestCode(REQUEST_CODE_CHOOSE)
                .start();
    }

    @OnClick(R.id.button_scan)
    public void onScan(View view) {
        FilePicker
                .from(this)
                .chooseForMimeType()
                .setMaxCount(10)
                .setFileTypes("png", "doc","apk", "mp3", "gif", "txt", "mp4", "zip")
                .requestCode(REQUEST_CODE_CHOOSE)
                .start();
    }

    @OnClick(R.id.button_select_pictures)
    public void onSelectPictures(View view){
        FilePicker
                .from(this)
                .chooseMedia()
                .enabledCapture(true)
                .setTheme(R.style.FilePicker_Dracula)
                .requestCode(REQUEST_CODE_CHOOSE)
                .start();
    }

    public TestFragment() {
    }

    public static TestFragment newInstance() {
        return new TestFragment();
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_test, container, false);
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        ButterKnife.bind(this,view);
        super.onViewCreated(view, savedInstanceState);
    }


    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode != RESULT_OK) {
            return;
        }
        if (requestCode == REQUEST_CODE_CHOOSE) {
            ArrayList<EssFile> essFileList = data.getParcelableArrayListExtra(Const.EXTRA_RESULT_SELECTION);
            StringBuilder builder = new StringBuilder();
            for (EssFile file :
                    essFileList) {
                builder.append(file.getMimeType()).append(" | ").append(file.getName()).append("\n\n");
            }
            textView.setText(builder.toString());
        }
    }
}


================================================
FILE: app/src/main/res/drawable/ic_launcher_background.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="108dp"
    android:height="108dp"
    android:viewportHeight="108"
    android:viewportWidth="108">
    <path
        android:fillColor="#26A69A"
        android:pathData="M0,0h108v108h-108z" />
    <path
        android:fillColor="#00000000"
        android:pathData="M9,0L9,108"
        android:strokeColor="#33FFFFFF"
        android:strokeWidth="0.8" />
    <path
        android:fillColor="#00000000"
        android:pathData="M19,0L19,108"
        android:strokeColor="#33FFFFFF"
        android:strokeWidth="0.8" />
    <path
        android:fillColor="#00000000"
        android:pathData="M29,0L29,108"
        android:strokeColor="#33FFFFFF"
        android:strokeWidth="0.8" />
    <path
        android:fillColor="#00000000"
        android:pathData="M39,0L39,108"
        android:strokeColor="#33FFFFFF"
        android:strokeWidth="0.8" />
    <path
        android:fillColor="#00000000"
        android:pathData="M49,0L49,108"
        android:strokeColor="#33FFFFFF"
        android:strokeWidth="0.8" />
    <path
        android:fillColor="#00000000"
        android:pathData="M59,0L59,108"
        android:strokeColor="#33FFFFFF"
        android:strokeWidth="0.8" />
    <path
        android:fillColor="#00000000"
        android:pathData="M69,0L69,108"
        android:strokeColor="#33FFFFFF"
        android:strokeWidth="0.8" />
    <path
        android:fillColor="#00000000"
        android:pathData="M79,0L79,108"
        android:strokeColor="#33FFFFFF"
        android:strokeWidth="0.8" />
    <path
        android:fillColor="#00000000"
        android:pathData="M89,0L89,108"
        android:strokeColor="#33FFFFFF"
        android:strokeWidth="0.8" />
    <path
        android:fillColor="#00000000"
        android:pathData="M99,0L99,108"
        android:strokeColor="#33FFFFFF"
        android:strokeWidth="0.8" />
    <path
        android:fillColor="#00000000"
        android:pathData="M0,9L108,9"
        android:strokeColor="#33FFFFFF"
        android:strokeWidth="0.8" />
    <path
        android:fillColor="#00000000"
        android:pathData="M0,19L108,19"
        android:strokeColor="#33FFFFFF"
        android:strokeWidth="0.8" />
    <path
        android:fillColor="#00000000"
        android:pathData="M0,29L108,29"
        android:strokeColor="#33FFFFFF"
        android:strokeWidth="0.8" />
    <path
        android:fillColor="#00000000"
        android:pathData="M0,39L108,39"
        android:strokeColor="#33FFFFFF"
        android:strokeWidth="0.8" />
    <path
        android:fillColor="#00000000"
        android:pathData="M0,49L108,49"
        android:strokeColor="#33FFFFFF"
        android:strokeWidth="0.8" />
    <path
        android:fillColor="#00000000"
        android:pathData="M0,59L108,59"
        android:strokeColor="#33FFFFFF"
        android:strokeWidth="0.8" />
    <path
        android:fillColor="#00000000"
        android:pathData="M0,69L108,69"
        android:strokeColor="#33FFFFFF"
        android:strokeWidth="0.8" />
    <path
        android:fillColor="#00000000"
        android:pathData="M0,79L108,79"
        android:strokeColor="#33FFFFFF"
        android:strokeWidth="0.8" />
    <path
        android:fillColor="#00000000"
        android:pathData="M0,89L108,89"
        android:strokeColor="#33FFFFFF"
        android:strokeWidth="0.8" />
    <path
        android:fillColor="#00000000"
        android:pathData="M0,99L108,99"
        android:strokeColor="#33FFFFFF"
        android:strokeWidth="0.8" />
    <path
        android:fillColor="#00000000"
        android:pathData="M19,29L89,29"
        android:strokeColor="#33FFFFFF"
        android:strokeWidth="0.8" />
    <path
        android:fillColor="#00000000"
        android:pathData="M19,39L89,39"
        android:strokeColor="#33FFFFFF"
        android:strokeWidth="0.8" />
    <path
        android:fillColor="#00000000"
        android:pathData="M19,49L89,49"
        android:strokeColor="#33FFFFFF"
        android:strokeWidth="0.8" />
    <path
        android:fillColor="#00000000"
        android:pathData="M19,59L89,59"
        android:strokeColor="#33FFFFFF"
        android:strokeWidth="0.8" />
    <path
        android:fillColor="#00000000"
        android:pathData="M19,69L89,69"
        android:strokeColor="#33FFFFFF"
        android:strokeWidth="0.8" />
    <path
        android:fillColor="#00000000"
        android:pathData="M19,79L89,79"
        android:strokeColor="#33FFFFFF"
        android:strokeWidth="0.8" />
    <path
        android:fillColor="#00000000"
        android:pathData="M29,19L29,89"
        android:strokeColor="#33FFFFFF"
        android:strokeWidth="0.8" />
    <path
        android:fillColor="#00000000"
        android:pathData="M39,19L39,89"
        android:strokeColor="#33FFFFFF"
        android:strokeWidth="0.8" />
    <path
        android:fillColor="#00000000"
        android:pathData="M49,19L49,89"
        android:strokeColor="#33FFFFFF"
        android:strokeWidth="0.8" />
    <path
        android:fillColor="#00000000"
        android:pathData="M59,19L59,89"
        android:strokeColor="#33FFFFFF"
        android:strokeWidth="0.8" />
    <path
        android:fillColor="#00000000"
        android:pathData="M69,19L69,89"
        android:strokeColor="#33FFFFFF"
        android:strokeWidth="0.8" />
    <path
        android:fillColor="#00000000"
        android:pathData="M79,19L79,89"
        android:strokeColor="#33FFFFFF"
        android:strokeWidth="0.8" />
</vector>


================================================
FILE: app/src/main/res/drawable-v24/ic_launcher_foreground.xml
================================================
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:aapt="http://schemas.android.com/aapt"
    android:width="108dp"
    android:height="108dp"
    android:viewportHeight="108"
    android:viewportWidth="108">
    <path
        android:fillType="evenOdd"
        android:pathData="M32,64C32,64 38.39,52.99 44.13,50.95C51.37,48.37 70.14,49.57 70.14,49.57L108.26,87.69L108,109.01L75.97,107.97L32,64Z"
        android:strokeColor="#00000000"
        android:strokeWidth="1">
        <aapt:attr name="android:fillColor">
            <gradient
                android:endX="78.5885"
                android:endY="90.9159"
                android:startX="48.7653"
                android:startY="61.0927"
                android:type="linear">
                <item
                    android:color="#44000000"
                    android:offset="0.0" />
                <item
                    android:color="#00000000"
                    android:offset="1.0" />
            </gradient>
        </aapt:attr>
    </path>
    <path
        android:fillColor="#FFFFFF"
        android:fillType="nonZero"
        android:pathData="M66.94,46.02L66.94,46.02C72.44,50.07 76,56.61 76,64L32,64C32,56.61 35.56,50.11 40.98,46.06L36.18,41.19C35.45,40.45 35.45,39.3 36.18,38.56C36.91,37.81 38.05,37.81 38.78,38.56L44.25,44.05C47.18,42.57 50.48,41.71 54,41.71C57.48,41.71 60.78,42.57 63.68,44.05L69.11,38.56C69.84,37.81 70.98,37.81 71.71,38.56C72.44,39.3 72.44,40.45 71.71,41.19L66.94,46.02ZM62.94,56.92C64.08,56.92 65,56.01 65,54.88C65,53.76 64.08,52.85 62.94,52.85C61.8,52.85 60.88,53.76 60.88,54.88C60.88,56.01 61.8,56.92 62.94,56.92ZM45.06,56.92C46.2,56.92 47.13,56.01 47.13,54.88C47.13,53.76 46.2,52.85 45.06,52.85C43.92,52.85 43,53.76 43,54.88C43,56.01 43.92,56.92 45.06,56.92Z"
        android:strokeColor="#00000000"
        android:strokeWidth="1" />
</vector>


================================================
FILE: app/src/main/res/layout/activity_fragment_test.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/container_fragment"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="40dp"
    android:background="#aa000000"
    >



</FrameLayout>


================================================
FILE: app/src/main/res/layout/activity_main.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="40dp"
    android:orientation="vertical"
    >

    <android.support.v7.widget.Toolbar
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>

    <Button
        android:id="@+id/button_browse"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="文件夹中选择文件"
        />

    <Button
        android:id="@+id/button_scan"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="按文件类型选择文件"
        />

    <Button
        android:id="@+id/button_single_pick"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="单选特定文件"
        />

    <Button
        android:id="@+id/button_select_pictures"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="选择照片"
        />
    <Button
        android:id="@+id/button_fragment"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/fragment"
        />

    <TextView
        android:id="@+id/textView_filename"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="TextView"
        />

</LinearLayout>


================================================
FILE: app/src/main/res/layout/fragment_test.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#fff"
    android:orientation="vertical"
    >

    <android.support.v7.widget.Toolbar
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>

    <Button
        android:id="@+id/button_browse"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="文件夹中选择文件"
        />

    <Button
        android:id="@+id/button_scan"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="按文件类型选择文件"
        />

    <Button
        android:id="@+id/button_select_pictures"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="选择照片"
        />

    <TextView
        android:id="@+id/textView_filename"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="TextView"
        />

</LinearLayout>


================================================
FILE: app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
    <background android:drawable="@drawable/ic_launcher_background" />
    <foreground android:drawable="@drawable/ic_launcher_foreground" />
</adaptive-icon>

================================================
FILE: app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
    <background android:drawable="@drawable/ic_launcher_background" />
    <foreground android:drawable="@drawable/ic_launcher_foreground" />
</adaptive-icon>

================================================
FILE: app/src/main/res/values/colors.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="colorPrimary">#1bbc9b</color>
    <color name="colorPrimaryDark">#1bbc9b</color>
    <color name="colorAccent">#FF4081</color>
</resources>


================================================
FILE: app/src/main/res/values/strings.xml
================================================
<resources>
    <string name="app_name">文件浏览</string>

    <!-- TODO: Remove or change this placeholder text -->
    <string name="hello_blank_fragment">Hello blank fragment</string>
    <string name="fragment">Fragment</string>
</resources>


================================================
FILE: app/src/main/res/values/styles.xml
================================================
<resources xmlns:tools="http://schemas.android.com/tools">

    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
        <!--自定义右侧溢出图标-->
        <!--<item name="android:actionOverflowButtonStyle">@style/OverflowButtonStyle</item>-->
    </style>

    <style name="AppTheme.NoActionBar">
        <item name="windowActionBar">false</item>
        <item name="windowNoTitle">true</item>
    </style>

    <style name="AppTheme.AppBarOverlay" parent="ThemeOverlay.AppCompat.Dark.ActionBar"/>

    <style name="AppTheme.PopupOverlay" parent="ThemeOverlay.AppCompat.Light"/>


</resources>


================================================
FILE: app/src/test/java/com/ess/essfilepicker/ExampleUnitTest.java
================================================
package com.ess.essfilepicker;

import org.junit.Test;

import static org.junit.Assert.*;

/**
 * Example local unit test, which will execute on the development machine (host).
 *
 * @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
 */
public class ExampleUnitTest {
    @Test
    public void addition_isCorrect() throws Exception {
        assertEquals(4, 2 + 2);
    }
}

================================================
FILE: build.gradle
================================================
// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {
    
    repositories {
        google()
        jcenter()
        mavenCentral()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.1.1'
        classpath 'com.jakewharton:butterknife-gradle-plugin:8.8.1'
        classpath 'com.novoda:bintray-release:0.8.0'

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {
    repositories {
        google()
        jcenter()
        maven { url "https://jitpack.io" }
    }
    tasks.withType(Javadoc) {
        options.addStringOption('Xdoclint:none', '-quiet')
        options.addStringOption('encoding', 'UTF-8')
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

ext {
    userOrg = 'libo'
    groupId = 'cn.imlibo'
    uploadName = 'FilePicker'
    publishVersion = 'v0.0.5_alpha'
    desc = 'Android文件选择器、图片选择器、MIMEType分类选择器'
    website = 'https://github.com/imLibo/FilePicker'
    licences = ['MIT']
}

================================================
FILE: filepicker/.gitignore
================================================
/build


================================================
FILE: filepicker/build.gradle
================================================
apply plugin: 'com.android.library'
apply plugin: 'com.novoda.bintray-release'

android {
    compileSdkVersion 27

    defaultConfig {
        minSdkVersion 14
        targetSdkVersion 27
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"

    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }

    lintOptions {
        abortOnError false
    }


}

dependencies {
    implementation fileTree(include: ['*.jar'], dir: 'libs')
    implementation 'com.android.support:recyclerview-v7:27.1.0'
    implementation 'com.android.support:appcompat-v7:27.1.0'
    implementation 'com.android.support:design:27.1.0'
    implementation 'com.android.support:appcompat-v7:27.1.0'
    implementation 'com.github.CymChad:BaseRecyclerViewAdapterHelper:2.9.34'
    implementation 'com.android.support.constraint:constraint-layout:1.0.2'
    implementation 'com.github.bumptech.glide:glide:4.6.1'
    implementation 'com.android.support:support-v4:27.1.0'
    implementation 'org.greenrobot:eventbus:3.1.1'
    implementation 'top.zibin:Luban:1.1.3'
}

publish {
    userOrg = rootProject.userOrg
    groupId = rootProject.groupId
    artifactId = rootProject.uploadName
    publishVersion = rootProject.publishVersion
    desc = rootProject.desc
    website = rootProject.website
}






================================================
FILE: filepicker/proguard-rules.pro
================================================
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
#   http://developer.android.com/guide/developing/tools/proguard.html

# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
#   public *;
#}

# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable

# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile


================================================
FILE: filepicker/src/androidTest/java/com/ess/filepicker/ExampleInstrumentedTest.java
================================================
package com.ess.filepicker;

import android.content.Context;
import android.support.test.InstrumentationRegistry;
import android.support.test.runner.AndroidJUnit4;

import org.junit.Test;
import org.junit.runner.RunWith;

import static org.junit.Assert.*;

/**
 * Instrumented test, which will execute on an Android device.
 *
 * @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
 */
@RunWith(AndroidJUnit4.class)
public class ExampleInstrumentedTest {
    @Test
    public void useAppContext() throws Exception {
        // Context of the app under test.
        Context appContext = InstrumentationRegistry.getTargetContext();

        assertEquals("com.imlibo.filepicker.test", appContext.getPackageName());
    }
}


================================================
FILE: filepicker/src/main/AndroidManifest.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.ess.filepicker">

    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

    <application>
        <activity android:name="com.ess.filepicker.activity.SelectFileByBrowserActivity" />
        <activity android:name="com.ess.filepicker.activity.SelectPictureActivity" />
        <activity android:name="com.ess.filepicker.activity.SelectFileByScanActivity" />

        <provider
            android:name="com.ess.filepicker.model.EssFileProvider"
            android:authorities="${applicationId}.ess.file.provider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/provider_paths" />
        </provider>

        <activity android:name="com.ess.filepicker.activity.PicturesViewActivity"/>
    </application>

</manifest>

================================================
FILE: filepicker/src/main/java/com/ess/filepicker/BaseFileFragment.java
================================================
package com.ess.filepicker;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.os.Message;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import java.lang.reflect.Field;

/**
 * BaseFileFragment
 * Created by 李波 on 2018/2/23.
 */

public abstract class BaseFileFragment extends Fragment{

    protected Activity mActivity = null;
    protected Bundle bundle = null;
    protected Fragment mFragment = null;
    /**
     * fragment管理器
     */
    protected FragmentManager mFManager = null;

    protected boolean isVisible; //是否可见的标志

    protected boolean isFirstLoad = true; //是否是第一次加载

    protected boolean isPrepared = false; //是否已经准备好

    protected boolean isOnDetach = false;


    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        this.mActivity = getActivity();
        this.mFragment = this;
        isOnDetach = false;
        bundle = getArguments();
        mFManager = getChildFragmentManager();
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        super.onCreateView(inflater, container, savedInstanceState);
        View view = inflater.inflate(getFragmentLayout(), container, false);
        initUI(view);
        onVisible();
        return view;
    }


    /**
     * fragment布局文件
     *
     * @return
     */
    public abstract int getFragmentLayout();


    /**
     * 设置是否是第一次加载 用于刷新数据
     *
     * @param isFirstLoad
     */
    public void setFirstLoad(boolean isFirstLoad) {
        this.isFirstLoad = isFirstLoad;
    }

    /**
     * 在这里实现Fragment数据的缓加载.
     *
     * @param isVisibleToUser
     */
    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);
        if (getUserVisibleHint()) {
            isVisible = true;
            onVisible();
        } else {
            isVisible = false;
            onInvisible();
        }
    }

    /**
     * 可见的时候
     */
    private void onVisible() {
        if (isFirstLoad && isVisible && isPrepared) {
            lazyLoad();
            isFirstLoad = false;
        }
    }

    /**
     * 不可见时
     */
    protected void onInvisible() {

    }

    /**
     * 初始化控件
     * @param view
     */
    protected void initUI(View view) {
        isPrepared = true;
    }

    /**
     * 延迟加载
     * 需要在
     */
    protected abstract void lazyLoad();

    /**
     * 刷新数据
     *
     * @param msg
     */
    protected void onRefresh(Message msg) {
        if (!isOnDetach) {
        }
    }

    @Override
    public void onDetach() {
        super.onDetach();
        isOnDetach = true;
        try {
            Field childFragmentManager = Fragment.class.getDeclaredField("mChildFragmentManager");
            childFragmentManager.setAccessible(true);
            childFragmentManager.set(this, null);
        } catch (NoSuchFieldException e) {
            throw new RuntimeException(e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        }
    }

}


================================================
FILE: filepicker/src/main/java/com/ess/filepicker/FilePicker.java
================================================
package com.ess.filepicker;

import android.app.Activity;
import android.support.v4.app.Fragment;

import java.lang.ref.WeakReference;


/**
 * FilePicker 构造器
 * Created by 李波 on 2018/2/8.
 *
 */

public final class FilePicker {

    private final WeakReference<Activity> mContext;
    private final WeakReference<Fragment> mFragment;

    private FilePicker(Activity activity) {
        this(activity,null);
    }

    private FilePicker(Fragment fragment){
        this(fragment.getActivity(),fragment);
    }

    private FilePicker(Activity mContext, Fragment mFragment) {
        this.mContext = new WeakReference<>(mContext);
        this.mFragment = new WeakReference<>(mFragment);
    }

    public static FilePicker from(Activity activity){
        return new FilePicker(activity);
    }

    public static FilePicker from(Fragment fragment){
        return new FilePicker(fragment);
    }

    public SelectCreator chooseForBrowser(){
        return new SelectCreator(this,SelectOptions.CHOOSE_TYPE_BROWSER);
    }

    public SelectCreator chooseForMimeType(){
        return new SelectCreator(this,SelectOptions.CHOOSE_TYPE_SCAN);
    }

    public SelectCreator chooseMedia(){
        return new SelectCreator(this,SelectOptions.CHOOSE_TYPE_MEDIA);
    }


    public Activity getActivity() {
        return mContext.get();
    }

    public Fragment getFragment() {
        return mFragment != null ? mFragment.get() : null;
    }

}


================================================
FILE: filepicker/src/main/java/com/ess/filepicker/SelectCreator.java
================================================
package com.ess.filepicker;

import android.app.Activity;
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.support.annotation.StyleRes;
import android.support.v4.app.Fragment;

import com.ess.filepicker.activity.SelectFileByBrowserActivity;
import com.ess.filepicker.activity.SelectFileByScanActivity;
import com.ess.filepicker.activity.SelectPictureActivity;

import java.io.File;

/**
 * SelectCreator
 * Created by 李波 on 2018/3/7.
 */

public final class SelectCreator {

    private final FilePicker filePicker;
    private final SelectOptions selectOptions;
    private String chooseType;

    public SelectCreator(FilePicker filePicker, String chooseType) {
        selectOptions = SelectOptions.getCleanInstance();
        this.chooseType = chooseType;
        this.filePicker = filePicker;
    }

    public SelectCreator setMaxCount(int maxCount) {
        selectOptions.maxCount = maxCount;
        if (maxCount <= 1) {
            selectOptions.maxCount = 1;
            selectOptions.isSingle = true;
        } else {
            selectOptions.isSingle = false;
        }
        return this;
    }

    public SelectCreator setCompressImage(boolean compressImage){
        selectOptions.compressImage = compressImage;
        return this;
    }

    public SelectCreator setTargetPath(String path){
        selectOptions.targetPath = path;
        return this;
    }

    public SelectCreator setTheme(@StyleRes int theme) {
        selectOptions.themeId = theme;
        return this;
    }

    public SelectCreator setFileTypes(String... fileTypes) {
        selectOptions.mFileTypes = fileTypes;
        return this;
    }

    public SelectCreator setSortType(String sortType) {
        selectOptions.mSortType = sortType;
        return this;
    }

    public SelectCreator isSingle() {
        selectOptions.isSingle = true;
        selectOptions.maxCount = 1;
        return this;
    }

    public SelectCreator onlyShowImages() {
        selectOptions.onlyShowImages = true;
        return this;
    }

    public SelectCreator onlyShowVideos() {
        selectOptions.onlyShowVideos = true;
        return this;
    }

    public SelectCreator placeHolder(Drawable placeHolder) {
        selectOptions.placeHolder = placeHolder;
        return this;
    }

    public SelectCreator enabledCapture(boolean enabledCapture) {
        selectOptions.enabledCapture = enabledCapture;
        return this;
    }

    public SelectCreator requestCode(int requestCode) {
        selectOptions.request_code = requestCode;
        return this;
    }

    public void start() {
        final Activity activity = filePicker.getActivity();
        if (activity == null) {
            return;
        }
        Intent intent = new Intent();
        if (SelectCreator.this.chooseType.equals(SelectOptions.CHOOSE_TYPE_BROWSER)) {
            intent.setClass(activity, SelectFileByBrowserActivity.class);
        } else if (SelectCreator.this.chooseType.equals(SelectOptions.CHOOSE_TYPE_SCAN)) {
            intent.setClass(activity, SelectFileByScanActivity.class);
        } else if (SelectCreator.this.chooseType.equals(SelectOptions.CHOOSE_TYPE_MEDIA)) {
            intent.setClass(activity, SelectPictureActivity.class);
        } else {
            return;
        }
        Fragment fragment = filePicker.getFragment();
        if (fragment != null) {
            fragment.startActivityForResult(intent, selectOptions.request_code);
        } else {
            activity.startActivityForResult(intent, selectOptions.request_code);
        }
    }

}


================================================
FILE: filepicker/src/main/java/com/ess/filepicker/SelectOptions.java
================================================
package com.ess.filepicker;

import android.graphics.drawable.Drawable;
import android.os.Environment;
import android.text.TextUtils;

import com.ess.filepicker.util.FileUtils;
import com.ess.filepicker.util.MimeType;

import java.io.File;
import java.util.Set;

/**
 * SelectOptions
 * Created by 李波 on 2018/3/7.
 */

public class SelectOptions {

    public static final String CHOOSE_TYPE_BROWSER = "choose_type_browser";
    public static final String CHOOSE_TYPE_SCAN = "choose_type_scan";
    public static final String CHOOSE_TYPE_MEDIA = "choose_type_media";

    public static final String defaultTargetPath = Environment.getExternalStorageDirectory() + "/essPictures";

    public String[] mFileTypes;
    public String mSortType;
    public boolean isSingle = false;
    public int maxCount = 10;
    public int request_code;
    public boolean onlyShowImages = false;
    public boolean onlyShowVideos = false;
    public boolean enabledCapture = false;
    public Drawable placeHolder;
    public boolean compressImage = true;
    public String targetPath = defaultTargetPath;
    public int themeId = R.style.FilePicker_Elec;

    public String[] getFileTypes() {
        if (mFileTypes == null || mFileTypes.length == 0) {
            return new String[]{};
        }
        return mFileTypes;
    }

    public int getSortType() {
        if (TextUtils.isEmpty(mSortType)) {
            return FileUtils.BY_NAME_ASC;
        }
        return Integer.valueOf(mSortType);
    }

    public String getTargetPath() {
        if (!new File(targetPath).exists()) {
            File file = new File(defaultTargetPath);
            if (!file.exists()) {
                file.mkdirs();
            }
            return defaultTargetPath;
        }
        return targetPath;
    }

    public void setSortType(int sortType) {
        mSortType = String.valueOf(sortType);
    }

    public static SelectOptions getInstance() {
        return InstanceHolder.INSTANCE;
    }

    public static SelectOptions getCleanInstance() {
        SelectOptions options = getInstance();
        options.reset();
        return options;
    }

    private void reset() {
        mFileTypes = new String[]{};
        mSortType = String.valueOf(FileUtils.BY_NAME_ASC);
        isSingle = false;
        maxCount = 10;
        onlyShowImages = false;
        onlyShowVideos = false;
        enabledCapture = false;
        compressImage = true;
        themeId = R.style.FilePicker_Elec;
    }

    private static final class InstanceHolder {
        private static final SelectOptions INSTANCE = new SelectOptions();
    }

}


================================================
FILE: filepicker/src/main/java/com/ess/filepicker/activity/FileTypeListFragment.java
================================================
package com.ess.filepicker.activity;


import android.os.Bundle;
import android.support.design.widget.Snackbar;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.View;

import com.chad.library.adapter.base.BaseQuickAdapter;
import com.ess.filepicker.BaseFileFragment;
import com.ess.filepicker.R;
import com.ess.filepicker.SelectOptions;
import com.ess.filepicker.adapter.FileListAdapter;
import com.ess.filepicker.loader.EssMimeTypeCollection;
import com.ess.filepicker.model.EssFile;
import com.ess.filepicker.model.FileScanActEvent;
import com.ess.filepicker.model.FileScanFragEvent;
import com.ess.filepicker.model.FileScanSortChangedEvent;

import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;

import java.util.ArrayList;
import java.util.List;

/**
 * FileTypeListFragment
 */
public class FileTypeListFragment extends BaseFileFragment implements BaseQuickAdapter.OnItemClickListener,
        EssMimeTypeCollection.EssMimeTypeCallbacks {

    private static final String ARG_FileType = "ARG_FileType";
    private static final String ARG_IsSingle = "mIsSingle";
    private static final String ARG_MaxCount = "mMaxCount";
    private static final String ARG_SortType = "mSortType";
    private static final String ARG_Loader_Id = "ARG_Loader_Id";

    private String mFileType;
    private boolean mIsSingle;
    private int mMaxCount;
    private int mSortType;
    private int mLoaderId;

    private boolean mSortTypeHasChanged = false;

    private List<EssFile> mSelectedFileList = new ArrayList<>();

    private RecyclerView mRecyclerView;
    private FileListAdapter mAdapter;
    private EssMimeTypeCollection mMimeTypeCollection = new EssMimeTypeCollection();

    public FileTypeListFragment() {
    }

    public static FileTypeListFragment newInstance(String param1, boolean IsSingle, int mMaxCount, int mSortType, int loaderId) {
        FileTypeListFragment fragment = new FileTypeListFragment();
        Bundle args = new Bundle();
        args.putString(ARG_FileType, param1);
        args.putBoolean(ARG_IsSingle, IsSingle);
        args.putInt(ARG_MaxCount, mMaxCount);
        args.putInt(ARG_SortType, mSortType);
        args.putInt(ARG_Loader_Id, loaderId);
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (getArguments() != null) {
            mFileType = getArguments().getString(ARG_FileType);
            mIsSingle = getArguments().getBoolean(ARG_IsSingle);
            mMaxCount = getArguments().getInt(ARG_MaxCount);
            mSortType = getArguments().getInt(ARG_SortType);
            mLoaderId = getArguments().getInt(ARG_Loader_Id);
        }
    }

    @Override
    public int getFragmentLayout() {
        return R.layout.fragment_file_type_list;
    }

    @Override
    protected void lazyLoad() {
        mMimeTypeCollection.load(mFileType, mSortType,mLoaderId);
    }

    @Override
    protected void initUI(View view) {
        mMimeTypeCollection.onCreate(getActivity(), this);
        EventBus.getDefault().register(this);
        mRecyclerView = view.findViewById(R.id.rcv_file_list_scan);
        mRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
        mAdapter = new FileListAdapter(new ArrayList<EssFile>());
        mRecyclerView.setAdapter(mAdapter);
        mAdapter.bindToRecyclerView(mRecyclerView);
        mAdapter.setEmptyView(R.layout.loading_layout);
        mAdapter.setOnItemClickListener(this);
        super.initUI(view);
    }

    /**
     * 接收到Activity刷新最大数量后
     *
     * @param event event
     */
    @Subscribe
    public void onFreshCount(FileScanActEvent event) {
        mMaxCount = event.getCanSelectMaxCount();
    }

    /**
     * 接收到Activity改变排序方式后
     */
    @Subscribe
    public void onFreshSortType(FileScanSortChangedEvent event) {
        mSortType = event.getSortType();
        if(mLoaderId == event.getCurrentItem()+EssMimeTypeCollection.LOADER_ID){
            mMimeTypeCollection.load(mFileType, mSortType,mLoaderId);
        }else {
            mSortTypeHasChanged = true;
        }
    }

    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);
        if(getUserVisibleHint()){
            if(!isFirstLoad && mSortTypeHasChanged){
                mSortTypeHasChanged = false;
                mAdapter.setNewData(new ArrayList<EssFile>());
                mAdapter.setEmptyView(R.layout.loading_layout);
                mMimeTypeCollection.load(mFileType, mSortType,mLoaderId);
            }
        }
    }

    @Override
    public void onItemClick(BaseQuickAdapter adapter, View view, int position) {
        EssFile item = mAdapter.getData().get(position);
        //选中某文件后,判断是否单选
        if (mIsSingle) {
            mSelectedFileList.add(item);
            EventBus.getDefault().post(new FileScanFragEvent(item, true));
            return;
        }
        if (mAdapter.getData().get(position).isChecked()) {
            int index = findFileIndex(item);
            if (index != -1) {
                mSelectedFileList.remove(index);
                EventBus.getDefault().post(new FileScanFragEvent(item, false));
                mAdapter.getData().get(position).setChecked(!mAdapter.getData().get(position).isChecked());
                mAdapter.notifyItemChanged(position, "");
            }
        } else {
            if (mMaxCount <= 0) {
                //超出最大可选择数量后
                Snackbar.make(mRecyclerView, "您最多只能选择" + SelectOptions.getInstance().maxCount + "个。", Snackbar.LENGTH_SHORT).show();
                return;
            }
            mSelectedFileList.add(item);
            EventBus.getDefault().post(new FileScanFragEvent(item, true));
            mAdapter.getData().get(position).setChecked(!mAdapter.getData().get(position).isChecked());
            mAdapter.notifyItemChanged(position, "");
        }

    }

    /**
     * 查找文件位置
     */
    private int findFileIndex(EssFile item) {
        for (int i = 0; i < mSelectedFileList.size(); i++) {
            if (mSelectedFileList.get(i).getAbsolutePath().equals(item.getAbsolutePath())) {
                return i;
            }
        }
        return -1;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        EventBus.getDefault().unregister(this);
        mMimeTypeCollection.onDestroy();
    }

    @Override
    public void onFileLoad(List<EssFile> essFileList) {
        Log.i("TAG","size --> "+essFileList.size());
        mAdapter.setNewData(essFileList);
        mRecyclerView.scrollToPosition(0);
        if (essFileList.isEmpty()) {
            mAdapter.setEmptyView(R.layout.empty_file_list);
        }
    }

    @Override
    public void onFileReset() {

    }
}


================================================
FILE: filepicker/src/main/java/com/ess/filepicker/activity/PicturesViewActivity.java
================================================
package com.ess.filepicker.activity;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;

import com.ess.filepicker.R;
import com.ess.filepicker.model.EssFile;

import java.util.List;

/**
 * 图片浏览界面
 */
public class PicturesViewActivity extends AppCompatActivity {

    /*要浏览的图片列表*/
    private List<EssFile> mViewPicturesList;
    /*当前所处位置*/
    private int mCurPosition;
    /*是否是预览图片选择中的图片*/
    private boolean mIsViewForSelect;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_pictures_detail);
    }
}


================================================
FILE: filepicker/src/main/java/com/ess/filepicker/activity/SelectFileByBrowserActivity.java
================================================
package com.ess.filepicker.activity;

import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.os.Environment;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.ImageView;
import android.widget.PopupWindow;

import com.chad.library.adapter.base.BaseQuickAdapter;
import com.ess.filepicker.R;
import com.ess.filepicker.SelectOptions;
import com.ess.filepicker.adapter.BreadAdapter;
import com.ess.filepicker.adapter.FileListAdapter;
import com.ess.filepicker.adapter.SelectSdcardAdapter;
import com.ess.filepicker.model.BreadModel;
import com.ess.filepicker.model.EssFile;
import com.ess.filepicker.model.EssFileCountCallBack;
import com.ess.filepicker.model.EssFileListCallBack;
import com.ess.filepicker.task.EssFileCountTask;
import com.ess.filepicker.task.EssFileListTask;
import com.ess.filepicker.util.Const;
import com.ess.filepicker.util.FileUtils;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

/**
 * 文件浏览界面
 */
public class SelectFileByBrowserActivity extends AppCompatActivity
        implements BaseQuickAdapter.OnItemClickListener, BaseQuickAdapter.OnItemChildClickListener,
        View.OnClickListener, EssFileListCallBack, EssFileCountCallBack, FileListAdapter.onLoadFileCountListener {

    /*todo 是否可预览文件,默认可预览*/
    private boolean mCanPreview = true;

    /*当前目录,默认是SD卡根目录*/
    private String mCurFolder = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator;
    /*所有可访问存储设备列表*/
    private List<String> mSdCardList;

    private FileListAdapter mAdapter;
    private RecyclerView mRecyclerView;
    private RecyclerView mBreadRecyclerView;
    private ImageView mImbSelectSdCard;
    private Toolbar mToolBar;
    private BreadAdapter mBreadAdapter;
    private PopupWindow mSelectSdCardWindow;

    /*是否刚才切换了SD卡路径*/
    private boolean mHasChangeSdCard = false;
    /*已选中的文件列表*/
    private ArrayList<EssFile> mSelectedFileList = new ArrayList<>();
    /*当前选中排序方式的位置*/
    private int mSelectSortTypeIndex = 0;
    private MenuItem mCountMenuItem;

    private EssFileListTask essFileListTask;
    private EssFileCountTask essFileCountTask;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_select_file);
        // TODO: 2019/3/12 暂时移除
//        EventBus.getDefault().register(this);

        mSdCardList = FileUtils.getAllSdPaths(this);
        if (!mSdCardList.isEmpty()) {
            mCurFolder = mSdCardList.get(0) + File.separator;
        }
        initUi();
        initData();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.browse_menu, menu);
        mCountMenuItem = menu.findItem(R.id.browser_select_count);
        mCountMenuItem.setTitle(String.format(getString(R.string.selected_file_count), String.valueOf(mSelectedFileList.size()), String.valueOf(SelectOptions.getInstance().maxCount)));
        return true;
    }

    private void initUi() {
        mToolBar = findViewById(R.id.toolbar);
        setSupportActionBar(mToolBar);
        getSupportActionBar().setTitle("文件选择");
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        getSupportActionBar().setHomeButtonEnabled(true);
        mToolBar.setNavigationOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                onBackPressed();
            }
        });

        mRecyclerView = findViewById(R.id.rcv_file_list);
        mBreadRecyclerView = findViewById(R.id.breadcrumbs_view);
        mImbSelectSdCard = findViewById(R.id.imb_select_sdcard);
        mImbSelectSdCard.setOnClickListener(this);
        if (!mSdCardList.isEmpty() && mSdCardList.size() > 1) {
            mImbSelectSdCard.setVisibility(View.VISIBLE);
        }

        mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
        mAdapter = new FileListAdapter(new ArrayList<EssFile>());
        mAdapter.setLoadFileCountListener(this);
        mRecyclerView.setAdapter(mAdapter);
        mAdapter.bindToRecyclerView(mRecyclerView);
        mAdapter.setOnItemClickListener(this);

        mBreadRecyclerView.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false));
        mBreadAdapter = new BreadAdapter(new ArrayList<BreadModel>());
        mBreadRecyclerView.setAdapter(mBreadAdapter);
        mBreadAdapter.bindToRecyclerView(mBreadRecyclerView);
        mBreadAdapter.setOnItemChildClickListener(this);
    }

    private void initData() {
        executeListTask(mSelectedFileList, mCurFolder, SelectOptions.getInstance().getFileTypes(), SelectOptions.getInstance().getSortType());
    }

    private void executeListTask(List<EssFile> essFileList, String queryPath, String[] types, int sortType) {
        essFileListTask = new EssFileListTask(essFileList, queryPath, types, sortType, this);
        essFileListTask.execute();
    }

    /**
     * 查找到文件列表后
     *
     * @param queryPath 查询路径
     * @param fileList  文件列表
     */
    @Override
    public void onFindFileList(String queryPath, List<EssFile> fileList) {
        if (fileList.isEmpty()) {
            mAdapter.setEmptyView(R.layout.empty_file_list);
        }
        mCurFolder = queryPath;
        mAdapter.setNewData(fileList);
        List<BreadModel> breadModelList = FileUtils.getBreadModeListFromPath(mSdCardList, mCurFolder);
        if (mHasChangeSdCard) {
            mBreadAdapter.setNewData(breadModelList);
            mHasChangeSdCard = false;
        } else {
            if (breadModelList.size() > mBreadAdapter.getData().size()) {
                //新增
                List<BreadModel> newList = BreadModel.getNewBreadModel(mBreadAdapter.getData(), breadModelList);
                mBreadAdapter.addData(newList);
            } else {
                //减少
                int removePosition = BreadModel.getRemovedBreadModel(mBreadAdapter.getData(), breadModelList);
                if (removePosition > 0) {
                    mBreadAdapter.setNewData(mBreadAdapter.getData().subList(0, removePosition));
                }
            }
        }

        mBreadRecyclerView.smoothScrollToPosition(mBreadAdapter.getItemCount() - 1);
        //先让其滚动到顶部,然后再scrollBy,滚动到之前保存的位置
        mRecyclerView.scrollToPosition(0);
        int scrollYPosition = mBreadAdapter.getData().get(mBreadAdapter.getData().size() - 1).getPrePosition();
        //恢复之前的滚动位置
        mRecyclerView.scrollBy(0, scrollYPosition);
    }

    /**
     * 显示选择SdCard的PopupWindow
     * 点击其他区域隐藏,阴影
     */
    private void showPopupWindow() {
        if (mSelectSdCardWindow != null) {
            mSelectSdCardWindow.showAsDropDown(mImbSelectSdCard);
            return;
        }
        View popView = LayoutInflater.from(this).inflate(R.layout.pop_select_sdcard, null);
        mSelectSdCardWindow = new PopupWindow(popView, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        mSelectSdCardWindow.setFocusable(true);
        mSelectSdCardWindow.setOutsideTouchable(true);
        RecyclerView recyclerView = popView.findViewById(R.id.rcv_pop_select_sdcard);
        recyclerView.setLayoutManager(new LinearLayoutManager(this));
        final SelectSdcardAdapter adapter = new SelectSdcardAdapter(FileUtils.getAllSdCardList(mSdCardList));
        recyclerView.setAdapter(adapter);
        adapter.bindToRecyclerView(recyclerView);
        adapter.setOnItemClickListener(new BaseQuickAdapter.OnItemClickListener() {
            @Override
            public void onItemClick(BaseQuickAdapter adapterIn, View view, int position) {
                mSelectSdCardWindow.dismiss();
                mHasChangeSdCard = true;
                executeListTask(mSelectedFileList, FileUtils.getChangeSdCard(adapter.getData().get(position), mSdCardList), SelectOptions.getInstance().getFileTypes(), SelectOptions.getInstance().getSortType());
            }
        });
        mSelectSdCardWindow.showAsDropDown(mImbSelectSdCard);
    }

    /**
     * 设置添加屏幕的背景透明度
     *
     * @param bgAlpha bgAlpha
     */
    public void backgroundAlpha(float bgAlpha) {
        WindowManager.LayoutParams lp = getWindow().getAttributes();
        lp.alpha = bgAlpha; //0.0-1.0
        getWindow().setAttributes(lp);
    }


    @Override
    public void onFindChildFileAndFolderCount(int position, String childFileCount, String childFolderCount) {
        mAdapter.getData().get(position).setChildCounts(childFileCount, childFolderCount);
        mAdapter.notifyItemChanged(position, "childCountChanges");
    }


    @Override
    public void onItemClick(BaseQuickAdapter adapter, View view, int position) {
        if (adapter.equals(mAdapter)) {
            EssFile item = mAdapter.getData().get(position);
            if (item.isDirectory()) {
                //点击文件夹
                //保存当前的垂直滚动位置
                mBreadAdapter.getData().get(mBreadAdapter.getData().size() - 1).setPrePosition(mRecyclerView.computeVerticalScrollOffset());
                executeListTask(mSelectedFileList, mCurFolder + item.getName() + File.separator, SelectOptions.getInstance().getFileTypes(), SelectOptions.getInstance().getSortType());
            } else {
                //选中某文件后,判断是否单选
                if (SelectOptions.getInstance().isSingle) {
                    mSelectedFileList.add(item);
                    Intent result = new Intent();
                    result.putParcelableArrayListExtra(Const.EXTRA_RESULT_SELECTION, mSelectedFileList);
                    setResult(RESULT_OK, result);
                    super.onBackPressed();
                    return;
                }
                if (mAdapter.getData().get(position).isChecked()) {
                    int index = findFileIndex(item);
                    if (index != -1) {
                        mSelectedFileList.remove(index);
                    }
                } else {
                    if (mSelectedFileList.size() >= SelectOptions.getInstance().maxCount) {
                        //超出最大可选择数量后
                        Snackbar.make(mRecyclerView, "您最多只能选择" + SelectOptions.getInstance().maxCount + "个。", Snackbar.LENGTH_SHORT).show();
                        return;
                    }
                    mSelectedFileList.add(item);
                }
                mAdapter.getData().get(position).setChecked(!mAdapter.getData().get(position).isChecked());
                mAdapter.notifyItemChanged(position, "");
                mCountMenuItem.setTitle(String.format(getString(R.string.selected_file_count), String.valueOf(mSelectedFileList.size()), String.valueOf(SelectOptions.getInstance().maxCount)));
            }
        }
    }

    /**
     * 查找文件位置
     */
    private int findFileIndex(EssFile item) {
        for (int i = 0; i < mSelectedFileList.size(); i++) {
            if (mSelectedFileList.get(i).getAbsolutePath().equals(item.getAbsolutePath())) {
                return i;
            }
        }
        return -1;
    }

    @Override
    public void onBackPressed() {
        if (!FileUtils.canBackParent(mCurFolder, mSdCardList)) {
            super.onBackPressed();
            return;
        }
        executeListTask(mSelectedFileList, new File(mCurFolder).getParentFile().getAbsolutePath() + File.separator, SelectOptions.getInstance().getFileTypes(), SelectOptions.getInstance().getSortType());
    }

    @Override
    public void onItemChildClick(BaseQuickAdapter adapter, View view, int position) {
        if (adapter.equals(mBreadAdapter) && view.getId() == R.id.btn_bread) {
            //点击某个路径时
            String queryPath = FileUtils.getBreadModelListByPosition(mSdCardList, mBreadAdapter.getData(), position);
            if (mCurFolder.equals(queryPath)) {
                return;
            }
            executeListTask(mSelectedFileList, queryPath, SelectOptions.getInstance().getFileTypes(), SelectOptions.getInstance().getSortType());
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        // TODO: 2019/3/12 暂时移除
//        EventBus.getDefault().unregister(this);
        if(essFileListTask!=null){
            essFileListTask.cancel(true);
        }
        if(essFileCountTask!=null){
            essFileCountTask.cancel(true);
        }
    }

    @Override
    public void onClick(View v) {
        int id = v.getId();
        if (id == R.id.imb_select_sdcard) {
            showPopupWindow();
        }
    }


    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int i = item.getItemId();
        if (i == R.id.browser_select_count) {
            //选中
            if (mSelectedFileList.isEmpty()) {
                return true;
            }
            //不为空
            Intent result = new Intent();
            result.putParcelableArrayListExtra(Const.EXTRA_RESULT_SELECTION, mSelectedFileList);
            setResult(RESULT_OK, result);
            super.onBackPressed();
        } else if (i == R.id.browser_sort) {
            //排序
            new AlertDialog
                    .Builder(this)
                    .setSingleChoiceItems(R.array.sort_list, 0, new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            mSelectSortTypeIndex = which;
                        }
                    })
                    .setNegativeButton("降序", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            switch (mSelectSortTypeIndex) {
                                case 0:
                                    SelectOptions.getInstance().setSortType(FileUtils.BY_NAME_DESC);
                                    break;
                                case 1:
                                    SelectOptions.getInstance().setSortType(FileUtils.BY_TIME_ASC);
                                    break;
                                case 2:
                                    SelectOptions.getInstance().setSortType(FileUtils.BY_SIZE_DESC);
                                    break;
                                case 3:
                                    SelectOptions.getInstance().setSortType(FileUtils.BY_EXTENSION_DESC);
                                    break;
                            }
                            //恢复排序
                            mBreadAdapter.getData().get(mBreadAdapter.getData().size() - 1).setPrePosition(0);
                            executeListTask(mSelectedFileList, mCurFolder, SelectOptions.getInstance().getFileTypes(), SelectOptions.getInstance().getSortType());
                        }
                    })
                    .setPositiveButton("升序", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            switch (mSelectSortTypeIndex) {
                                case 0:
                                    SelectOptions.getInstance().setSortType(FileUtils.BY_NAME_ASC);
                                    break;
                                case 1:
                                    SelectOptions.getInstance().setSortType(FileUtils.BY_TIME_DESC);
                                    break;
                                case 2:
                                    SelectOptions.getInstance().setSortType(FileUtils.BY_SIZE_ASC);
                                    break;
                                case 3:
                                    SelectOptions.getInstance().setSortType(FileUtils.BY_EXTENSION_ASC);
                                    break;
                            }
                            //恢复排序
                            mBreadAdapter.getData().get(mBreadAdapter.getData().size() - 1).setPrePosition(0);
                            executeListTask(mSelectedFileList, mCurFolder, SelectOptions.getInstance().getFileTypes(), SelectOptions.getInstance().getSortType());
                        }
                    })
                    .setTitle("请选择")
                    .show();

        }
        return true;
    }

    @Override
    public void onLoadFileCount(int position) {
        essFileCountTask = new EssFileCountTask(position, mAdapter.getData().get(position).getAbsolutePath(), SelectOptions.getInstance().getFileTypes(), this);
        essFileCountTask.execute();
    }
}


================================================
FILE: filepicker/src/main/java/com/ess/filepicker/activity/SelectFileByScanActivity.java
================================================
package com.ess.filepicker.activity;

import android.content.DialogInterface;
import android.content.Intent;
import android.support.design.widget.TabLayout;
import android.support.v4.app.Fragment;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;

import com.ess.filepicker.R;
import com.ess.filepicker.SelectOptions;
import com.ess.filepicker.adapter.FragmentPagerAdapter;
import com.ess.filepicker.loader.EssMimeTypeCollection;
import com.ess.filepicker.model.EssFile;
import com.ess.filepicker.model.FileScanActEvent;
import com.ess.filepicker.model.FileScanFragEvent;
import com.ess.filepicker.model.FileScanSortChangedEvent;
import com.ess.filepicker.util.Const;
import com.ess.filepicker.util.FileUtils;

import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;


/**
 * 通过扫描来选择文件
 */
public class SelectFileByScanActivity extends AppCompatActivity implements ViewPager.OnPageChangeListener {

    /*todo 是否可预览文件,默认可预览*/
    private boolean mCanPreview = true;

    private ViewPager mViewPager;
    private TabLayout mTabLayout;
    private Toolbar mToolBar;
    private MenuItem mCountMenuItem;

    private ArrayList<EssFile> mSelectedFileList = new ArrayList<>();
    /*当前选中排序方式的位置*/
    private int mSelectSortTypeIndex = 0;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_select_file_by_scan);
        EventBus.getDefault().register(this);

        initUi();
        initData();
    }

    private void initData() {
    }

    private void initUi() {
        mViewPager = findViewById(R.id.vp_select_file_scan);
        mTabLayout = findViewById(R.id.tabl_select_file_scan);
        mToolBar = findViewById(R.id.toolbar);
        setSupportActionBar(mToolBar);
        getSupportActionBar().setTitle("文件选择");
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        getSupportActionBar().setHomeButtonEnabled(true);
        mToolBar.setNavigationOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                onBackPressed();
            }
        });

        mTabLayout.setTabGravity(TabLayout.GRAVITY_CENTER);
        mTabLayout.setTabMode(TabLayout.MODE_SCROLLABLE);

        List<Fragment> fragmentList = new ArrayList<>();
        for (int i = 0; i < SelectOptions.getInstance().getFileTypes().length; i++) {
            fragmentList.add(FileTypeListFragment.newInstance(SelectOptions.getInstance().getFileTypes()[i],SelectOptions.getInstance().isSingle,SelectOptions.getInstance().maxCount,SelectOptions.getInstance().getSortType(),EssMimeTypeCollection.LOADER_ID+i));
        }
        FragmentPagerAdapter adapter = new FragmentPagerAdapter(getSupportFragmentManager(), fragmentList, Arrays.asList(SelectOptions.getInstance().getFileTypes()));
        mViewPager.setAdapter(adapter);
        mTabLayout.setupWithViewPager(mViewPager);
        mViewPager.setOffscreenPageLimit(fragmentList.size() - 1);
        mViewPager.addOnPageChangeListener(this);

    }


    /**
     * Fragment中选择文件后
     *
     * @param event event
     */
    @Subscribe
    public void onFragSelectFile(FileScanFragEvent event) {
        if (event.isAdd()) {
            if (SelectOptions.getInstance().isSingle) {
                mSelectedFileList.add(event.getSelectedFile());
                Intent result = new Intent();
                result.putParcelableArrayListExtra(Const.EXTRA_RESULT_SELECTION, mSelectedFileList);
                setResult(RESULT_OK, result);
                super.onBackPressed();
                return;
            }
            mSelectedFileList.add(event.getSelectedFile());
        } else {
            mSelectedFileList.remove(event.getSelectedFile());
        }
        mCountMenuItem.setTitle(String.format(getString(R.string.selected_file_count), String.valueOf(mSelectedFileList.size()), String.valueOf(SelectOptions.getInstance().maxCount)));
        EventBus.getDefault().post(new FileScanActEvent(SelectOptions.getInstance().maxCount - mSelectedFileList.size()));
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        EventBus.getDefault().unregister(this);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.browse_menu, menu);
        mCountMenuItem = menu.findItem(R.id.browser_select_count);
        mCountMenuItem.setTitle(String.format(getString(R.string.selected_file_count), String.valueOf(mSelectedFileList.size()), String.valueOf(SelectOptions.getInstance().maxCount)));
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int i = item.getItemId();
        if (i == R.id.browser_select_count) {
            //选中
            if (mSelectedFileList.isEmpty()) {
                return true;
            }
            //不为空
            Intent result = new Intent();
            result.putParcelableArrayListExtra(Const.EXTRA_RESULT_SELECTION, mSelectedFileList);
            setResult(RESULT_OK, result);
            super.onBackPressed();
        } else if (i == R.id.browser_sort) {
            //排序
            new AlertDialog
                    .Builder(this)
                    .setSingleChoiceItems(R.array.sort_list_scan, 0, new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            mSelectSortTypeIndex = which;
                        }
                    })
                    .setNegativeButton("降序", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            switch (mSelectSortTypeIndex) {
                                case 0:
                                    SelectOptions.getInstance().setSortType(FileUtils.BY_NAME_DESC);
                                    break;
                                case 1:
                                    SelectOptions.getInstance().setSortType(FileUtils.BY_TIME_ASC);
                                    break;
                                case 2:
                                    SelectOptions.getInstance().setSortType(FileUtils.BY_SIZE_DESC);
                                    break;
                            }
                            EventBus.getDefault().post(new FileScanSortChangedEvent(SelectOptions.getInstance().getSortType(),mViewPager.getCurrentItem()));
                        }
                    })
                    .setPositiveButton("升序", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            switch (mSelectSortTypeIndex) {
                                case 0:
                                    SelectOptions.getInstance().setSortType(FileUtils.BY_NAME_ASC);
                                    break;
                                case 1:
                                    SelectOptions.getInstance().setSortType(FileUtils.BY_TIME_DESC);
                                    break;
                                case 2:
                                    SelectOptions.getInstance().setSortType(FileUtils.BY_SIZE_ASC);
                                    break;
                            }
                            EventBus.getDefault().post(new FileScanSortChangedEvent(SelectOptions.getInstance().getSortType(),mViewPager.getCurrentItem()));
                        }
                    })
                    .setTitle("请选择")
                    .show();

        }
        return true;
    }

    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

    }

    @Override
    public void onPageSelected(int position) {
        EventBus.getDefault().post(new FileScanActEvent(SelectOptions.getInstance().maxCount - mSelectedFileList.size()));
    }

    @Override
    public void onPageScrollStateChanged(int state) {

    }
}


================================================
FILE: filepicker/src/main/java/com/ess/filepicker/activity/SelectPictureActivity.java
================================================
package com.ess.filepicker.activity;

import android.content.Intent;
import android.content.res.TypedArray;
import android.database.Cursor;
import android.graphics.PorterDuff;
import android.graphics.drawable.Drawable;
import android.support.design.widget.Snackbar;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.TextView;

import com.chad.library.adapter.base.BaseQuickAdapter;
import com.ess.filepicker.R;
import com.ess.filepicker.SelectOptions;
import com.ess.filepicker.adapter.BuketAdapter;
import com.ess.filepicker.adapter.EssMediaAdapter;
import com.ess.filepicker.loader.EssAlbumCollection;
import com.ess.filepicker.loader.EssMediaCollection;
import com.ess.filepicker.model.Album;
import com.ess.filepicker.model.EssFile;
import com.ess.filepicker.util.Const;
import com.ess.filepicker.util.UiUtils;
import com.ess.filepicker.widget.MediaItemDecoration;
import com.ess.filepicker.widget.ToolbarSpinner;

import java.io.File;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;

import top.zibin.luban.Luban;
import top.zibin.luban.OnCompressListener;


/**
 * 选择图片界面
 */
public class SelectPictureActivity extends AppCompatActivity implements EssAlbumCollection.EssAlbumCallbacks, AdapterView.OnItemSelectedListener, EssMediaCollection.EssMediaCallbacks, BaseQuickAdapter.OnItemChildClickListener, BaseQuickAdapter.OnItemClickListener {

    /*4. 最多可选择个数,默认10*/
    private int mMaxCount = 10;
    /*5. todo 是否需要压缩,默认返回压缩之后的图片*/
    private boolean mNeedCompress = true;
    /*6. todo 是否需要裁剪/旋转等,默认不裁剪*/
    private boolean mNeedClip = false;
    /*7. 是否需要显示照相机*/
    private boolean mNeedCamera = true;
    /*8. todo 相机为自定义相机还是系统相机,仅当mNeedCamera=true时有效*/
    private boolean mUseCustomCamera = true;
    /*9. todo 是否可预览图片,默认可预览*/
    private boolean mCanPreview = true;

    private RecyclerView mRecyclerView;
    private TextView mTvSelectedFolder;
    private BuketAdapter mBuketAdapter;
    private EssMediaAdapter mMediaAdapter;

    private final EssAlbumCollection mAlbumCollection = new EssAlbumCollection();
    private final EssMediaCollection mMediaCollection = new EssMediaCollection();
    private MenuItem mCountMenuItem;
    private Set<EssFile> mSelectedFileList = new LinkedHashSet<>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        setTheme(SelectOptions.getInstance().themeId);
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_select_picture);
//        EventBus.getDefault().register(this);
        mRecyclerView = findViewById(R.id.rcv_file_picture_list);
        mTvSelectedFolder = findViewById(R.id.selected_folder);

        initUI();
    }

    private void initUI() {
        Toolbar toolbar = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        ActionBar actionBar = getSupportActionBar();
        if (actionBar != null) {
            actionBar.setDisplayShowTitleEnabled(false);
            actionBar.setDisplayHomeAsUpEnabled(true);
        }
        toolbar.setNavigationOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                onBackPressed();
            }
        });
        Drawable navigationIcon = toolbar.getNavigationIcon();
        TypedArray ta = getTheme().obtainStyledAttributes(new int[]{R.attr.album_element_color});
        int color = ta.getColor(0, 0);
        ta.recycle();
        if (navigationIcon != null) {
            navigationIcon.setColorFilter(color, PorterDuff.Mode.SRC_IN);
        }

        mBuketAdapter = new BuketAdapter(this, null, false);
        ToolbarSpinner spinner = new ToolbarSpinner(this);
        spinner.setSelectedTextView((TextView) findViewById(R.id.selected_folder));
        spinner.setPopupAnchorView(findViewById(R.id.toolbar));
        spinner.setOnItemSelectedListener(this);
        spinner.setAdapter(mBuketAdapter);

        mAlbumCollection.onCreate(this, this);
        mAlbumCollection.load();
        mMediaCollection.onCreate(this, this);

        mRecyclerView.setLayoutManager(new GridLayoutManager(this, 3));
        mRecyclerView.addItemDecoration(new MediaItemDecoration());
        mMediaAdapter = new EssMediaAdapter(new ArrayList<EssFile>());
        mMediaAdapter.setImageResize(UiUtils.getImageResize(this, mRecyclerView));
        mRecyclerView.setAdapter(mMediaAdapter);
        mMediaAdapter.bindToRecyclerView(mRecyclerView);
        mMediaAdapter.setOnItemChildClickListener(this);
        if (SelectOptions.getInstance().isSingle || SelectOptions.getInstance().maxCount == 1) {
            //单选
            mMediaAdapter.setOnItemClickListener(this);
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.media_menu, menu);
        mCountMenuItem = menu.findItem(R.id.browser_select_count);
        mCountMenuItem.setTitle(String.format(getString(R.string.selected_file_count), String.valueOf(mSelectedFileList.size()), String.valueOf(mMaxCount)));
        return true;
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        mAlbumCollection.onDestroy();
        mMediaCollection.onDestroy();
    }

    @Override
    public void onAlbumMediaLoad(Cursor cursor) {
        mBuketAdapter.swapCursor(cursor);
        cursor.moveToFirst();
        Album album = Album.valueOf(cursor);
        mMediaCollection.load(album, mNeedCamera, mSelectedFileList);
    }

    @Override
    public void onAlbumMediaReset() {

    }

    @Override
    public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
        mBuketAdapter.getCursor().moveToPosition(position);
        Album album = Album.valueOf(mBuketAdapter.getCursor());
        mMediaCollection.load(album, mNeedCamera, mSelectedFileList);
    }

    @Override
    public void onNothingSelected(AdapterView<?> parent) {

    }

    @Override
    public void onMediaLoad(List<EssFile> essFileList) {
        mMediaAdapter.setNewData(essFileList);
        if (essFileList == null || essFileList.isEmpty()) {
            mMediaAdapter.setEmptyView(R.layout.empty_file_list);
        }
    }

    @Override
    public void onmMediaReset() {

    }

    @Override
    public void onItemChildClick(BaseQuickAdapter adapter, View view, int position) {
        EssFile item = mMediaAdapter.getItem(position);
        if (!adapter.equals(mMediaAdapter)) {
            return;
        }
        if (view.getId() == R.id.check_view) {
            if (mSelectedFileList.size() >= SelectOptions.getInstance().maxCount && !item.isChecked()) {
                mMediaAdapter.notifyItemChanged(position, "");
                Snackbar.make(mRecyclerView, "您最多只能选择" + SelectOptions.getInstance().maxCount + "个。", Snackbar.LENGTH_SHORT).show();
                return;
            }
            boolean addSuccess = mSelectedFileList.add(mMediaAdapter.getItem(position));
            if (addSuccess) {
                mMediaAdapter.getData().get(position).setChecked(true);
            } else {
                //已经有了就删掉
                mSelectedFileList.remove(item);
                mMediaAdapter.getData().get(position).setChecked(false);
            }
            mMediaAdapter.notifyItemChanged(position, "");
            mCountMenuItem.setTitle(String.format(getString(R.string.selected_file_count), String.valueOf(mSelectedFileList.size()), String.valueOf(mMaxCount)));
        } else if (view.getId() == R.id.media_thumbnail) {
            //预览
            // TODO: 2018/3/7  预览照片
        } else if (view.getId() == R.id.capture) {
            //照相
            // TODO: 2018/3/7  自定义相机照相
        }
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int itemId = item.getItemId();
        if (itemId == R.id.browser_select_count) {
            //选中
            if (mSelectedFileList.isEmpty()) {
                return true;
            }
            if (SelectOptions.getInstance().compressImage) {
                //需要压缩
                final ArrayList<String> imageList = EssFile.getFilePathList(EssFile.getEssFileList(this, mSelectedFileList));
                final int[] successCount = {0};
                //todo 当目标文件夹存在此文件时不覆盖
                Luban.with(this)
                        .load(imageList)// 传人要压缩的图片列表
                        .ignoreBy(100) // 忽略不压缩图片的大小
                        .setTargetDir(SelectOptions.getInstance().getTargetPath())// 设置压缩后文件存储位置
                        .setCompressListener(new OnCompressListener() { //设置回调
                            @Override
                            public void onStart() {

                            }

                            @Override
                            public void onSuccess(File file) {
                                successCount[0]++;
                                if(successCount[0] == imageList.size()){
                                    Intent result = new Intent();
                                    result.putParcelableArrayListExtra(Const.EXTRA_RESULT_SELECTION, EssFile.getEssFileList(SelectPictureActivity.this, mSelectedFileList));
                                    setResult(RESULT_OK, result);
                                    onBackPressed();
                                }
                            }

                            @Override
                            public void onError(Throwable e) {
                                Log.i("TAG", e.toString());
                            }
                        })
                        .launch();    //启动压缩
            }else {
                Intent result = new Intent();
                result.putParcelableArrayListExtra(Const.EXTRA_RESULT_SELECTION, EssFile.getEssFileList(SelectPictureActivity.this, mSelectedFileList));
                setResult(RESULT_OK, result);
                onBackPressed();
            }
        }
        return true;
    }


    @Override
    public void onItemClick(BaseQuickAdapter adapter, View view, int position) {
        //单选
        mSelectedFileList.add(mMediaAdapter.getData().get(position));
        Intent result = new Intent();
        result.putParcelableArrayListExtra(Const.EXTRA_RESULT_SELECTION, EssFile.getEssFileList(this, mSelectedFileList));
        setResult(RESULT_OK, result);
        super.onBackPressed();
    }
}


================================================
FILE: filepicker/src/main/java/com/ess/filepicker/adapter/BreadAdapter.java
================================================
package com.ess.filepicker.adapter;


import android.support.annotation.Nullable;

import com.chad.library.adapter.base.BaseQuickAdapter;
import com.chad.library.adapter.base.BaseViewHolder;
import com.ess.filepicker.model.BreadModel;
import com.ess.filepicker.R;

import java.util.List;

/**
 * BreadAdapter
 * Created by 李波 on 2018/2/5.
 */

public class BreadAdapter extends BaseQuickAdapter<BreadModel, BaseViewHolder> {

    public BreadAdapter(@Nullable List<BreadModel> data) {
        super(R.layout.bread_item,data);
    }

    @Override
    protected void convert(BaseViewHolder helper, BreadModel item) {
        helper.setText(R.id.btn_bread,item.getCurName());
        helper.addOnClickListener(R.id.btn_bread);
    }
}


================================================
FILE: filepicker/src/main/java/com/ess/filepicker/adapter/BuketAdapter.java
================================================
package com.ess.filepicker.adapter;

import android.content.Context;
import android.content.res.TypedArray;
import android.database.Cursor;
import android.graphics.drawable.Drawable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CursorAdapter;
import android.widget.ImageView;
import android.widget.TextView;

import com.bumptech.glide.Glide;
import com.bumptech.glide.request.RequestOptions;
import com.ess.filepicker.R;
import com.ess.filepicker.SelectOptions;
import com.ess.filepicker.model.Album;

/**
 * BuketAdapter
 * Created by 李波 on 2018/3/1.
 */

public class BuketAdapter extends CursorAdapter{

    private final Drawable mPlaceholder;

    public BuketAdapter(Context context, Cursor c, boolean autoRequery) {
        super(context, c, autoRequery);
        TypedArray ta = context.getTheme().obtainStyledAttributes(
                new int[]{R.attr.album_thumbnail_placeholder});
        mPlaceholder = ta.getDrawable(0);
        ta.recycle();
    }

    @Override
    public View newView(Context context, Cursor cursor, ViewGroup parent) {
        return LayoutInflater.from(context).inflate(R.layout.buket_list_item, parent, false);
    }

    @Override
    public void bindView(View view, Context context, Cursor cursor) {
        Album album = Album.valueOf(cursor);
        ((TextView) view.findViewById(R.id.album_name)).setText(album.getDisplayName(context));
        ((TextView) view.findViewById(R.id.album_media_count)).setText(String.valueOf(album.getCount()));
        RequestOptions options = new RequestOptions()
                .centerCrop()
                .placeholder(mPlaceholder);
        Glide
                .with(context)
                .load(album.getCoverPath())
                .apply(options)
                .into((ImageView) view.findViewById(R.id.album_cover));
    }
}


================================================
FILE: filepicker/src/main/java/com/ess/filepicker/adapter/EssMediaAdapter.java
================================================
package com.ess.filepicker.adapter;

import android.support.annotation.Nullable;
import android.support.v7.widget.AppCompatCheckBox;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;

import com.bumptech.glide.Glide;
import com.bumptech.glide.request.RequestOptions;
import com.chad.library.adapter.base.BaseQuickAdapter;
import com.chad.library.adapter.base.BaseViewHolder;
import com.ess.filepicker.R;
import com.ess.filepicker.SelectOptions;
import com.ess.filepicker.model.EssFile;
import com.ess.filepicker.util.UiUtils;

import java.util.List;


/**
 * EssMediaAdapter
 * Created by 李波 on 2018/3/2.
 */

public class EssMediaAdapter extends BaseQuickAdapter<EssFile, BaseViewHolder> {

    private int mImageResize;

    public EssMediaAdapter(@Nullable List<EssFile> data) {
        super(R.layout.ess_media_item,data);
    }

    public void setImageResize(int imageSize) {
        this.mImageResize = imageSize;
    }

    @Override
    protected void convert(BaseViewHolder helper, EssFile item) {
        if (item.getItemType() == EssFile.CAPTURE) {
            helper.getView(R.id.media).setVisibility(View.GONE);
            helper.getView(R.id.capture).setVisibility(View.VISIBLE);
            helper.itemView.setLayoutParams(new ViewGroup.LayoutParams(mImageResize- UiUtils.dpToPx(mContext,4), mImageResize));
            helper.addOnClickListener(R.id.capture);
        } else {
            helper.getView(R.id.capture).setVisibility(View.GONE);
            helper.getView(R.id.media).setVisibility(View.VISIBLE);
            helper.itemView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, mImageResize));
            ImageView imageView = helper.getView(R.id.media_thumbnail);
            RequestOptions options = new RequestOptions()
                    .centerCrop()
                    .override(mImageResize, mImageResize)
                    .placeholder(SelectOptions.getInstance().placeHolder == null ? mContext.getResources().getDrawable(R.mipmap.png_holder) : SelectOptions.getInstance().placeHolder);
            Glide
                    .with(mContext)
                    .load(item.getUri())
                    .apply(options)
                    .into(imageView);
            if(SelectOptions.getInstance().isSingle || SelectOptions.getInstance().maxCount == 1){
                helper.setVisible(R.id.check_view,false);
            }else {
                AppCompatCheckBox checkBox = helper.getView(R.id.check_view);
                helper.setVisible(R.id.check_view,true);
                helper.addOnClickListener(R.id.check_view);
                helper.addOnClickListener(R.id.media_thumbnail);
                checkBox.setChecked(item.isChecked());
            }
        }

    }


}


================================================
FILE: filepicker/src/main/java/com/ess/filepicker/adapter/FileListAdapter.java
================================================
package com.ess.filepicker.adapter;

import android.support.annotation.Nullable;
import android.widget.ImageView;
import android.widget.TextView;

import com.bumptech.glide.Glide;
import com.bumptech.glide.request.RequestOptions;
import com.chad.library.adapter.base.BaseQuickAdapter;
import com.chad.library.adapter.base.BaseViewHolder;
import com.ess.filepicker.model.EssFile;
import com.ess.filepicker.util.FileSizeUtil;
import com.ess.filepicker.util.FileUtils;
import com.ess.filepicker.R;

import java.util.List;

/**
 * FileListAdapter
 * Created by 李波 on 2018/2/3.
 */

public class FileListAdapter extends BaseQuickAdapter<EssFile, BaseViewHolder> {

    private onLoadFileCountListener loadFileCountListener;

    public interface onLoadFileCountListener{
        void onLoadFileCount(int posistion);
    }

    public onLoadFileCountListener getLoadFileCountListener() {
        return loadFileCountListener;
    }

    public void setLoadFileCountListener(onLoadFileCountListener loadFileCountListener) {
        this.loadFileCountListener = loadFileCountListener;
    }

    public FileListAdapter(@Nullable List<EssFile> data) {
        super(R.layout.item_file_list, data);
    }

    @Override
    protected void convert(BaseViewHolder helper, EssFile item) {
        TextView textView = helper.getView(R.id.tv_item_file_list_desc);
        if (item.isDirectory()) {
            helper.setVisible(R.id.iv_item_file_select_right, true);
            if(item.getChildFolderCount().equals("加载中")){
                //查找数量
                if(loadFileCountListener!=null){
                    loadFileCountListener.onLoadFileCount(helper.getAdapterPosition());
                }
            }
            textView.setText(String.format(mContext.getString(R.string.folder_desc), item.getChildFileCount(),item.getChildFolderCount()));
        } else {
            helper.setVisible(R.id.iv_item_file_select_right, false);
            textView.setText(String.format(mContext.getString(R.string.file_desc), FileUtils.getDateTime(item.getAbsolutePath()), FileSizeUtil.getAutoFileOrFilesSize(item.getFile())));
        }
        helper.setText(R.id.tv_item_file_list, item.getName());
        if(item.isChecked()){
            helper.setVisible(R.id.checkbox_item_file_list,true);
        }else {
            helper.setVisible(R.id.checkbox_item_file_list,false);
        }
        ImageView imageView = helper.getView(R.id.iv_item_file_select_left);
        String fileNameExtension = FileUtils.getExtension(item.getName()).toLowerCase();
        switch (fileNameExtension) {
            case "apk":
                imageView.setImageResource(R.mipmap.apk);
                break;
            case "avi":
                imageView.setImageResource(R.mipmap.avi);
                break;
            case "doc":
            case "docx":
                imageView.setImageResource(R.mipmap.doc);
                break;
            case "exe":
                imageView.setImageResource(R.mipmap.exe);
                break;
            case "flv":
                imageView.setImageResource(R.mipmap.flv);
                break;
            case "gif":
                RequestOptions options = new RequestOptions()
                        .centerCrop()
                        .placeholder(R.mipmap.gif);
                Glide
                        .with(mContext)
                        .load(item.getAbsolutePath())
                        .apply(options)
                        .into(imageView);
                break;
            case "jpg":
            case "jpeg":
            case "png":
                RequestOptions options2 = new RequestOptions()
                        .centerCrop()
                        .placeholder(R.mipmap.png);
                Glide
                        .with(mContext)
                        .load(item.getAbsolutePath())
                        .apply(options2)
                        .into(imageView);
                break;
            case "mp3":
                imageView.setImageResource(R.mipmap.mp3);
                break;
            case "mp4":
            case "f4v":
                imageView.setImageResource(R.mipmap.movie);
                break;
            case "pdf":
                imageView.setImageResource(R.mipmap.pdf);
                break;
            case "ppt":
            case "pptx":
                imageView.setImageResource(R.mipmap.ppt);
                break;
            case "wav":
                imageView.setImageResource(R.mipmap.wav);
                break;
            case "xls":
            case "xlsx":
                imageView.setImageResource(R.mipmap.xls);
                break;
            case "zip":
                imageView.setImageResource(R.mipmap.zip);
                break;
            case "ext":
            default:
                if (item.isDirectory()) {
                    imageView.setImageResource(R.mipmap.folder);
                } else {
                    imageView.setImageResource(R.mipmap.documents);
                }
                break;
        }
    }
}


================================================
FILE: filepicker/src/main/java/com/ess/filepicker/adapter/FragmentPagerAdapter.java
================================================
package com.ess.filepicker.adapter;

import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;
import android.support.v4.app.FragmentTransaction;
import android.view.ViewGroup;

import java.util.ArrayList;
import java.util.List;

/**
 * Fragment结合ViewPager一起使用的Adapter
 */
public class FragmentPagerAdapter extends FragmentStatePagerAdapter {

    private List<Fragment> fragmentList;
    private List<String> titleArray;
    private FragmentManager fm;

    public FragmentPagerAdapter(FragmentManager fm) {
        super(fm);
        this.fm = fm;
    }

    public FragmentPagerAdapter(FragmentManager fm, List<Fragment> fragmentList, List<String> titleArray) {
        this(fm);
        this.fragmentList = fragmentList;
        this.titleArray = titleArray;
    }

    public FragmentPagerAdapter(FragmentManager fm, List<Fragment> fragmentList) {
        this(fm);
        this.fragmentList = fragmentList;
    }

    public void setFragments(ArrayList<Fragment> fragments) {
        if (this.fragmentList != null) {
            FragmentTransaction ft = fm.beginTransaction();
            for (Fragment f : this.fragmentList) {
                ft.remove(f);
            }
            ft.commit();
            ft = null;
            fm.executePendingTransactions();
        }
        this.fragmentList = fragments;
        notifyDataSetChanged();
    }

    @Override
    public CharSequence getPageTitle(int position) {
        if (titleArray != null) {
            return titleArray.get(position);
        }
        return "";
    }

    @Override
    public int getCount() {
        return fragmentList.size();
    }

    @Override
    public Fragment getItem(int position) {
        return fragmentList.get(position);
    }

    @Override
    public int getItemPosition(Object object) {
        return POSITION_NONE;
    }

    @Override
    public Object instantiateItem(ViewGroup container, final int position) {
        return super.instantiateItem(container, position);
    }
}


================================================
FILE: filepicker/src/main/java/com/ess/filepicker/adapter/OnFileSelectListener.java
================================================
package com.ess.filepicker.adapter;

import com.ess.filepicker.model.EssFile;

import java.util.List;

/**
 * OnFileSelectListener
 * Created by 李波 on 2018/2/26.
 */

public interface OnFileSelectListener {
    void onSelected(List<EssFile> essFileList);
}


================================================
FILE: filepicker/src/main/java/com/ess/filepicker/adapter/SelectSdcardAdapter.java
================================================
package com.ess.filepicker.adapter;

import android.support.annotation.Nullable;

import com.chad.library.adapter.base.BaseQuickAdapter;
import com.chad.library.adapter.base.BaseViewHolder;
import com.ess.filepicker.R;

import java.util.List;

/**
 * SelectSdcardAdapter
 * Created by 李波 on 2018/2/8.
 */

public class SelectSdcardAdapter extends BaseQuickAdapter<String,BaseViewHolder>{
    public SelectSdcardAdapter(@Nullable List<String> data) {
        super(R.layout.item_select_sdcard,data);
    }

    @Override
    protected void convert(BaseViewHolder helper, String item) {
        helper.setText(R.id.tv_item_select_sdcard,item);
    }
}


================================================
FILE: filepicker/src/main/java/com/ess/filepicker/loader/EssAlbumCollection.java
================================================
/*
 * Copyright (C) 2014 nohana, Inc.
 * Copyright 2017 Zhihu Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an &quot;AS IS&quot; BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.ess.filepicker.loader;

import android.content.Context;
import android.database.Cursor;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.Loader;

import java.lang.ref.WeakReference;

public class EssAlbumCollection implements LoaderManager.LoaderCallbacks<Cursor> {
    private static final int LOADER_ID = 1;
    private WeakReference<Context> mContext;
    private LoaderManager mLoaderManager;
    private EssAlbumCallbacks mCallbacks;

    @Override
    public Loader<Cursor> onCreateLoader(int id, Bundle args) {
        Context context = mContext.get();
        if (context == null) {
            return null;
        }


        return EssAlbumLoader.newInstance(context);
    }

    @Override
    public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
        Context context = mContext.get();
        if (context == null) {
            return;
        }

        mCallbacks.onAlbumMediaLoad(data);
    }

    @Override
    public void onLoaderReset(Loader<Cursor> loader) {
        Context context = mContext.get();
        if (context == null) {
            return;
        }

        mCallbacks.onAlbumMediaReset();
    }

    public void onCreate(@NonNull FragmentActivity context, @NonNull EssAlbumCallbacks callbacks) {
        mContext = new WeakReference<Context>(context);
        mLoaderManager = context.getSupportLoaderManager();
        mCallbacks = callbacks;
    }

    public void onDestroy() {
        mLoaderManager.destroyLoader(LOADER_ID);
        mCallbacks = null;
    }

    public void load() {
        Bundle args = new Bundle();
        mLoaderManager.initLoader(LOADER_ID, args, this);
    }

    public interface EssAlbumCallbacks {

        void onAlbumMediaLoad(Cursor cursor);

        void onAlbumMediaReset();
    }
}


================================================
FILE: filepicker/src/main/java/com/ess/filepicker/loader/EssAlbumLoader.java
================================================
package com.ess.filepicker.loader;

import android.content.Context;
import android.database.Cursor;
import android.database.MatrixCursor;
import android.database.MergeCursor;
import android.net.Uri;
import android.provider.MediaStore;
import android.support.v4.content.CursorLoader;

import com.ess.filepicker.SelectOptions;
import com.ess.filepicker.model.Album;

/**
 * EssAlbumLoader
 * Created by 李波 on 2018/2/27.
 */

public class EssAlbumLoader extends CursorLoader {

    public static final String COLUMN_COUNT = "count";
    private static final Uri QUERY_URI = MediaStore.Files.getContentUri("external");
    private static final String[] COLUMNS = {
            MediaStore.Files.FileColumns._ID,
            "bucket_id",
            "bucket_display_name",
            MediaStore.MediaColumns.DATA,
            COLUMN_COUNT};
    private static final String[] PROJECTION = {
            MediaStore.Files.FileColumns._ID,
            "bucket_id",
            "bucket_display_name",
            MediaStore.MediaColumns.DATA,
            "COUNT(*) AS " + COLUMN_COUNT};

    // === params for showSingleMediaType: false ===
    private static final String SELECTION =
            "(" + MediaStore.Files.FileColumns.MEDIA_TYPE + "=?"
                    + " OR "
                    + MediaStore.Files.FileColumns.MEDIA_TYPE + "=?)"
                    + " AND " + MediaStore.MediaColumns.SIZE + ">0"
                    + ") GROUP BY (bucket_id";
    private static final String[] SELECTION_ARGS = {
            String.valueOf(MediaStore.Files.FileColumns.MEDIA_TYPE_IMAGE),
            String.valueOf(MediaStore.Files.FileColumns.MEDIA_TYPE_VIDEO),
    };
    // =============================================

    // === params for showSingleMediaType: true ===
    private static final String SELECTION_FOR_SINGLE_MEDIA_TYPE =
            MediaStore.Files.FileColumns.MEDIA_TYPE + "=?"
                    + " AND " + MediaStore.MediaColumns.SIZE + ">0"
                    + ") GROUP BY (bucket_id";

    private static String[] getSelectionArgsForSingleMediaType(int mediaType) {
        return new String[]{String.valueOf(mediaType)};
    }
    // =============================================

    private static final String BUCKET_ORDER_BY = "datetaken DESC";

    public EssAlbumLoader(Context context, String selection, String[] selectionArgs) {
        super(context, QUERY_URI, PROJECTION, selection, selectionArgs, BUCKET_ORDER_BY);
    }

    public static CursorLoader newInstance(Context context) {
        String selection;
        String[] selectionArgs;
        if (SelectOptions.getInstance().onlyShowImages) {
            selection = SELECTION_FOR_SINGLE_MEDIA_TYPE;
            selectionArgs = getSelectionArgsForSingleMediaType(MediaStore.Files.FileColumns.MEDIA_TYPE_IMAGE);
        } else if (SelectOptions.getInstance().onlyShowVideos) {
            selection = SELECTION_FOR_SINGLE_MEDIA_TYPE;
            selectionArgs = getSelectionArgsForSingleMediaType(MediaStore.Files.FileColumns.MEDIA_TYPE_VIDEO);
        } else {
            selection = SELECTION;
            selectionArgs = SELECTION_ARGS;
        }
        return new EssAlbumLoader(context, selection, selectionArgs);
    }

    @Override
    public Cursor loadInBackground() {
        Cursor albums = super.loadInBackground();
        MatrixCursor allAlbum = new MatrixCursor(COLUMNS);
        int totalCount = 0;
        String allAlbumCoverPath = "";
        if (albums != null) {
            while (albums.moveToNext()) {
                totalCount += albums.getInt(albums.getColumnIndex(COLUMN_COUNT));
            }
            if (albums.moveToFirst()) {
                allAlbumCoverPath = albums.getString(albums.getColumnIndex(MediaStore.MediaColumns.DATA));
            }
        }
        allAlbum.addRow(new String[]{Album.ALBUM_ID_ALL, Album.ALBUM_ID_ALL, Album.ALBUM_NAME_ALL, allAlbumCoverPath,
                String.valueOf(totalCount)});



        return new MergeCursor(new Cursor[]{allAlbum, albums});
    }


}


================================================
FILE: filepicker/src/main/java/com/ess/filepicker/loader/EssMediaCollection.java
================================================
package com.ess.filepicker.loader;

import android.content.Context;
import android.database.Cursor;
import android.os.Bundle;
import android.provider.MediaStore;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.Loader;

import com.ess.filepicker.model.Album;
import com.ess.filepicker.model.EssFile;

import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;

/**
 * EssMediaCollection
 * Created by 李波 on 2018/3/2.
 */

public class EssMediaCollection implements LoaderManager.LoaderCallbacks<Cursor>{

    private static final int LOADER_ID = 2;
    private static final String ARGS_ALBUM = "args_album";
    private static final String ARGS_ENABLE_CAPTURE = "args_enable_capture";
    private static final String ARGS_ONLY_SHOWIMAGE = "args_only_showimage";
    private WeakReference<Context> mContext;
    private LoaderManager mLoaderManager;
    private EssMediaCallbacks mCallbacks;
    private Set<EssFile> essFileSet = new LinkedHashSet<>();

    @Override
    public Loader<Cursor> onCreateLoader(int id, Bundle args) {
        Context context = mContext.get();
        if (context == null) {
            return null;
        }

        Album album = args.getParcelable(ARGS_ALBUM);
        if (album == null) {
            return null;
        }

        return EssMediaLoader.newInstance(context, album);
    }

    @Override
    public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
        Context context = mContext.get();
        if (context == null) {
            return;
        }

        List<EssFile> essFileList = new ArrayList<>();
        while (data.moveToNext()){
            EssFile essFile = new EssFile(data.getLong(data.getColumnIndexOrThrow(MediaStore.MediaColumns._ID)),
                    data.getString(data.getColumnIndexOrThrow(MediaStore.MediaColumns.MIME_TYPE)));
            if(data.getLong(data.getColumnIndexOrThrow(MediaStore.MediaColumns._ID))==-1){
                //capture
                essFile.setItemType(EssFile.CAPTURE);
            }
            if(essFileSet.contains(essFile)){
                essFile.setChecked(true);
            }
            essFileList.add(essFile);
        }

        mCallbacks.onMediaLoad(essFileList);
    }

    @Override
    public void onLoaderReset(Loader<Cursor> loader) {
        Context context = mContext.get();
        if (context == null) {
            return;
        }

        mCallbacks.onmMediaReset();
    }

    public void onCreate(@NonNull FragmentActivity context, @NonNull EssMediaCallbacks callbacks) {
        mContext = new WeakReference<Context>(context);
        mLoaderManager = context.getSupportLoaderManager();
        mCallbacks = callbacks;
    }

    public void onDestroy() {
        mLoaderManager.destroyLoader(LOADER_ID);
        mCallbacks = null;
    }

    public void load(@Nullable Album target) {
        load(target, false, new LinkedHashSet<EssFile>());
    }

    public void load(@Nullable Album target, boolean enableCapture, Set<EssFile> essFileSet) {
        Bundle args = new Bundle();
        this.essFileSet = essFileSet;
        args.putParcelable(ARGS_ALBUM, target);
        args.putBoolean(ARGS_ENABLE_CAPTURE, enableCapture);
        if(mContext.get() == null){
            mLoaderManager.initLoader(LOADER_ID, args, this);
        }else {
            mLoaderManager.restartLoader(LOADER_ID,args,this);
        }
    }

    public void load(@Nullable Album target, boolean enableCapture, boolean onlyShouwIMage) {
        Bundle args = new Bundle();
        args.putParcelable(ARGS_ALBUM, target);
        args.putBoolean(ARGS_ENABLE_CAPTURE, enableCapture);
        args.putBoolean(ARGS_ONLY_SHOWIMAGE, onlyShouwIMage);
        if(mContext.get() == null){
            mLoaderManager.initLoader(LOADER_ID, args, this);
        }else {
            mLoaderManager.restartLoader(LOADER_ID,args,this);
        }
    }

    public interface EssMediaCallbacks {

        void onMediaLoad(List<EssFile> cursor);

        void onmMediaReset();
    }
}


================================================
FILE: filepicker/src/main/java/com/ess/filepicker/loader/EssMediaLoader.java
================================================
package com.ess.filepicker.loader;

import android.content.Context;
import android.database.Cursor;
import android.database.MatrixCursor;
import android.database.MergeCursor;
import android.net.Uri;
import android.provider.MediaStore;
import android.support.v4.content.CursorLoader;

import com.ess.filepicker.SelectOptions;
import com.ess.filepicker.model.Album;
import com.ess.filepicker.util.MediaStoreCompat;

/**
 * EssMediaLoader
 * Created by 李波 on 2018/3/2.
 */

public class EssMediaLoader extends CursorLoader {

    private static final Uri QUERY_URI = MediaStore.Files.getContentUri("external");
    private static final String[] PROJECTION = {
            MediaStore.Files.FileColumns._ID,
            MediaStore.MediaColumns.DISPLAY_NAME,
            MediaStore.MediaColumns.MIME_TYPE,
            MediaStore.MediaColumns.SIZE,
            "duration"};

    // === params for album ALL && showSingleMediaType: false ===
    private static final String SELECTION_ALL =
            "(" + MediaStore.Files.FileColumns.MEDIA_TYPE + "=?"
                    + " OR "
                    + MediaStore.Files.FileColumns.MEDIA_TYPE + "=?)"
                    + " AND " + MediaStore.MediaColumns.SIZE + ">0";
    private static final String[] SELECTION_ALL_ARGS = {
            String.valueOf(MediaStore.Files.FileColumns.MEDIA_TYPE_IMAGE),
            String.valueOf(MediaStore.Files.FileColumns.MEDIA_TYPE_VIDEO),
    };
    // ===========================================================

    // === params for album ALL && showSingleMediaType: true ===
    private static final String SELECTION_ALL_FOR_SINGLE_MEDIA_TYPE =
            MediaStore.Files.FileColumns.MEDIA_TYPE + "=?"
                    + " AND " + MediaStore.MediaColumns.SIZE + ">0";

    private static String[] getSelectionArgsForSingleMediaType(int mediaType) {
        return new String[]{String.valueOf(mediaType)};
    }
    // =========================================================

    // === params for ordinary album && showSingleMediaType: false ===
    private static final String SELECTION_ALBUM =
            "(" + MediaStore.Files.FileColumns.MEDIA_TYPE + "=?"
                    + " OR "
                    + MediaStore.Files.FileColumns.MEDIA_TYPE + "=?)"
                    + " AND "
                    + " bucket_id=?"
                    + " AND " + MediaStore.MediaColumns.SIZE + ">0";

    private static String[] getSelectionAlbumArgs(String albumId) {
        return new String[]{
                String.valueOf(MediaStore.Files.FileColumns.MEDIA_TYPE_IMAGE),
                String.valueOf(MediaStore.Files.FileColumns.MEDIA_TYPE_VIDEO),
                albumId
        };
    }
    // ===============================================================

    // === params for ordinary album && showSingleMediaType: true ===
    private static final String SELECTION_ALBUM_FOR_SINGLE_MEDIA_TYPE =
            MediaStore.Files.FileColumns.MEDIA_TYPE + "=?"
                    + " AND "
                    + " bucket_id=?"
                    + " AND " + MediaStore.MediaColumns.SIZE + ">0";

    private static String[] getSelectionAlbumArgsForSingleMediaType(int mediaType, String albumId) {
        return new String[]{String.valueOf(mediaType), albumId};
    }
    // ===============================================================

    private static final String ORDER_BY = MediaStore.Images.Media.DATE_TAKEN + " DESC";
    private final boolean mEnableCapture;

    private EssMediaLoader(Context context, String selection, String[] selectionArgs, boolean capture) {
        super(context, QUERY_URI, PROJECTION, selection, selectionArgs, ORDER_BY);
        mEnableCapture = capture;
    }

    public static CursorLoader newInstance(Context context, Album album) {
        String selection;
        String[] selectionArgs;
        boolean enableCapture;
        if (album.isAll()) {
            if (SelectOptions.getInstance().onlyShowImages) {
                selection = SELECTION_ALL_FOR_SINGLE_MEDIA_TYPE;
                selectionArgs = getSelectionArgsForSingleMediaType(MediaStore.Files.FileColumns.MEDIA_TYPE_IMAGE);
            } else if (SelectOptions.getInstance().onlyShowVideos) {
                selection = SELECTION_ALL_FOR_SINGLE_MEDIA_TYPE;
                selectionArgs = getSelectionArgsForSingleMediaType(MediaStore.Files.FileColumns.MEDIA_TYPE_VIDEO);
            } else {
                selection = SELECTION_ALL;
                selectionArgs = SELECTION_ALL_ARGS;
            }
            enableCapture = SelectOptions.getInstance().enabledCapture;
        } else {
            if (SelectOptions.getInstance().onlyShowImages) {
                selection = SELECTION_ALBUM_FOR_SINGLE_MEDIA_TYPE;
                selectionArgs = getSelectionAlbumArgsForSingleMediaType(MediaStore.Files.FileColumns.MEDIA_TYPE_IMAGE,
                        album.getId());
            } else if (SelectOptions.getInstance().onlyShowVideos) {
                selection = SELECTION_ALBUM_FOR_SINGLE_MEDIA_TYPE;
                selectionArgs = getSelectionAlbumArgsForSingleMediaType(MediaStore.Files.FileColumns.MEDIA_TYPE_VIDEO,
                        album.getId());
            } else {
                selection = SELECTION_ALBUM;
                selectionArgs = getSelectionAlbumArgs(album.getId());
            }
            enableCapture = false;
        }
        return new EssMediaLoader(context, selection, selectionArgs, enableCapture);
    }

    @Override
    public Cursor loadInBackground() {
        Cursor result = super.loadInBackground();
        if (!mEnableCapture || !MediaStoreCompat.hasCameraFeature(getContext())) {
            return result;
        }
        MatrixCursor dummy = new MatrixCursor(PROJECTION);
        dummy.addRow(new Object[]{"-1", "capture", "", 0, ""});
        return new MergeCursor(new Cursor[]{dummy, result});
    }

    @Override
    public void onContentChanged() {
    }
}


================================================
FILE: filepicker/src/main/java/com/ess/filepicker/loader/EssMimeTypeCollection.java
================================================
/*
 * Copyright (C) 2014 nohana, Inc.
 * Copyright 2017 Zhihu Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an &quot;AS IS&quot; BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.ess.filepicker.loader;

import android.content.Context;
import android.database.Cursor;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.Loader;

import com.ess.filepicker.model.EssFile;

import java.lang.ref.WeakReference;
import java.util.List;

/**
 * 按照文件类型查找
 */
public class EssMimeTypeCollection implements LoaderManager.LoaderCallbacks<Cursor> {
    public static final int LOADER_ID = 3;
    private WeakReference<Context> mContext;
    private static final String ARGS_EXTENSION = "args_extension";
    private static final String ARGS_SORT_TYPE = "args_sort_type";
    private LoaderManager mLoaderManager;
    private EssMimeTypeCallbacks mCallbacks;

    @Override
    public Loader<Cursor> onCreateLoader(int id, Bundle args) {
        Context context = mContext.get();
        if (context == null) {
            return null;
        }

        String extension = args.getString(ARGS_EXTENSION);
        int sortType = args.getInt(ARGS_SORT_TYPE);

        return EssMimeTypeLoader.newInstance(context, extension, sortType);
    }

    @Override
    public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
        Context context = mContext.get();
        if (context == null) {
            return;
        }
        mCallbacks.onFileLoad(((EssMimeTypeLoader)loader).getEssFileList());
    }

    @Override
    public void onLoaderReset(Loader<Cursor> loader) {
        Context context = mContext.get();
        if (context == null) {
            return;
        }
        if(mCallbacks!=null){
            mCallbacks.onFileReset();
        }
    }

    public void onCreate(@NonNull FragmentActivity context, @NonNull EssMimeTypeCallbacks callbacks) {
        mContext = new WeakReference<Context>(context);
        mLoaderManager = context.getSupportLoaderManager();
        mCallbacks = callbacks;
    }

    public void onDestroy() {
        mLoaderManager.destroyLoader(LOADER_ID);
        mCallbacks = null;
    }

    public void load(String extension, int sortType,int loaderId) {
        Bundle args = new Bundle();
        args.putString(ARGS_EXTENSION,extension);
        args.putInt(ARGS_SORT_TYPE,sortType);
        if(mContext.get() == null){
            mLoaderManager.initLoader(loaderId, args, this);
        }else {
            mLoaderManager.restartLoader(loaderId,args,this);
        }
    }

    public interface EssMimeTypeCallbacks {

        void onFileLoad(List<EssFile> essFileList);

        void onFileReset();
    }
}


================================================
FILE: filepicker/src/main/java/com/ess/filepicker/loader/EssMimeTypeLoader.java
================================================
package com.ess.filepicker.loader;

import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.provider.MediaStore;
import android.support.v4.content.CursorLoader;
import android.webkit.MimeTypeMap;

import com.ess.filepicker.model.EssFile;
import com.ess.filepicker.util.Const;
import com.ess.filepicker.util.FileUtils;

import java.util.ArrayList;
import java.util.List;

/**
 * 按照文件类型查找
 */

public class EssMimeTypeLoader extends CursorLoader {

    private static final Uri QUERY_URI = MediaStore.Files.getContentUri("external");

    private static final String[] PROJECTION = new String[]{
            MediaStore.Images.Media._ID,
            MediaStore.Images.Media.DATA,
            MediaStore.Files.FileColumns.MIME_TYPE,
            MediaStore.Files.FileColumns.SIZE,
            MediaStore.Images.Media.DATE_ADDED,
            MediaStore.Files.FileColumns.TITLE,
            MediaStore.Files.FileColumns.DATE_MODIFIED};

    private List<EssFile> essFileList;

    public EssMimeTypeLoader(Context context, String selection, String[] selectionArgs, String sortOrder) {
        //默认按照创建时间降序排列
        super(context, QUERY_URI, PROJECTION, selection, selectionArgs, sortOrder);
    }

    public static CursorLoader newInstance(Context context, String extension, int mSortType) {
        String mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension);
        String selection = MediaStore.Files.FileColumns.MIME_TYPE + "='" + mimeType + "'";
        String[] selectionArgs = null;
        if (extension == null) {
            extension = "";
        }
        if (extension.equalsIgnoreCase("doc") || extension.equalsIgnoreCase("docx")) {
            selection = MediaStore.Files.FileColumns.MIME_TYPE + " in(?,?) ";
            selectionArgs = new String[]{Const.mimeTypeMap.get("doc"), Const.mimeTypeMap.get("docx")};
        }
        if (extension.equalsIgnoreCase("xls") || extension.equalsIgnoreCase("xlsx")) {
            selection = MediaStore.Files.FileColumns.MIME_TYPE + " in(?,?) ";
            selectionArgs = new String[]{Const.mimeTypeMap.get("xls"), Const.mimeTypeMap.get("xlsx")};
        }
        if (extension.equalsIgnoreCase("ppt") || extension.equalsIgnoreCase("pptx")) {
            selection = MediaStore.Files.FileColumns.MIME_TYPE + " in(?,?) ";
            selectionArgs = new String[]{Const.mimeTypeMap.get("ppt"), Const.mimeTypeMap.get("pptx")};
        }
        if (extension.equalsIgnoreCase("png") || extension.equalsIgnoreCase("jpg") || extension.equalsIgnoreCase("jpeg")) {
            selection = MediaStore.Files.FileColumns.MIME_TYPE + " in(?,?,?) ";
            selectionArgs = new String[]{Const.mimeTypeMap.get("png"), Const.mimeTypeMap.get("jpg"), Const.mimeTypeMap.get("jpeg")};
            //不扫描有.nomedia文件的文件夹下的多媒体文件,带有.nomedia文件的文件夹下的多媒体文件的media_type都被置为了0
            selection = selection + " and " + MediaStore.Files.FileColumns.MEDIA_TYPE + " != " + MediaStore.Files.FileColumns.MEDIA_TYPE_NONE;
        }
        if (extension.equalsIgnoreCase("apk")) {
            selection = MediaStore.Files.FileColumns.DATA + " LIKE '%.apk' ";
        }

        selection = selection + " and " + MediaStore.Files.FileColumns.SIZE + " >0 " ;


        String sortOrder = MediaStore.Files.FileColumns.DATE_ADDED + " DESC ";
        if (mSortType == FileUtils.BY_NAME_ASC) {
            sortOrder = MediaStore.Files.FileColumns.DATA + " ASC ";
        } else if (mSortType == FileUtils.BY_NAME_DESC) {
            sortOrder = MediaStore.Files.FileColumns.DATA + " DESC ";
        } else if (mSortType == FileUtils.BY_TIME_ASC) {
            sortOrder = MediaStore.Files.FileColumns.DATE_ADDED + " ASC ";
        } else if (mSortType == FileUtils.BY_TIME_DESC) {
            sortOrder = MediaStore.Files.FileColumns.DATE_ADDED + " DESC ";
        } else if (mSortType == FileUtils.BY_SIZE_ASC) {
            sortOrder = MediaStore.Files.FileColumns.SIZE + " ASC ";
        } else if (mSortType == FileUtils.BY_SIZE_DESC) {
            sortOrder = MediaStore.Files.FileColumns.SIZE + " DESC ";
        }
        return new EssMimeTypeLoader(context, selection, selectionArgs, sortOrder);
    }

    public List<EssFile> getEssFileList() {
        return essFileList;
    }

    @Override
    public Cursor loadInBackground() {
        Cursor data = super.loadInBackground();
        essFileList = new ArrayList<>();
        if (data != null) {
            while (data.moveToNext()){
                EssFile essFile = new EssFile(data.getString(data.getColumnIndexOrThrow(MediaStore.Images.Media.DATA)));
                if(essFile.isExits()){
                    essFileList.add(essFile);
                }
            }
            data.moveToFirst();
        }

        return data;
    }


}


================================================
FILE: filepicker/src/main/java/com/ess/filepicker/model/Album.java
================================================
/*
 * Copyright (C) 2014 nohana, Inc.
 * Copyright 2017 Zhihu Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an &quot;AS IS&quot; BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.ess.filepicker.model;

import android.content.Context;
import android.database.Cursor;
import android.os.Parcel;
import android.os.Parcelable;
import android.provider.MediaStore;
import android.support.annotation.Nullable;

import com.ess.filepicker.loader.EssAlbumLoader;

public class Album implements Parcelable {
    public static final Creator<Album> CREATOR = new Creator<Album>() {
        @Nullable
        @Override
        public Album createFromParcel(Parcel source) {
            return new Album(source);
        }

        @Override
        public Album[] newArray(int size) {
            return new Album[size];
        }
    };
    public static final String ALBUM_ID_ALL = String.valueOf(-1);
    public static final String ALBUM_NAME_ALL = "All";

    private final String mId;
    private final String mCoverPath;
    private final String mDisplayName;
    private long mCount;

    Album(String id, String coverPath, String albumName, long count) {
        mId = id;
        mCoverPath = coverPath;
        mDisplayName = albumName;
        mCount = count;
    }

    Album(Parcel source) {
        mId = source.readString();
        mCoverPath = source.readString();
        mDisplayName = source.readString();
        mCount = source.readLong();
    }

    /**
     * Constructs a new {@link Album} entity from the {@link Cursor}.
     * This method is not responsible for managing cursor resource, such as close, iterate, and so on.
     */
    public static Album valueOf(Cursor cursor) {
        return new Album(
                cursor.getString(cursor.getColumnIndex("bucket_id")),
                cursor.getString(cursor.getColumnIndex(MediaStore.MediaColumns.DATA)),
                cursor.getString(cursor.getColumnIndex("bucket_display_name")),
                cursor.getLong(cursor.getColumnIndex(EssAlbumLoader.COLUMN_COUNT)));
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(mId);
        dest.writeString(mCoverPath);
        dest.writeString(mDisplayName);
        dest.writeLong(mCount);
    }

    public String getId() {
        return mId;
    }

    public String getCoverPath() {
        return mCoverPath;
    }

    public long getCount() {
        return mCount;
    }

    public void addCaptureCount() {
        mCount++;
    }

    public String getDisplayName(Context context) {
        if (isAll()) {
            return "全部";
        }
        return mDisplayName;
    }

    public boolean isAll() {
        return ALBUM_ID_ALL.equals(mId);
    }

    public boolean isEmpty() {
        return mCount == 0;
    }

}

================================================
FILE: filepicker/src/main/java/com/ess/filepicker/model/BreadModel.java
================================================
package com.ess.filepicker.model;


import java.util.ArrayList;
import java.util.List;

/**
 * BreadModel
 * Created by 李波 on 2018/2/5.
 */

public class BreadModel {

    /*当前Path*/
    private String mCurPath;

    /*之前的浏览位置,默认0*/
    private int mPrePosition = 0;

    /*当前面包屑的名称*/
    private String mCurName;

    public String getCurName() {
        return mCurName;
    }

    public void setCurName(String mCurName) {
        this.mCurName = mCurName;
    }

    public int getPrePosition() {
        return mPrePosition;
    }

    public void setPrePosition(int mPrePosition) {
        this.mPrePosition = mPrePosition;
    }

    public String getCurPath() {
        return mCurPath;
    }

    public void setmCurPath(String mCurPath) {
        this.mCurPath = mCurPath;
    }

    /**
     * 获取需要添加的路径列表
     * @param oldList
     * @param newList
     * @return
     */
    public static List<BreadModel> getNewBreadModel(List<BreadModel> oldList, List<BreadModel> newList) {
        List<BreadModel> newModelList = new ArrayList<>();
        if (oldList == null || newList == null) {
            return newModelList;
        }
        if (oldList.size() >= newList.size()) {
            return newModelList;
        }
        for (int i = 0; i < newList.size(); i++) {
            if (i < oldList.size()) {
                continue;
            }
            newModelList.add(newList.get(i));
        }
        return newModelList;
    }

    /**
     * 获取路径List需要裁剪的位置
     * @param oldList
     * @param newList
     * @return
     */
    public static int getRemovedBreadModel(List<BreadModel> oldList, List<BreadModel> newList) {
        int removeFirstPosition = 0;
        if (oldList == null || newList == null) {
            return removeFirstPosition;
        }
        if (oldList.size() <= newList.size()) {
            return removeFirstPosition;
        }
        for (int i = 0; i < oldList.size(); i++) {
            if (i == newList.size()) {
                return i;
            }
        }
        return removeFirstPosition;
    }


}


================================================
FILE: filepicker/src/main/java/com/ess/filepicker/model/CaptureStrategy.java
================================================
/*
 * Copyright 2017 Zhihu Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.ess.filepicker.model;

public class CaptureStrategy {

    public final boolean isPublic;
    public final String authority;

    public CaptureStrategy(boolean isPublic, String authority) {
        this.isPublic = isPublic;
        this.authority = authority;
    }
}


================================================
FILE: filepicker/src/main/java/com/ess/filepicker/model/EssFile.java
================================================
package com.ess.filepicker.model;

import android.content.ContentUris;
import android.content.Context;
import android.net.Uri;
import android.os.Parcel;
import android.os.Parcelable;
import android.provider.MediaStore;

import com.ess.filepicker.util.FileUtils;
import com.ess.filepicker.util.MimeType;
import com.ess.filepicker.util.PathUtils;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

/**
 * EssFile
 * Created by 李波 on 2018/2/5.
 */

public class EssFile implements Parcelable {

    public static final int CAPTURE = 0;
    public static final int MEDIA = 1;

    private String mFilePath;
    private String mimeType;
    private String childFolderCount = "加载中";
    private String childFileCount = "加载中";
    private boolean isChecked = false;
    private boolean isExits = false;
    private boolean isDirectory = false;
    private boolean isFile = false;
    private String mFileName;
    private Uri uri;

    private int itemType = MEDIA;

    protected EssFile(Parcel in) {
        mFilePath = in.readString();
        mimeType = in.readString();
        childFolderCount = in.readString();
        childFileCount = in.readString();
        isChecked = in.readByte() != 0;
        isExits = in.readByte() != 0;
        isDirectory = in.readByte() != 0;
        isFile = in.readByte() != 0;
        mFileName = in.readString();
        uri = in.readParcelable(Uri.class.getClassLoader());
        itemType = in.readInt();
    }

    public static final Creator<EssFile> CREATOR = new Creator<EssFile>() {
        @Override
        public EssFile createFromParcel(Parcel in) {
            return new EssFile(in);
        }

        @Override
        public EssFile[] newArray(int size) {
            return new EssFile[size];
        }
    };

    public boolean isChecked() {
        return isChecked;
    }

    public void setChecked(boolean checked) {
        isChecked = checked;
    }

    public EssFile(String path) {
        mFilePath = path;
        File file = new File(mFilePath);
        if (file.exists()) {
            isExits = true;
            isDirectory = file.isDirectory();
            isFile = file.isFile();
            mFileName = file.getName();
        }
        mimeType = FileUtils.getMimeType(mFilePath);
    }

    public EssFile(File file) {
        mFilePath = file.getAbsolutePath();
        if (file.exists()) {
            isExits = true;
            isDirectory = file.isDirectory();
            isFile = file.isFile();
        }
        mimeType = FileUtils.getMimeType(file.getAbsolutePath());
    }

    public EssFile(long id, String mimeType) {
        this.mimeType = mimeType;
        Uri contentUri;
        if (isImage()) {
            contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
        } else if (isVideo()) {
            contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
        } else {
            // ?
            contentUri = MediaStore.Files.getContentUri("external");
        }
        this.uri = ContentUris.withAppendedId(contentUri, id);
    }

    public Uri getUri() {
        return uri;
    }

    public boolean isExits() {
        return isExits;
    }

    public String getMimeType() {
        return mimeType;
    }

    public void setMimeType(String mimeType) {
        this.mimeType = mimeType;
    }

    public String getChildFolderCount() {
        return childFolderCount;
    }

    public void setChildFolderCount(String childFolderCount) {
        this.childFolderCount = childFolderCount;
    }

    public String getChildFileCount() {
        return childFileCount;
    }

    public void setChildFileCount(String childFileCount) {
        this.childFileCount = childFileCount;
    }

    public void setChildCounts(String childFileCount, String childFolderCount) {
        this.childFileCount = childFileCount;
        this.childFolderCount = childFolderCount;
    }


    public File getFile() {
        return new File(mFilePath);
    }

    public String getName() {
        return new File(mFilePath).getName();
    }

    public boolean isDirectory() {
        return isDirectory;
    }

    public boolean isFile() {
        return isFile;
    }

    public String getAbsolutePath() {
        return mFilePath;
    }

    public static List<EssFile> getEssFileList(List<File> files) {
        List<EssFile> essFileList = new ArrayList<>();
        for (File file :
                files) {
            essFileList.add(new EssFile(file));
        }
        return essFileList;
    }

    public static ArrayList<EssFile> getEssFileList(Context context, Set<EssFile> essFileSet) {
        ArrayList<EssFile> essFileArrayList = new ArrayList<>();
        for (EssFile ess_file :
                essFileSet) {
            ess_file.mFilePath = PathUtils.getPath(context, ess_file.uri);
            essFileArrayList.add(ess_file);
        }
        return essFileArrayList;
    }

    public static ArrayList<String> getFilePathList(ArrayList<EssFile> essFileArrayList){
        ArrayList<String> resultList = new ArrayList<>();
        for (EssFile essFile:essFileArrayList) {
            resultList.add(essFile.getAbsolutePath());
        }
        return resultList;
    }


    @Override
    public String toString() {
        return "EssFile{" +
                "mFilePath='" + mFilePath + '\'' +
                ", mimeType='" + mimeType + '\'' +
                ", mFileName='" + mFileName + '\'' +
                '}';
    }

    public boolean isImage() {
        if (mimeType == null) return false;
        return mimeType.equals(MimeType.JPEG.toString())
                || mimeType.equals(MimeType.PNG.toString())
                || mimeType.equals(MimeType.GIF.toString())
                || mimeType.equals(MimeType.BMP.toString())
                || mimeType.equals(MimeType.WEBP.toString());
    }

    public boolean isGif() {
        if (mimeType == null) return false;
        return mimeType.equals(MimeType.GIF.toString());
    }

    public boolean isVideo() {
        if (mimeType == null) return false;
        return mimeType.equals(MimeType.MPEG.toString())
                || mimeType.equals(MimeType.MP4.toString())
                || mimeType.equals(MimeType.QUICKTIME.toString())
                || mimeType.equals(MimeType.THREEGPP.toString())
                || mimeType.equals(MimeType.THREEGPP2.toString())
                || mimeType.equals(MimeType.MKV.toString())
                || mimeType.equals(MimeType.WEBM.toString())
                || mimeType.equals(MimeType.TS.toString())
                || mimeType.equals(MimeType.AVI.toString());
    }

    public void setItemType(int itemType) {
        this.itemType = itemType;
    }

    public int getItemType() {
        return itemType;
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(mFilePath);
        dest.writeString(mimeType);
        dest.writeString(childFolderCount);
        dest.writeString(childFileCount);
        dest.writeByte((byte) (isChecked ? 1 : 0));
        dest.writeByte((byte) (isExits ? 1 : 0));
        dest.writeByte((byte) (isDirectory ? 1 : 0));
        dest.writeByte((byte) (isFile ? 1 : 0));
        dest.writeString(mFileName);
        dest.writeParcelable(uri, flags);
        dest.writeInt(itemType);
    }

    @Override
    public boolean equals(Object obj) {
        if (!(obj instanceof EssFile)) {
            return false;
        }

        EssFile other = (EssFile) obj;
        if (uri == null) {
            return mFilePath.equalsIgnoreCase(other.getAbsolutePath());
        } else {
            return uri.equals(other.getUri());
        }
    }

    @Override
    public int hashCode() {
        int result = mFilePath != null ? mFilePath.hashCode() : 0;
        result = 31 * result + (uri != null ? uri.hashCode() : 0);
        result = 31 * result + itemType;
        return result;
    }
}


================================================
FILE: filepicker/src/main/java/com/ess/filepicker/model/EssFileCountCallBack.java
================================================
package com.ess.filepicker.model;

/**
 * EssFileCountCallBack
 * Created by 李波 on 2018/3/5.
 */

public interface EssFileCountCallBack {
    void onFindChildFileAndFolderCount(int position, String childFileCount, String childFolderCount);
}


================================================
FILE: filepicker/src/main/java/com/ess/filepicker/model/EssFileFilter.java
================================================
package com.ess.filepicker.model;

import java.io.File;
import java.io.FileFilter;

/**
 * EssFileFilter
 * 不显示隐藏文件、文件夹
 */
public class EssFileFilter implements FileFilter {
    private String[] mTypes;

    public EssFileFilter(String[] types) {
        this.mTypes = types;
    }

    @Override
    public boolean accept(File file) {
        if (file.isDirectory() && !file.isHidden()) {
            return true;
        }
        if (mTypes != null && mTypes.length > 0) {
            for (String mType : mTypes) {
                if ((file.getName().endsWith(mType.toLowerCase()) || file.getName().endsWith(mType.toUpperCase())) && !file.isHidden()) {
//                if (FileUtils.getMimeType(file.getAbsolutePath()).equalsIgnoreCase(MimeTypeMap.getSingleton().getMimeTypeFromExtension(mType))) {
                    return true;
                }
            }
        }else {
            return true;
        }
        return false;
    }
}


================================================
FILE: filepicker/src/main/java/com/ess/filepicker/model/EssFileListCallBack.java
================================================
package com.ess.filepicker.model;

import java.util.List;

/**
 * EssFileListCallBack
 * Created by 李波 on 2018/3/5.
 */

public interface EssFileListCallBack {
    void onFindFileList(String queryPath, List<EssFile> essFileList);
}


================================================
FILE: filepicker/src/main/java/com/ess/filepicker/model/EssFileProvider.java
================================================
package com.ess.filepicker.model;

import android.support.v4.content.FileProvider;

/**
 * EssFileProvider
 * Created by 李波 on 2018/2/23.
 */

public class EssFileProvider extends FileProvider {
}


================================================
FILE: filepicker/src/main/java/com/ess/filepicker/model/FileScanActEvent.java
================================================
package com.ess.filepicker.model;

/**
 * FileScanActEvent
 * Created by 李波 on 2018/2/23.
 */

public class FileScanActEvent {
    private int canSelectMaxCount;

    public FileScanActEvent(int canSelectMaxCount) {
        this.canSelectMaxCount = canSelectMaxCount;
    }

    public int getCanSelectMaxCount() {
        return canSelectMaxCount;
    }

    public void setCanSelectMaxCount(int canSelectMaxCount) {
        this.canSelectMaxCount = canSelectMaxCount;
    }
}


================================================
FILE: filepicker/src/main/java/com/ess/filepicker/model/FileScanFragEvent.java
================================================
package com.ess.filepicker.model;


/**
 * FileScanFragEvent
 * Created by 李波 on 2018/2/23.
 */

public class FileScanFragEvent {

    private EssFile selectedFile;
    private boolean isAdd;

    public FileScanFragEvent(EssFile selectedFile, boolean isAdd) {
        this.selectedFile = selectedFile;
        this.isAdd = isAdd;
    }

    public EssFile getSelectedFile() {
        return selectedFile;
    }

    public void setSelectedFile(EssFile selectedFile) {
        this.selectedFile = selectedFile;
    }

    public boolean isAdd() {
        return isAdd;
    }

    public void setAdd(boolean add) {
        isAdd = add;
    }

    public EssFile getSelectedFileList() {
        return selectedFile;
    }

    public void setSelectedFileList(EssFile selectedFileList) {
        this.selectedFile = selectedFileList;
    }
}


================================================
FILE: filepicker/src/main/java/com/ess/filepicker/model/FileScanSortChangedEvent.java
================================================
package com.ess.filepicker.model;

/**
 * FileScanSortChangedEvent
 * Created by 李波 on 2018/2/26.
 */

public class FileScanSortChangedEvent {
    private int sortType;
    private int currentItem;

    public FileScanSortChangedEvent(int sortType, int currentItem) {
        this.sortType = sortType;
        this.currentItem = currentItem;
    }

    public int getCurrentItem() {
        return currentItem;
    }

    public void setCurrentItem(int currentItem) {
        this.currentItem = currentItem;
    }

    public FileScanSortChangedEvent(int sortType) {
        this.sortType = sortType;
    }

    public int getSortType() {
        return sortType;
    }

    public void setSortType(int sortType) {
        this.sortType = sortType;
    }
}


================================================
FILE: filepicker/src/main/java/com/ess/filepicker/task/EssFileCountTask.java
================================================
package com.ess.filepicker.task;

import android.os.AsyncTask;

import com.ess.filepicker.model.EssFile;
import com.ess.filepicker.model.EssFileCountCallBack;
import com.ess.filepicker.model.EssFileFilter;

import java.io.File;
import java.util.Arrays;
import java.util.List;

/**
 * EssFileCountTask
 * Created by 李波 on 2018/3/5.
 */

public class EssFileCountTask extends AsyncTask<Void,Void,Void>{

    private int position;
    private String queryPath;
    private String[] types;
    private EssFileCountCallBack countCallBack;
    private int childFileCount = 0;
    private int childFolderCount = 0;

    public EssFileCountTask(int position, String queryPath, String[] types, EssFileCountCallBack countCallBack) {
        this.position = position;
        this.queryPath = queryPath;
        this.types = types;
        this.countCallBack = countCallBack;
    }

    @Override
    protected Void doInBackground(Void... voids) {
        File file = new File(queryPath);
        File[] files = file.listFiles(new EssFileFilter(types));
        if(files == null){
            return null;
        }
        List<EssFile> fileList = EssFile.getEssFileList(Arrays.asList(files));
        for (EssFile essFile :
                fileList) {
            if(essFile.isDirectory()){
                childFolderCount++;
            }else {
                childFileCount++;
            }
        }
        return null;
    }

    @Override
    protected void onPostExecute(Void aVoid) {
        if(countCallBack!=null){
            countCallBack.onFindChildFileAndFolderCount(position,String.valueOf(childFileCount),String.valueOf(childFolderCount));
        }
    }
}


================================================
FILE: filepicker/src/main/java/com/ess/filepicker/task/EssFileListTask.java
================================================
package com.ess.filepicker.task;

import android.os.AsyncTask;

import com.ess.filepicker.model.EssFile;
import com.ess.filepicker.model.EssFileFilter;
import com.ess.filepicker.model.EssFileListCallBack;
import com.ess.filepicker.util.FileUtils;

import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

/**
 * EssFileListTask
 * Created by 李波 on 2018/3/5.
 */

public class EssFileListTask extends AsyncTask<Void,Void,List<EssFile>> {

    private List<EssFile> mSelectedFileList;
    private String queryPath;
    private String[] types;
    private int mSortType;
    private EssFileListCallBack callBack;

    public EssFileListTask(List<EssFile> mSelectedFileList, String queryPath, String[] types, int mSortType, EssFileListCallBack fileCallBack) {
        this.mSelectedFileList = mSelectedFileList;
        this.queryPath = queryPath;
        this.types = types;
        this.mSortType = mSortType;
        this.callBack = fileCallBack;
    }

    @Override
    protected List<EssFile> doInBackground(Void... voids) {
        File file = new File(queryPath);
        File[] files = file.listFiles(new EssFileFilter(types));
        if(files == null){
            return new ArrayList<>();
        }
        List<File> fileList = Arrays.asList(files);
        if(mSortType == FileUtils.BY_NAME_ASC){
            Collections.sort(fileList, new FileUtils.SortByName());
        }else if(mSortType == FileUtils.BY_NAME_DESC){
            Collections.sort(fileList, new FileUtils.SortByName());
            Collections.reverse(fileList);
        }else if(mSortType == FileUtils.BY_TIME_ASC){
            Collections.sort(fileList,new FileUtils.SortByTime());
        }else if(mSortType == FileUtils.BY_TIME_DESC){
            Collections.sort(fileList,new FileUtils.SortByTime());
            Collections.reverse(fileList);
        }else if(mSortType == FileUtils.BY_SIZE_ASC){
            Collections.sort(fileList,new FileUtils.SortBySize());
        }else if(mSortType == FileUtils.BY_SIZE_DESC){
            Collections.sort(fileList,new FileUtils.SortBySize());
            Collections.reverse(fileList);
        }else if(mSortType == FileUtils.BY_EXTENSION_ASC){
            Collections.sort(fileList,new FileUtils.SortByExtension());
        }else if(mSortType == FileUtils.BY_EXTENSION_DESC){
            Collections.sort(fileList,new FileUtils.SortByExtension());
            Collections.reverse(fileList);
        }
        List<EssFile> tempFileList = EssFile.getEssFileList(fileList);
        for (EssFile selectedFile :
                mSelectedFileList) {
            for (int i = 0; i < tempFileList.size(); i++) {
                if (selectedFile.getAbsolutePath().equals(tempFileList.get(i).getAbsolutePath())) {
                    tempFileList.get(i).setChecked(true);
                    break;
                }
            }
        }
        return tempFileList;
    }

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
    }

    @Override
    protected void onPostExecute(List<EssFile> essFileList) {
        if(callBack!=null){
            callBack.onFindFileList(queryPath,essFileList);
        }
    }
}


================================================
FILE: filepicker/src/main/java/com/ess/filepicker/util/Const.java
================================================
package com.ess.filepicker.util;

import java.util.HashMap;
import java.util.Map;

/**
 * Const
 * Created by 李波 on 2018/2/22.
 */

public class Const {

    public static Map<String,String> mimeTypeMap = null;

    static {
        mimeTypeMap = new HashMap<>();
        mimeTypeMap.put("apk","application/vnd.android.package-archive");
        mimeTypeMap.put("asf", "video/x-ms-asf");
        mimeTypeMap.put("avi", "video/x-msvideo");
        mimeTypeMap.put("bin", "application/octet-stream");
        mimeTypeMap.put("bmp", "image/bmp");
        mimeTypeMap.put("c", "text/plain");
        mimeTypeMap.put("class", "application/octet-stream");
        mimeTypeMap.put("conf", "text/plain");
        mimeTypeMap.put("cpp", "text/plain");
        mimeTypeMap.put("doc", "application/msword");
        mimeTypeMap.put("docx", "application/vnd.openxmlformats-officedocument.wordprocessingml.document");
        mimeTypeMap.put("xls", "application/vnd.ms-excel");
        mimeTypeMap.put("xlsx", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        mimeTypeMap.put("exe", "application/octet-stream");
        mimeTypeMap.put("gif", "image/gif");
        mimeTypeMap.put("gtar", "application/x-gtar");
        mimeTypeMap.put("gz", "application/x-gzip");
        mimeTypeMap.put("h", "text/plain");
        mimeTypeMap.put("htm", "text/html");
        mimeTypeMap.put("html", "text/html");
        mimeTypeMap.put("jar", "application/java-archive");
        mimeTypeMap.put("java", "text/plain");
        mimeTypeMap.put("jpeg", "image/jpeg");
        mimeTypeMap.put("jpg", "image/jpeg");
        mimeTypeMap.put("js", "application/x-javascript");
        mimeTypeMap.put("log", "text/plain");
        mimeTypeMap.put("m3u", "audio/x-mpegurl");
        mimeTypeMap.put("m4a", "audio/mp4a-latm");
        mimeTypeMap.put("m4b", "audio/mp4a-latm");
        mimeTypeMap.put("m4p", "audio/mp4a-latm");
        mimeTypeMap.put("m4u", "video/vnd.mpegurl");
        mimeTypeMap.put("m4v", "video/x-m4v");
        mimeTypeMap.put("mov", "video/quicktime");
        mimeTypeMap.put("mp2", "audio/x-mpeg");
        mimeTypeMap.put("mp3", "audio/mpeg");
        mimeTypeMap.put("mp4", "video/mp4");
        mimeTypeMap.put("mpc", "application/vnd.mpohun.certificate");
        mimeTypeMap.put("mpe", "video/mpeg");
        mimeTypeMap.put("mpeg", "video/mpeg");
        mimeTypeMap.put("mpg", "video/mpeg");
        mimeTypeMap.put("mpg4", "video/mp4");
        mimeTypeMap.put("mpga", "audio/mpeg");
        mimeTypeMap.put("msg", "application/vnd.ms-outlook");
        mimeTypeMap.put("ogg", "audio/ogg");
        mimeTypeMap.put("pdf", "application/pdf");
        mimeTypeMap.put("png", "image/png");
        mimeTypeMap.put("pps", "application/vnd.ms-powerpoint");
        mimeTypeMap.put("ppt", "application/vnd.ms-powerpoint");
        mimeTypeMap.put("pptx", "application/vnd.openxmlformats-officedocument.presentationml.presentation");
        mimeTypeMap.put("prop", "text/plain");
        mimeTypeMap.put("rc", "text/plain");
        mimeTypeMap.put("rmvb", "audio/x-pn-realaudio");
        mimeTypeMap.put("rtf", "application/rtf");
        mimeTypeMap.put("sh", "text/plain");
        mimeTypeMap.put("tar", "application/x-tar");
        mimeTypeMap.put("tgz", "application/x-compressed");
        mimeTypeMap.put("txt", "text/plain");
        mimeTypeMap.put("wav", "audio/x-wav");
        mimeTypeMap.put("wma", "audio/x-ms-wma");
        mimeTypeMap.put("wmv", "audio/x-ms-wmv");
        mimeTypeMap.put("wps", "application/vnd.ms-works");
        mimeTypeMap.put("xml", "text/plain");
        mimeTypeMap.put("z", "application/x-compress");
        mimeTypeMap.put("zip", "application/x-zip-compressed");
        mimeTypeMap.put("", "*/*");
    }

    /*文件类型*/
    public static final String EXTRA_KEY_FILE_TYPE = "EXTRA_KEY_FILE_TYPE";
    /*排序类型*/
    public static final String EXTRA_KEY_SORT_TYPE = "EXTRA_KEY_SORT_TYPE";
    /*是否多选*/
    public static final String EXTRA_KEY_IS_SINGLE = "EXTRA_KEY_IS_SINGLE";
    /*最大可选择数量*/
    public static final String EXTRA_KEY_MAX_COUNT = "EXTRA_KEY_MAX_COUNT";
    public static final String EXTRA_KEY_OnSelectFileListener = "EXTRA_KEY_OnSelectFileListener";

    public static final String EXTRA_RESULT_SELECTION = "extra_result_selection";



}


================================================
FILE: filepicker/src/main/java/com/ess/filepicker/util/ConvertUtils.java
================================================
package com.ess.filepicker.util;

import android.annotation.TargetApi;
import android.content.ContentUris;
import android.content.Context;
import android.content.res.ColorStateList;
import android.content.res.Resources;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.NinePatchDrawable;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.provider.DocumentsContract;
import android.provider.MediaStore;
import android.support.annotation.ColorInt;
import android.support.annotation.FloatRange;
import android.text.TextUtils;
import android.view.View;
import android.widget.ListView;
import android.widget.ScrollView;

import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.text.DecimalFormat;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;

/**
 * 数据类型转换、单位转换
 *
 * @author 李玉江[QQ:1023694760]
 * @since 2014-4-18
 */
public class ConvertUtils {
    public static final long GB = 1073741824;
    public static final long MB = 1048576;
    public static final long KB = 1024;

    public static int toInt(Object obj) {
        try {
            return Integer.parseInt(obj.toString());
        } catch (NumberFormatException e) {
            return -1;
        }
    }

    public static int toInt(byte[] bytes) {
        int result = 0;
        byte abyte;
        for (int i = 0; i < bytes.length; i++) {
            abyte = bytes[i];
            result += (abyte & 0xFF) << (8 * i);
        }
        return result;
    }

    public static int toShort(byte first, byte second) {
        return (first << 8) + (second & 0xFF);
    }

    public static long toLong(Object obj) {
        try {
            return Long.parseLong(obj.toString());
        } catch (NumberFormatException e) {
            return -1L;
        }
    }

    public static float toFloat(Object obj) {
        try {
            return Float.parseFloat(obj.toString());
        } catch (NumberFormatException e) {
            return -1f;
        }
    }

    /**
     * int占4字节
     *
     * @param i the
     * @return byte [ ]
     */
    public static byte[] toByteArray(int i) {
        // byte[] bytes = new byte[4];
        // bytes[0] = (byte) (0xff & i);
        // bytes[1] = (byte) ((0xff00 & i) >> 8);
        // bytes[2] = (byte) ((0xff0000 & i) >> 16);
        // bytes[3] = (byte) ((0xff000000 & i) >> 24);
        // return bytes;
        return ByteBuffer.allocate(4).putInt(i).array();
    }

    public static byte[] toByteArray(String hexData, boolean isHex) {
        if (hexData == null || hexData.equals("")) {
            return null;
        }
        if (!isHex) {
            return hexData.getBytes();
        }
        hexData = hexData.replaceAll("\\s+", "");
        String hexDigits = "0123456789ABCDEF";
        ByteArrayOutputStream baos = new ByteArrayOutputStream(
                hexData.length() / 2);
        // 将每2位16进制整数组装成一个字节
        for (int i = 0; i < hexData.length(); i += 2) {
            baos.write((hexDigits.indexOf(hexData.charAt(i)) << 4 | hexDigits
                    .indexOf(hexData.charAt(i + 1))));
        }
        byte[] bytes = baos.toByteArray();
        try {
            baos.close();
        } catch (IOException e) {
            LogUtils.warn(e);
        }
        return bytes;
    }

    public static String toHexString(String str) {
        if (TextUtils.isEmpty(str))
            return "";
        StringBuilder builder = new StringBuilder();
        byte[] bytes = str.getBytes();
        for (byte aByte : bytes) {
            builder.append(Integer.toHexString(0xFF & aByte));
            builder.append(" ");
        }
        return builder.toString();
    }

    /**
     * To hex string string.
     *
     * @param bytes the bytes
     * @return the string
     */
    public static String toHexString(byte... bytes) {
        char[] DIGITS = {'0', '1', '2', '3', '4', '5', '6',
                '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
        // 参见:http://www.oschina.net/code/snippet_116768_9019
        char[] buffer = new char[bytes.length * 2];
        for (int i = 0, j = 0; i < bytes.length; ++i) {
            int u = bytes[i] < 0 ? bytes[i] + 256 : bytes[i];//转无符号整型
            buffer[j++] = DIGITS[u >>> 4];
            buffer[j++] = DIGITS[u & 0xf];
        }
        return new String(buffer);
    }

    /**
     * To hex string string.
     *
     * @param num the num
     * @return the string
     */
    public static String toHexString(int num) {
        String hexString = Integer.toHexString(num);
        LogUtils.verbose(String.format(Locale.CHINA, "%d to hex string is %s", num, hexString));
        return hexString;
    }

    /**
     * To binary string string.
     *
     * @param bytes the bytes
     * @return the string
     */
    public static String toBinaryString(byte... bytes) {
        char[] DIGITS = {'0', '1', '2', '3', '4', '5', '6',
                '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
        // 参见:http://www.oschina.net/code/snippet_116768_9019
        char[] buffer = new char[bytes.length * 8];
        for (int i = 0, j = 0; i < bytes.length; ++i) {
            int u = bytes[i] < 0 ? bytes[i] + 256 : bytes[i];//转无符号整型
            buffer[j++] = DIGITS[(u >>> 7) & 0x1];
            buffer[j++] = DIGITS[(u >>> 6) & 0x1];
            buffer[j++] = DIGITS[(u >>> 5) & 0x1];
            buffer[j++] = DIGITS[(u >>> 4) & 0x1];
            buffer[j++] = DIGITS[(u >>> 3) & 0x1];
            buffer[j++] = DIGITS[(u >>> 2) & 0x1];
            buffer[j++] = DIGITS[(u >>> 1) & 0x1];
            buffer[j++] = DIGITS[u & 0x1];
        }
        return new String(buffer);
    }

    /**
     * To binary string string.
     *
     * @param num the num
     * @return the string
     */
    public static String toBinaryString(int num) {
        String binaryString = Integer.toBinaryString(num);
        LogUtils.verbose(String.format(Locale.CHINA, "%d to binary string is %s", num, binaryString));
        return binaryString;
    }

    public static String toSlashString(String str) {
        String result = "";
        char[] chars = str.toCharArray();
        for (char chr : chars) {
            if (chr == '"' || chr == '\'' || chr == '\\') {
                result += "\\";//符合“"”“'”“\”这三个符号的前面加一个“\”
            }
            result += chr;
        }
        return result;
    }

    public static <T> T[] toArray(List<T> list) {
        //noinspection unchecked
        return (T[]) list.toArray();
    }

    public static <T> List<T> toList(T[] array) {
        return Arrays.asList(array);
    }

    public static String toString(Object[] objects) {
        return Arrays.deepToString(objects);
    }

    public static String toString(Object[] objects, String tag) {
        StringBuilder sb = new StringBuilder();
        for (Object object : objects) {
            sb.append(object);
            sb.append(tag);
        }
        return sb.toString();
    }

    public static byte[] toByteArray(InputStream is) {
        if (is == null) {
            return null;
        }
        try {
            ByteArrayOutputStream os = new ByteArrayOutputStream();
            byte[] buff = new byte[100];
            while (true) {
                int len = is.read(buff, 0, 100);
                if (len == -1) {
                    break;
                } else {
                    os.write(buff, 0, len);
                }
            }
            byte[] bytes = os.toByteArray();
            os.close();
            is.close();
            return bytes;
        } catch (IOException e) {
            LogUtils.warn(e);
        }
        return null;
    }

    public static byte[] toByteArray(Bitmap bitmap) {
        if (bitmap == null) {
            return null;
        }
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        // 将Bitmap压缩成PNG编码,质量为100%存储,除了PNG还有很多常见格式,如jpeg等。
        bitmap.compress(Bitmap.CompressFormat.PNG, 100, os);
        byte[] bytes = os.toByteArray();
        try {
            os.close();
        } catch (IOException e) {
            LogUtils.warn(e);
        }
        return bytes;
    }

    public static Bitmap toBitmap(byte[] bytes, int width, int height) {
        Bitmap bitmap = null;
        if (bytes.length != 0) {
            try {
                BitmapFactory.Options options = new BitmapFactory.Options();
                // 不进行图片抖动处理
                options.inDither = false;
                // 设置让解码器以最佳方式解码
                options.inPreferredConfig = null;
                if (width > 0 && height > 0) {
                    options.outWidth = width;
                    options.outHeight = height;
                }
                bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length, options);
                bitmap.setDensity(96);// 96 dpi
            } catch (Exception e) {
                LogUtils.error(e);
            }
        }
        return bitmap;
    }

    public static Bitmap toBitmap(byte[] bytes) {
        return toBitmap(bytes, -1, -1);
    }

    /**
     * 将Drawable转换为Bitmap
     * 参考:http://kylines.iteye.com/blog/1660184
     */
    public static Bitmap toBitmap(Drawable drawable) {
        if (drawable instanceof BitmapDrawable) {
            return ((BitmapDrawable) drawable).getBitmap();
        } else if (drawable instanceof ColorDrawable) {
            //color
            Bitmap bitmap = Bitmap.createBitmap(32, 32, Bitmap.Config.ARGB_8888);
            Canvas canvas = new Canvas(bitmap);
            canvas.drawColor(((ColorDrawable) drawable).getColor());
            return bitmap;
        } else if (drawable instanceof NinePatchDrawable) {
            //.9.png
            Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(),
                    drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
            Canvas canvas = new Canvas(bitmap);
            drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
            drawable.draw(canvas);
            return bitmap;
        }
        return null;
    }

    /**
     * 从第三方文件选择器获取路径。
     * 参见:http://blog.csdn.net/zbjdsbj/article/details/42387551
     */
    @TargetApi(Build.VERSION_CODES.KITKAT)
    public static String toPath(Context context, Uri uri) {
        if (uri == null) {
            LogUtils.verbose("uri is null");
            return "";
        }
        LogUtils.verbose("uri: " + uri.toString());
        String path = uri.getPath();
        String scheme = uri.getScheme();
        String authority = uri.getAuthority();
        //是否是4.4及以上版本
        boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
        // DocumentProvider
        if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {
            String docId = DocumentsContract.getDocumentId(uri);
            String[] split = docId.split(":");
            String type = split[0];
            Uri contentUri = null;
            switch (authority) {
                // ExternalStorageProvider
                case "com.android.externalstorage.documents":
                    if ("primary".equalsIgnoreCase(type)) {
                        return Environment.getExternalStorageDirectory() + "/" + split[1];
                    }
                    break;
                // DownloadsProvider
                case "com.android.providers.downloads.documents":
                    contentUri = ContentUris.withAppendedId(
                            Uri.parse("content://downloads/public_downloads"), Long.valueOf(docId));
                    return _queryPathFromMediaStore(context, contentUri, null, null);
                // MediaProvider
                case "com.android.providers.media.documents":
                    if ("image".equals(type)) {
                        contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
                    } else if ("video".equals(type)) {
                        contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
                    } else if ("audio".equals(type)) {
                        contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
                    }
                    String selection = "_id=?";
                    String[] selectionArgs = new String[]{split[1]};
                    return _queryPathFromMediaStore(context, contentUri, selection, selectionArgs);
            }
        }
        // MediaStore (and general)
        else {
            if ("content".equalsIgnoreCase(scheme)) {
                // Return the remote address
                if (authority.equals("com.google.android.apps.photos.content")) {
                    return uri.getLastPathSegment();
                }
                return _queryPathFromMediaStore(context, uri, null, null);
            }
            // File
            else if ("file".equalsIgnoreCase(scheme)) {
                return uri.getPath();
            }
        }
        LogUtils.verbose("uri to path: " + path);
        return path;
    }

    private static String _queryPathFromMediaStore(Context context, Uri uri, String selection, String[] selectionArgs) {
        String filePath = null;
        try {
            String[] projection = {MediaStore.Images.Media.DATA};
            Cursor cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, null);
            if (cursor != null) {
                int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
                cursor.moveToFirst();
                filePath = cursor.getString(column_index);
                cursor.close();
            }
        } catch (IllegalArgumentException e) {
            LogUtils.error(e);
        }
        return filePath;
    }

    /**
     * 把view转化为bitmap(截图)
     * 参见:http://www.cnblogs.com/lee0oo0/p/3355468.html
     */
    public static Bitmap toBitmap(View view) {
        int width = view.getWidth();
        int height = view.getHeight();
        if (view instanceof ListView) {
            height = 0;
            // 获取listView实际高度
            ListView listView = (ListView) view;
            for (int i = 0; i < listView.getChildCount(); i++) {
                height += listView.getChildAt(i).getHeight();
            }
        } else if (view instanceof ScrollView) {
            height = 0;
            // 获取scrollView实际高度
            ScrollView scrollView = (ScrollView) view;
            for (int i = 0; i < scrollView.getChildCount(); i++) {
                height += scrollView.getChildAt(i).getHeight();
            }
        }
        view.setDrawingCacheEnabled(true);
        view.clearFocus();
        view.setPressed(false);
        boolean willNotCache = view.willNotCacheDrawing();
        view.setWillNotCacheDrawing(false);
        // Reset the drawing cache background color to fully transparent for the duration of this operation
        int color = view.getDrawingCacheBackgroundColor();
        view.setDrawingCacheBackgroundColor(Color.WHITE);//截图去黑色背景(透明像素)
        if (color != Color.WHITE) {
            view.destroyDrawingCache();
        }
        view.buildDrawingCache();
        Bitmap cacheBitmap = view.getDrawingCache();
        if (cacheBitmap == null) {
            return null;
        }
        Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(bitmap);
        canvas.drawBitmap(cacheBitmap, 0, 0, null);
        canvas.save(Canvas.ALL_SAVE_FLAG);
        canvas.restore();
        if (!bitmap.isRecycled()) {
            LogUtils.verbose("recycle bitmap: " + bitmap.toString());
            bitmap.recycle();
        }
        // Restore the view
        view.destroyDrawingCache();
        view.setWillNotCacheDrawing(willNotCache);
        view.setDrawingCacheBackgroundColor(color);
        return bitmap;
    }

    public static Drawable toDrawable(Bitmap bitmap) {
        return bitmap == null ? null : new BitmapDrawable(Resources.getSystem(), bitmap);
    }

    public static byte[] toByteArray(Drawable drawable) {
        return toByteArray(toBitmap(drawable));
    }

    public static Drawable toDrawable(byte[] bytes) {
        return toDrawable(toBitmap(bytes));
    }

    /**
     * dp转换为px
     */
    public static int toPx(Context context, float dpValue) {
        final float scale = context.getResources().getDisplayMetrics().density;
        int pxValue = (int) (dpValue * scale + 0.5f);
        LogUtils.verbose(dpValue + " dp == " + pxValue + " px");
        return pxValue;
    }

    /**
     * px转换为dp
     */
    public static int toDp(Context context, float pxValue) {
        final float scale = context.getResources().getDisplayMetrics().density;
        int dpValue = (int) (pxValue / scale + 0.5f);
        LogUtils.verbose(pxValue + " px == " + dpValue + " dp");
        return dpValue;
    }

    /**
     * px转换为sp
     */
    public static int toSp(Context context, float pxValue) {
        final float fontScale = context.getResources().getDisplayMetrics().scaledDensity;
        int spValue = (int) (pxValue / fontScale + 0.5f);
        LogUtils.verbose(pxValue + " px == " + spValue + " sp");
        return spValue;
    }

    public static String toGbk(String str) {
        try {
            return new String(str.getBytes("utf-8"), "gbk");
        } catch (UnsupportedEncodingException e) {
            LogUtils.warn(e);
            return str;
        }
    }

    public static String toFileSizeString(long fileSize) {
        DecimalFormat df = new DecimalFormat("0.00");
        String fileSizeString;
        if (fileSize < KB) {
            fileSizeString = fileSize + "B";
        } else if (fileSize < MB) {
            fileSizeString = df.format((double) fileSize / KB) + "K";
        } else if (fileSize < GB) {
            fileSizeString = df.format((double) fileSize / MB) + "M";
        } else {
            fileSizeString = df.format((double) fileSize / GB) + "G";
        }
        return fileSizeString;
    }

    public static String toString(InputStream is, String charset) {
        StringBuilder sb = new StringBuilder();
        try {
            BufferedReader reader = new BufferedReader(new InputStreamReader(is, charset));
            while (true) {
                String line = reader.readLine();
                if (line == null) {
                    break;
                } else {
                    sb.append(line).append("\n");
                }
            }
            reader.close();
            is.close();
        } catch (IOException e) {
            LogUtils.error(e);
        }
        return sb.toString();
    }

    public static String toString(InputStream is) {
        return toString(is, "utf-8");
    }

    public static int toDarkenColor(@ColorInt int color) {
        return toDarkenColor(color, 0.8f);
    }

    public static int toDarkenColor(@ColorInt int color, @FloatRange(from = 0f, to = 1f) float value) {
        float[] hsv = new float[3];
        Color.colorToHSV(color, hsv);
        hsv[2] *= value;//HSV指Hue、Saturation、Value,即色调、饱和度和亮度,此处表示修改亮度
        return Color.HSVToColor(hsv);
    }

    /**
     * 转换为6位十六进制颜色代码,不含“#”
     */
    public static String toColorString(@ColorInt int color) {
        return toColorString(color, false);
    }

    /**
     * 转换为6位十六进制颜色代码,不含“#”
     */
    public static String toColorString(@ColorInt int color, boolean includeAlpha) {
        String alpha = Integer.toHexString(Color.alpha(color));
        String red = Integer.toHexString(Color.red(color));
        String green = Integer.toHexString(Color.green(color));
        String blue = Integer.toHexString(Color.blue(color));
        if (alpha.length() == 1) {
            alpha = "0" + alpha;
        }
        if (red.length() == 1) {
            red = "0" + red;
        }
        if (green.length() == 1) {
            green = "0" + green;
        }
        if (blue.length() == 1) {
            blue = "0" + blue;
        }
        String colorString;
        if (includeAlpha) {
            colorString = alpha + red + green + blue;
            LogUtils.verbose(String.format(Locale.CHINA, "%d to color string is %s", color, colorString));
        } else {
            colorString = red + green + blue;
            LogUtils.verbose(String.format(Locale.CHINA, "%d to color string is %s%s%s%s, exclude alpha is %s", color, alpha, red, green, blue, colorString));
        }
        return colorString;
    }

    /**
     * 对TextView、Button等设置不同状态时其文字颜色。
     * 参见:http://blog.csdn.net/sodino/article/details/6797821
     * Modified by liyujiang at 2015.08.13
     */
    public static ColorStateList toColorStateList(@ColorInt int normalColor, @ColorInt int pressedColor,
                                                  @ColorInt int focusedColor, @ColorInt int unableColor) {
        int[] colors = new int[]{pressedColor, focusedColor, normalColor, focusedColor, unableColor, normalColor};
        int[][] states = new int[6][];
        states[0] = new int[]{android.R.attr.state_pressed, android.R.attr.state_enabled};
        states[1] = new int[]{android.R.attr.state_enabled, android.R.attr.state_focused};
        states[2] = new int[]{android.R.attr.state_enabled};
        states[3] = new int[]{android.R.attr.state_focused};
        states[4] = new int[]{android.R.attr.state_window_focused};
        states[5] = new int[]{};
        return new ColorStateList(states, colors);
    }

    public static ColorStateList toColorStateList(@ColorInt int normalColor, @ColorInt int pressedColor) {
        return toColorStateList(normalColor, pressedColor, pressedColor, normalColor);
    }

}


================================================
FILE: filepicker/src/main/java/com/ess/filepicker/util/DateUtils.java
================================================
package com.ess.filepicker.util;

import android.support.annotation.IntDef;
import android.support.annotation.NonNull;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Locale;

/**
 * 日期时间工具类
 *
 * @author 李玉江[QQ:1023694760]
 * @since 2015/8/5
 */
public class DateUtils extends android.text.format.DateUtils {
    public static final int Second = 0;
    public static final int Minute = 1;
    public static final int Hour = 2;
    public static final int Day = 3;

    @IntDef(value = {Second, Minute, Hour, Day})
    @Retention(RetentionPolicy.SOURCE)
    public @interface DifferenceMode {
    }

    public static long calculateDifferentSecond(Date startDate, Date endDate) {
        return calculateDifference(startDate, endDate, Second);
    }

    public static long calculateDifferentMinute(Date startDate, Date endDate) {
        return calculateDifference(startDate, endDate, Minute);
    }

    public static long calculateDifferentHour(Date startDate, Date endDate) {
        return calculateDifference(startDate, endDate, Hour);
    }

    public static long calculateDifferentDay(Date startDate, Date endDate) {
        return calculateDifference(startDate, endDate, Day);
    }

    public static long calculateDifferentSecond(long startTimeMillis, long endTimeMillis) {
        return calculateDifference(startTimeMillis, endTimeMillis, Second);
    }

    public static long calculateDifferentMinute(long startTimeMillis, long endTimeMillis) {
        return calculateDifference(startTimeMillis, endTimeMillis, Minute);
    }

    public static long calculateDifferentHour(long startTimeMillis, long endTimeMillis) {
        return calculateDifference(startTimeMillis, endTimeMillis, Hour);
    }

    public static long calculateDifferentDay(long startTimeMillis, l
Download .txt
gitextract_v173hlks/

├── .gitignore
├── .idea/
│   ├── caches/
│   │   └── build_file_checksums.ser
│   ├── codeStyles/
│   │   └── Project.xml
│   ├── copyright/
│   │   └── Ess.xml
│   ├── gradle.xml
│   ├── misc.xml
│   ├── modules.xml
│   ├── runConfigurations.xml
│   └── vcs.xml
├── APK/
│   └── release/
│       └── filepicker-demo.apk
├── LICENSE
├── README.md
├── app/
│   ├── .gitignore
│   ├── build.gradle
│   ├── proguard-rules.pro
│   └── src/
│       ├── androidTest/
│       │   └── java/
│       │       └── com/
│       │           └── ess/
│       │               └── essfilepicker/
│       │                   └── ExampleInstrumentedTest.java
│       ├── main/
│       │   ├── AndroidManifest.xml
│       │   ├── java/
│       │   │   └── com/
│       │   │       └── ess/
│       │   │           └── essfilepicker/
│       │   │               ├── FragmentTestActivity.java
│       │   │               ├── LApplication.java
│       │   │               ├── MainActivity.java
│       │   │               └── TestFragment.java
│       │   └── res/
│       │       ├── drawable/
│       │       │   └── ic_launcher_background.xml
│       │       ├── drawable-v24/
│       │       │   └── ic_launcher_foreground.xml
│       │       ├── layout/
│       │       │   ├── activity_fragment_test.xml
│       │       │   ├── activity_main.xml
│       │       │   └── fragment_test.xml
│       │       ├── mipmap-anydpi-v26/
│       │       │   ├── ic_launcher.xml
│       │       │   └── ic_launcher_round.xml
│       │       └── values/
│       │           ├── colors.xml
│       │           ├── strings.xml
│       │           └── styles.xml
│       └── test/
│           └── java/
│               └── com/
│                   └── ess/
│                       └── essfilepicker/
│                           └── ExampleUnitTest.java
├── build.gradle
├── filepicker/
│   ├── .gitignore
│   ├── build.gradle
│   ├── proguard-rules.pro
│   └── src/
│       ├── androidTest/
│       │   └── java/
│       │       └── com/
│       │           └── ess/
│       │               └── filepicker/
│       │                   └── ExampleInstrumentedTest.java
│       ├── main/
│       │   ├── AndroidManifest.xml
│       │   ├── java/
│       │   │   └── com/
│       │   │       └── ess/
│       │   │           └── filepicker/
│       │   │               ├── BaseFileFragment.java
│       │   │               ├── FilePicker.java
│       │   │               ├── SelectCreator.java
│       │   │               ├── SelectOptions.java
│       │   │               ├── activity/
│       │   │               │   ├── FileTypeListFragment.java
│       │   │               │   ├── PicturesViewActivity.java
│       │   │               │   ├── SelectFileByBrowserActivity.java
│       │   │               │   ├── SelectFileByScanActivity.java
│       │   │               │   └── SelectPictureActivity.java
│       │   │               ├── adapter/
│       │   │               │   ├── BreadAdapter.java
│       │   │               │   ├── BuketAdapter.java
│       │   │               │   ├── EssMediaAdapter.java
│       │   │               │   ├── FileListAdapter.java
│       │   │               │   ├── FragmentPagerAdapter.java
│       │   │               │   ├── OnFileSelectListener.java
│       │   │               │   └── SelectSdcardAdapter.java
│       │   │               ├── loader/
│       │   │               │   ├── EssAlbumCollection.java
│       │   │               │   ├── EssAlbumLoader.java
│       │   │               │   ├── EssMediaCollection.java
│       │   │               │   ├── EssMediaLoader.java
│       │   │               │   ├── EssMimeTypeCollection.java
│       │   │               │   └── EssMimeTypeLoader.java
│       │   │               ├── model/
│       │   │               │   ├── Album.java
│       │   │               │   ├── BreadModel.java
│       │   │               │   ├── CaptureStrategy.java
│       │   │               │   ├── EssFile.java
│       │   │               │   ├── EssFileCountCallBack.java
│       │   │               │   ├── EssFileFilter.java
│       │   │               │   ├── EssFileListCallBack.java
│       │   │               │   ├── EssFileProvider.java
│       │   │               │   ├── FileScanActEvent.java
│       │   │               │   ├── FileScanFragEvent.java
│       │   │               │   └── FileScanSortChangedEvent.java
│       │   │               ├── task/
│       │   │               │   ├── EssFileCountTask.java
│       │   │               │   └── EssFileListTask.java
│       │   │               ├── util/
│       │   │               │   ├── Const.java
│       │   │               │   ├── ConvertUtils.java
│       │   │               │   ├── DateUtils.java
│       │   │               │   ├── DialogUtil.java
│       │   │               │   ├── FileSizeUtil.java
│       │   │               │   ├── FileUtils.java
│       │   │               │   ├── LogUtils.java
│       │   │               │   ├── MediaStoreCompat.java
│       │   │               │   ├── MimeType.java
│       │   │               │   ├── PathUtils.java
│       │   │               │   ├── PhotoMetadataUtils.java
│       │   │               │   ├── Platform.java
│       │   │               │   └── UiUtils.java
│       │   │               └── widget/
│       │   │                   ├── MediaItemDecoration.java
│       │   │                   └── ToolbarSpinner.java
│       │   └── res/
│       │       ├── color/
│       │       │   ├── dracula_bottom_toolbar_apply.xml
│       │       │   ├── dracula_bottom_toolbar_preview.xml
│       │       │   ├── dracula_preview_bottom_toolbar_apply.xml
│       │       │   ├── elec_bottom_toolbar_apply.xml
│       │       │   ├── elec_bottom_toolbar_preview.xml
│       │       │   └── elec_preview_bottom_toolbar_apply.xml
│       │       ├── drawable/
│       │       │   └── bg_bottom_line_gray.xml
│       │       ├── layout/
│       │       │   ├── activity_pictures_detail.xml
│       │       │   ├── activity_select_file.xml
│       │       │   ├── activity_select_file_by_scan.xml
│       │       │   ├── activity_select_picture.xml
│       │       │   ├── bread_item.xml
│       │       │   ├── buket_list_item.xml
│       │       │   ├── empty_file_list.xml
│       │       │   ├── ess_media_item.xml
│       │       │   ├── fragment_file_type_list.xml
│       │       │   ├── item_capture.xml
│       │       │   ├── item_file_list.xml
│       │       │   ├── item_select_sdcard.xml
│       │       │   ├── loading_layout.xml
│       │       │   └── pop_select_sdcard.xml
│       │       ├── layout-v21/
│       │       │   ├── activity_select_file.xml
│       │       │   └── bread_item.xml
│       │       ├── menu/
│       │       │   ├── browse_menu.xml
│       │       │   └── media_menu.xml
│       │       ├── values/
│       │       │   ├── attrs.xml
│       │       │   ├── colors.xml
│       │       │   ├── colors_dracula.xml
│       │       │   ├── colors_zhihu.xml
│       │       │   ├── dimens.xml
│       │       │   ├── strings.xml
│       │       │   └── styles.xml
│       │       ├── values-v21/
│       │       │   └── styles.xml
│       │       └── xml/
│       │           └── provider_paths.xml
│       └── test/
│           └── java/
│               └── com/
│                   └── ess/
│                       └── filepicker/
│                           └── ExampleUnitTest.java
├── filepicker.jks
├── gradle/
│   └── wrapper/
│       ├── gradle-wrapper.jar
│       └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
└── settings.gradle
Download .txt
SYMBOL INDEX (532 symbols across 58 files)

FILE: app/src/androidTest/java/com/ess/essfilepicker/ExampleInstrumentedTest.java
  class ExampleInstrumentedTest (line 17) | @RunWith(AndroidJUnit4.class)
    method useAppContext (line 19) | @Test

FILE: app/src/main/java/com/ess/essfilepicker/FragmentTestActivity.java
  class FragmentTestActivity (line 11) | public class FragmentTestActivity extends AppCompatActivity {
    method onCreate (line 16) | @Override

FILE: app/src/main/java/com/ess/essfilepicker/LApplication.java
  class LApplication (line 20) | public class LApplication extends Application{
    method onCreate (line 22) | @Override

FILE: app/src/main/java/com/ess/essfilepicker/MainActivity.java
  class MainActivity (line 30) | public class MainActivity extends AppCompatActivity {
    method onBrowse (line 37) | @OnClick(R.id.button_browse)
    method onScan (line 47) | @OnClick(R.id.button_scan)
    method onSinglePick (line 59) | @OnClick(R.id.button_single_pick)
    method onSelectPictures (line 70) | @OnClick(R.id.button_select_pictures)
    method onFragment (line 81) | @OnClick(R.id.button_fragment)
    method onCreate (line 87) | @Override
    method onActivityResult (line 106) | @Override

FILE: app/src/main/java/com/ess/essfilepicker/TestFragment.java
  class TestFragment (line 30) | public class TestFragment extends Fragment {
    method onBrowse (line 37) | @OnClick(R.id.button_browse)
    method onScan (line 47) | @OnClick(R.id.button_scan)
    method onSelectPictures (line 58) | @OnClick(R.id.button_select_pictures)
    method TestFragment (line 69) | public TestFragment() {
    method newInstance (line 72) | public static TestFragment newInstance() {
    method onCreate (line 76) | @Override
    method onCreateView (line 81) | @Override
    method onViewCreated (line 88) | @Override
    method onActivityResult (line 95) | @Override

FILE: app/src/test/java/com/ess/essfilepicker/ExampleUnitTest.java
  class ExampleUnitTest (line 12) | public class ExampleUnitTest {
    method addition_isCorrect (line 13) | @Test

FILE: filepicker/src/androidTest/java/com/ess/filepicker/ExampleInstrumentedTest.java
  class ExampleInstrumentedTest (line 17) | @RunWith(AndroidJUnit4.class)
    method useAppContext (line 19) | @Test

FILE: filepicker/src/main/java/com/ess/filepicker/BaseFileFragment.java
  class BaseFileFragment (line 20) | public abstract class BaseFileFragment extends Fragment{
    method onAttach (line 39) | @Override
    method onCreateView (line 49) | @Override
    method getFragmentLayout (line 64) | public abstract int getFragmentLayout();
    method setFirstLoad (line 72) | public void setFirstLoad(boolean isFirstLoad) {
    method setUserVisibleHint (line 81) | @Override
    method onVisible (line 96) | private void onVisible() {
    method onInvisible (line 106) | protected void onInvisible() {
    method initUI (line 114) | protected void initUI(View view) {
    method lazyLoad (line 122) | protected abstract void lazyLoad();
    method onRefresh (line 129) | protected void onRefresh(Message msg) {
    method onDetach (line 134) | @Override

FILE: filepicker/src/main/java/com/ess/filepicker/FilePicker.java
  class FilePicker (line 15) | public final class FilePicker {
    method FilePicker (line 20) | private FilePicker(Activity activity) {
    method FilePicker (line 24) | private FilePicker(Fragment fragment){
    method FilePicker (line 28) | private FilePicker(Activity mContext, Fragment mFragment) {
    method from (line 33) | public static FilePicker from(Activity activity){
    method from (line 37) | public static FilePicker from(Fragment fragment){
    method chooseForBrowser (line 41) | public SelectCreator chooseForBrowser(){
    method chooseForMimeType (line 45) | public SelectCreator chooseForMimeType(){
    method chooseMedia (line 49) | public SelectCreator chooseMedia(){
    method getActivity (line 54) | public Activity getActivity() {
    method getFragment (line 58) | public Fragment getFragment() {

FILE: filepicker/src/main/java/com/ess/filepicker/SelectCreator.java
  class SelectCreator (line 20) | public final class SelectCreator {
    method SelectCreator (line 26) | public SelectCreator(FilePicker filePicker, String chooseType) {
    method setMaxCount (line 32) | public SelectCreator setMaxCount(int maxCount) {
    method setCompressImage (line 43) | public SelectCreator setCompressImage(boolean compressImage){
    method setTargetPath (line 48) | public SelectCreator setTargetPath(String path){
    method setTheme (line 53) | public SelectCreator setTheme(@StyleRes int theme) {
    method setFileTypes (line 58) | public SelectCreator setFileTypes(String... fileTypes) {
    method setSortType (line 63) | public SelectCreator setSortType(String sortType) {
    method isSingle (line 68) | public SelectCreator isSingle() {
    method onlyShowImages (line 74) | public SelectCreator onlyShowImages() {
    method onlyShowVideos (line 79) | public SelectCreator onlyShowVideos() {
    method placeHolder (line 84) | public SelectCreator placeHolder(Drawable placeHolder) {
    method enabledCapture (line 89) | public SelectCreator enabledCapture(boolean enabledCapture) {
    method requestCode (line 94) | public SelectCreator requestCode(int requestCode) {
    method start (line 99) | public void start() {

FILE: filepicker/src/main/java/com/ess/filepicker/SelectOptions.java
  class SelectOptions (line 18) | public class SelectOptions {
    method getFileTypes (line 39) | public String[] getFileTypes() {
    method getSortType (line 46) | public int getSortType() {
    method getTargetPath (line 53) | public String getTargetPath() {
    method setSortType (line 64) | public void setSortType(int sortType) {
    method getInstance (line 68) | public static SelectOptions getInstance() {
    method getCleanInstance (line 72) | public static SelectOptions getCleanInstance() {
    method reset (line 78) | private void reset() {
    class InstanceHolder (line 90) | private static final class InstanceHolder {

FILE: filepicker/src/main/java/com/ess/filepicker/activity/FileTypeListFragment.java
  class FileTypeListFragment (line 31) | public class FileTypeListFragment extends BaseFileFragment implements Ba...
    method FileTypeListFragment (line 54) | public FileTypeListFragment() {
    method newInstance (line 57) | public static FileTypeListFragment newInstance(String param1, boolean ...
    method onCreate (line 69) | @Override
    method getFragmentLayout (line 81) | @Override
    method lazyLoad (line 86) | @Override
    method initUI (line 91) | @Override
    method onFreshCount (line 110) | @Subscribe
    method onFreshSortType (line 118) | @Subscribe
    method setUserVisibleHint (line 128) | @Override
    method onItemClick (line 141) | @Override
    method findFileIndex (line 175) | private int findFileIndex(EssFile item) {
    method onDestroy (line 184) | @Override
    method onFileLoad (line 191) | @Override
    method onFileReset (line 201) | @Override

FILE: filepicker/src/main/java/com/ess/filepicker/activity/PicturesViewActivity.java
  class PicturesViewActivity (line 14) | public class PicturesViewActivity extends AppCompatActivity {
    method onCreate (line 23) | @Override

FILE: filepicker/src/main/java/com/ess/filepicker/activity/SelectFileByBrowserActivity.java
  class SelectFileByBrowserActivity (line 44) | public class SelectFileByBrowserActivity extends AppCompatActivity
    method onCreate (line 75) | @Override
    method onCreateOptionsMenu (line 90) | @Override
    method initUi (line 98) | private void initUi() {
    method initData (line 133) | private void initData() {
    method executeListTask (line 137) | private void executeListTask(List<EssFile> essFileList, String queryPa...
    method onFindFileList (line 148) | @Override
    method showPopupWindow (line 185) | private void showPopupWindow() {
    method backgroundAlpha (line 215) | public void backgroundAlpha(float bgAlpha) {
    method onFindChildFileAndFolderCount (line 222) | @Override
    method onItemClick (line 229) | @Override
    method findFileIndex (line 271) | private int findFileIndex(EssFile item) {
    method onBackPressed (line 280) | @Override
    method onItemChildClick (line 289) | @Override
    method onDestroy (line 301) | @Override
    method onClick (line 314) | @Override
    method onOptionsItemSelected (line 323) | @Override
    method onLoadFileCount (line 397) | @Override

FILE: filepicker/src/main/java/com/ess/filepicker/activity/SelectFileByScanActivity.java
  class SelectFileByScanActivity (line 38) | public class SelectFileByScanActivity extends AppCompatActivity implemen...
    method onCreate (line 52) | @Override
    method initData (line 62) | private void initData() {
    method initUi (line 65) | private void initUi() {
    method onFragSelectFile (line 101) | @Subscribe
    method onDestroy (line 120) | @Override
    method onCreateOptionsMenu (line 126) | @Override
    method onOptionsItemSelected (line 134) | @Override
    method onPageScrolled (line 198) | @Override
    method onPageSelected (line 203) | @Override
    method onPageScrollStateChanged (line 208) | @Override

FILE: filepicker/src/main/java/com/ess/filepicker/activity/SelectPictureActivity.java
  class SelectPictureActivity (line 49) | public class SelectPictureActivity extends AppCompatActivity implements ...
    method onCreate (line 74) | @Override
    method initUI (line 86) | private void initUI() {
    method onCreateOptionsMenu (line 132) | @Override
    method onDestroy (line 140) | @Override
    method onAlbumMediaLoad (line 147) | @Override
    method onAlbumMediaReset (line 155) | @Override
    method onItemSelected (line 160) | @Override
    method onNothingSelected (line 167) | @Override
    method onMediaLoad (line 172) | @Override
    method onmMediaReset (line 180) | @Override
    method onItemChildClick (line 185) | @Override
    method onOptionsItemSelected (line 216) | @Override
    method onItemClick (line 267) | @Override

FILE: filepicker/src/main/java/com/ess/filepicker/adapter/BreadAdapter.java
  class BreadAdapter (line 18) | public class BreadAdapter extends BaseQuickAdapter<BreadModel, BaseViewH...
    method BreadAdapter (line 20) | public BreadAdapter(@Nullable List<BreadModel> data) {
    method convert (line 24) | @Override

FILE: filepicker/src/main/java/com/ess/filepicker/adapter/BuketAdapter.java
  class BuketAdapter (line 25) | public class BuketAdapter extends CursorAdapter{
    method BuketAdapter (line 29) | public BuketAdapter(Context context, Cursor c, boolean autoRequery) {
    method newView (line 37) | @Override
    method bindView (line 42) | @Override

FILE: filepicker/src/main/java/com/ess/filepicker/adapter/EssMediaAdapter.java
  class EssMediaAdapter (line 26) | public class EssMediaAdapter extends BaseQuickAdapter<EssFile, BaseViewH...
    method EssMediaAdapter (line 30) | public EssMediaAdapter(@Nullable List<EssFile> data) {
    method setImageResize (line 34) | public void setImageResize(int imageSize) {
    method convert (line 38) | @Override

FILE: filepicker/src/main/java/com/ess/filepicker/adapter/FileListAdapter.java
  class FileListAdapter (line 23) | public class FileListAdapter extends BaseQuickAdapter<EssFile, BaseViewH...
    type onLoadFileCountListener (line 27) | public interface onLoadFileCountListener{
      method onLoadFileCount (line 28) | void onLoadFileCount(int posistion);
    method getLoadFileCountListener (line 31) | public onLoadFileCountListener getLoadFileCountListener() {
    method setLoadFileCountListener (line 35) | public void setLoadFileCountListener(onLoadFileCountListener loadFileC...
    method FileListAdapter (line 39) | public FileListAdapter(@Nullable List<EssFile> data) {
    method convert (line 43) | @Override

FILE: filepicker/src/main/java/com/ess/filepicker/adapter/FragmentPagerAdapter.java
  class FragmentPagerAdapter (line 15) | public class FragmentPagerAdapter extends FragmentStatePagerAdapter {
    method FragmentPagerAdapter (line 21) | public FragmentPagerAdapter(FragmentManager fm) {
    method FragmentPagerAdapter (line 26) | public FragmentPagerAdapter(FragmentManager fm, List<Fragment> fragmen...
    method FragmentPagerAdapter (line 32) | public FragmentPagerAdapter(FragmentManager fm, List<Fragment> fragmen...
    method setFragments (line 37) | public void setFragments(ArrayList<Fragment> fragments) {
    method getPageTitle (line 51) | @Override
    method getCount (line 59) | @Override
    method getItem (line 64) | @Override
    method getItemPosition (line 69) | @Override
    method instantiateItem (line 74) | @Override

FILE: filepicker/src/main/java/com/ess/filepicker/adapter/OnFileSelectListener.java
  type OnFileSelectListener (line 12) | public interface OnFileSelectListener {
    method onSelected (line 13) | void onSelected(List<EssFile> essFileList);

FILE: filepicker/src/main/java/com/ess/filepicker/adapter/SelectSdcardAdapter.java
  class SelectSdcardAdapter (line 16) | public class SelectSdcardAdapter extends BaseQuickAdapter<String,BaseVie...
    method SelectSdcardAdapter (line 17) | public SelectSdcardAdapter(@Nullable List<String> data) {
    method convert (line 21) | @Override

FILE: filepicker/src/main/java/com/ess/filepicker/loader/EssAlbumCollection.java
  class EssAlbumCollection (line 29) | public class EssAlbumCollection implements LoaderManager.LoaderCallbacks...
    method onCreateLoader (line 35) | @Override
    method onLoadFinished (line 46) | @Override
    method onLoaderReset (line 56) | @Override
    method onCreate (line 66) | public void onCreate(@NonNull FragmentActivity context, @NonNull EssAl...
    method onDestroy (line 72) | public void onDestroy() {
    method load (line 77) | public void load() {
    type EssAlbumCallbacks (line 82) | public interface EssAlbumCallbacks {
      method onAlbumMediaLoad (line 84) | void onAlbumMediaLoad(Cursor cursor);
      method onAlbumMediaReset (line 86) | void onAlbumMediaReset();

FILE: filepicker/src/main/java/com/ess/filepicker/loader/EssAlbumLoader.java
  class EssAlbumLoader (line 19) | public class EssAlbumLoader extends CursorLoader {
    method getSelectionArgsForSingleMediaType (line 55) | private static String[] getSelectionArgsForSingleMediaType(int mediaTy...
    method EssAlbumLoader (line 62) | public EssAlbumLoader(Context context, String selection, String[] sele...
    method newInstance (line 66) | public static CursorLoader newInstance(Context context) {
    method loadInBackground (line 82) | @Override

FILE: filepicker/src/main/java/com/ess/filepicker/loader/EssMediaCollection.java
  class EssMediaCollection (line 27) | public class EssMediaCollection implements LoaderManager.LoaderCallbacks...
    method onCreateLoader (line 38) | @Override
    method onLoadFinished (line 53) | @Override
    method onLoaderReset (line 77) | @Override
    method onCreate (line 87) | public void onCreate(@NonNull FragmentActivity context, @NonNull EssMe...
    method onDestroy (line 93) | public void onDestroy() {
    method load (line 98) | public void load(@Nullable Album target) {
    method load (line 102) | public void load(@Nullable Album target, boolean enableCapture, Set<Es...
    method load (line 114) | public void load(@Nullable Album target, boolean enableCapture, boolea...
    type EssMediaCallbacks (line 126) | public interface EssMediaCallbacks {
      method onMediaLoad (line 128) | void onMediaLoad(List<EssFile> cursor);
      method onmMediaReset (line 130) | void onmMediaReset();

FILE: filepicker/src/main/java/com/ess/filepicker/loader/EssMediaLoader.java
  class EssMediaLoader (line 20) | public class EssMediaLoader extends CursorLoader {
    method getSelectionArgsForSingleMediaType (line 47) | private static String[] getSelectionArgsForSingleMediaType(int mediaTy...
    method getSelectionAlbumArgs (line 61) | private static String[] getSelectionAlbumArgs(String albumId) {
    method getSelectionAlbumArgsForSingleMediaType (line 77) | private static String[] getSelectionAlbumArgsForSingleMediaType(int me...
    method EssMediaLoader (line 85) | private EssMediaLoader(Context context, String selection, String[] sel...
    method newInstance (line 90) | public static CursorLoader newInstance(Context context, Album album) {
    method loadInBackground (line 124) | @Override
    method onContentChanged (line 135) | @Override

FILE: filepicker/src/main/java/com/ess/filepicker/loader/EssMimeTypeCollection.java
  class EssMimeTypeCollection (line 35) | public class EssMimeTypeCollection implements LoaderManager.LoaderCallba...
    method onCreateLoader (line 43) | @Override
    method onLoadFinished (line 56) | @Override
    method onLoaderReset (line 65) | @Override
    method onCreate (line 76) | public void onCreate(@NonNull FragmentActivity context, @NonNull EssMi...
    method onDestroy (line 82) | public void onDestroy() {
    method load (line 87) | public void load(String extension, int sortType,int loaderId) {
    type EssMimeTypeCallbacks (line 98) | public interface EssMimeTypeCallbacks {
      method onFileLoad (line 100) | void onFileLoad(List<EssFile> essFileList);
      method onFileReset (line 102) | void onFileReset();

FILE: filepicker/src/main/java/com/ess/filepicker/loader/EssMimeTypeLoader.java
  class EssMimeTypeLoader (line 21) | public class EssMimeTypeLoader extends CursorLoader {
    method EssMimeTypeLoader (line 36) | public EssMimeTypeLoader(Context context, String selection, String[] s...
    method newInstance (line 41) | public static CursorLoader newInstance(Context context, String extensi...
    method getEssFileList (line 90) | public List<EssFile> getEssFileList() {
    method loadInBackground (line 94) | @Override

FILE: filepicker/src/main/java/com/ess/filepicker/model/Album.java
  class Album (line 28) | public class Album implements Parcelable {
    method createFromParcel (line 30) | @Nullable
    method newArray (line 36) | @Override
    method Album (line 49) | Album(String id, String coverPath, String albumName, long count) {
    method Album (line 56) | Album(Parcel source) {
    method valueOf (line 67) | public static Album valueOf(Cursor cursor) {
    method describeContents (line 75) | @Override
    method writeToParcel (line 80) | @Override
    method getId (line 88) | public String getId() {
    method getCoverPath (line 92) | public String getCoverPath() {
    method getCount (line 96) | public long getCount() {
    method addCaptureCount (line 100) | public void addCaptureCount() {
    method getDisplayName (line 104) | public String getDisplayName(Context context) {
    method isAll (line 111) | public boolean isAll() {
    method isEmpty (line 115) | public boolean isEmpty() {

FILE: filepicker/src/main/java/com/ess/filepicker/model/BreadModel.java
  class BreadModel (line 12) | public class BreadModel {
    method getCurName (line 23) | public String getCurName() {
    method setCurName (line 27) | public void setCurName(String mCurName) {
    method getPrePosition (line 31) | public int getPrePosition() {
    method setPrePosition (line 35) | public void setPrePosition(int mPrePosition) {
    method getCurPath (line 39) | public String getCurPath() {
    method setmCurPath (line 43) | public void setmCurPath(String mCurPath) {
    method getNewBreadModel (line 53) | public static List<BreadModel> getNewBreadModel(List<BreadModel> oldLi...
    method getRemovedBreadModel (line 76) | public static int getRemovedBreadModel(List<BreadModel> oldList, List<...

FILE: filepicker/src/main/java/com/ess/filepicker/model/CaptureStrategy.java
  class CaptureStrategy (line 18) | public class CaptureStrategy {
    method CaptureStrategy (line 23) | public CaptureStrategy(boolean isPublic, String authority) {

FILE: filepicker/src/main/java/com/ess/filepicker/model/EssFile.java
  class EssFile (line 24) | public class EssFile implements Parcelable {
    method EssFile (line 42) | protected EssFile(Parcel in) {
    method createFromParcel (line 57) | @Override
    method newArray (line 62) | @Override
    method isChecked (line 68) | public boolean isChecked() {
    method setChecked (line 72) | public void setChecked(boolean checked) {
    method EssFile (line 76) | public EssFile(String path) {
    method EssFile (line 88) | public EssFile(File file) {
    method EssFile (line 98) | public EssFile(long id, String mimeType) {
    method getUri (line 112) | public Uri getUri() {
    method isExits (line 116) | public boolean isExits() {
    method getMimeType (line 120) | public String getMimeType() {
    method setMimeType (line 124) | public void setMimeType(String mimeType) {
    method getChildFolderCount (line 128) | public String getChildFolderCount() {
    method setChildFolderCount (line 132) | public void setChildFolderCount(String childFolderCount) {
    method getChildFileCount (line 136) | public String getChildFileCount() {
    method setChildFileCount (line 140) | public void setChildFileCount(String childFileCount) {
    method setChildCounts (line 144) | public void setChildCounts(String childFileCount, String childFolderCo...
    method getFile (line 150) | public File getFile() {
    method getName (line 154) | public String getName() {
    method isDirectory (line 158) | public boolean isDirectory() {
    method isFile (line 162) | public boolean isFile() {
    method getAbsolutePath (line 166) | public String getAbsolutePath() {
    method getEssFileList (line 170) | public static List<EssFile> getEssFileList(List<File> files) {
    method getEssFileList (line 179) | public static ArrayList<EssFile> getEssFileList(Context context, Set<E...
    method getFilePathList (line 189) | public static ArrayList<String> getFilePathList(ArrayList<EssFile> ess...
    method toString (line 198) | @Override
    method isImage (line 207) | public boolean isImage() {
    method isGif (line 216) | public boolean isGif() {
    method isVideo (line 221) | public boolean isVideo() {
    method setItemType (line 234) | public void setItemType(int itemType) {
    method getItemType (line 238) | public int getItemType() {
    method describeContents (line 242) | @Override
    method writeToParcel (line 247) | @Override
    method equals (line 262) | @Override
    method hashCode (line 276) | @Override

FILE: filepicker/src/main/java/com/ess/filepicker/model/EssFileCountCallBack.java
  type EssFileCountCallBack (line 8) | public interface EssFileCountCallBack {
    method onFindChildFileAndFolderCount (line 9) | void onFindChildFileAndFolderCount(int position, String childFileCount...

FILE: filepicker/src/main/java/com/ess/filepicker/model/EssFileFilter.java
  class EssFileFilter (line 10) | public class EssFileFilter implements FileFilter {
    method EssFileFilter (line 13) | public EssFileFilter(String[] types) {
    method accept (line 17) | @Override

FILE: filepicker/src/main/java/com/ess/filepicker/model/EssFileListCallBack.java
  type EssFileListCallBack (line 10) | public interface EssFileListCallBack {
    method onFindFileList (line 11) | void onFindFileList(String queryPath, List<EssFile> essFileList);

FILE: filepicker/src/main/java/com/ess/filepicker/model/EssFileProvider.java
  class EssFileProvider (line 10) | public class EssFileProvider extends FileProvider {

FILE: filepicker/src/main/java/com/ess/filepicker/model/FileScanActEvent.java
  class FileScanActEvent (line 8) | public class FileScanActEvent {
    method FileScanActEvent (line 11) | public FileScanActEvent(int canSelectMaxCount) {
    method getCanSelectMaxCount (line 15) | public int getCanSelectMaxCount() {
    method setCanSelectMaxCount (line 19) | public void setCanSelectMaxCount(int canSelectMaxCount) {

FILE: filepicker/src/main/java/com/ess/filepicker/model/FileScanFragEvent.java
  class FileScanFragEvent (line 9) | public class FileScanFragEvent {
    method FileScanFragEvent (line 14) | public FileScanFragEvent(EssFile selectedFile, boolean isAdd) {
    method getSelectedFile (line 19) | public EssFile getSelectedFile() {
    method setSelectedFile (line 23) | public void setSelectedFile(EssFile selectedFile) {
    method isAdd (line 27) | public boolean isAdd() {
    method setAdd (line 31) | public void setAdd(boolean add) {
    method getSelectedFileList (line 35) | public EssFile getSelectedFileList() {
    method setSelectedFileList (line 39) | public void setSelectedFileList(EssFile selectedFileList) {

FILE: filepicker/src/main/java/com/ess/filepicker/model/FileScanSortChangedEvent.java
  class FileScanSortChangedEvent (line 8) | public class FileScanSortChangedEvent {
    method FileScanSortChangedEvent (line 12) | public FileScanSortChangedEvent(int sortType, int currentItem) {
    method getCurrentItem (line 17) | public int getCurrentItem() {
    method setCurrentItem (line 21) | public void setCurrentItem(int currentItem) {
    method FileScanSortChangedEvent (line 25) | public FileScanSortChangedEvent(int sortType) {
    method getSortType (line 29) | public int getSortType() {
    method setSortType (line 33) | public void setSortType(int sortType) {

FILE: filepicker/src/main/java/com/ess/filepicker/task/EssFileCountTask.java
  class EssFileCountTask (line 18) | public class EssFileCountTask extends AsyncTask<Void,Void,Void>{
    method EssFileCountTask (line 27) | public EssFileCountTask(int position, String queryPath, String[] types...
    method doInBackground (line 34) | @Override
    method onPostExecute (line 53) | @Override

FILE: filepicker/src/main/java/com/ess/filepicker/task/EssFileListTask.java
  class EssFileListTask (line 21) | public class EssFileListTask extends AsyncTask<Void,Void,List<EssFile>> {
    method EssFileListTask (line 29) | public EssFileListTask(List<EssFile> mSelectedFileList, String queryPa...
    method doInBackground (line 37) | @Override
    method onPreExecute (line 79) | @Override
    method onPostExecute (line 84) | @Override

FILE: filepicker/src/main/java/com/ess/filepicker/util/Const.java
  class Const (line 11) | public class Const {

FILE: filepicker/src/main/java/com/ess/filepicker/util/ConvertUtils.java
  class ConvertUtils (line 47) | public class ConvertUtils {
    method toInt (line 52) | public static int toInt(Object obj) {
    method toInt (line 60) | public static int toInt(byte[] bytes) {
    method toShort (line 70) | public static int toShort(byte first, byte second) {
    method toLong (line 74) | public static long toLong(Object obj) {
    method toFloat (line 82) | public static float toFloat(Object obj) {
    method toByteArray (line 96) | public static byte[] toByteArray(int i) {
    method toByteArray (line 106) | public static byte[] toByteArray(String hexData, boolean isHex) {
    method toHexString (line 131) | public static String toHexString(String str) {
    method toHexString (line 149) | public static String toHexString(byte... bytes) {
    method toHexString (line 168) | public static String toHexString(int num) {
    method toBinaryString (line 180) | public static String toBinaryString(byte... bytes) {
    method toBinaryString (line 205) | public static String toBinaryString(int num) {
    method toSlashString (line 211) | public static String toSlashString(String str) {
    method toArray (line 223) | public static <T> T[] toArray(List<T> list) {
    method toList (line 228) | public static <T> List<T> toList(T[] array) {
    method toString (line 232) | public static String toString(Object[] objects) {
    method toString (line 236) | public static String toString(Object[] objects, String tag) {
    method toByteArray (line 245) | public static byte[] toByteArray(InputStream is) {
    method toByteArray (line 270) | public static byte[] toByteArray(Bitmap bitmap) {
    method toBitmap (line 286) | public static Bitmap toBitmap(byte[] bytes, int width, int height) {
    method toBitmap (line 308) | public static Bitmap toBitmap(byte[] bytes) {
    method toBitmap (line 316) | public static Bitmap toBitmap(Drawable drawable) {
    method toPath (line 341) | @TargetApi(Build.VERSION_CODES.KITKAT)
    method _queryPathFromMediaStore (line 403) | private static String _queryPathFromMediaStore(Context context, Uri ur...
    method toBitmap (line 424) | public static Bitmap toBitmap(View view) {
    method toDrawable (line 474) | public static Drawable toDrawable(Bitmap bitmap) {
    method toByteArray (line 478) | public static byte[] toByteArray(Drawable drawable) {
    method toDrawable (line 482) | public static Drawable toDrawable(byte[] bytes) {
    method toPx (line 489) | public static int toPx(Context context, float dpValue) {
    method toDp (line 499) | public static int toDp(Context context, float pxValue) {
    method toSp (line 509) | public static int toSp(Context context, float pxValue) {
    method toGbk (line 516) | public static String toGbk(String str) {
    method toFileSizeString (line 525) | public static String toFileSizeString(long fileSize) {
    method toString (line 540) | public static String toString(InputStream is, String charset) {
    method toString (line 560) | public static String toString(InputStream is) {
    method toDarkenColor (line 564) | public static int toDarkenColor(@ColorInt int color) {
    method toDarkenColor (line 568) | public static int toDarkenColor(@ColorInt int color, @FloatRange(from ...
    method toColorString (line 578) | public static String toColorString(@ColorInt int color) {
    method toColorString (line 585) | public static String toColorString(@ColorInt int color, boolean includ...
    method toColorStateList (line 618) | public static ColorStateList toColorStateList(@ColorInt int normalColo...
    method toColorStateList (line 631) | public static ColorStateList toColorStateList(@ColorInt int normalColo...

FILE: filepicker/src/main/java/com/ess/filepicker/util/DateUtils.java
  class DateUtils (line 22) | public class DateUtils extends android.text.format.DateUtils {
    method calculateDifferentSecond (line 33) | public static long calculateDifferentSecond(Date startDate, Date endDa...
    method calculateDifferentMinute (line 37) | public static long calculateDifferentMinute(Date startDate, Date endDa...
    method calculateDifferentHour (line 41) | public static long calculateDifferentHour(Date startDate, Date endDate) {
    method calculateDifferentDay (line 45) | public static long calculateDifferentDay(Date startDate, Date endDate) {
    method calculateDifferentSecond (line 49) | public static long calculateDifferentSecond(long startTimeMillis, long...
    method calculateDifferentMinute (line 53) | public static long calculateDifferentMinute(long startTimeMillis, long...
    method calculateDifferentHour (line 57) | public static long calculateDifferentHour(long startTimeMillis, long e...
    method calculateDifferentDay (line 61) | public static long calculateDifferentDay(long startTimeMillis, long en...
    method calculateDifference (line 68) | public static long calculateDifference(long startTimeMillis, long endT...
    method calculateDifference (line 75) | public static long calculateDifference(Date startDate, Date endDate, @...
    method calculateDifference (line 88) | private static long[] calculateDifference(Date startDate, Date endDate) {
    method calculateDifference (line 92) | private static long[] calculateDifference(long differentMilliSeconds) {
    method calculateDaysInMonth (line 112) | public static int calculateDaysInMonth(int month) {
    method calculateDaysInMonth (line 119) | public static int calculateDaysInMonth(int year, int month) {
    method fillZero (line 146) | @NonNull
    method trimZero (line 156) | public static int trimZero(@NonNull String text) {
    method isSameDay (line 175) | public static boolean isSameDay(Date date) {
    method parseDate (line 194) | public static Date parseDate(String dateStr, String dataFormat) {
    method parseDate (line 211) | public static Date parseDate(String dateStr) {
    method getFileLastModifyTime (line 215) | public static String getFileLastModifyTime(long time) {
    method formatDate (line 223) | public static String formatDate(Date date, String format) {
    method formatDate (line 231) | public static String formatDate(String format) {

FILE: filepicker/src/main/java/com/ess/filepicker/util/DialogUtil.java
  class DialogUtil (line 14) | public class DialogUtil {
    method showPermissionDialog (line 19) | public static void showPermissionDialog(final Activity mActivity, Stri...

FILE: filepicker/src/main/java/com/ess/filepicker/util/FileSizeUtil.java
  class FileSizeUtil (line 12) | public class FileSizeUtil {
    method getFileOrFilesSize (line 27) | public static double getFileOrFilesSize(String filePath, int sizeType) {
    method getAutoFileOrFilesSize (line 47) | public static String getAutoFileOrFilesSize(File file) {
    method getFileSize (line 68) | private static long getFileSize(File file) throws Exception {
    method getFileSizes (line 87) | private static long getFileSizes(File f) throws Exception {
    method FormetFileSize (line 106) | private static String FormetFileSize(long fileS) {
    method FormetFileSize (line 132) | private static double FormetFileSize(long fileS, int sizeType) {

FILE: filepicker/src/main/java/com/ess/filepicker/util/FileUtils.java
  class FileUtils (line 45) | public final class FileUtils {
    method separator (line 72) | public static String separator(String path) {
    method getBreadModeListFromPath (line 88) | public static List<BreadModel> getBreadModeListFromPath(List<String> m...
    method getBreadModelListByPosition (line 120) | public static String getBreadModelListByPosition(List<String> mSdCardL...
    method getChangeSdCard (line 144) | public static String getChangeSdCard(String sdCardName,List<String> mS...
    method canBackParent (line 160) | public static boolean canBackParent(String curFolder, List<String> sdC...
    method closeSilently (line 171) | public static void closeSilently(Closeable c) {
    method listDirs (line 185) | public static File[] listDirs(String startDirPath, String[] excludeDir...
    method listDirs (line 242) | public static File[] listDirs(String startDirPath, String[] excludeDir...
    method listDirs (line 249) | public static File[] listDirs(String startDirPath) {
    method listDirsAndFiles (line 256) | public static File[] listDirsAndFiles(String startDirPath, String[] al...
    method listDirsAndFiles (line 276) | public static File[] listDirsAndFiles(String startDirPath) {
    method listFiles (line 283) | public static File[] listFiles(String startDirPath, final Pattern filt...
    method listFiles (line 338) | public static File[] listFiles(String startDirPath, Pattern filterPatt...
    method listFiles (line 345) | public static File[] listFiles(String startDirPath) {
    method listFiles (line 352) | public static File[] listFiles(String startDirPath, final String[] all...
    method listFiles (line 370) | public static File[] listFiles(String startDirPath, String allowExtens...
    method exist (line 377) | public static boolean exist(String path) {
    method delete (line 385) | public static boolean delete(File file, boolean deleteRootDir) {
    method deleteResolveEBUSY (line 416) | private static boolean deleteResolveEBUSY(File file) {
    method delete (line 427) | public static boolean delete(String path, boolean deleteRootDir) {
    method delete (line 439) | public static boolean delete(String path) {
    method delete (line 446) | public static boolean delete(File file) {
    method copy (line 453) | public static boolean copy(String src, String tar) {
    method copy (line 461) | public static boolean copy(File src, File tar) {
    method move (line 498) | public static boolean move(String src, String tar) {
    method move (line 505) | public static boolean move(File src, File tar) {
    method rename (line 512) | public static boolean rename(String oldPath, String newPath) {
    method rename (line 519) | public static boolean rename(File src, File tar) {
    method readText (line 527) | public static String readText(String filepath, String charset) {
    method readText (line 543) | public static String readText(String filepath) {
    method readBytes (line 550) | public static byte[] readBytes(String filepath) {
    method writeText (line 579) | public static boolean writeText(String filepath, String content, Strin...
    method writeText (line 592) | public static boolean writeText(String filepath, String content) {
    method writeBytes (line 599) | public static boolean writeBytes(String filepath, byte[] data) {
    method appendText (line 624) | public static boolean appendText(String path, String content) {
    method getLength (line 647) | public static long getLength(String path) {
    method getName (line 658) | public static String getName(String pathOrUrl) {
    method getNameExcludeExtension (line 673) | public static String getNameExcludeExtension(String path) {
    method getSize (line 690) | public static String getSize(String path) {
    method getExtension (line 698) | public static String getExtension(String pathOrUrl) {
    method getMimeType (line 710) | public static String getMimeType(String pathOrUrl) {
    method getDateTime (line 725) | public static String getDateTime(String path) {
    method getDateTime (line 732) | public static String getDateTime(String path, String format) {
    method getDateTime (line 740) | public static String getDateTime(File file, String format) {
    method compareLastModified (line 749) | public static int compareLastModified(String path1, String path2) {
    method makeDirs (line 764) | public static boolean makeDirs(String path) {
    method makeDirs (line 771) | public static boolean makeDirs(File file) {
    class SortByExtension (line 775) | public static class SortByExtension implements Comparator<File> {
      method SortByExtension (line 777) | public SortByExtension() {
      method compare (line 781) | public int compare(File f1, File f2) {
    class SortByName (line 801) | public static class SortByName implements Comparator<File> {
      method SortByName (line 804) | public SortByName(boolean caseSensitive) {
      method SortByName (line 808) | public SortByName() {
      method compare (line 812) | public int compare(File f1, File f2) {
    class SortBySize (line 838) | public static class SortBySize implements Comparator<File> {
      method SortBySize (line 840) | public SortBySize() {
      method compare (line 844) | public int compare(File f1, File f2) {
    class SortByTime (line 868) | public static class SortByTime implements Comparator<File> {
      method SortByTime (line 870) | public SortByTime() {
      method compare (line 874) | public int compare(File f1, File f2) {
    method getAllSdPaths (line 904) | public static List<String> getAllSdPaths(Context context) {
    method getAllSdCardList (line 929) | public static List<String> getAllSdCardList(List<String> sdCardList) {

FILE: filepicker/src/main/java/com/ess/filepicker/util/LogUtils.java
  class LogUtils (line 21) | public final class LogUtils {
    method setIsDebug (line 28) | public static void setIsDebug(boolean isDebug) {
    method isDebug (line 32) | public static boolean isDebug() {
    method setDebugTag (line 36) | public static void setDebugTag(String debugTag) {
    method getDebugTag (line 40) | public static String getDebugTag() {
    method verbose (line 49) | public static void verbose(String message) {
    method verbose (line 59) | public static void verbose(Object object, String message) {
    method verbose (line 69) | public static void verbose(String tag, String msg) {
    method debug (line 82) | public static void debug(String message) {
    method debug (line 92) | public static void debug(Object object, String message) {
    method debug (line 102) | public static void debug(String tag, String msg) {
    method warn (line 115) | public static void warn(Throwable e) {
    method warn (line 124) | public static void warn(String message) {
    method warn (line 134) | public static void warn(Object object, String message) {
    method warn (line 144) | public static void warn(Object object, Throwable e) {
    method warn (line 154) | public static void warn(String tag, String msg) {
    method error (line 167) | public static void error(Throwable e) {
    method error (line 176) | public static void error(String message) {
    method error (line 186) | public static void error(Object object, String message) {
    method error (line 196) | public static void error(Object object, Throwable e) {
    method error (line 206) | public static void error(String tag, String msg) {
    method startMethodTracing (line 219) | public static void startMethodTracing() {
    method stopMethodTracing (line 228) | public static void stopMethodTracing() {
    method toStackTraceString (line 242) | public static String toStackTraceString(Throwable throwable) {
    method getTraceElement (line 263) | private static String getTraceElement() {
    method _getStackOffset (line 307) | private static int _getStackOffset(StackTraceElement[] trace) {
    method _getSimpleClassName (line 318) | private static String _getSimpleClassName(String name) {

FILE: filepicker/src/main/java/com/ess/filepicker/util/MediaStoreCompat.java
  class MediaStoreCompat (line 42) | public class MediaStoreCompat {
    method MediaStoreCompat (line 50) | public MediaStoreCompat(Activity activity) {
    method MediaStoreCompat (line 55) | public MediaStoreCompat(Activity activity, Fragment fragment) {
    method hasCameraFeature (line 66) | public static boolean hasCameraFeature(Context context) {
    method setCaptureStrategy (line 71) | public void setCaptureStrategy(CaptureStrategy strategy) {
    method dispatchCaptureIntent (line 75) | public void dispatchCaptureIntent(Context context, int requestCode) {
    method createImageFile (line 109) | private File createImageFile() throws IOException {
    method getCurrentPhotoUri (line 133) | public Uri getCurrentPhotoUri() {
    method getCurrentPhotoPath (line 137) | public String getCurrentPhotoPath() {

FILE: filepicker/src/main/java/com/ess/filepicker/util/MimeType.java
  type MimeType (line 38) | @SuppressWarnings("unused")
    method MimeType (line 95) | MimeType(String mimeTypeName, Set<String> extensions) {
    method ofAll (line 100) | public static Set<MimeType> ofAll() {
    method of (line 104) | public static Set<MimeType> of(MimeType type, MimeType... rest) {
    method ofImage (line 108) | public static Set<MimeType> ofImage() {
    method ofVideo (line 112) | public static Set<MimeType> ofVideo() {
    method arraySetOf (line 116) | private static Set<String> arraySetOf(String... suffixes) {
    method toString (line 120) | @Override
    method checkType (line 125) | public boolean checkType(ContentResolver resolver, Uri uri) {

FILE: filepicker/src/main/java/com/ess/filepicker/util/PathUtils.java
  class PathUtils (line 17) | public class PathUtils {
    method getPath (line 27) | @TargetApi(Build.VERSION_CODES.KITKAT)
    method getDataColumn (line 89) | public static String getDataColumn(Context context, Uri uri, String se...
    method isExternalStorageDocument (line 116) | public static boolean isExternalStorageDocument(Uri uri) {
    method isDownloadsDocument (line 124) | public static boolean isDownloadsDocument(Uri uri) {
    method isMediaDocument (line 132) | public static boolean isMediaDocument(Uri uri) {

FILE: filepicker/src/main/java/com/ess/filepicker/util/PhotoMetadataUtils.java
  class PhotoMetadataUtils (line 31) | public final class PhotoMetadataUtils {
    method PhotoMetadataUtils (line 36) | private PhotoMetadataUtils() {
    method getPixelsCount (line 40) | public static int getPixelsCount(ContentResolver resolver, Uri uri) {
    method getBitmapBound (line 45) | public static Point getBitmapBound(ContentResolver resolver, Uri uri) {
    method getPath (line 68) | public static String getPath(ContentResolver resolver, Uri uri) {
    method getSizeInMB (line 91) | public static float getSizeInMB(long sizeInBytes) {

FILE: filepicker/src/main/java/com/ess/filepicker/util/Platform.java
  class Platform (line 8) | public class Platform {
    method hasICS (line 9) | public static boolean hasICS() {
    method hasKitKat (line 13) | public static boolean hasKitKat() {

FILE: filepicker/src/main/java/com/ess/filepicker/util/UiUtils.java
  class UiUtils (line 14) | public class UiUtils {
    method dpToPx (line 22) | public static int dpToPx(Context c, float dipValue) {
    method getImageResize (line 27) | public static int getImageResize(Context context,RecyclerView recycler...

FILE: filepicker/src/main/java/com/ess/filepicker/widget/MediaItemDecoration.java
  class MediaItemDecoration (line 16) | public class MediaItemDecoration extends RecyclerView.ItemDecoration {
    method getSpanCount (line 18) | private int getSpanCount(RecyclerView parent) {
    method getItemOffsets (line 32) | @Override
    method isLastColum (line 48) | private boolean isLastColum(RecyclerView parent, int pos, int spanCount,
    method isLastRaw (line 73) | private boolean isLastRaw(RecyclerView parent, int pos, int spanCount,

FILE: filepicker/src/main/java/com/ess/filepicker/widget/ToolbarSpinner.java
  class ToolbarSpinner (line 34) | public class ToolbarSpinner {
    method ToolbarSpinner (line 42) | public ToolbarSpinner(@NonNull Context context) {
    method setOnItemSelectedListener (line 62) | public void setOnItemSelectedListener(AdapterView.OnItemSelectedListen...
    method setSelection (line 66) | public void setSelection(Context context, int position) {
    method onItemSelected (line 71) | private void onItemSelected(Context context, int position) {
    method setAdapter (line 94) | public void setAdapter(CursorAdapter adapter) {
    method setSelectedTextView (line 99) | public void setSelectedTextView(TextView textView) {
    method setPopupAnchorView (line 125) | public void setPopupAnchorView(View view) {

FILE: filepicker/src/test/java/com/ess/filepicker/ExampleUnitTest.java
  class ExampleUnitTest (line 12) | public class ExampleUnitTest {
    method addition_isCorrect (line 13) | @Test
Condensed preview — 129 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (344K chars).
[
  {
    "path": ".gitignore",
    "chars": 146,
    "preview": ".gradle\n/local.properties\n/.idea/workspace.xml\n/.idea/libraries\n.DS_Store\n/build\n/captures\n.externalNativeBuild\nbintrayK"
  },
  {
    "path": ".idea/codeStyles/Project.xml",
    "chars": 1775,
    "preview": "<component name=\"ProjectCodeStyleConfiguration\">\n  <code_scheme name=\"Project\" version=\"173\">\n    <Objective-C-extension"
  },
  {
    "path": ".idea/copyright/Ess.xml",
    "chars": 118,
    "preview": "<component name=\"CopyrightManager\">\n  <copyright>\n    <option name=\"myName\" value=\"Ess\" />\n  </copyright>\n</component>"
  },
  {
    "path": ".idea/gradle.xml",
    "chars": 682,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"GradleSettings\">\n    <option name=\"linke"
  },
  {
    "path": ".idea/misc.xml",
    "chars": 1522,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"NullableNotNullManager\">\n    <option nam"
  },
  {
    "path": ".idea/modules.xml",
    "chars": 482,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"ProjectModuleManager\">\n    <modules>\n   "
  },
  {
    "path": ".idea/runConfigurations.xml",
    "chars": 564,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"RunConfigurationProducerService\">\n    <o"
  },
  {
    "path": ".idea/vcs.xml",
    "chars": 180,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"VcsDirectoryMappings\">\n    <mapping dire"
  },
  {
    "path": "LICENSE",
    "chars": 1059,
    "preview": "MIT License\n\nCopyright (c) 2018 aj\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this"
  },
  {
    "path": "README.md",
    "chars": 5761,
    "preview": "### 介绍\n\n# 由于暂时没有更多的精力在此项目上,现将此项目转让给其他人,谁来认领一下,一起把这个库搞下去,加我微信bo_744172447,谢谢!\n\n---\n\n1. 可在文件浏览器中选择指定后缀名文件\n2. 可通过扫描全盘的方式,选择"
  },
  {
    "path": "app/.gitignore",
    "chars": 7,
    "preview": "/build\n"
  },
  {
    "path": "app/build.gradle",
    "chars": 2037,
    "preview": "apply plugin: 'com.android.application'\n\nandroid {\n    compileSdkVersion 27\n    defaultConfig {\n        applicationId \"c"
  },
  {
    "path": "app/proguard-rules.pro",
    "chars": 751,
    "preview": "# Add project specific ProGuard rules here.\n# You can control the set of applied configuration files using the\n# proguar"
  },
  {
    "path": "app/src/androidTest/java/com/ess/essfilepicker/ExampleInstrumentedTest.java",
    "chars": 746,
    "preview": "package com.ess.essfilepicker;\n\nimport android.content.Context;\nimport android.support.test.InstrumentationRegistry;\nimp"
  },
  {
    "path": "app/src/main/AndroidManifest.xml",
    "chars": 819,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    package="
  },
  {
    "path": "app/src/main/java/com/ess/essfilepicker/FragmentTestActivity.java",
    "chars": 823,
    "preview": "package com.ess.essfilepicker;\n\nimport android.support.v4.app.FragmentTransaction;\nimport android.support.v7.app.AppComp"
  },
  {
    "path": "app/src/main/java/com/ess/essfilepicker/LApplication.java",
    "chars": 721,
    "preview": "/*\n * Copyright (c) 2018. Lorem ipsum dolor sit amet, consectetur adipiscing elit.\n * Morbi non lorem porttitor neque fe"
  },
  {
    "path": "app/src/main/java/com/ess/essfilepicker/MainActivity.java",
    "chars": 4029,
    "preview": "package com.ess.essfilepicker;\n\nimport android.content.Intent;\nimport android.support.v4.app.Fragment;\nimport android.su"
  },
  {
    "path": "app/src/main/java/com/ess/essfilepicker/TestFragment.java",
    "chars": 3264,
    "preview": "package com.ess.essfilepicker;\n\n\nimport android.content.Intent;\nimport android.os.Bundle;\nimport android.support.annotat"
  },
  {
    "path": "app/src/main/res/drawable/ic_launcher_background.xml",
    "chars": 5606,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:wi"
  },
  {
    "path": "app/src/main/res/drawable-v24/ic_launcher_foreground.xml",
    "chars": 1880,
    "preview": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:aapt=\"http://schemas.android.com/aapt\"\n    "
  },
  {
    "path": "app/src/main/res/layout/activity_fragment_test.xml",
    "chars": 354,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<FrameLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    andro"
  },
  {
    "path": "app/src/main/res/layout/activity_main.xml",
    "chars": 1541,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    andr"
  },
  {
    "path": "app/src/main/res/layout/fragment_test.xml",
    "chars": 1162,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    andr"
  },
  {
    "path": "app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml",
    "chars": 272,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<adaptive-icon xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <b"
  },
  {
    "path": "app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml",
    "chars": 272,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<adaptive-icon xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <b"
  },
  {
    "path": "app/src/main/res/values/colors.xml",
    "chars": 208,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <color name=\"colorPrimary\">#1bbc9b</color>\n    <color name=\"color"
  },
  {
    "path": "app/src/main/res/values/strings.xml",
    "chars": 242,
    "preview": "<resources>\n    <string name=\"app_name\">文件浏览</string>\n\n    <!-- TODO: Remove or change this placeholder text -->\n    <st"
  },
  {
    "path": "app/src/main/res/values/styles.xml",
    "chars": 873,
    "preview": "<resources xmlns:tools=\"http://schemas.android.com/tools\">\n\n    <!-- Base application theme. -->\n    <style name=\"AppThe"
  },
  {
    "path": "app/src/test/java/com/ess/essfilepicker/ExampleUnitTest.java",
    "chars": 399,
    "preview": "package com.ess.essfilepicker;\n\nimport org.junit.Test;\n\nimport static org.junit.Assert.*;\n\n/**\n * Example local unit tes"
  },
  {
    "path": "build.gradle",
    "chars": 1115,
    "preview": "// Top-level build file where you can add configuration options common to all sub-projects/modules.\n\nbuildscript {\n    \n"
  },
  {
    "path": "filepicker/.gitignore",
    "chars": 7,
    "preview": "/build\n"
  },
  {
    "path": "filepicker/build.gradle",
    "chars": 1483,
    "preview": "apply plugin: 'com.android.library'\napply plugin: 'com.novoda.bintray-release'\n\nandroid {\n    compileSdkVersion 27\n\n    "
  },
  {
    "path": "filepicker/proguard-rules.pro",
    "chars": 751,
    "preview": "# Add project specific ProGuard rules here.\n# You can control the set of applied configuration files using the\n# proguar"
  },
  {
    "path": "filepicker/src/androidTest/java/com/ess/filepicker/ExampleInstrumentedTest.java",
    "chars": 745,
    "preview": "package com.ess.filepicker;\n\nimport android.content.Context;\nimport android.support.test.InstrumentationRegistry;\nimport"
  },
  {
    "path": "filepicker/src/main/AndroidManifest.xml",
    "chars": 1115,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    package="
  },
  {
    "path": "filepicker/src/main/java/com/ess/filepicker/BaseFileFragment.java",
    "chars": 3261,
    "preview": "package com.ess.filepicker;\n\nimport android.app.Activity;\nimport android.content.Context;\nimport android.os.Bundle;\nimpo"
  },
  {
    "path": "filepicker/src/main/java/com/ess/filepicker/FilePicker.java",
    "chars": 1448,
    "preview": "package com.ess.filepicker;\n\nimport android.app.Activity;\nimport android.support.v4.app.Fragment;\n\nimport java.lang.ref."
  },
  {
    "path": "filepicker/src/main/java/com/ess/filepicker/SelectCreator.java",
    "chars": 3604,
    "preview": "package com.ess.filepicker;\n\nimport android.app.Activity;\nimport android.content.Intent;\nimport android.graphics.drawabl"
  },
  {
    "path": "filepicker/src/main/java/com/ess/filepicker/SelectOptions.java",
    "chars": 2618,
    "preview": "package com.ess.filepicker;\n\nimport android.graphics.drawable.Drawable;\nimport android.os.Environment;\nimport android.te"
  },
  {
    "path": "filepicker/src/main/java/com/ess/filepicker/activity/FileTypeListFragment.java",
    "chars": 6962,
    "preview": "package com.ess.filepicker.activity;\n\n\nimport android.os.Bundle;\nimport android.support.design.widget.Snackbar;\nimport a"
  },
  {
    "path": "filepicker/src/main/java/com/ess/filepicker/activity/PicturesViewActivity.java",
    "chars": 640,
    "preview": "package com.ess.filepicker.activity;\n\nimport android.support.v7.app.AppCompatActivity;\nimport android.os.Bundle;\n\nimport"
  },
  {
    "path": "filepicker/src/main/java/com/ess/filepicker/activity/SelectFileByBrowserActivity.java",
    "chars": 17070,
    "preview": "package com.ess.filepicker.activity;\n\nimport android.content.DialogInterface;\nimport android.content.Intent;\nimport andr"
  },
  {
    "path": "filepicker/src/main/java/com/ess/filepicker/activity/SelectFileByScanActivity.java",
    "chars": 8502,
    "preview": "package com.ess.filepicker.activity;\n\nimport android.content.DialogInterface;\nimport android.content.Intent;\nimport andr"
  },
  {
    "path": "filepicker/src/main/java/com/ess/filepicker/activity/SelectPictureActivity.java",
    "chars": 10768,
    "preview": "package com.ess.filepicker.activity;\n\nimport android.content.Intent;\nimport android.content.res.TypedArray;\nimport andro"
  },
  {
    "path": "filepicker/src/main/java/com/ess/filepicker/adapter/BreadAdapter.java",
    "chars": 733,
    "preview": "package com.ess.filepicker.adapter;\n\n\nimport android.support.annotation.Nullable;\n\nimport com.chad.library.adapter.base."
  },
  {
    "path": "filepicker/src/main/java/com/ess/filepicker/adapter/BuketAdapter.java",
    "chars": 1886,
    "preview": "package com.ess.filepicker.adapter;\n\nimport android.content.Context;\nimport android.content.res.TypedArray;\nimport andro"
  },
  {
    "path": "filepicker/src/main/java/com/ess/filepicker/adapter/EssMediaAdapter.java",
    "chars": 2796,
    "preview": "package com.ess.filepicker.adapter;\n\nimport android.support.annotation.Nullable;\nimport android.support.v7.widget.AppCom"
  },
  {
    "path": "filepicker/src/main/java/com/ess/filepicker/adapter/FileListAdapter.java",
    "chars": 5090,
    "preview": "package com.ess.filepicker.adapter;\n\nimport android.support.annotation.Nullable;\nimport android.widget.ImageView;\nimport"
  },
  {
    "path": "filepicker/src/main/java/com/ess/filepicker/adapter/FragmentPagerAdapter.java",
    "chars": 2077,
    "preview": "package com.ess.filepicker.adapter;\n\nimport android.support.v4.app.Fragment;\nimport android.support.v4.app.FragmentManag"
  },
  {
    "path": "filepicker/src/main/java/com/ess/filepicker/adapter/OnFileSelectListener.java",
    "chars": 257,
    "preview": "package com.ess.filepicker.adapter;\n\nimport com.ess.filepicker.model.EssFile;\n\nimport java.util.List;\n\n/**\n * OnFileSele"
  },
  {
    "path": "filepicker/src/main/java/com/ess/filepicker/adapter/SelectSdcardAdapter.java",
    "chars": 650,
    "preview": "package com.ess.filepicker.adapter;\n\nimport android.support.annotation.Nullable;\n\nimport com.chad.library.adapter.base.B"
  },
  {
    "path": "filepicker/src/main/java/com/ess/filepicker/loader/EssAlbumCollection.java",
    "chars": 2568,
    "preview": "/*\n * Copyright (C) 2014 nohana, Inc.\n * Copyright 2017 Zhihu Inc.\n *\n * Licensed under the Apache License, Version 2.0 "
  },
  {
    "path": "filepicker/src/main/java/com/ess/filepicker/loader/EssAlbumLoader.java",
    "chars": 4031,
    "preview": "package com.ess.filepicker.loader;\n\nimport android.content.Context;\nimport android.database.Cursor;\nimport android.datab"
  },
  {
    "path": "filepicker/src/main/java/com/ess/filepicker/loader/EssMediaCollection.java",
    "chars": 4243,
    "preview": "package com.ess.filepicker.loader;\n\nimport android.content.Context;\nimport android.database.Cursor;\nimport android.os.Bu"
  },
  {
    "path": "filepicker/src/main/java/com/ess/filepicker/loader/EssMediaLoader.java",
    "chars": 5948,
    "preview": "package com.ess.filepicker.loader;\n\nimport android.content.Context;\nimport android.database.Cursor;\nimport android.datab"
  },
  {
    "path": "filepicker/src/main/java/com/ess/filepicker/loader/EssMimeTypeCollection.java",
    "chars": 3269,
    "preview": "/*\n * Copyright (C) 2014 nohana, Inc.\n * Copyright 2017 Zhihu Inc.\n *\n * Licensed under the Apache License, Version 2.0 "
  },
  {
    "path": "filepicker/src/main/java/com/ess/filepicker/loader/EssMimeTypeLoader.java",
    "chars": 4804,
    "preview": "package com.ess.filepicker.loader;\n\nimport android.content.Context;\nimport android.database.Cursor;\nimport android.net.U"
  },
  {
    "path": "filepicker/src/main/java/com/ess/filepicker/model/Album.java",
    "chars": 3347,
    "preview": "/*\n * Copyright (C) 2014 nohana, Inc.\n * Copyright 2017 Zhihu Inc.\n *\n * Licensed under the Apache License, Version 2.0 "
  },
  {
    "path": "filepicker/src/main/java/com/ess/filepicker/model/BreadModel.java",
    "chars": 2070,
    "preview": "package com.ess.filepicker.model;\n\n\nimport java.util.ArrayList;\nimport java.util.List;\n\n/**\n * BreadModel\n * Created by "
  },
  {
    "path": "filepicker/src/main/java/com/ess/filepicker/model/CaptureStrategy.java",
    "chars": 876,
    "preview": "/*\n * Copyright 2017 Zhihu Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use"
  },
  {
    "path": "filepicker/src/main/java/com/ess/filepicker/model/EssFile.java",
    "chars": 8031,
    "preview": "package com.ess.filepicker.model;\n\nimport android.content.ContentUris;\nimport android.content.Context;\nimport android.ne"
  },
  {
    "path": "filepicker/src/main/java/com/ess/filepicker/model/EssFileCountCallBack.java",
    "chars": 242,
    "preview": "package com.ess.filepicker.model;\n\n/**\n * EssFileCountCallBack\n * Created by 李波 on 2018/3/5.\n */\n\npublic interface EssFi"
  },
  {
    "path": "filepicker/src/main/java/com/ess/filepicker/model/EssFileFilter.java",
    "chars": 951,
    "preview": "package com.ess.filepicker.model;\n\nimport java.io.File;\nimport java.io.FileFilter;\n\n/**\n * EssFileFilter\n * 不显示隐藏文件、文件夹\n"
  },
  {
    "path": "filepicker/src/main/java/com/ess/filepicker/model/EssFileListCallBack.java",
    "chars": 232,
    "preview": "package com.ess.filepicker.model;\n\nimport java.util.List;\n\n/**\n * EssFileListCallBack\n * Created by 李波 on 2018/3/5.\n */\n"
  },
  {
    "path": "filepicker/src/main/java/com/ess/filepicker/model/EssFileProvider.java",
    "chars": 197,
    "preview": "package com.ess.filepicker.model;\n\nimport android.support.v4.content.FileProvider;\n\n/**\n * EssFileProvider\n * Created by"
  },
  {
    "path": "filepicker/src/main/java/com/ess/filepicker/model/FileScanActEvent.java",
    "chars": 478,
    "preview": "package com.ess.filepicker.model;\n\n/**\n * FileScanActEvent\n * Created by 李波 on 2018/2/23.\n */\n\npublic class FileScanActE"
  },
  {
    "path": "filepicker/src/main/java/com/ess/filepicker/model/FileScanFragEvent.java",
    "chars": 839,
    "preview": "package com.ess.filepicker.model;\n\n\n/**\n * FileScanFragEvent\n * Created by 李波 on 2018/2/23.\n */\n\npublic class FileScanFr"
  },
  {
    "path": "filepicker/src/main/java/com/ess/filepicker/model/FileScanSortChangedEvent.java",
    "chars": 757,
    "preview": "package com.ess.filepicker.model;\n\n/**\n * FileScanSortChangedEvent\n * Created by 李波 on 2018/2/26.\n */\n\npublic class File"
  },
  {
    "path": "filepicker/src/main/java/com/ess/filepicker/task/EssFileCountTask.java",
    "chars": 1667,
    "preview": "package com.ess.filepicker.task;\n\nimport android.os.AsyncTask;\n\nimport com.ess.filepicker.model.EssFile;\nimport com.ess."
  },
  {
    "path": "filepicker/src/main/java/com/ess/filepicker/task/EssFileListTask.java",
    "chars": 3237,
    "preview": "package com.ess.filepicker.task;\n\nimport android.os.AsyncTask;\n\nimport com.ess.filepicker.model.EssFile;\nimport com.ess."
  },
  {
    "path": "filepicker/src/main/java/com/ess/filepicker/util/Const.java",
    "chars": 4324,
    "preview": "package com.ess.filepicker.util;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\n/**\n * Const\n * Created by 李波 on 2018"
  },
  {
    "path": "filepicker/src/main/java/com/ess/filepicker/util/ConvertUtils.java",
    "chars": 22133,
    "preview": "package com.ess.filepicker.util;\n\nimport android.annotation.TargetApi;\nimport android.content.ContentUris;\nimport androi"
  },
  {
    "path": "filepicker/src/main/java/com/ess/filepicker/util/DateUtils.java",
    "chars": 7770,
    "preview": "package com.ess.filepicker.util;\n\nimport android.support.annotation.IntDef;\nimport android.support.annotation.NonNull;\n\n"
  },
  {
    "path": "filepicker/src/main/java/com/ess/filepicker/util/DialogUtil.java",
    "chars": 1292,
    "preview": "package com.ess.filepicker.util;\n\nimport android.app.Activity;\nimport android.content.DialogInterface;\nimport android.co"
  },
  {
    "path": "filepicker/src/main/java/com/ess/filepicker/util/FileSizeUtil.java",
    "chars": 4252,
    "preview": "package com.ess.filepicker.util;\n\nimport java.io.File;\nimport java.io.FileInputStream;\nimport java.text.DecimalFormat;\n\n"
  },
  {
    "path": "filepicker/src/main/java/com/ess/filepicker/util/FileUtils.java",
    "chars": 28259,
    "preview": "package com.ess.filepicker.util;\n\nimport android.content.Context;\nimport android.os.Environment;\nimport android.os.stora"
  },
  {
    "path": "filepicker/src/main/java/com/ess/filepicker/util/LogUtils.java",
    "chars": 8863,
    "preview": "package com.ess.filepicker.util;\n\nimport android.os.Debug;\nimport android.os.Environment;\nimport android.util.Log;\n\nimpo"
  },
  {
    "path": "filepicker/src/main/java/com/ess/filepicker/util/MediaStoreCompat.java",
    "chars": 5327,
    "preview": "/*\n * Copyright 2017 Zhihu Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use"
  },
  {
    "path": "filepicker/src/main/java/com/ess/filepicker/util/MimeType.java",
    "chars": 4251,
    "preview": "/*\n * Copyright (C) 2014 nohana, Inc.\n * Copyright 2017 Zhihu Inc.\n *\n * Licensed under the Apache License, Version 2.0 "
  },
  {
    "path": "filepicker/src/main/java/com/ess/filepicker/util/PathUtils.java",
    "chars": 5067,
    "preview": "package com.ess.filepicker.util;\n\nimport android.annotation.TargetApi;\nimport android.content.ContentUris;\nimport androi"
  },
  {
    "path": "filepicker/src/main/java/com/ess/filepicker/util/PhotoMetadataUtils.java",
    "chars": 3258,
    "preview": "/*\n * Copyright (C) 2014 nohana, Inc.\n * Copyright 2017 Zhihu Inc.\n *\n * Licensed under the Apache License, Version 2.0 "
  },
  {
    "path": "filepicker/src/main/java/com/ess/filepicker/util/Platform.java",
    "chars": 357,
    "preview": "package com.ess.filepicker.util;\n\nimport android.os.Build;\n\n/**\n * @author JoongWon Baik\n */\npublic class Platform {\n   "
  },
  {
    "path": "filepicker/src/main/java/com/ess/filepicker/util/UiUtils.java",
    "chars": 1040,
    "preview": "package com.ess.filepicker.util;\n\nimport android.content.Context;\nimport android.support.v7.widget.GridLayoutManager;\nim"
  },
  {
    "path": "filepicker/src/main/java/com/ess/filepicker/widget/MediaItemDecoration.java",
    "chars": 3795,
    "preview": "package com.ess.filepicker.widget;\n\nimport android.graphics.Rect;\nimport android.support.v7.widget.GridLayoutManager;\nim"
  },
  {
    "path": "filepicker/src/main/java/com/ess/filepicker/widget/ToolbarSpinner.java",
    "chars": 4954,
    "preview": "/*\n * Copyright 2017 Zhihu Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use"
  },
  {
    "path": "filepicker/src/main/res/color/dracula_bottom_toolbar_apply.xml",
    "chars": 884,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n  Copyright 2017 Zhihu Inc.\n\n  Licensed under the Apache License, Version 2."
  },
  {
    "path": "filepicker/src/main/res/color/dracula_bottom_toolbar_preview.xml",
    "chars": 888,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n  Copyright 2017 Zhihu Inc.\n\n  Licensed under the Apache License, Version 2."
  },
  {
    "path": "filepicker/src/main/res/color/dracula_preview_bottom_toolbar_apply.xml",
    "chars": 900,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n  Copyright 2017 Zhihu Inc.\n\n  Licensed under the Apache License, Version 2."
  },
  {
    "path": "filepicker/src/main/res/color/elec_bottom_toolbar_apply.xml",
    "chars": 878,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n  Copyright 2017 Zhihu Inc.\n\n  Licensed under the Apache License, Version 2."
  },
  {
    "path": "filepicker/src/main/res/color/elec_bottom_toolbar_preview.xml",
    "chars": 882,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n  Copyright 2017 Zhihu Inc.\n\n  Licensed under the Apache License, Version 2."
  },
  {
    "path": "filepicker/src/main/res/color/elec_preview_bottom_toolbar_apply.xml",
    "chars": 895,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n  Copyright 2017 Zhihu Inc.\n\n  Licensed under the Apache License, Version 2."
  },
  {
    "path": "filepicker/src/main/res/drawable/bg_bottom_line_gray.xml",
    "chars": 355,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<layer-list xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <item"
  },
  {
    "path": "filepicker/src/main/res/layout/activity_pictures_detail.xml",
    "chars": 449,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<android.support.constraint.ConstraintLayout xmlns:android=\"http://schemas.androi"
  },
  {
    "path": "filepicker/src/main/res/layout/activity_select_file.xml",
    "chars": 2360,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<android.support.design.widget.CoordinatorLayout xmlns:android=\"http://schemas.an"
  },
  {
    "path": "filepicker/src/main/res/layout/activity_select_file_by_scan.xml",
    "chars": 1597,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<android.support.design.widget.CoordinatorLayout xmlns:android=\"http://schemas.an"
  },
  {
    "path": "filepicker/src/main/res/layout/activity_select_picture.xml",
    "chars": 1846,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<android.support.design.widget.CoordinatorLayout xmlns:android=\"http://schemas.an"
  },
  {
    "path": "filepicker/src/main/res/layout/bread_item.xml",
    "chars": 1111,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    andr"
  },
  {
    "path": "filepicker/src/main/res/layout/buket_list_item.xml",
    "chars": 2176,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n  Copyright 2017 Zhihu Inc.\n\n  Licensed under the Apache License, Version 2."
  },
  {
    "path": "filepicker/src/main/res/layout/empty_file_list.xml",
    "chars": 533,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RelativeLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xm"
  },
  {
    "path": "filepicker/src/main/res/layout/ess_media_item.xml",
    "chars": 3165,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  Copyright 2017 Zhihu Inc.\n\n  Licensed under the Apache License, Version 2.0"
  },
  {
    "path": "filepicker/src/main/res/layout/fragment_file_type_list.xml",
    "chars": 509,
    "preview": "<FrameLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:tools=\"http://schemas.android.com/tool"
  },
  {
    "path": "filepicker/src/main/res/layout/item_capture.xml",
    "chars": 649,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<FrameLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    andro"
  },
  {
    "path": "filepicker/src/main/res/layout/item_file_list.xml",
    "chars": 2521,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    andr"
  },
  {
    "path": "filepicker/src/main/res/layout/item_select_sdcard.xml",
    "chars": 434,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<TextView xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:"
  },
  {
    "path": "filepicker/src/main/res/layout/loading_layout.xml",
    "chars": 1275,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<android.support.constraint.ConstraintLayout xmlns:android=\"http://schemas.androi"
  },
  {
    "path": "filepicker/src/main/res/layout/pop_select_sdcard.xml",
    "chars": 297,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n\n<android.support.v7.widget.RecyclerView xmlns:android=\"http://schemas.android.co"
  },
  {
    "path": "filepicker/src/main/res/layout-v21/activity_select_file.xml",
    "chars": 2370,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<android.support.design.widget.CoordinatorLayout xmlns:android=\"http://schemas.an"
  },
  {
    "path": "filepicker/src/main/res/layout-v21/bread_item.xml",
    "chars": 1131,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    andr"
  },
  {
    "path": "filepicker/src/main/res/menu/browse_menu.xml",
    "chars": 543,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<menu xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"h"
  },
  {
    "path": "filepicker/src/main/res/menu/media_menu.xml",
    "chars": 331,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<menu xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"h"
  },
  {
    "path": "filepicker/src/main/res/values/attrs.xml",
    "chars": 1847,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n  Copyright 2017 Zhihu Inc.\n\n  Licensed under the Apache License, Version 2."
  },
  {
    "path": "filepicker/src/main/res/values/colors.xml",
    "chars": 761,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n  Copyright 2017 Zhihu Inc.\n\n  Licensed under the Apache License, Version 2."
  },
  {
    "path": "filepicker/src/main/res/values/colors_dracula.xml",
    "chars": 1988,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n  Copyright 2017 Zhihu Inc.\n\n  Licensed under the Apache License, Version 2."
  },
  {
    "path": "filepicker/src/main/res/values/colors_zhihu.xml",
    "chars": 1919,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n  Copyright 2017 elec Inc.\n\n  Licensed under the Apache License, Version 2.0"
  },
  {
    "path": "filepicker/src/main/res/values/dimens.xml",
    "chars": 787,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n  Copyright 2017 Zhihu Inc.\n\n  Licensed under the Apache License, Version 2."
  },
  {
    "path": "filepicker/src/main/res/values/strings.xml",
    "chars": 709,
    "preview": "<resources>\n    <string name=\"app_name\">FilePicker</string>\n    <string name=\"folder_desc\">文件:%1$s&#160;&#160;|&#160;&#1"
  },
  {
    "path": "filepicker/src/main/res/values/styles.xml",
    "chars": 4441,
    "preview": "<resources xmlns:tools=\"http://schemas.android.com/tools\">\n\n\t<style name=\"OverflowButtonStyle\" parent=\"android:Widget.Ac"
  },
  {
    "path": "filepicker/src/main/res/values-v21/styles.xml",
    "chars": 326,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n\n    <style name=\"checkbox\" parent=\"Widget.AppCompat.CompoundButton.C"
  },
  {
    "path": "filepicker/src/main/res/xml/provider_paths.xml",
    "chars": 166,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<paths xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <external-"
  },
  {
    "path": "filepicker/src/test/java/com/ess/filepicker/ExampleUnitTest.java",
    "chars": 396,
    "preview": "package com.ess.filepicker;\n\nimport org.junit.Test;\n\nimport static org.junit.Assert.*;\n\n/**\n * Example local unit test, "
  },
  {
    "path": "gradle/wrapper/gradle-wrapper.properties",
    "chars": 230,
    "preview": "#Mon Apr 16 15:31:49 CST 2018\ndistributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\nzipStoreBase=GRADLE_USER_"
  },
  {
    "path": "gradlew",
    "chars": 4971,
    "preview": "#!/usr/bin/env bash\n\n##############################################################################\n##\n##  Gradle start "
  },
  {
    "path": "gradlew.bat",
    "chars": 2314,
    "preview": "@if \"%DEBUG%\" == \"\" @echo off\n@rem ##########################################################################\n@rem\n@rem "
  },
  {
    "path": "settings.gradle",
    "chars": 30,
    "preview": "include ':app', ':filepicker'\n"
  }
]

// ... and 4 more files (download for full content)

About this extraction

This page contains the full source code of the imLibo/FilePicker GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 129 files (307.1 KB), approximately 77.0k tokens, and a symbol index with 532 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!