From 4dcc6bea44fc8fb92239b631795b0b0be878c879 Mon Sep 17 00:00:00 2001 From: karntrehan Date: Wed, 16 Oct 2024 15:03:22 +0530 Subject: [PATCH 1/6] Fix readme with pushing new form data instructions --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index ccf2429cb44..dad98b16be6 100644 --- a/README.md +++ b/README.md @@ -120,10 +120,10 @@ When you first run Collect, it is set to download forms from [https://demo.getod 1. Once you have the XForm, use [adb](https://developer.android.com/studio/command-line/adb.html) to push the form to your device (after [enabling USB debugging](https://www.kingoapp.com/root-tutorials/how-to-enable-usb-debugging-mode-on-android.htm)) or emulator. ``` - adb push my_form.xml /sdcard/Android/data/org.odk.collect.android/files/forms + adb push my_form.xml /sdcard/Android/data/org.odk.collect.android/files/formsprojects/DEMO/forms ``` -1. Launch ODK Collect and tap `Fill Blank Form`. The new form will be there. +1. Launch ODK Collect and tap `+ Start new form`. The new form will be there. ## Using APIs for local development From a23196cebf331bbbe19f36b9c90082acb1490c97 Mon Sep 17 00:00:00 2001 From: karntrehan Date: Wed, 16 Oct 2024 15:17:53 +0530 Subject: [PATCH 2/6] [#6439] Button text and font changes. Empty text handling as well. --- .../support/pages/AddNewRepeatDialog.java | 2 +- .../formentry/repeats/AddRepeatDialog.java | 24 +++++++++++-------- strings/src/main/res/values/strings.xml | 1 + 3 files changed, 16 insertions(+), 11 deletions(-) diff --git a/collect_app/src/androidTest/java/org/odk/collect/android/support/pages/AddNewRepeatDialog.java b/collect_app/src/androidTest/java/org/odk/collect/android/support/pages/AddNewRepeatDialog.java index 5bb573d10c4..3727121a9d5 100644 --- a/collect_app/src/androidTest/java/org/odk/collect/android/support/pages/AddNewRepeatDialog.java +++ b/collect_app/src/androidTest/java/org/odk/collect/android/support/pages/AddNewRepeatDialog.java @@ -27,7 +27,7 @@ public > D clickOnAdd(D destination) { } public > D clickOnDoNotAdd(D destination) { - return clickOnTextInDialog(org.odk.collect.strings.R.string.dont_add_repeat, destination); + return clickOnTextInDialog(org.odk.collect.strings.R.string.cancel, destination); } } diff --git a/collect_app/src/main/java/org/odk/collect/android/formentry/repeats/AddRepeatDialog.java b/collect_app/src/main/java/org/odk/collect/android/formentry/repeats/AddRepeatDialog.java index 8ae1fd97113..de7f421ff5d 100644 --- a/collect_app/src/main/java/org/odk/collect/android/formentry/repeats/AddRepeatDialog.java +++ b/collect_app/src/main/java/org/odk/collect/android/formentry/repeats/AddRepeatDialog.java @@ -12,27 +12,31 @@ public class AddRepeatDialog { - private AddRepeatDialog() {} + private AddRepeatDialog() { + } public static void show(Context context, String groupLabel, Listener listener) { AlertDialog alertDialog = new MaterialAlertDialogBuilder(context).create(); DialogInterface.OnClickListener repeatListener = (dialog, i) -> { switch (i) { - case BUTTON_POSITIVE: - listener.onAddRepeatClicked(); - break; - case BUTTON_NEGATIVE: - listener.onCancelClicked(); - break; + case BUTTON_POSITIVE -> listener.onAddRepeatClicked(); + case BUTTON_NEGATIVE -> listener.onCancelClicked(); } }; - alertDialog.setMessage(context.getString(org.odk.collect.strings.R.string.add_repeat_question, - groupLabel)); + String dialogMessage; + if (groupLabel.isBlank()) { + dialogMessage = context.getString(org.odk.collect.strings.R.string.add_another_question); + } else { + dialogMessage = context.getString(org.odk.collect.strings.R.string.add_repeat_question, + groupLabel); + } + + alertDialog.setTitle(dialogMessage); alertDialog.setButton(BUTTON_POSITIVE, context.getString(org.odk.collect.strings.R.string.add_repeat), repeatListener); - alertDialog.setButton(BUTTON_NEGATIVE, context.getString(org.odk.collect.strings.R.string.dont_add_repeat), + alertDialog.setButton(BUTTON_NEGATIVE, context.getString(org.odk.collect.strings.R.string.cancel), repeatListener); alertDialog.setCancelable(false); diff --git a/strings/src/main/res/values/strings.xml b/strings/src/main/res/values/strings.xml index 235cf96f2e9..b096e24ceab 100644 --- a/strings/src/main/res/values/strings.xml +++ b/strings/src/main/res/values/strings.xml @@ -117,6 +117,7 @@ Add Do not add Add another + Add another? Edit Prompt From 373d79c82464ab26ea03ab22122995cf7935c855 Mon Sep 17 00:00:00 2001 From: karntrehan Date: Wed, 16 Oct 2024 16:32:22 +0530 Subject: [PATCH 3/6] [#6439] Text fixes --- .../android/feature/formentry/AddRepeatTest.java | 14 ++++++++++++++ .../android/support/pages/AddNewRepeatDialog.java | 8 +++++++- .../main/resources/forms/repeat_without_label.xml | 1 + 3 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 test-forms/src/main/resources/forms/repeat_without_label.xml diff --git a/collect_app/src/androidTest/java/org/odk/collect/android/feature/formentry/AddRepeatTest.java b/collect_app/src/androidTest/java/org/odk/collect/android/feature/formentry/AddRepeatTest.java index cf930ecc343..b1d889532c4 100644 --- a/collect_app/src/androidTest/java/org/odk/collect/android/feature/formentry/AddRepeatTest.java +++ b/collect_app/src/androidTest/java/org/odk/collect/android/feature/formentry/AddRepeatTest.java @@ -22,6 +22,7 @@ public class AddRepeatTest { private static final String ONE_QUESTION_REPEAT = "one-question-repeat.xml"; private static final String FIELD_LIST_REPEAT = "field-list-repeat.xml"; private static final String FIXED_COUNT_REPEAT = "fixed-count-repeat.xml"; + private static final String REPEAT_WITHOUT_LABEL = "repeat_without_label.xml"; private final CollectTestRule rule = new CollectTestRule(); @@ -117,4 +118,17 @@ public void whenInHierarchyForRepeat_clickingPlus_addsRepeatAtEndOfSeries() { .addGroup() .assertText("Person > 3"); } + + @Test + public void whenInEmptyRepeat_swipingNext_andClickingAdd_addsAnotherRepeat() { + rule.startAtMainMenu() + .copyForm(REPEAT_WITHOUT_LABEL) + .startBlankForm("Repeat without label") + .assertText("> 1") + .assertQuestion("First name", true) + .answerQuestion("First name", true, "Karan") + .swipeToNextQuestionWithRepeatGroup("") + .clickOnAdd(new FormEntryPage("Repeat without label")) + .assertText("> 2"); + } } diff --git a/collect_app/src/androidTest/java/org/odk/collect/android/support/pages/AddNewRepeatDialog.java b/collect_app/src/androidTest/java/org/odk/collect/android/support/pages/AddNewRepeatDialog.java index 3727121a9d5..144e42a7a91 100644 --- a/collect_app/src/androidTest/java/org/odk/collect/android/support/pages/AddNewRepeatDialog.java +++ b/collect_app/src/androidTest/java/org/odk/collect/android/support/pages/AddNewRepeatDialog.java @@ -16,7 +16,13 @@ public AddNewRepeatDialog(String repeatName) { @Override public AddNewRepeatDialog assertOnPage() { - onView(withText(getTranslatedString(org.odk.collect.strings.R.string.add_repeat_question, repeatName))) + String dialogMessage; + if (repeatName.isBlank()) { + dialogMessage = getTranslatedString(org.odk.collect.strings.R.string.add_another_question); + } else { + dialogMessage = getTranslatedString(org.odk.collect.strings.R.string.add_repeat_question, repeatName); + } + onView(withText(dialogMessage)) .inRoot(isDialog()) .check(matches(isDisplayed())); return this; diff --git a/test-forms/src/main/resources/forms/repeat_without_label.xml b/test-forms/src/main/resources/forms/repeat_without_label.xml new file mode 100644 index 00000000000..473ceec7ec4 --- /dev/null +++ b/test-forms/src/main/resources/forms/repeat_without_label.xml @@ -0,0 +1 @@ +Repeat without label \ No newline at end of file From fdd9417f5f2b6228550b1efddf508206e5fe7abc Mon Sep 17 00:00:00 2001 From: karntrehan Date: Wed, 16 Oct 2024 17:49:03 +0530 Subject: [PATCH 4/6] [#6439] Remove unused string resource - `dont_add_repeat` --- strings/src/main/res/values-ar/strings.xml | 1 - strings/src/main/res/values-cs/strings.xml | 1 - strings/src/main/res/values-da/strings.xml | 1 - strings/src/main/res/values-de/strings.xml | 1 - strings/src/main/res/values-es/strings.xml | 1 - strings/src/main/res/values-fa-rAF/strings.xml | 1 - strings/src/main/res/values-fa/strings.xml | 1 - strings/src/main/res/values-fi/strings.xml | 1 - strings/src/main/res/values-fr/strings.xml | 1 - strings/src/main/res/values-ht/strings.xml | 1 - strings/src/main/res/values-in/strings.xml | 1 - strings/src/main/res/values-it/strings.xml | 1 - strings/src/main/res/values-ja/strings.xml | 1 - strings/src/main/res/values-ka/strings.xml | 1 - strings/src/main/res/values-km/strings.xml | 1 - strings/src/main/res/values-nl/strings.xml | 1 - strings/src/main/res/values-pl/strings.xml | 1 - strings/src/main/res/values-pt/strings.xml | 1 - strings/src/main/res/values-ru/strings.xml | 1 - strings/src/main/res/values-rw/strings.xml | 1 - strings/src/main/res/values-sl/strings.xml | 1 - strings/src/main/res/values-sv-rSE/strings.xml | 1 - strings/src/main/res/values-sw-rKE/strings.xml | 1 - strings/src/main/res/values-sw/strings.xml | 1 - strings/src/main/res/values-te/strings.xml | 1 - strings/src/main/res/values-tl-rPH/strings.xml | 3 +-- strings/src/main/res/values-tr/strings.xml | 1 - strings/src/main/res/values-ur-rPK/strings.xml | 1 - strings/src/main/res/values-ur/strings.xml | 1 - strings/src/main/res/values-zh-rTW/strings.xml | 1 - strings/src/main/res/values-zh/strings.xml | 1 - strings/src/main/res/values/strings.xml | 1 - 32 files changed, 1 insertion(+), 33 deletions(-) diff --git a/strings/src/main/res/values-ar/strings.xml b/strings/src/main/res/values-ar/strings.xml index 4d071ebce05..61dccb5c81d 100644 --- a/strings/src/main/res/values-ar/strings.xml +++ b/strings/src/main/res/values-ar/strings.xml @@ -91,7 +91,6 @@ أضف \"%s\"؟ أضف - لا تقم بالإضافة إضافة أخرى تعديل التوجيه diff --git a/strings/src/main/res/values-cs/strings.xml b/strings/src/main/res/values-cs/strings.xml index 9a84d578eb4..4dd8c98cb0c 100644 --- a/strings/src/main/res/values-cs/strings.xml +++ b/strings/src/main/res/values-cs/strings.xml @@ -93,7 +93,6 @@ Přidat \"%s\"? Přidat - Nepřidat Přidat další Editovat otázku diff --git a/strings/src/main/res/values-da/strings.xml b/strings/src/main/res/values-da/strings.xml index a8e31ed5ce1..b7fa280e54a 100644 --- a/strings/src/main/res/values-da/strings.xml +++ b/strings/src/main/res/values-da/strings.xml @@ -63,7 +63,6 @@ Tilføj \"1%s \"?l Tilføj - Undlad at tilføje Tilføj anden Rediger prompt diff --git a/strings/src/main/res/values-de/strings.xml b/strings/src/main/res/values-de/strings.xml index 0bb8a2f2f8b..43783b66b68 100644 --- a/strings/src/main/res/values-de/strings.xml +++ b/strings/src/main/res/values-de/strings.xml @@ -93,7 +93,6 @@ \"%s\" hinzufügen? Hinzufügen - Nicht hinzufügen Weitere hinzufügen Eingabe ändern diff --git a/strings/src/main/res/values-es/strings.xml b/strings/src/main/res/values-es/strings.xml index 48208073c7f..3fd868cf69a 100644 --- a/strings/src/main/res/values-es/strings.xml +++ b/strings/src/main/res/values-es/strings.xml @@ -93,7 +93,6 @@ Agregar \"%s\"? Agregar - No agregar Agregar otro Editar entrada diff --git a/strings/src/main/res/values-fa-rAF/strings.xml b/strings/src/main/res/values-fa-rAF/strings.xml index 26eb99f0b13..3e32748fe0b 100644 --- a/strings/src/main/res/values-fa-rAF/strings.xml +++ b/strings/src/main/res/values-fa-rAF/strings.xml @@ -93,7 +93,6 @@ \"%s\" اضافه شود؟ اضافه کردن - اضافه نکنید اضافه کردن جدید ویرایش سریع diff --git a/strings/src/main/res/values-fa/strings.xml b/strings/src/main/res/values-fa/strings.xml index 26eb99f0b13..3e32748fe0b 100644 --- a/strings/src/main/res/values-fa/strings.xml +++ b/strings/src/main/res/values-fa/strings.xml @@ -93,7 +93,6 @@ \"%s\" اضافه شود؟ اضافه کردن - اضافه نکنید اضافه کردن جدید ویرایش سریع diff --git a/strings/src/main/res/values-fi/strings.xml b/strings/src/main/res/values-fi/strings.xml index 21daca43e1a..5e5c0d05089 100644 --- a/strings/src/main/res/values-fi/strings.xml +++ b/strings/src/main/res/values-fi/strings.xml @@ -93,7 +93,6 @@ Lisätäänkö \"%s\"? Lisätään - Ei lisätä Lisää toinen Kehotteen muokkaus diff --git a/strings/src/main/res/values-fr/strings.xml b/strings/src/main/res/values-fr/strings.xml index 74c360d2078..c634771136c 100644 --- a/strings/src/main/res/values-fr/strings.xml +++ b/strings/src/main/res/values-fr/strings.xml @@ -93,7 +93,6 @@ Ajouter «%s» ? Ajouter - Ne pas ajouter Ajouter un autre Ligne de modification diff --git a/strings/src/main/res/values-ht/strings.xml b/strings/src/main/res/values-ht/strings.xml index ef17e6a4977..cccb328fffc 100644 --- a/strings/src/main/res/values-ht/strings.xml +++ b/strings/src/main/res/values-ht/strings.xml @@ -82,7 +82,6 @@ Ajoute \"%s\"? Ajoute - Pa ajoute Ajoute yon lot Mesaj modifikasyon diff --git a/strings/src/main/res/values-in/strings.xml b/strings/src/main/res/values-in/strings.xml index 0faf37c1f7a..87260b5ccff 100644 --- a/strings/src/main/res/values-in/strings.xml +++ b/strings/src/main/res/values-in/strings.xml @@ -93,7 +93,6 @@ Tambah \"%s\"? Tambah - Batal tambah Tambah lainnya Ubah Risalah diff --git a/strings/src/main/res/values-it/strings.xml b/strings/src/main/res/values-it/strings.xml index 5f1d540e892..9b1848e6626 100644 --- a/strings/src/main/res/values-it/strings.xml +++ b/strings/src/main/res/values-it/strings.xml @@ -93,7 +93,6 @@ Aggingere \"%s\"? Aggiungere - Non aggiungere Aggiungi un altro Modifica Prompt diff --git a/strings/src/main/res/values-ja/strings.xml b/strings/src/main/res/values-ja/strings.xml index c4de52919d4..0b729f287b3 100644 --- a/strings/src/main/res/values-ja/strings.xml +++ b/strings/src/main/res/values-ja/strings.xml @@ -80,7 +80,6 @@ \"%s\" を追加? 追加 - 追加しない 別の追加… プロンプトを編集 diff --git a/strings/src/main/res/values-ka/strings.xml b/strings/src/main/res/values-ka/strings.xml index de347aa2b78..5fe510b0e47 100644 --- a/strings/src/main/res/values-ka/strings.xml +++ b/strings/src/main/res/values-ka/strings.xml @@ -77,7 +77,6 @@ დავამატოთ \"%s\"? დამატება - არ დაამატო დამატება გამოპასუხების რედაქტირება diff --git a/strings/src/main/res/values-km/strings.xml b/strings/src/main/res/values-km/strings.xml index cb54235ceeb..f6b5a8e7769 100644 --- a/strings/src/main/res/values-km/strings.xml +++ b/strings/src/main/res/values-km/strings.xml @@ -83,7 +83,6 @@ បន្ថែម \"%s\"? បន្ថែម - កុំបន្ថែម បន្ថែមមួយផ្សេងទៀត កែប្រែ Prompt diff --git a/strings/src/main/res/values-nl/strings.xml b/strings/src/main/res/values-nl/strings.xml index d7ff23b5734..a57cd825aae 100644 --- a/strings/src/main/res/values-nl/strings.xml +++ b/strings/src/main/res/values-nl/strings.xml @@ -85,7 +85,6 @@ %s toevoegen? Toevoegen - Niet toevoegen Voeg toe Edit Prompt diff --git a/strings/src/main/res/values-pl/strings.xml b/strings/src/main/res/values-pl/strings.xml index ad36fd1d0ae..abe25c88b94 100644 --- a/strings/src/main/res/values-pl/strings.xml +++ b/strings/src/main/res/values-pl/strings.xml @@ -80,7 +80,6 @@ Dodać \"%s\"? Dodaj - Nie dodawaj Dodaj kolejne Edytuj Pytanie diff --git a/strings/src/main/res/values-pt/strings.xml b/strings/src/main/res/values-pt/strings.xml index f2b43ffd877..49c356989f3 100644 --- a/strings/src/main/res/values-pt/strings.xml +++ b/strings/src/main/res/values-pt/strings.xml @@ -93,7 +93,6 @@ Adicionar \"%s\"? Adicionar - Não adicionar Adicionar outra Editar Prompt diff --git a/strings/src/main/res/values-ru/strings.xml b/strings/src/main/res/values-ru/strings.xml index 1af4075a5ee..c8664d30e7b 100644 --- a/strings/src/main/res/values-ru/strings.xml +++ b/strings/src/main/res/values-ru/strings.xml @@ -93,7 +93,6 @@ Добавить \"%s\"? Добавить - Не добавлять Добавить другое Изменить вопрос diff --git a/strings/src/main/res/values-rw/strings.xml b/strings/src/main/res/values-rw/strings.xml index 6c9dbac1578..ee0f8036d53 100644 --- a/strings/src/main/res/values-rw/strings.xml +++ b/strings/src/main/res/values-rw/strings.xml @@ -80,7 +80,6 @@ Ongera \'1%s\'  Shyiramo - Wishyiraho ibindi Shyiraho ibindi Gukosora ibyo wanditse diff --git a/strings/src/main/res/values-sl/strings.xml b/strings/src/main/res/values-sl/strings.xml index 20bcfd55e89..41cfb30c7ad 100644 --- a/strings/src/main/res/values-sl/strings.xml +++ b/strings/src/main/res/values-sl/strings.xml @@ -93,7 +93,6 @@ Dodaj \"%s\"? Dodaj - Ne dodaj Dodaj ponovno Uredi diff --git a/strings/src/main/res/values-sv-rSE/strings.xml b/strings/src/main/res/values-sv-rSE/strings.xml index 1c715bdc605..5b437b1cb6a 100644 --- a/strings/src/main/res/values-sv-rSE/strings.xml +++ b/strings/src/main/res/values-sv-rSE/strings.xml @@ -77,7 +77,6 @@ Vill du lägga till \"%s\"? Lägg till - Lägg inte till Lägg till ytterligare en Inmatningstext diff --git a/strings/src/main/res/values-sw-rKE/strings.xml b/strings/src/main/res/values-sw-rKE/strings.xml index d80112cfae5..2e5bdc23af7 100644 --- a/strings/src/main/res/values-sw-rKE/strings.xml +++ b/strings/src/main/res/values-sw-rKE/strings.xml @@ -53,7 +53,6 @@ Kikundi kinachoweza kurudiwa Toka - Usiongeze Ongeza nyingine Hariri ilani diff --git a/strings/src/main/res/values-sw/strings.xml b/strings/src/main/res/values-sw/strings.xml index 1e435c27dc5..efe69514cf1 100644 --- a/strings/src/main/res/values-sw/strings.xml +++ b/strings/src/main/res/values-sw/strings.xml @@ -89,7 +89,6 @@ Ongeza \"1%s\"? Ongeza - Usiongeze Ongeza ingine Hariri prompt diff --git a/strings/src/main/res/values-te/strings.xml b/strings/src/main/res/values-te/strings.xml index e4a578a6cfa..7140b332dba 100644 --- a/strings/src/main/res/values-te/strings.xml +++ b/strings/src/main/res/values-te/strings.xml @@ -80,7 +80,6 @@ %s జోడించు జోడించు - జోడించవద్దు మరొకదాన్ని జోడించండి ప్రాంప్ట్ సవరించండి diff --git a/strings/src/main/res/values-tl-rPH/strings.xml b/strings/src/main/res/values-tl-rPH/strings.xml index 827333ca4a4..7840fd8a614 100644 --- a/strings/src/main/res/values-tl-rPH/strings.xml +++ b/strings/src/main/res/values-tl-rPH/strings.xml @@ -47,8 +47,7 @@ Punta sa Simula Punta sa Dulo Punta Pataas - Huwag I-dagdag - Kina-karga ang Form + Kina-karga ang Form May Mali sa pag-karga ng Listahan ng Form Ang kawastuhan ay %1$s m Burahin ang Inimpok na Form diff --git a/strings/src/main/res/values-tr/strings.xml b/strings/src/main/res/values-tr/strings.xml index 9e2c1032fb8..4bcd73e2ad6 100644 --- a/strings/src/main/res/values-tr/strings.xml +++ b/strings/src/main/res/values-tr/strings.xml @@ -76,7 +76,6 @@ Ekle %s ? Ekle - Ekleme Bir daha ekle Bu yanıt kaldırılsın mı \"%s\"? diff --git a/strings/src/main/res/values-ur-rPK/strings.xml b/strings/src/main/res/values-ur-rPK/strings.xml index 84c39969b78..4c061839e9f 100644 --- a/strings/src/main/res/values-ur-rPK/strings.xml +++ b/strings/src/main/res/values-ur-rPK/strings.xml @@ -50,7 +50,6 @@ مزید شامل کریں - مزید شامل نہ کریں پرامپٹ کی تدوین کریں ‎%s‏ کو دیا گیا جواب ہٹائیں diff --git a/strings/src/main/res/values-ur/strings.xml b/strings/src/main/res/values-ur/strings.xml index f3b9be8c96c..d333f99d050 100644 --- a/strings/src/main/res/values-ur/strings.xml +++ b/strings/src/main/res/values-ur/strings.xml @@ -93,7 +93,6 @@ ایک اور \"1 %s\"؟ ایک دفعہ مزید - مزید نہیں ایک اور شامل کریں پرامپٹ کی ترمیم کریں diff --git a/strings/src/main/res/values-zh-rTW/strings.xml b/strings/src/main/res/values-zh-rTW/strings.xml index e05d5fd20d8..7b0f74982e8 100644 --- a/strings/src/main/res/values-zh-rTW/strings.xml +++ b/strings/src/main/res/values-zh-rTW/strings.xml @@ -93,7 +93,6 @@ 於 \"%s\"增加項目? 增加 - 不增加 增加其他項目 修改提示 diff --git a/strings/src/main/res/values-zh/strings.xml b/strings/src/main/res/values-zh/strings.xml index 3b3cae511e3..c44c955045e 100644 --- a/strings/src/main/res/values-zh/strings.xml +++ b/strings/src/main/res/values-zh/strings.xml @@ -93,7 +93,6 @@ 添加 \"%s\"? 添加 - 不添加 添加另一个 修改提示 diff --git a/strings/src/main/res/values/strings.xml b/strings/src/main/res/values/strings.xml index b096e24ceab..7472b22591b 100644 --- a/strings/src/main/res/values/strings.xml +++ b/strings/src/main/res/values/strings.xml @@ -115,7 +115,6 @@ Add \"%s\"? Add - Do not add Add another Add another? From 8513263247c40ec16a01a7525b8d457e36723cf7 Mon Sep 17 00:00:00 2001 From: karntrehan Date: Thu, 24 Oct 2024 09:23:59 +0530 Subject: [PATCH 5/6] [#6439] PR feedback - Readme and RepeatTest --- README.md | 329 +++++++++++++----- .../feature/formentry/AddRepeatTest.java | 3 +- 2 files changed, 242 insertions(+), 90 deletions(-) diff --git a/README.md b/README.md index dad98b16be6..4b5f1fb6851 100644 --- a/README.md +++ b/README.md @@ -1,80 +1,141 @@ # ODK Collect + ![Platform](https://img.shields.io/badge/platform-Android-blue.svg) [![License](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) [![Build status](https://circleci.com/gh/getodk/collect.svg?style=shield&circle-token=:circle-token)](https://circleci.com/gh/getodk/collect) [![Slack](https://img.shields.io/badge/chat-on%20slack-brightgreen)](https://slack.getodk.org) -ODK Collect is an Android app for filling out forms. It is designed to be used in resource-constrained environments with challenges such as unreliable connectivity or power infrastructure. ODK Collect is part the ODK project, a free and open-source set of tools which help organizations author, field, and manage mobile data collection solutions. Learn more about ODK and its history [here](https://getodk.org/) and read about example ODK deployments [here](https://forum.getodk.org/c/showcase). +ODK Collect is an Android app for filling out forms. It is designed to be used in +resource-constrained environments with challenges such as unreliable connectivity or power +infrastructure. ODK Collect is part the ODK project, a free and open-source set of tools which help +organizations author, field, and manage mobile data collection solutions. Learn more about ODK and +its history [here](https://getodk.org/) and read about example ODK +deployments [here](https://forum.getodk.org/c/showcase). -ODK Collect renders forms that are compliant with the [ODK XForms standard](https://getodk.github.io/xforms-spec/), a subset of the [XForms 1.1 standard](https://www.w3.org/TR/xforms/) with some extensions. The form parsing is done by the [JavaRosa library](https://github.com/getodk/javarosa) which Collect includes as a dependency. +ODK Collect renders forms that are compliant with +the [ODK XForms standard](https://getodk.github.io/xforms-spec/), a subset of +the [XForms 1.1 standard](https://www.w3.org/TR/xforms/) with some extensions. The form parsing is +done by the [JavaRosa library](https://github.com/getodk/javarosa) which Collect includes as a +dependency. Please note that the `master` branch reflects ongoing development and is not production-ready. ## Table of Contents + * [Learn more about ODK Collect](#learn-more-about-odk-collect) * [Release cycle](#release-cycle) * [Downloading builds](#downloading-builds) * [Suggesting new features](#suggesting-new-features) * Contributing - * [Contributing code](#contributing-code) - * [Contributing translations](#contributing-translations) + * [Contributing code](#contributing-code) + * [Contributing translations](#contributing-translations) * Developing - * [Setting up your development environment](#setting-up-your-development-environment) - * [Testing a form without a server](#testing-a-form-without-a-server) - * [Using APIs for local development](#using-apis-for-local-development) - * [Debugging JavaRosa](#debugging-javarosa) - * [Troubleshooting](#troubleshooting) - * [Test devices](#test-devices) + * [Setting up your development environment](#setting-up-your-development-environment) + * [Testing a form without a server](#testing-a-form-without-a-server) + * [Using APIs for local development](#using-apis-for-local-development) + * [Debugging JavaRosa](#debugging-javarosa) + * [Troubleshooting](#troubleshooting) + * [Test devices](#test-devices) * [Creating signed releases for Google Play Store](#creating-signed-releases-for-google-play-store) ## Learn more about ODK Collect + * ODK website: [https://getodk.org](https://getodk.org) -* ODK Collect usage documentation: [https://docs.getodk.org/collect-intro/](https://docs.getodk.org/collect-intro/) +* ODK Collect usage + documentation: [https://docs.getodk.org/collect-intro/](https://docs.getodk.org/collect-intro/) * ODK forum: [https://forum.getodk.org](https://forum.getodk.org) * ODK developer Slack chat: [https://slack.getodk.org](https://slack.getodk.org) ## Release cycle -Releases are planned to happen every 2-3 months (resulting in ~4 releases a year). Soon before (or just after) the end of one release cycle, the core team will plan a new set of work for the next release. This involves: +Releases are planned to happen every 2-3 months (resulting in ~4 releases a year). Soon before (or +just after) the end of one release cycle, the core team will plan a new set of work for the next +release. This involves: -1. Moving issues not finished in the last release and new items from the [ODK Roadmap](https://getodk.org/roadmap) to the [planning board](https://github.com/orgs/getodk/projects/9/views/25) +1. Moving issues not finished in the last release and new items from + the [ODK Roadmap](https://getodk.org/roadmap) to + the [planning board](https://github.com/orgs/getodk/projects/9/views/25) 2. Giving the core team a few days to review and reflect on the planning board -3. The core team will then meet to trim work that will not be included in the next release and pitch alternative things to work on -4. The milestone for the new release is added to [the backlog](https://github.com/orgs/getodk/projects/9) and is prioritized - -Sometimes issues will be assigned to core team members before they are actually started (moved to "in progress") to make it clear who's going to be working on what. - -Once the majority of high risk or visible work is done for a release, a new beta will then be released to the Play Store by [@lognaturel](https://github.com/lognaturel) and that will be used for regression testing by [@getodk/testers](https://github.com/orgs/getodk/teams/testers). If any problems are found, the release is blocked until we can merge fixes. Regression testing should continue on the original beta build (rather than a new one with fixes) unless problems block the rest of testing. Once the process is complete, [@lognaturel](https://github.com/lognaturel) pushes the releases to the Play Store following [these instructions](#creating-signed-releases-for-google-play-store). - -Fixes to a previous release should be merged to a "release" branch (`v2023.2.x` for example) so as to leave `master` available for the current release's work. If hotfix changes are needed in the current release as well then these can be merged in as a PR after hotfix releases (generally easiest as a single PR for the whole hotfix release). This approach can also be used if work for the next release starts before the current one is out - the next release continues on `master` while the release is on a release branch. - -At the beginning of each release cycle, [@grzesiek2010](https://github.com/grzesiek2010) updates all dependencies that have compatible upgrades available and ensures that the build targets the latest SDK. +3. The core team will then meet to trim work that will not be included in the next release and pitch + alternative things to work on +4. The milestone for the new release is added + to [the backlog](https://github.com/orgs/getodk/projects/9) and is prioritized + +Sometimes issues will be assigned to core team members before they are actually started (moved to " +in progress") to make it clear who's going to be working on what. + +Once the majority of high risk or visible work is done for a release, a new beta will then be +released to the Play Store by [@lognaturel](https://github.com/lognaturel) and that will be used for +regression testing by [@getodk/testers](https://github.com/orgs/getodk/teams/testers). If any +problems are found, the release is blocked until we can merge fixes. Regression testing should +continue on the original beta build (rather than a new one with fixes) unless problems block the +rest of testing. Once the process is complete, [@lognaturel](https://github.com/lognaturel) pushes +the releases to the Play Store +following [these instructions](#creating-signed-releases-for-google-play-store). + +Fixes to a previous release should be merged to a "release" branch (`v2023.2.x` for example) so as +to leave `master` available for the current release's work. If hotfix changes are needed in the +current release as well then these can be merged in as a PR after hotfix releases (generally easiest +as a single PR for the whole hotfix release). This approach can also be used if work for the next +release starts before the current one is out - the next release continues on `master` while the +release is on a release branch. + +At the beginning of each release cycle, [@grzesiek2010](https://github.com/grzesiek2010) updates all +dependencies that have compatible upgrades available and ensures that the build targets the latest +SDK. ## Downloading builds -Per-commit debug builds can be found on [CircleCI](https://circleci.com/gh/getodk/collect). Login with your GitHub account, click the build you'd like, then find the APK in the Artifacts tab. -If you are looking to use ODK Collect, we strongly recommend using the [Play Store build](https://play.google.com/store/apps/details?id=org.odk.collect.android). Current and previous production builds can be found in [Releases](https://github.com/getodk/collect/releases). +Per-commit debug builds can be found on [CircleCI](https://circleci.com/gh/getodk/collect). Login +with your GitHub account, click the build you'd like, then find the APK in the Artifacts tab. + +If you are looking to use ODK Collect, we strongly recommend using +the [Play Store build](https://play.google.com/store/apps/details?id=org.odk.collect.android). +Current and previous production builds can be found +in [Releases](https://github.com/getodk/collect/releases). ## Suggesting new features -We try to make sure that all issues in the issue tracker are as close to fully specified as possible so that they can be closed by a pull request. Feature suggestions should be described [in the forum Features category](https://forum.getodk.org/c/features) and discussed by the broader user community. Once there is a clear way forward, issues should be filed on the relevant repositories. More controversial features will be discussed as part of the Technical Steering Committee's [roadmapping process](https://github.com/getodk/governance/blob/master/TSC-1/STANDARD-OPERATING-PROCEDURES.md#roadmap). + +We try to make sure that all issues in the issue tracker are as close to fully specified as possible +so that they can be closed by a pull request. Feature suggestions should be +described [in the forum Features category](https://forum.getodk.org/c/features) and discussed by the +broader user community. Once there is a clear way forward, issues should be filed on the relevant +repositories. More controversial features will be discussed as part of the Technical Steering +Committee's [roadmapping process](https://github.com/getodk/governance/blob/master/TSC-1/STANDARD-OPERATING-PROCEDURES.md#roadmap). ## Contributing code -Any and all contributions to the project are welcome. ODK Collect is used across the world primarily by organizations with a social purpose so you can have real impact! -Issues tagged as [good first issue](https://github.com/getodk/collect/labels/good%20first%20issue) should be a good place to start. There are also currently many issues tagged as [needs reproduction](https://github.com/getodk/collect/labels/needs%20reproduction) which need someone to try to reproduce them with the current version of ODK Collect and comment on the issue with their findings. +Any and all contributions to the project are welcome. ODK Collect is used across the world primarily +by organizations with a social purpose so you can have real impact! + +Issues tagged as [good first issue](https://github.com/getodk/collect/labels/good%20first%20issue) +should be a good place to start. There are also currently many issues tagged +as [needs reproduction](https://github.com/getodk/collect/labels/needs%20reproduction) which need +someone to try to reproduce them with the current version of ODK Collect and comment on the issue +with their findings. If you're ready to contribute code, see [the contribution guide](docs/CONTRIBUTING.md). ## Contributing translations -If you know a language other than English, consider contributing translations through [Transifex](https://www.transifex.com/getodk/collect/). -Translations are updated right before the first beta for a release and before the release itself. To update translations, download the zip from https://www.transifex.com/getodk/collect/strings/. The contents of each folder then need to be moved to the Android project folders. A quick script like [the one in this gist](https://gist.github.com/lognaturel/9974fab4e7579fac034511cd4944176b) can help. We currently copy everything from Transifex to minimize manual intervention. Sometimes translation files will only get comment changes. When new languages are updated in Transifex, they need to be added to the script above. Additionally, `ApplicationConstants.TRANSLATIONS_AVAILABLE` needs to be updated. This array provides the choices for the language preference in settings. Ideally the list could be dynamically generated. +If you know a language other than English, consider contributing translations +through [Transifex](https://www.transifex.com/getodk/collect/). + +Translations are updated right before the first beta for a release and before the release itself. To +update translations, download the zip from https://www.transifex.com/getodk/collect/strings/. The +contents of each folder then need to be moved to the Android project folders. A quick script +like [the one in this gist](https://gist.github.com/lognaturel/9974fab4e7579fac034511cd4944176b) can +help. We currently copy everything from Transifex to minimize manual intervention. Sometimes +translation files will only get comment changes. When new languages are updated in Transifex, they +need to be added to the script above. Additionally, `ApplicationConstants.TRANSLATIONS_AVAILABLE` +needs to be updated. This array provides the choices for the language preference in settings. +Ideally the list could be dynamically generated. ## Setting up your development environment 1. Download and install [Git](https://git-scm.com/downloads) and add it to your PATH -1. Download and install [Android Studio](https://developer.android.com/studio/index.html) +1. Download and install [Android Studio](https://developer.android.com/studio/index.html) 1. Fork the collect project ([why and how to fork](https://help.github.com/articles/fork-a-repo/)) @@ -82,74 +143,126 @@ Translations are updated right before the first beta for a release and before th git clone https://github.com/YOUR-GITHUB-USERNAME/collect - If you prefer not to use the command line, you can use Android Studio to create a new project from version control using `https://github.com/YOUR-GITHUB-USERNAME/collect`. + If you prefer not to use the command line, you can use Android Studio to create a new project + from version control using `https://github.com/YOUR-GITHUB-USERNAME/collect`. -1. Use Android Studio to import the project from its Gradle settings. To run the project, click on the green arrow at the top of the screen. +1. Use Android Studio to import the project from its Gradle settings. To run the project, click on + the green arrow at the top of the screen. -1. Windows developers: continue configuring Android Studio with the steps in this document: [Developing ODK Collect on Windows](docs/WINDOWS-DEV-SETUP.md). +1. Windows developers: continue configuring Android Studio with the steps in this + document: [Developing ODK Collect on Windows](docs/WINDOWS-DEV-SETUP.md). -1. Make sure you can run unit tests by running everything under `collect_app/src/test/java` in Android Studio or on the command line: +1. Make sure you can run unit tests by running everything under `collect_app/src/test/java` in + Android Studio or on the command line: ``` ./gradlew testDebug ``` -1. Make sure you can run instrumented tests by running everything under `collect_app/src/androidTest/java` in Android Studio or on the command line: +1. Make sure you can run instrumented tests by running everything + under `collect_app/src/androidTest/java` in Android Studio or on the command line: ``` ./gradlew connectedAndroidTest ``` - **Note:** You can see the emulator setup used on CI in `.circleci/config.yml`. + **Note:** You can see the emulator setup used on CI in `.circleci/config.yml`. ## Customizing the development environment ### Changing JVM heap size -You can customize the heap size that is used for compiling and running tests. Increasing these will most likely speed up compilation and tests on your local machine. The default values are specified in the project's `gradle.properties` and this can be overriden by your user level `gradle.properties` (found in your `GRADLE_USER_HOME` directory). An example `gradle.properties` that would give you a heap size of 4GB (rather than the default 1GB) would look like: +You can customize the heap size that is used for compiling and running tests. Increasing these will +most likely speed up compilation and tests on your local machine. The default values are specified +in the project's `gradle.properties` and this can be overriden by your user +level `gradle.properties` (found in your `GRADLE_USER_HOME` directory). An +example `gradle.properties` that would give you a heap size of 4GB (rather than the default 1GB) +would look like: ``` org.gradle.jvmargs=-Xmx4096m ``` ## Testing a form without a server -When you first run Collect, it is set to download forms from [https://demo.getodk.org/](https://demo.getodk.org/), the demo server. You can sometimes verify your changes with those forms but it can also be helpful to put a specific test form on your device. Here are some options for that: -1. The `All question types` form from the default server is [here](https://docs.google.com/spreadsheets/d/1af_Sl8A_L8_EULbhRLHVl8OclCfco09Hq2tqb9CslwQ/edit#gid=0). You can also try [example forms](https://github.com/XLSForm/example-forms) and [test forms](https://github.com/XLSForm/test-forms) or [make your own](https://xlsform.org). +When you first run Collect, it is set to download forms +from [https://demo.getodk.org/](https://demo.getodk.org/), the demo server. You can sometimes verify +your changes with those forms but it can also be helpful to put a specific test form on your device. +Here are some options for that: -1. Convert the XLSForm (xlsx) to XForm (xml). Use the [ODK website](http://getodk.org/xlsform/) or [XLSForm Offline](https://gumroad.com/l/xlsform-offline) or [pyxform](https://github.com/XLSForm/pyxform). +1. The `All question types` form from the default server + is [here](https://docs.google.com/spreadsheets/d/1af_Sl8A_L8_EULbhRLHVl8OclCfco09Hq2tqb9CslwQ/edit#gid=0). + You can also try [example forms](https://github.com/XLSForm/example-forms) + and [test forms](https://github.com/XLSForm/test-forms) or [make your own](https://xlsform.org). -1. Once you have the XForm, use [adb](https://developer.android.com/studio/command-line/adb.html) to push the form to your device (after [enabling USB debugging](https://www.kingoapp.com/root-tutorials/how-to-enable-usb-debugging-mode-on-android.htm)) or emulator. - ``` - adb push my_form.xml /sdcard/Android/data/org.odk.collect.android/files/formsprojects/DEMO/forms - ``` +2. Convert the XLSForm (xlsx) to XForm (xml). Use the [ODK website](http://getodk.org/xlsform/) + or [XLSForm Offline](https://gumroad.com/l/xlsform-offline) + or [pyxform](https://github.com/XLSForm/pyxform). -1. Launch ODK Collect and tap `+ Start new form`. The new form will be there. +3. Once you have the XForm, use [adb](https://developer.android.com/studio/command-line/adb.html) to + push the form to your device ( + after [enabling USB debugging](https://www.kingoapp.com/root-tutorials/how-to-enable-usb-debugging-mode-on-android.htm)) + or emulator. + ``` + adb push my_form.xml /sdcard/Android/data/org.odk.collect.android/files/projects/{project-id}/forms + ``` -## Using APIs for local development +If you are using the demo project, kindly replace `{project_id}` with `DEMO` -Certain functions in ODK Collect depend on cloud services that require API keys or authorization steps to work. Here are the steps you need to take in order to use these functions in your development builds. +4. Launch ODK Collect and tap `+ Start new form`. The new form will be there. -**Google Maps API**: When the "Google Maps SDK" option is selected in the "User interface" settings, ODK Collect uses the Google Maps API for displaying maps in the geospatial question types (GeoPoint, GeoTrace, and GeoShape). To enable this API: - 1. [Get a Google Maps API key](https://developers.google.com/maps/documentation/android-api/signup). Note that this requires a credit card number, though the card will not be charged immediately; some free API usage is permitted. You should carefully read the terms before providing a credit card number. - 1. Edit or create `secrets.properties` and set the `GOOGLE_MAPS_API_KEY` property to your API key. You should end up with a line that looks like this: - ``` - GOOGLE_MAPS_API_KEY=AIbzvW8e0ub... - ``` +More information about using Android Debug Bridge with Collect can be found [here](https://docs.getodk.org/collect-adb/). -**Mapbox Maps SDK for Android**: When the "Mapbox SDK" option is selected in the "User interface" settings, ODK Collect uses the Mapbox SDK for displaying maps in the geospatial question types (GeoPoint, GeoTrace, and GeoShape). To enable this API: - 1. [Create a Mapbox account](https://www.mapbox.com/signup/). Note that signing up with the "Pay-As-You-Go" plan does not require a credit card. Mapbox provides free API usage up to the monthly thresholds documented at [https://www.mapbox.com/pricing](https://www.mapbox.com/pricing). If your usage exceeds these thresholds, you will receive e-mail with instructions on how to add a credit card for payment; services will remain live until the end of the 30-day billing term, after which the account will be deactivated and will require a credit card to reactivate. - 2. Find your access token on your [account page](https://account.mapbox.com/) - it should be in "Tokens" as "Default public token". - 3. Edit or create `secrets.properties` and set the `MAPBOX_ACCESS_TOKEN` property to your access token. You should end up with a line that looks like this: - ``` - MAPBOX_ACCESS_TOKEN=pk.eyJk3bumVp4i... - ``` - 4. Create a new secret token with the "DOWNLOADS:READ" secret scope and then add it to `secrets.properties` as `MAPBOX_DOWNLOADS_TOKEN`. +## Using APIs for local development -*Note: Mapbox will not be available as an option in compiled versions of Collect unless you follow the steps above. Mapbox will also not be available on x86 devices as the native libraries are excluded to reduce the APK size. If you need to use an x86 device, you can force the build to include x86 libs by include the `x86Libs` Gradle parameter. For example, to build a debug APK with x86 libs: `./gradlew assembleDebug -Px86Libs`.* +Certain functions in ODK Collect depend on cloud services that require API keys or authorization +steps to work. Here are the steps you need to take in order to use these functions in your +development builds. + +**Google Maps API**: When the "Google Maps SDK" option is selected in the "User interface" settings, +ODK Collect uses the Google Maps API for displaying maps in the geospatial question types (GeoPoint, +GeoTrace, and GeoShape). To enable this API: + +1. [Get a Google Maps API key](https://developers.google.com/maps/documentation/android-api/signup). + Note that this requires a credit card number, though the card will not be charged immediately; + some free API usage is permitted. You should carefully read the terms before providing a credit + card number. +1. Edit or create `secrets.properties` and set the `GOOGLE_MAPS_API_KEY` property to your API key. + You should end up with a line that looks like this: + ``` + GOOGLE_MAPS_API_KEY=AIbzvW8e0ub... + ``` + +**Mapbox Maps SDK for Android**: When the "Mapbox SDK" option is selected in the "User interface" +settings, ODK Collect uses the Mapbox SDK for displaying maps in the geospatial question types ( +GeoPoint, GeoTrace, and GeoShape). To enable this API: + +1. [Create a Mapbox account](https://www.mapbox.com/signup/). Note that signing up with the " + Pay-As-You-Go" plan does not require a credit card. Mapbox provides free API usage up to the + monthly thresholds documented + at [https://www.mapbox.com/pricing](https://www.mapbox.com/pricing). If your usage exceeds these + thresholds, you will receive e-mail with instructions on how to add a credit card for payment; + services will remain live until the end of the 30-day billing term, after which the account will + be deactivated and will require a credit card to reactivate. +2. Find your access token on your [account page](https://account.mapbox.com/) - it should be in " + Tokens" as "Default public token". +3. Edit or create `secrets.properties` and set the `MAPBOX_ACCESS_TOKEN` property to your access + token. You should end up with a line that looks like this: + ``` + MAPBOX_ACCESS_TOKEN=pk.eyJk3bumVp4i... + ``` +4. Create a new secret token with the "DOWNLOADS:READ" secret scope and then add it + to `secrets.properties` as `MAPBOX_DOWNLOADS_TOKEN`. + +*Note: Mapbox will not be available as an option in compiled versions of Collect unless you follow +the steps above. Mapbox will also not be available on x86 devices as the native libraries are +excluded to reduce the APK size. If you need to use an x86 device, you can force the build to +include x86 libs by include the `x86Libs` Gradle parameter. For example, to build a debug APK with +x86 libs: `./gradlew assembleDebug -Px86Libs`.* ## Debugging JavaRosa -JavaRosa is the form engine that powers Collect. If you want to debug or change that code while running Collect you can deploy it locally with Maven (you'll need `mvn` and `sed` installed): +JavaRosa is the form engine that powers Collect. If you want to debug or change that code while +running Collect you can deploy it locally with Maven (you'll need `mvn` and `sed` installed): 1. Build and install your changes of JavaRosa (into your local Maven repo): @@ -157,24 +270,41 @@ JavaRosa is the form engine that powers Collect. If you want to debug or change ./gradlew publishToMavenLocal ``` -1. Change `const val javarosa = javarosa_online` in `Dependencies.kt` to `const val javarosa = javarosa_local` +1. Change `const val javarosa = javarosa_online` in `Dependencies.kt` + to `const val javarosa = javarosa_local` ## Troubleshooting #### Error when running Robolectric tests from Android Studio on macOS: `build/intermediates/bundles/debug/AndroidManifest.xml (No such file or directory)` -> Configure the default JUnit test runner configuration in order to work around a bug where IntelliJ / Android Studio does not set the working directory to the module being tested. This can be accomplished by editing the run configurations, Defaults -> JUnit and changing the working directory value to $MODULE_DIR$. -> Source: [Robolectric Wiki](https://github.com/robolectric/robolectric/wiki/Running-tests-in-Android-Studio#notes-for-mac). +> Configure the default JUnit test runner configuration in order to work around a bug where +> IntelliJ / Android Studio does not set the working directory to the module being tested. This can be +> accomplished by editing the run configurations, Defaults -> JUnit and changing the working directory +> value to $MODULE_DIR$. + +> +Source: [Robolectric Wiki](https://github.com/robolectric/robolectric/wiki/Running-tests-in-Android-Studio#notes-for-mac). #### Android Studio Error: `SDK location not found. Define location with sdk.dir in the local.properties file or with an ANDROID_HOME environment variable.` -When cloning the project from Android Studio, click "No" when prompted to open the `build.gradle` file and then open project. + +When cloning the project from Android Studio, click "No" when prompted to open the `build.gradle` +file and then open project. #### Execution failed for task ':collect_app:transformClassesWithInstantRunForDebug'. -We have seen this problem happen in both IntelliJ IDEA and Android Studio, and believe it to be due to a bug in the IDE, which we can't fix. As a workaround, turning off [Instant Run](https://developer.android.com/studio/run/#set-up-ir) will usually avoid this problem. The problem is fixed in Android Studio 3.5 with the new [Apply Changes](https://medium.com/androiddevelopers/android-studio-project-marble-apply-changes-e3048662e8cd) feature. +We have seen this problem happen in both IntelliJ IDEA and Android Studio, and believe it to be due +to a bug in the IDE, which we can't fix. As a workaround, turning +off [Instant Run](https://developer.android.com/studio/run/#set-up-ir) will usually avoid this +problem. The problem is fixed in Android Studio 3.5 with the +new [Apply Changes](https://medium.com/androiddevelopers/android-studio-project-marble-apply-changes-e3048662e8cd) +feature. #### Moving to the main view if user minimizes the app -If you build the app on your own using Android Studio `(Build -> Build APK)` and then install it (from an `.apk` file), you might notice this strange behaviour thoroughly described: [#1280](https://github.com/getodk/collect/issues/1280) and [#1142](https://github.com/getodk/collect/issues/1142). + +If you build the app on your own using Android Studio `(Build -> Build APK)` and then install it ( +from an `.apk` file), you might notice this strange behaviour thoroughly +described: [#1280](https://github.com/getodk/collect/issues/1280) +and [#1142](https://github.com/getodk/collect/issues/1142). This problem occurs building other apps as well. @@ -191,21 +321,29 @@ A problem occurred configuring project ':collect_app'. > Could not initialize class com.android.sdklib.repository.AndroidSdkHandler ``` -You may have a mismatch between the embedded Android SDK Java and the JDK installed on your machine. You may wish to set your **JAVA_HOME** environment variable to that SDK. For example, on macOS: +You may have a mismatch between the embedded Android SDK Java and the JDK installed on your machine. +You may wish to set your **JAVA_HOME** environment variable to that SDK. For example, on macOS: `export JAVA_HOME="/Applications/Android\ Studio.app/Contents/jre/Contents/Home/" ` -Note that this change might cause problems with other Java-based applications (e.g., if you uninstall Android Studio). +Note that this change might cause problems with other Java-based applications (e.g., if you +uninstall Android Studio). #### gradlew Failure: `java.lang.NullPointerException (no error message).` -If you encounter the `java.lang.NullPointerException (no error message).` when running `gradlew`, please make sure your Java version for this project is Java 17. -This can be configured under **File > Project Structure** in Android Studio, or by editing `$USER_HOME/.gradle/gradle.properties` to set `org.gradle.java.home=(path to JDK home)` for command-line use. +If you encounter the `java.lang.NullPointerException (no error message).` when running `gradlew`, +please make sure your Java version for this project is Java 17. + +This can be configured under **File > Project Structure** in Android Studio, or by +editing `$USER_HOME/.gradle/gradle.properties` to set `org.gradle.java.home=(path to JDK home)` for +command-line use. #### `Unable to resolve artifact: Missing` while running tests -This is encountered when Robolectric has problems downloading the jars it needs for different Android SDK levels. If you keep running into this you can download the JARs locally and point Robolectric to them by doing: +This is encountered when Robolectric has problems downloading the jars it needs for different +Android SDK levels. If you keep running into this you can download the JARs locally and point +Robolectric to them by doing: ``` ./download-robolectric-deps.sh @@ -226,7 +364,9 @@ Devices that @getodk/testers have available for testing are as follows: * Huawei Y560-L01 1GB - Android 5.1 ## Creating signed releases for Google Play Store -Maintainers keep a folder with a clean checkout of the code and use [jenv.be](https://www.jenv.be) in that folder to ensure compilation with Java 17. + +Maintainers keep a folder with a clean checkout of the code and use [jenv.be](https://www.jenv.be) +in that folder to ensure compilation with Java 17. ### Release prerequisites: @@ -246,25 +386,37 @@ Maintainers keep a folder with a clean checkout of the code and use [jenv.be](ht RELEASE_KEY_PASSWORD=secure-alias-password ``` -- a `google-services.json` file in the `collect_app/src/odkCollectRelease` folder. The contents of the file are similar to the contents of `collect_app/src/google-services.json`. +- a `google-services.json` file in the `collect_app/src/odkCollectRelease` folder. The contents of + the file are similar to the contents of `collect_app/src/google-services.json`. ### Release checklist: - update translations - make sure CI is green for the chosen commit -- run `./gradlew releaseCheck`. If successful, a signed release will be at `collect_app/build/outputs/apk` (with an old version name) -- verify a basic "happy path": scan a QR code to configure a new project, get a blank form, fill it, open the form map (confirms that the Google Maps key is correct), send form +- run `./gradlew releaseCheck`. If successful, a signed release will be + at `collect_app/build/outputs/apk` (with an old version name) +- verify a basic "happy path": scan a QR code to configure a new project, get a blank form, fill it, + open the form map (confirms that the Google Maps key is correct), send form - run `./benchmark.sh` with a real device connected to verify performance -- verify new APK can be installed as update to previous version and that above "happy path" works in that case also +- verify new APK can be installed as update to previous version and that above "happy path" works in + that case also - create and publish scheduled forum post with release description - write Play Store release notes, include link to forum post -- create a release with the correct version by tagging the commit and running `./collect_app:assembleOdkCollectRelease` - - Tags for full releases must have the format `vX.X.X`. Tags for beta releases must have the format `vX.X.X-beta.X`. -- add a release to Github [here](https://github.com/getodk/collect/releases), generate release notes and attach the APK +- create a release with the correct version by tagging the commit and + running `./collect_app:assembleOdkCollectRelease` + - Tags for full releases must have the format `vX.X.X`. Tags for beta releases must have the + format `vX.X.X-beta.X`. +- add a release to Github [here](https://github.com/getodk/collect/releases), generate release notes + and attach the APK - upload APK to Play Store -- if there was an active beta before release (this can happen with point releases), publish a new beta release to replace the previous one which was disabled by the production release -- backup dependencies for the release by downloading the `vX.X.X.tar` artifact from the `create_dependency_backup` job on Circle CI (for the release commit) and then uploading it to [this folder](https://drive.google.com/drive/folders/1_tMKBFLdhzFZF9GKNeob4FbARjdfbtJu?usp=share_link) -- backup a self signed release APK by downloading the `selfSignedRelease.apk` from the `build_release` job on Circle CI (for the release commit) and then upload to [this folder](https://drive.google.com/drive/folders/1pbbeNaMTziFhtZmedOs0If3BeYu3Ex5x?usp=share_link) +- if there was an active beta before release (this can happen with point releases), publish a new + beta release to replace the previous one which was disabled by the production release +- backup dependencies for the release by downloading the `vX.X.X.tar` artifact from + the `create_dependency_backup` job on Circle CI (for the release commit) and then uploading it + to [this folder](https://drive.google.com/drive/folders/1_tMKBFLdhzFZF9GKNeob4FbARjdfbtJu?usp=share_link) +- backup a self signed release APK by downloading the `selfSignedRelease.apk` from + the `build_release` job on Circle CI (for the release commit) and then upload + to [this folder](https://drive.google.com/drive/folders/1pbbeNaMTziFhtZmedOs0If3BeYu3Ex5x?usp=share_link) ## Compiling a previous release using backed-up dependencies @@ -273,6 +425,7 @@ Maintainers keep a folder with a clean checkout of the code and use [jenv.be](ht ```bash tar -xf maven.tar -C ``` - -The project will now be able to fetch dependencies that are no longer available (but were used to compile the release) from the `.local-m2` Maven repo. + +The project will now be able to fetch dependencies that are no longer available (but were used to +compile the release) from the `.local-m2` Maven repo. diff --git a/collect_app/src/androidTest/java/org/odk/collect/android/feature/formentry/AddRepeatTest.java b/collect_app/src/androidTest/java/org/odk/collect/android/feature/formentry/AddRepeatTest.java index b1d889532c4..ab26c8291ac 100644 --- a/collect_app/src/androidTest/java/org/odk/collect/android/feature/formentry/AddRepeatTest.java +++ b/collect_app/src/androidTest/java/org/odk/collect/android/feature/formentry/AddRepeatTest.java @@ -120,12 +120,11 @@ public void whenInHierarchyForRepeat_clickingPlus_addsRepeatAtEndOfSeries() { } @Test - public void whenInEmptyRepeat_swipingNext_andClickingAdd_addsAnotherRepeat() { + public void whenInRepeatWithoutLabel_swipingNext_andClickingAdd_addsAnotherRepeat() { rule.startAtMainMenu() .copyForm(REPEAT_WITHOUT_LABEL) .startBlankForm("Repeat without label") .assertText("> 1") - .assertQuestion("First name", true) .answerQuestion("First name", true, "Karan") .swipeToNextQuestionWithRepeatGroup("") .clickOnAdd(new FormEntryPage("Repeat without label")) From db0ebcf50245e657a0039d124b6701de27505005 Mon Sep 17 00:00:00 2001 From: karntrehan Date: Mon, 4 Nov 2024 11:09:15 +0530 Subject: [PATCH 6/6] [#6439] PR feedback - Undo formatting changes to README.md --- README.md | 328 +++++++++++++++--------------------------------------- 1 file changed, 90 insertions(+), 238 deletions(-) diff --git a/README.md b/README.md index 4b5f1fb6851..f87d89d9307 100644 --- a/README.md +++ b/README.md @@ -5,137 +5,77 @@ [![Build status](https://circleci.com/gh/getodk/collect.svg?style=shield&circle-token=:circle-token)](https://circleci.com/gh/getodk/collect) [![Slack](https://img.shields.io/badge/chat-on%20slack-brightgreen)](https://slack.getodk.org) -ODK Collect is an Android app for filling out forms. It is designed to be used in -resource-constrained environments with challenges such as unreliable connectivity or power -infrastructure. ODK Collect is part the ODK project, a free and open-source set of tools which help -organizations author, field, and manage mobile data collection solutions. Learn more about ODK and -its history [here](https://getodk.org/) and read about example ODK -deployments [here](https://forum.getodk.org/c/showcase). - -ODK Collect renders forms that are compliant with -the [ODK XForms standard](https://getodk.github.io/xforms-spec/), a subset of -the [XForms 1.1 standard](https://www.w3.org/TR/xforms/) with some extensions. The form parsing is -done by the [JavaRosa library](https://github.com/getodk/javarosa) which Collect includes as a -dependency. +ODK Collect is an Android app for filling out forms. It is designed to be used in resource-constrained environments with challenges such as unreliable connectivity or power infrastructure. ODK Collect is part the ODK project, a free and open-source set of tools which help organizations author, field, and manage mobile data collection solutions. Learn more about ODK and its history [here](https://getodk.org/) and read about example ODK deployments [here](https://forum.getodk.org/c/showcase). + +ODK Collect renders forms that are compliant with the [ODK XForms standard](https://getodk.github.io/xforms-spec/), a subset of the [XForms 1.1 standard](https://www.w3.org/TR/xforms/) with some extensions. The form parsing is done by the [JavaRosa library](https://github.com/getodk/javarosa) which Collect includes as a dependency. Please note that the `master` branch reflects ongoing development and is not production-ready. ## Table of Contents - * [Learn more about ODK Collect](#learn-more-about-odk-collect) * [Release cycle](#release-cycle) * [Downloading builds](#downloading-builds) * [Suggesting new features](#suggesting-new-features) * Contributing - * [Contributing code](#contributing-code) - * [Contributing translations](#contributing-translations) + * [Contributing code](#contributing-code) + * [Contributing translations](#contributing-translations) * Developing - * [Setting up your development environment](#setting-up-your-development-environment) - * [Testing a form without a server](#testing-a-form-without-a-server) - * [Using APIs for local development](#using-apis-for-local-development) - * [Debugging JavaRosa](#debugging-javarosa) - * [Troubleshooting](#troubleshooting) - * [Test devices](#test-devices) + * [Setting up your development environment](#setting-up-your-development-environment) + * [Testing a form without a server](#testing-a-form-without-a-server) + * [Using APIs for local development](#using-apis-for-local-development) + * [Debugging JavaRosa](#debugging-javarosa) + * [Troubleshooting](#troubleshooting) + * [Test devices](#test-devices) * [Creating signed releases for Google Play Store](#creating-signed-releases-for-google-play-store) ## Learn more about ODK Collect - * ODK website: [https://getodk.org](https://getodk.org) -* ODK Collect usage - documentation: [https://docs.getodk.org/collect-intro/](https://docs.getodk.org/collect-intro/) +* ODK Collect usage documentation: [https://docs.getodk.org/collect-intro/](https://docs.getodk.org/collect-intro/) * ODK forum: [https://forum.getodk.org](https://forum.getodk.org) * ODK developer Slack chat: [https://slack.getodk.org](https://slack.getodk.org) ## Release cycle -Releases are planned to happen every 2-3 months (resulting in ~4 releases a year). Soon before (or -just after) the end of one release cycle, the core team will plan a new set of work for the next -release. This involves: +Releases are planned to happen every 2-3 months (resulting in ~4 releases a year). Soon before (or just after) the end of one release cycle, the core team will plan a new set of work for the next release. This involves: -1. Moving issues not finished in the last release and new items from - the [ODK Roadmap](https://getodk.org/roadmap) to - the [planning board](https://github.com/orgs/getodk/projects/9/views/25) +1. Moving issues not finished in the last release and new items from the [ODK Roadmap](https://getodk.org/roadmap) to the [planning board](https://github.com/orgs/getodk/projects/9/views/25) 2. Giving the core team a few days to review and reflect on the planning board -3. The core team will then meet to trim work that will not be included in the next release and pitch - alternative things to work on -4. The milestone for the new release is added - to [the backlog](https://github.com/orgs/getodk/projects/9) and is prioritized - -Sometimes issues will be assigned to core team members before they are actually started (moved to " -in progress") to make it clear who's going to be working on what. - -Once the majority of high risk or visible work is done for a release, a new beta will then be -released to the Play Store by [@lognaturel](https://github.com/lognaturel) and that will be used for -regression testing by [@getodk/testers](https://github.com/orgs/getodk/teams/testers). If any -problems are found, the release is blocked until we can merge fixes. Regression testing should -continue on the original beta build (rather than a new one with fixes) unless problems block the -rest of testing. Once the process is complete, [@lognaturel](https://github.com/lognaturel) pushes -the releases to the Play Store -following [these instructions](#creating-signed-releases-for-google-play-store). - -Fixes to a previous release should be merged to a "release" branch (`v2023.2.x` for example) so as -to leave `master` available for the current release's work. If hotfix changes are needed in the -current release as well then these can be merged in as a PR after hotfix releases (generally easiest -as a single PR for the whole hotfix release). This approach can also be used if work for the next -release starts before the current one is out - the next release continues on `master` while the -release is on a release branch. - -At the beginning of each release cycle, [@grzesiek2010](https://github.com/grzesiek2010) updates all -dependencies that have compatible upgrades available and ensures that the build targets the latest -SDK. +3. The core team will then meet to trim work that will not be included in the next release and pitch alternative things to work on +4. The milestone for the new release is added to [the backlog](https://github.com/orgs/getodk/projects/9) and is prioritized -## Downloading builds +Sometimes issues will be assigned to core team members before they are actually started (moved to "in progress") to make it clear who's going to be working on what. -Per-commit debug builds can be found on [CircleCI](https://circleci.com/gh/getodk/collect). Login -with your GitHub account, click the build you'd like, then find the APK in the Artifacts tab. +Once the majority of high risk or visible work is done for a release, a new beta will then be released to the Play Store by [@lognaturel](https://github.com/lognaturel) and that will be used for regression testing by [@getodk/testers](https://github.com/orgs/getodk/teams/testers). If any problems are found, the release is blocked until we can merge fixes. Regression testing should continue on the original beta build (rather than a new one with fixes) unless problems block the rest of testing. Once the process is complete, [@lognaturel](https://github.com/lognaturel) pushes the releases to the Play Store following [these instructions](#creating-signed-releases-for-google-play-store). -If you are looking to use ODK Collect, we strongly recommend using -the [Play Store build](https://play.google.com/store/apps/details?id=org.odk.collect.android). -Current and previous production builds can be found -in [Releases](https://github.com/getodk/collect/releases). +Fixes to a previous release should be merged to a "release" branch (`v2023.2.x` for example) so as to leave `master` available for the current release's work. If hotfix changes are needed in the current release as well then these can be merged in as a PR after hotfix releases (generally easiest as a single PR for the whole hotfix release). This approach can also be used if work for the next release starts before the current one is out - the next release continues on `master` while the release is on a release branch. -## Suggesting new features +At the beginning of each release cycle, [@grzesiek2010](https://github.com/grzesiek2010) updates all dependencies that have compatible upgrades available and ensures that the build targets the latest SDK. -We try to make sure that all issues in the issue tracker are as close to fully specified as possible -so that they can be closed by a pull request. Feature suggestions should be -described [in the forum Features category](https://forum.getodk.org/c/features) and discussed by the -broader user community. Once there is a clear way forward, issues should be filed on the relevant -repositories. More controversial features will be discussed as part of the Technical Steering -Committee's [roadmapping process](https://github.com/getodk/governance/blob/master/TSC-1/STANDARD-OPERATING-PROCEDURES.md#roadmap). +## Downloading builds +Per-commit debug builds can be found on [CircleCI](https://circleci.com/gh/getodk/collect). Login with your GitHub account, click the build you'd like, then find the APK in the Artifacts tab. -## Contributing code +If you are looking to use ODK Collect, we strongly recommend using the [Play Store build](https://play.google.com/store/apps/details?id=org.odk.collect.android). Current and previous production builds can be found in [Releases](https://github.com/getodk/collect/releases). -Any and all contributions to the project are welcome. ODK Collect is used across the world primarily -by organizations with a social purpose so you can have real impact! +## Suggesting new features +We try to make sure that all issues in the issue tracker are as close to fully specified as possible so that they can be closed by a pull request. Feature suggestions should be described [in the forum Features category](https://forum.getodk.org/c/features) and discussed by the broader user community. Once there is a clear way forward, issues should be filed on the relevant repositories. More controversial features will be discussed as part of the Technical Steering Committee's [roadmapping process](https://github.com/getodk/governance/blob/master/TSC-1/STANDARD-OPERATING-PROCEDURES.md#roadmap). + +## Contributing code +Any and all contributions to the project are welcome. ODK Collect is used across the world primarily by organizations with a social purpose so you can have real impact! -Issues tagged as [good first issue](https://github.com/getodk/collect/labels/good%20first%20issue) -should be a good place to start. There are also currently many issues tagged -as [needs reproduction](https://github.com/getodk/collect/labels/needs%20reproduction) which need -someone to try to reproduce them with the current version of ODK Collect and comment on the issue -with their findings. +Issues tagged as [good first issue](https://github.com/getodk/collect/labels/good%20first%20issue) should be a good place to start. There are also currently many issues tagged as [needs reproduction](https://github.com/getodk/collect/labels/needs%20reproduction) which need someone to try to reproduce them with the current version of ODK Collect and comment on the issue with their findings. If you're ready to contribute code, see [the contribution guide](docs/CONTRIBUTING.md). ## Contributing translations +If you know a language other than English, consider contributing translations through [Transifex](https://www.transifex.com/getodk/collect/). -If you know a language other than English, consider contributing translations -through [Transifex](https://www.transifex.com/getodk/collect/). - -Translations are updated right before the first beta for a release and before the release itself. To -update translations, download the zip from https://www.transifex.com/getodk/collect/strings/. The -contents of each folder then need to be moved to the Android project folders. A quick script -like [the one in this gist](https://gist.github.com/lognaturel/9974fab4e7579fac034511cd4944176b) can -help. We currently copy everything from Transifex to minimize manual intervention. Sometimes -translation files will only get comment changes. When new languages are updated in Transifex, they -need to be added to the script above. Additionally, `ApplicationConstants.TRANSLATIONS_AVAILABLE` -needs to be updated. This array provides the choices for the language preference in settings. -Ideally the list could be dynamically generated. +Translations are updated right before the first beta for a release and before the release itself. To update translations, download the zip from https://www.transifex.com/getodk/collect/strings/. The contents of each folder then need to be moved to the Android project folders. A quick script like [the one in this gist](https://gist.github.com/lognaturel/9974fab4e7579fac034511cd4944176b) can help. We currently copy everything from Transifex to minimize manual intervention. Sometimes translation files will only get comment changes. When new languages are updated in Transifex, they need to be added to the script above. Additionally, `ApplicationConstants.TRANSLATIONS_AVAILABLE` needs to be updated. This array provides the choices for the language preference in settings. Ideally the list could be dynamically generated. ## Setting up your development environment 1. Download and install [Git](https://git-scm.com/downloads) and add it to your PATH -1. Download and install [Android Studio](https://developer.android.com/studio/index.html) +1. Download and install [Android Studio](https://developer.android.com/studio/index.html) 1. Fork the collect project ([why and how to fork](https://help.github.com/articles/fork-a-repo/)) @@ -143,68 +83,46 @@ Ideally the list could be dynamically generated. git clone https://github.com/YOUR-GITHUB-USERNAME/collect - If you prefer not to use the command line, you can use Android Studio to create a new project - from version control using `https://github.com/YOUR-GITHUB-USERNAME/collect`. + If you prefer not to use the command line, you can use Android Studio to create a new project from version control using `https://github.com/YOUR-GITHUB-USERNAME/collect`. -1. Use Android Studio to import the project from its Gradle settings. To run the project, click on - the green arrow at the top of the screen. +1. Use Android Studio to import the project from its Gradle settings. To run the project, click on the green arrow at the top of the screen. -1. Windows developers: continue configuring Android Studio with the steps in this - document: [Developing ODK Collect on Windows](docs/WINDOWS-DEV-SETUP.md). +1. Windows developers: continue configuring Android Studio with the steps in this document: [Developing ODK Collect on Windows](docs/WINDOWS-DEV-SETUP.md). -1. Make sure you can run unit tests by running everything under `collect_app/src/test/java` in - Android Studio or on the command line: +1. Make sure you can run unit tests by running everything under `collect_app/src/test/java` in Android Studio or on the command line: ``` ./gradlew testDebug ``` -1. Make sure you can run instrumented tests by running everything - under `collect_app/src/androidTest/java` in Android Studio or on the command line: +1. Make sure you can run instrumented tests by running everything under `collect_app/src/androidTest/java` in Android Studio or on the command line: ``` ./gradlew connectedAndroidTest ``` - **Note:** You can see the emulator setup used on CI in `.circleci/config.yml`. + **Note:** You can see the emulator setup used on CI in `.circleci/config.yml`. ## Customizing the development environment ### Changing JVM heap size -You can customize the heap size that is used for compiling and running tests. Increasing these will -most likely speed up compilation and tests on your local machine. The default values are specified -in the project's `gradle.properties` and this can be overriden by your user -level `gradle.properties` (found in your `GRADLE_USER_HOME` directory). An -example `gradle.properties` that would give you a heap size of 4GB (rather than the default 1GB) -would look like: +You can customize the heap size that is used for compiling and running tests. Increasing these will most likely speed up compilation and tests on your local machine. The default values are specified in the project's `gradle.properties` and this can be overriden by your user level `gradle.properties` (found in your `GRADLE_USER_HOME` directory). An example `gradle.properties` that would give you a heap size of 4GB (rather than the default 1GB) would look like: ``` org.gradle.jvmargs=-Xmx4096m ``` ## Testing a form without a server +When you first run Collect, it is set to download forms from [https://demo.getodk.org/](https://demo.getodk.org/), the demo server. You can sometimes verify your changes with those forms but it can also be helpful to put a specific test form on your device. Here are some options for that: -When you first run Collect, it is set to download forms -from [https://demo.getodk.org/](https://demo.getodk.org/), the demo server. You can sometimes verify -your changes with those forms but it can also be helpful to put a specific test form on your device. -Here are some options for that: - -1. The `All question types` form from the default server - is [here](https://docs.google.com/spreadsheets/d/1af_Sl8A_L8_EULbhRLHVl8OclCfco09Hq2tqb9CslwQ/edit#gid=0). - You can also try [example forms](https://github.com/XLSForm/example-forms) - and [test forms](https://github.com/XLSForm/test-forms) or [make your own](https://xlsform.org). +1. The `All question types` form from the default server is [here](https://docs.google.com/spreadsheets/d/1af_Sl8A_L8_EULbhRLHVl8OclCfco09Hq2tqb9CslwQ/edit#gid=0). You can also try [example forms](https://github.com/XLSForm/example-forms) and [test forms](https://github.com/XLSForm/test-forms) or [make your own](https://xlsform.org). -2. Convert the XLSForm (xlsx) to XForm (xml). Use the [ODK website](http://getodk.org/xlsform/) - or [XLSForm Offline](https://gumroad.com/l/xlsform-offline) - or [pyxform](https://github.com/XLSForm/pyxform). +1. Convert the XLSForm (xlsx) to XForm (xml). Use the [ODK website](http://getodk.org/xlsform/) or [XLSForm Offline](https://gumroad.com/l/xlsform-offline) or [pyxform](https://github.com/XLSForm/pyxform). -3. Once you have the XForm, use [adb](https://developer.android.com/studio/command-line/adb.html) to - push the form to your device ( - after [enabling USB debugging](https://www.kingoapp.com/root-tutorials/how-to-enable-usb-debugging-mode-on-android.htm)) - or emulator. - ``` - adb push my_form.xml /sdcard/Android/data/org.odk.collect.android/files/projects/{project-id}/forms - ``` +1. Once you have the XForm, use [adb](https://developer.android.com/studio/command-line/adb.html) to push the form to your device (after [enabling USB debugging](https://www.kingoapp.com/root-tutorials/how-to-enable-usb-debugging-mode-on-android.htm)) or emulator. + ``` + adb push my_form.xml /sdcard/Android/data/org.odk.collect.android/files/projects/{project-id}/forms + ``` If you are using the demo project, kindly replace `{project_id}` with `DEMO` @@ -214,55 +132,29 @@ More information about using Android Debug Bridge with Collect can be found [her ## Using APIs for local development -Certain functions in ODK Collect depend on cloud services that require API keys or authorization -steps to work. Here are the steps you need to take in order to use these functions in your -development builds. - -**Google Maps API**: When the "Google Maps SDK" option is selected in the "User interface" settings, -ODK Collect uses the Google Maps API for displaying maps in the geospatial question types (GeoPoint, -GeoTrace, and GeoShape). To enable this API: - -1. [Get a Google Maps API key](https://developers.google.com/maps/documentation/android-api/signup). - Note that this requires a credit card number, though the card will not be charged immediately; - some free API usage is permitted. You should carefully read the terms before providing a credit - card number. -1. Edit or create `secrets.properties` and set the `GOOGLE_MAPS_API_KEY` property to your API key. - You should end up with a line that looks like this: - ``` - GOOGLE_MAPS_API_KEY=AIbzvW8e0ub... - ``` - -**Mapbox Maps SDK for Android**: When the "Mapbox SDK" option is selected in the "User interface" -settings, ODK Collect uses the Mapbox SDK for displaying maps in the geospatial question types ( -GeoPoint, GeoTrace, and GeoShape). To enable this API: - -1. [Create a Mapbox account](https://www.mapbox.com/signup/). Note that signing up with the " - Pay-As-You-Go" plan does not require a credit card. Mapbox provides free API usage up to the - monthly thresholds documented - at [https://www.mapbox.com/pricing](https://www.mapbox.com/pricing). If your usage exceeds these - thresholds, you will receive e-mail with instructions on how to add a credit card for payment; - services will remain live until the end of the 30-day billing term, after which the account will - be deactivated and will require a credit card to reactivate. -2. Find your access token on your [account page](https://account.mapbox.com/) - it should be in " - Tokens" as "Default public token". -3. Edit or create `secrets.properties` and set the `MAPBOX_ACCESS_TOKEN` property to your access - token. You should end up with a line that looks like this: - ``` - MAPBOX_ACCESS_TOKEN=pk.eyJk3bumVp4i... - ``` -4. Create a new secret token with the "DOWNLOADS:READ" secret scope and then add it - to `secrets.properties` as `MAPBOX_DOWNLOADS_TOKEN`. - -*Note: Mapbox will not be available as an option in compiled versions of Collect unless you follow -the steps above. Mapbox will also not be available on x86 devices as the native libraries are -excluded to reduce the APK size. If you need to use an x86 device, you can force the build to -include x86 libs by include the `x86Libs` Gradle parameter. For example, to build a debug APK with -x86 libs: `./gradlew assembleDebug -Px86Libs`.* +Certain functions in ODK Collect depend on cloud services that require API keys or authorization steps to work. Here are the steps you need to take in order to use these functions in your development builds. + +**Google Maps API**: When the "Google Maps SDK" option is selected in the "User interface" settings, ODK Collect uses the Google Maps API for displaying maps in the geospatial question types (GeoPoint, GeoTrace, and GeoShape). To enable this API: + 1. [Get a Google Maps API key](https://developers.google.com/maps/documentation/android-api/signup). Note that this requires a credit card number, though the card will not be charged immediately; some free API usage is permitted. You should carefully read the terms before providing a credit card number. + 1. Edit or create `secrets.properties` and set the `GOOGLE_MAPS_API_KEY` property to your API key. You should end up with a line that looks like this: + ``` + GOOGLE_MAPS_API_KEY=AIbzvW8e0ub... + ``` + +**Mapbox Maps SDK for Android**: When the "Mapbox SDK" option is selected in the "User interface" settings, ODK Collect uses the Mapbox SDK for displaying maps in the geospatial question types (GeoPoint, GeoTrace, and GeoShape). To enable this API: + 1. [Create a Mapbox account](https://www.mapbox.com/signup/). Note that signing up with the "Pay-As-You-Go" plan does not require a credit card. Mapbox provides free API usage up to the monthly thresholds documented at [https://www.mapbox.com/pricing](https://www.mapbox.com/pricing). If your usage exceeds these thresholds, you will receive e-mail with instructions on how to add a credit card for payment; services will remain live until the end of the 30-day billing term, after which the account will be deactivated and will require a credit card to reactivate. + 2. Find your access token on your [account page](https://account.mapbox.com/) - it should be in "Tokens" as "Default public token". + 3. Edit or create `secrets.properties` and set the `MAPBOX_ACCESS_TOKEN` property to your access token. You should end up with a line that looks like this: + ``` + MAPBOX_ACCESS_TOKEN=pk.eyJk3bumVp4i... + ``` + 4. Create a new secret token with the "DOWNLOADS:READ" secret scope and then add it to `secrets.properties` as `MAPBOX_DOWNLOADS_TOKEN`. + +*Note: Mapbox will not be available as an option in compiled versions of Collect unless you follow the steps above. Mapbox will also not be available on x86 devices as the native libraries are excluded to reduce the APK size. If you need to use an x86 device, you can force the build to include x86 libs by include the `x86Libs` Gradle parameter. For example, to build a debug APK with x86 libs: `./gradlew assembleDebug -Px86Libs`.* ## Debugging JavaRosa -JavaRosa is the form engine that powers Collect. If you want to debug or change that code while -running Collect you can deploy it locally with Maven (you'll need `mvn` and `sed` installed): +JavaRosa is the form engine that powers Collect. If you want to debug or change that code while running Collect you can deploy it locally with Maven (you'll need `mvn` and `sed` installed): 1. Build and install your changes of JavaRosa (into your local Maven repo): @@ -270,41 +162,24 @@ running Collect you can deploy it locally with Maven (you'll need `mvn` and `sed ./gradlew publishToMavenLocal ``` -1. Change `const val javarosa = javarosa_online` in `Dependencies.kt` - to `const val javarosa = javarosa_local` +1. Change `const val javarosa = javarosa_online` in `Dependencies.kt` to `const val javarosa = javarosa_local` ## Troubleshooting #### Error when running Robolectric tests from Android Studio on macOS: `build/intermediates/bundles/debug/AndroidManifest.xml (No such file or directory)` +> Configure the default JUnit test runner configuration in order to work around a bug where IntelliJ / Android Studio does not set the working directory to the module being tested. This can be accomplished by editing the run configurations, Defaults -> JUnit and changing the working directory value to $MODULE_DIR$. -> Configure the default JUnit test runner configuration in order to work around a bug where -> IntelliJ / Android Studio does not set the working directory to the module being tested. This can be -> accomplished by editing the run configurations, Defaults -> JUnit and changing the working directory -> value to $MODULE_DIR$. - -> -Source: [Robolectric Wiki](https://github.com/robolectric/robolectric/wiki/Running-tests-in-Android-Studio#notes-for-mac). +> Source: [Robolectric Wiki](https://github.com/robolectric/robolectric/wiki/Running-tests-in-Android-Studio#notes-for-mac). #### Android Studio Error: `SDK location not found. Define location with sdk.dir in the local.properties file or with an ANDROID_HOME environment variable.` - -When cloning the project from Android Studio, click "No" when prompted to open the `build.gradle` -file and then open project. +When cloning the project from Android Studio, click "No" when prompted to open the `build.gradle` file and then open project. #### Execution failed for task ':collect_app:transformClassesWithInstantRunForDebug'. -We have seen this problem happen in both IntelliJ IDEA and Android Studio, and believe it to be due -to a bug in the IDE, which we can't fix. As a workaround, turning -off [Instant Run](https://developer.android.com/studio/run/#set-up-ir) will usually avoid this -problem. The problem is fixed in Android Studio 3.5 with the -new [Apply Changes](https://medium.com/androiddevelopers/android-studio-project-marble-apply-changes-e3048662e8cd) -feature. +We have seen this problem happen in both IntelliJ IDEA and Android Studio, and believe it to be due to a bug in the IDE, which we can't fix. As a workaround, turning off [Instant Run](https://developer.android.com/studio/run/#set-up-ir) will usually avoid this problem. The problem is fixed in Android Studio 3.5 with the new [Apply Changes](https://medium.com/androiddevelopers/android-studio-project-marble-apply-changes-e3048662e8cd) feature. #### Moving to the main view if user minimizes the app - -If you build the app on your own using Android Studio `(Build -> Build APK)` and then install it ( -from an `.apk` file), you might notice this strange behaviour thoroughly -described: [#1280](https://github.com/getodk/collect/issues/1280) -and [#1142](https://github.com/getodk/collect/issues/1142). +If you build the app on your own using Android Studio `(Build -> Build APK)` and then install it (from an `.apk` file), you might notice this strange behaviour thoroughly described: [#1280](https://github.com/getodk/collect/issues/1280) and [#1142](https://github.com/getodk/collect/issues/1142). This problem occurs building other apps as well. @@ -321,29 +196,21 @@ A problem occurred configuring project ':collect_app'. > Could not initialize class com.android.sdklib.repository.AndroidSdkHandler ``` -You may have a mismatch between the embedded Android SDK Java and the JDK installed on your machine. -You may wish to set your **JAVA_HOME** environment variable to that SDK. For example, on macOS: +You may have a mismatch between the embedded Android SDK Java and the JDK installed on your machine. You may wish to set your **JAVA_HOME** environment variable to that SDK. For example, on macOS: `export JAVA_HOME="/Applications/Android\ Studio.app/Contents/jre/Contents/Home/" ` -Note that this change might cause problems with other Java-based applications (e.g., if you -uninstall Android Studio). +Note that this change might cause problems with other Java-based applications (e.g., if you uninstall Android Studio). #### gradlew Failure: `java.lang.NullPointerException (no error message).` +If you encounter the `java.lang.NullPointerException (no error message).` when running `gradlew`, please make sure your Java version for this project is Java 17. -If you encounter the `java.lang.NullPointerException (no error message).` when running `gradlew`, -please make sure your Java version for this project is Java 17. - -This can be configured under **File > Project Structure** in Android Studio, or by -editing `$USER_HOME/.gradle/gradle.properties` to set `org.gradle.java.home=(path to JDK home)` for -command-line use. +This can be configured under **File > Project Structure** in Android Studio, or by editing `$USER_HOME/.gradle/gradle.properties` to set `org.gradle.java.home=(path to JDK home)` for command-line use. #### `Unable to resolve artifact: Missing` while running tests -This is encountered when Robolectric has problems downloading the jars it needs for different -Android SDK levels. If you keep running into this you can download the JARs locally and point -Robolectric to them by doing: +This is encountered when Robolectric has problems downloading the jars it needs for different Android SDK levels. If you keep running into this you can download the JARs locally and point Robolectric to them by doing: ``` ./download-robolectric-deps.sh @@ -364,9 +231,7 @@ Devices that @getodk/testers have available for testing are as follows: * Huawei Y560-L01 1GB - Android 5.1 ## Creating signed releases for Google Play Store - -Maintainers keep a folder with a clean checkout of the code and use [jenv.be](https://www.jenv.be) -in that folder to ensure compilation with Java 17. +Maintainers keep a folder with a clean checkout of the code and use [jenv.be](https://www.jenv.be) in that folder to ensure compilation with Java 17. ### Release prerequisites: @@ -386,37 +251,25 @@ in that folder to ensure compilation with Java 17. RELEASE_KEY_PASSWORD=secure-alias-password ``` -- a `google-services.json` file in the `collect_app/src/odkCollectRelease` folder. The contents of - the file are similar to the contents of `collect_app/src/google-services.json`. +- a `google-services.json` file in the `collect_app/src/odkCollectRelease` folder. The contents of the file are similar to the contents of `collect_app/src/google-services.json`. ### Release checklist: - update translations - make sure CI is green for the chosen commit -- run `./gradlew releaseCheck`. If successful, a signed release will be - at `collect_app/build/outputs/apk` (with an old version name) -- verify a basic "happy path": scan a QR code to configure a new project, get a blank form, fill it, - open the form map (confirms that the Google Maps key is correct), send form +- run `./gradlew releaseCheck`. If successful, a signed release will be at `collect_app/build/outputs/apk` (with an old version name) +- verify a basic "happy path": scan a QR code to configure a new project, get a blank form, fill it, open the form map (confirms that the Google Maps key is correct), send form - run `./benchmark.sh` with a real device connected to verify performance -- verify new APK can be installed as update to previous version and that above "happy path" works in - that case also +- verify new APK can be installed as update to previous version and that above "happy path" works in that case also - create and publish scheduled forum post with release description - write Play Store release notes, include link to forum post -- create a release with the correct version by tagging the commit and - running `./collect_app:assembleOdkCollectRelease` - - Tags for full releases must have the format `vX.X.X`. Tags for beta releases must have the - format `vX.X.X-beta.X`. -- add a release to Github [here](https://github.com/getodk/collect/releases), generate release notes - and attach the APK +- create a release with the correct version by tagging the commit and running `./collect_app:assembleOdkCollectRelease` + - Tags for full releases must have the format `vX.X.X`. Tags for beta releases must have the format `vX.X.X-beta.X`. +- add a release to Github [here](https://github.com/getodk/collect/releases), generate release notes and attach the APK - upload APK to Play Store -- if there was an active beta before release (this can happen with point releases), publish a new - beta release to replace the previous one which was disabled by the production release -- backup dependencies for the release by downloading the `vX.X.X.tar` artifact from - the `create_dependency_backup` job on Circle CI (for the release commit) and then uploading it - to [this folder](https://drive.google.com/drive/folders/1_tMKBFLdhzFZF9GKNeob4FbARjdfbtJu?usp=share_link) -- backup a self signed release APK by downloading the `selfSignedRelease.apk` from - the `build_release` job on Circle CI (for the release commit) and then upload - to [this folder](https://drive.google.com/drive/folders/1pbbeNaMTziFhtZmedOs0If3BeYu3Ex5x?usp=share_link) +- if there was an active beta before release (this can happen with point releases), publish a new beta release to replace the previous one which was disabled by the production release +- backup dependencies for the release by downloading the `vX.X.X.tar` artifact from the `create_dependency_backup` job on Circle CI (for the release commit) and then uploading it to [this folder](https://drive.google.com/drive/folders/1_tMKBFLdhzFZF9GKNeob4FbARjdfbtJu?usp=share_link) +- backup a self signed release APK by downloading the `selfSignedRelease.apk` from the `build_release` job on Circle CI (for the release commit) and then upload to [this folder](https://drive.google.com/drive/folders/1pbbeNaMTziFhtZmedOs0If3BeYu3Ex5x?usp=share_link) ## Compiling a previous release using backed-up dependencies @@ -425,7 +278,6 @@ in that folder to ensure compilation with Java 17. ```bash tar -xf maven.tar -C ``` - -The project will now be able to fetch dependencies that are no longer available (but were used to -compile the release) from the `.local-m2` Maven repo. + +The project will now be able to fetch dependencies that are no longer available (but were used to compile the release) from the `.local-m2` Maven repo.