/* * The MIT License (MIT) * * Copyright � 2013 Clover Studio Ltd. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ package com.cloverstudio.spikademo; import java.util.ArrayList; import java.util.List; import android.app.Activity; import android.os.Bundle; import android.view.KeyEvent; import android.view.View; import android.view.ViewGroup; import android.view.View.OnClickListener; import android.view.animation.AlphaAnimation; import android.view.animation.Animation; import android.view.animation.Animation.AnimationListener; import android.widget.Button; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.RelativeLayout; import android.widget.TableLayout; import android.widget.TextView; import android.widget.Toast; import com.cloverstudio.spikademo.R; import com.cloverstudio.spikademo.utils.Logger; /** * PasscodeActivity * * Shows passcode interface allowing user to type new passcode or change existing one. */ public class PasscodeActivity extends Activity { private TextView mTvPasscode; private Button mBtnDelete; private ImageView mPasscode1; private ImageView mPasscode2; private ImageView mPasscode3; private ImageView mPasscode4; private Button mBtnPasscodeOk; private RelativeLayout mRlPasscodeResult; private TextView mTvPasscodeResult; private InputState mInputState; private PasscodeState mPasscodeState; private String mTargetPasscode = ""; private String mTypedPasscode = ""; private final AlphaAnimation mFadeIn = new AlphaAnimation(0F, 1.0F); private final AlphaAnimation mFadeOut = new AlphaAnimation(1.0F, 0F); private TableLayout mTlPasscodeKeyboard; private List<Button> mKeyboardButtons; private boolean mIsProtect; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_passcode); if (getIntent().getBooleanExtra("protect", false) == true) { mIsProtect = true; } else { mIsProtect = false; } mRlPasscodeResult = (RelativeLayout) findViewById(R.id.rlPasscodeResult); mRlPasscodeResult.setVisibility(View.GONE); mTvPasscodeResult = (TextView) findViewById(R.id.tvPasscodeResult); mTvPasscode = (TextView) findViewById(R.id.tvPasscode); mBtnDelete = (Button) findViewById(R.id.btnDelete); mPasscode1 = (ImageView) findViewById(R.id.passcode1); mPasscode2 = (ImageView) findViewById(R.id.passcode2); mPasscode3 = (ImageView) findViewById(R.id.passcode3); mPasscode4 = (ImageView) findViewById(R.id.passcode4); setInput(InputState.NONE); mBtnDelete.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { deleteInput(); } }); mTlPasscodeKeyboard = (TableLayout) findViewById(R.id.tlPasscodeKeyboard); mKeyboardButtons = new ArrayList<Button>(); for (View view : mTlPasscodeKeyboard.getTouchables()) { if (view instanceof Button) { mKeyboardButtons.add((Button) view); ((Button) view).setOnClickListener(getKeyboardListener()); } } mBtnPasscodeOk = (Button) findViewById(R.id.btnPasscodeOk); mBtnPasscodeOk.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { checkPasscode(); } }); getPasscodeFromPreferences(); } @Override protected void onDestroy() { unbindDrawables(findViewById(R.id.rlPasscodeResult)); mKeyboardButtons.clear(); mKeyboardButtons = null; mTlPasscodeKeyboard = null; super.onDestroy(); } private void unbindDrawables(View view) { if (view.getBackground() != null) { view.getBackground().setCallback(null); } if (view instanceof ViewGroup) { for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) { unbindDrawables(((ViewGroup) view).getChildAt(i)); } ((ViewGroup) view).removeAllViews(); } } private void getPasscodeFromPreferences() { String savedPasscode = SpikaApp.getPreferences().getPasscode(); if (savedPasscode.equals(null) || savedPasscode.equals("")) { mPasscodeState = PasscodeState.NEW_PASSCODE; mTvPasscode.setText(getString(R.string.please_enter_new_passcode)); } else { mPasscodeState = PasscodeState.CURRENT_PASSCODE; mTvPasscode.setText(getString(R.string.please_enter_passcode)); mTargetPasscode = savedPasscode; } } private OnClickListener getKeyboardListener() { return new OnClickListener() { @Override public void onClick(View v) { switch (mInputState) { case NONE: setInput(InputState.ONE); break; case ONE: setInput(InputState.TWO); break; case TWO: setInput(InputState.THREE); break; case THREE: setInput(InputState.ALL); break; case ALL: return; default: break; } switch (v.getId()) { case R.id.btn1: mTypedPasscode += "1"; break; case R.id.btn2: mTypedPasscode += "2"; break; case R.id.btn3: mTypedPasscode += "3"; break; case R.id.btn4: mTypedPasscode += "4"; break; case R.id.btn5: mTypedPasscode += "5"; break; case R.id.btn6: mTypedPasscode += "6"; break; case R.id.btn7: mTypedPasscode += "7"; break; case R.id.btn8: mTypedPasscode += "8"; break; case R.id.btn9: mTypedPasscode += "9"; break; case R.id.btn0: mTypedPasscode += "0"; break; default: break; } } }; } private void deleteInput() { switch (mInputState) { case NONE: break; case ONE: mTypedPasscode = ""; setInput(InputState.NONE); break; case TWO: setInput(InputState.ONE); mTypedPasscode = mTypedPasscode.substring(0, mTypedPasscode.length() - 1); break; case THREE: setInput(InputState.TWO); mTypedPasscode = mTypedPasscode.substring(0, mTypedPasscode.length() - 1); break; case ALL: setInput(InputState.THREE); mTypedPasscode = mTypedPasscode.substring(0, mTypedPasscode.length() - 1); break; default: break; } } private void setInput(InputState state) { mInputState = state; switch (state) { case NONE: mPasscode1.setImageResource(R.drawable.circle_shape_neutral); mPasscode2.setImageResource(R.drawable.circle_shape_neutral); mPasscode3.setImageResource(R.drawable.circle_shape_neutral); mPasscode4.setImageResource(R.drawable.circle_shape_neutral); break; case ONE: mPasscode1.setImageResource(R.drawable.circle_shape_alert); mPasscode2.setImageResource(R.drawable.circle_shape_neutral); mPasscode3.setImageResource(R.drawable.circle_shape_neutral); mPasscode4.setImageResource(R.drawable.circle_shape_neutral); break; case TWO: mPasscode1.setImageResource(R.drawable.circle_shape_alert); mPasscode2.setImageResource(R.drawable.circle_shape_alert); mPasscode3.setImageResource(R.drawable.circle_shape_neutral); mPasscode4.setImageResource(R.drawable.circle_shape_neutral); break; case THREE: mPasscode1.setImageResource(R.drawable.circle_shape_alert); mPasscode2.setImageResource(R.drawable.circle_shape_alert); mPasscode3.setImageResource(R.drawable.circle_shape_alert); mPasscode4.setImageResource(R.drawable.circle_shape_neutral); break; case ALL: mPasscode1.setImageResource(R.drawable.circle_shape_alert); mPasscode2.setImageResource(R.drawable.circle_shape_alert); mPasscode3.setImageResource(R.drawable.circle_shape_alert); mPasscode4.setImageResource(R.drawable.circle_shape_alert); break; case SUCCESS: animateResultForSuccess(true); break; case FAIL: animateResultForSuccess(false); break; } } private void checkPasscode() { if (mInputState == InputState.ALL) { switch (mPasscodeState) { case CURRENT_PASSCODE: if (mTypedPasscode.equals(mTargetPasscode)) { setInput(InputState.SUCCESS); } else { setInput(InputState.FAIL); } break; case NEW_PASSCODE: setInput(InputState.NONE); mTargetPasscode = mTypedPasscode; mTypedPasscode = ""; mPasscodeState = PasscodeState.NEW_PASSCODE_REPEAT; mTvPasscode .setText(getString(R.string.please_enter_new_passcode_again)); break; case NEW_PASSCODE_REPEAT: if (mTypedPasscode.equals(mTargetPasscode)) { SpikaApp.getPreferences().setPasscode(mTypedPasscode); setInput(InputState.SUCCESS); } else { setInput(InputState.FAIL); mTargetPasscode = ""; mPasscodeState = PasscodeState.NEW_PASSCODE; mTvPasscode .setText(getString(R.string.please_enter_new_passcode)); } break; default: break; } } } private void animateResultForSuccess(final boolean isSuccess) { if (isSuccess) { mRlPasscodeResult.setBackgroundResource(R.color.hookup_positive); mTvPasscodeResult.setText(getString(R.string.SUCCESS)); } else { mRlPasscodeResult.setBackgroundResource(R.color.hookup_alert); mTvPasscodeResult.setText(getString(R.string.FAIL)); } setInput(InputState.NONE); mTypedPasscode = ""; mFadeIn.setFillAfter(false); mFadeIn.setFillEnabled(false); mFadeIn.setDuration(getResources().getInteger( android.R.integer.config_longAnimTime)); mFadeIn.setAnimationListener(new AnimationListener() { public void onAnimationStart(Animation animation) { mRlPasscodeResult.setVisibility(View.VISIBLE); for (Button button : mKeyboardButtons) { button.setEnabled(false); } } public void onAnimationRepeat(Animation animation) { } public void onAnimationEnd(Animation animation) { mRlPasscodeResult.startAnimation(mFadeOut); } }); mFadeOut.setStartOffset(800); mFadeOut.setDuration(getResources().getInteger( android.R.integer.config_longAnimTime)); mFadeOut.setAnimationListener(new AnimationListener() { public void onAnimationStart(Animation animation) { if (isSuccess) { setResult(Activity.RESULT_OK); finish(); } } public void onAnimationRepeat(Animation animation) { } public void onAnimationEnd(Animation animation) { mRlPasscodeResult.setVisibility(View.INVISIBLE); for (Button button : mKeyboardButtons) { button.setEnabled(true); } } }); mRlPasscodeResult.startAnimation(mFadeIn); } @Override public void onBackPressed() { if (mInputState != InputState.NONE || mIsProtect) { deleteInput(); } else { setResult(Activity.RESULT_CANCELED); finish(); } } @Override public boolean onKeyDown(int keyCode, KeyEvent event) { if ((keyCode == KeyEvent.KEYCODE_BACK)) { if (mInputState != InputState.NONE || mIsProtect) { deleteInput(); return true; } } setResult(Activity.RESULT_CANCELED); return super.onKeyDown(keyCode, event); } private enum InputState { NONE, ONE, TWO, THREE, ALL, FAIL, SUCCESS } private enum PasscodeState { NEW_PASSCODE, NEW_PASSCODE_REPEAT, CURRENT_PASSCODE } }