在java中使用Gmail API发送电子邮件

时间:2015-10-21 11:42:19

标签: java email gmail

我想编写一个可以向任何Gmail帐户发送电子邮件的Java程序。 我正在为此目的搜索API。到目前为止,我发现Gmail API非常有用。我还在Google的开发者控制台上创建了一个APP。我在Gmail API中找不到任何Oauth授权和电子邮件发送的示例。任何人都可以参考任何材料或链接吗?

2 个答案:

答案 0 :(得分:2)

尝试JavaMail API 要使用它,您将需要两个依赖项:javaee.jar和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);
    }
}

答案 1 :(得分:1)

我能够使用这种方法发送电子邮件(虽然我的界面是机器人,但这可能对你有帮助):

我在gmail api示例中创建了一个单独的类,其中包含以下代码。出于测试目的,我将此类称为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;
}

在Android中,您必须能够允许用户选择一个帐户。在droid的新平台中,您还必须另外请求它们允许您使用帐户的信用,您可以在活动和清单中执行此操作。我在下面做的也是从googles例子中得到的:

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.");
        }
    }

}

}

这可能会或可能不会帮助您,但除非您计划使用您的/公司自己允许发送电子邮件,否则您将需要再次申请其凭据