In my application i want to let users sign in with their google account so i am using google play services. This works - they can login and logout. I also want to find out if the user is signed in the onCreate method when i pass from one activity to another. I am trying to use Google play services isSignedIn function for this but on onCreate method it always return false (because google play service trigger on onStart).
Why do I want it ?
Because, i have two login option. One is google account another is my own login panel. I want to know that is user sign in wtih google or my system or not on onCreate. So i will give direction my flow.
How can i achive this or do you have an alternative suggestion ?
Thank you for answers.
This is due to the Activity lifecycle. Every time an Activity goes into the background, it will get onStop. The Play Games API requires you to disconnect when this happens. When the Activity comes back into the foreground, it gets onStart, and then GameHelper will attempt to reestablish the connection. Until this happens, isSignedIn will return false. When the connection is restored (which should be very fast if the user had already signed in), the onSignInSucceeded callback will be called and from that point on isSignedIn will return true.
It's impossible to know, on onCreate, whether or not the sign-in will succeed. Instead, you should wait for either onSignInSucceeded or onSignInFailed. It is guaranteed that one of those two callbacks will be called shortly after the Activity comes into the foreground.
At that point, you can decide what to do, because it will be clear whether or not the user is signed in with Google+.
I am not certain how your app works but it sounds as though you may be calling GameHelper.onStop at the end of one activity when in fact you want the game to continue in another activity. I don't think you can do this (see the accepted answer here):
Google Play Game Services multiplayer with Activity switching
My app is arranged into fragments and I have one fragment which interacts with GameHelper. Therefore, once I have performed GameHelper.setup and GameHelper.onStart, I am able to call isSignedIn from any method in any fragment and get the correct response.
An alternative approach (which I have used in the past) is to save the result of isSignedIn in a boolean in shared preferences. You can then check this to determine whether the user is signed in or not.
Related
On Android, it is possible for users to use the Settings -> Application Manager -> App -> Clear Data feature and clear all the stored data for the app. However, if the user uses the app switcher to switch back to the app it will switch back to the activity last used. In some cases, say with an app that requires login, the activity will be inappropriate for the case where there is no data. How should application handle his case? Should each Activity be derived from a base Activity class that checks if the data has been deleted and then launch the appropriate Activity (say, the login Activity)? Is there a more elegant solution than that?
Instead of checking if data has been deleted, just check if the user is signed in. If he isn't, you can just send him back to the login screen as you suggested.
In any case, if you are using oAuth, or ever intend to implement it for login, checking if the user is logged in should be implemented since the oAuth tokens eventually expire. In this case, no data has been deleted, but the user is no longer signed-in, which would lead to them getting stuck in the inappropriate Activity anyway.
Just create a super-class for your ActivityThatRequiresLogin that will check if the user is logged in, and have all ActivityThatRequiresLogin extend that class. Then, you can call super whenever the onCreate and onResume method is called.
If the user wipes their data, they are automatically signed out, so all you have to do is check if they're signed in or not.
Pressing Clear Data stops your app's process, so your code will not be running.
Unfortunately there is no way to catch intent of such action unless you'r a system app.
The best practice way to handle this situation would use a SharedPreference mechanism and a base activity class.
I have an app that has implemented In App Billing for a premium version of my app. On startup, I check if the user has purchased the product using IabHelper. When I load up my next activity, I need to check for the purchase again to decide whether or not to show certain menu content. I do not want to store the result of the call at startup in preferences or local db for security reasons and understand the Play information is cached anyway. Is my best option in the second activity to create a new instance of IabHelper and call startSetup() again then queryInventoryAsync()? Trouble with this is, as the call is asynchronous, I'm not sure when the response will return in order to update the UI menu.
This is what I'm currently doing as well. I use the async callback to update a previously held menu object to show/hide a purchase option which in reality is never seen the speed of the returned call.
To speed up the process if you call queryInventoryAsync(false, mGotInventoryListener); (note the false flag) then you will only use a local cached inventory which is far quicker to respond.
Problem
User presses 'Scores' button (which kicks off the Login process to log into the Google Play Games Services via beginUserInitiatedSignIn()), and then presses the 'home' key before it manages to log in. When returning to the app, it looks like the play services tries to 'pick up where it left off' and continues to sign in. But it's not quite right.
onActivityResult returns 0 at first (Not successful, which I would expect as it was interupted), then attempts to log in again and returns -1 which means Successful Great! But no, if I call getGameHelper().isSignedIn(); it returns false.
What is happening here?! Anything I may be overlooking or anything I can check?
Until you get a call to ConnectionCallbacks.onConnected (or onSignInSucceeded if you are using GameHelper), you are not connected.
Your onActivityResult should call GoogleApiClient.connect() when it receives a successful response so that the appropriate connection can be established and your onConnected callback is made.
Typically applications cannot be "restored to the last screen" without also performing initialization.
For example, my app holds a live connection to a server which is established on initialization. It also needs to check for preconditions (like internet connection available, etc).
So when a user presses Home on the app and then restores the app, I need to restablish the connection (may require user input) and reinitialize everything.
I would've thought terminating the app on Home was the way to go, but from what I read, it's "not".
Just how are apps supposed to reinitialize themselves when restored on the Android platform?
note: I cannot use NO_HISTORY flag as it breaks the Google Play API.
Initialize the connections in the onStart method, and finish them in the onStop method, whenever the app loads up (new load of reloading) the onStart method will be called.
See the graphic here for more details about an activities lifecycle
I am working on an Android app that deals with sensitive user information. One of the requirements is that the user is required to log back into the application whenever they leave it and come back. This is easily dealt with for the case when the user presses the Home button and then relaunches the app (android:clearTaskOnLaunch attribute on the Activity in AndroidManifest.xml). However, we need to do the same thing when the user long presses the Home button, switches to another application, then comes back.
I have researched this every way that I can think of and have not found a workable solution. Is this even possible with Android?
When answering, please keep in mind that this is a business requirement which I have no control over.
Well, I had the same problem yesterday. This is what I did and it works fine:
Added android:launchMode="singleTask" to the main activity in the AndroidManifest.xml
Called my boss and say: ey, this is going to take a long while... hold on!
Went and drank beer all night.
Just to clarify, my main activity only has a button that says login and launches the login page.
What have you tried? You can always clear whatever session you are saving in the proper Activity lifecycle method.
If I understand you correctly that you want to require an authorisation every time someone backs into the app, whether afresh or coming back to it, then you can override the onRestart() activity lifecycle event on the activity (or activities). So in onRestart() you can redirect the user to the login screen (you may also wish to consider onResume() depending on your requirements)
The lifecycle chart on this page will make this clearer:
http://developer.android.com/reference/android/app/Activity.html
Would it be possible to make it a time based thing, rather than strictly left the app and returned?
You could have a separate service that keeps track of when the last time the user accessed the application was.
I.e, in each onPause the Activity tells the service that an Activity was paused. The service records the time of that.
In each onResume, the Activity informs the Service that it wishes to resume. If some amount of time has passed since the last onPause, then the Service indicates that a login is required.
I think this would make a nicer user experience than just every time they leave the app. That could be very frustrating, to take 30 seconds to read a text, and then have to sign in again.
I suppose if you tweak it to have the timeout be very short, it has very similar behavior to what you requested anyways, but with the option of making it less draconion.
I think the easiest way to implement this, would be to add a field to your main activity like private boolean isLocked = true;.
To lock the app when another one is shown, set isLocked = true in the onPause() method. To make sure, that your don't lock your app, when returning from your own activities, start them via startActivityForResult() and unlock it in onActivityResult.
You can now check in onResume() wether your app is locked and redirect the user to your login screen.