refactor generic settings architecture to android.shared and implement settings for tracking app

This commit is contained in:
Fredrik Teschke
2014-10-07 02:15:31 +02:00
parent 550beaab2a
commit 8d94f70410
51 changed files with 447 additions and 215 deletions

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

@@ -1,4 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools">
<string name="options_menu_live">Verbindungsinformationen</string>
<string name="remove">Entfernen</string>
<string name="enter_new_item">Neues Element eingeben</string>
<string name="add">Hinzufügen</string>
<string name="there_are_no_items_yet_">Bisher keine Elemente.</string>
<!-- Generic -->
<string name="generic_error">Fehler</string>
</resources>
@@ -9,6 +9,9 @@
<string name="preference_server_url_key">webserviceUrlPref</string>
<string name="preference_server_url_default">http://dev.sapsailing.com/</string>
<string name="preference_enableLifecycleLogging_key">enableLifecycleLogging</string>
<bool name="preference_enableLifecycleLogging_default">false</bool>
<!-- the following strings should be overridden by apps using this library (e.g. in their own preferences.xml -->
<string name="app_folder">com.sap.sailing</string>
<string name="intent_send_saved_intents">com.sap.sailing.android.shared.action.sendSavedIntents</string>
@@ -1,4 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools">
<string name="options_menu_live">Connection Information</string>
<string name="remove">Remove</string>
<string name="enter_new_item">Enter new item</string>
<string name="add">Add</string>
<string name="there_are_no_items_yet_">There are no items yet.</string>
<!-- SystemInformationActivity -->
<string name="application_information" translatable="false">Application Information</string>
<string name="application_identifier" translatable="false">Identifier</string>
<string name="application_install_date" translatable="false">Install Date</string>
<string name="persistence_information" translatable="false">Persistence Status</string>
<string name="persistence_waiting_clear_events" translatable="false">Clear events</string>
<string name="persistence_waiting_events" translatable="false">Waiting events</string>
<string name="application_version" translatable="false">Version</string>
<!-- Generic -->
<string name="empty"></string>
<string name="generic_error">Error</string>
</resources>
@@ -0,0 +1,49 @@
package com.sap.sailing.android.shared.application;
import java.lang.ref.WeakReference;
import android.app.Application;
import android.content.Context;
import android.content.Intent;
import com.sap.sailing.android.shared.R;
import com.sap.sailing.android.shared.logging.ExLog;
import com.sap.sailing.android.shared.logging.LifecycleLogger;
import com.sap.sailing.android.shared.logging.LoggingExceptionHandler;
import com.sap.sailing.android.shared.util.PrefUtils;
/**
* <p>Registers an additional exception handler for uncaught exception to have some crash logging.</p>
* <p>Offers a static {@link StringContext} to handle i18n in ugly cases.</p>
* <p>Sets the default preference values (if not set)</p>
*/
public class LoggableApplication extends Application {
private final static String TAG = LoggableApplication.class.getName();
private static StringContext stringContext;
public static StringContext getStringContext() {
return stringContext;
}
@Override
public void onCreate() {
super.onCreate();
ExLog.i(this, TAG, "Application is starting.");
Thread.setDefaultUncaughtExceptionHandler(new LoggingExceptionHandler(Thread
.getDefaultUncaughtExceptionHandler(), this));
LifecycleLogger.enableLifecycleLogging(PrefUtils.getBoolean(this, R.string.preference_enableLifecycleLogging_key,
R.bool.preference_enableLifecycleLogging_default));
stringContext = new StringContext(new WeakReference<Context>(getApplicationContext()));
}
public static void restartApp(Context context) {
Intent i = context.getPackageManager().getLaunchIntentForPackage(context.getPackageName());
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
context.startActivity(i);
}
}
@@ -1,4 +1,4 @@
package com.sap.sailing.racecommittee.app;
package com.sap.sailing.android.shared.application;
import java.lang.ref.WeakReference;
@@ -1,4 +1,4 @@
package com.sap.sailing.racecommittee.app.utils;
package com.sap.sailing.android.shared.logging;
import java.lang.Thread.UncaughtExceptionHandler;
import java.util.Date;
@@ -6,8 +6,6 @@ import java.util.Date;
import android.content.Context;
import android.util.Log;
import com.sap.sailing.android.shared.logging.FileLoggingTask;
public class LoggingExceptionHandler implements UncaughtExceptionHandler {
private static final String TAG = LoggingExceptionHandler.class.getName();
@@ -0,0 +1,39 @@
package com.sap.sailing.android.shared.ui.activities;
import android.content.Intent;
import android.view.MenuItem;
import com.sap.sailing.android.shared.logging.ExLog;
public class ResilientActivity extends LoggableActivity {
private static final String TAG = ResilientActivity.class.getName();
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
ExLog.i(this, TAG, "Clicked HOME.");
return onHomeClicked();
default:
return super.onOptionsItemSelected(item);
}
}
protected boolean onHomeClicked() {
return false;
}
protected void fadeActivity(Class<?> activity, boolean newTopTask) {
Intent intent = new Intent(getBaseContext(), activity);
if (newTopTask) {
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
}
fadeActivity(intent);
}
protected void fadeActivity(Intent intent) {
startActivity(intent);
overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out);
}
}
@@ -19,7 +19,7 @@ import com.sap.sailing.android.shared.services.sending.MessageSendingService.Mes
import com.sap.sailing.android.shared.services.sending.MessageSendingService.MessageSendingServiceLogger;
import com.sap.sailing.android.shared.util.PrefUtils;
public abstract class SendingServiceAwareActivity extends LoggableActivity {
public abstract class SendingServiceAwareActivity extends ResilientActivity {
private class MessageSendingServiceConnection implements ServiceConnection, MessageSendingServiceLogger {
@Override
@@ -0,0 +1,88 @@
package com.sap.sailing.android.shared.ui.activities;
import java.util.Date;
import android.content.pm.PackageInfo;
import android.text.format.DateFormat;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import com.sap.sailing.android.shared.R;
import com.sap.sailing.android.shared.util.AppUtils;
public class SystemInformationActivityHelper {
private final SendingServiceAwareActivity activity;
public SystemInformationActivityHelper(SendingServiceAwareActivity activity, String deviceIdentifier) {
this.activity = activity;
activity.setContentView(R.layout.system_information_view);
setupVersionView(deviceIdentifier);
setupInstalledView();
setupPersistenceView();
}
/**
* Override the SendingServiceInformation with this content, and then call parent.
*/
public void updateSendingServiceInformation() {
TextView statusView = (TextView) activity.findViewById(R.id.system_information_persistence_status);
ListView waitingView = (ListView) activity.findViewById(R.id.system_information_persistence_waiting);
if (activity.boundSendingService) {
Date lastSuccessfulSend = activity.sendingService.getLastSuccessfulSend();
statusView.setText(String.format("Currently %d events waiting to be sent.\nLast successful sent was at: %s.",
activity.sendingService.getDelayedIntentsCount(), lastSuccessfulSend == null ? "never" : lastSuccessfulSend));
waitingView.setAdapter(new ArrayAdapter<String>(activity,
android.R.layout.simple_list_item_1,
activity.sendingService.getDelayedIntensContent()));
} else {
statusView.setText(activity.getString(R.string.generic_error));
}
}
private void setupPersistenceView() {
// status and list view is updated by updateSendingServiceInformation
Button clearButton = (Button) activity.findViewById(R.id.system_information_persistence_clear);
clearButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
if (activity.boundSendingService) {
activity.sendingService.clearDelayedIntents();
} else {
Toast.makeText(activity.getApplicationContext(), "", Toast.LENGTH_SHORT).show();
}
}
});
}
private void setupVersionView(String deviceIdentifier) {
TextView identifierView = (TextView) activity.findViewById(R.id.system_information_application_identifier);
identifierView.setText(deviceIdentifier);
TextView versionView = (TextView) activity.findViewById(R.id.system_information_application_version);
PackageInfo info = AppUtils.getPackageInfo(activity);
if (info == null) {
versionView.setText(activity.getString(R.string.generic_error));
} else {
versionView.setText(String.format("%s (Code %s)", info.versionName, info.versionCode));
}
}
private void setupInstalledView() {
TextView installView = (TextView) activity.findViewById(R.id.system_information_application_install);
PackageInfo info = AppUtils.getPackageInfo(activity.getApplication());
if (info == null) {
installView.setText(activity.getString(R.string.generic_error));
} else {
Date installDate = new Date(info.lastUpdateTime);
installView.setText(String.format("%s - %s", DateFormat.getLongDateFormat(activity).format(installDate),
DateFormat.getTimeFormat(activity).format(installDate)));
}
}
}
@@ -1,4 +1,4 @@
package com.sap.sailing.racecommittee.app.ui.adapters;
package com.sap.sailing.android.shared.ui.adapters;
import java.util.List;
@@ -11,7 +11,7 @@ import android.widget.ArrayAdapter;
import android.widget.ImageButton;
import android.widget.TextView;
import com.sap.sailing.racecommittee.app.R;
import com.sap.sailing.android.shared.R;
public class ArrayRemoveAdapter<T> extends ArrayAdapter<T> {
@@ -1,4 +1,4 @@
package com.sap.sailing.racecommittee.app.ui.fragments.preference;
package com.sap.sailing.android.shared.ui.fragments.preference;
import java.util.ArrayList;
import java.util.Collections;
@@ -14,8 +14,8 @@ import android.preference.Preference.OnPreferenceChangeListener;
import android.preference.PreferenceFragment;
import android.preference.PreferenceManager;
import com.sap.sailing.racecommittee.app.ui.utils.MultiplePreferenceChangeListener;
import com.sap.sailing.racecommittee.app.ui.views.EditSetPreference;
import com.sap.sailing.android.shared.ui.utils.MultiplePreferenceChangeListener;
import com.sap.sailing.android.shared.ui.views.EditSetPreference;
/**
* Created by I074137 on 18.09.13.
@@ -1,4 +1,4 @@
package com.sap.sailing.racecommittee.app.ui.utils;
package com.sap.sailing.android.shared.ui.utils;
import java.util.HashSet;
import java.util.Set;
@@ -1,4 +1,4 @@
package com.sap.sailing.racecommittee.app.ui.views;
package com.sap.sailing.android.shared.ui.views;
import java.util.ArrayList;
import java.util.Arrays;
@@ -20,9 +20,9 @@ import android.widget.AutoCompleteTextView;
import android.widget.Button;
import android.widget.ListView;
import com.sap.sailing.racecommittee.app.R;
import com.sap.sailing.android.shared.R;
import com.sap.sailing.android.shared.logging.ExLog;
import com.sap.sailing.racecommittee.app.ui.adapters.ArrayRemoveAdapter;
import com.sap.sailing.android.shared.ui.adapters.ArrayRemoveAdapter;
public class EditSetPreference extends DialogPreference {
@@ -0,0 +1,15 @@
package com.sap.sailing.android.shared.util;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager.NameNotFoundException;
public class AppUtils {
public static PackageInfo getPackageInfo(Context app) {
try {
return app.getPackageManager().getPackageInfo(app.getPackageName(), 0);
} catch (NameNotFoundException e) {
return null;
}
}
}
@@ -14,6 +14,7 @@
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<application
android:name="com.sap.sailing.android.shared.application.LoggableApplication"
android:allowBackup="true"
android:hardwareAccelerated="true"
android:icon="@drawable/sap_sailing_app_icon"
@@ -33,6 +34,14 @@
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name="com.sap.sailing.android.tracking.app.ui.activities.SystemInformationActivity">
</activity>
<activity
android:name="com.sap.sailing.android.tracking.app.ui.activities.SettingsActivity">
</activity>
<service
android:name="com.sap.sailing.android.tracking.app.services.TrackingService"
@@ -1,3 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<lint>
</lint>
<issue id="TypographyDashes">
<ignore path="res/values/preferences.xml" />
</issue>
</lint>
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 853 B

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@+id/options_menu_settings"
android:icon="@drawable/settings_grey"
android:title="@string/options_menu_settings"
android:showAsAction="" />
<item android:id="@+id/options_menu_info"
android:icon="@drawable/ic_menu_info_details"
android:title="@string/options_menu_info"
android:showAsAction="" />
</menu>
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="not_tracking">Tracking aktiv</string>
<string name="tracking">Tracking nicht aktiv</string>
<string name="options_menu_settings">Einstellungen</string>
<string name="options_menu_info">Technische Informationen</string>
<string name="settings_category_general">General</string>
<string name="settings_category_connection">Verbindung</string>
<string name="server_url">Server</string>
<string name="device_identifier">Geräte-ID</string>
</resources>
@@ -1,5 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="MissingTranslation">
<string name="preference_device_identifier_key">deviceIdentifier</string>
<string name="preference_device_identifier_default">147d8230-4db0-11e4-916c-0800200c9a66</string>
<!-- override default values of android.shared -->
<string name="app_folder">tracking</string>
</resources>
@@ -3,4 +3,12 @@
<string name="app_name">SAP Sailing Tracking App</string>
<string name="not_tracking">Not Tracking</string>
<string name="tracking">Tracking</string>
<string name="options_menu_info">Expert Information</string>
<string name="options_menu_settings">Settings</string>
<string name="settings_category_general">General</string>
<string name="settings_category_connection">Connection</string>
<string name="server_url">Server</string>
<string name="device_identifier">Device Identifier</string>
</resources>
@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >
<PreferenceCategory android:title="@string/settings_category_connection" >
<EditTextPreference
android:defaultValue="@string/preference_device_identifier_default"
android:key="@string/preference_device_identifier_key"
android:summary="@string/empty"
android:title="@string/device_identifier" />
<EditTextPreference
android:defaultValue="@string/preference_server_url_default"
android:key="@string/preference_server_url_key"
android:summary="@string/empty"
android:title="@string/server_url" />
</PreferenceCategory>
</PreferenceScreen>
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<preference-headers xmlns:android="http://schemas.android.com/apk/res/android">
<header
android:fragment="com.sap.sailing.android.tracking.app.ui.fragments.preference.GeneralPreferenceFragment"
android:title="@string/settings_category_general" />
</preference-headers>
@@ -17,6 +17,8 @@ import com.google.android.gms.location.LocationListener;
import com.google.android.gms.location.LocationRequest;
import com.sap.sailing.android.shared.logging.ExLog;
import com.sap.sailing.android.shared.services.sending.MessageSendingService;
import com.sap.sailing.android.shared.util.PrefUtils;
import com.sap.sailing.android.tracking.app.R;
import com.sap.sailing.android.tracking.app.nmea.NmeaGprmcBuilder;
public class TrackingService extends Service implements ConnectionCallbacks, OnConnectionFailedListener,
@@ -29,8 +31,6 @@ LocationListener {
public static final int FIX_INTERVAL_MS = 500;
public static final int FASTEST_FIX_INTERVAL_MS = 100;
public static final String URL = "http://192.168.1.79";
@Override
public void onCreate() {
@@ -94,12 +94,17 @@ LocationListener {
public void onDisconnected() {
ExLog.i(this, TAG, "LocationClient was disconnected");
}
private String getServerURL() {
return PrefUtils.getString(this, R.string.preference_server_url_key,
R.string.preference_server_url_default);
}
@Override
public void onLocationChanged(Location location) {
String nmea = NmeaGprmcBuilder.buildNmeaStringFrom(location);
startService(MessageSendingService.createMessageIntent(
this, URL, null, UUID.randomUUID(), nmea, null));
this, getServerURL(), null, UUID.randomUUID(), nmea, null));
ExLog.i(this, TAG, "Sent NMEA to server:" + nmea);
//TODO also store to SD card
}
@@ -0,0 +1,33 @@
package com.sap.sailing.android.tracking.app.ui.activities;
import android.view.MenuItem;
import com.sap.sailing.android.shared.logging.ExLog;
import com.sap.sailing.android.shared.ui.activities.SendingServiceAwareActivity;
import com.sap.sailing.android.tracking.app.R;
public class BaseActivity extends SendingServiceAwareActivity {
private static final String TAG = SendingServiceAwareActivity.class.getName();
@Override
protected int getOptionsMenuResId() {
return R.menu.options_menu;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.options_menu_settings:
ExLog.i(this, TAG, "Clicked SETTINGS.");
fadeActivity(SettingsActivity.class, false);
return true;
case R.id.options_menu_info:
ExLog.i(this, TAG, "Clicked INFO.");
fadeActivity(SystemInformationActivity.class, false);
return true;
default:
return super.onOptionsItemSelected(item);
}
}
}
@@ -8,12 +8,11 @@ import android.os.Bundle;
import android.os.IBinder;
import android.widget.TextView;
import com.sap.sailing.android.shared.ui.activities.SendingServiceAwareActivity;
import com.sap.sailing.android.tracking.app.R;
import com.sap.sailing.android.tracking.app.services.TrackingService;
import com.sap.sailing.android.tracking.app.services.TrackingService.TrackingServiceBinder;
public class LaunchActivity extends SendingServiceAwareActivity {
public class LaunchActivity extends BaseActivity {
// private static final String TAG = LaunchActivity.class.getName();
private final TrackingServiceConnection trackingServiceConnection = new TrackingServiceConnection();
@@ -60,9 +59,4 @@ public class LaunchActivity extends SendingServiceAwareActivity {
unbindService(trackingServiceConnection);
}
}
@Override
protected int getOptionsMenuResId() {
return 0;
}
}
@@ -0,0 +1,22 @@
package com.sap.sailing.android.tracking.app.ui.activities;
import java.util.List;
import android.annotation.SuppressLint;
import android.preference.PreferenceActivity;
import com.sap.sailing.android.tracking.app.R;
import com.sap.sailing.android.tracking.app.ui.fragments.preference.GeneralPreferenceFragment;
public class SettingsActivity extends PreferenceActivity {
@Override
public void onBuildHeaders(List<Header> target) {
loadHeadersFromResource(R.xml.preference_headers, target);
}
/* (non-javadoc)
* Seems to be new for this target API level, fixing a security hole.
*/
@SuppressLint("Override")
protected boolean isValidFragment(String fragmentName) {
return GeneralPreferenceFragment.class.getName().equals(fragmentName);
}
}
@@ -0,0 +1,25 @@
package com.sap.sailing.android.tracking.app.ui.activities;
import android.os.Bundle;
import com.sap.sailing.android.shared.ui.activities.SystemInformationActivityHelper;
import com.sap.sailing.android.shared.util.PrefUtils;
import com.sap.sailing.android.tracking.app.R;
public class SystemInformationActivity extends BaseActivity {
private SystemInformationActivityHelper helper;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
helper = new SystemInformationActivityHelper(this, PrefUtils.getString(this,
R.string.preference_device_identifier_key, R.string.preference_device_identifier_default));
}
@Override
protected void updateSendingServiceInformation() {
helper.updateSendingServiceInformation();
super.updateSendingServiceInformation();
}
}
@@ -0,0 +1,18 @@
package com.sap.sailing.android.tracking.app.ui.fragments.preference;
import android.os.Bundle;
import com.sap.sailing.android.shared.ui.fragments.preference.BasePreferenceFragment;
import com.sap.sailing.android.tracking.app.R;
public class GeneralPreferenceFragment extends BasePreferenceFragment {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.preference_general);
bindPreferenceSummaryToValue(findPreference(R.string.preference_device_identifier_key));
bindPreferenceSummaryToValue(findPreference(R.string.preference_server_url_key));
}
}
@@ -30,7 +30,7 @@
<uses-feature android:name="android.hardware.camera.autofocus" />
<application
android:name="RaceApplication"
android:name=".RaceApplication"
android:allowBackup="true"
android:hardwareAccelerated="true"
android:icon="@drawable/sap_sailing_app_icon"
@@ -68,7 +68,7 @@
>
</activity>
<activity
android:name=".ui.activities.SystemInformationActivity"
android:name="com.sap.sailing.racecommittee.app.ui.activities.SystemInformationActivity"
android:screenOrientation="sensorLandscape" >
</activity>
@@ -110,7 +110,6 @@
<string name="results_capturing_view_add_photo">Foto hinzufügen</string>
<string name="results_capturing_view_list_header">Angehängte Fotos</string>
<string name="results_capturing_view_list_empty">Bisher keine Fotos</string>
<string name="remove">Entfernen</string>
<string name="results_mail_subject">[Race Committee] %s</string>
<string name="results_mail_body">Ergebnislisten für Rennen %s sind angehängt.</string>
@@ -193,13 +192,9 @@
<string name="login_type_officer_on_start_vessel">Als Startschiff-Wettfahrtleiter anmelden</string>
<string name="login_type_officer_on_finish_vessel">Als Zielschiff-Wettfahrtleiter anmelden</string>
<string name="login_type_shore_control">Als Regattaleitung an Land anmelden</string>
<string name="generic_error">Fehler</string>
<string name="gate_launch_stops_after">Gate Launch stoppt nach %dmin</string>
<string name="override_default_course_designer_type_select_header">Kursdesigner</string>
<string name="settings_course_designer_by_name_course_names_header">Kursnamen</string>
<string name="enter_new_item">Neues Element eingeben</string>
<string name="add">Hinzufügen</string>
<string name="there_are_no_items_yet_">Bisher keine Elemente.</string>
<string name="preference_racing_procedure_rrs26_startmode_flags_header">Startmodus Flaggen</string>
<string name="preference_racing_procedure_classflag_header">Klassenflagge</string>
<string name="preference_racing_procedure_hasxray_header">Einzelrückruf</string>
@@ -53,7 +53,6 @@
<string name="currentlyLoading">Currently loading &#8230;</string>
<string name="racingview_header">Races on course area \'%s\'</string>
<string name="running_on_unknown">(click to set course)</string>
<string name="empty"></string>
<string name="updateIndicator">Update indicator</string>
<string name="reset_race">Reset race</string>
<string name="postpone">Postpone</string>
@@ -113,7 +112,6 @@
<string name="results_capturing_view_add_photo">Add photo</string>
<string name="results_capturing_view_list_header">Attached photos</string>
<string name="results_capturing_view_list_empty">No photos yet</string>
<string name="remove">Remove</string>
<string name="results_mail_subject">[Race Committee] %s</string>
<string name="results_mail_body">Results for race %s are attached.</string>
@@ -169,16 +167,6 @@
<string name="today">Today</string>
<string name="start">Set start time</string>
<string name="application_information" translatable="false">Application Information</string>
<string name="application_identifier" translatable="false">Identifier</string>
<string name="application_install_date" translatable="false">Install Date</string>
<string name="persistence_information" translatable="false">Persistence Status</string>
<string name="persistence_waiting_clear_events" translatable="false">Clear events</string>
<string name="persistence_waiting_events" translatable="false">Waiting events</string>
<string name="application_version" translatable="false">Version</string>
<string name="generic_error">Error</string>
<string name="nationality">Nationality</string>
<string name="number">Number</string>
<string name="set_positionings">Set positionings</string>
@@ -201,10 +189,7 @@
<string name="settings_category_course_designer">Course Designer Configuration</string>
<string name="override_default_course_designer_type_select_header">Course Designer type</string>
<string name="settings_course_designer_by_name_course_names_header">Course Names</string>
<string name="enter_new_item">Enter new item</string>
<string name="add">Add</string>
<string name="there_are_no_items_yet_">There are no items yet.</string>
<string name="settings_course_designer_by_name_course_names_header">Course Names</string>
<string name="preference_racing_procedure_rrs26_startmode_flags_header">Startmode Flags</string>
<string name="preference_racing_procedure_classflag_header">Class Flag</string>
@@ -3,7 +3,7 @@
<PreferenceCategory android:title="By-Name Course Designer" >
<com.sap.sailing.racecommittee.app.ui.views.EditSetPreference
<com.sap.sailing.android.shared.ui.views.EditSetPreference
android:key="@string/preference_course_designer_by_name_course_names_key"
android:defaultValue="@array/preference_course_designer_by_name_course_names_default"
android:title="@string/settings_course_designer_by_name_course_names_header"
@@ -51,7 +51,7 @@
android:title="@string/settings_general_language_header"
android:summary="@string/settings_general_language_description" />
<com.sap.sailing.racecommittee.app.ui.views.EditSetPreference
<com.sap.sailing.android.shared.ui.views.EditSetPreference
android:key="@string/preference_course_areas_key"
android:defaultValue="@array/preference_course_areas_default"
android:title="@string/settings_general_manageareas_header"
@@ -5,7 +5,6 @@ import com.sap.sailing.racecommittee.app.ui.fragments.raceinfo.SetStartTimeRaceF
public class AppConstants {
public static final boolean IS_DATA_OFFLINE = false;
public static final boolean ENABLE_LIFECYCLE_LOGGING = false;
// Intent extra fields
public final static String COURSE_AREA_UUID_KEY = "courseUuid";
@@ -1,59 +1,12 @@
package com.sap.sailing.racecommittee.app;
import java.lang.ref.WeakReference;
import android.app.Application;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager.NameNotFoundException;
import com.sap.sailing.android.shared.logging.ExLog;
import com.sap.sailing.android.shared.logging.LifecycleLogger;
import com.sap.sailing.racecommittee.app.utils.LoggingExceptionHandler;
import com.sap.sailing.racecommittee.app.utils.PreferenceHelper;
/**
* <p>Registers an additional exception handler for uncaught exception to have some crash logging.</p>
* <p>Offers a static {@link StringContext} to handle i18n in ugly cases.</p>
* <p>Sets the default preference values (if not set)</p>
*/
public class RaceApplication extends Application {
private final static String TAG = RaceApplication.class.getName();
private static StringContext stringContext;
public static StringContext getStringContext() {
return stringContext;
}
@Override
public void onCreate() {
super.onCreate();
ExLog.i(this, TAG, "Application is starting.");
Thread.setDefaultUncaughtExceptionHandler(new LoggingExceptionHandler(Thread
.getDefaultUncaughtExceptionHandler(), this));
LifecycleLogger.enableLifecycleLogging(AppConstants.ENABLE_LIFECYCLE_LOGGING);
stringContext = new StringContext(new WeakReference<Context>(getApplicationContext()));
new PreferenceHelper(this).setupPreferences();
}
public static PackageInfo getPackageInfo(Context app) {
try {
return app.getPackageManager().getPackageInfo(app.getPackageName(), 0);
} catch (NameNotFoundException e) {
return null;
}
}
public static void restartApp(Context context) {
Intent i = context.getPackageManager().getLaunchIntentForPackage(context.getPackageName());
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
context.startActivity(i);
}
}
package com.sap.sailing.racecommittee.app;
import com.sap.sailing.android.shared.application.LoggableApplication;
import com.sap.sailing.racecommittee.app.utils.PreferenceHelper;
public class RaceApplication extends LoggableApplication {
@Override
public void onCreate() {
super.onCreate();
new PreferenceHelper(this).setupPreferences();
}
}
@@ -1,6 +1,5 @@
package com.sap.sailing.racecommittee.app.ui.activities;
import android.content.Intent;
import android.os.Bundle;
import android.view.MenuItem;
@@ -25,6 +24,11 @@ public class BaseActivity extends SendingServiceAwareActivity {
this.preferences = AppPreferences.on(getApplicationContext());
}
protected boolean onReset() {
fadeActivity(LoginActivity.class, true);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
@@ -40,36 +44,10 @@ public class BaseActivity extends SendingServiceAwareActivity {
ExLog.i(this, TAG, "Clicked INFO.");
fadeActivity(SystemInformationActivity.class, false);
return true;
case android.R.id.home:
ExLog.i(this, TAG, "Clicked HOME.");
return onHomeClicked();
default:
return super.onOptionsItemSelected(item);
}
}
protected boolean onHomeClicked() {
return false;
}
protected boolean onReset() {
fadeActivity(LoginActivity.class, true);
return true;
}
protected void fadeActivity(Class<?> activity, boolean newTopTask) {
Intent intent = new Intent(getBaseContext(), activity);
if (newTopTask) {
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
}
fadeActivity(intent);
}
protected void fadeActivity(Intent intent) {
startActivity(intent);
overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out);
}
public RaceApplication getRaceApplication() {
return (RaceApplication) getApplication();
@@ -1,89 +1,22 @@
package com.sap.sailing.racecommittee.app.ui.activities;
import java.util.Date;
import android.content.pm.PackageInfo;
import android.os.Bundle;
import android.text.format.DateFormat;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import com.sap.sailing.racecommittee.app.AppPreferences;
import com.sap.sailing.racecommittee.app.R;
import com.sap.sailing.racecommittee.app.RaceApplication;
import com.sap.sailing.android.shared.ui.activities.SystemInformationActivityHelper;
public class SystemInformationActivity extends BaseActivity {
private SystemInformationActivityHelper helper;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.system_information_view);
setupVersionView();
setupInstalledView();
setupPersistenceView();
helper = new SystemInformationActivityHelper(this, preferences.getDeviceIdentifier());
}
@Override
protected void updateSendingServiceInformation() {
TextView statusView = (TextView) findViewById(R.id.system_information_persistence_status);
ListView waitingView = (ListView) findViewById(R.id.system_information_persistence_waiting);
if (boundSendingService) {
Date lastSuccessfulSend = sendingService.getLastSuccessfulSend();
statusView.setText(String.format("Currently %d events waiting to be sent.\nLast successful sent was at: %s.",
sendingService.getDelayedIntentsCount(), lastSuccessfulSend == null ? "never" : lastSuccessfulSend));
waitingView.setAdapter(new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1,
sendingService.getDelayedIntensContent()));
} else {
statusView.setText(getString(R.string.generic_error));
}
}
private void setupPersistenceView() {
// status and list view is updated by updateSendingServiceInformation
Button clearButton = (Button) findViewById(R.id.system_information_persistence_clear);
clearButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
if (boundSendingService) {
sendingService.clearDelayedIntents();
} else {
Toast.makeText(getApplicationContext(), "", Toast.LENGTH_SHORT).show();
}
}
});
}
private void setupVersionView() {
TextView identifierView = (TextView) findViewById(R.id.system_information_application_identifier);
identifierView.setText(AppPreferences.on(getApplicationContext()).getDeviceIdentifier());
TextView versionView = (TextView) findViewById(R.id.system_information_application_version);
PackageInfo info = RaceApplication.getPackageInfo(getApplication());
if (info == null) {
versionView.setText(getString(R.string.generic_error));
} else {
versionView.setText(String.format("%s (Code %s)", info.versionName, info.versionCode));
}
}
private void setupInstalledView() {
TextView installView = (TextView) findViewById(R.id.system_information_application_install);
PackageInfo info = RaceApplication.getPackageInfo(getApplication());
if (info == null) {
installView.setText(getString(R.string.generic_error));
} else {
Date installDate = new Date(info.lastUpdateTime);
installView.setText(String.format("%s - %s", DateFormat.getLongDateFormat(this).format(installDate),
DateFormat.getTimeFormat(this).format(installDate)));
}
helper.updateSendingServiceInformation();
super.updateSendingServiceInformation();
}
}
@@ -3,8 +3,9 @@ package com.sap.sailing.racecommittee.app.ui.fragments.preference;
import android.os.Bundle;
import com.sap.sailing.android.shared.ui.fragments.preference.BasePreferenceFragment;
import com.sap.sailing.android.shared.ui.views.EditSetPreference;
import com.sap.sailing.racecommittee.app.R;
import com.sap.sailing.racecommittee.app.ui.views.EditSetPreference;
public class CourseDesignerPreferenceFragment extends BasePreferenceFragment {
@Override
@@ -16,10 +16,11 @@ import android.preference.Preference.OnPreferenceClickListener;
import android.preference.PreferenceManager;
import android.widget.Toast;
import com.sap.sailing.android.shared.ui.fragments.preference.BasePreferenceFragment;
import com.sap.sailing.android.shared.ui.views.EditSetPreference;
import com.sap.sailing.domain.common.impl.QRCodeUtils;
import com.sap.sailing.racecommittee.app.AppPreferences;
import com.sap.sailing.racecommittee.app.R;
import com.sap.sailing.racecommittee.app.ui.views.EditSetPreference;
import com.sap.sailing.racecommittee.app.utils.autoupdate.AutoUpdater;
import com.sap.sse.common.Util;
@@ -11,6 +11,7 @@ import android.preference.MultiSelectListPreference;
import android.preference.Preference;
import android.preference.Preference.OnPreferenceClickListener;
import com.sap.sailing.android.shared.ui.fragments.preference.BasePreferenceFragment;
import com.sap.sailing.domain.base.configuration.RegattaConfiguration;
import com.sap.sailing.domain.common.CourseDesignerMode;
import com.sap.sailing.domain.common.racelog.Flags;
@@ -12,6 +12,7 @@ import android.preference.Preference;
import android.preference.Preference.OnPreferenceClickListener;
import android.preference.PreferenceScreen;
import com.sap.sailing.android.shared.ui.fragments.preference.BasePreferenceFragment;
import com.sap.sailing.domain.base.racegroup.RaceGroup;
import com.sap.sailing.domain.common.impl.NaturalComparator;
import com.sap.sailing.racecommittee.app.R;
@@ -13,9 +13,9 @@ import android.content.DialogInterface.OnCancelListener;
import android.content.DialogInterface.OnClickListener;
import android.widget.Toast;
import com.sap.sailing.racecommittee.app.R;
import com.sap.sailing.racecommittee.app.RaceApplication;
import com.sap.sailing.android.shared.logging.ExLog;
import com.sap.sailing.android.shared.util.AppUtils;
import com.sap.sailing.racecommittee.app.R;
public class AutoUpdaterChecker {
@@ -93,7 +93,7 @@ public class AutoUpdaterChecker {
@Override
public void updateToVersion(int serverVersion, final String apkFileName) {
int currentVersion = RaceApplication.getPackageInfo(context).versionCode;
int currentVersion = AppUtils.getPackageInfo(context).versionCode;
boolean needsUpdate = currentVersion != serverVersion;
ExLog.i(context, TAG, String.format("Server version is %d. Local version is %d.", serverVersion, currentVersion));