Sahar Avr
Sahar Avr

Reputation: 131

Android - Main activity finishes for no reason?

On the main activity, I check if it's the first time the user logs in by reading SharedPreferences. Then I start a new simple Login/SignUp activity.

When pressing the "LOGIN" button on the second activity, I want to return the last time the user logged in to the main activity (I use getIntent().putExtra()).

For some reason, when I press "LOGIN", the second activity closes, then I see a Toast with the last login time but the app closes immediately! It's like something is closing the main activity. I've no idea why... Here are the codes:

Main Activity:

package com.technion.saharav.technionmobilehomework13_3_15;

import android.app.Activity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;


public class MainActivity extends Activity {

    private static final int REQ_CODE_LOGIN = 10;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);


        Intent intent = new Intent(getApplicationContext(), LoginActivity.class);
        startActivityForResult(intent, REQ_CODE_LOGIN);

    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        switch (requestCode) {
            case REQ_CODE_LOGIN:
                if (resultCode == LoginActivity.RESULT_FAIL) {
                    finish();
                }

                if (resultCode == RESULT_OK) {
                    Toast.makeText(getApplicationContext(),
                            "Last time connected: " + data.getExtras().get("lastLoginTime").toString(),
                            Toast.LENGTH_LONG).show();
                }

                break;
        }
        super.onActivityResult(requestCode, resultCode, data);
    }
}

LoginActivity:

package com.technion.saharav.technionmobilehomework13_3_15;

import android.app.Activity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

import java.util.Calendar;
import java.util.Date;


public class LoginActivity extends Activity {

    protected static int RESULT_FAIL = -1;

    EditText editext_username, editext_password;
    View tv;
    Button bt;
    private String username, password;

    Intent intent;
    SharedPreferences pref;
    SharedPreferences.Editor editor;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);

        editext_username = (EditText) findViewById(R.id.editText_Username);
        editext_password = (EditText) findViewById(R.id.editText_Password);
        tv = findViewById(R.id.textView_loginBottom);
        bt = (Button) findViewById(R.id.buttonClick);

        intent = getIntent();
        pref = getApplicationContext().getSharedPreferences("LoginInfo", MODE_PRIVATE);
        editor = pref.edit();

        if (!pref.getBoolean("firstLogin", true)) {
            username = pref.getString("username", "");
            password = pref.getString("password", "");
            tv.setVisibility(View.GONE);
        }
        else {
            bt.setText("CREATE");
        }


    }

    public void buttonClick(View view) {
        String userInput = editext_username.getText().toString();
        String passwordInput = editext_password.getText().toString();

        switch (bt.getText().toString()) {

            case "LOGIN":
                if (editext_username.getText().toString().equals(username)
                        && editext_password.getText().toString().equals(password)) {

                    intent.putExtra("lastLoginTime", pref.getString("lastLoginTime", ""));

                    editor.putString("lastLoginTime", Calendar.getInstance().getTime().toString());
                    editor.commit();

                    setResult(RESULT_OK, intent);
                    finish();
                } else {
                    Toast.makeText(getApplicationContext(),
                            "Login failed. Check the username or password and try again.", Toast.LENGTH_LONG).show();
                }
                break;

            case "CREATE":
                if (userInput.length() > 0 && passwordInput.length() > 0) {
                    editor.putString("username", userInput);
                    editor.putString("password", passwordInput);
                    editor.putString("lastLoginTime", Calendar.getInstance().getTime().toString());
                    editor.putBoolean("firstLogin", false);
                    editor.commit();
                    finish();
                }
                else {
                    Toast.makeText(getApplicationContext(),
                            "Username/Password cannot remain empty!", Toast.LENGTH_LONG).show();
                }
                break;
        }
    }

    @Override
    public void onBackPressed() {
        setResult(RESULT_FAIL, intent);
        super.onBackPressed();
    }
}

Upvotes: 1

Views: 324

Answers (1)

kris larson
kris larson

Reputation: 30985

You defined protected static int RESULT_FAIL = -1;

... which is the same value as RESULT_OK.

So when your onActivityResult() runs, the condition resultCode == LoginActivity.RESULT_FAIL is true, so finish() is executed. Keep in mind, finish() just tells the system to end your activity; it doesn't pop a call stack like return, so execution continues.

Then because you coded if instead of else if, the next condition resultCode == RESULT_OK also evaluates as true, so your Toast is shown.

Then because you called finish() your Activity exits.

When you're defining result codes, you can use Activity.RESULT_FIRST_USER as the starting value; it's defined as 1.

Best way is to do something like this:

public static final int RESULT_FAIL = RESULT_FIRST_USER;
public static final int RESULT_OTHER = RESULT_FIRST_USER + 1;
public static final int RESULT_CRASH = RESULT_FIRST_USER + 2;

etc. etc.

I also use nested switch statements, outside for request code, inside for result code. Then I know only one block is going to execute... unless I forget a break statement. :)

Upvotes: 1

Related Questions