com.metinkale.prayerapp.App.java Source code

Java tutorial

Introduction

Here is the source code for com.metinkale.prayerapp.App.java

Source

/*
 * Copyright (c) 2016 Metin Kale
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

package com.metinkale.prayerapp;

import android.app.AlarmManager;
import android.app.Application;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Build;
import android.os.Handler;
import android.preference.PreferenceManager;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;

import com.crashlytics.android.Crashlytics;
import com.evernote.android.job.Job;
import com.evernote.android.job.JobCreator;
import com.evernote.android.job.JobManager;
import com.github.anrwatchdog.ANRWatchDog;
import com.metinkale.prayer.BuildConfig;
import com.metinkale.prayerapp.settings.Prefs;
import com.metinkale.prayerapp.utils.AndroidTimeZoneProvider;
import com.metinkale.prayerapp.utils.AppRatingDialog;
import com.metinkale.prayerapp.utils.TimeZoneChangedReceiver;
import com.metinkale.prayerapp.vakit.Main;
import com.metinkale.prayerapp.vakit.WidgetProvider;
import com.metinkale.prayerapp.vakit.WidgetService;
import com.metinkale.prayerapp.vakit.times.Times;
import com.metinkale.prayerapp.vakit.times.WebTimes;
import com.squareup.leakcanary.LeakCanary;

import org.joda.time.DateTimeZone;

import java.lang.ref.WeakReference;

import io.fabric.sdk.android.Fabric;

public class App extends Application implements SharedPreferences.OnSharedPreferenceChangeListener {
    public static final String API_URL = "http://metinkale38.github.io/prayer-times-android/files";
    private static WeakReference<App> sApp;
    @NonNull
    private Handler mHandler = new Handler();

    private static Thread.UncaughtExceptionHandler mDefaultUEH;
    @NonNull
    private static Thread.UncaughtExceptionHandler mCaughtExceptionHandler = new Thread.UncaughtExceptionHandler() {
        @Override
        public void uncaughtException(Thread thread, @NonNull Throwable ex) {
            AppRatingDialog.setInstalltionTime(0);
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M
                    && ex.getClass().getName().contains("RemoteServiceException")) {
                if (ex.getMessage().contains("Couldn't update icon")) {
                    Prefs.setShowOngoingNumber(false);
                    //Toast.makeText(App.get(), "Crash detected. Show ongoing number disabled...", Toast.LENGTH_LONG).show();
                    Crashlytics.setBool("WORKAROUND#1", true);
                    Crashlytics.logException(ex);
                    return;
                }
            }
            // This will make Crashlytics do its job
            mDefaultUEH.uncaughtException(thread, ex);
        }
    };

    @NonNull
    public static App get() {
        if (sApp == null)
            return null;
        return sApp.get();
    }

    public static boolean isOnline() {
        //only checks for connection, not for actual internet connection
        //everything else need (or should be in) a seperate thread
        ConnectivityManager cm = (ConnectivityManager) get().getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
        return activeNetwork != null && activeNetwork.isConnected();
    }

    public static void setExact(@NonNull AlarmManager am, int type, long time, PendingIntent service) {
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP
                && type == AlarmManager.RTC_WAKEUP && Prefs.useAlarm()) {
            AlarmManager.AlarmClockInfo info = new AlarmManager.AlarmClockInfo(time, PendingIntent.getActivity(
                    App.get(), 0, new Intent(App.get(), Main.class), PendingIntent.FLAG_UPDATE_CURRENT));
            am.setAlarmClock(info, service);
        } else if (type == AlarmManager.RTC_WAKEUP && Build.VERSION.SDK_INT >= 23) {
            am.setExactAndAllowWhileIdle(type, time, service);
        } else if (Build.VERSION.SDK_INT >= 19) {
            am.setExact(type, time, service);
        } else {
            am.set(type, time, service);
        }

    }

    @NonNull
    public Handler getHandler() {
        return mHandler;
    }

    public App() {
        super();
        sApp = new WeakReference<>(this);
    }

    @Override
    public void onCreate() {
        super.onCreate();
        if (LeakCanary.isInAnalyzerProcess(this)) {
            return;
        }
        LeakCanary.install(this);

        Fabric.with(this, new Crashlytics());
        Crashlytics.setUserIdentifier(Prefs.getUUID());
        if (BuildConfig.DEBUG)
            Crashlytics.setBool("isDebug", true);

        JobManager.create(this).addJobCreator(new MyJobCreator());

        mDefaultUEH = Thread.getDefaultUncaughtExceptionHandler();
        Thread.setDefaultUncaughtExceptionHandler(mCaughtExceptionHandler);

        DateTimeZone.setProvider(new AndroidTimeZoneProvider());
        registerReceiver(new TimeZoneChangedReceiver(), new IntentFilter(Intent.ACTION_TIMEZONE_CHANGED));

        try {
            Times.getTimes();
        } catch (Exception e) {
            Crashlytics.logException(e);
        }

        Utils.init(this);

        startService(new Intent(this, WidgetService.class));
        Times.setAlarms();

        PreferenceManager.getDefaultSharedPreferences(this).registerOnSharedPreferenceChangeListener(this);

        if ("longcheer".equalsIgnoreCase(Build.BRAND) || "longcheer".equalsIgnoreCase(Build.MANUFACTURER)
                || "general mobile".equalsIgnoreCase(Build.BRAND)
                || "general mobile".equalsIgnoreCase(Build.MANUFACTURER)
                || "general_mobile".equalsIgnoreCase(Build.BRAND)
                || "general_mobile".equalsIgnoreCase(Build.MANUFACTURER)) {
            new ANRWatchDog().start();
        }

        if (AppRatingDialog.getInstallationTime() == 0) {
            AppRatingDialog.setInstalltionTime(System.currentTimeMillis());
        }
    }

    @Override
    public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
        if ("calendarIntegration".equals(key)) {
            MainIntentService.startCalendarIntegration(App.get());
        } else if ("ongoingIcon".equals(key) || "ongoingNumber".equals(key)) {
            WidgetService.updateOngoing();
        } else if ("alternativeOngoing".equals(key)) {
            WidgetService.updateOngoing();
        } else if ("useAlarm".equals(key)) {
            Times.setAlarms();
        } else if ("showAltWidgetHightlight".equals(key)) {
            WidgetProvider.updateWidgets(this);
        }
    }

    public static final class NotIds {
        public static final int ALARM = 1;
        public static final int ONGOING = 2;
    }

    private static class MyJobCreator implements JobCreator {
        @Nullable
        @Override
        public Job create(@NonNull String tag) {
            try {
                if (tag.startsWith(WebTimes.SyncJob.TAG)) {
                    Times t = Times.getTimes(Long.parseLong(tag.substring(WebTimes.SyncJob.TAG.length())));
                    if (t instanceof WebTimes)
                        return ((WebTimes) t).new SyncJob();
                }
            } catch (Exception e) {
                Crashlytics.logException(e);
            }
            return null;
        }
    }
}