-2

My english isn't perfect, but I hope it helps some people that are trying to solve this problem ;-)

My Question

I'm learning Android programming yet and I hope you guys can help me.

I'm trying to get a string from a txt file, from a ftp server. My string is called "contents" and I'm trying to show it with my "texto" TextView. I'm using FTPClient to acess the ftp server.

This is my method inside my MainActivity class:

public void get_txt() throws MalformedURLException {

    FTPClient ftpClient = new FTPClient();
    try {
        ftpClient.connect("my.ftp.url", 21);
        ftpClient.enterLocalPassiveMode();
        ftpClient.login("my_user", "my_password");


        InputStream inStream = ftpClient.retrieveFileStream("teste.txt");
        InputStreamReader isr = new InputStreamReader(inStream, "UTF8");

        String contents = isr.toString();
        texto.setText(contents);
        barra.setEnabled(false);
        ftpClient.disconnect();

    } catch (IOException e) {
        e.printStackTrace();
    } catch (Exception e) {
        e.printStackTrace();
    }

Thanks, and I hope you can help me :)

EDIT 1: I forgot to mention. My app is running ok, the problem is that the TextView never changes.

Ramon Machado
  • 15
  • 1
  • 6
  • Are you checking your logs for the stack traces you're printing in those `catch` blocks? – Mike M. Apr 08 '17 at 23:04
  • I think your code is good, Can you log the string contents to see if it is empty – Fady Saad Apr 08 '17 at 23:10
  • I found a "android.os.NetworkOnMainThreadException" error, but I don't think it's comming from the catch blocks. – Ramon Machado Apr 08 '17 at 23:13
  • How can I log my string? – Ramon Machado Apr 08 '17 at 23:14
  • Log.d(yourString) – Fady Saad Apr 08 '17 at 23:21
  • 1
    `I found a "android.os.NetworkOnMainThreadException" error` - as the error suggests perform the operation on a different thread than Main. Use `AsyncTask` from the Android Framework if you're new to Android .. RxJava if you're feeling brave... – Mark Apr 08 '17 at 23:21
  • @MarkKeen I'm trying to use AsyncTask (as you saida) but It's difficult to understand. – Ramon Machado Apr 08 '17 at 23:40
  • Maybe look at a couple tutorials on `AsyncTask` first, as well as looking at the documentation for it https://developer.android.com/reference/android/os/AsyncTask.html? – Mark Apr 08 '17 at 23:56
  • Okay, I managed to use a AsyncTask (thanks, a lot!). And I had some issues that I had to fix. And now it's finally "getting something". I just changed the code to use in AsyncTask, but it does still the same logic. But now, my TextView is showing "java.io.InputStreamReader@41e221b". – Ramon Machado Apr 09 '17 at 03:41
  • Thanks a lot, mates! I finally managed to get it! So, I'll edit my question with my new code for those who needs the solution. Thanks again for all your help, this community is amazing! – Ramon Machado Apr 09 '17 at 04:02

1 Answers1

0

The Final and Working Code (I hope it helps you)

Finally, after hours, I managed to get it right! For those who need the answer, here it is:

public class Principal extends AppCompatActivity {

    public static TextView texto;
    String contents;
    ProgressBar barra;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_principal);
        texto = (TextView) findViewById(R.id.texto);
        TarefaDownload download = new TarefaDownload();
        download.execute();
}

The code above is my MainActivity (I call it "Principal" here). I created only a TextView there, then I instaciated my AsyncTask class called "TarefaDownload". This class is a private class where all the logic to acess ftp is placed. Let's see this class code now.

private class TarefaDownload extends AsyncTask<Void, Void, Void> {
    @Override
    protected void onPreExecute() {
    }

    @Override
    protected Void doInBackground(Void... params) {
        FTPClient ftpClient = new FTPClient();
        try {
            ftpClient.connect("my_ftp_link_here", 21);
            ftpClient.enterLocalPassiveMode();
            ftpClient.login("my_user_login_here", "my_password_here");
            ftpClient.changeWorkingDirectory("/");

            InputStream inStream = ftpClient.retrieveFileStream("teste.txt");
            InputStreamReader isr = new InputStreamReader(inStream, "UTF8");


            int data = isr.read();
            contents = "";
            while(data != -1){
                char theChar = (char) data;
                contents = contents + theChar;
                data = isr.read();
            }

            isr.close();

            ftpClient.disconnect();

        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    protected void onPostExecute(Void result) {
        texto.setText(contents);
    }
}

So, basically I was trying to read a single line string from a txt file called "teste". The method "doInBackground" runs everything in background (don't you say?), so all the code to access ftp must come there. Then I created a String called "contents", started to read the chars (one per time) from the InputStreamReader and storing in the string. You must notice that the String contents is being used in this method, but it belongs to my MainActivity, so I can access it outside the AsyncTask class. Finally, when de doInBackground method finishes, the "onPostExecute" methos is called and set the text of my TextView to value of my String value.

That's all! You may notice that you must add a INTERNET permission on your Manifest file (or then you'll not be able to access the ftp server):

 <uses-permission android:name="android.permission.INTERNET" />

And that's it, your app should be reading data from the ftp server!

Ramon Machado
  • 15
  • 1
  • 6