Android - some code executes after the phone went to a different Activity - android

I have a strange scenario here.
I have this code:
// For checking if the person is logged in.
first_time_check();
setContentView(R.layout.main);
// ...next lines of code
and the first_time_check() function checks if the user is logged in for the first time. If their user_id is not in the SharedPreferences, I redirect them to log in:
public void first_time_check()
{
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences( ProblemioActivity.this);
String user_id = prefs.getString( "user_id", null ); // First arg is name and second is if not found.
String first_time_cookie = prefs.getString( "first_time_cookie" , null );
// About setting cookie. Check for first time cookie
if ( first_time_cookie == null )
{
// This user is a first-time visitor, 1) Create a cookie for them
first_time_cookie = "1";
// 2) Set it in the application session.
prefs.edit().putString("first_time_cookie", first_time_cookie ).commit();
// Make a remote call to the database to increment downloads number
// AND send me an email that it was a new user.
}
else
{
// If not first time, get their id.
// If user_id is empty, make them an account.
// If id not empty, call the update login date and be done.
if ( user_id == null )
{
// User id is null so they must have logged out.
Intent myIntent = new Intent(ProblemioActivity.this, LoginActivity.class);
ProblemioActivity.this.startActivity(myIntent);
}
else
{
// Make a remote call to the database to increment downloads number
}
}
return;
}
So after the code executes the
Intent myIntent = new Intent(ProblemioActivity.this, LoginActivity.class);
ProblemioActivity.this.startActivity(myIntent);
it still executes below the original code that calls this functions.
Any idea how that can happen?
Thanks!!

This is excerpted from the Dev Guide
Shutting Down an Activity
You can shut down an activity by calling its finish() method.
You can also shut down a separate activity that you previously
started by calling finishActivity().
Note: In most cases, you should not explicitly finish an activity
using these methods. As discussed in the following section about the
activity lifecycle, the Android system manages the life of an
activity for you, so you do not need to finish your own activities.
Calling these methods could adversely affect the expected user
experience and should only be used when you absolutely do not want
the user to return to this instance of the activity.
Calling finish() on the activity seems appropriate here as you do not want the user to return to this activity.

Related

Save Login state, logical error with SharedPreferences and passing a Bundle

I am developing my first networking application and have a small problem which I am unable to find a solution for.
On my startscreen, which is my main activity, there is the option to login. If you login, my login class passes data per intent to my main activity so I can update my UI. This is my main acitivity :
// Just to make sure Loginstatus is false on first run
loginstatus = false;
//Get saved data from SharedPreferences
loginstatus = PreferenceData.getUserLoggedInStatus(this);
Log.d("Loginstatus",""+loginstatus);
if (extras != null) {
login = extras.getString("loginy");
idt = extras.getString("id");
name = extras.getString("name");
vorname = extras.getString("vorname");
email = extras.getString("login");
zsm = vorname + " " + name;
}
else {
// Take saved Data instead the Bundle Data form first Login
idt = PreferenceData.getUSERID(this);
name = PreferenceData.getNachname(this);
vorname = PreferenceData.getVorname(this);
email = PreferenceData.getLoggedInEmailUser(this);
}
Obviously extra is NULL on Startup. If login was successful, my login class passes Data and my main activity is called again, so extras is NOT NULL and I can update my UI with that information.In addition, I save my Data in SharedPrefernces if login was true.
The Problem is, I want to save my login state after completley closing my app. So i reopen my App and I want to use my SharedPrefernces data, but somehow extras is still NOT NULL and I cant find a way to fix that.
This is how I handle login. Hope this is helpfully.
Login Activity
Keep one shared preferences value to check login status which default value set to false;
#Override
protected void onResume() {
super.onResume();
if (sharedpreferences.getBoolean("firstRun", true)) {
initializeDatabase();
sharedpreferences.edit().putBoolean("firstRun", false).apply();
sharedpreferences.edit().putBoolean("attendance", false).apply();
sharedpreferences.edit().putBoolean("loginStatus", false).apply();
}
loginCheck();
}
inside loginCheck() check method redirect to menu activity based on login status.
public void loginCheck(){
if(sharedpreferences.getBoolean("loginStatus", true)){
Intent i = new Intent(this, MainMenuActivity.class);
startActivity(i);
this.finish();
}
}
In case of User haven't log previously, after authenticate user successfully add needed data in to shared preference and change login status shared preference value to true so above explained redirect will happen.
if (message.equals("Login successful")) {
String employeeId = responseBody.getString("employee_id");
int userId = responseBody.getInt("user_id");
String employeeName = responseBody.getString("employee_name");
SharedPreferencesReference.get().edit().putString("employee_id", employeeId).apply();
SharedPreferencesReference.get().edit().putInt("user_id", userId).apply();
SharedPreferencesReference.get().edit().putString("employee_name", employeeName).apply();
SharedPreferencesReference.get().edit().putBoolean("loginStatus", true).apply();
Toasty.success(ActivityWeakReference.get(), message, Toast.LENGTH_SHORT, true).show();
Intent i = new Intent(ActivityWeakReference.get(), MainMenuActivity.class);
ActivityWeakReference.get().startActivity(i);
ActivityWeakReference.get().finish();
}
Menu Activity
In menu activity you should have a logout button which allow users to logout by changing shared preference login status value. In My case I had it as a Menu Item.
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.logout:
sharedpreferences.edit().putBoolean("loginStatus", false).apply();
Intent intent = new Intent(this,MainActivity.class);
startActivity(intent);
break;
}
return true;
}

