/* * Copyright (C) 2012-2016 The Android Money Manager Ex Project Team * * 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 com.money.manager.ex; import android.content.Context; import android.content.SharedPreferences; import android.database.Cursor; import android.preference.PreferenceManager; import android.support.multidex.MultiDexApplication; import android.text.TextUtils; import android.widget.TextView; import com.crashlytics.android.Crashlytics; import com.crashlytics.android.core.CrashlyticsCore; import com.mikepenz.iconics.Iconics; import com.mikepenz.mmex_icon_font_typeface_library.MMXIconFont; import com.money.manager.ex.common.MoneyParcelConverter; import com.money.manager.ex.core.InfoKeys; import com.money.manager.ex.core.UIHelper; import com.money.manager.ex.core.ioc.MmxComponent; import com.money.manager.ex.core.ioc.MmxModule; import com.money.manager.ex.database.MmxOpenHelper; import com.money.manager.ex.log.CrashReportingTree; import com.money.manager.ex.core.ioc.DaggerMmxComponent; import com.money.manager.ex.database.QueryAccountBills; import com.money.manager.ex.log.DebugTree; import com.money.manager.ex.servicelayer.InfoService; import com.money.manager.ex.settings.AppSettings; import com.money.manager.ex.settings.DatabaseSettings; import com.money.manager.ex.settings.LookAndFeelSettings; import com.money.manager.ex.settings.PreferenceConstants; import com.money.manager.ex.utils.MmxDatabaseUtils; import com.money.manager.ex.view.RobotoView; import com.shamanland.fonticon.FontIconTypefaceHolder; import io.fabric.sdk.android.Fabric; import org.parceler.Parcel; import org.parceler.ParcelClass; import org.parceler.ParcelClasses; import java.io.File; import java.util.Locale; import java.util.concurrent.atomic.AtomicReference; import info.javaperformance.money.Money; import timber.log.Timber; /** * Here we define the parcel converter for Money type. */ @ParcelClasses( @ParcelClass( value = Money.class, annotation = @Parcel(converter = MoneyParcelConverter.class)) ) public class MoneyManagerApplication extends MultiDexApplication { private static MoneyManagerApplication appInstance; private static float mTextSize; private static String userName = ""; public static MoneyManagerApplication getApp() { return appInstance; } /** * Reads the current database path from the preferences and checks for the existence of the * database file. * Creates a default database file if the one from preferences is not found. Sets this file as * the default database. * @param context Executing context. * @return Full path to the current database file. */ public static String getDatabasePath(Context context) { // todo: move this to the recent db provider DatabaseSettings dbSettings = new AppSettings(context).getDatabaseSettings(); String databasePath = dbSettings.getDatabasePath(); if (!TextUtils.isEmpty(databasePath)) { // Use the db path stored in the preferences. File databaseFile = new File(databasePath); if (databaseFile.getAbsoluteFile().exists()) { return databaseFile.getPath(); } } // otherwise try other paths or create the default database. String defaultPath = new MmxDatabaseUtils(context).getDefaultDatabasePath(); // Save db path to preferences. dbSettings.setDatabasePath(defaultPath); // Show notification if (databasePath.equals(defaultPath)) { new UIHelper(context).showToast("Default database file will be created at " + defaultPath); } else { new UIHelper(context).showToast("Database " + databasePath + " not found. Using default:" + defaultPath); } return defaultPath; } public static float getTextSize() { return MoneyManagerApplication.mTextSize; } public static void setTextSize(float textSize) { MoneyManagerApplication.mTextSize = textSize; } /** * close process application */ public static void killApplication() { // close application android.os.Process.killProcess(android.os.Process.myPid()); } // Instance fields. public MmxComponent iocComponent; public AtomicReference<MmxOpenHelper> openHelperAtomicReference; // Overrides. @Override public void onCreate() { super.onCreate(); // update instance of application appInstance = this; // set default text size. setTextSize(new TextView(getApplicationContext()).getTextSize()); // Font SharedPreferences appPreferences = PreferenceManager.getDefaultSharedPreferences(this); RobotoView.setUserFont(Integer.parseInt( appPreferences.getString(getString(PreferenceConstants.PREF_APPLICATION_FONT), "-1"))); RobotoView.setUserFontSize(getApplicationContext(), appPreferences.getString(getString(PreferenceConstants.PREF_APPLICATION_FONT_SIZE), "default")); registerCustomFonts(); // Initialize Joda Time // JodaTimeAndroid.init(this); // Exception reporting. Disabled for debug builds. Crashlytics crashlyticsKit = new Crashlytics.Builder() .core(new CrashlyticsCore.Builder().disabled(BuildConfig.DEBUG).build()) .build(); Fabric.with(this, crashlyticsKit); // new Crashlytics() // Loggers if (BuildConfig.DEBUG) { Timber.plant(new DebugTree()); } else { Timber.plant(new CrashReportingTree()); } initializeDependencyInjection(); } /** * Initialize Dagger 2 module(s). */ private void initializeDependencyInjection() { // Dependency Injection. IoC iocComponent = DaggerMmxComponent.builder() .mmxModule(new MmxModule(appInstance)) .build(); } @Override public void onTerminate() { super.onTerminate(); // on terminate is never called // ref: http://stackoverflow.com/questions/15162562/application-lifecycle Timber.d("Application terminated"); } @Override public void attachBaseContext(Context base) { super.attachBaseContext(base); // Trying to mitigate issues on some 4.2.2 devices // https://code.google.com/p/android/issues/detail?id=78377 // ref: https://developer.android.com/tools/building/multidex.html // MultiDex.install(this); } // dynamic public void initDb(String path) { MmxOpenHelper db = createDbInstance(path); if (openHelperAtomicReference == null) { openHelperAtomicReference = new AtomicReference<>(db); } else { // close existing db openHelperAtomicReference.get().close(); openHelperAtomicReference.set(db); } } private MmxOpenHelper createDbInstance(String path) { if (TextUtils.isEmpty(path)) { // path = new MmxDatabaseUtils(this).getDefaultDatabasePath(); path = getDatabasePath(this); } return new MmxOpenHelper(this, path); } public Locale getAppLocale() { Locale locale = null; Context context = getApplicationContext(); String language = new AppSettings(context).getGeneralSettings().getApplicationLanguage(); if(!TextUtils.isEmpty(language)) { try { locale = new Locale(language); } catch (Exception e) { Timber.e(e, "parsing locale: %s", language); } } // in case the above failed if (locale == null) { // use the default locale. locale = context.getResources().getConfiguration().locale; } if (locale == null) { locale = Locale.getDefault(); } return locale; } public boolean setUserName(String userName) { return this.setUserName(userName, false); } /** * @param userName the userName to set * @param save update into database * @deprecated Use Info Service directly to read and write this value as it is used only in * the main activity. */ @Deprecated public boolean setUserName(String userName, boolean save) { MoneyManagerApplication.userName = userName; if (save) { InfoService service = new InfoService(this.getApplicationContext()); boolean updateSuccessful = service.setInfoValue(InfoKeys.USERNAME, userName); if (!updateSuccessful) { return false; } } return true; } public String loadUserNameFromDatabase(Context context) { InfoService service = new InfoService(context); String username = service.getInfoValue(InfoKeys.USERNAME); String result = TextUtils.isEmpty(username) ? "" : username; return result; } /** * Compute account balance and returns balance * * @param context Executing context * @return total */ public double getSummaryAccounts(Context context) { try { return getSummaryAccountsInternal(context); } catch (Exception e) { Timber.e(e, "getting summary accounts"); } return 0; } /** * @return the userName */ public String getUserName() { return userName; } // public boolean isUriAvailable(Context context, Intent intent) { // return context.getPackageManager().resolveActivity(intent, 0) != null; // } /* Private */ private double getSummaryAccountsInternal(Context context) { double curTotal = 0; LookAndFeelSettings settings = new AppSettings(context) .getLookAndFeelSettings(); // compose whereClause String where = ""; // check if show only open accounts if (settings.getViewOpenAccounts()) { where = "LOWER(STATUS)='open'"; } // check if show fav accounts if (settings.getViewFavouriteAccounts()) { where = "LOWER(FAVORITEACCT)='true'"; } QueryAccountBills accountBills = new QueryAccountBills(context); Cursor cursor = context.getContentResolver().query(accountBills.getUri(), null, where, null, null); if (cursor == null) return 0; // calculate summary while (cursor.moveToNext()) { curTotal = curTotal + cursor.getDouble(cursor.getColumnIndex(QueryAccountBills.TOTALBASECONVRATE)); } cursor.close(); return curTotal; } private void registerCustomFonts() { String iconFontPath = "fonts/mmex.ttf"; // Font icons Iconics.registerFont(new MMXIconFont()); // Initialize font icons support. FontIconTypefaceHolder.init(getAssets(), iconFontPath); } }