From b2518ff927361e766f71a844022723e8fe950dc3 Mon Sep 17 00:00:00 2001 From: cpfeiffer Date: Thu, 7 May 2015 23:51:03 +0200 Subject: [PATCH] Discovery + pairing now works User info is asked on demand before starting the actual pairing. When no (valid) user info is given, dummy user infor will be used instead. --- .../gadgetbridge/miband/MiBandConst.java | 4 +- .../miband/MiBandCoordinator.java | 61 ++++++++++++++++++- .../miband/MiBandPairingActivity.java | 38 +++++++++++- .../gadgetbridge/miband/MiBandSupport.java | 43 ++----------- .../gadgetbridge/miband/UserInfo.java | 21 ++++++- app/src/main/res/values/strings.xml | 1 + 6 files changed, 126 insertions(+), 42 deletions(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/miband/MiBandConst.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/miband/MiBandConst.java index 6e99a6069..f525f6175 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/miband/MiBandConst.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/miband/MiBandConst.java @@ -1,10 +1,12 @@ package nodomain.freeyourgadget.gadgetbridge.miband; -public interface MiBandConst { +import nodomain.freeyourgadget.gadgetbridge.GB; +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"; + String PREF_MIBAND_ADDRESS = GB.PREF_DEVELOPMENT_MIBAND_ADDRESS; } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/miband/MiBandCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/miband/MiBandCoordinator.java index fb869e963..4a22d0044 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/miband/MiBandCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/miband/MiBandCoordinator.java @@ -1,13 +1,21 @@ package nodomain.freeyourgadget.gadgetbridge.miband; import android.app.Activity; +import android.content.SharedPreferences; +import android.preference.PreferenceManager; +import android.util.Log; + +import java.util.Calendar; import nodomain.freeyourgadget.gadgetbridge.DeviceCoordinator; -import nodomain.freeyourgadget.gadgetbridge.GBDevice; import nodomain.freeyourgadget.gadgetbridge.DeviceType; +import nodomain.freeyourgadget.gadgetbridge.GBApplication; +import nodomain.freeyourgadget.gadgetbridge.GBDevice; import nodomain.freeyourgadget.gadgetbridge.discovery.DeviceCandidate; public class MiBandCoordinator implements DeviceCoordinator { + private static final String TAG = "MiBandCoord"; + @Override public boolean supports(DeviceCandidate candidate) { return candidate.getMacAddress().toUpperCase().startsWith(MiBandService.MAC_ADDRESS_FILTER); @@ -27,4 +35,55 @@ public class MiBandCoordinator implements DeviceCoordinator { public Class getPairingActivity() { return MiBandPairingActivity.class; } + + public static boolean hasValidUserInfo() { + String dummyMacAddress = MiBandService.MAC_ADDRESS_FILTER + ":00:00:00"; + try { + UserInfo userInfo = getConfiguredUserInfo(dummyMacAddress); + return true; + } catch (IllegalArgumentException ex) { + return false; + } + } + + /** + * Returns the configured user info, or, if that is not available or invalid, + * a default user info. + * @param miBandAddress + */ + public static UserInfo getAnyUserInfo(String miBandAddress) { + try { + return getConfiguredUserInfo(miBandAddress); + } catch (Exception ex) { + Log.e(TAG, "Error creating user info from settings, using default user instead: " + ex); + return UserInfo.getDefault(miBandAddress); + } + } + + /** + * Returns the user info from the user configured data in the preferences. + * @param miBandAddress + * @throws IllegalArgumentException when the user info can not be created + */ + public static UserInfo getConfiguredUserInfo(String miBandAddress) throws IllegalArgumentException { + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(GBApplication.getContext()); + int userYear = Integer.parseInt(prefs.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 = UserInfo.create( + miBandAddress, + prefs.getString(MiBandConst.PREF_USER_ALIAS, null), + ("male".equals(prefs.getString(MiBandConst.PREF_USER_GENDER, null)) ? 1 : 0), + age, + Integer.parseInt(prefs.getString(MiBandConst.PREF_USER_HEIGHT_CM, "175")), + Integer.parseInt(prefs.getString(MiBandConst.PREF_USER_WEIGHT_KG, "70")), + 0 + ); + return info; + } } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/miband/MiBandPairingActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/miband/MiBandPairingActivity.java index 8bd28b473..af6f98244 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/miband/MiBandPairingActivity.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/miband/MiBandPairingActivity.java @@ -24,6 +24,8 @@ import nodomain.freeyourgadget.gadgetbridge.discovery.DiscoveryActivity; public class MiBandPairingActivity extends Activity { + private static final int MAGIC_CODE_USER_SETTINGS = 52; + private static final String STATE_MIBAND_ADDRESS = "mibandMacAddress"; private TextView message; private boolean isPairing; private String macAddress; @@ -47,6 +49,9 @@ public class MiBandPairingActivity extends Activity { message = (TextView) findViewById(R.id.miband_pair_message); Intent intent = getIntent(); macAddress = intent.getStringExtra(DeviceCoordinator.EXTRA_DEVICE_MAC_ADDRESS); + if (macAddress == null && savedInstanceState != null) { + macAddress = savedInstanceState.getString(STATE_MIBAND_ADDRESS, null); + } if (macAddress == null) { Toast.makeText(this, getString(R.string.message_cannot_pair_no_mac), Toast.LENGTH_SHORT).show(); startActivity(new Intent(this, DiscoveryActivity.class).setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)); @@ -54,9 +59,40 @@ public class MiBandPairingActivity extends Activity { return; } + if (!MiBandCoordinator.hasValidUserInfo()) { + Intent userSettingsIntent = new Intent(this, MiBandPreferencesActivity.class); + startActivityForResult(userSettingsIntent, MAGIC_CODE_USER_SETTINGS, null); + return; + } + + // already valid user info available, use that and pair startPairing(); } + @Override + protected void onSaveInstanceState(Bundle outState) { + super.onSaveInstanceState(outState); + outState.putString(STATE_MIBAND_ADDRESS, macAddress); + } + + @Override + protected void onRestoreInstanceState(Bundle savedInstanceState) { + super.onRestoreInstanceState(savedInstanceState); + macAddress = savedInstanceState.getString(STATE_MIBAND_ADDRESS, macAddress); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent data) { + super.onActivityResult(requestCode, resultCode, data); + // start pairing immediately when we return from the user settings + if (requestCode == MAGIC_CODE_USER_SETTINGS) { + if (!MiBandCoordinator.hasValidUserInfo()) { + Toast.makeText(this, getString(R.string.miband_pairing_using_dummy_userdata), Toast.LENGTH_SHORT).show(); + } + startPairing(); + } + } + @Override protected void onDestroy() { LocalBroadcastManager.getInstance(this).unregisterReceiver(mPairingReceiver); @@ -89,7 +125,7 @@ public class MiBandPairingActivity extends Activity { if (pairedSuccessfully) { SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(this); - sharedPrefs.edit().putString(GB.PREF_DEVELOPMENT_MIBAND_ADDRESS, macAddress).apply(); + sharedPrefs.edit().putString(MiBandConst.PREF_MIBAND_ADDRESS, macAddress).apply(); } Intent intent = new Intent(this, ControlCenter.class).setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 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 524eeb158..5d4cf02b9 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/miband/MiBandSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/miband/MiBandSupport.java @@ -71,33 +71,6 @@ public class MiBandSupport extends AbstractBTLEDeviceSupport { return vibrate; } - private UserInfo getUserInfo() { - 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()); - } - } - /** * Part of device initialization process. Do not call manually. * @@ -107,7 +80,7 @@ public class MiBandSupport extends AbstractBTLEDeviceSupport { private MiBandSupport sendUserInfo(TransactionBuilder builder) { Log.d(TAG, "Writing User Info!"); BluetoothGattCharacteristic characteristic = getCharacteristic(MiBandService.UUID_CHARACTERISTIC_USER_INFO); - builder.write(characteristic, getUserInfo().getData()); + builder.write(characteristic, MiBandCoordinator.getAnyUserInfo(getDevice().getAddress()).getData()); return this; } @@ -121,7 +94,7 @@ public class MiBandSupport extends AbstractBTLEDeviceSupport { /** * Part of device initialization process. Do not call manually. * - * @param builder + * @param transaction * @return */ private MiBandSupport pair(TransactionBuilder transaction) { @@ -204,8 +177,7 @@ public class MiBandSupport extends AbstractBTLEDeviceSupport { @Override public void onSetMusicInfo(String artist, String album, String track) { - // TODO Auto-generated method stub - + // not supported } @Override @@ -232,20 +204,17 @@ public class MiBandSupport extends AbstractBTLEDeviceSupport { @Override public void onAppInfoReq() { - // TODO Auto-generated method stub - + // not supported } @Override public void onAppDelete(int id, int index) { - // TODO Auto-generated method stub - + // not supported } @Override public void onPhoneVersion(byte os) { - // TODO Auto-generated method stub - + // not supported } @Override 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 4f2aa11dc..45b0c1044 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/miband/UserInfo.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/miband/UserInfo.java @@ -28,9 +28,25 @@ public class UserInfo { * Creates a user info with the given data * * @param address the address of the MI Band to connect to. + * @throws IllegalArgumentException when the given values are not valid */ - public UserInfo(String address, String alias, int gender, int age, int height, int weight, int type) { + public static UserInfo create(String address, String alias, int gender, int age, int height, int weight, int type) throws IllegalArgumentException { + if (address == null || alias == null || gender <= 0 || age <= 0 || weight <= 0 || type <= 0) { + throw new IllegalArgumentException("Invalid parameters"); + } + try { + return new UserInfo(address, alias, gender, age, height, weight, type); + } catch (Exception ex) { + throw new IllegalArgumentException("Illegal user info data", ex); + } + } + /** + * Creates a user info with the given data + * + * @param address the address of the MI Band to connect to. + */ + private UserInfo(String address, String alias, int gender, int age, int height, int weight, int type) { this.btAddress = address; this.alias = alias; this.gender = gender; @@ -66,6 +82,8 @@ public class UserInfo { this.data = sequence; } + + private String ensureTenCharacters(String alias) { char[] result = new char[10]; int aliasLen = alias.length(); @@ -113,5 +131,4 @@ public class UserInfo { } return (crc & 0xff); } - } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 00a3c83b8..7b26219db 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -86,5 +86,6 @@ male female other + No valid user data given, using dummy user data for now.