Trouble Implementing GoogleApiClient - android

I am trying to use Google SignIn on an app I'm creating. I have been using Google's developer tutorials, but I'm getting the error "Class 'HomeActivity' must either be declared abstract or implement abstract method 'onConnected(Bundle)' in 'ConnectionCallbacks' highlighted under:
public class HomeActivity extends Activity implements
ConnectionCallbacks,
OnConnectionFailedListener,
OnClickListener
Here is my HomeActivity code, much of which I used from Google:
import android.app.Activity;
import android.content.IntentSender;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.Scopes;
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.Scope;
import com.google.android.gms.plus.Plus;
import static android.view.View.*;
public class HomeActivity extends Activity implements
ConnectionCallbacks,
OnConnectionFailedListener,
OnClickListener {
private static final int RC_SIGN_IN = 0;
private GoogleApiClient mGoogleApiClient;
private Button mLoginButton;
private TextView mSignUpLabel;
/* Is there a ConnectionResult resolution in progress? */
private boolean mIsResolving = false;
/* Should we automatically resolve ConnectionResults when possible? */
private boolean mShouldResolve = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
mLoginButton = (Button) findViewById(R.id.btnLogin);
mLoginButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(HomeActivity.this, "Button Pressed", Toast.LENGTH_SHORT).show();
}
});
mSignUpLabel = (TextView) findViewById(R.id.lblAboutUs);
mSignUpLabel.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(HomeActivity.this, "WAY TO SIGN UP MAN", Toast.LENGTH_SHORT).show();
}
});
findViewById(R.id.sign_in_button).setOnClickListener(this);
// Build GoogleApiClient with access to basic profile
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(Plus.API)
.addScope(new Scope(Scopes.PROFILE))
.build();
}
#Override
public void onConnectionSuspended(int arg0) {
// what should i do here ? should i call mGoogleApiClient.connect() again ? ?
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_home, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
// Could not connect to Google Play Services. The user needs to select an account,
// grant permissions or resolve an error in order to sign in. Refer to the javadoc for
// ConnectionResult to see possible error codes.
Log.d(TAG, "onConnectionFailed:" + connectionResult);
if (!mIsResolving && mShouldResolve) {
if (connectionResult.hasResolution()) {
try {
connectionResult.startResolutionForResult(this, RC_SIGN_IN);
mIsResolving = true;
} catch (IntentSender.SendIntentException e) {
Log.e(TAG, "Could not resolve ConnectionResult.", e);
mIsResolving = false;
mGoogleApiClient.connect();
}
} else {
// Could not resolve the connection result, show the user an
// error dialog.
showErrorDialog(connectionResult);
}
} else {
// Show the signed-out UI
showSignedOutUI();
}
}
#Override
protected void onStart() {
super.onStart();
mGoogleApiClient.connect();
}
#Override
protected void onStop() {
super.onStop();
mGoogleApiClient.disconnect();
}
}
Any help would be much appreciated!!!

Your class declares that it will implement ConnectionCallbacks which means it's obligatory that you define all the methods included in that interface (and all other interfaces that you wish to implement). Both
Android Studio (Click on the light bulb at the left endge) and Eclipse have to ability to automatically implement uninmplemented methods (you will of course have to fill them up with any custom code)

Related

Google Sign In error: Status Code: SIGN_IN_REQUIRED when signing in with Google on android

