I need a help with my app.
I've been trying yo build a simple location app. Therefore, I followed the Android Developer Training (http://developer.android.com/training/location/retrieve-current.html). However, I am stuck with the last part.
My app seems to crash whenever it hits this code,
mLocationClient.connect();
I've added permission and activated location service in my device. Can anyone help me?
This is my whole code.
public class MainActivity extends FragmentActivity
implements
ConnectionCallbacks,
OnConnectionFailedListener{
private final static int CONNECTION_FAILURE_RESOLUTION_REQUEST = 9000;
private LocationClient mLocationClient;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mLocationClient = new LocationClient(this, this, this);
}
#Override
protected void onStart(){
super.onStart();
mLocationClient.connect();
}
#Override
protected void onStop(){
mLocationClient.disconnect();
super.onStop();
}
#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;
}
public static class ErrorDialogFragment extends DialogFragment{
private Dialog mDialog;
public ErrorDialogFragment(){
super();
mDialog = null;
}
public void setDialog(Dialog dialog){
mDialog = dialog;
}
#Override
public Dialog onCreateDialog(Bundle savedInstanceState){
return mDialog;
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
switch (requestCode) {
case CONNECTION_FAILURE_RESOLUTION_REQUEST :
switch (resultCode) {
case Activity.RESULT_OK:
break;
default:
break;
}
default:
break;
}
}
private boolean servicesConnected() {
int resultCode =
GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
if (ConnectionResult.SUCCESS == resultCode) {
Log.d("Location Update", "Google Play Services is available");
return true;
} else {
Dialog dialog = GooglePlayServicesUtil.getErrorDialog(resultCode, this, 0);
if (dialog != null) {
//ErrorDialogFragment errorFragment = new ErrorDialogFragment();
//errorFragment.setDialog(dialog);
//errorFragment.show(getFragmentManager(), "Location Updates");
//errorFragment.show(getSupportFragmentManager(), "Location Updates");
}
return false;
}
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
// TODO Auto-generated method stub
if (connectionResult.hasResolution()) {
try {
connectionResult.startResolutionForResult(
this,
CONNECTION_FAILURE_RESOLUTION_REQUEST);
} catch (IntentSender.SendIntentException e) {
e.printStackTrace();
}
} else {
showErrorDialog(connectionResult.getErrorCode());
}
}
private void showErrorDialog(int errorCode) {
Dialog errorDialog = GooglePlayServicesUtil.getErrorDialog(
errorCode,
this,
CONNECTION_FAILURE_RESOLUTION_REQUEST);
if (errorDialog != null) {
ErrorDialogFragment errorFragment = new ErrorDialogFragment();
errorFragment.setDialog(errorDialog);
}
}
#Override
public void onConnected(Bundle arg0) {
// TODO Auto-generated method stub
Toast.makeText(this, "Connected", Toast.LENGTH_SHORT).show();
}
#Override
public void onDisconnected() {
// TODO Auto-generated method stub
Toast.makeText(this, "Disconnected. Please re-connect.", Toast.LENGTH_SHORT).show();
}
}
I think you don't have Google Play Services installed. You have the method servicesConnected(), but you don't use it. You should wrap your call to mLocationClient.connect() in an if statement that checks servicesConnected().
I had a similar issue and I had forgotten to add this in my manifest under application:
<meta-data android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version" />
Read this again for help.
Related
I am trying to get users current location using FusedLocationApi using the following code. I am following the guide provided here https://developer.android.com/training/location/retrieve-current.html
public class MapActivity extends ActionBarActivity implements
GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener,LocationListener {
private Toolbar mToolbar;
private GoogleMap googleMap;
GoogleApiClient mGoogleApiClient;
private final static int PLAY_SERVICES_RESOLUTION_REQUEST = 1000;
private final static int CONNECTION_FAILURE_RESOLUTION_REQUEST =5000;
private Location mLastLocation;
private LocationRequest mLocationRequest;
LocationManager locationManager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_map);
mToolbar = (Toolbar)findViewById( R.id.toolbar );
mToolbar.setTitle(R.string.title_activity_map);
setSupportActionBar(mToolbar);
try {
initilizeMap();
} catch (Exception e) {
e.printStackTrace();
}
if (checkPlayServices()) {
buildGoogleApiClient();
}
mLocationRequest = LocationRequest.create()
.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
.setInterval(10 * 1000) // 10 seconds, in milliseconds
.setFastestInterval(1 * 1000);
}
private void initilizeMap() {
if (googleMap == null) {
googleMap = ((MapFragment) getFragmentManager().findFragmentById(
R.id.map)).getMap();
// check if map is created successfully or not
if (googleMap == null) {
Toast.makeText(getApplicationContext(),
"Sorry! unable to create maps", Toast.LENGTH_SHORT)
.show();
}
googleMap.setMyLocationEnabled(true);
}
}
private 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 {
Toast.makeText(getApplicationContext(),
"This device is not supported.", Toast.LENGTH_LONG)
.show();
finish();
}
return false;
}
return true;
}
#Override
protected void onResume() {
super.onResume();
initilizeMap();
checkPlayServices();
if (mGoogleApiClient != null) {
mGoogleApiClient.connect();
}
}
#Override
protected void onPause() {
super.onPause();
if (mGoogleApiClient.isConnected()) {
mGoogleApiClient.disconnect();
}
}
protected synchronized void buildGoogleApiClient() {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.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.map, 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);
}
#Override
public void onConnectionFailed(ConnectionResult arg0) {
// TODO Auto-generated method stub
if (arg0.hasResolution()) {
try {
// Start an Activity that tries to resolve the error
arg0.startResolutionForResult(this, CONNECTION_FAILURE_RESOLUTION_REQUEST);
} catch (Exception e) {
e.printStackTrace();
}
} else {
Log.e("Fail", "Location services connection failed with code " + arg0.getErrorCode());
}
}
#Override
public void onConnected(Bundle arg0) {
// TODO Auto-generated method stub
new GetLocation().execute();
}
#Override
public void onConnectionSuspended(int arg0) {
// TODO Auto-generated method stub
}
private class GetLocation extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... params) {
// TODO Auto-generated method stub
mLastLocation = LocationServices.FusedLocationApi.getLastLocation(
mGoogleApiClient);
if (mLastLocation != null) {
Log.e("If", "If");
} else {
Log.e("else", "else");
}
return null;
}
#Override
protected void onPostExecute(Void result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
}
}
#Override
public void onLocationChanged(Location location) {
// TODO Auto-generated method stub
}
#Override
public void onProviderDisabled(String provider) {
// TODO Auto-generated method stub
}
#Override
public void onProviderEnabled(String provider) {
// TODO Auto-generated method stub
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
// TODO Auto-generated method stub
}
}
When I run the code it always shows else in log, this means that I am not getting any Location. Is there something missing? what am I doing wrong?
Moved from comments:
make sure you have gps enabled on your phone. When enabling gps, phone may also ask you to send data anonymously to google, you should accept it.
I am using the periodic location updates and wanted to know which part should be put in service so that even when the app is closed it keeps running. Here is the code
public class MainActivity extends FragmentActivity implements LocationListener,
GooglePlayServicesClient.ConnectionCallbacks,
GooglePlayServicesClient.OnConnectionFailedListener {
private LocationRequest mLocationRequest;
private LocationClient mLocationClient;
private TextView mLatLng;
private TextView mConnectionState;
private TextView mConnectionStatus;
SharedPreferences mPrefs;
SharedPreferences.Editor mEditor;
boolean mUpdatesRequested = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mLatLng = (TextView) findViewById(R.id.lat_lng);
mConnectionState = (TextView) findViewById(R.id.text_connection_state);
mConnectionStatus = (TextView) findViewById(R.id.text_connection_status);
mLocationRequest = LocationRequest.create();
mLocationRequest
.setInterval(LocationUtils.UPDATE_INTERVAL_IN_MILLISECONDS);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
mLocationRequest
.setFastestInterval(LocationUtils.FAST_INTERVAL_CEILING_IN_MILLISECONDS);
mUpdatesRequested = false;
mPrefs = getSharedPreferences(LocationUtils.SHARED_PREFERENCES,
Context.MODE_PRIVATE);
mEditor = mPrefs.edit();
mLocationClient = new LocationClient(this, this, this);
}
#Override
public void onStop() {
if (mLocationClient.isConnected()) {
stopPeriodicUpdates();
}
mLocationClient.disconnect();
super.onStop();
}
#Override
public void onPause() {
mEditor.putBoolean(LocationUtils.KEY_UPDATES_REQUESTED,
mUpdatesRequested);
mEditor.commit();
super.onPause();
}
#Override
public void onStart() {
super.onStart();
mLocationClient.connect();
}
#Override
public void onResume() {
super.onResume();
// If the app already has a setting for getting location updates, get it
if (mPrefs.contains(LocationUtils.KEY_UPDATES_REQUESTED)) {
mUpdatesRequested = mPrefs.getBoolean(
LocationUtils.KEY_UPDATES_REQUESTED, false);
// Otherwise, turn off location updates until requested
} else {
mEditor.putBoolean(LocationUtils.KEY_UPDATES_REQUESTED, false);
mEditor.commit();
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode,
Intent intent) {
// Choose what to do based on the request code
switch (requestCode) {
// If the request code matches the code sent in onConnectionFailed
case LocationUtils.CONNECTION_FAILURE_RESOLUTION_REQUEST:
switch (resultCode) {
// If Google Play services resolved the problem
case Activity.RESULT_OK:
// Log the result
Log.d(LocationUtils.APPTAG, getString(R.string.resolved));
// Display the result
mConnectionState.setText(R.string.connected);
mConnectionStatus.setText(R.string.resolved);
break;
// If any other result was returned by Google Play services
default:
// Log the result
Log.d(LocationUtils.APPTAG, getString(R.string.no_resolution));
// Display the result
mConnectionState.setText(R.string.disconnected);
mConnectionStatus.setText(R.string.no_resolution);
break;
}
// If any other request code was received
default:
// Report that this Activity received an unknown requestCode
Log.d(LocationUtils.APPTAG,
getString(R.string.unknown_activity_request_code,
requestCode));
break;
}
}
private boolean servicesConnected() {
// Check that Google Play services is available
int resultCode = GooglePlayServicesUtil
.isGooglePlayServicesAvailable(this);
// If Google Play services is available
if (ConnectionResult.SUCCESS == resultCode) {
// In debug mode, log the status
Log.d(LocationUtils.APPTAG,
getString(R.string.play_services_available));
// Continue
return true;
// Google Play services was not available for some reason
} else {
// Display an error dialog
Dialog dialog = GooglePlayServicesUtil.getErrorDialog(resultCode,
this, 0);
if (dialog != null) {
ErrorDialogFragment errorFragment = new ErrorDialogFragment();
errorFragment.setDialog(dialog);
errorFragment.show(getFragmentManager(), LocationUtils.APPTAG);
}
return false;
}
}
public void getLocation(View v) {
if (servicesConnected()) {
Location currentLocation = mLocationClient.getLastLocation();
mLatLng.setText(LocationUtils.getLatLng(this, currentLocation));
}
}
public void startUpdates(View v) {
mUpdatesRequested = true;
if (servicesConnected()) {
startPeriodicUpdates();
}
}
public void stopUpdates(View v) {
mUpdatesRequested = false;
if (servicesConnected()) {
stopPeriodicUpdates();
}
}
#Override
public void onConnected(Bundle bundle) {
mConnectionStatus.setText(R.string.connected);
if (mUpdatesRequested) {
startPeriodicUpdates();
}
}
#Override
public void onDisconnected() {
mConnectionStatus.setText(R.string.disconnected);
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
/*
* Google Play services can resolve some errors it detects. If the error
* has a resolution, try sending an Intent to start a Google Play
* services activity that can resolve error.
*/
if (connectionResult.hasResolution()) {
try {
// Start an Activity that tries to resolve the error
connectionResult.startResolutionForResult(this,
LocationUtils.CONNECTION_FAILURE_RESOLUTION_REQUEST);
/*
* Thrown if Google Play services canceled the original
* PendingIntent
*/
} catch (IntentSender.SendIntentException e) {
// Log the error
e.printStackTrace();
}
} else {
// If no resolution is available, display a dialog to the user with
// the error.
showErrorDialog(connectionResult.getErrorCode());
}
}
#Override
public void onLocationChanged(Location location) {
mConnectionStatus.setText(R.string.location_updated);
mLatLng.setText(LocationUtils.getLatLng(this, location));
}
private void startPeriodicUpdates() {
mLocationClient.requestLocationUpdates(mLocationRequest, this);
mConnectionState.setText(R.string.location_requested);
}
private void stopPeriodicUpdates() {
mLocationClient.removeLocationUpdates(this);
mConnectionState.setText(R.string.location_updates_stopped);
}
private void showErrorDialog(int errorCode) {
Dialog errorDialog = GooglePlayServicesUtil.getErrorDialog(errorCode,
this, LocationUtils.CONNECTION_FAILURE_RESOLUTION_REQUEST);
if (errorDialog != null) {
ErrorDialogFragment errorFragment = new ErrorDialogFragment();
errorFragment.setDialog(errorDialog);
errorFragment.show(getFragmentManager(), LocationUtils.APPTAG);
}
}
public static class ErrorDialogFragment extends DialogFragment {
private Dialog mDialog;
public ErrorDialogFragment() {
super();
mDialog = null;
}
public void setDialog(Dialog dialog) {
mDialog = dialog;
}
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
return mDialog;
}
}
}
#Override
public void onLocationChanged(Location location) {
}
is the callback which is called when the location changes. So, this should be put in your service so that it is able to receive the updates.
This is a long question and might be confusing, please bear with me.
So i successfully created a Google+ sign in for my Android app following the instructions on the developers.google.com website and it successfully signs a user in.Here is the code of my main Activity.
//..imports
#SuppressWarnings("unused")
public class MainActivity extends Activity implements
ConnectionCallbacks, OnConnectionFailedListener, View.OnClickListener {
private static final int REQUEST_CODE_RESOLVE_ERR = 9000;
private static final String TAG = "MainActivity";
private ProgressDialog mConnectionProgressDialog;
private static PlusClient mPlusClient;
private ConnectionResult mConnectionResult;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mPlusClient = new PlusClient.Builder(this, this, this)
.setActions("http://schemas.google.com/AddActivity", "http://schemas.google.com/BuyActivity")
.setScopes(Scopes.PLUS_LOGIN) // recommended login scope for social features
// .setScopes("profile") // alternative basic login scope
.build();
// Progress bar to be displayed if the connection failure is not resolved.
mConnectionProgressDialog = new ProgressDialog(this);
mConnectionProgressDialog.setMessage("Signing in...");
}
#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);
findViewById(R.id.sign_in_button).setOnClickListener(this);
return true;
}
protected void onStart() {
super.onStart();
mPlusClient.connect();
}
protected void onStop() {
super.onStop();
mPlusClient.disconnect();
}
public PlusClient getMplusClient() {
return mPlusClient;
}
#Override
public void onConnectionFailed(ConnectionResult result) {
if (mConnectionProgressDialog.isShowing()) {
// The user clicked the sign-in button already. Start to resolve
// connection errors. Wait until onConnected() to dismiss the
// connection dialog.
if (result.hasResolution()) {
try {
result.startResolutionForResult(this, REQUEST_CODE_RESOLVE_ERR);
} catch (SendIntentException e) {
mPlusClient.connect();
}
}
}
// Save the intent so that we can start an activity when the user clicks
// the sign-in button.
mConnectionResult = result;
}
protected void onActivityResult(int requestCode, int responseCode, Intent intent) {
if (requestCode == REQUEST_CODE_RESOLVE_ERR && responseCode == RESULT_OK) {
mConnectionResult = null;
mPlusClient.connect();
}
}
public void onConnected(Bundle connectionHint) {
String accountName = mPlusClient.getAccountName();
Toast.makeText(this, accountName + " is connected.", Toast.LENGTH_LONG).show();
startActivity(new Intent(this, TestActivity.class));
}
public void onDisconnected() {
Log.d(TAG, "disconnected");
}
public void startTestActivity() {
startActivity(new Intent(this, TestActivity.class));
}
#Override
public void onClick(View view) {
if (view.getId() == R.id.sign_in_button && !mPlusClient.isConnected()) {
if (mConnectionResult == null) {
mConnectionProgressDialog.show();
} else {
try {
mConnectionResult.startResolutionForResult(this, REQUEST_CODE_RESOLVE_ERR);
} catch (SendIntentException e) {
// Try connecting again.
mConnectionResult = null;
mPlusClient.connect();
} } } }
}//end of class
`
Now i added a new activity to my project called TestActivity where i have the code to sign a user out of the app.And this TestActivity is started in the MainActivity from the block
public void onConnected(Bundle connectionHint) {
String accountName = mPlusClient.getAccountName();
Toast.makeText(this, accountName + " is connected.", Toast.LENGTH_LONG).show();
startActivity(new Intent(this, TestActivity.class));
}
This works fine and the TestActivity is started when a user is connected to the app, and when i run the app again, this is the activity is see(since the user is still signed in).
Now, the problem is the logout button in the TestActivity class does not do anything.Google's Sign Out method is
public void onClick(View view) {
if (view.getId() == R.id.sign_out_button) {
if (mPlusClient.isConnected()) {
mPlusClient.clearDefaultAccount();
mPlusClient.disconnect();
mPlusClient.connect();
}
}
}
Since mPlusClient is in the MainActivity and is declared as private i added the getMPlusCLient() method you see in the MainActivity (I think this is where my problem starts) which returns mPlusClient, a PlusClient object.Now, i ended up with this as my TestActivity
public class TestActivity extends Activity implements View.OnClickListener{
private Button sign_out_button;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.test, menu);
sign_out_button = (Button)findViewById(R.id.signOutButton);
sign_out_button.setOnClickListener(this);
return true;
}
public void signOut() {
MainActivity signOutObject = new MainActivity();
if (signOutObject.getMplusClient().isConnected()) {
signOutObject.getMplusClient().clearDefaultAccount();
signOutObject.getMplusClient().disconnect();
signOutObject.getMplusClient().connect();
}
}
#Override
public void onClick(View view) {
switch(view.getId()) {
case R.id.signOutButton:
signOut();
break;
}
}
}
The problem like i stated earlier is the logout button in my TestActivity class does not do anything and no error message is shown in logcat.Where did i go wrong?
I am writing a log in fragment that hosts Facebook and Google+ sign in. The fragment is a parent fragment for three fragments with user content that are called with view pager after successful log in. I am storing email and service name in shared preferences upon retrieval from Google or Facebook, and then if successful the view pager is displayed with user fragments. Facebook log in works fine but when I start Google+ sign in it does not get to the onConnected callback method. When I switch to other tabs and return to log in fragment it is somehow triggered and I get user fragments. How can i trigger the onConnected method upon pressing the Google+ sign in button?
to ensure the onActivityResult is called i added this in main activity
MainActivity.java
#Override
protected void onActivityResult(int arg0, int arg1, Intent arg2) {
// TODO Auto-generated method stub
super.onActivityResult(arg0, arg1, arg2);
LoginFragment lf = (LoginFragment)getSupportFragmentManager().findFragmentByTag("Login");
if (lf != null) {
lf.onActivityResult(arg0, arg1, arg2);
}
}
LoginFragment.java
#Override
public void onActivityCreated(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onActivityCreated(savedInstanceState);
// Session class instance
mSession = new SessionManager(getActivity());
setupGoogleplus();
loginButton = (SignInButton) getActivity().findViewById(R.id.sign_in_button);
loginButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
if (!mPlusClient.isConnected()) {
if (mConnectionResult == null) {
mConnectionProgressDialog.show();
} else {
try {
mConnectionResult.startResolutionForResult(getActivity(), REQUEST_CODE_RESOLVE_ERR);
} catch (SendIntentException e) {
// Try connecting again.
mConnectionResult = null;
mPlusClient.connect();
}
}
}
}
});
setupViewPager();
if (mSession.isLoggedIn()) {
onLoged();
}
}
private void setupViewPager() {
mMyFragmentPagerAdapter = new MyFragmentPagerAdapter(getChildFragmentManager());
mViewPager = (ViewPager) getActivity().findViewById(R.id.pager);
}
private void setupGoogleplus() {
// google+ part
mPlusClient = new PlusClient.Builder(getSherlockActivity(), new ConnectionCallbacks() {
#Override
public void onConnected(Bundle connectionHint) {
String accountName = mPlusClient.getAccountName();
// new
// DownloadImageTask(userPicture).execute(mPlusClient.getCurrentPerson().getImage().getUrl());
// Toast.makeText(getActivity(), accountName + " is connected.",
// Toast.LENGTH_LONG).show();
mConnectionProgressDialog.dismiss();
mSession.createLoginSession(mPlusClient.getCurrentPerson().getName().getGivenName().toString(), mPlusClient.getAccountName(), "Google+");
}
#Override
public void onDisconnected() {
Log.d(TAG, "disconnected");
}
}, new OnConnectionFailedListener() {
#Override
public void onConnectionFailed(ConnectionResult result) {
if (mConnectionProgressDialog.isShowing()) {
// The user clicked the sign-in button already. Start to
// resolve
// connection errors. Wait until onConnected() to dismiss
// the
// connection dialog.
if (result.hasResolution()) {
try {
result.startResolutionForResult(getActivity(), REQUEST_CODE_RESOLVE_ERR);
} catch (SendIntentException e) {
mPlusClient.connect();
}
}
}
// Save the result and resolve the connection failure upon a
// user click.
mConnectionResult = result;
}
}).setActions("http://schemas.google.com/AddActivity", "http://schemas.google.com/BuyActivity").build();
mConnectionProgressDialog = new ProgressDialog(getActivity());
mConnectionProgressDialog.setMessage("Signing in...");
}
private void onSessionStateChange(Session session, SessionState state, Exception exception) {
if (state.isOpened()) {
Log.i(TAG, "Logged in...");
// Request user data and show the results
Request.newMeRequest(session, new Request.GraphUserCallback() {
// callback after Graph API response with user object
#Override
public void onCompleted(GraphUser user, Response response) {
// TODO Auto-generated method stub
if (user != null) {
// Display the parsed user info
// Set the id for the ProfilePictureView
// view that in turn displays the profile picture.
// profilePictureView.setProfileId(user.getId());
// Set the Textview's text to the user's name.
mSession.createLoginSession(user.getName(), user.getProperty("email").toString(), "Facebook");
onLoged();
}
}
}).executeAsync();
} else if (state.isClosed()) {
Log.i(TAG, "Logged out...");
}
}
private Session.StatusCallback callback = new Session.StatusCallback() {
#Override
public void call(Session session, SessionState state, Exception exception) {
onSessionStateChange(session, state, exception);
}
};
#Override
public void onActivityResult(int requestCode, int responseCode, Intent intent) {
if (requestCode == REQUEST_CODE_RESOLVE_ERR) {
mConnectionResult = null;
mPlusClient.connect();
} else {
uiHelper.onActivityResult(requestCode, responseCode, intent);
}
super.onActivityResult(requestCode, responseCode, intent);
}
private static class MyFragmentPagerAdapter extends FragmentPagerAdapter {
public MyFragmentPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int index) {
switch (index) {
case 0:
return new FirstFragment();
case 1:
return new SecondFragment();
case 2:
return new ThirdFragment();
}
return null;
}
#Override
public int getCount() {
return NUMBER_OF_PAGES;
}
#Override
public CharSequence getPageTitle(int position) {
switch (position) {
case 0:
return "1";
case 1:
return "2";
case 2:
return "3";
}
return null;
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.login_fragment, container, false);
authButton = (LoginButton) view.findViewById(R.id.authButton);
authButton.setFragment(this);
authButton.setReadPermissions(Arrays.asList("email"));
return view;
}
#Override
public void onResume() {
super.onResume();
uiHelper.onResume();
}
#Override
public void onPause() {
super.onPause();
uiHelper.onPause();
}
#Override
public void onDestroy() {
super.onDestroy();
uiHelper.onDestroy();
}
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
uiHelper.onSaveInstanceState(outState);
}
#Override
public void onStart() {
mPlusClient.connect();
super.onStart();
}
#Override
public void onStop() {
super.onStop();
mPlusClient.disconnect();
}
public void googleLogout() {
if (mPlusClient.isConnected()) {
mPlusClient.clearDefaultAccount();
mPlusClient.disconnect();
mPlusClient.connect();
mSession.logoutUser();
}
}
public void onLoged() {
mViewPager.setAdapter(mMyFragmentPagerAdapter);
mViewPager.setVisibility(View.VISIBLE);
authButton.setVisibility(View.INVISIBLE);
loginButton.setVisibility(View.INVISIBLE);
}
public void onNotLoged() {
mViewPager.setAdapter(null);
mViewPager.setVisibility(View.INVISIBLE);
authButton.setVisibility(View.VISIBLE);
loginButton.setVisibility(View.VISIBLE);
}}
In onConnected method I call mySession object creation (shared preferences) to store the data and onLoged to display user fragments. Why do I have to switch tabs a few times for onConnected to be called?
Because the resolution for the connection failure was started with startIntentSenderForResult and the code REQUEST_CODE_RESOLVE_ERR, you need to capture the result inside Activity.onActivityResult.
protected void onActivityResult(int requestCode, int responseCode, Intent intent) {
if (requestCode == REQUEST_CODE_RESOLVE_ERR && responseCode == RESULT_OK) {
mConnectionResult = null;
mPlusClient.connect();
}
}
So in your case you should call mPlusClient.connect(); in LoginFragment onActivityResult after all needed checks.
I have started using the Google+ API for android, and I have created a sign-in application following this tutorial:
https://developers.google.com/+/mobile/android/sign-in
Now, the problem is that I want to create the sign out button from a different Activity, and what i tried to do didn't really worked..
My GPlusLogin code (Activity for the Google+ Login):
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.content.IntentSender.SendIntentException;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import com.google.android.gms.common.*;
import com.google.android.gms.common.GooglePlayServicesClient.ConnectionCallbacks;
import com.google.android.gms.common.GooglePlayServicesClient.OnConnectionFailedListener;
import com.google.android.gms.plus.PlusClient;
public class GPlusLogin extends Activity implements ConnectionCallbacks, OnConnectionFailedListener{
private static final int REQUEST_CODE_RESOLVE_ERR = 9000;
private static final String TAG = "GPlusLogin";
private ProgressDialog mConnectionProgressDialog;
private PlusClient mPlusClient;
private ConnectionResult mConnectionResult;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.gplus_layout);
mPlusClient = new PlusClient.Builder(this, this, this).setVisibleActivities("http://schemas.google.com/AddActivity", "http://schemas.google.com/BuyActivity").build();
Bundle extras = getIntent().getExtras();
mConnectionProgressDialog = new ProgressDialog(this);
mConnectionProgressDialog.setMessage("Signing in...");
if(extras!=null){
if(extras.getString("signout")!=null){
if (mPlusClient.isConnected()) {
mPlusClient.clearDefaultAccount();
mPlusClient.disconnect();
mPlusClient.connect();
finish();
startActivity(getIntent());
}
}
}else{
findViewById(R.id.sign_in_button).setOnClickListener(new OnClickListener() {
public void onClick(View view) {
// TODO Auto-generated method stub
if (view.getId() == R.id.sign_in_button && !mPlusClient.isConnected()) {
if (mConnectionResult == null) {
mConnectionProgressDialog.show();
} else {
try {
mConnectionResult.startResolutionForResult(GPlusLogin.this, REQUEST_CODE_RESOLVE_ERR);
} catch (SendIntentException e) {
// Try connecting again.
mConnectionResult = null;
mPlusClient.connect();
}
}
}
}
});
}
}
#Override
protected void onStart() {
// TODO Auto-generated method stub
super.onStart();
mPlusClient.connect();
}
#Override
protected void onStop() {
// TODO Auto-generated method stub
super.onStop();
mPlusClient.disconnect();
}
#Override
public void onConnectionFailed(ConnectionResult result) {
// TODO Auto-generated method stub
if (mConnectionProgressDialog.isShowing()) {
// The user clicked the sign-in button already. Start to resolve
// connection errors. Wait until onConnected() to dismiss the
// connection dialog.
if (result.hasResolution()) {
try {
result.startResolutionForResult(this, REQUEST_CODE_RESOLVE_ERR);
} catch (SendIntentException e) {
mPlusClient.connect();
}
}
}
mConnectionResult = result;
}
#Override
protected void onActivityResult(int requestCode, int responseCode, Intent intent) {
if (requestCode == REQUEST_CODE_RESOLVE_ERR && responseCode == RESULT_OK) {
mConnectionResult = null;
mPlusClient.connect();
}
}
#Override
public void onConnected() {
// TODO Auto-generated method stub
mConnectionProgressDialog.dismiss();
Intent main = new Intent(GPlusLogin.this, MainActivity.class);
main.putExtra("result", true);
startActivity(main);
}
#Override
public void onDisconnected() {
// TODO Auto-generated method stub
Log.d(TAG, "disconnected");
}
}
My Disconnect code on MainActivity:
import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends Activity{
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Bundle extras = getIntent().getExtras();
if(extras==null){
Intent intent = new Intent(this, GPlusLogin.class);
startActivity(intent);
}
TextView text1 = (TextView) findViewById(R.id.text1);
text1.setText("You Are Connected :D");
Button SignOut = (Button) findViewById(R.id.sign_out_gplus);
SignOut.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View view) {
// TODO Auto-generated method stub
Intent intent = new Intent(MainActivity.this, GPlusLogin.class);
intent.putExtra("signout", true);
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;
}
}
Just add this on your new activity, where you want your logout-button for google+ to be there :
#Override
protected void onStart() {
GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestEmail()
.build();
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(Auth.GOOGLE_SIGN_IN_API, gso)
.build();
mGoogleApiClient.connect();
super.onStart();
}
and next:
signout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Auth.GoogleSignInApi.signOut(mGoogleApiClient).setResultCallback(
new ResultCallback<Status>() {
#Override
public void onResult(Status status) {
// ...
Toast.makeText(getApplicationContext(),"Logged Out",Toast.LENGTH_SHORT).show();
Intent i=new Intent(getApplicationContext(),MainActivity.class);
startActivity(i);
}
});
}
});
Hey i solved this problem by myself, working like charm
What is the problem : Google plus signIn in one activity but need to Logout from another activity
Solution:
My Google-plus Logout Activity is like this:
public class MainActivity extends Activity implements OnClickListener,
ConnectionCallbacks, OnConnectionFailedListener,
ResultCallback<People.LoadPeopleResult> {
GoogleApiClient mGoogleApiClient;
boolean mSignInClicked;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this).addApi(Plus.API)
.addScope(Plus.SCOPE_PLUS_LOGIN).build();
//copy this code on "Logout" Onclick
logout.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
if (mGoogleApiClient.isConnected()) {
Plus.AccountApi.clearDefaultAccount(mGoogleApiClient);
mGoogleApiClient.disconnect();
mGoogleApiClient.connect();
// updateUI(false);
System.err.println("LOG OUT ^^^^^^^^^^^^^^^^^^^^ SUCESS");
}
}
});
}
#Override
public void onConnected(Bundle arg0) {
// TODO Auto-generated method stub
mSignInClicked = false;
// updateUI(true);
Plus.PeopleApi.loadVisible(mGoogleApiClient, null).setResultCallback(
this);
}
#Override
public void onConnectionSuspended(int arg0) {
// TODO Auto-generated method stub
mGoogleApiClient.connect();
// updateUI(false);
}
#Override
public void onConnectionFailed(ConnectionResult arg0) {
// TODO Auto-generated method stub
}
protected void onStart() {
super.onStart();
mGoogleApiClient.connect();
}
protected void onStop() {
super.onStop();
if (mGoogleApiClient.isConnected()) {
mGoogleApiClient.disconnect();
}
}
#Override
public void onResult(LoadPeopleResult arg0) {
// TODO Auto-generated method stub
}
Description about solution:
For single package google plus API will generate one token & session.Just here simply make one more session in logout page also.You can easily logout from session now
I to have tried a lot about this problem,to logout from current session, just try this .it will definitely work. any doubts let me know
It would probably be easier to create a base class and inherit the connect/disconnect methods. Photohunt, our full sample, documents this design in detail.
Docs
Code
You can get instance of FirebaseAuth anywhere from the app as FirebaseAuth is a singleton class.
mAuth = FirebaseAuth.getInstance();
mAuth.signOut();
After struggling for over a week to find out the answer.
I did this,
After signing in save boolean isSignedIn in sharedpreferences as true.
private SharedPreferences.Editor editor;
private SharedPreferences prefs;
editor = getSharedPreferences(getString(R.string.userDetails), MODE_PRIVATE).edit();
editor.putBoolean(getString(R.string.isSignedIn), true);
editor.apply();`
Now from any activity when the user clicks logout, change the boolean to false.
In your Login Activity where googleApiClient is build. In its onStart method.
Check if isSignedIn is false.
#Override
public void onStart() {
super.onStart();
if (!prefs.getBoolean(getString(R.string.isSignedIn), false)) {
signOut();
}
}
Do the same in onConnected
#Override
public void onConnected(Bundle connectionHint) {
if (mGoogleApiClient.isConnected()) {
Log.i(TAG, "onConnected: " + "yes it is connected");
if (!prefs.getBoolean(getString(R.string.isSignedIn), false)) {
signOut();
}
}
}
This will logout and revokeAccess.
public void signOut() {
if (mGoogleApiClient != null) {
Log.e(TAG, "signOut: " + mGoogleApiClient + mGoogleApiClient.isConnected());
Auth.GoogleSignInApi.signOut(mGoogleApiClient).setResultCallback(
if (mGoogleApiClient.isConnected()) {
new ResultCallback<Status>() {
#Override
public void onResult(Status status) {
// ...
Log.i(TAG, "onResult: " + mGoogleApiClient);
}
});
Auth.GoogleSignInApi.revokeAccess(mGoogleApiClient).setResultCallback(
new ResultCallback<Status>() {
#Override
public void onResult(Status status) {
Log.i(TAG, "onResult: Revoke Access status:" + status.getStatus());
}
});
}
}
}
Once you click logout from another activity,try send an intent with extra to indicate that logout button is clicked. Then on Login Activity
if (Intent.Extras != null && Intent.Extras.ContainsKey("LogoutAction")) {
_logoutRequest = Intent.Extras.GetBoolean("LogoutAction");
}
if (_logoutRequest) {
await PlusClass.AccountApi.RevokeAccessAndDisconnect(_apiClient);
_apiClient.Disconnect();
_apiClient.Connect ();
_logoutRequest = false;
}
Other Activity
var intent = new Intent(this.Activity,typeof(LoginActivity));
intent.PutExtra("LogoutAction",true);
Jonathan is correct that a base class or a fragment would make your life easier. That said, the code here could work - the problem is that you're checking whether the PlusClient is connected in onCreate() - but you don't connect it until onStart(). You'd probably need to check the intent in the onConnected() method, and perform the sign out there.
sommesh's answer is perfect, but for less code you can use "Public Static Method" like this:
public static GoogleApiClient mGoogleApiClient;
...
...
public static void signOutFromGoogle() {
Auth.GoogleSignInApi.signOut(mGoogleApiClient).setResultCallback(
new ResultCallback<Status>() {
#Override
public void onResult(Status status) {
//...
}
});
}
And on your other Activity call it:
Your_Google_Activity.mGoogleApiClient.connect();
btnSignOut.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Your_Google_Activity.signOutFromGoogle();
}
});
Here's my solution. I have made a Utils singleton class. In my LoginActivity, I have a GoogleSignInClient object. So just before starting the DashboardActivity after login, I save the instance of googleSignInClient object by calling Utils.getInstance().setGoogleSignInClient(googleSignInClient). Now anywhere else, if I want to logout I have this method in Utils ready:
public void signOut() {
googleSignInClient.signOut();
FirebaseAuth.getInstance().signOut();
}
So now, I can do this from any other activity:
else if (id == R.id.action_logout) {
Utils.getInstance().signOut();
Intent intent = new Intent(this, LoginActivity.class);
startActivity(intent);
}
Yes, you need to log out from both of them, otherwise, you might not see the account chooser the next time you tap the login button.