/*
* This source is part of the
* _____ ___ ____
* __ / / _ \/ _ | / __/___ _______ _
* / // / , _/ __ |/ _/_/ _ \/ __/ _ `/
* \___/_/|_/_/ |_/_/ (_)___/_/ \_, /
* /___/
* repository.
*
* Copyright (C) 2013-2014 Benoit 'BoD' Lubek (BoD@JRAF.org)
* Copyright (C) 2017 Carmen Alvarez (c@rmen.ca)
*
* 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 org.jraf.android.bikey.app.preference;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.preference.ListPreference;
import android.preference.Preference;
import android.preference.Preference.OnPreferenceClickListener;
import android.preference.PreferenceCategory;
import android.preference.PreferenceFragment;
import android.preference.PreferenceManager;
import android.preference.SwitchPreference;
import android.widget.Toast;
import org.jraf.android.bikey.R;
import org.jraf.android.bikey.backend.heartrate.HeartRateListener;
import org.jraf.android.bikey.backend.heartrate.HeartRateManager;
import org.jraf.android.bikey.backend.provider.ride.RideColumns;
import org.jraf.android.bikey.common.Constants;
import org.jraf.android.bikey.common.UnitUtil;
import org.jraf.android.bikey.common.wear.WearCommHelper;
import org.jraf.android.bikey.util.MediaButtonUtil;
public class MainPreferenceFragment extends PreferenceFragment {
private PreferenceCallbacks mCallbacks;
@SuppressLint("InlinedApi")
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.preferences);
updateListPreferenceSummary(Constants.PREF_UNITS);
// Show heart rate section only if supported
boolean heartRateSupported = getActivity().getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE);
if (heartRateSupported) {
findPreference(Constants.PREF_HEART_RATE_SCAN).setOnPreferenceClickListener(mOnPreferenceClickListener);
} else {
PreferenceCategory preferenceCategory = (PreferenceCategory) findPreference(Constants.PREF_CATEGORY_HEART_RATE);
getPreferenceScreen().removePreference(preferenceCategory);
}
// The headset button implementation is easier if we support lollipop+ only.
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
PreferenceCategory preferenceCategory = (PreferenceCategory) findPreference(Constants.PREF_CATEGORY_GENERAL);
Preference headsetPreference = preferenceCategory.findPreference(Constants.PREF_LISTEN_TO_HEADSET_BUTTON);
preferenceCategory.removePreference(headsetPreference);
}
findPreference(Constants.PREF_EXPORT).setOnPreferenceClickListener(mOnPreferenceClickListener);
findPreference(Constants.PREF_IMPORT).setOnPreferenceClickListener(mOnPreferenceClickListener);
findPreference(Constants.SYNC_WITH_GOOGLE_DRIVE).setOnPreferenceClickListener(mOnPreferenceClickListener);
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
mCallbacks = (PreferenceCallbacks) activity;
}
@Override
public void onDetach() {
mCallbacks = null;
super.onDetach();
}
public PreferenceCallbacks getCallbacks() {
return mCallbacks;
}
@Override
public void onStart() {
super.onStart();
PreferenceManager.getDefaultSharedPreferences(getActivity()).registerOnSharedPreferenceChangeListener(mOnSharedPreferenceChangeListener);
// HeartRate
HeartRateManager heartRateManager = HeartRateManager.get();
heartRateManager.addListener(mHeartRateListener);
if (heartRateManager.isConnecting()) {
mHeartRateListener.onConnecting();
} else if (heartRateManager.isConnected()) {
mHeartRateListener.onConnected();
} else {
mHeartRateListener.onHeartRateChange(heartRateManager.getLastValue());
mHeartRateListener.onDisconnected();
}
}
@Override
public void onStop() {
PreferenceManager.getDefaultSharedPreferences(getActivity()).unregisterOnSharedPreferenceChangeListener(mOnSharedPreferenceChangeListener);
// HeartRate
HeartRateManager.get().removeListener(mHeartRateListener);
super.onStop();
}
private final OnSharedPreferenceChangeListener mOnSharedPreferenceChangeListener = (sharedPreferences, key) -> {
updateListPreferenceSummary(key);
switch (key) {
case Constants.PREF_UNITS:
// Update units
UnitUtil.readPreferences(getActivity());
// Propagate unit preferences to wearables
WearCommHelper.get().updatePreferences();
// Notify observers of rides since they display distances using a conversion depending on the preference
getActivity().getContentResolver().notifyChange(RideColumns.CONTENT_URI, null);
break;
case Constants.PREF_LISTEN_TO_HEADSET_BUTTON:
if (sharedPreferences.getBoolean(key, Constants.PREF_LISTEN_TO_HEADSET_BUTTON_DEFAULT)) {
MediaButtonUtil.registerMediaButtonEventReceiver(getActivity());
} else {
MediaButtonUtil.unregisterMediaButtonEventReceiver();
}
break;
case Constants.PREF_RECORD_CADENCE:
if (sharedPreferences.getBoolean(Constants.PREF_RECORD_CADENCE, Constants.PREF_RECORD_CADENCE_DEFAULT)) {
getCallbacks().showRecordCadenceConfirmDialog();
} else {
// The pref was unchecked because the user pressed 'No' in the confirmation dialog.
// Update the switch.
SwitchPreference pref = (SwitchPreference) getPreferenceManager().findPreference(Constants.PREF_RECORD_CADENCE);
pref.setChecked(false);
}
break;
}
};
private void updateListPreferenceSummary(String key) {
if (Constants.PREF_UNITS.equals(key)) {
ListPreference pref = (ListPreference) getPreferenceManager().findPreference(key);
CharSequence entry = pref.getEntry();
pref.setSummary(entry);
}
}
private OnPreferenceClickListener mOnPreferenceClickListener = preference -> {
if (Constants.PREF_EXPORT.equals(preference.getKey())) {
getCallbacks().startExport();
return true;
} else if (Constants.PREF_IMPORT.equals(preference.getKey())) {
getCallbacks().startImport();
return true;
} else if (Constants.SYNC_WITH_GOOGLE_DRIVE.equals(preference.getKey())) {
getCallbacks().syncWithGoogleDrive();
return true;
} else if (Constants.PREF_HEART_RATE_SCAN.equals(preference.getKey())) {
HeartRateManager heartRateManager = HeartRateManager.get();
if (heartRateManager.isConnected()) {
getCallbacks().disconnectHeartRateMonitor();
} else if (heartRateManager.isConnecting()) {
getCallbacks().tryToReconnectHeartRateMonitorOrGiveUp();
} else {
getCallbacks().startHeartRateMonitorScan();
}
return true;
}
return false;
};
private HeartRateListener mHeartRateListener = new HeartRateListener() {
@Override
public void onConnecting() {
Preference pref = getPreferenceManager().findPreference(Constants.PREF_HEART_RATE_SCAN);
pref.setTitle(R.string.preference_heartRate_connecting_title);
pref.setSummary(R.string.preference_heartRate_connecting_summary);
pref.setWidgetLayoutResource(R.layout.heart_rate_pref_widget_connecting);
}
@Override
public void onConnected() {
Preference pref = getPreferenceManager().findPreference(Constants.PREF_HEART_RATE_SCAN);
pref.setTitle(R.string.preference_heartRate_disconnect_title);
pref.setSummary(R.string.preference_heartRate_disconnect_summary);
pref.setWidgetLayoutResource(R.layout.heart_rate_pref_widget_connected);
}
@Override
public void onHeartRateChange(int bpm) {}
@Override
public void onDisconnected() {
Preference pref = getPreferenceManager().findPreference(Constants.PREF_HEART_RATE_SCAN);
if (pref == null) {
// Could be null here, on devices where BTLE is not supported
return;
}
pref.setEnabled(true);
pref.setTitle(R.string.preference_heartRate_scan_title);
pref.setSummary(R.string.preference_heartRate_scan_summary);
pref.setWidgetLayoutResource(0);
}
@Override
public void onError() {
Toast.makeText(getActivity(), R.string.preference_heartRate_bt_error, Toast.LENGTH_LONG).show();
}
};
}