[] Android library that provides a file explorer to let users select files on external storage.

Related tags

UI/UX aFileChooser
Overview

aFileChooser - Android File Chooser

aFileChooser is an Android Library Project that simplifies the process of presenting a file chooser on Android 2.1+.

Intents provide the ability to hook into third-party app components for content selection. This works well for media files, but if you want users to be able to select any file, they must have an existing "file explorer" app installed. Because many Android devices don't have stock File Explorers, the developer must often instruct the user to install one, or build one, themselves. aFileChooser solves this issue.

Features:

  • Full file explorer
  • Simplify GET_CONTENT Intent creation
  • Hooks into Storage Access Framework
  • Determine MIME data types
  • Follows Android conventions (Fragments, Loaders, Intents, etc.)
  • Supports API 7+

screenshot-1 screenshot-2

Setup

Add aFileChooser to your project as an Android Library Project.

Add FileChooserActivity to your project's AndroidManifest.xml file with a fully-qualified name. The label and icon set here will be shown in the "Intent Chooser" dialog.

Important FileChooserActivity must have android:exported="true" and have the <intent-filter> set as follows:

<activity
    android:name="com.ipaulpro.afilechooser.FileChooserActivity"
    android:icon="@drawable/ic_chooser"
	android:enabled="@bool/use_activity"
    android:exported="true"
    android:label="@string/choose_file" >
    <intent-filter>
        <action android:name="android.intent.action.GET_CONTENT" />

        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.OPENABLE" />

        <data android:mimeType="*/*" />
    </intent-filter>
</activity>

If you want to use the Storage Access Framework (API 19+), include Ian Lake's LocalStorageProvider (included in this library) in your <application>:

<provider
    android:name="com.ianhanniballake.localstorage.LocalStorageProvider"
    android:authorities="com.ianhanniballake.localstorage.documents"
	android:enabled="@bool/use_provider"
    android:exported="true"
    android:grantUriPermissions="true"
    android:permission="android.permission.MANAGE_DOCUMENTS" >
        <intent-filter>
            <action android:name="android.content.action.DOCUMENTS_PROVIDER" />
        </intent-filter>
</provider>

Note that like a ContentProvider, the DocumentProvider authority must be unique. You should change com.ianhanniballake.localstorage.documents in your Manifest, as well as the LocalStorageProvider.AUTHORITY field.

Using FileChooserActivity and LocalStorageProvider together are redundant if you're only trying to insure your user has access to local storage. If this is the case, you should enable/disable based on the API level (above: @bool/use_provider and @bool/use_activity). See the aFileChooserExample project for their values.

Usage

Use startActivityForResult(Intent, int) to launch FileChooserActivity directly. FileChooserActivity returns the Uri of the file selected as the Intent data in onActivityResult(int, int, Intent). Alternatively, you can use the helper method FileUtils.createGetContentIntent() to construct an ACTION_GET_CONTENT Intent that will show an "Intent Chooser" dialog on pre Kit-Kat devices, and the "Documents UI" otherwise. E.g.:

private static final int REQUEST_CHOOSER = 1234;

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

    // Create the ACTION_GET_CONTENT Intent
    Intent getContentIntent = FileUtils.createGetContentIntent();
	
    Intent intent = Intent.createChooser(getContentIntent, "Select a file");
    startActivityForResult(intent, REQUEST_CHOOSER);
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    switch (requestCode) {
    	case REQUEST_CHOOSER:	
        	if (resultCode == RESULT_OK) {
				
            	final Uri uri = data.getData();
				
				// Get the File path from the Uri
            	String path = FileUtils.getPath(this, uri);
				
				// Alternatively, use FileUtils.getFile(Context, Uri)
				if (path != null && FileUtils.isLocal(path)) {
					File file = new File(path);
				}
        	}
			break;
    }
}

A more robust example can be found in the aFileChooserExample project.

Note the FileUtils method to get a file path from a Uri (FileUtils.getPath(Context, Uri)). This works for File, MediaStore, and DocumentProvider Uris.

Credits

Developed by Paul Burke (iPaulPro) - paulburke.co

Translations by TomTasche, booknara, brenouchoa

