Android - Configurable directory?

前端 未结 1 1936
面向向阳花
面向向阳花 2021-01-07 07:09

One of the steps in building my app is to let the user select a folder in which some files are stored. How can i make this configurable, without hardcoding the directory. Is

相关标签:
1条回答
  • 2021-01-07 07:30

    @Vikram's link provides a dialog that you can use. You can then save the directory the user chose using Shared Preferences.

    Here is a simple example on how to use Shared Preferences.

    Another tutorial can be found here.

    UPDATE: A switch suddenly turned on inside me to do something like this. Credits still go to schwiz in this answer for the base code used. :)

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

    The code above acts like a mini file explorer that lists the files and folders of the Android File System. You use it like:

    showFileListDialog(Environment.getExternalStorageDirectory().toString(),
        MainActivity.this);
    

    Answering your question: Add global key variables

    //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;
    

    initialize your SharedPreferences somewhere on onCreate before you use it:

    prefs = getSharedPreferences(PACKAGE_NAME, Context.MODE_PRIVATE);
    

    and then you can add a positive button to the dialog

    builder.setPositiveButton("Save Directory", new OnClickListener() {
    
        @Override
        public void onClick(DialogInterface dialog, int which) {
            prefs.edit().putString(KEY_DIRECTORY_SELECTED, directory).commit();
        }
    });
    

    In your activity, instead of using the SDCard default directory you can

    //if no saved directory yet, use SDCard directory as default
    String oldChosenDirectory = prefs.getString(KEY_DIRECTORY_SELECTED,
        Environment.getExternalStorageDirectory().toString());
    showFileListDialog(oldChosenDirectory, MainActivity.this);
    

    As Vikram pointed out. you also need to do this in your FileNameFilter so that the dialog will display directories ONLY.

    Update: As noted in this SO answer, the parameters dir and filename does not refer to the same file. The dir parameter is the directory containing the file, while filename is the filename of the file itself. To determine whether the filte itself is a directory, we need to create a new file from the parameters like so:

    FilenameFilter filter = new FilenameFilter() {
        public boolean accept(File dir, String filename) {
            File file = new File(dir.getAbsolutePath() + File.separator + filename);
            return file.isDirectory();
        }
    };
    
    0 讨论(0)
提交回复
热议问题