A file/directory-picker for android. Implemented as a library project.

Overview

Note: avoid using as SD-card file picker on Kitkat+

In Kitkat or above, use Android's built-in file-picker instead. Google has restricted the ability of external libraries like this from creating directories on external SD-cards in Kitkat and above which will manifest itself as a crash.

If you need to support pre-Kitkat devices see #158 for the recommendation approach.

This does not impact the library's utility for non-SD-card locations, nor does it impact you if you don't want to allow a user to create directories.

NoNonsense-FilePicker

Flattr this Dependency Status

  • Extendable for sources other than SD-card (Dropbox, FTP, Drive, etc)
  • Can select multiple items
  • Select directories or files, or both
  • Create new directories in the picker
  • Material theme with AppCompat

Yet another file picker library?

I needed a file picker that had two primary properties:

  1. Easy to extend: I needed a file picker that would work for normal files on the SD-card, and also for using the Dropbox API.
  2. Able to create a directory in the picker.

This project has both of those qualities. As a bonus, it also scales nicely to work on any phone or tablet. The core is placed in abstract classes, so it is fairly easy to extend the picker to create your own.

The library includes an implementation that allows the user to pick files from the SD-card. But the picker could easily be extended to get its file listings from another source, such as Dropbox, FTP, SSH and so on. The sample app includes implementations which browses your Dropbox and a Linux mirror FTP-server.

By inheriting from an Activity, the picker is able to be rendered as full screen on small screens and as a dialog on large screens. It does this through the theme system, so it is very important for the activity to use a correctly configured theme.

How to include in your project (with Gradle)

Just add the dependency to your build.gradle:

repositories {
    jcenter()
}

dependencies {
    compile 'com.nononsenseapps:filepicker:4.1.0'
}

How to use the included SD-card picker:

Include permission in your manifest

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

Include a provider element

Due to changes in Android 6.0 Marshmallow, bare File URIs can no longer be returned in a safe way. This change requires you to add an entry to your manifest to use the included FilePickerFragment:

NOTE: the authority of this provider is hard-coded in the bundled FilePickerFragment. If you have an existing content provider in your app with the same authority you will have a conflict. You'll either have to rename your existing authority or extend FilePickerFragment and override which authority is used.

    <provider
        android:name="android.support.v4.content.FileProvider"
        android:authorities="${applicationId}.provider"
        android:exported="false"
        android:grantUriPermissions="true">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/nnf_provider_paths" />
    </provider>

Include the file picker activity

The intent filter is optional depending on your use case. Note that the theme set in the manifest is important.

    <activity
       android:name="com.nononsenseapps.filepicker.FilePickerActivity"
       android:label="@string/app_name"
       android:theme="@style/FilePickerTheme">
       <intent-filter>
          <action android:name="android.intent.action.GET_CONTENT" />
          <category android:name="android.intent.category.DEFAULT" />
       </intent-filter>
    </activity>

Configure the theme

You must set the theme on the activity, but you can configure it to match your existing application theme. You can also name it whatever you like..

    <!-- You can also inherit from NNF_BaseTheme.Light -->
    <style name="FilePickerTheme" parent="NNF_BaseTheme">
        <!-- Set these to match your theme -->
        <item name="colorPrimary">@color/primary</item>
        <item name="colorPrimaryDark">@color/primary_dark</item>
        <item name="colorAccent">@color/accent</item>

        <!-- Setting a divider is entirely optional -->
        <item name="nnf_list_item_divider">?android:attr/listDivider</item>

        <!-- Need to set this also to style create folder dialog -->
        <item name="alertDialogTheme">@style/FilePickerAlertDialogTheme</item>

        <!-- If you want to set a specific toolbar theme, do it here -->
        <!-- <item name="nnf_toolbarTheme">@style/ThemeOverlay.AppCompat.Dark.ActionBar</item> -->
    </style>

    <style name="FilePickerAlertDialogTheme" parent="Theme.AppCompat.Dialog.Alert">
        <item name="colorPrimary">@color/primary</item>
        <item name="colorPrimaryDark">@color/primary_dark</item>
        <item name="colorAccent">@color/accent</item>
    </style>

