Android Question Email with b4a

Giusy

Active Member
Licensed User
Hi, I've searched , but I have not found what I need. Everyone wants to send emails, but I want to receive it, let me explain.
I want to indicate my email. The user presses and is able to write me what he wants.
Thanks
 

ronell

Well-Known Member
Licensed User
Longtime User
B4X:
Sub Email_Click
Dim msg As Email
    Dim intent1 As Intent
    Dim sdk as Int
    Dim pm As PackageManager
    Log(pm.QueryIntentActivities(msg.GetIntent))
    Dim list As List
    list.Initialize
   
    For Each em As String In pm.QueryIntentActivities(msg.getintent)
        list.Add(em)
        Log(em)
    Next
   
    sdk = phone.SdkVersion
     
    msg.Subject="Subject"
    msg.Body= ""
    msg.To.Add("youremail@gmail.com")
   
   
   
    intent1 = msg.GetIntent
    If sdk >= 23 Then
        intent1.SetComponent("com.google.android.gm/.ComposeActivityGmailExternal")
    Else
        intent1.SetComponent("com.google.android.gm/.ComposeActivityGmail")
    End If
   
    StartActivity(intent1)

End Sub
 
Upvote 0

Giusy

Active Member
Licensed User
Ronel, I have an error in this line

sdk = phone.SdkVersion (phone is red)

(phone library version 2.5)
 
Upvote 0

ronell

Well-Known Member
Licensed User
Longtime User
Check "Phone" in Libraries Manager

upload_2018-7-18_22-9-29.png
 
Upvote 0

Giusy

Active Member
Licensed User
Yes, is checked phone library ver 2.50

(Undeclared variable 'phone' is used before it was assigned any value)
 

Attachments

  • libreria.JPG
    libreria.JPG
    19 KB · Views: 192
Upvote 0

tummosoft

Member
Licensed User
Longtime User
How to receive an emal:

1. Library:

- NET 1.2 (POP3, SMTP, FTP) - http://www.b4x.com/android/help/net.html
- Encryption (decode data from Basa64)
- StringUtils (decode data from Basa64)

2. Add codes:

B4X:
Sub Process_Globals
Dim pop As POP3 ' Thư viện NET
End Sub

Sub Globals
Private ListView1 As ListView
End Sub

Sub Activity_Create(FirstTime As Boolean)
If FirstTime Then
pop.Initialize("pop.mail.yahoo.com", 995, "email address", "Password", "POP")
pop.UseSSL = True
End If
pop.ListMessages

Activity.LoadLayout("main")
End Sub

Sub POP_ListCompleted (Success As Boolean, Messages As Map)
If Success = False Then
' ----------------
Else
'download all messages
'change last parameter to True if you want to delete the messages from the server
For i = 0 To Messages.Size - 1
pop.DownloadMessage(Messages.GetKeyAt(i), False)   
Next   
End If
pop.Close
End Sub

Sub POP_DownloadCompleted (Success As Boolean, MessageId As Int, MessageText As String)
If Success = False Then

Else
Log(MessageText)   
End If

3. Result: we receive an email with Base64 strings

1zer2h.png


4. Now, I create an mail parser module.

B4X:
'Code module
Sub Process_Globals
    Type Message (FromField As String, ToField As String, CCField As String, BCCField As String, _
        Subject As String, Body As String, ContentType As String, Attachments As List)
    Dim index As Int
    Dim boundary As String
    Dim multipart As Boolean
    Dim dir As String
End Sub
'Parses a raw mail message and returns a Message object
'Mail - The mail raw text
'AttachmentsDir - Attachments will be saved in this folder
Sub ParseMail (Mail As String, AttachmentsDir As String) As Message
    index = 0
    multipart = False
    boundary = ""
    Dim msg As Message
    msg.Initialize
    msg.Attachments.Initialize
    ParseHeaders(Mail, msg)
    If multipart = False Then
        ParseSimpleBody(Mail, msg)
    Else
        dir = AttachmentsDir
        ParseMultipartBody(Mail, msg)
    End If
    Return msg
End Sub
Sub ParseMultipartBody (Mail As String, Msg As Message)
    'find first boundary
    index = Mail.IndexOf2("--" & boundary, index)
    ReadNextLine(Mail)
    Dim headers As StringBuilder
    headers.Initialize
    Do While index < Mail.Length
        Dim line As String
        line = ReadNextLine(Mail)
        If line.Length > 0 Then
            headers.Append(line).Append(" ")
        Else If index < Mail.Length Then
            Dim nextPart As Int
            nextPart = Mail.IndexOf2("--" & boundary, index)
            If nextPart-4 > index Then
                HandlePart(headers.ToString, Mail.SubString2(index, nextPart-4), Msg)
            End If
            If nextPart = -1 Then Return
            index = nextPart
            ReadNextLine(Mail)
            headers.Initialize
        End If
    Loop
