android gmail integration getting user photo and user name
.java file:
package mycompany.com.gmaildemoactivity;
import android.Manifest;
import android.accounts.AccountManager;
import android.app.Activity;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GoogleApiAvailability;
import com.google.api.client.extensions.android.http.AndroidHttp;
import com.google.api.client.googleapis.extensions.android.gms.auth.GoogleAccountCredential;
import com.google.api.client.googleapis.extensions.android.gms.auth.GooglePlayServicesAvailabilityIOException;
import com.google.api.client.googleapis.extensions.android.gms.auth.UserRecoverableAuthIOException;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.client.util.ExponentialBackOff;
import com.google.api.services.gmail.GmailScopes;
import com.nostra13.universalimageloader.core.ImageLoader;
import com.nostra13.universalimageloader.core.ImageLoaderConfiguration;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import pub.devrel.easypermissions.AfterPermissionGranted;
import pub.devrel.easypermissions.EasyPermissions;
public class Main3Activity extends Activity
implements EasyPermissions.PermissionCallbacks {
GoogleAccountCredential mCredential;
ProgressDialog mProgress;
static final int REQUEST_ACCOUNT_PICKER = 1000;
static final int REQUEST_AUTHORIZATION = 1001;
static final int REQUEST_GOOGLE_PLAY_SERVICES = 1002;
static final int REQUEST_PERMISSION_GET_ACCOUNTS = 1003;
private static final String BUTTON_TEXT = "Call Gmail API";
private static final String PREF_ACCOUNT_NAME = "accountName";
private static final String[] SCOPES = {GmailScopes.GMAIL_LABELS};
ImageLoader imageLoader;
String SCOPE="oauth2:https://www.googleapis.com/auth/userinfo.profile";
private ImageView imageView;
private Button mButton;
private TextView mOutputText;
/**
* Create the main activity.
*
* @param savedInstanceState previously saved instance data.
*/
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main3);
imageView = (ImageView) findViewById(R.id.image);
mOutputText = (TextView) findViewById(R.id.text);
mButton = (Button) findViewById(R.id.button);
mButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
getResultsFromApi();
}
});
mProgress = new ProgressDialog(this);
mProgress.setMessage("Calling Gmail API ...");
// Initialize credentials and service object.
mCredential = GoogleAccountCredential.usingOAuth2(
getApplicationContext(), Arrays.asList(SCOPE))
.setBackOff(new ExponentialBackOff());
}
/**
* Attempt to call the API, after verifying that all the preconditions are
* satisfied. The preconditions are: Google Play Services installed, an
* account was selected and the device currently has online access. If any
* of the preconditions are not satisfied, the app will prompt the user as
* appropriate.
*/
private void getResultsFromApi() {
if (!isGooglePlayServicesAvailable()) {
acquireGooglePlayServices();
} else if (mCredential.getSelectedAccountName() == null) {
chooseAccount();
} else if (!isDeviceOnline()) {
mOutputText.setText("No network connection available.");
} else {
new MakeRequestTask(mCredential).execute();
}
}
/**
* Attempts to set the account used with the API credentials. If an account
* name was previously saved it will use that one; otherwise an account
* picker dialog will be shown to the user. Note that the setting the
* account to use with the credentials object requires the app to have the
* GET_ACCOUNTS permission, which is requested here if it is not already
* present. The AfterPermissionGranted annotation indicates that this
* function will be rerun automatically whenever the GET_ACCOUNTS permission
* is granted.
*/
@AfterPermissionGranted(REQUEST_PERMISSION_GET_ACCOUNTS)
private void chooseAccount() {
if (EasyPermissions.hasPermissions(
this, Manifest.permission.GET_ACCOUNTS)) {
String accountName = getPreferences(Context.MODE_PRIVATE)
.getString(PREF_ACCOUNT_NAME, null);
if (accountName != null) {
mCredential.setSelectedAccountName(accountName);
getResultsFromApi();
} else {
// Start a dialog from which the user can choose an account
startActivityForResult(
mCredential.newChooseAccountIntent(),
REQUEST_ACCOUNT_PICKER);
}
} else {
// Request the GET_ACCOUNTS permission via a user dialog
EasyPermissions.requestPermissions(
this,
"This app needs to access your Google account (via Contacts).",
REQUEST_PERMISSION_GET_ACCOUNTS,
Manifest.permission.GET_ACCOUNTS);
}
}
/**
* Called when an activity launched here (specifically, AccountPicker
* and authorization) exits, giving you the requestCode you started it with,
* the resultCode it returned, and any additional data from it.
*
* @param requestCode code indicating which activity result is incoming.
* @param resultCode code indicating the result of the incoming
* activity result.
* @param data Intent (containing result data) returned by incoming
* activity result.
*/
@Override
protected void onActivityResult(
int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case REQUEST_GOOGLE_PLAY_SERVICES:
if (resultCode != RESULT_OK) {
mOutputText.setText(
"This app requires Google Play Services. Please install " +
"Google Play Services on your device and relaunch this app.");
} else {
getResultsFromApi();
}
break;
case REQUEST_ACCOUNT_PICKER:
if (resultCode == RESULT_OK && data != null &&
data.getExtras() != null) {
String accountName =
data.getStringExtra(AccountManager.KEY_ACCOUNT_NAME);
if (accountName != null) {
SharedPreferences settings =
getPreferences(Context.MODE_PRIVATE);
SharedPreferences.Editor editor = settings.edit();
editor.putString(PREF_ACCOUNT_NAME, accountName);
editor.apply();
mCredential.setSelectedAccountName(accountName);
getResultsFromApi();
}
}
break;
case REQUEST_AUTHORIZATION:
if (resultCode == RESULT_OK) {
getResultsFromApi();
}
break;
}
}
/**
* Respond to requests for permissions at runtime for API 23 and above.
*
* @param requestCode The request code passed in
* requestPermissions(android.app.Activity, String, int, String[])
* @param permissions The requested permissions. Never null.
* @param grantResults The grant results for the corresponding permissions
* which is either PERMISSION_GRANTED or PERMISSION_DENIED. Never null.
*/
@Override
public void onRequestPermissionsResult(int requestCode,
@NonNull String[] permissions,
@NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
EasyPermissions.onRequestPermissionsResult(
requestCode, permissions, grantResults, this);
}
/**
* Callback for when a permission is granted using the EasyPermissions
* library.
*
* @param requestCode The request code associated with the requested
* permission
* @param list The requested permission list. Never null.
*/
@Override
public void onPermissionsGranted(int requestCode, List<String> list) {
// Do nothing.
}
/**
* Callback for when a permission is denied using the EasyPermissions
* library.
*
* @param requestCode The request code associated with the requested
* permission
* @param list The requested permission list. Never null.
*/
@Override
public void onPermissionsDenied(int requestCode, List<String> list) {
// Do nothing.
}
/**
* Checks whether the device currently has a network connection.
*
* @return true if the device has a network connection, false otherwise.
*/
private boolean isDeviceOnline() {
ConnectivityManager connMgr =
(ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
return (networkInfo != null && networkInfo.isConnected());
}
/**
* Check that Google Play services APK is installed and up to date.
*
* @return true if Google Play Services is available and up to
* date on this device; false otherwise.
*/
private boolean isGooglePlayServicesAvailable() {
GoogleApiAvailability apiAvailability =
GoogleApiAvailability.getInstance();
final int connectionStatusCode =
apiAvailability.isGooglePlayServicesAvailable(this);
return connectionStatusCode == ConnectionResult.SUCCESS;
}
/**
* Attempt to resolve a missing, out-of-date, invalid or disabled Google
* Play Services installation via a user dialog, if possible.
*/
private void acquireGooglePlayServices() {
GoogleApiAvailability apiAvailability =
GoogleApiAvailability.getInstance();
final int connectionStatusCode =
apiAvailability.isGooglePlayServicesAvailable(this);
if (apiAvailability.isUserResolvableError(connectionStatusCode)) {
showGooglePlayServicesAvailabilityErrorDialog(connectionStatusCode);
}
}
/**
* Display an error dialog showing that Google Play Services is missing
* or out of date.
*
* @param connectionStatusCode code describing the presence (or lack of)
* Google Play Services on this device.
*/
void showGooglePlayServicesAvailabilityErrorDialog(
final int connectionStatusCode) {
GoogleApiAvailability apiAvailability = GoogleApiAvailability.getInstance();
Dialog dialog = apiAvailability.getErrorDialog(
Main3Activity.this,
connectionStatusCode,
REQUEST_GOOGLE_PLAY_SERVICES);
dialog.show();
}
/**
* An asynchronous task that handles the Gmail API call.
* Placing the API calls in their own task ensures the UI stays responsive.
*/
class MakeRequestTask extends AsyncTask<Void, Void, List<String>> {
private com.google.api.services.gmail.Gmail mService = null;
private Exception mLastError = null;
public MakeRequestTask(GoogleAccountCredential credential) {
HttpTransport transport = AndroidHttp.newCompatibleTransport();
JsonFactory jsonFactory = JacksonFactory.getDefaultInstance();
mService = new com.google.api.services.gmail.Gmail.Builder(
transport, jsonFactory, credential)
.setApplicationName("Gmail API Android Quickstart")
.build();
}
/**
* Background task to call Gmail API.
*
* @param params no parameters needed for this task.
*/
@Override
protected List<String> doInBackground(Void... params) {
try {
return getDataFromApi();
} catch (Exception e) {
mLastError = e;
cancel(true);
return null;
}
}
/**
* Fetch a list of Gmail labels attached to the specified account.
*
* @return List of Strings labels.
* @throws IOException
*/
private List<String> getDataFromApi() throws IOException {
// Get the labels in the user's account.
String user = "me";
List<String> labels = new ArrayList<String>();
// ListLabelsResponse listResponse =
// mService.users().labels().list(user).execute();
// for (Label label : listResponse.getLabels()) {
// labels.add(label.getName());
// }
String accountName = getPreferences(Context.MODE_PRIVATE)
.getString(PREF_ACCOUNT_NAME, null);
new GetNameInForeground(Main3Activity.this, accountName,SCOPE).execute();
return labels;
}
@Override
protected void onPreExecute() {
mOutputText.setText("");
mProgress.show();
}
@Override
protected void onPostExecute(List<String> output) {
mProgress.hide();
output.add(0, "Data retrieved using the Gmail API:");
JSONObject jsonObject;
imageLoader = ImageLoader.getInstance();
imageLoader.init(ImageLoaderConfiguration.createDefault(Main3Activity.this));
try {
jsonObject = new JSONObject(AbstractGetNameTask.GOOGLE_USER_DATA);
Log.d("Lokesh",jsonObject.toString());
String s = jsonObject.getString("name");
String pic = jsonObject.getString("picture");
imageLoader.displayImage(pic,imageView);
mOutputText.setText(s);
Log.d("Lokesh","user name is :"+s);
} catch (JSONException e) {
e.printStackTrace();
}
}
@Override
protected void onCancelled() {
mProgress.hide();
if (mLastError != null) {
if (mLastError instanceof GooglePlayServicesAvailabilityIOException) {
showGooglePlayServicesAvailabilityErrorDialog(
((GooglePlayServicesAvailabilityIOException) mLastError)
.getConnectionStatusCode());
} else if (mLastError instanceof UserRecoverableAuthIOException) {
startActivityForResult(
((UserRecoverableAuthIOException) mLastError).getIntent(),
Main3Activity.REQUEST_AUTHORIZATION);
} else {
mOutputText.setText("The following error occurred:\n"
+ mLastError.getMessage());
}
} else {
mOutputText.setText("Request cancelled.");
}
}
}
}
package mycompany.com.gmaildemoactivity;
import android.os.AsyncTask;
import android.util.Log;
import com.google.android.gms.auth.GoogleAuthUtil;
import org.json.JSONException;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
/**
* Created by Lokesh on 9/29/2016.
*/
public abstract class AbstractGetNameTask extends AsyncTask<Void, Void, Void> {
private static final String TAG = "TokenInfoTask";
protected Main3Activity mActivity;
public static String GOOGLE_USER_DATA="No_data";
protected String mScope;
protected String mEmail;
protected int mRequestCode;
AbstractGetNameTask(Main3Activity activity, String email, String scope) {
this.mActivity = activity;
this.mScope = scope;
this.mEmail = email;
}
@Override
protected Void doInBackground(Void... params) {
try {
fetchNameFromProfileServer();
} catch (IOException ex) {
onError("Following Error occured, please try again. "
+ ex.getMessage(), ex);
} catch (JSONException e) {
onError("Bad response: " + e.getMessage(), e);
}
return null;
}
protected void onError(String msg, Exception e) {
if (e != null) {
Log.e(TAG, "Exception: ", e);
}
}
/**
073
* Get a authentication token if one is not available. If the error is not
074
* recoverable then it displays the error message on parent activity.
075
*/
protected abstract String fetchToken() throws IOException;
/**
079
* Contacts the user info server to get the profile of the user and extracts
080
* the first name of the user from the profile. In order to authenticate
081
* with the user info server the method first fetches an access token from
082
* Google Play services.
083
* @return
084
* @return
085
*
086
* @throws IOException
087
* if communication with user info server failed.
088
* @throws JSONException
089
* if the response from the server could not be parsed.
090
*/
private void fetchNameFromProfileServer() throws IOException, JSONException {
String token = fetchToken();
URL url = new URL("https://www.googleapis.com/oauth2/v1/userinfo?access_token="+ token);
HttpURLConnection con = (HttpURLConnection) url.openConnection();
int sc = con.getResponseCode();
if (sc == 200) {
InputStream is = con.getInputStream();
GOOGLE_USER_DATA = readResponse(is);
is.close();
// intent.putExtra("email_id", mEmail);
return;
} else if (sc == 401) {
GoogleAuthUtil.invalidateToken(mActivity, token);
onError("Server auth error, please try again.", null);
//Toast.makeText(mActivity, "Please try again", Toast.LENGTH_SHORT).show();
//mActivity.finish();
return;
} else {
onError("Server returned the following error code: " + sc, null);
return;
}
}
/**
119
* Reads the response from the input stream and returns it as a string.
120
*/
private static String readResponse(InputStream is) throws IOException {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
byte[] data = new byte[2048];
int len = 0;
while ((len = is.read(data, 0, data.length)) >= 0) {
bos.write(data, 0, len);
}
return new String(bos.toByteArray(), "UTF-8");
}
}
package mycompany.com.gmaildemoactivity;
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 java.io.IOException;
/**
* Created by Dell on 9/29/2016.
*/
public class GetNameInForeground extends AbstractGetNameTask {
public GetNameInForeground(Main3Activity activity, String email, String mScope) {
super(activity, email,mScope);
}
/**
37
* Get a authentication token if one is not available. If the error is not recoverable then
38
* it displays the error message on parent activity right away.
39
*/
@Override
protected String fetchToken() throws IOException {
try {
return GoogleAuthUtil.getToken(mActivity, mEmail, mScope);
} catch (GooglePlayServicesAvailabilityException playEx) {
// GooglePlayServices.apk is either old, disabled, or not present.
} catch (UserRecoverableAuthException userRecoverableException) {
// Unable to authenticate, but the user can fix this.
// Forward the user to the appropriate activity.
mActivity.startActivityForResult(userRecoverableException.getIntent(), mRequestCode);
} catch (GoogleAuthException fatalException) {
onError("Unrecoverable error " + fatalException.getMessage(), fatalException);
}
return null;
}
}
activity_main3.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:orientation="vertical"
tools:context="mycompany.com.gmaildemoactivity.Main3Activity">
<Button
android:id="@+id/button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#000"
android:text="Click here" />
<TextView
android:id="@+id/text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#000"
android:text="Click here" />
<ImageView
android:id="@+id/image"
android:layout_marginTop="50dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:src="@mipmap/ic_launcher"/>
</LinearLayout>
output:
Full documentaion : Gmail API from google developers site, and youtube https://www.youtube.com/watch?v=8MkwcvcZefQ