简体   繁体   中英

Sending Email using Gmail API in java

I want to write a Java program that can send emails to any Gmail account. I am searching API's for this purpose. Till now I have found the Gmail API useful. I've also created an APP on Google's Developer Console. I could not find any example of Oauth Authorization and email sending in the Gmail API. Can anyone refer any materials or links?

try JavaMail API to use this you will need two dependencies :javaee.jar and mail.jar

Properties props = new Properties();
    props.put("mail.smtp.host", "smtp.gmail.com");
    props.put("mail.smtp.socketFactory.port", "465");
    props.put("mail.smtp.socketFactory.class",
            "javax.net.ssl.SSLSocketFactory");
    props.put("mail.smtp.auth", "true");
    props.put("mail.smtp.port", "465");

    Session session = Session.getDefaultInstance(props,
        new javax.mail.Authenticator() {
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication("username","password");
            }
        });

    try {

        Message message = new MimeMessage(session);
        message.setFrom(new InternetAddress("from@no-spam.com"));
        message.setRecipients(Message.RecipientType.TO,
                InternetAddress.parse("to@no-spam.com"));
        message.setSubject("Testing Subject");
        message.setText("Dear Mail Crawler," +
                "\n\n No spam to my email, please!");

        Transport.send(message);

        System.out.println("Done");

    } catch (MessagingException e) {
        throw new RuntimeException(e);
    }
}

I was able to send emails using this approach (this might help you although my interface was droid):

I created a separate class with the following code taken right off the gmail api example. For testing purposes I called this class SendMail.

  /**
 * Send an email from the user's mailbox to its recipient.
 *
 * @param service Authorized Gmail API instance.
 * @param userId User's email address. The special value "me"
 * can be used to indicate the authenticated user.
 * @param email Email to be sent.
 * @throws MessagingException
 * @throws IOException
 */
public static void sendMessage(Gmail service, String userId, MimeMessage email)
        throws MessagingException, IOException {
    Message message = createMessageWithEmail(email);
    message = service.users().messages().send(userId, message).execute();

    System.out.println("Message id: " + message.getId());
    System.out.println(message.toPrettyString());
}

/**
 * Create a Message from an email
 *
 * @param email Email to be set to raw of message
 * @return Message containing base64url encoded email.
 * @throws IOException
 * @throws MessagingException
 */
public static Message createMessageWithEmail(MimeMessage email)
        throws MessagingException, IOException {
    ByteArrayOutputStream bytes = new ByteArrayOutputStream();
    email.writeTo(bytes);
    String encodedEmail = Base64.encodeBase64URLSafeString(bytes.toByteArray());
    Message message = new Message();
    message.setRaw(encodedEmail);
    return message;
}

/**
 * Modify the labels a message is associated with.
 *
 * @param service Authorized Gmail API instance.
 * @param userId User's email address. The special value "me"
 * can be used to indicate the authenticated user.
 * @param messageId ID of Message to Modify.
 * @param labelsToAdd List of label ids to add.
 * @param labelsToRemove List of label ids to remove.
 * @throws IOException
 */
public static void modifyMessage(Gmail service, String userId, String messageId,
                                 List<String> labelsToAdd, List<String> labelsToRemove) throws IOException {
    ModifyMessageRequest mods = new ModifyMessageRequest().setAddLabelIds(labelsToAdd)
            .setRemoveLabelIds(labelsToRemove);
    Message message = service.users().messages().modify(userId, messageId, mods).execute();

    System.out.println("Message id: " + message.getId());
    System.out.println(message.toPrettyString());
}

/**
 * Create a MimeMessage using the parameters provided.
 *
 * @param to Email address of the receiver.
 * @param from Email address of the sender, the mailbox account.
 * @param subject Subject of the email.
 * @param bodyText Body text of the email.
 * @return MimeMessage to be used to send email.
 * @throws MessagingException
 */
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);
    InternetAddress tAddress = new InternetAddress(to);
    InternetAddress fAddress = new InternetAddress(from);

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

In Android you have to be able to allow the user to select an account. In the new platform of droid you have to also request additionally for them to allow you to use the creds of the account, you do that in the activity and in the manifest. I did that below also taken from googles example:

