/* * Copyright (C) 2013-2017 Stichting Akvo (Akvo Foundation) * * This file is part of Akvo Flow. * * Akvo Flow 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. * * Akvo Flow 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 Akvo Flow. If not, see <http://www.gnu.org/licenses/>. */ package org.akvo.flow.app; import android.app.Application; import android.content.res.Configuration; import android.database.Cursor; import android.support.annotation.Nullable; import android.text.TextUtils; import android.widget.Toast; import org.akvo.flow.R; import org.akvo.flow.data.database.SurveyDbAdapter; import org.akvo.flow.data.database.UserColumns; import org.akvo.flow.data.preference.Prefs; import org.akvo.flow.domain.SurveyGroup; import org.akvo.flow.domain.User; import org.akvo.flow.service.ApkUpdateService; import org.akvo.flow.injector.component.ApplicationComponent; import org.akvo.flow.injector.component.DaggerApplicationComponent; import org.akvo.flow.injector.module.ApplicationModule; import org.akvo.flow.util.ConstantUtil; import org.akvo.flow.util.logging.SentryHelper; import java.util.Arrays; import java.util.Locale; public class FlowApp extends Application { private static FlowApp app;// Singleton //TODO: use shared pref? private Locale mLocale; private User mUser; private long mSurveyGroupId;// Hacky way of filtering the survey group in Record search private Prefs prefs; private ApplicationComponent applicationComponent; @Override public void onCreate() { super.onCreate(); initializeInjector(); prefs = new Prefs(getApplicationContext()); initLogging(); init(); startUpdateService(); app = this; } private void startUpdateService() { ApkUpdateService.scheduleFirstTask(this); } private void initializeInjector() { this.applicationComponent = DaggerApplicationComponent.builder().applicationModule(new ApplicationModule(this)).build(); this.applicationComponent.inject(this); } public ApplicationComponent getApplicationComponent() { return this.applicationComponent; } private void initLogging() { SentryHelper helper = new SentryHelper(this); helper.initDebugTree(); helper.initSentry(); } public static FlowApp getApp() { return app; } @Override public void onConfigurationChanged(Configuration newConfig){ super.onConfigurationChanged(newConfig); // This config will contain system locale. We need a workaround // to enable our custom locale again. Note that this approach // is not very 'clean', but Android makes it really hard to // customize an application wide locale. if (mLocale != null && !mLocale.getLanguage().equalsIgnoreCase( newConfig.locale.getLanguage())) { // Re-enable our custom locale, using this newConfig reference newConfig.locale = mLocale; Locale.setDefault(mLocale); getBaseContext().getResources().updateConfiguration(newConfig, null); } } private void init() { // Load custom locale into the app. If the locale has not previously been configured // check if the device has a compatible language active. Otherwise, fall back to English String language = loadLocalePref(); //TODO: this is not necessary as by default locale is english anyway if (TextUtils.isEmpty(language)) { language = Locale.getDefault().getLanguage(); // Is that available in our language list? if (!Arrays.asList(getResources().getStringArray(R.array.app_language_codes)) .contains(language)) { language = ConstantUtil.ENGLISH_CODE;// TODO: Move this constant to @strings } } //TODO: only set the language if it is different than the device locale setAppLanguage(language, false); loadLastUser(); // Load last survey group mSurveyGroupId = prefs.getLong(Prefs.KEY_SURVEY_GROUP_ID, SurveyGroup.ID_NONE); } public void setUser(User user) { mUser = user; prefs.setLong(Prefs.KEY_USER_ID, mUser != null ? mUser.getId() : -1); } public User getUser() { return mUser; } public void setSurveyGroupId(long surveyGroupId) { mSurveyGroupId = surveyGroupId; prefs.setLong(Prefs.KEY_SURVEY_GROUP_ID, surveyGroupId); } public long getSurveyGroupId() { return mSurveyGroupId; } public String getAppLanguageCode() { return mLocale.getLanguage(); } public String getAppDisplayLanguage() { String lang = mLocale.getDisplayLanguage(); if (!TextUtils.isEmpty(lang)) { // Ensure the first letter is upper case char[] strArray = lang.toCharArray(); strArray[0] = Character.toUpperCase(strArray[0]); lang = new String(strArray); } return lang; } /** * Checks if the user preference to persist logged-in users is set and, if * so, loads the last logged-in user from the DB */ private void loadLastUser() { SurveyDbAdapter database = new SurveyDbAdapter(FlowApp.this); database.open(); // Consider the app set up if the DB contains users. This is relevant for v2.2.0 app upgrades if (!prefs.getBoolean(Prefs.KEY_SETUP, false)) { prefs.setBoolean(Prefs.KEY_SETUP, database.getUsers().getCount() > 0); } long id = prefs.getLong(Prefs.KEY_USER_ID, -1); if (id != -1) { Cursor cur = database.getUser(id); if (cur.moveToFirst()) { String userName = cur.getString(cur.getColumnIndexOrThrow(UserColumns.NAME)); mUser = new User(id, userName); cur.close(); } } database.close(); } public void setAppLanguage(String language, boolean requireRestart) { // Override system locale mLocale = new Locale(language); Locale.setDefault(mLocale); Configuration config = getBaseContext().getResources().getConfiguration(); config.locale = mLocale; getBaseContext().getResources().updateConfiguration(config, null); // Save it in the preferences saveLocalePref(language); if (requireRestart) { Toast.makeText(this, R.string.please_restart, Toast.LENGTH_LONG) .show(); } } @Nullable private String loadLocalePref() { return prefs.getString(Prefs.KEY_LOCALE, null); } private void saveLocalePref(String language) { prefs.setString(Prefs.KEY_LOCALE, language); } }