Android Tutorial Android FTP tutorial

Status
Not open for further replies.
Old and irrelevant tutorial. Follow this one instead: [B4X] Net library (FTP, SMTP, POP) with Wait For

This tutorial covers the FTP object which is part of the Net library.
The Net library is based on Apache Commons Net.

Android OS doesn't allow us, the developers, to block the main thread for more than 5 seconds. When the main thread is busy for too long and is not able to handle the user events the "Application not responding" dialog appears.
Therefore slow operations like network operations should be done in the background.
The FTP library is built in such a way. All of the methods return immediately. When a task completes an event is raised. In fact you can submit several tasks one after another. The FTP protocol supports a single task at a time so the tasks will be processed serially.

Using the FTP library is pretty simple.
The first step is to initialize the FTP object. If this is an Activity module then you should do it in Activity_Create when FirstTime is true.
For Service modules it should be initialized in Service_Create.
B4X:
Sub Process_Globals
    Dim FTP As FTP
End Sub
Sub Globals

End Sub

Sub Activity_Create(FirstTime As Boolean)
    If FirstTime Then
        FTP.Initialize("FTP", "ftp.example.com", 21, "user", "password")
    End If
FTP.Initialize doesn't connect to the server. Connection will be established implicitly together with the next task.

Download

Downloading a file is done by calling DownloadFile with the remote file path and the local file path.
If you want to show the download progress then you should handle DownloadProgress event.
When download completes the DownloadCompleted event is raised. The ServerPath is passed as the first parameter to all events. You can use it to distinguish between different tasks. Make sure to check the Success parameter. If Success is False then you can find the exception message by calling LastException.

B4X:
    FTP.DownloadFile("/somefolder/files/1.zip", False, File.DirRootExternal, "1.zip")
   
Sub FTP_DownloadProgress (ServerPath As String, TotalDownloaded As Long, Total As Long)
    Dim s As String
    s = "Downloaded " & Round(TotalDownloaded / 1000) & "KB"
    If Total > 0 Then s = s & " out of " & Round(Total / 1000) & "KB"
    Log(s)
End Sub

Sub FTP_DownloadCompleted (ServerPath As String, Success As Boolean)
    Log(ServerPath & ", Success=" & Success)
    If Success = False Then Log(LastException.Message)
End Sub
Upload

Uploading is similar to downloading.
B4X:
    FTP.UploadFile(File.DirRootExternal, "1.txt", True, "/somefolder/files/1.txt")

Sub FTP_UploadProgress (ServerPath As String, TotalUploaded As Long, Total As Long)
    Dim s As String
    s = "Uploaded " & Round(TotalUploaded / 1000) & "KB"
    If Total > 0 Then s = s & " out of " & Round(Total / 1000) & "KB"
    Log(s)
End Sub

Sub FTP_UploadCompleted (ServerPath As String, Success As Boolean)
    Log(ServerPath & ", Success=" & Success)
    If Success = False Then Log(LastException.Message)
End Sub
List files and folders

FTP.List sends a request for the list of files and folders in a specific path.
The ListCompleted event is raised when the data is available.
You can use code similar to the following code to get more information on the entries:
B4X:
FTP.List("/")
...
Sub FTP_ListCompleted (ServerPath As String, Success As Boolean, Folders() As FTPEntry, Files() As FTPEntry)
    Log(ServerPath)
    If Success = False Then
        Log(LastException)
    Else
        For i = 0 To Folders.Length - 1
            Log(Folders(i).Name)
        Next
        For i = 0 To Files.Length - 1
            Log(Files(i).Name & ", " & Files(i).Size & ", " & DateTime.Date(Files(i).Timestamp))
        Next
    End If
End Sub
Delete
Delete is done by calling FTP.Delete with the full path. Again an event will be raised when the task completes (DeleteCompleted).

Closing the connection
You can close the connection by calling FTP.Close. Close will wait for the other tasks to complete and then will close the connection. This happens in the background.
FTP.CloseNow will immediately close the connection, failing the remaining tasks.

Some notes:
- At any given time there should be less than 15 waiting tasks. Otherwise you will get a RejectedExecutionException (this happens when the internal threads pool is exhausted).
- The order of the completed tasks may be different than the order of submission.
- The AsciiFile parameters sets the file transfer mode. If AsciiFile is true then every occurrence of an end of line character will be translated based on the server native end of line character. If your FTP server is Unix or Linux then the end of line character is the same as Android.
In most cases you can set AsciiFile to false.

The library is available for download here: http://www.b4x.com/forum/additional...92-new-net-library-android-ftp-smtp-pop3.html
 
Last edited:

DonManfred

Expert
Licensed User
Longtime User
My FTP_UploadCompleted event is never fired event if the upload is successful.
I have the FTP object on a code module... could that be the reason? Must the FTP object be on a service module?

Must be a Service or activity-code
 

luciano deri

Active Member
Licensed User
Longtime User
I ran your program and it seems to run fine.
It download the file and printed this message to the log:
Team/prestadores.txt, Success=true
I have a same problem. Download and upload are ok but the App don't execute
B4X:
Sub FTP_DownloadProgress (ServerPath As String, TotalDownloaded As Long, Total As Long)
    Dim s As String
    s = "Downloaded " & Round(TotalDownloaded / 1000) & "KB"
    If Total > 0 Then s = s & " out of " & Round(Total / 1000) & "KB"
    Log(s)
End Sub

Sub FTP_DownloadCompleted (ServerPath As String, Success As Boolean)
    Log(ServerPath & ", Success=" & Success)
    If Success = False Then Log(LastException.Message)
    FTP.Close
