Skip to content

Instantly share code, notes, and snippets.

@nathanfletcher
Created August 9, 2016 20:40
Show Gist options
  • Save nathanfletcher/bbc999dc663b58c5e42b6802c25aad76 to your computer and use it in GitHub Desktop.
Save nathanfletcher/bbc999dc663b58c5e42b6802c25aad76 to your computer and use it in GitHub Desktop.
This is a simple file chooser class for android
import android.app.Activity;
import android.app.Dialog;
import android.os.Environment;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager.LayoutParams;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;
import java.io.File;
import java.io.FileFilter;
import java.util.Arrays;
public class FileChooser {
private static final String PARENT_DIR = "..";
private final Activity activity;
private ListView list;
private Dialog dialog;
private File currentPath;
// filter on file extension
private String extension = null;
public void setExtension(String extension) {
this.extension = (extension == null) ? null :
extension.toLowerCase();
}
// file selection event handling
public interface FileSelectedListener {
void fileSelected(File file);
}
public FileChooser setFileListener(FileSelectedListener fileListener) {
this.fileListener = fileListener;
return this;
}
private FileSelectedListener fileListener;
public FileChooser(Activity activity) {
this.activity = activity;
dialog = new Dialog(activity);
list = new ListView(activity);
list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override public void onItemClick(AdapterView<?> parent, View view, int which, long id) {
String fileChosen = (String) list.getItemAtPosition(which);
File chosenFile = getChosenFile(fileChosen);
if (chosenFile.isDirectory()) {
refresh(chosenFile);
} else {
if (fileListener != null) {
fileListener.fileSelected(chosenFile);
}
dialog.dismiss();
}
}
});
dialog.setContentView(list);
dialog.getWindow().setLayout(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
refresh(Environment.getExternalStorageDirectory());
}
public void showDialog() {
dialog.show();
}
/**
* Sort, filter and display the files for the given path.
*/
private void refresh(File path) {
this.currentPath = path;
if (path.exists()) {
File[] dirs = path.listFiles(new FileFilter() {
@Override public boolean accept(File file) {
return (file.isDirectory() && file.canRead());
}
});
File[] files = path.listFiles(new FileFilter() {
@Override public boolean accept(File file) {
if (!file.isDirectory()) {
if (!file.canRead()) {
return false;
} else if (extension == null) {
return true;
} else {
return file.getName().toLowerCase().endsWith(extension);
}
} else {
return false;
}
}
});
// convert to an array
int i = 0;
String[] fileList;
if (path.getParentFile() == null) {
fileList = new String[dirs.length + files.length];
} else {
fileList = new String[dirs.length + files.length + 1];
fileList[i++] = PARENT_DIR;
}
Arrays.sort(dirs);
Arrays.sort(files);
for (File dir : dirs) { fileList[i++] = dir.getName(); }
for (File file : files ) { fileList[i++] = file.getName(); }
// refresh the user interface
dialog.setTitle(currentPath.getPath());
list.setAdapter(new ArrayAdapter(activity,
android.R.layout.simple_list_item_1, fileList) {
@Override public View getView(int pos, View view, ViewGroup parent) {
view = super.getView(pos, view, parent);
((TextView) view).setSingleLine(true);
return view;
}
});
}
}
/**
* Convert a relative filename into an actual File object.
*/
private File getChosenFile(String fileChosen) {
if (fileChosen.equals(PARENT_DIR)) {
return currentPath.getParentFile();
} else {
return new File(currentPath, fileChosen);
}
}
}
//...ignoring other code.../
/*Call this method whenever you want to show the file chooser*/
/**
* Tweak method from website*/
private void processFile(){
FileChooser fileChooser = new FileChooser(MainActivity.this);
fileChooser.setFileListener(new FileChooser.FileSelectedListener() {
@Override
public void fileSelected(final File file) {
// ....do something with the file
String filename = file.getAbsolutePath();
Log.i("File Name", filename);
// then actually do something in another module
}
});
// Set up and filter my extension I am looking for
//fileChooser.setExtension("pdf");
fileChooser.showDialog();
}
/*According to documentation from Roger Keays*/
/*new FileChooser(activity).setFileListener(new FileSelectedListener() {
@Override public void fileSelected(final File file) {
// do something with the file
}).showDialog();*/
@xyznaveen
Copy link

