Android Code Snippet Sending email via SMTP with "POP before SMTP"

peacemaker

Expert
Licensed User
Hi, All

The emailing (via SMTP) trouble is solved: to avoid server auth error before using SMTP server we have to check email, say by POP3.
This class is tested during 3 days on popular app with around 70-80 emails from an app to the chosen GMAIL box to self. No sending errors now. Before there were 2-3 sending errors per day.

B4X:
' Class for working with SMTP emailing, but with POP3 check before any sending
'(c) Pomelov Vlad aka Peacemaker, v.0.1
Sub Class_Globals
    Private InternetConnected As Boolean, ph As PhoneEvents
    Private Callback As Object
    Private SMTP1 As SMTP
    Private pop As POP3
    Private SMTPserver, SMTPlogin, SMTPpass, SenderAdr, POPserver As String
    Private SMTPto As String
    Private const SMTPssl As Boolean = True
    Private SMTPport As Int = 465    '25, 587
    Private POPport As Int = 995
    Dim SMTPsent As Boolean
    Dim LatestError As String
End Sub

'Initializes the object. You can add parameters to this method if needed.
Public Sub Initialize(Parent As Object, mSMTPserver As String, mPOPserver As String, mSMTPlogin As String, mSMTPpass As String, mSenderAdr As String, mSMTPto As String)
    Callback = Parent
    SMTPserver = mSMTPserver
    SMTPlogin = mSMTPlogin
    SMTPpass = mSMTPpass
    SenderAdr = mSenderAdr
    POPserver = mPOPserver
    SMTPto = mSMTPto
End Sub


Sub SendEmail (Subj As String, Body As String, Att As Map) As ResumableSub
    ph.Initialize("ph")
    Wait For ph_ConnectivityChanged (NetworkType As String, State As String, Intent As Intent)
    If State = "CONNECTED" Then
        Log("ph_ConnectivityChanged: CONNECTED")
        InternetConnected = True
    Else    'NO INTERNET
        Log("ph_ConnectivityChanged: DISCONNECTED")
        InternetConnected = False
        LatestError = LastException.Message
        Check_Internet
        Return False
    End If
 
    'POP before SMTP
    pop.Initialize(POPserver, POPport, SMTPlogin, SMTPpass, "pop")
    pop.UseSSL = SMTPssl
    pop.Status

    Wait For pop_StatusCompleted (Success As Boolean, NumberOfMessages As Int, TotalSize As Int)
    If Success = False Then 
        LatestError = LastException.Message
        Return False
    End If
    ' setup the SMTP object
    SMTP1.Initialize(SMTPserver,SMTPport,SMTPlogin,SMTPpass,"SMTP1")
    SMTP1.UseSSL = SMTPssl
    #if release
        SMTP1.To.Add(SMTPto)
    #end if
    #if debug
        SMTP1.To.Add(your_debug_email)
    #End If

    SMTP1.Sender = SenderAdr
    SMTP1.Subject = Subj
    SMTP1.Body = Body
    SMTP1.Body = SMTP1.Body.Replace("=", "=3D")
    If Att <> Null Then
        If Att.IsInitialized Then
            For i = 0 To Att.Size - 1
                SMTP1.AddAttachment(Att.GetValueAt(i), Att.GetKeyAt(i))
            Next
        End If
    End If
    SMTP1.Send
    Return True
End Sub

Private Sub ph_ConnectivityChanged (NetworkType As String, State As String, Intent As Intent)
    If State = "CONNECTED" Then
        Log("ph_ConnectivityChanged: CONNECTED")
        InternetConnected = True
    Else    'NO INTERNET
        Log("ph_ConnectivityChanged: DISCONNECTED")
        InternetConnected = False
        
    End If
End Sub

Sub SMTP1_MessageSent(Success As Boolean)
    Log ("Message Sent: " & Success)
    If Success Then
        SMTPsent = True
        LatestError = ""
    Else
        SMTPsent = False
        LatestError = LastException.Message
        Log("Send Error: " & LastException.Message)
    End If
    If SubExists(Callback, "SMTP_MessageSent") Then
        CallSub2(Callback, "SMTP_MessageSent", Success)
    End If
End Sub

Sub Check_Internet As Boolean
    If InternetConnected = False Then
        Dim a As String = "Check Internet-connection..."
        ToastMessageShow(a, True)
        Return False
    Else
        Return True
    End If
End Sub

Usage:
B4X:
Sub Process_Globals
Dim emailing As clsEmail
End Sub

Sub Service_Start (StartingIntent As Intent)
    Dim a As String = "XXX@gmail.com"
    emailing.Initialize(Me, "smtp.gmail.com", "pop.gmail.com", a, YOUR_GMAIL_PASSWORD, a, a)
End Sub

'.... where needed:
        Dim res As ResumableSub = emailing.SendEmail(subject, body, AttachmentsList)
        Wait For(res) Complete (Success As Boolean)
        ProgressDialogHide
        If Success = False Then
            ToastMessageShow("Email settings error", False)
        End If
 
Last edited:

peacemaker

Expert
Licensed User
Save the class text under the spoiler into "clsEmail.bas" file, and add it to the project.
 
Top