Android File Picker built for modern storage.
FilePicker is a lightweight Android file and directory picker library for Java and Kotlin apps. It supports file selection, directory selection, single mode, multi mode, extension filtering, file size filtering, dialog themes, responsive dialog sizing, and detailed Android storage guidance for Android 11, 13, and 14+.
Download
/storage/emulated/0/Downloadinvoice.pdf
PDF • below 10 MBsample-video.mp4
Video • 100 MB - 2 GBProjectFiles
Directory selection supportedFiles & folders
Select files, directories, or both depending on your app flow.
Single / multi
Use single-selection mode or allow users to select many files.
Advanced filters
Filter by extension and file size using min/max byte limits.
Custom UI
Change title, buttons, theme, dialog width, and dialog height.
v10.1.2 focuses on modern Android support and professional developer experience.
The new version improves storage behavior, dialog customization, file size filtering, stability, and documentation for Play Store-safe Android apps.
v10.1.2 file size filtering
- Use
min_file_sizeandmax_file_size. - Select files below, above, or between size ranges.
- Works with videos, PDFs, images, audio, archives, and any readable file.
- Uses
longvalues for large files.
v10.1.1 dialog sizing
- Set width and height programmatically.
- Use responsive screen percentages.
- Improve tablet, foldable, landscape, and ultra-wide UI.
- Support
MATCH_PARENT,WRAP_CONTENT, and exact pixels.
Core stability improvements
- Safer checkbox handling.
- Safer selected item handling.
- Better null checks for unreadable folders.
- Predictable selected path ordering.
- Safer extension filter formats like
pdf,.pdf, and*.
Install from Maven Central or JitPack.
Use only one dependency source in your project. Maven Central is recommended for production apps. JitPack is available for GitHub-based dependency installation.
Step 1: Add Maven Central in project-level settings.gradle
Open YourProject/settings.gradle or YourProject/settings.gradle.kts. Add mavenCentral() inside dependencyResolutionManagement.
pluginManagement {
repositories {
google()
mavenCentral()
gradlePluginPortal()
}
}
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
google()
mavenCentral()
}
}
rootProject.name = "YourProjectName"
include ':app'Step 2: Add dependency in app/build.gradle
Open YourProject/app/build.gradle and add the dependency in the dependencies block.
dependencies {
implementation "io.github.tutorialsandroid:filepicker:10.1.2"
}Kotlin DSL
dependencies {
implementation("io.github.tutorialsandroid:filepicker:10.1.2")
}Step 1: Add JitPack in project-level settings.gradle
Open YourProject/settings.gradle and add maven { url 'https://jitpack.io' } inside dependencyResolutionManagement.
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
google()
mavenCentral()
maven { url 'https://jitpack.io' }
}
}Step 2: Add JitPack dependency
dependencies {
implementation "com.github.TutorialsAndroid:FilePicker:v10.1.2"
}Kotlin DSL
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
google()
mavenCentral()
maven("https://jitpack.io")
}
}
dependencies {
implementation("com.github.TutorialsAndroid:FilePicker:v10.1.2")
}Minimum SDK requirement
FilePicker v10.1.2 requires minSdk 23 or higher. Add this inside the android { defaultConfig { ... } } block of your app module Gradle file.
android {
namespace "com.example.yourapp"
compileSdk 35
defaultConfig {
applicationId "com.example.yourapp"
minSdk 23
targetSdk 35
versionCode 1
versionName "1.0"
}
}Modern Android storage is strict. Permission strategy matters.
FilePicker is path-based. Android 11+ may require All files access for broad raw path browsing. Android 13+ uses granular media permissions. Android 14+ can grant only selected photos/videos.
| Android version | API | Behavior | Recommended approach |
|---|---|---|---|
| Android 6.0 - 9 | 23 - 28 | Runtime read storage permission is required. | Request READ_EXTERNAL_STORAGE; request write only when truly needed on older devices. |
| Android 10 | 29 | Scoped storage introduced. | Use requestLegacyExternalStorage="true" only when needed for legacy path behavior. |
| Android 11 - 12L | 30 - 32 | Scoped storage enforced. Broad raw path browsing needs special access. | Use SAF/MediaStore where possible, or MANAGE_EXTERNAL_STORAGE only if eligible. |
| Android 13 | 33 | Media access uses granular permissions. | Use READ_MEDIA_IMAGES, READ_MEDIA_VIDEO, and/or READ_MEDIA_AUDIO. |
| Android 14+ | 34+ | Users can grant selected photo/video access. | Handle READ_MEDIA_VISUAL_USER_SELECTED behavior for media-only flows. |
Play Store policy warning
Do not blindly add MANAGE_EXTERNAL_STORAGE. Google Play treats All files access as high-risk/sensitive and allows it only when broad file access is required for the app's core functionality.
- Usually valid: file managers, backup/restore, antivirus, document management, device migration.
- Usually risky: simple upload, chat attachment picker, profile photo picker, gallery-only app.
- Use Android Photo Picker for images/videos.
- Use Storage Access Framework for user-selected documents/folders.
- Use MediaStore for media collections.
- Use app-specific storage for private app files.
Manifest setup for eligible broad path-based file browsing
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<uses-permission
android:name="android.permission.READ_EXTERNAL_STORAGE"
android:maxSdkVersion="32" />
<uses-permission
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="28" />
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />
<uses-permission android:name="android.permission.READ_MEDIA_VISUAL_USER_SELECTED" />
<uses-permission
android:name="android.permission.MANAGE_EXTERNAL_STORAGE"
tools:ignore="ScopedStorage" />
<application
android:theme="@style/AppTheme"
android:requestLegacyExternalStorage="true">
...
</application>
</manifest>Simple API for files, folders, and selected paths.
Create DialogProperties, configure selection behavior, create FilePickerDialog, and listen for selected paths.
DialogProperties properties = new DialogProperties();
properties.selection_mode = DialogConfigs.SINGLE_MODE;
properties.selection_type = DialogConfigs.FILE_SELECT;
properties.root = new File(DialogConfigs.DEFAULT_DIR);
properties.offset = new File(DialogConfigs.DEFAULT_DIR);
properties.error_dir = new File(DialogConfigs.DEFAULT_DIR);
properties.extensions = null;
properties.show_hidden_files = false;
FilePickerDialog dialog = new FilePickerDialog(MainActivity.this, properties);
dialog.setTitle("Select a File");
dialog.setPositiveBtnName("Select");
dialog.setNegativeBtnName("Cancel");
dialog.setDialogSelectionListener(files -> {
for (String path : files) {
File file = new File(path);
// Use the selected file path
}
});
dialog.show();Single file
properties.selection_mode = DialogConfigs.SINGLE_MODE;
properties.selection_type = DialogConfigs.FILE_SELECT;Multiple files
properties.selection_mode = DialogConfigs.MULTI_MODE;
properties.selection_type = DialogConfigs.FILE_SELECT;Directories
properties.selection_type = DialogConfigs.DIR_SELECT;
// Or files + directories
properties.selection_type = DialogConfigs.FILE_AND_DIR_SELECT;Everything needed for production usage.
Use these sections for theme customization, sizing, filtering, Android 11+ access, Android 13+ media permissions, and migration from v9.x.
Custom dialog theme
Pass a custom dialog theme resource while creating FilePickerDialog.
FilePickerDialog dialog = new FilePickerDialog(
MainActivity.this,
properties,
R.style.YourCustomFilePickerTheme
);
<style name="YourCustomFilePickerTheme"
parent="Theme.AppCompat.Light.Dialog.Alert">
<item name="colorPrimary">#6750A4</item>
<item name="colorPrimaryDark">#4F378B</item>
<item name="colorAccent">#6750A4</item>
<item name="android:fontFamily">sans</item>
</style>Dialog width and height
Useful for tablets, foldables, landscape screens, and ultra-wide layouts.
// 85% screen width and 75% screen height
dialog.setDialogSizeByPercent(0.85f, 0.75f);
// Or direct layout params
dialog.setDialogSize(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT
);
dialog.show();Extension filtering
Show all files, selected extensions, dot-prefixed extensions, or wildcard.
// Show all files
properties.extensions = null;
// Show only selected extensions
properties.extensions = new String[]{"pdf", "docx", "xlsx"};
// Dot prefix is supported
properties.extensions = new String[]{".pdf", ".docx"};
// Wildcard
properties.extensions = new String[]{"*"};File size filtering
Use byte values. Use L in calculations to avoid integer overflow.
// PDF files below 10 MB
properties.extensions = new String[]{"pdf"};
properties.max_file_size = 10L * 1024L * 1024L;
// Files between 5 MB and 200 MB
properties.min_file_size = 5L * 1024L * 1024L;
properties.max_file_size = 200L * 1024L * 1024L;
// Disable limits
properties.min_file_size = -1L;
properties.max_file_size = -1L;Modern Java permission flow using ActivityResultLauncher
private ActivityResultLauncher<String[]> permissionLauncher;
private ActivityResultLauncher<Intent> allFilesAccessLauncher;
private void setupPermissionLaunchers() {
permissionLauncher = registerForActivityResult(
new ActivityResultContracts.RequestMultiplePermissions(),
result -> {
if (hasRequiredAccess()) {
filePickerDialog.show();
} else {
showPermissionDeniedMessage();
}
}
);
allFilesAccessLauncher = registerForActivityResult(
new ActivityResultContracts.StartActivityForResult(),
result -> {
if (hasRequiredAccess()) {
filePickerDialog.show();
} else {
showPermissionDeniedMessage();
}
}
);
}
private boolean hasRequiredAccess() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
return Environment.isExternalStorageManager();
}
return ContextCompat.checkSelfPermission(
this,
Manifest.permission.READ_EXTERNAL_STORAGE
) == PackageManager.PERMISSION_GRANTED;
}DialogProperties and DialogConfigs.
DialogProperties
| Property | Description |
|---|---|
selection_mode | Single or multiple selection. |
selection_type | Select files, directories, or both. |
root | Highest accessible directory for picker navigation. |
offset | Initial directory opened when dialog starts. |
error_dir | Fallback directory when root/offset is invalid. |
extensions | Allowed file extensions. |
show_hidden_files | Show or hide dot-files. |
min_file_size | Minimum allowed file size in bytes. |
max_file_size | Maximum allowed file size in bytes. |
DialogConfigs
| Constant | Description |
|---|---|
SINGLE_MODE | User can select only one item. |
MULTI_MODE | User can select multiple items. |
FILE_SELECT | Files only. |
DIR_SELECT | Directories only. |
FILE_AND_DIR_SELECT | Files and directories. |
DEFAULT_DIR | Default external storage directory. |
Use the minimum permission needed.
The library can be used in Play Store apps, but your app’s declared permissions and usage must comply with Google Play policy.
File manager apps
All files access may be appropriate if broad file browsing/management is the core user-facing feature. You still need a clear permission explanation and Play Console declaration.
Normal upload/import apps
Do not use All files access for simple one-file upload or attachment flows. Use Storage Access Framework, Photo Picker, or MediaStore where possible.
Privacy policy
Explain what file types are accessed, whether processing is local or uploaded, what metadata is collected, and why the permission is needed.
Common questions.
Does FilePicker support Android 13?
Yes. Android 13 media permissions are documented. For non-media files such as PDF, ZIP, DOCX, or arbitrary folders, Android scoped storage restrictions still apply.
Does FilePicker support Android 14?
Yes, with awareness of selected/partial photo-video access. Apps should not assume they can see every image or video when users grant partial access.
Can I select PDF files on Android 13+?
Yes, but not only with READ_MEDIA_* permissions. For direct path browsing of documents on Android 11+, your app needs eligible All files access or should use Storage Access Framework.
Can I change dialog theme?
Yes. Use the constructor that accepts a theme resource ID and pass a dialog-compatible AppCompat or Material Components theme.
Can I change dialog width and height?
Yes. Use setDialogSizeByPercent for responsive sizing or setDialogSize for direct layout params and exact pixel values.
Does this library upload files?
No. FilePicker only provides local selection UI. Your app decides what to do with selected file paths.
Support open source FilePicker
If this library saves your development time, consider sponsoring the project. Your support helps improve documentation, bug fixes, Android version testing, and new features like SAF/URI mode.