Folder by Sergio Calcara from The Noun Project (ic_provider.png)

Document by Melvin Salas from The Noun Project (ic_file.png)

Licenses

Copyright (C) 2011 - 2013 Paul Burke

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.

Portions of FileUtils.java:

Copyright (C) 2007-2008 OpenIntents.org

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.

LocalStorageProvider.java:

Copyright (c) 2013, Ian Lake
All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

- Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
- Neither the name of the <ORGANIZATION> nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.	
Comments
  • Problem with Proguard

    Problem with Proguard

    I was trying to export the example application in the project and was unable to do so. In the aFileChooserExample project, I added the following line in project.properties file -

    proguard.config=proguard.cfg
    

    Then I tried to export the project by going to Android Tools > Export signed application package. It gave the following error message -

    Conversion to dalvik format failed with error 1

    opened by jaibatrik 5
  • NoClassDefFoundError when using aFileChooser with my app.

    NoClassDefFoundError when using aFileChooser with my app.

    Hello,

    I get the exception linked below when I select the built-in aFileChooser to select a file for my app to process. The sample provided with aFileChooser works fine, however.

    http://pastebin.com/hXaJ0jQ7

    Instead of adding the aFileChooser project as a dependency, I copied the JAR file to my project's libs folder and added it to the build path. I did this because I host my project on Google Code and I didn't want anyone cloning my repository to have to clone other repositories as well.

    opened by fishnet37222 5
  • Disabling Google Drive from menu

    Disabling Google Drive from menu

    I have been looking around but can't find an answer. Is there an easy way to simply disabling Google Drive from displaying in the fileChooser? That would be a much more simple solution if it is causing an error.

    opened by ericlokness 3
  • Design flaw

    Design flaw

    I have two apps into which which a added aFileChooser (patched version with extension filter and base path).

    When I started the demo for testing I saw:

    device-2014-01-02-140928

    Now I have three identical choose files options.

    That makes me wonder if there is not fundamental design flaw inside aFileChooser. I beginn to think that one library can not be an external and internal file chooser at the same time.

    opened by krischik 2
  • Start the FileChooserActivity directly

    Start the FileChooserActivity directly

    Hi,

    sorry, that I ask with a little problem like this.

    Im not able to start the FileChooserActivity directly. At the moment it is configured like the aFileChooserExample.

    private void openFile() {
        // Use the GET_CONTENT intent from the utility class
        Intent target = FileUtils.createGetContentIntent();
    
        // Create the chooser Intent
        Intent intent = Intent.createChooser(
                target, getString(R.string.chooser_title));
    
        try {
            startActivityForResult(intent, REQUEST_CODE);
    
        } catch (ActivityNotFoundException e) {
             //The reason for the existence of aFileChooser
        }
    }
    

    I dont want to see the other possibilitys (Music, photos,...) and start the aFileChooser directly.

    I tried with :

        private void openFile() {
            Intent in = new Intent("com.ipaulpro.afilechooser.FileChooserActivity");
            startActivityForResult(in, REQUEST_CODE);
        }
    

    or:

        private void openFile() {
            Intent in = new Intent("android.intent.action.GET_CONTENT");
            startActivityForResult(in, REQUEST_CODE);
        }
    

    But I get this message on start:

    E/AndroidRuntime(22091): android.content.ActivityNotFoundException: No Activity found to handle Intent { act=com.ipaulpro.afilechooser.FileChooserActivity }

    Can someone tell me, what changes I need?

    Thank you very much

    opened by AdminBWF 2
  • Crash when running aFileChooser.

    Crash when running aFileChooser.

    Hello,

    I get the exception and stack trace linked below whenever I run the aFileChooserExample project on my Nexus 7. I'm not sure why it's happening.

    http://pastebin.com/CYFv4dV0

    opened by fishnet37222 2
  • Fix for external SDCard on Android M

    Fix for external SDCard on Android M

    Starting from Android M, the external SD Card used as portable storage shows the SDCard ID as DocumentsContract first parameter.

    So docId has the following format: XXXX-XXXX:path/to/the/file And the real path would be: /storage/XXXX-XXXX/path/to/the/file

    if (type.matches("[A-F0-9]{4}-[A-F0-9]{4}")) {
         return "/storage/".concat(type).concat("/").concat(split[1]);
    }
    

    Tested on Moto X Play 6.0. Someone can confirm that it's the same for other devices? I don't like at all handwrite the "storage" path, and maybe the type is not always an SDCard ID.

    We should discuss this before merge.

    opened by jahertor 1
  • string/chooser——label Not found

    string/chooser——label Not found

    When i added the “FileChooserActivity” activity in manifest i came across such an error

    error: Error: No resource found that matches the given name (at 'label' with value '@string/chooser_label').

    Any help, thanks in advance

    opened by copywrite 1
  • Updated android-support-v4.jar

    Updated android-support-v4.jar

    What: I updated android-support-v4.jar to be the one in the most recent Android Support Library.

    Why: fixes #28. If I use the v7 appcompat library from the Android Support Library together with aFileChooser, the two different android-support-v4.jar files conflict so my project won't compile.

    No worries if you don't want to accept this pull request; I can continue using my own fork in that case. But I think it will help others who want to use the support libraries together with aFileChooser. Thanks for your consideration, and thanks for the great library!

    opened by garysheppardjr 1
  • Filter file types

    Filter file types

    First of all thanks for sharing this awesome piece of work :)

    Hey Guys is there a way to filter file types in this library?

    I mean I want to limit this chooser to select only pdf or doc files.

    Is there anything like this in here already ?

    opened by riyazMuhammad 1
  • Cannot receive result from started FileChooser activity

    Cannot receive result from started FileChooser activity

    Hi Paul,

    Firstly, thanks for your effort in making this FileChooser which is really neat.

    However, following the way from your Readme and code from example, I have encountered problems in getting

    intent result from the FilePicker which is my version of activity extends the FileChooser.

    Heres the codes:

    I starts the activity by:

                    Intent in = new Intent(v.getContext(),
                            org.vc.FilePicker.FilePicker.class);
                    in.setAction(Intent.ACTION_GET_CONTENT);
                    startActivityForResult(in, REQUEST_CODE);
    

    OnActivityResult:

    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (resultCode == RESULT_OK)
            if (requestCode == REQUEST_CODE) {
                if (data.hasExtra("tmp")) {
                    String tmp = data.getStringExtra("tmp");
                    Toast.makeText(this, "filename: " + tmp, Toast.LENGTH_LONG).show();
                    Log.i("Filename:", tmp);
                }
            }
    }
    

    In the newly created FilePicker Activity:

     @Override
     public void finish() {
     Intent data = new Intent();
     Log.i("&&&&&&&&&& PATH", tmp);
     data.putExtra("tmp", tmp);
     setResult(RESULT_OK, data);
     super.finish();
     }
    

    This setting turns out to be no result could be fetched by the

    main Activity although the FilePicker works perfectly on picking files.

    PS: for some reason, my testing Log.i(); outputs never triggers or could not be found in

    logcat neither.

    Thanks in advance, looking forward for you reply.

    opened by cowbaby 1
  • Crash when choosing pdf file in android 11

    Crash when choosing pdf file in android 11

    2021-12-26 19:23:23.097 25806-25806/com.parto.podingo E/AndroidRuntime: FATAL EXCEPTION: main Process: com.parto.podingo, PID: 25806 java.lang.NullPointerException: uri at java.util.Objects.requireNonNull(Objects.java:245) at android.content.ContentResolver.query(ContentResolver.java:1171) at android.content.ContentResolver.query(ContentResolver.java:1128) at android.content.ContentResolver.query(ContentResolver.java:1084) at com.parto.podingo.utils.FileUtils.getDataColumn(FileUtils.java:228) at com.parto.podingo.utils.FileUtils.getPath(FileUtils.java:320) at com.parto.podingo.utils.FileUtils.getFile(FileUtils.java:350) at com.parto.podingo.fragments.ApplySupportFragment.singleImageResultLauncher$lambda-11(ApplySupportFragment.kt:309) at com.parto.podingo.fragments.ApplySupportFragment.lambda$TH8lRf487SfLh29t7Z8ZnTgTGe4(Unknown Source:0) at com.parto.podingo.fragments.-$$Lambda$ApplySupportFragment$TH8lRf487SfLh29t7Z8ZnTgTGe4.onActivityResult(Unknown Source:4) at androidx.activity.result.ActivityResultRegistry$1.onStateChanged(ActivityResultRegistry.java:148) at androidx.lifecycle.LifecycleRegistry$ObserverWithState.dispatchEvent(LifecycleRegistry.java:354) at androidx.lifecycle.LifecycleRegistry.forwardPass(LifecycleRegistry.java:265) at androidx.lifecycle.LifecycleRegistry.sync(LifecycleRegistry.java:307) at androidx.lifecycle.LifecycleRegistry.moveToState(LifecycleRegistry.java:148) at androidx.lifecycle.LifecycleRegistry.handleLifecycleEvent(LifecycleRegistry.java:134) at androidx.fragment.app.Fragment.performStart(Fragment.java:3026) at androidx.fragment.app.FragmentStateManager.start(FragmentStateManager.java:589) at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:300) at androidx.fragment.app.FragmentStore.moveToExpectedState(FragmentStore.java:112) at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1647) at androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:3128) at androidx.fragment.app.FragmentManager.dispatchStart(FragmentManager.java:3079) at androidx.fragment.app.Fragment.performStart(Fragment.java:3030) at androidx.fragment.app.FragmentStateManager.start(FragmentStateManager.java:589) at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:300) at androidx.fragment.app.FragmentStore.moveToExpectedState(FragmentStore.java:112) at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1647) at androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:3128) at androidx.fragment.app.FragmentManager.dispatchStart(FragmentManager.java:3079) at androidx.fragment.app.FragmentController.dispatchStart(FragmentController.java:262) at androidx.fragment.app.FragmentActivity.onStart(FragmentActivity.java:510) at androidx.appcompat.app.AppCompatActivity.onStart(AppCompatActivity.java:246) at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1436) at android.app.Activity.performStart(Activity.java:8188) at android.app.ActivityThread.handleStartActivity(ActivityThread.java:3565) at android.app.servertransaction.TransactionExecutor.performLifecycleSequence(TransactionExecutor.java:221) at android.app.servertransaction.TransactionExecutor.cycleToPath(TransactionExecutor.java:201) at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:173) at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:97) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2135) at android.os.Handler.dispatchMessage(Handler.java:106) at android.os.Looper.loop(Looper.java:236) at android.app.ActivityThread.main(ActivityThread.java:8056) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:656) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:967)

    opened by prosperian 0
  • How to make FileUtils work for camera ?

    How to make FileUtils work for camera ?

    Hello, my use case is such that getting image from camera is necessary. Is there any reference material on how to modify FileUtils to make it work for camera also. I am not asking for implementation but just some reference/documentation to read up

    Thanks.

    opened by getmlcode 0
  • What is the new file chooser that we should use?

    What is the new file chooser that we should use?

    Since it was deprecated I think it is good if you can also provide a hint in README.md explaining what library we should use or alternatives of this library.

    opened by hendrawd 0
  • java.lang.SecurityException: Permission Denial

    java.lang.SecurityException: Permission Denial

    Caused by: java.lang.SecurityException: Permission Denial: reading com.android.providers.downloads.DownloadStorageProvider uri content://com.android.providers.downloads.documents/document/1103#Intent;launchFlags=0x43;end from pid=28543, uid=11351 requires that you obtain access using ACTION_OPEN_DOCUMENT or related APIs at android.os.Parcel.createException(Parcel.java:1953) at android.os.Parcel.readException(Parcel.java:1921) at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:183) at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:135) at android.content.ContentProviderProxy.query(ContentProviderNative.java:418) at android.content.ContentResolver.query(ContentResolver.java:804)

    opened by sonic154 1
