mirror of
https://github.com/iSoron/uhabits.git
synced 2025-12-06 09:08:52 -06:00
@@ -31,7 +31,6 @@ import android.content.pm.PackageManager;
|
|||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.AsyncTask;
|
import android.os.AsyncTask;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Environment;
|
|
||||||
import android.preference.PreferenceManager;
|
import android.preference.PreferenceManager;
|
||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
import android.support.v4.app.ActivityCompat;
|
import android.support.v4.app.ActivityCompat;
|
||||||
@@ -43,7 +42,6 @@ import android.view.MenuItem;
|
|||||||
import org.isoron.helpers.DateHelper;
|
import org.isoron.helpers.DateHelper;
|
||||||
import org.isoron.helpers.DialogHelper;
|
import org.isoron.helpers.DialogHelper;
|
||||||
import org.isoron.helpers.ReplayableActivity;
|
import org.isoron.helpers.ReplayableActivity;
|
||||||
import org.isoron.uhabits.dialogs.FilePickerDialog;
|
|
||||||
import org.isoron.uhabits.fragments.ListHabitsFragment;
|
import org.isoron.uhabits.fragments.ListHabitsFragment;
|
||||||
import org.isoron.uhabits.helpers.ReminderHelper;
|
import org.isoron.uhabits.helpers.ReminderHelper;
|
||||||
import org.isoron.uhabits.models.Habit;
|
import org.isoron.uhabits.models.Habit;
|
||||||
@@ -53,8 +51,6 @@ import org.isoron.uhabits.widgets.HistoryWidgetProvider;
|
|||||||
import org.isoron.uhabits.widgets.ScoreWidgetProvider;
|
import org.isoron.uhabits.widgets.ScoreWidgetProvider;
|
||||||
import org.isoron.uhabits.widgets.StreakWidgetProvider;
|
import org.isoron.uhabits.widgets.StreakWidgetProvider;
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
|
|
||||||
public class MainActivity extends ReplayableActivity
|
public class MainActivity extends ReplayableActivity
|
||||||
implements ListHabitsFragment.OnHabitClickListener
|
implements ListHabitsFragment.OnHabitClickListener
|
||||||
{
|
{
|
||||||
@@ -65,6 +61,9 @@ public class MainActivity extends ReplayableActivity
|
|||||||
|
|
||||||
public static final String ACTION_REFRESH = "org.isoron.uhabits.ACTION_REFRESH";
|
public static final String ACTION_REFRESH = "org.isoron.uhabits.ACTION_REFRESH";
|
||||||
|
|
||||||
|
public static final int RESULT_IMPORT_DATA = 1;
|
||||||
|
public static final int RESULT_EXPORT_ALL_AS_CSV = 2;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState)
|
protected void onCreate(Bundle savedInstanceState)
|
||||||
{
|
{
|
||||||
@@ -129,16 +128,10 @@ public class MainActivity extends ReplayableActivity
|
|||||||
{
|
{
|
||||||
switch (item.getItemId())
|
switch (item.getItemId())
|
||||||
{
|
{
|
||||||
case R.id.action_import:
|
|
||||||
{
|
|
||||||
onActionImportClicked();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
case R.id.action_settings:
|
case R.id.action_settings:
|
||||||
{
|
{
|
||||||
Intent intent = new Intent(this, SettingsActivity.class);
|
Intent intent = new Intent(this, SettingsActivity.class);
|
||||||
startActivity(intent);
|
startActivityForResult(intent, 0);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -154,6 +147,21 @@ public class MainActivity extends ReplayableActivity
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onActivityResult(int requestCode, int resultCode, Intent data)
|
||||||
|
{
|
||||||
|
switch (resultCode)
|
||||||
|
{
|
||||||
|
case RESULT_IMPORT_DATA:
|
||||||
|
onActionImportClicked();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RESULT_EXPORT_ALL_AS_CSV:
|
||||||
|
listHabitsFragment.exportAllHabits();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void onActionImportClicked()
|
private void onActionImportClicked()
|
||||||
{
|
{
|
||||||
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) !=
|
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) !=
|
||||||
|
|||||||
@@ -21,13 +21,9 @@ package org.isoron.uhabits.dialogs;
|
|||||||
|
|
||||||
import android.app.AlertDialog;
|
import android.app.AlertDialog;
|
||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
import android.content.Intent;
|
|
||||||
import android.net.Uri;
|
|
||||||
import android.os.AsyncTask;
|
|
||||||
import android.view.ActionMode;
|
import android.view.ActionMode;
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.view.View;
|
|
||||||
import android.widget.ProgressBar;
|
import android.widget.ProgressBar;
|
||||||
|
|
||||||
import com.android.colorpicker.ColorPickerDialog;
|
import com.android.colorpicker.ColorPickerDialog;
|
||||||
@@ -42,11 +38,10 @@ import org.isoron.uhabits.commands.ChangeHabitColorCommand;
|
|||||||
import org.isoron.uhabits.commands.DeleteHabitsCommand;
|
import org.isoron.uhabits.commands.DeleteHabitsCommand;
|
||||||
import org.isoron.uhabits.commands.UnarchiveHabitsCommand;
|
import org.isoron.uhabits.commands.UnarchiveHabitsCommand;
|
||||||
import org.isoron.uhabits.fragments.EditHabitFragment;
|
import org.isoron.uhabits.fragments.EditHabitFragment;
|
||||||
import org.isoron.uhabits.io.HabitsExporter;
|
import org.isoron.uhabits.fragments.ExportHabitsTask;
|
||||||
import org.isoron.uhabits.loaders.HabitListLoader;
|
import org.isoron.uhabits.loaders.HabitListLoader;
|
||||||
import org.isoron.uhabits.models.Habit;
|
import org.isoron.uhabits.models.Habit;
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@@ -224,50 +219,6 @@ public class HabitSelectionCallback implements ActionMode.Callback
|
|||||||
|
|
||||||
private void onExportHabitsClick(final LinkedList<Habit> selectedHabits)
|
private void onExportHabitsClick(final LinkedList<Habit> selectedHabits)
|
||||||
{
|
{
|
||||||
new AsyncTask<Void, Void, Void>()
|
new ExportHabitsTask(activity, selectedHabits, progressBar).execute();
|
||||||
{
|
|
||||||
String archiveFilename;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onPreExecute()
|
|
||||||
{
|
|
||||||
if(progressBar != null)
|
|
||||||
{
|
|
||||||
progressBar.setIndeterminate(true);
|
|
||||||
progressBar.setVisibility(View.VISIBLE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onPostExecute(Void aVoid)
|
|
||||||
{
|
|
||||||
if(archiveFilename != null)
|
|
||||||
{
|
|
||||||
Intent intent = new Intent();
|
|
||||||
intent.setAction(Intent.ACTION_SEND);
|
|
||||||
intent.setType("application/zip");
|
|
||||||
intent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(new File(archiveFilename)));
|
|
||||||
|
|
||||||
activity.startActivity(intent);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
activity.showToast(R.string.could_not_export);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(progressBar != null)
|
|
||||||
progressBar.setVisibility(View.GONE);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Void doInBackground(Void... params)
|
|
||||||
{
|
|
||||||
String dirName = String.format("%s/export/", activity.getExternalCacheDir());
|
|
||||||
HabitsExporter exporter = new HabitsExporter(selectedHabits, dirName);
|
|
||||||
archiveFilename = exporter.writeArchive();
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}.execute();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,72 @@
|
|||||||
|
package org.isoron.uhabits.fragments;
|
||||||
|
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.net.Uri;
|
||||||
|
import android.os.AsyncTask;
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.ProgressBar;
|
||||||
|
|
||||||
|
import org.isoron.helpers.ReplayableActivity;
|
||||||
|
import org.isoron.uhabits.R;
|
||||||
|
import org.isoron.uhabits.io.HabitsExporter;
|
||||||
|
import org.isoron.uhabits.models.Habit;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class ExportHabitsTask extends AsyncTask<Void, Void, Void>
|
||||||
|
{
|
||||||
|
private final ReplayableActivity activity;
|
||||||
|
private ProgressBar progressBar;
|
||||||
|
private final List<Habit> selectedHabits;
|
||||||
|
String archiveFilename;
|
||||||
|
|
||||||
|
public ExportHabitsTask(ReplayableActivity activity, List<Habit> selectedHabits,
|
||||||
|
ProgressBar progressBar)
|
||||||
|
{
|
||||||
|
this.selectedHabits = selectedHabits;
|
||||||
|
this.progressBar = progressBar;
|
||||||
|
this.activity = activity;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onPreExecute()
|
||||||
|
{
|
||||||
|
if(progressBar != null)
|
||||||
|
{
|
||||||
|
progressBar.setIndeterminate(true);
|
||||||
|
progressBar.setVisibility(View.VISIBLE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onPostExecute(Void aVoid)
|
||||||
|
{
|
||||||
|
if(archiveFilename != null)
|
||||||
|
{
|
||||||
|
Intent intent = new Intent();
|
||||||
|
intent.setAction(Intent.ACTION_SEND);
|
||||||
|
intent.setType("application/zip");
|
||||||
|
intent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(new File(archiveFilename)));
|
||||||
|
|
||||||
|
activity.startActivity(intent);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
activity.showToast(R.string.could_not_export);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(progressBar != null)
|
||||||
|
progressBar.setVisibility(View.GONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Void doInBackground(Void... params)
|
||||||
|
{
|
||||||
|
String dirName = String.format("%s/export/", activity.getExternalCacheDir());
|
||||||
|
HabitsExporter exporter = new HabitsExporter(selectedHabits, dirName);
|
||||||
|
archiveFilename = exporter.writeArchive();
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -466,4 +466,9 @@ public class ListHabitsFragment extends Fragment
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void exportAllHabits()
|
||||||
|
{
|
||||||
|
new ExportHabitsTask(activity, Habit.getAll(true), progressBar).execute();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,8 +22,10 @@ package org.isoron.uhabits.fragments;
|
|||||||
import android.app.backup.BackupManager;
|
import android.app.backup.BackupManager;
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.preference.Preference;
|
||||||
import android.preference.PreferenceFragment;
|
import android.preference.PreferenceFragment;
|
||||||
|
|
||||||
|
import org.isoron.uhabits.MainActivity;
|
||||||
import org.isoron.uhabits.R;
|
import org.isoron.uhabits.R;
|
||||||
|
|
||||||
public class SettingsFragment extends PreferenceFragment
|
public class SettingsFragment extends PreferenceFragment
|
||||||
@@ -34,6 +36,24 @@ public class SettingsFragment extends PreferenceFragment
|
|||||||
{
|
{
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
addPreferencesFromResource(R.xml.preferences);
|
addPreferencesFromResource(R.xml.preferences);
|
||||||
|
|
||||||
|
setResultOnPreferenceClick("importData", MainActivity.RESULT_IMPORT_DATA);
|
||||||
|
setResultOnPreferenceClick("exportCSV", MainActivity.RESULT_EXPORT_ALL_AS_CSV);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setResultOnPreferenceClick(String key, final int result)
|
||||||
|
{
|
||||||
|
Preference exportCSV = findPreference(key);
|
||||||
|
exportCSV.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public boolean onPreferenceClick(Preference preference)
|
||||||
|
{
|
||||||
|
getActivity().setResult(result);
|
||||||
|
getActivity().finish();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ public class HabitsExporter
|
|||||||
|
|
||||||
private void writeHabits() throws IOException
|
private void writeHabits() throws IOException
|
||||||
{
|
{
|
||||||
String filename = "habits.csv";
|
String filename = "Habits.csv";
|
||||||
new File(exportDirName).mkdirs();
|
new File(exportDirName).mkdirs();
|
||||||
FileWriter out = new FileWriter(exportDirName + filename);
|
FileWriter out = new FileWriter(exportDirName + filename);
|
||||||
generateFilenames.add(filename);
|
generateFilenames.add(filename);
|
||||||
@@ -67,7 +67,7 @@ public class HabitsExporter
|
|||||||
|
|
||||||
for(Habit h : habits)
|
for(Habit h : habits)
|
||||||
{
|
{
|
||||||
String habitDirName = String.format("%s/", h.name);
|
String habitDirName = String.format("%03d %s/", h.position, h.name);
|
||||||
new File(exportDirName + habitDirName).mkdirs();
|
new File(exportDirName + habitDirName).mkdirs();
|
||||||
generateDirs.add(habitDirName);
|
generateDirs.add(habitDirName);
|
||||||
|
|
||||||
@@ -78,7 +78,7 @@ public class HabitsExporter
|
|||||||
|
|
||||||
private void writeScores(String habitDirName, ScoreList scores) throws IOException
|
private void writeScores(String habitDirName, ScoreList scores) throws IOException
|
||||||
{
|
{
|
||||||
String path = habitDirName + "scores.csv";
|
String path = habitDirName + "Scores.csv";
|
||||||
FileWriter out = new FileWriter(exportDirName + path);
|
FileWriter out = new FileWriter(exportDirName + path);
|
||||||
generateFilenames.add(path);
|
generateFilenames.add(path);
|
||||||
scores.writeCSV(out);
|
scores.writeCSV(out);
|
||||||
@@ -87,7 +87,7 @@ public class HabitsExporter
|
|||||||
|
|
||||||
private void writeCheckmarks(String habitDirName, CheckmarkList checkmarks) throws IOException
|
private void writeCheckmarks(String habitDirName, CheckmarkList checkmarks) throws IOException
|
||||||
{
|
{
|
||||||
String filename = habitDirName + "checkmarks.csv";
|
String filename = habitDirName + "Checkmarks.csv";
|
||||||
FileWriter out = new FileWriter(exportDirName + filename);
|
FileWriter out = new FileWriter(exportDirName + filename);
|
||||||
generateFilenames.add(filename);
|
generateFilenames.add(filename);
|
||||||
checkmarks.writeCSV(out);
|
checkmarks.writeCSV(out);
|
||||||
@@ -98,7 +98,7 @@ public class HabitsExporter
|
|||||||
{
|
{
|
||||||
SimpleDateFormat dateFormat = DateHelper.getCSVDateFormat();
|
SimpleDateFormat dateFormat = DateHelper.getCSVDateFormat();
|
||||||
String date = dateFormat.format(DateHelper.getStartOfToday());
|
String date = dateFormat.format(DateHelper.getStartOfToday());
|
||||||
String zipFilename = String.format("%s/habits-%s.zip", exportDirName, date);
|
String zipFilename = String.format("%s/Loop-Habits-%s.zip", exportDirName, date);
|
||||||
|
|
||||||
FileOutputStream fos = new FileOutputStream(zipFilename);
|
FileOutputStream fos = new FileOutputStream(zipFilename);
|
||||||
ZipOutputStream zos = new ZipOutputStream(fos);
|
ZipOutputStream zos = new ZipOutputStream(fos);
|
||||||
|
|||||||
@@ -481,13 +481,16 @@ public class Habit extends Model
|
|||||||
|
|
||||||
public static void writeCSV(List<Habit> habits, Writer out) throws IOException
|
public static void writeCSV(List<Habit> habits, Writer out) throws IOException
|
||||||
{
|
{
|
||||||
|
String header[] = { "Name", "Description", "FrequencyNumerator", "FrequencyDenominator", "Color" };
|
||||||
|
|
||||||
CSVWriter csv = new CSVWriter(out);
|
CSVWriter csv = new CSVWriter(out);
|
||||||
|
csv.writeNext(header, false);
|
||||||
|
|
||||||
for(Habit habit : habits)
|
for(Habit habit : habits)
|
||||||
{
|
{
|
||||||
String[] cols = { habit.name, habit.description, Integer.toString(habit.freqNum),
|
String[] cols = { habit.name, habit.description, Integer.toString(habit.freqNum),
|
||||||
Integer.toString(habit.freqDen), ColorHelper.toHTML(habit.color) };
|
Integer.toString(habit.freqDen), ColorHelper.toHTML(habit.color) };
|
||||||
csv.writeAll(Collections.singletonList(cols));
|
csv.writeNext(cols, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
csv.close();
|
csv.close();
|
||||||
|
|||||||
@@ -28,12 +28,6 @@
|
|||||||
android:enabled="true"
|
android:enabled="true"
|
||||||
android:title="@string/show_archived"/>
|
android:title="@string/show_archived"/>
|
||||||
|
|
||||||
<item
|
|
||||||
android:id="@+id/action_import"
|
|
||||||
android:orderInCategory="50"
|
|
||||||
android:title="Import data"
|
|
||||||
app:showAsAction="never"/>
|
|
||||||
|
|
||||||
<item
|
<item
|
||||||
android:id="@+id/action_settings"
|
android:id="@+id/action_settings"
|
||||||
android:orderInCategory="100"
|
android:orderInCategory="100"
|
||||||
|
|||||||
@@ -106,7 +106,7 @@
|
|||||||
<string name="any_weekday">Monday to Friday</string>
|
<string name="any_weekday">Monday to Friday</string>
|
||||||
<string name="any_day">Any day of the week</string>
|
<string name="any_day">Any day of the week</string>
|
||||||
<string name="select_weekdays">Select days</string>
|
<string name="select_weekdays">Select days</string>
|
||||||
<string name="export_to_csv">Export data</string>
|
<string name="export_to_csv">Export as CSV</string>
|
||||||
|
|
||||||
<string name="done_label">Done</string>
|
<string name="done_label">Done</string>
|
||||||
<string name="clear_label">Clear</string>
|
<string name="clear_label">Clear</string>
|
||||||
@@ -142,4 +142,9 @@
|
|||||||
<string name="could_not_import">Failed to import habits from file.</string>
|
<string name="could_not_import">Failed to import habits from file.</string>
|
||||||
<string name="file_not_recognized">File type not recognized.</string>
|
<string name="file_not_recognized">File type not recognized.</string>
|
||||||
<string name="habits_imported">Habits imported successfully.</string>
|
<string name="habits_imported">Habits imported successfully.</string>
|
||||||
|
<string name="import_data_summary">Supports files exported by Loop, Tickmate, HabitBull or Rewire. See FAQ for more information.</string>
|
||||||
|
<string name="import_data">Import data</string>
|
||||||
|
<string name="export_as_csv_summary">This archive contains files that can be opened by spreadsheet software such as Microsoft Excel or OpenOffice Calc, but cannot be imported back.</string>
|
||||||
|
<string name="export_full_backup">Export full backup</string>
|
||||||
|
<string name="export_full_backup_summary">This file contains all your data and can be imported back.</string>
|
||||||
</resources>
|
</resources>
|
||||||
@@ -36,7 +36,8 @@
|
|||||||
android:entries="@array/snooze_interval_names"
|
android:entries="@array/snooze_interval_names"
|
||||||
android:entryValues="@array/snooze_interval_values"
|
android:entryValues="@array/snooze_interval_values"
|
||||||
android:key="pref_snooze_interval"
|
android:key="pref_snooze_interval"
|
||||||
android:title="@string/pref_snooze_interval_title"/>
|
android:title="@string/pref_snooze_interval_title"
|
||||||
|
android:summary="%s"/>
|
||||||
|
|
||||||
</PreferenceCategory>
|
</PreferenceCategory>
|
||||||
|
|
||||||
@@ -44,17 +45,21 @@
|
|||||||
android:key="pref_key_links"
|
android:key="pref_key_links"
|
||||||
android:title="Database">
|
android:title="Database">
|
||||||
|
|
||||||
<Preference android:title="Export data">
|
<Preference
|
||||||
<intent
|
android:summary="@string/export_full_backup_summary"
|
||||||
android:action="android.intent.action.VIEW"
|
android:title="@string/export_full_backup">
|
||||||
android:data="@string/helpURL"/>
|
|
||||||
</Preference>
|
</Preference>
|
||||||
|
|
||||||
<Preference android:title="Import data"
|
<Preference
|
||||||
android:summary="Supports files exported by Loop, Tickmate, HabitBull or Rewire. This feature is currently experimental.">
|
android:key="exportCSV"
|
||||||
<intent
|
android:summary="@string/export_as_csv_summary"
|
||||||
android:action="android.intent.action.VIEW"
|
android:title="@string/export_to_csv">
|
||||||
android:data="@string/helpURL"/>
|
</Preference>
|
||||||
|
|
||||||
|
<Preference
|
||||||
|
android:key="importData"
|
||||||
|
android:summary="@string/import_data_summary"
|
||||||
|
android:title="@string/import_data">
|
||||||
</Preference>
|
</Preference>
|
||||||
|
|
||||||
</PreferenceCategory>
|
</PreferenceCategory>
|
||||||
|
|||||||
Reference in New Issue
Block a user