-2

I would like to create an app in Android that checks if the input password is wrong or not.

The user has 5 attempts. Once the user runs out of attempts, the app locks itself for 5 minutes. Once the 5 minutes timeout expires, the app restores the 5 attempts and allows the user to login again.

I've created a onSaveInstanceState method to store the outcome of the latest attempts. When reopening the app, the onRestoreInstanceState method reloads the attempts while the checkLoginCount method checks if the attempts are equal or less than 0 and in that case blocks the app with the BlockLogin method.

However, there's a problem after the app is killed as it locks itself at every reopening, even though the user did not input an incorrect password. It seems like that the latest attempts cannot be saved after killing the app, but I don't know where is the problem.

    public class LoginActivity extends AppCompatActivity {
    EditText editText_enterLockCode;
    Button button_Login;

    String LockCode;
    int counter;
    CountDownTimer Timer = null;

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

        // load the lock code
        SharedPreferences PIN = getSharedPreferences("pin", 0);
        LockCode = PIN.getString("LockCode", "");

        editText_enterLockCode = (EditText) findViewById(R.id.enterLockCode);
        button_Login = (Button) findViewById(R.id.button_Login);

        // check the latest login attempt
        checkLoginCount();

        // the user have 5 times of chance to login
        counter = 5;

        button_Login.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                String text = editText_enterLockCode.getText().toString();

                // If login success
                if (text.equals(LockCode)) {
                    // set the number of attempts to 5 times
                    counter=5;
                    // Go to the main page
                    Intent intent = new Intent(getApplicationContext(), MainActivity.class);
                    startActivity(intent);
                    finish();
                } else {
                    // Decrease 1 time of login attempts
                    counter--;
                    Toast.makeText(LoginActivity.this, "Invalid login, No of attempts remaining: " + String.valueOf(counter), Toast.LENGTH_SHORT).show();
                    if(counter <= 0){
                        // lock the login button
                        BlockLogin();
                        Toast.makeText(LoginActivity.this, "The login was blocked for 5 minutes", Toast.LENGTH_SHORT).show();
                        Timer.start();
                    }
                }
            }
        });
    }

    public void checkLoginCount(){
        if(counter <= 0){
            // lock the login button
            BlockLogin();
        } else if (counter > 0){
            Toast.makeText(LoginActivity.this, "Please login", Toast.LENGTH_SHORT).show();
        }
    }

    public void BlockLogin(){
        button_Login.setEnabled(false);
        // Start to count 5 minutes for disable the login button
        Timer = new CountDownTimer(300000, 1000) {
            public void onTick(long millisUntilFinished) {
                counter=5;
            }
            public void onFinish() {
                // enable the login button after finish counting
                button_Login.setEnabled(true);
                counter=5;
            }
        };
        Toast.makeText(LoginActivity.this, "The login was blocked for 5 minutes", Toast.LENGTH_SHORT).show();
        Timer.start();
    }

    @Override
    protected void onSaveInstanceState (@NonNull Bundle outState) {
        // store the latest attempts if the app was killed
        outState.putInt("counter_value",counter);
        super.onSaveInstanceState(outState);
    }

    @Override
    protected void onRestoreInstanceState(@NonNull Bundle bluetoothgram) {
        // load the latest attempts when the app open again
        counter=bluetoothgram.getInt("counter_value");
        super.onRestoreInstanceState(bluetoothgram);
    }
}
Dan
  • 3,647
  • 5
  • 20
  • 26
Mark
  • 1
  • 2

1 Answers1

0

What do to mean by app is killed?

Please note that onSaveInstanceState os not always called by OS https://stackoverflow.com/a/12793395/2401535

And also, if you try to login, then it's some kind of server operation. Take login attempts number from server.

Also, if you really must store It on front-end, use persistent storage.

Marian Paździoch
  • 8,813
  • 10
  • 58
  • 103