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:

sterlingy

Active Member
Licensed User
Longtime User
Problem Solved!!!!

:D

As it turns out, I had to set FTP.Passive = True

Now everything works fine.

Also, and this may be a no-no, but I I to the FTP.Initialize out of the FirstTime if-then statement. The reason is that if I left the Camera activity, which is where all of this code resides, then went back to it, it wouldn't re-initialize the FTP.

Lastly, I put FTP.Close in the Pause subroutine. Since my camera Activity is locked into Landscape mode, the Activity will not pause if the phone orientation is rotated. Pausing will only take place when I leave the Activity with the back button.

Thanks for everyone's help.

Cheers,

Sterling
 

BarrySumpter

Active Member
Licensed User
Longtime User
FTP With IIS5.1 on WinXp Pro sp3 32bit

Make sure ftp is included with IIS5.1 install
Add or Remove Programs | Add/Windows Components | Internet Info Services (IIS) (ticked on) | Details ... | File Transfer Protocol (FTP) Service (ticked on)

Computer management | IIS | FTP Sites | Default FTP Site Properties | Security Accounts | Create New user like UID: ftpuser PW: zxcvb | Allow anonymous (ticked off) | allow IIS (ticked off)

Computer management | IIS | FTP SItes | FTP Site | IP Address: 192.168.1.6 (server IPAddress)

I DID NOT have to setup a new virtual directory.

Set router to port forward ftp port 21 to 192.168.1.6 (server IPAddress)

FTPExample app:
B4X:
Sub Activity_Create(FirstTime As Boolean)
    If FirstTime Then
            'FTP.Initialize( "FTP", "192.168.1.6", 21,  "ftpuser", "zxcvb")   'inTRAnet WORKS
            FTP.Initialize( "FTP", "myDomain.com", 21,  "ftpuser", "zxcvb")    'inTERnet WORKS
            'FTP.Initialize( "FTP", "ftp.myDomain.com", 21,  "ftpuser", "zxcvb") ' FTP.com DOES NOT WORK
                                                                                                    ' - don't know why in IIS5.1 
                                                                                                    ' - may need to contact my domain peeps
            
    End If
    Activity.LoadLayout("Main")
End Sub
 
Last edited:

rfresh

Well-Known Member
Licensed User
Longtime User
I meant that this could be an alternative for secured file transfers.

So what you're saying is that I can install an SSL Cert on my website and use regular B4A FTP and the files will go up or down encrypted via the SSL?

Update:

I moved my code over to one of my websites that has an SSL Cert on it.

My B4A FTP code is this:

B4X:
FTP2.Initialize("FTP", "ftp.my_ssl_website.com", 21, pUser, pPW)
FTP2.UseSSL = True
FTP2.PassiveMode = True

But when it tries to download a file I get this error in the log:

error:140770FC:SSL routines:SSL23_GET_SERVER_HELLO:unknown protocol (external/openssl/ssl/s23_clnt.c:683 0xad127577:0x00000000)

This site has no regular FTP server due to PCI requirements. It only has SFTP. So is this error msg because there is no regular FTP server installed?
 
Last edited:

gapi

Active Member
Licensed User
Longtime User
If I try to download more than twenty files returns me an error
B4X:
java.util.concurrent.RejectedExecutionException: pool=20/20 queue=0/0 Continue?
queue is full... solution ?

thanks
 
Last edited:

Rusty

Well-Known Member
Licensed User
Longtime User
Erel,
I am downloading a 32MB file using FTP. When my wireless/internet is "unoccupied" with other traffic, the full 32MB comes down just fine.
I notice when there is significant traffic on the wireless, it will download a portion of the file and "stall" out. Ultimately, it fails.
Is there a way to detect these errors and to recover from them?
Thanks,
 

Rusty

Well-Known Member
Licensed User
Longtime User
Yes,
B4X:
Sub MyFTP_DownloadCompleted (ServerPath As String, Success As Boolean)
   If Success Then
      Dim myzip As ABZipUnzip
      lblDownloaded.Text = "Unzipping..."
      myzip.ABUnzip(File.DirRootExternal & "/androidinstall.zip", File.DirRootExternal)
      File.Delete(File.DirRootExternal, "androidinstall.zip")
      pbProgress.Visible = False
      lblDownloaded.Text = "Installing..."
      btnInstall_Click
   Else
      Msgbox("Unable to download install information." & CRLF & LastException.Message, "Warning")
      Activity.Finish
   End If
End Sub

I get the error: org.apache.commons.net.io.copystramexception: ioExceptoin caught while copying
Any ideas?
Thanks,
 

Rusty

Well-Known Member
Licensed User
Longtime User
Thanks Erel,
Is there a method to recover from this? Does this mean the problem is on the server side? Perhaps, does this mean the server is failing or too busy or what?
Most importantly, can I recover from this and do you have any ideas how to recover?
 

androh

Member
Licensed User
Longtime User
Closenow command does not work while upload process is running.
How can I terminate upload command?
 
Last edited:

AscySoft

Active Member
Licensed User
Longtime User
Closenow command does not work while upload process is running.
How can I terminate upload command?

As I understand from the first post of this thread, you can't because:
<<FTP.CloseNow will immediately close the connection, failing the remaining tasks.>>
So, because is on a separate thread, I just think that it's suppose to work exactly this way!
Why do you need to close the current upload/download file? It is too large?
 

androh

Member
Licensed User
Longtime User
As I understand from the first post of this thread, you can't because:
<<FTP.CloseNow will immediately close the connection, failing the remaining tasks.>>
So, because is on a separate thread, I just think that it's suppose to work exactly this way!
Why do you need to close the current upload/download file? It is too large?
Yes too large file. I'll try with service module...
 

AscySoft

Active Member
Licensed User
Longtime User
Yes too large file. I'll try with service module...

The service module is intended for background working, even if main application is closed. I don't see how this could help, the ftp library is processing in background...
Maybe you should ask Erel, to develop further this library for killing working thread...
I guess is not OK to upload partial files on ftp server... don't know...maybe I'm wrong.
 

androh

Member
Licensed User
Longtime User
The service module is intended for background working, even if main application is closed. I don't see how this could help, the ftp library is processing in background...
Maybe you should ask Erel, to develop further this library for killing working thread...
I guess is not OK to upload partial files on ftp server... don't know...maybe I'm wrong.

I tried upload file with service module. After StopService(....) didn't kill ftp upload progress :(
:sign0085: Erel
 

androh

Member
Licensed User
Longtime User
What is exactly the problem? Does the download continue after you call CloseNow?
FTP.CloseNow should close the connection.

I'm uploading jpg file to ftp server. I want to cancel this upload process by user. But when I use ftp.close now, uploading is still running....
 
Status
Not open for further replies.
Top