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();*/
@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