mirror of
https://github.com/russok/FitoTrack.git
synced 2025-10-28 00:02:11 -07:00
#29 Option to save backup to internal storage
This commit is contained in:
parent
a36fc3ae71
commit
f71c75f180
@ -82,6 +82,9 @@ dependencies {
|
||||
implementation 'stax:stax-api:1.0.1'
|
||||
implementation 'com.fasterxml.jackson.dataformat:jackson-dataformat-xml:2.9.8'
|
||||
|
||||
// File Utils
|
||||
implementation 'commons-io:commons-io:2.6'
|
||||
|
||||
// Upload to OSM
|
||||
implementation('de.westnordost:osmapi-traces:1.0')
|
||||
configurations {
|
||||
|
||||
@ -27,6 +27,7 @@
|
||||
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
|
||||
|
||||
<application
|
||||
|
||||
@ -19,17 +19,14 @@
|
||||
|
||||
package de.tadris.fitness.activity;
|
||||
|
||||
import android.Manifest;
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.util.Log;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.util.TypedValue;
|
||||
|
||||
import androidx.annotation.StringRes;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import androidx.core.app.ActivityCompat;
|
||||
|
||||
import de.tadris.fitness.R;
|
||||
|
||||
@ -42,23 +39,6 @@ abstract public class FitoTrackActivity extends Activity {
|
||||
return value.data;
|
||||
}
|
||||
|
||||
void shareFile(Uri uri) {
|
||||
Intent intentShareFile = new Intent(Intent.ACTION_SEND);
|
||||
intentShareFile.setDataAndType(uri, getContentResolver().getType(uri));
|
||||
intentShareFile.putExtra(Intent.EXTRA_STREAM, uri);
|
||||
intentShareFile.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
|
||||
|
||||
startActivity(Intent.createChooser(intentShareFile, getString(R.string.shareFile)));
|
||||
|
||||
Log.d("Export", uri.toString());
|
||||
Log.d("Export", getContentResolver().getType(uri));
|
||||
try {
|
||||
Log.d("Export", new BufferedInputStream(getContentResolver().openInputStream(uri)).toString());
|
||||
} catch (FileNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
void showErrorDialog(Exception e, @StringRes int title, @StringRes int message) {
|
||||
new AlertDialog.Builder(this)
|
||||
.setTitle(title)
|
||||
@ -67,5 +47,16 @@ abstract public class FitoTrackActivity extends Activity {
|
||||
.create().show();
|
||||
}
|
||||
|
||||
protected void requestStoragePermissions() {
|
||||
if (!hasStoragePermission()) {
|
||||
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE}, 10);
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean hasStoragePermission() {
|
||||
return ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED &&
|
||||
ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -20,7 +20,6 @@
|
||||
package de.tadris.fitness.activity;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.content.Intent;
|
||||
import android.media.Ringtone;
|
||||
import android.media.RingtoneManager;
|
||||
import android.net.Uri;
|
||||
@ -30,36 +29,15 @@ import android.preference.PreferenceActivity;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.preference.RingtonePreference;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import android.view.MenuItem;
|
||||
|
||||
import androidx.annotation.StringRes;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
|
||||
import de.tadris.fitness.R;
|
||||
import de.tadris.fitness.util.unit.UnitUtils;
|
||||
|
||||
public abstract class FitoTrackSettingsActivity extends PreferenceActivity {
|
||||
|
||||
protected void shareFile(Uri uri) {
|
||||
Intent intentShareFile = new Intent(Intent.ACTION_SEND);
|
||||
intentShareFile.setDataAndType(uri, getContentResolver().getType(uri));
|
||||
intentShareFile.putExtra(Intent.EXTRA_STREAM, uri);
|
||||
intentShareFile.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
|
||||
|
||||
startActivity(Intent.createChooser(intentShareFile, getString(R.string.shareFile)));
|
||||
|
||||
Log.d("Export", uri.toString());
|
||||
Log.d("Export", getContentResolver().getType(uri));
|
||||
try {
|
||||
Log.d("Export", new BufferedInputStream(getContentResolver().openInputStream(uri)).toString());
|
||||
} catch (FileNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
protected void showErrorDialog(Exception e, @StringRes int title, @StringRes int message) {
|
||||
new AlertDialog.Builder(this)
|
||||
.setTitle(title)
|
||||
|
||||
@ -43,6 +43,7 @@ import de.tadris.fitness.R;
|
||||
import de.tadris.fitness.announcement.VoiceAnnouncements;
|
||||
import de.tadris.fitness.export.BackupController;
|
||||
import de.tadris.fitness.export.RestoreController;
|
||||
import de.tadris.fitness.util.FileUtils;
|
||||
import de.tadris.fitness.util.unit.UnitUtils;
|
||||
import de.tadris.fitness.view.ProgressDialogController;
|
||||
|
||||
@ -100,6 +101,10 @@ public class SettingsActivity extends FitoTrackSettingsActivity {
|
||||
}
|
||||
|
||||
private void showExportDialog() {
|
||||
if (!hasPermission()) {
|
||||
requestPermissions();
|
||||
return;
|
||||
}
|
||||
new AlertDialog.Builder(this)
|
||||
.setTitle(R.string.exportData)
|
||||
.setMessage(R.string.exportDataSummary)
|
||||
@ -113,7 +118,8 @@ public class SettingsActivity extends FitoTrackSettingsActivity {
|
||||
new Thread(() -> {
|
||||
try{
|
||||
String file= getFilesDir().getAbsolutePath() + "/shared/backup.ftb";
|
||||
if (!new File(file).getParentFile().mkdirs()) {
|
||||
File parent = new File(file).getParentFile();
|
||||
if (!parent.exists() && !parent.mkdirs()) {
|
||||
throw new IOException("Cannot write");
|
||||
}
|
||||
Uri uri= FileProvider.getUriForFile(getBaseContext(), "de.tadris.fitness.fileprovider", new File(file));
|
||||
@ -123,7 +129,7 @@ public class SettingsActivity extends FitoTrackSettingsActivity {
|
||||
|
||||
mHandler.post(() -> {
|
||||
dialogController.cancel();
|
||||
shareFile(uri);
|
||||
FileUtils.saveOrShareFile(this, uri, "ftb");
|
||||
});
|
||||
}catch (Exception e){
|
||||
e.printStackTrace();
|
||||
|
||||
@ -48,6 +48,7 @@ import de.tadris.fitness.data.WorkoutSample;
|
||||
import de.tadris.fitness.osm.OAuthAuthentication;
|
||||
import de.tadris.fitness.osm.OsmTraceUploader;
|
||||
import de.tadris.fitness.util.DialogUtils;
|
||||
import de.tadris.fitness.util.FileUtils;
|
||||
import de.tadris.fitness.util.gpx.GpxExporter;
|
||||
import de.tadris.fitness.util.unit.UnitUtils;
|
||||
import de.tadris.fitness.view.ProgressDialogController;
|
||||
@ -202,20 +203,25 @@ public class ShowWorkoutActivity extends WorkoutActivity implements DialogUtils.
|
||||
}
|
||||
|
||||
private void exportToGpx(){
|
||||
if (!hasStoragePermission()) {
|
||||
requestStoragePermissions();
|
||||
return;
|
||||
}
|
||||
ProgressDialogController dialogController= new ProgressDialogController(this, getString(R.string.exporting));
|
||||
dialogController.setIndeterminate(true);
|
||||
dialogController.show();
|
||||
new Thread(() -> {
|
||||
try{
|
||||
String file= getFilesDir().getAbsolutePath() + "/shared/workout.gpx";
|
||||
if (!new File(file).getParentFile().mkdirs()) {
|
||||
File parent = new File(file).getParentFile();
|
||||
if (!parent.exists() && !parent.mkdirs()) {
|
||||
throw new IOException("Cannot write to " + file);
|
||||
}
|
||||
Uri uri= FileProvider.getUriForFile(getBaseContext(), "de.tadris.fitness.fileprovider", new File(file));
|
||||
|
||||
GpxExporter.exportWorkout(getBaseContext(), workout, new File(file));
|
||||
dialogController.cancel();
|
||||
mHandler.post(() -> shareFile(uri));
|
||||
mHandler.post(() -> FileUtils.saveOrShareFile(this, uri, "gpx"));
|
||||
}catch (Exception e){
|
||||
e.printStackTrace();
|
||||
mHandler.post(() -> showErrorDialog(e, R.string.error, R.string.errorGpxExportFailed));
|
||||
|
||||
@ -65,6 +65,7 @@ public class BackupController {
|
||||
private void init(){
|
||||
database= Instance.getInstance(context).db;
|
||||
UnitUtils.setUnit(context); // Ensure unit system is correct
|
||||
newContainer();
|
||||
}
|
||||
|
||||
private void newContainer(){
|
||||
|
||||
78
app/src/main/java/de/tadris/fitness/util/FileUtils.java
Normal file
78
app/src/main/java/de/tadris/fitness/util/FileUtils.java
Normal file
@ -0,0 +1,78 @@
|
||||
package de.tadris.fitness.util;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.Environment;
|
||||
import android.util.Log;
|
||||
import android.widget.Toast;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import de.tadris.fitness.R;
|
||||
|
||||
public class FileUtils {
|
||||
|
||||
public static void saveOrShareFile(Activity activity, Uri uri, String suffix) {
|
||||
String[] colors = {activity.getString(R.string.share), activity.getString(R.string.save)};
|
||||
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(activity);
|
||||
builder.setItems(colors, (dialog, which) -> {
|
||||
if (which == 0) {
|
||||
shareFile(activity, uri);
|
||||
} else {
|
||||
try {
|
||||
saveFile(activity, uri, suffix);
|
||||
Toast.makeText(activity, R.string.savedToDownloads, Toast.LENGTH_LONG).show();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Toast.makeText(activity, R.string.savingFailed, Toast.LENGTH_LONG).show();
|
||||
}
|
||||
}
|
||||
});
|
||||
builder.show();
|
||||
}
|
||||
|
||||
private static void saveFile(Activity activity, Uri fileUri, String suffix) throws IOException {
|
||||
File target = new File(Environment.getExternalStorageDirectory(), "Download/fitotrack" + System.currentTimeMillis() + "." + suffix);
|
||||
if (!target.createNewFile()) {
|
||||
throw new IOException("Cannot write to file " + target);
|
||||
}
|
||||
copyFile(activity, fileUri, Uri.fromFile(target));
|
||||
}
|
||||
|
||||
private static void copyFile(Activity activity, Uri sourceUri, Uri targetUri) throws IOException {
|
||||
InputStream input = activity.getContentResolver().openInputStream(sourceUri);
|
||||
if (input == null) {
|
||||
throw new IOException("Source file not found");
|
||||
}
|
||||
OutputStream output = activity.getContentResolver().openOutputStream(targetUri);
|
||||
IOUtils.copy(input, output);
|
||||
}
|
||||
|
||||
private static void shareFile(Activity activity, Uri uri) {
|
||||
Intent intentShareFile = new Intent(Intent.ACTION_SEND);
|
||||
intentShareFile.setDataAndType(uri, activity.getContentResolver().getType(uri));
|
||||
intentShareFile.putExtra(Intent.EXTRA_STREAM, uri);
|
||||
intentShareFile.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
|
||||
|
||||
activity.startActivity(Intent.createChooser(intentShareFile, activity.getString(R.string.shareFile)));
|
||||
|
||||
Log.d("Export", uri.toString());
|
||||
Log.d("Export", activity.getContentResolver().getType(uri));
|
||||
try {
|
||||
Log.d("Export", new BufferedInputStream(activity.getContentResolver().openInputStream(uri)).toString());
|
||||
} catch (FileNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -150,4 +150,9 @@
|
||||
<string name="ttsNotAvailable">TextToSpeech is not available</string>
|
||||
<string name="action_edit_comment">Edit Comment</string>
|
||||
<string name="pref_announcement_mode">Announcement Mode</string>
|
||||
|
||||
<string name="save">Save</string>
|
||||
<string name="share">Share</string>
|
||||
<string name="savedToDownloads">Saved to Downloads</string>
|
||||
<string name="savingFailed">Saving failed</string>
|
||||
</resources>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user