Create Login/Registration view from a main activity

Im starting to get crazy on my problem here.
I have a main activity that connects to a server on onCreate event, (the program must be connected to the server or else it shall not be working).
client_thread = new ServerCom(this);
Now I want to create a login view with (Username, Password and Login buttom with a user exist validation).
And when there is a login view there has to be some sort of registration view (with Username, Password, confim Password and a Registration button with a user exist validation).
I have create a Login and Registration Activity (for handeling some data with login and registration).
public ClassLogIn(MainActivity owner)
{
this.owner = owner;
}
public ClassLogIn()
{
}
public void onClick(View view) {
if(view == btnLogIn)
{
if(TextUtils.isEmpty(userName.getText()) == false) {
if (TextUtils.isEmpty(userPassword.getText()) == false) {
owner.LogIn(userName.getText(),userPassword.getText());
}
...
To start the activitys from my mainActivity I have done this
else if(id == R.id.action_login){
Intent myIntent = new Intent(MainActivity.this, ClassLogIn.class);
startActivity(myIntent);
}
else if(id == R.id.action_registera){
Intent myIntent = new Intent(MainActivity.this, ClassRegistera.class);
startActivity(myIntent);
}
else if(id == R.id.action_Logout)
{
client_thread.LogOut();
}
Now my problem is how can I get the userName value to my client_thread?
And also how can I call Owner.LogIn from my ClassLogIn activity?
public boolean LogIn(Editable UserName, Editable Password)
{
return client_thread.LogIn(UserName.toString(),Password.toString());
}
Or do I trying to make something that is impossible in Android?
From the top of my head set up some IntentServies to catch intents and make then
set up your variables.
And static variables are not an option ?
(Would add a comment but don't have enough reps)
The specific code to do the following can differ depending on your specifics.
But in general, the procedure we do is the following:
NOTE - We use the WorkingStorage API to save parameters directly into the HHU (Hand Held Unit)
When we initially launch we make an attempt to retrieve from within the HHU the login credentials which includes an Authorization ID.
If they are present, we utilize the Authorization ID for subsequent WebService calls as needed throughout the Activities.
If they are Not present, we launch a User Data Entry 'screen' and get Username & Password input.
Then we send that data to the Server via a WebService call for validation.
The WebService responds to the HHU with a Result.
That Result is either a Valid Authorization ID or an Error Message (such as 'Not Valid', etc.).
If it is a Valid Authorization ID, then all of the login credentials are saved to the HHU with the WorkingStorage API and are then available to be utilized for subsequent WebService calls.

Verify if user is logged in or not, issues using Intent in Android

I am attempting to verify if a user is logged in or not, and if not sending them to a log in page. I am using the log in page template from Android Dev. and trying to use an Intent to send either a Boolean or a value ( 1 for logged in 0 for not). Here is the part of the code in LoginActivity with the Intent:
for (String credential : DUMMY_CREDENTIALS) {
String[] pieces = credential.split(":");
if (pieces[0].equals(mEmail)) {
// Account exists, return true if the password matches.
return pieces[1].equals(mPassword);
final boolean logged_in = true;
Intent intent = new Intent(LoginActivity.this, MainActivity.class);
intent.putExtra("log", logged_in);
startActivity(intent);
}
here I am trying as a Boolean and I am getting the error Unreachable code for the line with final boolean Logged_in = true. When I try as an int
int logged_in =1;
I get the same error. All the questions asked on SO state that I needed to use the current class, LoginActivity.this, instead of just this. When I did use just this, I got another error entirely.
How do I send a value to my MainActivity class to show whether they are logged in or not?
return pieces[1].equals(mPassword);
return ends the method routine so everything after is not reachable.

Login flow for Gigya in mobile app with custom login UI

I'm developing an Android app using Gigya to allow people to register using Facebook and Twitter; in parallel another developer is doing the same thing in iOS. We want to implement custom login UI.
The standard method uses Gigya's own UI and is documented here:
http://developers.gigya.com/035_Mobile_SDKs/020_Android#Logging_in_the_User
Beneath, it simply suggests:
If you wish to implement the graphic design by yourself, use the login method instead.
The standard login method calls a dedicated post-login callback with an onLogin(...) method and all subsequent flows are described as stemming from this event. The other login method calls a standard onGSResponse(...) callback; it's not clear how the response can be used to construct a user so I've set up my implementation to call socialize.getUserInfo. Attempts to call either method have resulted in lots of unusual errors.
As per the Gigya instructions I'm starting up with
mGSAPI = new GSAPI(GIGYA_APP_KEY, this);
mGSAPI.setAPIDomain("eu1.gigya.com");
in onCreate(...) (where GIGYA_APP_KEY is a value copied from our console). I'm calling setAPIDomain because we were getting an invalid data center error (albeit with a 500001 code, not a 301001 code!), which this has fixed.
Facebook login goes through the login flow as I'd expect and then comes back with error 400093 (which the docs tell me is an invalid API parameter, and has the message " Missing parameter: client_id").
Twitter login comes back with 206002, " Account Pending Verification", which seems to make sense; I then call
mGSAPI.sendRequest(
"getUserInfo",
null, //parameters
true, //use HTTPS
this, //the callback
null //a context object
);
and this gives me the error:
Missing required parameter: No secret or signature were provided. Request could not be verified.
The documentation for socialize.getUserInfo suggest a UID is required for web apps, but not for native ones. It mentions no other mandatory fields. I am a bit stuck ... shouldn't the GSAPI object be handling verification, as it's initialized with the API key?
I can give you some direction at a very high level for integrating GIGYA. (Code below is not verbatim) Hopefully it is somewhat helpful.
For a private Android app I had created a Manager object (GigyaManager) that maintained a singleton instance of the GSAPI object.
This singleton GigyaManager was initialized in my application object:
public static GigyaManager getInstance(String apiKey, Context context) {
mGSAPI = new GSAPI(apiKey, context);
}
My GigyaManager class also had a wrapper method for handling the login w/social services:
public void loginWithSocialService(GigyaSocialProvider provider, GSResponseListener listener) throws Exception {
// did the user attempt a social login, and bail out on the registration
// phase?
if (GigyaManager.getInstance().getGSAPI().getSession() != null) {
logout();
}
GSObject providerArgs = new GSObject();
providerArgs.put(GigyaManager.GIGYA_ARG_PROVIDER, provider.name().toLowerCase());
mGSAPI.login(providerArgs, listener, null);
}
This was fired from an onClick listener in a fragment that contained a "login" button:
GigyaManager.getInstance("appKey", getActivity()).loginWithSocialService(GigyaSocialProvider.FACEBOOK, this);
That fragment had to implement GSResponseListener that has the callbacks to deal with whether the login was successful or not:
#Override
public void onGSResponse(String method, GSResponse response, Object context) {
if (!method.equalsIgnoreCase("login") || response.getErrorCode() != 0) {
return;
}
GIGYAResponseWrapper resp = new GIGYAResponseWrapper(response.getResponseText());
// user is attached to login provider?
if (resp.isIsAttached()) {
// start some sort of loader or asynctask to get information about user account
// connected to GIGYA social login
Bundle args = new Bundle();
args.putString(ARG_UID, resp.getUid());
args.putString(ARG_UID_SIGNATURE, resp.getUidSignature());
args.putString(ARG_SIGNATURE_TIMESTAMP, resp.getSignatureTimestamp());
args.putString(ARG_SOCIAL_NICKNAME, resp.getNickname());
} else {
// login success, but this social account is not associated with anything in GIGYA
}
}

Android shared preferences conditional activity switching

I have an Android app which I use to register users on my web site. My first task is to register a user if my shared preferences file shows there is no registered user information.
If my app has a registered user, I provide the following code to simply and automatically switch to a "homepage" activity:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.signin);
if( USERPREFERENCES.getString(USERPREFERENCES_USERMAIL, "") == null && USERPREFERENCES.getString(USERPREFERENCES_USERID, "") == null && USERPREFERENCES.getString(USERPREFERENCES_USERNAME, "") == null){
//setContentView(R.layout.signin);
Toast.makeText(SignIn.this, "testing...", Toast.LENGTH_LONG).show();
}else{
Intent intent = new Intent(SignIn.this, Confirmed.class);
startActivity(intent);
}
... other code
So, from my default activity, signin.java, the app will either switch to the Confirmed activity or stay on and display the signin activity.
My problem is, when the system works and I get switched to the the Confirmed activity, I provide a logout onclick listener which is below:
signout.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
//USERPREFERENCES.cl
Toast.makeText(Confirmed.this, "signout responding!", Toast.LENGTH_LONG).show();
USERPREFERENCES.edit().clear().commit();
}
});
It responds and clears all my shared preferences variables. But, when I use my menu to manually switch to the sign-in activity, I still get switched back to the Confirmed activity.
This happens even though I can confirm the variables are empty.
This hardly ever will be true:
USERPREFERENCES.getString(USERPREFERENCES_USERMAIL, "") == null
What if you use this instead?
if( USERPREFERENCES.getString(USERPREFERENCES_USERMAIL, null) == null && USERPREFERENCES.getString(USERPREFERENCES_USERID, null) == null && USERPREFERENCES.getString(USERPREFERENCES_USERNAME, null) == null){
//setContentView(R.layout.signin); TRY TO AVOID DOING THIS THING!!!!!
Toast.makeText(SignIn.this, "testing...", Toast.LENGTH_LONG).show();
}else...
Also, as a recommendation... instead of being switching between activities... what if you create just a Signing.java activity and put a ViewFlipper in its layout. That way your app will be not only faster but also easier to maintain.
This is Because When you will switch back to LoginActivity, this will be resumed instead of being created , Means your Login code which you written inOnCreate will not be called because Dthis time Overrider OnResume has been called , not onCreate .
So either write this code again in onResume or call finish() before moving to second activity , so that next time it will call onCreate()
If you navigate back to the first activity, the onCreate is not called again (unless the activity was destroyed for lack of resources). Move the authentication code in onResume.

Categories

Resources