Import data implementation (begining)

- Adds an interface for the data import feature (not final)
- Can read data from a manually created backup file
This commit is contained in:
Tanguy Herbron 2018-07-09 23:47:30 +02:00
parent 7b9282bfef
commit de6fc36e6c
9 changed files with 224 additions and 16 deletions

Binary file not shown.

View File

@ -15,7 +15,7 @@ android {
minifyEnabled false minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
lintOptions { lintOptions {
disable 'MissingTranslation' //disable 'MissingTranslation'
} }
} }
} }

View File

@ -7,6 +7,7 @@
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.USE_FINGERPRINT" /> <uses-permission android:name="android.permission.USE_FINGERPRINT" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<application <application
android:allowBackup="true" android:allowBackup="true"

View File

@ -514,9 +514,9 @@ public class Summary extends Fragment implements BalanceSwitchManagerInterface,
public void onBalanceDataUpdated() { public void onBalanceDataUpdated() {
final List<Currency> balance = balanceManager.getTotalBalance(); final List<Currency> balance = balanceManager.getTotalBalance();
if(balanceManager.getTotalBalance().size() > 0) if(balance.size() > 0)
{ {
for(int i = 0; i < balanceManager.getTotalBalance().size(); i++) for(int i = 0; i < balance.size(); i++)
{ {
balance.get(i).updatePrice(getActivity(), defaultCurrency, new Currency.CurrencyCallBack() { balance.get(i).updatePrice(getActivity(), defaultCurrency, new Currency.CurrencyCallBack() {
@Override @Override

View File

@ -2,41 +2,58 @@ package com.herbron.moodl.Activities;
import android.Manifest; import android.Manifest;
import android.annotation.TargetApi; import android.annotation.TargetApi;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.KeyguardManager; import android.app.KeyguardManager;
import android.content.Context; import android.content.Context;
import android.content.DialogInterface;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.content.res.Configuration; import android.content.res.Configuration;
import android.hardware.fingerprint.FingerprintManager; import android.hardware.fingerprint.FingerprintManager;
import android.media.Ringtone;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.Build; import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.os.Environment;
import android.preference.EditTextPreference; import android.preference.EditTextPreference;
import android.preference.ListPreference; import android.preference.ListPreference;
import android.preference.Preference; import android.preference.Preference;
import android.preference.PreferenceActivity; import android.preference.PreferenceActivity;
import android.preference.PreferenceFragment; import android.preference.PreferenceFragment;
import android.preference.PreferenceManager; import android.preference.PreferenceManager;
import android.preference.PreferenceScreen;
import android.preference.RingtonePreference;
import android.preference.SwitchPreference; import android.preference.SwitchPreference;
import android.security.keystore.KeyGenParameterSpec; import android.security.keystore.KeyGenParameterSpec;
import android.security.keystore.KeyPermanentlyInvalidatedException; import android.security.keystore.KeyPermanentlyInvalidatedException;
import android.security.keystore.KeyProperties; import android.security.keystore.KeyProperties;
import android.support.design.widget.TextInputLayout;
import android.support.v4.app.ActivityCompat; import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.ActionBar; import android.support.v7.app.ActionBar;
import android.text.TextUtils; import android.support.v7.view.ContextThemeWrapper;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.TextView;
import com.herbron.moodl.BuildConfig; import com.herbron.moodl.BuildConfig;
import com.herbron.moodl.FingerprintToolkit.FingerprintDialogFragment; import com.herbron.moodl.FingerprintToolkit.FingerprintDialogFragment;
import com.herbron.moodl.FingerprintToolkit.FingerprintHandler; import com.herbron.moodl.FingerprintToolkit.FingerprintHandler;
import com.herbron.moodl.MoodlBox;
import com.herbron.moodl.R; import com.herbron.moodl.R;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException; import java.io.IOException;
import java.io.PrintWriter;
import java.security.InvalidAlgorithmParameterException; import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException; import java.security.InvalidKeyException;
import java.security.KeyStore; import java.security.KeyStore;
@ -45,7 +62,12 @@ import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException; import java.security.NoSuchProviderException;
import java.security.UnrecoverableKeyException; import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException; import java.security.cert.CertificateException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Locale;
import javax.crypto.Cipher; import javax.crypto.Cipher;
import javax.crypto.KeyGenerator; import javax.crypto.KeyGenerator;
@ -147,11 +169,125 @@ public class SettingsActivity extends AppCompatPreferenceActivity {
bindPreferenceSummaryToValue(findPreference("default_currency")); bindPreferenceSummaryToValue(findPreference("default_currency"));
bindPreferenceSummaryToValue(findPreference("minimum_value_displayed")); bindPreferenceSummaryToValue(findPreference("minimum_value_displayed"));
findPreference("import").setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
Context context = SettingsActivity.this;
AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(context);
View dialogView = LayoutInflater.from(context).inflate(R.layout.dialog_import_data, null, true);
dialogBuilder.setView(dialogView);
CheckBox enterPasswordCheckbox = dialogView.findViewById(R.id.checkboxEnterPassword);
final TextInputLayout textInputLayoutPassword = dialogView.findViewById(R.id.textInputLayoutPassword);
enterPasswordCheckbox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
if(b && textInputLayoutPassword.getVisibility() == View.GONE)
{
MoodlBox.expandH(textInputLayoutPassword);
}
if(!b && textInputLayoutPassword.getVisibility() == View.VISIBLE)
{
MoodlBox.collapseH(textInputLayoutPassword);
}
}
});
dialogBuilder.setTitle("Restore backup");
dialogBuilder.setPositiveButton("Confirm", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
checkPermissions();
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd_HH-mm-ss", Locale.getDefault());
Date currentDate = new Date();
//String fileName = getString(R.string.app_name) + "_" + formatter.format(currentDate) + ".backup";
String fileName = "backup.moodl";
File dir = new File(Environment.getExternalStorageDirectory(), getString(R.string.app_name));
if (!dir.exists()) {
if (!dir.mkdirs()) {
Log.d("moodl", "Error while creating directory");
}
}
File backupFile = new File(dir + "/" + fileName);
if(backupFile.exists())
{
try (FileReader fileReader = new FileReader(backupFile)) {
BufferedReader bufferedReader = new BufferedReader(fileReader);
String line;
while((line = bufferedReader.readLine()) != null)
{
Log.d("moodl", line);
}
} catch (IOException e) {
Log.d("moodl", "Error > " + e);
}
}
else
{
Log.d("moodl", "Not backup file found");
try (PrintWriter printWriter = new PrintWriter(new FileWriter(backupFile, true))) {
printWriter.write("Some data");
printWriter.close();
} catch (IOException e) {
Log.d("moodl", "Error > " + e);
}
}
dialog.dismiss();
}
});
dialogBuilder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
dialog.dismiss();
}
});
AlertDialog alertDialog = dialogBuilder.create();
alertDialog.show();
return false;
}
});
EditTextPreference editTextPreference = (EditTextPreference) findPreference("minimum_value_displayed"); EditTextPreference editTextPreference = (EditTextPreference) findPreference("minimum_value_displayed");
editTextPreference.setPositiveButtonText("Save"); editTextPreference.setPositiveButtonText("Save");
editTextPreference.setNegativeButtonText("Cancel"); editTextPreference.setNegativeButtonText("Cancel");
} }
private boolean checkPermissions() {
String[] permissions = new String[]{
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE,
};
int result;
List<String> listPermissionsNeeded = new ArrayList<>();
for (String p : permissions) {
result = ContextCompat.checkSelfPermission(this, p);
if (result != PackageManager.PERMISSION_GRANTED) {
listPermissionsNeeded.add(p);
}
}
if (!listPermissionsNeeded.isEmpty()) {
ActivityCompat.requestPermissions(this, listPermissionsNeeded.toArray(new String[listPermissionsNeeded.size()]), 100);
return false;
}
return true;
}
/** /**
* Set up the {@link android.app.ActionBar}, if the API is available. * Set up the {@link android.app.ActionBar}, if the API is available.
*/ */

