diff --git a/android_app/app/build.gradle b/android_app/app/build.gradle
index 99fbccd7..c65c7e01 100644
--- a/android_app/app/build.gradle
+++ b/android_app/app/build.gradle
@@ -6,7 +6,7 @@ android {
defaultConfig {
applicationId "com.health.openscale"
testApplicationId "com.health.openscale.test"
- minSdkVersion 18
+ minSdkVersion 19
targetSdkVersion 27
versionCode 23
versionName "1.7"
diff --git a/android_app/app/src/main/java/com/health/openscale/core/OpenScale.java b/android_app/app/src/main/java/com/health/openscale/core/OpenScale.java
index e13b6d8d..6b9fe3b4 100644
--- a/android_app/app/src/main/java/com/health/openscale/core/OpenScale.java
+++ b/android_app/app/src/main/java/com/health/openscale/core/OpenScale.java
@@ -49,10 +49,11 @@ import com.health.openscale.core.utils.CsvHelper;
import com.health.openscale.gui.fragments.FragmentUpdateListener;
import java.io.BufferedReader;
-import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Calendar;
@@ -194,6 +195,18 @@ public class OpenScale {
public void deleteScaleUser(int id) {
userDAO.delete(userDAO.get(id));
selectedScaleUser = null;
+
+ SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
+
+ // Remove user specific settings
+ SharedPreferences.Editor editor = prefs.edit();
+ final String prefix = ScaleUser.getPreferenceKey(id, "");
+ for (String key : prefs.getAll().keySet()) {
+ if (key.startsWith(prefix)) {
+ editor.remove(key);
+ }
+ }
+ editor.apply();
}
public void updateScaleUser(ScaleUser user) {
@@ -332,7 +345,7 @@ public class OpenScale {
updateScaleData();
}
- private String getFilenameFromUri(Uri uri) {
+ public String getFilenameFromUri(Uri uri) {
Cursor cursor = context.getContentResolver().query(
uri, null, null, null, null);
cursor.moveToFirst();
@@ -362,9 +375,10 @@ public class OpenScale {
}
}
- public boolean exportData(String filename) {
+ public boolean exportData(Uri uri) {
try {
- CsvHelper.exportTo(new FileWriter(filename), scaleMeasurementList);
+ OutputStream output = context.getContentResolver().openOutputStream(uri);
+ CsvHelper.exportTo(new OutputStreamWriter(output), scaleMeasurementList);
return true;
} catch (IOException e) {
Toast.makeText(context, context.getResources().getString(R.string.error_exporting) + " " + e.getMessage(), Toast.LENGTH_SHORT).show();
diff --git a/android_app/app/src/main/java/com/health/openscale/core/datatypes/ScaleUser.java b/android_app/app/src/main/java/com/health/openscale/core/datatypes/ScaleUser.java
index d99df719..b5d28f8b 100644
--- a/android_app/app/src/main/java/com/health/openscale/core/datatypes/ScaleUser.java
+++ b/android_app/app/src/main/java/com/health/openscale/core/datatypes/ScaleUser.java
@@ -152,6 +152,14 @@ public class ScaleUser {
return Converters.fromKilogram(initialWeight, scaleUnit);
}
+ public static String getPreferenceKey(int userId, String key) {
+ return String.format("user.%d.%s", userId, key);
+ }
+
+ public String getPreferenceKey(String key) {
+ return getPreferenceKey(getId(), key);
+ }
+
@Override
public String toString()
{
diff --git a/android_app/app/src/main/java/com/health/openscale/gui/MainActivity.java b/android_app/app/src/main/java/com/health/openscale/gui/MainActivity.java
index 8f0b723b..119dce65 100644
--- a/android_app/app/src/main/java/com/health/openscale/gui/MainActivity.java
+++ b/android_app/app/src/main/java/com/health/openscale/gui/MainActivity.java
@@ -26,7 +26,6 @@ import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.net.Uri;
import android.os.Bundle;
-import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.preference.PreferenceManager;
@@ -48,7 +47,6 @@ import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
-import android.widget.EditText;
import android.widget.Toast;
import com.health.openscale.BuildConfig;
@@ -81,6 +79,7 @@ public class MainActivity extends AppCompatActivity
private MenuItem bluetoothStatus;
private static final int IMPORT_DATA_REQUEST = 100;
+ private static final int EXPORT_DATA_REQUEST = 101;
private DrawerLayout drawerLayout;
private Toolbar toolbar;
@@ -400,9 +399,7 @@ public class MainActivity extends AppCompatActivity
importCsvFile();
return true;
case R.id.exportData:
- if (PermissionHelper.requestWritePermission(this)) {
- exportCsvFile();
- }
+ exportCsvFile();
return true;
case R.id.shareData:
shareCsvFile();
@@ -556,7 +553,7 @@ public class MainActivity extends AppCompatActivity
else {
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
- intent.setType("text/*");
+ intent.setType("*/*");
startActivityForResult(
Intent.createChooser(intent, getResources().getString(R.string.label_import)),
@@ -564,50 +561,95 @@ public class MainActivity extends AppCompatActivity
}
}
- private void exportCsvFile() {
- AlertDialog.Builder filenameDialog = new AlertDialog.Builder(this);
+ private String getExportFilename(ScaleUser selectedScaleUser) {
+ return String.format("openScale %s.csv", selectedScaleUser.getUserName());
+ }
- filenameDialog.setTitle(getResources().getString(R.string.info_set_filename) + " "
- + Environment.getExternalStorageDirectory().getPath());
+ private void startActionCreateDocumentForExportIntent() {
+ OpenScale openScale = OpenScale.getInstance(getApplicationContext());
+ ScaleUser selectedScaleUser = openScale.getSelectedScaleUser();
+
+ Intent intent = new Intent(Intent.ACTION_CREATE_DOCUMENT);
+ intent.addCategory(Intent.CATEGORY_OPENABLE);
+ intent.setType("text/csv");
+ intent.putExtra(Intent.EXTRA_TITLE, getExportFilename(selectedScaleUser));
+
+ startActivityForResult(intent, EXPORT_DATA_REQUEST);
+ }
+
+ private boolean doExportData(Uri uri) {
+ OpenScale openScale = OpenScale.getInstance(getApplicationContext());
+ if (openScale.exportData(uri)) {
+ String filename = openScale.getFilenameFromUri(uri);
+ Toast.makeText(this,
+ getResources().getString(R.string.info_data_exported) + " " + filename,
+ Toast.LENGTH_SHORT).show();
+ return true;
+ }
+ return false;
+ }
+
+ private String getExportPreferenceKey(ScaleUser selectedScaleUser) {
+ return selectedScaleUser.getPreferenceKey("exportUri");
+ }
+
+ private void exportCsvFile() {
+ OpenScale openScale = OpenScale.getInstance(getApplicationContext());
+ final ScaleUser selectedScaleUser = openScale.getSelectedScaleUser();
final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
- final ScaleUser selectedScaleUser = OpenScale.getInstance(getApplicationContext()).getSelectedScaleUser();
- String exportFilename = prefs.getString("exportFilename" + selectedScaleUser.getId(),
- "openScale_data_" + selectedScaleUser.getUserName() + ".csv");
+ Uri uri;
+ try {
+ String exportUri = prefs.getString(getExportPreferenceKey(selectedScaleUser), "");
+ uri = Uri.parse(exportUri);
+ getContentResolver().takePersistableUriPermission(uri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
+ }
+ catch (Exception ex) {
+ uri = null;
+ }
- final EditText txtFilename = new EditText(this);
- txtFilename.setText(exportFilename);
+ if (uri == null) {
+ startActionCreateDocumentForExportIntent();
+ return;
+ }
- filenameDialog.setView(txtFilename);
+ AlertDialog.Builder exportDialog = new AlertDialog.Builder(this);
+ exportDialog.setTitle(R.string.label_export);
+ exportDialog.setMessage(getResources().getString(R.string.label_export_overwrite,
+ openScale.getFilenameFromUri(uri)));
- filenameDialog.setPositiveButton(getResources().getString(R.string.label_export), new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int id) {
- String fullPath = Environment.getExternalStorageDirectory().getPath() + "/" + txtFilename.getText().toString();
-
- if (OpenScale.getInstance(getApplicationContext()).exportData(fullPath)) {
- prefs.edit().putString("exportFilename" + selectedScaleUser.getId(), txtFilename.getText().toString()).commit();
- Toast.makeText(getApplicationContext(), getResources().getString(
- R.string.info_data_exported) + " " + fullPath, Toast.LENGTH_SHORT).show();
+ final Uri exportUri = uri;
+ exportDialog.setPositiveButton(R.string.label_yes, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ if (!doExportData(exportUri)) {
+ prefs.edit().remove(getExportPreferenceKey(selectedScaleUser)).apply();
}
}
});
-
- filenameDialog.setNegativeButton(getResources().getString(R.string.label_cancel), new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int id) {
+ exportDialog.setNegativeButton(R.string.label_no, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ startActionCreateDocumentForExportIntent();
+ }
+ });
+ exportDialog.setNeutralButton(R.string.label_cancel, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
- filenameDialog.show();
+ exportDialog.show();
}
private void shareCsvFile() {
final ScaleUser selectedScaleUser = OpenScale.getInstance(getApplicationContext()).getSelectedScaleUser();
File shareFile = new File(getApplicationContext().getCacheDir(),
- String.format("openScale %s.csv", selectedScaleUser.getUserName()));
- if (!OpenScale.getInstance(getApplicationContext()).exportData(shareFile.getPath())) {
+ getExportFilename(selectedScaleUser));
+ if (!OpenScale.getInstance(getApplicationContext()).exportData(Uri.fromFile(shareFile))) {
return;
}
@@ -629,8 +671,30 @@ public class MainActivity extends AppCompatActivity
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
- if (requestCode == IMPORT_DATA_REQUEST && resultCode == RESULT_OK && data != null) {
- OpenScale.getInstance(getApplicationContext()).importData(data.getData());
+ if (resultCode != RESULT_OK || data == null) {
+ return;
+ }
+
+ OpenScale openScale = OpenScale.getInstance(getApplicationContext());
+
+ switch (requestCode) {
+ case IMPORT_DATA_REQUEST:
+ openScale.importData(data.getData());
+ break;
+ case EXPORT_DATA_REQUEST:
+ if (doExportData(data.getData())) {
+ try {
+ getContentResolver().takePersistableUriPermission(
+ data.getData(), Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
+ String key = getExportPreferenceKey(openScale.getSelectedScaleUser());
+ PreferenceManager.getDefaultSharedPreferences(this).edit()
+ .putString(key, data.getData().toString()).apply();
+ }
+ catch (Exception ex) {
+ // Ignore
+ }
+ }
+ break;
}
}
@@ -646,13 +710,6 @@ public class MainActivity extends AppCompatActivity
permissionGranted = false;
}
break;
- case PermissionHelper.PERMISSIONS_REQUEST_ACCESS_WRITE_STORAGE:
- if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
- exportCsvFile();
- } else {
- permissionGranted = false;
- }
- break;
}
if (!permissionGranted) {
diff --git a/android_app/app/src/main/res/values-ca/strings.xml b/android_app/app/src/main/res/values-ca/strings.xml
index 3713dcd6..1e50722f 100644
--- a/android_app/app/src/main/res/values-ca/strings.xml
+++ b/android_app/app/src/main/res/values-ca/strings.xml
@@ -78,7 +78,6 @@
Totes les entrades eliminades
Dades exportades a
Dades importades de
- Establir nom d\'arxiu a
Valor en cm
Valor en
Comentari opcional
diff --git a/android_app/app/src/main/res/values-de/strings.xml b/android_app/app/src/main/res/values-de/strings.xml
index c48e2b54..4e24dd87 100644
--- a/android_app/app/src/main/res/values-de/strings.xml
+++ b/android_app/app/src/main/res/values-de/strings.xml
@@ -18,7 +18,6 @@
ist nicht verfügbar
Kein Benutzer vorhanden. Bitte erzeugen Sie ein neuen Benutzer unter Einstellungen.
am
- Setzte Dateiname auf
Geburtstag
Suche nach Waage beim Start
Bluetooth
diff --git a/android_app/app/src/main/res/values-es/strings.xml b/android_app/app/src/main/res/values-es/strings.xml
index a71bb47e..71961e04 100644
--- a/android_app/app/src/main/res/values-es/strings.xml
+++ b/android_app/app/src/main/res/values-es/strings.xml
@@ -78,7 +78,6 @@
Todas las entradas borradas
Datos exportados a
Datos importados de
- Establecer nombre de archivo a
Introduzca valor en cm
Introduzca valor en
Introduzca un comentario opcional
diff --git a/android_app/app/src/main/res/values-fr/strings.xml b/android_app/app/src/main/res/values-fr/strings.xml
index be1449cc..4180d988 100644
--- a/android_app/app/src/main/res/values-fr/strings.xml
+++ b/android_app/app/src/main/res/values-fr/strings.xml
@@ -72,7 +72,6 @@
Toutes les entrées ont été supprimées de la base de données
Données exportées vers
Donnéees importées depuis
- Définir le nom du fichier vers
Entrez la valeur en cm
Entrez la valeur en
Ajouter un commentaire optionnel
diff --git a/android_app/app/src/main/res/values-ja/strings.xml b/android_app/app/src/main/res/values-ja/strings.xml
index 64fdc0e7..767d01ee 100644
--- a/android_app/app/src/main/res/values-ja/strings.xml
+++ b/android_app/app/src/main/res/values-ja/strings.xml
@@ -54,7 +54,6 @@
でした -
ユーザーは存在しません!設定で新しいユーザを入れてください
ユーザーの追加する
- にファイル名を設定
メモの上にデータ点
表示されています
表示されていません
diff --git a/android_app/app/src/main/res/values-nl/strings.xml b/android_app/app/src/main/res/values-nl/strings.xml
index 66485982..ed3f06c0 100644
--- a/android_app/app/src/main/res/values-nl/strings.xml
+++ b/android_app/app/src/main/res/values-nl/strings.xml
@@ -80,7 +80,6 @@
Alle database vermeldingen verwijderd
Data geexporteerd naar
Data geinporteerd van
- Zet bestandsnaam op
Geef waarde op cm\'s in
Geef waaarde op
Voeg een optionele opmerking toe.
diff --git a/android_app/app/src/main/res/values-pl/strings.xml b/android_app/app/src/main/res/values-pl/strings.xml
index c0ecdc96..0ded86a5 100644
--- a/android_app/app/src/main/res/values-pl/strings.xml
+++ b/android_app/app/src/main/res/values-pl/strings.xml
@@ -75,7 +75,6 @@
Wszytkie wpisy w bazie danych usunięte
Dane wyeksportowane do
Dane zaimportowane z
- Ustaw nazwę pliku na
Wprowadź wartość w cm
Wprowadź wartość w
Wprowadź opcjonlany komentarz
diff --git a/android_app/app/src/main/res/values-pt/strings.xml b/android_app/app/src/main/res/values-pt/strings.xml
index f7a34d45..152e4cf1 100644
--- a/android_app/app/src/main/res/values-pt/strings.xml
+++ b/android_app/app/src/main/res/values-pt/strings.xml
@@ -44,7 +44,6 @@
Valor não pode ser processado
em
Nenhum usuário existe. Por favor, crie um novo usuário em Configurações.
- Definir nome de arquivo para
Por favor suba na balança para medidas de referência
Adicionar usuário
Backup
diff --git a/android_app/app/src/main/res/values-sk/strings.xml b/android_app/app/src/main/res/values-sk/strings.xml
index 33cbf0da..6d3ddb4b 100644
--- a/android_app/app/src/main/res/values-sk/strings.xml
+++ b/android_app/app/src/main/res/values-sk/strings.xml
@@ -1,6 +1,6 @@
- Prehľad
+ Prehľad
Graf
Tabuľka
Štatistiky
@@ -64,7 +64,6 @@
Všetkých položky boli vymazané z databázy
Údaje boli exportované do
Údaje boli importované z
- Nastaviť názov súboru na
Zadajte hodnotu v cm
Zadajte hodnotu v palcoch
Zadajte voliteľný komentár
diff --git a/android_app/app/src/main/res/values-sv/strings.xml b/android_app/app/src/main/res/values-sv/strings.xml
index 768de44e..d7aecd25 100644
--- a/android_app/app/src/main/res/values-sv/strings.xml
+++ b/android_app/app/src/main/res/values-sv/strings.xml
@@ -80,7 +80,6 @@
Alla databasposter borttagna
Data exporterad till
Data importerad från
- Sätt filnamn till
Ange värde i cm
Ange värde i
Ange en frivillig kommentar
@@ -187,5 +186,6 @@
Ställ in standardordning
Veckovy
+ Skriv över föregående export \"%s\"?
diff --git a/android_app/app/src/main/res/values-tr/strings.xml b/android_app/app/src/main/res/values-tr/strings.xml
index 84fa4788..7e954e48 100644
--- a/android_app/app/src/main/res/values-tr/strings.xml
+++ b/android_app/app/src/main/res/values-tr/strings.xml
@@ -76,7 +76,6 @@
Veri tabaný giriþi silindi
Veri dýþarý aktarma
Veri içeri aktarma
- Dosya adýný ayarla
Deðeri cm olarak girin
Ýçine deðer girin
Ýsteðebaðlý açýklama girin
diff --git a/android_app/app/src/main/res/values/strings.xml b/android_app/app/src/main/res/values/strings.xml
index d45e0d5f..b3d5023e 100644
--- a/android_app/app/src/main/res/values/strings.xml
+++ b/android_app/app/src/main/res/values/strings.xml
@@ -88,7 +88,6 @@
All database entries deleted
Data exported to
Data imported from
- Set filename to
Enter value in cm
Enter value in
Enter an optional comment
@@ -211,6 +210,7 @@
Measurement order
Press and hold to reorder
Set default order
+ Overwrite previous export \"%s\"?