• This repository has been archived on 23/Jul/2022
  • Stars
    star
    284
  • Rank 145,616 (Top 3 %)
  • Language
    Java
  • License
    Apache License 2.0
  • Created over 9 years ago
  • Updated over 2 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

a lightweight file/folder chooser or picker

android-file-chooser

Financial Contributors on Open Collective Android Arsenal Download Release Build Status

IMPORTANT:

THIS REPO HAS BEEN STOPPED TO UPDATE TO COMPLY WITH THE NEWER ANDROID LIKE 'Q' AND ABOVE.


android-file-library is a lightweight file/folder chooser.

The usages at HERE, and Acknowledges.

Legacy

1. with AndroidX

dependencies {
	// implementation 'com.github.hedzr:android-file-chooser:1.2.0-SNAPSHOT'
	implementation 'com.github.hedzr:android-file-chooser:v1.2.0-final'
}

MediaStore for Android Q (still in beta)

dependencies {
	implementation 'com.github.hedzr:android-file-chooser:devel-SNAPSHOT'
}

Overview

banner

Demo Application

A demo-app can be installed from Play Store.

Get it on Google Play

Xamarin Binding

A Xamarin nuget package by @Guiorgy can be found at NuGet

Changes

v1.1.19

  • bugs fixed
  • minor fixes for themes
  • #60, #61, #62 fixed
  • revamped Dpad controls
  • added cancelOnTouchOutside and enableDpad (true by default)
  • mainly by Guiorgy.

