diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/ActivitySummariesActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/ActivitySummariesActivity.java
index dc7d0ef67..4deff97d9 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/ActivitySummariesActivity.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/ActivitySummariesActivity.java
@@ -17,7 +17,6 @@
along with this program. If not, see . */
package nodomain.freeyourgadget.gadgetbridge.activities;
-import android.app.Activity;
import android.app.DatePickerDialog;
import android.content.BroadcastReceiver;
import android.content.Context;
@@ -31,12 +30,14 @@ import android.view.ActionMode;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
+import android.view.animation.Animation;
+import android.view.animation.AnimationUtils;
import android.widget.AbsListView;
import android.widget.AdapterView;
-import android.widget.ArrayAdapter;
import android.widget.DatePicker;
+import android.widget.LinearLayout;
import android.widget.ListView;
-import android.widget.Spinner;
+import android.widget.TextView;
import android.widget.Toast;
import androidx.core.content.FileProvider;
@@ -45,26 +46,33 @@ import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
+import org.json.JSONException;
+import org.json.JSONObject;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
import java.io.File;
+import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Calendar;
+import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Objects;
+import java.util.concurrent.TimeUnit;
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.R;
-import nodomain.freeyourgadget.gadgetbridge.activities.appmanager.AppManagerActivity;
import nodomain.freeyourgadget.gadgetbridge.adapter.ActivitySummariesAdapter;
import nodomain.freeyourgadget.gadgetbridge.entities.BaseActivitySummary;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind;
import nodomain.freeyourgadget.gadgetbridge.model.ActivitySummary;
+import nodomain.freeyourgadget.gadgetbridge.model.ActivitySummaryJsonSummary;
import nodomain.freeyourgadget.gadgetbridge.model.RecordedDataTypes;
+import nodomain.freeyourgadget.gadgetbridge.util.DateTimeUtils;
import nodomain.freeyourgadget.gadgetbridge.util.GB;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
@@ -76,6 +84,7 @@ public class ActivitySummariesActivity extends AbstractListActivity keys = data.keys();
DecimalFormat df = new DecimalFormat("#.##");
@@ -294,76 +274,9 @@ public class ActivitySummaryDetail extends AbstractGBActivity {
}
}
- private JSONObject setGroups(){
- String groupDefinitions = "{'Strokes':['averageStrokeDistance','averageStrokesPerSecond','strokes'], " +
- "'Swimming':['swolfIndex','swimStyle'], " +
- "'Elevation':['ascentMeters','descentMeters','maxAltitude','minAltitude','ascentSeconds','descentSeconds','flatSeconds'], " +
- "'Speed':['maxSpeed','minPace','maxPace','averageKMPaceSeconds'], " +
- "'Activity':['distanceMeters','steps','activeSeconds','caloriesBurnt','totalStride'," +
- "'averageHR','averageStride'], " +
- "'Laps':['averageLapPace','laps']}";
- JSONObject data = null;
- try {
- data = new JSONObject(groupDefinitions);
- } catch (JSONException e) {
- LOG.error("SportsActivity", e);
- }
- return data;
- }
- private String getGroup(String searchItem) {
- String defaultGroup = "Activity";
- if (groupData == null) return defaultGroup;
- Iterator keys = groupData.keys();
- while (keys.hasNext()) {
- String key = keys.next();
- try {
- JSONArray itemList = (JSONArray) groupData.get(key);
- for (int i = 0; i < itemList.length(); i++) {
- if (itemList.getString(i).equals(searchItem)) {
- return key;
- }
- }
- } catch (JSONException e) {
- LOG.error("SportsActivity", e);
- }
- }
- return defaultGroup;
-}
- private JSONObject makeSummaryList(JSONObject summaryData){
- //make dictionary with data for each group
- JSONObject list = new JSONObject();
- Iterator keys = summaryData.keys();
- LOG.error("SportsActivity JSON:" + summaryData + keys);
- while (keys.hasNext()) {
- String key = keys.next();
-
- try {
- LOG.error("SportsActivity:" + key + ": " + summaryData.get(key) + "\n");
- JSONObject innerData = (JSONObject) summaryData.get(key);
- Object value = innerData.get("value");
- String unit = innerData.getString("unit");
- String group = getGroup(key);
-
- if (!list.has(group)) {
- list.put(group,new JSONArray());
- }
-
- JSONArray tmpl = (JSONArray) list.get(group);
- JSONObject innernew = new JSONObject();
- innernew.put("name", key);
- innernew.put("value", value);
- innernew.put("unit", unit);
- tmpl.put(innernew);
- list.put(group, tmpl);
- } catch (JSONException e) {
- LOG.error("SportsActivity", e);
- }
- }
- return list;
- }
public static int getAlternateColor(Context context) {
TypedValue typedValue = new TypedValue();
Resources.Theme theme = context.getTheme();
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/ActivitySummary.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/ActivitySummary.java
index a9846c110..897696cc6 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/ActivitySummary.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/ActivitySummary.java
@@ -21,6 +21,9 @@ import org.json.JSONObject;
import java.io.Serializable;
import java.util.Date;
+import nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiActivitySummaryParser;
+import nodomain.freeyourgadget.gadgetbridge.entities.BaseActivitySummary;
+
/**
* Summarized information about a temporal activity.
*
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/ActivitySummaryJsonSummary.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/ActivitySummaryJsonSummary.java
new file mode 100644
index 000000000..ac880d819
--- /dev/null
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/ActivitySummaryJsonSummary.java
@@ -0,0 +1,131 @@
+package nodomain.freeyourgadget.gadgetbridge.model;
+
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Iterator;
+
+import nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiActivitySummaryParser;
+import nodomain.freeyourgadget.gadgetbridge.entities.BaseActivitySummary;
+
+public class ActivitySummaryJsonSummary {
+ private static final Logger LOG = LoggerFactory.getLogger(ActivitySummaryJsonSummary.class);
+ private JSONObject groupData;
+ private JSONObject summaryData;
+ private JSONObject summaryGroupedList;
+ private BaseActivitySummary baseActivitySummary;
+
+ public ActivitySummaryJsonSummary(BaseActivitySummary baseActivitySummary){
+ this.baseActivitySummary=baseActivitySummary;
+ }
+
+ private JSONObject setSummaryData(BaseActivitySummary item){
+ String summary = getCorrectSummary(item);
+ JSONObject jsonSummary = getJSONSummary(summary);
+ return jsonSummary;
+ }
+
+ public JSONObject getSummaryData(){
+ //returns json with summaryData
+ if (summaryData==null) summaryData=setSummaryData(baseActivitySummary);
+ return summaryData;
+ }
+
+ private String getCorrectSummary(BaseActivitySummary item){
+ if (item.getRawSummaryData() != null) {
+ ActivitySummaryParser parser = new HuamiActivitySummaryParser(); // FIXME: if something else than huami supports that make sure to have the right parser
+ item = parser.parseBinaryData(item);
+ }
+ return item.getSummaryData();
+ }
+
+ private JSONObject getJSONSummary(String sumData){
+ JSONObject summarySubdata = null;
+ if (sumData != null) {
+ try {
+ summarySubdata = new JSONObject(sumData);
+ } catch (JSONException e) {
+ }
+ }
+ return summarySubdata;
+ }
+
+ public JSONObject getSummaryGroupedList() {
+ //returns list grouped by activity groups as per createActivitySummaryGroups
+ if (summaryData==null) summaryData=setSummaryData(baseActivitySummary);
+ if (summaryGroupedList==null) summaryGroupedList=setSummaryGroupedList(summaryData);
+ return summaryGroupedList;
+ }
+ private JSONObject setSummaryGroupedList(JSONObject summaryDatalist){
+ this.groupData = createActivitySummaryGroups(); //structure for grouping activities into groups, when vizualizing
+
+ if (summaryDatalist ==null ) return null;
+ Iterator keys = summaryDatalist.keys();
+ JSONObject list=new JSONObject();
+
+ while (keys.hasNext()) {
+ String key = keys.next();
+ try {
+ JSONObject innerData = (JSONObject) summaryDatalist.get(key);
+ Object value = innerData.get("value");
+ String unit = innerData.getString("unit");
+ String group = getGroup(key);
+
+ if (!list.has(group)) {
+ list.put(group,new JSONArray());
+ }
+
+ JSONArray tmpl = (JSONArray) list.get(group);
+ JSONObject innernew = new JSONObject();
+ innernew.put("name", key);
+ innernew.put("value", value);
+ innernew.put("unit", unit);
+ tmpl.put(innernew);
+ list.put(group, tmpl);
+ } catch (JSONException e) {
+ LOG.error("SportsActivity", e);
+ }
+ }
+ return list;
+ }
+
+ private String getGroup(String searchItem) {
+ String defaultGroup = "Activity";
+ if (groupData == null) return defaultGroup;
+ Iterator keys = groupData.keys();
+ while (keys.hasNext()) {
+ String key = keys.next();
+ try {
+ JSONArray itemList = (JSONArray) groupData.get(key);
+ for (int i = 0; i < itemList.length(); i++) {
+ if (itemList.getString(i).equals(searchItem)) {
+ return key;
+ }
+ }
+ } catch (JSONException e) {
+ LOG.error("SportsActivity", e);
+ }
+ }
+ return defaultGroup;
+ }
+ private JSONObject createActivitySummaryGroups(){
+ String groupDefinitions = "{'Strokes':['averageStrokeDistance','averageStrokesPerSecond','strokes'], " +
+ "'Swimming':['swolfIndex','swimStyle'], " +
+ "'Elevation':['ascentMeters','descentMeters','maxAltitude','minAltitude','ascentSeconds','descentSeconds','flatSeconds'], " +
+ "'Speed':['maxSpeed','minPace','maxPace','averageKMPaceSeconds'], " +
+ "'Activity':['distanceMeters','steps','activeSeconds','caloriesBurnt','totalStride'," +
+ "'averageHR','averageStride'], " +
+ "'Laps':['averageLapPace','laps']}";
+ JSONObject data = null;
+ try {
+ data = new JSONObject(groupDefinitions);
+ } catch (JSONException e) {
+ LOG.error("SportsActivity", e);
+ }
+ return data;
+ }
+
+}
diff --git a/app/src/main/res/anim/slidefromtop.xml b/app/src/main/res/anim/slidefromtop.xml
new file mode 100644
index 000000000..ee6056c37
--- /dev/null
+++ b/app/src/main/res/anim/slidefromtop.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/ic_outline_filter_9_plus.xml b/app/src/main/res/drawable/ic_outline_filter_9_plus.xml
new file mode 100644
index 000000000..90a643aea
--- /dev/null
+++ b/app/src/main/res/drawable/ic_outline_filter_9_plus.xml
@@ -0,0 +1,10 @@
+
+
+
diff --git a/app/src/main/res/layout/activity_list.xml b/app/src/main/res/layout/activity_list.xml
index 9d3b605cb..75721b465 100644
--- a/app/src/main/res/layout/activity_list.xml
+++ b/app/src/main/res/layout/activity_list.xml
@@ -17,6 +17,7 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/menu/activity_list_menu.xml b/app/src/main/res/menu/activity_list_menu.xml
index 468160a2c..4db46fef8 100644
--- a/app/src/main/res/menu/activity_list_menu.xml
+++ b/app/src/main/res/menu/activity_list_menu.xml
@@ -13,5 +13,11 @@
android:title="@string/pref_header_filter"
app:iconTint="@color/primarytext_dark"
app:showAsAction="ifRoom" />
+
\ 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 54a0a2135..4db708430 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -952,6 +952,7 @@
sec/m
min/km
bpm
+ km
Strokes
Swimming
@@ -961,9 +962,9 @@
Activity
Steps
- Start:
- End:
- Duration:
+ Start
+ End
+ Duration
Show GPS Track
Use device events to trigger actions and Android broadcasts
@@ -977,11 +978,12 @@
Broadcast message
Run action
Sports Activities Filter
- From:
- To:
+ From
+ To
Reset Filter
Filter
Apply Filter
+ Statistics