mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-10-27 14:27:15 +00:00
TRACKING APP: Multi-checkin works
This commit is contained in:
1 parent
9a66ae9479
commit
41ba14e1d5
4 files changed
+123
-104
No files matched your search
+11
-11
@@ -7,25 +7,25 @@ import android.provider.BaseColumns;
|
||||
public class AnalyticsContract {
|
||||
|
||||
interface CompetitorColumns {
|
||||
String COMPETITOR_ID = "id";
|
||||
String COMPETITOR_DISPLAY_NAME = "display_name";
|
||||
String COMPETITOR_COUNTRY_CODE = "country_code";
|
||||
String COMPETITOR_NATIONALITY = "nationality";
|
||||
String COMPETITOR_SAIL_ID = "saild_id";
|
||||
String COMPETITOR_ID = "competitor_id";
|
||||
String COMPETITOR_DISPLAY_NAME = "competitor_display_name";
|
||||
String COMPETITOR_COUNTRY_CODE = "competitor_country_code";
|
||||
String COMPETITOR_NATIONALITY = "competitor_nationality";
|
||||
String COMPETITOR_SAIL_ID = "competitor_saild_id";
|
||||
String COMPETITOR_LEADERBOARD_FK = "leaderboard_id";
|
||||
}
|
||||
|
||||
interface LeaderboardColumns {
|
||||
String LEADERBOARD_NAME = "name";
|
||||
String LEADERBOARD_NAME = "leaderboard_name";
|
||||
}
|
||||
|
||||
interface EventColumns {
|
||||
String EVENT_ID = "id";
|
||||
String EVENT_ID = "event_id";
|
||||
String EVENT_DATE_END = "date_end";
|
||||
String EVENT_DATE_START = "date_start";
|
||||
String EVENT_SERVER = "server";
|
||||
String EVENT_SERVER = "event_server";
|
||||
String EVENT_IMAGE_URL = "image_url";
|
||||
String EVENT_NAME = "name";
|
||||
String EVENT_NAME = "event_name";
|
||||
String EVENT_LEADERBOARD_FK = "leaderboard_id";
|
||||
}
|
||||
|
||||
@@ -54,9 +54,9 @@ public class AnalyticsContract {
|
||||
private static final String PATH_LEADERBOARD = "leaderboards";
|
||||
private static final String PATH_SENSOR_GPS = "sensor_gps";
|
||||
|
||||
public static class CheckEventLeaderboardCompetitorExists {
|
||||
public static class EventLeaderboardCompetitorJoined {
|
||||
public final static Uri CONTENT_URI = BASE_CONTENT_URI.buildUpon()
|
||||
.appendPath("check_event_leaderboard_competitor_exists")
|
||||
.appendPath("event_leaderboard_competitor_joined")
|
||||
.build();
|
||||
}
|
||||
|
||||
|
||||
+3
-3
@@ -45,7 +45,7 @@ public class AnalyticsProvider extends ContentProvider {
|
||||
private static final int SENSOR_GPS = 500;
|
||||
private static final int SENSOR_GPS_ID = 501;
|
||||
|
||||
private static final int CHECK_EVENT_LEADERBOARD_COMPETITOR_EXISTS = 600;
|
||||
private static final int EVENT_LEADERBOARD_COMPETITOR_JOINED = 600;
|
||||
|
||||
private static UriMatcher buildUriMatcher() {
|
||||
final UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);
|
||||
@@ -66,7 +66,7 @@ public class AnalyticsProvider extends ContentProvider {
|
||||
matcher.addURI(authority, "sensor_gps", SENSOR_GPS);
|
||||
matcher.addURI(authority, "sensor_gps/#", SENSOR_GPS_ID);
|
||||
|
||||
matcher.addURI(authority, "check_event_leaderboard_competitor_exists", CHECK_EVENT_LEADERBOARD_COMPETITOR_EXISTS);
|
||||
matcher.addURI(authority, "event_leaderboard_competitor_joined", EVENT_LEADERBOARD_COMPETITOR_JOINED);
|
||||
|
||||
return matcher;
|
||||
}
|
||||
@@ -100,7 +100,7 @@ public class AnalyticsProvider extends ContentProvider {
|
||||
|
||||
switch (sUriMatcher.match(uri)) {
|
||||
|
||||
case CHECK_EVENT_LEADERBOARD_COMPETITOR_EXISTS:
|
||||
case EVENT_LEADERBOARD_COMPETITOR_JOINED:
|
||||
SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
|
||||
qb.setTables(Tables.EVENTS_JOIN_LEADERBOARDS_JOIN_COMPETITORS);
|
||||
cursor = qb.query(db, projection, selection, selectionArgs, null, null, sortOrder);
|
||||
|
||||
+108
-89
@@ -53,10 +53,9 @@ import com.sap.sailing.android.tracking.app.provider.AnalyticsContract;
|
||||
import com.sap.sailing.android.tracking.app.provider.AnalyticsContract.Competitor;
|
||||
import com.sap.sailing.android.tracking.app.provider.AnalyticsContract.Event;
|
||||
import com.sap.sailing.android.tracking.app.provider.AnalyticsContract.Leaderboard;
|
||||
import com.sap.sailing.android.tracking.app.provider.AnalyticsProvider;
|
||||
import com.sap.sailing.android.tracking.app.ui.activities.RegattaActivity;
|
||||
import com.sap.sailing.android.tracking.app.utils.AppPreferences;
|
||||
import com.sap.sailing.android.tracking.app.utils.CheckinQRCodeHelper;
|
||||
import com.sap.sailing.android.tracking.app.utils.CheckinHelper;
|
||||
import com.sap.sailing.android.tracking.app.utils.VolleyHelper;
|
||||
import com.sap.sailing.domain.racelog.tracking.DeviceIdentifier;
|
||||
import com.sap.sailing.domain.racelog.tracking.impl.SmartphoneUUIDIdentifierImpl;
|
||||
@@ -147,10 +146,9 @@ public class HomeFragment extends BaseFragment implements
|
||||
|
||||
String leaderboardNameFromQR;
|
||||
try {
|
||||
leaderboardNameFromQR = URLEncoder
|
||||
.encode(uri
|
||||
.getQueryParameter(CheckinQRCodeHelper.LEADERBOARD_NAME),
|
||||
"UTF-8").replace("+", "%20");
|
||||
leaderboardNameFromQR = URLEncoder.encode(
|
||||
uri.getQueryParameter(CheckinHelper.LEADERBOARD_NAME),
|
||||
"UTF-8").replace("+", "%20");
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
ExLog.e(getActivity(), TAG,
|
||||
"Failed to encode leaderboard name: " + e.getMessage());
|
||||
@@ -158,12 +156,12 @@ public class HomeFragment extends BaseFragment implements
|
||||
}
|
||||
|
||||
final String competitorId = uri
|
||||
.getQueryParameter(CheckinQRCodeHelper.COMPETITOR_ID);
|
||||
.getQueryParameter(CheckinHelper.COMPETITOR_ID);
|
||||
final String checkinURLStr = prefs.getServerURL()
|
||||
+ prefs.getServerCheckinPath().replace(
|
||||
"{leaderboard-name}", leaderboardNameFromQR);
|
||||
final String eventId = uri
|
||||
.getQueryParameter(CheckinQRCodeHelper.EVENT_ID);
|
||||
.getQueryParameter(CheckinHelper.EVENT_ID);
|
||||
final String leaderboardName = leaderboardNameFromQR;
|
||||
|
||||
final DeviceIdentifier deviceUuid = new SmartphoneUUIDIdentifierImpl(
|
||||
@@ -288,7 +286,8 @@ public class HomeFragment extends BaseFragment implements
|
||||
data.eventFirstImageUrl = eventFirstImageUrl;
|
||||
data.eventServerUrl = checkinURLStr;
|
||||
data.leaderboardName = leaderboardName;
|
||||
data.deviceUid = deviceUuid.getStringRepresentation();
|
||||
data.deviceUid = deviceUuid
|
||||
.getStringRepresentation();
|
||||
|
||||
displayUserConfirmationScreen(data);
|
||||
|
||||
@@ -337,7 +336,7 @@ public class HomeFragment extends BaseFragment implements
|
||||
|
||||
VolleyHelper.getInstance(getActivity()).addRequest(
|
||||
getLeaderboardRequest);
|
||||
|
||||
|
||||
} else if (resultCode == Activity.RESULT_CANCELED) {
|
||||
Toast.makeText(getActivity(), "Scanning canceled",
|
||||
Toast.LENGTH_LONG).show();
|
||||
@@ -403,111 +402,128 @@ public class HomeFragment extends BaseFragment implements
|
||||
*/
|
||||
private boolean eventLeaderboardCompetitorCombnationAvailable(
|
||||
String eventId, String leaderboardName, String competitorId) {
|
||||
|
||||
ContentResolver cr = getActivity().getContentResolver();
|
||||
String sel = "leaderboards.name = \"" + leaderboardName
|
||||
+ "\" AND competitors.id = \"" + competitorId + "\" AND events.id = \"" + eventId + "\"";
|
||||
|
||||
int count = cr
|
||||
.query(AnalyticsContract.CheckEventLeaderboardCompetitorExists.CONTENT_URI,
|
||||
null, sel, null, null).getCount();
|
||||
ContentResolver cr = getActivity().getContentResolver();
|
||||
String sel = "leaderboards.leaderboard_name = \"" + leaderboardName
|
||||
+ "\" AND competitors.competitor_id = \"" + competitorId
|
||||
+ "\" AND events.event_id = \"" + eventId + "\"";
|
||||
|
||||
int count = cr.query(
|
||||
AnalyticsContract.EventLeaderboardCompetitorJoined.CONTENT_URI,
|
||||
null, sel, null, null).getCount();
|
||||
|
||||
return count == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform a checking request and launch RegattaAcitivity afterwards
|
||||
* Perform a checkin request and launch RegattaAcitivity afterwards
|
||||
*
|
||||
* TODO: Google Cloud Messaging token?
|
||||
*
|
||||
* @param deviceMappingData
|
||||
*/
|
||||
private void checkInWithAPIAndDisplayTrackingActivity(CheckinData checkinData) {
|
||||
private void checkInWithAPIAndDisplayTrackingActivity(
|
||||
CheckinData checkinData) {
|
||||
if (eventLeaderboardCompetitorCombnationAvailable(checkinData.eventId,
|
||||
checkinData.leaderboardName, checkinData.competitorId)) {
|
||||
|
||||
// inserting leaderboard first in order to get the ID.
|
||||
// This should be atomic, but couldn't get withValueBackReference to work yet.
|
||||
|
||||
|
||||
// inserting leaderboard first in order to get the ID.
|
||||
// This should be atomic, but couldn't get withValueBackReference to
|
||||
// work yet.
|
||||
|
||||
ContentResolver cr = getActivity().getContentResolver();
|
||||
|
||||
|
||||
ContentValues clv = new ContentValues();
|
||||
clv.put(Leaderboard.LEADERBOARD_NAME, checkinData.leaderboardName);
|
||||
cr.insert(Leaderboard.CONTENT_URI, clv);
|
||||
|
||||
Cursor cur = cr.query(Leaderboard.CONTENT_URI, null, null, null, null);
|
||||
|
||||
Cursor cur = cr.query(Leaderboard.CONTENT_URI, null, null, null,
|
||||
null);
|
||||
long lastLeaderboardId = 0;
|
||||
|
||||
if (cur.moveToLast())
|
||||
{
|
||||
lastLeaderboardId = cur.getLong(cur.getColumnIndex(BaseColumns._ID));
|
||||
|
||||
if (cur.moveToLast()) {
|
||||
lastLeaderboardId = cur.getLong(cur
|
||||
.getColumnIndex(BaseColumns._ID));
|
||||
}
|
||||
|
||||
|
||||
cur.close();
|
||||
|
||||
|
||||
// now, with the leaderboard id, insert event and competitor
|
||||
// todo: fix this so its atomic.
|
||||
|
||||
ArrayList<ContentProviderOperation> opList = new
|
||||
ArrayList<ContentProviderOperation>();
|
||||
|
||||
|
||||
ArrayList<ContentProviderOperation> opList = new ArrayList<ContentProviderOperation>();
|
||||
|
||||
ContentValues cev = new ContentValues();
|
||||
cev.put(Event.EVENT_ID, checkinData.eventId);
|
||||
cev.put(Event.EVENT_NAME, checkinData.eventName);
|
||||
cev.put(Event.EVENT_DATE_START, Long.parseLong(checkinData.eventStartDateStr));
|
||||
cev.put(Event.EVENT_DATE_END, Long.parseLong(checkinData.eventEndDateStr));
|
||||
cev.put(Event.EVENT_DATE_START,
|
||||
Long.parseLong(checkinData.eventStartDateStr));
|
||||
cev.put(Event.EVENT_DATE_END,
|
||||
Long.parseLong(checkinData.eventEndDateStr));
|
||||
cev.put(Event.EVENT_SERVER, checkinData.eventServerUrl);
|
||||
cev.put(Event.EVENT_IMAGE_URL, checkinData.eventFirstImageUrl);
|
||||
cev.put(Event.EVENT_LEADERBOARD_FK, lastLeaderboardId);
|
||||
|
||||
opList.add(ContentProviderOperation.
|
||||
newInsert(Event.CONTENT_URI).withValues(cev).build());
|
||||
|
||||
opList.add(ContentProviderOperation.newInsert(Event.CONTENT_URI)
|
||||
.withValues(cev).build());
|
||||
|
||||
ContentValues ccv = new ContentValues();
|
||||
|
||||
ccv.put(Competitor.COMPETITOR_COUNTRY_CODE, checkinData.competitorCountryCode);
|
||||
ccv.put(Competitor.COMPETITOR_DISPLAY_NAME, checkinData.competitorDisplayName);
|
||||
|
||||
ccv.put(Competitor.COMPETITOR_COUNTRY_CODE,
|
||||
checkinData.competitorCountryCode);
|
||||
ccv.put(Competitor.COMPETITOR_DISPLAY_NAME,
|
||||
checkinData.competitorDisplayName);
|
||||
ccv.put(Competitor.COMPETITOR_ID, checkinData.competitorId);
|
||||
ccv.put(Competitor.COMPETITOR_NATIONALITY, checkinData.competitorNationality);
|
||||
ccv.put(Competitor.COMPETITOR_NATIONALITY,
|
||||
checkinData.competitorNationality);
|
||||
ccv.put(Competitor.COMPETITOR_SAIL_ID, checkinData.competitorSailId);
|
||||
ccv.put(Competitor.COMPETITOR_LEADERBOARD_FK, lastLeaderboardId);
|
||||
|
||||
opList.add(ContentProviderOperation.
|
||||
newInsert(Competitor.CONTENT_URI).withValues(ccv).build());
|
||||
|
||||
opList.add(ContentProviderOperation
|
||||
.newInsert(Competitor.CONTENT_URI).withValues(ccv).build());
|
||||
|
||||
try {
|
||||
for (ContentProviderOperation op: opList)
|
||||
{
|
||||
for (ContentProviderOperation op : opList) {
|
||||
System.out.println("** INSERT: " + op);
|
||||
}
|
||||
|
||||
|
||||
cr.applyBatch(AnalyticsContract.CONTENT_AUTHORITY, opList);
|
||||
} catch (RemoteException e1) {
|
||||
ExLog.e(getActivity(), TAG, "Batch insert failed: " + e1.getMessage());
|
||||
ExLog.e(getActivity(), TAG,
|
||||
"Batch insert failed: " + e1.getMessage());
|
||||
displayDatabaseError();
|
||||
return;
|
||||
} catch (OperationApplicationException e1) {
|
||||
ExLog.e(getActivity(), TAG, "Batch insert failed: " + e1.getMessage());
|
||||
ExLog.e(getActivity(), TAG,
|
||||
"Batch insert failed: " + e1.getMessage());
|
||||
displayDatabaseError();
|
||||
return;
|
||||
}
|
||||
|
||||
if (BuildConfig.DEBUG)
|
||||
{
|
||||
ExLog.i(getActivity(), TAG, "Batch-insert of checkinData completed.");
|
||||
|
||||
if (BuildConfig.DEBUG) {
|
||||
ExLog.i(getActivity(), TAG,
|
||||
"Batch-insert of checkinData completed.");
|
||||
}
|
||||
} else {
|
||||
ExLog.w(getActivity(), TAG,
|
||||
"Combination of eventId, leaderboardName and competitorId already exists!");
|
||||
}
|
||||
else
|
||||
{
|
||||
ExLog.w(getActivity(), TAG, "Combination of eventId, leaderboardName and competitorId already exists!");
|
||||
}
|
||||
|
||||
|
||||
performAPICheckin(checkinData);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checkin with API.
|
||||
*
|
||||
* @param checkinData
|
||||
*/
|
||||
private void performAPICheckin(CheckinData checkinData) {
|
||||
Date date = new Date();
|
||||
|
||||
try {
|
||||
JSONObject requestObject = CheckinQRCodeHelper.getCheckinJson(
|
||||
checkinData.competitorId,
|
||||
checkinData.deviceUid, "TODO!!", date.getTime());
|
||||
JSONObject requestObject = CheckinHelper.getCheckinJson(
|
||||
checkinData.competitorId, checkinData.deviceUid, "TODO!!",
|
||||
date.getTime());
|
||||
|
||||
JsonObjectRequest checkinRequest = new JsonObjectRequest(
|
||||
checkinData.eventServerUrl, requestObject,
|
||||
@@ -521,7 +537,7 @@ public class HomeFragment extends BaseFragment implements
|
||||
"Failed to generate checkin JSON: " + e.getMessage());
|
||||
displayAPIErrorRecommendRetry();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows a pop-up-dialog that informs the user than an API-call has failed
|
||||
@@ -582,11 +598,13 @@ public class HomeFragment extends BaseFragment implements
|
||||
public Loader<Cursor> onCreateLoader(int loaderId, Bundle bundle) {
|
||||
switch (loaderId) {
|
||||
case REGATTA_LOADER:
|
||||
String[] projection = new String[] { Event._ID, Event.EVENT_NAME,
|
||||
Event.EVENT_SERVER };
|
||||
return new CursorLoader(getActivity(),
|
||||
AnalyticsContract.Event.CONTENT_URI, projection, null,
|
||||
null, null);
|
||||
String[] projection = new String[] { "events.event_id",
|
||||
"events._id", "events.event_name", "events.event_server",
|
||||
"competitors.competitor_id", "leaderboards.leaderboard_name" };
|
||||
return new CursorLoader(
|
||||
getActivity(),
|
||||
AnalyticsContract.EventLeaderboardCompetitorJoined.CONTENT_URI,
|
||||
projection, null, null, null);
|
||||
|
||||
default:
|
||||
return null;
|
||||
@@ -651,24 +669,25 @@ public class HomeFragment extends BaseFragment implements
|
||||
@Override
|
||||
public void onItemClick(AdapterView<?> parent, View view, int position,
|
||||
long id) {
|
||||
Cursor cursor = (Cursor) mAdapter.getItem(position);
|
||||
if (cursor.moveToFirst()) {
|
||||
ExLog.e(getActivity(), TAG,
|
||||
"TODO: onItemClick not implemented yet.");
|
||||
// prefs.setServerURL(cursor.getString(cursor.getColumnIndex(Event.EVENT_SERVER)));
|
||||
// String eventId =
|
||||
// cursor.getString(cursor.getColumnIndex(Event.EVENT_ID));
|
||||
// String competitorId = cursor
|
||||
// .getString(cursor
|
||||
// .getColumnIndex(com.sap.sailing.android.tracking.app.provider.AnalyticsContract.Competitor.COMPETITOR_ID));
|
||||
//
|
||||
//
|
||||
//
|
||||
// checkInWithAPIAndDisplayTrackingActivity(deviceMappingData);
|
||||
//
|
||||
// VolleyHelper.getInstance(getActivity()).addRequest(
|
||||
// checkInRequest(prefs.getServerURL(), eventId, competitorId));
|
||||
}
|
||||
Cursor cursor = (Cursor) mAdapter.getItem(position - 1); // -1, because there's a header row
|
||||
|
||||
prefs.setServerURL(cursor.getString(cursor
|
||||
.getColumnIndex(Event.EVENT_SERVER)));
|
||||
|
||||
String competitorId = cursor.getString(cursor.getColumnIndex("competitor_id"));
|
||||
String eventServer = cursor.getString(cursor.getColumnIndex("event_server"));
|
||||
String leaderboardName = cursor.getString(cursor.getColumnIndex("leaderboard_name"));
|
||||
|
||||
CheckinData data = new CheckinData();
|
||||
|
||||
data.competitorId = competitorId;
|
||||
data.deviceUid = new SmartphoneUUIDIdentifierImpl(
|
||||
UUID.fromString(prefs.getDeviceIdentifier()))
|
||||
.getStringRepresentation();
|
||||
data.eventServerUrl = eventServer;
|
||||
data.leaderboardName = leaderboardName;
|
||||
|
||||
performAPICheckin(data);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@ package com.sap.sailing.android.tracking.app.utils;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
public class CheckinQRCodeHelper {
|
||||
public class CheckinHelper {
|
||||
public static final String LEADERBOARD_NAME = "leaderboard_name";
|
||||
public static final String COMPETITOR_ID = "competitor_id";
|
||||
public static final String EVENT_ID = "event_id";
|
||||
Reference in new issue
Block a user