Starting the picker in your app

    // This always works
    Intent i = new Intent(context, FilePickerActivity.class);
    // This works if you defined the intent filter
    // Intent i = new Intent(Intent.ACTION_GET_CONTENT);

    // Set these depending on your use case. These are the defaults.
    i.putExtra(FilePickerActivity.EXTRA_ALLOW_MULTIPLE, false);
    i.putExtra(FilePickerActivity.EXTRA_ALLOW_CREATE_DIR, false);
    i.putExtra(FilePickerActivity.EXTRA_MODE, FilePickerActivity.MODE_FILE);

    // Configure initial directory by specifying a String.
    // You could specify a String like "/storage/emulated/0/", but that can
    // dangerous. Always use Android's API calls to get paths to the SD-card or
    // internal memory.
    i.putExtra(FilePickerActivity.EXTRA_START_PATH, Environment.getExternalStorageDirectory().getPath());

    startActivityForResult(i, FILE_CODE);

Handling the result

You can use the included utility method to parse the activity result:

protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
    if (requestCode == FILE_CODE && resultCode == Activity.RESULT_OK) {
        // Use the provided utility method to parse the result
        List<Uri> files = Utils.getSelectedFilesFromResult(intent);
        for (Uri uri: files) {
            File file = Utils.getFileForUri(uri);
            // Do something with the result...
        }
    }
}

Want to customize further?

See some examples in the Wiki

See the sample project for examples on dark and light themes, and implementations using Dropbox and FTP.

Not using Gradle yet?

Time to start! To convert your current Eclipse project, have a look at my brief explanation: http://cowboyprogrammer.org/convert-to-android-studio-and-gradle-today/

Changelog

See CHANGELOG

