diff --git a/mobile/com.sap.sailing.racecommittee.app/res/drawable-hdpi/ic_change_role_white_48dp.png b/mobile/com.sap.sailing.racecommittee.app/res/drawable-hdpi/ic_change_role_white_48dp.png
deleted file mode 100644
index c29cb246f25..00000000000
Binary files a/mobile/com.sap.sailing.racecommittee.app/res/drawable-hdpi/ic_change_role_white_48dp.png and /dev/null differ
diff --git a/mobile/com.sap.sailing.racecommittee.app/res/drawable-mdpi/ic_change_role_white_48dp.png b/mobile/com.sap.sailing.racecommittee.app/res/drawable-mdpi/ic_change_role_white_48dp.png
deleted file mode 100644
index e966f5104b8..00000000000
Binary files a/mobile/com.sap.sailing.racecommittee.app/res/drawable-mdpi/ic_change_role_white_48dp.png and /dev/null differ
diff --git a/mobile/com.sap.sailing.racecommittee.app/res/drawable-xhdpi/ic_change_role_white_48dp.png b/mobile/com.sap.sailing.racecommittee.app/res/drawable-xhdpi/ic_change_role_white_48dp.png
deleted file mode 100644
index b811a20b301..00000000000
Binary files a/mobile/com.sap.sailing.racecommittee.app/res/drawable-xhdpi/ic_change_role_white_48dp.png and /dev/null differ
diff --git a/mobile/com.sap.sailing.racecommittee.app/res/drawable-xxhdpi/ic_change_role_white_48dp.png b/mobile/com.sap.sailing.racecommittee.app/res/drawable-xxhdpi/ic_change_role_white_48dp.png
deleted file mode 100644
index 02076b894fb..00000000000
Binary files a/mobile/com.sap.sailing.racecommittee.app/res/drawable-xxhdpi/ic_change_role_white_48dp.png and /dev/null differ
diff --git a/mobile/com.sap.sailing.racecommittee.app/res/drawable-xxxhdpi/ic_change_role_white_48dp.png b/mobile/com.sap.sailing.racecommittee.app/res/drawable-xxxhdpi/ic_change_role_white_48dp.png
deleted file mode 100644
index e4cf3914bd9..00000000000
Binary files a/mobile/com.sap.sailing.racecommittee.app/res/drawable-xxxhdpi/ic_change_role_white_48dp.png and /dev/null differ
diff --git a/mobile/com.sap.sailing.racecommittee.app/res/layout/race_list_header_content.xml b/mobile/com.sap.sailing.racecommittee.app/res/layout/race_list_header_content.xml
index 88b2d17c939..b77bf67bbb8 100644
--- a/mobile/com.sap.sailing.racecommittee.app/res/layout/race_list_header_content.xml
+++ b/mobile/com.sap.sailing.racecommittee.app/res/layout/race_list_header_content.xml
@@ -26,7 +26,7 @@
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_margin="@dimen/default_margin"
- android:src="@drawable/ic_change_role_white_48dp"/>
+ android:src="@drawable/ic_refresh_white_48dp"/>
+ android:title="@string/reset_race" />
+ android:title="@string/options_menu_settings" />
+ android:title="@string/options_menu_info" />
+
+
+ android:title="@string/logout" />
\ No newline at end of file
diff --git a/mobile/com.sap.sailing.racecommittee.app/res/values-de/strings.xml b/mobile/com.sap.sailing.racecommittee.app/res/values-de/strings.xml
index 53d90b8bf10..7ccaf9b8572 100644
--- a/mobile/com.sap.sailing.racecommittee.app/res/values-de/strings.xml
+++ b/mobile/com.sap.sailing.racecommittee.app/res/values-de/strings.xml
@@ -500,6 +500,7 @@
Zeige nicht öffentliche Events
Lade alle Events, auch die nicht öffentlichen.
+ Rolle wechseln
Konfiguration vom Server laden
Rennen abbrechen
diff --git a/mobile/com.sap.sailing.racecommittee.app/res/values/strings.xml b/mobile/com.sap.sailing.racecommittee.app/res/values/strings.xml
index 65eaf5d2b3f..448dedfeab0 100644
--- a/mobile/com.sap.sailing.racecommittee.app/res/values/strings.xml
+++ b/mobile/com.sap.sailing.racecommittee.app/res/values/strings.xml
@@ -528,6 +528,7 @@
Show Non Public Events
Load all events including the no public one.
+ Change Regatta
Reload Configuration from Server
Abort Races
diff --git a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/AppConstants.java b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/AppConstants.java
index 8c5cd7fd0b7..0845520c5ab 100755
--- a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/AppConstants.java
+++ b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/AppConstants.java
@@ -22,11 +22,15 @@ public class AppConstants {
public final static String DARK_THEME = "dark";
public final static String LIGHT_THEME = "light";
- public final static String INTENT_ACTION_RESET = PACKAGE_NAME + ".action.reset";
- public final static String INTENT_ACTION_REGISTER_RACE = PACKAGE_NAME + ".action.registerRace";
- public final static String INTENT_ACTION_CLEAR_RACES = PACKAGE_NAME + ".action.clearRaces";
- public final static String INTENT_ACTION_ALARM_ACTION = PACKAGE_NAME + ".action.alarmAction";
- public final static String INTENT_ACTION_START_PROCEDURE_SPECIFIC_ACTION = PACKAGE_NAME + ".action.startProcedureSpecificAction";
+ private final static String INTENT_ACTION = PACKAGE_NAME + ".action";
+ public final static String INTENT_ACTION_RESET = INTENT_ACTION + ".reset";
+ public final static String INTENT_ACTION_REGISTER_RACE = INTENT_ACTION + ".registerRace";
+ public final static String INTENT_ACTION_UNREGISTER_RACE = INTENT_ACTION + ".unregisterRace";
+ public final static String INTENT_ACTION_CLEAR_RACES = INTENT_ACTION + ".clearRaces";
+ public final static String INTENT_ACTION_CLEANUP_RACES = INTENT_ACTION + ".cleanupRaces";
+ public final static String INTENT_ACTION_ALARM_ACTION = INTENT_ACTION + ".alarmAction";
+ public final static String INTENT_ACTION_RELOAD_RACES = INTENT_ACTION + ".reloadRaces";
+ public final static String INTENT_ACTION_START_PROCEDURE_SPECIFIC_ACTION = INTENT_ACTION + ".startProcedureSpecificAction";
// Login activity
public final static String EventIdTag = "EventId";
@@ -66,6 +70,7 @@ public class AppConstants {
public final static String INTENT_ACTION_SHOW_ONBOARDING = "show_onboarding";
public final static String INTENT_ACTION_SHOW_LOGIN = "show_login";
public final static String INTENT_ACTION_VALID_DATA = "valid_data";
+ public final static String INTENT_ACTION_SHOW_WELCOME = "show_welcome";
// clears all toggle buttons
public final static String INTENT_ACTION_CLEAR_TOGGLE = PACKAGE_NAME + ".action.toggle.clear";
diff --git a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/DataManager.java b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/DataManager.java
index 37d61f22fb4..86500daef9c 100644
--- a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/DataManager.java
+++ b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/DataManager.java
@@ -63,4 +63,9 @@ public abstract class DataManager implements ReadonlyDataManager {
context.startService(intent);
}
+
+ public void stopService() {
+ Intent intent = new Intent(context, RaceStateService.class);
+ context.stopService(intent);
+ }
}
diff --git a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/DataStore.java b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/DataStore.java
index c7f5875aabc..f980b97c709 100644
--- a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/DataStore.java
+++ b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/DataStore.java
@@ -32,10 +32,12 @@ public interface DataStore {
Collection getRaces();
void addRace(ManagedRace race);
- public ManagedRace getRace(String id);
- public ManagedRace getRace(SimpleRaceLogIdentifier id);
- public boolean hasRace(String id);
- public boolean hasRace(SimpleRaceLogIdentifier id);
+ void addRace(int index, ManagedRace race);
+ void removeRace(ManagedRace race);
+ ManagedRace getRace(String id);
+ ManagedRace getRace(SimpleRaceLogIdentifier id);
+ boolean hasRace(String id);
+ boolean hasRace(SimpleRaceLogIdentifier id);
Collection getMarks();
Mark getMark(Serializable id);
diff --git a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/InMemoryDataStore.java b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/InMemoryDataStore.java
index 5f74ce4e0c2..8f6c9244c5b 100644
--- a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/InMemoryDataStore.java
+++ b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/InMemoryDataStore.java
@@ -4,6 +4,7 @@ import java.io.Serializable;
import java.util.Collection;
import java.util.HashSet;
import java.util.LinkedHashMap;
+import java.util.Map;
import java.util.Set;
import java.util.UUID;
@@ -61,18 +62,22 @@ public enum InMemoryDataStore implements DataStore {
* * * * * *
*/
+ @Override
public Collection getEvents() {
return eventsById.values();
}
-
+
+ @Override
public void addEvent(EventBase event) {
eventsById.put(event.getId(), event);
}
+ @Override
public EventBase getEvent(Serializable id) {
return eventsById.get(id);
}
+ @Override
public boolean hasEvent(Serializable id) {
return eventsById.containsKey(id);
}
@@ -83,6 +88,7 @@ public enum InMemoryDataStore implements DataStore {
* * * * * * * *
*/
+ @Override
public Collection getCourseAreas(EventBase event) {
if (event.getVenue() != null) {
return CollectionUtils.newArrayList(event.getVenue().getCourseAreas());
@@ -102,6 +108,7 @@ public enum InMemoryDataStore implements DataStore {
return null;
}
+ @Override
public CourseArea getCourseArea(Serializable id) {
for (EventBase event : eventsById.values()) {
for (CourseArea courseArea : getCourseAreas(event)) {
@@ -113,6 +120,7 @@ public enum InMemoryDataStore implements DataStore {
return null;
}
+ @Override
public boolean hasCourseArea(Serializable id) {
for (EventBase event : eventsById.values()) {
for (CourseArea courseArea : getCourseAreas(event)) {
@@ -124,6 +132,7 @@ public enum InMemoryDataStore implements DataStore {
return false;
}
+ @Override
public void addCourseArea(EventBase event, CourseArea courseArea) {
if (event.getVenue() != null) {
event.getVenue().addCourseArea(courseArea);
@@ -136,14 +145,49 @@ public enum InMemoryDataStore implements DataStore {
* * * * * * * *
*/
+ @Override
public Collection getRaces() {
return managedRaceById.values();
}
+ @Override
public void addRace(ManagedRace race) {
managedRaceById.put(convertManagedRaceIdentifierToSimpleRaceLogIdentifier(race.getIdentifier()), race);
}
+ @Override
+ public void addRace(int index, ManagedRace race) {
+ if (index >= 0 && index <= managedRaceById.size()) {
+ LinkedHashMap output = new LinkedHashMap<>();
+ int i = 0;
+ if (index == 0) {
+ output.put(convertManagedRaceIdentifierToSimpleRaceLogIdentifier(race.getIdentifier()), race);
+ output.putAll(managedRaceById);
+ } else {
+ for (Map.Entry entry : managedRaceById.entrySet()) {
+ if (i == index) {
+ output.put(convertManagedRaceIdentifierToSimpleRaceLogIdentifier(race.getIdentifier()), race);
+ }
+ output.put(entry.getKey(), entry.getValue());
+ i++;
+ }
+ }
+ if (index == managedRaceById.size()) {
+ output.put(convertManagedRaceIdentifierToSimpleRaceLogIdentifier(race.getIdentifier()), race);
+ }
+ managedRaceById.clear();
+ managedRaceById.putAll(output);
+ output.clear();
+ } else {
+ throw new IndexOutOfBoundsException("index " + index + " must be greater than zero and less than size of the map");
+ }
+ }
+
+ @Override
+ public void removeRace(ManagedRace race) {
+ managedRaceById.remove(convertManagedRaceIdentifierToSimpleRaceLogIdentifier(race.getIdentifier()));
+ }
+
private SimpleRaceLogIdentifier convertManagedRaceIdentifierToSimpleRaceLogIdentifier(ManagedRaceIdentifier id) {
return new SimpleRaceLogIdentifierImpl(id.getRaceGroup().getName(), id.getRaceName(), id.getFleet().getName());
}
@@ -165,19 +209,17 @@ public enum InMemoryDataStore implements DataStore {
/**
* Parses a serialized version of a ManagedRaceIdentifier and creates a SimpleRaceLogIdentifier
- * this is needed as the serialized version is passed around in the bundle context, but the
- * InMemoryDataStore now has to use SimpleRaceLogIdentifier as key in the managedRaces HashMap in
- * order to allow for retrieving a managed race with exclusively the information provided by a
+ * this is needed as the serialized version is passed around in the bundle context, but the
+ * InMemoryDataStore now has to use SimpleRaceLogIdentifier as key in the managedRaces HashMap in
+ * order to allow for retrieving a managed race with exclusively the information provided by a
* SimpleRaceLogIdentifier (which is less than the information provided by a ManagedRaceIdentifier)
- *
- * @param escapedId
- * serialized version of a ManagedRaceIdentifier
- * @return
- * corresponding SimpleRaceLogIdentifier
+ *
+ * @param escapedId serialized version of a ManagedRaceIdentifier
+ * @return corresponding SimpleRaceLogIdentifier
*/
public SimpleRaceLogIdentifier parseManagedRaceLogIdentifier(final String escapedId) {
//Undo escaping
- final Triple id = FleetIdentifierImpl.unescape(escapedId);
+ final Triple id = FleetIdentifierImpl.unescape(escapedId);
return new SimpleRaceLogIdentifierImpl(id.getA(), id.getB(), id.getC());
}
@@ -230,7 +272,7 @@ public enum InMemoryDataStore implements DataStore {
}
return raceGroups;
}
-
+
@Override
public RaceGroup getRaceGroup(String name) {
for (RaceGroup group : getRaceGroups()) {
diff --git a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/OnlineDataManager.java b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/OnlineDataManager.java
index 1971c145688..d0f9f44a117 100644
--- a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/OnlineDataManager.java
+++ b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/OnlineDataManager.java
@@ -96,8 +96,9 @@ public class OnlineDataManager extends DataManager {
}
public void addRaces(Collection data) {
+ int index = 0;
for (ManagedRace race : data) {
- dataStore.addRace(race);
+ dataStore.addRace(index++, race);
}
}
@@ -110,12 +111,11 @@ public class OnlineDataManager extends DataManager {
@Override
public LoaderCallbacks>> createEventsLoader(
LoadClient> callback) {
- return new DataLoaderCallbacks>(callback, new LoaderCreator>() {
+ return new DataLoaderCallbacks<>(callback, new LoaderCreator>() {
@Override
public Loader>> create(int id, Bundle args) throws Exception {
ExLog.i(context, TAG, String.format("Creating Events-OnlineDataLoader %d", id));
- EventBaseJsonDeserializer serializer = new EventBaseJsonDeserializer(new VenueJsonDeserializer(
- new CourseAreaJsonDeserializer(domainFactory)), new LeaderboardGroupBaseJsonDeserializer());
+ EventBaseJsonDeserializer serializer = new EventBaseJsonDeserializer(new VenueJsonDeserializer(new CourseAreaJsonDeserializer(domainFactory)), new LeaderboardGroupBaseJsonDeserializer());
DataParser> parser = new EventsDataParser(serializer);
DataHandler> handler = new EventsDataHandler(OnlineDataManager.this);
@@ -123,8 +123,7 @@ public class OnlineDataManager extends DataManager {
List> params = new ArrayList<>();
params.add(new Util.Pair("showNonPublic", AppPreferences.on(context).showNonPublic()));
URL url = UrlHelper.generateUrl(preferences.getServerBaseURL(), "/sailingserver/api/v1/events", params);
- return new OnlineDataLoader>(context,
- url, parser, handler);
+ return new OnlineDataLoader>(context, url, parser, handler);
}
}, getContext());
}
diff --git a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/handlers/ManagedRacesDataHandler.java b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/handlers/ManagedRacesDataHandler.java
index 6be6e8cee77..cfb83fa2889 100644
--- a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/handlers/ManagedRacesDataHandler.java
+++ b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/data/handlers/ManagedRacesDataHandler.java
@@ -27,6 +27,15 @@ public class ManagedRacesDataHandler extends DataHandler
@Override
public void onResult(Collection data) {
+ Set deleteList = new HashSet<>();
+ for (ManagedRace race : manager.getDataStore().getRaces()) {
+ if (!data.contains(race)) {
+ deleteList.add(new DeleteFromDataStore(manager, race));
+ }
+ }
+ for (DeleteFromDataStore action : deleteList) {
+ action.run();
+ }
manager.addRaces(data);
calcRaceState(data);
}
@@ -54,4 +63,20 @@ public class ManagedRacesDataHandler extends DataHandler
raceStatesWithUnresolvedStartTimes.removeAll(resolved);
} while (oldNumberOfRaceStatesWithUnresolvedStartTimes != raceStatesWithUnresolvedStartTimes.size());
}
+
+ private static class DeleteFromDataStore implements Runnable {
+
+ private final OnlineDataManager mManager;
+ private final ManagedRace mRace;
+
+ public DeleteFromDataStore(OnlineDataManager manager, ManagedRace race) {
+ mManager = manager;
+ mRace = race;
+ }
+
+ @Override
+ public void run() {
+ mManager.getDataStore().removeRace(mRace);
+ }
+ }
}
diff --git a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/services/RaceStateService.java b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/services/RaceStateService.java
index 0baed8f581e..d67e5690f11 100755
--- a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/services/RaceStateService.java
+++ b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/services/RaceStateService.java
@@ -3,9 +3,11 @@ package com.sap.sailing.racecommittee.app.services;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
+import java.util.Set;
import java.util.UUID;
import android.annotation.TargetApi;
@@ -19,6 +21,7 @@ import android.graphics.BitmapFactory;
import android.os.Binder;
import android.os.Build;
import android.os.IBinder;
+import android.support.annotation.NonNull;
import android.support.v4.app.NotificationCompat;
import android.util.Pair;
@@ -74,7 +77,7 @@ public class RaceStateService extends Service {
private Map registeredLogListeners;
private Map registeredStateEventSchedulers;
- private Map>> managedIntents;
+ private Map>> managedIntents;
private NotificationManager notificationManager;
private NotificationCompat.Builder notificationBuilder;
@@ -146,10 +149,12 @@ public class RaceStateService extends Service {
for (Entry entry : registeredLogListeners.entrySet()) {
entry.getKey().getState().getRaceLog().removeListener(entry.getValue());
}
+ registeredLogListeners.clear();
for (Entry entry : registeredStateEventSchedulers.entrySet()) {
entry.getKey().getState().setStateEventScheduler(null);
}
+ registeredStateEventSchedulers.clear();
for (List> intents : managedIntents.values()) {
for (Pair intentPair : intents) {
@@ -161,12 +166,35 @@ public class RaceStateService extends Service {
ExLog.i(this, TAG, "All races unregistered.");
}
+ private void unregisterRace(ManagedRace race) {
+ poller.unregister(race);
+
+ race.getState().getRaceLog().removeAllListeners();
+ registeredLogListeners.remove(race);
+
+ race.getState().setStateEventScheduler(null);
+ registeredStateEventSchedulers.remove(race);
+
+ List> intents = managedIntents.get(race.getId());
+ for (Pair intentPair : intents) {
+ alarmManager.cancel(intentPair.first);
+ }
+ managedIntents.remove(race.getId());
+
+ ExLog.i(this, TAG, "Race " + race.getId() + " unregistered");
+ }
+
private void handleStartCommand(Intent intent) {
String action = intent.getAction();
ExLog.i(this, TAG, String.format("Command action '%s' received.", action));
if (AppConstants.INTENT_ACTION_CLEAR_RACES.equals(action)) {
- handleClearRaces(intent);
+ handleClearRaces();
+ return;
+ }
+
+ if (AppConstants.INTENT_ACTION_CLEANUP_RACES.equals(action)) {
+ handleCleanupRaces();
return;
}
@@ -175,6 +203,11 @@ public class RaceStateService extends Service {
return;
}
+ if (AppConstants.INTENT_ACTION_UNREGISTER_RACE.equals(action)) {
+ handleUnregisterRace(intent);
+ return;
+ }
+
if (!serviceId.equals(intent.getSerializableExtra(EXTRAS_SERVICE_ID))) {
ExLog.w(this, TAG, "Received event for different service version.");
return;
@@ -196,7 +229,7 @@ public class RaceStateService extends Service {
}
}
- private void handleClearRaces(Intent intent) {
+ private void handleClearRaces() {
unregisterAllRaces();
DataStore dataStore = dataManager.getDataStore();
dataStore.getRaces().clear();
@@ -206,6 +239,46 @@ public class RaceStateService extends Service {
stopForeground(true);
}
+ private class RemoveRaceAction implements Runnable {
+
+ private final ManagedRace managedRace;
+
+ public RemoveRaceAction(@NonNull ManagedRace race) {
+ managedRace = race;
+ }
+
+ @Override
+ public void run() {
+ unregisterRace(managedRace);
+ }
+ }
+
+ private void handleCleanupRaces() {
+ Set actions = new HashSet<>();
+ for (String raceId : managedIntents.keySet()) {
+ if (!inDataStore(raceId)) {
+ for (ManagedRace race : registeredLogListeners.keySet()) {
+ if (race.getId().equals(raceId)) {
+ actions.add(new RemoveRaceAction(race));
+ }
+ }
+ }
+ }
+ for (RemoveRaceAction action : actions) {
+ action.run();
+ }
+ updateNotification();
+ }
+
+ private boolean inDataStore(String raceId) {
+ for (ManagedRace race : dataManager.getDataStore().getRaces()) {
+ if (race.getId().equals(raceId)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
private void handleRegisterRace(Intent intent) {
ManagedRace race = getRaceFromIntent(intent);
if (race == null) {
@@ -214,6 +287,21 @@ public class RaceStateService extends Service {
}
registerRace(race);
+ updateNotification();
+ }
+
+ private void handleUnregisterRace(Intent intent) {
+ ManagedRace race = getRaceFromIntent(intent);
+ if (race == null) {
+ ExLog.w(this, TAG, "Intent did not carry valid race information");
+ return;
+ }
+ unregisterRace(race);
+
+ updateNotification();
+ }
+
+ private void updateNotification() {
int numRaces = managedIntents.keySet().size();
notificationManager.notify(NOTIFICATION_ID, notificationBuilder
.setContentText(getString(R.string.service_text_num_races, numRaces))
diff --git a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/services/polling/RaceLogPoller.java b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/services/polling/RaceLogPoller.java
index 43443f842ab..3a2f458ed9b 100644
--- a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/services/polling/RaceLogPoller.java
+++ b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/services/polling/RaceLogPoller.java
@@ -49,7 +49,7 @@ public class RaceLogPoller implements PollingActiveChangedListener {
// We want to use the main (UI) loop
this.pollingHandler = new Handler(Looper.getMainLooper());
this.pollingWorker = new PollingWorker(this, context);
- this.races = new HashMap();
+ this.races = new HashMap<>();
this.appPreferences = AppPreferences.on(context);
this.appPreferences.registerPollingActiveChangedListener(this);
this.hasRacesToPoll = false;
@@ -70,6 +70,10 @@ public class RaceLogPoller implements PollingActiveChangedListener {
}
}
+ public void unregister(ManagedRace race) {
+ races.remove(race);
+ }
+
private URL createURL(ManagedRace race) throws MalformedURLException, UnsupportedEncodingException {
return new URL(MessageSendingService.getRaceLogEventSendAndReceiveUrl(context, race.getRaceGroup().getName(),
race.getName(), race.getFleet().getName()));
diff --git a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/activities/RacingActivity.java b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/activities/RacingActivity.java
index aaa4d68f19a..d5edaf27b80 100644
--- a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/activities/RacingActivity.java
+++ b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/activities/RacingActivity.java
@@ -14,6 +14,7 @@ import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
+import android.content.Loader;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
@@ -23,7 +24,6 @@ import android.support.annotation.IdRes;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.content.LocalBroadcastManager;
-import android.support.v4.view.ViewCompat;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.AlertDialog;
import android.support.v7.internal.widget.TintImageView;
@@ -38,9 +38,11 @@ import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.Toast;
+
import com.sap.sailing.android.shared.logging.ExLog;
import com.sap.sailing.android.shared.util.AppUtils;
import com.sap.sailing.android.shared.util.BitmapHelper;
+import com.sap.sailing.android.shared.util.BroadcastManager;
import com.sap.sailing.android.shared.util.CollectionUtils;
import com.sap.sailing.android.shared.util.ViewHelper;
import com.sap.sailing.domain.abstractlog.race.SimpleRaceLogIdentifier;
@@ -55,6 +57,7 @@ import com.sap.sailing.racecommittee.app.data.DataManager;
import com.sap.sailing.racecommittee.app.data.DataStore;
import com.sap.sailing.racecommittee.app.data.ReadonlyDataManager;
import com.sap.sailing.racecommittee.app.data.clients.LoadClient;
+import com.sap.sailing.racecommittee.app.data.loaders.DataLoaderResult;
import com.sap.sailing.racecommittee.app.domain.ManagedRace;
import com.sap.sailing.racecommittee.app.domain.impl.RaceGroupSeriesFleet;
import com.sap.sailing.racecommittee.app.logging.LogEvent;
@@ -93,6 +96,7 @@ public class RacingActivity extends SessionActivity implements RaceListCallbacks
private RaceListFragment mRaceList;
private ManagedRace mSelectedRace;
private TimePoint startTime;
+ private Loader>> raceLoader;
private Collection lastSeenRaces = null;
private Serializable getCourseAreaIdFromIntent() {
@@ -126,7 +130,11 @@ public class RacingActivity extends SessionActivity implements RaceListCallbacks
setProgressSpinnerVisibility(true);
ExLog.i(this, TAG, "Issuing loading of managed races from data manager");
- getLoaderManager().initLoader(RacesLoaderId, null, dataManager.createRacesLoader(courseArea.getId(), new RaceLoadClient(courseArea)));
+ if (raceLoader == null) {
+ raceLoader = getLoaderManager().initLoader(RacesLoaderId, null, dataManager.createRacesLoader(courseArea.getId(), new RaceLoadClient(courseArea)));
+ } else {
+ raceLoader.forceLoad();
+ }
}
private boolean resetEditFragments(@IdRes int id, String action) {
@@ -253,7 +261,9 @@ public class RacingActivity extends SessionActivity implements RaceListCallbacks
IntentFilter filter = new IntentFilter();
filter.addAction(AppConstants.INTENT_ACTION_SHOW_MAIN_CONTENT);
filter.addAction(AppConstants.INTENT_ACTION_SHOW_SUMMARY_CONTENT);
+ filter.addAction(AppConstants.INTENT_ACTION_SHOW_WELCOME);
filter.addAction(AppConstants.INTENT_ACTION_REMOVE_PROTEST);
+ filter.addAction(AppConstants.INTENT_ACTION_RELOAD_RACES);
LocalBroadcastManager.getInstance(this).registerReceiver(mReceiver, filter);
}
@@ -350,6 +360,10 @@ public class RacingActivity extends SessionActivity implements RaceListCallbacks
resetRace();
return true;
+ case R.id.options_menu_role:
+ logoutSession();
+ return true;
+
default:
return super.onOptionsItemSelected(item);
}
@@ -383,18 +397,29 @@ public class RacingActivity extends SessionActivity implements RaceListCallbacks
}
private void registerOnService(final Collection races) {
+ // close current race, if no longer on server
+ if (!races.contains(mSelectedRace)) {
+ BroadcastManager.getInstance(this).addIntent(new Intent(AppConstants.INTENT_ACTION_SHOW_WELCOME));
+ mSelectedRace = null;
+ }
+
// since the service is the long-living component
// he should decide whether these races are already
// registered or not.
new Thread(new Runnable() {
@Override
public void run() {
+ // add all received races to the service
for (ManagedRace race : races) {
Intent registerIntent = new Intent(RacingActivity.this, RaceStateService.class);
registerIntent.setAction(AppConstants.INTENT_ACTION_REGISTER_RACE);
registerIntent.putExtra(AppConstants.RACE_ID_KEY, race.getId());
RacingActivity.this.startService(registerIntent);
}
+
+ Intent cleanupIntent = new Intent(RacingActivity.this, RaceStateService.class);
+ cleanupIntent.setAction(AppConstants.INTENT_ACTION_CLEANUP_RACES);
+ RacingActivity.this.startService(cleanupIntent);
}
}).start();
}
@@ -610,6 +635,14 @@ public class RacingActivity extends SessionActivity implements RaceListCallbacks
transaction.remove(extra);
}
}
+ }
+
+ if (AppConstants.INTENT_ACTION_SHOW_WELCOME.equals(action)) {
+ loadWelcomeFragment();
+ }
+
+ if (AppConstants.INTENT_ACTION_RELOAD_RACES.equals(action)) {
+ loadRaces(dataManager.getDataStore().getCourseArea(getCourseAreaIdFromIntent()));
}
transaction.commit();
diff --git a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/fragments/RaceListFragment.java b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/fragments/RaceListFragment.java
index 1c781517c0e..203f571fbd9 100644
--- a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/fragments/RaceListFragment.java
+++ b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/fragments/RaceListFragment.java
@@ -56,7 +56,6 @@ import com.sap.sailing.racecommittee.app.data.DataManager;
import com.sap.sailing.racecommittee.app.data.ReadonlyDataManager;
import com.sap.sailing.racecommittee.app.domain.ManagedRace;
import com.sap.sailing.racecommittee.app.domain.impl.RaceGroupSeriesFleet;
-import com.sap.sailing.racecommittee.app.ui.activities.RacingActivity;
import com.sap.sailing.racecommittee.app.ui.activities.SessionActivity;
import com.sap.sailing.racecommittee.app.ui.adapters.racelist.ManagedRaceListAdapter;
import com.sap.sailing.racecommittee.app.ui.adapters.racelist.RaceListDataType;
@@ -270,7 +269,7 @@ public class RaceListFragment extends LoggableFragment implements OnItemClickLis
@Override
public void onClick(View v) {
- ((RacingActivity) getActivity()).logoutSession();
+ BroadcastManager.getInstance(getActivity()).addIntent(new Intent(AppConstants.INTENT_ACTION_RELOAD_RACES));
}
});
}