【问题标题】:Android - Configurable directory?Android - 可配置目录?
【发布时间】:2013-09-02 14:03:26
【问题描述】:

构建我的应用程序的步骤之一是让用户选择一个文件夹来存储一些文件。我怎样才能使它可配置,而无需对目录进行硬编码。我可以使用任何第三方库来执行此操作吗?

【问题讨论】:

  • 这应该给你一些选择:Choose File Dialog。您也可以自己实现此功能。这很简单。
  • 这个对话框太酷了,我对其进行了调整,因此您可以将其用作迷你文件浏览器。稍后将发布代码,需要先对其进行重构。 :)

标签: android android-intent


【解决方案1】:

@Vikram 的链接提供了一个您可以使用的对话框。然后,您可以使用Shared Preferences 保存用户选择的目录。

Here 是一个关于如何使用共享首选项的简单示例。

另一个教程可以找到here

更新:我内心突然打开了一个开关来做这样的事情。对于所使用的基本代码,学分仍归 this answer 中的 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;

在使用之前在 onCreate 的某处初始化您的 SharedPreferences:

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 中执行此操作,以便对话框仅显示目录。

更新:如this SO answer 中所述,参数dirfilename 不引用同一个文件。 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();
    }
};

【讨论】:

  • 优秀的帖子。 +1。一个问题:OP 想要to let the user select a folder。所以,FilenameFilter.accept() 应该返回 file.isDirectory()
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-03-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-07
  • 1970-01-01
相关资源
最近更新 更多