se.bitcraze.crazyfliecontrol.prefs.PreferencesActivity.java Source code

Java tutorial

Introduction

Here is the source code for se.bitcraze.crazyfliecontrol.prefs.PreferencesActivity.java

Source

/**
 *    ||          ____  _ __
 * +------+      / __ )(_) /_______________ _____  ___
 * | 0xBC |     / __  / / __/ ___/ ___/ __ `/_  / / _ \
 * +------+    / /_/ / / /_/ /__/ /  / /_/ / / /_/  __/
 *  ||  ||    /_____/_/\__/\___/_/   \__,_/ /___/\___/
 *
 * Copyright (C) 2013 Bitcraze AB
 *
 * Crazyflie Nano Quadcopter Client
 *
 * 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 2
 * 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, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 *
 */

package se.bitcraze.crazyfliecontrol.prefs;

import java.io.IOException;

import se.bitcraze.crazyflie.lib.crazyradio.ConnectionData;
import se.bitcraze.crazyflie.lib.crazyradio.Crazyradio;
import se.bitcraze.crazyfliecontrol.prefs.SelectConnectionDialogFragment.SelectCrazyflieDialogListener;
import se.bitcraze.crazyfliecontrol2.R;
import se.bitcraze.crazyfliecontrol2.UsbLinkAndroid;
import android.annotation.TargetApi;
import android.app.ActionBar;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.content.pm.ActivityInfo;
import android.hardware.Sensor;
import android.hardware.SensorManager;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.preference.CheckBoxPreference;
import android.preference.Preference;
import android.preference.Preference.OnPreferenceClickListener;
import android.preference.PreferenceActivity;
import android.preference.PreferenceFragment;
import android.preference.PreferenceManager;
import android.support.v4.app.NavUtils;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.MenuItem;
import android.widget.Toast;

public class PreferencesActivity extends PreferenceActivity {

    private static final String LOG_TAG = "PreferencesActivity";

    public static final String KEY_PREF_RADIO_CHANNEL = "pref_radiochannel";
    public static final String KEY_PREF_RADIO_DATARATE = "pref_radiodatarate";
    public static final String KEY_PREF_RADIO_SCAN = "pref_radio_scan";
    public static final String KEY_PREF_RADIO_STATS = "pref_radio_stats";
    public static final String KEY_PREF_BLATENCY_BOOL = "pref_blatency_bool";

    public static final String KEY_PREF_MODE = "pref_mode";
    public static final String KEY_PREF_DEADZONE = "pref_deadzone";
    public static final String KEY_PREF_ROLLTRIM = "pref_rolltrim";
    public static final String KEY_PREF_PITCHTRIM = "pref_pitchtrim";
    public static final String KEY_PREF_AFC_BOOL = "pref_afc_bool";
    public static final String KEY_PREF_AFC_SCREEN = "pref_afc_screen";
    public static final String KEY_PREF_MAX_ROLLPITCH_ANGLE = "pref_maxrollpitchangle";
    public static final String KEY_PREF_MAX_YAW_ANGLE = "pref_maxyawangle";
    public static final String KEY_PREF_MAX_THRUST = "pref_maxthrust";
    public static final String KEY_PREF_MIN_THRUST = "pref_minthrust";
    public static final String KEY_PREF_XMODE = "pref_xmode";
    public static final String KEY_PREF_RESET_AFC = "pref_reset_afc";

    public static final String KEY_PREF_CONTROLLER = "pref_controller";
    public static final String KEY_PREF_USE_GYRO_BOOL = "pref_use_gyro_bool";
    public static final String KEY_PREF_GYRO_AMP = "pref_gyro_amp";
    public static final String KEY_PREF_BTN_SCREEN = "pref_btn_screen";
    public static final String KEY_PREF_TOUCH_THRUST_FULL_TRAVEL = "pref_touch_thrust_full_travel";
    public static final String KEY_PREF_RIGHT_ANALOG_X_AXIS = "pref_right_analog_x_axis";
    public static final String KEY_PREF_RIGHT_ANALOG_Y_AXIS = "pref_right_analog_y_axis";
    public static final String KEY_PREF_LEFT_ANALOG_X_AXIS = "pref_left_analog_x_axis";
    public static final String KEY_PREF_LEFT_ANALOG_Y_AXIS = "pref_left_analog_y_axis";
    public static final String KEY_PREF_SPLITAXIS_YAW_BOOL = "pref_splitaxis_yaw_bool";
    public static final String KEY_PREF_SPLITAXIS_YAW_LEFT_AXIS = "pref_splitaxis_yaw_left_axis";
    public static final String KEY_PREF_SPLITAXIS_YAW_RIGHT_AXIS = "pref_splitaxis_yaw_right_axis";
    public static final String KEY_PREF_EMERGENCY_BTN = "pref_emergency_btn";
    public static final String KEY_PREF_ROLLTRIM_PLUS_BTN = "pref_rolltrim_plus_btn";
    public static final String KEY_PREF_ROLLTRIM_MINUS_BTN = "pref_rolltrim_minus_btn";
    public static final String KEY_PREF_PITCHTRIM_PLUS_BTN = "pref_pitchtrim_plus_btn";
    public static final String KEY_PREF_PITCHTRIM_MINUS_BTN = "pref_pitchtrim_minus_btn";
    public static final String KEY_PREF_RESET_BTN = "pref_reset_btn";
    public static final String KEY_PREF_ALT1_BTN = "pref_alt1_btn";
    public static final String KEY_PREF_ALT1_ACTION = "pref_alt1_action";
    public static final String KEY_PREF_ALT2_BTN = "pref_alt2_btn";
    public static final String KEY_PREF_ALT2_ACTION = "pref_alt2_action";
    public static final String KEY_PREF_HOVER_BTN = "pref_hover_btn";

