diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 70080701a..9de4385ec 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -901,6 +901,11 @@
android:name=".activities.CameraActivity"
android:launchMode="singleInstance"
android:exported="false" />
+
+
\ No newline at end of file
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/cycling_sensor/activity/CyclingLiveDataActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/cycling_sensor/activity/CyclingLiveDataActivity.java
new file mode 100644
index 000000000..98a415325
--- /dev/null
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/cycling_sensor/activity/CyclingLiveDataActivity.java
@@ -0,0 +1,170 @@
+package nodomain.freeyourgadget.gadgetbridge.devices.cycling_sensor.activity;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import androidx.localbroadcastmanager.content.LocalBroadcastManager;
+
+import java.util.List;
+
+import nodomain.freeyourgadget.gadgetbridge.GBApplication;
+import nodomain.freeyourgadget.gadgetbridge.R;
+import nodomain.freeyourgadget.gadgetbridge.activities.AbstractGBActivity;
+import nodomain.freeyourgadget.gadgetbridge.activities.SettingsActivity;
+import nodomain.freeyourgadget.gadgetbridge.entities.CyclingSample;
+import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
+import nodomain.freeyourgadget.gadgetbridge.model.DeviceService;
+import nodomain.freeyourgadget.gadgetbridge.model.DeviceType;
+import nodomain.freeyourgadget.gadgetbridge.util.GB;
+
+public class CyclingLiveDataActivity extends AbstractGBActivity {
+ private TextView speedView, tripDistanceView, totalDistanceView;
+ private GBDevice selectedDevice;
+ private float tripStartDistance = 0, tripCurrentDistance = 0;
+ private float toUnitFactor = 1;
+ private int
+ speedStringResource = R.string.km_h,
+ tripStringResource = R.string.label_distance_trip,
+ totalStringResource = R.string.label_distance_total;
+
+ private static final String PREFS_KEY_TRIP_START = "CYCLING_TRIP_START";
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ if(getIntent() == null) {
+ selectedDevice = getStoredCyclingSensor();
+ }else if(getIntent().getExtras() == null) {
+ selectedDevice = getStoredCyclingSensor();
+ }else if((selectedDevice =
+ getIntent().getExtras().getParcelable("device")) == null) {
+ selectedDevice = getStoredCyclingSensor();
+ }
+
+ if (selectedDevice == null) {
+ GB.toast(getString(R.string.error_no_cycling_sensor_found), Toast.LENGTH_SHORT, GB.ERROR);
+ finish();
+ return;
+ }
+
+ setContentView(R.layout.activity_cycling_live_data);
+
+ speedView = findViewById(R.id.cycling_data_speed);
+ tripDistanceView = findViewById(R.id.cycling_data_trip_distance);
+ totalDistanceView = findViewById(R.id.cycling_data_total_distance);
+
+ tripStartDistance = GBApplication
+ .getDevicePrefs(selectedDevice)
+ .getFloat(PREFS_KEY_TRIP_START, 0);
+
+ tripDistanceView.setOnLongClickListener(new View.OnLongClickListener() {
+ @Override
+ public boolean onLongClick(View view) {
+ if(tripCurrentDistance == 0) {
+ return true;
+ }
+
+ tripStartDistance = tripCurrentDistance;
+
+ GBApplication
+ .getDeviceSpecificSharedPrefs(selectedDevice.getAddress())
+ .edit()
+ .putFloat(PREFS_KEY_TRIP_START, tripStartDistance)
+ .apply();
+
+ tripDistanceView.setText(getString(tripStringResource, 0f));
+
+ return true;
+ }
+ });
+
+ String measurementSystem = GBApplication.getPrefs().getString(SettingsActivity.PREF_MEASUREMENT_SYSTEM, "metric");
+
+ if(!measurementSystem.equals("metric")) {
+ toUnitFactor = 0.621371f;
+
+ speedStringResource = R.string.mi_h;
+ tripStringResource = R.string.label_distance_trip_mph;
+ totalStringResource = R.string.label_distance_total_mph;
+ }
+ }
+
+ private GBDevice getStoredCyclingSensor(){
+ List devices = GBApplication
+ .app()
+ .getDeviceManager()
+ .getDevices();
+
+ for(GBDevice device: devices) {
+ if (device.getState() != GBDevice.State.INITIALIZED) continue;
+ if (device.getType() != DeviceType.CYCLING_SENSOR) continue;
+
+ return device;
+ }
+
+ return null;
+ }
+
+ private BroadcastReceiver cyclingDataReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ String deviceAddress = intent.getStringExtra("EXTRA_DEVICE_ADDRESS");
+
+ if(deviceAddress == null) {
+ return;
+ }
+
+ if(!deviceAddress.equals(selectedDevice.getAddress())) {
+ return;
+ }
+
+ CyclingSample sample = (CyclingSample) intent.getSerializableExtra(DeviceService.EXTRA_REALTIME_SAMPLE);
+
+ if(sample == null) {
+ return;
+ }
+
+ Float metersPerSecond = sample.getSpeed();
+ if(metersPerSecond != null) {
+ float kmh = metersPerSecond * 3.6f * toUnitFactor;
+ speedView.setText(String.format("%.1f %s", kmh, getString(speedStringResource)));
+ }else{
+ speedView.setText(String.format("%.1f %s", 0f, getString(speedStringResource)));
+ }
+
+ tripCurrentDistance = sample.getDistance();
+
+ tripDistanceView.setText(getString(tripStringResource, ((tripCurrentDistance - tripStartDistance) * toUnitFactor) / 1000));
+ totalDistanceView.setText(getString(totalStringResource, (tripCurrentDistance * toUnitFactor) / 1000));
+ }
+ };
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+
+ LocalBroadcastManager
+ .getInstance(this)
+ .registerReceiver(
+ cyclingDataReceiver,
+ new IntentFilter(DeviceService.ACTION_REALTIME_SAMPLES)
+ );
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+
+ LocalBroadcastManager
+ .getInstance(this)
+ .unregisterReceiver(cyclingDataReceiver);
+ }
+
+}
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/cycling_sensor/coordinator/CyclingSensorCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/cycling_sensor/coordinator/CyclingSensorCoordinator.java
index 8dedd9fd5..ed74e0be0 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/cycling_sensor/coordinator/CyclingSensorCoordinator.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/cycling_sensor/coordinator/CyclingSensorCoordinator.java
@@ -11,6 +11,7 @@ import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.devices.AbstractBLEDeviceCoordinator;
import nodomain.freeyourgadget.gadgetbridge.devices.InstallHandler;
import nodomain.freeyourgadget.gadgetbridge.devices.TimeSampleProvider;
+import nodomain.freeyourgadget.gadgetbridge.devices.cycling_sensor.activity.CyclingLiveDataActivity;
import nodomain.freeyourgadget.gadgetbridge.devices.cycling_sensor.db.CyclingSampleProvider;
import nodomain.freeyourgadget.gadgetbridge.entities.CyclingSample;
import nodomain.freeyourgadget.gadgetbridge.entities.CyclingSampleDao;
@@ -80,7 +81,7 @@ public class CyclingSensorCoordinator extends AbstractBLEDeviceCoordinator {
@Override
public Class extends Activity> getAppsManagementActivity() {
- return null;
+ return CyclingLiveDataActivity.class;
}
@Override
@@ -110,4 +111,11 @@ public class CyclingSensorCoordinator extends AbstractBLEDeviceCoordinator {
public int getDeviceNameResource() {
return R.string.devicetype_cycling_sensor;
}
+
+ @Override
+ public boolean supportsAppsManagement(GBDevice device) {
+ return true;
+ }
+
+
}
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/cycling_sensor/support/CyclingSensorSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/cycling_sensor/support/CyclingSensorSupport.java
index aceb4d361..69367dfb0 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/cycling_sensor/support/CyclingSensorSupport.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/cycling_sensor/support/CyclingSensorSupport.java
@@ -1,7 +1,5 @@
package nodomain.freeyourgadget.gadgetbridge.service.devices.cycling_sensor.support;
-import static nodomain.freeyourgadget.gadgetbridge.model.ActivityKind.CYCLING;
-
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCharacteristic;
import android.content.Intent;
@@ -93,7 +91,7 @@ public class CyclingSensorSupport extends CyclingSensorBaseSupport {
private long persistenceInterval;
private long nextPersistenceTimestamp = 0;
- private float wheelCircumference;
+ private float wheelCircumferenceMeters;
private CyclingSpeedCadenceMeasurement lastReportedMeasurement = null;
private long lastMeasurementTime = 0;
@@ -125,7 +123,7 @@ public class CyclingSensorSupport extends CyclingSensorBaseSupport {
nextPersistenceTimestamp = 0;
float wheelDiameter = deviceSpecificPrefs.getFloat(DeviceSettingsPreferenceConst.PREF_CYCLING_SENSOR_WHEEL_DIAMETER, 29);
- wheelCircumference = (float)(wheelDiameter * 2.54 * Math.PI) / 100;
+ wheelCircumferenceMeters = (float)(wheelDiameter * 2.54 * Math.PI) / 100;
}
@Override
@@ -196,13 +194,30 @@ public class CyclingSensorSupport extends CyclingSensorBaseSupport {
float revolutionsPerSecond = revolutionsDelta * (1000f / millisDelta);
- speed = revolutionsPerSecond * wheelCircumference;
+ speed = revolutionsPerSecond * wheelCircumferenceMeters;
}
}
lastReportedMeasurement = currentMeasurement;
lastMeasurementTime = now;
+ CyclingSample sample = new CyclingSample();
+
+ if (currentMeasurement.revolutionDataPresent) {
+ sample.setRevolutionCount(currentMeasurement.revolutionCount);
+ sample.setSpeed(speed);
+ sample.setDistance(currentMeasurement.revolutionCount * wheelCircumferenceMeters);
+ }
+
+ sample.setTimestamp(now);
+
+ Intent liveIntent = new Intent(DeviceService.ACTION_REALTIME_SAMPLES);
+ liveIntent.putExtra(DeviceService.EXTRA_REALTIME_SAMPLE, sample);
+ liveIntent.putExtra("EXTRA_DEVICE_ADDRESS", getDevice().getAddress());
+ LocalBroadcastManager.getInstance(getContext())
+ .sendBroadcast(liveIntent);
+
+
if(now < nextPersistenceTimestamp){
// too early
return;
@@ -210,21 +225,6 @@ public class CyclingSensorSupport extends CyclingSensorBaseSupport {
nextPersistenceTimestamp = now + persistenceInterval;
- CyclingSample sample = new CyclingSample();
-
- if (currentMeasurement.revolutionDataPresent) {
- sample.setRevolutionCount(currentMeasurement.revolutionCount);
- sample.setSpeed(speed);
- sample.setDistance(currentMeasurement.revolutionCount * wheelCircumference);
- }
-
- sample.setTimestamp(now);
-
- Intent liveIntent = new Intent(DeviceService.ACTION_REALTIME_SAMPLES);
- liveIntent.putExtra(DeviceService.EXTRA_REALTIME_SAMPLE, sample);
- LocalBroadcastManager.getInstance(getContext())
- .sendBroadcast(liveIntent);
-
try(DBHandler handler = GBApplication.acquireDB()) {
DaoSession session = handler.getDaoSession();
diff --git a/app/src/main/res/layout/activity_cycling_live_data.xml b/app/src/main/res/layout/activity_cycling_live_data.xml
new file mode 100644
index 000000000..b06560ba1
--- /dev/null
+++ b/app/src/main/res/layout/activity_cycling_live_data.xml
@@ -0,0 +1,51 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ 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 7204f749c..cb2297548 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -3296,4 +3296,9 @@
Abort the import? This may lead to a corrupted or inconsistent database.
Restart
%1s will now restart.
+ Trip: %.1f km
+ Total: %.1f km
+ Trip: %.1f mi
+ Total: %.1f mi
+ no cycling sensor found