Skip to content
Permalink
Browse files

[Widget] Now shows error if network issue occurs. Added shorter netwo…

…rk timeout (10 seconds) to facilitate this. Added more concise error text for widget. Added analytics for widget.

[Wear] Added dedicated analytics event for HTTP errors.
  • Loading branch information...
thecosmicfrog committed May 16, 2019
1 parent 28c1b12 commit c852c268074738b6036484dcc8da09b17e15201d
@@ -28,6 +28,7 @@ dependencies {
api 'com.android.support:design:28.0.0'
api 'com.google.android.gms:play-services-wearable:16.0.1'
api 'com.squareup.retrofit:retrofit:1.9.0'
api 'com.squareup.okhttp:okhttp:2.7.5'
api 'com.android.support:support-v4:28.0.0'
api 'com.google.android.gms:play-services-maps:16.0.0'
api 'com.google.firebase:firebase-core:16.0.6'
@@ -198,9 +198,9 @@ public void failure(RetrofitError retrofitError) {
if (retrofitError.getKind() != null)
Log.e(LOG_TAG, retrofitError.getKind().toString());

Analytics.httpError(
Analytics.httpErrorWear(
getApplicationContext(),
"http_error",
"http_error_wear",
"http_error_general_wear"
);
}
@@ -37,6 +37,8 @@
import android.view.View;
import android.widget.RemoteViews;

import com.squareup.okhttp.OkHttpClient;

import org.thecosmicfrog.luasataglance.R;
import org.thecosmicfrog.luasataglance.api.ApiMethods;
import org.thecosmicfrog.luasataglance.api.ApiTimes;
@@ -55,10 +57,12 @@
import java.io.ObjectInputStream;
import java.util.List;
import java.util.Locale;
import java.util.concurrent.TimeUnit;

import retrofit.Callback;
import retrofit.RestAdapter;
import retrofit.RetrofitError;
import retrofit.client.OkClient;
import retrofit.client.Response;

public class WidgetListenerService extends Service {
@@ -224,9 +228,18 @@ private void loadStopForecast(final Context context,final AppWidgetManager appWi
setIsLoading(appWidgetManager, widgetId, views, true);

/*
* Prepare Retrofit API call.
* The widget has a configured timeout, which clears the stop forecast after a period.
* As such, the HTTP timeout should be less than the views timeout. Create an
* OkHttpClient to facilitate this.
*/
final long HTTP_TIMEOUT = 10;
OkHttpClient okHttpClient = new OkHttpClient();
okHttpClient.setConnectTimeout(HTTP_TIMEOUT, TimeUnit.SECONDS);
okHttpClient.setReadTimeout(HTTP_TIMEOUT, TimeUnit.SECONDS);

/* Prepare Retrofit API call. */
final RestAdapter restAdapter = new RestAdapter.Builder()
.setClient(new OkClient(okHttpClient))
.setEndpoint(API_URL)
.build();

@@ -260,6 +273,16 @@ public void success(ApiTimes apiTimes, Response response) {
public void failure(RetrofitError retrofitError) {
Log.e(LOG_TAG, "Failure during call to server.");

/*
* Update the stop forecast with a null StopForecast in order to show the user
* a generic network error.
*/
updateStopForecast(context, views, null);

appWidgetManager.partiallyUpdateAppWidget(widgetId, views);

setIsLoading(appWidgetManager, widgetId, views, false);

/*
* If we get a message or a response from the server, there's likely an issue
* with the client request or the server's response itself.
@@ -292,12 +315,13 @@ public void failure(RetrofitError retrofitError) {
* If we don't receive a message or response, we can still get an idea of what's
* going on by getting the "kind" of error.
*/
if (retrofitError.getKind() != null)
if (retrofitError.getKind() != null) {
Log.e(LOG_TAG, retrofitError.getKind().toString());
}

Analytics.httpError(
Analytics.httpErrorWidget(
getApplicationContext(),
"http_error",
"http_error_widget",
"http_error_general_widget"
);
}
@@ -442,16 +466,16 @@ private void updateStopForecast(Context context, RemoteViews views, StopForecast

String message;

if (localeDefault.startsWith(GAEILGE)) {
message = getString(R.string.message_success);
} else {
message = stopForecast.getMessage();
}

mapEnglishGaeilge = new EnglishGaeilgeMap();

/* If a valid stop forecast exists... */
if (stopForecast != null) {
if (localeDefault.startsWith(GAEILGE)) {
message = getString(R.string.message_success);
} else {
message = stopForecast.getMessage();
}

mapEnglishGaeilge = new EnglishGaeilgeMap();

if (stopForecast.getMessage() != null) {
if (message.contains(getString(R.string.message_success))) {
/*
@@ -470,15 +494,6 @@ private void updateStopForecast(Context context, RemoteViews views, StopForecast
"setBackgroundResource",
R.color.message_error
);

/*
* To make best use of the widget's real estate, re-use one of the inbound
* stop TextViews for the status message.
*/
views.setTextViewText(
R.id.textview_inbound_stop1_name,
message
);
}
}

@@ -597,14 +612,14 @@ private void updateStopForecast(Context context, RemoteViews views, StopForecast
* change the color of the message title box red.
*/
views.setInt(
TEXTVIEW_STOP_NAME,
R.id.linearlayout_stop_name,
"setBackgroundResource",
R.color.message_error
);

views.setTextViewText(
TEXTVIEW_INBOUND_STOP1_NAME,
getString(R.string.message_error)
getString(R.string.widget_message_error)
);
}
}
@@ -32,7 +32,11 @@
public final class Analytics {

private static final String EVENT_API_CREATED_PARSE_ERROR = "api_created_parse_error";
private static final String EVENT_DISABLE_WIDGET = "disable_widget";
private static final String EVENT_ENABLE_WIDGET = "enable_widget";
private static final String EVENT_HTTP_ERROR = "http_error";
private static final String EVENT_HTTP_ERROR_WEAR = "http_error_wear";
private static final String EVENT_HTTP_ERROR_WIDGET = "http_error_widget";
private static final String EVENT_NULL_APITIMES = "null_apitimes";
private static final String LOG_TAG = Analytics.class.getSimpleName();

@@ -54,6 +58,38 @@ public static void apiCreatedParseError(Context context, String contentType, Str
}
}

public static void disableWidget(Context context, String contentType, String itemId) {
try {
firebaseAnalytics = FirebaseAnalytics.getInstance(context);
} catch (Exception e) {
Log.e(LOG_TAG, "Error gathering analytics for " + itemId + ".");
Log.e(LOG_TAG, Log.getStackTraceString(e));
}

if (firebaseAnalytics != null) {
Bundle params = new Bundle();
params.putString(FirebaseAnalytics.Param.CONTENT_TYPE, contentType);
params.putString(FirebaseAnalytics.Param.ITEM_ID, itemId);
firebaseAnalytics.logEvent(EVENT_DISABLE_WIDGET, params);
}
}

public static void enableWidget(Context context, String contentType, String itemId) {
try {
firebaseAnalytics = FirebaseAnalytics.getInstance(context);
} catch (Exception e) {
Log.e(LOG_TAG, "Error gathering analytics for " + itemId + ".");
Log.e(LOG_TAG, Log.getStackTraceString(e));
}

if (firebaseAnalytics != null) {
Bundle params = new Bundle();
params.putString(FirebaseAnalytics.Param.CONTENT_TYPE, contentType);
params.putString(FirebaseAnalytics.Param.ITEM_ID, itemId);
firebaseAnalytics.logEvent(EVENT_ENABLE_WIDGET, params);
}
}

public static void httpError(Context context, String contentType, String itemId) {
try {
firebaseAnalytics = FirebaseAnalytics.getInstance(context);
@@ -70,6 +106,38 @@ public static void httpError(Context context, String contentType, String itemId)
}
}

public static void httpErrorWear(Context context, String contentType, String itemId) {
try {
firebaseAnalytics = FirebaseAnalytics.getInstance(context);
} catch (Exception e) {
Log.e(LOG_TAG, "Error gathering analytics for " + itemId + ".");
Log.e(LOG_TAG, Log.getStackTraceString(e));
}

if (firebaseAnalytics != null) {
Bundle params = new Bundle();
params.putString(FirebaseAnalytics.Param.CONTENT_TYPE, contentType);
params.putString(FirebaseAnalytics.Param.ITEM_ID, itemId);
firebaseAnalytics.logEvent(EVENT_HTTP_ERROR_WEAR, params);
}
}

public static void httpErrorWidget(Context context, String contentType, String itemId) {
try {
firebaseAnalytics = FirebaseAnalytics.getInstance(context);
} catch (Exception e) {
Log.e(LOG_TAG, "Error gathering analytics for " + itemId + ".");
Log.e(LOG_TAG, Log.getStackTraceString(e));
}

if (firebaseAnalytics != null) {
Bundle params = new Bundle();
params.putString(FirebaseAnalytics.Param.CONTENT_TYPE, contentType);
params.putString(FirebaseAnalytics.Param.ITEM_ID, itemId);
firebaseAnalytics.logEvent(EVENT_HTTP_ERROR_WIDGET, params);
}
}

public static void nullApitimes(Context context, String contentType, String itemId) {
try {
firebaseAnalytics = FirebaseAnalytics.getInstance(context);
@@ -38,6 +38,7 @@
import org.thecosmicfrog.luasataglance.R;
import org.thecosmicfrog.luasataglance.activity.MainActivity;
import org.thecosmicfrog.luasataglance.service.WidgetListenerService;
import org.thecosmicfrog.luasataglance.util.Analytics;
import org.thecosmicfrog.luasataglance.util.Constant;
import org.thecosmicfrog.luasataglance.util.Preferences;

@@ -58,8 +59,8 @@

private static final String LOG_TAG = StopForecastWidget.class.getSimpleName();
private static final String WIDGET_CLICK_STOP_NAME = "WidgetClickStopName";
private static final String WIDGET_CLICK_LEFT_ARROW = "WidgetClickLeftArrow";
private static final String WIDGET_CLICK_RIGHT_ARROW = "WidgetClickRightArrow";
private static final String WIDGET_CLICK_ARROW_LEFT = "WidgetClickArrowLeft";
private static final String WIDGET_CLICK_ARROW_RIGHT = "WidgetClickArrowRight";
private static final String WIDGET_CLICK_STOP_FORECAST = "WidgetClickStopForecast";

private static long stopForecastLastClickTime = 0;
@@ -123,11 +124,23 @@ public void onDeleted(Context context, int[] appWidgetIds) {
@Override
public void onEnabled(Context context) {
Log.i(LOG_TAG, "Widget first created.");

Analytics.enableWidget(
context,
"enable_widget",
"widget"
);
}

@Override
public void onDisabled(Context context) {
Log.i(LOG_TAG, "Widget disabled.");

Analytics.disableWidget(
context,
"disable_widget",
"widget"
);
}

@Override
@@ -162,12 +175,18 @@ public void onReceive(@NonNull Context context, @NonNull Intent intent) {
stopName
)
);

Analytics.selectContent(
context,
"button_tapped",
"widget_stop_name_tapped"
);
}

/*
* If the user taps one of the widget arrows, move to the next/previous stop.
*/
if (intent.getAction().equals(WIDGET_CLICK_LEFT_ARROW)) {
if (intent.getAction().equals(WIDGET_CLICK_ARROW_LEFT)) {
/*
* Move on to the previous index in the list. If we're on the first index, reset
* back to the last index [listSelectedStops.size() - 1].
@@ -184,9 +203,15 @@ public void onReceive(@NonNull Context context, @NonNull Intent intent) {
remoteViews,
indexNextStopToLoad
);

Analytics.selectContent(
context,
"button_tapped",
"widget_arrow_left_tapped"
);
}

if (intent.getAction().equals(WIDGET_CLICK_RIGHT_ARROW)) {
if (intent.getAction().equals(WIDGET_CLICK_ARROW_RIGHT)) {
/*
* Move on to the next index in the list. If we're on the last index, reset back to
* the first index (0).
@@ -203,6 +228,12 @@ public void onReceive(@NonNull Context context, @NonNull Intent intent) {
remoteViews,
indexNextStopToLoad
);

Analytics.selectContent(
context,
"button_tapped",
"widget_arrow_right_tapped"
);
}

/*
@@ -235,6 +266,12 @@ public void onReceive(@NonNull Context context, @NonNull Intent intent) {
remoteViews,
indexNextStopToLoad
);

Analytics.selectContent(
context,
"button_tapped",
"widget_stop_forecast_tapped"
);
}
}
}
@@ -364,32 +401,32 @@ static void updateAppWidget(Context context, AppWidgetManager appWidgetManager,
* Set up Intents to register taps on the widget.
*/
Intent intentWidgetClickStopName = new Intent(context, StopForecastWidget.class);
Intent intentWidgetClickLeftArrow = new Intent(context, StopForecastWidget.class);
Intent intentWidgetClickRightArrow = new Intent(context, StopForecastWidget.class);
Intent intentWidgetClickArrowLeft = new Intent(context, StopForecastWidget.class);
Intent intentWidgetClickArrowRight = new Intent(context, StopForecastWidget.class);
Intent intentWidgetClickStopForecast = new Intent(context, StopForecastWidget.class);

intentWidgetClickStopName.setAction(WIDGET_CLICK_STOP_NAME);
intentWidgetClickLeftArrow.setAction(WIDGET_CLICK_LEFT_ARROW);
intentWidgetClickRightArrow.setAction(WIDGET_CLICK_RIGHT_ARROW);
intentWidgetClickArrowLeft.setAction(WIDGET_CLICK_ARROW_LEFT);
intentWidgetClickArrowRight.setAction(WIDGET_CLICK_ARROW_RIGHT);
intentWidgetClickStopForecast.setAction(WIDGET_CLICK_STOP_FORECAST);

PendingIntent pendingIntentWidgetClickStopName =
PendingIntent.getBroadcast(context, 0, intentWidgetClickStopName, 0);
PendingIntent pendingIntentWidgetClickLeftArrow =
PendingIntent.getBroadcast(context, 0, intentWidgetClickLeftArrow, 0);
PendingIntent pendingIntentWidgetClickRightArrow =
PendingIntent.getBroadcast(context, 0, intentWidgetClickRightArrow, 0);
PendingIntent pendingIntentWidgetClickArrowLeft =
PendingIntent.getBroadcast(context, 0, intentWidgetClickArrowLeft, 0);
PendingIntent pendingIntentWidgetClickArrowRight =
PendingIntent.getBroadcast(context, 0, intentWidgetClickArrowRight, 0);
PendingIntent pendingIntentWidgetClickStopForecast =
PendingIntent.getBroadcast(context, 0, intentWidgetClickStopForecast, 0);

remoteViews.setOnClickPendingIntent(
R.id.textview_stop_name, pendingIntentWidgetClickStopName
);
remoteViews.setOnClickPendingIntent(
R.id.textview_stop_name_left_arrow, pendingIntentWidgetClickLeftArrow
R.id.textview_stop_name_left_arrow, pendingIntentWidgetClickArrowLeft
);
remoteViews.setOnClickPendingIntent(
R.id.textview_stop_name_right_arrow, pendingIntentWidgetClickRightArrow
R.id.textview_stop_name_right_arrow, pendingIntentWidgetClickArrowRight
);
remoteViews.setOnClickPendingIntent(
R.id.linearlayout_stop_forecast, pendingIntentWidgetClickStopForecast

0 comments on commit c852c26

Please sign in to comment.
You can’t perform that action at this time.