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.Calendar; import java.util.Date; import java.util.GregorianCalendar; import java.util.List; import org.openmrs.Patient; import org.openmrs.PatientIdentifier; import org.openmrs.PatientIdentifierType; import org.openmrs.PersonAddress; import org.openmrs.PersonName; import de.uni_koblenz_landau.apow.db.PatientDAO; import de.uni_koblenz_landau.apow.dialogs.DateDialogFragment; import de.uni_koblenz_landau.apow.dialogs.DateDialogListener; import de.uni_koblenz_landau.apow.helper.Constants; import de.uni_koblenz_landau.apow.helper.District; import de.uni_koblenz_landau.apow.helper.Helper; import de.uni_koblenz_landau.apow.helper.Region; import de.uni_koblenz_landau.apow.tasks.DataUpdateInterface; import de.uni_koblenz_landau.apow.tasks.EncounterDetailTask; import de.uni_koblenz_landau.apow.tasks.EncounterUpdateTask; import de.uni_koblenz_landau.apow.tasks.PatientDetailInterface; import de.uni_koblenz_landau.apow.tasks.PatientDetailTask; import de.uni_koblenz_landau.apow.tasks.PatientUpdateTask; import de.uni_koblenz_landau.apow.tasks.TaskActivity; import de.uni_koblenz_landau.apow.tasks.TaskActivityReference; import android.content.Intent; import android.os.Bundle; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentActivity; import android.support.v4.app.NavUtils; import android.text.TextUtils; 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.view.View.OnClickListener; import android.view.inputmethod.InputMethodManager; import android.widget.AdapterView; import android.widget.AdapterView.OnItemSelectedListener; import android.widget.ArrayAdapter; import android.widget.CheckBox; import android.widget.EditText; import android.widget.Spinner; import android.widget.TextView; import android.widget.Toast; import android.widget.LinearLayout; public class PatientDetailEditFragment extends Fragment implements PatientDetailInterface, DataUpdateInterface, TaskActivity, DateDialogListener { // Constants private static final String ARG_PATIENT = "patient"; public static final String ARG_PATIENT_ID = "patient_id"; private static final String ARG_REGIONS = "regions"; private static final String ARG_DEAD = "dead"; private static final String ARG_SELECTED_REGION = "region"; private static final String ARG_SELECTED_DISTRICT = "district"; private static final String BIRTHDATE_DIALOG_ID = "birthdatedialog"; private static final String DEATHDATE_DIALOG_ID = "deathdatedialog"; // Tasks private PatientUpdateTask mPatientUpdateTask; private PatientDetailTask mPatientDetailTask; // UI Variables private Patient mPatient; private int mPatientID; private List<Region> mRegions; // UI references private DateDialogFragment mBirthDateDialog; private DateDialogFragment mDeathDateDialog; private EditText mIdentifierView; private EditText mNamePrefixView; private EditText mGivenNameView; private EditText mMiddleNameView; private EditText mFamilyNamePrefixView; private EditText mFamilyNameView; private EditText mFamilyName2View; private EditText mFamilyNameSuffixView; private EditText mDegreeView; private Spinner mGenderView; private TextView mBirthdateView; private CheckBox mBirthdateEstimatedView; private EditText mAddress1View; private EditText mAddress2View; private EditText mCityVillageView; private Spinner mRegionsView; private Spinner mDistrictsView; private EditText mCountryView; private EditText mLongitudeView; private EditText mLatitudeView; private CheckBox mDeadView; private TextView mDeathdateView; private LinearLayout mDeadLayout; /** * Empty constructor for Instantiation */ public PatientDetailEditFragment() { } @Override public void onCreate(Bundle savedInstanceState) { setHasOptionsMenu(true); super.onCreate(savedInstanceState); // Re-attach Tasks. TaskActivityReference.getInstance().attach(PatientUpdateTask.TASK_ID, this); TaskActivityReference.getInstance().attach(PatientDetailTask.TASK_ID, this); if (getArguments().containsKey(ARG_PATIENT_ID)) { mPatientID = getArguments().getInt(ARG_PATIENT_ID); } } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.patient_detail_edit_fragment, container, false); // Create UI references. mBirthDateDialog = (DateDialogFragment) getFragmentManager().findFragmentByTag(BIRTHDATE_DIALOG_ID); if (mBirthDateDialog != null) { mBirthDateDialog.setListener(this); } mDeathDateDialog = (DateDialogFragment) getFragmentManager().findFragmentByTag(DEATHDATE_DIALOG_ID); if (mDeathDateDialog != null) { mDeathDateDialog.setListener(this); } mIdentifierView = (EditText) view.findViewById(R.id.patient_detail_edit_identifier); mNamePrefixView = (EditText) view.findViewById(R.id.patient_detail_edit_name_prefix); mGivenNameView = (EditText) view.findViewById(R.id.patient_detail_edit_name_given_name); mMiddleNameView = (EditText) view.findViewById(R.id.patient_detail_edit_name_middle_name); mFamilyNamePrefixView = (EditText) view.findViewById(R.id.patient_detail_edit_name_family_name_prefix); mFamilyNameView = (EditText) view.findViewById(R.id.patient_detail_edit_name_family_name); mFamilyName2View = (EditText) view.findViewById(R.id.patient_detail_edit_name_family_name2); mFamilyNameSuffixView = (EditText) view.findViewById(R.id.patient_detail_edit_name_family_name_suffix); mDegreeView = (EditText) view.findViewById(R.id.patient_detail_edit_name_degree); mGenderView = (Spinner) view.findViewById(R.id.patient_detail_edit_gender); mBirthdateView = (TextView) view.findViewById(R.id.patient_detail_edit_birthdate); mBirthdateEstimatedView = (CheckBox) view.findViewById(R.id.patient_detail_edit_birthdate_estimated); mAddress1View = (EditText) view.findViewById(R.id.patient_detail_edit_address_address1); mAddress2View = (EditText) view.findViewById(R.id.patient_detail_edit_address_address2); mCityVillageView = (EditText) view.findViewById(R.id.patient_detail_edit_address_cityvillage); mDistrictsView = (Spinner) view.findViewById(R.id.patient_detail_edit_address_district); mRegionsView = (Spinner) view.findViewById(R.id.patient_detail_edit_address_region); mRegionsView.setOnItemSelectedListener(new OnItemSelectedListener() { @Override public void onItemSelected(AdapterView<?> parent, View v, int pos, long id) { Region region = (Region) parent.getItemAtPosition(pos); ArrayAdapter<District> adapter = new ArrayAdapter<>(getActivity(), android.R.layout.simple_spinner_item, region.getDistricts()); adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); mDistrictsView.setAdapter(adapter); if (parent.getTag() != null) { mDistrictsView.setSelection((int) parent.getTag()); parent.setTag(null); } } @Override public void onNothingSelected(AdapterView<?> parent) { } }); mCountryView = (EditText) view.findViewById(R.id.patient_detail_edit_address_country); mLongitudeView = (EditText) view.findViewById(R.id.patient_detail_edit_address_longitude); mLatitudeView = (EditText) view.findViewById(R.id.patient_detail_edit_address_latitude); mDeathdateView = (TextView) view.findViewById(R.id.patient_detail_edit_deathdate); mDeadLayout = (LinearLayout) view.findViewById(R.id.patient_detail_edit_dead_group); mDeadLayout = (LinearLayout) view.findViewById(R.id.patient_detail_edit_dead_group); mDeadView = (CheckBox) view.findViewById(R.id.patient_detail_edit_dead); mDeadView.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { CheckBox dead = (CheckBox) v; if (dead.isChecked()) { mDeadLayout.setVisibility(View.VISIBLE); } else { mDeadLayout.setVisibility(View.GONE); } } }); // Restore UI from saved instance or load data. if (savedInstanceState != null) { mPatient = (Patient) savedInstanceState.getSerializable(ARG_PATIENT); if (mPatient != null) { mRegions = (List<Region>) savedInstanceState.getSerializable(ARG_REGIONS); ArrayAdapter<Region> adapter = new ArrayAdapter<>(getActivity(), android.R.layout.simple_spinner_item, mRegions); adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); mRegionsView.setAdapter(adapter); ArrayAdapter<District> adapter1 = new ArrayAdapter<>(getActivity(), android.R.layout.simple_spinner_item, mRegions.get(0).getDistricts()); adapter1.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); mDistrictsView.setAdapter(adapter1); String selectedRegion = savedInstanceState.getString(ARG_SELECTED_REGION); String selectedDistrict = savedInstanceState.getString(ARG_SELECTED_DISTRICT); for (int i = 0; i < adapter.getCount(); i++) { Region region = adapter.getItem(i); if (region.getRegionName().equals(selectedRegion)) { for (int j = 0; j < region.getDistricts().size(); j++) { if (region.getDistricts().get(j).getDistrictName().equals(selectedDistrict)) { mRegionsView.setTag(j); mRegionsView.setSelection(i, false); adapter1 = new ArrayAdapter<>(getActivity(), android.R.layout.simple_spinner_item, region.getDistricts()); adapter1.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); mDistrictsView.setAdapter(adapter1); mDistrictsView.setSelection(j, false); break; } } break; } } if (savedInstanceState.getBoolean(ARG_DEAD)) { mDeadLayout.setVisibility(View.VISIBLE); } else { mDeadLayout.setVisibility(View.GONE); } } } else { loadPatient(); } return view; } @Override public void onDestroy() { super.onDestroy(); // Detach tasks for preventing memory leaks. TaskActivityReference.getInstance().detach(PatientUpdateTask.TASK_ID); TaskActivityReference.getInstance().detach(PatientDetailTask.TASK_ID); } public void onSaveInstanceState(Bundle savedInstanceState) { savedInstanceState.putSerializable(ARG_PATIENT, mPatient); savedInstanceState.putString(ARG_SELECTED_DISTRICT, ((District) mDistrictsView.getSelectedItem()).getDistrictName()); savedInstanceState.putString(ARG_SELECTED_REGION, ((Region) mRegionsView.getSelectedItem()).getRegionName()); savedInstanceState.putBoolean(ARG_DEAD, mDeadView.isChecked()); savedInstanceState.putSerializable(ARG_REGIONS, (ArrayList<Region>) mRegions); super.onSaveInstanceState(savedInstanceState); } @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { inflater.inflate(R.menu.patient_detail_edit, menu); super.onCreateOptionsMenu(menu, inflater); } @Override public boolean onOptionsItemSelected(MenuItem item) { int id = item.getItemId(); if (id == android.R.id.home) { InputMethodManager inputManager = (InputMethodManager) getActivity() .getSystemService(FragmentActivity.INPUT_METHOD_SERVICE); if (getActivity().getCurrentFocus() != null) { inputManager.hideSoftInputFromWindow(getActivity().getCurrentFocus().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS); } NavUtils.navigateUpFromSameTask(getActivity()); return true; } if (id == R.id.patient_detail_edit_action_save) { save(); return true; } if (id == R.id.patient_detail_edit_action_cancel) { InputMethodManager inputManager = (InputMethodManager) getActivity() .getSystemService(FragmentActivity.INPUT_METHOD_SERVICE); if (getActivity().getCurrentFocus() != null) { inputManager.hideSoftInputFromWindow(getActivity().getCurrentFocus().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS); } NavUtils.navigateUpFromSameTask(getActivity()); return true; } return super.onOptionsItemSelected(item); } private boolean isNotEmpty(View view) { ((TextView) view).setError(null); if (TextUtils.isEmpty(((TextView) view).getText())) { ((TextView) view).setError(getActivity().getString(R.string.error_field_required)); focusView = view; return false; } return true; } private View focusView = null; private void save() { if (mPatientUpdateTask != null) { return; } boolean valid = isNotEmpty(mGivenNameView); valid &= isNotEmpty(mFamilyNameView); valid &= isNotEmpty(mBirthdateView); valid &= isNotEmpty(mAddress1View); valid &= isNotEmpty(mCityVillageView); valid &= isNotEmpty(mCountryView); boolean identifierNotEmpty = isNotEmpty(mIdentifierView); valid &= identifierNotEmpty; if (identifierNotEmpty) { PatientDAO dao = new PatientDAO(getActivity()); dao.open(getActivity()); // If it's a new patient, check if identifier is already in // database. if (mPatient.getPatientIdentifier().getIdentifier() == null) { if (!dao.isIdentifierUnique(mIdentifierView.getText().toString().trim())) { focusView = mIdentifierView; valid &= false; mIdentifierView .setError(getActivity().getString(R.string.patient_detail_edit_error_not_unique)); } // If it's an existing patient, check if identifier hasn't // changed and if not, check if it is already in database. } else { if (!mPatient.getPatientIdentifier().getIdentifier() .equals(mIdentifierView.getText().toString().trim()) && !dao.isIdentifierUnique(mIdentifierView.getText().toString().trim())) { focusView = mIdentifierView; valid &= false; mIdentifierView .setError(getActivity().getString(R.string.patient_detail_edit_error_not_unique)); } } dao.close(); } if (!valid) { focusView.requestFocus(); } else { if (mPatient.getPatientIdentifier() != null) { mPatient.getPatientIdentifier().setIdentifier(mIdentifierView.getText().toString().trim()); } if (mPatient.getPersonName() != null) { mPatient.getPersonName().setPrefix(mNamePrefixView.getText().toString().trim()); mPatient.getPersonName().setGivenName(mGivenNameView.getText().toString().trim()); mPatient.getPersonName().setMiddleName(mMiddleNameView.getText().toString().trim()); mPatient.getPersonName().setFamilyNamePrefix(mFamilyNamePrefixView.getText().toString().trim()); mPatient.getPersonName().setFamilyName(mFamilyNameView.getText().toString().trim()); mPatient.getPersonName().setFamilyName2(mFamilyName2View.getText().toString().trim()); mPatient.getPersonName().setFamilyNameSuffix(mFamilyNameSuffixView.getText().toString().trim()); mPatient.getPersonName().setDegree(mDegreeView.getText().toString().trim()); } switch (mGenderView.getSelectedItemPosition()) { case 0: mPatient.setGender("U"); break; case 1: mPatient.setGender("F"); break; case 2: mPatient.setGender("M"); break; } mPatient.setBirthdate( Helper.localeStringToDate(mBirthdateView.getText().toString().trim(), getActivity())); mPatient.setBirthdateEstimated(mBirthdateEstimatedView.isChecked()); PersonAddress personAddress = new PersonAddress(); if (mPatient.getPersonAddress() != null) { personAddress = mPatient.getPersonAddress(); } personAddress.setAddress1(mAddress1View.getText().toString().trim()); personAddress.setAddress2(mAddress2View.getText().toString().trim()); personAddress.setCityVillage(mCityVillageView.getText().toString().trim()); personAddress.setStateProvince(((Region) mRegionsView.getSelectedItem()).getRegionName()); personAddress.setCountyDistrict(((District) mDistrictsView.getSelectedItem()).getDistrictName()); personAddress.setCountry(mCountryView.getText().toString().trim()); personAddress.setLongitude(mLongitudeView.getText().toString().trim()); personAddress.setLatitude(mLatitudeView.getText().toString().trim()); if (mPatient.getPersonAddress() == null) { mPatient.addAddress(personAddress); } if (mDeadView.isChecked()) { mPatient.setDead(true); String deathdate = mDeathdateView.getText().toString().trim(); if ("".equals(deathdate)) { mPatient.setDeathDate(Helper.localeStringToDate(deathdate, getActivity())); } } // Start update task. mPatientUpdateTask = new PatientUpdateTask(); TaskActivityReference.getInstance().addTask(EncounterUpdateTask.TASK_ID, mPatientUpdateTask, this); mPatientUpdateTask.execute(mPatient); } } /** * Called by update task, when update is finished. */ @Override public void onDataUpdateFinished() { mPatientUpdateTask = null; InputMethodManager inputManager = (InputMethodManager) getActivity() .getSystemService(FragmentActivity.INPUT_METHOD_SERVICE); if (getActivity().getCurrentFocus() != null) { inputManager.hideSoftInputFromWindow(getActivity().getCurrentFocus().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS); } Intent back = new Intent(getActivity(), PatientListActivity.class); back.putExtra(PatientListActivity.ARG_CHANGED, true); NavUtils.navigateUpTo(getActivity(), back); } private void loadPatient() { // Abort if task is already running. if (mPatientDetailTask != null) { return; } // Start task. mPatientDetailTask = new PatientDetailTask(); TaskActivityReference.getInstance().addTask(EncounterDetailTask.TASK_ID, mPatientDetailTask, this); mPatientDetailTask.execute(mPatientID); } /** * Called by EncounterDetailTask, when loading is finished. */ @Override public void onPatientFetched(Patient patient, List<Region> regions) { mPatientDetailTask = null; // If result is not empty, update UI, else show error message. if (regions != null) { mRegions = regions; ArrayAdapter<Region> adapter = new ArrayAdapter<>(getActivity(), android.R.layout.simple_spinner_item, regions); adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); mRegionsView.setAdapter(adapter); ArrayAdapter<District> adapter1 = new ArrayAdapter<>(getActivity(), android.R.layout.simple_spinner_item, regions.get(0).getDistricts()); adapter1.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); mDistrictsView.setAdapter(adapter1); if (patient != null) { mPatient = patient; if (mPatient.getPatientIdentifier() != null) { Helper.setViewText(mIdentifierView, mPatient.getPatientIdentifier().getIdentifier()); } if (mPatient.getPersonName() != null) { getActivity().setTitle(mPatient.getPersonName().getFullName()); Helper.setViewText(mNamePrefixView, mPatient.getPersonName().getPrefix()); Helper.setViewText(mGivenNameView, mPatient.getPersonName().getGivenName()); Helper.setViewText(mMiddleNameView, mPatient.getPersonName().getMiddleName()); Helper.setViewText(mFamilyNamePrefixView, mPatient.getPersonName().getFamilyNamePrefix()); Helper.setViewText(mFamilyNameView, mPatient.getPersonName().getFamilyName()); Helper.setViewText(mFamilyName2View, mPatient.getPersonName().getFamilyName2()); Helper.setViewText(mFamilyNameSuffixView, mPatient.getPersonName().getFamilyNameSuffix()); Helper.setViewText(mDegreeView, mPatient.getPersonName().getDegree()); } if (mPatient.getGender() != null) { switch (mPatient.getGender()) { case "U": mGenderView.setSelection(0); break; case "F": mGenderView.setSelection(1); break; case "M": mGenderView.setSelection(2); break; } } else { mGenderView.setSelection(0); } if (mPatient.getBirthdate() != null) { Helper.setViewText(mBirthdateView, Helper.dateToLocaleString(mPatient.getBirthdate(), getActivity())); } mBirthdateEstimatedView.setChecked(mPatient.isBirthdateEstimated()); if (mPatient.getPersonAddress() != null) { Helper.setViewText(mAddress1View, mPatient.getPersonAddress().getAddress1()); Helper.setViewText(mAddress2View, mPatient.getPersonAddress().getAddress2()); Helper.setViewText(mCityVillageView, mPatient.getPersonAddress().getCityVillage()); String selectedRegion = mPatient.getPersonAddress().getStateProvince(); String selectedDistrict = mPatient.getPersonAddress().getCountyDistrict(); for (int i = 0; i < adapter.getCount(); i++) { Region region = adapter.getItem(i); if (region.getRegionName().equals(selectedRegion)) { for (int j = 0; j < region.getDistricts().size(); j++) { if (region.getDistricts().get(j).getDistrictName().equals(selectedDistrict)) { mRegionsView.setTag(j); mRegionsView.setSelection(i, false); adapter1 = new ArrayAdapter<>(getActivity(), android.R.layout.simple_spinner_item, region.getDistricts()); adapter1.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); mDistrictsView.setAdapter(adapter1); mDistrictsView.setSelection(j, false); break; } } break; } } Helper.setViewText(mCountryView, mPatient.getPersonAddress().getCountry()); Helper.setViewText(mLongitudeView, mPatient.getPersonAddress().getLongitude()); Helper.setViewText(mLatitudeView, mPatient.getPersonAddress().getLatitude()); } mDeadView.setChecked(mPatient.getDead()); if (mPatient.getDead()) { if (mPatient.getDeathDate() != null) { Helper.setViewText(mDeathdateView, Helper.dateToLocaleString(mPatient.getDeathDate(), getActivity())); } mDeadLayout.setVisibility(View.VISIBLE); } else { mDeadLayout.setVisibility(View.GONE); } } else { mPatient = new Patient(); PatientIdentifier patientIdentifier = new PatientIdentifier(); PatientIdentifierType patientIdentifierType = new PatientIdentifierType(); patientIdentifierType.setName(Constants.IDENTIFIER_TYPE_NAME); patientIdentifier.setIdentifierType(patientIdentifierType); mPatient.addIdentifier(patientIdentifier); PersonName personName = new PersonName(); mPatient.addName(personName); PersonAddress personAddress = new PersonAddress(); mPatient.addAddress(personAddress); } } else { Toast.makeText(getActivity(), R.string.error_database, Toast.LENGTH_SHORT).show(); } } /** * Create and open date dialog. * * @param view View */ public void openDateDialog(View view) { Calendar calendar = Calendar.getInstance(); // Get date of field. If no date is available, use today. Date date = Helper.localeStringToDate(((TextView) view).getText().toString().trim(), getActivity()); if (date != null) { calendar.setTime(date); } else { calendar = new GregorianCalendar(); } if (view.getId() == R.id.patient_detail_edit_birthdate) { mBirthDateDialog = DateDialogFragment.newInstance(calendar); mBirthDateDialog.setListener(this); mBirthDateDialog.show(getActivity().getSupportFragmentManager(), BIRTHDATE_DIALOG_ID); } if (view.getId() == R.id.patient_detail_edit_deathdate) { mDeathDateDialog = DateDialogFragment.newInstance(calendar); mDeathDateDialog.setListener(this); mDeathDateDialog.show(getActivity().getSupportFragmentManager(), DEATHDATE_DIALOG_ID); } } /** * Callback for date dialog. */ @Override public void dateSet(Calendar calendar, String target) { if (target.equals(BIRTHDATE_DIALOG_ID)) { mBirthdateView.setText(Helper.dateToLocaleString(calendar.getTime(), getActivity())); } if (target.equals(DEATHDATE_DIALOG_ID)) { mDeathdateView.setText(Helper.dateToLocaleString(calendar.getTime(), getActivity())); } } /** * Inserts scanned tags. * * @param tag Tag */ public void setIdentifierByNFC(String tag) { mIdentifierView.setText(tag); } }