mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge
synced 2024-12-25 18:15:49 +01:00
Huami: Migrate some settings to device specific settings
- Migrate language setting - Migrate menu items setting - Migrate lastsync timestamp from prefixed global shared prefercence All settings should be automatically be converted (e.g. Amazfit Bip settings to all paired Amazfit Bip devices) and then deleted. Cor Settings aleady completely vanished from the global settings menu. When migration is done we will have a much cleaner settings menu. Will also remove confusion that some Cor settings have to be done in Bip settings.
This commit is contained in:
parent
8f893d6f2b
commit
08e7d728c2
@ -59,6 +59,7 @@ import nodomain.freeyourgadget.gadgetbridge.database.DBHelper;
|
||||
import nodomain.freeyourgadget.gadgetbridge.database.DBOpenHelper;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.DeviceManager;
|
||||
import nodomain.freeyourgadget.gadgetbridge.entities.DaoMaster;
|
||||
import nodomain.freeyourgadget.gadgetbridge.entities.Device;
|
||||
import nodomain.freeyourgadget.gadgetbridge.externalevents.BluetoothStateChangeReceiver;
|
||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceService;
|
||||
@ -72,6 +73,7 @@ import nodomain.freeyourgadget.gadgetbridge.util.GBPrefs;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.LimitedQueue;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.Prefs;
|
||||
|
||||
import static nodomain.freeyourgadget.gadgetbridge.model.DeviceType.fromKey;
|
||||
import static nodomain.freeyourgadget.gadgetbridge.util.GB.NOTIFICATION_CHANNEL_ID;
|
||||
|
||||
/**
|
||||
@ -89,7 +91,7 @@ public class GBApplication extends Application {
|
||||
private static SharedPreferences sharedPrefs;
|
||||
private static final String PREFS_VERSION = "shared_preferences_version";
|
||||
//if preferences have to be migrated, increment the following and add the migration logic in migratePrefs below; see http://stackoverflow.com/questions/16397848/how-can-i-migrate-android-preferences-with-a-new-version
|
||||
private static final int CURRENT_PREFS_VERSION = 2;
|
||||
private static final int CURRENT_PREFS_VERSION = 3;
|
||||
private static LimitedQueue mIDSenderLookup = new LimitedQueue(16);
|
||||
private static Prefs prefs;
|
||||
private static GBPrefs gbPrefs;
|
||||
@ -166,7 +168,7 @@ public class GBApplication extends Application {
|
||||
// slf4j may be implicitly initialized before we properly configured it.
|
||||
setupLogging(isFileLoggingEnabled());
|
||||
|
||||
if (getPrefsFileVersion() != CURRENT_PREFS_VERSION) {
|
||||
if (getPrefsFileVersion() != CURRENT_PREFS_VERSION) {
|
||||
migratePrefs(getPrefsFileVersion());
|
||||
}
|
||||
|
||||
@ -582,44 +584,80 @@ public static String packageNameToPebbleMsgSender(String packageName) {
|
||||
|
||||
private void migratePrefs(int oldVersion) {
|
||||
SharedPreferences.Editor editor = sharedPrefs.edit();
|
||||
switch (oldVersion) {
|
||||
case 0:
|
||||
String legacyGender = sharedPrefs.getString("mi_user_gender", null);
|
||||
String legacyHeight = sharedPrefs.getString("mi_user_height_cm", null);
|
||||
String legacyWeight = sharedPrefs.getString("mi_user_weight_kg", null);
|
||||
String legacyYOB = sharedPrefs.getString("mi_user_year_of_birth", null);
|
||||
if (legacyGender != null) {
|
||||
int gender = "male".equals(legacyGender) ? 1 : "female".equals(legacyGender) ? 0 : 2;
|
||||
editor.putString(ActivityUser.PREF_USER_GENDER, Integer.toString(gender));
|
||||
editor.remove("mi_user_gender");
|
||||
}
|
||||
if (legacyHeight != null) {
|
||||
editor.putString(ActivityUser.PREF_USER_HEIGHT_CM, legacyHeight);
|
||||
editor.remove("mi_user_height_cm");
|
||||
}
|
||||
if (legacyWeight != null) {
|
||||
editor.putString(ActivityUser.PREF_USER_WEIGHT_KG, legacyWeight);
|
||||
editor.remove("mi_user_weight_kg");
|
||||
}
|
||||
if (legacyYOB != null) {
|
||||
editor.putString(ActivityUser.PREF_USER_YEAR_OF_BIRTH, legacyYOB);
|
||||
editor.remove("mi_user_year_of_birth");
|
||||
}
|
||||
editor.putString(PREFS_VERSION, Integer.toString(CURRENT_PREFS_VERSION));
|
||||
break;
|
||||
case 1:
|
||||
//migrate the integer version of gender introduced in version 1 to a string value, needed for the way Android accesses the shared preferences
|
||||
int legacyGender_1 = 2;
|
||||
try {
|
||||
legacyGender_1 = sharedPrefs.getInt(ActivityUser.PREF_USER_GENDER, 2);
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "Could not access legacy activity gender", e);
|
||||
}
|
||||
editor.putString(ActivityUser.PREF_USER_GENDER, Integer.toString(legacyGender_1));
|
||||
//also silently migrate the version to a string value
|
||||
editor.putString(PREFS_VERSION, Integer.toString(CURRENT_PREFS_VERSION));
|
||||
break;
|
||||
if (oldVersion == 0) {
|
||||
String legacyGender = sharedPrefs.getString("mi_user_gender", null);
|
||||
String legacyHeight = sharedPrefs.getString("mi_user_height_cm", null);
|
||||
String legacyWeight = sharedPrefs.getString("mi_user_weight_kg", null);
|
||||
String legacyYOB = sharedPrefs.getString("mi_user_year_of_birth", null);
|
||||
if (legacyGender != null) {
|
||||
int gender = "male".equals(legacyGender) ? 1 : "female".equals(legacyGender) ? 0 : 2;
|
||||
editor.putString(ActivityUser.PREF_USER_GENDER, Integer.toString(gender));
|
||||
editor.remove("mi_user_gender");
|
||||
}
|
||||
if (legacyHeight != null) {
|
||||
editor.putString(ActivityUser.PREF_USER_HEIGHT_CM, legacyHeight);
|
||||
editor.remove("mi_user_height_cm");
|
||||
}
|
||||
if (legacyWeight != null) {
|
||||
editor.putString(ActivityUser.PREF_USER_WEIGHT_KG, legacyWeight);
|
||||
editor.remove("mi_user_weight_kg");
|
||||
}
|
||||
if (legacyYOB != null) {
|
||||
editor.putString(ActivityUser.PREF_USER_YEAR_OF_BIRTH, legacyYOB);
|
||||
editor.remove("mi_user_year_of_birth");
|
||||
}
|
||||
}
|
||||
if (oldVersion < 2) {
|
||||
//migrate the integer version of gender introduced in version 1 to a string value, needed for the way Android accesses the shared preferences
|
||||
int legacyGender_1 = 2;
|
||||
try {
|
||||
legacyGender_1 = sharedPrefs.getInt(ActivityUser.PREF_USER_GENDER, 2);
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "Could not access legacy activity gender", e);
|
||||
}
|
||||
editor.putString(ActivityUser.PREF_USER_GENDER, Integer.toString(legacyGender_1));
|
||||
}
|
||||
if (oldVersion < 3) {
|
||||
List<Device> activeDevices = DBHelper.getActiveDevices(lockHandler.getDaoSession());
|
||||
for (Device dbDevice : activeDevices) {
|
||||
SharedPreferences.Editor deviceSharedPrefsEdit = GBApplication.getDeviceSpecificSharedPrefs(dbDevice.getIdentifier()).edit();
|
||||
if (sharedPrefs != null) {
|
||||
String preferenceKey = dbDevice.getIdentifier() + "_lastSportsActivityTimeMillis";
|
||||
long lastSportsActivityTimeMillis = sharedPrefs.getLong(preferenceKey, 0);
|
||||
if (lastSportsActivityTimeMillis != 0) {
|
||||
deviceSharedPrefsEdit.putLong("lastSportsActivityTimeMillis", lastSportsActivityTimeMillis);
|
||||
editor.remove(preferenceKey);
|
||||
}
|
||||
preferenceKey = dbDevice.getIdentifier() + "_lastSyncTimeMillis";
|
||||
long lastSyncTimeMillis = sharedPrefs.getLong(preferenceKey, 0);
|
||||
if (lastSyncTimeMillis != 0) {
|
||||
deviceSharedPrefsEdit.putLong("lastSyncTimeMillis", lastSyncTimeMillis);
|
||||
editor.remove(preferenceKey);
|
||||
}
|
||||
switch (fromKey(dbDevice.getType())) {
|
||||
case AMAZFITCOR:
|
||||
case AMAZFITBIP:
|
||||
case AMAZFITCOR2:
|
||||
int oldLanguage = prefs.getInt("amazfitbip_language", -1);
|
||||
String newLanguage = "auto";
|
||||
String[] oldLanguageLookup = {"zh_CN", "zh_TW", "en_US", "es_ES", "ru_RU", "de_DE", "it_IT", "fr_FR", "tr_TR"};
|
||||
if (oldLanguage >= 0 && oldLanguage < oldLanguageLookup.length) {
|
||||
newLanguage = oldLanguageLookup[oldLanguage];
|
||||
}
|
||||
deviceSharedPrefsEdit.putString("language", newLanguage);
|
||||
break;
|
||||
case MIBAND3:
|
||||
String language = sharedPrefs.getString("miband3_language", "auto");
|
||||
deviceSharedPrefsEdit.putString("language", language);
|
||||
}
|
||||
}
|
||||
|
||||
deviceSharedPrefsEdit.apply();
|
||||
}
|
||||
editor.remove("miband3_language");
|
||||
editor.remove("amazfitbip_language");
|
||||
}
|
||||
editor.putString(PREFS_VERSION, Integer.toString(CURRENT_PREFS_VERSION));
|
||||
editor.apply();
|
||||
}
|
||||
|
||||
|
@ -38,6 +38,9 @@ import android.preference.PreferenceManager;
|
||||
import android.provider.DocumentsContract;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.core.app.ActivityCompat;
|
||||
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@ -46,8 +49,6 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import androidx.core.app.ActivityCompat;
|
||||
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
|
||||
import nodomain.freeyourgadget.gadgetbridge.BuildConfig;
|
||||
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
||||
import nodomain.freeyourgadget.gadgetbridge.R;
|
||||
@ -63,14 +64,10 @@ 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_ACTIVATE_DISPLAY_ON_LIFT;
|
||||
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.huami.HuamiConst.PREF_DISPLAY_ON_LIFT_END;
|
||||
import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.PREF_DISPLAY_ON_LIFT_START;
|
||||
import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.PREF_MI2_DATEFORMAT;
|
||||
import static nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst.PREF_MI2_DISPLAY_ITEMS;
|
||||
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;
|
||||
@ -374,22 +371,6 @@ public class SettingsActivity extends AbstractSettingsActivity {
|
||||
autoFetchInterval);
|
||||
pref.setSummary(summary);
|
||||
|
||||
|
||||
|
||||
final Preference displayPages = findPreference("bip_display_items");
|
||||
displayPages.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object newVal) {
|
||||
invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
GBApplication.deviceService().onSendConfiguration(PREF_MI2_DISPLAY_ITEMS);
|
||||
}
|
||||
});
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
final Preference setDateFormat = findPreference(PREF_MI2_DATEFORMAT);
|
||||
setDateFormat.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
|
||||
@Override
|
||||
@ -404,20 +385,6 @@ public class SettingsActivity extends AbstractSettingsActivity {
|
||||
}
|
||||
});
|
||||
|
||||
final Preference miBand2DisplayItems = findPreference(PREF_MI2_DISPLAY_ITEMS);
|
||||
miBand2DisplayItems.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object newVal) {
|
||||
invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
GBApplication.deviceService().onSendConfiguration(PREF_MI2_DISPLAY_ITEMS);
|
||||
}
|
||||
});
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
final Preference miBand3ScreenUnlock = findPreference(PREF_MI3_BAND_SCREEN_UNLOCK);
|
||||
miBand3ScreenUnlock.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
|
||||
@Override
|
||||
@ -432,20 +399,6 @@ public class SettingsActivity extends AbstractSettingsActivity {
|
||||
}
|
||||
});
|
||||
|
||||
final Preference miBand3DisplayItems = findPreference("miband3_display_items");
|
||||
miBand3DisplayItems.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object newVal) {
|
||||
invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
GBApplication.deviceService().onSendConfiguration(PREF_MI2_DISPLAY_ITEMS);
|
||||
}
|
||||
});
|
||||
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);
|
||||
|
||||
@ -500,20 +453,6 @@ public class SettingsActivity extends AbstractSettingsActivity {
|
||||
}
|
||||
});
|
||||
|
||||
final Preference corDisplayItems = findPreference("cor_display_items");
|
||||
corDisplayItems.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object newVal) {
|
||||
invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
GBApplication.deviceService().onSendConfiguration(PREF_MI2_DISPLAY_ITEMS);
|
||||
}
|
||||
});
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
String disconnectNotificationState = prefs.getString(PREF_DISCONNECT_NOTIFICATION, PREF_MI2_DO_NOT_DISTURB_OFF);
|
||||
boolean disconnectNotificationScheduled = disconnectNotificationState.equals(PREF_MI2_DO_NOT_DISTURB_SCHEDULED);
|
||||
|
||||
|
@ -6,7 +6,7 @@ import androidx.preference.PreferenceFragmentCompat;
|
||||
|
||||
abstract public class DeviceSpecificSettingsFragment extends PreferenceFragmentCompat {
|
||||
|
||||
void setSettingsFileSuffix(String settingsFileSuffix) {
|
||||
public void setSettingsFileSuffix(String settingsFileSuffix) {
|
||||
Bundle args = new Bundle();
|
||||
args.putString("settingsFileSuffix", settingsFileSuffix);
|
||||
setArguments(args);
|
||||
|
@ -0,0 +1,21 @@
|
||||
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;
|
||||
}
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
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;
|
||||
}
|
||||
}
|
@ -0,0 +1,53 @@
|
||||
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;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,24 +1,21 @@
|
||||
package nodomain.freeyourgadget.gadgetbridge.activities.devicesettings;
|
||||
package nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.huami;
|
||||
|
||||
import android.os.Bundle;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.R;
|
||||
|
||||
public class HuamiSettingsFragment extends DeviceSpecificSettingsFragment {
|
||||
|
||||
public class MiBand2SettingsFragment extends HuamiSettingsFragment {
|
||||
@Override
|
||||
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
|
||||
super.onCreatePreferences(savedInstanceState, rootKey);
|
||||
setPreferencesFromResource(R.xml.devicesettings_huami, rootKey);
|
||||
addPreferencesFromResource(R.xml.devicesettings_huami_miband2);
|
||||
setChangeListener();
|
||||
}
|
||||
|
||||
public static HuamiSettingsFragment newInstance(String settingsFileSuffix) {
|
||||
HuamiSettingsFragment fragment = new HuamiSettingsFragment();
|
||||
HuamiSettingsFragment fragment = new MiBand2SettingsFragment();
|
||||
fragment.setSettingsFileSuffix(settingsFileSuffix);
|
||||
|
||||
return fragment;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,21 @@
|
||||
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;
|
||||
}
|
||||
}
|
@ -57,6 +57,8 @@ public class HuamiConst {
|
||||
public static final String PREF_DISCONNECT_NOTIFICATION_START = "disconnect_notification_start";
|
||||
public static final String PREF_DISCONNECT_NOTIFICATION_END = "disconnect_notification_end";
|
||||
|
||||
public static final String PREF_DISPLAY_ITEMS = "display_items";
|
||||
|
||||
public static int toActivityKind(int rawType) {
|
||||
switch (rawType) {
|
||||
case TYPE_DEEP_SLEEP:
|
||||
|
@ -21,9 +21,12 @@ import android.annotation.TargetApi;
|
||||
import android.app.Activity;
|
||||
import android.bluetooth.le.ScanFilter;
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.Build;
|
||||
import android.os.ParcelUuid;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@ -34,14 +37,13 @@ import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.Set;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import de.greenrobot.dao.query.QueryBuilder;
|
||||
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.HuamiSettingsFragment;
|
||||
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;
|
||||
@ -197,9 +199,9 @@ public abstract class HuamiCoordinator extends AbstractDeviceCoordinator {
|
||||
return getTimePreference(HuamiConst.PREF_DISCONNECT_NOTIFICATION_END, "00:00");
|
||||
}
|
||||
|
||||
public static Set<String> getDisplayItems() {
|
||||
Prefs prefs = GBApplication.getPrefs();
|
||||
return prefs.getStringSet(MiBandConst.PREF_MI2_DISPLAY_ITEMS, null);
|
||||
public static Set<String> getDisplayItems(String deviceAddress) {
|
||||
SharedPreferences prefs = GBApplication.getDeviceSpecificSharedPrefs(deviceAddress);
|
||||
return prefs.getStringSet(HuamiConst.PREF_DISPLAY_ITEMS, null);
|
||||
}
|
||||
|
||||
public static boolean getGoalNotification() {
|
||||
|
@ -26,6 +26,8 @@ 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.devices.InstallHandler;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiCoordinator;
|
||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||
@ -75,4 +77,9 @@ public class AmazfitBipCoordinator extends HuamiCoordinator {
|
||||
public boolean supportsWeather() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DeviceSpecificSettingsFragment getDeviceSpecificSettingsFragment(GBDevice device) {
|
||||
return AmazfitBipSettingsFragment.newInstance(device.getAddress());
|
||||
}
|
||||
}
|
||||
|
@ -26,6 +26,8 @@ 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.devices.InstallHandler;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiCoordinator;
|
||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||
@ -78,4 +80,9 @@ public class AmazfitCorCoordinator extends HuamiCoordinator {
|
||||
|
||||
@Override
|
||||
public boolean supportsUnicodeEmojis() { return true; }
|
||||
|
||||
@Override
|
||||
public DeviceSpecificSettingsFragment getDeviceSpecificSettingsFragment(GBDevice device) {
|
||||
return AmazfitCorSettingsFragment.newInstance(device.getAddress());
|
||||
}
|
||||
}
|
||||
|
@ -26,6 +26,8 @@ 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.devices.InstallHandler;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiCoordinator;
|
||||
@ -78,4 +80,9 @@ public class MiBand2Coordinator extends HuamiCoordinator {
|
||||
public boolean supportsWeather() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DeviceSpecificSettingsFragment getDeviceSpecificSettingsFragment(GBDevice device) {
|
||||
return MiBand2SettingsFragment.newInstance(device.getAddress());
|
||||
}
|
||||
}
|
||||
|
@ -29,6 +29,8 @@ 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.devices.InstallHandler;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiCoordinator;
|
||||
@ -101,4 +103,9 @@ public class MiBand3Coordinator extends HuamiCoordinator {
|
||||
public static Date getNightModeEnd() {
|
||||
return getTimePreference(MiBandConst.PREF_MI3_NIGHT_MODE_END, "07:00");
|
||||
}
|
||||
|
||||
@Override
|
||||
public DeviceSpecificSettingsFragment getDeviceSpecificSettingsFragment(GBDevice device) {
|
||||
return MiBand3SettingsFragment.newInstance(device.getAddress());
|
||||
}
|
||||
}
|
||||
|
@ -42,7 +42,6 @@ public final class MiBandConst {
|
||||
public static final String PREF_MIBAND_DEVICE_TIME_OFFSET_HOURS = "mi_device_time_offset_hours";
|
||||
public static final String PREF_MI2_DATEFORMAT = "mi2_dateformat";
|
||||
public static final String PREF_MI2_GOAL_NOTIFICATION = "mi2_goal_notification";
|
||||
public static final String PREF_MI2_DISPLAY_ITEMS = "mi2_display_items";
|
||||
public static final String PREF_MI2_DISPLAY_ITEM_CLOCK = "clock";
|
||||
public static final String PREF_MI2_DISPLAY_ITEM_STEPS = "steps";
|
||||
public static final String PREF_MI2_DISPLAY_ITEM_DISTANCE = "distance";
|
||||
|
@ -26,6 +26,8 @@ import android.net.Uri;
|
||||
import android.text.format.DateFormat;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
|
||||
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@ -38,13 +40,13 @@ import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.GregorianCalendar;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Set;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
|
||||
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
||||
import nodomain.freeyourgadget.gadgetbridge.Logging;
|
||||
import nodomain.freeyourgadget.gadgetbridge.R;
|
||||
@ -86,6 +88,7 @@ import nodomain.freeyourgadget.gadgetbridge.model.CalendarEvents;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.CallSpec;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.CannedMessagesSpec;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.DeviceService;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.DeviceType;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.MusicSpec;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.MusicStateSpec;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec;
|
||||
@ -98,6 +101,7 @@ import nodomain.freeyourgadget.gadgetbridge.service.btle.GattCharacteristic;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.btle.GattService;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.btle.actions.AbortTransactionAction;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.btle.actions.ConditionalWriteAction;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.btle.actions.SetDeviceStateAction;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.IntentListener;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.alertnotification.AlertCategory;
|
||||
@ -274,7 +278,7 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport {
|
||||
* @param builder
|
||||
*/
|
||||
public void setInitialized(TransactionBuilder builder) {
|
||||
builder.add(new SetDeviceStateAction(getDevice(), State.INITIALIZED, getContext()));
|
||||
builder.add(new SetDeviceStateAction(gbDevice, State.INITIALIZED, getContext()));
|
||||
}
|
||||
|
||||
// MB2: AVL
|
||||
@ -333,7 +337,7 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport {
|
||||
}
|
||||
|
||||
public NotificationStrategy getNotificationStrategy() {
|
||||
String firmwareVersion = getDevice().getFirmwareVersion();
|
||||
String firmwareVersion = gbDevice.getFirmwareVersion();
|
||||
if (firmwareVersion != null) {
|
||||
Version ver = new Version(firmwareVersion);
|
||||
if (MiBandConst.MI2_FW_VERSION_MIN_TEXT_NOTIFICATIONS.compareTo(ver) > 0) {
|
||||
@ -461,7 +465,7 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport {
|
||||
BluetoothGattCharacteristic characteristic = getCharacteristic(HuamiService.UUID_CHARACTERISTIC_8_USER_SETTINGS);
|
||||
if (characteristic != null) {
|
||||
builder.notify(characteristic, true);
|
||||
int location = MiBandCoordinator.getWearLocation(getDevice().getAddress());
|
||||
int location = MiBandCoordinator.getWearLocation(gbDevice.getAddress());
|
||||
switch (location) {
|
||||
case 0: // left hand
|
||||
builder.write(characteristic, HuamiService.WEAR_LOCATION_LEFT_WRIST);
|
||||
@ -516,7 +520,7 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport {
|
||||
* @param builder
|
||||
*/
|
||||
private HuamiSupport setHeartrateSleepSupport(TransactionBuilder builder) {
|
||||
final boolean enableHrSleepSupport = MiBandCoordinator.getHeartrateSleepSupport(getDevice().getAddress());
|
||||
final boolean enableHrSleepSupport = MiBandCoordinator.getHeartrateSleepSupport(gbDevice.getAddress());
|
||||
if (characteristicHRControlPoint != null) {
|
||||
builder.notify(characteristicHRControlPoint, true);
|
||||
if (enableHrSleepSupport) {
|
||||
@ -1352,7 +1356,7 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport {
|
||||
try (DBHandler handler = GBApplication.acquireDB()) {
|
||||
DaoSession session = handler.getDaoSession();
|
||||
|
||||
Device device = DBHelper.getDevice(getDevice(), session);
|
||||
Device device = DBHelper.getDevice(gbDevice, session);
|
||||
User user = DBHelper.getUser(session);
|
||||
int ts = (int) (System.currentTimeMillis() / 1000);
|
||||
MiBand2SampleProvider provider = new MiBand2SampleProvider(gbDevice, session);
|
||||
@ -1517,7 +1521,7 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport {
|
||||
case HuamiConst.PREF_DISCONNECT_NOTIFICATION_END:
|
||||
setDisconnectNotification(builder);
|
||||
break;
|
||||
case MiBandConst.PREF_MI2_DISPLAY_ITEMS:
|
||||
case HuamiConst.PREF_DISPLAY_ITEMS:
|
||||
setDisplayItems(builder);
|
||||
break;
|
||||
case MiBandConst.PREF_MI2_ROTATE_WRIST_TO_SWITCH_INFO:
|
||||
@ -1637,7 +1641,7 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport {
|
||||
}
|
||||
|
||||
protected HuamiSupport setDisplayItems(TransactionBuilder builder) {
|
||||
Set<String> pages = HuamiCoordinator.getDisplayItems();
|
||||
Set<String> pages = HuamiCoordinator.getDisplayItems(gbDevice.getAddress());
|
||||
LOG.info("Setting display items to " + (pages == null ? "none" : pages));
|
||||
|
||||
byte[] data = HuamiService.COMMAND_CHANGE_SCREENS.clone();
|
||||
@ -1809,6 +1813,54 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport {
|
||||
return this;
|
||||
}
|
||||
|
||||
protected HuamiSupport setLanguage(TransactionBuilder builder) {
|
||||
String localeString = GBApplication.getDeviceSpecificSharedPrefs(gbDevice.getAddress()).getString("language", "auto");
|
||||
if (localeString == null || localeString.equals("auto")) {
|
||||
String language = Locale.getDefault().getLanguage();
|
||||
String country = Locale.getDefault().getCountry();
|
||||
|
||||
if (country == null) {
|
||||
// sometimes country is null, no idea why, guess it.
|
||||
country = language;
|
||||
}
|
||||
localeString = language + "_" + country.toUpperCase();
|
||||
}
|
||||
LOG.info("Setting device to locale: " + localeString);
|
||||
final byte[] command_new = HuamiService.COMMAND_SET_LANGUAGE_NEW_TEMPLATE.clone();
|
||||
System.arraycopy(localeString.getBytes(), 0, command_new, 3, localeString.getBytes().length);
|
||||
|
||||
byte[] command_old;
|
||||
switch (localeString.substring(0, 2)) {
|
||||
case "es":
|
||||
command_old = AmazfitBipService.COMMAND_SET_LANGUAGE_SPANISH;
|
||||
break;
|
||||
case "zh":
|
||||
if (localeString.equals("zh_CN")) {
|
||||
command_old = AmazfitBipService.COMMAND_SET_LANGUAGE_SIMPLIFIED_CHINESE;
|
||||
} else {
|
||||
command_old = AmazfitBipService.COMMAND_SET_LANGUAGE_TRADITIONAL_CHINESE;
|
||||
|
||||
}
|
||||
break;
|
||||
default:
|
||||
command_old = AmazfitBipService.COMMAND_SET_LANGUAGE_ENGLISH;
|
||||
}
|
||||
final byte[] finalCommand_old = command_old;
|
||||
builder.add(new ConditionalWriteAction(getCharacteristic(HuamiService.UUID_CHARACTERISTIC_3_CONFIGURATION)) {
|
||||
@Override
|
||||
protected byte[] checkCondition() {
|
||||
if ((gbDevice.getType() == DeviceType.AMAZFITBIP && new Version(gbDevice.getFirmwareVersion()).compareTo(new Version("0.1.0.77")) >= 0) ||
|
||||
(gbDevice.getType() == DeviceType.AMAZFITCOR && new Version(gbDevice.getFirmwareVersion()).compareTo(new Version("1.0.7.23")) >= 0)) {
|
||||
return command_new;
|
||||
} else {
|
||||
return finalCommand_old;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
protected void writeToChunked(TransactionBuilder builder, int type, byte[] data) {
|
||||
final int MAX_CHUNKLENGTH = 17;
|
||||
int remaining = data.length;
|
||||
|
@ -62,7 +62,6 @@ import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.amazfitbip.ope
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.operations.FetchActivityOperation;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.operations.FetchSportsSummaryOperation;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.miband.NotificationStrategy;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.Prefs;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.StringUtils;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.Version;
|
||||
|
||||
@ -185,14 +184,7 @@ public class AmazfitBipSupport extends HuamiSupport {
|
||||
return this;
|
||||
}
|
||||
|
||||
Version version = new Version(gbDevice.getFirmwareVersion());
|
||||
if (version.compareTo(new Version("0.1.1.14")) < 0) {
|
||||
LOG.warn("Won't set menu items since firmware is too low to be safe");
|
||||
return this;
|
||||
}
|
||||
|
||||
Prefs prefs = GBApplication.getPrefs();
|
||||
Set<String> pages = prefs.getStringSet("bip_display_items", null);
|
||||
Set<String> pages = HuamiCoordinator.getDisplayItems(gbDevice.getAddress());
|
||||
LOG.info("Setting display items to " + (pages == null ? "none" : pages));
|
||||
byte[] command = AmazfitBipService.COMMAND_CHANGE_SCREENS.clone();
|
||||
|
||||
@ -483,114 +475,6 @@ public class AmazfitBipSupport extends HuamiSupport {
|
||||
return this;
|
||||
}
|
||||
|
||||
protected AmazfitBipSupport setLanguage(TransactionBuilder builder) {
|
||||
|
||||
String language = Locale.getDefault().getLanguage();
|
||||
String country = Locale.getDefault().getCountry();
|
||||
|
||||
LOG.info("Setting watch language, phone language = " + language + " country = " + country);
|
||||
|
||||
final byte[] command_new;
|
||||
final byte[] command_old;
|
||||
String localeString;
|
||||
|
||||
switch (GBApplication.getPrefs().getInt("amazfitbip_language", -1)) {
|
||||
case 0:
|
||||
command_old = AmazfitBipService.COMMAND_SET_LANGUAGE_SIMPLIFIED_CHINESE;
|
||||
localeString = "zh_CN";
|
||||
break;
|
||||
case 1:
|
||||
command_old = AmazfitBipService.COMMAND_SET_LANGUAGE_TRADITIONAL_CHINESE;
|
||||
localeString = "zh_TW";
|
||||
break;
|
||||
case 2:
|
||||
command_old = AmazfitBipService.COMMAND_SET_LANGUAGE_ENGLISH;
|
||||
localeString = "en_US";
|
||||
break;
|
||||
case 3:
|
||||
command_old = AmazfitBipService.COMMAND_SET_LANGUAGE_SPANISH;
|
||||
localeString = "es_ES";
|
||||
break;
|
||||
case 4:
|
||||
command_old = AmazfitBipService.COMMAND_SET_LANGUAGE_ENGLISH;
|
||||
localeString = "ru_RU";
|
||||
break;
|
||||
case 5:
|
||||
command_old = AmazfitBipService.COMMAND_SET_LANGUAGE_ENGLISH;
|
||||
localeString = "de_DE";
|
||||
break;
|
||||
case 6:
|
||||
command_old = AmazfitBipService.COMMAND_SET_LANGUAGE_ENGLISH;
|
||||
localeString = "it_IT";
|
||||
break;
|
||||
case 7:
|
||||
command_old = AmazfitBipService.COMMAND_SET_LANGUAGE_ENGLISH;
|
||||
localeString = "fr_FR";
|
||||
break;
|
||||
case 8:
|
||||
command_old = AmazfitBipService.COMMAND_SET_LANGUAGE_ENGLISH;
|
||||
localeString = "tr_TR";
|
||||
break;
|
||||
default:
|
||||
switch (language) {
|
||||
case "zh":
|
||||
if (country.equals("TW") || country.equals("HK") || country.equals("MO")) { // Taiwan, Hong Kong, Macao
|
||||
command_old = AmazfitBipService.COMMAND_SET_LANGUAGE_TRADITIONAL_CHINESE;
|
||||
localeString = "zh_TW";
|
||||
} else {
|
||||
command_old = AmazfitBipService.COMMAND_SET_LANGUAGE_SIMPLIFIED_CHINESE;
|
||||
localeString = "zh_CN";
|
||||
}
|
||||
break;
|
||||
case "es":
|
||||
command_old = AmazfitBipService.COMMAND_SET_LANGUAGE_SPANISH;
|
||||
localeString = "es_ES";
|
||||
break;
|
||||
case "ru":
|
||||
command_old = AmazfitBipService.COMMAND_SET_LANGUAGE_ENGLISH;
|
||||
localeString = "ru_RU";
|
||||
break;
|
||||
case "de":
|
||||
command_old = AmazfitBipService.COMMAND_SET_LANGUAGE_ENGLISH;
|
||||
localeString = "de_DE";
|
||||
break;
|
||||
case "it":
|
||||
command_old = AmazfitBipService.COMMAND_SET_LANGUAGE_ENGLISH;
|
||||
localeString = "it_IT";
|
||||
break;
|
||||
case "fr":
|
||||
command_old = AmazfitBipService.COMMAND_SET_LANGUAGE_ENGLISH;
|
||||
localeString = "fr_FR";
|
||||
break;
|
||||
case "tr":
|
||||
command_old = AmazfitBipService.COMMAND_SET_LANGUAGE_ENGLISH;
|
||||
localeString = "tr_TR";
|
||||
break;
|
||||
default:
|
||||
command_old = AmazfitBipService.COMMAND_SET_LANGUAGE_ENGLISH;
|
||||
localeString = "en_US";
|
||||
break;
|
||||
}
|
||||
}
|
||||
command_new = HuamiService.COMMAND_SET_LANGUAGE_NEW_TEMPLATE.clone();
|
||||
System.arraycopy(localeString.getBytes(), 0, command_new, 3, localeString.getBytes().length);
|
||||
|
||||
builder.add(new ConditionalWriteAction(getCharacteristic(HuamiService.UUID_CHARACTERISTIC_3_CONFIGURATION)) {
|
||||
@Override
|
||||
protected byte[] checkCondition() {
|
||||
if ((gbDevice.getType() == DeviceType.AMAZFITBIP && new Version(gbDevice.getFirmwareVersion()).compareTo(new Version("0.1.0.77")) >= 0) ||
|
||||
(gbDevice.getType() == DeviceType.AMAZFITCOR && new Version(gbDevice.getFirmwareVersion()).compareTo(new Version("1.0.7.23")) >= 0)) {
|
||||
return command_new;
|
||||
} else {
|
||||
return command_old;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void phase2Initialize(TransactionBuilder builder) {
|
||||
super.phase2Initialize(builder);
|
||||
|
@ -25,14 +25,13 @@ import org.slf4j.LoggerFactory;
|
||||
import java.io.IOException;
|
||||
import java.util.Set;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiCoordinator;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiFWHelper;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiService;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.huami.amazfitcor.AmazfitCorFWHelper;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.huami.amazfitcor.AmazfitCorService;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.amazfitbip.AmazfitBipSupport;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.Prefs;
|
||||
|
||||
public class AmazfitCorSupport extends AmazfitBipSupport {
|
||||
|
||||
@ -41,8 +40,7 @@ public class AmazfitCorSupport extends AmazfitBipSupport {
|
||||
@Override
|
||||
protected AmazfitCorSupport setDisplayItems(TransactionBuilder builder) {
|
||||
|
||||
Prefs prefs = GBApplication.getPrefs();
|
||||
Set<String> pages = prefs.getStringSet("cor_display_items", null);
|
||||
Set<String> pages = HuamiCoordinator.getDisplayItems(getDevice().getAddress());
|
||||
LOG.info("Setting display items to " + (pages == null ? "none" : pages));
|
||||
byte[] command = AmazfitCorService.COMMAND_CHANGE_SCREENS.clone();
|
||||
|
||||
|
@ -125,29 +125,6 @@ public class MiBand3Support extends AmazfitBipSupport {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected MiBand3Support setLanguage(TransactionBuilder builder) {
|
||||
String localeString = GBApplication.getPrefs().getString("miband3_language", "auto");
|
||||
|
||||
if (localeString.equals("auto")) {
|
||||
String language = Locale.getDefault().getLanguage();
|
||||
String country = Locale.getDefault().getCountry();
|
||||
|
||||
if (country == null) {
|
||||
// sometimes country is null, no idea why, guess it.
|
||||
country = language;
|
||||
}
|
||||
localeString = language + "_" + country.toUpperCase();
|
||||
}
|
||||
LOG.info("Setting device to locale: " + localeString);
|
||||
byte[] command_new = HuamiService.COMMAND_SET_LANGUAGE_NEW_TEMPLATE.clone();
|
||||
System.arraycopy(localeString.getBytes(), 0, command_new, 3, localeString.getBytes().length);
|
||||
|
||||
builder.write(getCharacteristic(HuamiService.UUID_CHARACTERISTIC_3_CONFIGURATION), command_new);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
private MiBand3Support setBandScreenUnlock(TransactionBuilder builder) {
|
||||
boolean enable = MiBand3Coordinator.getBandScreenUnlock();
|
||||
LOG.info("Setting band screen unlock to " + enable);
|
||||
|
@ -22,6 +22,9 @@ import android.bluetooth.BluetoothGattCharacteristic;
|
||||
import android.content.SharedPreferences;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.CallSuper;
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@ -33,8 +36,6 @@ import java.util.GregorianCalendar;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import androidx.annotation.CallSuper;
|
||||
import androidx.annotation.NonNull;
|
||||
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
||||
import nodomain.freeyourgadget.gadgetbridge.Logging;
|
||||
import nodomain.freeyourgadget.gadgetbridge.R;
|
||||
@ -57,11 +58,10 @@ public abstract class AbstractFetchOperation extends AbstractHuamiOperation {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(AbstractFetchOperation.class);
|
||||
|
||||
protected byte lastPacketCounter;
|
||||
protected int fetchCount;
|
||||
int fetchCount;
|
||||
protected BluetoothGattCharacteristic characteristicActivityData;
|
||||
protected BluetoothGattCharacteristic characteristicFetch;
|
||||
protected Calendar startTimestamp;
|
||||
protected int expectedDataLength;
|
||||
Calendar startTimestamp;
|
||||
|
||||
public AbstractFetchOperation(HuamiSupport support) {
|
||||
super(support);
|
||||
@ -123,7 +123,7 @@ public abstract class AbstractFetchOperation extends AbstractHuamiOperation {
|
||||
|
||||
@CallSuper
|
||||
protected void handleActivityFetchFinish(boolean success) {
|
||||
GB.updateTransferNotification(null,"",false,100,getContext());
|
||||
GB.updateTransferNotification(null, "", false, 100, getContext());
|
||||
operationFinished();
|
||||
unsetBusy();
|
||||
}
|
||||
@ -175,13 +175,13 @@ public abstract class AbstractFetchOperation extends AbstractHuamiOperation {
|
||||
});
|
||||
}
|
||||
|
||||
protected void handleActivityMetadata(byte[] value) {
|
||||
private void handleActivityMetadata(byte[] value) {
|
||||
if (value.length == 15) {
|
||||
// first two bytes are whether our request was accepted
|
||||
if (ArrayUtils.equals(value, HuamiService.RESPONSE_ACTIVITY_DATA_START_DATE_SUCCESS, 0)) {
|
||||
// the third byte (0x01 on success) = ?
|
||||
// the 4th - 7th bytes epresent the number of bytes/packets to expect, excluding the counter bytes
|
||||
expectedDataLength = BLETypeConversions.toUint32(Arrays.copyOfRange(value, 3, 7));
|
||||
//int expectedDataLength = BLETypeConversions.toUint32(Arrays.copyOfRange(value, 3, 7));
|
||||
|
||||
// last 8 bytes are the start date
|
||||
Calendar startTimestamp = getSupport().fromTimeBytes(Arrays.copyOfRange(value, 7, value.length));
|
||||
@ -189,7 +189,7 @@ public abstract class AbstractFetchOperation extends AbstractHuamiOperation {
|
||||
|
||||
GB.updateTransferNotification(getContext().getString(R.string.busy_task_fetch_activity_data),
|
||||
getContext().getString(R.string.FetchActivityOperation_about_to_transfer_since,
|
||||
DateFormat.getDateTimeInstance().format(startTimestamp.getTime())), true, 0, getContext());;
|
||||
DateFormat.getDateTimeInstance().format(startTimestamp.getTime())), true, 0, getContext());
|
||||
} else {
|
||||
LOG.warn("Unexpected activity metadata: " + Logging.formatBytes(value));
|
||||
handleActivityFetchFinish(false);
|
||||
@ -207,30 +207,30 @@ public abstract class AbstractFetchOperation extends AbstractHuamiOperation {
|
||||
}
|
||||
}
|
||||
|
||||
protected void setStartTimestamp(Calendar startTimestamp) {
|
||||
private void setStartTimestamp(Calendar startTimestamp) {
|
||||
this.startTimestamp = startTimestamp;
|
||||
}
|
||||
|
||||
protected Calendar getLastStartTimestamp() {
|
||||
Calendar getLastStartTimestamp() {
|
||||
return startTimestamp;
|
||||
}
|
||||
|
||||
protected void saveLastSyncTimestamp(@NonNull GregorianCalendar timestamp) {
|
||||
SharedPreferences.Editor editor = GBApplication.getPrefs().getPreferences().edit();
|
||||
void saveLastSyncTimestamp(@NonNull GregorianCalendar timestamp) {
|
||||
SharedPreferences.Editor editor = GBApplication.getDeviceSpecificSharedPrefs(getDevice().getAddress()).edit();
|
||||
editor.putLong(getLastSyncTimeKey(), timestamp.getTimeInMillis());
|
||||
editor.apply();
|
||||
}
|
||||
|
||||
|
||||
protected GregorianCalendar getLastSuccessfulSyncTime() {
|
||||
long timeStampMillis = GBApplication.getPrefs().getLong(getLastSyncTimeKey(), 0);
|
||||
long timeStampMillis = GBApplication.getDeviceSpecificSharedPrefs(getDevice().getAddress()).getLong(getLastSyncTimeKey(), 0);
|
||||
if (timeStampMillis != 0) {
|
||||
GregorianCalendar calendar = BLETypeConversions.createCalendar();
|
||||
calendar.setTimeInMillis(timeStampMillis);
|
||||
return calendar;
|
||||
}
|
||||
GregorianCalendar calendar = BLETypeConversions.createCalendar();
|
||||
calendar.add(Calendar.DAY_OF_MONTH, - 100);
|
||||
calendar.add(Calendar.DAY_OF_MONTH, -100);
|
||||
return calendar;
|
||||
}
|
||||
}
|
||||
|
@ -203,6 +203,6 @@ public class FetchActivityOperation extends AbstractFetchOperation {
|
||||
|
||||
@Override
|
||||
protected String getLastSyncTimeKey() {
|
||||
return getDevice().getAddress() + "_" + "lastSyncTimeMillis";
|
||||
return "lastSyncTimeMillis";
|
||||
}
|
||||
}
|
||||
|
@ -56,7 +56,7 @@ public class FetchSportsDetailsOperation extends AbstractFetchOperation {
|
||||
|
||||
private ByteArrayOutputStream buffer;
|
||||
|
||||
public FetchSportsDetailsOperation(@NonNull BaseActivitySummary summary, @NonNull HuamiSupport support, @NonNull String lastSyncTimeKey) {
|
||||
FetchSportsDetailsOperation(@NonNull BaseActivitySummary summary, @NonNull HuamiSupport support, @NonNull String lastSyncTimeKey) {
|
||||
super(support);
|
||||
setName("fetching sport details");
|
||||
this.summary = summary;
|
||||
@ -131,7 +131,7 @@ public class FetchSportsDetailsOperation extends AbstractFetchOperation {
|
||||
super.handleActivityFetchFinish(success);
|
||||
}
|
||||
|
||||
protected ActivityTrackExporter createExporter() {
|
||||
private ActivityTrackExporter createExporter() {
|
||||
GPXExporter exporter = new GPXExporter();
|
||||
exporter.setCreator(GBApplication.app().getNameAndVersion());
|
||||
return exporter;
|
||||
@ -169,7 +169,6 @@ public class FetchSportsDetailsOperation extends AbstractFetchOperation {
|
||||
} else {
|
||||
GB.toast("Error " + getName() + ", invalid package counter: " + value[0] + ", last was: " + lastPacketCounter, Toast.LENGTH_LONG, GB.ERROR);
|
||||
handleActivityFetchFinish(false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -241,6 +241,6 @@ public class FetchSportsSummaryOperation extends AbstractFetchOperation {
|
||||
|
||||
@Override
|
||||
protected String getLastSyncTimeKey() {
|
||||
return getDevice().getAddress() + "_" + "lastSportsActivityTimeMillis";
|
||||
return "lastSportsActivityTimeMillis";
|
||||
}
|
||||
}
|
||||
|
@ -350,29 +350,29 @@
|
||||
</string-array>
|
||||
|
||||
<string-array name="pref_amazfitbip_language">
|
||||
<item name="-1">@string/automatic</item>
|
||||
<item name="0">@string/simplified_chinese</item>
|
||||
<item name="1">@string/traditional_chinese</item>
|
||||
<item name="2">@string/english</item>
|
||||
<item name="3">@string/spanish</item>
|
||||
<item name="4">@string/russian</item>
|
||||
<item name="5">@string/german</item>
|
||||
<item name="6">@string/italian</item>
|
||||
<item name="7">@string/french</item>
|
||||
<item name="8">@string/turkish</item>
|
||||
<item name="auto">@string/automatic</item>
|
||||
<item name="zh_CH">@string/simplified_chinese</item>
|
||||
<item name="zh_TW">@string/traditional_chinese</item>
|
||||
<item name="en_US">@string/english</item>
|
||||
<item name="es_ES">@string/spanish</item>
|
||||
<item name="de_DE">@string/german</item>
|
||||
<item name="it_IT">@string/italian</item>
|
||||
<item name="fr_FR">@string/french</item>
|
||||
<item name="tr_TR">@string/turkish</item>
|
||||
<item name="ru_RU">@string/russian</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="pref_amazfitbip_language_values">
|
||||
<item>-1</item>
|
||||
<item>0</item>
|
||||
<item>1</item>
|
||||
<item>2</item>
|
||||
<item>3</item>
|
||||
<item>4</item>
|
||||
<item>5</item>
|
||||
<item>6</item>
|
||||
<item>7</item>
|
||||
<item>8</item>
|
||||
<item>auto</item>
|
||||
<item>zh_CH</item>
|
||||
<item>zh_TW</item>
|
||||
<item>en_US</item>
|
||||
<item>es_ES</item>
|
||||
<item>de_DE</item>
|
||||
<item>it_IT</item>
|
||||
<item>fr_FR</item>
|
||||
<item>tr_TR</item>
|
||||
<item>ru_RU</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="pref_miband3_language">
|
||||
|
@ -1,6 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
<androidx.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<EditTextPreference
|
||||
android:key="authkey"
|
||||
|
18
app/src/main/res/xml/devicesettings_huami_bip.xml
Normal file
18
app/src/main/res/xml/devicesettings_huami_bip.xml
Normal file
@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<MultiSelectListPreference
|
||||
android:defaultValue="@array/pref_bip_display_items_default"
|
||||
android:dialogTitle="@string/mi2_prefs_display_items"
|
||||
android:entries="@array/pref_bip_display_items"
|
||||
android:entryValues="@array/pref_bip_display_items_values"
|
||||
android:key="display_items"
|
||||
android:summary="@string/mi2_prefs_display_items_summary"
|
||||
android:title="@string/mi2_prefs_display_items" />
|
||||
<ListPreference
|
||||
android:defaultValue="auto"
|
||||
android:entries="@array/pref_amazfitbip_language"
|
||||
android:entryValues="@array/pref_amazfitbip_language_values"
|
||||
android:key="language"
|
||||
android:summary="%s"
|
||||
android:title="@string/pref_title_language" />
|
||||
</androidx.preference.PreferenceScreen>
|
18
app/src/main/res/xml/devicesettings_huami_cor.xml
Normal file
18
app/src/main/res/xml/devicesettings_huami_cor.xml
Normal file
@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<MultiSelectListPreference
|
||||
android:defaultValue="@array/pref_cor_display_items_default"
|
||||
android:dialogTitle="@string/mi2_prefs_display_items"
|
||||
android:entries="@array/pref_cor_display_items"
|
||||
android:entryValues="@array/pref_cor_display_items_values"
|
||||
android:key="display_items"
|
||||
android:summary="@string/mi2_prefs_display_items_summary"
|
||||
android:title="@string/mi2_prefs_display_items" />
|
||||
<ListPreference
|
||||
android:defaultValue="auto"
|
||||
android:entries="@array/pref_amazfitbip_language"
|
||||
android:entryValues="@array/pref_amazfitbip_language_values"
|
||||
android:key="language"
|
||||
android:summary="%s"
|
||||
android:title="@string/pref_title_language" />
|
||||
</androidx.preference.PreferenceScreen>
|
11
app/src/main/res/xml/devicesettings_huami_miband2.xml
Normal file
11
app/src/main/res/xml/devicesettings_huami_miband2.xml
Normal file
@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<MultiSelectListPreference
|
||||
android:defaultValue="@array/pref_mi2_display_items_default"
|
||||
android:dialogTitle="@string/mi2_prefs_display_items"
|
||||
android:entries="@array/pref_mi2_display_items"
|
||||
android:entryValues="@array/pref_mi2_display_items_values"
|
||||
android:key="display_items"
|
||||
android:summary="@string/mi2_prefs_display_items_summary"
|
||||
android:title="@string/mi2_prefs_display_items" />
|
||||
</androidx.preference.PreferenceScreen>
|
18
app/src/main/res/xml/devicesettings_huami_miband3.xml
Normal file
18
app/src/main/res/xml/devicesettings_huami_miband3.xml
Normal file
@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<MultiSelectListPreference
|
||||
android:defaultValue="@array/pref_miband3_display_items_default"
|
||||
android:dialogTitle="@string/mi2_prefs_display_items"
|
||||
android:entries="@array/pref_miband3_display_items"
|
||||
android:entryValues="@array/pref_miband3_display_items_values"
|
||||
android:key="display_items"
|
||||
android:summary="@string/mi2_prefs_display_items_summary"
|
||||
android:title="@string/mi2_prefs_display_items" />
|
||||
<ListPreference
|
||||
android:defaultValue="auto"
|
||||
android:entries="@array/pref_miband3_language"
|
||||
android:entryValues="@array/pref_miband3_language_values"
|
||||
android:key="language"
|
||||
android:summary="%s"
|
||||
android:title="@string/pref_title_language" />
|
||||
</androidx.preference.PreferenceScreen>
|
@ -288,40 +288,17 @@
|
||||
android:key="mi2_dateformat"
|
||||
android:title="@string/miband2_prefs_dateformat"
|
||||
android:summary="%s" />
|
||||
<MultiSelectListPreference
|
||||
android:dialogTitle="@string/mi2_prefs_display_items"
|
||||
android:defaultValue="@array/pref_mi2_display_items_default"
|
||||
android:entries="@array/pref_mi2_display_items"
|
||||
android:entryValues="@array/pref_mi2_display_items_values"
|
||||
android:key="mi2_display_items"
|
||||
android:summary="@string/mi2_prefs_display_items_summary"
|
||||
android:title="@string/mi2_prefs_display_items"/>
|
||||
</PreferenceScreen>
|
||||
|
||||
<PreferenceScreen
|
||||
android:icon="@drawable/ic_device_miband2"
|
||||
android:title="@string/preferences_miband3_settings">
|
||||
<ListPreference
|
||||
android:defaultValue="auto"
|
||||
android:entries="@array/pref_miband3_language"
|
||||
android:entryValues="@array/pref_miband3_language_values"
|
||||
android:key="miband3_language"
|
||||
android:summary="%s"
|
||||
android:title="@string/pref_title_language" />
|
||||
<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" />
|
||||
<MultiSelectListPreference
|
||||
android:dialogTitle="@string/mi2_prefs_display_items"
|
||||
android:defaultValue="@array/pref_miband3_display_items_default"
|
||||
android:entries="@array/pref_miband3_display_items"
|
||||
android:entryValues="@array/pref_miband3_display_items_values"
|
||||
android:key="miband3_display_items"
|
||||
android:summary="@string/mi2_prefs_display_items_summary"
|
||||
android:title="@string/mi2_prefs_display_items"/>
|
||||
<PreferenceScreen
|
||||
android:persistent="false"
|
||||
android:title="@string/mi3_prefs_night_mode"
|
||||
@ -353,21 +330,6 @@
|
||||
<PreferenceScreen
|
||||
android:icon="@drawable/ic_device_hplus"
|
||||
android:title="@string/preferences_amazfitbip_settings">
|
||||
<ListPreference
|
||||
android:defaultValue="-1"
|
||||
android:entries="@array/pref_amazfitbip_language"
|
||||
android:entryValues="@array/pref_amazfitbip_language_values"
|
||||
android:key="amazfitbip_language"
|
||||
android:summary="%s"
|
||||
android:title="@string/pref_title_language" />
|
||||
<MultiSelectListPreference
|
||||
android:dialogTitle="@string/mi2_prefs_display_items"
|
||||
android:defaultValue="@array/pref_bip_display_items_default"
|
||||
android:entries="@array/pref_bip_display_items"
|
||||
android:entryValues="@array/pref_bip_display_items_values"
|
||||
android:key="bip_display_items"
|
||||
android:summary="@string/mi2_prefs_display_items_summary"
|
||||
android:title="@string/mi2_prefs_display_items"/>
|
||||
<PreferenceScreen
|
||||
android:persistent="false"
|
||||
android:title="@string/prefs_disconnect_notification">
|
||||
@ -396,18 +358,6 @@
|
||||
</PreferenceScreen>
|
||||
|
||||
</PreferenceScreen>
|
||||
<PreferenceScreen
|
||||
android:icon="@drawable/ic_device_miband"
|
||||
android:title="@string/preferences_amazfitcor_settings">
|
||||
<MultiSelectListPreference
|
||||
android:dialogTitle="@string/mi2_prefs_display_items"
|
||||
android:defaultValue="@array/pref_cor_display_items_default"
|
||||
android:entries="@array/pref_cor_display_items"
|
||||
android:entryValues="@array/pref_cor_display_items_values"
|
||||
android:key="cor_display_items"
|
||||
android:summary="@string/mi2_prefs_display_items_summary"
|
||||
android:title="@string/mi2_prefs_display_items"/>
|
||||
</PreferenceScreen>
|
||||
<PreferenceScreen
|
||||
android:icon="@drawable/ic_device_pebble"
|
||||
android:key="pref_key_pebble"
|
||||
|
Loading…
Reference in New Issue
Block a user