Search in sources :

Example 6 with JavaRosaException

use of org.odk.collect.android.exception.JavaRosaException in project collect by opendatakit.

the class FormEntryActivity method createRepeatDialog.

/**
 * Creates and displays a dialog asking the user if they'd like to create a
 * repeat of the current group.
 */
private void createRepeatDialog() {
    Collect.getInstance().getActivityLogger().logInstanceAction(this, "createRepeatDialog", "show");
    // alertDialog is being used for all alert dialogs in this activity.
    if (alertDialog != null && alertDialog.isShowing() && shownAlertDialogIsGroupRepeat) {
        return;
    }
    alertDialog = new AlertDialog.Builder(this).create();
    DialogInterface.OnClickListener repeatListener = new DialogInterface.OnClickListener() {

        @Override
        public void onClick(DialogInterface dialog, int i) {
            shownAlertDialogIsGroupRepeat = false;
            FormController formController = getFormController();
            switch(i) {
                case // yes, repeat
                BUTTON_POSITIVE:
                    Collect.getInstance().getActivityLogger().logInstanceAction(this, "createRepeatDialog", "addRepeat");
                    try {
                        formController.newRepeat();
                    } catch (Exception e) {
                        FormEntryActivity.this.createErrorDialog(e.getMessage(), DO_NOT_EXIT);
                        return;
                    }
                    if (!formController.indexIsInFieldList()) {
                        // we are at a REPEAT event that does not have a
                        // field-list appearance
                        // step to the next visible field...
                        // which could be the start of a new repeat group...
                        showNextView();
                    } else {
                        // we are at a REPEAT event that has a field-list
                        // appearance
                        // just display this REPEAT event's group.
                        refreshCurrentView();
                    }
                    break;
                case // no, no repeat
                BUTTON_NEGATIVE:
                    Collect.getInstance().getActivityLogger().logInstanceAction(this, "createRepeatDialog", "showNext");
                    // 
                    // Make sure the error dialog will not disappear.
                    // 
                    // When showNextView() popups an error dialog (because of a
                    // JavaRosaException)
                    // the issue is that the "add new repeat dialog" is referenced by
                    // alertDialog
                    // like the error dialog. When the "no repeat" is clicked, the error dialog
                    // is shown. Android by default dismisses the dialogs when a button is
                    // clicked,
                    // so instead of closing the first dialog, it closes the second.
                    new Thread() {

                        @Override
                        public void run() {
                            FormEntryActivity.this.runOnUiThread(() -> {
                                try {
                                    Thread.sleep(500);
                                } catch (InterruptedException e) {
                                    // This is rare
                                    Timber.e(e);
                                }
                                showNextView();
                            });
                        }
                    }.start();
                    break;
            }
        }
    };
    FormController formController = getFormController();
    if (formController.getLastRepeatCount() > 0) {
        alertDialog.setTitle(getString(R.string.leaving_repeat_ask));
        alertDialog.setMessage(getString(R.string.add_another_repeat, formController.getLastGroupText()));
        alertDialog.setButton(BUTTON_POSITIVE, getString(R.string.add_another), repeatListener);
        alertDialog.setButton(BUTTON_NEGATIVE, getString(R.string.leave_repeat_yes), repeatListener);
    } else {
        alertDialog.setTitle(getString(R.string.entering_repeat_ask));
        alertDialog.setMessage(getString(R.string.add_repeat, formController.getLastGroupText()));
        alertDialog.setButton(BUTTON_POSITIVE, getString(R.string.entering_repeat), repeatListener);
        alertDialog.setButton(BUTTON_NEGATIVE, getString(R.string.add_repeat_no), repeatListener);
    }
    alertDialog.setCancelable(false);
    beenSwiped = false;
    shownAlertDialogIsGroupRepeat = true;
    alertDialog.show();
}
Also used : FormController(org.odk.collect.android.logic.FormController) DialogInterface(android.content.DialogInterface) OnClickListener(android.view.View.OnClickListener) GDriveConnectionException(org.odk.collect.android.exception.GDriveConnectionException) JavaRosaException(org.odk.collect.android.exception.JavaRosaException)

Example 7 with JavaRosaException

use of org.odk.collect.android.exception.JavaRosaException in project collect by opendatakit.

the class FormEntryActivity method showPreviousView.

/**
 * Determines what should be displayed between a question, or the start
 * screen and displays the appropriate view. Also saves answers to the data
 * model without checking constraints.
 */
private void showPreviousView() {
    if (allowMovingBackwards) {
        state = null;
        try {
            FormController formController = getFormController();
            if (formController != null) {
                // ignored.
                if (formController.currentPromptIsQuestion()) {
                    saveAnswersForCurrentScreen(DO_NOT_EVALUATE_CONSTRAINTS);
                }
                if (formController.getEvent() != FormEntryController.EVENT_BEGINNING_OF_FORM) {
                    int event = formController.stepToPreviousScreenEvent();
                    // this swipe
                    if (event == FormEntryController.EVENT_BEGINNING_OF_FORM) {
                        event = formController.stepToNextScreenEvent();
                        beenSwiped = false;
                        if (event != FormEntryController.EVENT_PROMPT_NEW_REPEAT) {
                            // Returning here prevents the same view sliding when user is on the first screen
                            return;
                        }
                    }
                    if (event == FormEntryController.EVENT_GROUP || event == FormEntryController.EVENT_QUESTION) {
                        // create savepoint
                        if ((++viewCount) % SAVEPOINT_INTERVAL == 0) {
                            nonblockingCreateSavePointData();
                        }
                    }
                    // Close timer events
                    formController.getTimerLogger().exitView();
                    View next = createView(event, false);
                    showView(next, AnimationType.LEFT);
                } else {
                    beenSwiped = false;
                }
            } else {
                Timber.w("FormController has a null value");
            }
        } catch (JavaRosaException e) {
            Timber.d(e);
            createErrorDialog(e.getCause().getMessage(), DO_NOT_EXIT);
        }
    } else {
        beenSwiped = false;
    }
}
Also used : FormController(org.odk.collect.android.logic.FormController) ODKView(org.odk.collect.android.views.ODKView) View(android.view.View) AdapterView(android.widget.AdapterView) TextView(android.widget.TextView) ListView(android.widget.ListView) FailedConstraint(org.odk.collect.android.logic.FormController.FailedConstraint) JavaRosaException(org.odk.collect.android.exception.JavaRosaException)

Example 8 with JavaRosaException

use of org.odk.collect.android.exception.JavaRosaException in project collect by opendatakit.

the class FormEntryActivity method onActivityResult.

@Override
protected void onActivityResult(int requestCode, int resultCode, final Intent intent) {
    super.onActivityResult(requestCode, resultCode, intent);
    FormController formController = getFormController();
    if (formController == null) {
        // try to save this callback data to the FormLoaderTask
        if (formLoaderTask != null && formLoaderTask.getStatus() != AsyncTask.Status.FINISHED) {
            formLoaderTask.setActivityResult(requestCode, resultCode, intent);
        } else {
            Timber.e("Got an activityResult without any pending form loader");
        }
        return;
    }
    if (resultCode == RESULT_CANCELED) {
        // request was canceled...
        if (requestCode != RequestCodes.HIERARCHY_ACTIVITY && getCurrentViewIfODKView() != null) {
            getCurrentViewIfODKView().cancelWaitingForBinaryData();
        }
        return;
    }
    // intent is needed for all requestCodes except of DRAW_IMAGE, ANNOTATE_IMAGE, SIGNATURE_CAPTURE, IMAGE_CAPTURE and HIERARCHY_ACTIVITY
    if (intent == null && requestCode != RequestCodes.DRAW_IMAGE && requestCode != RequestCodes.ANNOTATE_IMAGE && requestCode != RequestCodes.SIGNATURE_CAPTURE && requestCode != RequestCodes.IMAGE_CAPTURE && requestCode != RequestCodes.HIERARCHY_ACTIVITY) {
        Timber.w("The intent has a null value for requestCode: " + requestCode);
        ToastUtils.showLongToast(getString(R.string.null_intent_value));
        return;
    }
    // For handling results returned by the Zxing Barcode scanning library
    IntentResult barcodeScannerResult = IntentIntegrator.parseActivityResult(requestCode, resultCode, intent);
    if (barcodeScannerResult != null) {
        if (barcodeScannerResult.getContents() == null) {
            // request was canceled...
            Timber.i("QR code scanning cancelled");
        } else {
            String sb = intent.getStringExtra("SCAN_RESULT");
            if (getCurrentViewIfODKView() != null) {
                getCurrentViewIfODKView().setBinaryData(sb);
            }
            saveAnswersForCurrentScreen(DO_NOT_EVALUATE_CONSTRAINTS);
            refreshCurrentView();
            return;
        }
    }
    switch(requestCode) {
        case RequestCodes.OSM_CAPTURE:
            String osmFileName = intent.getStringExtra("OSM_FILE_NAME");
            if (getCurrentViewIfODKView() != null) {
                getCurrentViewIfODKView().setBinaryData(osmFileName);
            }
            saveAnswersForCurrentScreen(DO_NOT_EVALUATE_CONSTRAINTS);
            break;
        case RequestCodes.EX_STRING_CAPTURE:
        case RequestCodes.EX_INT_CAPTURE:
        case RequestCodes.EX_DECIMAL_CAPTURE:
            String key = "value";
            boolean exists = intent.getExtras().containsKey(key);
            if (exists) {
                Object externalValue = intent.getExtras().get(key);
                if (getCurrentViewIfODKView() != null) {
                    getCurrentViewIfODKView().setBinaryData(externalValue);
                }
                saveAnswersForCurrentScreen(DO_NOT_EVALUATE_CONSTRAINTS);
            }
            break;
        case RequestCodes.EX_GROUP_CAPTURE:
            try {
                Bundle extras = intent.getExtras();
                if (getCurrentViewIfODKView() != null) {
                    getCurrentViewIfODKView().setDataForFields(extras);
                }
            } catch (JavaRosaException e) {
                Timber.e(e);
                createErrorDialog(e.getCause().getMessage(), DO_NOT_EXIT);
            }
            break;
        case RequestCodes.DRAW_IMAGE:
        case RequestCodes.ANNOTATE_IMAGE:
        case RequestCodes.SIGNATURE_CAPTURE:
        case RequestCodes.IMAGE_CAPTURE:
            /*
                 * We saved the image to the tempfile_path, but we really want it to
                 * be in: /sdcard/odk/instances/[current instnace]/something.jpg so
                 * we move it there before inserting it into the content provider.
                 * Once the android image capture bug gets fixed, (read, we move on
                 * from Android 1.6) we want to handle images the audio and video
                 */
            // The intent is empty, but we know we saved the image to the temp
            // file
            ImageConverter.execute(Collect.TMPFILE_PATH, getWidgetWaitingForBinaryData(), this);
            File fi = new File(Collect.TMPFILE_PATH);
            String instanceFolder = formController.getInstanceFile().getParent();
            String s = instanceFolder + File.separator + System.currentTimeMillis() + ".jpg";
            File nf = new File(s);
            if (!fi.renameTo(nf)) {
                Timber.e("Failed to rename %s", fi.getAbsolutePath());
            } else {
                Timber.i("Renamed %s to %s", fi.getAbsolutePath(), nf.getAbsolutePath());
            }
            if (getCurrentViewIfODKView() != null) {
                getCurrentViewIfODKView().setBinaryData(nf);
            }
            saveAnswersForCurrentScreen(DO_NOT_EVALUATE_CONSTRAINTS);
            break;
        case RequestCodes.ALIGNED_IMAGE:
            /*
                 * We saved the image to the tempfile_path; the app returns the full
                 * path to the saved file in the EXTRA_OUTPUT extra. Take that file
                 * and move it into the instance folder.
                 */
            String path = intent.getStringExtra(android.provider.MediaStore.EXTRA_OUTPUT);
            fi = new File(path);
            instanceFolder = formController.getInstanceFile().getParent();
            s = instanceFolder + File.separator + System.currentTimeMillis() + ".jpg";
            nf = new File(s);
            if (!fi.renameTo(nf)) {
                Timber.e("Failed to rename %s", fi.getAbsolutePath());
            } else {
                Timber.i("Renamed %s to %s", fi.getAbsolutePath(), nf.getAbsolutePath());
            }
            if (getCurrentViewIfODKView() != null) {
                getCurrentViewIfODKView().setBinaryData(nf);
            }
            saveAnswersForCurrentScreen(DO_NOT_EVALUATE_CONSTRAINTS);
            break;
        case RequestCodes.IMAGE_CHOOSER:
            /*
                 * We have a saved image somewhere, but we really want it to be in:
                 * /sdcard/odk/instances/[current instnace]/something.jpg so we move
                 * it there before inserting it into the content provider. Once the
                 * android image capture bug gets fixed, (read, we move on from
                 * Android 1.6) we want to handle images the audio and video
                 */
            showDialog(SAVING_IMAGE_DIALOG);
            Runnable runnable = () -> saveChosenImage(intent.getData());
            new Thread(runnable).start();
            break;
        case RequestCodes.AUDIO_CAPTURE:
        case RequestCodes.VIDEO_CAPTURE:
            Uri mediaUri = intent.getData();
            saveAudioVideoAnswer(mediaUri);
            String filePath = MediaUtils.getDataColumn(this, mediaUri, null, null);
            if (filePath != null) {
                new File(filePath).delete();
            }
            try {
                getContentResolver().delete(mediaUri, null, null);
            } catch (Exception e) {
                Timber.e(e);
            }
            break;
        case RequestCodes.AUDIO_CHOOSER:
        case RequestCodes.VIDEO_CHOOSER:
            saveAudioVideoAnswer(intent.getData());
            break;
        case RequestCodes.LOCATION_CAPTURE:
            String sl = intent.getStringExtra(LOCATION_RESULT);
            if (getCurrentViewIfODKView() != null) {
                getCurrentViewIfODKView().setBinaryData(sl);
            }
            saveAnswersForCurrentScreen(DO_NOT_EVALUATE_CONSTRAINTS);
            break;
        case RequestCodes.GEOSHAPE_CAPTURE:
            String gshr = intent.getStringExtra(GEOSHAPE_RESULTS);
            if (getCurrentViewIfODKView() != null) {
                getCurrentViewIfODKView().setBinaryData(gshr);
            }
            saveAnswersForCurrentScreen(DO_NOT_EVALUATE_CONSTRAINTS);
            break;
        case RequestCodes.GEOTRACE_CAPTURE:
            String traceExtra = intent.getStringExtra(GEOTRACE_RESULTS);
            if (getCurrentViewIfODKView() != null) {
                getCurrentViewIfODKView().setBinaryData(traceExtra);
            }
            saveAnswersForCurrentScreen(DO_NOT_EVALUATE_CONSTRAINTS);
            break;
        case RequestCodes.BEARING_CAPTURE:
            String bearing = intent.getStringExtra(BEARING_RESULT);
            if (getCurrentViewIfODKView() != null) {
                getCurrentViewIfODKView().setBinaryData(bearing);
            }
            saveAnswersForCurrentScreen(DO_NOT_EVALUATE_CONSTRAINTS);
            break;
        case RequestCodes.HIERARCHY_ACTIVITY:
            // refresh
            break;
    }
    refreshCurrentView();
}
Also used : FormController(org.odk.collect.android.logic.FormController) IntentResult(com.google.zxing.integration.android.IntentResult) Bundle(android.os.Bundle) File(java.io.File) Uri(android.net.Uri) JavaRosaException(org.odk.collect.android.exception.JavaRosaException) GDriveConnectionException(org.odk.collect.android.exception.GDriveConnectionException) JavaRosaException(org.odk.collect.android.exception.JavaRosaException)

Example 9 with JavaRosaException

use of org.odk.collect.android.exception.JavaRosaException in project collect by opendatakit.

the class FormController method stepToPreviousScreenEvent.

/**
 * Move the current form index to the index of the previous question in the form.
 * Step backward out of repeats and groups as needed. If the resulting question
 * is itself within a field-list, move upward to the group or repeat defining that
 * field-list.
 */
public int stepToPreviousScreenEvent() throws JavaRosaException {
    try {
        if (getEvent() != FormEntryController.EVENT_BEGINNING_OF_FORM) {
            int event = stepToPreviousEvent();
            while (event == FormEntryController.EVENT_REPEAT_JUNCTURE || event == FormEntryController.EVENT_PROMPT_NEW_REPEAT || (event == FormEntryController.EVENT_QUESTION && indexIsInFieldList()) || ((event == FormEntryController.EVENT_GROUP || event == FormEntryController.EVENT_REPEAT) && !indexIsInFieldList())) {
                event = stepToPreviousEvent();
            }
            // Handle nested field-list group
            if (getEvent() == FormEntryController.EVENT_GROUP) {
                FormIndex currentIndex = getFormIndex();
                IFormElement element = formEntryController.getModel().getForm().getChild(currentIndex);
                if (element instanceof GroupDef) {
                    GroupDef gd = (GroupDef) element;
                    if (ODKView.FIELD_LIST.equalsIgnoreCase(gd.getAppearanceAttr())) {
                        // jump to outermost containing field-list
                        FormEntryCaption[] fclist = this.getCaptionHierarchy(currentIndex);
                        for (FormEntryCaption caption : fclist) {
                            if (groupIsFieldList(caption.getIndex())) {
                                formEntryController.jumpToIndex(caption.getIndex());
                                break;
                            }
                        }
                    }
                }
            }
        }
        return getEvent();
    } catch (RuntimeException e) {
        throw new JavaRosaException(e);
    }
}
Also used : IFormElement(org.javarosa.core.model.IFormElement) FormEntryCaption(org.javarosa.form.api.FormEntryCaption) FormIndex(org.javarosa.core.model.FormIndex) GroupDef(org.javarosa.core.model.GroupDef) JavaRosaException(org.odk.collect.android.exception.JavaRosaException)

