android-file-library
is a lightweight file/folder chooser.
A demo-app can be installed from Play Store.
- In progress
- uses AndroidX
- Done:
- Keyboard supports: process SPACE and ENTER up event;
- file list no focus when dailog first showing;
- better storage media detect algorithm for Android M+;
- no WRITE_EXTERNAL_STORAGE requests if not
enableOptions(true)
; - after requested permissions, try showing dialog again instead of return directly;
-
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
- create new folder on the fly, and the optional multiple select mode for developer, thx Guiorgy and his android-smbfile-chooser
- 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)
- ...
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.
there is a way to taste the master
branch with jitpack.io:
- add the jitpack repository url to your root build.gradle:
allprojects {
repositories {
google()
jcenter()
maven { url "https://jitpack.io" }
}
}
- import
android-file-chooser
implementation 'com.github.hedzr:android-file-chooser:master-SNAPSHOT'
// implementation 'com.github.hedzr:android-file-chooser:v1.1.10'
FileChooser android library give a simple file/folder chooser in single call:
new ChooserDialog().with(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();
new ChooserDialog().with(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();
new ChooserDialog().with(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();
new ChooserDialog().with(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();
Since 1.1.3, new builder options withDateFormat(String)
added.
new ChooserDialog().with(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();
Since 1.1.6, 2 new options are available:
new ChooserDialog().with(this)
.withFilter(true, false)
.withStartFile(startingDir)
.withIcon(R.drawable.ic_file_chooser)
.withLayoutView(R.layout.alert_file_chooser)
.withChosenListener(new ChooserDialog.Result() {
@Override
public void onChoosePath(String path, File pathFile) {
Toast.makeText(MainActivity.this, "FOLDER: " + path, Toast.LENGTH_SHORT).show();
}
})
.build()
.show();
1.1.7 or Higher, try withNegativeButton()
and withNegativeButtonListener()
instead of withOnBackPressedListener()
.
deprecated.
onCancelListener
will be triggered on back pressed or clicked outside of dialog.
You MUST invoke dialog.cancel()
while override the default onCancelListener
:
.withOnCancelListener(new DialogInterface.OnCancelListener() {
public void onCancel(DialogInterface dialog) {
Log.d("CANCEL", "CANCEL");
dialog.cancel(); // MUST have
}
})
1.1.7+, new constructor ChooserDialog(context)
can simplify the chain invoking, such as:
new ChooserDialog(this)
.withFilter(true, false)
.withStartFile(startingDir)
...
And, old style is still available. No need to modify your existing codes.
1.1.8+. Now you can customize each row.
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.
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();
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);
}
})
1.1.10+. withNavigateUpTo
.withNavigateUpTo(new ChooserDialog.CanNavigateUp() {
@Override
public boolean canUpTo(File dir) {
return true;
}
})
1.1.10+. withNavigateTo
.withNavigateTo(new ChooserDialog.CanNavigateTo() {
@Override
public boolean canNavigate(File dir) {
return 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)
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:
- extra
WRITE_EXTERNAL_STORAGE
permission should be declared in yourAndroidManifest.xml
. - we'll ask the extra runtime permission to
WRITE_EXTERNAL_STORAGE
on Android M and higher too.
as named as working.
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)")
.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()
cat >keystore.properties<<EOF
keyAlias=youKeyAlias
keyPassword=password
storeFile=/Users/me/android-file-chooser.keystore
storePassword=password
EOF
git clone [email protected]:hedzr/android-file-chooser.git somewhere
cd somewhere
./gradlew assembleDebug
you'd better generate a new file android-file-chooser.keystore
at homedir or else. such as: keytool -genkey -alias android.keystore -keyalg RSA -validity 20000 -keystore android.keystore
, see also Sign an app.
Or, erase the KS_PATH
lines and signature section in app/build.gradle.
just fork and build me currently.
Contributions and translations are welcome.
feel free to make an new issue.
many peoples report or contribute to improve me, but only a few of them be put here — it's hard to list all.
- logo and banner by: iqbalhood
- codes and reports: bostrot, SeppPenner, lucian-cm, ghost, UmeshBaldaniya46, Guiorgy ...
- DPad s
Copyright 2015-2018 Hedzr Yeh.
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.