public class ContactsActivity extends Activity {
GoogleAccountCredential mCredential;
private TextView mOutputText;
ProgressDialog mProgress;
public static String accountName;

static final int REQUEST_ACCOUNT_PICKER = 1000;
static final int REQUEST_AUTHORIZATION = 1001;
static final int REQUEST_GOOGLE_PLAY_SERVICES = 1002;
private static final String PREF_ACCOUNT_NAME = "accountName";
private static final String[] SCOPES = {GmailScopes.GMAIL_LABELS,GmailScopes.GMAIL_SEND,GmailScopes.GMAIL_COMPOSE,GmailScopes.GMAIL_INSERT,GmailScopes.MAIL_GOOGLE_COM};
public static Gmail mService;

/**
 * Create the main activity.
 *
 * @param savedInstanceState previously saved instance data.
 */
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    LinearLayout activityLayout = new LinearLayout(this);
    LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
            LinearLayout.LayoutParams.MATCH_PARENT,
            LinearLayout.LayoutParams.MATCH_PARENT);
    activityLayout.setLayoutParams(lp);
    activityLayout.setOrientation(LinearLayout.VERTICAL);
    activityLayout.setPadding(16, 16, 16, 16);

    ViewGroup.LayoutParams tlp = new ViewGroup.LayoutParams(
            ViewGroup.LayoutParams.WRAP_CONTENT,
            ViewGroup.LayoutParams.WRAP_CONTENT);

    mOutputText = new TextView(this);
    mOutputText.setLayoutParams(tlp);
    mOutputText.setPadding(16, 16, 16, 16);
    mOutputText.setVerticalScrollBarEnabled(true);
    mOutputText.setMovementMethod(new ScrollingMovementMethod());
    activityLayout.addView(mOutputText);

    mProgress = new ProgressDialog(this);
    mProgress.setMessage("Calling Gmail API ...");

    setContentView(activityLayout);

    int permissionCheck = ContextCompat.checkSelfPermission(this,
            Manifest.permission.GET_ACCOUNTS);

    // Initialize credentials and service object.
    SharedPreferences settings = getPreferences(Context.MODE_PRIVATE);
    mCredential = GoogleAccountCredential.usingOAuth2(getApplicationContext(), Arrays.asList(SCOPES))
            .setBackOff(new ExponentialBackOff())
            .setSelectedAccountName(settings.getString(PREF_ACCOUNT_NAME, null));
}

@Override
protected void onPostCreate(Bundle savedInstanceState) {
    super.onPostCreate(savedInstanceState);
    ActivityCompat.requestPermissions(this,
            new String[]{Manifest.permission.GET_ACCOUNTS},729);
}

/**
 * Called whenever this activity is pushed to the foreground, such as after
 * a call to onCreate().
 */
@Override
protected void onResume() {
    super.onResume();
    if (isGooglePlayServicesAvailable()) {
        refreshResults();
    } else {
        mOutputText.setText("Google Play Services required: " +
                "after installing, close and relaunch this app.");
    }
}

/**
 * Called when an activity launched here (specifically, AccountPicker
 * and authorization) exits, giving you the requestCode you started it with,
 * the resultCode it returned, and any additional data from it.
 *
 * @param requestCode code indicating which activity result is incoming.
 * @param resultCode  code indicating the result of the incoming
 *                    activity result.
 * @param data        Intent (containing result data) returned by incoming
 *                    activity result.
 */
@Override
protected void onActivityResult(
        int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    switch (requestCode) {
        case REQUEST_GOOGLE_PLAY_SERVICES:
            if (resultCode != RESULT_OK) {
                isGooglePlayServicesAvailable();
            }
            break;
        case REQUEST_ACCOUNT_PICKER:
            if (resultCode == RESULT_OK && data != null &&
                    data.getExtras() != null) {
                accountName =
                        data.getStringExtra(AccountManager.KEY_ACCOUNT_NAME);
                if (accountName != null) {
                    mCredential.setSelectedAccountName(accountName);

                    SharedPreferences settings =
                            getPreferences(Context.MODE_PRIVATE);
                    SharedPreferences.Editor editor = settings.edit();
                    editor.putString(PREF_ACCOUNT_NAME, accountName);
                    editor.apply();
                }
            } else if (resultCode == RESULT_CANCELED) {
                mOutputText.setText("Account unspecified.");
            }
            break;
        case REQUEST_AUTHORIZATION:
            if (resultCode != RESULT_OK) {
                chooseAccount();
            }
            break;
    }

    super.onActivityResult(requestCode, resultCode, data);
}


/**
 * Attempt to get a set of data from the Gmail API to display. If the
 * email address isn't known yet, then call chooseAccount() method so the
 * user can pick an account.
 */
private void refreshResults() {
    mCredential.setSelectedAccountName("jennifer.ijcg@gmail.com");
    if (mCredential.getSelectedAccountName() == null) {
        chooseAccount();
    } else {
        if (isDeviceOnline()) {
            new MakeRequestTask(mCredential).execute();
        } else {
            mOutputText.setText("No network connection available.");
        }
    }
}

