Panagiotis Triantafyllou

telematics addition

...@@ -65,10 +65,11 @@ ...@@ -65,10 +65,11 @@
65 android:screenOrientation="portrait" 65 android:screenOrientation="portrait"
66 android:theme="@style/SDKAppTheme" /> 66 android:theme="@style/SDKAppTheme" />
67 67
68 +<!-- android:screenOrientation="portrait"-->
68 <activity 69 <activity
69 android:name="ly.warp.sdk.activities.TelematicsActivity" 70 android:name="ly.warp.sdk.activities.TelematicsActivity"
70 android:exported="false" 71 android:exported="false"
71 - android:screenOrientation="portrait" 72 + android:configChanges="orientation|screenSize"
72 android:theme="@style/SDKAppTheme" /> 73 android:theme="@style/SDKAppTheme" />
73 74
74 <activity 75 <activity
......
...@@ -4,6 +4,7 @@ import android.Manifest; ...@@ -4,6 +4,7 @@ import android.Manifest;
4 import android.app.Activity; 4 import android.app.Activity;
5 import android.content.Context; 5 import android.content.Context;
6 import android.content.pm.PackageManager; 6 import android.content.pm.PackageManager;
7 +import android.content.res.Configuration;
7 import android.hardware.Sensor; 8 import android.hardware.Sensor;
8 import android.hardware.SensorEvent; 9 import android.hardware.SensorEvent;
9 import android.hardware.SensorEventListener; 10 import android.hardware.SensorEventListener;
...@@ -14,7 +15,7 @@ import android.location.LocationManager; ...@@ -14,7 +15,7 @@ import android.location.LocationManager;
14 import android.os.Bundle; 15 import android.os.Bundle;
15 import android.os.Environment; 16 import android.os.Environment;
16 import android.os.Handler; 17 import android.os.Handler;
17 -import android.util.Log; 18 +import android.view.MotionEvent;
18 import android.view.View; 19 import android.view.View;
19 import android.view.WindowManager; 20 import android.view.WindowManager;
20 import android.widget.ImageView; 21 import android.widget.ImageView;
...@@ -27,6 +28,7 @@ import androidx.core.content.ContextCompat; ...@@ -27,6 +28,7 @@ import androidx.core.content.ContextCompat;
27 28
28 import com.google.android.material.snackbar.Snackbar; 29 import com.google.android.material.snackbar.Snackbar;
29 30
31 +import org.jetbrains.annotations.NotNull;
30 import org.json.JSONArray; 32 import org.json.JSONArray;
31 import org.json.JSONException; 33 import org.json.JSONException;
32 import org.json.JSONObject; 34 import org.json.JSONObject;
...@@ -39,7 +41,6 @@ import java.util.Arrays; ...@@ -39,7 +41,6 @@ import java.util.Arrays;
39 41
40 import io.github.inflationx.viewpump.ViewPumpContextWrapper; 42 import io.github.inflationx.viewpump.ViewPumpContextWrapper;
41 import ly.warp.sdk.R; 43 import ly.warp.sdk.R;
42 -import ly.warp.sdk.db.WarplyDBHelper;
43 44
44 /** 45 /**
45 * Created by Panagiotis Triantafyllou on 26/June/2023. 46 * Created by Panagiotis Triantafyllou on 26/June/2023.
...@@ -58,30 +59,33 @@ public class TelematicsActivity extends Activity implements View.OnClickListener ...@@ -58,30 +59,33 @@ public class TelematicsActivity extends Activity implements View.OnClickListener
58 private ImageView mIvBack; 59 private ImageView mIvBack;
59 private boolean mIsTripStarted = false; 60 private boolean mIsTripStarted = false;
60 private LinearLayout mLlTripButton, mLlTelematicsMain; 61 private LinearLayout mLlTripButton, mLlTelematicsMain;
61 - private TextView mTvTripButton, mTvSensorData, mTvVelocity, mTvAvgVelocity, mTvRecordsSaved; 62 + private TextView mTvTripButton, mTvSensorData, mTvVelocity, mTvAvgVelocity, mTvRecordsSaved,
63 + mTvOrientationCount, mTvTouchCount;
62 private SensorManager mSensorManager; 64 private SensorManager mSensorManager;
63 private Sensor mSensor; 65 private Sensor mSensor;
64 - private Handler mHandler, mLoctionHandler; 66 + private Handler mHandler, mLocationHandler, mTouchHandler;
65 - private Runnable mRunnable, mLocationRunnable; 67 + private Runnable mRunnable, mLocationRunnable, mTouchRunnable;
66 private long lastUpdate = 0; 68 private long lastUpdate = 0;
67 private float lastX, lastY, lastZ; 69 private float lastX, lastY, lastZ;
68 private float velocity = 0; 70 private float velocity = 0;
69 private ArrayList<JSONObject> mAccelerationTimestamps = new ArrayList<>(); 71 private ArrayList<JSONObject> mAccelerationTimestamps = new ArrayList<>();
70 - float mAcceleration = 0; 72 + private float mAcceleration = 0;
71 -
72 private static final float ALPHA = 0.8f; // Filter factor 73 private static final float ALPHA = 0.8f; // Filter factor
73 private static final float STOP_THRESHOLD = 8.0f; // Stop threshold in m/s² 74 private static final float STOP_THRESHOLD = 8.0f; // Stop threshold in m/s²
74 private static final int PERMISSION_REQUEST_WRITE_EXTERNAL_STORAGE = 4000; 75 private static final int PERMISSION_REQUEST_WRITE_EXTERNAL_STORAGE = 4000;
75 private static final int PERMISSION_REQUEST_ACCESS_FINE_LOCATION = 4001; 76 private static final int PERMISSION_REQUEST_ACCESS_FINE_LOCATION = 4001;
76 - JSONArray jsonArray = new JSONArray(); 77 + private JSONArray jsonArray = new JSONArray();
77 private LocationManager locationManager; 78 private LocationManager locationManager;
78 private static final int LOCATION_UPDATE_INTERVAL = 1000; 79 private static final int LOCATION_UPDATE_INTERVAL = 1000;
79 - double mLatitude = 0; 80 + private double mLatitude = 0;
80 - double mLongitude = 0; 81 + private double mLongitude = 0;
81 // Radius of the Earth in meters 82 // Radius of the Earth in meters
82 - private static final double EARTH_RADIUS = 6371000.0; 83 + private final double EARTH_RADIUS = 6371000.0;
83 private Location previousLocation; 84 private Location previousLocation;
84 - double mSpeed = 0; 85 + private double mSpeed = 0;
86 + private int orientationCount = 0, touchCount = 0;
87 + final long REFRESH_TIME = 100; // miliseconds
88 +
85 89
86 // =========================================================== 90 // ===========================================================
87 // Methods for/from SuperClass/Interfaces 91 // Methods for/from SuperClass/Interfaces
...@@ -103,6 +107,8 @@ public class TelematicsActivity extends Activity implements View.OnClickListener ...@@ -103,6 +107,8 @@ public class TelematicsActivity extends Activity implements View.OnClickListener
103 mTvAvgVelocity = findViewById(R.id.tv_avg); 107 mTvAvgVelocity = findViewById(R.id.tv_avg);
104 mTvRecordsSaved = findViewById(R.id.tv_records); 108 mTvRecordsSaved = findViewById(R.id.tv_records);
105 mIvBack.setOnClickListener(this); 109 mIvBack.setOnClickListener(this);
110 + mTvOrientationCount = findViewById(R.id.tv_orientation);
111 + mTvTouchCount = findViewById(R.id.tv_touch);
106 112
107 locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE); 113 locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
108 previousLocation = null; 114 previousLocation = null;
...@@ -192,6 +198,13 @@ public class TelematicsActivity extends Activity implements View.OnClickListener ...@@ -192,6 +198,13 @@ public class TelematicsActivity extends Activity implements View.OnClickListener
192 mIsTripStarted = false; 198 mIsTripStarted = false;
193 mTvTripButton.setText(R.string.cos_dlg_start_trip); 199 mTvTripButton.setText(R.string.cos_dlg_start_trip);
194 } else { 200 } else {
201 + mTouchHandler = new Handler();
202 + mTouchRunnable = new Runnable() {
203 + @Override
204 + public void run() {
205 + mTouchHandler.postDelayed(this, REFRESH_TIME);
206 + }
207 + };
195 requestLocationUpdates(); 208 requestLocationUpdates();
196 registerSensor(); 209 registerSensor();
197 mIsTripStarted = true; 210 mIsTripStarted = true;
...@@ -239,22 +252,6 @@ public class TelematicsActivity extends Activity implements View.OnClickListener ...@@ -239,22 +252,6 @@ public class TelematicsActivity extends Activity implements View.OnClickListener
239 // requestLocationUpdatePeriodically(location); 252 // requestLocationUpdatePeriodically(location);
240 mLatitude = location.getLatitude(); 253 mLatitude = location.getLatitude();
241 mLongitude = location.getLongitude(); 254 mLongitude = location.getLongitude();
242 -
243 - //TODO: similar implementation, comment all of the above blocks
244 -// if (previousLocation != null) {
245 -// // Calculate the distance traveled between the previous and current location
246 -// float distance = previousLocation.distanceTo(location); // Distance in meters
247 -//
248 -// // Calculate the speed based on the distance traveled over a timeframe of x seconds
249 -// float speed = distance / (LOCATION_UPDATE_INTERVAL / 1000); // Speed in meters/second
250 -//
251 -// // Convert speed to km/h
252 -// float speedKmH = speed * 3.6f;
253 -//
254 -// mTvAvgVelocity.setText(String.format("%.1f", Math.floor(speedKmH)) + " km/h");
255 -// }
256 -//
257 -// previousLocation = location;
258 } 255 }
259 256
260 @Override 257 @Override
...@@ -272,6 +269,40 @@ public class TelematicsActivity extends Activity implements View.OnClickListener ...@@ -272,6 +269,40 @@ public class TelematicsActivity extends Activity implements View.OnClickListener
272 // Handle provider disabled if needed 269 // Handle provider disabled if needed
273 } 270 }
274 271
272 + @Override
273 + public void onConfigurationChanged(@NotNull Configuration newConfig) {
274 + super.onConfigurationChanged(newConfig);
275 + if (mIsTripStarted) {
276 + if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE || newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
277 + orientationCount++;
278 + mTvOrientationCount.setText(String.valueOf(orientationCount));
279 + }
280 + }
281 + }
282 +
283 + @Override
284 + public boolean onTouchEvent(MotionEvent event) {
285 +// return super.onTouchEvent(event);
286 + if (mIsTripStarted) {
287 +// touchCount++;
288 +// mTvTouchCount.setText(String.valueOf(touchCount));
289 +// return true;
290 +
291 + switch (event.getAction()) {
292 + case MotionEvent.ACTION_DOWN:
293 + touchCount++;
294 + mTvTouchCount.setText(String.valueOf(touchCount));
295 + mTouchHandler.post(mTouchRunnable);
296 + return true;
297 + case MotionEvent.ACTION_UP:
298 + mTouchHandler.removeCallbacks(mTouchRunnable);
299 + return true;
300 + }
301 + return false;
302 + }
303 + return false;
304 + }
305 +
275 // =========================================================== 306 // ===========================================================
276 // Methods 307 // Methods
277 // =========================================================== 308 // ===========================================================
...@@ -304,16 +335,16 @@ public class TelematicsActivity extends Activity implements View.OnClickListener ...@@ -304,16 +335,16 @@ public class TelematicsActivity extends Activity implements View.OnClickListener
304 } 335 }
305 336
306 private void requestLocationUpdatePeriodically(Location location) { 337 private void requestLocationUpdatePeriodically(Location location) {
307 - mLoctionHandler = new Handler(); 338 + mLocationHandler = new Handler();
308 mLocationRunnable = new Runnable() { 339 mLocationRunnable = new Runnable() {
309 @Override 340 @Override
310 public void run() { 341 public void run() {
311 double speed = calculateSpeed(mLatitude, mLongitude, location.getLatitude(), location.getLongitude(), (LOCATION_UPDATE_INTERVAL / 1000)); 342 double speed = calculateSpeed(mLatitude, mLongitude, location.getLatitude(), location.getLongitude(), (LOCATION_UPDATE_INTERVAL / 1000));
312 mTvAvgVelocity.setText(String.format("%.1f", Math.floor(speed)) + " km/h"); 343 mTvAvgVelocity.setText(String.format("%.1f", Math.floor(speed)) + " km/h");
313 - mLoctionHandler.postDelayed(this, LOCATION_UPDATE_INTERVAL); 344 + mLocationHandler.postDelayed(this, LOCATION_UPDATE_INTERVAL);
314 } 345 }
315 }; 346 };
316 - mLoctionHandler.postDelayed(mLocationRunnable, LOCATION_UPDATE_INTERVAL); 347 + mLocationHandler.postDelayed(mLocationRunnable, LOCATION_UPDATE_INTERVAL);
317 } 348 }
318 349
319 private double calculateDistance(double lat1, double lon1, double lat2, double lon2) { 350 private double calculateDistance(double lat1, double lon1, double lat2, double lon2) {
...@@ -339,8 +370,8 @@ public class TelematicsActivity extends Activity implements View.OnClickListener ...@@ -339,8 +370,8 @@ public class TelematicsActivity extends Activity implements View.OnClickListener
339 370
340 private void stopLocationUpdates() { 371 private void stopLocationUpdates() {
341 locationManager.removeUpdates(this); 372 locationManager.removeUpdates(this);
342 - if (mLoctionHandler != null) 373 + if (mLocationHandler != null)
343 - mLoctionHandler.removeCallbacks(mLocationRunnable); 374 + mLocationHandler.removeCallbacks(mLocationRunnable);
344 } 375 }
345 376
346 private void registerSensor() { 377 private void registerSensor() {
...@@ -361,6 +392,8 @@ public class TelematicsActivity extends Activity implements View.OnClickListener ...@@ -361,6 +392,8 @@ public class TelematicsActivity extends Activity implements View.OnClickListener
361 JSONObject jobjData = new JSONObject(); 392 JSONObject jobjData = new JSONObject();
362 jobjData.putOpt("acceleration", mAcceleration); 393 jobjData.putOpt("acceleration", mAcceleration);
363 jobjData.putOpt("speed", mSpeed); 394 jobjData.putOpt("speed", mSpeed);
395 + jobjData.putOpt("orientation_count", orientationCount);
396 + jobjData.putOpt("touch_count", touchCount);
364 jobj.putOpt(String.valueOf(System.currentTimeMillis()), jobjData); 397 jobj.putOpt(String.valueOf(System.currentTimeMillis()), jobjData);
365 mAccelerationTimestamps.add(jobj); 398 mAccelerationTimestamps.add(jobj);
366 recordsCount[0]++; 399 recordsCount[0]++;
...@@ -376,12 +409,16 @@ public class TelematicsActivity extends Activity implements View.OnClickListener ...@@ -376,12 +409,16 @@ public class TelematicsActivity extends Activity implements View.OnClickListener
376 } 409 }
377 410
378 private void unregisterSensor() { 411 private void unregisterSensor() {
412 + orientationCount = 0;
413 + touchCount = 0;
379 mSensorManager.unregisterListener(this); 414 mSensorManager.unregisterListener(this);
380 mTvVelocity.setText("0.0 km/h"); 415 mTvVelocity.setText("0.0 km/h");
381 mTvAvgVelocity.setText("0.0 km/h"); 416 mTvAvgVelocity.setText("0.0 km/h");
382 Snackbar.make(mLlTelematicsMain, "Sensor Unregistered", Snackbar.LENGTH_SHORT).show(); 417 Snackbar.make(mLlTelematicsMain, "Sensor Unregistered", Snackbar.LENGTH_SHORT).show();
383 if (mHandler != null) 418 if (mHandler != null)
384 mHandler.removeCallbacks(mRunnable); 419 mHandler.removeCallbacks(mRunnable);
420 + if (mTouchHandler != null)
421 + mTouchHandler.removeCallbacks(mTouchRunnable);
385 saveAccelerationDataToFile(); 422 saveAccelerationDataToFile();
386 } 423 }
387 424
...@@ -393,37 +430,37 @@ public class TelematicsActivity extends Activity implements View.OnClickListener ...@@ -393,37 +430,37 @@ public class TelematicsActivity extends Activity implements View.OnClickListener
393 } 430 }
394 431
395 //TODO: uncomment if needed to write to file 432 //TODO: uncomment if needed to write to file
396 -// if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) 433 + if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
397 -// != PackageManager.PERMISSION_GRANTED) { 434 + != PackageManager.PERMISSION_GRANTED) {
398 -// ActivityCompat.requestPermissions(this, 435 + ActivityCompat.requestPermissions(this,
399 -// new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 436 + new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
400 -// PERMISSION_REQUEST_WRITE_EXTERNAL_STORAGE); 437 + PERMISSION_REQUEST_WRITE_EXTERNAL_STORAGE);
401 -// } else { 438 + } else {
402 saveAccelerationDataToExternalStorage(jsonArray); 439 saveAccelerationDataToExternalStorage(jsonArray);
403 -// } 440 + }
404 } 441 }
405 442
406 private void saveAccelerationDataToExternalStorage(JSONArray jsonArray) { 443 private void saveAccelerationDataToExternalStorage(JSONArray jsonArray) {
407 //TODO: comment if needed to write to file 444 //TODO: comment if needed to write to file
408 - WarplyDBHelper.getInstance(this).saveTelematics(jsonArray); 445 +// WarplyDBHelper.getInstance(this).saveTelematics(jsonArray);
409 446
410 //TODO: uncomment if needed to write to file 447 //TODO: uncomment if needed to write to file
411 -// String state = Environment.getExternalStorageState(); 448 + String state = Environment.getExternalStorageState();
412 -// if (Environment.MEDIA_MOUNTED.equals(state)) { 449 + if (Environment.MEDIA_MOUNTED.equals(state)) {
413 -// File documentsDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS); 450 + File documentsDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS);
414 -// File file = new File(documentsDir, "telematics_data.json"); 451 + File file = new File(documentsDir, "telematics_data" + String.valueOf(System.currentTimeMillis()) + ".json");
415 -// try { 452 + try {
416 -// FileOutputStream fileOutputStream = new FileOutputStream(file); 453 + FileOutputStream fileOutputStream = new FileOutputStream(file);
417 -// fileOutputStream.write(jsonArray.toString().getBytes()); 454 + fileOutputStream.write(jsonArray.toString().getBytes());
418 -// fileOutputStream.close(); 455 + fileOutputStream.close();
419 -// Snackbar.make(mLlTelematicsMain, "Success saving data to file", Snackbar.LENGTH_SHORT).show(); 456 + Snackbar.make(mLlTelematicsMain, "Success saving data to file", Snackbar.LENGTH_SHORT).show();
420 -// } catch (IOException e) { 457 + } catch (IOException e) {
421 -// e.printStackTrace(); 458 + e.printStackTrace();
422 -// Snackbar.make(mLlTelematicsMain, "Error saving acceleration data to file", Snackbar.LENGTH_SHORT).show(); 459 + Snackbar.make(mLlTelematicsMain, "Error saving acceleration data to file", Snackbar.LENGTH_SHORT).show();
423 -// } 460 + }
424 -// } else { 461 + } else {
425 -// Snackbar.make(mLlTelematicsMain, "External storage is not accessible", Snackbar.LENGTH_SHORT).show(); 462 + Snackbar.make(mLlTelematicsMain, "External storage is not accessible", Snackbar.LENGTH_SHORT).show();
426 -// } 463 + }
427 } 464 }
428 465
429 // // Low-pass filter function using Exponential Moving Average (EMA) 466 // // Low-pass filter function using Exponential Moving Average (EMA)
......
...@@ -114,6 +114,59 @@ ...@@ -114,6 +114,59 @@
114 android:textSize="16sp" /> 114 android:textSize="16sp" />
115 115
116 <TextView 116 <TextView
117 + android:id="@+id/tv_orientation_label"
118 + fontPath="fonts/PeridotPE-Regular.ttf"
119 + android:layout_width="wrap_content"
120 + android:layout_height="wrap_content"
121 + android:layout_alignParentStart="true"
122 + android:layout_marginTop="24dp"
123 + android:layout_marginStart="24dp"
124 + android:text="Orientation Count"
125 + android:layout_below="@+id/tv_avg"
126 + android:textColor="@color/blue_dark"
127 + android:textSize="16sp" />
128 +
129 + <TextView
130 + android:id="@+id/tv_orientation"
131 + fontPath="fonts/PeridotPE-Bold.ttf"
132 + android:layout_width="wrap_content"
133 + android:layout_height="wrap_content"
134 + android:layout_below="@+id/tv_orientation_label"
135 + android:layout_alignStart="@+id/tv_orientation_label"
136 + android:layout_alignEnd="@+id/tv_orientation_label"
137 + android:layout_marginTop="24dp"
138 + android:gravity="center"
139 + android:textColor="@color/blue_dark"
140 + android:textSize="16sp" />
141 +
142 + <TextView
143 + android:id="@+id/tv_touch_label"
144 + fontPath="fonts/PeridotPE-Regular.ttf"
145 + android:layout_width="wrap_content"
146 + android:layout_height="wrap_content"
147 + android:layout_marginTop="24dp"
148 + android:layout_marginEnd="24dp"
149 + android:layout_alignParentEnd="true"
150 + android:text="Touch Count"
151 + android:layout_below="@+id/tv_avg"
152 + android:layout_alignEnd="@+id/tv_orientation_label"
153 + android:textColor="@color/blue_dark"
154 + android:textSize="16sp" />
155 +
156 + <TextView
157 + android:id="@+id/tv_touch"
158 + fontPath="fonts/PeridotPE-Bold.ttf"
159 + android:layout_width="wrap_content"
160 + android:layout_height="wrap_content"
161 + android:layout_below="@+id/tv_touch_label"
162 + android:layout_alignStart="@+id/tv_touch_label"
163 + android:layout_alignEnd="@+id/tv_touch_label"
164 + android:layout_marginTop="24dp"
165 + android:gravity="center"
166 + android:textColor="@color/blue_dark"
167 + android:textSize="16sp" />
168 +
169 + <TextView
117 android:id="@+id/tv_records_label" 170 android:id="@+id/tv_records_label"
118 fontPath="fonts/PeridotPE-Regular.ttf" 171 fontPath="fonts/PeridotPE-Regular.ttf"
119 android:layout_width="wrap_content" 172 android:layout_width="wrap_content"
...@@ -121,7 +174,7 @@ ...@@ -121,7 +174,7 @@
121 android:layout_centerHorizontal="true" 174 android:layout_centerHorizontal="true"
122 android:layout_marginTop="24dp" 175 android:layout_marginTop="24dp"
123 android:text="Records Saved" 176 android:text="Records Saved"
124 - android:layout_below="@+id/tv_avg" 177 + android:layout_below="@+id/tv_orientation"
125 android:textColor="@color/blue_dark" 178 android:textColor="@color/blue_dark"
126 android:textSize="16sp" /> 179 android:textSize="16sp" />
127 180
......