com.colossaldb.dnd.prefs.AppPreferences.java Source code

Java tutorial

Introduction

Here is the source code for com.colossaldb.dnd.prefs.AppPreferences.java

Source

package com.colossaldb.dnd.prefs;

import android.content.Context;
import android.content.SharedPreferences;
import android.util.Log;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * Copyright (C) 2013  Jayaprakash Pasala
 *
 * 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
 * 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/>.
 *
 *
 */

/**
 * Created by Jayaprakash Pasala
 * Date:  12/10/13
 * Time:  10:28 AM
 * <p/>
 * A singleton class representing the options used by the application (and also has helper methods to write and read debug logs).
 */
public class AppPreferences {
    private static final String PREFERENCE_NAME = "AppPreferences";
    private static final String DEBUG_PREF_NAME = "DebugAppInfo";

    private static final int MAX_LIST_SIZE = 250;

    // Broadcast
    public static final String BROADCAST_START_STOP_ACTION = "com.colossaldb.dnd.START_STOP";

    // Keys
    private static final String START_HOUR = "sh";
    private static final String START_MIN = "sm";
    private static final String END_HOUR = "eh";
    private static final String END_MIN = "em";
    private static final String DND_ENABLED = "dnd_enabled";
    private static final String RING_ON_REPEAT = "ring_on_repeat";
    private static final String RING_FOR_CONTACTS = "ring_for_contacts";

    public static final String NEXT_ALARM_KEY = "NextAlarm";
    public static final String ERROR_EVENTS_KEY = "ErrorEvents";
    public static final String DEBUG_EVENTS_KEY = "DebugEvents";
    public static final String TITLE_KEY = "title";
    public static final String DETAIL_KEY = "detail";
    public static final String TIMESTAMP_KEY = "ts";
    public static final String SETTINGS_CHANGED_KEY = "SettingsChanged";

    private static volatile AppPreferences INSTANCE = null;
    //private static JSONArray LOCAL_STORE = new JSONArray();
    private static final DateFormat DF = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");

    private final SharedPreferences preferences;
    private final SharedPreferences debugPreferences;

    /**
     * Expected to be called only once during the full lifecycle.
     *
     * @param appContext - Application context
     */
    public static synchronized void initialize(Context appContext) {
        INSTANCE = new AppPreferences(appContext);
    }

    public static AppPreferences getInstance() {
        return INSTANCE;
    }

    private AppPreferences(Context appContext) {
        preferences = appContext.getSharedPreferences(PREFERENCE_NAME, Context.MODE_PRIVATE);
        debugPreferences = appContext.getSharedPreferences(DEBUG_PREF_NAME, Context.MODE_PRIVATE);
    }

    public int getStartHour(int defValue) {
        return preferences.getInt(START_HOUR, defValue);
    }

    public int getStartMinute(int defValue) {
        return preferences.getInt(START_MIN, defValue);
    }

    public int getEndHour(int defValue) {
        return preferences.getInt(END_HOUR, defValue);
    }

    public int getEndMinute(int defValue) {
        return preferences.getInt(END_MIN, defValue);
    }

    public boolean isEnabled() {
        return preferences.getBoolean(DND_ENABLED, false);
    }

    public boolean ringOnRepeatCall() {
        return preferences.getBoolean(RING_ON_REPEAT, false);
    }

    public void setStartTime(int startHour, int startMin) {
        setTimes(START_HOUR, startHour, START_MIN, startMin);
    }

    public void setEndTime(int endHour, int endMin) {
        setTimes(END_HOUR, endHour, END_MIN, endMin);
    }

    public boolean ringForContacts() {
        return preferences.getBoolean(RING_FOR_CONTACTS, false);
    }

    private void setTimes(String hourKey, int hour, String minKey, int mins) {
        SharedPreferences.Editor e = preferences.edit();
        e.putInt(hourKey, hour);
        e.putInt(minKey, mins);
        e.apply();
    }

    public void save(boolean dndEnabled, int startHour, int startMin, int endHour, int endMin, boolean ringOnRepeat,
            boolean ringForContacts) {
        assert startHour >= 0 && startHour < 24;
        assert endHour >= 0 && endHour < 24;
        assert startMin >= 0 && startMin < 60;
        assert endMin >= 0 && endMin < 60;

        SharedPreferences.Editor edit = preferences.edit();
        edit.putBoolean(DND_ENABLED, dndEnabled);
        edit.putInt(START_HOUR, startHour);
        edit.putInt(START_MIN, startMin);
        edit.putInt(END_HOUR, endHour);
        edit.putInt(END_MIN, endMin);
        edit.putBoolean(RING_ON_REPEAT, ringOnRepeat);
        edit.putBoolean(RING_FOR_CONTACTS, ringForContacts);
        edit.apply();
    }

