- Pattern Lock Setting added
This commit is contained in:
parent
2f37534bc2
commit
6598d4aacb
13 changed files with 401 additions and 13 deletions
|
@ -68,4 +68,5 @@ dependencies {
|
|||
implementation 'com.github.esafirm.android-image-picker:imagepicker:1.11.1'
|
||||
compile 'id.zelory:compressor:2.1.0'
|
||||
compile 'com.vincent.filepicker:MultiTypeFilePicker:1.0.7'
|
||||
compile 'com.andrognito.patternlockview:patternlockview:1.0.0'
|
||||
}
|
||||
|
|
|
@ -47,6 +47,9 @@
|
|||
<activity android:name=".activities.PinRequestActivity"
|
||||
android:noHistory="true">
|
||||
</activity>
|
||||
<activity android:name=".activities.PatternRequestActivity"
|
||||
android:noHistory="true">
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".activities.SettingsActivity"
|
||||
android:theme="@style/AppTheme.NoActionBar"
|
||||
|
|
|
@ -0,0 +1,103 @@
|
|||
package cy.agorise.crystalwallet.activities;
|
||||
|
||||
import android.arch.lifecycle.LiveData;
|
||||
import android.arch.lifecycle.Observer;
|
||||
import android.arch.lifecycle.ViewModelProviders;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.text.Editable;
|
||||
import android.widget.EditText;
|
||||
|
||||
import com.andrognito.patternlockview.PatternLockView;
|
||||
import com.andrognito.patternlockview.listener.PatternLockViewListener;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.OnTextChanged;
|
||||
import cy.agorise.crystalwallet.R;
|
||||
import cy.agorise.crystalwallet.models.GeneralSetting;
|
||||
import cy.agorise.crystalwallet.util.PasswordManager;
|
||||
import cy.agorise.crystalwallet.viewmodels.GeneralSettingListViewModel;
|
||||
|
||||
public class PatternRequestActivity extends AppCompatActivity {
|
||||
private String patternEncrypted;
|
||||
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
//Do nothing to prevent the user to use the back button
|
||||
}
|
||||
|
||||
@BindView(R.id.patternLockView)
|
||||
PatternLockView patternLockView;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_pattern_request);
|
||||
ButterKnife.bind(this);
|
||||
|
||||
GeneralSettingListViewModel generalSettingListViewModel = ViewModelProviders.of(this).get(GeneralSettingListViewModel.class);
|
||||
LiveData<List<GeneralSetting>> generalSettingsLiveData = generalSettingListViewModel.getGeneralSettingList();
|
||||
|
||||
final PatternRequestActivity thisActivity = this;
|
||||
|
||||
generalSettingsLiveData.observe(this, new Observer<List<GeneralSetting>>() {
|
||||
@Override
|
||||
public void onChanged(@Nullable List<GeneralSetting> generalSettings) {
|
||||
patternEncrypted = "";
|
||||
|
||||
if (generalSettings != null){
|
||||
for (GeneralSetting generalSetting:generalSettings) {
|
||||
if (generalSetting.getName().equals(GeneralSetting.SETTING_PATTERN)){
|
||||
if (!generalSetting.getValue().isEmpty()){
|
||||
patternEncrypted = generalSetting.getValue();
|
||||
|
||||
patternLockView.addPatternLockListener(new PatternLockViewListener() {
|
||||
@Override
|
||||
public void onStarted() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onProgress(List<PatternLockView.Dot> progressPattern) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onComplete(List<PatternLockView.Dot> pattern) {
|
||||
if (PasswordManager.checkPassword(patternEncrypted,patternToString(pattern))){
|
||||
thisActivity.finish();
|
||||
} else {
|
||||
patternLockView.clearPattern();
|
||||
patternLockView.requestFocus();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCleared() {
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public String patternToString(List<PatternLockView.Dot> pattern){
|
||||
String patternString = "";
|
||||
for (PatternLockView.Dot nextDot : pattern){
|
||||
patternString = patternString+(nextDot.getRow()*3+nextDot.getColumn());
|
||||
}
|
||||
|
||||
return patternString;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -100,8 +100,8 @@ public class SettingsActivity extends AppCompatActivity{
|
|||
return new SecuritySettingsFragment();
|
||||
case 2:
|
||||
return new BackupsSettingsFragment();
|
||||
case 3:
|
||||
return new AccountsSettingsFragment();
|
||||
//case 3:
|
||||
// return new AccountsSettingsFragment();
|
||||
}
|
||||
|
||||
|
||||
|
@ -110,7 +110,7 @@ public class SettingsActivity extends AppCompatActivity{
|
|||
|
||||
@Override
|
||||
public int getCount() {
|
||||
return 4;
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@ import android.support.v4.app.FragmentActivity;
|
|||
|
||||
import java.util.List;
|
||||
|
||||
import cy.agorise.crystalwallet.activities.PatternRequestActivity;
|
||||
import cy.agorise.crystalwallet.activities.PinRequestActivity;
|
||||
import cy.agorise.crystalwallet.models.GeneralSetting;
|
||||
import cy.agorise.crystalwallet.viewmodels.GeneralSettingListViewModel;
|
||||
|
@ -24,6 +25,7 @@ import cy.agorise.crystalwallet.viewmodels.GeneralSettingListViewModel;
|
|||
public class CrystalSecurityMonitor implements Application.ActivityLifecycleCallbacks {
|
||||
private int numStarted = 0;
|
||||
private String passwordEncrypted;
|
||||
private String patternEncrypted;
|
||||
|
||||
public CrystalSecurityMonitor(final FragmentActivity fragmentActivity){
|
||||
GeneralSettingListViewModel generalSettingListViewModel = ViewModelProviders.of(fragmentActivity).get(GeneralSettingListViewModel.class);
|
||||
|
@ -38,12 +40,17 @@ public class CrystalSecurityMonitor implements Application.ActivityLifecycleCall
|
|||
if (generalSettings != null){
|
||||
for (GeneralSetting generalSetting:generalSettings) {
|
||||
if (generalSetting.getName().equals(GeneralSetting.SETTING_PASSWORD)){
|
||||
founded = true;
|
||||
if (!generalSetting.getValue().isEmpty()){
|
||||
passwordEncrypted = generalSetting.getValue();
|
||||
callPasswordRequest(fragmentActivity);
|
||||
}
|
||||
break;
|
||||
} else if (generalSetting.getName().equals(GeneralSetting.SETTING_PATTERN)){
|
||||
if (!generalSetting.getValue().isEmpty()){
|
||||
patternEncrypted = generalSetting.getValue();
|
||||
callPasswordRequest(fragmentActivity);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -54,7 +61,10 @@ public class CrystalSecurityMonitor implements Application.ActivityLifecycleCall
|
|||
@Override
|
||||
public void onActivityStarted(Activity activity) {
|
||||
if (numStarted == 0) {
|
||||
if ((this.passwordEncrypted != null) && (!this.passwordEncrypted.equals(""))) {
|
||||
if (
|
||||
((this.passwordEncrypted != null) && (!this.passwordEncrypted.equals("")))
|
||||
|| ((this.patternEncrypted != null) && (!this.patternEncrypted.equals("")))
|
||||
) {
|
||||
callPasswordRequest(activity);
|
||||
}
|
||||
}
|
||||
|
@ -65,7 +75,10 @@ public class CrystalSecurityMonitor implements Application.ActivityLifecycleCall
|
|||
public void onActivityStopped(Activity activity) {
|
||||
numStarted--;
|
||||
if (numStarted == 0) {
|
||||
if ((this.passwordEncrypted != null) && (!this.passwordEncrypted.equals(""))) {
|
||||
if (
|
||||
((this.passwordEncrypted != null) && (!this.passwordEncrypted.equals("")))
|
||||
|| ((this.patternEncrypted != null) && (!this.patternEncrypted.equals("")))
|
||||
) {
|
||||
callPasswordRequest(activity);
|
||||
}
|
||||
}
|
||||
|
@ -73,11 +86,18 @@ public class CrystalSecurityMonitor implements Application.ActivityLifecycleCall
|
|||
|
||||
public void callPasswordRequest(Activity activity){
|
||||
if ((!activity.getIntent().hasExtra("ACTIVITY_TYPE")) || (!activity.getIntent().getStringExtra("ACTIVITY_TYPE").equals("PASSWORD_REQUEST"))) {
|
||||
Intent intent = new Intent(activity, PinRequestActivity.class);
|
||||
Intent intent = null;
|
||||
if ((this.passwordEncrypted != null) && (!this.passwordEncrypted.equals(""))) {
|
||||
intent = new Intent(activity, PinRequestActivity.class);
|
||||
} else if ((this.patternEncrypted != null) && (!this.patternEncrypted.equals(""))) {
|
||||
intent = new Intent(activity, PatternRequestActivity.class);
|
||||
}
|
||||
if (intent != null) {
|
||||
intent.putExtra("ACTIVITY_TYPE", "PASSWORD_REQUEST");
|
||||
activity.startActivity(intent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityCreated(Activity activity, Bundle bundle) {
|
||||
|
|
|
@ -0,0 +1,223 @@
|
|||
package cy.agorise.crystalwallet.fragments;
|
||||
|
||||
import android.arch.lifecycle.LiveData;
|
||||
import android.arch.lifecycle.Observer;
|
||||
import android.arch.lifecycle.ViewModelProviders;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.text.Editable;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.EditText;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.andrognito.patternlockview.PatternLockView;
|
||||
import com.andrognito.patternlockview.listener.PatternLockViewListener;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.OnTextChanged;
|
||||
import cy.agorise.crystalwallet.R;
|
||||
import cy.agorise.crystalwallet.models.GeneralSetting;
|
||||
import cy.agorise.crystalwallet.util.PasswordManager;
|
||||
import cy.agorise.crystalwallet.viewmodels.GeneralSettingListViewModel;
|
||||
import cy.agorise.crystalwallet.viewmodels.validators.PinSecurityValidator;
|
||||
import cy.agorise.crystalwallet.viewmodels.validators.UIValidatorListener;
|
||||
import cy.agorise.crystalwallet.viewmodels.validators.validationfields.ValidationField;
|
||||
|
||||
/**
|
||||
* Created by xd on 1/18/18.
|
||||
*/
|
||||
|
||||
public class PatternSecurityFragment extends Fragment {
|
||||
|
||||
GeneralSettingListViewModel generalSettingListViewModel;
|
||||
GeneralSetting patternGeneralSetting;
|
||||
//PatternSecurityValidator patternSecurityValidator;
|
||||
|
||||
@BindView(R.id.patternLockView)
|
||||
PatternLockView patternLockView;
|
||||
@BindView(R.id.tvPatternText)
|
||||
TextView tvPatternText;
|
||||
|
||||
private PatternLockViewListener actualPatternListener;
|
||||
private String patternEntered;
|
||||
|
||||
public PatternSecurityFragment() {
|
||||
// Required empty public constructor
|
||||
}
|
||||
|
||||
public static PatternSecurityFragment newInstance() {
|
||||
PatternSecurityFragment fragment = new PatternSecurityFragment();
|
||||
Bundle args = new Bundle();
|
||||
fragment.setArguments(args);
|
||||
return fragment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
// Inflate the layout for this fragment
|
||||
View v = inflater.inflate(R.layout.fragment_pattern_security, container, false);
|
||||
ButterKnife.bind(this, v);
|
||||
|
||||
generalSettingListViewModel = ViewModelProviders.of(this).get(GeneralSettingListViewModel.class);
|
||||
LiveData<List<GeneralSetting>> generalSettingsLiveData = generalSettingListViewModel.getGeneralSettingList();
|
||||
|
||||
generalSettingsLiveData.observe(this, new Observer<List<GeneralSetting>>() {
|
||||
@Override
|
||||
public void onChanged(@Nullable List<GeneralSetting> generalSettings) {
|
||||
boolean founded = false;
|
||||
|
||||
if (generalSettings != null){
|
||||
for (GeneralSetting generalSetting:generalSettings) {
|
||||
if (generalSetting.getName().equals(GeneralSetting.SETTING_PATTERN)){
|
||||
founded = true;
|
||||
if (!generalSetting.getValue().isEmpty()){
|
||||
patternGeneralSetting = generalSetting;
|
||||
showEnterPatternUI();
|
||||
} else {
|
||||
showNewPatternUI();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!founded){
|
||||
showNewPatternUI();
|
||||
}
|
||||
} else {
|
||||
showNewPatternUI();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
public String patternToString(List<PatternLockView.Dot> pattern){
|
||||
String patternString = "";
|
||||
for (PatternLockView.Dot nextDot : pattern){
|
||||
patternString = patternString+(nextDot.getRow()*3+nextDot.getColumn());
|
||||
}
|
||||
|
||||
return patternString;
|
||||
}
|
||||
|
||||
public void removePatternListener(){
|
||||
if (actualPatternListener != null){
|
||||
patternLockView.removePatternLockListener(actualPatternListener);
|
||||
actualPatternListener = null;
|
||||
}
|
||||
}
|
||||
|
||||
public void showNewPatternUI(){
|
||||
removePatternListener();
|
||||
patternLockView.clearPattern();
|
||||
tvPatternText.setText("Enter new pattern");
|
||||
|
||||
actualPatternListener = new PatternLockViewListener() {
|
||||
@Override
|
||||
public void onStarted() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onProgress(List<PatternLockView.Dot> progressPattern) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onComplete(List<PatternLockView.Dot> pattern) {
|
||||
patternEntered = patternToString(pattern);
|
||||
showConfirmPatternUI();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCleared() {
|
||||
|
||||
}
|
||||
};
|
||||
patternLockView.addPatternLockListener(actualPatternListener);
|
||||
}
|
||||
|
||||
public void showConfirmPatternUI(){
|
||||
removePatternListener();
|
||||
patternLockView.clearPattern();
|
||||
patternLockView.requestFocus();
|
||||
tvPatternText.setText("Confirm new pattern");
|
||||
|
||||
actualPatternListener = new PatternLockViewListener() {
|
||||
@Override
|
||||
public void onStarted() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onProgress(List<PatternLockView.Dot> progressPattern) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onComplete(List<PatternLockView.Dot> pattern) {
|
||||
if (patternEntered.equals(patternToString(pattern))){
|
||||
savePattern(patternEntered);
|
||||
showEnterPatternUI();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCleared() {
|
||||
|
||||
}
|
||||
};
|
||||
patternLockView.addPatternLockListener(actualPatternListener);
|
||||
}
|
||||
|
||||
public void savePattern(String pattern){
|
||||
String patternEncripted = PasswordManager.encriptPassword(pattern);
|
||||
|
||||
if (patternGeneralSetting == null) {
|
||||
patternGeneralSetting = new GeneralSetting();
|
||||
patternGeneralSetting.setName(GeneralSetting.SETTING_PATTERN);
|
||||
}
|
||||
|
||||
patternGeneralSetting.setValue(patternEncripted);
|
||||
generalSettingListViewModel.saveGeneralSetting(patternGeneralSetting);
|
||||
}
|
||||
|
||||
public void showEnterPatternUI(){
|
||||
removePatternListener();
|
||||
patternLockView.clearPattern();
|
||||
tvPatternText.setText("Enter old pattern");
|
||||
|
||||
actualPatternListener = new PatternLockViewListener() {
|
||||
@Override
|
||||
public void onStarted() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onProgress(List<PatternLockView.Dot> progressPattern) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onComplete(List<PatternLockView.Dot> pattern) {
|
||||
if (PasswordManager.checkPassword(patternGeneralSetting.getValue(),patternToString(pattern))){
|
||||
showNewPatternUI();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCleared() {
|
||||
|
||||
}
|
||||
};
|
||||
patternLockView.addPatternLockListener(actualPatternListener);
|
||||
}
|
||||
}
|
|
@ -69,7 +69,7 @@ public class SecuritySettingsFragment extends Fragment {
|
|||
case 1:
|
||||
return new PinSecurityFragment();
|
||||
case 2:
|
||||
return new BackupsSettingsFragment();
|
||||
return new PatternSecurityFragment();
|
||||
}
|
||||
|
||||
return null; //new OnConstructionFragment();
|
||||
|
|
|
@ -20,6 +20,7 @@ public class GeneralSetting {
|
|||
public final static String SETTING_NAME_PREFERRED_LANGUAGE = "PREFERRED_LANGUAGE";
|
||||
public final static String SETTING_NAME_TIME_ZONE = "TIME_ZONE";
|
||||
public final static String SETTING_PASSWORD = "PASSWORD";
|
||||
public final static String SETTING_PATTERN = "PATTERN";
|
||||
public final static String SETTING_NAME_RECEIVED_FUNDS_SOUND_PATH = "RECEIVED_FUNDS_SOUND_PATH";
|
||||
|
||||
/**
|
||||
|
|
|
@ -31,7 +31,7 @@ public class GeneralSettingListViewModel extends AndroidViewModel {
|
|||
}
|
||||
|
||||
public void saveGeneralSetting(GeneralSetting generalSetting){
|
||||
this.db.generalSettingDao().insertGeneralSetting(generalSetting);
|
||||
this.db.generalSettingDao ().insertGeneralSetting(generalSetting);
|
||||
}
|
||||
|
||||
public void saveGeneralSettings(GeneralSetting... generalSettings){
|
||||
|
|
18
app/src/main/res/layout/activity_pattern_request.xml
Normal file
18
app/src/main/res/layout/activity_pattern_request.xml
Normal file
|
@ -0,0 +1,18 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:gravity="center"
|
||||
android:padding="5dp"
|
||||
android:background="@color/colorPrimary">
|
||||
<com.andrognito.patternlockview.PatternLockView
|
||||
android:id="@+id/patternLockView"
|
||||
android:layout_width="280dp"
|
||||
android:layout_height="280dp" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
|
@ -104,11 +104,12 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:text="@string/backups" />
|
||||
|
||||
<android.support.design.widget.TabItem
|
||||
<!--<android.support.design.widget.TabItem
|
||||
android:id="@+id/tabItem4"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/accounts" />
|
||||
android:text="@string/accounts"
|
||||
android:visibility="gone" />-->
|
||||
|
||||
</android.support.design.widget.TabLayout>
|
||||
|
||||
|
|
17
app/src/main/res/layout/fragment_pattern_security.xml
Normal file
17
app/src/main/res/layout/fragment_pattern_security.xml
Normal file
|
@ -0,0 +1,17 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<android.support.constraint.ConstraintLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvPatternText"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
<com.andrognito.patternlockview.PatternLockView
|
||||
android:id="@+id/patternLockView"
|
||||
android:layout_width="280dp"
|
||||
android:layout_height="280dp"/>
|
||||
</android.support.constraint.ConstraintLayout>
|
|
@ -68,6 +68,7 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="140dp"
|
||||
android:background="@color/lightGray"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
|
|
Loading…
Reference in a new issue