Everytime I try to login with Google API, I get the following error. My manifest has the appropriate permissions and I did create my credentials accordingly. So I don't know what the problem is. The consent screen doesn't show either.
com.omer.notetoself D/NTS:﹕ ConnectionResult{statusCode=SIGN_IN_REQUIRED, resolution=PendingIntent{3678d5c: android.os.BinderProxy#19bcbe30}, message=null}
package com.omer.notetoself;
import android.app.Activity;
import android.content.Intent;
import android.content.IntentSender;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.Scopes;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.Scope;
import com.google.android.gms.plus.Plus;
`public class Activity_Login extends Activity implements View.OnClickListener,GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener{`
private static final int RC_SIGN_IN = 0;
private GoogleApiClient mGoogleApiClient;
/* Is there a ConnectionResult resolution in progress? */
private boolean mIsResolving = false;
/* Should we automatically resolve ConnectionResults when possible? */
private boolean mShouldResolve = false;
EditText editText_userName;
EditText editText_password;
Button button_facebook_login;
Button button_google_login;
Button button_login;
Button button_signUp;
String userName;
String password;
#Override
protected void onStop() {
super.onStop();
mGoogleApiClient.disconnect();
}
#Override
protected void onStart() {
super.onStart();
mGoogleApiClient.connect();
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
editText_userName = (EditText)findViewById(R.id.editText_username);
editText_password = (EditText)findViewById(R.id.editText_password);
button_login = (Button)findViewById(R.id.button_login);
button_facebook_login = (Button)findViewById(R.id.button_facebook);
button_google_login = (Button)findViewById(R.id.button_google);
button_signUp = (Button)findViewById(R.id.button_signup);
button_login.setOnClickListener(this);
button_signUp.setOnClickListener(this);
button_facebook_login.setOnClickListener(this);
button_google_login.setOnClickListener(this);
//GOOGLE+ API
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(Plus.API)
.addScope(new Scope(Scopes.PROFILE))
.addScope(new Scope(Scopes.EMAIL))
.build();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_activity_login, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
public void onClick(View v) {
switch(v.getId()){
case R.id.button_login: //AUTHENTICATE PARSE
userName = editText_userName.getText().toString().trim();
password = editText_password.getText().toString().trim();
AppUtilities.parseLogin(this, userName, password);
break;
case R.id.button_signup: //LAUNCH SIGN UP ACTIVITY
Intent intent = new Intent(
Activity_Login.this,
Activity_SignUp.class);
startActivity(intent);
break;
case R.id.button_facebook:
AppUtilities.facebookLogin(this);
break;
case R.id.button_google:
initGoogle();
break;
}
}
public void initGoogle(){
mGoogleApiClient.connect();
}
#Override
public void onConnected(Bundle bundle) {
String email = Plus.AccountApi.getAccountName(mGoogleApiClient);
AppUtilities.googleLogin(this,email);
}
#Override
public void onConnectionSuspended(int i) {
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
AppUtilities.log(connectionResult.toString());
if (!mIsResolving && mShouldResolve) {
if (connectionResult.hasResolution()) {
try {
connectionResult.startResolutionForResult(this, RC_SIGN_IN);
mIsResolving = true;
} catch (IntentSender.SendIntentException e) {
Log.e(AppUtilities.TAG, "Could not resolve ConnectionResult.", e);
mIsResolving = false;
mGoogleApiClient.connect();
}
} else {
// Could not resolve the connection result, show the user an
// error dialog.
//showErrorDialog(connectionResult);
}
} else {
// Show the signed-out UI
//showSignedOutUI();
}
}
}
Make sure SHA-1 signing-certificate fingerprint of your app in google developers console belong to the same key which is used to sign APK you are testing.
By default, when assembling debug build Android Studio use own debug key. You can change it through right-clicking on the app and selecting "Open Module Settings". Go to "Signing" tab and configure the same key you have mentioned in dev console. After that navigate to the "Build Types" tab and select your signing configuration.

connection Result android

I am using android 5.0.1 and compile my app with API 21.
I want to connect to google play services with the this code:
package com.example.getlocation2;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.util.Log;
import com.google.android.gms.common.ConnectionResult;
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.drive.Drive;
import com.google.android.gms.location.LocationServices;
public class MainActivity extends ActionBarActivity implements
ConnectionCallbacks, OnConnectionFailedListener{
public GoogleApiClient mGoogleApiClient;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String tag="test";
Log.i(tag, "just for test");
//buildGoogleApiClient();
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(Drive.API)
.addScope(Drive.SCOPE_FILE)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
}
/**
* Builds a GoogleApiClient. Uses the addApi() method to request the LocationServices API.
*/
/*protected synchronized void buildGoogleApiClient() {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
mGoogleApiClient.connect();
}*/
#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;
}
#Override
protected void onStart() {
super.onStart();
mGoogleApiClient.connect();
}
#Override
protected void onStop() {
super.onStop();
if (mGoogleApiClient.isConnected()) {
mGoogleApiClient.disconnect();
}
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
public void onConnectionFailed(ConnectionResult result) {
// Refer to the java doc for ConnectionResult to see what error
//codes might be returned in
// onConnectionFailed.
String TAG="Fword";
Log.i(TAG, "Connection failed: ConnectionResult.getErrorCode() = " + result.getErrorCode());
}
/**
* Runs when a GoogleApiClient object successfully connects.
*/
#Override
public void onConnected(Bundle connectionHint) {
// Provides a simple way of getting a device's location and is well suited for
// applications that do not require a fine-grained location and that do not need location
// updates. Gets the best and most recent location currently available, which may be null
// in rare cases when a location is not available.
String TAG="GoodWord";
Log.i(TAG, "Connectioned");
}
#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.
/*String TAG="Sword";
Log.i(TAG, "Connection suspended");
mGoogleApiClient.connect();*/
}
}
but it returns connection result code 8 that means: "internal error occurred. Retrying should resolve the problem."
what does this error means and how can I resolve it?
Add this to your gradle build file in the dependencies section.
compile 'com.google.android.gms:play-services:7.0.0'

