I am trying to design a good architecture for implementing Google API Services.
The current documentation looks like this:
public class MainActivity extends ActionBarActivity {
public static final String TAG = "BasicHistoryApi";
private static final int REQUEST_OAUTH = 1;
private static final String DATE_FORMAT = "yyyy.MM.dd HH:mm:ss";
/**
* Track whether an authorization activity is stacking over the current activity, i.e. when
* a known auth error is being resolved, such as showing the account chooser or presenting a
* consent dialog. This avoids common duplications as might happen on screen rotations, etc.
*/
private static final String AUTH_PENDING = "auth_state_pending";
private boolean authInProgress = false;
private GoogleApiClient mClient = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// This method sets up our custom logger, which will print all log messages to the device
// screen, as well as to adb logcat.
initializeLogging();
if (savedInstanceState != null) {
authInProgress = savedInstanceState.getBoolean(AUTH_PENDING);
}
buildFitnessClient();
}
/**
* Build a {#link GoogleApiClient} that will authenticate the user and allow the application
* to connect to Fitness APIs. The scopes included should match the scopes your app needs
* (see documentation for details). Authentication will occasionally fail intentionally,
* and in those cases, there will be a known resolution, which the OnConnectionFailedListener()
* can address. Examples of this include the user never having signed in before, or
* having multiple accounts on the device and needing to specify which account to use, etc.
*/
private void buildFitnessClient() {
// Create the Google API Client
mClient = new GoogleApiClient.Builder(this)
.addApi(Fitness.HISTORY_API)
.addScope(new Scope(Scopes.FITNESS_ACTIVITY_READ_WRITE))
.addConnectionCallbacks(
new GoogleApiClient.ConnectionCallbacks() {
#Override
public void onConnected(Bundle bundle) {
Log.i(TAG, "Connected!!!");
// Now you can make calls to the Fitness APIs. What to do?
// Look at some data!!
new InsertAndVerifyDataTask().execute();
}
#Override
public void onConnectionSuspended(int i) {
// If your connection to the sensor gets lost at some point,
// you'll be able to determine the reason and react to it here.
if (i == ConnectionCallbacks.CAUSE_NETWORK_LOST) {
Log.i(TAG, "Connection lost. Cause: Network Lost.");
} else if (i == ConnectionCallbacks.CAUSE_SERVICE_DISCONNECTED) {
Log.i(TAG, "Connection lost. Reason: Service Disconnected");
}
}
}
)
.addOnConnectionFailedListener(
new GoogleApiClient.OnConnectionFailedListener() {
// Called whenever the API client fails to connect.
#Override
public void onConnectionFailed(ConnectionResult result) {
Log.i(TAG, "Connection failed. Cause: " + result.toString());
if (!result.hasResolution()) {
// Show the localized error dialog
GooglePlayServicesUtil.getErrorDialog(result.getErrorCode(),
MainActivity.this, 0).show();
return;
}
// The failure has a resolution. Resolve it.
// Called typically when the app is not yet authorized, and an
// authorization dialog is displayed to the user.
if (!authInProgress) {
try {
Log.i(TAG, "Attempting to resolve failed connection");
authInProgress = true;
result.startResolutionForResult(MainActivity.this,
REQUEST_OAUTH);
} catch (IntentSender.SendIntentException e) {
Log.e(TAG,
"Exception while starting resolution activity", e);
}
}
}
}
)
.build();
}
#Override
protected void onStart() {
super.onStart();
// Connect to the Fitness API
Log.i(TAG, "Connecting...");
mClient.connect();
}
#Override
protected void onStop() {
super.onStop();
if (mClient.isConnected()) {
mClient.disconnect();
}
}
.... // MORE CODE
}
This looks really ugly inside an Activity, what if I have multiple Activities using Google API Services.
Would it be possible to move everything to a Client.java class that just handles creation of a GoogleApiClient object.
How would I pass an activity context parameter to GoogleApiClient.Builder(this)? Should I use an event bus driven system that sends off context values from each activity to the client and builds it each time?
This is pretty ugly, any way I can trim this code so I don't have to copy it everywhere in like 30 activities?
How about a manager class GoogleApiManager.java that would handle all that for me? What sorts of interfaces would I need to implement on this?
Can I instead store inside an application class instead?
Would appreciate any help on this.
You are going to have to mess around with the code to get it all working correctly. I don't have google api client hooked up so I can't debug.
You could create a separate class like below
public class BuildFitnessClient {
private static boolean mAuthInProgress;
private static final String TAG = "BasicHistoryApi";
private static final int REQUEST_OAUTH = 1;
public static GoogleApiClient googleApiClient(final Activity activity, boolean authInProgress) {
mAuthInProgress = authInProgress;
return new GoogleApiClient.Builder(activity)
.addApi(Fitness.HISTORY_API)
.addScope(new Scope(Scopes.FITNESS_ACTIVITY_READ_WRITE))
.addConnectionCallbacks(
new GoogleApiClient.ConnectionCallbacks() {
#Override
public void onConnected(Bundle bundle) {
mCallbacks.connected();
}
#Override
public void onConnectionSuspended(int i) {
if (i == GoogleApiClient.ConnectionCallbacks.CAUSE_NETWORK_LOST) {
Log.i(TAG, "Connection lost. Cause: Network Lost.");
}
}
}
)
.addOnConnectionFailedListener(
new GoogleApiClient.OnConnectionFailedListener() {
// Called whenever the API client fails to connect.
#Override
public void onConnectionFailed(ConnectionResult result) {
Log.i(TAG, "Connection failed. Cause: " + result.toString());
if (!result.hasResolution()) {
// Show the localized error dialog
GooglePlayServicesUtil.getErrorDialog(result.getErrorCode(),
activity, 0).show();
return;
}
if (!mAuthInProgress) {
try {
Log.i(TAG, "Attempting to resolve failed connection");
mAuthInProgress = true;
result.startResolutionForResult(activity,
REQUEST_OAUTH);
} catch (IntentSender.SendIntentException e) {
Log.e(TAG,
"Exception while starting resolution activity", e);
}
}
}
}
)
.build();
}
/**
* Interface to communicate to the parent activity (MainActivity.java)
*/
private static MyCallbacks mCallbacks;
public interface MyCallbacks {
void connected();
}
public void onAttach(Activity activity) {
try {
mCallbacks = (MyCallbacks) activity;
} catch (ClassCastException e) {
throw new ClassCastException("Activity must implement Fragment One.");
}
}
}
Then in your Activity you could call it like:
public class TestingActivity extends AppCompatActivity implements BuildFitnessClient.MyCallbacks {
GoogleApiClient mClient;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_testing);
new BuildFitnessClient().onAttach(this);
mClient = new BuildFitnessClient().googleApiClient(this, true);
}
#Override
protected void onStart() {
super.onStart();
mClient.connect();
}
#Override
protected void onStop() {
super.onStop();
if (mClient.isConnected()) {
mClient.disconnect();
}
}
#Override
public void connected() {
Log.e("Connected", "Connected");
new InsertAndVerifyDataTask().execute();
}
}
Related
I am working on a project in Android Studio where I am supposed to connect two devices using Wifi-Direct.
I have managed to connect to another device with Wifi-direct. My problem is that when I close the app manually on my phone, the devices do not disconnect. How can I achieve this? I am quite new with Android Studio and java.
Here is my WifiDirectActivity class:
public class WiFiDirectActivity extends Activity implements WifiP2pManager.ChannelListener, DeviceListFragment.DeviceActionListener {
public static final String TAG = "wifidirectdemo";
private WifiP2pManager manager;
private boolean isWifiP2pEnabled = false;
private boolean retryChannel = false;
private final IntentFilter intentFilter = new IntentFilter();
private WifiP2pManager.Channel channel;
private BroadcastReceiver receiver = null;
/**
* #param isWifiP2pEnabled the isWifiP2pEnabled to set
*/
public void setIsWifiP2pEnabled(boolean isWifiP2pEnabled) {
this.isWifiP2pEnabled = isWifiP2pEnabled;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_peers);
// add necessary intent values to be matched.
intentFilter.addAction(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION);
intentFilter.addAction(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION);
intentFilter.addAction(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION);
intentFilter.addAction(WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION);
manager = (WifiP2pManager) getSystemService(Context.WIFI_P2P_SERVICE);
channel = manager.initialize(this, getMainLooper(), null);
}
/** register the BroadcastReceiver with the intent values to be matched */
#Override
public void onResume() {
super.onResume();
receiver = new WiFiDirectBroadcastReceiver(manager, channel, this);
registerReceiver(receiver, intentFilter);
if (!amConnected) {
performSearch();
}
}
#Override
public void onPause() {
super.onPause();
unregisterReceiver(receiver);
}
/**
* Remove all peers and clear all fields. This is called on
* BroadcastReceiver receiving a state change event.
*/
public void resetData() {
DeviceListFragment fragmentList = (DeviceListFragment) getFragmentManager()
.findFragmentById(R.id.frag_list);
DeviceDetailFragment fragmentDetails = (DeviceDetailFragment) getFragmentManager()
.findFragmentById(R.id.frag_detail);
if (fragmentList != null) {
fragmentList.clearPeers();
}
if (fragmentDetails != null) {
fragmentDetails.resetViews();
}
}
#Override
public void showDetails(WifiP2pDevice device) {
DeviceDetailFragment fragment = (DeviceDetailFragment) getFragmentManager()
.findFragmentById(R.id.frag_detail);
fragment.showDetails(device);
}
#Override
public void connect(WifiP2pConfig config) {
manager.connect(channel, config, new WifiP2pManager.ActionListener() {
#Override
public void onSuccess() {
// WiFiDirectBroadcastReceiver will notify us. Ignore for now.
}
#Override
public void onFailure(int reason) {
Toast.makeText(WiFiDirectActivity.this, "Connect failed. Retry.",
Toast.LENGTH_SHORT).show();
}
});
}
#Override
public void disconnect() {
final DeviceDetailFragment fragment = (DeviceDetailFragment) getFragmentManager()
.findFragmentById(R.id.frag_detail);
fragment.resetViews();
manager.removeGroup(channel, new WifiP2pManager.ActionListener() {
#Override
public void onFailure(int reasonCode) {
Log.d(TAG, "Disconnect failed. Reason :" + reasonCode);
}
#Override
public void onSuccess() {
fragment.getView().setVisibility(View.GONE);
}
});
}
#Override
public void onChannelDisconnected() {
// we will try once more
if (manager != null && !retryChannel) {
Toast.makeText(this, "Channel lost. Trying again", Toast.LENGTH_LONG).show();
resetData();
retryChannel = true;
manager.initialize(this, getMainLooper(), this);
} else {
Toast.makeText(this,
"Severe! Channel is probably lost premanently. Try Disable/Re-Enable P2P.",
Toast.LENGTH_LONG).show();
}
}
#Override
public void cancelDisconnect() {
/*
* A cancel abort request by user. Disconnect i.e. removeGroup if
* already connected. Else, request WifiP2pManager to abort the ongoing
* request
*/
if (manager != null) {
final DeviceListFragment fragment = (DeviceListFragment) getFragmentManager()
.findFragmentById(R.id.frag_list);
if (fragment.getDevice() == null
|| fragment.getDevice().status == WifiP2pDevice.CONNECTED) {
disconnect();
} else if (fragment.getDevice().status == WifiP2pDevice.AVAILABLE
|| fragment.getDevice().status == WifiP2pDevice.INVITED) {
manager.cancelConnect(channel, new WifiP2pManager.ActionListener() {
#Override
public void onSuccess() {
Toast.makeText(WiFiDirectActivity.this, "Aborting connection",
Toast.LENGTH_SHORT).show();
}
#Override
public void onFailure(int reasonCode) {
Toast.makeText(WiFiDirectActivity.this,
"Connect abort request failed. Reason Code: " + reasonCode,
Toast.LENGTH_SHORT).show();
}
});
}
}
}
private void performSearch() {
final DeviceListFragment fragment = (DeviceListFragment) getFragmentManager()
.findFragmentById(R.id.frag_list);
fragment.onInitiateDiscovery();
manager.discoverPeers(channel, new WifiP2pManager.ActionListener() {
#Override
public void onSuccess() {
Toast.makeText(WiFiDirectActivity.this, "Discovery Initiated",
Toast.LENGTH_SHORT).show();
}
#Override
public void onFailure(int reasonCode) {
Toast.makeText(WiFiDirectActivity.this, "Discovery Failed : " + reasonCode,
Toast.LENGTH_SHORT).show();
}
});
}
}
When you close the app the execution will run through onPause() callback, there you should call the disconnect() method. However, take 5 minutes of your time to understand Android's life cycle principle: https://developer.android.com/guide/components/activities/activity-lifecycle.html. It's one of the first things to learn before developing an Android app.
Hi I'm try to get Google Play Service Ads Id in AsyncTask.
I read Android AsyncTask API documentation and many stackoverflow Answer. I want to get Ads Id first and will start other process.
Accordingly, I made AdIdAsyncTask for getting Ads Id in BackgroundThread and invoke in my MainActivity. But My AsyncTask status is always RUNNING.
What's Wrong?
MainActivity and AdIdAsyncTask
public class MainActivity extends Activity {
private static final String TAG = "DummyActivity";
private final long MEDIA_ID = 292929L;
private final String ACCESS_KEY = "xxxx-xxxx-xxxx";
private String adId = null;
private AdContext adContext;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
AdIdAsyncTask task = new AdIdAsyncTask();
task.execute();
Log.d(TAG, "task.getStatus=" + task.getStatus());
if (task.getStatus().equals(AsyncTask.Status.FINISHED)) {
// do work
}
}
#Override
protected void onDestroy() {
super.onDestroy();
Log.i(TAG, "onDestroy");
}
public class AdIdAsyncTask extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... params) {
Log.d(TAG, "doInBackground");
AdvertisingIdClient.Info idInfo = null;
try {
idInfo = AdvertisingIdClient.getAdvertisingIdInfo(getApplicationContext());
} catch (GooglePlayServicesNotAvailableException | GooglePlayServicesRepairableException | IOException e) {
Log.e(TAG, "fetch Google Ads is failed. message=" + e.getMessage());
}
String advertisingId = null;
try {
advertisingId = idInfo.getId();
} catch (NullPointerException e) {
Log.e(TAG, "adId is null. message=" + e.getMessage());
}
adId = advertisingId;
cancel(true);
Log.i(TAG, "adId=" + advertisingId + ", isCancelled=" + isCancelled());
return null;
}
#Override
protected void onCancelled() {
super.onCancelled();
Log.i(TAG, "onCancelled");
}
#Override
protected void onCancelled(Void aVoid) {
super.onCancelled(aVoid);
Log.i(TAG, "onCancelled");
}
}
}
Log
D/DummyActivity: task.getStatus=RUNNING
D/DummyActivity: doInBackground
I/DummyActivity: adId=xxxx-xxxx-xxxx, isCancelled=true
I/DummyActivity: onCancelled
I/DummyActivity: onCancelled
SdkVersion
compileSdkVersion 25
minSdkVersion 14
targetSdkVersion 25
Hello you can force close the AsyncTask
Please use the following code in yout AsyncTask with condition and call it in your activity where you want to stop, it will stop your asynk task running
/**
* Check if asynctask is running, if still running cancel it.
*/
public void forceCancel(){
if (getStatus().equals(AsyncTask.Status.RUNNING)) {
cancel(true);
}
}
I coded an Android Game in Java using Android Studio. Now I want to exchange the players highscore online, via the GoogleApi. So I initialize a GoogleApiClient in my onCreate function:
googleApi = new GoogleApiClient.Builder(FullscreenActivity.this)
.addApi(Games.API)
.addOnConnectionFailedListener(this)
.addConnectionCallbacks(this)
.build();
Where googleApiis a public GoogleApiClient variable.
Then there are:
#Override
protected void onStart() {
super.onStart();
Log.e("Connected?", String.valueOf(googleApi.isConnected()));
googleApi.connect();
}
#Override
public void onConnectionFailed(ConnectionResult result) {
Log.d("ConnectionFailed", String.valueOf(result));
if (result.hasResolution()) {
try {
// !!!
result.startResolutionForResult(this, REQUEST_CODE_RESOLVE_ERR);
} catch (IntentSender.SendIntentException e) {
googleApi.connect();
}
}
}
#Override
public void onConnected(Bundle bundle) {
if(!started){
started = true;
setContentView(new Game(this));
}
}
#Override
public void onConnectionSuspended(int i) {
if(!started){
started = true;
this.setContentView(new Game(this));
}
}
The output of onConnectionFailed(...) says: D/ConnectionFailed: ConnectionResult{statusCode=SIGN_IN_REQUIRED, resolution=PendingIntent{2b5bddee: android.os.BinderProxy#7d0328f}, message=null}
On my mobile the Google Play Games Login window showed up, and I logged in. Then a rotating progress circle was showing, and it disappeared. The onConnected(...) function never got called.
What to add/remove/edit?
This is most likely not a duplicate, because I did not find a working solution for several other questions, that equal in content.
During the signin process, there can be multiple calls to onConnectionFailed. Have you looked at the samples in GitHub: https://github.com/playgameservices/android-basic-samples/tree/master/BasicSamples ?
In the samples onConnectionFailed is implemented as:
public void onConnectionFailed(ConnectionResult connectionResult) {
Log.d(TAG, "onConnectionFailed");
if (mIsResolving) {
// The application is attempting to resolve this connection failure already.
Log.d(TAG, "onConnectionFailed: already resolving");
return;
}
if (mSignInClicked || mAutoStartSignIn) {
mSignInClicked = false;
mAutoStartSignIn = false;
// Attempt to resolve the connection failure.
Log.d(TAG, "onConnectionFailed: begin resolution.");
mIsResolving = resolveConnectionFailure(this, mGoogleApiClient,
connectionResult, RC_SIGN_IN, getString(R.string.signin_other_error));
}
updateUI();
}
And resolveConnectionFailure is:
public static boolean resolveConnectionFailure(Activity activity,
GoogleApiClient client, ConnectionResult result, int requestCode,
String fallbackErrorMessage) {
if (result.hasResolution()) {
try {
result.startResolutionForResult(activity, requestCode);
return 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.
client.connect();
return false;
}
} else {
// not resolvable... so show an error message
int errorCode = result.getErrorCode();
Dialog dialog = GooglePlayServicesUtil.getErrorDialog(errorCode,
activity, requestCode);
if (dialog != null) {
dialog.show();
} else {
// no built-in dialog: show the fallback error message
showAlert(activity, fallbackErrorMessage);
}
return false;
}
}
I'm trying to connect mGoogleAPIClient, following this Guide.
When i debug, a little window popsup asking me what googleplus account i would like to sign in as. As soon as I select my main account and click OK, it stops from there and does absolutely nothing. No error Messages, Warnings, Infos, no nothing.
My Source:
public class MainMenu_Activity extends Activity implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {
private Button btnStart;
private Button btnSubmit;
private Button btnHOF;
private GoogleApiClient mGoogleApiClient;
public static int REQUEST_LEADERBOARD = 100;
// 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;
private static final String STATE_RESOLVING_ERROR = "resolving_error";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_mainmenu);
mResolvingError = savedInstanceState != null
&& savedInstanceState.getBoolean(STATE_RESOLVING_ERROR, false);
this.mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(Drive.API)
.addScope(Drive.SCOPE_FILE)
.addApi(Plus.API)
.addScope(Plus.SCOPE_PLUS_LOGIN)
.addScope(Plus.SCOPE_PLUS_PROFILE)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
}
#Override
protected void onStart() {
super.onStart();
if (!mResolvingError) { // more about this later
mGoogleApiClient.connect();
}
}
#Override
protected void onStop() {
mGoogleApiClient.disconnect();
super.onStop();
}
#Override
public void onConnected(Bundle connectionHint) {
// Connected to Google Play services!
// The good stuff goes here.
System.out.println("CONNECTED!");
}
#Override
public void onConnectionSuspended(int cause) {
// The connection has been interrupted.
// Disable any UI components that depend on Google APIs
// until onConnected() is called.
System.out.println("SUSPENDED!");
}
#Override
public void onConnectionFailed(ConnectionResult result) {
System.out.println("Connection Failed - mResolvingError=" + mResolvingError);
if (mResolvingError) {
System.out.println("Connection Failed - Already attempting to resolve...");
// Already attempting to resolve an error.
return;
} else if (result.hasResolution()) {
System.out.println("Connection Failed - resolving now...");
try {
mResolvingError = true;
result.startResolutionForResult(this, REQUEST_RESOLVE_ERROR);
} catch (IntentSender.SendIntentException e) {
System.out.println("Connection Failed - Exception...");
// There was an error with the resolution intent. Try again.
mGoogleApiClient.connect();
}
} else {
// Show dialog using GooglePlayServicesUtil.getErrorDialog()
Dialog errDia = GooglePlayServicesUtil.getErrorDialog(result.getErrorCode(), this, 1);
errDia.show();
mResolvingError = true;
}
}
#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();
}
}
}
}
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putBoolean(STATE_RESOLVING_ERROR, mResolvingError);
}
}
As you can see, i tagged certain places to follow the procedure.
Well this is what the logcat logs:
06-02 17:52:48.175 2302-2302/com.dudewithfacial.game.gamebase I/System.out﹕
Connection Failed - mResolvingError=false 06-02 17:52:48.175
2302-2302/com.dudewithfacial.game.gamebase I/System.out﹕ Connection Failed -
resolving now...
I follow the guide step by step :(
Well appaently not really, what am i doing wrong Stackoverflow-Gurus?
Thx boys, really appreciated!
NVM, figured out i can't use Launchmode, SingleUser, SingleInstance.
Also haven't configred some of the requested APIs such as ".addApi(Plus.API)"
Problem fixed.
I am trying to give my users the option to sign in with either Google or Facebook. So far I found an example to implement a Google Sign in Flow, but I am confused if I can implement a similar Facebook Login Flow within the same Activity.
Anyone have an Idea as to handle the Logins? I was thinking about potentially defining a class to handle the Login Flows for both Google / Facebook, and perhaps just check to see which is being used when the app launches. Any Ideas?
public class MainActivity extends Activity implements ConnectionCallbacks,
OnConnectionFailedListener, OnClickListener, OnAccessRevokedListener {
private static final String TAG = "MainActivity";
// A magic number we will use to know that our sign-in error
// resolution activity has completed.
private static final int OUR_REQUEST_CODE = 49404;
// The core Google+ client.
private PlusClient mPlusClient;
// A flag to stop multiple dialogues appearing for the user.
private boolean mResolveOnFail;
// We can store the connection result from a failed connect()
// attempt in order to make the application feel a bit more
// responsive for the user.
private ConnectionResult mConnectionResult;
// A progress dialog to display when the user is connecting in
// case there is a delay in any of the dialogs being ready.
private ProgressDialog mConnectionProgressDialog;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
// We pass through this for all three arguments, specifying the:
// 1. Context
// 2. Object to call onConnected and onDisconnected on
// 3. Object to call onConnectionFailed on
mPlusClient = new PlusClient.Builder(this, this, this)
.setVisibleActivities("http://schemas.google.com/BuyActivity")
.build();
// We use mResolveOnFail as a flag to say whether we should trigger
// the resolution of a connectionFailed ConnectionResult.
mResolveOnFail = false;
// Connect our sign in, sign out and disconnect buttons.
findViewById(R.id.sign_in_button).setOnClickListener(this);
findViewById(R.id.sign_out_button).setOnClickListener(this);
findViewById(R.id.sign_out_button).setVisibility(View.GONE);
findViewById(R.id.authButton).setOnClickListener(this);
// Configure the ProgressDialog that will be shown if there is a
// delay in presenting the user with the next sign in step.
mConnectionProgressDialog = new ProgressDialog(this);
mConnectionProgressDialog.setMessage("Signing in...");
}
#Override
protected void onStart() {
super.onStart();
Log.v(TAG, "Start");
// Every time we start we want to try to connect. If it
// succeeds we'll get an onConnected() callback. If it
// fails we'll get onConnectionFailed(), with a result!
mPlusClient.connect();
}
#Override
protected void onStop() {
super.onStop();
Log.v(TAG, "Stop");
// It can be a little costly to keep the connection open
// to Google Play Services, so each time our activity is
// stopped we should disconnect.
mPlusClient.disconnect();
}
#Override
public void onConnectionFailed(ConnectionResult result) {
Log.v(TAG, "ConnectionFailed");
// Most of the time, the connection will fail with a
// user resolvable result. We can store that in our
// mConnectionResult property ready for to be used
// when the user clicks the sign-in button.
if (result.hasResolution()) {
mConnectionResult = result;
if (mResolveOnFail) {
// This is a local helper function that starts
// the resolution of the problem, which may be
// showing the user an account chooser or similar.
startResolution();
}
}
}
#Override
public void onConnected(Bundle bundle) {
// Yay! We can get the oAuth 2.0 access token we are using.
Log.v(TAG, "Connected. Yay!");
// Turn off the flag, so if the user signs out they'll have to
// tap to sign in again.
mResolveOnFail = false;
// Hide the progress dialog if its showing.
mConnectionProgressDialog.dismiss();
// Hide the sign in button, show the sign out buttons.
findViewById(R.id.sign_in_button).setVisibility(View.GONE);
findViewById(R.id.sign_out_button).setVisibility(View.VISIBLE);
// Retrieve the oAuth 2.0 access token.
final Context context = this.getApplicationContext();
AsyncTask task = new AsyncTask() {
#Override
protected Object doInBackground(Object... params) {
String scope = "oauth2:" + Scopes.PLUS_LOGIN;
try {
// We can retrieve the token to check via
// tokeninfo or to pass to a service-side
// application.
String token = GoogleAuthUtil.getToken(context,
mPlusClient.getAccountName(), scope);
} catch (UserRecoverableAuthException e) {
// This error is recoverable, so we could fix this
// by displaying the intent to the user.
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (GoogleAuthException e) {
e.printStackTrace();
}
return null;
}
};
task.execute((Void) null);
// THIS IS TO CONNECT TO NAVI ACTIVITY AFTER YOU CONNECT Also makes it
// so you cannot go back to main activity
/*
* if (mPlusClient.isConnected()) { Intent intent = new Intent(this,
* NaviActivity.class); startActivity(intent); } finish();
*/
}
#Override
public void onDisconnected() {
// Bye!
Log.v(TAG, "Disconnected. Bye!");
}
protected void onActivityResult(int requestCode, int responseCode,
Intent intent) {
Log.v(TAG, "ActivityResult: " + requestCode);
if (requestCode == OUR_REQUEST_CODE && responseCode == RESULT_OK) {
// If we have a successful result, we will want to be able to
// resolve any further errors, so turn on resolution with our
// flag.
mResolveOnFail = true;
// If we have a successful result, lets call connect() again. If
// there are any more errors to resolve we'll get our
// onConnectionFailed, but if not, we'll get onConnected.
mPlusClient.connect();
} else if (requestCode == OUR_REQUEST_CODE && responseCode != RESULT_OK) {
// If we've got an error we can't resolve, we're no
// longer in the midst of signing in, so we can stop
// the progress spinner.
mConnectionProgressDialog.dismiss();
}
}
#Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.sign_in_button:
Log.v(TAG, "Tapped sign in");
if (!mPlusClient.isConnected()) {
// Show the dialog as we are now signing in.
mConnectionProgressDialog.show();
// Make sure that we will start the resolution (e.g. fire the
// intent and pop up a dialog for the user) for any errors
// that come in.
mResolveOnFail = true;
// We should always have a connection result ready to resolve,
// so we can start that process.
if (mConnectionResult != null) {
startResolution();
} else {
// If we don't have one though, we can start connect in
// order to retrieve one.
mPlusClient.connect();
}
}
break;
case R.id.sign_out_button:
Log.v(TAG, "Tapped sign out");
// We only want to sign out if we're connected.
if (mPlusClient.isConnected()) {
// Clear the default account in order to allow the user
// to potentially choose a different account from the
// account chooser.
mPlusClient.clearDefaultAccount();
// Disconnect from Google Play Services, then reconnect in
// order to restart the process from scratch.
mPlusClient.disconnect();
mPlusClient.connect();
// Hide the sign out buttons, show the sign in button.
findViewById(R.id.sign_in_button).setVisibility(View.VISIBLE);
findViewById(R.id.sign_out_button).setVisibility(View.GONE);
}
break;
// THIS SHOULD NOT BE NEEDED, MUST SWITCH ACTIVITIES UPON AUTHORIZATION
case R.id.authButton:
Log.v(TAG, "Switch Activities");
if (mPlusClient.isConnected()) {
Intent intent = new Intent(view.getContext(),
NaviActivity.class);
view.getContext().startActivity(intent);
}
break;
default:
// Unknown id.
}
}
#Override
public void onAccessRevoked(ConnectionResult status) {
// mPlusClient is now disconnected and access has been revoked.
// We should now delete any data we need to comply with the
// developer properties. To reset ourselves to the original state,
// we should now connect again. We don't have to disconnect as that
// happens as part of the call.
mPlusClient.connect();
// Hide the sign out buttons, show the sign in button.
findViewById(R.id.sign_in_button).setVisibility(View.VISIBLE);
findViewById(R.id.sign_out_button).setVisibility(View.GONE);
}
/**
* A helper method to flip the mResolveOnFail flag and start the resolution
* of the ConnenctionResult from the failed connect() call.
*/
private void startResolution() {
try {
// Don't start another resolution now until we have a
// result from the activity we're about to start.
mResolveOnFail = false;
// If we can resolve the error, then call start resolution
// and pass it an integer tag we can use to track. This means
// that when we get the onActivityResult callback we'll know
// its from being started here.
mConnectionResult.startResolutionForResult(this, OUR_REQUEST_CODE);
} catch (SendIntentException e) {
// Any problems, just try to connect() again so we get a new
// ConnectionResult.
mPlusClient.connect();
}
}
}
set both fragments (facebook and google) in the layout that you use as login and in another to receive the session validated
<com.facebook.widget.LoginButton
android:id="#+id/authButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="30dp" />
<com.google.android.gms.common.SignInButton
android:id="#+id/sign_in_button"
android:layout_below="#id/authButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
then use al functions required by each one
public class MainActivity extends Activity implements ConnectionCallbacks,OnConnectionFailedListener {
//google
private PlusClient plusClient;
private SignInButton btnSignIn;
private ProgressDialog connectionProgressDialog;
private ConnectionResult connectionResult;
private static final int REQUEST_CODE_RESOLVE_ERR = 9000;
//face
private LoginButton buttonLoginLogout;
private UiLifecycleHelper uiHelper;
static Usuario appusuario;
static String urldelogin="algo";
private Session.StatusCallback callback = new Session.StatusCallback() {
#Override
public void call(Session session, SessionState state, Exception exception) {
onSessionStateChange(session, state, exception);
if (session.isOpened()) {
Log.e("usuario", "si hay sesion");
// make request to the /me API
Request.newMeRequest(session, new Request.GraphUserCallback() {
// callback after Graph API response with user object
#Override
public void onCompleted(GraphUser user, Response response) {
if (user != null) {
Log.e("usuario", "si hay usuario");
buildUserInfoDisplay(user);
//start another activity
}
}
}).executeAsync();
}
}
private void onSessionStateChange(Session session, SessionState state,
Exception exception) {
// TODO Auto-generated method stub
}
};
#Override
public void onResume() {
super.onResume();
uiHelper.onResume();
}
#Override
public void onPause() {
super.onPause();
uiHelper.onPause();
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
uiHelper.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_CODE_RESOLVE_ERR &&
resultCode == RESULT_OK)
{
connectionResult = null;
plusClient.connect();
}
}
#Override
public void onDestroy() {
super.onDestroy();
uiHelper.onDestroy();
}
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
uiHelper.onSaveInstanceState(outState);
}
public static void buildUserInfoDisplay(GraphUser user) {
appusuario=new Usuario(user.getName(),user.getUsername());
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
uiHelper = new UiLifecycleHelper(this, callback);
uiHelper.onCreate(savedInstanceState);
buttonLoginLogout = (LoginButton)findViewById(R.id.authButton);
buttonLoginLogout.setReadPermissions(Arrays.asList("user_status"));
btnSignIn = (SignInButton)findViewById(R.id.sign_in_button);
buttonLoginLogout.setVisibility(View.VISIBLE);
btnSignIn.setVisibility(View.VISIBLE);
plusClient = new PlusClient.Builder(this, this, this).setActions("http://schemas.google.com/AddActivity", "http://schemas.google.com/BuyActivity")
.build();
connectionProgressDialog = new ProgressDialog(this);
connectionProgressDialog.setMessage("Conectando...");
btnSignIn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View view)
{
if (!plusClient.isConnected())
{
if (connectionResult == null)
{
connectionProgressDialog.show();
}
else
{
try
{
connectionResult.startResolutionForResult(
MainActivity.this,
REQUEST_CODE_RESOLVE_ERR);
}
catch (SendIntentException e)
{
connectionResult = null;
plusClient.connect();
}
}
}
}
});
}
#Override
protected void onStart()
{
super.onStart();
plusClient.connect();
}
#Override
protected void onStop()
{
super.onStop();
plusClient.disconnect();
}
#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
public void onConnected(Bundle connectionHint)
{
connectionProgressDialog.dismiss();
//nombre
String accountName = plusClient.getAccountName();
//cuenta con mail
Person accountperson=plusClient.getCurrentPerson();
String personName = accountperson.getDisplayName();
Log.e("Google +", "Conectado");
//start another activity
}
#Override
public void onDisconnected()
{
Log.e("Google +", "Desconectado");
}
#Override
public void onConnectionFailed(ConnectionResult result) {
// TODO Auto-generated method stub
if (connectionProgressDialog.isShowing())
{
if (result.hasResolution())
{
try
{
result.startResolutionForResult(this,
REQUEST_CODE_RESOLVE_ERR);
}
catch (SendIntentException e)
{
plusClient.connect();
}
}
}
connectionResult = result;
}
}
in the new activity place the same functions to validate the sesion and use
if (session.isOpened()) { }
to hide google login button or
public void onConnected(Bundle connectionHint)
{
}
to hide facebook login button