End Sub
Sub ftp_UploadCompleted (ServerPath As String, Success As Boolean)
    Msgbox(ServerPath & ", Success=" & Success,"")
    FTP.Close
End Sub
So i can't know when someting not is ok.
 

luciano deri

Active Member
Licensed User
Longtime User
Which app doesn't execute?
I call this sub pass the nomefile
B4X:
Sub ftp_download(nomefile As String)
    NomefileLocale = nomefile 
    NomefileRemoto = PthMultidataIN 
    If Not(NomefileRemoto.EndsWith("/")) Then
      NomefileRemoto = NomefileRemoto & "/" 
    End If  
    NomefileRemoto = NomefileRemoto & NomefileLocale 
    ProgressDialogShow("Download " & NomefileRemoto)
   
      ftp_imposta
    DoEvents
    FTP.DownloadFile(NomefileRemoto,True,Main.PthIO,NomefileLocale)
End Sub
Sub ftp_imposta
    DoEvents
    FTP.Initialize("FTP","WPOS001.mdata.locale",21,"tablet01","pwd01")
    FTP.PassiveMode=True
End Sub
The download is ok, but the app dont' enter in
FTP_DownloadCompleted ad
FTP_DownloadProgress
I thinked that app must execute this subs automatically. Is not so?
By, thanks
 

luciano deri

Active Member
Licensed User
Longtime User
You shouldn't initialize FTP multiple times. Just initialize it once.
ok, call ftp_imposta only in Activity_Create. But the problem persist, don't pass by ftp_UploadCompleted .
The file contain the report of FTP server where i upload file from tablet. I read in this forum that some other user had have this problem how had solve this?
 

Attachments

  • logFTPserver.txt
    4.8 KB · Views: 342

luciano deri

Active Member
Licensed User
Longtime User
The issue discussed in the other thread was related to very large files combined with slow connection (note that I wasn't able to reproduce that issue).

Please try to reproduce your issue in a small project and upload it.
Ok, thanks for your disponibility, next monday i return at work and i post a little example
 

Todd Carlton

Member
Licensed User
Longtime User
If within the same activity I need to download files from a server with two different user accounts, is there a way to initialize FTP a second time with different credentials?

First account's home = /home/user1
Second account's home is /home/user2

... and so I cannot use a single instance to download everything I need.

I have created an additional activity to start, download user 2's files and then finish. That works with a warning that FTP is already initialized. I am hoping to write the app free of warnings. ;)

Thank you for any direction or instructions.

-OCS
 

JdV

Active Member
Licensed User
Longtime User
Hello

I'm using version 1.53 of the Net library and calling FTP.CloseNow doesn't seem to cancel the job - files are still downloaded in their entirety.

The test files I'm downloading aren't huge at around 8MB and 26MB each.

Regards

Joe
 

JdV

Active Member
Licensed User
Longtime User
Erel

Is there a plan to fix this?

I see that the attachment to post #123 addresses this issue but I think it was for uploads only. (I have tried the attachment for my situation and it didn't kill the downloads.)

Also, if 'total' usually returns "-1" in
FTP_DownloadProgress (ServerPath AsString, TotalDownloaded AsLong, Total AsLong) is that seen as a bug?

Regards

Joe
 
Last edited:

JdV

Active Member
Licensed User
Longtime User
Erel

Yes I have implemented the DownloadProgress event - I can see the TotalDownloaded value ticking up even after calling FTP.CloseNow several times.

Regards

Joe
 

JdV

Active Member
Licensed User
Longtime User
No it doesn't stop until after the complete file has downloaded.

Yes I'm using that version.

Regards

Joe
 

JdV

Active Member
Licensed User
Longtime User
I see what the issue is now!

In your example you name the variable, object and event 'FTP'. In my code I didn't.

If I follow your example exactly it works OK.

Thanks for the help.

Joe
 

atulindore

Member
Licensed User
Longtime User
Hi
I am using net lib to upload my file to ftp server.

===================================================
B4X:
Sub Activity_Create(FirstTime As Boolean)
    If FirstTime Then
        FTP.Initialize("FTP", "ftp.doamin.com", 21, "user", "pwd")
        FTP.PassiveMode = True
    End If
    Activity.LoadLayout("1")
End Sub

Sub BtnUpload_Click
        UploadBhavCopy
End Sub

Sub UploadBhavCopy
      FTP.UploadFile(File.DirDefaultExternal , "EQ081014.CSV", True, "/EQ081014.csv")
End sub

Sub FTP_UploadProgress (ServerPath As String, TotalUploaded As Long, Total As Long)
    Dim s As String
    s = "Uploaded " & Round(TotalUploaded / 1000) & "KB"
    If Total > 0 Then s = s & " out of " & Round(Total / 1000) & "KB"
    Log(s)
End Sub

Sub FTP_UploadCompleted (ServerPath As String, Success As Boolean)
    Log(ServerPath & ", Success=" & Success)
    If Success = False Then Log(LastException.Message)
    ToastMessageShow("File Uploaded",True)
    FTP.List("/")
    FTP.Close
    BtnUpload.Enabled = True
End Sub
===================================================
But file uploaded with 0 bytes ..


am I doing something wrong ?

My logs are showing correct uploading

Uploaded 256KB
Uploaded 257KB
Uploaded 258KB
Uploaded 259KB
Uploaded 260KB
Uploaded 261KB
Uploaded 262KB
Uploaded 263KB
Uploaded 264KB

Pls suggest ..

Thanks

Its working now ...
 
Last edited:
Status
Not open for further replies.
Top