diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index dd79d2760..f15ef9079 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -42,6 +42,13 @@
android:name="android.support.PARENT_ACTIVITY"
android:value=".ControlCenter" />
+
+
+
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/SettingsActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/SettingsActivity.java
index 3254c986f..eac298401 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/SettingsActivity.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/SettingsActivity.java
@@ -1,6 +1,7 @@
package nodomain.freeyourgadget.gadgetbridge;
import android.content.Intent;
+import android.media.audiofx.BassBoost;
import android.os.Bundle;
import android.preference.ListPreference;
import android.preference.Preference;
@@ -10,12 +11,19 @@ import android.support.v4.app.NavUtils;
import android.support.v4.content.LocalBroadcastManager;
import android.view.MenuItem;
-public class SettingsActivity extends PreferenceActivity {
+import nodomain.freeyourgadget.gadgetbridge.activities.AbstractSettingsActivity;
+import nodomain.freeyourgadget.gadgetbridge.miband.MiBandPreferencesActivity;
+
+public class SettingsActivity extends AbstractSettingsActivity {
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ addPreferencesFromResource(R.xml.preferences);
+ }
+
@Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
- getActionBar().setDisplayHomeAsUpEnabled(true);
- addPreferencesFromResource(R.xml.preferences);
Preference pref = (Preference) findPreference("notifications_generic");
pref.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
@@ -25,9 +33,16 @@ public class SettingsActivity extends PreferenceActivity {
return true;
}
});
- final Preference developmentMiaddr = findPreference(GB.PREF_DEVELOPMENT_MIBAND_ADDRESS);
- bindPreferenceSummaryToValue(developmentMiaddr);
+ pref = (Preference) findPreference("pref_key_miband");
+ pref.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
+ public boolean onPreferenceClick(Preference preference) {
+ Intent enableIntent = new Intent(SettingsActivity.this, MiBandPreferencesActivity.class);
+ startActivity(enableIntent);
+ return true;
+ }
+ });
+ final Preference developmentMiaddr = findPreference(GB.PREF_DEVELOPMENT_MIBAND_ADDRESS);
developmentMiaddr.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newVal) {
@@ -40,65 +55,8 @@ public class SettingsActivity extends PreferenceActivity {
});
}
-
- /**
- * A preference value change listener that updates the preference's summary
- * to reflect its new value.
- */
- private static Preference.OnPreferenceChangeListener sBindPreferenceSummaryToValueListener = new Preference.OnPreferenceChangeListener() {
- @Override
- public boolean onPreferenceChange(Preference preference, Object value) {
- String stringValue = value.toString();
-
- if (preference instanceof ListPreference) {
- // For list preferences, look up the correct display value in
- // the preference's 'entries' list.
- ListPreference listPreference = (ListPreference) preference;
- int index = listPreference.findIndexOfValue(stringValue);
-
- // Set the summary to reflect the new value.
- preference.setSummary(
- index >= 0
- ? listPreference.getEntries()[index]
- : null);
-
- } else {
- // For all other preferences, set the summary to the value's
- // simple string representation.
- preference.setSummary(stringValue);
- }
- return true;
- }
- };
-
- /**
- * Binds a preference's summary to its value. More specifically, when the
- * preference's value is changed, its summary (line of text below the
- * preference title) is updated to reflect the value. The summary is also
- * immediately updated upon calling this method. The exact display format is
- * dependent on the type of preference.
- *
- * @see #sBindPreferenceSummaryToValueListener
- */
- private static void bindPreferenceSummaryToValue(Preference preference) {
- // Set the listener to watch for value changes.
- preference.setOnPreferenceChangeListener(sBindPreferenceSummaryToValueListener);
-
- // Trigger the listener immediately with the preference's
- // current value.
- sBindPreferenceSummaryToValueListener.onPreferenceChange(preference,
- PreferenceManager
- .getDefaultSharedPreferences(preference.getContext())
- .getString(preference.getKey(), ""));
- }
-
@Override
- public boolean onOptionsItemSelected(MenuItem item) {
- switch (item.getItemId()) {
- case android.R.id.home:
- NavUtils.navigateUpFromSameTask(this);
- return true;
- }
- return super.onOptionsItemSelected(item);
+ protected String[] getPreferenceKeysWithSummary() {
+ return new String[] { GB.PREF_DEVELOPMENT_MIBAND_ADDRESS };
}
}
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/AbstractSettingsActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/AbstractSettingsActivity.java
new file mode 100644
index 000000000..da88e019a
--- /dev/null
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/AbstractSettingsActivity.java
@@ -0,0 +1,101 @@
+package nodomain.freeyourgadget.gadgetbridge.activities;
+
+import android.os.Bundle;
+import android.preference.ListPreference;
+import android.preference.Preference;
+import android.preference.PreferenceActivity;
+import android.preference.PreferenceManager;
+import android.support.v4.app.NavUtils;
+import android.util.Log;
+import android.view.MenuItem;
+
+public class AbstractSettingsActivity extends PreferenceActivity {
+
+ private static final String TAG = "AbstractSettingsAct";
+
+ @Override
+ protected void onPostCreate(Bundle savedInstanceState) {
+ super.onPostCreate(savedInstanceState);
+
+ getActionBar().setDisplayHomeAsUpEnabled(true);
+
+ for (String prefKey : getPreferenceKeysWithSummary()) {
+ final Preference pref = findPreference(prefKey);
+ if (pref != null) {
+ bindPreferenceSummaryToValue(pref);
+ } else {
+ Log.e(TAG, "Unknown preference key: " + prefKey + ", unable to display value.");
+ }
+ }
+ }
+
+ /**
+ * Subclasses should reimplement this to return the keys of those
+ * preferences which should print its values as a summary below the
+ * preference name.
+ */
+ protected String[] getPreferenceKeysWithSummary() {
+ return new String[0];
+ }
+
+ /**
+ * A preference value change listener that updates the preference's summary
+ * to reflect its new value.
+ */
+ private static Preference.OnPreferenceChangeListener sBindPreferenceSummaryToValueListener = new Preference.OnPreferenceChangeListener() {
+ @Override
+ public boolean onPreferenceChange(Preference preference, Object value) {
+ String stringValue = value.toString();
+
+ if (preference instanceof ListPreference) {
+ // For list preferences, look up the correct display value in
+ // the preference's 'entries' list.
+ ListPreference listPreference = (ListPreference) preference;
+ int index = listPreference.findIndexOfValue(stringValue);
+
+ // Set the summary to reflect the new value.
+ preference.setSummary(
+ index >= 0
+ ? listPreference.getEntries()[index]
+ : null);
+
+ } else {
+ // For all other preferences, set the summary to the value's
+ // simple string representation.
+ preference.setSummary(stringValue);
+ }
+ return true;
+ }
+ };
+
+ /**
+ * Binds a preference's summary to its value. More specifically, when the
+ * preference's value is changed, its summary (line of text below the
+ * preference title) is updated to reflect the value. The summary is also
+ * immediately updated upon calling this method. The exact display format is
+ * dependent on the type of preference.
+ *
+ * @see #sBindPreferenceSummaryToValueListener
+ */
+ private static void bindPreferenceSummaryToValue(Preference preference) {
+ // Set the listener to watch for value changes.
+ preference.setOnPreferenceChangeListener(sBindPreferenceSummaryToValueListener);
+
+ // Trigger the listener immediately with the preference's
+ // current value.
+ sBindPreferenceSummaryToValueListener.onPreferenceChange(preference,
+ PreferenceManager
+ .getDefaultSharedPreferences(preference.getContext())
+ .getString(preference.getKey(), ""));
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case android.R.id.home:
+ NavUtils.navigateUpFromSameTask(this);
+ return true;
+ }
+ return super.onOptionsItemSelected(item);
+ }
+}
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/miband/MiBandConst.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/miband/MiBandConst.java
new file mode 100644
index 000000000..6e99a6069
--- /dev/null
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/miband/MiBandConst.java
@@ -0,0 +1,10 @@
+package nodomain.freeyourgadget.gadgetbridge.miband;
+
+public interface MiBandConst {
+
+ String PREF_USER_ALIAS = "mi_user_alias";
+ String PREF_USER_YEAR_OF_BIRTH = "mi_user_year_of_birth";
+ String PREF_USER_GENDER = "mi_user_gender";
+ String PREF_USER_HEIGHT_CM = "mi_user_height_cm";
+ String PREF_USER_WEIGHT_KG = "mi_user_weight_kg";
+}
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/miband/MiBandPreferencesActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/miband/MiBandPreferencesActivity.java
new file mode 100644
index 000000000..6c55ac8eb
--- /dev/null
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/miband/MiBandPreferencesActivity.java
@@ -0,0 +1,30 @@
+package nodomain.freeyourgadget.gadgetbridge.miband;
+
+import android.os.Bundle;
+import android.preference.Preference;
+import android.preference.PreferenceActivity;
+
+import nodomain.freeyourgadget.gadgetbridge.GB;
+import nodomain.freeyourgadget.gadgetbridge.R;
+import nodomain.freeyourgadget.gadgetbridge.activities.AbstractSettingsActivity;
+
+public class MiBandPreferencesActivity extends AbstractSettingsActivity {
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ addPreferencesFromResource(R.xml.miband_preferences);
+ }
+
+ @Override
+ protected String[] getPreferenceKeysWithSummary() {
+ String[] prefsWithSummary = {
+ MiBandConst.PREF_USER_ALIAS,
+ MiBandConst.PREF_USER_YEAR_OF_BIRTH,
+ MiBandConst.PREF_USER_GENDER,
+ MiBandConst.PREF_USER_HEIGHT_CM,
+ MiBandConst.PREF_USER_WEIGHT_KG
+ };
+ return prefsWithSummary;
+ }
+}
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/miband/MiBandSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/miband/MiBandSupport.java
index fe0699fdc..524eeb158 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/miband/MiBandSupport.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/miband/MiBandSupport.java
@@ -2,6 +2,8 @@ package nodomain.freeyourgadget.gadgetbridge.miband;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCharacteristic;
+import android.content.SharedPreferences;
+import android.preference.PreferenceManager;
import android.util.Log;
import java.io.IOException;
@@ -10,6 +12,7 @@ import java.util.UUID;
import nodomain.freeyourgadget.gadgetbridge.GBCommand;
import nodomain.freeyourgadget.gadgetbridge.GBDevice.State;
+import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.btle.AbstractBTLEDeviceSupport;
import nodomain.freeyourgadget.gadgetbridge.btle.TransactionBuilder;
@@ -69,17 +72,30 @@ public class MiBandSupport extends AbstractBTLEDeviceSupport {
}
private UserInfo getUserInfo() {
- // SharedPreferences mSharedPreferences = PreferenceManager.getDefaultSharedPreferences(mContext.getApplicationContext());
- // UserInfo mInfo = new UserInfo(
- // mSharedPreferences.getString(MiBandConstants.PREFERENCE_MAC_ADDRESS, ""),
- // "1550050550",
- // (mSharedPreferences.getString(MiBandConstants.PREFERENCE_GENDER, "Male") == "Male") ? 1 : 0,
- // Integer.parseInt(mSharedPreferences.getString(MiBandConstants.PREFERENCE_AGE, "25")),
- // Integer.parseInt(mSharedPreferences.getString(MiBandConstants.PREFERENCE_HEIGHT, "175")),
- // Integer.parseInt(mSharedPreferences.getString(MiBandConstants.PREFERENCE_WEIGHT, "60")),
- // 0
- // );
- return UserInfo.getDefault(getDevice().getAddress());
+ try {
+ SharedPreferences mSharedPreferences = PreferenceManager.getDefaultSharedPreferences(getContext().getApplicationContext());
+ int userYear = Integer.parseInt(mSharedPreferences.getString(MiBandConst.PREF_USER_YEAR_OF_BIRTH, "0"));
+ int age = 25;
+ if (userYear > 1900) {
+ age = Calendar.getInstance().get(Calendar.YEAR) - userYear;
+ if (age <= 0) {
+ age = 25;
+ }
+ }
+ UserInfo info = new UserInfo(
+ getDevice().getAddress(),
+ mSharedPreferences.getString(MiBandConst.PREF_USER_ALIAS, "1550050550"),
+ (mSharedPreferences.getString(MiBandConst.PREF_USER_GENDER, "male") == "male" ? 1 : 0),
+ age,
+ Integer.parseInt(mSharedPreferences.getString(MiBandConst.PREF_USER_HEIGHT_CM, "175")),
+ Integer.parseInt(mSharedPreferences.getString(MiBandConst.PREF_USER_WEIGHT_KG, "70")),
+ 0
+ );
+ return info;
+ } catch (Exception ex) {
+ Log.e(TAG, "Error creating user info from settings, using default user instead: " + ex);
+ return UserInfo.getDefault(getDevice().getAddress());
+ }
}
/**
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/miband/UserInfo.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/miband/UserInfo.java
index 1ecc8412a..4f2aa11dc 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/miband/UserInfo.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/miband/UserInfo.java
@@ -41,8 +41,8 @@ public class UserInfo {
byte[] sequence = new byte[20];
- int uid = Integer.parseInt(alias);
-
+ int uid = calculateUidFrom(alias);
+ String normalizedAlias = ensureTenCharacters(alias);
sequence[0] = (byte) uid;
sequence[1] = (byte) (uid >>> 8);
sequence[2] = (byte) (uid >>> 16);
@@ -55,7 +55,7 @@ public class UserInfo {
sequence[8] = (byte) (type & 0xff);
for (int u = 9; u < 19; u++)
- sequence[u] = alias.getBytes()[u - 9];
+ sequence[u] = normalizedAlias.getBytes()[u - 9];
byte[] crcSequence = new byte[19];
for (int u = 0; u < crcSequence.length; u++)
@@ -66,6 +66,30 @@ public class UserInfo {
this.data = sequence;
}
+ private String ensureTenCharacters(String alias) {
+ char[] result = new char[10];
+ int aliasLen = alias.length();
+ int maxLen = Math.min(10, alias.length());
+ int diff = 10 - maxLen;
+ for (int i = 0; i < maxLen; i++) {
+ result[i + diff] = alias.charAt(i);
+ }
+ for (int i = 0; i < diff; i++) {
+ result[i] = '0';
+ }
+ return new String(result);
+ }
+
+ private int calculateUidFrom(String alias) {
+ int uid = 0;
+ try {
+ uid = Integer.parseInt(alias);
+ } catch (NumberFormatException ex) {
+ uid = alias.hashCode(); // simple as that
+ }
+ return uid;
+ }
+
public byte[] getData() {
return this.data;
}
diff --git a/app/src/main/res/values/arrays.xml b/app/src/main/res/values/arrays.xml
index c808fd1f2..7d88bcb66 100644
--- a/app/src/main/res/values/arrays.xml
+++ b/app/src/main/res/values/arrays.xml
@@ -11,4 +11,14 @@
- never
+
+ - @string/male
+ - @string/female
+ - @string/other
+
+
+ - male
+ - female
+ - other
+
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index d070488bb..00a3c83b8 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -81,4 +81,10 @@
Pair your Mi Band
Pairing with %s…
No mac address passed, cannot pair.
+ Device Specific Settings
+ Mi Band Settings
+ male
+ female
+ other
+
diff --git a/app/src/main/res/xml/miband_preferences.xml b/app/src/main/res/xml/miband_preferences.xml
new file mode 100644
index 000000000..70c20af46
--- /dev/null
+++ b/app/src/main/res/xml/miband_preferences.xml
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/xml/preferences.xml b/app/src/main/res/xml/preferences.xml
index ca0024956..7ab3c00aa 100644
--- a/app/src/main/res/xml/preferences.xml
+++ b/app/src/main/res/xml/preferences.xml
@@ -52,6 +52,14 @@
android:title="@string/pref_title_whenscreenon" />
+
+
+
+