Several fixs and UI update
Fix fingerprint cancel button crash Update fingerprint dialog
This commit is contained in:
parent
55819c422e
commit
b7c2e57824
@ -21,6 +21,7 @@ import android.preference.Preference;
|
||||
import android.preference.PreferenceActivity;
|
||||
import android.preference.PreferenceFragment;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.preference.PreferenceScreen;
|
||||
import android.preference.RingtonePreference;
|
||||
import android.security.keystore.KeyGenParameterSpec;
|
||||
import android.security.keystore.KeyPermanentlyInvalidatedException;
|
||||
@ -65,14 +66,6 @@ import javax.crypto.SecretKey;
|
||||
*/
|
||||
public class SettingsActivity extends AppCompatPreferenceActivity {
|
||||
|
||||
private static final String KEY_NAME = "NAUKEY";
|
||||
private Cipher cipher;
|
||||
private KeyStore keyStore;
|
||||
private KeyGenerator keyGenerator;
|
||||
private FingerprintManager.CryptoObject cryptoObject;
|
||||
private FingerprintManager fingerprintManager;
|
||||
private KeyguardManager keyguardManager;
|
||||
|
||||
/**
|
||||
* A preference value change listener that updates the preference's summary
|
||||
* to reflect its new value.
|
||||
@ -140,6 +133,9 @@ public class SettingsActivity extends AppCompatPreferenceActivity {
|
||||
finish();
|
||||
return true;
|
||||
}
|
||||
|
||||
Log.d("coinfolio", "hello");
|
||||
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
@ -169,120 +165,6 @@ public class SettingsActivity extends AppCompatPreferenceActivity {
|
||||
super.onCreate(savedInstanceState);
|
||||
setupActionBar();
|
||||
|
||||
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
|
||||
|
||||
if(preferences.getBoolean("enable_fingerprint", false))
|
||||
{
|
||||
|
||||
FingerprintDialogFragment newFragment = FingerprintDialogFragment.newInstance();
|
||||
newFragment.setCancelable(false);
|
||||
newFragment.show(getFragmentManager(), "dialog");
|
||||
|
||||
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
|
||||
{
|
||||
keyguardManager = (KeyguardManager) getSystemService(KEYGUARD_SERVICE);
|
||||
fingerprintManager = (FingerprintManager) getSystemService(FINGERPRINT_SERVICE);
|
||||
|
||||
if(!fingerprintManager.isHardwareDetected())
|
||||
{
|
||||
findViewById(R.id.fingerprint_switch).setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
if(ActivityCompat.checkSelfPermission(this, Manifest.permission.USE_FINGERPRINT) != PackageManager.PERMISSION_GRANTED)
|
||||
{
|
||||
findViewById(R.id.fingerprint_switch).setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
if(!fingerprintManager.hasEnrolledFingerprints())
|
||||
{
|
||||
findViewById(R.id.fingerprint_switch).setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
if(!keyguardManager.isKeyguardSecure())
|
||||
{
|
||||
findViewById(R.id.fingerprint_switch).setVisibility(View.GONE);
|
||||
}
|
||||
else
|
||||
{
|
||||
try {
|
||||
generateKey();
|
||||
} catch (FingerprintException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
if(initCipher())
|
||||
{
|
||||
cryptoObject = new FingerprintManager.CryptoObject(cipher);
|
||||
|
||||
FingerprintHandler helper = new FingerprintHandler(this, newFragment);
|
||||
helper.startAuth(fingerprintManager, cryptoObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
Log.d("coinfolio", "Hello");
|
||||
}
|
||||
|
||||
private void generateKey() throws FingerprintException
|
||||
{
|
||||
try {
|
||||
keyStore = KeyStore.getInstance("AndroidKeyStore");
|
||||
keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES, "AndroidKeyStore");
|
||||
keyStore.load(null);
|
||||
keyGenerator.init(new KeyGenParameterSpec.Builder(KEY_NAME, KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
|
||||
.setBlockModes(KeyProperties.BLOCK_MODE_CBC)
|
||||
.setUserAuthenticationRequired(true)
|
||||
.setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_PKCS7)
|
||||
.build());
|
||||
|
||||
keyGenerator.generateKey();
|
||||
|
||||
} catch (KeyStoreException
|
||||
| NoSuchAlgorithmException
|
||||
| NoSuchProviderException
|
||||
| InvalidAlgorithmParameterException
|
||||
| CertificateException
|
||||
| IOException e) {
|
||||
e.printStackTrace();
|
||||
throw new FingerprintException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean initCipher()
|
||||
{
|
||||
try {
|
||||
cipher = Cipher.getInstance(
|
||||
KeyProperties.KEY_ALGORITHM_AES + "/"
|
||||
+ KeyProperties.BLOCK_MODE_CBC + "/"
|
||||
+ KeyProperties.ENCRYPTION_PADDING_PKCS7);
|
||||
} catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
|
||||
throw new RuntimeException("Failed to get Cipher", e);
|
||||
}
|
||||
|
||||
try {
|
||||
keyStore.load(null);
|
||||
SecretKey key = (SecretKey) keyStore.getKey(KEY_NAME, null);
|
||||
cipher.init(Cipher.ENCRYPT_MODE, key);
|
||||
return true;
|
||||
} catch (KeyPermanentlyInvalidatedException e) {
|
||||
return false;
|
||||
} catch (KeyStoreException | CertificateException
|
||||
| UnrecoverableKeyException | IOException
|
||||
| NoSuchAlgorithmException | InvalidKeyException e) {
|
||||
throw new RuntimeException("Failed to init Cipher", e);
|
||||
}
|
||||
}
|
||||
|
||||
private class FingerprintException extends Exception {
|
||||
public FingerprintException(Exception e)
|
||||
{
|
||||
super(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -358,6 +240,15 @@ public class SettingsActivity extends AppCompatPreferenceActivity {
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
|
||||
public static class ExchangePreferenceFragment extends PreferenceFragment {
|
||||
|
||||
private static final String KEY_NAME = "NAUKEY";
|
||||
private Cipher cipher;
|
||||
private KeyStore keyStore;
|
||||
private KeyGenerator keyGenerator;
|
||||
private FingerprintManager.CryptoObject cryptoObject;
|
||||
private FingerprintManager fingerprintManager;
|
||||
private KeyguardManager keyguardManager;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
@ -366,10 +257,12 @@ public class SettingsActivity extends AppCompatPreferenceActivity {
|
||||
setHasOptionsMenu(true);
|
||||
|
||||
bindPreferenceSummaryToValue(findPreference("hitbtc_publickey"));
|
||||
bindPreferenceSummaryToValue(findPreference("hitbtc_privatekey"));
|
||||
|
||||
bindPreferenceSummaryToValue(findPreference("binance_publickey"));
|
||||
|
||||
bindPreferenceSummaryToValue(findPreference("hitbtc_privatekey"));
|
||||
bindPreferenceSummaryToValue(findPreference("binance_privatekey"));
|
||||
|
||||
startFingerprintProtocol();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -381,6 +274,123 @@ public class SettingsActivity extends AppCompatPreferenceActivity {
|
||||
}
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
|
||||
private void startFingerprintProtocol()
|
||||
{
|
||||
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this.getContext());
|
||||
FingerprintDialogFragment newFragment = FingerprintDialogFragment.newInstance();
|
||||
|
||||
if(preferences.getBoolean("enable_fingerprint", false))
|
||||
{
|
||||
|
||||
newFragment.setCancelable(false);
|
||||
newFragment.show(getFragmentManager(), "dialog");
|
||||
|
||||
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
|
||||
{
|
||||
keyguardManager = (KeyguardManager) this.getActivity().getSystemService(KEYGUARD_SERVICE);
|
||||
fingerprintManager = (FingerprintManager) this.getActivity().getSystemService(FINGERPRINT_SERVICE);
|
||||
|
||||
try {
|
||||
if(!fingerprintManager.isHardwareDetected())
|
||||
{
|
||||
this.getActivity().findViewById(R.id.fingerprint_switch).setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
if(ActivityCompat.checkSelfPermission(this.getContext(), Manifest.permission.USE_FINGERPRINT) != PackageManager.PERMISSION_GRANTED)
|
||||
{
|
||||
this.getActivity().findViewById(R.id.fingerprint_switch).setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
if(!fingerprintManager.hasEnrolledFingerprints())
|
||||
{
|
||||
this.getActivity().findViewById(R.id.fingerprint_switch).setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
if(!keyguardManager.isKeyguardSecure())
|
||||
{
|
||||
this.getActivity().findViewById(R.id.fingerprint_switch).setVisibility(View.GONE);
|
||||
}
|
||||
else
|
||||
{
|
||||
try {
|
||||
generateKey();
|
||||
} catch (FingerprintException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
if(initCipher())
|
||||
{
|
||||
cryptoObject = new FingerprintManager.CryptoObject(cipher);
|
||||
|
||||
FingerprintHandler helper = new FingerprintHandler(this.getContext(), newFragment);
|
||||
helper.startAuth(fingerprintManager, cryptoObject);
|
||||
}
|
||||
}
|
||||
} catch (NullPointerException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void generateKey() throws FingerprintException
|
||||
{
|
||||
try {
|
||||
keyStore = KeyStore.getInstance("AndroidKeyStore");
|
||||
keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES, "AndroidKeyStore");
|
||||
keyStore.load(null);
|
||||
keyGenerator.init(new KeyGenParameterSpec.Builder(KEY_NAME, KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
|
||||
.setBlockModes(KeyProperties.BLOCK_MODE_CBC)
|
||||
.setUserAuthenticationRequired(true)
|
||||
.setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_PKCS7)
|
||||
.build());
|
||||
|
||||
keyGenerator.generateKey();
|
||||
|
||||
} catch (KeyStoreException
|
||||
| NoSuchAlgorithmException
|
||||
| NoSuchProviderException
|
||||
| InvalidAlgorithmParameterException
|
||||
| CertificateException
|
||||
| IOException e) {
|
||||
e.printStackTrace();
|
||||
throw new FingerprintException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean initCipher()
|
||||
{
|
||||
try {
|
||||
cipher = Cipher.getInstance(
|
||||
KeyProperties.KEY_ALGORITHM_AES + "/"
|
||||
+ KeyProperties.BLOCK_MODE_CBC + "/"
|
||||
+ KeyProperties.ENCRYPTION_PADDING_PKCS7);
|
||||
} catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
|
||||
throw new RuntimeException("Failed to get Cipher", e);
|
||||
}
|
||||
|
||||
try {
|
||||
keyStore.load(null);
|
||||
SecretKey key = (SecretKey) keyStore.getKey(KEY_NAME, null);
|
||||
cipher.init(Cipher.ENCRYPT_MODE, key);
|
||||
return true;
|
||||
} catch (KeyPermanentlyInvalidatedException e) {
|
||||
return false;
|
||||
} catch (KeyStoreException | CertificateException
|
||||
| UnrecoverableKeyException | IOException
|
||||
| NoSuchAlgorithmException | InvalidKeyException e) {
|
||||
throw new RuntimeException("Failed to init Cipher", e);
|
||||
}
|
||||
}
|
||||
|
||||
private class FingerprintException extends Exception {
|
||||
public FingerprintException(Exception e)
|
||||
{
|
||||
super(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -20,6 +20,8 @@ import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.animation.Animation;
|
||||
import android.widget.Button;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.mattprecious.swirl.SwirlView;
|
||||
import com.nauk.coinfolio.Activities.SettingsActivity;
|
||||
@ -42,11 +44,15 @@ public class FingerprintDialogFragment extends DialogFragment{
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
|
||||
{
|
||||
|
||||
View view = inflater.inflate(R.layout.fragment_fingerprint_scanner, container);
|
||||
|
||||
//getDialog().getWindow().setLayout(getResources().getDimensionPixelSize(R.dimen.fingerprint_dialog_width), getResources().getDimensionPixelSize(R.dimen.fingerprint_dialog_height));
|
||||
|
||||
((Button) view.findViewById(R.id.cancelButton)).setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
dismiss();
|
||||
getActivity().finish();
|
||||
}
|
||||
});
|
||||
@ -65,17 +71,20 @@ public class FingerprintDialogFragment extends DialogFragment{
|
||||
swirlView.setState(SwirlView.State.ON);
|
||||
}
|
||||
|
||||
public void wrongFingerprint()
|
||||
public void wrongFingerprint(String errorString)
|
||||
{
|
||||
((SwirlView) this.getView().findViewById(R.id.swirl)).clearColorFilter();
|
||||
((SwirlView) this.getView().findViewById(R.id.swirlBackground)).clearColorFilter();
|
||||
((SwirlView) this.getView().findViewById(R.id.swirl)).setState(SwirlView.State.ERROR);
|
||||
((SwirlView) this.getView().findViewById(R.id.swirlBackground)).setState(SwirlView.State.ERROR);
|
||||
|
||||
((TextView) this.getView().findViewById(R.id.fingerprint_error)).setText(errorString);
|
||||
}
|
||||
|
||||
public void resetFingerprint()
|
||||
{
|
||||
((SwirlView) this.getView().findViewById(R.id.swirlBackground)).setState(SwirlView.State.ON);
|
||||
((TextView) this.getView().findViewById(R.id.fingerprint_error)).setText("");
|
||||
SwirlView swirlView = this.getView().findViewById(R.id.swirl);
|
||||
|
||||
swirlView.clearColorFilter();
|
||||
|
@ -40,32 +40,58 @@ public class FingerprintHandler extends FingerprintManager.AuthenticationCallbac
|
||||
public void onAuthenticationError(int errMsgId, CharSequence errString)
|
||||
{
|
||||
//Toast.makeText(context, "Authentification error\n" + errString, Toast.LENGTH_LONG).show();
|
||||
dialogFragment.wrongFingerprint();
|
||||
if(dialogFragment.isVisible())
|
||||
{
|
||||
dialogFragment.wrongFingerprint("Error");
|
||||
new Handler().postDelayed(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if(dialogFragment.isVisible())
|
||||
{
|
||||
dialogFragment.resetFingerprint();
|
||||
}
|
||||
}
|
||||
}, 500);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAuthenticationFailed()
|
||||
{
|
||||
//Toast.makeText(context, "Authentification failed", Toast.LENGTH_LONG).show();
|
||||
dialogFragment.wrongFingerprint();
|
||||
if(dialogFragment.isVisible())
|
||||
{
|
||||
dialogFragment.wrongFingerprint("Wrong fingerprint");
|
||||
new Handler().postDelayed(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if(dialogFragment.isVisible())
|
||||
{
|
||||
dialogFragment.resetFingerprint();
|
||||
}
|
||||
}
|
||||
}, 500);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAuthenticationHelp(int helpMsgIf, CharSequence helpString)
|
||||
{
|
||||
Toast.makeText(context, "Authentification help\n" + helpString, Toast.LENGTH_LONG).show();
|
||||
//Toast.makeText(context, "Authentification help\n" + helpString, Toast.LENGTH_LONG).show();
|
||||
|
||||
if(dialogFragment.isVisible())
|
||||
{
|
||||
dialogFragment.wrongFingerprint(helpString.toString());
|
||||
new Handler().postDelayed(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if(dialogFragment.isVisible())
|
||||
{
|
||||
dialogFragment.resetFingerprint();
|
||||
}
|
||||
}
|
||||
}, 500);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1,18 +1,24 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<RelativeLayout 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:id="@+id/edit_name"
|
||||
android:layout_width="250dp"
|
||||
android:layout_height="125dp"
|
||||
android:layout_gravity="center"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="center">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="@dimen/fingerprint_dialog_width"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/fingerprint_textview"
|
||||
android:text="@string/pref_fingerprint"
|
||||
android:text="@string/fingerprint_dialog_title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
android:layout_height="wrap_content"
|
||||
android:textStyle="bold"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_margin="@dimen/mainText"/>
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="wrap_content"
|
||||
@ -33,12 +39,33 @@
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="50dp"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="end">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/fingerprint_error"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="0.5"
|
||||
android:gravity="center"
|
||||
android:textColor="@color/red"
|
||||
android:layout_margin="5dp"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/cancelButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:text="@string/fingerprint_dialog_cancel"
|
||||
style="?android:attr/borderlessButtonStyle"
|
||||
android:layout_gravity="end"/>
|
||||
android:layout_alignParentEnd="true"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</RelativeLayout>
|
@ -13,4 +13,6 @@
|
||||
<dimen name="activity_vertical_margin">16dp</dimen>
|
||||
|
||||
<dimen name="swirl_size">60dp</dimen>
|
||||
<dimen name="fingerprint_dialog_height">125dp</dimen>
|
||||
<dimen name="fingerprint_dialog_width">250dp</dimen>
|
||||
</resources>
|
||||
|
@ -147,5 +147,6 @@
|
||||
<string name="title_activity_main">MainActivity</string>
|
||||
|
||||
<string name="fingerprint_dialog_cancel">Cancel</string>
|
||||
<string name="fingerprint_dialog_title">Verify your fingerprint to continue</string>
|
||||
|
||||
</resources>
|
||||
|
@ -1,5 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:key="exchange">
|
||||
|
||||
<SwitchPreference
|
||||
android:id="@+id/fingerprint_switch"
|
||||
|
Loading…
Reference in New Issue
Block a user