1
0
mirror of https://codeberg.org/Freeyourgadget/Gadgetbridge synced 2024-12-25 18:15:49 +01:00

Make per-device settings more versatile, move more settings

This allows to construct per-device settings by device type very easily

device coordinators just do the following to declare which setting they support,
the settings activity is then composed at runtime.

@Override
public int[] getSupportedDeviceSpecificSettings(GBDevice device) {
     return new int[]{
            R.xml.devicesettings_miband3,
            R.xml.devicesettings_swipeunlock,
            R.xml.devicesettings_pairingkey
    };
}
This commit is contained in:
Andreas Shimokawa 2019-05-22 00:42:22 +02:00
parent 49667451d7
commit 9bfef4cf4f
32 changed files with 475 additions and 336 deletions

View File

@ -590,7 +590,7 @@ public class DiscoveryActivity extends AbstractGBActivity implements AdapterView
DeviceCoordinator coordinator = DeviceHelper.getInstance().getCoordinator(deviceCandidate);
GBDevice device = DeviceHelper.getInstance().toSupportedDevice(deviceCandidate);
if (!coordinator.supportsDeviceSpecificSettings(device)) {
if (coordinator.getSupportedDeviceSpecificSettings(device) != null) {
return true;
}

View File

@ -64,14 +64,8 @@ import nodomain.freeyourgadget.gadgetbridge.util.GB;
import nodomain.freeyourgadget.gadgetbridge.util.GBPrefs;
import nodomain.freeyourgadget.gadgetbridge.util.Prefs;
import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF_DISCONNECT_NOTIFICATION;
import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF_DISCONNECT_NOTIFICATION_END;
import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF_DISCONNECT_NOTIFICATION_START;
import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.PREF_MI2_DATEFORMAT;
import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.PREF_MI2_DO_NOT_DISTURB_OFF;
import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.PREF_MI2_DO_NOT_DISTURB_SCHEDULED;
import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.PREF_MI2_ENABLE_TEXT_NOTIFICATIONS;
import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.PREF_MI3_BAND_SCREEN_UNLOCK;
import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.PREF_MI3_NIGHT_MODE;
import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.PREF_MI3_NIGHT_MODE_END;
import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.PREF_MI3_NIGHT_MODE_OFF;
@ -385,20 +379,6 @@ public class SettingsActivity extends AbstractSettingsActivity {
}
});
final Preference miBand3ScreenUnlock = findPreference(PREF_MI3_BAND_SCREEN_UNLOCK);
miBand3ScreenUnlock.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newVal) {
invokeLater(new Runnable() {
@Override
public void run() {
GBApplication.deviceService().onSendConfiguration(PREF_MI3_BAND_SCREEN_UNLOCK);
}
});
return true;
}
});
String nightModeState = prefs.getString(MiBandConst.PREF_MI3_NIGHT_MODE, PREF_MI3_NIGHT_MODE_OFF);
boolean nightModeScheduled = nightModeState.equals(PREF_MI3_NIGHT_MODE_SCHEDULED);
@ -453,59 +433,6 @@ public class SettingsActivity extends AbstractSettingsActivity {
}
});
String disconnectNotificationState = prefs.getString(PREF_DISCONNECT_NOTIFICATION, PREF_MI2_DO_NOT_DISTURB_OFF);
boolean disconnectNotificationScheduled = disconnectNotificationState.equals(PREF_MI2_DO_NOT_DISTURB_SCHEDULED);
final Preference disconnectNotificationStart = findPreference(PREF_DISCONNECT_NOTIFICATION_START);
disconnectNotificationStart.setEnabled(disconnectNotificationScheduled);
disconnectNotificationStart.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newVal) {
invokeLater(new Runnable() {
@Override
public void run() {
GBApplication.deviceService().onSendConfiguration(PREF_DISCONNECT_NOTIFICATION_START);
}
});
return true;
}
});
final Preference disconnectNotificationEnd = findPreference(PREF_DISCONNECT_NOTIFICATION_END);
disconnectNotificationStart.setEnabled(disconnectNotificationScheduled);
disconnectNotificationStart.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newVal) {
invokeLater(new Runnable() {
@Override
public void run() {
GBApplication.deviceService().onSendConfiguration(PREF_DISCONNECT_NOTIFICATION_END);
}
});
return true;
}
});
final Preference disconnectNotification = findPreference(PREF_DISCONNECT_NOTIFICATION);
disconnectNotification.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newVal) {
final boolean scheduled = PREF_MI2_DO_NOT_DISTURB_SCHEDULED.equals(newVal.toString());
disconnectNotificationStart.setEnabled(scheduled);
disconnectNotificationEnd.setEnabled(scheduled);
invokeLater(new Runnable() {
@Override
public void run() {
GBApplication.deviceService().onSendConfiguration(PREF_DISCONNECT_NOTIFICATION);
}
});
return true;
}
});
// Get all receivers of Media Buttons
Intent mediaButtonIntent = new Intent(Intent.ACTION_MEDIA_BUTTON);

View File

@ -19,10 +19,10 @@ package nodomain.freeyourgadget.gadgetbridge.activities.devicesettings;
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentTransaction;
import androidx.preference.PreferenceFragmentCompat;
import androidx.preference.PreferenceScreen;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -34,31 +34,46 @@ import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.util.DeviceHelper;
public class DeviceSettingsActivity extends AbstractGBActivity {
public class DeviceSettingsActivity extends AbstractGBActivity implements
PreferenceFragmentCompat.OnPreferenceStartScreenCallback {
private static final Logger LOG = LoggerFactory.getLogger(DeviceSettingsActivity.class);
private GBDevice device;
GBDevice device;
@Override
protected void onCreate(Bundle savedInstanceState) {
device = getIntent().getParcelableExtra(GBDevice.EXTRA_DEVICE);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_device_settings);
if (savedInstanceState == null) {
Fragment fragment = getSupportFragmentManager().findFragmentByTag(DeviceSpecificSettingsFragment.FRAGMENT_TAG);
if (fragment == null) {
DeviceCoordinator coordinator = DeviceHelper.getInstance().getCoordinator(device);
fragment = DeviceSpecificSettingsFragment.newInstance(device.getAddress(), coordinator.getSupportedDeviceSpecificSettings(device));
}
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.settings_container, fragment, DeviceSpecificSettingsFragment.FRAGMENT_TAG)
.commit();
DeviceCoordinator coordinator = DeviceHelper.getInstance().getCoordinator(device);
PreferenceFragmentCompat fragment = coordinator.getDeviceSpecificSettingsFragment(device);
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.settings_container, fragment)
.commit();
}
public class DoesNotExistSettingsFragment extends PreferenceFragmentCompat {
@Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
}
}
}
@Override
public boolean onPreferenceStartScreen(PreferenceFragmentCompat caller, PreferenceScreen preferenceScreen) {
DeviceCoordinator coordinator = DeviceHelper.getInstance().getCoordinator(device);
PreferenceFragmentCompat fragment = DeviceSpecificSettingsFragment.newInstance(device.getAddress(), coordinator.getSupportedDeviceSpecificSettings(device));
Bundle args = fragment.getArguments();
args.putString(PreferenceFragmentCompat.ARG_PREFERENCE_ROOT, preferenceScreen.getKey());
fragment.setArguments(args);
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.settings_container, fragment, preferenceScreen.getKey())
.addToBackStack(preferenceScreen.getKey())
.commit();
return true;
}
}

View File

@ -2,21 +2,193 @@ package nodomain.freeyourgadget.gadgetbridge.activities.devicesettings;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.fragment.app.DialogFragment;
import androidx.preference.Preference;
import androidx.preference.PreferenceFragmentCompat;
abstract public class DeviceSpecificSettingsFragment extends PreferenceFragmentCompat {
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst;
import nodomain.freeyourgadget.gadgetbridge.util.Prefs;
import nodomain.freeyourgadget.gadgetbridge.util.XTimePreference;
import nodomain.freeyourgadget.gadgetbridge.util.XTimePreferenceFragment;
public void setSettingsFileSuffix(String settingsFileSuffix) {
import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF_DISCONNECT_NOTIFICATION;
import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF_DISCONNECT_NOTIFICATION_END;
import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF_DISCONNECT_NOTIFICATION_START;
import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.PREF_MI2_DO_NOT_DISTURB_OFF;
import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.PREF_MI2_DO_NOT_DISTURB_SCHEDULED;
import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.PREF_SWIPE_UNLOCK;
public class DeviceSpecificSettingsFragment extends PreferenceFragmentCompat {
static final String FRAGMENT_TAG = "DEVICE_SPECIFIC_SETTINGS_FRAGMENT";
private void setSettingsFileSuffix(String settingsFileSuffix, @NonNull int[] supportedSettings) {
Bundle args = new Bundle();
args.putString("settingsFileSuffix", settingsFileSuffix);
args.putIntArray("supportedSettings", supportedSettings);
setArguments(args);
}
@Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
String settingsFileSuffix = getArguments().getString("settingsFileSuffix", "_bug");
Bundle arguments = getArguments();
if (arguments == null) {
return;
}
String settingsFileSuffix = arguments.getString("settingsFileSuffix", null);
int[] supportedSettings = arguments.getIntArray("supportedSettings");
if (settingsFileSuffix == null || supportedSettings == null) {
return;
}
getPreferenceManager().setSharedPreferencesName("devicesettings_" + settingsFileSuffix);
if (rootKey == null) {
// we are the main preference screen
boolean first = true;
for (int setting : supportedSettings) {
if (first) {
setPreferencesFromResource(setting, null);
first = false;
} else {
addPreferencesFromResource(setting);
}
}
} else {
// Now, this is ugly: search all the xml files for the rootKey
for (int setting : supportedSettings) {
try {
setPreferencesFromResource(setting, rootKey);
} catch (Exception ignore) {
continue;
}
break;
}
}
setChangeListener();
}
/*
* delayed execution so that the preferences are applied first
*/
private void invokeLater(Runnable runnable) {
getListView().post(runnable);
}
private void setChangeListener() {
final Preference displayItems = findPreference("display_items");
if (displayItems != null) {
displayItems.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newVal) {
invokeLater(new Runnable() {
@Override
public void run() {
GBApplication.deviceService().onSendConfiguration(HuamiConst.PREF_DISPLAY_ITEMS);
}
});
return true;
}
});
}
Prefs prefs = new Prefs(getPreferenceManager().getSharedPreferences());
String disconnectNotificationState = prefs.getString(PREF_DISCONNECT_NOTIFICATION, PREF_MI2_DO_NOT_DISTURB_OFF);
boolean disconnectNotificationScheduled = disconnectNotificationState.equals(PREF_MI2_DO_NOT_DISTURB_SCHEDULED);
final Preference disconnectNotificationStart = findPreference(PREF_DISCONNECT_NOTIFICATION_START);
if (disconnectNotificationStart != null) {
disconnectNotificationStart.setEnabled(disconnectNotificationScheduled);
disconnectNotificationStart.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newVal) {
invokeLater(new Runnable() {
@Override
public void run() {
GBApplication.deviceService().onSendConfiguration(PREF_DISCONNECT_NOTIFICATION_START);
}
});
return true;
}
});
}
final Preference disconnectNotificationEnd = findPreference(PREF_DISCONNECT_NOTIFICATION_END);
if (disconnectNotificationEnd != null) {
disconnectNotificationEnd.setEnabled(disconnectNotificationScheduled);
disconnectNotificationEnd.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newVal) {
invokeLater(new Runnable() {
@Override
public void run() {
GBApplication.deviceService().onSendConfiguration(PREF_DISCONNECT_NOTIFICATION_END);
}
});
return true;
}
});
}
final Preference disconnectNotification = findPreference(PREF_DISCONNECT_NOTIFICATION);
if (disconnectNotification != null) {
disconnectNotification.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newVal) {
final boolean scheduled = PREF_MI2_DO_NOT_DISTURB_SCHEDULED.equals(newVal.toString());
disconnectNotificationStart.setEnabled(scheduled);
disconnectNotificationEnd.setEnabled(scheduled);
invokeLater(new Runnable() {
@Override
public void run() {
GBApplication.deviceService().onSendConfiguration(PREF_DISCONNECT_NOTIFICATION);
}
});
return true;
}
});
}
final Preference swipeUnlock = findPreference(PREF_SWIPE_UNLOCK);
if (swipeUnlock != null) {
swipeUnlock.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newVal) {
invokeLater(new Runnable() {
@Override
public void run() {
GBApplication.deviceService().onSendConfiguration(PREF_SWIPE_UNLOCK);
}
});
return true;
}
});
}
}
static DeviceSpecificSettingsFragment newInstance(String settingsFileSuffix, @NonNull int[] supportedSettings) {
DeviceSpecificSettingsFragment fragment = new DeviceSpecificSettingsFragment();
fragment.setSettingsFileSuffix(settingsFileSuffix, supportedSettings);
return fragment;
}
@Override
public void onDisplayPreferenceDialog(Preference preference) {
DialogFragment dialogFragment = null;
if (preference instanceof XTimePreference) {
dialogFragment = new XTimePreferenceFragment();
Bundle bundle = new Bundle(1);
bundle.putString("key", preference.getKey());
dialogFragment.setArguments(bundle);
dialogFragment.setTargetFragment(this, 0);
dialogFragment.show(getFragmentManager(), "androidx.preference.PreferenceFragment.DIALOG");
} else {
super.onDisplayPreferenceDialog(preference);
}
}
}

View File

@ -1,21 +0,0 @@
package nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.huami;
import android.os.Bundle;
import nodomain.freeyourgadget.gadgetbridge.R;
public class AmazfitBipSettingsFragment extends HuamiSettingsFragment {
@Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
super.onCreatePreferences(savedInstanceState, rootKey);
addPreferencesFromResource(R.xml.devicesettings_huami_bip);
setChangeListener();
}
public static HuamiSettingsFragment newInstance(String settingsFileSuffix) {
HuamiSettingsFragment fragment = new AmazfitBipSettingsFragment();
fragment.setSettingsFileSuffix(settingsFileSuffix);
return fragment;
}
}

View File

