Search code examples
androidgmail-apicredentials

Use Gmail api for send mail via Android app


I know there are a lot of toturials, questions etc and I was working on it at the past weeks but couldn't figure it out.

I am developing an Android app that I want to send an email to some email address, using my gmail account.

I have read all the Google Developers Documentation and tried all the examples but still can't achieve it.

1. First of all - do I have to own a G Suite account? it doesn't say that I do, but the Gmail Api overview is under G Suite section??

If I don't need a G Suite -

2. Is this the right guide to send mail by app?

If so

3. How can I get the Gmail service? I opened a project in console.developers.google and got the OAuth 2.0 Client IDs json file, but I couldn't find an explanation how to use it in Android to get the credentionals.

Please, I know those are big question but I am desperate for help. Please give me any answers or correct links (that I haven't visit yet...). I also will appreciate help via chat / mail etc.

Thanks

EDIT 8/10 my code right now:

Main Activity calls AsyncMail

AsyncMail.java

package com.send.mymailapplication;

import android.content.Context;
import android.content.res.AssetManager;
import android.os.AsyncTask;

import com.google.api.client.extensions.android.http.AndroidHttp;
import com.google.api.client.http.HttpRequestInitializer;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.client.util.Base64;
import com.google.api.services.gmail.Gmail;
import com.google.api.services.gmail.GmailScopes;
import com.google.api.services.gmail.model.Message;
import com.google.auth.http.HttpCredentialsAdapter;
import com.google.auth.oauth2.AccessToken;
import com.google.auth.oauth2.GoogleCredentials;
import com.google.common.collect.Lists;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Collections;
import java.util.Properties;

import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;



public class AsyncMail extends AsyncTask<String, Void, Void> {

    Context context;

    static HttpTransport HTTP_TRANSPORT = AndroidHttp.newCompatibleTransport();
    static JsonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance();

    public AsyncMail (Context c) {
        context = c;
    }


    @Override
    protected Void doInBackground (String... strings) {


        try {

            AssetManager assetManager = context.getAssets();
            InputStream jsonStream = assetManager.open("mail.json");

            // those 2 tryings also works but gave me the same error
            /*ServiceAccountCredentials sourceCredentials = ServiceAccountCredentials.fromStream(jsonStream);
            sourceCredentials = (ServiceAccountCredentials) sourceCredentials.createScoped(Arrays.asList("https://mail.google.com/", "https://www.googleapis.com/auth/iam"));

            GoogleCredential credential = GoogleCredential.fromStream(jsonStream).createScoped(Lists.newArrayList("https://www.googleapis.com/auth/cloud-platform", GmailScopes.MAIL_GOOGLE_COM));
            Gmail gmail = new Gmail.Builder(HTTP_TRANSPORT, JSON_FACTORY, credential).build();*/


            GoogleCredentials credential = GoogleCredentials.fromStream(jsonStream)
                           .createScoped(Lists.newArrayList("https://www.googleapis.com/auth/cloud-platform", "https://www.googleapis.com/auth/dialogflow", GmailScopes.MAIL_GOOGLE_COM));
            credential.refreshIfExpired();
            AccessToken accessToken = credential.getAccessToken ();
            String AuthToken = accessToken.getTokenValue ();


            HttpRequestInitializer requestInitializer = new HttpCredentialsAdapter (credential);


            Gmail gmail = new Gmail.Builder(HTTP_TRANSPORT, JSON_FACTORY, requestInitializer).build();

            MimeMessage mimeMessage = createEmail ("[email protected]", "[email protected]", "subbb", "bodyyyy");

            Message message = createMessageWithEmail(mimeMessage);

            gmail.users().messages().send ("[email protected]", message).execute();


        } catch (IOException | MessagingException e) {
            e.printStackTrace ();
        }
        
        return null;
    }

    private Message createMessageWithEmail (MimeMessage emailContent) throws IOException, MessagingException {

        ByteArrayOutputStream buffer = new ByteArrayOutputStream();
        emailContent.writeTo(buffer);
        byte[] bytes = buffer.toByteArray();
        String encodedEmail = Base64.encodeBase64URLSafeString(bytes);
        Message message = new Message ();
        message.setRaw(encodedEmail);
        return message;
    }

    public static MimeMessage createEmail(String to, String from, String subject, String bodyText) throws MessagingException {

        Properties props = new Properties ();
        Session session = Session.getDefaultInstance(props, null);

        MimeMessage email = new MimeMessage(session);

        email.setFrom(new InternetAddress (from));
        email.addRecipient(javax.mail.Message.RecipientType.TO,
                new InternetAddress(to));
        email.setSubject(subject);
        email.setText(bodyText);
        return email;
    }
}

I also not sure:

  1. Which credentials should I get? I would think it is ServiceAccountCredentials but the documentation says to use GoogleCredential which is deprecated so I tried GoogleCredentials

  2. Which email address shoud I use as the sender - the gmail? the sevice account? "me"? there are 2 places that I should use it

  3. What should I do with the token?

  4. At the top of the Google Api Console it says "Your free trial is waiting: activate now..." - I must activate the account to use the api? I don't think so but not sure


Solution

  • I will try to answer your multiple question

    1. No, you don't need a G Suite account to use the Gmail API, you can do it with a normal gmail account.

    2. The guide that you linked is fine, just think that inside an app or in a console, the API works over HTTPs request with a REST architecture, therefore you can use the API in any platform that support HTTP requests.

    3. This last bit will depend highly on the architecture you are using, and take into consideration that I'm not an Android expert. But the "difficult" part will be to get the authorization from the user, but I believe you can do it normally with Java.

    Useful links