Comments
  • Add static helper method

    Add static helper method

    The code in the readme is really just boilerplate code, which could be easily extracted in a static helper, as I just did here. I also adjusted the sample to show how it's used.

    enhancement 
    opened by F43nd1r 5
  • Fixed `FileUriExposed` error on Nougat properly

    Fixed `FileUriExposed` error on Nougat properly

    fixes #107 fixes #115

    changelog: You are now required to define a FileProvider in your manifest for the SD-card picker

    Due to recent changes in Android 7.0 Nougat, bare File URIs can no longer be returned in a safe way. This change requires you to add an entry to your manifest to use the included FilePickerFragment and change how you handle the results.

    • You need to add the following to your app's AndroidManifest.xml:
            <provider
                android:name="android.support.v4.content.FileProvider"
                android:authorities="${applicationId}.provider"
                android:exported="false"
                android:grantUriPermissions="true">
                <meta-data
                    android:name="android.support.FILE_PROVIDER_PATHS"
                    android:resource="@xml/nnf_provider_paths" />
            </provider>
    
    • Then you must change your result handling. Here is a code snippet illustrating the change for a single result (the same applies to multiple results):
    protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
        // The URI will now be something like content://PACKAGE-NAME/root/path/to/file
        Uri uri = intent.getData();
        // A new utility method is provided to transform the URI to a File object
        File file = com.nononsenseapps.filepicker.Utils.getFileForUri(uri);
        // If you want a URI which matches the old return value, you can do
        Uri fileUri = Uri.fromFile(file);
        // Do something with the result...
    }
    

    This change was required in order to fix FileUriExposedException being thrown on Android 7.0 Nougat, as reported in #115 and #107.

    Please see the updated activity in the sample app for more examples.

    changelog breaking 
    opened by spacecowboy 5
  • Ability to specify new file name

    Ability to specify new file name

    Name of a new (non-existing) file name can be specified, e.g. when the file should be created by the app. This is presented to the user as additional menu item and has to be activated: intent.putExtra(FilePickerActivity.EXTRA_ALLOW_CREATE_FILE, true);

    enhancement addition 
    opened by rastikw 4
  • Update build tools to 26.0.2 and update Dropbox sample to v2 API

    Update build tools to 26.0.2 and update Dropbox sample to v2 API

    Hello,

    I wanted to use NoNonesense FilePicker in my project to select directories from Dropbox, but it wouldn't work because Dropbox has discontinued the v1 API used by the samples.

    I have re-written the Dropbox sample to use the v2 API and thought I would share it for others to benefit.

    The only thing that I'm not sure about, and would appreciate your help with, is the change I made in commit a0349ef, which I did to remove a NullPointerException when I first tried to run the Dropbox sample. I feel like I have missed something and that recyclerView in DropboxFilePickerFragment.java should somehow get automatically assigned. Is there a better way that I could have used to do this?

    change 
    opened by mitchyboy9 3
  • Fixed RuntimeException with empty state in onSaveInstanceState

    Fixed RuntimeException with empty state in onSaveInstanceState

    This adds a dummy value to the state if it is empty in AbstractFilePickerActivity.java. This also first adds the values to the state, and then saves (instead of the other way around) in AbstractFilePickerFragment.java

    changelog fix 
    opened by jangrewe 2
  • Ensure toasts don't get queued up

    Ensure toasts don't get queued up

    If the user spams the OK button with nothing selected, the Toasts queue up which can end up having it display for a long time. This just makes sure only one Toast is enqueued so it will disappear after Toast.LENGTH_SHORT.

    bug 
    opened by hcoosthuizen 2
  • Select one file with a single click

    Select one file with a single click

    If only one file is to be selected, it is easier just to click on the file and not used checkboxes. It has to be activated: intent.putExtra(FilePickerActivity.EXTRA_SINGLE_CLICK, true);

    This pull request makes changes to the same method signatures as my previous pull request, so merging might be a bit more complicated.

    enhancement addition 
    opened by rastikw 1
  • NPE on empty dir

    NPE on empty dir

    Caused by: java.lang.NullPointerException at com.nononsenseapps.filepicker.FilePickerFragment$2.loadInBackground(FilePickerFragment.java:142) at com.nononsenseapps.filepicker.FilePickerFragment$2.loadInBackground(FilePickerFragment.java:135)

    fix 
    opened by arkty 1
  • Fixed multiple selection throwing exception on nougat

    Fixed multiple selection throwing exception on nougat

    fixes #107 fixes #115

    changelog: Multiple selection now returns Strings in ClipData instead of URIs

    This means you have to change your code from

    intent.getClipData().getItemAt(i).getUri()
    

    to

    intent.getClipData().getItemAt(i).getText()
    

    This change was required in order to fix FileUriExposedException being thrown on Android 7.0 Nougat, as reported in #115 and #107.

    In addition, the alternative way of getting the result via intent.getStringArrayListExtra(AbstractFilePickerActivity.EXTRA_PATHS) is now available on all SDK versions and not only on pre-android 4.3 as previously. So an alternative would be to do this instead:

    ArrayList<String> paths = 
            intent.getStringArrayListExtra(AbstractFilePickerActivity.EXTRA_PATHS);
    

    Please see the updated activity in the sample app for details.

    invalid 
    opened by spacecowboy 0
  • Add ability to enter a new filename

    Add ability to enter a new filename

    And a bunch of other improvements

    Fixes #82

    Needs:

    • [x] Ability to define a default filename
    • [x] Play nice when given a specified path pointing to a file
    • [x] Handle if a filename with path is given, e.g. path/to/file. The goal is not to create all folders. In that case, the user knows what he wants and the calling app should handle non-existing dirs

    Image of current state

    screenshot may 14 2016 01-02-49

    enhancement addition 
    opened by spacecowboy 0
  • Make click events overridable

    Make click events overridable

    • Added additional methods in AbstractFilePickerFragment to allow more customized behavior. All methods have default behavior, but can be augmented by child classes.:

      goUp, navigates to parent directory. goToDir, navigates to specified directory. onClickOK, handles ok button. onClickCancel, handles cancel button. onClickHeader, handles clicks on "..". onClickDir, handles clicks on non-selectable items (usually directories). onLongClickDir, handles long clicks on non-selectable items. onClickCheckable, handles clicks on selectable items. onLongClickCheckable, handles long clicks on selectable items. onClickCheckBox, handles clicks on the checkbox of selectable items.

      Please see default implementation and docstrings before overriding them.

    enhancement addition 
    opened by spacecowboy 0
Releases(4.2.1)
Owner
Jonas Kalderstam
Self hoster and virtual prepper
Jonas Kalderstam
[] Android library that provides a file explorer to let users select files on external storage.

aFileChooser - Android File Chooser aFileChooser is an Android Library Project that simplifies the process of presenting a file chooser on Android 2.1

Paul Burke 1.8k Jan 5, 2023
A color picker and a color preference for use in Android applications.

HSV-Alpha Color Picker for Android This library implements a color picker and a color preference for use in Android applications. Features I couldn't

Martin Stone 279 Nov 26, 2022
This is a picker view for android , support linkage effect, timepicker and optionspicker.(时间选择器、省市区三级联动)

