简体   繁体   中英

How can I tell if the selected index in a ListView is a file or directory?

I have an Activity with a ListView. am using Apache FTP Commons to connect and populate the ListView with files and directories. How can I determine if the selected item is a file or directory?

public void onCreate(Bundle icicle) {
        super.onCreate(icicle);
        setContentView(R.layout.ftp);

        editAddress = (EditText) findViewById(R.id.editAddress);
        editUser = (EditText) findViewById(R.id.editUsername);
        editPassword = (EditText) findViewById(R.id.editPassword);
        remote = (ListView) findViewById(R.id.localList);
        itla.setListItems(directoryEntries);
        remote.setAdapter(itla);

        remote.setOnItemClickListener(this);
        connect = (ToggleButton) findViewById(R.id.connectButton);
        connect.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            public void onCheckedChanged(CompoundButton buttonView,
                    boolean isChecked) {
                address = editAddress.getText().toString();
                user = editUser.getText().toString();
                pass = editPassword.getText().toString();
                ftpConnect(address, user,pass, 21);
            }
        });

    }

    public boolean ftpConnect(String host, String username, String password,
            int port) {
        try {
            mFTPClient = new FTPClient();
            // connecting to the host
            mFTPClient.connect(host, port);

            // now check the reply code, if positive mean connection success
            if (FTPReply.isPositiveCompletion(mFTPClient.getReplyCode())) {
                // login using username & password
                boolean status = mFTPClient.login(username, password);

                /*
                 * Set File Transfer Mode
                 * 
                 * To avoid corruption issue you must specified a correct
                 * transfer mode, such as ASCII_FILE_TYPE, BINARY_FILE_TYPE,
                 * EBCDIC_FILE_TYPE .etc. Here, I use BINARY_FILE_TYPE for
                 * transferring text, image, and compressed files.
                 */
                mFTPClient.setFileType(FTP.BINARY_FILE_TYPE);
                mFTPClient.enterLocalPassiveMode();

                ftpPrintFilesList(ftpGetCurrentWorkingDirectory());
                return status;
            }
        } catch (Exception e) {
            // Log.d(TAG, "Error: could not connect to host " + host );
        }

        return false;
    }

    public boolean ftpDisconnect() {
        try {
            mFTPClient.logout();
            mFTPClient.disconnect();
            return true;
        } catch (Exception e) {
            // Log.d(TAG,
            // "Error occurred while disconnecting from ftp server.");
        }

        return false;
    }

    public String ftpGetCurrentWorkingDirectory() {
        try {
            String workingDir = mFTPClient.printWorkingDirectory();
            return workingDir;
        } catch (Exception e) {
            // Log.d(TAG, "Error: could not get current working directory.");
        }

        return null;
    }

    public boolean ftpChangeDirectory(String directory_path) {
        try {
            return mFTPClient.changeWorkingDirectory(directory_path);
        } catch (Exception e) {
            // Log.d(TAG, "Error: could not change directory to " +
            // directory_path);
        }

        return false;
    }

    public void ftpPrintFilesList(String dir_path) {
        try {
            FTPFile[] ftpFiles = mFTPClient.listFiles(dir_path);
            int length = ftpFiles.length;

            for (int i = 0; i < length; i++) {
                File name = new File(ftpFiles[i].getName());
                boolean isFile = ftpFiles[i].isFile();
                boolean isDirectory = ftpFiles[i].isDirectory();
                if (isDirectory) {
                    Drawable currentIcon = getResources().getDrawable(
                            R.drawable.folder);
                    directoryEntries.add(new IconifiedText(name, currentIcon));

                    // Log.i(TAG, "File : " + name);
                } else if (isFile) {
                    Drawable currentIcon = getResources().getDrawable(
                            R.drawable.mimetxt);
                    directoryEntries.add(new IconifiedText(name, currentIcon));
                    // Log.i(TAG, "Directory : " + name);
                }
                Collections.sort(this.directoryEntries);
                itla.setListItems(directoryEntries);
                remote.setAdapter(itla);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onItemClick(AdapterView<?> adapter, View view, int position,
            long id) {
        String selectedFile = directoryEntries.get(position).getText();
        try {
            ftpPrintFilesList(selectedFile);
            itla.notifyDataSetChanged();
        } catch (NullPointerException e) {

        }
        Toast.makeText(FTPConnector.this, selectedFile, Toast.LENGTH_LONG)
                .show();

    }
}

The Toast returns the correct file name.

Here is the complete code using Backslash's suggestion for anyone who might find it useful.

public class FTPConnector extends Activity implements OnItemClickListener {

    public ListView remote;
    public ArrayAdapter<String> adapter;
    public FTPClient mFTPClient = null;
    public ToggleButton connect;
    public EditText editAddress;
    private String address;
    public String currentDirectory = "/";
    public EditText editUser;
    private String user;

    public EditText editPassword;
    private String pass;
    public File[] fileList;
    public HashMap<String, Boolean> map = new HashMap<String, Boolean>();

    private List<IconifiedText> directoryEntries = new ArrayList<IconifiedText>();
    private IconifiedTextListAdapter itla = new IconifiedTextListAdapter(this);
    public String[] files;

    public void onCreate(Bundle icicle) {
        super.onCreate(icicle);
        setContentView(R.layout.ftp);

        editAddress = (EditText) findViewById(R.id.editAddress);
        editUser = (EditText) findViewById(R.id.editUsername);
        editPassword = (EditText) findViewById(R.id.editPassword);
        remote = (ListView) findViewById(R.id.remoteList);
        itla.setListItems(directoryEntries);
        remote.setAdapter(itla);

        remote.setOnItemClickListener(this);
        connect = (ToggleButton) findViewById(R.id.connectButton);
        connect.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            public void onCheckedChanged(CompoundButton buttonView,
                    boolean isChecked) {
                if (isChecked) {
                    address = editAddress.getText().toString();
                    user = editUser.getText().toString();
                    pass = editPassword.getText().toString();
                    ftpConnect(address, user,
                            pass, 21);
                } else {
                    ftpDisconnect();
                    directoryEntries.clear();
                    itla.notifyDataSetChanged();
                }
            }
        });

    }

    public boolean ftpConnect(String host, String username, String password,
            int port) {
        try {
            mFTPClient = new FTPClient();
            // connecting to the host
            mFTPClient.connect(host, port);

            // now check the reply code, if positive mean connection success
            if (FTPReply.isPositiveCompletion(mFTPClient.getReplyCode())) {
                // login using username & password
                boolean status = mFTPClient.login(username, password);

                /*
                 * Set File Transfer Mode
                 * 
                 * To avoid corruption issue you must specified a correct
                 * transfer mode, such as ASCII_FILE_TYPE, BINARY_FILE_TYPE,
                 * EBCDIC_FILE_TYPE .etc. Here, I use BINARY_FILE_TYPE for
                 * transferring text, image, and compressed files.
                 */
                mFTPClient.setFileType(FTP.BINARY_FILE_TYPE);
                mFTPClient.enterLocalPassiveMode();

                ftpPrintFilesList(ftpGetCurrentWorkingDirectory());
                return status;
            }
        } catch (Exception e) {
            // Log.d(TAG, "Error: could not connect to host " + host );
        }

        return false;
    }

    public boolean ftpDisconnect() {
        try {
            mFTPClient.logout();
            mFTPClient.disconnect();
            return true;
        } catch (Exception e) {
            // Log.d(TAG,
            // "Error occurred while disconnecting from ftp server.");
        }

        return false;
    }

    public String ftpGetCurrentWorkingDirectory() {
        try {
            String workingDir = mFTPClient.printWorkingDirectory();
            return workingDir;
        } catch (Exception e) {
            // Log.d(TAG, "Error: could not get current working directory.");
        }

        return null;
    }

    public boolean ftpChangeDirectory(String directory_path) {
        try {
            return mFTPClient.changeWorkingDirectory(directory_path);
        } catch (Exception e) {
            // Log.d(TAG, "Error: could not change directory to " +
            // directory_path);
        }

        return false;
    }

    public void ftpPrintFilesList(String dir_path) {
        map.clear();
        try {
            FTPFile[] ftpFiles = mFTPClient.listFiles(dir_path);
            int length = ftpFiles.length;

            for (int i = 0; i < length; i++) {
                File name = new File(ftpFiles[i].getName());
                boolean isFile = ftpFiles[i].isFile();
                boolean isDirectory = ftpFiles[i].isDirectory();
                if (isDirectory) {
                    Drawable currentIcon = getResources().getDrawable(
                            R.drawable.folder);
                    directoryEntries.add(new IconifiedText(name, currentIcon));
                    map.put(ftpFiles[i].getName(),
                            Boolean.valueOf(ftpFiles[i].isDirectory()));
                    // Log.i(TAG, "File : " + name);
                } else if (isFile) {
                    Drawable currentIcon = getResources().getDrawable(
                            R.drawable.mimetxt);
                    directoryEntries.add(new IconifiedText(name, currentIcon));
                    map.put(ftpFiles[i].getName(),
                            Boolean.valueOf(ftpFiles[i].isFile()));
                    // Log.i(TAG, "Directory : " + name);
                }
                Collections.sort(this.directoryEntries);
                itla.setListItems(directoryEntries);
                remote.setAdapter(itla);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onItemClick(AdapterView<?> adapter, View view, int position,
            long id) {

        String selectedFile = directoryEntries.get(position).getText();
        boolean isDirectory = map.get(selectedFile).booleanValue();
        if (isDirectory) {
            directoryEntries.clear();
            itla.notifyDataSetChanged();
            ftpPrintFilesList(selectedFile);
        } else if (!isDirectory) {
            Toast.makeText(FTPConnector.this, selectedFile, Toast.LENGTH_LONG)
                    .show();
        }

    }
}

When you use a FTPClient by Apache Commons Net, if you list a directory the client will send you back an array of FTPFile s. Each FTPFile has a isDirectory() and isFile() method that can tell you if it is a directory or a file.

Apache Commons FTPFile JavaDoc

So you basically need to find which file has the selected name in your list (maybe serching in it using the getName() function?) and then use one of the two methods provided in the FTPFile class

UPDATE

Try this:

Declare a HashMap instance variable

//this will contain the file name and it's isDirectory() result
HashMap<String, Boolean> map = new HashMap<String, Boolean>();

Now, at the beginning of the ftpPrintFilesList(path) method:

//resets the map, you are listing new FTPFiles, so older ones need to be removed
map.clear(); 

Then, in your for loop, in ftpPrintFilesList(path) add every FTPFile info to the map like this:

//Add file's name and isDirectory() value to the map
map.put(ftpFiles[i].getName(),new Boolean(ftpFiles[i].isDirectory()));

Finally, in the onItemClick method, just use

boolean isDirectory = map.get(selectedFile).booleanValue();

It will return true if the selected item is a directory, false if it is a file

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM