首页 文章

如何从我的Android应用访问新的Gmail API?

提问于
浏览
24

我试图从我的Android应用程序访问新的Gmail API(已宣布25.06.2014),以便返回某个用户帐户中的所有电子邮件 . 我正在使用ADT插件在Eclipse中开发应用程序 .
到目前为止我做了什么:

  • 我在Google Developers Console中注册了该应用程序
    (链接: console.developers.google.com/project ) .

  • 我已实施Google登录按钮(链接: developers.google.com/+/mobile/android/sign-in ) . Google登录按钮可对用户进行身份验证并管理OAuth 2.0流程,从而简化您与Google API的集成 .

  • 我已将附加范围'https:// www.googleapis.com/auth/gmail.readonly'添加到Google授权中,以便访问Gmail API,如
    (链接: developers.google.com/gmail/api/v1/reference/users/threads/list ) .

此时我有一个初始化的GoogleApiClient对象 .

GoogleApiClient对象将ServiceConnection(链接: developer.android.com/reference/android/content/ServiceConnection.html )包装到Google Play服务 . GoogleApiClient对象用于与Google API通信,并在与服务 Build 异步连接后正常运行,表明:

  • Google Play服务正在设备上运行,应用程序Activity已成功绑定服务连接,

  • 用户已选择他们希望与该应用一起使用的帐户,并且

  • 用户的帐户已授予应用请求的权限 .

如何从此处继续使用此httprequest获取所有消息?
我此时尝试访问Gmail API,但我收到身份验证错误401:需要登录,即使Google登录成功,我也成功返回了用户圈子列表 .

编辑: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);
       }

    }

编辑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

4 回答

  • 1

    (Feb 2017) Gmail API(v1 launched 2014年6月)是将Gmail功能集成到您的应用中的最佳方式(并且优先于POP / IMAP和SMTP) . 要使用Android和Android中的大多数其他Google API,您需要获取the Google APIs Client Library for Android(或更常用的Java,the Google APIs Client Library for Java) .

    现在有一些工作样本:这里是Android quickstart和更通用的Java quickstart . 让Gmail API JavaDocs reference在您这边't a bad idea either. OAuth2 is now the preferred way to perform auth, meaning you' ll需要看起来像这样的代码,加上正确的scope

    // 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());
    

    除了这个“设置”之外,OP还拥有最需要的东西来完成工作:

    • developers console中有一个项目并使用SHA1哈希启用了Gmail API(如上所述,在Android快速入门中)

    • 使用正确的范围实施OAuth2

    • the call设为 ListThreadsResponse listResponse = mService.users().threads().list(user).execute(); - 快速入门使用 labels() ,因此您只需更改为 threads()

    要了解有关API的更多信息,请参阅下面的3个视频,第一个是在推出时介绍API . 如果你对Python没有“过敏”,我使用Gmail API(非移动版)制作另一对使用简短但更“真实”的例子:

    它没有被提及作为 Headers 的一部分,但上面的第二个视频包含一个使用Gmail API访问线程和消息的代码示例 .

  • 2

    我使用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;
    }
    }
    

    要使用此课程 -

    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);
    
  • 1

    使用此代码:

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

    希望这会有所帮助

  • 3

    根据NoClassDefFoundError: com/google/api/client/util/Lists when setting up oauth2 on app engine

    您的

    java.lang.NoClassDefFoundError: com.google.api.client.googleapis.auth.oauth2.GoogleCredential
    

    错误意味着您在类路径中缺少依赖项 .

    但另一方面,您的身份验证错误可能只是一个服务器错误,因为您的令牌已经过时,您只需要重新提交一个新令牌 . 看看this是否对你有帮助 . 它有点老(写于2013年),但也许一些评论可以帮助 .

相关问题