Archived History:

  • rewrite demo app

  • #48: add displayPath(boolean), thank you @Guiorgy, and your android-smbfile-chooser.

  • new style demo app by @Guiorgy.

  • NOTE: displayPath is true by default now.

  • since v1.1.16, bumped targer sdk to 1.8 (please include the following into your build.gradle)

    android {
        compileOptions {
            sourceCompatibility JavaVersion.VERSION_1_8
            targetCompatibility JavaVersion.VERSION_1_8
        }
    }
  • no WRITE_EXTERNAL_STORAGE requests if not enableOptions(true);

  • after requested permissions, try showing dialog again instead of return directly;

  • #42: onBackPressedListener not fired. Now, use withCancelListener to handle back key. see also below

  • #45: add titleFollowsDir(boolean) to allow title following the change of current directory.

  • create new folder on the fly, and the optional multiple select mode for developer, thx @Guiorgy.

  • Up (..) on the primary storage root will be replaced with .. SDCard, it allows to jump to external storage such as a SDCard and going back available too.

  • DPad supports, arrow keys supports (#30)

Snapshots

More images (beyond v1.1.16) have been found at Gallery

Usages

Configuration

build.gradle

android-file-chooser was released at jcenter, declare deps with:

implementation 'com.obsez.android.lib.filechooser:filechooser:$android_file_chooser_version'

for the newest version(s), looking up the badges above.

taste the fresh

there is a way to taste the master branch with jitpack.io:

  1. add the jitpack repository url to your root build.gradle:
allprojects {
    repositories {
        google()
        jcenter()
        maven { url "https://jitpack.io" }
    }
}
  1. import android-file-chooser
implementation 'com.github.hedzr:android-file-chooser:master-SNAPSHOT'
// implementation 'com.github.hedzr:android-file-chooser:v1.1.14'

Tips for using JitPack.io

To disable gradle local cache in your project, add stretegy into your top build.grable:

configurations.all {
    resolutionStrategy.cacheChangingModulesFor 0, 'seconds'
    resolutionStrategy.cacheDynamicVersionsFor 0, 'seconds'
}

ref: spring-gradle-plugins/dependency-management-plugin#74 (comment)

Sometimes it's right, sometimes ... no more warrants.

Codes

Tips

  1. I am hands down AlertDialog.
  2. Any codes about ChooserDialog, such as the following demo codes, should be only put into UI thread.

FileChooser android library give a simple file/folder chooser in single call (Fluent):

Choose a Folder

    new ChooserDialog(MainActivity.this)
            .withFilter(true, false)
        	.withStartFile(startingDir)
        	// to handle the result(s)
            .withChosenListener(new ChooserDialog.Result() {
                @Override
                public void onChoosePath(String path, File pathFile) {
                    Toast.makeText(MainActivity.this, "FOLDER: " + path, Toast.LENGTH_SHORT).show();
                }
            })
            .build()
            .show();

Choose a File

    new ChooserDialog(MainActivity.this)
            .withStartFile(path)
            .withChosenListener(new ChooserDialog.Result() {
                @Override
                public void onChoosePath(String path, File pathFile) {
                    Toast.makeText(MainActivity.this, "FILE: " + path, Toast.LENGTH_SHORT).show();
                }
            })
        	// to handle the back key pressed or clicked outside the dialog:
        	.withOnCancelListener(new DialogInterface.OnCancelListener() {
    			public void onCancel(DialogInterface dialog) {
			        Log.d("CANCEL", "CANCEL");
			        dialog.cancel(); // MUST have
    			}
			})
            .build()
            .show();

Wild-match

    new ChooserDialog(MainActivity.this)
            .withFilter(false, false, "jpg", "jpeg", "png")
            .withStartFile(path)
            .withResources(R.string.title_choose_file, R.string.title_choose, R.string.dialog_cancel)
            .withChosenListener(new ChooserDialog.Result() {
                @Override
                public void onChoosePath(String path, File pathFile) {
                    Toast.makeText(MainActivity.this, "FILE: " + path, Toast.LENGTH_SHORT).show();
                }
            })
            .build()
            .show();

Regex filter

    new ChooserDialog(MainActivity.this)
            .withFilterRegex(false, false, ".*\\.(jpe?g|png)")
            .withStartFile(path)
            .withResources(R.string.title_choose_file, R.string.title_choose, R.string.dialog_cancel)
            .withChosenListener(new ChooserDialog.Result() {
                @Override
                public void onChoosePath(String path, File pathFile) {
                    Toast.makeText(NewMainActivity.this, "FILE: " + path, Toast.LENGTH_SHORT).show();
                }
            })
            .build()
            .show();

Date Format String

Since 1.1.3, new builder options withDateFormat(String) added.

    new ChooserDialog(MainActivity.this)
            .withFilter(true, false)
            .withStartFile(startingDir)
            .withDateFormat("HH:mm")    // see also SimpleDateFormat format specifiers
            .withChosenListener(new ChooserDialog.Result() {
                @Override
                public void onChoosePath(String path, File pathFile) {
                    Toast.makeText(MainActivity.this, "FOLDER: " + path, Toast.LENGTH_SHORT).show();
                }
            })
            .build()
            .show();

Modify Icon or View Layout of AlertDialog:

Since 1.1.6, 2 new options are available:

    new ChooserDialog(MainActivity.this)
            .withFilter(true, false)
            .withStartFile(startingDir)
            .withIcon(R.drawable.ic_file_chooser)
            .withLayoutView(R.layout.alert_file_chooser) // (API > 20)
            .withChosenListener(new ChooserDialog.Result() {
                @Override
                public void onChoosePath(String path, File pathFile) {
                    Toast.makeText(MainActivity.this, "FOLDER: " + path, Toast.LENGTH_SHORT).show();
                }
            })
            .build()
            .show();

Customizable NegativeButton

1.1.7 or Higher, try withNegativeButton() and/or withNegativeButtonListener()


withOnBackPressedListener

BackPressedListener will be called every time back key is pressed, and current directory is not the root of Primary/SdCard storage. LastBackPressedListener will be called if back key is pressed, and current directory is the root of Primary/SdCard storage.

.withOnBackPressedListener(dialog -> chooserDialog.goBack())
.withOnLastBackPressedListener(dialog -> dialog.cancel())

onCancelListener

OnCancelListener will be called when touching outside the dialog (cancelOnTouchOutside must be set true), and when pressing back key. If BackPressedListener is overridden, it wont be called if dialog.dismiss is used instead of dialog.cancel. OnCancelListener will NOT be called when pressing the negative button. use withNegativeButtonListener for that.

.withOnCancelListener(new DialogInterface.OnCancelListener() {
    public void onCancel(DialogInterface dialog) {
        Log.d("CANCEL", "CANCEL");
    }
})

---

#### New calling chain

1.1.7+, new constructor `ChooserDialog(context)` can simplify the chain invoking. Also `build()` is no longer obligatory to be called:

​```java
    new ChooserDialog(MainActivity.this)
            .withFilter(true, false)
            .withStartFile(startingDir)
            ...
			.show();

And, old style is still available. No need to modify your existing codes.

withRowLayoutView(resId)

1.1.8+. Now you can customize each row.

since 1.1.17, DirAdatper.GetViewListener#getView allows you do the same thing and more, and withRowLayoutView will be deprecated. See also: withAdapterSetter(setter)

withFileIcons

1.1.9+. withFileIcons(resolveMime, fileIcon, folderIcon) and withFileIconsRes(resolveMime, fileIconResId, folderIconResId) allow user-defined file/folder icon.

resolveMime: true means that DirAdapter will try get icon from the associated app with the file's mime type.

    final Context ctx = MainActivity.this;
    new ChooserDialog(ctx)
            .withStartFile(_path)
            .withResources(R.string.title_choose_any_file, R.string.title_choose, R.string.dialog_cancel)
            .withFileIconsRes(false, R.mipmap.ic_my_file, R.mipmap.ic_my_folder)
            .withChosenListener(new ChooserDialog.Result() {
                @Override
                public void onChoosePath(String path, File pathFile) {
                    Toast.makeText(ctx, "FILE: " + path, Toast.LENGTH_SHORT).show();
                }
            })
            .build()
            .show();

withAdapterSetter(setter)

1.1.9+. a AdapterSetter can be use to customize the DirAdapter.

.withAdapterSetter(new ChooserDialog.AdapterSetter() {
    @Override
    public void apply(DirAdapter adapter) {
        adapter.setDefaultFileIcon(fileIcon);
        adapter.setDefaultFolderIcon(folderIcon);
        adapter.setResolveFileType(tryResolveFileTypeAndIcon);
		// since 1.1.17
		adapter.overrideGetView((file, isSelected, isFocused, convertView, parent, inflater) -> {
			ViewGroup view = (ViewGroup) inflater.inflate(R.layout.li_row, parent, false);
			...
			return view;
		}
    }
})

More information in source code of DirAdapter.

since 1.1.17, DirAdapter.overrideGetView() supports GetViewListener interface.

    public interface GetView {
        /**
         * @param file        file that should me displayed
         * @param isSelected  whether file is selected when _enableMultiple is set to true
         * @param isFocused   whether this file is focused when using dpad controls
		 					  deprecated since 1.1.18! use fileListItemFocusedDrawable attribute instead
         * @param convertView see ArrayAdapter#getView(int, View, ViewGroup)
         * @param parent      see ArrayAdapter#getView(int, View, ViewGroup)
         * @param inflater    a layout inflater with the FileChooser theme wrapped context
         * @return your custom row item view
         */
        @NonNull
        View getView(@NonNull File file, boolean isSelected, boolean isFocused, View convertView,
            @NonNull ViewGroup parent, @NonNull LayoutInflater inflater);
    }

withNavigateUpTo(CanNavigateUp)

1.1.10+. withNavigateUpTo

You can disallow someone enter some special directories.

.withNavigateUpTo(new ChooserDialog.CanNavigateUp() {
    @Override
    public boolean canUpTo(File dir) {
        return true;
    }
})

withNavigateTo(CanNavigateTo)

1.1.10+. withNavigateTo

With withStartFile(), you can limit the root folder.

.withNavigateTo(new ChooserDialog.CanNavigateTo() {
    @Override
    public boolean canNavigate(File dir) {
        return true;
    }
})

enableOptions(true)

a tri-dot menu icon will be shown at bottom left corner. this icon button allows end user to create new folder on the fly or delete one.

further tunes:

  • withOptionResources(@StringRes int createDirRes, @StringRes int deleteRes, @StringRes int newFolderCancelRes, @StringRes int newFolderOkRes)

  • withOptionStringResources(@Nullable String createDir, @Nullable String delete, @Nullable String newFolderCancel, @Nullable String newFolderOk)

    since v1.1.17

  • withOptionIcons(@DrawableRes int optionsIconRes, @DrawableRes int createDirIconRes, @DrawableRes int deleteRes)

  • withNewFolderFilter(NewFolderFilter filter)

  • withOnBackPressedListener(OnBackPressedListener listener)

  • withOnLastBackPressedListener(OnBackPressedListener listener)

see the sample codes in demo app.

NOTE:

  1. extra WRITE_EXTERNAL_STORAGE permission should be declared in your AndroidManifest.xml.
  2. we'll ask the extra runtime permission to WRITE_EXTERNAL_STORAGE on Android M and higher too.

disableTitle(true)

as named as working.

psuedo .. SDCard Storage and .. Primary Storage

since v1.11, external storage will be detected automatically. That means user can switch between internal and external storage by clicking on psuedo folder names.

titleFollowsDir(true)

since the latest patch of v1.14, it allows the chooser dialog title updated by changing directory.

displayPath(true), customizePathView(callback)

since the latest patch of v1.15, it allows a path string displayed below the title area.

since v1.16, its default value is true.

Screen Snapshot

As a useful complement, customizePathView(callback) allows tuning the path TextView. For example:

.customizePathView((pathView) -> {
    pathView.setGravity(Gravity.RIGHT);
})

since 1.1.17, this can also be done through a custom theme:

<style name="FileChooserStyle">
	...
	<item name="fileChooserPathViewStyle">@style/FileChooserPathViewStyle</item>
</style>

<style name="FileChooserPathViewStyle">
	<item name="android:background">#ffffffff</item>
	<item name="android:textColor">#40000000</item>
	<item name="android:textSize">12sp</item>
	<item name="fileChooserPathViewElevation">2</item>
	<item name="fileChooserPathViewDisplayRoot">true</item>
</style>

withResources, withStringResources

you can customize the text of buttons:

            .withResources(R.string.title_choose_any_file, R.string.title_choose, R.string.dialog_cancel)
            .withStringResources("Title", "OK", "Cancel")

Under Kotlin

class MyFragment : Fragment() {

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
                              savedInstanceState: Bundle?): View? {
        val root = inflater.inflate(R.layout.fragment_book, container, false)
        root.upload_button.setOnClickListener { _: View ->
            ChooserDialog().with(activity)
                    .withStartFile(Environment.getExternalStorageDirectory().absolutePath)
                    // .withStartFile(Environment.getExternalStorageState()+"/")
                    .withFilterRegex(false, false, ".*\\.(jpe?g|png)")
                    .titleFollowsDir(true)
                    .displayPath(true)
                    .customizePathView{ pathView -> pathView.setGravity(Gravity.RIGHT) }
                    .withChosenListener { path, pathFile -> activity!!.toast("FILE: $path / $pathFile") }
                    .build()
                    .show()
        }

        return root
    }
}

And:

        ChooserDialog(context)
                .withFilterRegex(false, true, ".*\\.(jpe?g|png)")
                .withStartFile(startPath)
                .withResources(R.string.title_choose_file, R.string.title_choose, R.string.dialog_cancel)
                .withChosenListener { path, pathFile ->
                    Toast.makeText(context, "FILE: $path; PATHFILE: $pathFile", Toast.LENGTH_SHORT).show()

                    //_path = path
                    //_tv.setText(_path)
                    ////_iv.setImageURI(Uri.fromFile(pathFile));
                    //_iv.setImageBitmap(ImageUtil.decodeFile(pathFile))
                }
                .withNavigateUpTo { true }
                .withNavigateTo { true }
                .build()
                .show()

For Library Developers

Just fork and build me currently.

Contrib

Contributions and translations are welcome.

Feedback

feel free to make a new issue.

Acknowledges

many peoples report or contribute to improve me, but only a few of them be put here — it's hard to list all.

Contributors

Code Contributors

This project exists thanks to all the people who contribute. [Contribute].

Financial Contributors

Become a financial contributor and help us sustain our community. [Contribute]

Individuals

Organizations

Support this project with your organization. Your logo will show up here with a link to your website. [Contribute]

License

Standard Apache 2.0

Copyright 2015-2019 Hedzr Yeh.

More Repositories

1

mirror-list

list of Chinese mainland mirrors
Makefile
159
star
2

cmdr

POSIX-compliant command-line UI (CLI) parser and Hierarchical-configuration operations
Go
135
star
3

go-ringbuf

Lock-free MPMC Ring Buffer (Generic) for SMP, in golang. Some posts in chinese:
Go
80
star
4

docker-compose-file-format

Translation of docker-compose file format, įŧ–æŽ’č¯­æŗ•č¯‘æ–‡ v3.8
27
star
5

cmdr-cxx

cmdr cxx version, a C++17 header-only command-line parser with hierarchical config data manager here
C++
17
star
6

fsm-cxx

a finite state machine within c++17
C++
14
star
7

lb

concurrent load balancers, go lib,
Go
13
star
8

consul-tags

A CLI tool to Update, add, remove the service tags at consul store.
Go
12
star
9

bash.sh

main entry template of your first bash script file
Shell
11
star
10

progressbar

A task-based terminal progress bar in golang, with a python rich-like progressbar. Integrated more styles.
Go
11
star
11

awesome-tool

a command-line tool to retrieve the stars of all repos in an awesome-list
Go
10
star
12

pxe-server-and-focal

files for [build-pxe-server-and-autoinstall-ubuntu-server]
Shell
10
star
13

evendeep

Per-field copying deeply, and comparing deeply abilities: deepcopy, deepdiff and more...
Go
7
star
14

ini-op

small command-line tool to read/write inifile. it's used by my `git-submodule-rm` script
Go
7
star
15

errors

Nestable/wrappable golang errors library.
Go
7
star
16

design-patterns-cxx

exercises about design patterns, in c++17
C++
6
star
17

bgo

make go building easier: an efficient and extensible tool for go apps
Go
6
star
18

undo-cxx

a c++17 undo/redo subsystem (linear or restricted non-linear)
CMake
6
star
19

store

extensible, high-performance configuration management library, optimized for hierarchical data
Go
5
star
20

Cmdr.Core

Useful POSIX command line arguments parser for .Net. Hierarchical-configuration Store for app.
C#
5
star
21

ticker-cxx

c++17 timing and trigger abilities
C++
5
star
22

logex

an enhanced over logrus/zap. `logex` attaches the caller info to the logging output.
Go
4
star
23

Mdx.Core

loading mdx/mdd (MDict) file format with dotnetcore, legacy codes
C#
4
star
24

meijue-ui

an android kotlin extension library
Kotlin
4
star
25

go-faker

faked records generator. A CLI app for generating the faked records such as names, addresses, and phone numbers.
Go
4
star
26

hio

Enhanced Http Client for Dart/Flutter.
Dart
3
star
27

bash-framework

minimal starting of bash programming
Shell
3
star
28

hicc

hi, cc! hicc is a c++ template class library to provide some basic data structures and algorithms
C++
3
star
29

go-socketlib

A simple, fast approach to implement your communication protocol.
Go
3
star
30

hedzr.github.io

main gh io pages and sites
HTML
3
star
31

rate

rate limit library in golang
Go
3
star
32

cmdr-http2

a http2 server with `cmdr` full daemon supports and graceful shutdown.
Go
2
star
33

zag-common

Java
2
star
34

pools

golang connection pool, task pool, and jobs scheduler, ...
Go
2
star
35

zag-servers

prototype of microservice system / æœåŠĄæ˛ģį†å’Œį°åēĻ发布įŗģįģŸį ”发原型
Java
2
star
36

ansible-k8s

maintain k8s ha cluster via ansible
Jinja
2
star
37

deb-build-tutor

stuffs about building a deb file
Shell
2
star
38

log

Minimal logging interface without other dependencies, basics common codes: dir,exec,detects,pheripheral,...
Go
2
star
39

cmdr-addons

helpers for go `cmdr`
Go
2
star
40

study-cmake

the demo project for cmake-hello posts
CMake
2
star
41

zsh-extras

personal terminal initial files
Shell
2
star
42

cmdr-docs

documentation for hedzr/cmdr (SIP)
Shell
2
star
43

is

go lib to provide a set of minimal environ container and detectors
Go
2
star
44

mac-sparse-disk.sh

A bash utility to operate a .sparsebundle file
Shell
1
star
45

vscode-ext-zig-main-runner

run or debug a zig main function in-place
TypeScript
1
star
46

mk

Utilities or Helpers for improving your Makefile
Makefile
1
star
47

vscode-ext-go-main-runner

run or debug a golang main function in-place
TypeScript
1
star
48

docker-basics

basic docker images of mine
Makefile
1
star
49

kvl

simple golang kvstore abstract layer
Go
1
star
50

sphinx-study

a notebook for studying sphinx documenter
JavaScript
1
star
51

cmdr-examples

The example apps for go `cmdr` project
Go
1
star
52

sql-xx-core-demo

part of mysql 5.x sql parser
C++
1
star
53

rules

1
star
54

list.dos

list, a DOS text file browser by Vernon D. Buerg
Assembly
1
star
55

kcxt

kotlin context-awareness library for android libraries or applications
Kotlin
1
star
56

bsd3-1

1
star
57

sphinx-builder

extending official sphinx docker image with usesful plugins
Dockerfile
1
star
58

logg

colored logger with log/slog like api
Go
1
star