Java tutorial
/** * Apow - a mobile EHR Management System for low-resource environments * in developing countries, exemplified by rural Ghana * Copyright (C) 2014 Martin Landua * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see http://www.gnu.org/licenses/. */ package de.uni_koblenz_landau.apow; import java.util.ArrayList; import java.util.List; import org.openmrs.Concept; import org.openmrs.ConceptDatatype; import org.openmrs.ConceptNumeric; import org.openmrs.Encounter; import org.openmrs.Obs; import android.content.Intent; import android.os.Bundle; import android.support.v4.app.Fragment; import android.support.v4.app.NavUtils; import android.text.Editable; import android.text.TextUtils; import android.text.TextWatcher; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; import android.widget.AdapterView.OnItemSelectedListener; import android.widget.ArrayAdapter; import android.widget.AutoCompleteTextView; import android.widget.CheckBox; import android.widget.EditText; import android.widget.LinearLayout; import android.widget.Spinner; import android.widget.TextView; import android.widget.Toast; import de.uni_koblenz_landau.apow.db.ConceptAdapter; import de.uni_koblenz_landau.apow.dialogs.DeleteDialogFragment; import de.uni_koblenz_landau.apow.dialogs.DeleteDialogListener; import de.uni_koblenz_landau.apow.helper.Constants; import de.uni_koblenz_landau.apow.helper.ListViewItem; import de.uni_koblenz_landau.apow.tasks.FindingListInterface; import de.uni_koblenz_landau.apow.tasks.FindingListTask; import de.uni_koblenz_landau.apow.tasks.ObsDeleteTask; import de.uni_koblenz_landau.apow.tasks.ObsDetailInterface; import de.uni_koblenz_landau.apow.tasks.ObsDetailTask; import de.uni_koblenz_landau.apow.tasks.DataUpdateInterface; import de.uni_koblenz_landau.apow.tasks.ObsUpdateTask; import de.uni_koblenz_landau.apow.tasks.SettingsUpdateTask; import de.uni_koblenz_landau.apow.tasks.SymptomListInterface; import de.uni_koblenz_landau.apow.tasks.SymptomListTask; import de.uni_koblenz_landau.apow.tasks.TaskActivity; import de.uni_koblenz_landau.apow.tasks.TaskActivityReference; /** * Fragment for showing an updating an observation. * * @author Martin Landua * */ public class ObsDetailFragment extends Fragment implements ObsDetailInterface, DataUpdateInterface, FindingListInterface, SymptomListInterface, TaskActivity, DeleteDialogListener { // Constants public static final String ARG_OBS_ID = "obs_id"; private static final String ARG_OBS = "obs"; public static final String ARG_TESTS = "tests"; public static final String ARG_ENCOUNTER_ID = "encounter_id"; public static final String ARG_TITLE = "title"; private static final String ARG_FINDING_CODE = "finding_code"; private static final String ARG_SYMPTOM_CODE = "symptom_code"; private static final String ARG_TEST_CONCEPTS = "test_concepts"; private static final String DELETE_DIALOG_ID = "deletedialog"; private static final int KEY_QUESTION = 0; private static final int KEY_TEST = 1; private static final int KEY_FINDING = 2; private static final int KEY_SYMPTOM = 3; // Tasks private FindingListTask mFindingListTask; private ObsDeleteTask mObsDeleteTask; private ObsDetailTask mObsDetailTask; private ObsUpdateTask mObsUpdateTask; private SymptomListTask mSymptomListTask; // UI Variables private int mEncounterID; private Obs mObs; private int mObsID; private String mQuestionText; private String mTestValue; private List<ListViewItem> mTestConcepts; private int findingCode; private Boolean findingCodeBlock = true; private int symptomCode; private Boolean symptomCodeBlock = true; // UI references private DeleteDialogFragment mDeleteDialog; private LinearLayout mClassLayout; private Spinner mClassSpinner; private LinearLayout mQuestionLayout; private EditText mQuestionTextView; private LinearLayout mTestLayout; private EditText mTestValueView; private Spinner mTestConceptView; private TextView mTestUnitView; private LinearLayout mFindingLayout; private AutoCompleteTextView mFindingValueCodedView; private CheckBox mFindingCertaintyView; private CheckBox mFindingSeverityCodedView; private LinearLayout mSymptomLayout; private AutoCompleteTextView mSymptomValueView; /** * Empty constructor for Instantiation */ public ObsDetailFragment() { } @Override public void onCreate(Bundle savedInstanceState) { setHasOptionsMenu(true); getActivity().setTitle(getArguments().getString(ARG_TITLE)); super.onCreate(savedInstanceState); // Re-attach Tasks. TaskActivityReference.getInstance().attach(FindingListTask.TASK_ID, this); TaskActivityReference.getInstance().attach(ObsDeleteTask.TASK_ID, this); TaskActivityReference.getInstance().attach(ObsDetailTask.TASK_ID, this); TaskActivityReference.getInstance().attach(ObsUpdateTask.TASK_ID, this); TaskActivityReference.getInstance().attach(SymptomListTask.TASK_ID, this); if (getArguments().containsKey(ARG_ENCOUNTER_ID)) { mEncounterID = getArguments().getInt(ARG_ENCOUNTER_ID); } if (getArguments().containsKey(ARG_OBS_ID)) { mObsID = getArguments().getInt(ARG_OBS_ID); } } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.obs_detail_fragment, container, false); // Create UI references. mDeleteDialog = (DeleteDialogFragment) getFragmentManager().findFragmentByTag(DELETE_DIALOG_ID); if (mDeleteDialog != null) { mDeleteDialog.setListener(this); } mClassLayout = (LinearLayout) view.findViewById(R.id.obs_detail_class); mClassSpinner = (Spinner) view.findViewById(R.id.obs_detail_class_spinner); mClassSpinner.setOnItemSelectedListener(new OnItemSelectedListener() { @Override public void onItemSelected(AdapterView<?> parent, View v, int pos, long id) { mQuestionLayout.setVisibility(View.GONE); mTestLayout.setVisibility(View.GONE); mFindingLayout.setVisibility(View.GONE); mSymptomLayout.setVisibility(View.GONE); switch (pos) { case Constants.CLASS_QUESTION: mQuestionLayout.setVisibility(View.VISIBLE); break; case Constants.CLASS_TEST: mTestLayout.setVisibility(View.VISIBLE); break; case Constants.CLASS_FINDING: mFindingLayout.setVisibility(View.VISIBLE); break; case Constants.CLASS_SYMPTOM: mSymptomLayout.setVisibility(View.VISIBLE); break; } } @Override public void onNothingSelected(AdapterView<?> parent) { } }); mQuestionLayout = (LinearLayout) view.findViewById(R.id.obs_detail_question); mQuestionTextView = (EditText) view.findViewById(R.id.obs_detail_question_text); mTestLayout = (LinearLayout) view.findViewById(R.id.obs_detail_test); mTestConceptView = (Spinner) view.findViewById(R.id.obs_detail_test_concept); mTestConceptView.setOnItemSelectedListener(new OnItemSelectedListener() { @Override public void onItemSelected(AdapterView<?> parent, View v, int pos, long id) { ListViewItem item = (ListViewItem) parent.getItemAtPosition(pos); mTestUnitView.setText(item.getField2()); } @Override public void onNothingSelected(AdapterView<?> parent) { } }); mTestUnitView = (TextView) view.findViewById(R.id.obs_detail_test_unit); mTestValueView = (EditText) view.findViewById(R.id.obs_detail_test_value); mFindingLayout = (LinearLayout) view.findViewById(R.id.obs_detail_finding); mFindingValueCodedView = (AutoCompleteTextView) view.findViewById(R.id.obs_detail_finding_value_coded); mFindingValueCodedView.addTextChangedListener(new TextWatcher() { @Override public void afterTextChanged(Editable s) { } @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } @Override public void onTextChanged(CharSequence s, int start, int before, int count) { if (!findingCodeBlock) { findingCode = -1; } findingCodeBlock = false; searchFindings(s.toString().trim()); } }); mFindingValueCodedView.setOnItemClickListener(new OnItemClickListener() { public void onItemClick(AdapterView<?> listView, View view, int position, long id) { findingCode = (int) id; } }); mFindingCertaintyView = (CheckBox) view.findViewById(R.id.obs_detail_finding_certainty); mFindingSeverityCodedView = (CheckBox) view.findViewById(R.id.obs_detail_finding_severity_coded); mSymptomLayout = (LinearLayout) view.findViewById(R.id.obs_detail_symptom); mSymptomValueView = (AutoCompleteTextView) view.findViewById(R.id.obs_detail_symptom_value); mSymptomValueView.addTextChangedListener(new TextWatcher() { @Override public void afterTextChanged(Editable s) { } @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } @Override public void onTextChanged(CharSequence s, int start, int before, int count) { if (!symptomCodeBlock) { symptomCode = -1; } symptomCodeBlock = false; searchSymptoms(s.toString().trim()); } }); mSymptomValueView.setOnItemClickListener(new OnItemClickListener() { public void onItemClick(AdapterView<?> listView, View view, int position, long id) { symptomCode = (int) id; } }); // Restore UI from saved instance or load data. if (savedInstanceState != null) { findingCode = savedInstanceState.getInt(ARG_FINDING_CODE); symptomCode = savedInstanceState.getInt(ARG_SYMPTOM_CODE); mObs = (Obs) savedInstanceState.getSerializable(ARG_OBS); if (mObs != null) { mTestConcepts = savedInstanceState.getParcelableArrayList(ARG_TEST_CONCEPTS); ArrayAdapter<ListViewItem> adapter = new ArrayAdapter<>(getActivity(), android.R.layout.simple_spinner_item, mTestConcepts); adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); mTestConceptView.setAdapter(adapter); restoreView(); } } else { findingCode = -1; symptomCode = -1; loadObs(); } return view; } @Override public void onDestroy() { super.onDestroy(); // Detach tasks for preventing memory leaks. TaskActivityReference.getInstance().detach(FindingListTask.TASK_ID); TaskActivityReference.getInstance().detach(ObsDeleteTask.TASK_ID); TaskActivityReference.getInstance().detach(ObsDetailTask.TASK_ID); TaskActivityReference.getInstance().detach(ObsUpdateTask.TASK_ID); TaskActivityReference.getInstance().detach(SymptomListTask.TASK_ID); } @Override public void onSaveInstanceState(Bundle savedInstanceState) { savedInstanceState.putInt(ARG_FINDING_CODE, findingCode); savedInstanceState.putInt(ARG_SYMPTOM_CODE, symptomCode); savedInstanceState.putSerializable(ARG_OBS, mObs); savedInstanceState.putParcelableArrayList(ARG_TEST_CONCEPTS, (ArrayList<ListViewItem>) mTestConcepts); } @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { inflater.inflate(R.menu.obs_detail, menu); // If new observation, hide delete button. if (getArguments().containsKey(ARG_OBS_ID) && getArguments().getInt(ARG_OBS_ID) != -1) { menu.findItem(R.id.obs_detail_action_discard).setVisible(true); } super.onCreateOptionsMenu(menu, inflater); } @Override public boolean onOptionsItemSelected(MenuItem item) { int id = item.getItemId(); if (id == android.R.id.home) { NavUtils.navigateUpFromSameTask(getActivity()); return true; } if (id == R.id.obs_detail_action_discard) { mDeleteDialog = DeleteDialogFragment.newInstance(R.string.obs_detail_delete_dialog_title); mDeleteDialog.setListener(this); mDeleteDialog.show(getActivity().getSupportFragmentManager(), DELETE_DIALOG_ID); return true; } if (id == R.id.obs_detail_action_save) { save(); return true; } if (id == R.id.obs_detail_action_cancel) { Intent back = new Intent(getActivity(), ObsListActivity.class); NavUtils.navigateUpTo(getActivity(), back); return true; } return super.onOptionsItemSelected(item); } /** * Checks input and saves settings to database. */ public void save() { // Abort if task is already running. if (mObsUpdateTask != null) { return; } // Reset errors. mQuestionTextView.setError(null); mTestValueView.setError(null); mFindingValueCodedView.setError(null); mSymptomValueView.setError(null); // Store UI values. mQuestionText = mQuestionTextView.getText().toString().trim(); mTestValue = mTestValueView.getText().toString().trim(); // Find observation type. int type = -1; // Observation is question. if ((mObs.getConcept() != null && mObs.getConcept().getConceptId() == Constants.QUESTION_CONCEPT_ID) || (mObs.getConcept() == null && mClassSpinner.getSelectedItemPosition() == Constants.CLASS_QUESTION)) { type = KEY_QUESTION; // Observation is test. } else if ((mObs.getConcept() != null && mObs.getConcept().getConceptClass() != null && mObs.getConcept().getConceptClass().getConceptClassId() == Constants.TEST_CLASS_ID) || (mObs.getConcept() == null && mClassSpinner.getSelectedItemPosition() == Constants.CLASS_TEST)) { type = KEY_TEST; // Observation is finding. } else if ((mObs.getConcept() != null && mObs.getConcept().getConceptId() == Constants.FINDING_SET_CONCEPT_ID) || (mObs.getConcept() == null && mClassSpinner.getSelectedItemPosition() == Constants.CLASS_FINDING)) { type = KEY_FINDING; // Observation is symptom. } else if ((mObs.getConcept() != null && mObs.getConcept().getConceptClass() != null && mObs.getConcept().getConceptClass().getConceptClassId() == Constants.SYMPTOM_CONCEPT_CLASS_ID) || (mObs.getConcept() == null && mClassSpinner.getSelectedItemPosition() == Constants.CLASS_SYMPTOM)) { type = KEY_SYMPTOM; } Boolean cancel = false; View focusView = null; // Validate UI input. Double mTestValueDouble = null; if (type == KEY_QUESTION) { if (TextUtils.isEmpty(mQuestionText)) { mQuestionTextView.setError(getString(R.string.error_field_required)); focusView = mQuestionTextView; cancel = true; } } else if (type == KEY_TEST) { if (TextUtils.isEmpty(mTestValue)) { mTestValueView.setError(getString(R.string.error_field_required)); focusView = mTestValueView; cancel = true; } else { try { mTestValueDouble = Double.parseDouble(mTestValue); Double low = ((ListViewItem) mTestConceptView.getSelectedItem()).getValue1(); Double hi = ((ListViewItem) mTestConceptView.getSelectedItem()).getValue2(); if (low != -1 && hi != -1 && (mTestValueDouble < low || mTestValueDouble > hi)) { mTestValueView.setError(getActivity().getString(R.string.error_field_out_of_range) + " [" + low + "," + hi + "]"); focusView = mTestValueView; cancel = true; } } catch (NumberFormatException nfe) { mTestValueView.setError(getActivity().getString(R.string.error_field_not_numeric)); focusView = mTestValueView; cancel = true; } } } else if (type == KEY_FINDING) { if (findingCode == -1) { mFindingValueCodedView.setError(getActivity().getString(R.string.error_field_not_from_list)); focusView = mTestValueView; cancel = true; } } else if (type == KEY_SYMPTOM) { if (symptomCode == -1) { mSymptomValueView.setError(getActivity().getString(R.string.error_field_not_from_list)); focusView = mTestValueView; cancel = true; } } // If there are errors cancel, else save to database. if (cancel) { focusView.requestFocus(); } else { // Update obs object if (type == KEY_QUESTION) { mObs.setConcept(new Concept(Constants.QUESTION_CONCEPT_ID)); mObs.setValueText(mQuestionText); } else if (type == KEY_TEST) { ConceptNumeric concept = new ConceptNumeric( ((ListViewItem) mTestConceptView.getSelectedItem()).getId()); ConceptDatatype datatype = new ConceptDatatype(); datatype.setName(Constants.CONCEPT_DATATYPE_NUMERIC); concept.setDatatype(datatype); mObs.setConcept(concept); mObs.setValueNumeric(mTestValueDouble); } else if (type == KEY_FINDING) { if (mObs.hasGroupMembers()) { for (Obs obs : mObs.getGroupMembers()) { if (obs.getConcept().getConceptId() == Constants.FINDING_CONCEPT) { if (findingCode != -1) { obs.setValueCoded(new Concept(findingCode)); } } if (obs.getConcept().getConceptId() == Constants.FINDING_CERTAINTY) { if (mFindingCertaintyView.isChecked()) { obs.setValueCoded(new Concept(Constants.FINDING_CERTAINTY_CONFIRMED)); } else { obs.setValueCoded(new Concept(Constants.FINDING_CERTAINTY_NOT_CONFIRMED)); } } if (obs.getConcept().getConceptId() == Constants.FINDING_SEVERITY) { if (mFindingSeverityCodedView.isChecked()) { obs.setValueCoded(new Concept(Constants.FINDING_SEVERITY_PRIMARY)); } else { obs.setValueCoded(new Concept(Constants.FINDING_SEVERITY_SECONDARY)); } } } } else { mObs.setConcept(new Concept(Constants.FINDING_SET_CONCEPT_ID)); Obs concept = new Obs(); concept.setConcept(new Concept(Constants.FINDING_CONCEPT)); concept.setValueCoded(new Concept(findingCode)); mObs.addGroupMember(concept); Obs certainty = new Obs(); certainty.setConcept(new Concept(Constants.FINDING_CERTAINTY)); if (mFindingCertaintyView.isChecked()) { certainty.setValueCoded(new Concept(Constants.FINDING_CERTAINTY_CONFIRMED)); } else { certainty.setValueCoded(new Concept(Constants.FINDING_CERTAINTY_NOT_CONFIRMED)); } mObs.addGroupMember(certainty); Obs severity = new Obs(); severity.setConcept(new Concept(Constants.FINDING_SEVERITY)); if (mFindingSeverityCodedView.isChecked()) { severity.setValueCoded(new Concept(Constants.FINDING_SEVERITY_PRIMARY)); } else { severity.setValueCoded(new Concept(Constants.FINDING_SEVERITY_SECONDARY)); } mObs.addGroupMember(severity); } } else if (type == KEY_SYMPTOM) { mObs.setConcept(new Concept(symptomCode)); } // Start update task. mObsUpdateTask = new ObsUpdateTask(); TaskActivityReference.getInstance().addTask(SettingsUpdateTask.TASK_ID, mObsUpdateTask, this); mObsUpdateTask.execute(mObs); } } /** * Called by update task, when update is finished. */ @Override public void onDataUpdateFinished() { mObsUpdateTask = null; // Leave activity. Intent intent = new Intent(getActivity(), ObsListActivity.class); NavUtils.navigateUpTo(getActivity(), intent); } /** * Starts task to load settings. */ private void loadObs() { // Abort if task is already running. if (mObsDetailTask != null) { return; } // Start detail task. mObsDetailTask = new ObsDetailTask(); TaskActivityReference.getInstance().addTask(ObsDetailTask.TASK_ID, mObsDetailTask, this); mObsDetailTask.execute(mObsID); } /** * Called by settings task, when loading is finished. */ @Override public void onObsFetched(Obs obs, List<ListViewItem> testConcepts) { mObsDetailTask = null; // If result is not empty, update UI, else show error message. if (testConcepts != null) { mTestConcepts = testConcepts; ArrayAdapter<ListViewItem> adapter = new ArrayAdapter<>(getActivity(), android.R.layout.simple_spinner_item, mTestConcepts); adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); mTestConceptView.setAdapter(adapter); if (obs != null) { mObs = obs; // Observation is question. if (mObs.getConcept().getConceptId() == Constants.QUESTION_CONCEPT_ID) { mQuestionTextView.setText(mObs.getValueText()); // Observation is test. } else if (mObs.getConcept().getConceptClass().getConceptClassId() == Constants.TEST_CLASS_ID) { mTestValueView.setText("" + mObs.getValueNumeric()); mTestUnitView.setText(((ConceptNumeric) mObs.getConcept()).getUnits()); int position = -1; for (int i = 0; i < adapter.getCount(); i++) { if (adapter.getItem(i).getId() == mObs.getConcept().getConceptId()) { position = i; break; } } mTestConceptView.setSelection(position); // Observation is finding. } else if (mObs.getConcept().getConceptId() == Constants.FINDING_SET_CONCEPT_ID) { for (Obs obs1 : mObs.getGroupMembers()) { if (obs1.getConcept().getConceptId() == Constants.FINDING_CONCEPT) { mFindingValueCodedView.setText(obs1.getValueCoded().getName().getName()); findingCode = obs1.getValueCoded().getConceptId(); } if (obs1.getConcept().getConceptId() == Constants.FINDING_CERTAINTY && obs1.getValueCoded().getConceptId() == Constants.FINDING_CERTAINTY_CONFIRMED) { mFindingCertaintyView.setChecked(true); } if (obs1.getConcept().getConceptId() == Constants.FINDING_SEVERITY && obs1.getValueCoded().getConceptId() == Constants.FINDING_SEVERITY_PRIMARY) { mFindingSeverityCodedView.setChecked(true); } } // Observation is symptom. } else if (mObs.getConcept().getConceptClass() .getConceptClassId() == Constants.SYMPTOM_CONCEPT_CLASS_ID) { mSymptomValueView.setText(mObs.getConcept().getName().getName()); symptomCode = mObs.getConcept().getConceptId(); } } else { mObs = new Obs(); mObs.setEncounter(new Encounter(mEncounterID)); } restoreView(); } else { Toast.makeText(getActivity(), R.string.error_database, Toast.LENGTH_SHORT).show(); } } /** * Initialize views. */ public void restoreView() { if (mObs != null) { if (mObs.getId() == null) { mClassLayout.setVisibility(View.VISIBLE); } else { // Observation is question. if (mObs.getConcept().getConceptId() == Constants.QUESTION_CONCEPT_ID) { mQuestionLayout.setVisibility(View.VISIBLE); } // Observation is test. if (mObs.getConcept().getConceptClass().getConceptClassId() == Constants.TEST_CLASS_ID) { mTestLayout.setVisibility(View.VISIBLE); } // Observation is finding. if (mObs.getConcept().getConceptId() == Constants.FINDING_SET_CONCEPT_ID) { mFindingLayout.setVisibility(View.VISIBLE); } // Observation is symptom. if (mObs.getConcept().getConceptClass().getConceptClassId() == Constants.SYMPTOM_CONCEPT_CLASS_ID) { mSymptomLayout.setVisibility(View.VISIBLE); } } } } /** * Starts task to find findings. * * @param search Search query */ private void searchFindings(String search) { // Abort if task is already running. if (mFindingListTask != null) { return; } // Start task. mFindingListTask = new FindingListTask(); TaskActivityReference.getInstance().addTask(FindingListTask.TASK_ID, mFindingListTask, this); mFindingListTask.execute(search); } /** * Called by findings task, when loading is finished. */ @Override public void onFindingsFetched(List<Concept> concepts) { mFindingListTask = null; // If result is not empty, update UI, else show error message. if (concepts != null) { ConceptAdapter adapter = new ConceptAdapter(getActivity(), concepts); mFindingValueCodedView.setAdapter(adapter); } else { Toast.makeText(getActivity(), R.string.error_database, Toast.LENGTH_SHORT).show(); } } /** * Starts task to find symptoms. * * @param search Search query */ private void searchSymptoms(String search) { // Abort if task is already running. if (mSymptomListTask != null) { return; } // Start task. mSymptomListTask = new SymptomListTask(); TaskActivityReference.getInstance().addTask(SymptomListTask.TASK_ID, mSymptomListTask, this); mSymptomListTask.execute(search); } /** * Called by symptoms task, when loading is finished. */ @Override public void onSymptomsFetched(List<Concept> concepts) { mSymptomListTask = null; // If result is not empty, update UI, else show error message. if (concepts != null) { ConceptAdapter adapter = new ConceptAdapter(getActivity(), concepts); mSymptomValueView.setAdapter(adapter); } else { Toast.makeText(getActivity(), R.string.error_database, Toast.LENGTH_SHORT).show(); } } /** * Callback for delete dialog. */ @Override public void deleteItem(String voidReason) { // Abort if task is already running. if (mObsDeleteTask != null) { return; } // Start task. mObsDeleteTask = new ObsDeleteTask(mObsID, mObs.hasGroupMembers(), voidReason); TaskActivityReference.getInstance().addTask(ObsDeleteTask.TASK_ID, mObsDeleteTask, this); mObsDeleteTask.execute(); } }