Android Tutorial Using POP3 to communicate with Android devices

Discussion in 'Tutorials & Examples' started by Erel, Sep 5, 2011.

  1. Erel

    Erel Administrator Staff Member Licensed User

    Many developers face the challenge of sending data to remote devices. These devices can be at times offline, sleeping or without proper network coverage.
    There are several possible solutions. The device can contact a web server which will return the required data.
    Another solution is to use Google push notification framework.
    Here I want to present a third solution which doesn't require any custom server and is pretty simple.
    Using the Net library a device can connect to a mail server and download the mail messages.
    This solution can fit very well in many cases and is very simple to manage. Mail servers are very common and are easy to work with.
    All you need is an email service that supports POP3. Gmail is one such service.

    The POP3 object from the Net library returns the raw messages as strings.
    Additional work is required to get the message fields and especially to extract attachments from the messages.
    MailParser code module is included in the attached project.
    MailParser parses the messages, saves the attachments and returns Messages objects which hold the various fields.

    MailParser cannot be used as a real mail client. There are many possible formats and encodings. MailParser can handle simple formats with zero or more attachments.

    Parsing a message is done by calling:
    Code:
    Dim m As Message
          m = MailParser.ParseMail(MessageText, 
    File.DirRootExternal)
    The first parameter is the raw message and the second is the folder that the attachments will be saved to.

    MailParser requires StringUtils library for the base64 decoding.
     

    Attached Files:

    koaunglay likes this.
  2. thedesolatesoul

    thedesolatesoul Expert Licensed User

    Very interesting!!!
    But I am not completely sure how this will work.
    You set an email address app@gmail.com and save the username/password in the app to be able to retrieve the message.
    How does the sending server know how to send it to a particular device? It may be useful for broadcast but cant you put in an ID for each device?
    Also, doesnt POP retrieval delete the message from the server, in that case how do you broadcast to all devices?
    Thanks for this though :)
     
  3. Erel

    Erel Administrator Staff Member Licensed User

    There is nothing special here. It is not a push service. The device should connect to the server and check for mails. The last parameter in POP3.DownloadMessage determines whether the mail will be deleted after it is downloaded or not.

    If you are using a single mail account for multiple devices then you can use the message subject or something similar to distinguish between different targeted devices.
     
  4. thedesolatesoul

    thedesolatesoul Expert Licensed User

    I will try this soon.
    Just wondering if there is a way to POP messages from a particular date (so that the app doesnt try to retrieve all the old messages)?
     
  5. Erel

    Erel Administrator Staff Member Licensed User

    Currently there is no way to do it.
     
  6. thedesolatesoul

    thedesolatesoul Expert Licensed User

    Okay, thanks. :)
     
  7. alain bertrand

    alain bertrand Member Licensed User

    Erel,
    Mailparser module is working fine returning the string (eg):
    Parser SubjectField =?utf-8?Q?Mademoiselle_Julie_au_Th=C3=A9=C3=A2tre_du_Parc?=
    How to get rid of "=?utf-8?Q?" and "?=" to return just:
    Mademoiselle Julie au Théâtre du Parc
    I guess I'm not the first to ask, but I've found the answer.
    Thanks.
     
  8. Erel

    Erel Administrator Staff Member Licensed User

    You can use this code:
    Code:
    Sub Activity_Create(FirstTime As Boolean)
       
    Log(DecodeQuotePrintable("=?utf-8?Q?Mademoiselle_Julie_au_Th=C3=A9=C3=A2tre_du_Parc?="))
    End Sub

    Sub DecodeQuotePrintable(q As StringAs String
       
    Dim m As Matcher
       m = 
    Regex.Matcher("=\?([^?]*)\?Q\?(.*)\?=$", q)
       
    If m.Find Then
          
    Dim charset As String
          
    Dim data As String
          charset = m.Group(
    1)
          data = m.Group(
    2)
          
    Dim bytes As List
          bytes.Initialize
          
    Dim i As Int
          
    Do While i < data.Length
             
    Dim c As String
             c = data.CharAt(i)
             
    If c = "_" Then
                bytes.AddAll(
    " ".GetBytes(charset))
             
    Else If c = "=" Then
                
    Dim hex As String
                hex = data.CharAt(i + 
    1) & data.CharAt(i + 2)
                i = i + 
    2
                bytes.Add(
    Bit.ParseInt(hex, 16))
             
    Else
                bytes.AddAll(c.GetBytes(charset))
             
    End If
             i = i + 
    1
          
    Loop
          
    Dim b(bytes.Size) As Byte
          
    For i = 0 To bytes.Size - 1
             b(i) = bytes.Get(i)
          
    Next
          
    Return BytesToString(b, 0, b.Length, charset)
       
    Else
          
    Return q
       
    End If
    End Sub
    Note that it wasn't tested thoroughly enough...
     
  9. alain bertrand

    alain bertrand Member Licensed User

    Great ! I didn't expect a so quick answer.
    So it isn't a built-in function.
    We have got to code. Thanks * 1000 for doing it.
    What would we make without regular expressions ?
     
  10. Mickster

    Mickster Active Member Licensed User

    Could someone please demonstrate how I can use this code to obtain the subject of an email?
     
  11. William Hunter

    William Hunter Active Member Licensed User

    Net Library and mailparser

    I too have been trying to find a way to use native B4A tools to obtain header info. Without the means of using messageID as a pointer, I can't find a way. I would be most appreciative of any help in this regard. :sign0085:

    Best regards
     
  12. Mickster

    Mickster Active Member Licensed User

    It would be useful to be able to read the email subject before downloading the entire thing including attachments, since there will be many emails in the account and many large attachments.

    At the moment I'm downloading all the emails and I'm noticing that each email seems to be held in the device's memory. It piles up QUICK. Any reason for this?
     
  13. wl

    wl Well-Known Member Licensed User

    I have created a extended POP3 library that should be able to this. William Hunter has been using it: I just created it and have not used it really myself (yet)
     
  14. Mickster

    Mickster Active Member Licensed User

    Sounds cool, could I use it please?
     
  15. sacad

    sacad Member Licensed User

    Struggeling to see inbox messages?

    Hi ive downloaded the mailparser app and also have the required libaries but cannot get the application to display any email messages?
    Im at gmail and this is what ive done in the activity_create event
    If FirstTime Then
    pop.Initialize("pop.gmail.com",995,"my gmail adress with .com","my password of gmail","pop")
    End If
    pop.ListMessages
    end sub

    dont know if the server and port is incorrect coz found that on net
     
  16. Mickster

    Mickster Active Member Licensed User

  17. sacad

    sacad Member Licensed User

    Why my email inbox messages does not display?

    This is my whole program when i run the emulator it is blank showing no messages. what must i do. i did send email to that account and have internet but the emulator shows nothing. im using the core(v 1.9) net(version 1.20) and stringutils(version 1.0)


    Sub Process_Globals
    Dim pop As POP3
    End Sub
    Sub Globals

    End Sub
    Sub Activity_Create(FirstTime As Boolean)
    If FirstTime Then
    pop.useSSL = True
    pop.Initialize("pop.gmail.com",995,"my email.gmail.com","my password",pop)
    pop.useSSL = True

    End If
    pop.useSSL = True
    pop.ListMessages

    End Sub

    Sub POP_ListCompleted (Success As Boolean, Messages As Map)
    If Success = False Then
    Log(LastException.Message)
    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
    Log(LastException.Message)
    Else
    Log(MessageId)
    'Parse the mail
    Dim m As Message
    m = MailParser.ParseMail(MessageText, File.DirRootExternal)
    Log(m)
    End If
    End Sub

    Sub Activity_Pause(UserClosed As Boolean)

    End Sub
    Sub Activity_Resume

    End Sub
     
  18. sacad

    sacad Member Licensed User

    mailparser gmail setup

    Configuring other mail clients - Gmail Help
    I also did this tutorial and enabled my pop in gmail and saved changes
     
  19. Mickster

    Mickster Active Member Licensed User

    If your mail is being successfully downloaded (check your log to make sure you aren't receiving errors), then 'm' contains all the data from the email.

    As you're looping through all the emails in the account and re-declaring 'm' every time, it's only going to hold the information from the last email it successfully downloaded. Bear in mind that if your account has a lot of emails then the device most likely wasn't able to keep up and has probably crashed due to the loop.

    Anyway, to display the data from the email that is now stored in 'm', you need to create a label or something that can display the data. Use:

    Code:
    m.body...
    m.subject...
    etc to print the different parts of your mail.
     
  20. Erel

    Erel Administrator Staff Member Licensed User

    @sacad, please do not post duplicate questions.
     
Loading...
  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice