diff --git a/app/app.iml b/app/app.iml index 9ec727f78..bbc7e2985 100644 --- a/app/app.iml +++ b/app/app.iml @@ -1,5 +1,5 @@ - + @@ -9,6 +9,7 @@ + diff --git a/app/build.gradle b/app/build.gradle index 2e44289b6..f46855385 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -9,8 +9,8 @@ android { applicationId "no.nordicsemi.android.nrftoolbox" minSdkVersion 18 targetSdkVersion 21 - versionCode 27 - versionName "1.11.4" + versionCode 28 + versionName "1.11.5" } buildTypes { release { diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index e7146ead4..b7142251a 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -23,8 +23,8 @@ + android:versionCode="28" + android:versionName="1.11.5" > + + + - { private TextView mSpeedView; + private TextView mSpeedUnitView; private TextView mCadenceView; private TextView mDistanceView; private TextView mDistanceUnitView; private TextView mTotalDistanceView; + private TextView mTotalDistanceUnitView; private TextView mGearRatioView; @Override @@ -64,21 +69,53 @@ protected void onDestroy() { private void setGui() { mSpeedView = (TextView) findViewById(R.id.speed); + mSpeedUnitView = (TextView) findViewById(R.id.speed_unit); mCadenceView = (TextView) findViewById(R.id.cadence); mDistanceView = (TextView) findViewById(R.id.distance); mDistanceUnitView = (TextView) findViewById(R.id.distance_unit); mTotalDistanceView = (TextView) findViewById(R.id.distance_total); + mTotalDistanceUnitView = (TextView) findViewById(R.id.distance_total_unit); mGearRatioView = (TextView) findViewById(R.id.ratio); } + @Override + protected void onResume() { + super.onResume(); + setDefaultUI(); + } + @Override protected void setDefaultUI() { mSpeedView.setText(R.string.not_available_value); mCadenceView.setText(R.string.not_available_value); mDistanceView.setText(R.string.not_available_value); - mDistanceUnitView.setText(R.string.csc_distance_unit_m); mTotalDistanceView.setText(R.string.not_available_value); mGearRatioView.setText(R.string.not_available_value); + + setUnits(); + } + + private void setUnits() { + final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this); + final int unit = Integer.parseInt(preferences.getString(SettingsFragment.SETTINGS_UNIT, String.valueOf(SettingsFragment.SETTINGS_UNIT_DEFAULT))); + + switch (unit) { + case SettingsFragment.SETTINGS_UNIT_M_S: // [m/s] + mSpeedUnitView.setText(R.string.csc_speed_unit_m_s); + mDistanceUnitView.setText(R.string.csc_distance_unit_m); + mTotalDistanceUnitView.setText(R.string.csc_total_distance_unit_km); + break; + case SettingsFragment.SETTINGS_UNIT_KM_H: // [km/h] + mSpeedUnitView.setText(R.string.csc_speed_unit_km_h); + mDistanceUnitView.setText(R.string.csc_distance_unit_m); + mTotalDistanceUnitView.setText(R.string.csc_total_distance_unit_km); + break; + case SettingsFragment.SETTINGS_UNIT_MPH: // [mph] + mSpeedUnitView.setText(R.string.csc_speed_unit_mph); + mDistanceUnitView.setText(R.string.csc_distance_unit_yd); + mTotalDistanceUnitView.setText(R.string.csc_total_distance_unit_mile); + break; + } } @Override @@ -98,7 +135,7 @@ protected int getAboutTextId() { @Override public boolean onCreateOptionsMenu(final Menu menu) { - getMenuInflater().inflate(R.menu.csc_menu, menu); + getMenuInflater().inflate(R.menu.settings_and_about, menu); return true; } @@ -138,17 +175,40 @@ public void onServicesDiscovered(final boolean optionalServicesFound) { // not used } - private void onMeasurementReceived(final float speed, final float distance, final float totalDistance) { - mSpeedView.setText(String.format("%.1f", speed)); - if (distance < 1000) { // 1 km in m - mDistanceView.setText(String.format("%.0f", distance)); - mDistanceUnitView.setText(R.string.csc_distance_unit_m); - } else { - mDistanceView.setText(String.format("%.2f", distance / 1000.0f)); - mDistanceUnitView.setText(R.string.csc_distance_unit_km); + private void onMeasurementReceived(float speed, float distance, float totalDistance) { + final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this); + final int unit = Integer.parseInt(preferences.getString(SettingsFragment.SETTINGS_UNIT, String.valueOf(SettingsFragment.SETTINGS_UNIT_DEFAULT))); + + switch (unit) { + case SettingsFragment.SETTINGS_UNIT_KM_H: + speed = speed * 3.6f; + // pass through intended + case SettingsFragment.SETTINGS_UNIT_M_S: + if (distance < 1000) { // 1 km in m + mDistanceView.setText(String.format("%.0f", distance)); + mDistanceUnitView.setText(R.string.csc_distance_unit_m); + } else { + mDistanceView.setText(String.format("%.2f", distance / 1000.0f)); + mDistanceUnitView.setText(R.string.csc_distance_unit_km); + } + + mTotalDistanceView.setText(String.format("%.2f", totalDistance / 1000.0f)); + break; + case SettingsFragment.SETTINGS_UNIT_MPH: + speed = speed * 2.2369f; + if (distance < 1760) { // 1 mile in yrs + mDistanceView.setText(String.format("%.0f", distance)); + mDistanceUnitView.setText(R.string.csc_distance_unit_yd); + } else { + mDistanceView.setText(String.format("%.2f", distance / 1760.0f)); + mDistanceUnitView.setText(R.string.csc_distance_unit_mile); + } + + mTotalDistanceView.setText(String.format("%.2f", totalDistance / 1609.31f)); + break; } - mTotalDistanceView.setText(String.format("%.2f", totalDistance / 1000.0f)); + mSpeedView.setText(String.format("%.1f", speed)); } private void onGearRatioUpdate(final float ratio, final int cadence) { @@ -162,7 +222,7 @@ public void onReceive(final Context context, final Intent intent) { final String action = intent.getAction(); if (CSCService.BROADCAST_WHEEL_DATA.equals(action)) { - final float speed = intent.getFloatExtra(CSCService.EXTRA_SPEED, 0.0f); + final float speed = intent.getFloatExtra(CSCService.EXTRA_SPEED, 0.0f); // [m/s] final float distance = intent.getFloatExtra(CSCService.EXTRA_DISTANCE, CSCManagerCallbacks.NOT_AVAILABLE); final float totalDistance = intent.getFloatExtra(CSCService.EXTRA_TOTAL_DISTANCE, CSCManagerCallbacks.NOT_AVAILABLE); // Update GUI diff --git a/app/src/main/java/no/nordicsemi/android/nrftoolbox/csc/settings/SettingsFragment.java b/app/src/main/java/no/nordicsemi/android/nrftoolbox/csc/settings/SettingsFragment.java index e4e0f39a5..559b73e50 100644 --- a/app/src/main/java/no/nordicsemi/android/nrftoolbox/csc/settings/SettingsFragment.java +++ b/app/src/main/java/no/nordicsemi/android/nrftoolbox/csc/settings/SettingsFragment.java @@ -31,6 +31,12 @@ public class SettingsFragment extends PreferenceFragment implements SharedPreferences.OnSharedPreferenceChangeListener { public static final String SETTINGS_WHEEL_SIZE = "settings_wheel_size"; public static final int SETTINGS_WHEEL_SIZE_DEFAULT = 2340; + public static final String SETTINGS_UNIT = "settings_csc_unit"; + public static final int SETTINGS_UNIT_M_S = 0; // [m/s] + public static final int SETTINGS_UNIT_KM_H = 1; // [m/s] + public static final int SETTINGS_UNIT_MPH = 2; // [m/s] + public static final int SETTINGS_UNIT_DEFAULT = SETTINGS_UNIT_KM_H; + @Override public void onCreate(final Bundle savedInstanceState) { diff --git a/app/src/main/java/no/nordicsemi/android/nrftoolbox/dfu/DfuActivity.java b/app/src/main/java/no/nordicsemi/android/nrftoolbox/dfu/DfuActivity.java index 1dfee4037..69318e570 100644 --- a/app/src/main/java/no/nordicsemi/android/nrftoolbox/dfu/DfuActivity.java +++ b/app/src/main/java/no/nordicsemi/android/nrftoolbox/dfu/DfuActivity.java @@ -417,7 +417,7 @@ private void copyRawResource(final int rawResId, final File dest) { @Override public boolean onCreateOptionsMenu(final Menu menu) { - getMenuInflater().inflate(R.menu.dfu_menu, menu); + getMenuInflater().inflate(R.menu.settings_and_about, menu); return true; } diff --git a/app/src/main/java/no/nordicsemi/android/nrftoolbox/hts/HTSActivity.java b/app/src/main/java/no/nordicsemi/android/nrftoolbox/hts/HTSActivity.java index 3a9c0dd99..752aa2e3e 100644 --- a/app/src/main/java/no/nordicsemi/android/nrftoolbox/hts/HTSActivity.java +++ b/app/src/main/java/no/nordicsemi/android/nrftoolbox/hts/HTSActivity.java @@ -25,14 +25,20 @@ import java.util.UUID; import no.nordicsemi.android.nrftoolbox.R; +import no.nordicsemi.android.nrftoolbox.hts.settings.SettingsFragment; import no.nordicsemi.android.nrftoolbox.profile.BleProfileService; import no.nordicsemi.android.nrftoolbox.profile.BleProfileServiceReadyActivity; +import no.nordicsemi.android.nrftoolbox.hts.settings.SettingsActivity; + import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; +import android.content.SharedPreferences; import android.os.Bundle; +import android.preference.PreferenceManager; import android.support.v4.content.LocalBroadcastManager; +import android.view.Menu; import android.widget.TextView; /** @@ -43,17 +49,34 @@ public class HTSActivity extends BleProfileServiceReadyActivity initializeManager() { - return mManager = new HTSManager(); + return mManager = HTSManager.getHTSManager(); } @Override diff --git a/app/src/main/java/no/nordicsemi/android/nrftoolbox/hts/settings/SettingsActivity.java b/app/src/main/java/no/nordicsemi/android/nrftoolbox/hts/settings/SettingsActivity.java new file mode 100644 index 000000000..3c548fcec --- /dev/null +++ b/app/src/main/java/no/nordicsemi/android/nrftoolbox/hts/settings/SettingsActivity.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2015, Nordic Semiconductor + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package no.nordicsemi.android.nrftoolbox.hts.settings; + +import android.os.Bundle; +import android.support.v7.app.ActionBarActivity; +import android.view.MenuItem; + +public class SettingsActivity extends ActionBarActivity { + + @Override + protected void onCreate(final Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + + // Display the fragment as the main content. + getFragmentManager().beginTransaction().replace(android.R.id.content, new SettingsFragment()).commit(); + } + + @Override + public boolean onOptionsItemSelected(final MenuItem item) { + switch (item.getItemId()) { + case android.R.id.home: + onBackPressed(); + return true; + } + return super.onOptionsItemSelected(item); + } +} diff --git a/app/src/main/java/no/nordicsemi/android/nrftoolbox/hts/settings/SettingsFragment.java b/app/src/main/java/no/nordicsemi/android/nrftoolbox/hts/settings/SettingsFragment.java new file mode 100644 index 000000000..685d53f43 --- /dev/null +++ b/app/src/main/java/no/nordicsemi/android/nrftoolbox/hts/settings/SettingsFragment.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2015, Nordic Semiconductor + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package no.nordicsemi.android.nrftoolbox.hts.settings; + +import android.os.Bundle; +import android.preference.PreferenceFragment; + +import no.nordicsemi.android.nrftoolbox.R; + +public class SettingsFragment extends PreferenceFragment { + public static final String SETTINGS_UNIT = "settings_hts_unit"; + public static final int SETTINGS_UNIT_C = 0; // [C] + public static final int SETTINGS_UNIT_F = 1; // [F] + public static final int SETTINGS_UNIT_K = 2; // [K] + public static final int SETTINGS_UNIT_DEFAULT = SETTINGS_UNIT_C; + + @Override + public void onCreate(final Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + addPreferencesFromResource(R.xml.settings_hts); + } +} diff --git a/app/src/main/java/no/nordicsemi/android/nrftoolbox/rsc/RSCActivity.java b/app/src/main/java/no/nordicsemi/android/nrftoolbox/rsc/RSCActivity.java index 6d52aab5c..eb9a8675e 100644 --- a/app/src/main/java/no/nordicsemi/android/nrftoolbox/rsc/RSCActivity.java +++ b/app/src/main/java/no/nordicsemi/android/nrftoolbox/rsc/RSCActivity.java @@ -25,22 +25,29 @@ import java.util.UUID; import no.nordicsemi.android.nrftoolbox.R; +import no.nordicsemi.android.nrftoolbox.rsc.settings.SettingsFragment; +import no.nordicsemi.android.nrftoolbox.rsc.settings.SettingsActivity; import no.nordicsemi.android.nrftoolbox.profile.BleProfileService; import no.nordicsemi.android.nrftoolbox.profile.BleProfileServiceReadyActivity; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; +import android.content.SharedPreferences; import android.os.Bundle; +import android.preference.PreferenceManager; import android.support.v4.content.LocalBroadcastManager; +import android.view.Menu; import android.widget.TextView; public class RSCActivity extends BleProfileServiceReadyActivity { private TextView mSpeedView; + private TextView mSpeedUnitView; private TextView mCadenceView; private TextView mDistanceView; private TextView mDistanceUnitView; private TextView mTotalDistanceView; + private TextView mTotalDistanceUnitView; private TextView mStridesCountView; private TextView mActivityView; @@ -63,23 +70,55 @@ protected void onDestroy() { private void setGui() { mSpeedView = (TextView) findViewById(R.id.speed); + mSpeedUnitView = (TextView) findViewById(R.id.speed_unit); mCadenceView = (TextView) findViewById(R.id.cadence); mDistanceView = (TextView) findViewById(R.id.distance); mDistanceUnitView = (TextView) findViewById(R.id.distance_unit); mTotalDistanceView = (TextView) findViewById(R.id.total_distance); + mTotalDistanceUnitView = (TextView) findViewById(R.id.total_distance_unit); mStridesCountView = (TextView) findViewById(R.id.strides); mActivityView = (TextView) findViewById(R.id.activity); } + @Override + protected void onResume() { + super.onResume(); + setDefaultUI(); + } + @Override protected void setDefaultUI() { mSpeedView.setText(R.string.not_available_value); mCadenceView.setText(R.string.not_available_value); mDistanceView.setText(R.string.not_available_value); - mDistanceUnitView.setText(R.string.rsc_distance_unit_m); mTotalDistanceView.setText(R.string.not_available_value); mStridesCountView.setText(R.string.not_available_value); mActivityView.setText(R.string.not_available); + + setUnits(); + } + + private void setUnits() { + final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this); + final int unit = Integer.parseInt(preferences.getString(SettingsFragment.SETTINGS_UNIT, String.valueOf(SettingsFragment.SETTINGS_UNIT_DEFAULT))); + + switch (unit) { + case SettingsFragment.SETTINGS_UNIT_M_S: // [m/s] + mSpeedUnitView.setText(R.string.csc_speed_unit_m_s); + mDistanceUnitView.setText(R.string.csc_distance_unit_m); + mTotalDistanceUnitView.setText(R.string.csc_total_distance_unit_km); + break; + case SettingsFragment.SETTINGS_UNIT_KM_H: // [km/h] + mSpeedUnitView.setText(R.string.csc_speed_unit_km_h); + mDistanceUnitView.setText(R.string.csc_distance_unit_m); + mTotalDistanceUnitView.setText(R.string.csc_total_distance_unit_km); + break; + case SettingsFragment.SETTINGS_UNIT_MPH: // [mph] + mSpeedUnitView.setText(R.string.csc_speed_unit_mph); + mDistanceUnitView.setText(R.string.csc_distance_unit_yd); + mTotalDistanceUnitView.setText(R.string.csc_total_distance_unit_mile); + break; + } } @Override @@ -97,6 +136,23 @@ protected int getAboutTextId() { return R.string.rsc_about_text; } + @Override + public boolean onCreateOptionsMenu(final Menu menu) { + getMenuInflater().inflate(R.menu.settings_and_about, menu); + return true; + } + + @Override + protected boolean onOptionsItemSelected(final int itemId) { + switch (itemId) { + case R.id.action_settings: + final Intent intent = new Intent(this, SettingsActivity.class); + startActivity(intent); + break; + } + return true; + } + @Override protected Class getServiceClass() { return RSCService.class; @@ -122,28 +178,69 @@ public void onServicesDiscovered(final boolean optionalServicesFound) { // not used } - private void onMeasurementReceived(final float speed, final int cadence, final float totalDistance, final int activity) { - mSpeedView.setText(String.format("%.1f", speed)); - mCadenceView.setText(String.format("%d", cadence)); - if (totalDistance == RSCManagerCallbacks.NOT_AVAILABLE) { - mTotalDistanceView.setText(R.string.not_available); - } else { - mTotalDistanceView.setText(String.format("%.2f", totalDistance / 10000.0f)); // 1km in dm + private void onMeasurementReceived(float speed, int cadence, float totalDistance, final int activity) { + final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this); + final int unit = Integer.parseInt(preferences.getString(SettingsFragment.SETTINGS_UNIT, String.valueOf(SettingsFragment.SETTINGS_UNIT_DEFAULT))); + + switch (unit) { + case SettingsFragment.SETTINGS_UNIT_KM_H: + speed = speed * 3.6f; + // pass through intended + case SettingsFragment.SETTINGS_UNIT_M_S: + if (totalDistance == RSCManagerCallbacks.NOT_AVAILABLE) { + mTotalDistanceView.setText(R.string.not_available); + mTotalDistanceUnitView.setText(null); + } else { + mTotalDistanceView.setText(String.format("%.2f", totalDistance / 1000.0f)); // 1 km in m + mTotalDistanceUnitView.setText(R.string.rsc_total_distance_unit_km); + } + break; + case SettingsFragment.SETTINGS_UNIT_MPH: + speed = speed * 2.2369f; + if (totalDistance == RSCManagerCallbacks.NOT_AVAILABLE) { + mTotalDistanceView.setText(R.string.not_available); + mTotalDistanceUnitView.setText(null); + } else { + mTotalDistanceView.setText(String.format("%.2f", totalDistance / 1609.31f)); // 1 mile in m + mTotalDistanceUnitView.setText(R.string.rsc_total_distance_unit_mile); + } + break; } + mSpeedView.setText(String.format("%.1f", speed)); + mCadenceView.setText(String.format("%d", cadence)); mActivityView.setText(activity == RSCManagerCallbacks.ACTIVITY_RUNNING ? R.string.rsc_running : R.string.rsc_walking); } - private void onStripsesUpdate(final float distance, final int strides) { + private void onStripesUpdate(final float distance, final int strides) { if (distance == RSCManagerCallbacks.NOT_AVAILABLE) { mDistanceView.setText(R.string.not_available); mDistanceUnitView.setText(R.string.rsc_distance_unit_m); - } else if (distance < 100000) { // 1 km in cm - mDistanceView.setText(String.format("%.0f", distance / 100.0f)); - mDistanceUnitView.setText(R.string.rsc_distance_unit_m); } else { - mDistanceView.setText(String.format("%.2f", distance / 100000.0f)); - mDistanceUnitView.setText(R.string.rsc_distance_unit_km); + final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this); + final int unit = Integer.parseInt(preferences.getString(SettingsFragment.SETTINGS_UNIT, String.valueOf(SettingsFragment.SETTINGS_UNIT_DEFAULT))); + + switch (unit) { + case SettingsFragment.SETTINGS_UNIT_KM_H: + case SettingsFragment.SETTINGS_UNIT_M_S: + if (distance < 100000) { // 1 km in cm + mDistanceView.setText(String.format("%.0f", distance / 100.0f)); + mDistanceUnitView.setText(R.string.rsc_distance_unit_m); + } else { + mDistanceView.setText(String.format("%.2f", distance / 100000.0f)); + mDistanceUnitView.setText(R.string.rsc_distance_unit_km); + } + break; + case SettingsFragment.SETTINGS_UNIT_MPH: + if (distance < 160931) { // 1 mile in cm + mDistanceView.setText(String.format("%.0f", distance / 91.4392f)); + mDistanceUnitView.setText(R.string.rsc_distance_unit_yd); + } else { + mDistanceView.setText(String.format("%.2f", distance / 160931.23f)); + mDistanceUnitView.setText(R.string.rsc_distance_unit_mile); + } + break; + } } mStridesCountView.setText(String.valueOf(strides)); @@ -165,7 +262,7 @@ public void onReceive(final Context context, final Intent intent) { final int strides = intent.getIntExtra(RSCService.EXTRA_STRIDES, 0); final float distance = intent.getFloatExtra(RSCService.EXTRA_DISTANCE, 0); // Update GUI - onStripsesUpdate(distance, strides); + onStripesUpdate(distance, strides); } } }; diff --git a/app/src/main/java/no/nordicsemi/android/nrftoolbox/rsc/RSCManager.java b/app/src/main/java/no/nordicsemi/android/nrftoolbox/rsc/RSCManager.java index 9b27a330e..0b81316ed 100644 --- a/app/src/main/java/no/nordicsemi/android/nrftoolbox/rsc/RSCManager.java +++ b/app/src/main/java/no/nordicsemi/android/nrftoolbox/rsc/RSCManager.java @@ -190,22 +190,22 @@ public void onCharacteristicChanged(final BluetoothGatt gatt, final BluetoothGat final boolean tdPreset = (flags & TOTAL_DISTANCE_PRESENT) > 0; final boolean running = (flags & WALKING_OR_RUNNING_STATUS_BITS) > 0; - final float instantaneousSpeed = (float) characteristic.getIntValue(BluetoothGattCharacteristic.FORMAT_UINT16, offset) / 256.0f * 3.6f; // 1/256 m/s in km/h + final float instantaneousSpeed = (float) characteristic.getIntValue(BluetoothGattCharacteristic.FORMAT_UINT16, offset) / 256.0f; // 1/256 m/s in [m/s] offset += 2; - final int instantaneousCadence = characteristic.getIntValue(BluetoothGattCharacteristic.FORMAT_UINT8, offset); + final int instantaneousCadence = characteristic.getIntValue(BluetoothGattCharacteristic.FORMAT_UINT8, offset); // [SPM] offset += 1; float instantaneousStrideLength = RSCManagerCallbacks.NOT_AVAILABLE; if (islmPresent) { - instantaneousStrideLength = characteristic.getIntValue(BluetoothGattCharacteristic.FORMAT_UINT16, offset); + instantaneousStrideLength = characteristic.getIntValue(BluetoothGattCharacteristic.FORMAT_UINT16, offset); // [cm] offset += 2; } float totalDistance = RSCManagerCallbacks.NOT_AVAILABLE; if (tdPreset) { - totalDistance = (float) characteristic.getIntValue(BluetoothGattCharacteristic.FORMAT_UINT32, offset) / 10.0f; - offset += 4; + totalDistance = (float) characteristic.getIntValue(BluetoothGattCharacteristic.FORMAT_UINT32, offset) / 10.0f; // 1/10 m in [m] + //offset += 4; } // Notify listener about the new measurement diff --git a/app/src/main/java/no/nordicsemi/android/nrftoolbox/rsc/settings/SettingsActivity.java b/app/src/main/java/no/nordicsemi/android/nrftoolbox/rsc/settings/SettingsActivity.java new file mode 100644 index 000000000..53a001aae --- /dev/null +++ b/app/src/main/java/no/nordicsemi/android/nrftoolbox/rsc/settings/SettingsActivity.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2015, Nordic Semiconductor + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package no.nordicsemi.android.nrftoolbox.rsc.settings; + +import android.os.Bundle; +import android.support.v7.app.ActionBarActivity; +import android.view.MenuItem; + +public class SettingsActivity extends ActionBarActivity { + + @Override + protected void onCreate(final Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + + // Display the fragment as the main content. + getFragmentManager().beginTransaction().replace(android.R.id.content, new SettingsFragment()).commit(); + } + + @Override + public boolean onOptionsItemSelected(final MenuItem item) { + switch (item.getItemId()) { + case android.R.id.home: + onBackPressed(); + return true; + } + return super.onOptionsItemSelected(item); + } +} diff --git a/app/src/main/java/no/nordicsemi/android/nrftoolbox/rsc/settings/SettingsFragment.java b/app/src/main/java/no/nordicsemi/android/nrftoolbox/rsc/settings/SettingsFragment.java new file mode 100644 index 000000000..9a0e030b0 --- /dev/null +++ b/app/src/main/java/no/nordicsemi/android/nrftoolbox/rsc/settings/SettingsFragment.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2015, Nordic Semiconductor + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package no.nordicsemi.android.nrftoolbox.rsc.settings; + +import android.content.SharedPreferences; +import android.os.Bundle; +import android.preference.PreferenceFragment; +import android.preference.PreferenceScreen; + +import no.nordicsemi.android.nrftoolbox.R; + +public class SettingsFragment extends PreferenceFragment { + public static final String SETTINGS_UNIT = "settings_rsc_unit"; + public static final int SETTINGS_UNIT_M_S = 0; // [m/s] + public static final int SETTINGS_UNIT_KM_H = 1; // [m/s] + public static final int SETTINGS_UNIT_MPH = 2; // [m/s] + public static final int SETTINGS_UNIT_DEFAULT = SETTINGS_UNIT_KM_H; + + @Override + public void onCreate(final Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + addPreferencesFromResource(R.xml.settings_rsc); + } +} diff --git a/app/src/main/res/layout-land/activity_feature_csc.xml b/app/src/main/res/layout-land/activity_feature_csc.xml index 8dfc641d5..547b6a5d8 100644 --- a/app/src/main/res/layout-land/activity_feature_csc.xml +++ b/app/src/main/res/layout-land/activity_feature_csc.xml @@ -119,11 +119,12 @@ android:textSize="36sp" /> + android:text="@string/csc_speed_unit_km_h" /> + android:text="@string/csc_total_distance_unit_km" /> + android:text="@string/rsc_speed_unit_km_h" /> + android:text="@string/rsc_total_distance_unit_km" /> + android:text="@string/csc_speed_unit_km_h" /> + android:text="@string/csc_total_distance_unit_km" /> + android:text="@string/rsc_speed_unit_km_h" /> + android:text="@string/rsc_total_distance_unit_km" /> + android:text="@string/csc_speed_unit_km_h" /> + android:text="@string/csc_total_distance_unit_km" /> + android:text="@string/rsc_speed_unit_km_h" /> + android:text="@string/rsc_total_distance_unit_km" /> + + + + + + + diff --git a/app/src/main/res/values/strings_csc.xml b/app/src/main/res/values/strings_csc.xml index 96744efe0..d71ff92b8 100644 --- a/app/src/main/res/values/strings_csc.xml +++ b/app/src/main/res/values/strings_csc.xml @@ -29,21 +29,25 @@ SPEED AND CADENCE SPEED - km/h + m/s + km/h + mph CADENCE RPM DISTANCE m km + yd + mile TOTAL DISTANCE - km + km + mile GEAR RATIO DEFAULT CSC Disconnect %s is connected. - Wheel size Wheel size Wheel circumference: %s mm @@ -151,6 +155,19 @@ 1282 1272 + + Units + %s + + m/s + km/h + mph + + + 0 + 1 + 2 + CSC (Cycling Speed and Cadence) profile allows you to connect to your bike activity sensor. \nIt reads wheel and crank data if they are supported by the sensor and calculates speed, cadence, total and trip distance and gear ratio. Set up your wheel size in the settings to get correct readings. diff --git a/app/src/main/res/values/strings_hts.xml b/app/src/main/res/values/strings_hts.xml index fe328bfa0..13a66bec4 100644 --- a/app/src/main/res/values/strings_hts.xml +++ b/app/src/main/res/values/strings_hts.xml @@ -22,15 +22,31 @@ --> HTM + HTM Settings HEALTH THERMOMETER MONITOR -236dp DEFAULT HTM - °C - - Disconnect + °C + °F + °K + + Disconnect %s is connected. + + Units + %s + + Celsius + Fahrenheit + Kelvin + + + 0 + 1 + 2 + HTM (Health Thermometer Monitor) profile allows you to connect to your Health Thermometer sensor. It shows you the temperature value in Celsius. diff --git a/app/src/main/res/values/strings_rsc.xml b/app/src/main/res/values/strings_rsc.xml index 8aec5806b..4fa736f07 100644 --- a/app/src/main/res/values/strings_rsc.xml +++ b/app/src/main/res/values/strings_rsc.xml @@ -22,21 +22,27 @@ --> RSC + RSC Settings RUNNING SPEED & CADENCE -192dp SPEED AND CADENCE SPEED - km/h + km/h + km/h + mph CADENCE SPM DISTANCE m km + yd + mile TOTAL DISTANCE - km + km + mile STEPS ACTIVITY @@ -46,6 +52,19 @@ DEFAULT RSC Disconnect %s is connected. + + Units + %s + + m/s + km/h + mph + + + 0 + 1 + 2 + RSC (Running Speed and Cadence) profile allows you to connect to your activity sensor. \nIt reads speed and cadence values from the sensor and calculates trip distance if stride length is supported. Strides count is calculated basing on the cadence and the time. diff --git a/app/src/main/res/xml/settings_csc.xml b/app/src/main/res/xml/settings_csc.xml index 8dd3d543c..bea3d6ef7 100644 --- a/app/src/main/res/xml/settings_csc.xml +++ b/app/src/main/res/xml/settings_csc.xml @@ -23,13 +23,19 @@ - - - + + + \ No newline at end of file diff --git a/app/src/main/res/xml/settings_hts.xml b/app/src/main/res/xml/settings_hts.xml new file mode 100644 index 000000000..36e1706f5 --- /dev/null +++ b/app/src/main/res/xml/settings_hts.xml @@ -0,0 +1,34 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/xml/settings_rsc.xml b/app/src/main/res/xml/settings_rsc.xml new file mode 100644 index 000000000..489d4cd7d --- /dev/null +++ b/app/src/main/res/xml/settings_rsc.xml @@ -0,0 +1,34 @@ + + + + + + + + \ No newline at end of file