mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-10-27 06:17:27 +00:00
TRACKING APP: Fix bug in transmitting GPSFixes to API, report GPS accurracy to user
This commit is contained in:
1 parent
b493f2f642
commit
0b247ae11c
6 files changed
+211
-44
No files matched your search
@@ -68,7 +68,7 @@
|
||||
android:contentDescription="@string/signal_quality_indicator_view_description"
|
||||
android:focusable="true"
|
||||
android:paddingRight="20dp"
|
||||
app:signalQuality="good" />
|
||||
app:signalQuality="none" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/qps_quality"
|
||||
|
||||
+74
-1
@@ -18,6 +18,7 @@ import android.content.ContentValues;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.location.Location;
|
||||
import android.os.Binder;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.IBinder;
|
||||
@@ -47,6 +48,9 @@ public class TrackingService extends Service implements ConnectionCallbacks, OnC
|
||||
private boolean locationUpdateRequested = false;
|
||||
private AppPreferences prefs;
|
||||
private ScheduledExecutorService scheduler;
|
||||
|
||||
private GPSQualityListener gpsQualityListener;
|
||||
private final IBinder trackingBinder = new TrackingBinder();
|
||||
|
||||
private static final String TAG = TrackingService.class.getName();
|
||||
|
||||
@@ -124,11 +128,39 @@ public class TrackingService extends Service implements ConnectionCallbacks, OnC
|
||||
public void onDisconnected() {
|
||||
ExLog.i(this, TAG, "LocationClient was disconnected");
|
||||
}
|
||||
|
||||
public void reportGPSQuality( float gpsAccurracy )
|
||||
{
|
||||
GPSQuality quality = GPSQuality.noSignal;
|
||||
|
||||
if (gpsQualityListener != null)
|
||||
{
|
||||
if (gpsAccurracy > 163)
|
||||
{
|
||||
quality = GPSQuality.poor;
|
||||
}
|
||||
else if (gpsAccurracy > 48)
|
||||
{
|
||||
quality = GPSQuality.good;
|
||||
}
|
||||
else if (gpsAccurracy < 48)
|
||||
{
|
||||
quality = GPSQuality.great;
|
||||
}
|
||||
|
||||
gpsQualityListener.gpsQualityUpdated(quality);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
|
||||
@Override
|
||||
public void onLocationChanged(Location location) {
|
||||
|
||||
reportGPSQuality(location.getAccuracy());
|
||||
|
||||
JSONObject json = new JSONObject();
|
||||
|
||||
try {
|
||||
json.put(FlatSmartphoneUuidAndGPSFixMovingJsonDeserializer.DEVICE_UUID,
|
||||
prefs.getDeviceIdentifier());
|
||||
@@ -193,7 +225,7 @@ public class TrackingService extends Service implements ConnectionCallbacks, OnC
|
||||
|
||||
@Override
|
||||
public IBinder onBind(Intent intent) {
|
||||
return null;
|
||||
return trackingBinder;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -213,4 +245,45 @@ public class TrackingService extends Service implements ConnectionCallbacks, OnC
|
||||
notification.flags |= Notification.FLAG_NO_CLEAR;
|
||||
startForeground(NOTIFICATION_ID, notification);
|
||||
}
|
||||
|
||||
public void registerGPSQualityListener( GPSQualityListener listener )
|
||||
{
|
||||
gpsQualityListener = listener;
|
||||
}
|
||||
|
||||
public void unregisterGPSQualityListener()
|
||||
{
|
||||
gpsQualityListener = null;
|
||||
}
|
||||
|
||||
|
||||
public class TrackingBinder extends Binder {
|
||||
public TrackingService getService() {
|
||||
return TrackingService.this;
|
||||
}
|
||||
}
|
||||
|
||||
public enum GPSQuality {
|
||||
noSignal (0),
|
||||
poor (2),
|
||||
good (3),
|
||||
great (4);
|
||||
|
||||
private final int gpsQuality;
|
||||
|
||||
GPSQuality(int quality)
|
||||
{
|
||||
this.gpsQuality = quality;
|
||||
}
|
||||
|
||||
public int toInt()
|
||||
{
|
||||
return this.gpsQuality;
|
||||
}
|
||||
}
|
||||
|
||||
public interface GPSQualityListener {
|
||||
public void gpsQualityUpdated( GPSQuality quality );
|
||||
}
|
||||
|
||||
}
|
||||
-1
@@ -279,7 +279,6 @@ public class TransmittingService extends Service {
|
||||
|
||||
|
||||
sendingAttempted = true;
|
||||
|
||||
VolleyHelper.getInstance(this).addRequest(
|
||||
new JsonObjectRequest(prefs.getServerURL()
|
||||
+ prefs.getServerGpsFixesPostPath(), requestObject,
|
||||
|
||||
+61
-11
@@ -1,32 +1,38 @@
|
||||
package com.sap.sailing.android.tracking.app.ui.activities;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.DialogInterface.OnClickListener;
|
||||
import android.annotation.TargetApi;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.ServiceConnection;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.app.FragmentActivity;
|
||||
import android.os.IBinder;
|
||||
import android.provider.Settings;
|
||||
import android.provider.Settings.SettingNotFoundException;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.sap.sailing.android.tracking.app.R;
|
||||
import com.sap.sailing.android.tracking.app.services.TrackingService;
|
||||
import com.sap.sailing.android.tracking.app.ui.fragments.HomeFragment;
|
||||
import com.sap.sailing.android.tracking.app.services.TrackingService.GPSQuality;
|
||||
import com.sap.sailing.android.tracking.app.services.TrackingService.GPSQualityListener;
|
||||
import com.sap.sailing.android.tracking.app.services.TrackingService.TrackingBinder;
|
||||
import com.sap.sailing.android.tracking.app.ui.fragments.TrackingFragment;
|
||||
|
||||
public class TrackingActivity extends BaseActivity {
|
||||
|
||||
public class TrackingActivity extends BaseActivity implements GPSQualityListener {
|
||||
|
||||
TrackingService trackingService;
|
||||
boolean trackingServiceBound;
|
||||
|
||||
private final static String TAG = TrackingActivity.class.getName();
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
//Intent intent = getIntent();
|
||||
|
||||
setContentView(R.layout.fragment_container);
|
||||
|
||||
|
||||
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
|
||||
if (toolbar != null) {
|
||||
setSupportActionBar(toolbar);
|
||||
@@ -42,6 +48,30 @@ public class TrackingActivity extends BaseActivity {
|
||||
startTrackingService();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStart() {
|
||||
super.onStart();
|
||||
Intent intent = new Intent(this, TrackingService.class);
|
||||
bindService(intent, trackingServiceConnection, Context.BIND_AUTO_CREATE);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStop() {
|
||||
super.onStop();
|
||||
if (trackingServiceBound) {
|
||||
trackingService.unregisterGPSQualityListener();
|
||||
unbindService(trackingServiceConnection);
|
||||
trackingServiceBound = false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void gpsQualityUpdated(GPSQuality quality) {
|
||||
TrackingFragment trackingFragment = (TrackingFragment) getSupportFragmentManager()
|
||||
.findFragmentById(R.id.content_frame);
|
||||
trackingFragment.setGPSQuality(quality);
|
||||
}
|
||||
|
||||
private void startTrackingService()
|
||||
{
|
||||
Intent intent = new Intent(this, TrackingService.class);
|
||||
@@ -49,6 +79,7 @@ public class TrackingActivity extends BaseActivity {
|
||||
startService(intent);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
TrackingFragment trackingFragment = (TrackingFragment) getSupportFragmentManager()
|
||||
@@ -56,4 +87,23 @@ public class TrackingActivity extends BaseActivity {
|
||||
|
||||
trackingFragment.userTappedBackButton();
|
||||
}
|
||||
|
||||
/** Defines callbacks for service binding, passed to bindService() */
|
||||
private ServiceConnection trackingServiceConnection = new ServiceConnection() {
|
||||
|
||||
@Override
|
||||
public void onServiceConnected(ComponentName className,
|
||||
IBinder service) {
|
||||
// We've bound to LocalService, cast the IBinder and get LocalService instance
|
||||
TrackingBinder binder = (TrackingBinder) service;
|
||||
trackingService = binder.getService();
|
||||
trackingServiceBound = true;
|
||||
trackingService.registerGPSQualityListener(TrackingActivity.this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServiceDisconnected(ComponentName arg0) {
|
||||
trackingServiceBound = false;
|
||||
}
|
||||
};
|
||||
}
|
||||
+17
-30
@@ -160,8 +160,9 @@ public class HomeFragment extends BaseFragment implements
|
||||
|
||||
final String server = scheme + "://" + uri.getHost();
|
||||
final int port = (uri.getPort() == -1) ? 80 : uri.getPort();
|
||||
final String hostWithPort = server + ":" + port;
|
||||
|
||||
prefs.setServerURL(server + ":" + port);
|
||||
prefs.setServerURL(hostWithPort);
|
||||
|
||||
String leaderboardNameFromQR;
|
||||
try {
|
||||
@@ -174,13 +175,9 @@ public class HomeFragment extends BaseFragment implements
|
||||
leaderboardNameFromQR = "";
|
||||
}
|
||||
|
||||
final String competitorId = uri
|
||||
.getQueryParameter(CheckinHelper.COMPETITOR_ID);
|
||||
final String checkinURLStr = prefs.getServerURL()
|
||||
+ prefs.getServerCheckinPath().replace(
|
||||
"{leaderboard-name}", leaderboardNameFromQR);
|
||||
final String eventId = uri
|
||||
.getQueryParameter(CheckinHelper.EVENT_ID);
|
||||
final String competitorId = uri.getQueryParameter(CheckinHelper.COMPETITOR_ID);
|
||||
final String checkinURLStr = prefs.getServerURL() + prefs.getServerCheckinPath().replace("{leaderboard-name}", leaderboardNameFromQR);
|
||||
final String eventId = uri.getQueryParameter(CheckinHelper.EVENT_ID);
|
||||
final String leaderboardName = leaderboardNameFromQR;
|
||||
|
||||
final DeviceIdentifier deviceUuid = new SmartphoneUUIDIdentifierImpl(
|
||||
@@ -193,12 +190,9 @@ public class HomeFragment extends BaseFragment implements
|
||||
// 4. Let user confirm that the information is correct
|
||||
// 5. Checkin
|
||||
|
||||
final String getEventUrl = prefs.getServerURL()
|
||||
+ prefs.getServerEventPath(eventId);
|
||||
final String getLeaderboardUrl = prefs.getServerURL()
|
||||
+ prefs.getServerLeaderboardPath(leaderboardName);
|
||||
final String getCompetitorUrl = prefs.getServerURL()
|
||||
+ prefs.getServerCompetitorPath(competitorId);
|
||||
final String getEventUrl = prefs.getServerURL() + prefs.getServerEventPath(eventId);
|
||||
final String getLeaderboardUrl = prefs.getServerURL() + prefs.getServerLeaderboardPath(leaderboardName);
|
||||
final String getCompetitorUrl = prefs.getServerURL() + prefs.getServerCompetitorPath(competitorId);
|
||||
|
||||
JsonObjectRequest getLeaderboardRequest = new JsonObjectRequest(
|
||||
getLeaderboardUrl, null, new Listener<JSONObject>() {
|
||||
@@ -303,7 +297,8 @@ public class HomeFragment extends BaseFragment implements
|
||||
data.eventStartDateStr = eventStartDateStr;
|
||||
data.eventEndDateStr = eventEndDateStr;
|
||||
data.eventFirstImageUrl = eventFirstImageUrl;
|
||||
data.eventServerUrl = checkinURLStr;
|
||||
data.eventServerUrl = hostWithPort;
|
||||
data.checkinURL = checkinURLStr;
|
||||
data.leaderboardName = leaderboardName;
|
||||
data.deviceUid = deviceUuid
|
||||
.getStringRepresentation();
|
||||
@@ -534,9 +529,9 @@ public class HomeFragment extends BaseFragment implements
|
||||
JSONObject requestObject = CheckinHelper.getCheckinJson(
|
||||
checkinData.competitorId, checkinData.deviceUid, "TODO!!",
|
||||
date.getTime());
|
||||
|
||||
|
||||
JsonObjectRequest checkinRequest = new JsonObjectRequest(
|
||||
checkinData.eventServerUrl, requestObject,
|
||||
checkinData.checkinURL, requestObject,
|
||||
new CheckinListener(checkinData.leaderboardName),
|
||||
new CheckinErrorListener());
|
||||
|
||||
@@ -654,6 +649,7 @@ public class HomeFragment extends BaseFragment implements
|
||||
public String eventEndDateStr;
|
||||
public String eventFirstImageUrl;
|
||||
public String eventServerUrl;
|
||||
public String checkinURL;
|
||||
public String competitorDisplayName;
|
||||
public String competitorId;
|
||||
public String competitorSailId;
|
||||
@@ -687,23 +683,14 @@ public class HomeFragment extends BaseFragment implements
|
||||
|
||||
Cursor cursor = (Cursor) mAdapter.getItem(position - 1); // -1, because there's a header row
|
||||
|
||||
prefs.setServerURL(cursor.getString(cursor
|
||||
.getColumnIndex(Event.EVENT_SERVER)));
|
||||
prefs.setServerURL(cursor.getString(cursor.getColumnIndex(Event.EVENT_SERVER)));
|
||||
|
||||
String competitorId = cursor.getString(cursor.getColumnIndex("competitor_id"));
|
||||
String eventServer = cursor.getString(cursor.getColumnIndex("event_server"));
|
||||
// String competitorId = cursor.getString(cursor.getColumnIndex("competitor_id"));
|
||||
// String eventServer = cursor.getString(cursor.getColumnIndex("event_server"));
|
||||
String leaderboardName = cursor.getString(cursor.getColumnIndex("leaderboard_name"));
|
||||
|
||||
CheckinData data = new CheckinData();
|
||||
|
||||
data.competitorId = competitorId;
|
||||
data.deviceUid = new SmartphoneUUIDIdentifierImpl(
|
||||
UUID.fromString(prefs.getDeviceIdentifier()))
|
||||
.getStringRepresentation();
|
||||
data.eventServerUrl = eventServer;
|
||||
data.leaderboardName = leaderboardName;
|
||||
|
||||
performAPICheckin(data);
|
||||
startRegatta(leaderboardName, leaderboardName);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+58
@@ -1,25 +1,38 @@
|
||||
package com.sap.sailing.android.tracking.app.ui.fragments;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.app.AlertDialog;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.provider.Settings;
|
||||
import android.provider.Settings.SettingNotFoundException;
|
||||
import android.text.TextUtils;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Button;
|
||||
|
||||
import com.sap.sailing.android.shared.logging.ExLog;
|
||||
import com.sap.sailing.android.tracking.app.BuildConfig;
|
||||
import com.sap.sailing.android.tracking.app.R;
|
||||
import com.sap.sailing.android.tracking.app.services.TrackingService;
|
||||
import com.sap.sailing.android.tracking.app.services.TrackingService.GPSQuality;
|
||||
import com.sap.sailing.android.tracking.app.utils.AppPreferences;
|
||||
import com.sap.sailing.android.tracking.app.views.AutoResizeTextView;
|
||||
import com.sap.sailing.android.tracking.app.views.SignalQualityIndicatorView;
|
||||
|
||||
public class TrackingFragment extends BaseFragment implements OnClickListener {
|
||||
|
||||
private TimerRunnable timer;
|
||||
private AppPreferences prefs;
|
||||
private long lastGPSQualityUpdate;
|
||||
|
||||
private String TAG = TrackingFragment.class.getName();
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
@@ -77,6 +90,42 @@ public class TrackingFragment extends BaseFragment implements OnClickListener {
|
||||
textView.setText(getTimeFormatString(diff));
|
||||
}
|
||||
|
||||
/**
|
||||
* If last GPS update is too long ago, let's assume there's no signal and set quality to .noSignal
|
||||
*/
|
||||
public void checkLastGPSReceived()
|
||||
{
|
||||
if (System.currentTimeMillis() - lastGPSQualityUpdate > 3000 && !isLocationEnabled(getActivity()))
|
||||
{
|
||||
if (BuildConfig.DEBUG)
|
||||
{
|
||||
ExLog.i(getActivity(), TAG, "Setting GPS Quality to 0 because timeout occurred and location is reported as disabled.");
|
||||
}
|
||||
setGPSQuality(GPSQuality.noSignal);
|
||||
}
|
||||
}
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.KITKAT)
|
||||
@SuppressWarnings("deprecation")
|
||||
private boolean isLocationEnabled(Context context) {
|
||||
int locationMode = 0;
|
||||
String locationProviders;
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT){
|
||||
try {
|
||||
locationMode = Settings.Secure.getInt(context.getContentResolver(), Settings.Secure.LOCATION_MODE);
|
||||
|
||||
} catch (SettingNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return locationMode != Settings.Secure.LOCATION_MODE_OFF;
|
||||
|
||||
} else {
|
||||
locationProviders = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.LOCATION_PROVIDERS_ALLOWED);
|
||||
return !TextUtils.isEmpty(locationProviders);
|
||||
}
|
||||
}
|
||||
public void userTappedBackButton()
|
||||
{
|
||||
showStopTrackingConfirmationDialog();
|
||||
@@ -114,6 +163,14 @@ public class TrackingFragment extends BaseFragment implements OnClickListener {
|
||||
return String.format(getResources().getConfiguration().locale, "%02d:%02d:%02d", hours, minutes, seconds);
|
||||
}
|
||||
|
||||
public void setGPSQuality( GPSQuality quality )
|
||||
{
|
||||
SignalQualityIndicatorView indicatorView = (SignalQualityIndicatorView) getActivity().findViewById(R.id.qps_quality_indicator);
|
||||
indicatorView.setSignalQuality( quality.toInt() );
|
||||
|
||||
lastGPSQualityUpdate = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
private class TimerRunnable implements Runnable {
|
||||
|
||||
public Thread t;
|
||||
@@ -132,6 +189,7 @@ public class TrackingFragment extends BaseFragment implements OnClickListener {
|
||||
getActivity().runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
checkLastGPSReceived();
|
||||
updateTimer();
|
||||
}
|
||||
});
|
||||
|
||||
Reference in new issue
Block a user