Один из шагов при создании моего приложения - позволить пользователю выбрать папку, в которой хранятся некоторые файлы. Как я могу сделать эту конфигурацию без жесткого кодирования каталога. Есть ли сторонняя библиотека, которую я могу использовать для этого?
Android - настраиваемый каталог?
Ответ 1
Ссылка @Vikram предоставляет диалоговое окно, которое вы можете использовать. Затем вы можете сохранить каталог, который выбрал пользователь, используя Общие настройки.
Здесь - простой пример того, как использовать общие настройки.
Еще один учебник можно найти здесь.
UPDATE: В меня внезапно включился переключатель, чтобы сделать что-то вроде этого. Кредиты по-прежнему идут в schwiz в этом ответе для используемого базового кода.:)
//global variables
private File[] fileList;
private String[] filenameList;
private File[] loadFileList(String directory) {
File path = new File(directory);
if(path.exists()) {
FilenameFilter filter = new FilenameFilter() {
public boolean accept(File dir, String filename) {
//add some filters here, for now return true to see all files
//File file = new File(dir, filename);
//return filename.contains(".txt") || file.isDirectory();
return true;
}
};
//if null return an empty array instead
File[] list = path.listFiles(filter);
return list == null ? new File[0] : list;
} else {
return new File[0];
}
}
public void showFileListDialog(final String directory, final Context context) {
Dialog dialog = null;
AlertDialog.Builder builder = new Builder(context);
File[] tempFileList = loadFileList(directory);
//if directory is root, no need to up one directory
if(directory.equals("/")) {
fileList = new File[tempFileList.length];
filenameList = new String[tempFileList.length];
//iterate over tempFileList
for(int i = 0; i < tempFileList.length; i++) {
fileList[i] = tempFileList[i];
filenameList[i] = tempFileList[i].getName();
}
} else {
fileList = new File[tempFileList.length+1];
filenameList = new String[tempFileList.length+1];
//add an "up" option as first item
fileList[0] = new File(upOneDirectory(directory));
filenameList[0] = "..";
//iterate over tempFileList
for(int i = 0; i < tempFileList.length; i++) {
fileList[i+1] = tempFileList[i];
filenameList[i+1] = tempFileList[i].getName();
}
}
builder.setTitle("Choose your file: " + directory);
builder.setItems(filenameList, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
File chosenFile = fileList[which];
if(chosenFile.isDirectory()) {
showFileListDialog(chosenFile.getAbsolutePath(), context);
}
}
});
builder.setNegativeButton("Cancel", new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
dialog = builder.create();
dialog.show();
}
public String upOneDirectory(String directory) {
String[] dirs = directory.split(File.separator);
StringBuilder stringBuilder = new StringBuilder("");
for(int i = 0; i < dirs.length-1; i++) {
stringBuilder.append(dirs[i]).append(File.separator);
}
return stringBuilder.toString();
}
Приведенный выше код действует как мини файловый проводник, в котором перечислены файлы и папки файловой системы Android. Вы используете его как:
showFileListDialog(Environment.getExternalStorageDirectory().toString(),
MainActivity.this);
Отвечая на ваш вопрос: Добавить глобальные ключевые переменные
//package name goes here.
public static final String PACKAGE_NAME = "com.example.app";
public static final String KEY_DIRECTORY_SELECTED =
PACKAGE_NAME + ".DIRECTORY_SELECTED";
private SharedPreferences prefs;
инициализируйте свои SharedPreferences где-нибудь в onCreate, прежде чем использовать его:
prefs = getSharedPreferences(PACKAGE_NAME, Context.MODE_PRIVATE);
а затем вы можете добавить положительную кнопку в диалог
builder.setPositiveButton("Save Directory", new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
prefs.edit().putString(KEY_DIRECTORY_SELECTED, directory).commit();
}
});
В вашей деятельности вместо использования каталога по умолчанию SDCard вы можете
//if no saved directory yet, use SDCard directory as default
String oldChosenDirectory = prefs.getString(KEY_DIRECTORY_SELECTED,
Environment.getExternalStorageDirectory().toString());
showFileListDialog(oldChosenDirectory, MainActivity.this);
Как отметил Викрам. вам также нужно сделать это в своем FileNameFilter, чтобы в диалоговом окне отображались только каталоги.
Обновление: как указано в этом SO-ответе, параметры dir
и filename
не относятся к одному и тому же файлу. Параметр dir
- это каталог, содержащий файл, а filename
- имя файла самого файла. Чтобы определить, является ли сама filte каталогом, нам нужно создать новый файл из таких параметров:
FilenameFilter filter = new FilenameFilter() {
public boolean accept(File dir, String filename) {
File file = new File(dir.getAbsolutePath() + File.separator + filename);
return file.isDirectory();
}
};