I am new to android and trying to use Google Drive to store and retrieve data.I have write a code to connect google drive. It is showing account chooser dialog and on selecting of account nothing is happening.
public class SyncActivity extends MainActivity implements GoogleApiClient.ConnectionCallbacks,GoogleApiClient.OnConnectionFailedListener
{
GoogleApiClient googleApiClient;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sync);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
googleApiClient = new GoogleApiClient.Builder(this)
.addApi(Drive.API)
.addScope(Drive.SCOPE_FILE)
.addScope(Drive.SCOPE_APPFOLDER)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
Button btnConnectDrive = (Button)findViewById(R.id.connectDrive);
btnConnectDrive.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
try{
googleApiClient.connect();
}
catch(Exception e){
e.printStackTrace();
}
}
});
}
#Override
public void onConnected(Bundle bundle) {
super.onConnected(bundle);
System.out.println("Connected!!!!!!!!!!!!!!!");
}
#Override
public void onConnectionSuspended(int i) {
super.onConnectionSuspended(i);
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
super.onConnectionFailed(connectionResult);
if(connectionResult.hasResolution()){
try {
connectionResult.startResolutionForResult(this, ConnectionResult.RESOLUTION_REQUIRED);
} catch (IntentSender.SendIntentException e) {
// Unable to resolve, message user appropriately
e.printStackTrace();
}
}
else {
GooglePlayServicesUtil.getErrorDialog(connectionResult.getErrorCode(), this, 0).show();
}
}
}
There's a bunch of steps you need to follow like setup SHA1 fingerprint and obtaining credentials from your Google Dev Console. Follow the Steps indicated in Android Quickstart, the code snippets are provided too.
If you want a quick code reference, download the Android Demo for Drive API. I was able to run it on my Android device.
Here's a snippet on the Account chooser:
/**
* 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;
}
}
Related
Maybe I overlooked something, but through Play Games Services documentation https://developers.google.com/games/services/android/quickstart,I did not yet get any idea about how to implement backend server authentication like how to get a token from Google's server and pass it to my own backend server to verify a login. I wish someone can give me a clue. Thanks !
Step 1:
Create a button with standard google Login button
Step2 : Add a buttonclick listener
Step 3 : In listner check for google play services availablity
public void googleLoginClicked(View v){
if (checkPlayServices()) {
pickUserAccount();
}else{
showToast("Google Play Services is not installed or updated in your deivce", Toast.LENGTH_LONG);
}
}
protected boolean checkPlayServices() {
int resultCode =
GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
if (resultCode != ConnectionResult.SUCCESS) {
if (GooglePlayServicesUtil.isUserRecoverableError(resultCode)) {
GooglePlayServicesUtil.getErrorDialog(resultCode, this,
PLAY_SERVICES_RESOLUTION_REQUEST).show();
} else {
// Log.i("GCM", "This device is not supported.");
finish();
}
return false;
}
return true;
}
Step 4:
search for google accounts in phone:
private void pickUserAccount() {
String[] accountTypes = new String[]{"com.google"};
Intent intent = AccountPicker.newChooseAccountIntent(null, null,
accountTypes, false, null, null, null, null);
startActivityForResult(intent, REQUEST_CODE_PICK_ACCOUNT);
}
Step5:
onActivityResult:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_CODE_PICK_ACCOUNT) {
if (resultCode == RESULT_OK) {
mEmail = data.getStringExtra(AccountManager.KEY_ACCOUNT_NAME);
getUsername(null);
} else if (resultCode == RESULT_CANCELED) {
showToast("You must pick an account",
Toast.LENGTH_SHORT);
}
} else if (requestCode == REQUEST_CODE_RECOVER_FROM_PLAY_SERVICES_ERROR && resultCode == RESULT_OK) {
Bundle extra = data.getExtras();
String oneTimeToken = extra.getString("authtoken");
getUsername(oneTimeToken);
}
}
Step6: ON success get username from google using a background task
AsyncTask:
doinbackground(){
...
fetchToken
...
}
protected String fetchToken() throws IOException {
try {
return GoogleAuthUtil.getToken(mActivity, mEmail, mScope);
} catch (UserRecoverableAuthException userRecoverableException) {
// GooglePlayServices.apk is either old, disabled, or not present, which is
// recoverable, so we need to show the user some UI through the activity.
mActivity.handleException(userRecoverableException);
} catch (GoogleAuthException fatalException) {
onError("Unrecoverable error " + fatalException.getMessage(), fatalException);
}
return null;
}
I'm trying to implement Google+ login in my application but it won't work.
Everytime I click log in, the onConnectionFailed gets called as soon as I choose the account.
Could someone please let me know what's wrong?
public class LoginActivity extends ActionBarActivity
implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, View.OnClickListener{
/*
Variables
*/
/* Request code used to invoke sign in user interactions. */
private static final int RC_SIGN_IN = 0;
/* Client used to interact with Google APIs. */
private GoogleApiClient mGoogleApiClient;
/* A flag indicating that a PendingIntent is in progress and prevents
* us from starting further intents.
*/
private boolean mIntentInProgress;
/*
* True if the sign-in button was clicked. When true, we know to resolve all
* issues preventing sign-in without waiting.
*/
private boolean mSignInClicked;
/*
Lifecycle
*/
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(Plus.API, Plus.PlusOptions.builder().build())
.addScope(Plus.SCOPE_PLUS_LOGIN)
.build();
// Sign in button click listener
findViewById(R.id.googleSignInButton).setOnClickListener(this);
}
#Override
protected void onStart() {
super.onStart();
mGoogleApiClient.connect();
}
#Override
protected void onStop() {
super.onStop();
if (mGoogleApiClient.isConnected()) {
mGoogleApiClient.disconnect();
}
}
/*
Callbacks
*/
#Override
public void onClick(View v) {
if (v.getId() == R.id.googleSignInButton && !mGoogleApiClient.isConnecting()) {
mSignInClicked = true;
mGoogleApiClient.connect();
}
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
Log.i("TAG", "onConnectionFailed");
if (!mIntentInProgress) {
if (mSignInClicked && connectionResult.hasResolution()) {
// The user has already clicked 'sign-in' so we attempt to resolve all
// errors until the user is signed in, or they cancel.
try {
connectionResult.startResolutionForResult(this, RC_SIGN_IN);
mIntentInProgress = true;
} catch (IntentSender.SendIntentException e) {
// The intent was canceled before it was sent. Return to the default
// state and attempt to connect to get an updated ConnectionResult.
mIntentInProgress = false;
mGoogleApiClient.connect();
}
}
}
}
#Override
public void onConnected(Bundle bundle) {
Log.i("TAG", "onConnected");
mSignInClicked = false;
Toast.makeText(this, "User is connected!", Toast.LENGTH_LONG).show();
}
#Override
public void onConnectionSuspended(int i) {
Log.i("TAG", "onConnectionSuspended");
mGoogleApiClient.connect();
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == RC_SIGN_IN) {
if (resultCode != RESULT_OK) {
mSignInClicked = false;
}
mIntentInProgress = false;
if (!mGoogleApiClient.isConnected()) {
mGoogleApiClient.reconnect();
}
}
}
}
I even downloaded official Google sample for login and I get the same error. It just won't log in and connect.
I have good connection (even wifi) and I tried it on multiple phones.
It just might be an issue with the key you are using.
Go to your google api's console Try Generating a new Cient id with your
SHA1 obtained from debug.keystore and try Login again.I'm sure it'll help solve your issue.
I am new to android development. I am integrating google plus login into my App, I am little bit confusing that the Singing in prompt of google is occurring repeatedly. I can't understand why, is anything wrong with me?
I am following Google Developer Site to make this thing. I tested the app using multiple google account but 2 of them are works fine but rest of the account did not.
Have you tried:
How do I debug my Google+ integration?
By enabling logging, you can diagnose network issues when working with the Google APIs.
To enable logging, run the following command:
adb shell setprop log.tag.GooglePlusPlatform VERBOSE
To disable logging, run the following command:
adb shell setprop log.tag.GooglePlusPlatform ""
Permission which you have to add:
To access Google+ APIs:
<uses-permission android:name="android.permission.INTERNET" />
To retrieve the account name (email) as part of sign-in:
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
To retrieve OAuth 2.0 tokens or invalidate tokens to disconnect a user. This disconnect option is required to comply with the Google+ Sign-In developer policies:
<uses-permission android:name="android.permission.USE_CREDENTIALS" />
See, if that helps.
protected void onStart() {
super.onStart();
mGoogleApiClient.connect();
}
protected void onStop() {
super.onStop();
if (mGoogleApiClient.isConnected()) {
mGoogleApiClient.disconnect();
}
}
onCreate(Bundle bundle){
mGoogleApiClient = new GoogleApiClient.Builder(YourActivity.this)
.addConnectionCallbacks(YourActivity.this)
.addOnConnectionFailedListener(YourActivity.this).addApi(Plus.API)
.addScope(Plus.SCOPE_PLUS_LOGIN).build();
}
btn_gpluslogin.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
signInWithGplus();
}
});
private void signInWithGplus() {
if (!mGoogleApiClient.isConnecting()) {
mSignInClicked = true;
resolveSignInError();
}
}
private void resolveSignInError() {
if (mConnectionResult.hasResolution()) {
try {
mIntentInProgress = true;
mConnectionResult.startResolutionForResult(this, RC_SIGN_IN);
} catch (IntentSender.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
public void onConnected(Bundle arg0) {
mSignInClicked = false;
Toast.makeText(this, "User is connected!", Toast.LENGTH_LONG).show();
// Get user's information
SharedPreferences pref = getApplicationContext().getSharedPreferences("MyPref", 0); // 0 - for private mode
boolean isSignedUp = pref.getBoolean("isSignedUp", false);
if (!isSignedUp)
getGProfileInformation();
// Update the UI after signin
}
private void updateUI(boolean isSignedIn) {
if (isSignedIn) {
getGProfileInformation();
} else {
btn_gpluslogin.setVisibility(View.VISIBLE);
}
}
/**
* Fetching user's information name, email, profile pic
*/
private void getGProfileInformation() {
try {
if (Plus.PeopleApi.getCurrentPerson(mGoogleApiClient) != null) {
Person currentPerson = Plus.PeopleApi
.getCurrentPerson(mGoogleApiClient);
Log.d("Google Info", currentPerson.toString());
String personName = currentPerson.getDisplayName();
String email = Plus.AccountApi.getAccountName(mGoogleApiClient);
} else {
Toast.makeText(getApplicationContext(),
"Person information is null", Toast.LENGTH_LONG).show();
}
} catch (Exception e) {
e.printStackTrace();
}
}
Since you did not provided any code, let me guess. If you say you have problems with certain accounts and others not, it seems to me these problematic accounts have not authorized your app. Please check (while logged in a browser) this configuration:
https://security.google.com/settings/security/permissions?pli=1
Or this?
https://plus.google.com/u/0/apps
And look for your app in the list. Maybe your permissions were denied or something. Perhaps you just need to grant them again, reset and try again.
Here is what I bet is happening.
In onConnectionFailed you are starting the resolution from the connectionResult. This then launches the Activity to resolve the failure and should return the result to onActivityResult. However you need to make sure not to get into a resolution loop.
So in onConnectionFailed, do this:
private boolean mIsResolving = false;
// ...
public void onConnectionFailed(ConnectionResult connectionResult) {
if (connectionResult.hasResolution() && !mIsResolving) {
mIsResolving = true;
connectionResult.startResolutionForResult(this, RC_SIGN_IN);
}
}
Then in onActivityResult do this:
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == RC_SIGN_IN) {
if (resultCode == RESULT_OK) {
mIsResolving = false;
mGoogleApitClient.connect();
} else {
// ...
}
}
}
Once I logged in gdrive I tried to upload csv file programmatically. But it throws error in service.
public class Gdriveactivity extends Activity implements ConnectionCallbacks,
OnConnectionFailedListener {
private static final String TAG = "android-drive-quickstart";
private static final int REQUEST_CODE_CAPTURE_IMAGE = 1;
private static final int REQUEST_CODE_CREATOR = 2;
private static final int REQUEST_CODE_RESOLUTION = 3;
private GoogleApiClient mGoogleApiClient;
private Bitmap mBitmapToSave;
private void saveFiletoDrive() {
ResultCallback<DriveApi.ContentsResult> contentsCallback = new
ResultCallback<DriveApi.ContentsResult>() {
#Override
public void onResult(DriveApi.ContentsResult result) {
MetadataChangeSet changeSet = new MetadataChangeSet.Builder()
.setTitle("New file")
.setMimeType("text/plain").build();
Drive.DriveApi.getRootFolder(mGoogleApiClient)
.createFile(mGoogleApiClient, changeSet, null /* DriveContents */)
.setResultCallback(this);
}
};
}
#Override
protected void onResume() {
super.onResume();
if (mGoogleApiClient == null) {
// Create the API client and bind it to an instance variable.
// We use this instance as the callback for connection and connection
// failures.
// Since no account name is passed, the user is prompted to choose.
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(Drive.API)
.addScope(Drive.SCOPE_FILE)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
}
// Connect the client. Once connected, the camera is launched.
mGoogleApiClient.connect();
}
#Override
protected void onPause() {
if (mGoogleApiClient != null) {
mGoogleApiClient.disconnect();
}
super.onPause();
}
#Override
protected void onActivityResult(final int requestCode, final int resultCode, final Intent data) {
switch (requestCode) {
case REQUEST_CODE_CAPTURE_IMAGE:
// Called after a photo has been taken.
if (resultCode == Activity.RESULT_OK) {
// Store the image data as a bitmap for writing later.
mBitmapToSave = (Bitmap) data.getExtras().get("data");
}
break;
case REQUEST_CODE_CREATOR:
// Called after a file is saved to Drive.
if (resultCode == RESULT_OK) {
Log.i(TAG, "Image successfully saved.");
mBitmapToSave = null;
// Just start the camera again for another photo.
startActivityForResult(new Intent(MediaStore.ACTION_IMAGE_CAPTURE),
REQUEST_CODE_CAPTURE_IMAGE);
}
break;
}
}
#Override
public void onConnectionFailed(ConnectionResult result) {
// Called whenever the API client fails to connect.
Log.i(TAG, "GoogleApiClient connection failed: " + result.toString());
Toast.makeText(Gdriveactivity.this, "connected failed", 1000).show();
if (!result.hasResolution()) {
// show the localized error dialog.
GooglePlayServicesUtil.getErrorDialog(result.getErrorCode(), this, 0).show();
return;
}
// Called typically when the app is not yet authorized,
// authorization
// dialog is displayed to the user.
try {
result.startResolutionForResult(this, REQUEST_CODE_RESOLUTION);
} catch (SendIntentException e) {
Log.e(TAG, "Exception while starting resolution activity", e);
}
}
#Override
public void onConnected(Bundle connectionHint) {
Log.i(TAG, "API client connected.");
if (mBitmapToSave == null) {
// This activity has no UI of its own. Just start the camera.
Toast.makeText(Gdriveactivity.this, "connected", 1000).show();
//startActivityForResult(new Intent(MediaStore.ACTION_IMAGE_CAPTURE),
// REQUEST_CODE_CAPTURE_IMAGE);
// return;
}
insertFile();
}
Once I connected to gdrive account only I tried to upload file. But it shows error in service.
I can't use Drive service to initialize also because I imported drive in gms way
import com.google.android.gms.drive.Drive;
import com.google.api.client.http.FileContent;
import com.google.api.services.drive.model.File;
import com.google.api.services.drive.model.ParentReference;
There are a number of methods of Creating a Google Drive File including using a CreateFileActivityBuilder to allow the user to pick exactly where on their Google Drive they would like to create the file or programmatically calling createFile() on a DriveFolder you have. Ways of retrieving the appropriate DriveFolder include:
Drive.DriveApi.getRootFolder() (for the public root directory)
Drive.DriveApi.getAppFolder() (for your application private directory - the user cannot see these files, only how much storage space they take)
through a result of Drive.DriveApi.query().
I've been following this tutorial.
http://www.androidhive.info/2014/02/android-login-with-google-plus-account-1/
But when I'm tested the app through the real device,
When I click on the Sign in button, a toast is appeared saying "An internal error has occurred"
Could you please help me with this.
Thanks in advance.
Usually 'Internal error' shows up if one of the following is wrong:
In Google's Developer console website:
You have created a project, but not enabled Google api
Inside the Project:
Credentials
SHA1 Code is not correct
Package Name is not correct
Consent Screen
The associated email address is missing
Product Name is missing
If all these are correct, it should work automatically....
Try below code:
private static final int REQUEST_CODE_RESOLVE_ERR = 9000;
private static final int REQUEST_CODE_SHARE = 1000;
private PlusClient mPlusClient;
private PlusClient.Builder mPlusClientBuilder;
private PlusShare.Builder mPlusShareBuilder;
// In your onCreate()
mPlusClientBuilder = new Builder(this, this, this);
mPlusClientBuilder.setScopes(Scopes.PLUS_LOGIN, Scopes.PROFILE);
mPlusClient = mPlusClientBuilder.build();
mPlusClient.connect();
// Overrides methods
#Override
public void onConnectionFailed(ConnectionResult result) {
if (result.hasResolution()) {
// The user clicked the sign-in button already. Start to resolve
// connection errors. Wait until onConnected() to dismiss the
// connection dialog.
try {
result.startResolutionForResult(this, REQUEST_CODE_RESOLVE_ERR);
} catch (SendIntentException e) {
mPlusClient.disconnect();
mPlusClient.connect();
}
}
}
#Override
public void onConnected(Bundle arg0) {
String accountName = mPlusClient.getAccountName();
btnSignIn.setText(getString(R.string.signout));
textUserName.setText(accountName);
}
// Signin Click event
btnSignIn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
if (!mPlusClient.isConnected() && btnSignIn.getText().equals(getString(R.string.signin))) {
mPlusClient.connect();
} else if (mPlusClient.isConnected() && btnSignIn.getText().equals(getString(R.string.signout))) {
mPlusClient.clearDefaultAccount();
mPlusClient.disconnect();
btnSignIn.setText(getString(R.string.signin));
textUserName.setText("");
txtLoginAs.setVisibility(View.GONE);
}
}
});
//onActivityResult
#Override
protected void onActivityResult(int requestCode, int responseCode, Intent data) {
super.onActivityResult(requestCode, responseCode, data);
if (requestCode == REQUEST_CODE_RESOLVE_ERR && responseCode == RESULT_OK) {
mPlusClient.disconnect();
mPlusClient.connect();
} else if (requestCode == REQUEST_CODE_SHARE && responseCode == RESULT_OK) {
finish();
}
}