mirror of https://github.com/beemdevelopment/Aegis
Add a new activity that allows editing key profiles
parent
05cfc0bc5f
commit
07c3e43160
@ -0,0 +1,220 @@
|
||||
package me.impy.aegis;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.support.v7.app.ActionBar;
|
||||
import android.support.v7.app.AlertDialog;
|
||||
import android.text.Editable;
|
||||
import android.text.TextWatcher;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.Spinner;
|
||||
|
||||
import me.impy.aegis.crypto.KeyInfo;
|
||||
import me.impy.aegis.db.DatabaseEntry;
|
||||
import me.impy.aegis.encoding.Base32;
|
||||
import me.impy.aegis.helpers.SpinnerHelper;
|
||||
|
||||
public class EditProfileActivity extends AegisActivity {
|
||||
private boolean _edited = false;
|
||||
private KeyProfile _profile;
|
||||
|
||||
private EditText _textName;
|
||||
private EditText _textIssuer;
|
||||
private EditText _textPeriod;
|
||||
private EditText _textSecret;
|
||||
|
||||
private Spinner _spinnerType;
|
||||
private Spinner _spinnerAlgo;
|
||||
private Spinner _spinnerDigits;
|
||||
private SpinnerItemSelectedListener _selectedListener = new SpinnerItemSelectedListener();
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_edit_profile);
|
||||
|
||||
_profile = (KeyProfile) getIntent().getSerializableExtra("KeyProfile");
|
||||
|
||||
ActionBar bar = getSupportActionBar();
|
||||
bar.setHomeAsUpIndicator(R.drawable.ic_close);
|
||||
bar.setDisplayHomeAsUpEnabled(true);
|
||||
|
||||
ImageView imageView = findViewById(R.id.profile_drawable);
|
||||
imageView.setImageDrawable(_profile.getDrawable());
|
||||
|
||||
DatabaseEntry entry = _profile.getEntry();
|
||||
_textName = findViewById(R.id.text_name);
|
||||
_textName.setText(entry.getName());
|
||||
_textName.addTextChangedListener(watcher);
|
||||
|
||||
_textIssuer = findViewById(R.id.text_issuer);
|
||||
_textIssuer.setText(entry.getInfo().getIssuer());
|
||||
_textIssuer.addTextChangedListener(watcher);
|
||||
|
||||
_textPeriod = findViewById(R.id.text_period);
|
||||
_textPeriod.setText(Integer.toString(entry.getInfo().getPeriod()));
|
||||
_textPeriod.addTextChangedListener(watcher);
|
||||
|
||||
_textSecret = findViewById(R.id.text_secret);
|
||||
_textSecret.setText(Base32.encodeOriginal(entry.getInfo().getSecret()));
|
||||
_textSecret.addTextChangedListener(watcher);
|
||||
|
||||
_spinnerType = findViewById(R.id.spinner_type);
|
||||
SpinnerHelper.fillSpinner(this, _spinnerType, R.array.otp_types_array);
|
||||
_spinnerType.setOnTouchListener(_selectedListener);
|
||||
_spinnerType.setOnItemSelectedListener(_selectedListener);
|
||||
|
||||
_spinnerAlgo = findViewById(R.id.spinner_algo);
|
||||
SpinnerHelper.fillSpinner(this, _spinnerAlgo, R.array.otp_algo_array);
|
||||
_spinnerAlgo.setOnTouchListener(_selectedListener);
|
||||
_spinnerAlgo.setOnItemSelectedListener(_selectedListener);
|
||||
|
||||
_spinnerDigits = findViewById(R.id.spinner_digits);
|
||||
SpinnerHelper.fillSpinner(this, _spinnerDigits, R.array.otp_digits_array);
|
||||
_spinnerDigits.setOnTouchListener(_selectedListener);
|
||||
_spinnerDigits.setOnItemSelectedListener(_selectedListener);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setPreferredTheme(boolean nightMode) {
|
||||
if (nightMode) {
|
||||
setTheme(R.style.AppTheme_Dark_TransparentActionBar);
|
||||
} else {
|
||||
setTheme(R.style.AppTheme_Default_TransparentActionBar);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
if (!_edited) {
|
||||
super.onBackPressed();
|
||||
return;
|
||||
}
|
||||
|
||||
new AlertDialog.Builder(this)
|
||||
.setMessage("Your changes have not been saved")
|
||||
.setPositiveButton(R.string.save, (dialog, which) -> onSave())
|
||||
.setNegativeButton(R.string.discard, (dialog, which) -> super.onBackPressed())
|
||||
.show();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case android.R.id.home:
|
||||
onBackPressed();
|
||||
return true;
|
||||
case R.id.action_save:
|
||||
return onSave();
|
||||
case R.id.action_delete:
|
||||
return onDelete();
|
||||
default:
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.menu_edit, menu);
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean onDelete() {
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean onSave() {
|
||||
int period;
|
||||
try {
|
||||
period = Integer.parseInt(_textPeriod.getText().toString());
|
||||
} catch (NumberFormatException e) {
|
||||
onError("Period is not an integer.");
|
||||
return false;
|
||||
}
|
||||
|
||||
String type = _spinnerType.getSelectedItem().toString();
|
||||
String algo = _spinnerAlgo.getSelectedItem().toString();
|
||||
|
||||
int digits;
|
||||
try {
|
||||
digits = Integer.parseInt(_spinnerDigits.getSelectedItem().toString());
|
||||
} catch (NumberFormatException e) {
|
||||
onError("Digits is not an integer.");
|
||||
return false;
|
||||
}
|
||||
|
||||
DatabaseEntry entry = _profile.getEntry();
|
||||
entry.setName(_textName.getText().toString());
|
||||
KeyInfo info = entry.getInfo();
|
||||
info.setIssuer(_textIssuer.getText().toString());
|
||||
info.setSecret(Base32.decode(_textSecret.getText().toString()));
|
||||
info.setPeriod(period);
|
||||
info.setDigits(digits);
|
||||
info.setAlgorithm(algo);
|
||||
info.setType(type);
|
||||
|
||||
Intent intent = new Intent();
|
||||
intent.putExtra("KeyProfile", _profile);
|
||||
setResult(RESULT_OK, intent);
|
||||
finish();
|
||||
return true;
|
||||
}
|
||||
|
||||
private void onError(String msg) {
|
||||
new AlertDialog.Builder(this)
|
||||
.setTitle("Error saving profile")
|
||||
.setMessage(msg)
|
||||
.setPositiveButton(android.R.string.ok, null)
|
||||
.show();
|
||||
}
|
||||
|
||||
private void onFieldEdited() {
|
||||
_edited = true;
|
||||
}
|
||||
|
||||
private TextWatcher watcher = new TextWatcher() {
|
||||
@Override
|
||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||
onFieldEdited();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||
onFieldEdited();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterTextChanged(Editable s) {
|
||||
onFieldEdited();
|
||||
}
|
||||
};
|
||||
|
||||
private class SpinnerItemSelectedListener implements AdapterView.OnItemSelectedListener, View.OnTouchListener {
|
||||
private boolean _userSelect = false;
|
||||
|
||||
@Override
|
||||
public boolean onTouch(View v, MotionEvent event) {
|
||||
_userSelect = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
|
||||
if (_userSelect) {
|
||||
onFieldEdited();
|
||||
_userSelect = false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNothingSelected(AdapterView<?> parent) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
package me.impy.aegis.helpers;
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.annotation.ArrayRes;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.Spinner;
|
||||
|
||||
public class SpinnerHelper {
|
||||
private SpinnerHelper() {
|
||||
|
||||
}
|
||||
|
||||
public static void fillSpinner(Context context, Spinner spinner, @ArrayRes int textArrayResId) {
|
||||
ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(context, textArrayResId, android.R.layout.simple_spinner_item);
|
||||
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||
spinner.setAdapter(adapter);
|
||||
spinner.invalidate();
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="#FFFFFF"
|
||||
android:pathData="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z" />
|
||||
<path
|
||||
android:pathData="M0 0h24v24H0z" />
|
||||
</vector>
|
@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
|
||||
<path
|
||||
android:pathData="M0 0h24v24H0z" />
|
||||
<path
|
||||
android:fillColor="#000000"
|
||||
android:pathData="M11 17h2v-6h-2v6zm1-15C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8zM11 9h2V7h-2v2z" />
|
||||
</vector>
|
@ -0,0 +1,185 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<LinearLayout android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/viewA"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="0.66"
|
||||
android:background="@color/colorPrimary"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="100dp"
|
||||
android:layout_height="100dp"
|
||||
android:id="@+id/profile_drawable"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_centerHorizontal="true"/>
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
<TableLayout
|
||||
android:id="@+id/viewB"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="0.33"
|
||||
android:background="?attr/background"
|
||||
android:orientation="vertical"
|
||||
android:stretchColumns="1"
|
||||
android:layout_marginEnd="35dp">
|
||||
|
||||
<TableRow
|
||||
android:layout_marginTop="5dp"
|
||||
android:layout_marginBottom="5dp">
|
||||
<ImageView android:layout_column="0"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:src="@drawable/ic_person_black_24dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_marginTop="10dp"
|
||||
android:tint="@color/cardview_dark_background"
|
||||
android:layout_marginStart="15dp"
|
||||
android:layout_marginEnd="20dp"/>
|
||||
|
||||
<EditText android:layout_column="1"
|
||||
android:id="@+id/text_name"
|
||||
android:hint="Name"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"/>
|
||||
</TableRow>
|
||||
|
||||
<TableRow
|
||||
android:layout_marginTop="5dp"
|
||||
android:layout_marginBottom="5dp">
|
||||
<EditText android:layout_column="1"
|
||||
android:id="@+id/text_issuer"
|
||||
android:hint="Issuer"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"/>
|
||||
</TableRow>
|
||||
|
||||
<TableRow
|
||||
android:layout_marginTop="5dp"
|
||||
android:layout_marginBottom="5dp">
|
||||
<ImageView android:layout_column="0"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:src="@drawable/ic_info_outline_black_24dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_marginTop="10dp"
|
||||
android:tint="@color/cardview_dark_background"
|
||||
android:layout_marginStart="15dp"
|
||||
android:layout_marginEnd="20dp"/>
|
||||
|
||||
<LinearLayout android:layout_column="1"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
<Spinner
|
||||
android:id="@+id/spinner_type"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="3"
|
||||
style="@style/Base.Widget.AppCompat.Spinner.Underlined"/>
|
||||
<Spinner
|
||||
android:id="@+id/spinner_algo"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="3"
|
||||
style="@style/Base.Widget.AppCompat.Spinner.Underlined"/>
|
||||
<Spinner
|
||||
android:id="@+id/spinner_digits"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="2"
|
||||
style="@style/Base.Widget.AppCompat.Spinner.Underlined"/>
|
||||
</LinearLayout>
|
||||
|
||||
</TableRow>
|
||||
|
||||
<TableRow
|
||||
android:layout_marginTop="5dp"
|
||||
android:layout_marginBottom="5dp">
|
||||
<ImageView android:layout_column="0"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:src="@drawable/ic_timelapse_black_24dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_marginTop="10dp"
|
||||
android:tint="@color/cardview_dark_background"
|
||||
android:layout_marginStart="15dp"
|
||||
android:layout_marginEnd="20dp"/>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
<RelativeLayout
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:orientation="vertical">
|
||||
<EditText
|
||||
android:id="@+id/text_period"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentStart="true"
|
||||
android:layout_gravity="center"
|
||||
android:inputType="numberDecimal"/>
|
||||
<TextView
|
||||
android:id="@+id/text_hint"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:text="seconds"
|
||||
android:textSize="18sp"
|
||||
android:layout_marginEnd="10dp"
|
||||
android:textColor="#808080"/>
|
||||
</RelativeLayout>
|
||||
<LinearLayout
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"/>
|
||||
</LinearLayout>
|
||||
</TableRow>
|
||||
|
||||
<TableRow
|
||||
android:layout_marginTop="5dp"
|
||||
android:layout_marginBottom="5dp">
|
||||
<ImageView android:layout_column="0"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:src="@drawable/ic_vpn_key_black_24dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_marginTop="10dp"
|
||||
android:tint="@color/cardview_dark_background"
|
||||
android:layout_marginStart="15dp"
|
||||
android:layout_marginEnd="20dp"/>
|
||||
|
||||
<android.support.design.widget.TextInputLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:hintEnabled="false"
|
||||
app:passwordToggleEnabled="true">
|
||||
|
||||
<EditText
|
||||
android:id="@+id/text_secret"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:hint="Secret (base32)"
|
||||
android:inputType="textPassword"/>
|
||||
</android.support.design.widget.TextInputLayout>
|
||||
</TableRow>
|
||||
|
||||
</TableLayout>
|
||||
|
||||
</LinearLayout>
|
||||
</android.support.design.widget.CoordinatorLayout>
|
@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu 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"
|
||||
tools:context="me.impy.aegis.EditProfileActivity">
|
||||
<item
|
||||
android:id="@+id/action_save"
|
||||
app:showAsAction="ifRoom"
|
||||
android:title="@string/save"/>
|
||||
<item
|
||||
android:id="@+id/action_delete"
|
||||
android:title="@string/action_delete"
|
||||
app:showAsAction="never"/>
|
||||
</menu>
|
Loading…
Reference in New Issue