    public static final String KEY_PREF_JOYSTICK_SIZE = "pref_touch_slider_size";

    public static final String KEY_PREF_SCREEN_ROTATION_LOCK_BOOL = "pref_screen_rotation_lock_bool";
    public static final String KEY_PREF_IMMERSIVE_MODE_BOOL = "pref_immersive_mode_bool";

    private static final int RADIOCHANNEL_UPPER_LIMIT = 125;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // Display the fragment as the main content.
        getFragmentManager().beginTransaction().replace(android.R.id.content, new PreferencesFragment()).commit();

        this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE);

        setupActionBar();
    }

    public static class PreferencesFragment extends PreferenceFragment implements OnSharedPreferenceChangeListener {
        private SharedPreferences mSharedPreferences;

        private String mRadioChannelDefaultValue;
        private String mDeadzoneDefaultValue;
        private String mMaxRollPitchAngleDefaultValue;
        private String mMaxYawAngleDefaultValue;
        private String mMaxThrustDefaultValue;
        private String mMinThrustDefaultValue;

        private String mGyroAmpDefaultValue;

        private String mJoystickSizeDefaultValue;

        private String mRightAnalogXAxisDefaultValue;
        private String mRightAnalogYAxisDefaultValue;
        private String mLeftAnalogXAxisDefaultValue;
        private String mLeftAnalogYAxisDefaultValue;
        private String mSplitAxisLeftAxisDefaultValue;
        private String mSplitAxisRightAxisDefaultValue;
        private String mEmergencyBtnDefaultValue;
        private String mRollTrimPlusBtnDefaultValue;
        private String mRollTrimMinusBtnDefaultValue;
        private String mPitchTrimPlusBtnDefaultValue;
        private String mPitchTrimMinusBtnDefaultValue;
        private String mAlt1BtnDefaultValue;
        private String mAlt2BtnDefaultValue;
        private String mHoverBtnDefaultValue;

        private String[] mDatarateStrings;

        private boolean mNoGyroSensor = false;

        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);

            // Make sure default values are applied.  In a real app, you would
            // want this in a shared function that is used to retrieve the
            // SharedPreferences wherever they are needed.
            //            PreferenceManager.setDefaultValues(getActivity(), R.xml.advanced_preferences, false);

            // Load the preferences from an XML resource
            addPreferencesFromResource(R.xml.preferences);

            mSharedPreferences = PreferenceManager.getDefaultSharedPreferences(getActivity());
            setInitialSummaries();

            mDatarateStrings = getResources().getStringArray(R.array.radioDatarateEntries);
        }

        /**
         * Set initial summaries and get default values
         */
        private void setInitialSummaries() {
            // Connection settings
            mRadioChannelDefaultValue = setInitialSummaryAndReturnDefaultValue(KEY_PREF_RADIO_CHANNEL,
                    R.string.preferences_radio_channel_defaultValue);
            setSummaryArray(KEY_PREF_RADIO_DATARATE, R.string.preferences_radio_datarate_defaultValue,
                    R.array.radioDatarateEntries, 0);
            findPreference(KEY_PREF_RADIO_SCAN).setOnPreferenceClickListener(new OnPreferenceClickListener() {

                @Override
                public boolean onPreferenceClick(Preference preference) {
                    radioScan();
                    return true;
                }
            });

            //Radio stats
            setRadioStats();
            findPreference(KEY_PREF_RADIO_STATS).setOnPreferenceClickListener(new OnPreferenceClickListener() {

                @Override
                public boolean onPreferenceClick(Preference preference) {
                    setRadioStats();
                    return true;
                }
            });

            // Flight control settings
            setSummaryArray(KEY_PREF_MODE, R.string.preferences_mode_defaultValue, R.array.modeEntries, -1);

            mDeadzoneDefaultValue = setInitialSummaryAndReturnDefaultValue(KEY_PREF_DEADZONE,
                    R.string.preferences_deadzone_defaultValue);
            setInitialSummaryAndReturnDefaultValue(KEY_PREF_PITCHTRIM, R.string.preferences_trim_defaultValue);

            // Controller settings
            setSummaryArray(KEY_PREF_CONTROLLER, R.string.preferences_controller_defaultValue,
                    R.array.controllerEntries, 0);
            setControllerSpecificPreferences();
            mGyroAmpDefaultValue = setInitialSummaryAndReturnDefaultValue(KEY_PREF_GYRO_AMP,
                    R.string.preferences_gyro_amp_defaultValue);
            mJoystickSizeDefaultValue = setInitialSummaryAndReturnDefaultValue(KEY_PREF_JOYSTICK_SIZE,
                    R.string.preferences_joystick_size_defaultValue);

            // Gamepad and button mapping
            mRightAnalogXAxisDefaultValue = setInitialSummaryAndReturnDefaultValue(KEY_PREF_RIGHT_ANALOG_X_AXIS,
                    R.string.preferences_right_analog_x_axis_defaultValue);
            mRightAnalogYAxisDefaultValue = setInitialSummaryAndReturnDefaultValue(KEY_PREF_RIGHT_ANALOG_Y_AXIS,
                    R.string.preferences_right_analog_y_axis_defaultValue);
            mLeftAnalogXAxisDefaultValue = setInitialSummaryAndReturnDefaultValue(KEY_PREF_LEFT_ANALOG_X_AXIS,
                    R.string.preferences_left_analog_x_axis_defaultValue);
            mLeftAnalogYAxisDefaultValue = setInitialSummaryAndReturnDefaultValue(KEY_PREF_LEFT_ANALOG_Y_AXIS,
                    R.string.preferences_left_analog_y_axis_defaultValue);

            findPreference(KEY_PREF_SPLITAXIS_YAW_LEFT_AXIS)
                    .setEnabled(mSharedPreferences.getBoolean(KEY_PREF_SPLITAXIS_YAW_BOOL, false));
            findPreference(KEY_PREF_SPLITAXIS_YAW_RIGHT_AXIS)
                    .setEnabled(mSharedPreferences.getBoolean(KEY_PREF_SPLITAXIS_YAW_BOOL, false));
            mSplitAxisLeftAxisDefaultValue = setInitialSummaryAndReturnDefaultValue(
                    KEY_PREF_SPLITAXIS_YAW_LEFT_AXIS, R.string.preferences_splitaxis_yaw_left_axis_defaultValue);
            mSplitAxisRightAxisDefaultValue = setInitialSummaryAndReturnDefaultValue(
                    KEY_PREF_SPLITAXIS_YAW_RIGHT_AXIS, R.string.preferences_splitaxis_yaw_right_axis_defaultValue);

            mEmergencyBtnDefaultValue = setInitialSummaryAndReturnDefaultValue(KEY_PREF_EMERGENCY_BTN,
                    R.string.preferences_emergency_btn_defaultValue);
            mRollTrimPlusBtnDefaultValue = setInitialSummaryAndReturnDefaultValue(KEY_PREF_ROLLTRIM_PLUS_BTN,
                    R.string.preferences_rolltrim_plus_btn_defaultValue);
            mRollTrimMinusBtnDefaultValue = setInitialSummaryAndReturnDefaultValue(KEY_PREF_ROLLTRIM_MINUS_BTN,
                    R.string.preferences_rolltrim_minus_btn_defaultValue);
            mPitchTrimPlusBtnDefaultValue = setInitialSummaryAndReturnDefaultValue(KEY_PREF_PITCHTRIM_PLUS_BTN,
                    R.string.preferences_pitchtrim_plus_btn_defaultValue);
            mPitchTrimMinusBtnDefaultValue = setInitialSummaryAndReturnDefaultValue(KEY_PREF_PITCHTRIM_MINUS_BTN,
                    R.string.preferences_pitchtrim_minus_btn_defaultValue);
            mAlt1BtnDefaultValue = setInitialSummaryAndReturnDefaultValue(KEY_PREF_ALT1_BTN,
                    R.string.preferences_alt1_btn_defaultValue);
            setSummaryArrayString(KEY_PREF_ALT1_ACTION, R.string.preferences_alt1_action_defaultValue,
                    R.array.actionEntries, R.array.actionValues);
            mAlt2BtnDefaultValue = setInitialSummaryAndReturnDefaultValue(KEY_PREF_ALT2_BTN,
                    R.string.preferences_alt2_btn_defaultValue);
            setSummaryArrayString(KEY_PREF_ALT2_ACTION, R.string.preferences_alt2_action_defaultValue,
                    R.array.actionEntries, R.array.actionValues);
            mHoverBtnDefaultValue = setInitialSummaryAndReturnDefaultValue(KEY_PREF_HOVER_BTN,
                    R.string.preferences_hover_btn_defaultValue);

            findPreference(KEY_PREF_RESET_BTN).setOnPreferenceClickListener(new OnPreferenceClickListener() {

                @Override
                public boolean onPreferenceClick(Preference preference) {
                    resetPreference(KEY_PREF_RIGHT_ANALOG_X_AXIS, mRightAnalogXAxisDefaultValue, null);
                    resetPreference(KEY_PREF_RIGHT_ANALOG_Y_AXIS, mRightAnalogYAxisDefaultValue, null);
                    resetPreference(KEY_PREF_LEFT_ANALOG_X_AXIS, mLeftAnalogXAxisDefaultValue, null);
                    resetPreference(KEY_PREF_LEFT_ANALOG_Y_AXIS, mLeftAnalogYAxisDefaultValue, null);
                    resetPreference(KEY_PREF_SPLITAXIS_YAW_BOOL, false);
                    resetPreference(KEY_PREF_SPLITAXIS_YAW_LEFT_AXIS, mSplitAxisLeftAxisDefaultValue, null);
                    resetPreference(KEY_PREF_SPLITAXIS_YAW_RIGHT_AXIS, mSplitAxisRightAxisDefaultValue, null);

                    resetPreference(KEY_PREF_EMERGENCY_BTN, mEmergencyBtnDefaultValue, null);
                    resetPreference(KEY_PREF_ROLLTRIM_PLUS_BTN, mRollTrimPlusBtnDefaultValue, null);
                    resetPreference(KEY_PREF_ROLLTRIM_MINUS_BTN, mRollTrimMinusBtnDefaultValue, null);
                    resetPreference(KEY_PREF_PITCHTRIM_PLUS_BTN, mPitchTrimPlusBtnDefaultValue, null);
                    resetPreference(KEY_PREF_PITCHTRIM_MINUS_BTN, mPitchTrimMinusBtnDefaultValue, null);
                    resetPreference(KEY_PREF_ALT1_BTN, mAlt1BtnDefaultValue, null);
                    resetPreference(KEY_PREF_ALT2_BTN, mAlt2BtnDefaultValue, null);
                    resetPreference(KEY_PREF_HOVER_BTN, mHoverBtnDefaultValue, null);
                    Toast.makeText(getActivity(), "Resetting to default values...", Toast.LENGTH_SHORT).show();
                    return true;
                }
            });

            // Advanced flight control settings
            findPreference(KEY_PREF_AFC_SCREEN).setEnabled(mSharedPreferences.getBoolean(KEY_PREF_AFC_BOOL, false));

            mMaxRollPitchAngleDefaultValue = setInitialSummaryAndReturnDefaultValue(KEY_PREF_MAX_ROLLPITCH_ANGLE,
                    R.string.preferences_maxRollPitchAngle_defaultValue);
            mMaxYawAngleDefaultValue = setInitialSummaryAndReturnDefaultValue(KEY_PREF_MAX_YAW_ANGLE,
                    R.string.preferences_maxYawAngle_defaultValue);
            mMaxThrustDefaultValue = setInitialSummaryAndReturnDefaultValue(KEY_PREF_MAX_THRUST,
                    R.string.preferences_maxThrust_defaultValue);
            mMinThrustDefaultValue = setInitialSummaryAndReturnDefaultValue(KEY_PREF_MIN_THRUST,
                    R.string.preferences_minThrust_defaultValue);

            findPreference(KEY_PREF_RESET_AFC).setOnPreferenceClickListener(new OnPreferenceClickListener() {

                @Override
                public boolean onPreferenceClick(Preference preference) {
                    resetPreference(KEY_PREF_MAX_ROLLPITCH_ANGLE, mMaxRollPitchAngleDefaultValue, null);
                    resetPreference(KEY_PREF_MAX_YAW_ANGLE, mMaxYawAngleDefaultValue, null);
                    resetPreference(KEY_PREF_MAX_THRUST, mMaxThrustDefaultValue, null);
                    resetPreference(KEY_PREF_MIN_THRUST, mMinThrustDefaultValue, null);
                    resetPreference(KEY_PREF_XMODE, false);
                    return true;
                }
            });
        }

        private void checkGyroSensors() {
            //Test the available sensors
            SensorManager sensorManager = (SensorManager) getActivity().getSystemService(Context.SENSOR_SERVICE);
            CheckBoxPreference pref = (CheckBoxPreference) findPreference(KEY_PREF_USE_GYRO_BOOL);

            if (sensorManager.getDefaultSensor(Sensor.TYPE_ROTATION_VECTOR) == null
                    && sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER) == null) {
                pref.setEnabled(false);
                pref.setChecked(false);
                resetPreference(KEY_PREF_USE_GYRO_BOOL, false);
                mNoGyroSensor = true;
                pref.setSummaryOff("No gyro or accelerometer sensors found");
                Log.i(LOG_TAG, "No gyro or accelerometer sensors found");
            } else {
                pref.setEnabled(true);
                mNoGyroSensor = false;
            }
        }

        private void setRadioStats() {
            Preference prefRadioStats = findPreference(KEY_PREF_RADIO_STATS);
            String defaultValue = getResources().getString(R.string.preferences_radio_stats_summary);

            UsbLinkAndroid usbLinkAndroid = null;

            try {
                usbLinkAndroid = new UsbLinkAndroid(getActivity());
                if (usbLinkAndroid != null) {
                    usbLinkAndroid.initDevice(Crazyradio.CRADIO_VID, Crazyradio.CRADIO_PID);
                    if (usbLinkAndroid.isUsbConnected()) {
                        prefRadioStats.setSummary("Firmware version: " + usbLinkAndroid.getFirmwareVersion() + "\n"
                                + "Serial number: " + usbLinkAndroid.getSerialNumber());
                        enableDisableRadioSettings(true);
                    } else {
                        prefRadioStats.setSummary(defaultValue);
                        enableDisableRadioSettings(false);
                    }
                } else {
                    prefRadioStats.setSummary(defaultValue);
                    enableDisableRadioSettings(false);
                }
            } catch (IllegalArgumentException e) {
                Log.d(LOG_TAG, e.getMessage());
                prefRadioStats.setSummary(defaultValue);
                enableDisableRadioSettings(false);
            } catch (IOException iae) {
                Log.e(LOG_TAG, iae.getMessage());
                prefRadioStats.setSummary(defaultValue);
                enableDisableRadioSettings(false);
            } finally {
                if (usbLinkAndroid != null) {
                    usbLinkAndroid.releaseInterface();
                }
            }
        }

        private void enableDisableRadioSettings(boolean enable) {
            findPreference(KEY_PREF_RADIO_CHANNEL).setEnabled(enable);
            findPreference(KEY_PREF_RADIO_DATARATE).setEnabled(enable);
            findPreference(KEY_PREF_RADIO_SCAN).setEnabled(enable);
            findPreference(KEY_PREF_RADIO_STATS).setEnabled(enable);
        }

        // Set summary to be the user-description for the selected value
        public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
            // Connection settings
            if (key.equals(KEY_PREF_RADIO_CHANNEL)) {
                setSummaryInt(key, mRadioChannelDefaultValue, RADIOCHANNEL_UPPER_LIMIT, "Radio channel");
            }
            if (key.equals(KEY_PREF_RADIO_DATARATE)) {
                setSummaryArray(key, R.string.preferences_radio_datarate_defaultValue, R.array.radioDatarateEntries,
                        0);
            }

            // Flight control settings
            if (key.equals(KEY_PREF_MODE)) {
                setSummaryArray(key, R.string.preferences_mode_defaultValue, R.array.modeEntries, -1);
            }
            if (key.equals(KEY_PREF_DEADZONE)) {
                findPreference(key).setSummary(sharedPreferences.getString(key, mDeadzoneDefaultValue));
            }

            // Controller settings
            if (key.equals(KEY_PREF_CONTROLLER)) {
                setSummaryArray(key, R.string.preferences_controller_defaultValue, R.array.controllerEntries, 0);
                setControllerSpecificPreferences();
            }

            if (key.equals(KEY_PREF_USE_GYRO_BOOL)) {
                CheckBoxPreference pref = (CheckBoxPreference) findPreference(key);
                boolean useGyro = sharedPreferences.getBoolean(key, false);
                pref.setChecked(useGyro);
                // automatically activate the screen rotation lock preference
                CheckBoxPreference screenRotationLock = (CheckBoxPreference) findPreference(
                        KEY_PREF_SCREEN_ROTATION_LOCK_BOOL);
                if (useGyro) {
                    Toast.makeText(getActivity(), "Activating screen rotation lock...", Toast.LENGTH_LONG).show();
                    screenRotationLock.setSummary("Locked because gyroscope is used as controller.");
                } else {
                    Toast.makeText(getActivity(), "Deactivating screen rotation lock...", Toast.LENGTH_LONG).show();
                    screenRotationLock.setSummary("");
                }
                screenRotationLock.setChecked(useGyro);
                screenRotationLock.setEnabled(!useGyro);

                SliderPreference gyroAmp = (SliderPreference) findPreference(KEY_PREF_GYRO_AMP);
                gyroAmp.setEnabled(useGyro);
            }

            if (key.equals(KEY_PREF_GYRO_AMP)) {
                findPreference(key).setSummary(sharedPreferences.getString(key, mGyroAmpDefaultValue));
            }

            if (key.equals(KEY_PREF_JOYSTICK_SIZE)) {
                findPreference(key).setSummary(sharedPreferences.getString(key, mJoystickSizeDefaultValue));
            }

            // Gamepad and button mapping
            if (key.equals(KEY_PREF_RIGHT_ANALOG_X_AXIS)) {
                findPreference(key).setSummary(sharedPreferences.getString(key, mRightAnalogXAxisDefaultValue));
            }
            if (key.equals(KEY_PREF_RIGHT_ANALOG_Y_AXIS)) {
                findPreference(key).setSummary(sharedPreferences.getString(key, mRightAnalogYAxisDefaultValue));
            }
            if (key.equals(KEY_PREF_LEFT_ANALOG_X_AXIS)) {
                findPreference(key).setSummary(sharedPreferences.getString(key, mLeftAnalogXAxisDefaultValue));
            }
            if (key.equals(KEY_PREF_LEFT_ANALOG_Y_AXIS)) {
                findPreference(key).setSummary(sharedPreferences.getString(key, mLeftAnalogYAxisDefaultValue));
            }

            if (key.equals(KEY_PREF_SPLITAXIS_YAW_BOOL)) {
                CheckBoxPreference pref = (CheckBoxPreference) findPreference(key);
                pref.setChecked(sharedPreferences.getBoolean(key, false));
                findPreference(KEY_PREF_SPLITAXIS_YAW_LEFT_AXIS)
                        .setEnabled(sharedPreferences.getBoolean(key, false));
                findPreference(KEY_PREF_SPLITAXIS_YAW_RIGHT_AXIS)
                        .setEnabled(sharedPreferences.getBoolean(key, false));
            }

            if (key.equals(KEY_PREF_SPLITAXIS_YAW_LEFT_AXIS)) {
                findPreference(key).setSummary(sharedPreferences.getString(key, mSplitAxisLeftAxisDefaultValue));
            }
            if (key.equals(KEY_PREF_SPLITAXIS_YAW_RIGHT_AXIS)) {
                findPreference(key).setSummary(sharedPreferences.getString(key, mSplitAxisRightAxisDefaultValue));
            }
            if (key.equals(KEY_PREF_EMERGENCY_BTN)) {
                findPreference(key).setSummary(sharedPreferences.getString(key, mEmergencyBtnDefaultValue));
            }
            if (key.equals(KEY_PREF_ROLLTRIM_PLUS_BTN)) {
                findPreference(key).setSummary(sharedPreferences.getString(key, mRollTrimPlusBtnDefaultValue));
            }
            if (key.equals(KEY_PREF_ROLLTRIM_MINUS_BTN)) {
                findPreference(key).setSummary(sharedPreferences.getString(key, mRollTrimMinusBtnDefaultValue));
            }
            if (key.equals(KEY_PREF_PITCHTRIM_PLUS_BTN)) {
                findPreference(key).setSummary(sharedPreferences.getString(key, mPitchTrimPlusBtnDefaultValue));
            }
            if (key.equals(KEY_PREF_PITCHTRIM_MINUS_BTN)) {
                findPreference(key).setSummary(sharedPreferences.getString(key, mPitchTrimMinusBtnDefaultValue));
            }
            if (key.equals(KEY_PREF_ALT1_BTN)) {
                findPreference(key).setSummary(sharedPreferences.getString(key, mAlt1BtnDefaultValue));
            }
            if (key.equals(KEY_PREF_ALT2_BTN)) {
                findPreference(key).setSummary(sharedPreferences.getString(key, mAlt2BtnDefaultValue));
            }
            if (key.equals(KEY_PREF_HOVER_BTN)) {
                findPreference(key).setSummary(sharedPreferences.getString(key, mHoverBtnDefaultValue));
            }

            if (key.equals(KEY_PREF_ALT1_ACTION)) {
                setSummaryArrayString(key, R.string.preferences_alt1_action_defaultValue, R.array.actionEntries,
                        R.array.actionValues);
            }
            if (key.equals(KEY_PREF_ALT2_ACTION)) {
                setSummaryArrayString(key, R.string.preferences_alt2_action_defaultValue, R.array.actionEntries,
                        R.array.actionValues);
            }

            // Advanced flight control settings
            if (key.equals(KEY_PREF_AFC_BOOL)) {
                Preference afcScreenPref = findPreference(KEY_PREF_AFC_SCREEN);
                afcScreenPref.setEnabled(sharedPreferences.getBoolean(key, false));
                if (!sharedPreferences.getBoolean(key, false)) {
                    Toast.makeText(getActivity(),
                            "Resetting to default values:\n" + "Max roll/pitch angle: "
                                    + mMaxRollPitchAngleDefaultValue + "\n" + "Max yaw angle: "
                                    + mMaxYawAngleDefaultValue + "\n" + "Max thrust: " + mMaxThrustDefaultValue
                                    + "\n" + "Min thrust: " + mMinThrustDefaultValue,
                            Toast.LENGTH_LONG).show();
                } else {
                    Toast.makeText(getActivity(), "You have been warned!", Toast.LENGTH_LONG).show();
                }
            }
            if (key.equals(KEY_PREF_MAX_ROLLPITCH_ANGLE)) {
                findPreference(key).setSummary(sharedPreferences.getString(key, mMaxRollPitchAngleDefaultValue));
            }
            if (key.equals(KEY_PREF_MAX_YAW_ANGLE)) {
                findPreference(key).setSummary(sharedPreferences.getString(key, mMaxYawAngleDefaultValue));
            }
            if (key.equals(KEY_PREF_MAX_THRUST)) {
                findPreference(key).setSummary(sharedPreferences.getString(key, mMaxThrustDefaultValue));
            }
            if (key.equals(KEY_PREF_MIN_THRUST)) {
                findPreference(key).setSummary(sharedPreferences.getString(key, mMinThrustDefaultValue));
            }
            if (key.equals(KEY_PREF_XMODE)) {
                CheckBoxPreference pref = (CheckBoxPreference) findPreference(key);
                pref.setChecked(sharedPreferences.getBoolean(key, false));
            }

            // App settings
            if (key.equals(KEY_PREF_SCREEN_ROTATION_LOCK_BOOL)) {
                CheckBoxPreference pref = (CheckBoxPreference) findPreference(key);
                pref.setChecked(sharedPreferences.getBoolean(key, false));
            }
            if (key.equals(KEY_PREF_IMMERSIVE_MODE_BOOL)) {
                CheckBoxPreference pref = (CheckBoxPreference) findPreference(key);
                pref.setChecked(sharedPreferences.getBoolean(key, false));
            }
        }

        private void setControllerSpecificPreferences() {
            String controllerDefaultValue = getResources().getString(R.string.preferences_controller_defaultValue);
            int controllerIndex = Integer
                    .parseInt(mSharedPreferences.getString(KEY_PREF_CONTROLLER, controllerDefaultValue));
            boolean useGyro = mSharedPreferences.getBoolean(KEY_PREF_USE_GYRO_BOOL, false);
            if (!mNoGyroSensor) {
                findPreference(KEY_PREF_USE_GYRO_BOOL).setEnabled(controllerIndex == 0);
                findPreference(KEY_PREF_GYRO_AMP).setEnabled(controllerIndex == 0 && useGyro);
            }
            findPreference(KEY_PREF_BTN_SCREEN).setEnabled(controllerIndex == 1);
            findPreference(KEY_PREF_TOUCH_THRUST_FULL_TRAVEL).setEnabled(controllerIndex == 0);
            findPreference(KEY_PREF_JOYSTICK_SIZE).setEnabled(controllerIndex == 0);
        }

        private String setInitialSummaryAndReturnDefaultValue(String pKey, int pRDefaultValue) {
            Preference pref = findPreference(pKey);
            String defaultValue = getResources().getString(pRDefaultValue);
            pref.setSummary(mSharedPreferences.getString(pKey, defaultValue));
            return defaultValue;
        }

        private void setSummaryInt(String key, String pDefaultValue, int pUpperLimit, String pValueName) {
            Preference pref = findPreference(key);
            try {
                int newPrefValue = Integer.parseInt(mSharedPreferences.getString(key, pDefaultValue));
                if (newPrefValue < 0 || newPrefValue > pUpperLimit) {
                    resetPreference(key, pDefaultValue,
                            pValueName + " must be an integer value between 0 and " + pUpperLimit + ".");
                }
            } catch (NumberFormatException nfe) {
                resetPreference(key, pDefaultValue,
                        pValueName + " must be an integer value between 0 and " + pUpperLimit + ".");
            }
            pref.setSummary(mSharedPreferences.getString(key, ""));
        }

        private void setSummaryArray(String key, int pRDefaultValue, int pRArray, int arrayOffset) {
            Preference pref = findPreference(key);
            String preDefaultValue = getResources().getString(pRDefaultValue);
            String[] stringArray = getResources().getStringArray(pRArray);
            String keyString = mSharedPreferences.getString(key, preDefaultValue);
            pref.setSummary(stringArray[Integer.parseInt(keyString) + arrayOffset]);
        }

        private void setSummaryArrayString(String key, int pRDefaultValue, int pRArrayEntries, int pRArrayValues) {
            Preference pref = findPreference(key);
            String preDefaultValue = getResources().getString(pRDefaultValue);
            String[] stringArrayEntries = getResources().getStringArray(pRArrayEntries);
            String[] stringArrayValues = getResources().getStringArray(pRArrayValues);
            String keyString = mSharedPreferences.getString(key, preDefaultValue);
            for (int i = 0; i < stringArrayValues.length; i++) {
                if (keyString.equals(stringArrayValues[i])) {
                    pref.setSummary(stringArrayEntries[i]);
                }
            }
        }

        private void resetPreference(String pKey, String pDefaultValue, String pErrorMessage) {
            if (pErrorMessage != null) {
                Toast.makeText(getActivity(), pErrorMessage + "\nResetting to default value " + pDefaultValue + ".",
                        Toast.LENGTH_SHORT).show();
            }
            SharedPreferences.Editor editor = mSharedPreferences.edit();
            editor.putString(pKey, pDefaultValue);
            editor.apply();
        }

        private void resetPreference(String pKey, boolean pDefaultValue) {
            SharedPreferences.Editor editor = mSharedPreferences.edit();
            editor.putBoolean(pKey, pDefaultValue);
            editor.apply();
        }

        @Override
        public void onResume() {
            super.onResume();
            getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
            checkGyroSensors();
        }

        @Override
        public void onPause() {
            getPreferenceScreen().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this);
            super.onPause();
        }

        private void radioScan() {
            new AsyncTask<Void, Void, ConnectionData[]>() {

                private Exception mException = null;
                private ProgressDialog mProgress;

                @Override
                protected void onPreExecute() {
                    mProgress = ProgressDialog.show(getActivity(), "Radio Scan", "Searching for the Crazyflie...",
                            true, false);
                }

                @Override
                protected ConnectionData[] doInBackground(Void... arg0) {
                    UsbLinkAndroid usbLinkAndroid;
                    Crazyradio crlink = null;
                    try {
                        usbLinkAndroid = new UsbLinkAndroid(getActivity());
                        crlink = new Crazyradio(usbLinkAndroid);
                        if (!usbLinkAndroid.isUsbConnected()) {
                            throw new IllegalArgumentException("Scanning is only supported with Crazyradio.");
                        }
                        //For testing purposes only
                        //                        return new ConnectionData[0];
                        boolean useSlowScan = false;
                        //Use slow scan, when Crazyradio firmware version is 0.52 or 0.53
                        float firmwareVersion = usbLinkAndroid.getFirmwareVersion();
                        if (0.52f == firmwareVersion || 0.53f == firmwareVersion) {
                            useSlowScan = true;
                        }
                        return crlink.scanChannels(useSlowScan);
                    } catch (IOException ioe) {
                        mException = ioe;
                        return new ConnectionData[0];
                    } catch (IllegalArgumentException iae) {
                        mException = iae;
                        return new ConnectionData[0];
                    } finally {
                        if (crlink != null) {
                            crlink.disconnect();
                        }
                    }
                }

                @Override
                protected void onPostExecute(ConnectionData[] result) {
                    mProgress.dismiss();

                    if (mException != null) {
                        Toast.makeText(getActivity(), mException.getMessage(), Toast.LENGTH_SHORT).show();
                    } else {
                        //TEST DATA for debugging SelectionConnectionDialogFragment (replace with test!)
                        //                      result = new ConnectionData[3];
                        //                      result[0] = new ConnectionData(13, 2);
                        //                      result[1] = new ConnectionData(15, 1);
                        //                      result[2] = new ConnectionData(125, 2);

                        if (result != null && result.length > 0) {
                            if (result.length > 1) {
                                // let user choose connection, if there is more than one Crazyflie
                                showSelectConnectionDialog(result);
                            } else {
                                // use first channel
                                setRadioChannelAndDatarate(result[0].getChannel(), result[0].getDataRate());
                            }
                        } else {
                            Toast.makeText(getActivity(), "No connection found", Toast.LENGTH_SHORT).show();
                        }
                    }
                }
            }.execute();
        }

        private void showSelectConnectionDialog(final ConnectionData[] result) {
            SelectConnectionDialogFragment selectConnectionDialogFragment = new SelectConnectionDialogFragment();
            //supply list of Crazyflie connections as arguments
            Bundle args = new Bundle();
            String[] crazyflieArray = new String[result.length];
            for (int i = 0; i < result.length; i++) {
                crazyflieArray[i] = i + ": Channel " + result[i].getChannel() + ", Data rate "
                        + mDatarateStrings[result[i].getDataRate()];
            }
            args.putStringArray("connection_array", crazyflieArray);
            selectConnectionDialogFragment.setArguments(args);
            selectConnectionDialogFragment.setListener(new SelectCrazyflieDialogListener() {
                @Override
                public void onClick(int which) {
                    setRadioChannelAndDatarate(result[which].getChannel(), result[which].getDataRate());
                }
            });
            selectConnectionDialogFragment.show(getFragmentManager(), "select_crazyflie");
        }

        private void setRadioChannelAndDatarate(int channel, int datarate) {
            if (channel != -1 && datarate != -1) {
                SharedPreferences.Editor editor = mSharedPreferences.edit();
                editor.putString(PreferencesActivity.KEY_PREF_RADIO_CHANNEL, String.valueOf(channel));
                editor.putString(PreferencesActivity.KEY_PREF_RADIO_DATARATE, String.valueOf(datarate));
                editor.apply();

                Toast.makeText(getActivity(), "Channel: " + channel + " Data rate: " + mDatarateStrings[datarate]
                        + "\nSetting preferences...", Toast.LENGTH_SHORT).show();
            }
        }

    }

    /**
     * Set default joystick size according to screen size
     *
     * @param context
     */
    public static void setDefaultJoystickSize(Context context) {
        SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context);

        // If no default value exists, set new default value according to screen size
        if (!sharedPreferences.contains(KEY_PREF_JOYSTICK_SIZE)) {
            String defaultValue = getDefaultJoystickSize(context);
            Log.d(LOG_TAG, "Prefs do NOT contain joystick size. Setting new default: " + defaultValue);

            SharedPreferences.Editor editor = sharedPreferences.edit();
            editor.putString(PreferencesActivity.KEY_PREF_JOYSTICK_SIZE, String.valueOf(defaultValue));
            editor.apply();
        } else {
            Log.d(LOG_TAG, "Prefs already contain joystick size.");
        }
    }

    /**
     * Set up the {@link android.app.ActionBar}, if the API is available.
     */
    @TargetApi(Build.VERSION_CODES.HONEYCOMB)
    private void setupActionBar() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
            final ActionBar actionBar = getActionBar();
            if (actionBar != null) {
                actionBar.setDisplayHomeAsUpEnabled(true);
            }
        }
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
        case android.R.id.home:
            NavUtils.navigateUpFromSameTask(this);
            return true;
        }
        return super.onOptionsItemSelected(item);
    }

    public static String getDefaultJoystickSize(Context context) {
        long screenSizeInInches = getScreenSizeInInches(context);
        int size = 100;
        if (screenSizeInInches >= 4) {
            size = 80;
        }
        if (screenSizeInInches >= 7) {
            size = 50;
        }
        if (screenSizeInInches >= 9) {
            size = 40;
        }
        if (screenSizeInInches >= 10) {
            size = 30;
        }
        return String.valueOf(size);
    }

    private static long getScreenSizeInInches(Context context) {
        DisplayMetrics dm = new DisplayMetrics();
        ((Activity) context).getWindowManager().getDefaultDisplay().getMetrics(dm);
        int dens = dm.densityDpi;
        double wi = (double) dm.widthPixels / (double) dens;
        double hi = (double) dm.heightPixels / (double) dens;
        double x = Math.pow(wi, 2);
        double y = Math.pow(hi, 2);
        return Math.round(Math.sqrt(x + y));
    }

}