View File

@ -0,0 +1,51 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_gravity="center"
android:theme="@style/AppTheme"
android:padding="5dp"
android:focusableInTouchMode="true">
<CheckBox
android:id="@+id/checkboxConserveData"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/conserve_data" />
<CheckBox
android:id="@+id/checkboxRestoreEntries"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/restore_manual_entries" />
<CheckBox
android:id="@+id/checkboxRestoreKeys"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/restore_keys" />
<CheckBox
android:id="@+id/checkboxEnterPassword"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/enter_password"/>
<android.support.design.widget.TextInputLayout
android:id="@+id/textInputLayoutPassword"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="gone">
<EditText
android:id="@+id/editTextPassword"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/password"
android:inputType="textPassword"/>
</android.support.design.widget.TextInputLayout>
</LinearLayout>

View File

@ -14,6 +14,7 @@
<!-- Example settings for Data & Sync --> <!-- Example settings for Data & Sync -->
<string name="pref_title_category_display">Display</string> <string name="pref_title_category_display">Display</string>
<string name="pref_title_category_data_backup">Data backup</string> <string name="pref_title_category_data_backup">Data backup</string>
<string name="pref_title_category_synchronization">Synchronization</string>
<string name="pref_title_category_other">Other</string> <string name="pref_title_category_other">Other</string>
<string name="pref_title_minimum_amount_displayed">Minimum amount displayed</string> <string name="pref_title_minimum_amount_displayed">Minimum amount displayed</string>
@ -89,6 +90,7 @@
<!--Exchange strings--> <!--Exchange strings-->
<string name="pref_header_exchange">Exchanges settings</string> <string name="pref_header_exchange">Exchanges settings</string>
<string name="pref_header_wallet">Wallets settings</string>
<string name="pref_fingerprint" translatable="false">Touch ID</string> <string name="pref_fingerprint" translatable="false">Touch ID</string>
<!--HitBTC--> <!--HitBTC-->
@ -198,5 +200,10 @@
<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="restore_manual_entries">Restore manual entries</string>
<string name="restore_keys">Restore API keys</string>
<string name="enter_password">Enter password</string>
<string name="password">Password</string>
</resources> </resources>

