diff --git a/mobile/com.sap.sailing.android.tracking.app.test-test/.classpath b/mobile/com.sap.sailing.android.tracking.app.test-test/.classpath
new file mode 100644
index 00000000000..f895a38f5f3
--- /dev/null
+++ b/mobile/com.sap.sailing.android.tracking.app.test-test/.classpath
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/mobile/com.sap.sailing.android.tracking.app.test-test/.project b/mobile/com.sap.sailing.android.tracking.app.test-test/.project
new file mode 100644
index 00000000000..fb93d637769
--- /dev/null
+++ b/mobile/com.sap.sailing.android.tracking.app.test-test/.project
@@ -0,0 +1,34 @@
+
+
+ com.sap.sailing.android.tracking.app.test
+
+
+ com.sap.sailing.android.tracking.app
+
+
+
+ com.android.ide.eclipse.adt.ResourceManagerBuilder
+
+
+
+
+ com.android.ide.eclipse.adt.PreCompilerBuilder
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+ com.android.ide.eclipse.adt.ApkBuilder
+
+
+
+
+
+ com.android.ide.eclipse.adt.AndroidNature
+ org.eclipse.jdt.core.javanature
+
+
diff --git a/mobile/com.sap.sailing.android.tracking.app.test-test/.settings/org.eclipse.jdt.core.prefs b/mobile/com.sap.sailing.android.tracking.app.test-test/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 00000000000..b080d2ddc88
--- /dev/null
+++ b/mobile/com.sap.sailing.android.tracking.app.test-test/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,4 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
+org.eclipse.jdt.core.compiler.compliance=1.6
+org.eclipse.jdt.core.compiler.source=1.6
diff --git a/mobile/com.sap.sailing.android.tracking.app.test-test/AndroidManifest.xml b/mobile/com.sap.sailing.android.tracking.app.test-test/AndroidManifest.xml
new file mode 100644
index 00000000000..fd69f4b8347
--- /dev/null
+++ b/mobile/com.sap.sailing.android.tracking.app.test-test/AndroidManifest.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/mobile/com.sap.sailing.android.tracking.app.test-test/bin/AndroidManifest.xml b/mobile/com.sap.sailing.android.tracking.app.test-test/bin/AndroidManifest.xml
new file mode 100644
index 00000000000..fd69f4b8347
--- /dev/null
+++ b/mobile/com.sap.sailing.android.tracking.app.test-test/bin/AndroidManifest.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/mobile/com.sap.sailing.android.tracking.app.test-test/gen/.gitignore b/mobile/com.sap.sailing.android.tracking.app.test-test/gen/.gitignore
new file mode 100644
index 00000000000..c2d9872a163
--- /dev/null
+++ b/mobile/com.sap.sailing.android.tracking.app.test-test/gen/.gitignore
@@ -0,0 +1 @@
+/com/
diff --git a/mobile/com.sap.sailing.android.tracking.app.test-test/proguard-project.txt b/mobile/com.sap.sailing.android.tracking.app.test-test/proguard-project.txt
new file mode 100644
index 00000000000..f2fe1559a21
--- /dev/null
+++ b/mobile/com.sap.sailing.android.tracking.app.test-test/proguard-project.txt
@@ -0,0 +1,20 @@
+# To enable ProGuard in your project, edit project.properties
+# to define the proguard.config property as described in that file.
+#
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in ${sdk.dir}/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the ProGuard
+# include property in project.properties.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
diff --git a/mobile/com.sap.sailing.android.tracking.app.test-test/project.properties b/mobile/com.sap.sailing.android.tracking.app.test-test/project.properties
new file mode 100644
index 00000000000..6e18427a424
--- /dev/null
+++ b/mobile/com.sap.sailing.android.tracking.app.test-test/project.properties
@@ -0,0 +1,14 @@
+# This file is automatically generated by Android Tools.
+# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
+#
+# This file must be checked in Version Control Systems.
+#
+# To customize properties used by the Ant build system edit
+# "ant.properties", and override values to adapt the script to your
+# project structure.
+#
+# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
+#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
+
+# Project target.
+target=android-21
diff --git a/mobile/com.sap.sailing.android.tracking.app.test-test/res/drawable-hdpi/ic_launcher.png b/mobile/com.sap.sailing.android.tracking.app.test-test/res/drawable-hdpi/ic_launcher.png
new file mode 100644
index 00000000000..96a442e5b8e
Binary files /dev/null and b/mobile/com.sap.sailing.android.tracking.app.test-test/res/drawable-hdpi/ic_launcher.png differ
diff --git a/mobile/com.sap.sailing.android.tracking.app.test-test/res/drawable-ldpi/ic_launcher.png b/mobile/com.sap.sailing.android.tracking.app.test-test/res/drawable-ldpi/ic_launcher.png
new file mode 100644
index 00000000000..99238729d87
Binary files /dev/null and b/mobile/com.sap.sailing.android.tracking.app.test-test/res/drawable-ldpi/ic_launcher.png differ
diff --git a/mobile/com.sap.sailing.android.tracking.app.test-test/res/drawable-mdpi/ic_launcher.png b/mobile/com.sap.sailing.android.tracking.app.test-test/res/drawable-mdpi/ic_launcher.png
new file mode 100644
index 00000000000..359047dfa4e
Binary files /dev/null and b/mobile/com.sap.sailing.android.tracking.app.test-test/res/drawable-mdpi/ic_launcher.png differ
diff --git a/mobile/com.sap.sailing.android.tracking.app.test-test/res/drawable-xhdpi/ic_launcher.png b/mobile/com.sap.sailing.android.tracking.app.test-test/res/drawable-xhdpi/ic_launcher.png
new file mode 100644
index 00000000000..71c6d760f05
Binary files /dev/null and b/mobile/com.sap.sailing.android.tracking.app.test-test/res/drawable-xhdpi/ic_launcher.png differ
diff --git a/mobile/com.sap.sailing.android.tracking.app.test-test/res/values/strings.xml b/mobile/com.sap.sailing.android.tracking.app.test-test/res/values/strings.xml
new file mode 100644
index 00000000000..8c405e56633
--- /dev/null
+++ b/mobile/com.sap.sailing.android.tracking.app.test-test/res/values/strings.xml
@@ -0,0 +1,6 @@
+
+
+
+ Com.sap.sailing.android.tracking.app.testTest
+
+
diff --git a/mobile/com.sap.sailing.android.tracking.app.test-test/src/com/sap/sailing/android/tracking/app/test/ActivityUnitTestCase.java b/mobile/com.sap.sailing.android.tracking.app.test-test/src/com/sap/sailing/android/tracking/app/test/ActivityUnitTestCase.java
new file mode 100644
index 00000000000..ec40cee60cf
--- /dev/null
+++ b/mobile/com.sap.sailing.android.tracking.app.test-test/src/com/sap/sailing/android/tracking/app/test/ActivityUnitTestCase.java
@@ -0,0 +1,343 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.sap.sailing.android.tracking.app.test;
+
+import android.app.Activity;
+import android.app.Application;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ActivityInfo;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.test.ActivityInstrumentationTestCase;
+import android.test.ActivityTestCase;
+import android.test.mock.MockApplication;
+import android.view.Window;
+
+/**
+ * This class provides isolated testing of a single activity. The activity under test will
+ * be created with minimal connection to the system infrastructure, and you can inject mocked or
+ * wrappered versions of many of Activity's dependencies. Most of the work is handled
+ * automatically here by {@link #setUp} and {@link #tearDown}.
+ *
+ *
If you prefer a functional test, see {@link android.test.ActivityInstrumentationTestCase}.
+ *
+ *
It must be noted that, as a true unit test, your Activity will not be running in the
+ * normal system and will not participate in the normal interactions with other Activities.
+ * The following methods should not be called in this configuration - most of them will throw
+ * exceptions:
+ *
+ * {@link android.app.Activity#createPendingResult(int, Intent, int)}
+ * {@link android.app.Activity#startActivityIfNeeded(Intent, int)}
+ * {@link android.app.Activity#startActivityFromChild(Activity, Intent, int)}
+ * {@link android.app.Activity#startNextMatchingActivity(Intent)}
+ * {@link android.app.Activity#getCallingActivity()}
+ * {@link android.app.Activity#getCallingPackage()}
+ * {@link android.app.Activity#createPendingResult(int, Intent, int)}
+ * {@link android.app.Activity#getTaskId()}
+ * {@link android.app.Activity#isTaskRoot()}
+ * {@link android.app.Activity#moveTaskToBack(boolean)}
+ * {@link android.app.Activity#setPersistent(boolean)}
+ *
+ *
+ * The following methods may be called but will not do anything. For test purposes, you can use
+ * the methods {@link #getStartedActivityIntent()} and {@link #getStartedActivityRequest()} to
+ * inspect the parameters that they were called with.
+ *
+ * {@link android.app.Activity#startActivity(Intent)}
+ * {@link android.app.Activity#startActivityForResult(Intent, int)}
+ *
+ *
+ * The following methods may be called but will not do anything. For test purposes, you can use
+ * the methods {@link #isFinishCalled()} and {@link #getFinishedActivityRequest()} to inspect the
+ * parameters that they were called with.
+ *
+ * {@link android.app.Activity#finish()}
+ * {@link android.app.Activity#finishFromChild(Activity child)}
+ * {@link android.app.Activity#finishActivity(int requestCode)}
+ *
+ *
+ */
+public abstract class ActivityUnitTestCase
+ extends ActivityTestCase {
+
+ private Class mActivityClass;
+
+ private Context mActivityContext;
+ private Application mApplication;
+ private MockParent mMockParent;
+
+ private boolean mAttached = false;
+ private boolean mCreated = false;
+
+ public ActivityUnitTestCase(Class activityClass) {
+ mActivityClass = activityClass;
+ }
+
+ @Override
+ public T getActivity() {
+ return (T) super.getActivity();
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ // default value for target context, as a default
+ mActivityContext = getInstrumentation().getTargetContext();
+ }
+
+ /**
+ * Start the activity under test, in the same way as if it was started by
+ * {@link android.content.Context#startActivity Context.startActivity()}, providing the
+ * arguments it supplied. When you use this method to start the activity, it will automatically
+ * be stopped by {@link #tearDown}.
+ *
+ * This method will call onCreate(), but if you wish to further exercise Activity life
+ * cycle methods, you must call them yourself from your test case.
+ *
+ *
Do not call from your setUp() method. You must call this method from each of your
+ * test methods.
+ *
+ * @param intent The Intent as if supplied to {@link android.content.Context#startActivity}.
+ * @param savedInstanceState The instance state, if you are simulating this part of the life
+ * cycle. Typically null.
+ * @param lastNonConfigurationInstance This Object will be available to the
+ * Activity if it calls {@link android.app.Activity#getLastNonConfigurationInstance()}.
+ * Typically null.
+ * @return Returns the Activity that was created
+ */
+ protected T startActivity(Intent intent, Bundle savedInstanceState,
+ Object lastNonConfigurationInstance) {
+ assertFalse("Activity already created", mCreated);
+
+ if (!mAttached) {
+ assertNotNull(mActivityClass);
+ setActivity(null);
+ T newActivity = null;
+ try {
+ IBinder token = null;
+ if (mApplication == null) {
+ setApplication(new MockApplication());
+ }
+// ComponentName cn = new ComponentName(mActivityClass.getPackage().getName(),
+// mActivityClass.getName());
+ ComponentName cn = new ComponentName(getInstrumentation().getTargetContext(), mActivityClass);
+ intent.setComponent(cn);
+ ActivityInfo info = new ActivityInfo();
+ CharSequence title = mActivityClass.getName();
+ mMockParent = new MockParent();
+ String id = null;
+
+ newActivity = (T) getInstrumentation().newActivity(mActivityClass, mActivityContext,
+ token, mApplication, intent, info, title, mMockParent, id,
+ lastNonConfigurationInstance);
+ } catch (Exception e) {
+ assertNotNull(newActivity);
+ }
+
+ assertNotNull(newActivity);
+ setActivity(newActivity);
+
+ mAttached = true;
+ }
+
+ T result = getActivity();
+ if (result != null) {
+ getInstrumentation().callActivityOnCreate(getActivity(), savedInstanceState);
+ mCreated = true;
+ }
+ return result;
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+
+ setActivity(null);
+
+ // Scrub out members - protects against memory leaks in the case where someone
+ // creates a non-static inner class (thus referencing the test case) and gives it to
+ // someone else to hold onto
+ scrubClass(ActivityInstrumentationTestCase.class);
+
+ super.tearDown();
+ }
+
+ /**
+ * Set the application for use during the test. You must call this function before calling
+ * {@link #startActivity}. If your test does not call this method,
+ * @param application The Application object that will be injected into the Activity under test.
+ */
+ public void setApplication(Application application) {
+ mApplication = application;
+ }
+
+ /**
+ * If you wish to inject a Mock, Isolated, or otherwise altered context, you can do so
+ * here. You must call this function before calling {@link #startActivity}. If you wish to
+ * obtain a real Context, as a building block, use getInstrumentation().getTargetContext().
+ */
+ public void setActivityContext(Context activityContext) {
+ mActivityContext = activityContext;
+ }
+
+ /**
+ * This method will return the value if your Activity under test calls
+ * {@link android.app.Activity#setRequestedOrientation}.
+ */
+ public int getRequestedOrientation() {
+ if (mMockParent != null) {
+ return mMockParent.mRequestedOrientation;
+ }
+ return 0;
+ }
+
+ /**
+ * This method will return the launch intent if your Activity under test calls
+ * {@link android.app.Activity#startActivity(Intent)} or
+ * {@link android.app.Activity#startActivityForResult(Intent, int)}.
+ * @return The Intent provided in the start call, or null if no start call was made.
+ */
+ public Intent getStartedActivityIntent() {
+ if (mMockParent != null) {
+ return mMockParent.mStartedActivityIntent;
+ }
+ return null;
+ }
+
+ /**
+ * This method will return the launch request code if your Activity under test calls
+ * {@link android.app.Activity#startActivityForResult(Intent, int)}.
+ * @return The request code provided in the start call, or -1 if no start call was made.
+ */
+ public int getStartedActivityRequest() {
+ if (mMockParent != null) {
+ return mMockParent.mStartedActivityRequest;
+ }
+ return 0;
+ }
+
+ /**
+ * This method will notify you if the Activity under test called
+ * {@link android.app.Activity#finish()},
+ * {@link android.app.Activity#finishFromChild(Activity)}, or
+ * {@link android.app.Activity#finishActivity(int)}.
+ * @return Returns true if one of the listed finish methods was called.
+ */
+ public boolean isFinishCalled() {
+ if (mMockParent != null) {
+ return mMockParent.mFinished;
+ }
+ return false;
+ }
+
+ /**
+ * This method will return the request code if the Activity under test called
+ * {@link android.app.Activity#finishActivity(int)}.
+ * @return The request code provided in the start call, or -1 if no finish call was made.
+ */
+ public int getFinishedActivityRequest() {
+ if (mMockParent != null) {
+ return mMockParent.mFinishedActivityRequest;
+ }
+ return 0;
+ }
+
+ /**
+ * This mock Activity represents the "parent" activity. By injecting this, we allow the user
+ * to call a few more Activity methods, including:
+ *
+ * {@link android.app.Activity#getRequestedOrientation()}
+ * {@link android.app.Activity#setRequestedOrientation(int)}
+ * {@link android.app.Activity#finish()}
+ * {@link android.app.Activity#finishActivity(int requestCode)}
+ * {@link android.app.Activity#finishFromChild(Activity child)}
+ *
+ *
+ * TODO: Make this overrideable, and the unit test can look for calls to other methods
+ */
+ private static class MockParent extends Activity {
+
+ public int mRequestedOrientation = 0;
+ public Intent mStartedActivityIntent = null;
+ public int mStartedActivityRequest = -1;
+ public boolean mFinished = false;
+ public int mFinishedActivityRequest = -1;
+
+ /**
+ * Implementing in the parent allows the user to call this function on the tested activity.
+ */
+ @Override
+ public void setRequestedOrientation(int requestedOrientation) {
+ mRequestedOrientation = requestedOrientation;
+ }
+
+ /**
+ * Implementing in the parent allows the user to call this function on the tested activity.
+ */
+ @Override
+ public int getRequestedOrientation() {
+ return mRequestedOrientation;
+ }
+
+ /**
+ * By returning null here, we inhibit the creation of any "container" for the window.
+ */
+ @Override
+ public Window getWindow() {
+ return null;
+ }
+
+ /**
+ * By defining this in the parent, we allow the tested activity to call
+ *
+ * {@link android.app.Activity#startActivity(Intent)}
+ * {@link android.app.Activity#startActivityForResult(Intent, int)}
+ *
+ */
+ @Override
+ public void startActivityFromChild(Activity child, Intent intent, int requestCode) {
+ mStartedActivityIntent = intent;
+ mStartedActivityRequest = requestCode;
+ }
+
+ /**
+ * By defining this in the parent, we allow the tested activity to call
+ *
+ * {@link android.app.Activity#finish()}
+ * {@link android.app.Activity#finishFromChild(Activity child)}
+ *
+ */
+ @Override
+ public void finishFromChild(Activity child) {
+ mFinished = true;
+ }
+
+ /**
+ * By defining this in the parent, we allow the tested activity to call
+ *
+ * {@link android.app.Activity#finishActivity(int requestCode)}
+ *
+ */
+ @Override
+ public void finishActivityFromChild(Activity child, int requestCode) {
+ mFinished = true;
+ mFinishedActivityRequest = requestCode;
+ }
+ }
+}
diff --git a/mobile/com.sap.sailing.android.tracking.app.test-test/src/com/sap/sailing/android/tracking/app/test/StartActivityTest.java b/mobile/com.sap.sailing.android.tracking.app.test-test/src/com/sap/sailing/android/tracking/app/test/StartActivityTest.java
new file mode 100644
index 00000000000..f87b002f4c0
--- /dev/null
+++ b/mobile/com.sap.sailing.android.tracking.app.test-test/src/com/sap/sailing/android/tracking/app/test/StartActivityTest.java
@@ -0,0 +1,50 @@
+package com.sap.sailing.android.tracking.app.test;
+
+import android.content.Intent;
+import android.support.v4.app.FragmentManager;
+import android.view.ContextThemeWrapper;
+import android.widget.Button;
+
+import com.sap.sailing.android.tracking.app.R;
+import com.sap.sailing.android.tracking.app.ui.activities.StartActivity;
+
+public class StartActivityTest extends ActivityUnitTestCase {
+ private Intent mStartIntent;
+ private FragmentManager fragmentManager;
+
+ public StartActivityTest() {
+ super(StartActivity.class);
+ }
+
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ ContextThemeWrapper context = new ContextThemeWrapper(
+ getInstrumentation().getTargetContext(), R.style.AppTheme);
+ setActivityContext(context);
+
+ mStartIntent = new Intent(Intent.ACTION_MAIN);
+ startActivity(mStartIntent, null, null);
+ fragmentManager = getActivity().getSupportFragmentManager();
+ }
+
+ public void testHasTwoButtons() {
+
+ getInstrumentation().callActivityOnStart(getActivity());
+ getInstrumentation().callActivityOnResume(getActivity());
+ getActivity().getFragmentManager().executePendingTransactions();
+
+ fragmentManager.executePendingTransactions();
+
+ Button scanButton = (Button) getActivity().findViewById(R.id.scanQr);
+ Button noQRButton = (Button) getActivity().findViewById(R.id.noQrCode);
+
+ assertNotNull(getActivity());
+ assertNotNull(scanButton);
+ assertNotNull(noQRButton);
+ }
+
+
+}
diff --git a/mobile/com.sap.sailing.android.tracking.app/AndroidManifest.xml b/mobile/com.sap.sailing.android.tracking.app/AndroidManifest.xml
index 4b4eaeb5d0f..1ee8e99a985 100644
--- a/mobile/com.sap.sailing.android.tracking.app/AndroidManifest.xml
+++ b/mobile/com.sap.sailing.android.tracking.app/AndroidManifest.xml
@@ -14,7 +14,6 @@
-
@@ -36,7 +35,7 @@
+ android:screenOrientation="unspecified" >
@@ -52,7 +51,7 @@
+ android:screenOrientation="unspecified" >
@@ -60,14 +59,14 @@
+ android:screenOrientation="unspecified" >
+ android:screenOrientation="unspecified" >
@@ -82,13 +81,13 @@
+ android:screenOrientation="unspecified" />
+ android:screenOrientation="unspecified" />
+ android:screenOrientation="unspecified" />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/mobile/com.sap.sailing.android.tracking.app/res/layout-land/fragment_regatta.xml b/mobile/com.sap.sailing.android.tracking.app/res/layout-land/fragment_regatta.xml
new file mode 100644
index 00000000000..49b94dc886b
--- /dev/null
+++ b/mobile/com.sap.sailing.android.tracking.app/res/layout-land/fragment_regatta.xml
@@ -0,0 +1,337 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/mobile/com.sap.sailing.android.tracking.app/res/layout-land/fragment_tracking.xml b/mobile/com.sap.sailing.android.tracking.app/res/layout-land/fragment_tracking.xml
new file mode 100644
index 00000000000..8e17f3ced9c
--- /dev/null
+++ b/mobile/com.sap.sailing.android.tracking.app/res/layout-land/fragment_tracking.xml
@@ -0,0 +1,162 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/mobile/com.sap.sailing.android.tracking.app/res/layout/fragment_home.xml b/mobile/com.sap.sailing.android.tracking.app/res/layout/fragment_home.xml
index f8ca1331c24..0c792c8ee12 100644
--- a/mobile/com.sap.sailing.android.tracking.app/res/layout/fragment_home.xml
+++ b/mobile/com.sap.sailing.android.tracking.app/res/layout/fragment_home.xml
@@ -13,15 +13,17 @@
android:contentDescription="@string/empty"
android:scaleType="centerCrop"
android:src="@drawable/working_title" />
+
-
-
-
-
-
-
-
-
+ android:padding="10dp"
+ android:visibility="invisible" >
-
-
-
-
-
-
-
-
-
-
-
+
+ android:layout_alignParentLeft="true"
+ android:background="@color/darker_gray" >
-
-
-
-
-
-
-
-
-
-
- Vielen Dank, Sie haben erfolgreich an der Regatta teilgenommen.\n\nIhr SAP Sailing Team
Kein QR-Code?
Bitte kontaktieren Sie die Rennleitung, falls Sie keinen QR-Code erhalten haben.
+ Tracke:
\ No newline at end of file
diff --git a/mobile/com.sap.sailing.android.tracking.app/res/values/strings.xml b/mobile/com.sap.sailing.android.tracking.app/res/values/strings.xml
index 214082ad1f7..e86190be9e3 100644
--- a/mobile/com.sap.sailing.android.tracking.app/res/values/strings.xml
+++ b/mobile/com.sap.sailing.android.tracking.app/res/values/strings.xml
@@ -63,5 +63,6 @@
Thank you, you have successfully taken part in the regatta.\n\nYour SAP Sailing Team
No QR-Code?
Please contact race management if you have not received a QR-Code.
+ Tracking:
diff --git a/mobile/com.sap.sailing.android.tracking.app/res/values/strings_activity.xml b/mobile/com.sap.sailing.android.tracking.app/res/values/strings_activity.xml
index 0fde358914c..753cc57f1df 100644
--- a/mobile/com.sap.sailing.android.tracking.app/res/values/strings_activity.xml
+++ b/mobile/com.sap.sailing.android.tracking.app/res/values/strings_activity.xml
@@ -1,5 +1,4 @@
trackingActivityEventId
- startedByStartActivity
diff --git a/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/customviews/OpenSansButton.java b/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/customviews/OpenSansButton.java
new file mode 100644
index 00000000000..7c09f07f065
--- /dev/null
+++ b/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/customviews/OpenSansButton.java
@@ -0,0 +1,36 @@
+package com.sap.sailing.android.tracking.app.customviews;
+
+import android.content.Context;
+import android.graphics.Typeface;
+import android.util.AttributeSet;
+import android.widget.Button;
+
+public class OpenSansButton extends Button {
+
+ public OpenSansButton(Context context) {
+ super(context);
+ init();
+ }
+
+ public OpenSansButton(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ init();
+ }
+
+ public OpenSansButton(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ init();
+ }
+
+ public OpenSansButton(Context context, AttributeSet attrs,
+ int defStyleAttr, int defStyleRes) {
+ super(context, attrs, defStyleAttr, defStyleRes);
+ init();
+ }
+
+ protected void init()
+ {
+ setTypeface(Typeface.createFromAsset(getContext().getAssets(), "fonts/OpenSans-Regular.ttf"));
+ }
+
+}
diff --git a/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/customviews/OpenSansTextView.java b/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/customviews/OpenSansTextView.java
new file mode 100644
index 00000000000..e1a290a9f17
--- /dev/null
+++ b/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/customviews/OpenSansTextView.java
@@ -0,0 +1,28 @@
+package com.sap.sailing.android.tracking.app.customviews;
+
+import android.content.Context;
+import android.graphics.Typeface;
+import android.util.AttributeSet;
+import android.widget.TextView;
+
+public class OpenSansTextView extends TextView {
+
+ public OpenSansTextView(Context context) {
+ super(context);
+ init();
+ }
+
+ public OpenSansTextView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ init();
+ }
+
+ public OpenSansTextView(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ init();
+ }
+
+ protected void init() {
+ setTypeface(Typeface.createFromAsset(getContext().getAssets(), "fonts/OpenSans-Regular.ttf"));
+ }
+}
diff --git a/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/customviews/OpenSansToolbar.java b/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/customviews/OpenSansToolbar.java
new file mode 100644
index 00000000000..492c2300868
--- /dev/null
+++ b/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/customviews/OpenSansToolbar.java
@@ -0,0 +1,68 @@
+package com.sap.sailing.android.tracking.app.customviews;
+
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import android.content.Context;
+import android.graphics.Typeface;
+import android.support.v7.widget.Toolbar;
+import android.util.AttributeSet;
+import android.widget.TextView;
+
+public class OpenSansToolbar extends Toolbar {
+
+ public OpenSansToolbar(Context context) {
+ super(context);
+ init();
+ }
+
+ public OpenSansToolbar(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ init();
+ }
+
+ public OpenSansToolbar(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ init();
+ }
+
+ protected void init() {
+ TextView titleTextView = getActionBarTextView();
+ if (titleTextView != null)
+ {
+ System.out.println("NOT NULL");
+ titleTextView.setTypeface(Typeface.createFromAsset(getContext().getAssets(), "fonts/Admiration Pains.ttf"));
+ }
+ System.out.println("NULL");
+ }
+
+ private TextView getActionBarTextView() {
+ TextView titleTextView = null;
+
+ ArrayList fields = getAllFields(new ArrayList(), this.getClass());
+ for (Field fld : fields)
+ System.out.println(" " + fld);
+
+ try {
+ Field f = this.getClass().getSuperclass().getDeclaredField("mTitleTextView");
+ f.setAccessible(true);
+ titleTextView = (TextView) f.get(this);
+ } catch (NoSuchFieldException e) {
+ } catch (IllegalAccessException e) {
+ }
+ return titleTextView;
+ }
+
+ public static ArrayList getAllFields(ArrayList fields, Class> type) {
+ fields.addAll(Arrays.asList(type.getDeclaredFields()));
+
+ if (type.getSuperclass() != null) {
+ fields = getAllFields(fields, type.getSuperclass());
+ }
+
+ return fields;
+ }
+
+}
diff --git a/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/provider/AnalyticsContract.java b/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/provider/AnalyticsContract.java
index 032a6df239d..ae27fc81a8e 100644
--- a/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/provider/AnalyticsContract.java
+++ b/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/provider/AnalyticsContract.java
@@ -53,6 +53,12 @@ public class AnalyticsContract {
private static final String PATH_LEADERBOARD = "leaderboards";
private static final String PATH_SENSOR_GPS = "sensor_gps";
+
+ public static class LeaderboardsEventsJoined {
+ public final static Uri CONTENT_URI = BASE_CONTENT_URI.buildUpon()
+ .appendPath("leaderboards_events_joined").build();
+ }
+
public static class EventGpsFixesJoined {
public final static Uri CONTENT_URI = BASE_CONTENT_URI.buildUpon()
.appendPath("event_gps_fix_joined").build();
diff --git a/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/provider/AnalyticsDatabase.java b/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/provider/AnalyticsDatabase.java
index db1a3895515..be3f2222ef1 100644
--- a/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/provider/AnalyticsDatabase.java
+++ b/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/provider/AnalyticsDatabase.java
@@ -33,6 +33,7 @@ public class AnalyticsDatabase extends SQLiteOpenHelper {
" INNER JOIN " + Tables.EVENTS + " ON (" + Tables.LEADERBOARDS + "." + BaseColumns._ID + " = " + Tables.EVENTS + ".leaderboard_id ) " +
" INNER JOIN " + Tables.COMPETITORS + " ON (" + Tables.LEADERBOARDS + "."+ BaseColumns._ID + " = " + Tables.COMPETITORS + ".leaderboard_id ) ";
String GPS_FIXES_JOIN_EVENTS = "sensor_gps LEFT JOIN events ON sensor_gps.event_id = events._id ";
+ String LEADERBOARDS_JOIN_EVENTS = "events LEFT JOIN leaderboards ON events.leaderboard_id = leaderboards._id ";
}
public AnalyticsDatabase(Context context) {
diff --git a/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/provider/AnalyticsProvider.java b/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/provider/AnalyticsProvider.java
index b9c5e9e8af9..d43d60c22ed 100644
--- a/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/provider/AnalyticsProvider.java
+++ b/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/provider/AnalyticsProvider.java
@@ -48,6 +48,8 @@ public class AnalyticsProvider extends ContentProvider {
private static final int EVENT_GPS_FIXES_JOINED = 700;
+ private static final int LEADERBOARDS_EVENTS_JOINED = 800;
+
private static UriMatcher buildUriMatcher() {
final UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);
final String authority = AnalyticsContract.CONTENT_AUTHORITY;
@@ -71,6 +73,8 @@ public class AnalyticsProvider extends ContentProvider {
matcher.addURI(authority, "event_gps_fix_joined", EVENT_GPS_FIXES_JOINED);
+ matcher.addURI(authority, "leaderboards_events_joined", LEADERBOARDS_EVENTS_JOINED);
+
return matcher;
}
@@ -113,6 +117,12 @@ public class AnalyticsProvider extends ContentProvider {
cursor = eb.query(db, projection, selection, selectionArgs, null, null, sortOrder);
return cursor;
+ case LEADERBOARDS_EVENTS_JOINED:
+ SQLiteQueryBuilder el = new SQLiteQueryBuilder();
+ el.setTables(Tables.LEADERBOARDS_JOIN_EVENTS);
+ cursor = el.query(db, projection, selection, selectionArgs, null, null, sortOrder);
+ return cursor;
+
default:
final SelectionBuilder builder = buildExpandedSelection(uri);
diff --git a/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/ui/activities/RegattaActivity.java b/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/ui/activities/RegattaActivity.java
index 491cd3dc1a0..06fb7e0770d 100644
--- a/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/ui/activities/RegattaActivity.java
+++ b/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/ui/activities/RegattaActivity.java
@@ -15,7 +15,6 @@ import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
-import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.AsyncTask;
@@ -23,9 +22,6 @@ import android.os.Bundle;
import android.os.Environment;
import android.provider.BaseColumns;
import android.support.v7.widget.Toolbar;
-import android.text.Spannable;
-import android.text.SpannableString;
-import android.text.style.StyleSpan;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
@@ -35,7 +31,6 @@ import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
-import com.android.volley.Request.Method;
import com.android.volley.Response.ErrorListener;
import com.android.volley.Response.Listener;
import com.android.volley.VolleyError;
@@ -95,15 +90,13 @@ public class RegattaActivity extends BaseActivity {
toolbar.setNavigationIcon(R.drawable.sap_logo_64_sq);
toolbar.setPadding(20, 0, 0, 0);
getSupportActionBar().setTitle(leaderboardName);
- Spannable subtitle = new SpannableString("Registered for: " + eventName);
- StyleSpan styleBold = new StyleSpan(Typeface.BOLD);
- subtitle.setSpan(styleBold, 16, 20, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
- getSupportActionBar().setSubtitle(subtitle);
+ getSupportActionBar().setSubtitle(eventName);
}
-
- replaceFragment(R.id.content_frame, new RegattaFragment());
+
+ replaceFragment(R.id.content_frame, new RegattaFragment());
+
}
-
+
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
diff --git a/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/ui/activities/StartActivity.java b/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/ui/activities/StartActivity.java
index 96a0cc6e7f1..9f32f66354b 100644
--- a/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/ui/activities/StartActivity.java
+++ b/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/ui/activities/StartActivity.java
@@ -18,18 +18,18 @@ public class StartActivity extends BaseActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
-
+
setContentView(R.layout.fragment_container);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
if (toolbar != null) {
setSupportActionBar(toolbar);
-
toolbar.setNavigationIcon(R.drawable.sap_logo_64_sq);
toolbar.setPadding(20, 0, 0, 0);
toolbar.setBackgroundColor(getResources().getColor(R.color.colorPrimary));
}
if (getSupportActionBar() != null) {
- getSupportActionBar().setHomeButtonEnabled(false);
+ getSupportActionBar().setTitle(getString(R.string.title_activity_start));
+ getSupportActionBar().setHomeButtonEnabled(false);
}
replaceFragment(R.id.content_frame, new HomeFragment());
@@ -77,7 +77,6 @@ public class StartActivity extends BaseActivity {
private void startTrackingActivity(int eventId) {
Intent intent = new Intent(this, TrackingActivity.class);
intent.putExtra(getString(R.string.tracking_activity_event_id_parameter), eventId);
- intent.putExtra(getString(R.string.tracking_activity_started_by_start_activity_parameter), true);
startActivity(intent);
}
diff --git a/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/ui/activities/TrackingActivity.java b/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/ui/activities/TrackingActivity.java
index 3eb957b935f..b99bb3fbe31 100644
--- a/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/ui/activities/TrackingActivity.java
+++ b/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/ui/activities/TrackingActivity.java
@@ -1,16 +1,25 @@
package com.sap.sailing.android.tracking.app.ui.activities;
import android.content.ComponentName;
+import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
+import android.database.Cursor;
+import android.graphics.Typeface;
import android.os.Bundle;
import android.os.IBinder;
+import android.provider.BaseColumns;
import android.support.v7.widget.Toolbar;
+import android.text.Spannable;
+import android.text.SpannableString;
+import android.text.style.StyleSpan;
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.provider.AnalyticsContract.Event;
+import com.sap.sailing.android.tracking.app.provider.AnalyticsContract.LeaderboardsEventsJoined;
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.services.TrackingService.GPSQualityListener;
@@ -28,10 +37,10 @@ public class TrackingActivity extends BaseActivity implements GPSQualityListener
TransmittingService transmittingService;
boolean transmittingServiceBound;
- boolean startedByStartActivity;
private final static String TAG = TrackingActivity.class.getName();
-
+ private final static String SIS_FRAGMENT = "savedInstanceTrackingFragment";
+
private int eventId;
@Override
@@ -39,8 +48,7 @@ public class TrackingActivity extends BaseActivity implements GPSQualityListener
super.onCreate(savedInstanceState);
Intent intent = getIntent();
- eventId = intent.getExtras().getInt(getString(R.string.tracking_activity_event_id_parameter));
- startedByStartActivity = intent.getExtras().getBoolean(getString(R.string.tracking_activity_started_by_start_activity_parameter));
+ eventId = intent.getExtras().getInt(getString(R.string.tracking_activity_event_id_parameter));
setContentView(R.layout.fragment_container);
@@ -51,16 +59,54 @@ public class TrackingActivity extends BaseActivity implements GPSQualityListener
toolbar.setPadding(20, 0, 0, 0);
toolbar.setBackgroundColor(getResources().getColor(R.color.colorPrimary));
}
+
if (getSupportActionBar() != null) {
- getSupportActionBar().setDisplayHomeAsUpEnabled(false);
- getSupportActionBar().setHomeButtonEnabled(false);
- getSupportActionBar().setTitle(R.string.title_activity_tracking);
+
+ String leaderboardName = "";
+ String eventName = "";
+ ContentResolver cr = getContentResolver();
+ String projectionStr = "events._id,leaderboards.leaderboard_name,events.event_name";
+ String[] projection = projectionStr.split(",");
+ Cursor cursor = cr.query(LeaderboardsEventsJoined.CONTENT_URI, projection, "events._id = " + eventId, null, null);
+ if (cursor.moveToFirst())
+ {
+ eventName = cursor.getString(cursor.getColumnIndex("event_name"));
+ leaderboardName = cursor.getString(cursor.getColumnIndex("leaderboard_name"));
+ }
+
+ cursor.close();
+
+ getSupportActionBar().setDisplayHomeAsUpEnabled(true);
+ getSupportActionBar().setHomeButtonEnabled(true);
+ toolbar.setNavigationIcon(R.drawable.sap_logo_64_sq);
+ toolbar.setPadding(20, 0, 0, 0);
+ getSupportActionBar().setTitle(leaderboardName);
+ getSupportActionBar().setSubtitle(getString(R.string.tracking_colon) + " " + eventName);
}
-
- replaceFragment(R.id.content_frame, new TrackingFragment());
+
+ TrackingFragment fragment;
+ if (savedInstanceState != null)
+ {
+ fragment = (TrackingFragment)getSupportFragmentManager().getFragment(savedInstanceState, SIS_FRAGMENT);
+ }
+ else
+ {
+ fragment = new TrackingFragment();
+ }
+
+ replaceFragment(R.id.content_frame, fragment);
startTrackingService(eventId);
}
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+
+ TrackingFragment fragment = (TrackingFragment)getSupportFragmentManager()
+ .findFragmentById(R.id.content_frame);
+ getSupportFragmentManager().putFragment(outState, SIS_FRAGMENT, fragment);
+ }
+
@Override
protected void onStart() {
super.onStart();
@@ -176,13 +222,4 @@ public class TrackingActivity extends BaseActivity implements GPSQualityListener
trackingServiceBound = false;
}
};
-
- /**
- * the fragment can call this to know if tracking was running before, so it doesn't reset the timer.
- * @return
- */
- public boolean getStartedByStartActivity()
- {
- return startedByStartActivity;
- }
}
diff --git a/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/ui/fragments/HomeFragment.java b/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/ui/fragments/HomeFragment.java
index 871c2582c3c..b689c7c4763 100644
--- a/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/ui/fragments/HomeFragment.java
+++ b/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/ui/fragments/HomeFragment.java
@@ -104,6 +104,7 @@ public class HomeFragment extends BaseFragment implements
if (listView != null) {
listView.addHeaderView(inflater.inflate(
R.layout.regatta_listview_header, null));
+
adapter = new RegattaAdapter(getActivity(),
R.layout.ragatta_listview_row, null, 0);
listView.setAdapter(adapter);
diff --git a/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/ui/fragments/RegattaFragment.java b/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/ui/fragments/RegattaFragment.java
index 9fe59bc50ac..b4d08bf2dae 100644
--- a/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/ui/fragments/RegattaFragment.java
+++ b/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/ui/fragments/RegattaFragment.java
@@ -36,7 +36,7 @@ public class RegattaFragment extends BaseFragment implements OnClickListener {
private final int SELECT_PHOTO_REQUEST_CODE = 1693;
private boolean showingThankYouNote;
-
+
private TimerRunnable timer;
@Override
@@ -65,21 +65,19 @@ public class RegattaFragment extends BaseFragment implements OnClickListener {
return view;
}
-
- private void checkAndSwitchToThankYouScreenIfRegattaOver()
- {
+
+ private void checkAndSwitchToThankYouScreenIfRegattaOver() {
RegattaActivity regattaActivity = (RegattaActivity) getActivity();
long regattaEnd = regattaActivity.getEventEndMillis();
-
- if (System.currentTimeMillis() > regattaEnd)
- {
+
+ if (System.currentTimeMillis() > regattaEnd) {
switchToThankYouScreen();
}
}
private void switchToThankYouScreen() {
showingThankYouNote = true;
-
+
RelativeLayout startsInLayout = (RelativeLayout) getActivity()
.findViewById(R.id.start_date_layout);
startsInLayout.setVisibility(View.INVISIBLE);
@@ -90,10 +88,12 @@ public class RegattaFragment extends BaseFragment implements OnClickListener {
.getColor(R.color.sap_yellow));
startTrackingButton.setText(getActivity().getString(R.string.close));
- TextView bottomAnnouncement = (TextView) getActivity().findViewById(R.id.bottom_announcement);
+ TextView bottomAnnouncement = (TextView) getActivity().findViewById(
+ R.id.bottom_announcement);
bottomAnnouncement.setVisibility(View.INVISIBLE);
-
- RelativeLayout thankYouLayout = (RelativeLayout)getActivity().findViewById(R.id.thank_you_layout);
+
+ RelativeLayout thankYouLayout = (RelativeLayout) getActivity()
+ .findViewById(R.id.thank_you_layout);
thankYouLayout.setVisibility(View.VISIBLE);
}
@@ -115,14 +115,11 @@ public class RegattaFragment extends BaseFragment implements OnClickListener {
public void onClick(View view) {
switch (view.getId()) {
case R.id.start_tracking:
- if (showingThankYouNote)
- {
- RegattaActivity regattaActivity = (RegattaActivity)getActivity();
+ if (showingThankYouNote) {
+ RegattaActivity regattaActivity = (RegattaActivity) getActivity();
regattaActivity.checkout();
- }
- else
- {
- startTrackingActivity();
+ } else {
+ startTrackingActivity();
}
break;
case R.id.add_photo_button:
@@ -218,7 +215,9 @@ public class RegattaFragment extends BaseFragment implements OnClickListener {
private void startTrackingActivity() {
RegattaActivity regattaActivity = (RegattaActivity) getActivity();
Intent intent = new Intent(getActivity(), TrackingActivity.class);
- intent.putExtra(getString(R.string.tracking_activity_event_id_parameter), regattaActivity.getEventId());
+ intent.putExtra(
+ getString(R.string.tracking_activity_event_id_parameter),
+ regattaActivity.getEventId());
getActivity().startActivity(intent);
}
diff --git a/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/ui/fragments/TrackingFragment.java b/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/ui/fragments/TrackingFragment.java
index c6debec3923..f37b7527537 100644
--- a/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/ui/fragments/TrackingFragment.java
+++ b/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/ui/fragments/TrackingFragment.java
@@ -33,6 +33,10 @@ import com.sap.sailing.android.tracking.app.views.SignalQualityIndicatorView;
public class TrackingFragment extends BaseFragment implements OnClickListener {
+ static final String SIS_MODE = "instanceStateMode";
+ static final String SIS_STATUS = "instanceStateStatus";
+ static final String SIS_GPS_QUALITY = "instanceStateGpsQuality";
+
private TimerRunnable timer;
private AppPreferences prefs;
private long lastGPSQualityUpdate;
@@ -50,8 +54,7 @@ public class TrackingFragment extends BaseFragment implements OnClickListener {
stopTracking.setOnClickListener(this);
prefs = new AppPreferences(getActivity());
-
- if (((TrackingActivity)getActivity()).getStartedByStartActivity() == false)
+ if (prefs.getTrackingTimerStarted() == 0)
{
prefs.setTrackingTimerStarted(System.currentTimeMillis());
}
@@ -84,9 +87,38 @@ public class TrackingFragment extends BaseFragment implements OnClickListener {
}
@Override
- public void onDestroy() {
- super.onDestroy();
- timer.stop();
+ public void onActivityCreated(Bundle savedInstanceState) {
+ System.out.println("ON ACTIVITY CREATED");
+ super.onActivityCreated(savedInstanceState);
+ if (savedInstanceState != null)
+ {
+ System.out.println("NOT NULL");
+ TextView modeText = (TextView)getActivity().findViewById(R.id.mode);
+ TextView statusText = (TextView)getActivity().findViewById(R.id.tracking_status);
+ SignalQualityIndicatorView qualityIndicator = (SignalQualityIndicatorView)getActivity().findViewById(R.id.qps_quality_indicator);
+
+ modeText.setText(savedInstanceState.getString(SIS_MODE));
+ statusText.setText(savedInstanceState.getString(SIS_STATUS));
+ qualityIndicator.setSignalQuality(savedInstanceState.getInt(SIS_GPS_QUALITY));
+ }
+ else
+ {
+ System.out.println("NULL");
+ }
+ }
+
+ @Override
+ public void onSaveInstanceState(Bundle outState) {
+ System.out.println("ON SAVE INSTANCE STATE");
+ super.onSaveInstanceState(outState);
+
+ TextView modeText = (TextView)getActivity().findViewById(R.id.mode);
+ TextView statusText = (TextView)getActivity().findViewById(R.id.tracking_status);
+ SignalQualityIndicatorView qualityIndicator = (SignalQualityIndicatorView)getActivity().findViewById(R.id.qps_quality_indicator);
+
+ outState.putString(SIS_MODE, modeText.getText().toString());
+ outState.putString(SIS_STATUS, statusText.getText().toString());
+ outState.putInt(SIS_GPS_QUALITY, qualityIndicator.getSignalQuality());
}
/**
@@ -214,6 +246,8 @@ public class TrackingFragment extends BaseFragment implements OnClickListener {
}
private void stopTracking() {
+ prefs.setTrackingTimerStarted(0);
+
Intent intent = new Intent(getActivity(), TrackingService.class);
intent.setAction(getString(R.string.tracking_service_stop));
getActivity().startService(intent);
diff --git a/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/views/AutoResizeTextView.java b/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/views/AutoResizeTextView.java
index 3c28e9d2d15..2faf0e7805d 100644
--- a/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/views/AutoResizeTextView.java
+++ b/mobile/com.sap.sailing.android.tracking.app/src/com/sap/sailing/android/tracking/app/views/AutoResizeTextView.java
@@ -19,6 +19,7 @@ package com.sap.sailing.android.tracking.app.views;
*/
import android.content.Context;
+import android.graphics.Typeface;
import android.text.Layout.Alignment;
import android.text.StaticLayout;
import android.text.TextPaint;
@@ -85,6 +86,7 @@ public class AutoResizeTextView extends TextView {
// Default constructor override
public AutoResizeTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
+ setTypeface(Typeface.createFromAsset(getContext().getAssets(), "fonts/OpenSans-Regular.ttf"));
mTextSize = getTextSize();
}
diff --git a/mobile/com.sap.sailing.racecommittee.app/res/layout/welcome_fragment.xml b/mobile/com.sap.sailing.racecommittee.app/res/layout/welcome_fragment.xml
new file mode 100644
index 00000000000..82c717d7177
--- /dev/null
+++ b/mobile/com.sap.sailing.racecommittee.app/res/layout/welcome_fragment.xml
@@ -0,0 +1,67 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/mobile/com.sap.sailing.racecommittee.app/res/values/preferences.xml b/mobile/com.sap.sailing.racecommittee.app/res/values/preferences.xml
index 297d0bc20d6..696bc9df25d 100644
--- a/mobile/com.sap.sailing.racecommittee.app/res/values/preferences.xml
+++ b/mobile/com.sap.sailing.racecommittee.app/res/values/preferences.xml
@@ -78,4 +78,7 @@
racecommittee
false
+
+ enable_wakelock
+ true
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 6a2142c1628..28d89800189 100644
--- a/mobile/com.sap.sailing.racecommittee.app/res/values/strings.xml
+++ b/mobile/com.sap.sailing.racecommittee.app/res/values/strings.xml
@@ -1,6 +1,7 @@
-
+
+
http://maps.googleapis.com/maps/api/geocode/json?address=
\?sensor=true
@@ -9,7 +10,6 @@
SAP Race Committee Service
Waiting for races to monitor…
Currently monitoring %d races.
-
SAP Race Committee Cockpit
Start
Restart
@@ -89,8 +89,8 @@
- Port
- Starboard
- Gate
- - Line
- - Offset
+ - Line
+ - Offset
Publish
@@ -114,7 +114,6 @@
Add photo
Attached photos
No photos yet
-
[Race Committee] %s
Results for race %s are attached.
Wind direction from (degrees)
@@ -132,34 +131,29 @@
Location search …
Could not find a location based on your query.
Store wind
-
-
- Settings
- Other
+
+
+ Settings
+ Other
Managed Course Areas
Select Language
Select the language. You might need to restart the app to have changes applied.
-
Default start procedure type when overriden
Races will use selected start procedure type as a default. For this option to be active override checkbox has to be enabled.
-
Please execute action \'Reload\' to apply changes.
Webservice URL
Positioning mail recipient
-
Polling
Activate Polling
When active the server will be polled for changes.
Polling Interval (seconds)
-
Compass
Needle
-
Course area could not be loaded. Please go back to the login page.
Successfully loaded %d races.
There was an error loading the requested data:\n\n\"%s\"\n\nDo you want to retry?
Set the course layout
-
+
Load failure
(click to set wind)
(%1$s kn, %2$s)
@@ -190,27 +184,29 @@
Remote configuration applied.
Gate Launch stops after %dmin
-
+
Regatta Configuration (default)
Regatta Configuration (specific)
Course Designer Configuration
Course Designer type
-
+
Course Names
- Startmode Flags
- Class Flag
+ Startmode Flags
+ Class Flag
Individual Recall
- Activate this option to enable individual recall
- Activate this option to enable choosing the Pathfinder
+ Activate this option to enable individual recall
+ Activate this option to enable choosing the Pathfinder
Pathfinder
Activate this option to enable choosing the additional Golf-Down time
- Additional Golf-down time
- Device identifier
- Synchronize with server
+ Additional Golf-down time
+ Device identifier
+ Synchronize with server
When creating a configuration on the server, click here to synchronize your app and connection settings via QRCode.
Force update
Force an update from the server. It\'s a better idea to use the synchronize option.
+ Stay screen on
+ Force the screen to stay awake. Caution: Uses more battery.
Expert Information
@@ -251,4 +247,7 @@
Group Race?
No Group Racing
Group Racing
+
+ WELCOME
+ CHANGE
\ No newline at end of file
diff --git a/mobile/com.sap.sailing.racecommittee.app/res/xml/preference_general.xml b/mobile/com.sap.sailing.racecommittee.app/res/xml/preference_general.xml
index ef49a906817..e47696a89eb 100644
--- a/mobile/com.sap.sailing.racecommittee.app/res/xml/preference_general.xml
+++ b/mobile/com.sap.sailing.racecommittee.app/res/xml/preference_general.xml
@@ -2,67 +2,66 @@
-
-
-
+
-
-
-
-
-
-
-
+ android:key="@string/preference_identifier_key"
+ android:summary="@string/empty"
+ android:title="@string/device_identifier" />
+
+
+
+
-
-
-
+
-
+ android:key="@string/preference_polling_active_key"
+ android:summary="@string/settings_polling_active_description"
+ android:title="@string/settings_polling_active_header" />
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/AppPreferences.java b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/AppPreferences.java
index 8773ff561c9..06be8fb124c 100644
--- a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/AppPreferences.java
+++ b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/AppPreferences.java
@@ -26,10 +26,23 @@ import com.sap.sailing.racecommittee.app.domain.coursedesign.WindWardLeeWardCour
* Wrapper for {@link SharedPreferences} for all hidden and non-hidden preferences and state variables.
*/
public class AppPreferences {
- public Context getContext() {
- return context;
+ public interface PollingActiveChangedListener {
+ void onPollingActiveChanged(boolean isActive);
}
-
+
+ private final static String HIDDEN_PREFERENCE_AUTHOR_NAME = "authorName";
+
+ private final static String HIDDEN_PREFERENCE_AUTHOR_PRIORITY = "authorPriority";
+
+ private final static String HIDDEN_PREFERENCE_BOAT_CLASS = "boatClassPref";
+ private final static String HIDDEN_PREFERENCE_COURSE_LAYOUT = "courseLayoutPref";
+
+ private final static String HIDDEN_PREFERENCE_NUMBER_OF_ROUNDS = "numberOfRoundsPref";
+
+ private final static String HIDDEN_PREFERENCE_WIND_BEARING = "windBearingPref";
+
+ private final static String HIDDEN_PREFERENCE_WIND_SPEED = "windSpeedPref";
+
public static AppPreferences on(Context context) {
return new AppPreferences(context);
}
@@ -37,48 +50,30 @@ public class AppPreferences {
public static AppPreferences on(Context context, String preferenceName) {
return new AppPreferences(context, preferenceName);
}
-
- protected final SharedPreferences preferences;
protected final Context context;
+ private OnSharedPreferenceChangeListener pollingActiveChangedListener = new OnSharedPreferenceChangeListener() {
+ @Override
+ public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
+ if (key(R.string.preference_polling_active_key).equals(key)) {
+ for (PollingActiveChangedListener listener : pollingActiveChangedListeners) {
+ listener.onPollingActiveChanged(isPollingActive());
+ }
+ }
+ }
+ };
+ private Set pollingActiveChangedListeners = new HashSet();
+
+ protected final SharedPreferences preferences;
protected AppPreferences(Context context) {
this.context = context;
this.preferences = PreferenceManager.getDefaultSharedPreferences(context);
}
-
public AppPreferences(Context context, String preferenceName) {
this.context = context;
this.preferences = context.getSharedPreferences(preferenceName, Context.MODE_PRIVATE);
}
- protected String key(int keyId) {
- return context.getString(keyId);
- }
-
- public interface PollingActiveChangedListener {
- void onPollingActiveChanged(boolean isActive);
- }
-
- private final static String HIDDEN_PREFERENCE_AUTHOR_NAME = "authorName";
- private final static String HIDDEN_PREFERENCE_AUTHOR_PRIORITY = "authorPriority";
-
- private final static String HIDDEN_PREFERENCE_WIND_BEARING = "windBearingPref";
- private final static String HIDDEN_PREFERENCE_WIND_SPEED = "windSpeedPref";
-
- private final static String HIDDEN_PREFERENCE_BOAT_CLASS = "boatClassPref";
- private final static String HIDDEN_PREFERENCE_COURSE_LAYOUT = "courseLayoutPref";
- private final static String HIDDEN_PREFERENCE_NUMBER_OF_ROUNDS = "numberOfRoundsPref";
-
- public String getDeviceIdentifier() {
- String identifier = preferences.getString(key(R.string.preference_identifier_key), "");
- return identifier.isEmpty() ? Secure.getString(context.getContentResolver(), Secure.ANDROID_ID) : identifier;
- }
-
- public void setAuthor(RaceLogEventAuthor author) {
- preferences.edit().putString(HIDDEN_PREFERENCE_AUTHOR_NAME, author.getName()).commit();
- preferences.edit().putInt(HIDDEN_PREFERENCE_AUTHOR_PRIORITY, author.getPriority()).commit();
- }
-
public RaceLogEventAuthor getAuthor() {
String authorName = preferences.getString(HIDDEN_PREFERENCE_AUTHOR_NAME, "");
int authorPriority = preferences.getInt(HIDDEN_PREFERENCE_AUTHOR_PRIORITY, 0);
@@ -93,9 +88,14 @@ public class AppPreferences {
return BoatClassType.valueOf(boatClass);
}
- public void setBoatClass(BoatClassType boatClass) {
- String boatClassString = boatClass.name();
- preferences.edit().putString(HIDDEN_PREFERENCE_BOAT_CLASS, boatClassString).commit();
+ public List getByNameCourseDesignerCourseNames() {
+ Set values = preferences.getStringSet(
+ key(R.string.preference_course_designer_by_name_course_names_key), new HashSet());
+ return new ArrayList(values);
+ }
+
+ public Context getContext() {
+ return context;
}
public CourseLayouts getCourseLayout() {
@@ -113,9 +113,38 @@ public class AppPreferences {
return storedCourseLayout;
}
- public void setCourseLayout(CourseLayouts courseLayout) {
- String courseLayoutString = courseLayout.name();
- preferences.edit().putString(HIDDEN_PREFERENCE_COURSE_LAYOUT, courseLayoutString).commit();
+ public CourseDesignerMode getDefaultCourseDesignerMode() {
+ String mode = preferences.getString(key(R.string.preference_course_designer_override_key), "");
+ return CourseDesignerMode.valueOf(mode);
+ }
+
+ public RacingProcedureType getDefaultRacingProcedureType() {
+ String defaultStartProcedureType = preferences.getString(
+ key(R.string.preference_racing_procedure_override_key), "");
+ return RacingProcedureType.valueOf(defaultStartProcedureType);
+ }
+
+ public String getDeviceIdentifier() {
+ String identifier = preferences.getString(key(R.string.preference_identifier_key), "");
+ return identifier.isEmpty() ? Secure.getString(context.getContentResolver(), Secure.ANDROID_ID) : identifier;
+ }
+
+ public boolean getGateStartHasAdditionalGolfDownTime() {
+ return preferences.getBoolean(
+ key(R.string.preference_racing_procedure_gatestart_hasadditionalgolfdowntime_key), true);
+ }
+
+ public boolean getGateStartHasPathfinder() {
+ return preferences.getBoolean(key(R.string.preference_racing_procedure_gatestart_haspathfinder_key), true);
+ }
+
+ public String getMailRecipient() {
+ return preferences.getString(key(R.string.preference_mail_key), "");
+ }
+
+ public List getManagedCourseAreaNames() {
+ Set values = preferences.getStringSet(key(R.string.preference_course_areas_key), new HashSet());
+ return new ArrayList(values);
}
public NumberOfRounds getNumberOfRounds() {
@@ -125,64 +154,6 @@ public class AppPreferences {
return NumberOfRounds.valueOf(numberOfRounds);
}
- public void setNumberOfRounds(NumberOfRounds numberOfRounds) {
- String numberOfRoundsString = numberOfRounds.name();
- preferences.edit().putString(HIDDEN_PREFERENCE_NUMBER_OF_ROUNDS, numberOfRoundsString).commit();
- }
-
- public double getWindBearingFromDirection() {
- long windBearingAsLong = preferences.getLong(HIDDEN_PREFERENCE_WIND_BEARING, 0);
- return Double.longBitsToDouble(windBearingAsLong);
- }
-
- public void setWindBearingFromDirection(double enteredWindBearing) {
- long windBearingAsLong = Double.doubleToLongBits(enteredWindBearing);
- preferences.edit().putLong(HIDDEN_PREFERENCE_WIND_BEARING, windBearingAsLong).commit();
- }
-
- public double getWindSpeed() {
- long windSpeedAsLong = preferences.getLong(HIDDEN_PREFERENCE_WIND_SPEED, 0);
- return Double.longBitsToDouble(windSpeedAsLong);
- }
-
- public void setWindSpeed(double enteredWindSpeed) {
- long windSpeedAsLong = Double.doubleToLongBits(enteredWindSpeed);
- preferences.edit().putLong(HIDDEN_PREFERENCE_WIND_SPEED, windSpeedAsLong).commit();
- }
-
- public List getManagedCourseAreaNames() {
- Set values = preferences.getStringSet(key(R.string.preference_course_areas_key), new HashSet());
- return new ArrayList(values);
- }
-
- public void setManagedCourseAreaNames(List courseAreaNames) {
- preferences
- .edit()
- .putStringSet(key(R.string.preference_course_areas_key),
- new HashSet(courseAreaNames)).commit();
- }
-
- public String getServerBaseURL() {
- String value = preferences.getString(key(R.string.preference_server_url_key), "");
- if (value.equals("")) {
- return "http://localhost:8889";
- }
- return value;
- }
-
- public String getMailRecipient() {
- return preferences.getString(key(R.string.preference_mail_key), "");
- }
-
- public void setMailRecipient(String mail) {
- preferences.edit().putString(key(R.string.preference_mail_key), mail).commit();
- }
-
- public boolean isPollingActive() {
- return preferences.getBoolean(key(R.string.preference_polling_active_key), false);
- }
-
-
/**
* Gets polling interval in minutes
*/
@@ -190,91 +161,10 @@ public class AppPreferences {
return preferences.getInt(key(R.string.preference_polling_interval_key), 0);
}
- public RacingProcedureType getDefaultRacingProcedureType() {
- String defaultStartProcedureType = preferences.getString(key(R.string.preference_racing_procedure_override_key), "");
- return RacingProcedureType.valueOf(defaultStartProcedureType);
- }
-
- public void setDefaultRacingProcedureType(RacingProcedureType type) {
- preferences.edit().putString(key(R.string.preference_racing_procedure_override_key), type.name()).commit();
- }
-
- public CourseDesignerMode getDefaultCourseDesignerMode() {
- String mode = preferences.getString(key(R.string.preference_course_designer_override_key), "");
- return CourseDesignerMode.valueOf(mode);
- }
-
- public void setDefaultCourseDesignerMode(CourseDesignerMode mode) {
- preferences.edit().putString(key(R.string.preference_course_designer_override_key), mode.name()).commit();
- }
-
- public List getByNameCourseDesignerCourseNames() {
- Set values = preferences.getStringSet(key(R.string.preference_course_designer_by_name_course_names_key), new HashSet());
- return new ArrayList(values);
- }
-
- public void setByNameCourseDesignerCourseNames(List courseNames) {
- preferences
- .edit()
- .putStringSet(key(R.string.preference_course_designer_by_name_course_names_key),
- new HashSet(courseNames)).commit();
- }
-
- public void setRacingProcedureClassFlag(RacingProcedureType type, Flags flag) {
- String key = getRacingProcedureClassFlagKey(type);
- preferences.edit().putString(key, flag.name()).commit();
- }
-
public Flags getRacingProcedureClassFlag(RacingProcedureType type) {
String key = getRacingProcedureClassFlagKey(type);
return Flags.valueOf(preferences.getString(key, Flags.CLASS.name()));
}
-
- public void setRacingProcedureHasIndividualRecall(RacingProcedureType type, Boolean hasRecall) {
- String key = getRacingProcedureHasIndividualRecallKey(type);
- preferences.edit().putBoolean(key, hasRecall).commit();
- }
-
- public boolean getRacingProcedureHasIndividualRecall(RacingProcedureType type) {
- String key = getRacingProcedureHasIndividualRecallKey(type);
- return preferences.getBoolean(key, false);
- }
-
- public void setRRS26StartmodeFlags(Set flags) {
- Set flagNames = new HashSet();
- for (Flags flag : flags) {
- flagNames.add(flag.name());
- }
- preferences.edit().putStringSet(key(R.string.preference_racing_procedure_rrs26_startmode_flags_key), flagNames).commit();
- }
-
- public Set getRRS26StartmodeFlags() {
- Set flagNames = preferences.getStringSet(key(R.string.preference_racing_procedure_rrs26_startmode_flags_key), new HashSet());
- if (flagNames != null) {
- Set flags = new HashSet();
- for (String flagName : flagNames) {
- flags.add(Flags.valueOf(flagName));
- }
- return flags;
- }
- return null;
- }
-
- public void setGateStartHasPathfinder(boolean hasPathfinder) {
- preferences.edit().putBoolean(key(R.string.preference_racing_procedure_gatestart_haspathfinder_key), hasPathfinder).commit();
- }
-
- public boolean getGateStartHasPathfinder() {
- return preferences.getBoolean(key(R.string.preference_racing_procedure_gatestart_haspathfinder_key), true);
- }
-
- public void setGateStartHasAdditionalGolfDownTime(boolean hasAdditionalGolfDownTime) {
- preferences.edit().putBoolean(key(R.string.preference_racing_procedure_gatestart_hasadditionalgolfdowntime_key), hasAdditionalGolfDownTime).commit();
- }
-
- public boolean getGateStartHasAdditionalGolfDownTime() {
- return preferences.getBoolean(key(R.string.preference_racing_procedure_gatestart_hasadditionalgolfdowntime_key), true);
- }
private String getRacingProcedureClassFlagKey(RacingProcedureType type) {
switch (type) {
@@ -290,7 +180,12 @@ public class AppPreferences {
throw new IllegalArgumentException("Unknown racing procedure type.");
}
}
-
+
+ public boolean getRacingProcedureHasIndividualRecall(RacingProcedureType type) {
+ String key = getRacingProcedureHasIndividualRecallKey(type);
+ return preferences.getBoolean(key, false);
+ }
+
private String getRacingProcedureHasIndividualRecallKey(RacingProcedureType type) {
switch (type) {
case RRS26:
@@ -305,41 +200,159 @@ public class AppPreferences {
throw new IllegalArgumentException("Unknown racing procedure type.");
}
}
-
- private Set pollingActiveChangedListeners = new HashSet();
-
- private OnSharedPreferenceChangeListener pollingActiveChangedListener = new OnSharedPreferenceChangeListener() {
- @Override
- public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
- if (key(R.string.preference_polling_active_key).equals(key)) {
- for (PollingActiveChangedListener listener : pollingActiveChangedListeners) {
- listener.onPollingActiveChanged(isPollingActive());
- }
+
+ public Set getRRS26StartmodeFlags() {
+ Set flagNames = preferences.getStringSet(
+ key(R.string.preference_racing_procedure_rrs26_startmode_flags_key), new HashSet());
+ if (flagNames != null) {
+ Set flags = new HashSet();
+ for (String flagName : flagNames) {
+ flags.add(Flags.valueOf(flagName));
}
+ return flags;
}
- };
-
+ return null;
+ }
+
+ public String getServerBaseURL() {
+ String value = preferences.getString(key(R.string.preference_server_url_key), "");
+ if (value.equals("")) {
+ return "http://localhost:8889";
+ }
+ return value;
+ }
+
+ public double getWindBearingFromDirection() {
+ long windBearingAsLong = preferences.getLong(HIDDEN_PREFERENCE_WIND_BEARING, 0);
+ return Double.longBitsToDouble(windBearingAsLong);
+ }
+
+ public double getWindSpeed() {
+ long windSpeedAsLong = preferences.getLong(HIDDEN_PREFERENCE_WIND_SPEED, 0);
+ return Double.longBitsToDouble(windSpeedAsLong);
+ }
+
+ public boolean isPollingActive() {
+ return preferences.getBoolean(key(R.string.preference_polling_active_key), false);
+ }
+
+ public boolean isSendingActive() {
+ return preferences.getBoolean(context.getResources().getString(R.string.preference_isSendingActive_key),
+ context.getResources().getBoolean(R.bool.preference_isSendingActive_default));
+ }
+
+ protected String key(int keyId) {
+ return context.getString(keyId);
+ }
+
public void registerPollingActiveChangedListener(final PollingActiveChangedListener listener) {
if (pollingActiveChangedListeners.isEmpty()) {
preferences.registerOnSharedPreferenceChangeListener(pollingActiveChangedListener);
}
pollingActiveChangedListeners.add(listener);
}
-
+
+ public void setAuthor(RaceLogEventAuthor author) {
+ preferences.edit().putString(HIDDEN_PREFERENCE_AUTHOR_NAME, author.getName()).commit();
+ preferences.edit().putInt(HIDDEN_PREFERENCE_AUTHOR_PRIORITY, author.getPriority()).commit();
+ }
+
+ public void setBoatClass(BoatClassType boatClass) {
+ String boatClassString = boatClass.name();
+ preferences.edit().putString(HIDDEN_PREFERENCE_BOAT_CLASS, boatClassString).commit();
+ }
+
+ public void setByNameCourseDesignerCourseNames(List courseNames) {
+ preferences
+ .edit()
+ .putStringSet(key(R.string.preference_course_designer_by_name_course_names_key),
+ new HashSet(courseNames)).commit();
+ }
+
+ public void setCourseLayout(CourseLayouts courseLayout) {
+ String courseLayoutString = courseLayout.name();
+ preferences.edit().putString(HIDDEN_PREFERENCE_COURSE_LAYOUT, courseLayoutString).commit();
+ }
+
+ public void setDefaultCourseDesignerMode(CourseDesignerMode mode) {
+ preferences.edit().putString(key(R.string.preference_course_designer_override_key), mode.name()).commit();
+ }
+
+ public void setDefaultRacingProcedureType(RacingProcedureType type) {
+ preferences.edit().putString(key(R.string.preference_racing_procedure_override_key), type.name()).commit();
+ }
+
+ public void setGateStartHasAdditionalGolfDownTime(boolean hasAdditionalGolfDownTime) {
+ preferences
+ .edit()
+ .putBoolean(key(R.string.preference_racing_procedure_gatestart_hasadditionalgolfdowntime_key),
+ hasAdditionalGolfDownTime).commit();
+ }
+
+ public void setGateStartHasPathfinder(boolean hasPathfinder) {
+ preferences.edit()
+ .putBoolean(key(R.string.preference_racing_procedure_gatestart_haspathfinder_key), hasPathfinder)
+ .commit();
+ }
+
+ public void setMailRecipient(String mail) {
+ preferences.edit().putString(key(R.string.preference_mail_key), mail).commit();
+ }
+
+ public void setManagedCourseAreaNames(List courseAreaNames) {
+ preferences.edit()
+ .putStringSet(key(R.string.preference_course_areas_key), new HashSet(courseAreaNames)).commit();
+ }
+
+ public void setNumberOfRounds(NumberOfRounds numberOfRounds) {
+ String numberOfRoundsString = numberOfRounds.name();
+ preferences.edit().putString(HIDDEN_PREFERENCE_NUMBER_OF_ROUNDS, numberOfRoundsString).commit();
+ }
+
+ public void setRacingProcedureClassFlag(RacingProcedureType type, Flags flag) {
+ String key = getRacingProcedureClassFlagKey(type);
+ preferences.edit().putString(key, flag.name()).commit();
+ }
+
+ public void setRacingProcedureHasIndividualRecall(RacingProcedureType type, Boolean hasRecall) {
+ String key = getRacingProcedureHasIndividualRecallKey(type);
+ preferences.edit().putBoolean(key, hasRecall).commit();
+ }
+
+ public void setRRS26StartmodeFlags(Set flags) {
+ Set flagNames = new HashSet();
+ for (Flags flag : flags) {
+ flagNames.add(flag.name());
+ }
+ preferences.edit().putStringSet(key(R.string.preference_racing_procedure_rrs26_startmode_flags_key), flagNames)
+ .commit();
+ }
+
+ public void setSendingActive(boolean activate) {
+ preferences.edit()
+ .putBoolean(context.getResources().getString(R.string.preference_isSendingActive_key), activate)
+ .commit();
+ }
+
+ public void setWindBearingFromDirection(double enteredWindBearing) {
+ long windBearingAsLong = Double.doubleToLongBits(enteredWindBearing);
+ preferences.edit().putLong(HIDDEN_PREFERENCE_WIND_BEARING, windBearingAsLong).commit();
+ }
+
+ public void setWindSpeed(double enteredWindSpeed) {
+ long windSpeedAsLong = Double.doubleToLongBits(enteredWindSpeed);
+ preferences.edit().putLong(HIDDEN_PREFERENCE_WIND_SPEED, windSpeedAsLong).commit();
+ }
+
public void unregisterPollingActiveChangedListener(PollingActiveChangedListener listener) {
pollingActiveChangedListeners.remove(listener);
if (pollingActiveChangedListeners.isEmpty()) {
preferences.unregisterOnSharedPreferenceChangeListener(pollingActiveChangedListener);
}
}
-
- public boolean isSendingActive() {
- return preferences.getBoolean(context.getResources().getString(R.string.preference_isSendingActive_key),
- context.getResources().getBoolean(R.bool.preference_isSendingActive_default));
- }
-
- public void setSendingActive(boolean activate) {
- preferences.edit().putBoolean(context.getResources().getString(R.string.preference_isSendingActive_key),
- activate).commit();
+
+ public boolean wakelockEnabled() {
+ return preferences.getBoolean(context.getResources().getString(R.string.preference_wakelock_key), context
+ .getResources().getBoolean(R.bool.preference_wakelock_default));
}
}
diff --git a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/activities/BaseActivity.java b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/activities/BaseActivity.java
index 2deeccc120c..bbc7dd7b501 100644
--- a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/activities/BaseActivity.java
+++ b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/activities/BaseActivity.java
@@ -2,6 +2,7 @@ package com.sap.sailing.racecommittee.app.ui.activities;
import android.os.Bundle;
import android.view.MenuItem;
+import android.view.WindowManager;
import com.sap.sailing.android.shared.logging.ExLog;
import com.sap.sailing.racecommittee.app.AppPreferences;
@@ -17,17 +18,21 @@ public class BaseActivity extends SendingServiceAwareActivity {
protected AppPreferences preferences;
+ @Override
+ protected int getOptionsMenuResId() {
+ return R.menu.options_menu;
+ }
+
+ public RaceApplication getRaceApplication() {
+ return (RaceApplication) getApplication();
+ }
+
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.preferences = AppPreferences.on(getApplicationContext());
}
-
- protected boolean onReset() {
- fadeActivity(LoginActivity.class, true);
- return true;
- }
-
+
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
@@ -55,13 +60,26 @@ public class BaseActivity extends SendingServiceAwareActivity {
return super.onOptionsItemSelected(item);
}
}
-
- public RaceApplication getRaceApplication() {
- return (RaceApplication) getApplication();
- }
@Override
- protected int getOptionsMenuResId() {
- return R.menu.options_menu;
+ public void onPause() {
+ super.onPause();
+
+ getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
+ }
+
+ protected boolean onReset() {
+ fadeActivity(LoginActivity.class, true);
+ return true;
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+
+ preferences = AppPreferences.on(this);
+ if (preferences.wakelockEnabled()) {
+ getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
+ }
}
}
diff --git a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/activities/LoginActivity.java b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/activities/LoginActivity.java
index 2d2339c4e45..a154e9e6369 100755
--- a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/activities/LoginActivity.java
+++ b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/activities/LoginActivity.java
@@ -41,27 +41,162 @@ import com.sap.sailing.racecommittee.app.utils.autoupdate.AutoUpdater;
public class LoginActivity extends BaseActivity implements EventSelectedListenerHost, CourseAreaSelectedListenerHost,
DialogListenerHost {
- private final static String TAG = LoginActivity.class.getName();
-
private final static String CourseAreaListFragmentTag = "CourseAreaListFragmentTag";
- private LoginDialog loginDialog;
- private CourseArea selectedCourseArea;
+ private final static String TAG = LoginActivity.class.getName();
+
+ private ItemSelectedListener courseAreaSelectionListener = new ItemSelectedListener() {
+
+ public void itemSelected(Fragment sender, CourseArea courseArea) {
+ ExLog.i(LoginActivity.this, TAG, "Starting view for " + courseArea.getName());
+ ExLog.i(LoginActivity.this, LogEvent.COURSE_SELECTED, courseArea.getName());
+ selectCourseArea(courseArea);
+ }
+ };
+ private ItemSelectedListener eventSelectionListener = new ItemSelectedListener() {
+
+ public void itemSelected(Fragment sender, EventBase event) {
+ final Serializable eventId = event.getId();
+ ExLog.i(LoginActivity.this, LogEvent.EVENT_SELECTED, eventId.toString());
+
+ setProgressBarIndeterminateVisibility(true);
+ final ProgressDialog progressDialog = new ProgressDialog(LoginActivity.this);
+ progressDialog.setMessage(getString(R.string.loading_configuration));
+ progressDialog.setCancelable(false);
+ progressDialog.setIndeterminate(true);
+ progressDialog.show();
+
+ ReadonlyDataManager dataManager = OnlineDataManager.create(LoginActivity.this);
+ DeviceConfigurationIdentifier identifier = new DeviceConfigurationIdentifierImpl(AppPreferences.on(
+ getApplicationContext()).getDeviceIdentifier());
+
+ LoaderCallbacks> configurationLoader = dataManager.createConfigurationLoader(identifier,
+ new LoadClient() {
+
+ @Override
+ public void onLoadFailed(Exception reason) {
+ setProgressBarIndeterminateVisibility(false);
+ progressDialog.dismiss();
+
+ if (reason instanceof FileNotFoundException) {
+ Toast.makeText(getApplicationContext(),
+ getString(R.string.loading_configuration_not_found), Toast.LENGTH_LONG).show();
+ ExLog.w(LoginActivity.this,
+ TAG,
+ String.format("There seems to be no configuration for this device: %s",
+ reason.toString()));
+ } else {
+ Toast.makeText(getApplicationContext(),
+ getString(R.string.loading_configuration_failed), Toast.LENGTH_LONG).show();
+ ExLog.ex(LoginActivity.this, TAG, reason);
+ }
+
+ showCourseAreaListFragment(eventId);
+ }
+
+ @Override
+ public void onLoadSucceded(DeviceConfiguration configuration, boolean isCached) {
+ setProgressBarIndeterminateVisibility(false);
+ progressDialog.dismiss();
+
+ // this is our 'global' configuration, let's store it in app preferences
+ PreferencesDeviceConfigurationLoader.wrap(configuration, preferences).store();
+
+ Toast.makeText(getApplicationContext(), getString(R.string.loading_configuration_succeded),
+ Toast.LENGTH_LONG).show();
+ showCourseAreaListFragment(eventId);
+ }
+ });
+ // always reload the configuration...
+ getLoaderManager().restartLoader(0, null, configurationLoader).forceLoad();
+ }
+ };
+
+
+ private LoginDialog mLoginDialog;
private ProgressBar mProgressSpinner;
+ private CourseArea mSelectedCourseArea;
+
+ private Serializable mSelectedEvent;
+
public LoginActivity() {
- this.loginDialog = new LoginDialog();
- this.selectedCourseArea = null;
+ mLoginDialog = new LoginDialog();
+ mSelectedCourseArea = null;
+ }
+
+ private void addCourseAreaListFragment(Serializable eventId) {
+ Bundle args = new Bundle();
+ args.putSerializable(AppConstants.EventIdTag, eventId);
+ mSelectedEvent = eventId;
+
+ Fragment fragment = new CourseAreaListFragment();
+ fragment.setArguments(args);
+ FragmentTransaction transaction = getFragmentManager().beginTransaction();
+ transaction.setCustomAnimations(R.animator.slide_in, R.animator.slide_out);
+ transaction.replace(R.id.login_view_right_container, fragment, CourseAreaListFragmentTag);
+ transaction.commitAllowingStateLoss();
+ ExLog.i(this, "LoginActivity", "CourseFragment created.");
+ }
+
+ private void addEventListFragment() {
+ FragmentTransaction transaction = getFragmentManager().beginTransaction();
+ transaction.replace(R.id.login_view_left_container, new EventListFragment());
+ transaction.setTransition(FragmentTransaction.TRANSIT_NONE);
+ transaction.commit();
+ }
+
+ public ItemSelectedListener getCourseAreaSelectionListener() {
+ return courseAreaSelectionListener;
+ }
+
+ public ItemSelectedListener getEventSelectionListener() {
+ return eventSelectionListener;
}
@Override
- protected boolean onReset() {
- Fragment courseAreaFragment = getFragmentManager().findFragmentByTag(CourseAreaListFragmentTag);
- if (courseAreaFragment != null) {
- getFragmentManager().beginTransaction().remove(courseAreaFragment).commit();
- }
- recreate();
- return true;
+ public DialogResultListener getListener() {
+ return new DialogResultListener() {
+
+ @Override
+ public void onDialogNegativeButton(AttachedDialogFragment dialog) {
+ /* nothing here... */
+ }
+
+ @Override
+ public void onDialogPositiveButton(AttachedDialogFragment dialog) {
+ // We have to take the passed instance, LoginActivity.this might be a new instance!
+ LoginDialog localLoginDialog = (LoginDialog) dialog;
+ switch (localLoginDialog.getSelectedLoginType()) {
+ case OFFICER:
+ ExLog.i(LoginActivity.this, TAG, "Communication with backend is active.");
+ preferences.setSendingActive(true);
+ break;
+ case VIEWER:
+ ExLog.i(LoginActivity.this, TAG, "Communication with backend is inactive.");
+ preferences.setSendingActive(false);
+ break;
+ default:
+ ExLog.i(LoginActivity.this, TAG, "An invalid log type, e.g. NONE, was selected");
+ Toast.makeText(LoginActivity.this, getString(R.string.please_select_a_login_type),
+ Toast.LENGTH_LONG).show();
+ return;
+ }
+ preferences.setAuthor(localLoginDialog.getAuthor());
+
+ if (mSelectedCourseArea == null) {
+ Toast.makeText(LoginActivity.this, "The selected course area was lost.", Toast.LENGTH_LONG).show();
+ ExLog.e(LoginActivity.this, TAG,
+ "Course area reference was not set - cannot start racing activity.");
+ return;
+ }
+
+ Intent message = new Intent(LoginActivity.this, RacingActivity.class);
+ message.putExtra(AppConstants.COURSE_AREA_UUID_KEY, mSelectedCourseArea.getId());
+ message.putExtra(AppConstants.EventIdTag, mSelectedEvent);
+ fadeActivity(message);
+ }
+ };
}
/** Called when the activity is first created. */
@@ -90,159 +225,26 @@ public class LoginActivity extends BaseActivity implements EventSelectedListener
new AutoUpdater(this).notifyAfterUpdate();
}
- private void addEventListFragment() {
- FragmentTransaction transaction = getFragmentManager().beginTransaction();
- transaction.replace(R.id.login_view_left_container, new EventListFragment());
- transaction.setTransition(FragmentTransaction.TRANSIT_NONE);
- transaction.commit();
- }
-
- private void addCourseAreaListFragment(Serializable eventId) {
- Bundle args = new Bundle();
- args.putSerializable(AppConstants.EventIdTag, eventId);
-
- Fragment fragment = new CourseAreaListFragment();
- fragment.setArguments(args);
- FragmentTransaction transaction = getFragmentManager().beginTransaction();
- transaction.setCustomAnimations(R.animator.slide_in, R.animator.slide_out);
- transaction.replace(R.id.login_view_right_container, fragment, CourseAreaListFragmentTag);
- transaction.commitAllowingStateLoss();
- ExLog.i(this, "LoginActivity", "CourseFragment created.");
- }
-
- private ItemSelectedListener eventSelectionListener = new ItemSelectedListener() {
-
- public void itemSelected(Fragment sender, EventBase event) {
- final Serializable eventId = event.getId();
- ExLog.i(LoginActivity.this, LogEvent.EVENT_SELECTED, eventId.toString());
-
- setProgressBarIndeterminateVisibility(true);
- final ProgressDialog progressDialog = new ProgressDialog(LoginActivity.this);
- progressDialog.setMessage(getString(R.string.loading_configuration));
- progressDialog.setCancelable(false);
- progressDialog.setIndeterminate(true);
- progressDialog.show();
-
- ReadonlyDataManager dataManager = OnlineDataManager.create(LoginActivity.this);
- DeviceConfigurationIdentifier identifier = new DeviceConfigurationIdentifierImpl(AppPreferences.on(
- getApplicationContext()).getDeviceIdentifier());
-
- LoaderCallbacks> configurationLoader = dataManager.createConfigurationLoader(identifier,
- new LoadClient() {
-
- @Override
- public void onLoadSucceded(DeviceConfiguration configuration, boolean isCached) {
- setProgressBarIndeterminateVisibility(false);
- progressDialog.dismiss();
-
- // this is our 'global' configuration, let's store it in app preferences
- PreferencesDeviceConfigurationLoader.wrap(configuration, preferences).store();
-
- Toast.makeText(getApplicationContext(), getString(R.string.loading_configuration_succeded),
- Toast.LENGTH_LONG).show();
- showCourseAreaListFragment(eventId);
- }
-
- @Override
- public void onLoadFailed(Exception reason) {
- setProgressBarIndeterminateVisibility(false);
- progressDialog.dismiss();
-
- if (reason instanceof FileNotFoundException) {
- Toast.makeText(getApplicationContext(),
- getString(R.string.loading_configuration_not_found), Toast.LENGTH_LONG).show();
- ExLog.w(LoginActivity.this,
- TAG,
- String.format("There seems to be no configuration for this device: %s",
- reason.toString()));
- } else {
- Toast.makeText(getApplicationContext(),
- getString(R.string.loading_configuration_failed), Toast.LENGTH_LONG).show();
- ExLog.ex(LoginActivity.this, TAG, reason);
- }
-
- showCourseAreaListFragment(eventId);
- }
- });
- // always reload the configuration...
- getLoaderManager().restartLoader(0, null, configurationLoader).forceLoad();
- }
- };
-
- public ItemSelectedListener getEventSelectionListener() {
- return eventSelectionListener;
- }
-
- private void showCourseAreaListFragment(Serializable eventId) {
- addCourseAreaListFragment(eventId);
- }
-
- private ItemSelectedListener courseAreaSelectionListener = new ItemSelectedListener() {
-
- public void itemSelected(Fragment sender, CourseArea courseArea) {
- ExLog.i(LoginActivity.this, TAG, "Starting view for " + courseArea.getName());
- ExLog.i(LoginActivity.this, LogEvent.COURSE_SELECTED, courseArea.getName());
- selectCourseArea(courseArea);
- }
- };
-
- public ItemSelectedListener getCourseAreaSelectionListener() {
- return courseAreaSelectionListener;
- }
-
- private void selectCourseArea(CourseArea courseArea) {
- selectedCourseArea = courseArea;
- loginDialog.show(getFragmentManager(), "LoginDialog");
- }
-
@Override
- public DialogResultListener getListener() {
- return new DialogResultListener() {
-
- @Override
- public void onDialogPositiveButton(AttachedDialogFragment dialog) {
- // We have to take the passed instance, LoginActivity.this might be a new instance!
- LoginDialog localLoginDialog = (LoginDialog) dialog;
- switch (localLoginDialog.getSelectedLoginType()) {
- case OFFICER:
- ExLog.i(LoginActivity.this, TAG, "Communication with backend is active.");
- preferences.setSendingActive(true);
- break;
- case VIEWER:
- ExLog.i(LoginActivity.this, TAG, "Communication with backend is inactive.");
- preferences.setSendingActive(false);
- break;
- default:
- ExLog.i(LoginActivity.this, TAG, "An invalid log type, e.g. NONE, was selected");
- Toast.makeText(LoginActivity.this, getString(R.string.please_select_a_login_type),
- Toast.LENGTH_LONG).show();
- return;
- }
- preferences.setAuthor(localLoginDialog.getAuthor());
-
- if (selectedCourseArea == null) {
- Toast.makeText(LoginActivity.this, "The selected course area was lost.", Toast.LENGTH_LONG).show();
- ExLog.e(LoginActivity.this, TAG,
- "Course area reference was not set - cannot start racing activity.");
- return;
- }
-
- Intent message = new Intent(LoginActivity.this, RacingActivity.class);
- message.putExtra(AppConstants.COURSE_AREA_UUID_KEY, selectedCourseArea.getId());
- fadeActivity(message);
- }
-
- @Override
- public void onDialogNegativeButton(AttachedDialogFragment dialog) {
- /* nothing here... */
- }
- };
+ protected boolean onReset() {
+ Fragment courseAreaFragment = getFragmentManager().findFragmentByTag(CourseAreaListFragmentTag);
+ if (courseAreaFragment != null) {
+ getFragmentManager().beginTransaction().remove(courseAreaFragment).commit();
+ }
+ recreate();
+ return true;
}
-
+
+
+ private void selectCourseArea(CourseArea courseArea) {
+ mSelectedCourseArea = courseArea;
+ mLoginDialog.show(getFragmentManager(), "LoginDialog");
+ }
+
@Override
public void setSupportProgressBarIndeterminateVisibility(boolean visible) {
super.setSupportProgressBarIndeterminateVisibility(visible);
-
+
if (mProgressSpinner != null) {
if (visible) {
mProgressSpinner.setVisibility(View.VISIBLE);
@@ -251,4 +253,8 @@ public class LoginActivity extends BaseActivity implements EventSelectedListener
}
}
}
+
+ private void showCourseAreaListFragment(Serializable eventId) {
+ addCourseAreaListFragment(eventId);
+ }
}
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 6b613bded10..b199e7e5ccd 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
@@ -7,6 +7,7 @@ import java.util.Collection;
import android.annotation.SuppressLint;
import android.app.AlertDialog;
+import android.app.Fragment;
import android.app.FragmentTransaction;
import android.content.DialogInterface;
import android.content.Intent;
@@ -42,6 +43,7 @@ import com.sap.sailing.racecommittee.app.ui.fragments.NavigationDrawerFragment;
import com.sap.sailing.racecommittee.app.ui.fragments.NavigationDrawerFragment.NavigationDrawerCallbacks;
import com.sap.sailing.racecommittee.app.ui.fragments.RaceFragment;
import com.sap.sailing.racecommittee.app.ui.fragments.RaceInfoFragment;
+import com.sap.sailing.racecommittee.app.ui.fragments.WelcomeFragment;
import com.sap.sailing.racecommittee.app.ui.fragments.WindFragment;
import com.sap.sailing.racecommittee.app.ui.fragments.raceinfo.RaceInfoListener;
import com.sap.sailing.racecommittee.app.utils.TickListener;
@@ -101,20 +103,21 @@ public class RacingActivity extends SessionActivity implements RaceInfoListener,
}
}
+
+ private static ProgressBar mProgressSpinner;
private static final int RacesLoaderId = 0;
private static final String TAG = RacingActivity.class.getName();
- private static ProgressBar mProgressSpinner;
+ private Button currentTime;
private ReadonlyDataManager dataManager;
private RaceInfoFragment infoFragment;
- private WindFragment windFragment;
+ private Wind mWind;
private NavigationDrawerFragment navDrawerFragment;
private ManagedRace selectedRace;
- private Button currentTime;
private Button windButton;
- private Wind mWind;
+ private WindFragment windFragment;
private Serializable getCourseAreaIdFromIntent() {
if (getIntent() == null || getIntent().getExtras() == null) {
@@ -130,6 +133,19 @@ public class RacingActivity extends SessionActivity implements RaceInfoListener,
return courseId;
}
+ private Serializable getEventIdFromItent() {
+ if (getIntent() == null || getIntent().getExtras() == null) {
+ Log.e(getClass().getName(), "Expected an intent carrying event extras.");
+ }
+
+ final Serializable eventId = getIntent().getExtras().getSerializable(AppConstants.EventIdTag);
+ if (eventId == null) {
+ Log.e(getClass().getName(), "Expected an intent carrying the event id.");
+ return null;
+ }
+ return eventId;
+ }
+
private void loadRaces(final CourseArea courseArea) {
setSupportProgressBarIndeterminateVisibility(true);
@@ -148,6 +164,10 @@ public class RacingActivity extends SessionActivity implements RaceInfoListener,
}
}
+ public void logout() {
+ logoutSession();
+ }
+
@SuppressLint("SimpleDateFormat")
@Override
public void notifyTick() {
@@ -157,25 +177,25 @@ public class RacingActivity extends SessionActivity implements RaceInfoListener,
}
}
-
@Override
public void onBackPressed() {
- if (getFragmentManager().getBackStackEntryCount() > 0) {
- getFragmentManager().popBackStackImmediate();
- getFragmentManager().beginTransaction().commit();
-
- // fix for filled out RaceInfoFragment
- if ( infoFragment != null && infoFragment.isFragmentUIActive() && selectedRace != null){
- ExLog.i(this, this.getClass().getCanonicalName(), "Returning to RaceInfoFragment");
- getFragmentManager().popBackStackImmediate();
-
- onRaceItemClicked(selectedRace);
- }
+ Fragment fragment = getFragmentManager().findFragmentById(R.id.racing_view_right_container);
+ if (!(fragment instanceof RaceInfoFragment || fragment instanceof WelcomeFragment)) {
+ if (getFragmentManager().getBackStackEntryCount() > 0) {
+ getFragmentManager().popBackStackImmediate();
+ getFragmentManager().beginTransaction().commit();
+
+ // fix for filled out RaceInfoFragment
+ if (infoFragment != null && infoFragment.isFragmentUIActive() && selectedRace != null) {
+ ExLog.i(this, this.getClass().getCanonicalName(), "Returning to RaceInfoFragment");
+ getFragmentManager().popBackStackImmediate();
+ onRaceItemClicked(selectedRace);
+ }
+ }
} else {
logoutSession();
- }
+ }
}
-
@Override
public void onClick(View view) {
@@ -189,27 +209,6 @@ public class RacingActivity extends SessionActivity implements RaceInfoListener,
}
}
-
- public void onWindEntered(Wind windFix){
- if ( windFix != null ){
- windButton.setText(String.format(getString(R.string.wind_info), windFix.getKnots(), windFix.getBearing().reverse().toString()));
- if (selectedRace != null) {
- selectedRace.getState().setWindFix(MillisecondsTimePoint.now(), windFix);
- }
-
- mWind = windFix;
- }
-
- getFragmentManager().popBackStackImmediate();
-
- if (infoFragment != null && infoFragment.isFragmentUIActive()) {
- ExLog.i(this, this.getClass().getCanonicalName(), "Returning to RaceInfoFragment from WindFragment");
- getFragmentManager().popBackStackImmediate();
-
- onRaceItemClicked(selectedRace);
- }
- }
-
@Override
public void onCreate(Bundle savedInstanceState) {
// features must be requested before anything else
@@ -258,6 +257,17 @@ public class RacingActivity extends SessionActivity implements RaceInfoListener,
onWindEntered(mWind);
}
}
+
+ Serializable eventId = getEventIdFromItent();
+ if (eventId == null) {
+ throw new IllegalStateException("There was no event id transmitted...");
+ }
+ getFragmentManager()
+ .beginTransaction()
+ .replace(R.id.racing_view_right_container,
+ new WelcomeFragment(dataManager.getDataStore(), courseAreaId, eventId, preferences.getAuthor()))
+ .commit();
+
}
@Override
@@ -293,6 +303,13 @@ public class RacingActivity extends SessionActivity implements RaceInfoListener,
infoFragment.onResetTime();
}
+ @Override
+ public void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+
+ outState.putSerializable("wind", mWind);
+ }
+
@Override
public void onStart() {
super.onStart();
@@ -308,11 +325,25 @@ public class RacingActivity extends SessionActivity implements RaceInfoListener,
TickSingleton.INSTANCE.unregisterListener(this);
}
- @Override
- public void onSaveInstanceState(Bundle outState) {
- super.onSaveInstanceState(outState);
+ public void onWindEntered(Wind windFix) {
+ if (windFix != null) {
+ windButton.setText(String.format(getString(R.string.wind_info), windFix.getKnots(), windFix.getBearing()
+ .reverse().toString()));
+ if (selectedRace != null) {
+ selectedRace.getState().setWindFix(MillisecondsTimePoint.now(), windFix);
+ }
- outState.putSerializable("wind", mWind);
+ mWind = windFix;
+ }
+
+ getFragmentManager().popBackStackImmediate();
+
+ if (infoFragment != null && infoFragment.isFragmentUIActive()) {
+ ExLog.i(this, this.getClass().getCanonicalName(), "Returning to RaceInfoFragment from WindFragment");
+ getFragmentManager().popBackStackImmediate();
+
+ onRaceItemClicked(selectedRace);
+ }
}
private void registerOnService(Collection races) {
@@ -327,14 +358,6 @@ public class RacingActivity extends SessionActivity implements RaceInfoListener,
}
}
- private void setupActionBar(CourseArea courseArea) {
- RaceLogEventAuthor author = preferences.getAuthor();
- String title = String.format(getString(R.string.racingview_header), courseArea.getName());
- title += " (" + author.getName() + ")";
-
- getSupportActionBar().setTitle(title);
- }
-
@Override
public void setSupportProgressBarIndeterminateVisibility(boolean visible) {
super.setSupportProgressBarIndeterminateVisibility(visible);
@@ -347,4 +370,12 @@ public class RacingActivity extends SessionActivity implements RaceInfoListener,
}
}
}
+
+ private void setupActionBar(CourseArea courseArea) {
+ RaceLogEventAuthor author = preferences.getAuthor();
+ String title = String.format(getString(R.string.racingview_header), courseArea.getName());
+ title += " (" + author.getName() + ")";
+
+ getSupportActionBar().setTitle(title);
+ }
}
diff --git a/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/fragments/WelcomeFragment.java b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/fragments/WelcomeFragment.java
new file mode 100644
index 00000000000..a8d26de10f7
--- /dev/null
+++ b/mobile/com.sap.sailing.racecommittee.app/src/com/sap/sailing/racecommittee/app/ui/fragments/WelcomeFragment.java
@@ -0,0 +1,68 @@
+package com.sap.sailing.racecommittee.app.ui.fragments;
+
+import java.io.Serializable;
+
+import android.app.Fragment;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.view.ViewGroup;
+import android.widget.Button;
+import android.widget.TextView;
+
+import com.sap.sailing.android.shared.util.ViewHolder;
+import com.sap.sailing.domain.base.CourseArea;
+import com.sap.sailing.domain.base.EventBase;
+import com.sap.sailing.domain.racelog.RaceLogEventAuthor;
+import com.sap.sailing.racecommittee.app.R;
+import com.sap.sailing.racecommittee.app.data.DataStore;
+import com.sap.sailing.racecommittee.app.ui.activities.RacingActivity;
+
+public class WelcomeFragment extends Fragment implements OnClickListener {
+
+ private static CourseArea mCourseArea;
+ private static EventBase mEvent;
+ private static RaceLogEventAuthor mEventAuthor;
+
+ public WelcomeFragment() {
+ // needed for screen rotation
+ }
+
+ public WelcomeFragment(DataStore dataStore, Serializable courseAreaId, Serializable eventId,
+ RaceLogEventAuthor raceLogEventAuthor) {
+ mCourseArea = dataStore.getCourseArea(courseAreaId);
+ mEvent = dataStore.getEvent(eventId);
+ mEventAuthor = raceLogEventAuthor;
+ }
+
+ @Override
+ public void onClick(View v) {
+ ((RacingActivity) getActivity()).logout();
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+ View view = inflater.inflate(R.layout.welcome_fragment, container, false);
+
+ TextView event_name = ViewHolder.get(view, R.id.event_name);
+ if (event_name != null) {
+ event_name.setText(mEvent.getName());
+ }
+ TextView area_name = ViewHolder.get(view, R.id.area_name);
+ if (area_name != null) {
+ area_name.setText(mCourseArea.getName());
+ }
+ TextView position = ViewHolder.get(view, R.id.position);
+ if (position != null) {
+ position.setText(mEventAuthor.getName());
+ }
+
+ Button logout = ViewHolder.get(view, R.id.logout);
+ if (logout != null) {
+ logout.setOnClickListener(this);
+ }
+
+ return view;
+ }
+}