    public CharSequence getFormattedStartTime() {
        return String.format("%2d:%02d ", INSTANCE.getStartHour(-1), INSTANCE.getStartMinute(-1));
    }

    public CharSequence getFormattedEndTime() {
        return String.format("%2d:%02d ", INSTANCE.getEndHour(-1), INSTANCE.getEndMinute(-1));
    }

    /**
     * Write the debug events that have already occurred.
     *
     * @param title  - title of the event
     * @param detail - event details
     */
    public void writeDebugEvent(String title, String detail) {
        try {
            writeToPrefList(debugPreferences, DEBUG_EVENTS_KEY, title, detail);
        } catch (JSONException ignored) {
            Log.e("AppPreferences", "Title [" + title + "] and detail [" + detail + "]", ignored);
        }
    }

    public JSONArray getDebugEvents() {
        //return LOCAL_STORE; //getJSONArray(debugPreferences, DEBUG_EVENTS_KEY);
        return getJSONArray(debugPreferences, DEBUG_EVENTS_KEY);
    }

    /**
     * Write the error event.
     *
     * @param title  - title
     * @param detail - detail
     */
    public void writeErrorEvent(String title, String detail) {
        try {
            writeToPrefList(debugPreferences, ERROR_EVENTS_KEY, title, detail);
        } catch (JSONException ignored) {
            Log.e("AppPreferences", "Title [" + title + "] and detail [" + detail + "]", ignored);
        }
    }

    public JSONArray getErrorEvents() {
        return getJSONArray(debugPreferences, ERROR_EVENTS_KEY);
    }

    /**
     * Store the details when the next scheduled event is going to run.
     *
     * @param details - details
     */
    public void logNextRun(String details) {
        debugPreferences.edit().putString(NEXT_ALARM_KEY, details).apply();
    }

    /**
     * @return The next scheduled run details.
     */
    public String getNextScheduleRun() {
        return debugPreferences.getString(NEXT_ALARM_KEY, "");
    }

    private static void writeToPrefList(SharedPreferences preferences, String listKey, String title, String detail)
            throws JSONException {
        //JSONArray events = LOCAL_STORE ;//getJSONArray(preferences, listKey);
        JSONArray events = getJSONArray(preferences, listKey);
        JSONObject jsonObject = new JSONObject();
        jsonObject.put(TIMESTAMP_KEY, DF.format(new Date(System.currentTimeMillis())));
        jsonObject.put(TITLE_KEY, title);
        jsonObject.put(DETAIL_KEY, detail);
        events.put(jsonObject);

        if (events.length() > MAX_LIST_SIZE) {
            JSONArray newArray = new JSONArray();
            for (int i = events.length() - MAX_LIST_SIZE; i < MAX_LIST_SIZE; i++) {
                newArray.put(events.get(i));
            }
            events = newArray;
        }

        //LOCAL_STORE = events;
        preferences.edit().putString(listKey, events.toString()).apply();
    }

    private static JSONArray getJSONArray(SharedPreferences preferences, String listKey) {
        JSONArray events;
        String eventStr = preferences.getString(listKey, null);
        if (eventStr == null) {
            events = new JSONArray();
        } else {
            try {
                events = new JSONArray(eventStr);
            } catch (JSONException ignored) {
                // Cannot do much...
                Log.e("AppPreferences", "Error: " + ignored.getMessage(), ignored);
                events = new JSONArray();
            }
        }
        return events;
    }

    public void markRingerChangedManually() {
        SharedPreferences.Editor ed = preferences.edit();
        ed.putBoolean("VOLUME_MANUALLY_CHANGED", true);
        ed.putLong("VOLUME_MANUALLY_CHANGED_TIME", System.currentTimeMillis());
        ed.apply();
        writeDebugEvent("Manual volume change",
                "Manual volume change during quiet period. The app will not change volume when the incoming call comes.");
    }

    public void clearRingerChangedManually() {
        if (preferences.getBoolean("VOLUME_MANUALLY_CHANGED", false)) {
            writeDebugEvent("Reset Manual volume change", "Resetting manual volume change flag");
        }
        SharedPreferences.Editor ed = preferences.edit();
        ed.remove("VOLUME_MANUALLY_CHANGED");
        ed.remove("VOLUME_MANUALLY_CHANGED_TIME");
        ed.apply();
    }

    public boolean isRingerChangedManually() {
        return preferences.getBoolean("VOLUME_MANUALLY_CHANGED", false);
    }
}