/**
 * Starts an activity in Google Play Services so the user can pick an
 * account.
 */
private void chooseAccount() {
    startActivityForResult(
            mCredential.newChooseAccountIntent(), REQUEST_ACCOUNT_PICKER);
}

/**
 * Checks whether the device currently has a network connection.
 *
 * @return true if the device has a network connection, false otherwise.
 */
private boolean isDeviceOnline() {
    ConnectivityManager connMgr =
            (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
    return (networkInfo != null && networkInfo.isConnected());
}

/**
 * Check that Google Play services APK is installed and up to date. Will
 * launch an error dialog for the user to update Google Play Services if
 * possible.
 *
 * @return true if Google Play Services is available and up to
 * date on this device; false otherwise.
 */
private boolean isGooglePlayServicesAvailable() {
    final int connectionStatusCode =
            GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
    if (GooglePlayServicesUtil.isUserRecoverableError(connectionStatusCode)) {
        showGooglePlayServicesAvailabilityErrorDialog(connectionStatusCode);
        return false;
    } else if (connectionStatusCode != ConnectionResult.SUCCESS) {
        return false;
    }
    return true;
}

/**
 * Display an error dialog showing that Google Play Services is missing
 * or out of date.
 *
 * @param connectionStatusCode code describing the presence (or lack of)
 *                             Google Play Services on this device.
 */
void showGooglePlayServicesAvailabilityErrorDialog(
        final int connectionStatusCode) {
    Dialog dialog = GooglePlayServicesUtil.getErrorDialog(
            connectionStatusCode,
            ContactsActivity.this,
            REQUEST_GOOGLE_PLAY_SERVICES);
    dialog.show();
}

/**
 * An asynchronous task that handles the Gmail API call.
 * Placing the API calls in their own task ensures the UI stays responsive.
 */
private class MakeRequestTask extends AsyncTask<Void, Void, List<String>> {
    private Exception mLastError = null;

    public MakeRequestTask(GoogleAccountCredential credential) {
        HttpTransport transport = AndroidHttp.newCompatibleTransport();
        JsonFactory jsonFactory = JacksonFactory.getDefaultInstance();
        mService = new com.google.api.services.gmail.Gmail.Builder(
                transport, jsonFactory, credential)
                .setApplicationName("RUOkay")
                .build();
    }

    /**
     * Background task to call Gmail API.
     *
     * @param params no parameters needed for this task.
     */
    @Override
    protected List<String> doInBackground(Void... params) {
        try {
            sendEmail();
            return null; //getDataFromApi();
        } catch (Exception e) {
            mLastError = e;
            cancel(true);
            return null;
        }
    }

    private void sendEmail() throws IOException {
        // Get the labels in the user's account.
        MimeMessage mimeMessage = null;
        Message message = null;
        String user = "jennifer.ijcg@gmail.com";
        try {
            mimeMessage = SendMail.createEmail("test@gmail.com",user,"u figured it out","your awesome");
        } catch (MessagingException e) {
            e.printStackTrace();
        }
        try {
            message = SendMail.createMessageWithEmail(mimeMessage);
        }
        catch (MessagingException e) {
            e.printStackTrace();
        }


       // mService.users().messages().send(user, message);
        try {
            SendMail.sendMessage(mService, user, mimeMessage);
        } catch (MessagingException e) {
            e.printStackTrace();
        }

    }


    @Override
    protected void onPreExecute() {
        mOutputText.setText("");
        mProgress.show();
    }

    @Override
    protected void onPostExecute(List<String> output) {
        mProgress.hide();
        if (output == null || output.size() == 0) {
            mOutputText.setText("No results returned.");
        } else {
            output.add(0, "Data retrieved using the Gmail API:");
            mOutputText.setText(TextUtils.join("\n", output));
        }
    }

    @Override
    protected void onCancelled() {
        mProgress.hide();
        if (mLastError != null) {
            if (mLastError instanceof GooglePlayServicesAvailabilityIOException) {
                showGooglePlayServicesAvailabilityErrorDialog(
                        ((GooglePlayServicesAvailabilityIOException) mLastError)
                                .getConnectionStatusCode());
            } else if (mLastError instanceof UserRecoverableAuthIOException) {
                startActivityForResult(
                        ((UserRecoverableAuthIOException) mLastError).getIntent(),
                        ContactsActivity.REQUEST_AUTHORIZATION);
            } else {
                mOutputText.setText("The following error occurred:\n"
                        + mLastError.getMessage());
            }
        } else {
            mOutputText.setText("Request cancelled.");
        }
    }

}

}

This may or may not help you but again you will need away to request their credentials unless you plan on using your/companies own to allow for emails to be sent

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM