diff --git a/CHANGELOG.md b/CHANGELOG.md index e98a9e609..e30699b10 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +### 1.5.4 (May 29, 2016) + +* Fix crash upon opening settings screen in some phones +* Fix missing folders in CSV archive +* Add Serbian translation + ### 1.5.3 (May 22, 2016) * Complete Arabic and Czech translations diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 7eeedca29..0ad4db1d1 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -21,8 +21,8 @@ + android:versionCode="20" + android:versionName="1.5.4"> diff --git a/app/src/main/java/org/isoron/uhabits/fragments/SettingsFragment.java b/app/src/main/java/org/isoron/uhabits/fragments/SettingsFragment.java index 838527589..29ab76a4c 100644 --- a/app/src/main/java/org/isoron/uhabits/fragments/SettingsFragment.java +++ b/app/src/main/java/org/isoron/uhabits/fragments/SettingsFragment.java @@ -134,6 +134,7 @@ public class SettingsFragment extends PreferenceFragmentCompat private void updateRingtoneDescription() { String ringtoneName = ReminderHelper.getRingtoneName(getContext()); + if(ringtoneName == null) return; Preference ringtonePreference = findPreference("reminderSound"); ringtonePreference.setSummary(ringtoneName); } diff --git a/app/src/main/java/org/isoron/uhabits/helpers/ReminderHelper.java b/app/src/main/java/org/isoron/uhabits/helpers/ReminderHelper.java index 35e1a92a1..2956815a4 100644 --- a/app/src/main/java/org/isoron/uhabits/helpers/ReminderHelper.java +++ b/app/src/main/java/org/isoron/uhabits/helpers/ReminderHelper.java @@ -144,21 +144,30 @@ public class ReminderHelper fragment.startActivityForResult(intent, requestCode); } + @Nullable public static String getRingtoneName(Context context) { - Uri ringtoneUri = getRingtoneUri(context); - String ringtoneName = context.getResources().getString(R.string.none); - - if(ringtoneUri != null) + try { - Ringtone ringtone = RingtoneManager.getRingtone(context, ringtoneUri); - if(ringtone != null) + Uri ringtoneUri = getRingtoneUri(context); + String ringtoneName = context.getResources().getString(R.string.none); + + if (ringtoneUri != null) { - ringtoneName = ringtone.getTitle(context); - ringtone.stop(); + Ringtone ringtone = RingtoneManager.getRingtone(context, ringtoneUri); + if (ringtone != null) + { + ringtoneName = ringtone.getTitle(context); + ringtone.stop(); + } } - } - return ringtoneName; + return ringtoneName; + } + catch (RuntimeException e) + { + e.printStackTrace(); + return null; + } } } diff --git a/app/src/main/java/org/isoron/uhabits/io/HabitsCSVExporter.java b/app/src/main/java/org/isoron/uhabits/io/HabitsCSVExporter.java index f84ad666c..67ddd3a15 100644 --- a/app/src/main/java/org/isoron/uhabits/io/HabitsCSVExporter.java +++ b/app/src/main/java/org/isoron/uhabits/io/HabitsCSVExporter.java @@ -19,6 +19,8 @@ package org.isoron.uhabits.io; +import android.support.annotation.NonNull; + import org.isoron.uhabits.helpers.DateHelper; import org.isoron.uhabits.models.CheckmarkList; import org.isoron.uhabits.models.Habit; @@ -64,7 +66,10 @@ public class HabitsCSVExporter for(Habit h : habits) { - String habitDirName = String.format("%03d %s/", h.position + 1, h.name); + String sane = sanitizeFilename(h.name); + String habitDirName = String.format("%03d %s", h.position + 1, sane); + habitDirName = habitDirName.trim() + "/"; + new File(exportDirName + habitDirName).mkdirs(); generateDirs.add(habitDirName); @@ -73,6 +78,13 @@ public class HabitsCSVExporter } } + @NonNull + private String sanitizeFilename(String name) + { + String s = name.replaceAll("[^a-zA-Z0-9\\._-]+", ""); + return s.substring(0, Math.min(s.length(), 100)); + } + private void writeScores(String habitDirName, ScoreList scores) throws IOException { String path = habitDirName + "Scores.csv"; diff --git a/app/src/main/java/org/isoron/uhabits/models/Habit.java b/app/src/main/java/org/isoron/uhabits/models/Habit.java index 1fdb982ad..6973dcc55 100644 --- a/app/src/main/java/org/isoron/uhabits/models/Habit.java +++ b/app/src/main/java/org/isoron/uhabits/models/Habit.java @@ -489,7 +489,7 @@ public class Habit extends Model */ public static void writeCSV(List habits, Writer out) throws IOException { - String header[] = { "Name", "Description", "NumRepetitions", "Interval", "Color" }; + String header[] = { "Position", "Name", "Description", "NumRepetitions", "Interval", "Color" }; CSVWriter csv = new CSVWriter(out); csv.writeNext(header, false); @@ -498,6 +498,7 @@ public class Habit extends Model { String[] cols = { + String.format("%03d", habit.position + 1), habit.name, habit.description, Integer.toString(habit.freqNum), diff --git a/app/src/main/res/layout/about.xml b/app/src/main/res/layout/about.xml index 47fd5ea92..0308cd4c6 100644 --- a/app/src/main/res/layout/about.xml +++ b/app/src/main/res/layout/about.xml @@ -180,6 +180,10 @@ style="@style/About.Item" android:text="Robin (Svenska)"/> + + diff --git a/app/src/main/res/values-sr/strings.xml b/app/src/main/res/values-sr/strings.xml new file mode 100644 index 000000000..ad03fd5f2 --- /dev/null +++ b/app/src/main/res/values-sr/strings.xml @@ -0,0 +1,180 @@ + + + "Loop – праћење навика" + "Навике" + "Поставке" + "Уреди" + "Обриши" + "Архивирај" + "Врати из архива" + "Додај навику" + "Промена боје" + "Навика је створена." + "Навике су обрисане." + "Навике су враћене." + "Нема шта да се опозове." + "Нема шта да се понови." + "Навика је промењена." + + + "Навика је враћена." + "Навике су архивиране." + "Навике су враћене из архива." + "Преглед" + "Снага навике" + "Историја" + "Очисти" + "Питање (нпр. „Да ли сте трчали данас?)" + + + "Понови" + "пута у" + "дана" + "Подсетник" + "Одбаци" + "Сачувај" + + + "Низови" + "Немате активних навика." + "Притисните и држите да бисте маркирали или демаркирали." + "искључен" + "Име не може бити празно." + "Број мора бити позитиван." + "Можете имати највише једно понављање на дан." + "Стварање навике" + "Уређивање навике" + "Маркирај" + "Касније" + + + "Добро дошли" + "Loop вам помаже да створите и одржавате здраве навике." + "Створите нове навике" + "Сваког дана, након што обавите навику, означите поље у апликацији." + "Будите истрајни" + "Навике којих се доследно придржавате дужи период биће означене пуном звездом." + "Пратите свој напредак" + "Детаљни графикони показују вам колико су се ваше навике временом побољшале." + "15 минута" + "30 минута" + "1 сат" + "2 сата" + "4 сата" + "8 сати" + "Маркирај кратким додиром" + "Практичније, али може доћи до случајног маркирања." + "Одлагање подсетника" + "Оцени апликацију" + "Повратне информације" + "Изворни кôд на GitHub-у" + "Увод апликације" + "Везе" + "Понашање" + "Име" + "Прикажи архивиране" + "Поставке" + "Време одлагања" + "Да ли сте знали?" + "Притисните и држите име навике да бисте је прераспоредили." + "Положите уређај да бисте видели више дана." + "Брисање навика" + "Навике ће бити трајно обрисане. Ова радња је неповратна." + "викендом" + "понедељак–петак" + "сваког дана" + "Избор дана" + "Извези као CSV" + "Готово" + "Очисти" + "Избор часова" + "Избор минута" + + + "Створите здраве навике и пратите напредак (без огласа)." + "Loop вам помаже да створите и одржавате здраве навике, самим тим и да достигнете дугорочне циљеве. Детаљна статистика и графикони показују вам колико су се ваше навике временом побољшале. Апликација је отвореног кода и не садржи огласе." +"<b>Једноставан, леп и модеран дизајн</b> +Loop има минималистички интерфејс који је једноставан за коришћење и прати смернице за материјални дизајн." +"<b>Оцена навике</b> +Поред приказа тренутног низа, Loop поседује напредни алгоритам за израчунавање снаге ваших навика. Ваша навика са сваким понављањем постаје јача, а са сваким пропуштеним даном слабија. Неколико пропуштених дана након дугог низа, пак, неће у потпуности упропастити ваш резултат." +"<b>Детаљни графикони и статистика</b> +Пратите свој напредак уз лепе и детаљне графиконе. Вратите се уназад да бисте видели целу историју навика." +"<b>Флексибилни распоред</b> +Подржава како дневне навике, тако и оне са сложенијим понављањем (трипут недељно, једанпут сваке друге недеље, сваки други дан и сл.)." +"<b>Подсетници</b> +Направите појединачни подсетник за сваку навику у жељено доба дана. С лакоћом маркирајте, одложите или откажите навику директно из обавештења, без отварања апликације." +"<b>У потпуности отвореног кода и без огласа</b> +Апликација не садржи никакве огласе, досадна обавештења или наметљиве дозволе; никада и неће. Изворни кôд је у целости доступан под лиценцом GPLv3." +"<b>Оптимизовано за паметне сатове</b> +Навике можете маркирати, одложити или отказати директно помоћу Android Wear сата." + "О апликацији" + "Преводиоци" + "Програмери" + + + "Верзија %s" + "Учесталост" + "Штрикла" + + + "Снага" + "Најбољи низови" + "Тренутни низ" + "Број понављања" + "посл. %d дана" + "посл. %d нед." + "посл. %d мес." + "посл. %d год." + + + "одувек" + "сваког дана" + "сваке недеље" + "2 пута недељно" + "5 пута недељно" + "прилагоди…" + "Помоћ" + "Не могу да извезем податке." + "Не могу да увезем податке." + + + "Датотека није препозната." + "Резервна копија је враћена." + "Направљена је резервна копија." + "Врати резервну копију" + "Направи резервну копију" + "Поред матичног формата, апликација подржава и увоз датотека које је направио Tickmate, HabitBull и Rewire. Детаљније у ЧПП." + "Направите датотеку коју можете отворити у програму за рад са табелама (нпр. Microsoft Excel или OpenOffice Calc). Њу не можете да увезете назад у апликацију." + "Направите датотеку са свим подацима апликације. Њу касније можете да увезете." + "Не могу да направим извештај о грешци." + "Направи извештај о грешци" + "Решавање проблема" + "Помоћ у преводу" + "Ноћни режим" + "Чиста црна у ноћном режиму" + "Замењује сиву позадину са чистом црном у ноћном режиму. Смањује потрошњу батерије код телефона са AMOLED екраном." + "Интерфејс" + "Обрнути редослед дана" + "Прикажите дане у обрнутом редоследу на главном екрану." + "дан" + "недеља" + "месец" + + + "тромесечје" + "година" + + + + "пут у" + "Сваких %d дана" + "Сваких %d недеља" + "Сваких %d месеци" + + + "снага" + "Звук подсетника" + + + "Без звука" + \ No newline at end of file