com.irccloud.android.IRCCloudApplicationBase.java Source code

Java tutorial

Introduction

Here is the source code for com.irccloud.android.IRCCloudApplicationBase.java

Source

/*
 * Copyright (c) 2015 IRCCloud, Ltd.
 *
 * 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.irccloud.android;

import android.app.Activity;
import android.app.ActivityManager;
import android.app.Application;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.graphics.Typeface;
import android.net.ConnectivityManager;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.os.Handler;
import android.os.HandlerThread;
import android.preference.PreferenceManager;
import android.provider.MediaStore;
import android.support.annotation.Nullable;
import android.support.text.emoji.EmojiCompat;
import android.support.text.emoji.FontRequestEmojiCompatConfig;
import android.support.text.emoji.bundled.BundledEmojiCompatConfig;
import android.support.v4.app.ActivityCompat;
import android.support.v4.provider.FontRequest;
import android.support.v4.provider.FontsContractCompat;
import android.util.Log;

import com.crashlytics.android.Crashlytics;
import com.datatheorem.android.trustkit.TrustKit;
import com.irccloud.android.data.collection.ServersList;
import com.irccloud.android.data.model.Buffer;
import com.irccloud.android.data.collection.BuffersList;
import com.irccloud.android.data.collection.EventsList;
import com.raizlabs.android.dbflow.config.FlowManager;

import java.io.File;
import java.util.Timer;
import java.util.TimerTask;

import io.fabric.sdk.android.Fabric;

@SuppressWarnings("unused")
public class IRCCloudApplicationBase extends Application {
    private NetworkConnection conn = null;
    private TimerTask notifierSockerTimerTask = null;
    private static final Timer notifierTimer = new Timer("notifier-timer");
    private Typeface csFont;
    private Handler mFontsHandler;

    @Override
    public void onCreate() {
        super.onCreate();
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1)
            TrustKit.initializeWithNetworkSecurityConfiguration(getApplicationContext(),
                    R.xml.network_security_config);
        Fabric.with(this, new Crashlytics());
        Crashlytics.log(Log.INFO, "IRCCloud", "Crashlytics Initialized");
        FlowManager.init(this);
        SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
        if (Build.VERSION.SDK_INT >= 19)
            EmojiCompat.init(
                    new BundledEmojiCompatConfig(this).setReplaceAll(!prefs.getBoolean("preferSystemEmoji", true)));
        /*EmojiCompat.init(new FontRequestEmojiCompatConfig(getApplicationContext(), new FontRequest(
                "com.google.android.gms.fonts",
                "com.google.android.gms",
                "Noto Color Emoji Compat",
                R.array.com_google_android_gms_fonts_certs))
                .setReplaceAll(!prefs.getBoolean("preferSystemEmoji", true))
                .registerInitCallback(new EmojiCompat.InitCallback() {
                    @Override
                    public void onInitialized() {
                        super.onInitialized();
                        EventsList.getInstance().clearCaches();
                        conn.notifyHandlers(NetworkConnection.EVENT_FONT_DOWNLOADED, null);
                    }
                }));*/
        NetworkConnection.getInstance().registerForConnectivity();

        //Disable HTTP keep-alive for our app, as some versions of Android will return an empty response
        System.setProperty("http.keepAlive", "false");

        //Allocate all the shared objects at launch
        conn = NetworkConnection.getInstance();
        ColorFormatter.init();

        if (prefs.contains("notify")) {
            SharedPreferences.Editor editor = prefs.edit();
            editor.putString("notify_type", prefs.getBoolean("notify", true) ? "1" : "0");
            editor.remove("notify");
            editor.commit();
        }

        if (prefs.contains("notify_sound")) {
            SharedPreferences.Editor editor = prefs.edit();
            if (!prefs.getBoolean("notify_sound", true))
                editor.putString("notify_ringtone", "");
            editor.remove("notify_sound");
            editor.commit();
        }

        if (prefs.contains("notify_lights")) {
            SharedPreferences.Editor editor = prefs.edit();
            if (!prefs.getBoolean("notify_lights", true))
                editor.putString("notify_led_color", "0");
            editor.remove("notify_lights");
            editor.commit();
        }

        if (!prefs.getBoolean("ringtone_migrated", false)) {
            if (ActivityCompat.checkSelfPermission(this,
                    android.Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
                String notification_uri = prefs.getString("notify_ringtone", "");
                if (notification_uri.startsWith("content://media/external/audio/media/")) {
                    Cursor c = getContentResolver().query(Uri.parse(notification_uri),
                            new String[] { MediaStore.Audio.Media.TITLE }, null, null, null);

                    if (c != null && c.moveToFirst()) {
                        if (c.getString(0).equals("IRCCloud")) {
                            Log.d("IRCCloud", "Migrating notification ringtone setting: " + notification_uri);
                            SharedPreferences.Editor editor = prefs.edit();
                            editor.remove("notify_ringtone");
                            editor.commit();
                        }
                    }
                    if (c != null && !c.isClosed()) {
                        c.close();
                    }
                }

                File path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_NOTIFICATIONS);
                File file = new File(path, "IRCCloud.mp3");
                if (file.exists()) {
                    file.delete();
                }

                try {
                    getContentResolver().delete(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
                            MediaStore.Audio.Media.TITLE + " = 'IRCCloud'", null);
                } catch (Exception e) {
                    // Ringtone not in media DB
                }
            }

            try {
                String notification_uri = prefs.getString("notify_ringtone", "");
                if (notification_uri.startsWith("content://media/")) {
                    Cursor c = getContentResolver().query(Uri.parse(notification_uri),
                            new String[] { MediaStore.Audio.Media.TITLE }, null, null, null);

                    if (c != null && c.moveToFirst()) {
                        if (c.getString(0).equals("IRCCloud")) {
                            Log.d("IRCCloud", "Migrating notification ringtone setting: " + notification_uri);
                            SharedPreferences.Editor editor = prefs.edit();
                            editor.remove("notify_ringtone");
                            editor.commit();
                        }
                    }
                    if (c != null && !c.isClosed()) {
                        c.close();
                    }
                }
            } catch (Exception e) {
                //We might not have permission to query the media DB
            }

            try {
                getContentResolver().delete(MediaStore.Audio.Media.INTERNAL_CONTENT_URI,
                        MediaStore.Audio.Media.TITLE + " = 'IRCCloud'", null);
            } catch (Exception e) {
                // Ringtone not in media DB
                e.printStackTrace();
            }

            File file = new File(getFilesDir(), "IRCCloud.mp3");
            if (file.exists()) {
                file.delete();
            }

            SharedPreferences.Editor editor = prefs.edit();
            editor.putBoolean("ringtone_migrated", true);
            editor.commit();
        }

        if (prefs.contains("notify_pebble")) {
            try {
                int pebbleVersion = getPackageManager().getPackageInfo("com.getpebble.android", 0).versionCode;
                if (pebbleVersion >= 553 && Build.VERSION.SDK_INT >= 18) {
                    SharedPreferences.Editor editor = prefs.edit();
                    editor.remove("notify_pebble");
                    editor.commit();
                }
            } catch (Exception e) {
            }
        }

        if (prefs.contains("acra.enable")) {
            SharedPreferences.Editor editor = prefs.edit();
            editor.remove("acra.enable");
            editor.commit();
        }

        if (prefs.contains("notifications_json")) {
            SharedPreferences.Editor editor = prefs.edit();
            editor.remove("notifications_json");
            editor.remove("networks_json");
            editor.remove("lastseeneids_json");
            editor.remove("dismissedeids_json");
            editor.commit();
        }

        prefs = getSharedPreferences("prefs", 0);
        if (prefs.getString("host", "www.irccloud.com").equals("www.irccloud.com") && !prefs.contains("path")
                && prefs.contains("session_key")) {
            Crashlytics.log(Log.INFO, "IRCCloud", "Migrating path from session key");
            SharedPreferences.Editor editor = prefs.edit();
            editor.putString("path", "/websocket/" + prefs.getString("session_key", "").charAt(0));
            editor.commit();
        }
        if (prefs.contains("host") && prefs.getString("host", "").equals("www.irccloud.com")) {
            Crashlytics.log(Log.INFO, "IRCCloud", "Migrating host");
            SharedPreferences.Editor editor = prefs.edit();
            editor.putString("host", "api.irccloud.com");
            editor.commit();
        }
        if (prefs.contains("gcm_app_version")) {
            SharedPreferences.Editor editor = prefs.edit();
            editor.remove("gcm_app_version");
            editor.remove("gcm_app_build");
            editor.remove("gcm_registered");
            editor.remove("gcm_reg_id");
            editor.commit();
        }

        NetworkConnection.IRCCLOUD_HOST = prefs.getString("host", BuildConfig.HOST);
        NetworkConnection.IRCCLOUD_PATH = prefs.getString("path", "/");

        /*try {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            if (0 != (getApplicationInfo().flags &= ApplicationInfo.FLAG_DEBUGGABLE))
                WebView.setWebContentsDebuggingEnabled(true);
        }
        } catch (Exception e) {
        }*/

        /*FontRequest request = new FontRequest(
            "com.google.android.gms.fonts",
            "com.google.android.gms",
            "Dekko",
            R.array.com_google_android_gms_fonts_certs);
            
        FontsContractCompat.requestFont(getApplicationContext(), request, new FontsContractCompat.FontRequestCallback() {
        @Override
        public void onTypefaceRetrieved(Typeface typeface) {
            csFont = typeface;
            EventsList.getInstance().clearCaches();
            NetworkConnection.getInstance().notifyHandlers(NetworkConnection.EVENT_FONT_DOWNLOADED, null);
        }
        }, getFontsHandler());*/

        Crashlytics.log(Log.INFO, "IRCCloud", "App Initialized");
    }

    @Override
    public void onTerminate() {
        NetworkConnection.getInstance().unregisterForConnectivity();
        NetworkConnection.getInstance().save(1);
        super.onTerminate();
    }

    public void onPause(final Activity context) {
        final ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        if (notifierSockerTimerTask != null)
            notifierSockerTimerTask.cancel();
        notifierSockerTimerTask = new TimerTask() {
            @Override
            public void run() {
                notifierSockerTimerTask = null;
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                    ActivityManager am = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
                    for (ActivityManager.RunningAppProcessInfo info : am.getRunningAppProcesses()) {
                        if (info.processName.equals(context.getPackageName())
                                && info.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND)
                            return;
                    }
                }
                if (!conn.notifier && conn.getState() == NetworkConnection.STATE_CONNECTED) {
                    conn.disconnect();
                    if (ServersList.getInstance().count() < 1) {
                        Crashlytics.log(Log.DEBUG, "IRCCloud",
                                "No servers configured, not connecting notifier socket");
                        return;
                    }
                    if (!(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N && cm.isActiveNetworkMetered() && cm
                            .getRestrictBackgroundStatus() == ConnectivityManager.RESTRICT_BACKGROUND_STATUS_ENABLED)) {
                        try {
                            Thread.sleep(1000);
                            conn.notifier = true;
                            conn.connect();
                        } catch (Exception e) {
                        }
                    }
                }
            }
        };

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N && cm.isActiveNetworkMetered()
                && cm.getRestrictBackgroundStatus() == ConnectivityManager.RESTRICT_BACKGROUND_STATUS_ENABLED) {
            notifierTimer.schedule(notifierSockerTimerTask, 5000);
        } else {
            notifierTimer.schedule(notifierSockerTimerTask, 300000);
        }
    }

    public void onResume(Activity context) {
        cancelNotifierTimer();
    }

    public void cancelNotifierTimer() {
        if (notifierSockerTimerTask != null) {
            notifierSockerTimerTask.cancel();
            notifierSockerTimerTask = null;
        }
    }

    @Override
    public void onLowMemory() {
        super.onLowMemory();
        if (!NetworkConnection.getInstance().isVisible()) {
            Crashlytics.log(Log.DEBUG, "IRCCloud",
                    "Received low memory warning in the background, cleaning backlog in all buffers");
            BuffersList buffersList = BuffersList.getInstance();
            EventsList eventsList = EventsList.getInstance();
            for (Buffer b : buffersList.getBuffers()) {
                if (!b.getScrolledUp())
                    eventsList.pruneEvents(b.getBid());
            }
        }
    }

    @Override
    public void onTrimMemory(int level) {
        super.onTrimMemory(level);
        if (level >= TRIM_MEMORY_MODERATE) {
            onLowMemory();
        }
    }

    public Typeface getCsFont() {
        return csFont;
    }

    private Handler getFontsHandler() {
        if (mFontsHandler == null) {
            HandlerThread handlerThread = new HandlerThread("fonts");
            handlerThread.start();
            mFontsHandler = new Handler(handlerThread.getLooper());
        }
        return mFontsHandler;
    }
}