From 75eb6c5a9dcb423872485bb134c8e53b380295bb Mon Sep 17 00:00:00 2001 From: Ka-Ping Yee Date: Sun, 17 Mar 2024 14:36:25 +0545 Subject: [PATCH] Make the FormFillingActivity launchable from a link of the form "odkcollect://form/", allowing an entity to be preselected with a query parameter. --- collect_app/src/main/AndroidManifest.xml | 10 ++++- .../collect/android/tasks/FormLoaderTask.java | 39 +++++++++++++++++++ 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/collect_app/src/main/AndroidManifest.xml b/collect_app/src/main/AndroidManifest.xml index d7fd1e1e23d..b3d7f71cfb1 100644 --- a/collect_app/src/main/AndroidManifest.xml +++ b/collect_app/src/main/AndroidManifest.xml @@ -121,7 +121,15 @@ the specific language governing permissions and limitations under the License. + android:windowSoftInputMode="adjustResize" + android:exported="true"> + + + + + + + diff --git a/collect_app/src/main/java/org/odk/collect/android/tasks/FormLoaderTask.java b/collect_app/src/main/java/org/odk/collect/android/tasks/FormLoaderTask.java index e1248a546a8..65235bf289c 100644 --- a/collect_app/src/main/java/org/odk/collect/android/tasks/FormLoaderTask.java +++ b/collect_app/src/main/java/org/odk/collect/android/tasks/FormLoaderTask.java @@ -29,6 +29,8 @@ import org.javarosa.core.model.FormDef; import org.javarosa.core.model.FormIndex; +import org.javarosa.core.model.data.SelectOneData; +import org.javarosa.core.model.data.helper.Selection; import org.javarosa.core.model.instance.InstanceInitializationFactory; import org.javarosa.core.model.instance.TreeElement; import org.javarosa.core.model.instance.TreeReference; @@ -42,6 +44,7 @@ import org.odk.collect.android.dynamicpreload.ExternalAnswerResolver; import org.odk.collect.android.dynamicpreload.ExternalDataManager; import org.odk.collect.android.dynamicpreload.ExternalDataUseCases; +import org.odk.collect.android.exception.JavaRosaException; import org.odk.collect.android.external.FormsContract; import org.odk.collect.android.external.InstancesContract; import org.odk.collect.android.fastexternalitemset.ItemsetDbAdapter; @@ -178,6 +181,15 @@ protected FECWrapper doInBackground(Void... ignored) { * explicitly saved instance is edited via edit-saved-form. */ instancePath = loadSavePoint(); + } else if (uri.getScheme().equals("odkcollect") && uri.getHost().equals("form")) { + // Launch a form from a browsable web link in the format: odkcollect://form/ + String formId = uri.getPathSegments().get(0); + List
forms = new FormsRepositoryProvider(Collect.getInstance()).get().getAllByFormId(formId); + if (forms.size() == 0) { + Timber.e(new Error("Form not found for URL: " + uri)); + return null; + } + form = forms.get(0); } if (form.getFormFilePath() == null) { @@ -270,10 +282,37 @@ protected FECWrapper doInBackground(Void... ignored) { fc.setIndexWaitingForData(idx); } } + + preselectEntity(fc, uri); + data = new FECWrapper(fc, usedSavepoint); return data; } + private void preselectEntity(FormController fc, Uri uri) { + FormIndex saved = fc.getFormIndex(); + try { + for (int event = fc.jumpToIndex(FormIndex.createBeginningOfFormIndex()); + event != FormEntryController.EVENT_END_OF_FORM; + event = fc.stepToNextEvent(false)) { + FormIndex index = fc.getFormIndex(); + TreeReference ref = fc.getFormDef().getChildInstanceRef(index); + if (ref != null) { + String value = uri.getQueryParameter(ref.getNameLast()); + if (value != null) { + try { + fc.answerQuestion(index, new SelectOneData(new Selection(value))); + } catch (JavaRosaException e) { + Timber.w("Could not preselect answer " + value + " for question " + ref); + } + } + } + } + } finally { + fc.jumpToIndex(saved); + } + } + private static void unzipMediaFiles(File formMediaDir) { File[] zipFiles = formMediaDir.listFiles(new FileFilter() { @Override