End Sub
Sub HandlePart(Headers As String, Body As String, Msg As Message)
    If Regex.Matcher2("Content-Transfer-Encoding:\s*base64", _
        Regex.CASE_INSENSITIVE, Headers).Find Then
        'we are dealing with an attachment
        Dim filename As String
        Dim m As Matcher
        m = Regex.Matcher2("filename=\s*q([^q]+)q".Replace("q", QUOTE), Regex.CASE_INSENSITIVE, Headers)
        If m.Find Then filename = m.Group(1) Else filename = "attachment" & (Msg.Attachments.Size + 1)
        Dim su As StringUtils
        Dim out As OutputStream
        out = File.OpenOutput(dir, filename, False)
        Dim data() As Byte
        'su.DecodeBase64
        data = su.DecodeBase64(Body)
        Log("file saved: "  & filename & " (" & data.Length & " bytes)")
        out.WriteBytes(data, 0, data.Length)
        out.Close
        Msg.Attachments.Add(filename)
    Else If Regex.Matcher2("Content-Type:\s*text/", _
        Regex.CASE_INSENSITIVE, Headers).Find Then
        Msg.Body = Body
    End If
End Sub
 
Sub ParseSimpleBody (Mail As String, Msg As Message)
    Msg.Body = Mail.SubString(index)
End Sub
 
Sub ParseHeaders (Mail As String, Msg As Message)
    Dim line As String
    line = ReadNextLine(Mail)
    Do While line.Length > 0
        Dim parts() As String
        parts = Regex.Split(":", line)
        If parts.Length >= 2 Then
            Dim first As String
            first = parts(0).ToLowerCase
            Select first
                Case "from"
                    Msg.FromField = parts(1)
                Case "to"
                    Msg.ToField = parts(1)
                Case "cc"
                    Msg.CCField = parts(1)
                Case "bcc"
                    Msg.BCCField = parts(1)
                Case "subject"
                    Msg.Subject = parts(1)
                Case "content-type"
                    Dim second As String
                    second =  parts(1).ToLowerCase
                    Msg.ContentType = parts(1)
                    If second.Contains("multipart/") Then
                        multipart = True
                        If FindBoundary(line) = False Then
                            line = ReadNextLine(Mail)
                            FindBoundary(line)
                        End If
                    End If
            End Select
        End If
        line = ReadNextLine(Mail)
    Loop
End Sub
 
Sub FindBoundary(line As String) As Boolean
    Dim m As Matcher
    m = Regex.Matcher2("boundary=\q([^q]+)\q".Replace("q", QUOTE), Regex.CASE_INSENSITIVE, line)
    If m.Find Then
        boundary = m.Group(1)
        Return True
    Else
        Return False
    End If
End Sub
 
Sub ReadNextLine (Mail As String)
    Dim sb As StringBuilder
    sb.Initialize
    Dim c As Char
    Do While index < Mail.Length
        c = Mail.CharAt(index)
        index = index + 1
        If c = Chr(13) OR c = Chr(10) Then
            If c = Chr(13) AND index < Mail.Length AND Mail.CharAt(index) = Chr(10) Then
                index = index + 1
            End If
            Exit 'break the loop
        End If
        sb.Append(c)
    Loop
    Return sb.ToString
End Sub

5. I using this code on decode from Base64

B4X:
Sub POP_DownloadCompleted (Success As Boolean, MessageId As Int, MessageText As String)
    If Success = False Then
        'Log(LastException.Message)
        'Msgbox(LastException.Message, "Thong bao")
    Else
        Dim m As Message
      
        m = MailParser.ParseMail(MessageText, File.DirRootExternal)
              
        ListView1.AddTwoLines(m.FromField, m.Subject)     
      
    End If
End Sub
B4X:
Sub POP_DownloadCompleted (Success As Boolean, MessageId As Int, MessageText As String)
    If Success = False Then
        'Log(LastException.Message)
        'Msgbox(LastException.Message, "Thong bao")
    Else
        Dim m As Message
      
        m = MailParser.ParseMail(MessageText, File.DirRootExternal)
              
        ListView1.AddTwoLines(m.FromField, m.Subject)     
      
    End If
End Sub

6. The results are displayed on listview

2430zlk.png


7. I create a sub, it will get email adress

B4X:
Sub FindEMailAddressesInStr(StringWithEmails As String) As String
        Dim pattern As String
    Dim Matcher1 As Matcher
    Dim result As String
  
    pattern = "\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*"
  
    Matcher1 = Regex.Matcher(pattern, StringWithEmails)
  
    Do While Matcher1.Find
        result = Matcher1.Match
    Loop
  
    Return result
End Sub

8. I will remove UTF8 tag

=?UTF-8?B?
SGnhur9uIE5ndXnhu4VuIFbEg24
=?=

9. Convert base64 to string

Dim B64 As Base64
Dim result As String
result = B64.DecodeStoS("SGnhur9uIE5ndXnhu4VuIFbEg24", "UTF8")
 
Upvote 0
Top