Search code examples
javaandroidftpapache-commons-netsamsung-galaxy

Apache Commons Net Ftp throws error: Invalid server reply (MLST): '250 on Android only on Samsung s7


When my application tries to download a file from an Ftp server (running on a Pi zero W with DietPi) it throws the error above, but when I tried with other phones(Xiaomi Redmi 4x with android 6.0 and Samsung Galaxy J5 running on android 7.0) the error does not occur, only on the Samsung galaxy s7 running android 7.0. Also, uploading still works from the same phone

Invalid server reply (MLST): '250-modify=20180603012615;perm=adfrw;size=3679098;type=file;unique=801U4A;UNIX.group=0;UNIX.mode=0777;UNIX.owner=0; /C-jegyzet.pdf'

And the class that throws the error:

private class DownloadFileAsync extends AsyncTask<String, Long, Boolean>
    {
        ProgressBar downloadProgressbar;
        TextView titleTextView;
        TextView nameTextView;
        TextView percentageTextView;
        TextView completedTextView;
        CardView downloadCardView;

        boolean isFirstCall = true;
        String name;
        Long fileLength;
        String errorMessage = Constants.ErrorCodes.NO_ERROR_CODE;

        int progress;
        @Override
        protected Boolean doInBackground(String... strings)
        {
            int port = 21;
            FTPClient client = new FTPClient();
            try
            {
                client.connect(server, port);
                client.login(username, password);
                client.enterLocalPassiveMode();
                client.setFileType(FTPClient.BINARY_FILE_TYPE);
                client.setBufferSize(1);
                File fileToWrite = new File(strings[2] + "/" + strings[1]);
                name = strings[1];
                OutputStream outputStream = new BufferedOutputStream(new FileOutputStream(fileToWrite));
                fileLength = client.mlistFile(strings[0]).getSize();
                client.setCopyStreamListener(new CopyStreamListener() {
                    @Override
                    public void bytesTransferred(CopyStreamEvent copyStreamEvent)
                    {

                    }

                    @Override
                    public void bytesTransferred(long l, int i, long l1)
                    {
                        progress += i;
                        if(progress > 50000)
                        {
                            progress = 0;
                            publishProgress(l, l1);
                        }


                    }
                });
                boolean isSuccessful = client.retrieveFile(strings[0], outputStream);
                client.logout();
                outputStream.close();
                return isSuccessful;



            } catch (IOException e) {
                errorMessage = e.getMessage();
                Log.d("ftperror", errorMessage);
                return false;
            }


        }

        @Override
        protected void onProgressUpdate(Long... values)
        {
            //int percentage = Math.round((float)(values[0] / fileLength) * 100);
            float c = (((float)values[0]/(float)fileLength)*100);
            int percentage = Math.round(c);
            if(isFirstCall)
            {
                isFirstCall = false;
                downloadCardView = ((Activity) context).findViewById(R.id.downloadingCardView);
                downloadProgressbar = ((Activity) context).findViewById(R.id.downloadingProgressBar);
                titleTextView = ((Activity) context).findViewById(R.id.downloadingTitleTextView);
                nameTextView = ((Activity) context).findViewById(R.id.donwloadingNameTextView);
                percentageTextView = ((Activity) context).findViewById(R.id.downloadingPercentageTextView);
                completedTextView = ((Activity) context).findViewById(R.id.downloadingCompletedTextView);

                downloadCardView.setVisibility(View.VISIBLE);
                titleTextView.setText(R.string.file_handler_downloading);
                nameTextView.setText(name);
                downloadProgressbar.setProgress(0);


            }
            downloadProgressbar.setProgress(percentage);
            percentageTextView.setText(percentage + "%");
            completedTextView.setText(android.text.format.Formatter.formatShortFileSize(context, values[0]) + "/" + android.text.format.Formatter.formatShortFileSize(context, fileLength));



        }

        @Override
        protected void onPostExecute(Boolean aBoolean)
        {
            if(!isFirstCall)
            {
                downloadCardView.setVisibility(View.GONE);
            }

            if (aBoolean)
            {
                Toast.makeText(context, R.string.file_handler_download_success, Toast.LENGTH_LONG).show();
            }
            else
            {
                Toast.makeText(context, R.string.file_handler_download_failure, Toast.LENGTH_LONG).show();
                if (!errorMessage.equals(Constants.ErrorCodes.NO_ERROR_CODE))
                {
                    DisplayFilesActivity displayFilesActivity = (DisplayFilesActivity)context;
                    displayFilesActivity.showError(errorMessage);
                }

            }

        }
    }


Solution

  • I figured it out. The problem was not with the retrieve file but actually with the mlist method. Turns out my ftp server doesn't actually support the command. Using a list with the file as the argument had the same effect and my code works with that