@ -1,21 +0,0 @@
package nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.huami;
import android.os.Bundle;
import nodomain.freeyourgadget.gadgetbridge.R;
public class AmazfitCorSettingsFragment extends HuamiSettingsFragment{
@Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
super.onCreatePreferences(savedInstanceState, rootKey);
addPreferencesFromResource(R.xml.devicesettings_huami_cor);
setChangeListener();
}
public static HuamiSettingsFragment newInstance(String settingsFileSuffix) {
HuamiSettingsFragment fragment = new AmazfitCorSettingsFragment();
fragment.setSettingsFileSuffix(settingsFileSuffix);
return fragment;
}
}

View File

@ -1,53 +0,0 @@
package nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.huami;
import android.os.Bundle;
import androidx.preference.Preference;
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSpecificSettingsFragment;
import nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst;
public class HuamiSettingsFragment extends DeviceSpecificSettingsFragment {
/*
* delayed execution so that the preferences are applied first
*/
private void invokeLater(Runnable runnable) {
getListView().post(runnable);
}
@Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
super.onCreatePreferences(savedInstanceState, rootKey);
setPreferencesFromResource(R.xml.devicesettings_huami, rootKey);
}
public static HuamiSettingsFragment newInstance(String settingsFileSuffix) {
HuamiSettingsFragment fragment = new HuamiSettingsFragment();
fragment.setSettingsFileSuffix(settingsFileSuffix);
return fragment;
}
void setChangeListener() {
final Preference displayItems = findPreference("display_items");
if (displayItems != null) {
displayItems.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newVal) {
invokeLater(new Runnable() {
@Override
public void run() {
GBApplication.deviceService().onSendConfiguration(HuamiConst.PREF_DISPLAY_ITEMS);
}
});
return true;
}
});
}
}
}

View File

@ -1,21 +0,0 @@
package nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.huami;
import android.os.Bundle;
import nodomain.freeyourgadget.gadgetbridge.R;
public class MiBand2SettingsFragment extends HuamiSettingsFragment {
@Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
super.onCreatePreferences(savedInstanceState, rootKey);
addPreferencesFromResource(R.xml.devicesettings_huami_miband2);
setChangeListener();
}
public static HuamiSettingsFragment newInstance(String settingsFileSuffix) {
HuamiSettingsFragment fragment = new MiBand2SettingsFragment();
fragment.setSettingsFileSuffix(settingsFileSuffix);
return fragment;
}
}

View File

@ -1,21 +0,0 @@
package nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.huami;
import android.os.Bundle;
import nodomain.freeyourgadget.gadgetbridge.R;
public class MiBand3SettingsFragment extends HuamiSettingsFragment {
@Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
super.onCreatePreferences(savedInstanceState, rootKey);
addPreferencesFromResource(R.xml.devicesettings_huami_miband3);
setChangeListener();
}
public static HuamiSettingsFragment newInstance(String settingsFileSuffix) {
HuamiSettingsFragment fragment = new MiBand3SettingsFragment();
fragment.setSettingsFileSuffix(settingsFileSuffix);
return fragment;
}
}

View File