Came across this when in need and I cannot thank you enough! 💯

@kan-1337
Copy link

kan-1337 commented Apr 4, 2019

Attempt to get length of null array in the Filechooser

@beegee-tokyo
Copy link

Thanks a lot, exactly what I was looking for.
Only thing I needed to change was
public FileChooser(Activity activity)
into
public FileChooser(Activity activity, String extension, String path)
because I wanted to look only into a specific folder and see only files with specific extension in the first list view.

@Hunte060708
Copy link

Thanks you, itś great. I had a problem: when the dialog was displayed, it did not filter the files based on the file extension. For this, only the method "Refresh (File Path)" had to run, so for example by changing to another folder.

I solved that as follows:
I duplicated the method "refresh (File path)" to a seconds method without variable only using "currentpath" for refreshing. I call this method "(fileChooser.refresh()" directly after "fileChooser.showDialog()".

@Hunte060708
Copy link

Hunte060708 commented Sep 30, 2019

I need help with another problem. When I am at the highest level, ie the root directory of external storage and go to ".." (PARENT_DIR), I get an exception because the app is trying to go up a directory, and it probably can not.
I would like to close the dialogue (dialog.dismiss ()) when this happens, does anyone have any idea where to intercept the exception?

        at de.example.myapp.FileChooser.refresh(FileChooser.java:103)
        at de.example.myapp.FileChooser$1.onItemClick(FileChooser.java:51)
        at android.widget.AdapterView.performItemClick(AdapterView.java:318)
        at android.widget.AbsListView.performItemClick(AbsListView.java:1159)```

EDIT - SOLVED IT: 
```    public FileChooser(Activity activity) {
        this.activity = activity;
        dialog = new Dialog(activity);
        list = new ListView(activity);
        list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override public void onItemClick(AdapterView<?> parent, View view, int which, long id) {
                String fileChosen = (String) list.getItemAtPosition(which);
                if (fileChosen.equalsIgnoreCase(PARENT_DIR) && currentPath.getAbsolutePath().equalsIgnoreCase(startPath.getAbsolutePath())) {
                    dialog.dismiss();
                } else {
                    File chosenFile = getChosenFile(fileChosen);
                    if (chosenFile.isDirectory()) {
                        refresh(chosenFile);
                    } else {
                        if (fileListener != null) {
                            fileListener.fileSelected(chosenFile);
                        }
                        dialog.dismiss();
                    }
                }
            }
        });
        dialog.setContentView(list);
        dialog.getWindow().setLayout(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
        startPath = Environment.getExternalStorageDirectory();
        refresh(startPath);
    }```

The variable "startPath" is defined in FileChooser.java and is only set once you create the dialog as shown above.

@horuscentro
Copy link

        this.activity = activity;
        dialog = new Dialog(activity);
        list = new ListView(activity);
        list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override public void onItemClick(AdapterView<?> parent, View view, int which, long id) {
                String fileChosen = (String) list.getItemAtPosition(which);
                if (fileChosen.equalsIgnoreCase(PARENT_DIR) && currentPath.getAbsolutePath().equalsIgnoreCase(startPath.getAbsolutePath())) {
                    dialog.dismiss();
return;
                } else {
                    File chosenFile = getChosenFile(fileChosen);
                    if (chosenFile.isDirectory()) {
                        refresh(chosenFile);
                    } else {
                        if (fileListener != null) {
                            fileListener.fileSelected(chosenFile);
                        }
                        dialog.dismiss();
                    }
                }
            }
        });
        dialog.setContentView(list);
        dialog.getWindow().setLayout(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
        startPath = Environment.getExternalStorageDirectory();
        refresh(startPath);
    }```

@Daniel63656
Copy link

Environment.getExternalStorageDirectory() is deprecated. Does anybody know how to access the root directory now?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment