Commit 349ed645 authored by rahadi's avatar rahadi

Added external intent handlers

parent d542b9ff
......@@ -17,7 +17,8 @@ import java.util.List;
import id.ac.stis.capi.R;
import id.ac.stis.capi.collectiva.preferences.Constants;
import id.ac.stis.capi.lessthink.fragments.FormEntryDialogFragment;
import id.ac.stis.capi.lessthink.listeners.OnAddButtonClickListener;
import id.ac.stis.capi.lessthink.fragments.FormEntryRVDialogFragment;
import id.ac.stis.capi.lessthink.listeners.OnTableAddButtonClickListener;
import id.ac.stis.capi.lessthink.models.FormLabels;
import id.ac.stis.capi.lessthink.models.InstanceValues;
import id.ac.stis.capi.lessthink.utils.XmlUtils;
......@@ -31,6 +32,7 @@ import id.ac.stis.capi.odk.dto.Instance;
import id.ac.stis.capi.odk.provider.FormsProviderAPI;
import id.ac.stis.capi.odk.provider.InstanceProviderAPI;
import id.ac.stis.capi.odk.utilities.ApplicationConstants;
import timber.log.Timber;
public class ListingInstanceActivity extends AppCompatActivity {
......@@ -41,7 +43,8 @@ public class ListingInstanceActivity extends AppCompatActivity {
private TableRowView tableRowView;
private TableFooterView tableFooterView;
private String formId, formName;
private FormEntryDialogFragment entryDialogFragment;
// private FormEntryDialogFragment entryDialogFragment;
private FormEntryRVDialogFragment entryDialogFragment;
@Override
protected void onCreate(Bundle savedInstanceState) {
......@@ -91,7 +94,9 @@ public class ListingInstanceActivity extends AppCompatActivity {
// Toast.makeText(ListingInstanceActivity.this, "Click : " + view.getTag(), Toast.LENGTH_LONG).show();
String instanceUuid = view.getTag().toString();
entryDialogFragment = FormEntryDialogFragment.newInstance(instanceUuid,
// entryDialogFragment = FormEntryDialogFragment.newInstance(instanceUuid,
// FormEntryDialogFragment.MODE_EDIT, false);
entryDialogFragment = FormEntryRVDialogFragment.newInstance(instanceUuid,
FormEntryDialogFragment.MODE_EDIT, false);
entryDialogFragment.show(getSupportFragmentManager(), instanceUuid);
//
......@@ -101,7 +106,7 @@ public class ListingInstanceActivity extends AppCompatActivity {
}
});
tableFooterView.setOnAddButtonClickListener(new OnAddButtonClickListener() {
tableFooterView.setOnTableAddButtonClickListener(new OnTableAddButtonClickListener() {
@Override
public void onAddButtonClick(View v) {
fillBlankForm();
......@@ -109,6 +114,14 @@ public class ListingInstanceActivity extends AppCompatActivity {
});
}
@Override
public void onActivityResult(int requestCode, int resultCode, final Intent intent) {
super.onActivityResult(requestCode, resultCode, intent);
Timber.d("Activity Result : %s %s", requestCode, resultCode);
entryDialogFragment.onActivityResult(requestCode, resultCode, intent);
}
//todo: update yow
private void fillBlankForm() {
Cursor formslist = new FormsDao().getFormsCursor();
......
package id.ac.stis.capi.lessthink.adapters;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import java.util.List;
import id.ac.stis.capi.lessthink.models.BaseHierarchy;
import timber.log.Timber;
/**
* Author : Rahadi Jalu
* Email : 14.8325@stis.ac.id
* Company: Politeknik Statistika STIS
*/
public class HierarchyRVAdapter extends RecyclerView.Adapter<HierarchyRVAdapter.ViewHolder> {
private List<BaseHierarchy> hierarchies;
public HierarchyRVAdapter(List<BaseHierarchy> hierarchies) {
this.hierarchies = hierarchies;
}
public void setHierarchies(List<BaseHierarchy> hierarchies) {
this.hierarchies = hierarchies;
}
public BaseHierarchy getItem(int position) {
return hierarchies.get(position);
}
@Override
public int getItemViewType(int position) {
return position;
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
Timber.d("Creating with type %s", viewType);
// BaseHierarchy hierarchy = hierarchies.get(viewType);
// if (hierarchy instanceof PromptHierarchy) {
// ((PromptHierarchy) hierarchy).setOnChangeListener(onChangeListener);
// return new PromptViewHolder(hierarchy.getView());
// } else if (hierarchy instanceof CaptionHierarchy) {
// return new CaptionViewHolder(hierarchy.getView());
// } else {
// // Should not be happening
// return new ViewHolder(hierarchy.getView());
// }
return new ViewHolder(new LinearLayout(parent.getContext()));
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
// if (holder instanceof PromptViewHolder) {
// PromptHierarchy hierarchy = (PromptHierarchy) hierarchies.get(position);
// }
holder.bind(hierarchies.get(position));
}
@Override
public int getItemCount() {
return hierarchies.size();
}
class ViewHolder extends RecyclerView.ViewHolder {
public ViewHolder(View itemView) {
super(itemView);
}
void bind(BaseHierarchy hierarchy) {
ViewGroup parent = (ViewGroup) itemView;
if (parent != null) {
parent.removeAllViews();
parent.addView(hierarchy.getView());
}
}
}
}
package id.ac.stis.capi.lessthink.fragments;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.provider.MediaStore;
import android.support.annotation.NonNull;
import android.support.v4.app.DialogFragment;
import android.support.v4.content.ContextCompat;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.Toast;
import com.google.zxing.integration.android.IntentIntegrator;
import com.google.zxing.integration.android.IntentResult;
import org.javarosa.core.model.Constants;
import org.javarosa.core.model.FormIndex;
import org.javarosa.core.model.data.IAnswerData;
import org.javarosa.core.model.instance.TreeReference;
import org.javarosa.form.api.FormEntryController;
import org.javarosa.form.api.FormEntryPrompt;
import java.io.File;
import java.io.InvalidObjectException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.LinkedHashMap;
import java.util.Locale;
import java.util.Set;
import id.ac.stis.capi.R;
import id.ac.stis.capi.lessthink.adapters.HierarchyRVAdapter;
import id.ac.stis.capi.lessthink.listeners.OnButtonHierarchyClickListener;
import id.ac.stis.capi.lessthink.listeners.OnChangeListener;
import id.ac.stis.capi.lessthink.listeners.OnEditRutaSavedListener;
import id.ac.stis.capi.lessthink.models.BaseHierarchy;
import id.ac.stis.capi.lessthink.models.ButtonHierarchy;
import id.ac.stis.capi.lessthink.models.PromptHierarchy;
import id.ac.stis.capi.lessthink.utils.ViewUtils;
import id.ac.stis.capi.odk.application.Collect;
import id.ac.stis.capi.odk.dao.FormsDao;
import id.ac.stis.capi.odk.dao.InstancesDao;
import id.ac.stis.capi.odk.dto.Form;
import id.ac.stis.capi.odk.dto.Instance;
import id.ac.stis.capi.odk.exception.GDriveConnectionException;
import id.ac.stis.capi.odk.exception.JavaRosaException;
import id.ac.stis.capi.odk.external.ExternalAppsUtils;
import id.ac.stis.capi.odk.listeners.FormLoaderListener;
import id.ac.stis.capi.odk.logic.FailedConstraint;
import id.ac.stis.capi.odk.logic.FormController;
import id.ac.stis.capi.odk.provider.FormsProviderAPI;
import id.ac.stis.capi.odk.provider.InstanceProviderAPI;
import id.ac.stis.capi.odk.tasks.FormLoaderTask;
import id.ac.stis.capi.odk.utilities.FileUtils;
import id.ac.stis.capi.odk.utilities.MediaUtils;
import id.ac.stis.capi.odk.utilities.TimerLogger;
import id.ac.stis.capi.odk.utilities.ToastUtils;
import id.ac.stis.capi.odk.widgets.IBinaryWidget;
import id.ac.stis.capi.odk.widgets.QuestionWidget;
import timber.log.Timber;
import static android.app.Activity.RESULT_CANCELED;
import static id.ac.stis.capi.odk.activities.FormEntryActivity.ALIGNED_IMAGE;
import static id.ac.stis.capi.odk.activities.FormEntryActivity.ANNOTATE_IMAGE;
import static id.ac.stis.capi.odk.activities.FormEntryActivity.AUDIO_CAPTURE;
import static id.ac.stis.capi.odk.activities.FormEntryActivity.AUDIO_CHOOSER;
import static id.ac.stis.capi.odk.activities.FormEntryActivity.BARCODE_CAPTURE;
import static id.ac.stis.capi.odk.activities.FormEntryActivity.BEARING_CAPTURE;
import static id.ac.stis.capi.odk.activities.FormEntryActivity.BEARING_RESULT;
import static id.ac.stis.capi.odk.activities.FormEntryActivity.DRAW_IMAGE;
import static id.ac.stis.capi.odk.activities.FormEntryActivity.EX_DECIMAL_CAPTURE;
import static id.ac.stis.capi.odk.activities.FormEntryActivity.EX_GROUP_CAPTURE;
import static id.ac.stis.capi.odk.activities.FormEntryActivity.EX_INT_CAPTURE;
import static id.ac.stis.capi.odk.activities.FormEntryActivity.EX_STRING_CAPTURE;
import static id.ac.stis.capi.odk.activities.FormEntryActivity.GEOSHAPE_CAPTURE;
import static id.ac.stis.capi.odk.activities.FormEntryActivity.GEOSHAPE_RESULTS;
import static id.ac.stis.capi.odk.activities.FormEntryActivity.GEOTRACE_CAPTURE;
import static id.ac.stis.capi.odk.activities.FormEntryActivity.GEOTRACE_RESULTS;
import static id.ac.stis.capi.odk.activities.FormEntryActivity.HIERARCHY_ACTIVITY;
import static id.ac.stis.capi.odk.activities.FormEntryActivity.IMAGE_CAPTURE;
import static id.ac.stis.capi.odk.activities.FormEntryActivity.IMAGE_CHOOSER;
import static id.ac.stis.capi.odk.activities.FormEntryActivity.LOCATION_CAPTURE;
import static id.ac.stis.capi.odk.activities.FormEntryActivity.LOCATION_RESULT;
import static id.ac.stis.capi.odk.activities.FormEntryActivity.LOKASI_ASLI;
import static id.ac.stis.capi.odk.activities.FormEntryActivity.OSM_CAPTURE;
import static id.ac.stis.capi.odk.activities.FormEntryActivity.SIGNATURE_CAPTURE;
import static id.ac.stis.capi.odk.activities.FormEntryActivity.VIDEO_CAPTURE;
import static id.ac.stis.capi.odk.activities.FormEntryActivity.VIDEO_CHOOSER;
/**
* Author : Rahadi Jalu
* Email : 14.8325@stis.ac.id
* Company: Politeknik Statistika STIS
*/
public class FormEntryRVDialogFragment extends DialogFragment implements FormLoaderListener, OnChangeListener,
OnButtonHierarchyClickListener {
public static final int MODE_EDIT = 0;
public static final int MODE_INSERT = 1;
private static final int EVALUATE_CONSTRAINTS = 1;
private static final int DO_NOT_EVALUATE_CONSTRAINTS = 2;
private static final int EVALUATE_CONSTRAINTS_BUT_CAN_SKIP = 3;
private static final int PROGRESS_DIALOG = 1;
private static final int SAVING_DIALOG = 2;
private static final int SAVING_IMAGE_DIALOG = 3;
private static final String INSTANCE_UUID = "instance_uuid";
private static final String FLAG_FROM_DETAIL = "from_detail";
private static final String VIEW_MODE = "viewMode";
private boolean fromDetail;
private int viewMode, locationState;
private String instanceUuid, formPath;
private OnEditRutaSavedListener onEditRutaSavedListener;
private FormLoaderTask formLoaderTask;
private FormsDao formsDao;
private InstancesDao instancesDao;
// private LinearLayout questionContainer;
private TimerLogger timerLogger;
private RecyclerView mainContent;
private HierarchyRVAdapter adapter;
private ArrayList<BaseHierarchy> hierarchies;
private ProgressDialog progressDialog;
public FormEntryRVDialogFragment() {
// Required empty public constructor
}
public static FormEntryRVDialogFragment newInstance(String uuid, int mode, boolean fromDetail) {
FormEntryRVDialogFragment fragment = new FormEntryRVDialogFragment();
Bundle args = new Bundle();
args.putString(INSTANCE_UUID, uuid);
args.putBoolean(FLAG_FROM_DETAIL, fromDetail);
args.putInt(VIEW_MODE, mode);
fragment.setArguments(args);
return fragment;
}
public void setOnEditRutaSavedListener(OnEditRutaSavedListener onEditRutaSavedListener) {
this.onEditRutaSavedListener = onEditRutaSavedListener;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
instanceUuid = getArguments().getString(INSTANCE_UUID);
fromDetail = getArguments().getBoolean(FLAG_FROM_DETAIL);
viewMode = getArguments().getInt(VIEW_MODE);
}
Collect.getInstance().setFormController(null);
instancesDao = new InstancesDao();
Cursor c = instancesDao.getInstancesCursor(InstanceProviderAPI.InstanceColumns.INSTANCE_UUID + "=?",
new String[]{instanceUuid});
// should be unique
Instance instance = instancesDao.getInstancesFromCursor(c).get(0);
String instancePath = instance.getInstanceFilePath();
String formId = instance.getJrFormId();
formsDao = new FormsDao();
Cursor c1 = formsDao.getFormsCursorForFormId(formId);
Form form = formsDao.getFormsFromCursor(c1).get(0);
String formPath = form.getFormFilePath();
formLoaderTask = new FormLoaderTask(instancePath, null, null);
formLoaderTask.setFormLoaderListener(this);
Collect.getInstance().getActivityLogger()
.logAction(this, "formLoaded", formPath);
formLoaderTask.execute(formPath);
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
if (null != savedInstanceState) {
}
}
@Override
public void onStart() {
super.onStart();
setPositiveButtonState(false);
}
@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
LayoutInflater inflater = getActivity().getLayoutInflater();
View v = inflater.inflate(R.layout.fragment_updating_dialog, null);
// questionContainer = v.findViewById(R.id.question_container);
mainContent = v.findViewById(R.id.question_container);
LinearLayoutManager layoutManager = new LinearLayoutManager(getContext());
mainContent.setLayoutManager(layoutManager);
hierarchies = new ArrayList<>();
adapter = new HierarchyRVAdapter(hierarchies);
mainContent.setAdapter(adapter);
builder.setView(v).setPositiveButton(getString(R.string.save_all_answers), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
if (null != onEditRutaSavedListener) {
onEditRutaSavedListener.onEditRutaSaved();
}
}
});
return builder.create();
}
@Override
public void onStop() {
super.onStop();
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
}
private void initializeView() {
refreshView();
setPositiveButtonState(validateAnswers(false));
}
private void refreshView() {
FormController controller = Collect.getInstance().getFormController();
hierarchies = controller.getAllQuestions(getActivity());
setupChangeListener();
adapter.setHierarchies(hierarchies);
adapter.notifyDataSetChanged();
}
void setupChangeListener() {
for (BaseHierarchy hierarchy : hierarchies) {
if (hierarchy instanceof PromptHierarchy) {
try {
ViewUtils.setChangeListener(((PromptHierarchy) hierarchy).getWidget(),
((PromptHierarchy) hierarchy).getPrompt().getIndex(), this);
} catch (InvalidObjectException e) {
e.printStackTrace();
}
} else if (hierarchy instanceof ButtonHierarchy) {
((ButtonHierarchy) hierarchy).setOnButtonHierarchyClickListener(this);
}
}
}
private void setTimerLogger(FormController formController) {
// Create the timer logger and then log the resume event
timerLogger = new TimerLogger(formController.getInstancePath(),
PreferenceManager.getDefaultSharedPreferences(getContext()),
formController);
}
private void setPositiveButtonState(boolean enabled) {
AlertDialog dialog = (AlertDialog) getDialog();
final Window window = dialog.getWindow();
if (window != null) {
window.clearFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
/*| WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL*/
| WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
}
Button positiveButton = dialog.getButton(AlertDialog.BUTTON_POSITIVE);
LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) positiveButton.getLayoutParams();
positiveButton.setLayoutParams(params);
View buttonPanel = (View) positiveButton.getParent();
Timber.d("Button Panel is %s", buttonPanel);
if (buttonPanel != null) {
if (enabled) {
buttonPanel.setBackgroundColor(ContextCompat.getColor(getContext(), R.color.colorAccent));
} else {
buttonPanel.setBackgroundColor(ContextCompat.getColor(getContext(), R.color.grey_999));
}
}
// ViewUtils.debugViewIds(positiveButton.getRootView(), "DEBUGVIEW");
Drawable icon = getResources().getDrawable(R.drawable.ic_save);
icon.setBounds(0, 0, 50, 50);
positiveButton.setCompoundDrawables(null, null, icon, null);
positiveButton.setCompoundDrawablePadding(14);
positiveButton.setTextColor(ContextCompat.getColor(getContext(), android.R.color.white));
positiveButton.setEnabled(enabled);
}
private String getNextNo(String oldNomor) {
String prefix, suffix;
final char[] abc = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray();
StringBuilder suffixEd = new StringBuilder();
if (oldNomor.length() == 3) {
// Ex: 001 --> 001A
return oldNomor + abc[0];
} else if (oldNomor.length() > 3) {
// Ex: 001A --> 001B, 001AA --> 001AB
prefix = oldNomor.substring(0, 3);
suffix = oldNomor.substring(3);
// Identify char in int sequence
int chint = -1;
for (int i = 0; i < suffix.length(); i++) {
char ch = suffix.charAt(i);
int pos = 0;
for (int j = 0; j < abc.length; j++) {
if (String.valueOf(ch).equalsIgnoreCase(String.valueOf(abc[j]))) {
pos = j;
break;
}
}
chint += Math.pow(26, i) * (pos + 1);
}
// Convert next int sequence to char
chint++;
do {
int mod = chint % 26;
suffixEd.insert(0, abc[mod]);
chint /= 26;
} while (chint > 0);
return prefix + suffixEd.toString();
}
return "";
}
@Override
public void loadingComplete(FormLoaderTask task) {
final FormController formController = task.getFormController();
int requestCode = task.getRequestCode(); // these are bogus if
// pendingActivityResult is
// false
int resultCode = task.getResultCode();
Intent intent = task.getIntent();
formLoaderTask.setFormLoaderListener(null);
FormLoaderTask t = formLoaderTask;
formLoaderTask = null;
t.cancel(true);
t.destroy();
Collect.getInstance().setFormController(formController);
Collect.getInstance().setExternalDataManager(task.getExternalDataManager());
// Set the language if one has already been set in the past
String[] languageTest = formController.getLanguages();
if (languageTest != null) {
String defaultLanguage = formController.getLanguage();
String newLanguage = "";
Cursor c = null;
try {
c = formsDao.getFormsCursorForFormFilePath(formPath);
if (c.getCount() == 1) {
c.moveToFirst();
newLanguage = c.getString(c
.getColumnIndex(FormsProviderAPI.FormsColumns.LANGUAGE));
}
} finally {
if (c != null) {
c.close();
}
}
long start = System.currentTimeMillis();
Timber.i("calling formController.setLanguage");
try {
formController.setLanguage(newLanguage);
} catch (Exception e) {
// if somehow we end up with a bad language, set it to the default
Timber.e("Ended up with a bad language. %s", newLanguage);
formController.setLanguage(defaultLanguage);
}
Timber.i("Done in %.3f seconds.", (System.currentTimeMillis() - start) / 1000F);
}
boolean pendingActivityResult = task.hasPendingActivityResult();
if (pendingActivityResult) {
// set the current view to whatever group we were at...
initializeView();
// process the pending activity request...
onActivityResult(requestCode, resultCode, intent);
return;
}
// it can be a normal flow for a pending activity result to restore from
// a savepoint
// (the call flow handled by the above if statement). For all other use
// cases, the
// user should be notified, as it means they wandered off doing other
// things then
// returned to ODK Collect and chose Edit Saved Form, but that the
// savepoint for that
// form is newer than the last saved version of their form data.
// boolean hasUsedSavepoint = task.hasUsedSavepoint();
// if (hasUsedSavepoint) {
// runOnUiThread(new Runnable() {
// @Override
// public void run() {
// ToastUtils.showLongToast(R.string.savepoint_used);
// }
// });
// }
// Set saved answer path
if (formController.getInstancePath() == null) {
// Create new answer folder.
String time = new SimpleDateFormat("yyyy-MM-dd_HH-mm-ss",
Locale.ENGLISH).format(Calendar.getInstance().getTime());
String file = formPath.substring(formPath.lastIndexOf('/') + 1,
formPath.lastIndexOf('.'));
String path = Collect.INSTANCES_PATH + File.separator + file + "_"
+ time;
if (FileUtils.createFolder(path)) {
File instanceFile = new File(path + File.separator + file + "_" + time + ".xml");
formController.setInstancePath(instanceFile);
}
setTimerLogger(formController);
timerLogger.logTimerEvent(TimerLogger.EventTypes.FORM_START, 0, null, false, true);
}
initializeView();
}
private boolean validateAnswers(final boolean refreshView) {
final boolean[] clean = {false};
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
clean[0] = saveAnswers(refreshView);
}
});
return clean[0];
}
/**
* Attempt to save the answer(s) into the data model.
*
* @return false if any error occurs while saving (constraint violated,
* etc...), true otherwise.
*/
private boolean saveAnswers(boolean refreshView) {
AlertDialog dialog = (AlertDialog) getDialog();
final Window window = dialog.getWindow();
if (window != null) {
window.addFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE);
window.addFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
}
boolean isClean = true;
FormController formController = Collect.getInstance().getFormController();
LinkedHashMap<FormIndex, IAnswerData> answers = new LinkedHashMap<>();
for (int i = 0; i < adapter.getItemCount(); i++) {
if (adapter.getItem(i) instanceof PromptHierarchy) {
PromptHierarchy hierarchy = (PromptHierarchy) adapter.getItem(i);
answers.put(hierarchy.getPrompt().getIndex(), hierarchy.getAnswer());
}
}
try {
ArrayList<FailedConstraint> constraints = formController.saveAllScreenAnswers(answers,
true);
if (refreshView) {
refreshView();
}
if (constraints != null) {
for (FailedConstraint constraint : constraints) {