Example 10 with JavaRosaException

use of org.odk.collect.android.exception.JavaRosaException in project collect by opendatakit.

the class QuestionWidget method clearNextLevelsOfCascadingSelect.

/**
 * It's needed only for external choices. Everything works well and
 * out of the box when we use internal choices instead
 */
protected void clearNextLevelsOfCascadingSelect() {
    FormController formController = Collect.getInstance().getFormController();
    if (formController == null) {
        return;
    }
    if (formController.currentCaptionPromptIsQuestion()) {
        try {
            FormIndex startFormIndex = formController.getQuestionPrompt().getIndex();
            formController.stepToNextScreenEvent();
            while (formController.currentCaptionPromptIsQuestion() && formController.getQuestionPrompt().getFormElement().getAdditionalAttribute(null, "query") != null) {
                formController.saveAnswer(formController.getQuestionPrompt().getIndex(), null);
                formController.stepToNextScreenEvent();
            }
            formController.jumpToIndex(startFormIndex);
        } catch (JavaRosaException e) {
            Timber.d(e);
        }
    }
}
Also used : FormController(org.odk.collect.android.logic.FormController) FormIndex(org.javarosa.core.model.FormIndex) JavaRosaException(org.odk.collect.android.exception.JavaRosaException)

Aggregations

JavaRosaException (org.odk.collect.android.exception.JavaRosaException)10 FormController (org.odk.collect.android.logic.FormController)6 FormIndex (org.javarosa.core.model.FormIndex)5 View (android.view.View)3 AdapterView (android.widget.AdapterView)3 ListView (android.widget.ListView)3 TextView (android.widget.TextView)3 FailedConstraint (org.odk.collect.android.logic.FormController.FailedConstraint)3 ODKView (org.odk.collect.android.views.ODKView)3 Uri (android.net.Uri)2 OnClickListener (android.view.View.OnClickListener)2 FormEntryCaption (org.javarosa.form.api.FormEntryCaption)2 HierarchyListAdapter (org.odk.collect.android.adapters.HierarchyListAdapter)2 GDriveConnectionException (org.odk.collect.android.exception.GDriveConnectionException)2 HierarchyElement (org.odk.collect.android.logic.HierarchyElement)2 DialogInterface (android.content.DialogInterface)1 Cursor (android.database.Cursor)1 Bundle (android.os.Bundle)1 Editable (android.text.Editable)1 InputFilter (android.text.InputFilter)1