Android-PickerView English Document 注意事项、详请使用方式、更新日志等,请查看 Wiki文档 Wiki文档,Wiki文档,Wiki文档 !~ 重要的事情说三遍 对于使用上有任何疑问或优化建议等,欢迎加入QQ群讨论交流技术问题。 交流群1: 387051294(推荐

Bigkoo 13.2k Jan 6, 2023
Google Calendar Recurrence picker

Android Recurrence Picker Google Calendar Recurrence picker Screenshot Usage Maven / Gradle Maven: <dependency> <groupId>be.billington.calendar.recu

Benoit Billington 240 Nov 29, 2022
A color picker for Jetpack compose 🎨

Compose Color Picker ?? Color Picker for Jetpack compose A color picker for Jetpack compose ?? Download ?? Working on it ?? Usage ColorPicker { co

mhssn 12 Dec 8, 2022
MarkdownView is an Android webview with the capablity of loading Markdown text or file and display it as HTML, it uses MarkdownJ and extends Android webview.

About MarkdownView (Markdown For Android) is an Android library that helps you display Markdown text or files (local/remote) as formatted HTML, and st

Feras Alnatsheh 1k Dec 20, 2022
A standalone library project for certificate pinning on Android.

Android Pinning AndroidPinning is a standalone Android library project that facilitates certificate pinning for SSL connections from Android apps, in

Moxie Marlinspike 597 Dec 23, 2022
Library and example project on how to use the UITableView component

UITableView for Android Usage Installation Android Studio Paste or clone this library into the /libs folder, in the root directory of your project. Cr

Thiago Locatelli 679 Nov 11, 2022
Graduation project of "Android Bootcamp Turkey"

Spending Tracking Mobile App Screenshots ENG Description This application allows you to record your bills, rent and all other expenses in 4 different

Yasin Tohan 6 Jun 1, 2021
Android Bootcamp Turkey Final Project

Expenses App Features Splash Screen OnBoarding Screen Change Icon Room Database Navigation View Binding / Data Binding Retrofit RecyclerView Currency

Sinan Türkoğlu 6 Aug 30, 2022
This is a sample Android Studio project that shows the necessary code to create a note list widget, And it's an implementation of a lesson on the Pluralsight platform, but with some code improvements

NoteKeeper-Custom-Widgets This is a sample Android Studio project that shows the necessary code to create a note list widget, And it's an implementati

Ibrahim Mushtaha 3 Oct 29, 2022
This project has been superseded by SuperSLiM, a layout manager for RecyclerView. I strongly recommend using SuperSLiM and not StickyGridHeaders.

StickyGridHeaders Replacement project at SuperSLiM This repository is abandoned and will no longer see any development or support. The replacement Sup

Tonic Artos 1.5k Nov 15, 2022
Hackathon Project

Notify Playstore Link Events Problem Statement : Whenever we try to attend events like interviews, exams, marriage, trips, catching a flight, train. T

Mausam Singh 5 Feb 1, 2022
Simple project where it is possible to calculate the average fuel when refueling

Aplicativo simples onde é calculado qual combustível é mais vantajoso ao abastec

Wesley V N De L Torres 0 Jan 23, 2022
Project of PDP UOC's subject

PDP Häagen-Dazs Backend -> MacadamiaNut Tech Stack Macadamia Nut has been written using Kotlin ver 1.6.0, and uses Spring Boot as framework. For DataB

Ivan Moll 1 Jan 16, 2022
Ms-goals - Project developed using Kotlin and Spring

Goals microservice Kotlin + Spring CRUD application. You can find the following

Gabriel Babler 0 Jan 28, 2022
This project created just for help developer who want to and ability of read VISA, UNION PAY, HUMO, ATTO and some other cards data read.

If you enjoy my content, please consider supporting what I do. Thank you. By me a Coffee To get a Git project into your build: Step 1. Add the JitPack

Fozilbek Imomov 1 Oct 15, 2022
A new canvas drawing library for Android. Aims to be the Fabric.js for Android. Supports text, images, and hand/stylus drawing input. The library has a website and API docs, check it out

FabricView - A new canvas drawing library for Android. The library was born as part of a project in SD Hacks (www.sdhacks.io) on October 3rd. It is cu

Antwan Gaggi 1k Dec 13, 2022