AndroidFilePickerLight
A file and directory chooser widget for Android that focuses on presenting an easy to configure lightweight UI. Designed from the top down to work with Android 10 and 11 (API 29+).
Install / Use
/learn @maxieds/AndroidFilePickerLightREADME
📂 Android File Chooser (Picker) Light Library
<hr /><img src="https://jitpack.io/v/maxieds/AndroidFilePickerLight.svg" /><img src="https://img.shields.io/badge/API%2029%2B-Tested%20on%20Android%2010-yellowgreen" /><img src="https://badges.frapsoft.com/os/gpl/gpl.svg?v=103" />
<img src="https://forthebadge.com/images/badges/made-with-java.svg" /><img src="https://forthebadge.com/images/badges/powered-by-coffee.svg" /><img src="https://forthebadge.com/images/badges/built-for-android.svg" />
<img src="https://raw.githubusercontent.com/maxieds/AndroidFileChooserLight/master/Screenshots/ReadmeEmojiBadges/HackerCatEmoji-v1.png" /><img src="https://badges.frapsoft.com/os/v2/open-source-175x29.png?v=103" /><img src="https://raw.githubusercontent.com/maxieds/AndroidFileChooserLight/master/Screenshots/ReadmeEmojiBadges/tRUTH.png" />
<hr />About the library
A file and directory chooser widget for Android that focuses on presenting an easy to configure lightweight UI. This library is intended to be a replacement for other picker libraries that works with the new Android 11 file system and storage management changes. The source is made openly available as free software according to the project license.
The main design considerations were to create a file picker library with as minimal a footprint as possible to do basic file selection operations, and that the resulting library chooser display must be very easy to extend and configure with respect to its look-and-feel themes, color schemes, icons and other UI options that users will want to customize to their client application. I was unable to find a solid external library for my application use cases that was not bloated with respect to media loaders and image processing features, that could be easily extended, and that was not limited by only a cumbersome list of built-in themes that the user can select. Therefore, I decided to take the best functionality I found in other libraries (many written in Kotlin) and write a custom implementation in Java while keeping the media file processing minimal.
Feature set
Key features in the library include the following:
- Easy to configure themes and UI display settings including icons and color choices (see docs link below)
- Simple actions and extendable Java interface to select and filter files/directories (see docs link below)
- Allows client code to access many standard file system types on the Android device without complicated procedures and permissions issues inherited by the new Android 11 policy changes
Screenshots of the library in action
<img src="https://raw.githubusercontent.com/maxieds/AndroidFileChooserLight/master/Screenshots/WorkingUI-Screenshot_20201112-052224.png" width="250" /> <img src="https://raw.githubusercontent.com/maxieds/AndroidFileChooserLight/master/Screenshots/WorkingUI-Screenshot_20201113-134724.png" width="250" /> <img src="https://raw.githubusercontent.com/maxieds/AndroidFilePickerLight/master/Screenshots/SampleApplicationDemo-ProgressBarDisplay.png" width="250" /> <img src="https://raw.githubusercontent.com/maxieds/AndroidFileChooserLight/master/Screenshots/SampleAppGreeenThemeWithPosixStylePerms-Screenshot_20201117-124350.png" width="250" /> <img src="https://raw.githubusercontent.com/maxieds/AndroidFileChooserLight/master/Screenshots/SampleAppThemeOrangeWithGradientToolbars-Screenshot_20201117-065739.png" width="250" /> <img src="https://raw.githubusercontent.com/maxieds/AndroidFileChooserLight/master/Screenshots/SampleAppThemeOrangeWithNavLongLabels-Screenshot_20201117-094425.png" width="250" />
Including the library for use in a client Android application
There are a couple of quickstart items covered in the sections below to handle before this library can be included in the client Android application:
- Include the library using Jitpack.io/GitHub in the application build.gradle configuration.
- Update the project AndroidManifest.xml file to extend the documents provider, request required permissions, and setup some helpful legacy file handling options for devices targeting Android platforms with SDK < Android OS 11.
Application build.gradle modifications
We will require the following small modifications to the client project build.gradle configuration:
android {
defaultConfig {
minSdkVersion 26
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
dependencies {
// FOR the most recent build:
implementation 'com.github.maxieds:AndroidFilePickerLight:master-SNAPSHOT'
// -- OR: for the latest release:
implementation 'com.github.maxieds:AndroidFilePickerLight:release-v7'
}
allprojects {
repositories {
maven {
url 'https://maven.fabric.io/public'
}
}
}
Project manifest modifications
For applications targeting so-called legacy platforms, that is Android devices where the new
Android 11 storage management options are not explicitly required, it is
recommended for compatibility sake by the Google developer docs
that the application set the option
requestLegacyExternalStorage="true". For example, use the following code:
<application
android:name=".MyAndroidProjectName"
android:description="@string/appDesc"
android:icon="@drawable/appIcon"
android:label="@string/appLabelDesc"
android:roundIcon="@drawable/appRoundIcon"
android:theme="${appTheme}"
android:launchMode="singleTop"
android:manageSpaceActivity=".MyAndroidProjectMainActivity"
android:requestLegacyExternalStorage="true"
android:allowBackup="true"
>
<!-- Complete the internals of the application tag (activities, etc.) below -->
</application>
Note that unlike some samples to get other Android libraries up and running, there is no need to define references
to the custom FileProvider implemented by the library. It is sufficient to just use the standardized wrappers
to launch a new FileChooserActivity instance and use the file picker functionality bundled within that interface.
Sample client source code in Java
The next examples document basic, advanced, and custom uses of the library in client code.
The file chooser instance is launched via a traditional startActivityForResult call
from within the client caller's code. The following is a suggestion as to how to handle
the results:
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
// Handle activity codes:
// FileChooserBuilder.ACTIVITY_CODE_SELECT_FILE_ONLY ||
// FileChooserBuilder.ACTIVITY_CODE_SELECT_DIRECTORY_ONLY ||
// FileChooserBuilder.ACTIVITY_CODE_SELECT_MULTIPLE_FILES:
super.onActivityResult(requestCode, resultCode, data);
try {
selectedFilePaths = FileChooserBuilder.handleActivityResult(this, requestCode, resultCode, data);
} catch (RuntimeException rte) {
if (data != null) {
rteErrorMsg = rte.getMessage();
}
if (rteErrorMsg == null) {
rteErrorMsg = "Unknown reason for exception.";
}
}
showFileChooserResultsDialog(selectedFilePaths, rteErrorMsg);
}
The following are the unique Intent keys that are associated with the returned data (if available):
public static final String FILE_PICKER_INTENT_DATA_TYPE_KEY = "FilePickerIntentKey.SelectedIntentDataType";
public static final String FILE_PICKER_INTENT_DATA_PAYLOAD_KEY = "FilePickerIntentKey.SelectedIntentDataPayloadList";
public static final String FILE_PICKER_EXCEPTION_MESSAGE_KEY = "FilePickerIntentKey.UnexpectedExitMessage";
public static final String FILE_PICKER_EXCEPTION_CAUSE_KEY = "FilePickerIntentKey.ExceptionCauseDescKey";
Basic usage: Returning a file path selected by the user
This is a quick method to select a file and/or directory picked by the user:
public void actionButtonLaunchSingleFilePickerActivity(View btnView) {
FileChooserBuilder fpInst = FileChooserBuilder.getDirectoryChooserInstance(this);
fpInst.showHidden(true);
fpInst.setPickerInitialPath(FileChooserBuilder.BaseFolderPathType.BASE_PATH_DEFAULT);
fpInst.launchFilePicker();
}
public void actionButtonLaunchSingleFilePickerActivity(View btnView) {
FileChooserBuilder fpInst = FileChooserBuilder.getSingleFilePickerInstance(this);
fpInst.showHidden(true);
fpInst.setPickerInitialPath(FileChooserBuilder.BaseFolderPathType.BASE_PATH_TYPE_EXTERNAL_FILES_SCREENSHOTS);
fpInst.launchFilePicker();
}
public void actionButtonLaunchOmnivorousMultiPickerActivity(View btnView) {
FileChooserBuilder fpInst = new FileChooserBuilder(this);
fpInst.setSelectionMode(FileChooserBuilder.SelectionModeType.SELECT_OMNIVORE);
fpInst.setSelectMultiple(5);
fpInst.setActionCode(FileChooserBuilder.ACTIVITY_CODE_SELECT_MULTIPLE_FILES);
fpInst.showHidden(true);
fpInst.setPickerInitialPath(FileChooserBuilder.BaseFolderPathType.BASE_PATH_TYPE_EXTERNAL_FILES_DOWNLOADS);
fpInst.launchFilePicker();
}
Detailed list of non-display type options
The next options are available to configure the non-display type (e.g., properties of the file chooser that do not depend on how it looks) proper
