diff --git a/Calendula/build.gradle b/Calendula/build.gradle index ff66f8862..c6a81d2ad 100644 --- a/Calendula/build.gradle +++ b/Calendula/build.gradle @@ -26,7 +26,8 @@ apply plugin: 'kotlin-android' apply plugin: 'kotlin-android-extensions' apply plugin: 'kotlin-kapt' apply plugin: 'idea' - +// build config fields +apply from: 'config.gradle' repositories { @@ -76,8 +77,8 @@ android { defaultConfig { minSdkVersion 16 targetSdkVersion 25 - versionCode 33 - versionName "2.5.2" + versionCode 34 + versionName "2.5.3" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" applicationId "es.usc.citius.servando.calendula" multiDexEnabled true diff --git a/Calendula/src/main/java/es/usc/citius/servando/calendula/util/SettingsPropertiesKeys.java b/Calendula/config.gradle similarity index 75% rename from Calendula/src/main/java/es/usc/citius/servando/calendula/util/SettingsPropertiesKeys.java rename to Calendula/config.gradle index 5f39c74f8..de0d65bd7 100644 --- a/Calendula/src/main/java/es/usc/citius/servando/calendula/util/SettingsPropertiesKeys.java +++ b/Calendula/config.gradle @@ -16,14 +16,9 @@ * along with this software. If not, see . */ -package es.usc.citius.servando.calendula.util; - - -public class SettingsPropertiesKeys { - - public static final String DATABASE_LOCATION = "db.url"; - public static final String GENERATE_TEST_DATA = "test.generate.testdata"; - - private SettingsPropertiesKeys() { +android { + defaultConfig { + buildConfigField 'String', 'DB_DOWNLOAD_URL', '"http://tec.citius.usc.es/calendula/dbs/"' + buildConfigField 'boolean', 'TEST_GENERATE_TESTDATA', 'false' } -} +} \ No newline at end of file diff --git a/Calendula/proguard/proguard-jsoup.pro b/Calendula/proguard/proguard-jsoup.pro new file mode 100644 index 000000000..5de7877f9 --- /dev/null +++ b/Calendula/proguard/proguard-jsoup.pro @@ -0,0 +1 @@ +-keeppackagenames org.jsoup.nodes \ No newline at end of file diff --git a/Calendula/src/androidTest/java/es/usc/citius/servando/calendula/activities/MedicinesActivityEditTest.java b/Calendula/src/androidTest/java/es/usc/citius/servando/calendula/activities/MedicinesActivityEditTest.java index 098d8c1f2..dbcef7f24 100644 --- a/Calendula/src/androidTest/java/es/usc/citius/servando/calendula/activities/MedicinesActivityEditTest.java +++ b/Calendula/src/androidTest/java/es/usc/citius/servando/calendula/activities/MedicinesActivityEditTest.java @@ -25,6 +25,7 @@ import org.junit.Before; import org.junit.Test; +import es.usc.citius.servando.calendula.BuildConfig; import es.usc.citius.servando.calendula.CalendulaApp; import es.usc.citius.servando.calendula.R; import es.usc.citius.servando.calendula.database.DB; diff --git a/Calendula/src/main/AndroidManifest.xml b/Calendula/src/main/AndroidManifest.xml index b475ff2cf..280f86df6 100644 --- a/Calendula/src/main/AndroidManifest.xml +++ b/Calendula/src/main/AndroidManifest.xml @@ -21,7 +21,7 @@ - + @@ -81,7 +81,7 @@ android:name=".activities.MedicinesSearchActivity" android:label="@string/title_activity_medicines_search" android:screenOrientation="portrait" - android:windowSoftInputMode="adjustPan"/> + android:windowSoftInputMode="stateVisible"/> . -# -db.url=http://tec.citius.usc.es/calendula/dbs/ -# set to 'yes' to generate test data -test.generate.testdata=no \ No newline at end of file diff --git a/Calendula/src/main/java/es/usc/citius/servando/calendula/activities/MedicinesSearchActivity.java b/Calendula/src/main/java/es/usc/citius/servando/calendula/activities/MedicinesSearchActivity.java index 8b69e0f0b..5cb9678b4 100644 --- a/Calendula/src/main/java/es/usc/citius/servando/calendula/activities/MedicinesSearchActivity.java +++ b/Calendula/src/main/java/es/usc/citius/servando/calendula/activities/MedicinesSearchActivity.java @@ -185,6 +185,12 @@ public void handleDbInstalled(PersistenceEvents.DatabaseInstalledEvent event) { LogUtil.d(TAG, "handleDbInstalled() called with: event = [" + event + "]"); // enable barcode scan + refreshViews(); + + } + + private void refreshViews() { + // TODO: 23/02/18 the current DBVersionMgr should tell us if the DB can handle barcodes if (!PreferenceUtils.getString(PreferenceKeys.DRUGDB_CURRENT_DB, CalendulaApp.getContext().getString(R.string.database_none_id)) .equals(CalendulaApp.getContext().getString(R.string.database_none_id))) { runOnUiThread(new Runnable() { @@ -194,7 +200,6 @@ public void run() { } }); } - } @@ -268,6 +273,7 @@ public void afterTextChanged(Editable s) { final String search = getIntent().getStringExtra(EXTRA_SEARCH_TERM); if (search != null) { searchEditText.setText(search); + searchEditText.setSelection(search.length()); } searchList.setOnItemClickListener(new AdapterView.OnItemClickListener() { @@ -302,10 +308,8 @@ public boolean onTouch(View v, MotionEvent event) { if (!PreferenceUtils.getString(PreferenceKeys.DRUGDB_CURRENT_DB, CalendulaApp.getContext().getString(R.string.database_none_id)) .equals(CalendulaApp.getContext().getString(R.string.database_none_id))) { enableBarcodeScan(); - } else { - if (!PreferenceUtils.getBoolean(PreferenceKeys.MEDICINES_USE_PRESCRIPTIONS_SHOWN, false)) { - askForDatabase(); - } + } else if (!PreferenceUtils.getBoolean(PreferenceKeys.MEDICINES_USE_PRESCRIPTIONS_SHOWN, false)) { + askForDatabase(); } @@ -379,6 +383,7 @@ protected void addCustomMed() { protected void onResume() { super.onResume(); EventBus.getDefault().register(this); + refreshViews(); } @Override diff --git a/Calendula/src/main/java/es/usc/citius/servando/calendula/drugdb/download/DBVersionManager.java b/Calendula/src/main/java/es/usc/citius/servando/calendula/drugdb/download/DBVersionManager.java index d6dcb3d07..d62a2d591 100644 --- a/Calendula/src/main/java/es/usc/citius/servando/calendula/drugdb/download/DBVersionManager.java +++ b/Calendula/src/main/java/es/usc/citius/servando/calendula/drugdb/download/DBVersionManager.java @@ -33,14 +33,13 @@ import java.util.List; import java.util.Map; +import es.usc.citius.servando.calendula.BuildConfig; import es.usc.citius.servando.calendula.R; import es.usc.citius.servando.calendula.database.DatabaseHelper; import es.usc.citius.servando.calendula.util.HttpDownloadUtil; import es.usc.citius.servando.calendula.util.LogUtil; import es.usc.citius.servando.calendula.util.PreferenceKeys; import es.usc.citius.servando.calendula.util.PreferenceUtils; -import es.usc.citius.servando.calendula.util.SettingsProperties; -import es.usc.citius.servando.calendula.util.SettingsPropertiesKeys; public class DBVersionManager { @@ -56,7 +55,7 @@ public class DBVersionManager { * @return the newest working version */ public static String getLastDBVersion(String databaseID) { - final String downloadUrl = SettingsProperties.instance().get(SettingsPropertiesKeys.DATABASE_LOCATION); + final String downloadUrl = BuildConfig.DB_DOWNLOAD_URL; final String url = downloadUrl + VERSION_FILE; try { diff --git a/Calendula/src/main/java/es/usc/citius/servando/calendula/drugdb/download/DownloadDatabaseHelper.java b/Calendula/src/main/java/es/usc/citius/servando/calendula/drugdb/download/DownloadDatabaseHelper.java index 2ba802938..577bff05a 100644 --- a/Calendula/src/main/java/es/usc/citius/servando/calendula/drugdb/download/DownloadDatabaseHelper.java +++ b/Calendula/src/main/java/es/usc/citius/servando/calendula/drugdb/download/DownloadDatabaseHelper.java @@ -35,6 +35,7 @@ import java.io.File; import java.net.URI; +import es.usc.citius.servando.calendula.BuildConfig; import es.usc.citius.servando.calendula.R; import es.usc.citius.servando.calendula.drugdb.DBRegistry; import es.usc.citius.servando.calendula.drugdb.PrescriptionDBMgr; @@ -42,8 +43,6 @@ import es.usc.citius.servando.calendula.util.NetworkUtils; import es.usc.citius.servando.calendula.util.PreferenceKeys; import es.usc.citius.servando.calendula.util.PreferenceUtils; -import es.usc.citius.servando.calendula.util.SettingsProperties; -import es.usc.citius.servando.calendula.util.SettingsPropertiesKeys; public class DownloadDatabaseHelper { @@ -197,7 +196,7 @@ protected Boolean doInBackground(String... params) { final DownloadManager manager = (DownloadManager) ctx.getSystemService(Context.DOWNLOAD_SERVICE); - final String downloadUrl = SettingsProperties.instance().get(SettingsPropertiesKeys.DATABASE_LOCATION); + final String downloadUrl = BuildConfig.DB_DOWNLOAD_URL; final String dbName = mgr.id(); try {//get version diff --git a/Calendula/src/main/java/es/usc/citius/servando/calendula/fragments/ScheduleTimetableFragment.java b/Calendula/src/main/java/es/usc/citius/servando/calendula/fragments/ScheduleTimetableFragment.java index 69ba12b16..9aa8c158a 100644 --- a/Calendula/src/main/java/es/usc/citius/servando/calendula/fragments/ScheduleTimetableFragment.java +++ b/Calendula/src/main/java/es/usc/citius/servando/calendula/fragments/ScheduleTimetableFragment.java @@ -20,17 +20,21 @@ import android.app.AlertDialog; import android.app.DatePickerDialog; +import android.content.ContextWrapper; import android.content.DialogInterface; +import android.content.res.Resources; import android.graphics.Color; import android.graphics.Typeface; import android.graphics.drawable.GradientDrawable; import android.graphics.drawable.StateListDrawable; import android.os.Bundle; +import android.support.annotation.NonNull; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentManager; import android.text.Html; import android.text.Spanned; import android.text.format.Time; +import android.util.Log; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; @@ -66,6 +70,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; +import java.util.IllegalFormatConversionException; import java.util.List; import es.usc.citius.servando.calendula.R; @@ -204,7 +209,7 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container, setupScheduleSpinner(); setupDaySelectionListeners(rootView); - setupHourlyRepetitionLinsteners(); + setupHourlyRepetitionListeners(); setupStartEndDatePickers(rootView); setupForCurrentSchedule(rootView); setupCycleSpinner(); @@ -288,7 +293,7 @@ public void onTimeSet(RadialTimePickerDialogFragment dialog, int hour, int minut schedule.setStartTime(new LocalTime(hour, minute)); } - void setupHourlyRepetitionLinsteners() { + void setupHourlyRepetitionListeners() { hourlyIntervalEditText.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { @@ -320,6 +325,38 @@ public void onClick(View v) { void setupStartEndDatePickers(View rootView) { + /* + * Needed to fix crashes on samsung 5.0 devices. + * + * See: https://stackoverflow.com/q/28618405/4243049 + */ + final ContextWrapper datePickerContext = new ContextWrapper(getActivity()) { + + private Resources wrappedResources; + + @Override + public Resources getResources() { + Resources r = super.getResources(); + if(wrappedResources == null) { + wrappedResources = new Resources(r.getAssets(), r.getDisplayMetrics(), r.getConfiguration()) { + @NonNull + @Override + public String getString(int id, Object... formatArgs) throws NotFoundException { + try { + return super.getString(id, formatArgs); + } catch (IllegalFormatConversionException e) { + Log.w(TAG, "Trying to fix resource exception", e); + String template = super.getString(id); + template = template.replaceAll("%" + e.getConversion(), "%s"); + return String.format(getConfiguration().locale, template, formatArgs); + } + } + }; + } + return wrappedResources; + } + }; + if (schedule.start() == null) { schedule.setStart(LocalDate.now()); } @@ -331,7 +368,7 @@ void setupStartEndDatePickers(View rootView) { public void onClick(View v) { DatePickerDialog dpd = - new DatePickerDialog(getActivity(), new DatePickerDialog.OnDateSetListener() { + new DatePickerDialog(datePickerContext, new DatePickerDialog.OnDateSetListener() { @Override public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) { @@ -353,7 +390,7 @@ public void onClick(View v) { schedule.end() != null ? schedule.end() : scheduleStart.plusMonths(3); DatePickerDialog dpd = - new DatePickerDialog(getActivity(), new DatePickerDialog.OnDateSetListener() { + new DatePickerDialog(datePickerContext, new DatePickerDialog.OnDateSetListener() { @Override public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) { @@ -370,7 +407,7 @@ public void onDateSet(DatePicker view, int year, int monthOfYear, @Override public boolean onLongClick(View v) { AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); - builder.setMessage("Do you want this schedule to continue indefinitely?") + builder.setMessage(R.string.schedule_continue_indefinitely) .setCancelable(true) .setPositiveButton(getString(R.string.dialog_yes_option), new DialogInterface.OnClickListener() { diff --git a/Calendula/src/main/java/es/usc/citius/servando/calendula/modules/modules/BaseModule.java b/Calendula/src/main/java/es/usc/citius/servando/calendula/modules/modules/BaseModule.java index 90b5c30b5..107220828 100644 --- a/Calendula/src/main/java/es/usc/citius/servando/calendula/modules/modules/BaseModule.java +++ b/Calendula/src/main/java/es/usc/citius/servando/calendula/modules/modules/BaseModule.java @@ -48,7 +48,6 @@ import es.usc.citius.servando.calendula.util.PreferenceKeys; import es.usc.citius.servando.calendula.util.PreferenceUtils; import es.usc.citius.servando.calendula.util.PresentationsTypeface; -import es.usc.citius.servando.calendula.util.SettingsProperties; public class BaseModule extends CalendulaModule { @@ -97,13 +96,6 @@ public void setupUpdateDailyAgendaAlarm(Context ctx) { protected void onApplicationStartup(Context ctx) { PreferenceUtils.init(ctx); - - try { - SettingsProperties.init(ctx); - } catch (IOException e) { - LogUtil.e(TAG, "onApplicationStartup: An exception happened when loading settings file"); - } - // initialize SQLite engine initializeDatabase(ctx); diff --git a/Calendula/src/main/java/es/usc/citius/servando/calendula/modules/modules/TestDataModule.java b/Calendula/src/main/java/es/usc/citius/servando/calendula/modules/modules/TestDataModule.java index 54f74101b..a1002443d 100644 --- a/Calendula/src/main/java/es/usc/citius/servando/calendula/modules/modules/TestDataModule.java +++ b/Calendula/src/main/java/es/usc/citius/servando/calendula/modules/modules/TestDataModule.java @@ -33,6 +33,7 @@ import java.util.Map; import java.util.concurrent.Callable; +import es.usc.citius.servando.calendula.BuildConfig; import es.usc.citius.servando.calendula.activities.PatientDetailActivity; import es.usc.citius.servando.calendula.database.DB; import es.usc.citius.servando.calendula.modules.CalendulaModule; @@ -47,8 +48,6 @@ import es.usc.citius.servando.calendula.util.LogUtil; import es.usc.citius.servando.calendula.util.PreferenceKeys; import es.usc.citius.servando.calendula.util.PreferenceUtils; -import es.usc.citius.servando.calendula.util.SettingsProperties; -import es.usc.citius.servando.calendula.util.SettingsPropertiesKeys; public class TestDataModule extends CalendulaModule { @@ -73,7 +72,7 @@ protected void onApplicationStartup(final Context ctx) { final boolean testDataGenerated = PreferenceUtils.getBoolean(PreferenceKeys.TEST_DATA_GENERATED, false); if (testDataGenerated) { LogUtil.d(TAG, "onApplicationStartup: Test data already generated, skipping"); - } else if (!SettingsProperties.instance().get(SettingsPropertiesKeys.GENERATE_TEST_DATA).equals("yes")) { + } else if (!BuildConfig.TEST_GENERATE_TESTDATA) { LogUtil.d(TAG, "onApplicationStartup: GENERATE_TEST_DATA is not set"); } else { LogUtil.d(TAG, "onApplicationStartup: Generating test data"); diff --git a/Calendula/src/main/java/es/usc/citius/servando/calendula/mvp/BaseActivityView.kt b/Calendula/src/main/java/es/usc/citius/servando/calendula/mvp/BaseActivityView.kt new file mode 100644 index 000000000..106cfacf9 --- /dev/null +++ b/Calendula/src/main/java/es/usc/citius/servando/calendula/mvp/BaseActivityView.kt @@ -0,0 +1,39 @@ +/* + * Calendula - An assistant for personal medication management. + * Copyright (C) 2016 CITIUS - USC + * + * Calendula 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 software. If not, see . + */ + +package es.usc.citius.servando.calendula.mvp + +import android.os.Bundle +import es.usc.citius.servando.calendula.CalendulaActivity + + +abstract class BaseActivityView> : CalendulaActivity(), IView { + + abstract val presenter: P + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + @Suppress("UNCHECKED_CAST") + presenter.attachView(this as V) + } + + override fun onDestroy() { + presenter.detachView() + super.onDestroy() + } +} \ No newline at end of file diff --git a/Calendula/src/main/java/es/usc/citius/servando/calendula/mvp/BasePresenter.kt b/Calendula/src/main/java/es/usc/citius/servando/calendula/mvp/BasePresenter.kt index 7f87a0f59..a83c35e93 100644 --- a/Calendula/src/main/java/es/usc/citius/servando/calendula/mvp/BasePresenter.kt +++ b/Calendula/src/main/java/es/usc/citius/servando/calendula/mvp/BasePresenter.kt @@ -1,6 +1,6 @@ /* * Calendula - An assistant for personal medication management. - * Copyright (C) 2014-2018 CiTIUS - University of Santiago de Compostela + * Copyright (C) 2016 CITIUS - USC * * Calendula is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,11 +18,37 @@ package es.usc.citius.servando.calendula.mvp -interface BasePresenter { +import kotlin.reflect.KProperty - /** - * Initialization logic for the view. Load default values, etc... Android views should call this on onResume(). - */ - fun start() +abstract class BasePresenter : + IPresenter { + + private var delegate = ViewDelegate() + var view: V by delegate + + override fun attachView(view: V) { + this.view = view + } + + override fun detachView() { + this.delegate.view = null + } + + + fun isAttachedToView(): Boolean = this.delegate.view != null + + + private class ViewDelegate { + + var view: V? = null + + operator fun getValue(pres: BasePresenter, prop: KProperty<*>): V { + return view ?: throw IllegalStateException("View cannot be null") + } + + operator fun setValue(pres: BasePresenter, prop: KProperty<*>, view: V) { + this.view = view + } + } } \ No newline at end of file diff --git a/Calendula/src/main/java/es/usc/citius/servando/calendula/mvp/IPresenter.kt b/Calendula/src/main/java/es/usc/citius/servando/calendula/mvp/IPresenter.kt new file mode 100644 index 000000000..e70c07261 --- /dev/null +++ b/Calendula/src/main/java/es/usc/citius/servando/calendula/mvp/IPresenter.kt @@ -0,0 +1,43 @@ +/* + * Calendula - An assistant for personal medication management. + * Copyright (C) 2014-2018 CiTIUS - University of Santiago de Compostela + * + * Calendula 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 software. If not, see . + */ + +package es.usc.citius.servando.calendula.mvp + +/** + * Interface for MVP presenters + */ + +interface IPresenter { + /** + * Initialization logic for the view. Load default values, etc... Android views should call this on onResume(). + */ + fun start() + + /** + * Notify view attachment to the presenter + */ + fun attachView(view: V) + + /** + * Notify view detachment to the presenter + */ + fun detachView() + +} + + diff --git a/Calendula/src/main/java/es/usc/citius/servando/calendula/mvp/BaseView.kt b/Calendula/src/main/java/es/usc/citius/servando/calendula/mvp/IView.kt similarity index 93% rename from Calendula/src/main/java/es/usc/citius/servando/calendula/mvp/BaseView.kt rename to Calendula/src/main/java/es/usc/citius/servando/calendula/mvp/IView.kt index f7aef4df9..ed731074b 100644 --- a/Calendula/src/main/java/es/usc/citius/servando/calendula/mvp/BaseView.kt +++ b/Calendula/src/main/java/es/usc/citius/servando/calendula/mvp/IView.kt @@ -18,6 +18,8 @@ package es.usc.citius.servando.calendula.mvp -interface BaseView { - var presenter: T -} \ No newline at end of file + +/** + * Interface for MVP views + */ +interface IView \ No newline at end of file diff --git a/Calendula/src/main/java/es/usc/citius/servando/calendula/mvp/StatefulBaseActivityView.kt b/Calendula/src/main/java/es/usc/citius/servando/calendula/mvp/StatefulBaseActivityView.kt new file mode 100644 index 000000000..4262eb4f3 --- /dev/null +++ b/Calendula/src/main/java/es/usc/citius/servando/calendula/mvp/StatefulBaseActivityView.kt @@ -0,0 +1,40 @@ +/* + * Calendula - An assistant for personal medication management. + * Copyright (C) 2016 CITIUS - USC + * + * Calendula 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 software. If not, see . + */ + +package es.usc.citius.servando.calendula.mvp + +import android.os.Bundle + +abstract class StatefulBaseActivityView> : + BaseActivityView() { + + companion object { + private const val SAVED_STATE_KEY = "STATEFUL_BASE_ACTIVITY_VIEW_STATE_BUNDLE" + } + + override fun onSaveInstanceState(outState: Bundle?) { + outState?.putParcelable(SAVED_STATE_KEY, presenter.getState()) + super.onSaveInstanceState(outState) + } + + override fun onRestoreInstanceState(savedState: Bundle?) { + super.onRestoreInstanceState(savedState) + savedState?.let { presenter.setState(it.getParcelable(SAVED_STATE_KEY)) } + } + +} \ No newline at end of file diff --git a/Calendula/src/main/java/es/usc/citius/servando/calendula/mvp/StatefulPresenter.kt b/Calendula/src/main/java/es/usc/citius/servando/calendula/mvp/StatefulPresenter.kt new file mode 100644 index 000000000..75d0f43ae --- /dev/null +++ b/Calendula/src/main/java/es/usc/citius/servando/calendula/mvp/StatefulPresenter.kt @@ -0,0 +1,26 @@ +/* + * Calendula - An assistant for personal medication management. + * Copyright (C) 2016 CITIUS - USC + * + * Calendula 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 software. If not, see . + */ + +package es.usc.citius.servando.calendula.mvp + +import android.os.Parcelable + +interface StatefulPresenter : IPresenter { + fun getState(): Parcelable + fun setState(state: Parcelable) +} \ No newline at end of file diff --git a/Calendula/src/main/java/es/usc/citius/servando/calendula/pinlock/PinLockActivity.java b/Calendula/src/main/java/es/usc/citius/servando/calendula/pinlock/PinLockActivity.java index 54468ec78..5cb3a24d6 100644 --- a/Calendula/src/main/java/es/usc/citius/servando/calendula/pinlock/PinLockActivity.java +++ b/Calendula/src/main/java/es/usc/citius/servando/calendula/pinlock/PinLockActivity.java @@ -19,7 +19,6 @@ package es.usc.citius.servando.calendula.pinlock; import android.app.Activity; -import android.content.Context; import android.content.Intent; import android.graphics.Color; import android.hardware.fingerprint.FingerprintManager; @@ -122,7 +121,11 @@ public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) @OnClick(R.id.use_fingerprint_btn) @RequiresApi(Build.VERSION_CODES.M) void launchFingerprintAuth() { + showFingerprintDialog(); + fpHelper.startAuthentication(new LoginFPCallbackAdapter(this, fingerprintDialog)); + } + private void showFingerprintDialog() { fingerprintDialog = new MaterialDialog.Builder(this) .icon(IconUtils.icon(this, CommunityMaterial.Icon.cmd_fingerprint, R.color.android_blue_dark, 48)) .title(R.string.fingerprint_unlock_dialog_title) @@ -137,47 +140,6 @@ public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) }) .build(); fingerprintDialog.show(); - - final Context ctx = getApplicationContext(); - fpHelper.startAuthentication(new FingerprintHelper.FingerprintCallbackAdapter() { - @Override - public void onAuthenticationFailed() { - if (fingerprintDialog != null) { - fingerprintDialog.setTitle(R.string.fingerprint_unlock_dialog_failed_title); - fingerprintDialog.setContent(R.string.fingerprint_unlock_dialog_failed_message); - fingerprintDialog.setIcon(IconUtils.icon(PinLockActivity.this, GoogleMaterial.Icon.gmd_alert_circle, R.color.android_red, 48)); - } else { - Toast.makeText(ctx, R.string.fingerprint_unlock_dialog_failed_title, Toast.LENGTH_SHORT).show(); - } - } - - @Override - public void onAuthenticationSucceeded(FingerprintManager.AuthenticationResult result) { - if (fingerprintDialog != null) { - fingerprintDialog.setActionButton(DialogAction.NEGATIVE, null); - fingerprintDialog.setTitle(R.string.fingerprint_unlock_dialog_successful_title); - fingerprintDialog.setContent(R.string.fingerprint_unlock_dialog_successful_message); - fingerprintDialog.setIcon(IconUtils.icon(PinLockActivity.this, GoogleMaterial.Icon.gmd_check_circle, R.color.android_green, 48)); - } - UnlockStateManager.getInstance().unlock(); - Intent i = new Intent(PinLockActivity.this, StartActivity.class); - startActivity(i); - finish(); - } - }); - } - - @RequiresApi(api = Build.VERSION_CODES.M) - @Override - protected void onDestroy() { - super.onDestroy(); - if (fpHelper != null) { - fpHelper.stop(); - fpHelper = null; - } - if (fingerprintDialog != null) { - fingerprintDialog.dismiss(); - } } @Override @@ -244,13 +206,22 @@ protected void onPause() { super.onPause(); } + @Override + protected void onResume() { + super.onResume(); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + if (fpHelper != null && fingerprintDialog != null && fingerprintDialog.isShowing()) { + fpHelper.startAuthentication(new LoginFPCallbackAdapter(this, fingerprintDialog)); + } + } + } + @RequiresApi(Build.VERSION_CODES.M) private void setupFingerprintAuth() { fpHelper = new FingerprintHelper(this); - if (fpHelper.fingerPrintEnabled() && fpHelper.canUseFingerPrint()) { useFingerprintButton.setVisibility(View.VISIBLE); - launchFingerprintAuth(); + showFingerprintDialog(); } } @@ -342,4 +313,41 @@ public void run() { } } + + + private static class LoginFPCallbackAdapter implements FingerprintHelper.FingerprintCallbackAdapter { + + private Activity activity; + private MaterialDialog fingerprintDialog; + + LoginFPCallbackAdapter(Activity activity, MaterialDialog fingerprintDialog) { + this.activity = activity; + this.fingerprintDialog = fingerprintDialog; + } + + @Override + public void onAuthenticationFailed() { + if (fingerprintDialog != null) { + fingerprintDialog.setTitle(R.string.fingerprint_unlock_dialog_failed_title); + fingerprintDialog.setContent(R.string.fingerprint_unlock_dialog_failed_message); + fingerprintDialog.setIcon(IconUtils.icon(activity, GoogleMaterial.Icon.gmd_alert_circle, R.color.android_red, 48)); + } else { + Toast.makeText(activity, R.string.fingerprint_unlock_dialog_failed_title, Toast.LENGTH_SHORT).show(); + } + } + + @Override + public void onAuthenticationSucceeded(FingerprintManager.AuthenticationResult result) { + if (fingerprintDialog != null) { + fingerprintDialog.setActionButton(DialogAction.NEGATIVE, null); + fingerprintDialog.setTitle(R.string.fingerprint_unlock_dialog_successful_title); + fingerprintDialog.setContent(R.string.fingerprint_unlock_dialog_successful_message); + fingerprintDialog.setIcon(IconUtils.icon(activity, GoogleMaterial.Icon.gmd_check_circle, R.color.android_green, 48)); + } + UnlockStateManager.getInstance().unlock(); + Intent i = new Intent(activity, StartActivity.class); + activity.startActivity(i); + activity.finish(); + } + } } diff --git a/Calendula/src/main/java/es/usc/citius/servando/calendula/pinlock/fingerprint/FingerprintHelper.java b/Calendula/src/main/java/es/usc/citius/servando/calendula/pinlock/fingerprint/FingerprintHelper.java index e3f98f8ea..a183be4dd 100644 --- a/Calendula/src/main/java/es/usc/citius/servando/calendula/pinlock/fingerprint/FingerprintHelper.java +++ b/Calendula/src/main/java/es/usc/citius/servando/calendula/pinlock/fingerprint/FingerprintHelper.java @@ -75,11 +75,14 @@ public class FingerprintHelper { public FingerprintHelper(Context context) { this.context = context.getApplicationContext(); keyguardManager = (KeyguardManager) this.context.getSystemService(Context.KEYGUARD_SERVICE); - fingerprintManager = (FingerprintManager) this.context.getSystemService(Context.FINGERPRINT_SERVICE); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + fingerprintManager = (FingerprintManager) this.context.getSystemService(Context.FINGERPRINT_SERVICE); + } } @RequiresApi(api = Build.VERSION_CODES.M) public void startAuthentication(FingerprintCallbackAdapter adapter) { + LogUtil.d(TAG, "startAuthentication() called with: adapter = [" + adapter + "]"); if (!canUseFingerPrint()) { LogUtil.e(TAG, "Cannot use fingerprint on this device"); throw new IllegalStateException("Can't use fingerprint on this device!"); @@ -94,6 +97,7 @@ public void startAuthentication(FingerprintCallbackAdapter adapter) { @RequiresApi(api = Build.VERSION_CODES.M) public void stop() { + LogUtil.d(TAG, "stop() called"); if (handler != null) { handler.stopAuth(); handler = null; @@ -110,12 +114,14 @@ public boolean hasPermissions() { return true; } - @RequiresApi(api = Build.VERSION_CODES.M) public boolean canUseFingerPrint() { - return hasPermissions() && checkKeyguard() && fingerprintManager.hasEnrolledFingerprints(); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + return hasPermissions() && checkKeyguard() && fingerprintManager.hasEnrolledFingerprints(); + } else { + return false; + } } - @RequiresApi(api = Build.VERSION_CODES.M) public boolean fingerPrintEnabled() { return PreferenceUtils.getBoolean(PreferenceKeys.FINGERPRINT_ENABLED, false); } @@ -203,7 +209,7 @@ public FingerprintHandler(Context context, FingerprintCallbackAdapter adapter) { } public void startAuth(FingerprintManager manager, FingerprintManager.CryptoObject cryptoObject) { - + LogUtil.d(TAG, "startAuth() called with: manager = [" + manager + "], cryptoObject = [" + cryptoObject + "]"); cancellationSignal = new CancellationSignal(); if (ActivityCompat.checkSelfPermission(appContext, Manifest.permission.USE_FINGERPRINT) != PackageManager.PERMISSION_GRANTED) { @@ -213,6 +219,7 @@ public void startAuth(FingerprintManager manager, FingerprintManager.CryptoObjec } public void stopAuth() { + LogUtil.d(TAG, "stopAuth() called"); if (cancellationSignal != null && !cancellationSignal.isCanceled()) { cancellationSignal.cancel(); } @@ -220,11 +227,13 @@ public void stopAuth() { @Override public void onAuthenticationError(int errMsgId, CharSequence errString) { + LogUtil.w(TAG, "onAuthenticationError() called with: errMsgId = [" + errMsgId + "], errString = [" + errString + "]"); Toast.makeText(appContext, errString, Toast.LENGTH_LONG).show(); } @Override public void onAuthenticationHelp(int helpMsgId, CharSequence helpString) { + LogUtil.d(TAG, "onAuthenticationHelp() called with: helpMsgId = [" + helpMsgId + "], helpString = [" + helpString + "]"); Toast.makeText(appContext, helpString, Toast.LENGTH_LONG).show(); } diff --git a/Calendula/src/main/java/es/usc/citius/servando/calendula/scheduling/AlarmScheduler.java b/Calendula/src/main/java/es/usc/citius/servando/calendula/scheduling/AlarmScheduler.java index d27565336..830db9852 100644 --- a/Calendula/src/main/java/es/usc/citius/servando/calendula/scheduling/AlarmScheduler.java +++ b/Calendula/src/main/java/es/usc/citius/servando/calendula/scheduling/AlarmScheduler.java @@ -450,7 +450,9 @@ private void onHourlyScheduleLost(Schedule schedule, AlarmIntentParams params, C private void cancelIntake(Routine r, LocalDate date) { for (ScheduleItem scheduleItem : r.getScheduleItems()) { DailyScheduleItem ds = DB.dailyScheduleItems().findByScheduleItemAndDate(scheduleItem, date); - if (ds.getTimeTaken() == null) { + if (ds == null) { + LogUtil.w(TAG, "cancelIntake: Schedule item not present in database"); + } else if (ds.getTimeTaken() == null) { LogUtil.d(TAG, "Cancelling schedule item"); ds.setTimeTaken(LocalTime.now()); ds.save(); diff --git a/Calendula/src/main/java/es/usc/citius/servando/calendula/settings/CalendulaPrefsFragment.kt b/Calendula/src/main/java/es/usc/citius/servando/calendula/settings/CalendulaPrefsFragment.kt index f7be0b72e..3155f468f 100644 --- a/Calendula/src/main/java/es/usc/citius/servando/calendula/settings/CalendulaPrefsFragment.kt +++ b/Calendula/src/main/java/es/usc/citius/servando/calendula/settings/CalendulaPrefsFragment.kt @@ -19,21 +19,46 @@ package es.usc.citius.servando.calendula.settings import android.content.SharedPreferences +import android.os.Bundle import android.support.annotation.StringRes import android.support.v7.preference.PreferenceFragmentCompat +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup import es.usc.citius.servando.calendula.CalendulaActivity +import es.usc.citius.servando.calendula.mvp.IPresenter +import es.usc.citius.servando.calendula.mvp.IView import es.usc.citius.servando.calendula.util.PreferenceUtils /** * A [PreferenceFragmentCompat] that registers and unregisters itself as a [SharedPreferences.OnSharedPreferenceChangeListener] */ -abstract class CalendulaPrefsFragment : PreferenceFragmentCompat(), - SharedPreferences.OnSharedPreferenceChangeListener { +abstract class CalendulaPrefsFragment> : + PreferenceFragmentCompat(), IView, SharedPreferences.OnSharedPreferenceChangeListener { + + abstract val presenter: P + + + override fun onCreateView( + inflater: LayoutInflater?, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + @Suppress("UNCHECKED_CAST") + presenter.attachView(this as V) + return super.onCreateView(inflater, container, savedInstanceState) + } + + override fun onDestroy() { + presenter.detachView() + super.onDestroy() + } override fun onResume() { super.onResume() PreferenceUtils.instance().preferences().registerOnSharedPreferenceChangeListener(this) (activity as CalendulaActivity).supportActionBar?.setTitle(fragmentTitle) + presenter.start() } override fun onPause() { diff --git a/Calendula/src/main/java/es/usc/citius/servando/calendula/settings/database/DatabasePrefsContract.kt b/Calendula/src/main/java/es/usc/citius/servando/calendula/settings/database/DatabasePrefsContract.kt index 2c14c4b49..940b8bb90 100644 --- a/Calendula/src/main/java/es/usc/citius/servando/calendula/settings/database/DatabasePrefsContract.kt +++ b/Calendula/src/main/java/es/usc/citius/servando/calendula/settings/database/DatabasePrefsContract.kt @@ -21,13 +21,13 @@ package es.usc.citius.servando.calendula.settings.database import android.content.Context import android.content.Intent import android.support.annotation.StringRes -import es.usc.citius.servando.calendula.mvp.BasePresenter -import es.usc.citius.servando.calendula.mvp.BaseView +import es.usc.citius.servando.calendula.mvp.IPresenter +import es.usc.citius.servando.calendula.mvp.IView interface DatabasePrefsContract { - interface View : BaseView { + interface View : IView { fun setDbList(dbIds: Array, dbDisplayNames: Array) fun showSelectedDb(dbId: String) fun resolveString(@StringRes stringRes: Int): String @@ -35,13 +35,16 @@ interface DatabasePrefsContract { fun showDatabaseUpdateNotAvailable() fun getIntent(): Intent fun openDatabaseSelection() + fun askForDownloadPermission(dbId: String) + fun hasDownloadPermission(): Boolean } - interface Presenter : BasePresenter { + interface Presenter : IPresenter { fun currentDbUpdated(dbId: String) fun selectNewDb(dbId: String): Boolean fun onDbDownloadChoiceResult(result: Boolean) fun checkDatabaseUpdate(ctx: Context) + fun onDownloadPermissionGranted(dbId: String) } } \ No newline at end of file diff --git a/Calendula/src/main/java/es/usc/citius/servando/calendula/settings/database/DatabasePrefsFragment.kt b/Calendula/src/main/java/es/usc/citius/servando/calendula/settings/database/DatabasePrefsFragment.kt index 3b96983a2..cd4435b3a 100644 --- a/Calendula/src/main/java/es/usc/citius/servando/calendula/settings/database/DatabasePrefsFragment.kt +++ b/Calendula/src/main/java/es/usc/citius/servando/calendula/settings/database/DatabasePrefsFragment.kt @@ -20,15 +20,19 @@ package es.usc.citius.servando.calendula.settings.database import android.content.Intent import android.content.SharedPreferences +import android.content.pm.PackageManager import android.os.Bundle import android.support.annotation.StringRes +import android.support.v4.app.ActivityCompat import android.support.v7.preference.ListPreference import android.support.v7.preference.Preference import android.widget.Toast +import es.usc.citius.servando.calendula.CalendulaActivity import es.usc.citius.servando.calendula.R import es.usc.citius.servando.calendula.drugdb.download.DownloadDatabaseHelper import es.usc.citius.servando.calendula.settings.CalendulaPrefsFragment import es.usc.citius.servando.calendula.util.LogUtil +import es.usc.citius.servando.calendula.util.PermissionUtils import es.usc.citius.servando.calendula.util.PreferenceKeys import es.usc.citius.servando.calendula.util.PreferenceUtils @@ -36,15 +40,24 @@ import es.usc.citius.servando.calendula.util.PreferenceUtils /** * Instantiated via reflection, don't delete! */ -class DatabasePrefsFragment : CalendulaPrefsFragment(), DatabasePrefsContract.View { +class DatabasePrefsFragment : + CalendulaPrefsFragment(), + DatabasePrefsContract.View { companion object { private const val TAG = "DatabasePrefsFragment" + private const val REQUEST_DL_PERMISSION = 938 } - override lateinit var presenter: DatabasePrefsContract.Presenter override val fragmentTitle: Int = R.string.pref_header_prescriptions - + override val presenter: DatabasePrefsContract.Presenter by lazy { + DatabasePrefsPresenter( + PreferenceUtils.getString( + PreferenceKeys.DRUGDB_CURRENT_DB, + getString(R.string.database_none_id) + ) + ) + } private val dbPref: ListPreference by lazy { findPreference(getString(R.string.prefkey_drugdb_current_db)) as ListPreference @@ -56,13 +69,6 @@ class DatabasePrefsFragment : CalendulaPrefsFragment(), DatabasePrefsContract.Vi private val noneId by lazy { getString(R.string.database_none_id) } private val settingUpId by lazy { getString(R.string.database_setting_up_id) } - - override fun onResume() { - super.onResume() - presenter.start() - } - - override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { LogUtil.d(TAG, "onCreatePreferences() called") addPreferencesFromResource(R.xml.pref_database) @@ -75,15 +81,9 @@ class DatabasePrefsFragment : CalendulaPrefsFragment(), DatabasePrefsContract.Vi presenter.checkDatabaseUpdate(context) true } - - DatabasePrefsPresenter( - this, PreferenceUtils.getString( - PreferenceKeys.DRUGDB_CURRENT_DB, - getString(R.string.database_none_id) - ) - ) } + /** * From [SharedPreferences.OnSharedPreferenceChangeListener] * @@ -134,6 +134,38 @@ class DatabasePrefsFragment : CalendulaPrefsFragment(), DatabasePrefsContract.Vi preferenceManager.showDialog(dbPref) } + override fun askForDownloadPermission(dbId: String) { + if (!hasDownloadPermission()) { + (activity as CalendulaActivity).requestPermission(object : + PermissionUtils.PermissionRequest { + override fun reqCode(): Int = REQUEST_DL_PERMISSION + + override fun permissions(): Array = + arrayOf(android.Manifest.permission.WRITE_EXTERNAL_STORAGE) + + override fun onPermissionGranted() { + LogUtil.d(TAG, "onPermissionGranted() called") + presenter.onDownloadPermissionGranted(dbId) + } + + override fun onPermissionDenied() { + LogUtil.d(TAG, "onPermissionDenied: permission denied") + } + }) + } else { + throw IllegalStateException("Permissions already granted!") + } + } + + override fun hasDownloadPermission(): Boolean { + val hasPermission = ActivityCompat.checkSelfPermission( + context, + android.Manifest.permission.WRITE_EXTERNAL_STORAGE + ) == PackageManager.PERMISSION_GRANTED + LogUtil.d(TAG, "hasDownloadPermission: result is $hasPermission") + return hasPermission + } + private fun refreshUi() { LogUtil.d(TAG, "refreshUi() called") diff --git a/Calendula/src/main/java/es/usc/citius/servando/calendula/settings/database/DatabasePrefsPresenter.kt b/Calendula/src/main/java/es/usc/citius/servando/calendula/settings/database/DatabasePrefsPresenter.kt index 12cf5bf1c..8f3673544 100644 --- a/Calendula/src/main/java/es/usc/citius/servando/calendula/settings/database/DatabasePrefsPresenter.kt +++ b/Calendula/src/main/java/es/usc/citius/servando/calendula/settings/database/DatabasePrefsPresenter.kt @@ -23,35 +23,35 @@ import android.os.AsyncTask import es.usc.citius.servando.calendula.R import es.usc.citius.servando.calendula.drugdb.DBRegistry import es.usc.citius.servando.calendula.jobs.CheckDatabaseUpdatesJob +import es.usc.citius.servando.calendula.mvp.BasePresenter import es.usc.citius.servando.calendula.settings.CalendulaSettingsActivity import es.usc.citius.servando.calendula.util.LogUtil import es.usc.citius.servando.calendula.util.PreferenceKeys import es.usc.citius.servando.calendula.util.PreferenceUtils class DatabasePrefsPresenter( - private val view: DatabasePrefsContract.View, private var currentDbId: String ) : - DatabasePrefsContract.Presenter { + DatabasePrefsContract.Presenter, BasePresenter() { companion object { private val TAG = "DatabasePrefsPresenter" } - private val noneId: String - private val settingUpId: String - private val noneDisplay: String + private lateinit var noneId: String + private lateinit var settingUpId: String + private lateinit var noneDisplay: String + private var selectIdTemp: String? = null - init { - view.presenter = this + override fun attachView(view: DatabasePrefsContract.View) { + super.attachView(view) noneDisplay = view.resolveString(R.string.database_none_display) noneId = view.resolveString(R.string.database_none_id) settingUpId = view.resolveString(R.string.database_setting_up_id) } - override fun start() { LogUtil.d(TAG, "start() called") val (entries, entryValues) = getActiveDbs() @@ -61,6 +61,7 @@ class DatabasePrefsPresenter( false )) { view.openDatabaseSelection() + view.getIntent().removeExtra(CalendulaSettingsActivity.EXTRA_SHOW_DB_DIALOG) } } @@ -91,9 +92,12 @@ class DatabasePrefsPresenter( LogUtil.d(TAG, "selectNewDb() called with dbId=$dbId") if (dbId != currentDbId) { // if there is no actual update just return true and skip checks - - if (dbId != noneId && noneId != settingUpId) { - view.showDatabaseDownloadChoice(dbId) + if (dbId != noneId && dbId != settingUpId) { + if (!view.hasDownloadPermission()) { + view.askForDownloadPermission(dbId) + } else { + view.showDatabaseDownloadChoice(dbId) + } return false } else if (dbId == noneId) { // if the db ID is "none", delete the current DB and let the pref update @@ -117,6 +121,11 @@ class DatabasePrefsPresenter( CheckDbUpdateTask(this).execute(ctx) } + + override fun onDownloadPermissionGranted(dbId: String) { + selectNewDb(dbId) + } + private fun notifyNoUpdate() { view.showDatabaseUpdateNotAvailable() } @@ -142,5 +151,4 @@ class DatabasePrefsPresenter( } - } \ No newline at end of file diff --git a/Calendula/src/main/java/es/usc/citius/servando/calendula/settings/notifications/NotificationPrefsContract.kt b/Calendula/src/main/java/es/usc/citius/servando/calendula/settings/notifications/NotificationPrefsContract.kt index f8bfeb39c..838cee664 100644 --- a/Calendula/src/main/java/es/usc/citius/servando/calendula/settings/notifications/NotificationPrefsContract.kt +++ b/Calendula/src/main/java/es/usc/citius/servando/calendula/settings/notifications/NotificationPrefsContract.kt @@ -20,19 +20,19 @@ package es.usc.citius.servando.calendula.settings.notifications import android.content.Intent import android.net.Uri -import es.usc.citius.servando.calendula.mvp.BasePresenter -import es.usc.citius.servando.calendula.mvp.BaseView +import es.usc.citius.servando.calendula.mvp.IPresenter +import es.usc.citius.servando.calendula.mvp.IView interface NotificationPrefsContract { - interface View : BaseView { + interface View : IView { fun hideStockPref() fun requestRingtone(reqCode: Int, ringtoneType: Int, currentValue: Uri?) fun setNotificationRingtoneText(text: String) fun setInsistentRingtoneText(text: String) } - interface Presenter : BasePresenter { + interface Presenter : IPresenter { fun onResult(reqCode: Int, result: Int, data: Intent?) fun selectNotificationRingtone() fun selectInsistentRingtone() diff --git a/Calendula/src/main/java/es/usc/citius/servando/calendula/settings/notifications/NotificationPrefsFragment.kt b/Calendula/src/main/java/es/usc/citius/servando/calendula/settings/notifications/NotificationPrefsFragment.kt index 9e116db4a..96356c79f 100644 --- a/Calendula/src/main/java/es/usc/citius/servando/calendula/settings/notifications/NotificationPrefsFragment.kt +++ b/Calendula/src/main/java/es/usc/citius/servando/calendula/settings/notifications/NotificationPrefsFragment.kt @@ -34,29 +34,27 @@ import es.usc.citius.servando.calendula.util.PreferenceKeys /** * Instantiated via reflection, don't delete! */ -class NotificationPrefsFragment : CalendulaPrefsFragment(), NotificationPrefsContract.View { +class NotificationPrefsFragment : + CalendulaPrefsFragment(), + NotificationPrefsContract.View { companion object { private const val TAG = "NotificationPrefsFragm" } - override lateinit var presenter: NotificationPrefsContract.Presenter override val fragmentTitle: Int = R.string.pref_header_notifications - + override val presenter: NotificationPrefsContract.Presenter by lazy { + NotificationPrefsPresenter( + RingtoneNameResolver(context) + ) + } private val notificationPref by lazy { findPreference(PreferenceKeys.SETTINGS_NOTIFICATION_TONE.key()) } private val insistentNotificationPref by lazy { findPreference(PreferenceKeys.SETTINGS_INSISTENT_NOTIFICATION_TONE.key()) } - override fun onResume() { - super.onResume() - presenter.start() - } - override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { LogUtil.d(TAG, "onCreatePreferences called") addPreferencesFromResource(R.xml.pref_notifications) - - NotificationPrefsPresenter(this, RingtoneNameResolver(context)) } override fun onPreferenceTreeClick(preference: Preference?): Boolean { diff --git a/Calendula/src/main/java/es/usc/citius/servando/calendula/settings/notifications/NotificationPrefsPresenter.kt b/Calendula/src/main/java/es/usc/citius/servando/calendula/settings/notifications/NotificationPrefsPresenter.kt index bbb9ee91f..16f01bf84 100644 --- a/Calendula/src/main/java/es/usc/citius/servando/calendula/settings/notifications/NotificationPrefsPresenter.kt +++ b/Calendula/src/main/java/es/usc/citius/servando/calendula/settings/notifications/NotificationPrefsPresenter.kt @@ -24,16 +24,16 @@ import android.net.Uri import android.provider.Settings import es.usc.citius.servando.calendula.modules.ModuleManager import es.usc.citius.servando.calendula.modules.modules.StockModule +import es.usc.citius.servando.calendula.mvp.BasePresenter import es.usc.citius.servando.calendula.util.LogUtil import es.usc.citius.servando.calendula.util.PreferenceKeys import es.usc.citius.servando.calendula.util.PreferenceUtils class NotificationPrefsPresenter( - val view: NotificationPrefsContract.View, private val ringtoneNameResolver: RingtoneNameResolver ) : - NotificationPrefsContract.Presenter { + NotificationPrefsContract.Presenter, BasePresenter() { companion object { private const val TAG = "NotifPrefsPresenter" @@ -41,9 +41,6 @@ class NotificationPrefsPresenter( const val REQ_CODE_INSIST_RINGTONE = 41 } - init { - view.presenter = this - } override fun start() { if (!ModuleManager.isEnabled(StockModule.ID)) { diff --git a/Calendula/src/main/java/es/usc/citius/servando/calendula/settings/privacy/PrivacyPrefsContract.kt b/Calendula/src/main/java/es/usc/citius/servando/calendula/settings/privacy/PrivacyPrefsContract.kt index 63ecdf87b..532b5ae5f 100644 --- a/Calendula/src/main/java/es/usc/citius/servando/calendula/settings/privacy/PrivacyPrefsContract.kt +++ b/Calendula/src/main/java/es/usc/citius/servando/calendula/settings/privacy/PrivacyPrefsContract.kt @@ -20,12 +20,12 @@ package es.usc.citius.servando.calendula.settings.privacy import android.content.Intent import android.support.annotation.StringRes -import es.usc.citius.servando.calendula.mvp.BasePresenter -import es.usc.citius.servando.calendula.mvp.BaseView +import es.usc.citius.servando.calendula.mvp.IPresenter +import es.usc.citius.servando.calendula.mvp.IView interface PrivacyPrefsContract { - interface View : BaseView { + interface View : IView { fun recordPIN() fun showPINOptions() @@ -36,7 +36,7 @@ interface PrivacyPrefsContract { } - interface Presenter : BasePresenter { + interface Presenter : IPresenter { fun onResult(request: Int, result: Int, data: Intent?) fun onClickPINPref() diff --git a/Calendula/src/main/java/es/usc/citius/servando/calendula/settings/privacy/PrivacyPrefsFragment.kt b/Calendula/src/main/java/es/usc/citius/servando/calendula/settings/privacy/PrivacyPrefsFragment.kt index bdb4cefaf..9e5f1370d 100644 --- a/Calendula/src/main/java/es/usc/citius/servando/calendula/settings/privacy/PrivacyPrefsFragment.kt +++ b/Calendula/src/main/java/es/usc/citius/servando/calendula/settings/privacy/PrivacyPrefsFragment.kt @@ -38,14 +38,21 @@ import es.usc.citius.servando.calendula.util.PreferenceKeys /** * Instantiated via reflection, don't delete! */ -class PrivacyPrefsFragment : CalendulaPrefsFragment(), PrivacyPrefsContract.View { +class PrivacyPrefsFragment : + CalendulaPrefsFragment(), + PrivacyPrefsContract.View { companion object { private const val TAG = "PrivacyPrefsFragment" } - override lateinit var presenter: PrivacyPrefsContract.Presenter + + override val presenter: PrivacyPrefsContract.Presenter by lazy { + PrivacyPrefsPresenter( + FingerprintHelper(context) + ) + } override val fragmentTitle: Int = R.string.pref_header_privacy @@ -53,12 +60,6 @@ class PrivacyPrefsFragment : CalendulaPrefsFragment(), PrivacyPrefsContract.View private val fingerprintPref: SwitchPreference by lazy { findPreference(PreferenceKeys.FINGERPRINT_ENABLED.key()) as SwitchPreference } - override fun onResume() { - super.onResume() - presenter.start() - } - - override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { LogUtil.d(TAG, "onCreatePreferences called") addPreferencesFromResource(R.xml.pref_privacy) @@ -68,7 +69,6 @@ class PrivacyPrefsFragment : CalendulaPrefsFragment(), PrivacyPrefsContract.View true } - PrivacyPrefsPresenter(this, FingerprintHelper(context)) } override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { diff --git a/Calendula/src/main/java/es/usc/citius/servando/calendula/settings/privacy/PrivacyPrefsPresenter.kt b/Calendula/src/main/java/es/usc/citius/servando/calendula/settings/privacy/PrivacyPrefsPresenter.kt index 513d73cfc..1c271205d 100644 --- a/Calendula/src/main/java/es/usc/citius/servando/calendula/settings/privacy/PrivacyPrefsPresenter.kt +++ b/Calendula/src/main/java/es/usc/citius/servando/calendula/settings/privacy/PrivacyPrefsPresenter.kt @@ -20,30 +20,26 @@ package es.usc.citius.servando.calendula.settings.privacy import android.app.Activity import android.content.Intent -import android.os.Build import es.usc.citius.servando.calendula.R +import es.usc.citius.servando.calendula.mvp.BasePresenter import es.usc.citius.servando.calendula.pinlock.PINManager import es.usc.citius.servando.calendula.pinlock.PinLockActivity import es.usc.citius.servando.calendula.pinlock.fingerprint.FingerprintHelper import es.usc.citius.servando.calendula.util.LogUtil -class PrivacyPrefsPresenter(val view: PrivacyPrefsContract.View, val fpHelper: FingerprintHelper) : - PrivacyPrefsContract.Presenter { +class PrivacyPrefsPresenter(val fpHelper: FingerprintHelper) : + PrivacyPrefsContract.Presenter, BasePresenter() { companion object { private const val TAG = "PrivacyPrefsPresenter" } - init { - view.presenter = this - } - override fun start() { if (PINManager.isPINSet()) { view.setPINPrefText(R.string.pref_summary_pin_lock_set) - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && fpHelper.canUseFingerPrint()) { + if (fpHelper.canUseFingerPrint()) { view.setFingerprintPrefEnabled(true) } } else { @@ -58,7 +54,7 @@ class PrivacyPrefsPresenter(val view: PrivacyPrefsContract.View, val fpHelper: F val pinManagerResult = PINManager.savePIN(pin) if (pinManagerResult) { view.setPINPrefText(R.string.pref_summary_pin_lock_set) - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && fpHelper.canUseFingerPrint()) { + if (fpHelper.canUseFingerPrint()) { view.setFingerprintPrefEnabled(true) view.showEnableFingerprintDialog() } diff --git a/Calendula/src/main/java/es/usc/citius/servando/calendula/util/SettingsProperties.java b/Calendula/src/main/java/es/usc/citius/servando/calendula/util/SettingsProperties.java deleted file mode 100644 index 4a3fb0a33..000000000 --- a/Calendula/src/main/java/es/usc/citius/servando/calendula/util/SettingsProperties.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Calendula - An assistant for personal medication management. - * Copyright (C) 2014-2018 CiTIUS - University of Santiago de Compostela - * - * Calendula 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 software. If not, see . - */ - -package es.usc.citius.servando.calendula.util; - -import android.content.Context; -import android.content.res.AssetManager; -import android.content.res.Resources; - -import java.io.IOException; -import java.io.InputStream; -import java.util.Properties; - -public class SettingsProperties { - - private static final String TAG = "SettingsProperties"; - - private static final String SETTINGS_FILE_NAME = "settings.properties"; - - private static SettingsProperties instance; - - private Properties properties; - - private SettingsProperties(final Context ctx) throws IOException { - Resources resources = ctx.getResources(); - AssetManager assetManager = resources.getAssets(); - - LogUtil.d(TAG, "Loading settings..."); - InputStream inputStream = null; - try { - inputStream = assetManager.open(SETTINGS_FILE_NAME); - properties = new Properties(); - properties.load(inputStream); - LogUtil.d(TAG, "SettingsProperties loaded successfully!" + properties.toString()); - } catch (IOException e) { - properties = new Properties(); - throw e; - } finally { - CloseableUtil.closeQuietly(inputStream); - } - } - - /** - * @return the instance - * @throws if {@link #init(Context)} hasn't been called yet - */ - public static SettingsProperties instance() throws IllegalStateException { - if (instance == null) - throw new IllegalStateException("SettingsProperties not initialized!"); - return instance; - } - - public synchronized static void init(Context ctx) throws IOException { - if (instance == null) - instance = new SettingsProperties(ctx); - } - - public String get(String key) { - return properties.getProperty(key); - } - - public String get(String key, String defaultValue) { - return properties.getProperty(key, defaultValue); - } - -} diff --git a/Calendula/src/main/res/layout/activity_medicines_search.xml b/Calendula/src/main/res/layout/activity_medicines_search.xml index 0d0c63027..008e61b9a 100644 --- a/Calendula/src/main/res/layout/activity_medicines_search.xml +++ b/Calendula/src/main/res/layout/activity_medicines_search.xml @@ -52,7 +52,6 @@ android:layout_toLeftOf="@+id/main_progress_bar" android:layout_toStartOf="@+id/main_progress_bar" android:background="@null" - android:capitalize="words" android:gravity="center_vertical" android:hint="@string/search_med_hint" android:imeOptions="actionDone" @@ -62,7 +61,10 @@ android:textColor="#fff" android:textColorHint="#ececec" android:textCursorDrawable="@null" - android:textSize="20dp"/> + android:textSize="20dp"> + + + "In weniger als 1 Woche" "In weniger als 2 Wochen" "In weniger als 3 Wochen" -"Nichts" +"Keine" "AEMPS Datenbank" "Agencia Española de Medicamentos y Productos Sanitarios Datenbank" "Einrichtung läuft..." diff --git a/Calendula/src/main/res/values-es/strings_translatable.xml b/Calendula/src/main/res/values-es/strings_translatable.xml index f15204c8f..ed873234c 100644 --- a/Calendula/src/main/res/values-es/strings_translatable.xml +++ b/Calendula/src/main/res/values-es/strings_translatable.xml @@ -350,7 +350,7 @@ Para este desarrollo hacemos uso de algunas librerías y utilidades de código a "La instalación ha fallado" "Algo ha ido mal durante la instalación de la base de datos" "¡Bienvenido a Calendula!" -"Tomar correctamente tu medicación no tiene por qué ser fácil, pero ahora al menos no será tan difícil +"Tomar correctamente tu medicación no es fácil, pero ahora al menos no será tan difícil. Por favor, ¡echa un vistazo a lo que tenemos para ti!" @@ -501,4 +501,5 @@ Quieres instalar la nueva base de datos ahora?" "Ninguno" "Añadir paciente" "Descargar y configurar" +"¿Quieres que esta pauta continúe indefinidamente?" \ No newline at end of file diff --git a/Calendula/src/main/res/values-gl-rES/strings_translatable.xml b/Calendula/src/main/res/values-gl-rES/strings_translatable.xml index 4b637504b..64f8f12a9 100644 --- a/Calendula/src/main/res/values-gl-rES/strings_translatable.xml +++ b/Calendula/src/main/res/values-gl-rES/strings_translatable.xml @@ -348,7 +348,7 @@ Para este desenvolvemento facemos uso dalgunhas librarías e utilidades de códi "Fallou a instalación" "Algo foi mal durante a instalación da base de datos" "Benvido a Calendula!" -"Tomar correctamente a túa medicación non tén por que ser fácil, pero agora polo menos non será tan difícil. +"Tomar correctamente a túa medicación non é fácil, pero agora polo menos non será tan difícil. Por favor, bota un ollo ao que temos para ti!" "Rutinas" @@ -502,4 +502,5 @@ Queres instalar a nova base de datos agora?" "Ningún" "Engadir paciente" "Descargar e instalar" +"Queres que esta pauta continúe indefinidamente?" \ No newline at end of file diff --git a/Calendula/src/main/res/values/strings_translatable.xml b/Calendula/src/main/res/values/strings_translatable.xml index 48e1525ab..8fed903d0 100644 --- a/Calendula/src/main/res/values/strings_translatable.xml +++ b/Calendula/src/main/res/values/strings_translatable.xml @@ -500,4 +500,5 @@ Do you want to install the new database now? "None" "Add patient" "Download and setup" +"Do you want this schedule to continue indefinitely?" \ No newline at end of file diff --git a/Calendula/src/test/java/es/usc/citius/servando/calendula/settings/database/DatabasePrefsPresenterTest.kt b/Calendula/src/test/java/es/usc/citius/servando/calendula/settings/database/DatabasePrefsPresenterTest.kt index ae0d1bae5..9499b5011 100644 --- a/Calendula/src/test/java/es/usc/citius/servando/calendula/settings/database/DatabasePrefsPresenterTest.kt +++ b/Calendula/src/test/java/es/usc/citius/servando/calendula/settings/database/DatabasePrefsPresenterTest.kt @@ -64,6 +64,7 @@ class DatabasePrefsPresenterTest { Mockito.`when`(dbPrefView.resolveString(Mockito.anyInt())).thenAnswer { RuntimeEnvironment.application.getString(it.arguments[0] as Int) } + Mockito.`when`(dbPrefView.hasDownloadPermission()).thenReturn(true) // init DB registry so there are DB handlers DBRegistry.init(RuntimeEnvironment.application) @@ -74,12 +75,8 @@ class DatabasePrefsPresenterTest { .commit() - dbPrefPresenter = DatabasePrefsPresenter(dbPrefView, INITIAL_DB_ID) - } - - @Test - fun isPresenterSet() { - verify(dbPrefView).presenter = dbPrefPresenter + dbPrefPresenter = DatabasePrefsPresenter(INITIAL_DB_ID) + dbPrefPresenter.attachView(dbPrefView) } @Test @@ -125,6 +122,18 @@ class DatabasePrefsPresenterTest { verify(dbPrefView).showDatabaseDownloadChoice(kotlinEq(NEW_DB_ID)) } + + @Test + fun selectDifferentDbNoPerms() { + Mockito.`when`(dbPrefView.hasDownloadPermission()).thenReturn(false) + + dbPrefPresenter.selectNewDb(NEW_DB_ID) + + verify(dbPrefView, never()).showDatabaseDownloadChoice(kotlinEq(NEW_DB_ID)) + verify(dbPrefView).askForDownloadPermission(kotlinEq(NEW_DB_ID)) + } + + @Test fun selectSameDb() { dbPrefPresenter.selectNewDb(INITIAL_DB_ID) diff --git a/Calendula/src/test/java/es/usc/citius/servando/calendula/settings/notifications/NotificationPrefsPresenterTest.kt b/Calendula/src/test/java/es/usc/citius/servando/calendula/settings/notifications/NotificationPrefsPresenterTest.kt index 73a9be502..dfacc3950 100644 --- a/Calendula/src/test/java/es/usc/citius/servando/calendula/settings/notifications/NotificationPrefsPresenterTest.kt +++ b/Calendula/src/test/java/es/usc/citius/servando/calendula/settings/notifications/NotificationPrefsPresenterTest.kt @@ -70,14 +70,10 @@ class NotificationPrefsPresenterTest { ).commit() presenter = NotificationPrefsPresenter( - view, resolver ) - } - @Test - fun isPresenterSet() { - Mockito.verify(view).presenter = presenter + presenter.attachView(view) } @Test diff --git a/Calendula/src/test/java/es/usc/citius/servando/calendula/settings/privacy/PrivacyPrefsPresenterTest.kt b/Calendula/src/test/java/es/usc/citius/servando/calendula/settings/privacy/PrivacyPrefsPresenterTest.kt index d14a5a564..25fb3d0c0 100644 --- a/Calendula/src/test/java/es/usc/citius/servando/calendula/settings/privacy/PrivacyPrefsPresenterTest.kt +++ b/Calendula/src/test/java/es/usc/citius/servando/calendula/settings/privacy/PrivacyPrefsPresenterTest.kt @@ -71,12 +71,8 @@ class PrivacyPrefsPresenterTest { .commit() - presenter = PrivacyPrefsPresenter(view, fpHelper) - } - - @Test - fun isPresenterSet() { - Mockito.verify(view).presenter = presenter + presenter = PrivacyPrefsPresenter(fpHelper) + presenter.attachView(view) } @Test diff --git a/Calendula/src/test/java/es/usc/citius/servando/calendula/util/stock/StockCalculatorWithEndTest.kt b/Calendula/src/test/java/es/usc/citius/servando/calendula/util/stock/StockCalculatorWithEndTest.kt index dc004fa0c..a0e10ab28 100644 --- a/Calendula/src/test/java/es/usc/citius/servando/calendula/util/stock/StockCalculatorWithEndTest.kt +++ b/Calendula/src/test/java/es/usc/citius/servando/calendula/util/stock/StockCalculatorWithEndTest.kt @@ -19,8 +19,6 @@ package es.usc.citius.servando.calendula.util.stock import es.usc.citius.servando.calendula.kotlinAny -import es.usc.citius.servando.calendula.util.stock.StockCalculator -import es.usc.citius.servando.calendula.util.stock.StockForDayProvider import org.joda.time.DateTime import org.junit.Assert import org.junit.Before @@ -47,6 +45,7 @@ class StockCalculatorWithEndTest( arrayOf(1F, 1F, 1), arrayOf(1F, 1.1F, 0), arrayOf(1F, 2F, 0), + arrayOf(29F, 3F, 9), arrayOf(3F, 1.5F, 2), arrayOf(3F, 2.5F, 1), arrayOf(7F, 1F, 7), diff --git a/assets/screenshots/v2.5-en/1.png b/assets/screenshots/v2.5-en/1.png new file mode 100644 index 000000000..35dd93f7c Binary files /dev/null and b/assets/screenshots/v2.5-en/1.png differ diff --git a/assets/screenshots/v2.5-en/2.png b/assets/screenshots/v2.5-en/2.png new file mode 100644 index 000000000..1f83cb42c Binary files /dev/null and b/assets/screenshots/v2.5-en/2.png differ diff --git a/assets/screenshots/v2.5-en/3.png b/assets/screenshots/v2.5-en/3.png new file mode 100644 index 000000000..b0ffc2a08 Binary files /dev/null and b/assets/screenshots/v2.5-en/3.png differ diff --git a/assets/screenshots/v2.5-en/4.png b/assets/screenshots/v2.5-en/4.png new file mode 100644 index 000000000..51be247c9 Binary files /dev/null and b/assets/screenshots/v2.5-en/4.png differ diff --git a/assets/screenshots/v2.5-en/5.png b/assets/screenshots/v2.5-en/5.png new file mode 100644 index 000000000..a64c03bcb Binary files /dev/null and b/assets/screenshots/v2.5-en/5.png differ diff --git a/assets/screenshots/v2.5-en/6.png b/assets/screenshots/v2.5-en/6.png new file mode 100644 index 000000000..131364c5d Binary files /dev/null and b/assets/screenshots/v2.5-en/6.png differ diff --git a/assets/screenshots/v2.5-en/7.png b/assets/screenshots/v2.5-en/7.png new file mode 100644 index 000000000..97dae2f78 Binary files /dev/null and b/assets/screenshots/v2.5-en/7.png differ diff --git a/assets/screenshots/v2.5-en/8.png b/assets/screenshots/v2.5-en/8.png new file mode 100644 index 000000000..30dc844b2 Binary files /dev/null and b/assets/screenshots/v2.5-en/8.png differ diff --git a/metadata/de/full_description.txt b/metadata/de/full_description.txt new file mode 100644 index 000000000..0783e772d --- /dev/null +++ b/metadata/de/full_description.txt @@ -0,0 +1,31 @@ +Calendula ist der Assistent für Ihr persönliches Medizin-Management und wird Ihnen helfen, sich an Ihre Rezepte und Einnahmepläne zu halten. Sie müssen sich nicht mehr etliche Wecker auf dem Smartphone stellen oder Angst haben die Einnahme eines Medikaments zu vergessen. Stellen Sie sich einfach Ihren Einnahmeplan zusammen und lassen Sie Calendula die Arbeit erledigen. + +--- + +Calendula bietet: +○ Ein hübsches und benutzerfreundliches Design +○ Individualisierbare Benachrichtigungen und Erinnerungen für Medikamente +○ Flexible Einnahmepläne mit speziellen Optionen, etwa Pausezeiten für die Verhütungspille +○ Medikamentensuche und Packungsbeilagen mit Daten von der spanischen "Agencia Española de Medicamentos y Productos Sanitarios" (http://www.aemps.gob.es) +○ Kontrolle über die eingenommenen Medikamente +○ Unterstützung für mehrere Patienten + +Besuchen Sie unsere Webseite für weitere Informationen: https://tec.citius.usc.es/calendula/ + +--- + +App-Berechtigungen: + +Calendula benötigt keine vorherige Registrierung und sammelt auch keine persönlichen Daten. Wenn nötig fordert Calendula folgende Berechtigungen auf Ihrem Gerät an: + +○ Speicher: Wird benötigt um auf gespeicherte Benachrichtigungstöne für Ihre Erinnerungen zuzugreifen und um ggf. eine Medizindatenbank zu speichern. +○ Kamera: Es ist möglich Medikamente durch scannen eines Barcodes hinzuzufügen. Dazu wird die Kamera benötigt. +○ Internet: Diese Berechtigung wird nicht explizit angefordert und ist nur dazu nötig, ggf. eine Medizindatenbank herunterzuladen. Ihre persönlichen Medizindaten werden niemals Ihr Gerät verlassen. + +--- + +Open Source: +Calendula ist ein Open Source Projekt. Wenn Sie Ideen haben oder am Projekt mitarbeiten möchten, können Sie direkt durch unsere Webseite (https://tec.citius.usc.es/calendula/) oder auf Github (https://github.com/citiususc/calendula) mit uns in Kontakt treten. Wir freuen uns über jede Mithilfe oder Anregung. + +Vielen Dank, +das Calendula-Team diff --git a/metadata/de/short_description.txt b/metadata/de/short_description.txt new file mode 100644 index 000000000..400f2aff0 --- /dev/null +++ b/metadata/de/short_description.txt @@ -0,0 +1 @@ +Medizin-Management leicht gemacht diff --git a/metadata/en/full_description.txt b/metadata/en/full_description.txt new file mode 100644 index 000000000..42ce7cd50 --- /dev/null +++ b/metadata/en/full_description.txt @@ -0,0 +1,33 @@ +Calendula is an assistant for personal medication management that will help you to fulfill your prescriptions, +without setting thousands of alarms on your phone, or being worried about forgetting your medication. Just set +up your dose and schedule, bind them to your daily routines and let Calendula do the work for you. + +--- + +Calendula provides: +○ A nice, simple and friendly interface +○ Medication alerts and reminders, with fully customizable alarms +○ Flexible medication schedules, with specific options for birth control pills and other meds with rest intervals. +○ Medicines search and leaflet consultation, with data provided by the "Agencia Española de Medicamentos y Productos Sanitarios" (http://www.aemps.gob.es) +○ Daily control over taken medicines +○ Multiple patient support + +Visit our web site for more info: https://tec.citius.usc.es/calendula/ + +--- + +About app permissions: + +Calendula does not require a previous registration and do not collects personal data. At some time, Calendula may request permission to access different resources of your device. Here's why: + +○ Storage: We need this permission to access ringtones stored on your device and allow you to choose the one you like the most for medication notifications, and to download medicine databases. +○ Camera: It is possible to add drugs (only AEMPS at the moment) to the med-kit by scanning a bar code. We need access to your device's camera in order to do this. +○ Internet access: This permission is not explicitly requested, and is only necessary to download the medication leaflets and setup the med database. Your medication data will not leave your phone at any time. + +--- + +Open Source: +Calendula is an open source project. If you have any ideas or are interested in contributing you can do it through our web site (https://tec.citius.usc.es/calendula/) or through our Github community https://github.com/citiususc/calendula. We appreciate any contribution or suggestion. + +Thank you very much, +Calendula team. \ No newline at end of file diff --git a/metadata/en/short_description.txt b/metadata/en/short_description.txt new file mode 100644 index 000000000..4635cc675 --- /dev/null +++ b/metadata/en/short_description.txt @@ -0,0 +1 @@ +Medication management made easy \ No newline at end of file diff --git a/metadata/es/full_description.txt b/metadata/es/full_description.txt new file mode 100644 index 000000000..10a198400 --- /dev/null +++ b/metadata/es/full_description.txt @@ -0,0 +1,31 @@ +Calendula es un asistente para la gestión personal de la medicación que te ayudará a seguir de forma correcta todas tus prescripciones, sin tener que recurrir a miles de alarmas en tu teléfono, o estar continuamente pendiente de haber tomado tu medicación. Simplemente introduce tus dosis y horarios, asócialos a tu rutina diaria y deja que Calendula haga el resto del trabajo por ti, avisándote en el momento oportuno para que no te olvides. + +--- + +Te ofrecemos: +○ Una interfaz simple y agradable +○ Avisos y recordatorios de medicación, con alarmas totalmente configurables +○ Pautas de medicación flexibles, con opciones específicas para anticonceptivos y otros medicamentos con descansos. +○ Buscador de medicamentos y consulta de prospectos oficiales proporcionados por la Agencia Española de Medicamentos y Productos Sanitarios (http://www.aemps.gob.es) +○ Control diario de medicinas tomadas +○ Gestión de varios pacientes en la misma aplicación + +Para más información, visita nuestra web: https://tec.citius.usc.es/calendula/ + +--- + +Información de permisos: + +Calendula no requiere registro previo ni recopila datos de carácter personal. Puede que solicite permiso en algún momento para acceder a diferentes recursos de tu dispositivo. A continuación te explicamos por qué: + +○ Almacenamiento: Necesitamos este permiso para acceder a los tonos de notificación almacenados en tu dispositivo y que así puedas seleccionar el que más te apetezca como tono para Calendula, y para descargar la base de datos de medicamentos. +○ Cámara: Como sabes, puedes añadir medicamentos de AEMPS al botiquín escaneando su código de barras. Para poder escanearlos necesitamos tener acceso a la cámara de tu dispositivo. +○ Acceso a internet: Este permiso no se solicita de forma explícita, y solo es necesario para descargar prospectos y configurar la base de datos medicamentos. Tus datos de medicación no saldrán en ningún momento de tu teléfono. + +--- + +Open Source: +Calendula es un proyecto de código abierto. Si tienes alguna idea o estás interesado en contribuir puedes hacerlo a través de nuestra web (https://tec.citius.usc.es/calendula/) o en nuestra comunidad de Github https://github.com/citiususc/calendula. Agradecemos cualquier aportación o sugerencia. + +Muchas gracias, +el equipo de Calendula. \ No newline at end of file diff --git a/metadata/es/short_description.txt b/metadata/es/short_description.txt new file mode 100644 index 000000000..cebe24fad --- /dev/null +++ b/metadata/es/short_description.txt @@ -0,0 +1 @@ +Tu medicación, ahora más fácil \ No newline at end of file