Error implementing GoogleApiClient Builder for Android development

I am following Google's documentation to implement Google+ Sign In feature into an app.
https://developers.google.com/+/mobile/android/getting-started
I followed each step according to the guide but got stuck in an error generated by the GoogleApiClient.Builder , I searched thoroughly but got no result.
Please help me sort it out. Thank you.
Error code:
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this).addApi(Plus.API, null)
.addScope(Plus.SCOPE_PLUS_LOGIN).build();
Error Message :
The method addConnectionCallbacks(GoogleApiClient.ConnectionCallbacks) in the type
GoogleApiClient.Builder is not applicable for the arguments (MainActivity)
Complete MainActivity.java code :
package mad.project.mightysatta;
import android.content.Intent;
import android.content.IntentSender.SendIntentException;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v7.app.ActionBarActivity;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesClient.ConnectionCallbacks;
import com.google.android.gms.common.GooglePlayServicesClient.OnConnectionFailedListener;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.plus.Plus;
public class MainActivity extends ActionBarActivity implements
ConnectionCallbacks, OnConnectionFailedListener {
/* 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;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this).addApi(Plus.API, null)
.addScope(Plus.SCOPE_PLUS_LOGIN).build();
setContentView(R.layout.activity_main);
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction()
.add(R.id.container, new PlaceholderFragment()).commit();
}
}
#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);
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main_activity_actions, menu);
return super.onCreateOptionsMenu(menu);
// return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
/**
* A placeholder fragment containing a simple view.
*/
public static class PlaceholderFragment extends Fragment {
public PlaceholderFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container,
false);
return rootView;
}
}
#Override
public void onConnectionFailed(ConnectionResult result) {
// TODO Auto-generated method stub
if (!mIntentInProgress && result.hasResolution()) {
try {
mIntentInProgress = true;
result.startResolutionForResult(this, // your activity
RC_SIGN_IN);
} catch (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 connectionHint) {
// TODO Auto-generated method stub
}
#Override
public void onDisconnected() {
// TODO Auto-generated method stub
}
protected void onStart() {
super.onStart();
mGoogleApiClient.connect();
}
protected void onStop() {
super.onStop();
if (mGoogleApiClient.isConnected()) {
mGoogleApiClient.disconnect();
}
}
protected void onActivityResult(int requestCode, int responseCode,
Intent intent) {
if (requestCode == RC_SIGN_IN) {
mIntentInProgress = false;
if (!mGoogleApiClient.isConnecting()) {
mGoogleApiClient.connect();
}
}
}
public void onConnectionSuspended(int cause) {
mGoogleApiClient.connect();
}
}
In this code if I comment out .addConnectionCallbacks and .addOnConnectionFailedListener , then the error goes away. The error seems to be related with their arguments.
mGoogleApiClient = new GoogleApiClient.Builder(this)
// .addConnectionCallbacks(this)
// .addOnConnectionFailedListener(this)
.addApi(Plus.API, null)
.addScope(Plus.SCOPE_PLUS_LOGIN).build();
Updated Main Activity , after replacing implements to
GooglePlayServicesClient.ConnectionCallbacks,
GooglePlayServicesClient.OnConnectionFailedListener
MainActivity.java(Updated)
package mad.project.mightysatta;
import android.content.Intent;
import android.content.IntentSender.SendIntentException;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v7.app.ActionBarActivity;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesClient;
import com.google.android.gms.common.GooglePlayServicesClient.ConnectionCallbacks;
import com.google.android.gms.common.GooglePlayServicesClient.OnConnectionFailedListener;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.plus.Plus;
public class MainActivity extends ActionBarActivity implements
GooglePlayServicesClient.ConnectionCallbacks,
GooglePlayServicesClient.OnConnectionFailedListener {
/* 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;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(Plus.API, null)
.addScope(Plus.SCOPE_PLUS_LOGIN).build();
setContentView(R.layout.activity_main);
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction()
.add(R.id.container, new PlaceholderFragment()).commit();
}
}
#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);
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main_activity_actions, menu);
return super.onCreateOptionsMenu(menu);
// return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
/**
* A placeholder fragment containing a simple view.
*/
public static class PlaceholderFragment extends Fragment {
public PlaceholderFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container,
false);
return rootView;
}
}
#Override
public void onConnectionFailed(ConnectionResult result) {
// TODO Auto-generated method stub
if (!mIntentInProgress && result.hasResolution()) {
try {
mIntentInProgress = true;
result.startResolutionForResult(this, // your activity
RC_SIGN_IN);
} catch (SendIntentException e) {
// The intent was canceled before it was sent. Return to
// default
// state and attempt to connect to get an updated
// ConnectionResult.
mIntentInProgress = false;
mGoogleApiClient.connect();
}
}
}
#Override
public void onConnected(Bundle connectionHint) {
// TODO Auto-generated method stub
}
#Override
public void onDisconnected() {
// TODO Auto-generated method stub
}
protected void onStart() {
super.onStart();
mGoogleApiClient.connect();
}
protected void onStop() {
super.onStop();
if (mGoogleApiClient.isConnected()) {
mGoogleApiClient.disconnect();
}
}
protected void onActivityResult(int requestCode, int responseCode,
Intent intent) {
if (requestCode == RC_SIGN_IN) {
mIntentInProgress = false;
if (!mGoogleApiClient.isConnecting()) {
mGoogleApiClient.connect();
}
}
}
public void onConnectionSuspended(int cause) {
mGoogleApiClient.connect();
}
}
I see in their documentation where they clearly instruct you to include this import:
import com.google.android.gms.common.GooglePlayServicesClient.ConnectionCallbacks;
However, the error being thrown is expecting a different class than GooglePlayServicesClient.ConnectionCallbacks, it's asking for GoogleApiClient.ConnectionCallbacks. Try changing your implements to use the more-qualified class name. That looks to be the only possible thing throwing the code for a loop and without the explicit qualified classname, it will default to the directly imported class name.
It's always tougher when you have to question the manual.
Edit: I mean a change like this:
public class MainActivity
extends ActionBarActivity
implements GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener {
I too faced the same problem, i resolved by doing the following things.
import the right ConnectionCallbacks.
here is my code:
import android.content.Context;
import android.os.Bundle;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.drive.Drive;
public class GplusLogin implements
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener {
GoogleApiClient mGoogleApiClient;
GplusLogin(Context context){
mGoogleApiClient = new GoogleApiClient.Builder(context)
.addApi(Drive.API)
.addScope(Drive.SCOPE_FILE)
.addConnectionCallbacks((GoogleApiClient.ConnectionCallbacks) context)
.addOnConnectionFailedListener(this)
.build();
}
#Override
public void onConnected(Bundle bundle) {
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
}
#Override
public void onConnectionSuspended(int i) {
}
}
turns out they (google) don't follow much of the guide themselves. Use their Google Drive Android Quickstart as a reference, which they actually do mention at the top of the tutorial, but they give it the misleading name "Android Quickstart" even though it is specific to Google Drive
The note at the top of the guide:
click alt enter and force android studio to implement:
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener
implements LocationListener, GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener,OnMapReadyCallback
to the Activity

startResolutionForResult returns an error (application crashes), GoogleApiClient connect

I've been trying to figure out how to solve this problem for a long time now, but I can't find any good information on what is going wrong.
The code originates from: http://developer.android.com/google/auth/api-client.html
So first I build the GoogleApiClient object and then onStart() try to connect it.
The connection fails and I end up inside "onConnectionFailed()"..
Here I've printed the result and this is what I get: "SIGN_IN_REQUIRED"
As that error has a solution "result.startResolutionForResult(this, REQUEST_RESOLVE_ERROR)" will be called.
Here is where the program suddenly crashes.
Any help would be appriciated I'm quite new to android development so go easy on me!
import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.content.IntentSender.SendIntentException;
import android.util.Log;
import android.view.Menu;
import com.google.android.gms.common.ConnectionResult;
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.GoogleApiClient;
import com.google.android.gms.plus.Plus;
public class MainActivity extends Activity implements
ConnectionCallbacks, OnConnectionFailedListener {
/* Client used to interact with Google APIs. */
private GoogleApiClient mGoogleApiClient;
// Request code to use when launching the resolution activity
private static final int REQUEST_RESOLVE_ERROR = 1001;
// Bool to track whether the app is already resolving an error
private boolean mResolvingError = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
super.onCreate(savedInstanceState);
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(Plus.API, null)
.addScope(Plus.SCOPE_PLUS_LOGIN)
.build();
}
#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;
}
protected void onStart() {
super.onStart();
mGoogleApiClient.connect();
}
protected void onStop() {
super.onStop();
if (mGoogleApiClient.isConnected()) {
mGoogleApiClient.disconnect();
}
}
#Override
public void onConnectionFailed(ConnectionResult result) {
if (mResolvingError) {
// Already attempting to resolve an error.
return;
} else if (result.hasResolution()) {
Log.d("MyApp",result.toString());
try {
mResolvingError = true;
result.startResolutionForResult(this, REQUEST_RESOLVE_ERROR);
} catch (SendIntentException e) {
// There was an error with the resolution intent. Try again.
mGoogleApiClient.connect();
}
} else {
// Show dialog using GooglePlayServicesUtil.getErrorDialog()
//showErrorDialog(result.getErrorCode());
mResolvingError = true;
}
}
#Override
public void onConnected(Bundle connectionHint) {
}
#Override
public void onConnectionSuspended(int cause) {
mGoogleApiClient.connect();
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_RESOLVE_ERROR) {
mResolvingError = false;
if (resultCode == RESULT_OK) {
// Make sure the app is not already connected or attempting to connect
if (!mGoogleApiClient.isConnecting() && !mGoogleApiClient.isConnected()) {
mGoogleApiClient.connect();
}
}
}
}
}
In the onCreate method try to:
remove the duplicated line super.onCreate(savedInstanceState);
remove .addScope(Plus.SCOPE_PLUS_LOGIN) or .setScopes("PLUS_LOGIN") as was in my case
If this does not help, try to import and run great example project from SDK samples:
<android-sdk-folder>/extras/google/google_play_services/
See https://developers.google.com/+/mobile/android/getting-started