@ -152,7 +152,7 @@ public class GBDeviceAdapterv2 extends RecyclerView.Adapter<GBDeviceAdapterv2.Vi
}
//device specific settings
holder.deviceSpecificSettingsView.setVisibility(coordinator.supportsDeviceSpecificSettings(device) ? View.VISIBLE : View.GONE);
holder.deviceSpecificSettingsView.setVisibility(coordinator.getSupportedDeviceSpecificSettings(device) != null ? View.VISIBLE : View.GONE);
holder.deviceSpecificSettingsView.setOnClickListener(new View.OnClickListener()
{

View File

@ -31,7 +31,6 @@ import androidx.annotation.NonNull;
import de.greenrobot.dao.query.QueryBuilder;
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.GBException;
import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSpecificSettingsFragment;
import nodomain.freeyourgadget.gadgetbridge.database.DBHandler;
import nodomain.freeyourgadget.gadgetbridge.database.DBHelper;
import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession;
@ -155,12 +154,7 @@ public abstract class AbstractDeviceCoordinator implements DeviceCoordinator {
public boolean supportsUnicodeEmojis() { return false; }
@Override
public boolean supportsDeviceSpecificSettings(GBDevice device) {
return false;
}
@Override
public DeviceSpecificSettingsFragment getDeviceSpecificSettingsFragment(GBDevice device) {
public int[] getSupportedDeviceSpecificSettings(GBDevice device) {
return null;
}

View File

@ -281,12 +281,7 @@ public interface DeviceCoordinator {
boolean supportsUnicodeEmojis();
/**
* Indicates whether the device supports device specific settings (not per device type or family, but unique per device).
* Indicates which device specific settings the device supports (not per device type or family, but unique per device).
*/
boolean supportsDeviceSpecificSettings(GBDevice device);
/**
* Creates and returns a device specific settings fragment, or null if there is none
*/
DeviceSpecificSettingsFragment getDeviceSpecificSettingsFragment(GBDevice device);
int[] getSupportedDeviceSpecificSettings(GBDevice device);
}

View File

@ -42,8 +42,6 @@ import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.GBException;
import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.activities.SettingsActivity;
import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSpecificSettingsFragment;
import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.huami.HuamiSettingsFragment;
import nodomain.freeyourgadget.gadgetbridge.devices.AbstractDeviceCoordinator;
import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider;
import nodomain.freeyourgadget.gadgetbridge.devices.miband.DateTimeDisplay;
@ -124,13 +122,8 @@ public abstract class HuamiCoordinator extends AbstractDeviceCoordinator {
}
@Override
public boolean supportsDeviceSpecificSettings(GBDevice device) {
return true;
}
@Override
public DeviceSpecificSettingsFragment getDeviceSpecificSettingsFragment(GBDevice device) {
return HuamiSettingsFragment.newInstance(device.getAddress());
public int[] getSupportedDeviceSpecificSettings(GBDevice device) {
return new int[]{R.xml.devicesettings_pairingkey};
}
@Override
@ -173,8 +166,8 @@ public abstract class HuamiCoordinator extends AbstractDeviceCoordinator {
return getTimePreference(HuamiConst.PREF_DISPLAY_ON_LIFT_END, "00:00");
}
public static DisconnectNotificationSetting getDisconnectNotificationSetting(Context context) {
Prefs prefs = GBApplication.getPrefs();
public static DisconnectNotificationSetting getDisconnectNotificationSetting(Context context, String deviceAddress) {
Prefs prefs = new Prefs(GBApplication.getDeviceSpecificSharedPrefs(deviceAddress));
String liftOff = context.getString(R.string.p_off);
String liftOn = context.getString(R.string.p_on);
@ -253,6 +246,11 @@ public abstract class HuamiCoordinator extends AbstractDeviceCoordinator {
return getTimePreference(MiBandConst.PREF_MI2_DO_NOT_DISTURB_END, "06:00");
}
public static boolean getBandScreenUnlock(String deviceAddress) {
Prefs prefs = new Prefs(GBApplication.getDeviceSpecificSharedPrefs(deviceAddress));
return prefs.getBoolean(MiBandConst.PREF_SWIPE_UNLOCK, false);
}
public static Date getTimePreference(String key, String defaultValue) {
Prefs prefs = GBApplication.getPrefs();
String time = prefs.getString(key, defaultValue);

View File

@ -26,8 +26,7 @@ import androidx.annotation.NonNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.huami.AmazfitBipSettingsFragment;
import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSpecificSettingsFragment;
import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.devices.InstallHandler;
import nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiCoordinator;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
@ -79,7 +78,11 @@ public class AmazfitBipCoordinator extends HuamiCoordinator {
}
@Override
public DeviceSpecificSettingsFragment getDeviceSpecificSettingsFragment(GBDevice device) {
return AmazfitBipSettingsFragment.newInstance(device.getAddress());
public int[] getSupportedDeviceSpecificSettings(GBDevice device) {
return new int[]{
R.xml.devicesettings_amazfitbip,
R.xml.devicesettings_disconnectnotification,
R.xml.devicesettings_pairingkey
};
}
}

View File

@ -26,8 +26,7 @@ import androidx.annotation.NonNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.huami.AmazfitCorSettingsFragment;
import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSpecificSettingsFragment;
import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.devices.InstallHandler;
import nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiCoordinator;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
@ -82,7 +81,11 @@ public class AmazfitCorCoordinator extends HuamiCoordinator {
public boolean supportsUnicodeEmojis() { return true; }
@Override
public DeviceSpecificSettingsFragment getDeviceSpecificSettingsFragment(GBDevice device) {
return AmazfitCorSettingsFragment.newInstance(device.getAddress());
public int[] getSupportedDeviceSpecificSettings(GBDevice device) {
return new int[]{
R.xml.devicesettings_amazfitcor,
R.xml.devicesettings_disconnectnotification,
R.xml.devicesettings_swipeunlock,
R.xml.devicesettings_pairingkey};
}
}

View File

@ -26,8 +26,7 @@ import androidx.annotation.NonNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSpecificSettingsFragment;
import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.huami.MiBand2SettingsFragment;
import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.devices.InstallHandler;
import nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst;
import nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiCoordinator;
@ -82,7 +81,7 @@ public class MiBand2Coordinator extends HuamiCoordinator {
}
@Override
public DeviceSpecificSettingsFragment getDeviceSpecificSettingsFragment(GBDevice device) {
return MiBand2SettingsFragment.newInstance(device.getAddress());
public int[] getSupportedDeviceSpecificSettings(GBDevice device) {
return new int[]{R.xml.devicesettings_miband2, R.xml.devicesettings_pairingkey};
}
}

View File

@ -29,8 +29,7 @@ import org.slf4j.LoggerFactory;
import java.util.Date;
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSpecificSettingsFragment;
import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.huami.MiBand3SettingsFragment;
import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.devices.InstallHandler;
import nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst;
import nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiCoordinator;
@ -85,10 +84,6 @@ public class MiBand3Coordinator extends HuamiCoordinator {
return true;
}
public static boolean getBandScreenUnlock() {
Prefs prefs = GBApplication.getPrefs();
return prefs.getBoolean(MiBandConst.PREF_MI3_BAND_SCREEN_UNLOCK, false);
}
public static String getNightMode() {
Prefs prefs = GBApplication.getPrefs();
@ -105,7 +100,11 @@ public class MiBand3Coordinator extends HuamiCoordinator {
}
@Override
public DeviceSpecificSettingsFragment getDeviceSpecificSettingsFragment(GBDevice device) {
return MiBand3SettingsFragment.newInstance(device.getAddress());
public int[] getSupportedDeviceSpecificSettings(GBDevice device) {
return new int[]{
R.xml.devicesettings_miband3,
R.xml.devicesettings_swipeunlock,
R.xml.devicesettings_pairingkey
};
}
}

View File

@ -65,7 +65,7 @@ public final class MiBandConst {
public static final String PREF_MI2_INACTIVITY_WARNINGS_DND_END = "mi2_inactivity_warnings_dnd_end";
public static final String PREF_MIBAND_SETUP_BT_PAIRING = "mi_setup_bt_pairing";
public static final String PREF_MI3_BAND_SCREEN_UNLOCK = "mi3_band_screen_unlock";
public static final String PREF_SWIPE_UNLOCK = "swipe_unlock";
public static final String PREF_MI3_NIGHT_MODE = "mi3_night_mode";
public static final String PREF_MI3_NIGHT_MODE_START = "mi3_night_mode_start";
public static final String PREF_MI3_NIGHT_MODE_END = "mi3_night_mode_end";

View File

@ -135,7 +135,7 @@ public class MiBandPairingActivity extends AbstractGBActivity {
DeviceCoordinator coordinator = DeviceHelper.getInstance().getCoordinator(deviceCandidate);
GBDevice device = DeviceHelper.getInstance().toSupportedDevice(deviceCandidate);
if (coordinator.supportsDeviceSpecificSettings(device)) {
if (coordinator.getSupportedDeviceSpecificSettings(device) != null) { // FIXME: this will no longer be sane in the future
SharedPreferences sharedPrefs = GBApplication.getDeviceSpecificSharedPrefs(device.getAddress());
String authKey = sharedPrefs.getString("authkey", null);
if (authKey == null || authKey.isEmpty()) {

View File

@ -68,6 +68,8 @@ import nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiFWHelper;
import nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiService;
import nodomain.freeyourgadget.gadgetbridge.devices.huami.amazfitbip.AmazfitBipService;
import nodomain.freeyourgadget.gadgetbridge.devices.huami.miband2.MiBand2FWHelper;
import nodomain.freeyourgadget.gadgetbridge.devices.huami.miband3.MiBand3Coordinator;
import nodomain.freeyourgadget.gadgetbridge.devices.huami.miband3.MiBand3Service;
import nodomain.freeyourgadget.gadgetbridge.devices.miband.DateTimeDisplay;
import nodomain.freeyourgadget.gadgetbridge.devices.miband.DoNotDisturb;
import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBand2SampleProvider;
@ -110,6 +112,7 @@ import nodomain.freeyourgadget.gadgetbridge.service.devices.common.SimpleNotific
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.actions.StopNotificationAction;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.miband2.Mi2NotificationStrategy;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.miband2.Mi2TextNotificationStrategy;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.miband3.MiBand3Support;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.operations.FetchActivityOperation;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.operations.FetchSportsSummaryOperation;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.operations.InitOperation;
@ -1547,6 +1550,9 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport {
case SettingsActivity.PREF_MEASUREMENT_SYSTEM:
setDistanceUnit(builder);
break;
case MiBandConst.PREF_SWIPE_UNLOCK:
setBandScreenUnlock(builder);
break;
}
builder.queue(getQueue());
} catch (IOException e) {
@ -1772,7 +1778,7 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport {
}
private HuamiSupport setDisconnectNotification(TransactionBuilder builder) {
DisconnectNotificationSetting disconnectNotificationSetting = HuamiCoordinator.getDisconnectNotificationSetting(getContext());
DisconnectNotificationSetting disconnectNotificationSetting = HuamiCoordinator.getDisconnectNotificationSetting(getContext(), gbDevice.getAddress());
LOG.info("Setting disconnect notification to " + disconnectNotificationSetting);
switch (disconnectNotificationSetting) {
@ -1813,6 +1819,20 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport {
return this;
}
protected HuamiSupport setBandScreenUnlock(TransactionBuilder builder) {
boolean enable = MiBand3Coordinator.getBandScreenUnlock(gbDevice.getAddress());
LOG.info("Setting band screen unlock to " + enable);
if (enable) {
builder.write(getCharacteristic(HuamiService.UUID_CHARACTERISTIC_3_CONFIGURATION), MiBand3Service.COMMAND_ENABLE_BAND_SCREEN_UNLOCK);
} else {
builder.write(getCharacteristic(HuamiService.UUID_CHARACTERISTIC_3_CONFIGURATION), MiBand3Service.COMMAND_DISABLE_BAND_SCREEN_UNLOCK);
}
return this;
}
protected HuamiSupport setLanguage(TransactionBuilder builder) {
String localeString = GBApplication.getDeviceSpecificSharedPrefs(gbDevice.getAddress()).getString("language", "auto");
if (localeString == null || localeString.equals("auto")) {

View File

@ -78,6 +78,13 @@ public class AmazfitCorSupport extends AmazfitBipSupport {
return this;
}
@Override
public void phase2Initialize(TransactionBuilder builder) {
super.phase2Initialize(builder);
LOG.info("phase2Initialize...");
setBandScreenUnlock(builder);
}
@Override
public HuamiFWHelper createFWHelper(Uri uri, Context context) throws IOException {
return new AmazfitCorFWHelper(uri, context);

View File

@ -27,7 +27,6 @@ import java.io.IOException;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Locale;
import java.util.Set;
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
@ -107,9 +106,6 @@ public class MiBand3Support extends AmazfitBipSupport {
try {
builder = performInitialized("Sending configuration for option: " + config);
switch (config) {
case MiBandConst.PREF_MI3_BAND_SCREEN_UNLOCK:
setBandScreenUnlock(builder);
break;
case MiBandConst.PREF_MI3_NIGHT_MODE:
case MiBandConst.PREF_MI3_NIGHT_MODE_START:
case MiBandConst.PREF_MI3_NIGHT_MODE_END:
@ -125,19 +121,6 @@ public class MiBand3Support extends AmazfitBipSupport {
}
}
private MiBand3Support setBandScreenUnlock(TransactionBuilder builder) {
boolean enable = MiBand3Coordinator.getBandScreenUnlock();
LOG.info("Setting band screen unlock to " + enable);
if (enable) {
builder.write(getCharacteristic(HuamiService.UUID_CHARACTERISTIC_3_CONFIGURATION), MiBand3Service.COMMAND_ENABLE_BAND_SCREEN_UNLOCK);
} else {
builder.write(getCharacteristic(HuamiService.UUID_CHARACTERISTIC_3_CONFIGURATION), MiBand3Service.COMMAND_DISABLE_BAND_SCREEN_UNLOCK);
}
return this;
}
private MiBand3Support setNightMode(TransactionBuilder builder) {
String nightMode = MiBand3Coordinator.getNightMode();
LOG.info("Setting night mode to " + nightMode);
@ -178,6 +161,7 @@ public class MiBand3Support extends AmazfitBipSupport {
public void phase2Initialize(TransactionBuilder builder) {
super.phase2Initialize(builder);
LOG.info("phase2Initialize...");
setLanguage(builder);
setBandScreenUnlock(builder);
setNightMode(builder);
}

View File

@ -0,0 +1,86 @@
/* Copyright (C) 2017-2019 Carsten Pfeiffer, José Rebelo
This file is part of Gadgetbridge.
Gadgetbridge is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Gadgetbridge 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 Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.util;
import android.content.Context;
import android.content.res.TypedArray;
import android.text.format.DateFormat;
import android.util.AttributeSet;
import androidx.preference.DialogPreference;
public class XTimePreference extends DialogPreference {
protected int hour = 0;
protected int minute = 0;
public XTimePreference(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected Object onGetDefaultValue(TypedArray a, int index) {
return a.getString(index);
}
@Override
protected void onSetInitialValue(boolean restoreValue, Object defaultValue) {
String time;
if (restoreValue) {
if (defaultValue == null) {
time = getPersistedString("00:00");
} else {
time = getPersistedString(defaultValue.toString());
}
} else {
if (defaultValue != null) {
time = defaultValue.toString();
} else {
time = "00:00";
}
}
String[] pieces = time.split(":");
hour = Integer.parseInt(pieces[0]);
minute = Integer.parseInt(pieces[1]);
updateSummary();
}
void updateSummary() {
if (DateFormat.is24HourFormat(getContext()))
setSummary(getTime24h());
else
setSummary(getTime12h());
}
String getTime24h() {
return String.format("%02d", hour) + ":" + String.format("%02d", minute);
}
private String getTime12h() {
String suffix = hour < 12 ? " AM" : " PM";
int h = hour > 12 ? hour - 12 : hour;
return h + ":" + String.format("%02d", minute) + suffix;
}
void persistStringValue(String value) {
persistString(value);
}
}

View File

@ -0,0 +1,71 @@
/* Copyright (C) 2017-2019 Carsten Pfeiffer, José Rebelo
This file is part of Gadgetbridge.
Gadgetbridge is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Gadgetbridge 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 Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.util;
import android.content.Context;
import android.text.format.DateFormat;
import android.view.View;
import android.widget.TimePicker;
import androidx.preference.DialogPreference;
import androidx.preference.Preference;
import androidx.preference.PreferenceDialogFragmentCompat;
public class XTimePreferenceFragment extends PreferenceDialogFragmentCompat implements DialogPreference.TargetFragment {
private TimePicker picker = null;
@Override
protected View onCreateDialogView(Context context) {
picker = new TimePicker(context);
picker.setIs24HourView(DateFormat.is24HourFormat(getContext()));
picker.setPadding(0, 50, 0, 50);
return picker;
}
@Override
protected void onBindDialogView(View v) {
super.onBindDialogView(v);
XTimePreference pref = (XTimePreference) getPreference();
picker.setCurrentHour(pref.hour);
picker.setCurrentMinute(pref.minute);
}
@Override
public void onDialogClosed(boolean positiveResult) {
if (positiveResult) {
XTimePreference pref = (XTimePreference) getPreference();
pref.hour = picker.getCurrentHour();
pref.minute = picker.getCurrentMinute();
String time = pref.getTime24h();
if (pref.callChangeListener(time)) {
pref.persistStringValue(time);
pref.updateSummary();
}
}
}
@Override
public Preference findPreference(CharSequence key) {
return getPreference();
}
}

View File

@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<PreferenceScreen
android:key="screen_disconnect_nofifiction"
android:persistent="false"
android:title="@string/prefs_disconnect_notification">
<!-- workaround for missing toolbar -->
<PreferenceCategory android:title="@string/prefs_disconnect_notification" />
<ListPreference
android:defaultValue="@string/p_off"
android:entries="@array/activate_display_on_lift"
android:entryValues="@array/activate_display_on_lift_values"
android:key="disconnect_notification"
android:summary="%s"
android:title="@string/prefs_disconnect_notification" />
<nodomain.freeyourgadget.gadgetbridge.util.XTimePreference
android:defaultValue="00:00"
android:key="disconnect_notification_start"
android:title="@string/mi2_prefs_do_not_disturb_start" />
<nodomain.freeyourgadget.gadgetbridge.util.XTimePreference
android:defaultValue="00:00"
android:key="disconnect_notification_end"
android:title="@string/mi2_prefs_do_not_disturb_end" />
</PreferenceScreen>
</androidx.preference.PreferenceScreen>

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<CheckBoxPreference
android:defaultValue="false"
android:key="swipe_unlock"
android:layout="@layout/preference_checkbox"
android:summary="@string/mi3_prefs_band_screen_unlock_summary"
android:title="@string/mi3_prefs_band_screen_unlock" />
</androidx.preference.PreferenceScreen>

View File

@ -293,12 +293,6 @@
<PreferenceScreen
android:icon="@drawable/ic_device_miband2"
android:title="@string/preferences_miband3_settings">
<CheckBoxPreference
android:layout="@layout/preference_checkbox"
android:defaultValue="false"
android:key="mi3_band_screen_unlock"
android:summary="@string/mi3_prefs_band_screen_unlock_summary"
android:title="@string/mi3_prefs_band_screen_unlock" />
<PreferenceScreen
android:persistent="false"
android:title="@string/mi3_prefs_night_mode"
@ -327,37 +321,6 @@
</PreferenceScreen>
</PreferenceScreen>
<PreferenceScreen
android:icon="@drawable/ic_device_hplus"
android:title="@string/preferences_amazfitbip_settings">
<PreferenceScreen
android:persistent="false"
android:title="@string/prefs_disconnect_notification">
<!-- workaround for missing toolbar -->
<PreferenceCategory android:title="@string/prefs_disconnect_notification" />
<ListPreference
android:defaultValue="@string/p_off"
android:entries="@array/activate_display_on_lift"
android:entryValues="@array/activate_display_on_lift_values"
android:key="disconnect_notification"
android:summary="%s"
android:title="@string/prefs_disconnect_notification" />
<nodomain.freeyourgadget.gadgetbridge.util.TimePreference
android:defaultValue="00:00"
android:key="disconnect_notification_start"
android:title="@string/mi2_prefs_do_not_disturb_start" />
<nodomain.freeyourgadget.gadgetbridge.util.TimePreference
android:defaultValue="00:00"
android:key="disconnect_notification_end"
android:title="@string/mi2_prefs_do_not_disturb_end" />
</PreferenceScreen>
</PreferenceScreen>
<PreferenceScreen
android:icon="@drawable/ic_device_pebble"
android:key="pref_key_pebble"