View File

@ -28,19 +28,30 @@
android:title="@string/pref_title_category_data_backup"> android:title="@string/pref_title_category_data_backup">
<PreferenceScreen android:title="@string/pref_title_export" <PreferenceScreen android:title="@string/pref_title_export"
android:key="export"/> android:key="export"
android:enabled="false"/>
<PreferenceScreen android:title="@string/pref_title_import" <Preference android:title="@string/pref_title_import"
android:key="import"/> android:key="import"/>
</PreferenceCategory> </PreferenceCategory>
<PreferenceCategory <PreferenceCategory
android:title="@string/pref_title_category_other"> android:title="@string/pref_title_category_synchronization">
<Preference <PreferenceScreen
android:fragment="com.herbron.moodl.Activities.SettingsActivity$ExchangePreferenceFragment" android:fragment="com.herbron.moodl.Activities.SettingsActivity$ExchangePreferenceFragment"
android:title="@string/pref_header_exchange" /> android:title="@string/pref_header_exchange"
android:enabled="false"/>
<PreferenceScreen
android:title="@string/pref_header_wallet"
android:enabled="false"/>
</PreferenceCategory>
<PreferenceCategory
android:title="@string/pref_title_category_other">
<PreferenceScreen android:title="@string/pref_title_version" <PreferenceScreen android:title="@string/pref_title_version"
android:key="version"/> android:key="version"/>

View File

@ -7,7 +7,7 @@ buildscript {
jcenter() jcenter()
} }
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:3.1.2' classpath 'com.android.tools.build:gradle:3.1.3'
// NOTE: Do not place your application dependencies here; they belong // NOTE: Do not place your application dependencies here; they belong
@ -19,7 +19,9 @@ allprojects {
repositories { repositories {
google() google()
jcenter() jcenter()
maven { url "https://jitpack.io" } maven {
url "https://jitpack.io"
}
} }
} }