Backup encryption feature
- Add encryption option when exporting and importing backup - Add wipe data option when importing backup
This commit is contained in:
parent
f8bb7b0487
commit
47c4fb0daf
@ -28,6 +28,7 @@ import com.herbron.moodl.Activities.HomeActivityFragments.Summary;
|
|||||||
import com.herbron.moodl.Activities.HomeActivityFragments.Watchlist;
|
import com.herbron.moodl.Activities.HomeActivityFragments.Watchlist;
|
||||||
import com.herbron.moodl.BalanceSwitchManagerInterface;
|
import com.herbron.moodl.BalanceSwitchManagerInterface;
|
||||||
import com.herbron.moodl.BalanceUpdateInterface;
|
import com.herbron.moodl.BalanceUpdateInterface;
|
||||||
|
import com.herbron.moodl.DataManagers.DatabaseManager;
|
||||||
import com.herbron.moodl.DataManagers.PreferencesManager;
|
import com.herbron.moodl.DataManagers.PreferencesManager;
|
||||||
import com.herbron.moodl.PlaceholderManager;
|
import com.herbron.moodl.PlaceholderManager;
|
||||||
import com.herbron.moodl.R;
|
import com.herbron.moodl.R;
|
||||||
@ -59,7 +60,6 @@ public class HomeActivity extends AppCompatActivity implements BalanceUpdateInte
|
|||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
/**Interface setup**/
|
/**Interface setup**/
|
||||||
Window w = getWindow();
|
|
||||||
|
|
||||||
setContentView(R.layout.activity_currency_summary);
|
setContentView(R.layout.activity_currency_summary);
|
||||||
|
|
||||||
|
@ -70,7 +70,7 @@ public class Summary extends Fragment implements BalanceSwitchManagerInterface,
|
|||||||
|
|
||||||
private LinearLayout currencyLayout;
|
private LinearLayout currencyLayout;
|
||||||
private PreferencesManager preferencesManager;
|
private PreferencesManager preferencesManager;
|
||||||
private com.herbron.moodl.DataManagers.BalanceManager balanceManager;
|
private BalanceManager balanceManager;
|
||||||
private SwipeRefreshLayout refreshLayout;
|
private SwipeRefreshLayout refreshLayout;
|
||||||
private Dialog loadingDialog;
|
private Dialog loadingDialog;
|
||||||
private String defaultCurrency;
|
private String defaultCurrency;
|
||||||
|
@ -46,6 +46,10 @@ import com.herbron.moodl.FingerprintToolkit.FingerprintHandler;
|
|||||||
import com.herbron.moodl.MoodlBox;
|
import com.herbron.moodl.MoodlBox;
|
||||||
import com.herbron.moodl.R;
|
import com.herbron.moodl.R;
|
||||||
|
|
||||||
|
import org.json.JSONArray;
|
||||||
|
import org.json.JSONException;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileReader;
|
import java.io.FileReader;
|
||||||
@ -468,21 +472,34 @@ public class SettingsActivity extends AppCompatPreferenceActivity {
|
|||||||
checkPermissions();
|
checkPermissions();
|
||||||
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd_HH-mm-ss", Locale.getDefault());
|
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd_HH-mm-ss", Locale.getDefault());
|
||||||
Date currentDate = new Date();
|
Date currentDate = new Date();
|
||||||
String fileName = getString(R.string.app_name) + "_" + formatter.format(currentDate) + ".backup";
|
String fileName = "Bakup_" + formatter.format(currentDate) + ".moodl";
|
||||||
DatabaseManager databaseManager = new DatabaseManager(getContext());
|
DatabaseManager databaseManager = new DatabaseManager(getContext());
|
||||||
|
|
||||||
|
if(enterPasswordCheckbox.isChecked())
|
||||||
|
{
|
||||||
|
DataCrypter.updateKey(textInputLayoutPassword.getEditText().getText().toString());
|
||||||
|
}
|
||||||
|
|
||||||
File backupFile = new File(textViewFilePath.getText() + "/" + fileName);
|
File backupFile = new File(textViewFilePath.getText() + "/" + fileName);
|
||||||
|
|
||||||
try (PrintWriter printWriter = new PrintWriter(new FileWriter(backupFile, true))) {
|
try (PrintWriter printWriter = new PrintWriter(new FileWriter(backupFile, true))) {
|
||||||
|
|
||||||
if(enterPasswordCheckbox.isChecked())
|
try {
|
||||||
{
|
JSONObject backupJson = new JSONObject();
|
||||||
DataCrypter.updateKey(textInputLayoutPassword.getEditText().getText().toString());
|
|
||||||
printWriter.write(DataCrypter.encrypt(getActivity(), databaseManager.getBackupData()));
|
if(enterPasswordCheckbox.isChecked())
|
||||||
}
|
{
|
||||||
else
|
backupJson.put("encodeChecker", DataCrypter.encrypt(getContext(), "NaukVerification"));
|
||||||
{
|
}
|
||||||
printWriter.write(databaseManager.getBackupData());
|
else
|
||||||
|
{
|
||||||
|
backupJson.put("encodeChecker", "NaukVerification");
|
||||||
|
}
|
||||||
|
backupJson.put("transactions", databaseManager.getBackupData(getContext(),enterPasswordCheckbox.isChecked()));
|
||||||
|
|
||||||
|
printWriter.write(backupJson.toString());
|
||||||
|
} catch (JSONException e) {
|
||||||
|
Log.d("moodl", "Error while creating backup json " + e.getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
printWriter.close();
|
printWriter.close();
|
||||||
@ -542,6 +559,10 @@ public class SettingsActivity extends AppCompatPreferenceActivity {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
final CheckBox enterPasswordCheckbox = dialogView.findViewById(R.id.checkboxEnterPassword);
|
||||||
|
final CheckBox wipeCheckbox = dialogView.findViewById(R.id.checkboxWipeData);
|
||||||
|
final TextInputLayout textInputLayoutPassword = dialogView.findViewById(R.id.textInputLayoutPassword);
|
||||||
|
|
||||||
dialogBuilder.setTitle(getString(R.string.restoreBackup));
|
dialogBuilder.setTitle(getString(R.string.restoreBackup));
|
||||||
dialogBuilder.setPositiveButton(getString(R.string.confirm), new DialogInterface.OnClickListener() {
|
dialogBuilder.setPositiveButton(getString(R.string.confirm), new DialogInterface.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
@ -551,6 +572,16 @@ public class SettingsActivity extends AppCompatPreferenceActivity {
|
|||||||
|
|
||||||
DatabaseManager databaseManager = new DatabaseManager(context);
|
DatabaseManager databaseManager = new DatabaseManager(context);
|
||||||
|
|
||||||
|
if(enterPasswordCheckbox.isChecked())
|
||||||
|
{
|
||||||
|
DataCrypter.updateKey(textInputLayoutPassword.getEditText().getText().toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
if(wipeCheckbox.isChecked())
|
||||||
|
{
|
||||||
|
databaseManager.wipeTransactions();
|
||||||
|
}
|
||||||
|
|
||||||
File backupFile = new File(textViewFilePath.getText().toString());
|
File backupFile = new File(textViewFilePath.getText().toString());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -564,13 +595,37 @@ public class SettingsActivity extends AppCompatPreferenceActivity {
|
|||||||
completeFile += str;
|
completeFile += str;
|
||||||
}
|
}
|
||||||
|
|
||||||
String[] results = completeFile.split(Pattern.quote("]"));
|
try {
|
||||||
|
JSONObject backupJson = new JSONObject(completeFile);
|
||||||
|
String checker;
|
||||||
|
|
||||||
for(int i = 0; i < results.length; i++)
|
if(enterPasswordCheckbox.isChecked())
|
||||||
{
|
{
|
||||||
String[] columnValues = results[i].split(Pattern.quote(";@"));
|
checker = DataCrypter.decrypt(getContext(), backupJson.getString("encodeChecker"));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
checker = backupJson.getString("encodeChecker");
|
||||||
|
}
|
||||||
|
|
||||||
databaseManager.addRowTransaction(columnValues);
|
if(checker.equals("NaukVerification"))
|
||||||
|
{
|
||||||
|
JSONArray transactionsArray = backupJson.getJSONArray("transactions");
|
||||||
|
|
||||||
|
for(int i = 0; i < transactionsArray.length(); i++)
|
||||||
|
{
|
||||||
|
JSONObject transactionObject = transactionsArray.getJSONObject(i);
|
||||||
|
|
||||||
|
databaseManager.addRowTransaction(transactionObject, getContext(), enterPasswordCheckbox.isChecked());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
textInputLayoutPassword.setError("Wrong password");
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (JSONException e) {
|
||||||
|
Log.d("moodl", "Error while creating backup json " + e);
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
|
@ -56,7 +56,6 @@ public class CurrencyDetailsList {
|
|||||||
|
|
||||||
if (response.length() > 0) {
|
if (response.length() > 0) {
|
||||||
processDetailResult(response, callBack);
|
processDetailResult(response, callBack);
|
||||||
upToDate = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -109,6 +108,8 @@ public class CurrencyDetailsList {
|
|||||||
|
|
||||||
sortDetails();
|
sortDetails();
|
||||||
|
|
||||||
|
upToDate = true;
|
||||||
|
|
||||||
callBack.onSuccess();
|
callBack.onSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,10 +4,10 @@ import android.content.Context;
|
|||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import com.herbron.moodl.R;
|
import com.herbron.moodl.R;
|
||||||
|
import android.util.Base64;
|
||||||
import org.apache.commons.codec.binary.Base64;
|
|
||||||
|
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.security.InvalidAlgorithmParameterException;
|
import java.security.InvalidAlgorithmParameterException;
|
||||||
import java.security.InvalidKeyException;
|
import java.security.InvalidKeyException;
|
||||||
import java.security.Key;
|
import java.security.Key;
|
||||||
@ -20,19 +20,19 @@ import javax.crypto.NoSuchPaddingException;
|
|||||||
import javax.crypto.spec.IvParameterSpec;
|
import javax.crypto.spec.IvParameterSpec;
|
||||||
import javax.crypto.spec.SecretKeySpec;
|
import javax.crypto.spec.SecretKeySpec;
|
||||||
|
|
||||||
|
|
||||||
public class DataCrypter {
|
public class DataCrypter {
|
||||||
|
|
||||||
private static Key aesKey;
|
private static Key aesKey;
|
||||||
|
|
||||||
public static void updateKey(String key)
|
public static void updateKey(String key)
|
||||||
{
|
{
|
||||||
for(int i = 0; key.getBytes().length < 32; i++)
|
|
||||||
{
|
|
||||||
key += "0";
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
aesKey = new SecretKeySpec(key.getBytes("UTF-8"), "AES");
|
byte[] keyByte = key.getBytes("UTF-8");
|
||||||
|
byte[] finalKey = new byte[32];
|
||||||
|
System.arraycopy(keyByte, 0, finalKey, 0, keyByte.length);
|
||||||
|
|
||||||
|
aesKey = new SecretKeySpec(finalKey, "AES");
|
||||||
} catch (UnsupportedEncodingException e) {
|
} catch (UnsupportedEncodingException e) {
|
||||||
Log.d("moodl", "Error while creating encryption key " + e.getMessage());
|
Log.d("moodl", "Error while creating encryption key " + e.getMessage());
|
||||||
}
|
}
|
||||||
@ -49,9 +49,10 @@ public class DataCrypter {
|
|||||||
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
|
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
|
||||||
cipher.init(Cipher.ENCRYPT_MODE, aesKey, ivParameterSpec);
|
cipher.init(Cipher.ENCRYPT_MODE, aesKey, ivParameterSpec);
|
||||||
|
|
||||||
byte[] encryptedBytes = cipher.doFinal(data.getBytes());
|
byte[] encryptedBytes = cipher.doFinal(data.getBytes("UTF-8"));
|
||||||
|
|
||||||
|
encryptedData = Base64.encodeToString(encryptedBytes, Base64.DEFAULT);
|
||||||
|
|
||||||
encryptedData = Base64.encodeBase64String(encryptedBytes);
|
|
||||||
} catch (NoSuchPaddingException | NoSuchAlgorithmException
|
} catch (NoSuchPaddingException | NoSuchAlgorithmException
|
||||||
| InvalidKeyException | BadPaddingException
|
| InvalidKeyException | BadPaddingException
|
||||||
| IllegalBlockSizeException | UnsupportedEncodingException
|
| IllegalBlockSizeException | UnsupportedEncodingException
|
||||||
@ -63,4 +64,26 @@ public class DataCrypter {
|
|||||||
|
|
||||||
return encryptedData;
|
return encryptedData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String decrypt(Context context, String data)
|
||||||
|
{
|
||||||
|
String decryptedData = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
IvParameterSpec ivParameterSpec = new IvParameterSpec(context.getString(R.string.ivKey).getBytes("UTF-8"));
|
||||||
|
|
||||||
|
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
|
||||||
|
cipher.init(Cipher.ENCRYPT_MODE, aesKey, ivParameterSpec);
|
||||||
|
|
||||||
|
byte[] dataBytes = Base64.decode(data, Base64.DEFAULT);
|
||||||
|
decryptedData = new String(dataBytes, StandardCharsets.UTF_8);
|
||||||
|
|
||||||
|
} catch(NoSuchPaddingException | NoSuchAlgorithmException
|
||||||
|
| InvalidKeyException | UnsupportedEncodingException
|
||||||
|
| InvalidAlgorithmParameterException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
return decryptedData;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,10 +5,15 @@ import android.content.Context;
|
|||||||
import android.database.Cursor;
|
import android.database.Cursor;
|
||||||
import android.database.sqlite.SQLiteDatabase;
|
import android.database.sqlite.SQLiteDatabase;
|
||||||
import android.database.sqlite.SQLiteOpenHelper;
|
import android.database.sqlite.SQLiteOpenHelper;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
import com.herbron.moodl.DataManagers.CurrencyData.Currency;
|
import com.herbron.moodl.DataManagers.CurrencyData.Currency;
|
||||||
import com.herbron.moodl.DataManagers.CurrencyData.Transaction;
|
import com.herbron.moodl.DataManagers.CurrencyData.Transaction;
|
||||||
|
|
||||||
|
import org.json.JSONArray;
|
||||||
|
import org.json.JSONException;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -152,36 +157,82 @@ public class DatabaseManager extends SQLiteOpenHelper{
|
|||||||
db.close();
|
db.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getBackupData()
|
public JSONArray getBackupData(Context context, boolean encryptData)
|
||||||
{
|
{
|
||||||
String selectQuerry = "SELECT * FROM " + TABLE_MANUAL_CURRENCIES;
|
String selectQuerry = "SELECT * FROM " + TABLE_MANUAL_CURRENCIES;
|
||||||
SQLiteDatabase db = this.getWritableDatabase();
|
SQLiteDatabase db = this.getWritableDatabase();
|
||||||
Cursor result = db.rawQuery(selectQuerry, null);
|
Cursor result = db.rawQuery(selectQuerry, null);
|
||||||
|
|
||||||
String backupData = "";
|
JSONArray transactionsArray = new JSONArray();
|
||||||
|
|
||||||
while(result.moveToNext())
|
while(result.moveToNext())
|
||||||
{
|
{
|
||||||
|
JSONObject transactionJson = new JSONObject();
|
||||||
|
|
||||||
for(int i = 0; i < result.getColumnCount(); i++)
|
for(int i = 0; i < result.getColumnCount(); i++)
|
||||||
{
|
{
|
||||||
backupData += result.getString(i) + ";@";
|
try {
|
||||||
|
if(result.getString(i) != null)
|
||||||
|
{
|
||||||
|
if(encryptData)
|
||||||
|
{
|
||||||
|
transactionJson.put(result.getColumnName(i), DataCrypter.encrypt(context, result.getString(i)));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
transactionJson.put(result.getColumnName(i), result.getString(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
transactionJson.put(result.getColumnName(i), "");
|
||||||
|
}
|
||||||
|
} catch (JSONException e) {
|
||||||
|
Log.d("moodl", "Error while creating a json transaction");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
backupData += "\n";
|
transactionsArray.put(transactionJson);
|
||||||
}
|
}
|
||||||
|
|
||||||
return backupData;
|
return transactionsArray;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addRowTransaction(String[] rowValues)
|
public void wipeTransactions()
|
||||||
|
{
|
||||||
|
SQLiteDatabase db = this.getWritableDatabase();
|
||||||
|
db.execSQL("DELETE FROM "+ TABLE_MANUAL_CURRENCIES);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addRowTransaction(JSONObject rawValues, Context context, boolean decrypt)
|
||||||
{
|
{
|
||||||
SQLiteDatabase db = this.getWritableDatabase();
|
SQLiteDatabase db = this.getWritableDatabase();
|
||||||
ContentValues values = new ContentValues();
|
ContentValues values = new ContentValues();
|
||||||
|
|
||||||
values.put(KEY_CURRENCY_SYMBOL, rowValues[1]);
|
try {
|
||||||
values.put(KEY_CURRENCY_BALANCE, rowValues[3]);
|
if(decrypt)
|
||||||
values.put(KEY_CURRENCY_DATE, rowValues[4]);
|
{
|
||||||
values.put(KEY_CURRENCY_PURCHASED_PRICE, rowValues[5]);
|
values.put(KEY_CURRENCY_SYMBOL, DataCrypter.decrypt(context, rawValues.getString(KEY_CURRENCY_SYMBOL)));
|
||||||
|
values.put(KEY_CURRENCY_NAME, DataCrypter.decrypt(context, rawValues.getString(KEY_CURRENCY_NAME)));
|
||||||
|
values.put(KEY_CURRENCY_BALANCE, DataCrypter.decrypt(context, rawValues.getString(KEY_CURRENCY_BALANCE)));
|
||||||
|
values.put(KEY_CURRENCY_DATE, DataCrypter.decrypt(context, rawValues.getString(KEY_CURRENCY_DATE)));
|
||||||
|
values.put(KEY_CURRENCY_PURCHASED_PRICE, DataCrypter.decrypt(context, rawValues.getString(KEY_CURRENCY_PURCHASED_PRICE)));
|
||||||
|
values.put(KEY_CURRENCY_IS_MINED, DataCrypter.decrypt(context, rawValues.getString(KEY_CURRENCY_IS_MINED)));
|
||||||
|
values.put(KEY_CURRENCY_FEES, DataCrypter.decrypt(context, rawValues.getString(KEY_CURRENCY_FEES)));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
values.put(KEY_CURRENCY_SYMBOL, rawValues.getString(KEY_CURRENCY_SYMBOL));
|
||||||
|
values.put(KEY_CURRENCY_NAME, rawValues.getString(KEY_CURRENCY_NAME));
|
||||||
|
values.put(KEY_CURRENCY_BALANCE, rawValues.getString(KEY_CURRENCY_BALANCE));
|
||||||
|
values.put(KEY_CURRENCY_DATE, rawValues.getString(KEY_CURRENCY_DATE));
|
||||||
|
values.put(KEY_CURRENCY_PURCHASED_PRICE, rawValues.getString(KEY_CURRENCY_PURCHASED_PRICE));
|
||||||
|
values.put(KEY_CURRENCY_IS_MINED, rawValues.getString(KEY_CURRENCY_IS_MINED));
|
||||||
|
values.put(KEY_CURRENCY_FEES, rawValues.getString(KEY_CURRENCY_FEES));
|
||||||
|
}
|
||||||
|
} catch (JSONException e) {
|
||||||
|
Log.d("moodl", "Error while inserting transaction");
|
||||||
|
}
|
||||||
|
|
||||||
db.insert(TABLE_MANUAL_CURRENCIES, null, values);
|
db.insert(TABLE_MANUAL_CURRENCIES, null, values);
|
||||||
db.close();
|
db.close();
|
||||||
|
@ -17,10 +17,10 @@
|
|||||||
android:background="@drawable/background_filepath"/>
|
android:background="@drawable/background_filepath"/>
|
||||||
|
|
||||||
<CheckBox
|
<CheckBox
|
||||||
android:id="@+id/checkboxConserveData"
|
android:id="@+id/checkboxWipeData"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="@string/conserve_data"
|
android:text="@string/wipe_data"
|
||||||
android:enabled="false" />
|
android:enabled="false" />
|
||||||
|
|
||||||
<CheckBox
|
<CheckBox
|
||||||
@ -41,8 +41,7 @@
|
|||||||
android:id="@+id/checkboxEnterPassword"
|
android:id="@+id/checkboxEnterPassword"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="@string/enter_password"
|
android:text="@string/enter_password"/>
|
||||||
android:enabled="false"/>
|
|
||||||
|
|
||||||
<android.support.design.widget.TextInputLayout
|
<android.support.design.widget.TextInputLayout
|
||||||
android:id="@+id/textInputLayoutPassword"
|
android:id="@+id/textInputLayoutPassword"
|
||||||
|
@ -17,11 +17,10 @@
|
|||||||
android:background="@drawable/background_filepath"/>
|
android:background="@drawable/background_filepath"/>
|
||||||
|
|
||||||
<CheckBox
|
<CheckBox
|
||||||
android:id="@+id/checkboxConserveData"
|
android:id="@+id/checkboxWipeData"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="@string/conserve_data"
|
android:text="@string/wipe_data"/>
|
||||||
android:enabled="false"/>
|
|
||||||
|
|
||||||
<CheckBox
|
<CheckBox
|
||||||
android:id="@+id/checkboxRestoreEntries"
|
android:id="@+id/checkboxRestoreEntries"
|
||||||
@ -41,8 +40,7 @@
|
|||||||
android:id="@+id/checkboxEnterPassword"
|
android:id="@+id/checkboxEnterPassword"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="@string/enter_password"
|
android:text="@string/enter_password"/>
|
||||||
android:enabled="false"/>
|
|
||||||
|
|
||||||
<android.support.design.widget.TextInputLayout
|
<android.support.design.widget.TextInputLayout
|
||||||
android:id="@+id/textInputLayoutPassword"
|
android:id="@+id/textInputLayoutPassword"
|
||||||
|
@ -87,10 +87,10 @@
|
|||||||
<string name="pref_title_export">Exporter les entrées manuelles</string>
|
<string name="pref_title_export">Exporter les entrées manuelles</string>
|
||||||
<string name="pref_title_import">Importer de nouvelles entrées</string>
|
<string name="pref_title_import">Importer de nouvelles entrées</string>
|
||||||
<string name="pref_title_category_synchronization">Synchronisation</string>
|
<string name="pref_title_category_synchronization">Synchronisation</string>
|
||||||
<string name="conserve_data">Conserver les données</string>
|
<string name="wipe_data">Supprimer les données actuelles</string>
|
||||||
<string name="restore_manual_entries">Restaurer les transactions manuelles</string>
|
<string name="restore_manual_entries">Restaurer les transactions manuelles</string>
|
||||||
<string name="restore_keys">Restaurer les clefs d\'API</string>
|
<string name="restore_keys">Restaurer les clefs d\'API</string>
|
||||||
<string name="enter_password">Entrerr un mot de passe</string>
|
<string name="enter_password">Entrer un mot de passe</string>
|
||||||
<string name="password">Mot de passe</string>
|
<string name="password">Mot de passe</string>
|
||||||
<string name="title_activity_exchange_settings">Réglages</string>
|
<string name="title_activity_exchange_settings">Réglages</string>
|
||||||
<string name="save">Sauvegarder</string>
|
<string name="save">Sauvegarder</string>
|
||||||
|
@ -203,7 +203,7 @@
|
|||||||
<string name="field_empty">This field cannot be blank</string>
|
<string name="field_empty">This field cannot be blank</string>
|
||||||
<string name="field_nan">This field must be a number</string>
|
<string name="field_nan">This field must be a number</string>
|
||||||
<string name="field_negative">This field must be positive</string>
|
<string name="field_negative">This field must be positive</string>
|
||||||
<string name="conserve_data">Conserve current data</string>
|
<string name="wipe_data">Wipe current data</string>
|
||||||
<string name="restore_manual_entries">Restore manual entries</string>
|
<string name="restore_manual_entries">Restore manual entries</string>
|
||||||
<string name="restore_keys">Restore API keys</string>
|
<string name="restore_keys">Restore API keys</string>
|
||||||
<string name="enter_password">Enter password</string>
|
<string name="enter_password">Enter password</string>
|
||||||
|
Loading…
Reference in New Issue
Block a user