Infinite loop when attemping to check if user is signed in. google +

I am attempting to check if the user is signed in and weather or not they are, send them to the login or keep them on the main activity.
Main Activity
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.plus.Plus;
public class MainActivity extends Activity {
private GoogleApiClient mGoogleApiClient;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(Plus.API, null).addScope(Plus.SCOPE_PLUS_LOGIN).build();
if (!mGoogleApiClient.isConnected()) {
Intent intent = new Intent(MainActivity.this, LoginActivity.class);
startActivity(intent);
}
}
#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;
}
}
LoginActivity
package com.alfalfa.thisthat;
import android.app.Activity;
import android.content.Intent;
import android.content.IntentSender.SendIntentException;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Toast;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.SignInButton;
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.plus.Plus;
public class LoginActivity extends Activity implements ConnectionCallbacks,
OnConnectionFailedListener, OnClickListener {
private static final int RC_SIGN_IN = 0;
private GoogleApiClient mGoogleApiClient;
private boolean mIntentInProgress;
private boolean mSignInClicked;
private static SignInButton mSignInButton;
private ConnectionResult mConnectionResult;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
mSignInButton = (SignInButton) findViewById(R.id.sign_in_button);
mSignInButton.setOnClickListener(this);
mSignInButton.setEnabled(true);
mSignInButton.setSize(SignInButton.SIZE_WIDE);
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();
}
}
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 onClick(View view) {
if (view.getId() == R.id.sign_in_button
&& !mGoogleApiClient.isConnecting()) {
mSignInClicked = true;
resolveSignInErrors();
}
}
#Override
public void onConnectionFailed(ConnectionResult result) {
if (!mIntentInProgress) {
mConnectionResult = result;
if (mSignInClicked) {
resolveSignInErrors();
}
}
}
private void resolveSignInErrors() {
if (mConnectionResult.hasResolution()) {
try {
mIntentInProgress = true;
mConnectionResult.startResolutionForResult(this, RC_SIGN_IN);
} catch (SendIntentException e) {
mIntentInProgress = false;
mGoogleApiClient.connect();
}
}
}
#Override
public void onConnected(Bundle connectionHint) {
mSignInClicked = false;
navigateToMainActivity();
Toast.makeText(this, "User is connected!", Toast.LENGTH_SHORT).show();
}
#Override
public void onConnectionSuspended(int cause) {
mGoogleApiClient.connect();
}
public void navigateToMainActivity() {
Intent intent = new Intent(LoginActivity.this, MainActivity.class);
startActivity(intent);
}
}
When I start the app, it loads into the login screen. When I click the sign in button, the app backs in and our of the LoginActivity infinitely.
I removed a piece of code from my app that does something similar. It is Google Drive related, but easy to adapt.
On menu selection, it pops-up account picker and connects to GAC with the selected account.
Checking if the user is signed-in is irrelevant in my situation. If there has been a valid user connected before, the connect() is successful, otherwise the account picker pops-up. There is more about it in SO 21610239. And I believe there is no way to get current signed user, unless you pop-up the account picker and get it from the return (KEY_ACCOUNT_NAME below).
public class SomeActivity extends Activity
implements ConnectionCallbacks, OnConnectionFailedListener {
GoogleApiClient mGAC;
// from menu: user pops up account picker and selects account
#Override public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.acc_select:
Intent intent = AccountPicker.newChooseAccountIntent(null, null,
new String[]{GoogleAuthUtil.GOOGLE_ACCOUNT_TYPE}, false, null, null, null, null);
startActivityForResult(intent, AUTH_REQUEST);
return true;
}
return super.onOptionsItemSelected(item);
}
// back from account picker (invoked from menu OR from onConnectionFailed())
#Override protected void onActivityResult(final int rqst, final int rslt, final Intent it) {
switch (rqst) {
case AUTH_REQUEST:
if (mGAC == null) {
mGAC = new GoogleApiClient.Builder(this).addApi(Drive.API).addScope(Drive.SCOPE_FILE)
.setAccountName(it.getStringExtra(AccountManager.KEY_ACCOUNT_NAME))
.addConnectionCallbacks(this).addOnConnectionFailedListener(this).build();
}
if ((mGAC != null) && !mGAC.isConnected())
mGAC.connect();
break;
}
}
// connection failed, either fatal, or needs account / authorization
#Override public void onConnectionFailed(ConnectionResult rslt) {
if (!rslt.hasResolution()) { // FATAL ------->>>>
Toast.makeText(this, "FAILED", Toast.LENGTH_LONG).show();
} else try { // needs authorization
rslt.startResolutionForResult(this, AUTH_REQUEST);
} catch (SendIntentException e) {}
}
#Override public void onConnected(Bundle connectionHint) {
// do my stuff here
}
#Override public void onConnectionSuspended(int i) {}
}
There's one glaring issue I see in the code you posted:
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(Plus.API, null).addScope(Plus.SCOPE_PLUS_LOGIN).build();
if (!mGoogleApiClient.isConnected()) {
Intent intent = new Intent(MainActivity.this, LoginActivity.class);
startActivity(intent);
}
At this point mGoogleApiClient will never be connected. To determine if the user isn't successfully connected (there are a number of reasons this could happen), you want to add an OnConnectionFailedListener to the Builder, then call .connect() on mGoogleApiClient and wait for OnConnectionFailedListener#onConnectionFailed() to be called. If that happens, then redirect the user back to the login Activity.

Categories

Resources