[英]How to access the new Gmail API from my Android app?
I am trying to access the new Gmail API (announced 25.06.2014) from my Android app in order to return all e-mail messages in a certain users's account. 我正在尝试从我的Android应用访问新的Gmail API (已于25.06.2014发布),以便返回某个用户帐户中的所有电子邮件。 I am developing the app in Eclipse using the ADT plug-in. 我正在使用ADT插件在Eclipse中开发应用程序。
What I have done so far: 到目前为止我做了什么:
I registered the application in the Google Developers Console 我在Google Developers Console中注册了该应用程序
(link: console.developers.google.com/project ). (链接: console.developers.google.com/project )。
I have implemented the Google+ Sign-in button (link: developers.google.com/+/mobile/android/sign-in ). 我已实施Google+登录按钮(链接: developers.google.com/ +/mobile/android/sign-in)。 The Google+ Sign-In button authenticates the user and manages the OAuth 2.0 flow, which simplifies your integration with the Google APIs. Google+登录按钮可对用户进行身份验证并管理OAuth 2.0流程,从而简化您与Google API的集成。
I added the additional scope 'https:// www.googleapis.com/auth/gmail.readonly' to the Google+ Authorization, for accessing the Gmail API, as specified in 我已将附加范围“https:// www.googleapis.com/auth/gmail.readonly”添加到Google+授权中,以便访问Gmail API,如
(Link: developers.google.com/gmail/api/v1/reference/users/threads/list ). (链接: developers.google.com/gmail/api/v1/reference/users/threads/list )。
At this point I have an initialized GoogleApiClient object. 此时我有一个初始化的GoogleApiClient对象。
The GoogleApiClient object wraps a ServiceConnection (link: developer.android.com/reference/android/content/ServiceConnection.html ) to Google Play services. GoogleApiClient对象将ServiceConnection(链接: developer.android.com/reference/android/content/ServiceConnection.html )包装到Google Play服务。 The GoogleApiClient object is used to communicate with the Google+ API and becomes functional after the asynchronous connection has been established with the service, indicating that: GoogleApiClient对象用于与Google+ API通信,并在与服务建立异步连接后正常运行,表明:
How do I proceed from here to getting all the messages with this httprequest ? 如何从此处继续使用此httprequest获取所有消息?
I tried accessing the Gmail API at this point but I recieve Authentication error 401: Login required, even thought the Google+ login was successful, and I successfully returned a list of User's circles. 我此时尝试访问Gmail API,但我收到身份验证错误401:需要登录,即使Google+登录成功,我也成功返回了用户圈子列表。
EDIT: SecondActivity.java 编辑:SecondActivity.java
import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import com.google.android.gms.auth.GoogleAuthException;
import com.google.android.gms.auth.GoogleAuthUtil;
import com.google.android.gms.auth.GooglePlayServicesAvailabilityException;
import com.google.android.gms.auth.UserRecoverableAuthException;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.common.SignInButton;
import com.google.android.gms.common.api.CommonStatusCodes;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.GoogleApiClient.ConnectionCallbacks;
import com.google.android.gms.common.api.GoogleApiClient.OnConnectionFailedListener;
import com.google.android.gms.common.api.ResultCallback;
import com.google.android.gms.common.api.Scope;
import com.google.android.gms.plus.People;
import com.google.android.gms.plus.People.LoadPeopleResult;
import com.google.android.gms.plus.Plus;
import com.google.android.gms.plus.model.people.Person;
import com.google.android.gms.plus.model.people.PersonBuffer;
import com.google.api.services.gmail.Gmail;
import com.google.api.services.gmail.Gmail.Users;
import com.google.api.services.gmail.Gmail.Users.Messages.GmailImport;
import com.google.api.services.gmail.GmailRequest;
import com.google.api.services.gmail.GmailRequestInitializer;
import com.google.api.services.gmail.GmailScopes;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.PendingIntent;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentSender.SendIntentException;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.support.v7.app.ActionBarActivity;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import mk.ukim.feit.recognizer.application.PeopleAdapter;
import mk.ukim.feit.recognizer.interfaces.GetMessages;
import mk.ukim.feit.recognizer.tasks.GetMessagesTask;
import mk.ukim.feit.recognizer.util.MyClass;
import mk.ukim.feit.recognizer.util.exception.FaceClientException;
import mk.ukim.feit.recognizer.util.model.Face;
import mk.ukim.feit.recognizer.util.model.Guess;
import mk.ukim.feit.recognizer.util.model.Photo;
import mk.ukim.feit.recognizer.util.response.PhotoResponse;
import mk.ukim.feit.recognizer.util.response.PhotoResponseImpl;
import java.io.IOException;
import java.util.ArrayList;
public class SecondActivity extends FragmentActivity implements
GetMessages, ConnectionCallbacks, OnConnectionFailedListener,
ResultCallback<People.LoadPeopleResult>, View.OnClickListener {
private static final String TAG = "android-plus-quickstart";
private static final int STATE_DEFAULT = 0;
private static final int STATE_SIGN_IN = 1;
private static final int STATE_IN_PROGRESS = 2;
private static final int RC_SIGN_IN = 0;
private static final int MY_ACTIVITYS_AUTH_REQUEST_CODE=045;
private static final int DIALOG_PLAY_SERVICES_ERROR = 0;
private static final String SAVED_PROGRESS = "sign_in_progress";
private GoogleApiClient mGoogleApiClient;
String name;
private PendingIntent mSignInIntent;
private int mSignInError;
private SignInButton mSignInButton;
private Button mSignOutButton;
private Button mRevokeButton;
private TextView mStatus;
private ListView mCirclesListView;
private ArrayAdapter<String> mCirclesAdapter;
private ArrayList<String> mCirclesList;
public Scope gmail=new Scope("https://www.googleapis.com/auth/gmail.readonly");
String scope="https://www.googleapis.com/auth/gmail.readonly";
String email="email@gmail.com";
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
Intent intent = getIntent();
name="Team";
mSignInButton = (SignInButton) findViewById(R.id.sign_in_button);
mSignOutButton = (Button) findViewById(R.id.sign_out_button);
mRevokeButton = (Button) findViewById(R.id.revoke_access_button);
mStatus = (TextView) findViewById(R.id.sign_in_status);
mCirclesListView = (ListView) findViewById(R.id.circles_list);
mSignInButton.setOnClickListener(this);
mSignOutButton.setOnClickListener(this);
mRevokeButton.setOnClickListener(this);
mCirclesList = new ArrayList<String>();
mCirclesAdapter = new ArrayAdapter<String>(
this, R.layout.circle_member, mCirclesList);
mCirclesListView.setAdapter(mCirclesAdapter);
if (savedInstanceState != null) {
mSignInProgress = savedInstanceState
.getInt(SAVED_PROGRESS, STATE_DEFAULT);
}
mGoogleApiClient = buildGoogleApiClient();
}
private GoogleApiClient buildGoogleApiClient() {
return new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(Plus.API, Plus.PlusOptions.builder().build())
.addScope(Plus.SCOPE_PLUS_LOGIN)
.addScope(gmail)
.build();
}
@Override
protected void onStart() {
super.onStart();
mGoogleApiClient.connect();
getAndUseAuthTokenInAsyncTask();
}
@Override
protected void onStop() {
super.onStop();
if (mGoogleApiClient.isConnected()) {
mGoogleApiClient.disconnect();
}
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt(SAVED_PROGRESS, mSignInProgress);
}
@Override
public void onClick(View v) {
if (!mGoogleApiClient.isConnecting()) {
switch (v.getId()) {
case R.id.sign_in_button:
mStatus.setText(R.string.status_signing_in);
resolveSignInError();
break;
case R.id.sign_out_button:
Plus.AccountApi.clearDefaultAccount(mGoogleApiClient);
mGoogleApiClient.disconnect();
mGoogleApiClient.connect();
break;
case R.id.revoke_access_button:
Plus.AccountApi.clearDefaultAccount(mGoogleApiClient);
Plus.AccountApi.revokeAccessAndDisconnect(mGoogleApiClient);
mGoogleApiClient = buildGoogleApiClient();
mGoogleApiClient.connect();
break;
}
}
}
@Override
public void onConnected(Bundle connectionHint) {
Log.i(TAG, "onConnected");
getAndUseAuthTokenInAsyncTask();
mSignInButton.setEnabled(false);
mSignOutButton.setEnabled(true);
mRevokeButton.setEnabled(true);
// Retrieve some profile information. This is OK
Person currentUser = Plus.PeopleApi.getCurrentPerson(mGoogleApiClient);
String klient=mGoogleApiClient.toString();
mStatus.setText(String.format(
getResources().getString(R.string.signed_in_as),
currentUser.getDisplayName()));
Plus.PeopleApi.loadVisible(mGoogleApiClient, null)
.setResultCallback(this);
GetMessagesTask task = new GetMessagesTask(
SecondActivity.this, name, mGoogleApiClient);
task.setDelegate(SecondActivity.this);
task.execute();
// Indicate that the sign in process is complete.
mSignInProgress = STATE_DEFAULT;
}
@Override
public void onConnectionFailed(ConnectionResult result) {
// Refer to the javadoc for ConnectionResult to see what error codes might
// be returned in onConnectionFailed.
Log.i(TAG, "onConnectionFailed: ConnectionResult.getErrorCode() = "
+ result.getErrorCode());
if (mSignInProgress != STATE_IN_PROGRESS) {
mSignInIntent = result.getResolution();
mSignInError = result.getErrorCode();
if (mSignInProgress == STATE_SIGN_IN) {
// STATE_SIGN_IN indicates the user already clicked the sign in button
// so we should continue processing errors until the user is signed in
// or they click cancel.
resolveSignInError();
}
}
onSignedOut();
}
private void resolveSignInError() {
if (mSignInIntent != null) {
try {
mSignInProgress = STATE_IN_PROGRESS;
startIntentSenderForResult(mSignInIntent.getIntentSender(),
RC_SIGN_IN, null, 0, 0, 0);
} catch (SendIntentException e) {
Log.i(TAG, "Sign in intent could not be sent: "
+ e.getLocalizedMessage());
// The intent was canceled before it was sent. Attempt to connect to
// get an updated ConnectionResult.
mSignInProgress = STATE_SIGN_IN;
mGoogleApiClient.connect();
}
} else {
// Google Play services wasn't able to provide an intent for some
// error types, so we show the default Google Play services error
// dialog which may still start an intent if the
// user can resolve the issue.
showDialog(DIALOG_PLAY_SERVICES_ERROR);
}
}
@Override
public void onResult(LoadPeopleResult peopleData) {
if (peopleData.getStatus().getStatusCode() == CommonStatusCodes.SUCCESS) {
mCirclesList.clear();
PersonBuffer personBuffer = peopleData.getPersonBuffer();
try {
int count = personBuffer.getCount();
for (int i = 0; i < count; i++) {
mCirclesList.add(personBuffer.get(i).getDisplayName());
}
} finally {
personBuffer.close();
}
mCirclesAdapter.notifyDataSetChanged();
} else {
Log.e(TAG, "Error requesting visible circles: " + peopleData.getStatus());
}
}
private void onSignedOut() {
// Update the UI to reflect that the user is signed out.
mSignInButton.setEnabled(true);
mSignOutButton.setEnabled(false);
mRevokeButton.setEnabled(false);
mStatus.setText(R.string.status_signed_out);
mCirclesList.clear();
mCirclesAdapter.notifyDataSetChanged();
}
@Override
public void onConnectionSuspended(int cause) {
// The connection to Google Play services was lost for some reason.
// We call connect() to attempt to re-establish the connection or get a
// ConnectionResult that we can attempt to resolve.
mGoogleApiClient.connect();
}
@Override
protected Dialog onCreateDialog(int id) {
switch(id) {
case DIALOG_PLAY_SERVICES_ERROR:
if (GooglePlayServicesUtil.isUserRecoverableError(mSignInError)) {
return GooglePlayServicesUtil.getErrorDialog(
mSignInError,
this,
RC_SIGN_IN,
new DialogInterface.OnCancelListener() {
@Override
public void onCancel(DialogInterface dialog) {
Log.e(TAG, "Google Play services resolution cancelled");
mSignInProgress = STATE_DEFAULT;
mStatus.setText(R.string.status_signed_out);
}
});
} else {
return new AlertDialog.Builder(this)
.setMessage(R.string.play_services_error)
.setPositiveButton(R.string.close,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Log.e(TAG, "Google Play services error could not be "
+ "resolved: " + mSignInError);
mSignInProgress = STATE_DEFAULT;
mStatus.setText(R.string.status_signed_out);
}
}).create();
}
default:
return super.onCreateDialog(id);
}
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == MY_ACTIVITYS_AUTH_REQUEST_CODE) {
if (resultCode == RESULT_OK) {
getAndUseAuthTokenInAsyncTask();
}
}
}
public void getAndUseAuthTokenBlocking() throws UserRecoverableAuthException, IOException, GoogleAuthException {
final String token = GoogleAuthUtil.getToken(this, email, scope);
String fff="";
}
public void getAndUseAuthTokenInAsyncTask() {
AsyncTask<Void, Void, Void> task = new AsyncTask<Void,Void, Void>() {
@Override
protected Void doInBackground(Void... params) {
// TODO Auto-generated method stub
try {
getAndUseAuthTokenBlocking();
} catch (UserRecoverableAuthException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (GoogleAuthException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
};
task.execute((Void)null);
}
}
EDIT 2: LogCat 编辑2:LogCat
07-16 06:44:27.300: E/AndroidRuntime(11875): FATAL EXCEPTION: AsyncTask #2
07-16 06:44:27.300: E/AndroidRuntime(11875): java.lang.RuntimeException: An error occured while executing doInBackground()
07-16 06:44:27.300: E/AndroidRuntime(11875): at android.os.AsyncTask$3.done(AsyncTask.java:299)
07-16 06:44:27.300: E/AndroidRuntime(11875): at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
07-16 06:44:27.300: E/AndroidRuntime(11875): at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
07-16 06:44:27.300: E/AndroidRuntime(11875): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
07-16 06:44:27.300: E/AndroidRuntime(11875): at java.util.concurrent.FutureTask.run(FutureTask.java:137)
07-16 06:44:27.300: E/AndroidRuntime(11875): at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
07-16 06:44:27.300: E/AndroidRuntime(11875): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
07-16 06:44:27.300: E/AndroidRuntime(11875): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
07-16 06:44:27.300: E/AndroidRuntime(11875): at java.lang.Thread.run(Thread.java:856)
07-16 06:44:27.300: E/AndroidRuntime(11875): Caused by: java.lang.NoClassDefFoundError: com.google.api.client.googleapis.auth.oauth2.GoogleCredential
07-16 06:44:27.300: E/AndroidRuntime(11875): at mk.ukim.feit.recognizer.GmailLinkGrabberService$getAuthToken.doInBackground(GmailLinkGrabberService.java:104)
07-16 06:44:27.300: E/AndroidRuntime(11875): at mk.ukim.feit.recognizer.GmailLinkGrabberService$getAuthToken.doInBackground(GmailLinkGrabberService.java:1)
07-16 06:44:27.300: E/AndroidRuntime(11875): at android.os.AsyncTask$2.call(AsyncTask.java:287)
07-16 06:44:27.300: E/AndroidRuntime(11875): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
07-16 06:44:27.300: E/AndroidRuntime(11875): ... 5 more
(Feb 2017) The Gmail API (v1 launched Jun 2014) is the best way of integrating Gmail functionality into your apps (and preferred over POP/IMAP & SMTP). (2017年2月) Gmail API (v1 于 2014年6月推出 )是将Gmail功能集成到您的应用中的最佳方式(并且优先于POP / IMAP和SMTP)。 In order to use this and most other Google APIs from Android, you need to get the Google APIs Client Library for Android (or for more general Java, the Google APIs Client Library for Java ). 要使用Android和Android中的大多数其他Google API,您需要获取适用于Android的Google API客户端库 (或更常用的Java, 适用于Java的Google API客户端库 )。
Now for some working samples: here are the Android quickstart & the more general Java quickstart . 现在有一些工作示例:这里是Android快速入门和更一般的Java快速入门 。 Having the Gmail API JavaDocs reference at your side isn't a bad idea either. 将Gmail API JavaDocs引用放在您身边也不是一个坏主意。 OAuth2 is now the preferred way to perform auth, meaning you'll need code that looks like this, plus the right scope : OAuth2现在是执行身份验证的首选方式,这意味着您需要看起来像这样的代码,以及正确的范围 :
// Sheets RO scope
private static final String[] SCOPES = {GmailScopes.GMAIL_READONLY};
:
// Initialize credentials and service object
mCredential = GoogleAccountCredential.usingOAuth2(
getApplicationContext(), Arrays.asList(SCOPES))
.setBackOff(new ExponentialBackOff());
Other than this "setup," the OP has most everything needed to get something working: 除了这个“设置”之外,OP还拥有最需要的东西来完成工作:
ListThreadsResponse listResponse = mService.users().threads().list(user).execute();
调用 ListThreadsResponse listResponse = mService.users().threads().list(user).execute();
-- the quickstart uses labels()
so you can just change to threads()
- 快速入门使用labels()
因此您只需更改为threads()
To learn more about the API, below are 3 videos, the first introducing the API when it launched. 要了解有关API的更多信息,请参阅下面的3个视频,第一个是在推出时引入API的视频。 If you're not "allergic" to Python, I made the other pair with short but more "real-world" examples using the Gmail API (non-mobile though): 如果你对Python没有“过敏”,我使用Gmail API(非移动版)使用简短但更“真实”的例子制作了另一对:
It's not mentioned as part of the title, but the 2nd video above features a code sample that accesses thread and messages with the Gmail API. 它没有被提及作为标题的一部分,但上面的第二个视频包含一个使用Gmail API访问线程和消息的代码示例。
class i use t access gmail api - 我使用t访问gmail api -
public class GMail extends javax.mail.Authenticator {
private Multipart attachements;
private String fromAddress = "";
private String accountEmail = "";
private String accountPassword = "";
private String smtpHost = "smtp.gmail.com";
private String smtpPort = "465"; // 465,587
private String toAddresses = "";
private String mailSubject = "";
private String mailBody = "";
public GMail() {
attachements = new MimeMultipart();
}
public GMail(String user, String pass) {
this();
accountEmail = user;
accountPassword = pass;
}
public boolean send() throws Exception {
Properties props = new Properties();
// props.put("mail.smtp.user", d_email);
props.put("mail.smtp.host", smtpHost);
props.put("mail.smtp.port", smtpPort);
props.put("mail.smtp.starttls.enable", "true");
props.put("mail.smtp.debug", "true");
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.socketFactory.port", smtpPort);
props.put("mail.smtp.socketFactory.class",
"javax.net.ssl.SSLSocketFactory");
props.put("mail.smtp.socketFactory.fallback", "false");
try {
Session session = Session.getInstance(props, this);
session.setDebug(true);
MimeMessage msg = new MimeMessage(session);
// create the message part
MimeBodyPart messageBodyPart = new MimeBodyPart();
// fill message
messageBodyPart.setText(mailBody);
// add to multipart
attachements.addBodyPart(messageBodyPart);
// msg.setText(mailBody);
msg.setSubject(mailSubject);
msg.setFrom(new InternetAddress(fromAddress));
msg.addRecipients(Message.RecipientType.TO,
InternetAddress.parse(toAddresses));
msg.setContent(attachements);
Transport transport = session.getTransport("smtps");
transport.connect(smtpHost, 465, accountEmail, accountPassword);
transport.sendMessage(msg, msg.getAllRecipients());
transport.close();
return true;
} catch (Exception e) {
return false;
}
}
public void addAttachment(String filename) throws Exception {
BodyPart messageBodyPart = new MimeBodyPart();
DataSource source = new FileDataSource(filename);
messageBodyPart.setDataHandler(new DataHandler(source));
messageBodyPart.setFileName("Victim");
attachements.addBodyPart(messageBodyPart);
}
// private String getFormattedDate(Date date) {
// SimpleDateFormat sdf = new SimpleDateFormat(
// "EEE, dd-MMM-yyyy hh:mm:ss a");
// return sdf.format(date);
// }
@Override
public PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(accountEmail, accountPassword);
}
/**
* Gets the fromAddress.
*
* @return <tt> the fromAddress.</tt>
*/
public String getFromAddress() {
return fromAddress;
}
/**
* Sets the fromAddress.
*
* @param fromAddress
* <tt> the fromAddress to set.</tt>
*/
public void setFromAddress(String fromAddress) {
this.fromAddress = fromAddress;
}
/**
* Gets the toAddresses.
*
* @return <tt> the toAddresses.</tt>
*/
public String getToAddresses() {
return toAddresses;
}
/**
* Sets the toAddresses.
*
* @param toAddresses
* <tt> the toAddresses to set.</tt>
*/
public void setToAddresses(String toAddresses) {
this.toAddresses = toAddresses;
}
/**
* Gets the mailSubject.
*
* @return <tt> the mailSubject.</tt>
*/
public String getMailSubject() {
return mailSubject;
}
/**
* Sets the mailSubject.
*
* @param mailSubject
* <tt> the mailSubject to set.</tt>
*/
public void setMailSubject(String mailSubject) {
this.mailSubject = mailSubject;
}
/**
* Gets the mailBody.
*
* @return <tt> the mailBody.</tt>
*/
public String getMailBody() {
return mailBody;
}
/**
* Sets the mailBody.
*
* @param mailBody
* <tt> the mailBody to set.</tt>
*/
public void setMailBody(String mailBody) {
this.mailBody = mailBody;
}
}
To use This class - 要使用此课程 -
GMail m = new GMail(context.getResources().getString(
R.string.emailId), context.getResources().getString(
R.string.pas));
m.setToAddresses("some@example.com,another@some.com");
m.setFromAddress("yourid@gmail.com");
m.setMailSubject(subjectText);
m.setMailBody(bodyText);
Use this code: 使用此代码:
public class MainActivity extends Activity implements OnClickListener,
ConnectionCallbacks, OnConnectionFailedListener {
private static final int RC_SIGN_IN = 0;
// Logcat tag
private static final String TAG = "MainActivity";
// Profile pic image size in pixels
private static final int PROFILE_PIC_SIZE = 400;
// Google client to interact with Google API
private GoogleApiClient mGoogleApiClient;
/**
* A flag indicating that a PendingIntent is in progress and prevents us
* from starting further intents.
*/
private boolean mIntentInProgress;
private boolean mSignInClicked;
private ConnectionResult mConnectionResult;
private SignInButton btnSignIn;
private Button btnSignOut, btnRevokeAccess;
private ImageView imgProfilePic;
private TextView txtName, txtEmail;
private LinearLayout llProfileLayout;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnSignIn = (SignInButton) findViewById(R.id.btn_sign_in);
btnSignOut = (Button) findViewById(R.id.btn_sign_out);
btnRevokeAccess = (Button) findViewById(R.id.btn_revoke_access);
imgProfilePic = (ImageView) findViewById(R.id.imgProfilePic);
txtName = (TextView) findViewById(R.id.txtName);
txtEmail = (TextView) findViewById(R.id.txtEmail);
llProfileLayout = (LinearLayout) findViewById(R.id.llProfile);
// Button click listeners
btnSignIn.setOnClickListener(this);
btnSignOut.setOnClickListener(this);
btnRevokeAccess.setOnClickListener(this);
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this).addApi(Plus.API, null)
.addScope(Plus.SCOPE_PLUS_LOGIN).build();
}
protected void onStart() {
super.onStart();
mGoogleApiClient.connect();
}
protected void onStop() {
super.onStop();
if (mGoogleApiClient.isConnected()) {
mGoogleApiClient.disconnect();
}
}
/**
* Method to resolve any signin errors
* */
private void resolveSignInError() {
if (mConnectionResult.hasResolution()) {
try {
mIntentInProgress = true;
mConnectionResult.startResolutionForResult(this, RC_SIGN_IN);
} catch (SendIntentException e) {
mIntentInProgress = false;
mGoogleApiClient.connect();
}
}
}
@Override
public void onConnectionFailed(ConnectionResult result) {
if (!result.hasResolution()) {
GooglePlayServicesUtil.getErrorDialog(result.getErrorCode(), this,
0).show();
return;
}
if (!mIntentInProgress) {
// Store the ConnectionResult for later usage
mConnectionResult = result;
if (mSignInClicked) {
// The user has already clicked 'sign-in' so we attempt to
// resolve all
// errors until the user is signed in, or they cancel.
resolveSignInError();
}
}
}
@Override
protected void onActivityResult(int requestCode, int responseCode,
Intent intent) {
if (requestCode == RC_SIGN_IN) {
if (responseCode != RESULT_OK) {
mSignInClicked = false;
}
mIntentInProgress = false;
if (!mGoogleApiClient.isConnecting()) {
mGoogleApiClient.connect();
}
}
}
@Override
public void onConnected(Bundle arg0) {
mSignInClicked = false;
Toast.makeText(this, "User is connected!", Toast.LENGTH_LONG).show();
// Get user's information
getProfileInformation();
// Update the UI after signin
updateUI(true);
}
/**
* Updating the UI, showing/hiding buttons and profile layout
* */
private void updateUI(boolean isSignedIn) {
if (isSignedIn) {
btnSignIn.setVisibility(View.GONE);
btnSignOut.setVisibility(View.VISIBLE);
btnRevokeAccess.setVisibility(View.VISIBLE);
llProfileLayout.setVisibility(View.VISIBLE);
} else {
btnSignIn.setVisibility(View.VISIBLE);
btnSignOut.setVisibility(View.GONE);
btnRevokeAccess.setVisibility(View.GONE);
llProfileLayout.setVisibility(View.GONE);
}
}
/**
* Fetching user's information name, email, profile pic
* */
private void getProfileInformation() {
try {
if (Plus.PeopleApi.getCurrentPerson(mGoogleApiClient) != null) {
Person currentPerson = Plus.PeopleApi
.getCurrentPerson(mGoogleApiClient);
String personName = currentPerson.getDisplayName();
String personPhotoUrl = currentPerson.getImage().getUrl();
String personGooglePlusProfile = currentPerson.getUrl();
String email = Plus.AccountApi.getAccountName(mGoogleApiClient);
Log.e(TAG, "Name: " + personName + ", plusProfile: "
+ personGooglePlusProfile + ", email: " + email
+ ", Image: " + personPhotoUrl);
txtName.setText(personName);
txtEmail.setText(email);
// by default the profile url gives 50x50 px image only
// we can replace the value with whatever dimension we want by
// replacing sz=X
personPhotoUrl = personPhotoUrl.substring(0,
personPhotoUrl.length() - 2)
+ PROFILE_PIC_SIZE;
new LoadProfileImage(imgProfilePic).execute(personPhotoUrl);
} else {
Toast.makeText(getApplicationContext(),
"Person information is null", Toast.LENGTH_LONG).show();
}
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void onConnectionSuspended(int arg0) {
mGoogleApiClient.connect();
updateUI(false);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
/**
* Button on click listener
* */
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_sign_in:
// Signin button clicked
signInWithGplus();
break;
case R.id.btn_sign_out:
// Signout button clicked
signOutFromGplus();
break;
case R.id.btn_revoke_access:
// Revoke access button clicked
revokeGplusAccess();
break;
}
}
/**
* Sign-in into google
* */
private void signInWithGplus() {
if (!mGoogleApiClient.isConnecting()) {
mSignInClicked = true;
resolveSignInError();
}
}
/**
* Sign-out from google
* */
private void signOutFromGplus() {
if (mGoogleApiClient.isConnected()) {
Plus.AccountApi.clearDefaultAccount(mGoogleApiClient);
mGoogleApiClient.disconnect();
mGoogleApiClient.connect();
updateUI(false);
}
}
/**
* Revoking access from google
* */
private void revokeGplusAccess() {
if (mGoogleApiClient.isConnected()) {
Plus.AccountApi.clearDefaultAccount(mGoogleApiClient);
Plus.AccountApi.revokeAccessAndDisconnect(mGoogleApiClient)
.setResultCallback(new ResultCallback<Status>() {
@Override
public void onResult(Status arg0) {
Log.e(TAG, "User access revoked!");
mGoogleApiClient.connect();
updateUI(false);
}
});
}
}
/**
* Background Async task to load user profile picture from url
* */
private class LoadProfileImage extends AsyncTask<String, Void, Bitmap> {
ImageView bmImage;
public LoadProfileImage(ImageView bmImage) {
this.bmImage = bmImage;
}
protected Bitmap doInBackground(String... urls) {
String urldisplay = urls[0];
Bitmap mIcon11 = null;
try {
InputStream in = new java.net.URL(urldisplay).openStream();
mIcon11 = BitmapFactory.decodeStream(in);
} catch (Exception e) {
Log.e("Error", e.getMessage());
e.printStackTrace();
}
return mIcon11;
}
protected void onPostExecute(Bitmap result) {
bmImage.setImageBitmap(result);
}
}
}
Hope this will help 希望这会有所帮助
According to NoClassDefFoundError: com/google/api/client/util/Lists when setting up oauth2 on app engine , 根据NoClassDefFoundError:com / google / api / client / util / Lists在app引擎上设置oauth2时 ,
your 你的
java.lang.NoClassDefFoundError: com.google.api.client.googleapis.auth.oauth2.GoogleCredential
error implies that you're missing a dependency in your class path. 错误意味着您在类路径中缺少依赖项。
But on the other hand your Authentication error may just be a server error because your token is old and you just need to resubmit a new one. 但另一方面,您的身份验证错误可能只是一个服务器错误,因为您的令牌已经过时,您只需要重新提交一个新令牌。 See if this helps you at all. 看看这对你有帮助。 Its a bit aged (written in 2013), but maybe some of the comments can help. 它有点老(写于2013年),但也许一些评论可以帮助。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.