Owner
Paul Burke
Senior Android Developer @Majestykapps
Paul Burke
A file/directory-picker for android. Implemented as a library project.

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

Jonas Kalderstam 711 Dec 27, 2022
[Archived] Highlight the best bits of your app to users quickly, simply, and cool...ly

ShowcaseView The ShowcaseView (SCV) library is designed to highlight and showcase specific parts of apps to the user with a distinctive and attractive

Alex Curran 5.6k Dec 16, 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
Android layout decorators : Injecting custom attributes in layout files, Using decorators to get rid of unnecessary class explosion with custom views

Decor Decor is a library that applies decorators to Android layout with additional attributes without the need to extend and create a custom View for

Mouna Cheikhna 304 Nov 25, 2022
Wizard Pager is a library that provides an example implementation of a Wizard UI on Android, it's based of Roman Nurik's wizard pager (https://github.com/romannurik/android-wizardpager)

Wizard Pager Wizard Pager is a library that provides an example implementation of a Wizard UI on Android, it's based of Roman Nurik's wizard pager (ht

Julián Suárez 520 Nov 11, 2022
This library provides a simple way to add a draggable sliding up panel (popularized by Google Music and Google Maps) to your Android application. Brought to you by Umano.

Note: we are not actively responding to issues right now. If you find a bug, please submit a PR. Android Sliding Up Panel This library provides a simp

Umano: News Read To You 9.4k Dec 31, 2022
Wizard Pager is a library that provides an example implementation of a Wizard UI on Android

Wizard Pager is a library that provides an example implementation of a Wizard UI on Android, it's based of Roman Nurik's wizard pager.

Julián Suárez 520 Nov 11, 2022
A library that provides an implementation of the banner widget from the Material design.

MaterialBanner A banner displays a prominent message and related optional actions. MaterialBanner is a library that provides an implementation of the

Sergey Ivanov 252 Nov 18, 2022
Janishar Ali 2.1k Jan 1, 2023
Xamarin.Android provides open-source bindings of the Android SDK for use with .NET managed languages such as C#

Xamarin.Android Xamarin.Android provides open-source bindings of the Android SDK for use with .NET managed languages such as C#. Build Status Platform

Xamarin 1.8k Jan 5, 2023
Provides 9-patch based drop shadow for view elements. Works on API level 9 or later.

Material Shadow 9-Patch This library provides 9-patch based drop shadow for view elements. Works on API level 14 or later. Target platforms API level

Haruki Hasegawa 481 Dec 19, 2022
The CustomCalendarView provides an easy and customizable calendar to create a Calendar. It dispaly the days of a month in a grid layout and allows to navigate between months

Custom-Calendar-View To use the CustomCalendarView in your application, you first need to add the library to your application. You can do this by eith

Nilanchala Panigrahy 113 Nov 29, 2022
a custom view that provides dragged and scaled

DragScaleCircleView A custom imageview that provides the circle window can be dragged and scaled, crop image. How does it look? Why? Sometimes need to

null 514 Dec 22, 2022
Sentinel is a simple one screen UI which provides a standardised entry point for tools used in development and QA alongside device, application and permissions data.

Sentinel Sentinel is a simple one screen UI that provides standardised entry point for tools used in development and QA alongside device, application

Infinum 29 Dec 12, 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
Android StackBlur is a library that can perform a blurry effect on a Bitmap based on a gradient or radius, and return the result. The library is based on the code of Mario Klingemann.

Android StackBlur Android StackBlur is a library that can perform a blurry effect on a Bitmap based on a gradient or radius, and return the result. Th

Enrique López Mañas 3.6k Dec 29, 2022
Android library providing bread crumbs to the support library fragments.

Hansel And Gretel Android library providing bread crumbs for compatibility fragments. Usage For a working implementation of this project see the sampl

Jake Wharton 163 Nov 25, 2022
Android library used to create an awesome Android UI based on a draggable element similar to the last YouTube graphic component.

Draggable Panel DEPRECATED. This project is not maintained anymore. Draggable Panel is an Android library created to build a draggable user interface

Pedro Vicente Gómez Sánchez 3k Dec 6, 2022
TourGuide is an Android library that aims to provide an easy way to add pointers with animations over a desired Android View

TourGuide TourGuide is an Android library. It lets you add pointer, overlay and tooltip easily, guiding users on how to use your app. Refer to the exa

Tan Jun Rong 2.6k Jan 5, 2023