Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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. I am developing the app in Eclipse using the ADT plug-in.
What I have done so far:

  • I registered the application in the Google Developers Console
    (link: console.developers.google.com/project).

  • I have implemented the Google+ Sign-in button (link: 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.

  • I added the additional scope 'https:// www.googleapis.com/auth/gmail.readonly' to the Google+ Authorization, for accessing the Gmail API, as specified in
    (Link: developers.google.com/gmail/api/v1/reference/users/threads/list).

At this point I have an initialized GoogleApiClient object.

The GoogleApiClient object wraps a ServiceConnection (link: developer.android.com/reference/android/content/ServiceConnection.html) to Google Play services. 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:

  • Google Play services is running on the device and the app Activity has successfully bound the service connection,
  • the user has selected an account that they wish to use with the app, and
  • the user's account has granted the permissions that the app is requesting.



How do I proceed from here to getting all the messages with this 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.

EDIT: 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 protected]";



@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

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
like image 763
ViktoriaDoneva Avatar asked Jul 10 '14 21:07

ViktoriaDoneva


4 Answers

(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). 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).

Now for some working samples: here are the Android quickstart & the more general Java quickstart. Having the Gmail API JavaDocs reference at your side isn't a bad idea either. OAuth2 is now the preferred way to perform auth, meaning you'll need code that looks like this, plus the right 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());

Other than this "setup," the OP has most everything needed to get something working:

  1. Having a project in the developers console & enabled the Gmail API with the SHA1 hash (as described above in the Android quickstart)
  2. Implementing OAuth2 with the correct scope(s)
  3. Making the call to ListThreadsResponse listResponse = mService.users().threads().list(user).execute(); -- the quickstart uses labels() so you can just change to threads()

To learn more about the API, below are 3 videos, the first introducing the API when it launched. 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):

  • Introducing the Gmail API
  • Revolutionizing Email Access with the Gmail API (code deep dive post)
  • Modifying your signature with the Gmail API (code deep dive post)

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.

like image 136
wescpy Avatar answered Oct 15 '22 16:10

wescpy


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

like image 33
Sukhbir Avatar answered Oct 15 '22 17:10

Sukhbir


class i use t access 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("[email protected],[email protected]");
m.setFromAddress("[email protected]");
m.setMailSubject(subjectText);
m.setMailBody(bodyText);
like image 1
Archit Jain Avatar answered Oct 15 '22 15:10

Archit Jain


According to NoClassDefFoundError: com/google/api/client/util/Lists when setting up oauth2 on app engine,

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.

like image 1
Joe B. Avatar answered Oct 15 '22 17:10

Joe B.