使用Android中的OAuth2.0通过GMail发送邮件,引发异常com.google.android.gms.auth.UserRecoverableAuthException:商业G-suit帐户需要权限,并且与普通的gmail帐户配合正常
按如下所示初始化Google API客户端。
GoogleAccountCredential mCredential;
String[] SCOPES = {
GmailScopes.GMAIL_LABELS,
GmailScopes.GMAIL_COMPOSE,
GmailScopes.GMAIL_INSERT,
GmailScopes.GMAIL_MODIFY,
GmailScopes.GMAIL_READONLY,
GmailScopes.MAIL_GOOGLE_COM
};
初始化凭据和服务对象。
mCredential = GoogleAccountCredential.usingOAuth2(
getApplicationContext(), Arrays.asList(SCOPES))
.setBackOff(new ExponentialBackOff());
//用于使用GMail OAuth发送邮件的异步任务
private class MakeRequestTask extends AsyncTask {
private com.google.api.services.gmail.Gmail mService = null;
private Exception mLastError = null;
private View view = sendFabButton;
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(getResources().getString(R.string.app_name))
.build();
}
@Override
protected String doInBackground(Void... params) {
try {
return getDataFromApi();
} catch (Exception e) {
mLastError = e;
cancel(true);
return null;
}
}
private String getDataFromApi() throws IOException {
// getting Values for to Address, from Address, Subject and Body
String user = "me";
String to = Utils.getString(edtToAddress);
String from = mCredential.getSelectedAccountName();
String subject = Utils.getString(edtSubject);
String body = Utils.getString(edtMessage);
MimeMessage mimeMessage;
String response = "";
try {
mimeMessage = createEmail(to, from, subject, body);
response = sendMessage(mService, user, mimeMessage);
} catch (MessagingException e) {
e.printStackTrace();
}
return response;
}
// Method to send email
private String sendMessage(Gmail service,
String userId,
MimeMessage email)
throws MessagingException, IOException {
Message message = createMessageWithEmail(email);
// GMail's official method to send email with oauth2.0
message = service.users().messages().send(userId, message).execute();
System.out.println("Message id: " + message.getId());
System.out.println(message.toPrettyString());
return message.getId();
}
// Method to create email Params
private 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(fAddress);
email.addRecipient(javax.mail.Message.RecipientType.TO, tAddress);
email.setSubject(subject);
// Create Multipart object and add MimeBodyPart objects to this object
Multipart multipart = new MimeMultipart();
// Changed for adding attachment and text
// This line is used for sending only text messages through mail
// email.setText(bodyText);
BodyPart textBody = new MimeBodyPart();
textBody.setText(bodyText);
multipart.addBodyPart(textBody);
if (!(activity.fileName.equals(""))) {
// Create new MimeBodyPart object and set DataHandler object to this object
MimeBodyPart attachmentBody = new MimeBodyPart();
String filename = activity.fileName; // change accordingly
DataSource source = new FileDataSource(filename);
attachmentBody.setDataHandler(new DataHandler(source));
attachmentBody.setFileName(filename);
multipart.addBodyPart(attachmentBody);
}
// Set the multipart object to the message object
email.setContent(multipart);
return email;
}
private 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;
}
@Override
protected void onPreExecute() {
mProgress.show();
}
@Override
protected void onPostExecute(String output) {
mProgress.hide();
if (output == null || output.length() == 0) {
showMessage(view, "No results returned.");
} else {
showMessage(view, 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(),
Utils.REQUEST_AUTHORIZATION);
} else {
showMessage(view, "The following error occurred:\n" + mLastError.getMessage());
Log.v("Error", mLastError.getMessage());
}
} else {
showMessage(view, "Request Cancelled.");
}
}
}
如果是企业帐户,它将转到oncancelled()方法并抛出
com.google.android.gms.auth.UserRecoverableAuthException: NeedPermission
答案 0 :(得分:0)
您的身份验证令牌已过期,您需要再次向Google进行身份验证。捕获UserRecoverableAuthException并在Exception对象上调用getIntent以获取身份验证Intent。然后再次启动活动进行身份验证。 reference
try {
// Your code
...
} catch (UserRecoverableAuthIOException e) {
startActivityForResult(e.getIntent(), REQUEST_AUTHORIZATION);
}