diff --git a/app/build.gradle b/app/build.gradle index c3ae65c..4c2a881 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -43,19 +43,18 @@ android { } } +apply plugin: 'com.getkeepsafe.dexcount' + dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) compile 'com.android.support:support-v4:23.2.1' compile 'com.android.support:appcompat-v7:23.2.1' compile 'com.android.support:design:23.2.1' - // View annotation bindings - compile 'com.jakewharton:butterknife:7.0.1' - // Dependency injection tool - compile 'com.google.dagger:dagger:2.0.1' - // Charts - compile 'com.github.PhilJay:MPAndroidChart:v2.2.4' - // Advanced logging tool - compile 'com.jakewharton.timber:timber:4.1.2' + + compile 'com.jakewharton:butterknife:7.0.1' // View annotation bindings + compile 'com.google.dagger:dagger:2.0.1' // Dependency injection tool + compile 'com.github.PhilJay:MPAndroidChart:v2.2.4' // Charts + compile 'com.jakewharton.timber:timber:4.1.2' // Advanced logging tool apt 'com.google.dagger:dagger-compiler:2.0.1' provided 'org.glassfish:javax.annotation:10.0-b28' diff --git a/app/libs/dropbox-android-sdk-1.6.3.jar b/app/libs/dropbox-android-sdk-1.6.3.jar new file mode 100644 index 0000000..1a0ee36 Binary files /dev/null and b/app/libs/dropbox-android-sdk-1.6.3.jar differ diff --git a/app/libs/json_simple-1.1.jar b/app/libs/json_simple-1.1.jar new file mode 100644 index 0000000..f395f41 Binary files /dev/null and b/app/libs/json_simple-1.1.jar differ diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 78b87df..151b6ab 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -2,6 +2,9 @@ + + + - + + + + + + + + + + dbApi; + + @Bind(R.id.btn_backup_now) + View btnBackupNow; + @Bind(R.id.list_view) + ListView listView; + + @Override + protected int getContentViewId() { + return R.layout.activity_backup; + } + + @Override + protected boolean initData() { + getAppComponent().inject(BackupActivity.this); + + AppKeyPair appKeys = new AppKeyPair(APP_KEY, APP_SECRET); + String accessToken = preferenceController.readDropboxAccessToken(); + + AndroidAuthSession session = new AndroidAuthSession(appKeys); + dbApi = new DropboxAPI<>(session); + if (accessToken == null) dbApi.getSession().startOAuth2Authentication(BackupActivity.this); + else { + dbApi.getSession().setOAuth2AccessToken(accessToken); + fetchBackups(); + } + + return super.initData(); + } + + @Override + protected void initViews() { + super.initViews(); + btnBackupNow.setEnabled(preferenceController.readDropboxAccessToken() != null); + } + + @Override + protected void onResume() { + super.onResume(); + + if (dbApi.getSession().authenticationSuccessful()) { + try { + // Required to complete auth, sets the access token on the session + dbApi.getSession().finishAuthentication(); + preferenceController.writeDropboxAccessToken(dbApi.getSession().getOAuth2AccessToken()); + btnBackupNow.setEnabled(true); + fetchBackups(); + } catch (IllegalStateException e) { + Timber.e("Error authenticating: %s", e.getMessage()); + } + } + } + + @OnClick(R.id.btn_backup_now) + public void backupNow() { + startProgress(); + backupController.makeBackup(dbApi, new BackupController.OnBackupListener() { + @Override + public void onBackupSuccess() { + Timber.d("Backup success."); + stopProgress(); + fetchBackups(); + } + + @Override + public void onBackupFailure(String reason) { + Timber.d("Backup failure."); + stopProgress(); + showToast(R.string.failed_create_backup); + + if (BackupController.OnBackupListener.ERROR_AUTHENTICATION.equals(reason)) logout(); + } + }); + } + + @OnItemClick(R.id.list_view) + public void restoreBackupClicked(int position) { + final String backupName = listView.getAdapter().getItem(position).toString(); + + AlertDialog.Builder builder = new AlertDialog.Builder(BackupActivity.this); + builder.setTitle(getString(R.string.warning)); + builder.setMessage(getString(R.string.want_erase_and_restore, backupName)); + builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + restoreBackup(backupName); + } + }); + builder.setNegativeButton(android.R.string.cancel, null); + builder.show(); + } + + private void restoreBackup(final String backupName) { + startProgress(); + backupController.restoreBackup(dbApi, backupName, new BackupController.OnRestoreBackupListener() { + @Override + public void onRestoreSuccess() { + Timber.d("Restore success."); + stopProgress(); + + AlertDialog.Builder builder = new AlertDialog.Builder(BackupActivity.this); + builder.setTitle(getString(R.string.backup_is_restored)); + builder.setMessage(getString(R.string.backup_restored, backupName)); + builder.setOnDismissListener(new DialogInterface.OnDismissListener() { + @Override + public void onDismiss(DialogInterface dialog) { + MtApp.get().buildAppComponent(); + setResult(RESULT_OK); + finish(); + } + }); + builder.setPositiveButton(android.R.string.ok, null); + builder.show(); + } + + @Override + public void onRestoreFailure(String reason) { + Timber.d("Restore failure."); + stopProgress(); + showToast(R.string.failed_restore_backup); + + if (BackupController.OnRestoreBackupListener.ERROR_AUTHENTICATION.equals(reason)) + logout(); + } + }); + } + + private void fetchBackups() { + startProgress(); + backupController.fetchBackups(dbApi, new BackupController.OnFetchBackupListListener() { + @Override + public void onBackupsFetched(@NonNull List backupList) { + stopProgress(); + ArrayAdapter adapter = new ArrayAdapter<>(BackupActivity.this, + android.R.layout.simple_list_item_1, backupList); + listView.setAdapter(adapter); + } + }); + } + + private void logout() { + preferenceController.writeDropboxAccessToken(null); + dbApi.getSession().startOAuth2Authentication(BackupActivity.this); + btnBackupNow.setEnabled(false); + } +} diff --git a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/external/ExportActivity.java b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/external/ExportActivity.java deleted file mode 100644 index e7023ec..0000000 --- a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/external/ExportActivity.java +++ /dev/null @@ -1,84 +0,0 @@ -package com.blogspot.e_kanivets.moneytracker.activity.external; - -import android.content.Intent; -import android.net.Uri; -import android.support.annotation.NonNull; -import android.support.v4.content.FileProvider; - -import com.blogspot.e_kanivets.moneytracker.R; -import com.blogspot.e_kanivets.moneytracker.activity.base.BaseBackActivity; -import com.blogspot.e_kanivets.moneytracker.controller.external.ExportController; - -import java.io.File; -import java.io.FileNotFoundException; -import java.io.PrintWriter; -import java.util.List; - -import javax.inject.Inject; - -import butterknife.OnClick; -import timber.log.Timber; - -public class ExportActivity extends BaseBackActivity { - @SuppressWarnings("unused") - private static final String TAG = "ExportActivity"; - - private static final String DEFAULT_EXPORT_FILE_NAME = "money_tracker.csv"; - - @Inject - ExportController exportController; - - @Override - protected int getContentViewId() { - return R.layout.activity_export; - } - - @Override - protected boolean initData() { - boolean result = super.initData(); - getAppComponent().inject(ExportActivity.this); - return result; - } - - @OnClick(R.id.btn_export) - public void exportRecords() { - List records = exportController.getRecordsForExport(0, Long.MAX_VALUE); - - File exportDir = new File(getCacheDir(), "export"); - boolean exportDirCreated = exportDir.mkdirs(); - Timber.d("ExportDirCreated: %b", exportDirCreated); - - File outFile; - if (exportDir.exists()) outFile = new File(exportDir, DEFAULT_EXPORT_FILE_NAME); - else return; - - PrintWriter pw = null; - try { - pw = new PrintWriter(outFile); - } catch (FileNotFoundException e) { - e.printStackTrace(); - } - - if (pw != null) { - for (String record : records) { - pw.println(record); - pw.flush(); - } - - pw.flush(); - pw.close(); - - shareExportedRecords(outFile); - } - } - - private void shareExportedRecords(@NonNull File exportFile) { - Uri fileUri = FileProvider.getUriForFile(ExportActivity.this, getPackageName(), exportFile); - - Intent sendIntent = new Intent(); - sendIntent.setAction(Intent.ACTION_SEND); - sendIntent.putExtra(Intent.EXTRA_STREAM, fileUri); - sendIntent.setType("text/plain"); - startActivity(Intent.createChooser(sendIntent, "Share exported records")); - } -} diff --git a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/external/ImportActivity.java b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/external/ImportExportActivity.java similarity index 55% rename from app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/external/ImportActivity.java rename to app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/external/ImportExportActivity.java index 318b9b7..4026285 100644 --- a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/external/ImportActivity.java +++ b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/external/ImportExportActivity.java @@ -1,6 +1,10 @@ package com.blogspot.e_kanivets.moneytracker.activity.external; +import android.content.Intent; +import android.net.Uri; import android.os.AsyncTask; +import android.support.annotation.NonNull; +import android.support.v4.content.FileProvider; import android.support.v7.app.AlertDialog; import android.view.Menu; import android.view.MenuItem; @@ -8,32 +12,41 @@ import com.blogspot.e_kanivets.moneytracker.R; import com.blogspot.e_kanivets.moneytracker.activity.base.BaseBackActivity; +import com.blogspot.e_kanivets.moneytracker.controller.external.ExportController; import com.blogspot.e_kanivets.moneytracker.controller.external.ImportController; import com.blogspot.e_kanivets.moneytracker.entity.data.Record; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.PrintWriter; import java.util.List; import javax.inject.Inject; import butterknife.Bind; import butterknife.OnClick; +import timber.log.Timber; + +public class ImportExportActivity extends BaseBackActivity { + private static final String DEFAULT_EXPORT_FILE_NAME = "money_tracker.csv"; -public class ImportActivity extends BaseBackActivity { @Inject ImportController importController; + @Inject + ExportController exportController; @Bind(R.id.et_import_data) EditText etImportData; @Override protected int getContentViewId() { - return R.layout.activity_import; + return R.layout.activity_import_export; } @Override protected boolean initData() { boolean result = super.initData(); - getAppComponent().inject(ImportActivity.this); + getAppComponent().inject(ImportExportActivity.this); return result; } @@ -47,7 +60,7 @@ public boolean onCreateOptionsMenu(Menu menu) { public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.action_help: - AlertDialog.Builder builder = new AlertDialog.Builder(ImportActivity.this); + AlertDialog.Builder builder = new AlertDialog.Builder(ImportExportActivity.this); builder.setTitle(R.string.help) .setMessage(R.string.import_help) .setPositiveButton(android.R.string.ok, null) @@ -82,9 +95,50 @@ protected void onPostExecute(Integer recordCount) { stopProgress(); showToast(getString(R.string.records_imported, recordCount)); setResult(RESULT_OK); - finish(); } }; importTask.execute(); } + + @OnClick(R.id.btn_export) + public void exportRecords() { + List records = exportController.getRecordsForExport(0, Long.MAX_VALUE); + + File exportDir = new File(getCacheDir(), "export"); + boolean exportDirCreated = exportDir.mkdirs(); + Timber.d("ExportDirCreated: %b", exportDirCreated); + + File outFile; + if (exportDir.exists()) outFile = new File(exportDir, DEFAULT_EXPORT_FILE_NAME); + else return; + + PrintWriter pw = null; + try { + pw = new PrintWriter(outFile); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } + + if (pw != null) { + for (String record : records) { + pw.println(record); + pw.flush(); + } + + pw.flush(); + pw.close(); + + shareExportedRecords(outFile); + } + } + + private void shareExportedRecords(@NonNull File exportFile) { + Uri fileUri = FileProvider.getUriForFile(ImportExportActivity.this, getPackageName(), exportFile); + + Intent sendIntent = new Intent(); + sendIntent.setAction(Intent.ACTION_SEND); + sendIntent.putExtra(Intent.EXTRA_STREAM, fileUri); + sendIntent.setType("text/plain"); + startActivity(Intent.createChooser(sendIntent, "Share exported records")); + } } diff --git a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/record/MainActivity.java b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/record/MainActivity.java index 9e235cf..5a2a875 100644 --- a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/record/MainActivity.java +++ b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/activity/record/MainActivity.java @@ -41,7 +41,7 @@ public class MainActivity extends BaseDrawerActivity { @SuppressWarnings("unused") private static final String TAG = "MainActivity"; - private static final int REQUEST_ACTION_RECORD = 1; + private static final int REQUEST_ACTION_RECORD = 6; private List recordList; private Period period; @@ -158,6 +158,11 @@ public void onActivityResult(int requestCode, int resultCode, Intent data) { update(); break; + case REQUEST_BACKUP: + getAppComponent().inject(MainActivity.this); + update(); + break; + default: break; } diff --git a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/controller/BackupController.java b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/controller/BackupController.java new file mode 100644 index 0000000..9d0bddd --- /dev/null +++ b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/controller/BackupController.java @@ -0,0 +1,277 @@ +package com.blogspot.e_kanivets.moneytracker.controller; + +import android.os.AsyncTask; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; + +import com.dropbox.client2.DropboxAPI; +import com.dropbox.client2.android.AndroidAuthSession; +import com.dropbox.client2.exception.DropboxException; +import com.dropbox.client2.exception.DropboxUnlinkedException; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * Controller class to encapsulate backup logic. + * Created on 8/10/16. + * + * @author Evgenii Kanivets + */ +public class BackupController { + private FormatController formatController; + private String filesDir; + + public BackupController(FormatController formatController, String filesDir) { + this.formatController = formatController; + this.filesDir = filesDir; + } + + public void makeBackup(@NonNull DropboxAPI dbApi, + @Nullable OnBackupListener listener) { + FileInputStream fileInputStream = readAppDb(); + long fileLength = readAppDbFileLength(); + if (fileInputStream == null) return; + + DropboxBackupAsyncTask asyncTask = new DropboxBackupAsyncTask(dbApi, + formatController.formatDateAndTime(System.currentTimeMillis()), + fileInputStream, fileLength, listener); + asyncTask.execute(); + } + + public void restoreBackup(@NonNull DropboxAPI dbApi, @NonNull String backupName, + @Nullable final OnRestoreBackupListener listener) { + final File file = new File(getRestoreFileName()); + FileOutputStream outputStream = null; + try { + outputStream = new FileOutputStream(file); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } + + if (outputStream == null) { + if (listener != null) listener.onRestoreFailure(null); + } else { + final FileOutputStream finalOutputStream = outputStream; + DropboxRestoreBackupAsyncTask asyncTask = new DropboxRestoreBackupAsyncTask(dbApi, + backupName, outputStream, new OnRestoreBackupListener() { + @Override + public void onRestoreSuccess() { + try { + finalOutputStream.close(); + } catch (IOException e) { + if (listener != null) listener.onRestoreFailure(null); + e.printStackTrace(); + } + + if (file.exists() && file.length() != 0) { + boolean renamed = file.renameTo(new File(getAppDbFileName())); + if (listener != null) { + if (renamed) listener.onRestoreSuccess(); + else listener.onRestoreFailure(null); + } + } + } + + @Override + public void onRestoreFailure(String reason) { + if (listener != null) listener.onRestoreFailure(reason); + } + }); + asyncTask.execute(); + } + } + + public void fetchBackups(@NonNull DropboxAPI dbApi, + @Nullable OnFetchBackupListListener listener) { + DropboxFetchBackupListAsyncTask asyncTask = new DropboxFetchBackupListAsyncTask(dbApi, listener); + asyncTask.execute(); + } + + @Nullable + private FileInputStream readAppDb() { + File dbFile = new File(getAppDbFileName()); + FileInputStream fis = null; + + try { + fis = new FileInputStream(dbFile); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } + + return fis; + } + + private long readAppDbFileLength() { + File dbFile = new File(getAppDbFileName()); + + if (dbFile.exists()) return dbFile.length(); + else return 0; + } + + @NonNull + private String getAppDbFileName() { + return filesDir + "/databases/database"; + } + + @NonNull + private String getRestoreFileName() { + return getAppDbFileName() + ".restore"; + } + + private class DropboxBackupAsyncTask extends AsyncTask { + private DropboxAPI dbApi; + private String fileName; + private FileInputStream fileInputStream; + private long fileLength; + + @Nullable + private OnBackupListener listener; + + public DropboxBackupAsyncTask(DropboxAPI dbApi, String fileName, + FileInputStream fileInputStream, long fileLength, + @Nullable OnBackupListener listener) { + this.dbApi = dbApi; + this.fileName = fileName; + this.fileInputStream = fileInputStream; + this.fileLength = fileLength; + this.listener = listener; + } + + @Override + protected String doInBackground(Void... params) { + DropboxAPI.Entry response = null; + try { + response = dbApi.putFile(fileName, fileInputStream, fileLength, null, null); + } catch (DropboxUnlinkedException e) { + e.printStackTrace(); + return OnBackupListener.ERROR_AUTHENTICATION; + } catch (DropboxException e) { + e.printStackTrace(); + } + + if (response == null) return null; + else return OnBackupListener.SUCCESS; + } + + @Override + protected void onPostExecute(String result) { + super.onPostExecute(result); + if (listener == null) return; + + if (OnBackupListener.SUCCESS.equals(result)) listener.onBackupSuccess(); + else listener.onBackupFailure(result); + } + } + + private class DropboxFetchBackupListAsyncTask extends AsyncTask, List> { + private DropboxAPI dbApi; + + @Nullable + private OnFetchBackupListListener listener; + + public DropboxFetchBackupListAsyncTask(DropboxAPI dbApi, + @Nullable OnFetchBackupListListener listener) { + this.dbApi = dbApi; + this.listener = listener; + } + + @Override + protected List doInBackground(Void... params) { + List entryList = new ArrayList<>(); + List backupList = new ArrayList<>(); + + try { + DropboxAPI.Entry entry = dbApi.metadata("/", -1, null, true, null); + entryList = entry.contents; + } catch (DropboxException e) { + e.printStackTrace(); + } + + for (DropboxAPI.Entry entry : entryList) { + backupList.add(entry.fileName()); + } + + return backupList; + } + + @Override + protected void onPostExecute(List backupList) { + super.onPostExecute(backupList); + if (listener == null) return; + + Collections.reverse(backupList); + listener.onBackupsFetched(backupList); + } + } + + private class DropboxRestoreBackupAsyncTask extends AsyncTask { + private DropboxAPI dbApi; + private String backupName; + private FileOutputStream outputStream; + + @Nullable + private OnRestoreBackupListener listener; + + public DropboxRestoreBackupAsyncTask(DropboxAPI dbApi, String backupName, + FileOutputStream outputStream, + @Nullable OnRestoreBackupListener listener) { + this.dbApi = dbApi; + this.backupName = backupName; + this.outputStream = outputStream; + this.listener = listener; + } + + @Override + protected String doInBackground(Void... params) { + DropboxAPI.DropboxFileInfo info = null; + try { + info = dbApi.getFile(backupName, null, outputStream, null); + } catch (DropboxUnlinkedException e) { + e.printStackTrace(); + return OnRestoreBackupListener.ERROR_AUTHENTICATION; + } catch (DropboxException e) { + e.printStackTrace(); + } + + if (info == null) return null; + else return OnBackupListener.SUCCESS; + } + + @Override + protected void onPostExecute(String result) { + super.onPostExecute(result); + if (listener == null) return; + + if (OnBackupListener.SUCCESS.equals(result)) listener.onRestoreSuccess(); + else listener.onRestoreFailure(result); + } + } + + public interface OnBackupListener { + String SUCCESS = "success"; + String ERROR_AUTHENTICATION = "error_authentication"; + + void onBackupSuccess(); + + void onBackupFailure(String reason); + } + + public interface OnFetchBackupListListener { + void onBackupsFetched(@NonNull List backupList); + } + + public interface OnRestoreBackupListener { + String ERROR_AUTHENTICATION = "error_authentication"; + + void onRestoreSuccess(); + + void onRestoreFailure(String reason); + } +} diff --git a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/controller/PreferenceController.java b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/controller/PreferenceController.java index c342ee7..a3130f3 100644 --- a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/controller/PreferenceController.java +++ b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/controller/PreferenceController.java @@ -21,6 +21,7 @@ public class PreferenceController { private static final String KEY_FIRST_TS = "key_first_ts"; private static final String KEY_LAST_TS = "key_last_ts"; private static final String KEY_PERIOD_TYPE = "key_period_type"; + private static final String KEY_DROPBOX_ACCESS_TOKEN = "key_dropbox_access_token"; private static final int RATE_PERIOD = 5; @@ -79,6 +80,14 @@ public void writePeriodType(String periodType) { editor.apply(); } + public void writeDropboxAccessToken(String accessToken) { + SharedPreferences preferences = getDefaultPrefs(); + SharedPreferences.Editor editor = preferences.edit(); + + editor.putString(KEY_DROPBOX_ACCESS_TOKEN, accessToken); + editor.apply(); + } + public long readDefaultAccountId() { String defaultAccountPref = context.getString(R.string.pref_default_account); SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context); @@ -115,6 +124,11 @@ public String readPeriodType() { return getDefaultPrefs().getString(KEY_PERIOD_TYPE, null); } + @Nullable + public String readDropboxAccessToken() { + return getDefaultPrefs().getString(KEY_DROPBOX_ACCESS_TOKEN, null); + } + private SharedPreferences getDefaultPrefs() { return context.getSharedPreferences(context.getPackageName(), Context.MODE_PRIVATE); } diff --git a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/di/AppComponent.java b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/di/AppComponent.java index aeac91e..b3894ec 100644 --- a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/di/AppComponent.java +++ b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/di/AppComponent.java @@ -1,8 +1,8 @@ package com.blogspot.e_kanivets.moneytracker.di; import com.blogspot.e_kanivets.moneytracker.activity.ChartsActivity; -import com.blogspot.e_kanivets.moneytracker.activity.external.ExportActivity; -import com.blogspot.e_kanivets.moneytracker.activity.external.ImportActivity; +import com.blogspot.e_kanivets.moneytracker.activity.external.BackupActivity; +import com.blogspot.e_kanivets.moneytracker.activity.external.ImportExportActivity; import com.blogspot.e_kanivets.moneytracker.activity.ReportActivity; import com.blogspot.e_kanivets.moneytracker.activity.SettingsActivity; import com.blogspot.e_kanivets.moneytracker.activity.account.AccountsActivity; @@ -50,14 +50,14 @@ public interface AppComponent { void inject(TransferActivity transferActivity); - void inject(ImportActivity importActivity); - - void inject(ExportActivity exportActivity); + void inject(ImportExportActivity importExportActivity); void inject(ReportActivity reportActivity); void inject(ChartsActivity chartsActivity); + void inject(BackupActivity backupActivity); + void inject(SettingsActivity.SettingsFragment settingsFragment); void inject(AccountsSummaryPresenter accountsSummaryPresenter); diff --git a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/di/module/ControllerModule.java b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/di/module/ControllerModule.java index 48163b5..d54f1be 100644 --- a/app/src/main/java/com/blogspot/e_kanivets/moneytracker/di/module/ControllerModule.java +++ b/app/src/main/java/com/blogspot/e_kanivets/moneytracker/di/module/ControllerModule.java @@ -3,6 +3,7 @@ import android.content.Context; import android.support.annotation.NonNull; +import com.blogspot.e_kanivets.moneytracker.controller.BackupController; import com.blogspot.e_kanivets.moneytracker.controller.external.ExportController; import com.blogspot.e_kanivets.moneytracker.controller.FormatController; import com.blogspot.e_kanivets.moneytracker.controller.PeriodController; @@ -122,4 +123,11 @@ public ExportController providesExportController(RecordController recordControll public ImportController providesImportController(RecordController recordController) { return new ImportController(recordController); } + + @Provides + @NonNull + @Singleton + public BackupController providesBackupController(FormatController formatController) { + return new BackupController(formatController, context.getApplicationInfo().dataDir); + } } diff --git a/app/src/main/res/drawable/ic_import.xml b/app/src/main/res/drawable/ic_backup.xml similarity index 58% rename from app/src/main/res/drawable/ic_import.xml rename to app/src/main/res/drawable/ic_backup.xml index 22ee01c..8235e92 100644 --- a/app/src/main/res/drawable/ic_import.xml +++ b/app/src/main/res/drawable/ic_backup.xml @@ -9,5 +9,5 @@ tools:targetApi="kitkat"> + android:pathData="M12,3A9,9 0,0 0,3 12H0L4,16L8,12H5A7,7 0,0 1,12 5A7,7 0,0 1,19 12A7,7 0,0 1,12 19C10.5,19 9.09,18.5 7.94,17.7L6.5,19.14C8.04,20.3 9.94,21 12,21A9,9 0,0 0,21 12A9,9 0,0 0,12 3M14,12A2,2 0,0 0,12 10A2,2 0,0 0,10 12A2,2 0,0 0,12 14A2,2 0,0 0,14 12Z" /> diff --git a/app/src/main/res/drawable/ic_export.xml b/app/src/main/res/drawable/ic_import_export.xml similarity index 60% rename from app/src/main/res/drawable/ic_export.xml rename to app/src/main/res/drawable/ic_import_export.xml index dfe4bbd..0fb4dfb 100644 --- a/app/src/main/res/drawable/ic_export.xml +++ b/app/src/main/res/drawable/ic_import_export.xml @@ -9,5 +9,5 @@ tools:targetApi="kitkat"> + android:pathData="M19,8L15,12H18A6,6 0,0 1,12 18C11,18 10.03,17.75 9.2,17.3L7.74,18.76C8.97,19.54 10.43,20 12,20A8,8 0,0 0,20 12H23M6,12A6,6 0,0 1,12 6C13,6 13.97,6.25 14.8,6.7L16.26,5.24C15.03,4.46 13.57,4 12,4A8,8 0,0 0,4 12H1L5,16L9,12" /> diff --git a/app/src/main/res/layout/activity_import.xml b/app/src/main/res/layout/activity_backup.xml similarity index 68% rename from app/src/main/res/layout/activity_import.xml rename to app/src/main/res/layout/activity_backup.xml index 25ecf46..adc8bc1 100644 --- a/app/src/main/res/layout/activity_import.xml +++ b/app/src/main/res/layout/activity_backup.xml @@ -5,7 +5,7 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:fitsSystemWindows="true" - tools:context=".activity.external.ImportActivity"> + tools:context="com.blogspot.e_kanivets.moneytracker.activity.external.BackupActivity"> - + android:layout_weight="1" />