package de.qspool.clementineremote.ui.dialogs; import com.afollestad.materialdialogs.DialogAction; import com.afollestad.materialdialogs.MaterialDialog; import android.app.Activity; import android.app.Dialog; import android.os.Environment; import android.util.Log; import android.view.View; import android.widget.Toast; import java.io.File; import java.io.FilenameFilter; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Locale; import de.qspool.clementineremote.R; public class FileDialog { private static final String PARENT_DIR = ".."; private final String TAG = getClass().getSimpleName(); private String[] fileList; private File currentPath; private boolean checkIfWritable = false; public interface FileSelectedListener { void fileSelected(File file); } public interface DirectorySelectedListener { void directorySelected(File directory); } private ListenerList<FileSelectedListener> fileListenerList = new ListenerList<>(); private ListenerList<DirectorySelectedListener> dirListenerList = new ListenerList<>(); private final Activity activity; private boolean selectDirectoryOption; private String fileEndsWith; public FileDialog(Activity activity, File path) { this.activity = activity; if (!path.exists()) { path = Environment.getExternalStorageDirectory(); } if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { loadFileList(path); } } /** * @return file dialog */ public Dialog createFileDialog() { MaterialDialog.Builder builder = new MaterialDialog.Builder(activity); builder.title(currentPath.getPath()); if (selectDirectoryOption) { builder.positiveText(activity.getString(R.string.file_dialog_set_dir)); builder.negativeText(activity.getString(R.string.dialog_close)); } builder.items(fileList); builder.itemsCallback(new MaterialDialog.ListCallback() { @Override public void onSelection(MaterialDialog materialDialog, View view, int i, CharSequence charSequence) { String fileChosen = fileList[i]; File chosenFile = getChosenFile(fileChosen); if (chosenFile.isDirectory()) { loadFileList(chosenFile); showDialog(); } else { fireFileSelectedEvent(chosenFile); } } }); builder.onPositive(new MaterialDialog.SingleButtonCallback() { @Override public void onClick(MaterialDialog dialog, DialogAction which) { if (isCheckIfWritable()) { // Check the external store state File checkFile = new File( currentPath.getAbsolutePath() + "/ClementineTestFile.CheckIfWritable"); try { if (checkFile.createNewFile()) checkFile.delete(); Log.d(TAG, checkFile.getAbsolutePath() + " is writable"); dialog.dismiss(); fireDirectorySelectedEvent(currentPath); } catch (IOException e) { Toast.makeText(activity, R.string.file_dialog_not_writable, Toast.LENGTH_LONG).show(); } } else { fireDirectorySelectedEvent(currentPath); dialog.dismiss(); } } }); return builder.show(); } public void addFileListener(FileSelectedListener listener) { fileListenerList.add(listener); } public void removeFileListener(FileSelectedListener listener) { fileListenerList.remove(listener); } public void setSelectDirectoryOption(boolean selectDirectoryOption) { this.selectDirectoryOption = selectDirectoryOption; } public void addDirectoryListener(DirectorySelectedListener listener) { dirListenerList.add(listener); } public void removeDirectoryListener(DirectorySelectedListener listener) { dirListenerList.remove(listener); } /** * Show file dialog */ public void showDialog() { createFileDialog(); } private void fireFileSelectedEvent(final File file) { fileListenerList.fireEvent(new FireHandler<FileDialog.FileSelectedListener>() { public void fireEvent(FileSelectedListener listener) { listener.fileSelected(file); } }); } private void fireDirectorySelectedEvent(final File directory) { dirListenerList.fireEvent(new FireHandler<FileDialog.DirectorySelectedListener>() { public void fireEvent(DirectorySelectedListener listener) { listener.directorySelected(directory); } }); } private void loadFileList(File path) { this.currentPath = path; List<String> r = new ArrayList<>(); if (path.exists()) { if (path.getParentFile() != null) { r.add(PARENT_DIR); } FilenameFilter filter = new FilenameFilter() { public boolean accept(File dir, String filename) { File sel = new File(dir, filename); if (!sel.canRead()) { return false; } if (selectDirectoryOption) { return sel.isDirectory(); } else { boolean endsWith = fileEndsWith == null || filename .toLowerCase(Locale.getDefault()).endsWith(fileEndsWith); return endsWith || sel.isDirectory(); } } }; String[] fileList1 = path.list(filter); if (fileList1 != null) { Collections.addAll(r, fileList1); } } Collections.sort(r); fileList = r.toArray(new String[]{}); } private File getChosenFile(String fileChosen) { if (fileChosen.equals(PARENT_DIR)) { return currentPath.getParentFile(); } else { return new File(currentPath, fileChosen); } } public void setFileEndsWith(String fileEndsWith) { this.fileEndsWith = fileEndsWith != null ? fileEndsWith.toLowerCase(Locale.getDefault()) : fileEndsWith; } public boolean isCheckIfWritable() { return checkIfWritable; } public void setCheckIfWritable(boolean checkIfWritable) { this.checkIfWritable = checkIfWritable; } public interface FireHandler<L> { void fireEvent(L listener); } class ListenerList<L> { private List<L> listenerList = new ArrayList<>(); public void add(L listener) { listenerList.add(listener); } public void fireEvent(FireHandler<L> fireHandler) { List<L> copy = new ArrayList<>(listenerList); for (L l : copy) { fireHandler.fireEvent(l); } } public void remove(L listener) { listenerList.remove(listener); } public List<L> getListenerList() { return listenerList; } } }