mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge
synced 2024-12-25 10:05:49 +01:00
ActivityDetail with steps
This commit is contained in:
parent
94afcba363
commit
7a46d39193
@ -419,6 +419,11 @@
|
||||
android:parentActivityName=".activities.ControlCenterv2"
|
||||
android:screenOrientation="portrait"
|
||||
android:windowSoftInputMode="stateHidden" />
|
||||
<activity
|
||||
android:name=".activities.ActivitySummaryDetail"
|
||||
android:label="Activity Summary Detail"
|
||||
android:screenOrientation="portrait"
|
||||
android:windowSoftInputMode="stateHidden" />
|
||||
|
||||
<activity
|
||||
android:name=".activities.DbManagementActivity"
|
||||
|
@ -58,9 +58,13 @@ import nodomain.freeyourgadget.gadgetbridge.model.ActivitySummary;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.RecordedDataTypes;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.AndroidUtils;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.GB;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
||||
|
||||
public class ActivitySummariesActivity extends AbstractListActivity<BaseActivitySummary> {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(ActivitySummariesActivity.class);
|
||||
private GBDevice mGBDevice;
|
||||
private SwipeRefreshLayout swipeLayout;
|
||||
|
||||
@ -129,13 +133,12 @@ public class ActivitySummariesActivity extends AbstractListActivity<BaseActivity
|
||||
Object item = parent.getItemAtPosition(position);
|
||||
if (item != null) {
|
||||
ActivitySummary summary = (ActivitySummary) item;
|
||||
|
||||
String gpxTrack = summary.getGpxTrack();
|
||||
if (gpxTrack != null) {
|
||||
showTrack(gpxTrack);
|
||||
} else {
|
||||
GB.toast("This activity does not contain GPX tracks.", Toast.LENGTH_LONG, GB.INFO);
|
||||
try {
|
||||
showDetail(summary);
|
||||
} catch (Exception e) {
|
||||
GB.toast(getApplicationContext(), "Unable to display Activity Detail, maybe the activity is not available yet: " + e.getMessage(), Toast.LENGTH_LONG, GB.ERROR, e);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -263,6 +266,13 @@ public class ActivitySummariesActivity extends AbstractListActivity<BaseActivity
|
||||
refresh();
|
||||
}
|
||||
|
||||
private void showDetail(ActivitySummary summary){
|
||||
Intent ActivitySummaryDetailIntent = new Intent(this, ActivitySummaryDetail.class);
|
||||
ActivitySummaryDetailIntent.putExtra("summary", summary);
|
||||
ActivitySummaryDetailIntent.putExtra(GBDevice.EXTRA_DEVICE, mGBDevice);
|
||||
startActivity(ActivitySummaryDetailIntent);
|
||||
}
|
||||
|
||||
private void showTrack(String gpxTrack) {
|
||||
try {
|
||||
AndroidUtils.viewFile(gpxTrack, Intent.ACTION_VIEW, this);
|
||||
|
@ -0,0 +1,125 @@
|
||||
/* Copyright (C) 2015-2020 abettenburg, Andreas Shimokawa, Carsten Pfeiffer,
|
||||
Daniele Gobbetti, Lem Dulfo
|
||||
|
||||
This file is part of Gadgetbridge.
|
||||
|
||||
Gadgetbridge is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published
|
||||
by the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Gadgetbridge is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
package nodomain.freeyourgadget.gadgetbridge.activities;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
||||
import nodomain.freeyourgadget.gadgetbridge.R;
|
||||
import nodomain.freeyourgadget.gadgetbridge.activities.charts.ActivityAnalysis;
|
||||
import nodomain.freeyourgadget.gadgetbridge.database.DBHandler;
|
||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.ActivityAmounts;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.ActivitySummary;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.ActivityTrack;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.DailyTotals;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.AndroidUtils;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.DateTimeUtils;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.GB;
|
||||
|
||||
public class ActivitySummaryDetail extends AbstractGBActivity {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(ActivitySummaryDetail.class);
|
||||
private GBDevice mGBDevice;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_summary_details);
|
||||
|
||||
Intent intent = getIntent();
|
||||
ActivitySummary summary = (ActivitySummary) intent.getSerializableExtra("summary");
|
||||
GBDevice device = intent.getParcelableExtra(GBDevice.EXTRA_DEVICE);
|
||||
mGBDevice = device;
|
||||
|
||||
final String gpxTrack = summary.getGpxTrack();
|
||||
Button show_track_btn = (Button) findViewById(R.id.showTrack);
|
||||
show_track_btn.setVisibility(View.GONE);
|
||||
|
||||
if (gpxTrack != null) {
|
||||
ActivityTrack activityTrack = new ActivityTrack();
|
||||
|
||||
show_track_btn.setVisibility(View.VISIBLE);
|
||||
show_track_btn.setOnClickListener(new View.OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
try {
|
||||
AndroidUtils.viewFile(gpxTrack, Intent.ACTION_VIEW, getApplicationContext());
|
||||
} catch (IOException e) {
|
||||
GB.toast(getApplicationContext(), "Unable to display GPX track: " + e.getMessage(), Toast.LENGTH_LONG, GB.ERROR, e);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
String activitykind = ActivityKind.asString(summary.getActivityKind(), getApplicationContext());
|
||||
|
||||
String starttime = DateTimeUtils.formatDateTime(summary.getStartTime());
|
||||
String endtime = DateTimeUtils.formatDateTime(summary.getEndTime());
|
||||
Long startTs = summary.getStartTime().getTime() / 1000;
|
||||
Long endTs = summary.getEndTime().getTime() / 1000;
|
||||
Long durationms = (summary.getEndTime().getTime() - summary.getStartTime().getTime());
|
||||
String durationhms = String.format("%02d:%02d:%02d", TimeUnit.MILLISECONDS.toHours(durationms),
|
||||
TimeUnit.MILLISECONDS.toMinutes(durationms) % TimeUnit.HOURS.toMinutes(1),
|
||||
TimeUnit.MILLISECONDS.toSeconds(durationms) % TimeUnit.MINUTES.toSeconds(1));
|
||||
|
||||
int steps = getSteps(startTs.intValue(), endTs.intValue());
|
||||
|
||||
ImageView activity_icon = (ImageView) findViewById(R.id.item_image);
|
||||
activity_icon.setImageResource(ActivityKind.getIconId(summary.getActivityKind()));
|
||||
TextView activity_kind = (TextView) findViewById(R.id.activitykind);
|
||||
activity_kind.setText(activitykind);
|
||||
TextView start_time = (TextView) findViewById(R.id.starttime);
|
||||
start_time.setText(starttime);
|
||||
TextView end_time = (TextView) findViewById(R.id.endtime);
|
||||
end_time.setText(endtime);
|
||||
TextView activity_duration = (TextView) findViewById(R.id.duration);
|
||||
activity_duration.setText(durationhms);
|
||||
TextView activity_steps = (TextView) findViewById(R.id.steps);
|
||||
activity_steps.setText(String.valueOf(steps));
|
||||
}
|
||||
|
||||
|
||||
private int getSteps(int tsStart, int tsEnd) {
|
||||
|
||||
try (DBHandler handler = GBApplication.acquireDB()) {
|
||||
DailyTotals dt = new DailyTotals();
|
||||
ActivityAnalysis analysis = new ActivityAnalysis();
|
||||
ActivityAmounts amountsSteps;
|
||||
amountsSteps = analysis.calculateActivityAmounts(dt.getSamples(handler, mGBDevice, tsStart, tsEnd));
|
||||
return (int) dt.getTotalsStepsForActivityAmounts(amountsSteps);
|
||||
|
||||
} catch (Exception e) {
|
||||
|
||||
GB.toast("Error loading activity steps.", Toast.LENGTH_SHORT, GB.ERROR, e);
|
||||
}
|
||||
return 0;
|
||||
|
||||
}
|
||||
}
|
@ -21,6 +21,7 @@ import android.widget.Toast;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import de.greenrobot.dao.query.QueryBuilder;
|
||||
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
||||
@ -60,21 +61,38 @@ public class ActivitySummariesAdapter extends AbstractItemAdapter<BaseActivitySu
|
||||
|
||||
@Override
|
||||
protected String getName(BaseActivitySummary item) {
|
||||
|
||||
|
||||
|
||||
|
||||
String name = item.getName();
|
||||
if (name != null && name.length() > 0) {
|
||||
return name;
|
||||
}
|
||||
|
||||
Date startTime = item.getStartTime();
|
||||
Long duration = (item.getEndTime().getTime() - item.getStartTime().getTime());
|
||||
String durationhms = String.format("%02d:%02d:%02d", TimeUnit.MILLISECONDS.toHours(duration),
|
||||
TimeUnit.MILLISECONDS.toMinutes(duration) % TimeUnit.HOURS.toMinutes(1),
|
||||
TimeUnit.MILLISECONDS.toSeconds(duration) % TimeUnit.MINUTES.toSeconds(1));
|
||||
|
||||
if (startTime != null) {
|
||||
return DateTimeUtils.formatDateTime(startTime);
|
||||
return DateTimeUtils.formatDateTime(startTime) + " (" + durationhms + ")";
|
||||
}
|
||||
|
||||
|
||||
|
||||
return "Unknown activity";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getDetails(BaseActivitySummary item) {
|
||||
return ActivityKind.asString(item.getActivityKind(), getContext());
|
||||
String gpxTrack = item.getGpxTrack();
|
||||
String hasGps = "";
|
||||
if (gpxTrack != null) {
|
||||
hasGps=" 🛰️";
|
||||
}
|
||||
return ActivityKind.asString(item.getActivityKind(), getContext())+ hasGps;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -104,7 +104,7 @@ public class DailyTotals {
|
||||
}
|
||||
|
||||
|
||||
private long getTotalsStepsForActivityAmounts(ActivityAmounts activityAmounts) {
|
||||
public long getTotalsStepsForActivityAmounts(ActivityAmounts activityAmounts) {
|
||||
long totalSteps = 0;
|
||||
|
||||
for (ActivityAmount amount : activityAmounts.getAmounts()) {
|
||||
@ -131,7 +131,7 @@ public class DailyTotals {
|
||||
}
|
||||
|
||||
|
||||
protected List<? extends ActivitySample> getSamples(DBHandler db, GBDevice device, int tsFrom, int tsTo) {
|
||||
public List<? extends ActivitySample> getSamples(DBHandler db, GBDevice device, int tsFrom, int tsTo) {
|
||||
return getAllSamples(db, device, tsFrom, tsTo);
|
||||
}
|
||||
|
||||
|
138
app/src/main/res/layout/activity_summary_details.xml
Normal file
138
app/src/main/res/layout/activity_summary_details.xml
Normal file
@ -0,0 +1,138 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?android:attr/activatedBackgroundIndicator"
|
||||
android:padding="8dp">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/item_image"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="48dp"
|
||||
android:layout_alignParentStart="true"
|
||||
android:contentDescription="activity image" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_toEndOf="@+id/item_image"
|
||||
android:orientation="vertical"
|
||||
android:paddingStart="8dp"
|
||||
android:paddingEnd="8dp">
|
||||
|
||||
|
||||
<TextView
|
||||
android:id="@+id/activitykind"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:fontFamily="sans-serif-black"
|
||||
android:maxLines="1"
|
||||
android:scrollHorizontally="false" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/start"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/starttime_label"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:gravity="start"
|
||||
android:text="Start:" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/starttime"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:gravity="end" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/end"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/endtime_label"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:gravity="start"
|
||||
android:text="End:" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/endtime"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:gravity="end" />
|
||||
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/dur"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/duration_label"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:gravity="start"
|
||||
android:text="Duration:" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/duration"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:gravity="end" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/stps"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/steps_label"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:gravity="start"
|
||||
android:text="Steps:" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/steps"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:gravity="end" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
<Button
|
||||
android:id="@+id/showTrack"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Show GPS Track" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</RelativeLayout>
|
Loading…
Reference in New Issue
Block a user