Android Tutorial Trial Period using FTP

Here is a method using FTP to create a trial period for your app. Since there is no local file with trial information, the user cannot defeat it by manipulating stored data. Also, FTP calls are very simple and no database required. Thought I would share this method since I have benefited so much from others in forum.

Process steps:
1. Get a unique id. This will be your file name on FTP site.
2. Do a FTP.list on your site to see if a file is present with that name
3. If it does not exist, create a file with unique id as its name and put timestamp inside file
  1. tell the user that the trial period of 30 (you pick) days has begun and continue with program
4. If it does exist, download the file and read the timestamp
  1. Compare current time with timestamp
  2. if within 30 day, send a message of time remaining and continue on your program
  3. if outside of 30 days, end program
Misc. Items:
1 libraries required: DateUtils, Reflection, Phone, Net
2. You could modify the comparison as a countdown rather than days by putting counter in file
3. Each file on your FTP site will represent a user who is trying (or has tried) your program. You can get a count from this information.

here is the code:

B4X:
Sub Globals
      Private trialperiod As Int
      Private uniqueid As String
      Private ctm As CustomTrustManager
end Sub

Sub Activity_Create(FirstTime as Boolean)
    uniqueid = GetDeviceId
    trialperiod = 30
    checktrial
end Sub



Sub GetDeviceId As String
    Dim r As Reflector
    Dim Api As Int
    Dim p As Phone
    Dim id As String
    Api = r.GetStaticField("android.os.Build$VERSION", "SDK_INT")
    If Api < 9 Then
        'Old device
        id= p.GetSettings("android_id")
        Return id
    Else
        'New device
       Return r.GetStaticField("android.os.Build", "SERIAL")
    End If
End Sub

Sub checktrial
   FTP.Initialize("FTP", ftpsite, 21, un, pw)
   ctm.InitializeAcceptAll
   FTP.SetCustomSSLTrustManager(ctm)
   FTP.PassiveMode = True
   FTP.UseSSLexplicit = True
   Sleep(1000) 'pause for initialize
   FTP.List("/" & "invitetextntally" &"/")
End Sub


Sub FTP_ListCompleted (ServerPath As String, Success As Boolean, Folders() As FTPEntry, Files() As FTPEntry)
    'Log(ServerPath)
    If Success = False Then
        Log(LastException)
    Else
        Dim foundit As Int = 0
        For i = 0 To Files.Length - 1
            'Log(Files(i).Name & ", " & Files(i).Size & ", " & DateTime.Date(Files(i).Timestamp))
            If Files(i).Name = uniqueid & ".txt" Then
                foundit = 1
            End If
        Next
        If foundit = 0 Then
            'create a file and upload it
            File.WriteString(File.DirInternal, uniqueid & ".txt", DateTime.now)
            FTP.UploadFile(File.DirInternal, uniqueid & ".txt", False, "/" & "invitetextntally" &"/" & uniqueid &".txt")
        Else
            'download the file
            FTP.DownloadFile("/" & "invitetextntally" &"/" & uniqueid &".txt", False, File.DirInternal, uniqueid &".txt")
        End If
    End If
End Sub

Sub FTP_UploadCompleted (ServerPath As String, Success As Boolean)
    Log(ServerPath & ", Success=" & Success)
    If Success = False Then
        Log(LastException.Message)
    Else
        ToastMessageShow("30 day trial period begins now",True)
    End If
End Sub

Sub FTP_DownloadCompleted (ServerPath As String, Success As Boolean)
    Log(ServerPath & ", Success=" & Success)
    If Success = False Then
        Msgbox("FTP Download error for trial check","")
        Log(LastException.Message)
        FTP.close
    Else
        FTP.close
        Dim ts As String = File.ReadString(File.DirInternal, uniqueid & ".txt")
        Dim per As Period = DateUtils.PeriodBetweenindays(ts, DateTime.Now)
        If per.days <= trialperiod Then
            Dim daysleft As Int = trialperiod - per.days
            ToastMessageShow(daysleft & " days left in trial period",True)
        Else
            Msgbox("Trial Period over", "")
            Activity.finish
        End If
    End If
End Sub
 
Last edited:

Erel

B4X founder
Staff member
Licensed User
Longtime User
Tips and notes:
- There is no longer any reason to use CallSubUtils. You can instead write:
B4X:
Sleep(1000)
'make the call here

Also worth learning to use Wait For: https://www.b4x.com/android/forum/threads/b4x-net-library-ftp-smtp-pop-with-wait-for.84821/#content

- FTP is an insecure protocol. Don't use it if security is important.
Everything is sent as plain text so it is very simple to find the username and password.

- Make sure to use a FTP user that is limited to this folder. It can still be dangerous.
 

gregchao

Member
Licensed User
Longtime User
I have tried to address the issues you brought up by:

1. using Sleep(1000) instead
2. using FTP with SSL
3. limiting the FTP user to this folder is done on the server side

I do not understand why I would use "wait for". Would it replace the "Sleep(1000)"?
 

Tempomaster

Active Member
Licensed User
Longtime User
Hello,

I tried the code. He works perfectly. However, I can only use FTP without SSL. But this is not a big problem because there are only a few files in the accessible folder.

But it should be enough to call the routine "checktrial" only if the internal file is missing (for example after an uninstall and subsequent reinstallation). A manipulation of the internal file is only possible with rooted devices. On the other hand, one could protect oneself, for example, by writing a second line. In this one writes for example a checksum which forms from the first line. Thus, the app would also be usable offline.

Best regards,
Gunnar
 
Top