add notifications for upcoming possible trip
This commit is contained in:
parent
7451be0fcc
commit
a0b7e18b7b
|
@ -44,6 +44,13 @@
|
|||
android:authorities="com.eleith.calchoochoo.data"
|
||||
android:exported="false"/>
|
||||
|
||||
<receiver android:name=".ChooChooAlarmReceiver">
|
||||
<intent-filter>
|
||||
<action android:name="android.media.action.DISPLAY_NOTIFICATION" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
|
||||
<receiver
|
||||
android:name="ChooChooWidgetProvider"
|
||||
android:icon="@drawable/calchoochoo"
|
||||
|
|
|
@ -0,0 +1,65 @@
|
|||
package com.eleith.calchoochoo;
|
||||
|
||||
import android.app.Notification;
|
||||
import android.app.NotificationManager;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Bitmap;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.app.NotificationCompat;
|
||||
import android.support.v4.app.TaskStackBuilder;
|
||||
|
||||
import com.eleith.calchoochoo.utils.BundleKeys;
|
||||
import com.eleith.calchoochoo.utils.DrawableUtils;
|
||||
import com.eleith.calchoochoo.utils.Notifications;
|
||||
|
||||
import org.joda.time.LocalTime;
|
||||
import org.joda.time.format.DateTimeFormat;
|
||||
|
||||
public class ChooChooAlarmReceiver extends BroadcastReceiver {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
Bundle bundle = intent.getExtras();
|
||||
String tripId = bundle.getString(BundleKeys.TRIP);
|
||||
String sourceId = bundle.getString(BundleKeys.STOP_SOURCE);
|
||||
String destinationId = bundle.getString(BundleKeys.STOP_DESTINATION);
|
||||
String sourceName = bundle.getString(BundleKeys.STOP_SOURCE_NAME);
|
||||
String destinationName = bundle.getString(BundleKeys.STOP_DESTINATION_NAME);
|
||||
Long sourceTime = bundle.getLong(BundleKeys.STOP_SOURCE_TIME);
|
||||
Long destinationTime = bundle.getLong(BundleKeys.STOP_DESTINATION_TIME);
|
||||
String method = bundle.getString(BundleKeys.STOP_METHOD, Notifications.ARRIVING);
|
||||
|
||||
Intent notificationIntent = new Intent(context, TripActivity.class);
|
||||
notificationIntent.putExtras(bundle);
|
||||
|
||||
TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);
|
||||
stackBuilder.addParentStack(TripActivity.class);
|
||||
stackBuilder.addNextIntent(notificationIntent);
|
||||
|
||||
PendingIntent pendingIntent;
|
||||
String title;
|
||||
String timeString;
|
||||
String content;
|
||||
String ticker;
|
||||
|
||||
if (method.equals(Notifications.ARRIVING)) {
|
||||
pendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
|
||||
timeString = DateTimeFormat.forPattern("h:mma").print(new LocalTime(destinationTime));
|
||||
title = String.format("Train #%s", tripId);
|
||||
content = String.format("%s at %s", "Arriving", timeString);
|
||||
ticker = "Caltrain Train Arrival Notification";
|
||||
} else {
|
||||
pendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
|
||||
timeString = DateTimeFormat.forPattern("h:mma").print(new LocalTime(sourceTime));
|
||||
title = String.format("Train #%s", tripId);
|
||||
content = String.format("%s at %s", "Departing", timeString);
|
||||
ticker = "Caltrain Train Departure Notification";
|
||||
}
|
||||
|
||||
Notifications notifications = new Notifications(context);
|
||||
Notification notificationBuilder = notifications.build(title, content, ticker, R.drawable.ic_cal_choo_choo, pendingIntent);
|
||||
notifications.send(notificationBuilder, tripId, method);
|
||||
}
|
||||
}
|
|
@ -1,7 +1,10 @@
|
|||
package com.eleith.calchoochoo;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.content.res.ColorStateList;
|
||||
import android.os.Bundle;
|
||||
import android.support.design.widget.FloatingActionButton;
|
||||
import android.support.v4.util.Pair;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
|
||||
import com.eleith.calchoochoo.dagger.ChooChooComponent;
|
||||
|
@ -10,21 +13,30 @@ import com.eleith.calchoochoo.data.ChooChooLoader;
|
|||
import com.eleith.calchoochoo.data.PossibleTrip;
|
||||
import com.eleith.calchoochoo.data.StopTimes;
|
||||
import com.eleith.calchoochoo.data.Trips;
|
||||
import com.eleith.calchoochoo.fragments.SetAlarmDialogFragment;
|
||||
import com.eleith.calchoochoo.utils.BundleKeys;
|
||||
import com.eleith.calchoochoo.utils.ColorUtils;
|
||||
import com.eleith.calchoochoo.utils.Notifications;
|
||||
import com.eleith.calchoochoo.utils.RxBus;
|
||||
import com.eleith.calchoochoo.utils.RxBusMessage.RxMessage;
|
||||
import com.eleith.calchoochoo.utils.RxBusMessage.RxMessageKeys;
|
||||
import com.eleith.calchoochoo.utils.RxBusMessage.RxMessageNotificationPair;
|
||||
import com.eleith.calchoochoo.utils.RxBusMessage.RxMessagePossibleTrip;
|
||||
import com.eleith.calchoochoo.utils.RxBusMessage.RxMessageTrip;
|
||||
import com.eleith.calchoochoo.utils.RxBusMessage.RxMessageTripStops;
|
||||
import com.eleith.calchoochoo.utils.StopTimesUtils;
|
||||
import com.google.android.gms.common.api.GoogleApiClient;
|
||||
|
||||
import org.joda.time.LocalDateTime;
|
||||
import org.parceler.Parcels;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.OnClick;
|
||||
import rx.Subscription;
|
||||
import rx.functions.Action1;
|
||||
|
||||
|
@ -37,6 +49,9 @@ public class TripActivity extends AppCompatActivity {
|
|||
private PossibleTrip possibleTrip;
|
||||
private String tripId;
|
||||
private Trips trip;
|
||||
private static final String PREFS_NAME = "com.eleith.calchoochoo.TripActivity";
|
||||
private static final String PREF_PREFIX_KEY = "choochoo_trip_";
|
||||
private Notifications notifications;
|
||||
|
||||
@Inject
|
||||
RxBus rxBus;
|
||||
|
@ -47,6 +62,9 @@ public class TripActivity extends AppCompatActivity {
|
|||
@Inject
|
||||
ChooChooLoader chooChooLoader;
|
||||
|
||||
@BindView(R.id.activityFloatingActionButton)
|
||||
FloatingActionButton floatingActionButton;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
chooChooComponent = ChooChooApplication.from(this).getAppComponent().activityComponent(new ChooChooModule(this));
|
||||
|
@ -55,10 +73,14 @@ public class TripActivity extends AppCompatActivity {
|
|||
super.onCreate(savedInstanceState);
|
||||
postponeEnterTransition();
|
||||
|
||||
setContentView(R.layout.activity_appbar_main);
|
||||
setContentView(R.layout.activity_appbar_main_with_fab);
|
||||
|
||||
ButterKnife.bind(this);
|
||||
subscription = rxBus.observeEvents(RxMessage.class).subscribe(new HandleRxMessages());
|
||||
notifications = new Notifications(this);
|
||||
|
||||
floatingActionButton.setImageDrawable(getDrawable(R.drawable.ic_add_alarm_black_24dp));
|
||||
floatingActionButton.setBackgroundTintList(ColorStateList.valueOf(ColorUtils.getThemeColor(this, R.attr.colorAccent)));
|
||||
|
||||
Intent intent = getIntent();
|
||||
if (intent != null) {
|
||||
|
@ -77,6 +99,46 @@ public class TripActivity extends AppCompatActivity {
|
|||
}
|
||||
}
|
||||
|
||||
@OnClick(R.id.activityFloatingActionButton)
|
||||
public void openAlarmDialog() {
|
||||
Bundle bundle = new Bundle();
|
||||
SetAlarmDialogFragment dialog = new SetAlarmDialogFragment();
|
||||
bundle.putParcelable(BundleKeys.POSSIBLE_TRIP, Parcels.wrap(possibleTrip));
|
||||
dialog.setArguments(bundle);
|
||||
dialog.show(getSupportFragmentManager(), "dialog");
|
||||
}
|
||||
|
||||
private void changeNotificationPreferences(int departureMinutes, int arrivalMinutes) {
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putString(BundleKeys.TRIP, tripId);
|
||||
bundle.putString(BundleKeys.STOP_SOURCE, sourceId);
|
||||
bundle.putString(BundleKeys.STOP_DESTINATION, destinationId);
|
||||
bundle.putString(BundleKeys.STOP_SOURCE_NAME, possibleTrip.getFirstStopName());
|
||||
bundle.putLong(BundleKeys.STOP_SOURCE_TIME, possibleTrip.getDepartureTime().toDateTimeToday().getMillis());
|
||||
bundle.putString(BundleKeys.STOP_DESTINATION_NAME, possibleTrip.getLastStopName());
|
||||
bundle.putLong(BundleKeys.STOP_DESTINATION_TIME, possibleTrip.getArrivalTime().toDateTimeToday().getMillis());
|
||||
|
||||
notifications.cancel(tripId, Notifications.ARRIVING);
|
||||
notifications.cancel(tripId, Notifications.DEPARTING);
|
||||
floatingActionButton.setBackgroundTintList(ColorStateList.valueOf(ColorUtils.getThemeColor(this, R.attr.colorAccent)));
|
||||
|
||||
if (arrivalMinutes > 0) {
|
||||
LocalDateTime arrivingDateTime = new LocalDateTime(possibleTrip.getArrivalTime().toDateTimeToday());
|
||||
|
||||
bundle.putString(BundleKeys.STOP_METHOD, Notifications.ARRIVING);
|
||||
notifications.set(tripId, arrivingDateTime, arrivalMinutes, Notifications.ARRIVING, bundle);
|
||||
floatingActionButton.setBackgroundTintList(ColorStateList.valueOf(ColorUtils.getThemeColor(this, R.attr.colorPrimary)));
|
||||
}
|
||||
|
||||
if (departureMinutes > 0) {
|
||||
LocalDateTime departingDateTime = new LocalDateTime(possibleTrip.getDepartureTime().toDateTimeToday());
|
||||
|
||||
bundle.putString(BundleKeys.STOP_METHOD, Notifications.DEPARTING);
|
||||
notifications.set(tripId, departingDateTime, departureMinutes, Notifications.DEPARTING, bundle);
|
||||
floatingActionButton.setBackgroundTintList(ColorStateList.valueOf(ColorUtils.getThemeColor(this, R.attr.colorPrimary)));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStart() {
|
||||
super.onStart();
|
||||
|
@ -115,6 +177,14 @@ public class TripActivity extends AppCompatActivity {
|
|||
|
||||
private void loadFragments() {
|
||||
if (tripStops != null && possibleTrip != null) {
|
||||
if (notifications.getAlarmMinutes(possibleTrip.getTripId(), Notifications.ARRIVING) != -1) {
|
||||
floatingActionButton.setBackgroundTintList(ColorStateList.valueOf(ColorUtils.getThemeColor(this, R.attr.colorPrimary)));
|
||||
}
|
||||
|
||||
if (notifications.getAlarmMinutes(possibleTrip.getTripId(), Notifications.DEPARTING) != -1) {
|
||||
floatingActionButton.setBackgroundTintList(ColorStateList.valueOf(ColorUtils.getThemeColor(this, R.attr.colorPrimary)));
|
||||
}
|
||||
|
||||
tripStops = StopTimesUtils.filterAndOrder(tripStops, possibleTrip.getTripDirection(), sourceId, destinationId);
|
||||
chooChooRouterManager.loadTripDetailsFragments(possibleTrip, tripStops);
|
||||
}
|
||||
|
@ -138,6 +208,9 @@ public class TripActivity extends AppCompatActivity {
|
|||
tripStops = StopTimesUtils.filterAndOrder(tripStops, trip.direction_id, sourceId);
|
||||
destinationId = tripStops.get(tripStops.size() - 1).stop_id;
|
||||
chooChooLoader.loadPossibleTrip(tripId, sourceId, destinationId);
|
||||
} else if (rxMessage.isMessageValidFor(RxMessageKeys.NOTIFICATION_SELECTED)) {
|
||||
Pair<Integer, Integer> notifications = ((RxMessageNotificationPair) rxMessage).getMessage();
|
||||
changeNotificationPreferences(notifications.first, notifications.second);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -97,6 +97,7 @@ public class TripFilterActivity extends AppCompatActivity {
|
|||
super.onStop();
|
||||
googleApiClient.disconnect();
|
||||
fabShow();
|
||||
subscription.unsubscribe();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -4,6 +4,7 @@ import com.eleith.calchoochoo.StopActivity;
|
|||
import com.eleith.calchoochoo.StopSearchActivity;
|
||||
import com.eleith.calchoochoo.TripActivity;
|
||||
import com.eleith.calchoochoo.TripFilterActivity;
|
||||
import com.eleith.calchoochoo.fragments.SetAlarmDialogFragment;
|
||||
import com.eleith.calchoochoo.fragments.TripFilterSuggestionsFragment;
|
||||
import com.eleith.calchoochoo.fragments.TripFilterTimeAndMethodDialogFragment;
|
||||
import com.eleith.calchoochoo.MapSearchActivity;
|
||||
|
@ -39,4 +40,5 @@ public interface ChooChooComponent {
|
|||
void inject(TripDetailFragment tripDetailFragment);
|
||||
void inject(MapSearchFragment mapSearchFragment);
|
||||
void inject(StopDetailsFragment stopDetailsFragment);
|
||||
void inject(SetAlarmDialogFragment setAlarmDialogFragment);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,160 @@
|
|||
package com.eleith.calchoochoo.fragments;
|
||||
|
||||
import android.app.Dialog;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.util.Pair;
|
||||
import android.support.v7.app.AlertDialog;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.Spinner;
|
||||
import android.widget.Switch;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.eleith.calchoochoo.R;
|
||||
import com.eleith.calchoochoo.TripActivity;
|
||||
import com.eleith.calchoochoo.data.PossibleTrip;
|
||||
import com.eleith.calchoochoo.utils.BundleKeys;
|
||||
import com.eleith.calchoochoo.utils.Notifications;
|
||||
import com.eleith.calchoochoo.utils.RxBus;
|
||||
import com.eleith.calchoochoo.utils.RxBusMessage.RxMessageKeys;
|
||||
import com.eleith.calchoochoo.utils.RxBusMessage.RxMessageNotificationPair;
|
||||
|
||||
import org.parceler.Parcels;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.OnClick;
|
||||
|
||||
public class SetAlarmDialogFragment extends android.support.v4.app.DialogFragment {
|
||||
private PossibleTrip possibleTrip;
|
||||
|
||||
@Inject
|
||||
RxBus rxBus;
|
||||
|
||||
@BindView(R.id.alarm_dialog_arrival_minutes)
|
||||
Spinner arrivalSpinner;
|
||||
@BindView(R.id.alarm_dialog_departure_minutes)
|
||||
Spinner departureSpinner;
|
||||
@BindView(R.id.alarm_dialog_arrival_minutes_form)
|
||||
LinearLayout arrivalForm;
|
||||
@BindView(R.id.alarm_dialog_departure_minutes_form)
|
||||
LinearLayout departureForm;
|
||||
@BindView(R.id.alarm_dialog_arrival_enable)
|
||||
Switch arrivalSwitch;
|
||||
@BindView(R.id.alarm_dialog_departure_enable)
|
||||
Switch departureSwitch;
|
||||
@BindView(R.id.alarm_dialog_ok)
|
||||
Button okButton;
|
||||
@BindView(R.id.alarm_dialog_cancel)
|
||||
Button cancelButton;
|
||||
@BindView(R.id.alarm_dialog_arrival_text)
|
||||
TextView arrivalText;
|
||||
@BindView(R.id.alarm_dialog_departure_text)
|
||||
TextView departureText;
|
||||
@BindView(R.id.alarm_dialog_trip_number)
|
||||
TextView tripText;
|
||||
|
||||
@Override
|
||||
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
((TripActivity) getActivity()).getComponent().inject(this);
|
||||
unWrapBundle(savedInstanceState == null ? getArguments() : savedInstanceState);
|
||||
}
|
||||
|
||||
@Override
|
||||
@NonNull
|
||||
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
|
||||
LayoutInflater inflater = getActivity().getLayoutInflater();
|
||||
View view = inflater.inflate(R.layout.fragment_alarm_dialog, null);
|
||||
ButterKnife.bind(this, view);
|
||||
builder.setView(view);
|
||||
|
||||
unWrapBundle(savedInstanceState);
|
||||
initializeDialogValues();
|
||||
|
||||
return builder.create();
|
||||
}
|
||||
|
||||
private void initializeDialogValues() {
|
||||
Notifications notifications = new Notifications(getContext());
|
||||
int arrivingMinutes = notifications.getAlarmMinutes(possibleTrip.getTripId(), Notifications.ARRIVING);
|
||||
int departingMinutes = notifications.getAlarmMinutes(possibleTrip.getTripId(), Notifications.DEPARTING);
|
||||
|
||||
tripText.setText(possibleTrip.getTripId());
|
||||
arrivalText.setText(possibleTrip.getLastStopName().replace(" Caltrain", ""));
|
||||
departureText.setText(possibleTrip.getFirstStopName().replace(" Caltrain", ""));
|
||||
|
||||
if (arrivingMinutes != -1) {
|
||||
arrivalSpinner.setSelection((arrivingMinutes / 5) - 1);
|
||||
arrivalSwitch.setChecked(true);
|
||||
toggleArrivalForm();
|
||||
} else {
|
||||
arrivalSpinner.setSelection(2);
|
||||
arrivalSwitch.setChecked(false);
|
||||
}
|
||||
|
||||
if (departingMinutes != -1) {
|
||||
departureSpinner.setSelection((departingMinutes / 5) - 1);
|
||||
departureSwitch.setChecked(true);
|
||||
toggleDepartureForm();
|
||||
} else {
|
||||
departureSpinner.setSelection(2);
|
||||
departureSwitch.setChecked(false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSaveInstanceState(Bundle outState) {
|
||||
outState.putParcelable(BundleKeys.POSSIBLE_TRIP, Parcels.wrap(possibleTrip));
|
||||
super.onSaveInstanceState(outState);
|
||||
}
|
||||
|
||||
private void unWrapBundle(Bundle bundle) {
|
||||
if (bundle != null) {
|
||||
possibleTrip = Parcels.unwrap(bundle.getParcelable(BundleKeys.POSSIBLE_TRIP));
|
||||
}
|
||||
}
|
||||
|
||||
@OnClick(R.id.alarm_dialog_cancel)
|
||||
public void cancelDialog() {
|
||||
getDialog().dismiss();
|
||||
}
|
||||
|
||||
@OnClick(R.id.alarm_dialog_ok)
|
||||
public void submitDialog() {
|
||||
Boolean arrivalOn = arrivalSwitch.isChecked();
|
||||
Boolean departureOn = departureSwitch.isChecked();
|
||||
|
||||
int arrivalMinutes = arrivalOn ? (arrivalSpinner.getSelectedItemPosition() + 1) * 5 : -1;
|
||||
int departureMinutes = departureOn ? (departureSpinner.getSelectedItemPosition() + 1) * 5 : -1;
|
||||
|
||||
rxBus.send(new RxMessageNotificationPair(RxMessageKeys.NOTIFICATION_SELECTED, new Pair<>(departureMinutes, arrivalMinutes)));
|
||||
|
||||
getDialog().dismiss();
|
||||
}
|
||||
|
||||
@OnClick(R.id.alarm_dialog_arrival_enable)
|
||||
public void toggleArrivalForm() {
|
||||
if (arrivalSwitch.isChecked()) {
|
||||
arrivalForm.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
arrivalForm.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
@OnClick(R.id.alarm_dialog_departure_enable)
|
||||
public void toggleDepartureForm() {
|
||||
if (departureSwitch.isChecked()) {
|
||||
departureForm.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
departureForm.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -114,7 +114,7 @@ public class TripFilterTimeAndMethodDialogFragment extends android.support.v4.ap
|
|||
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
|
||||
LayoutInflater inflater = getActivity().getLayoutInflater();
|
||||
View view = inflater.inflate(R.layout.fragment_departing_arriving_selector, null);
|
||||
View view = inflater.inflate(R.layout.fragment_time_selection_dialog, null);
|
||||
ButterKnife.bind(this, view);
|
||||
builder.setView(view);
|
||||
|
||||
|
|
|
@ -17,4 +17,8 @@ public class BundleKeys {
|
|||
public static final String ROUTES = "routes";
|
||||
public static final String POSSIBLE_TRAINS = "possibleTrains";
|
||||
public static final String DIRECTION = "direction";
|
||||
public static final String STOP_SOURCE_NAME = "stopSourceName";
|
||||
public static final String STOP_DESTINATION_NAME = "stopDestinationName";
|
||||
public static final String STOP_SOURCE_TIME = "stopSourceTime";
|
||||
public static final String STOP_DESTINATION_TIME = "stopDestinationTime";
|
||||
}
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
package com.eleith.calchoochoo.utils;
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.annotation.AttrRes;
|
||||
import android.support.annotation.ColorInt;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.util.TypedValue;
|
||||
|
||||
public class ColorUtils {
|
||||
@ColorInt
|
||||
public static int getThemeColor
|
||||
(
|
||||
@NonNull final Context context,
|
||||
@AttrRes final int attributeColor
|
||||
) {
|
||||
final TypedValue value = new TypedValue();
|
||||
context.getTheme().resolveAttribute(attributeColor, value, true);
|
||||
return value.data;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,99 @@
|
|||
package com.eleith.calchoochoo.utils;
|
||||
|
||||
import android.app.AlarmManager;
|
||||
import android.app.Notification;
|
||||
import android.app.NotificationManager;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.graphics.Bitmap;
|
||||
import android.os.Bundle;
|
||||
import android.support.v7.app.NotificationCompat;
|
||||
|
||||
import org.joda.time.LocalDateTime;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class Notifications {
|
||||
public static final String ARRIVING = "arriving";
|
||||
public static final String DEPARTING = "departing";
|
||||
private static final String PREFS_NAME = "com.eleith.calchoochoo.TripActivity";
|
||||
private static final String PREF_PREFIX_KEY = "choochoo_trip_";
|
||||
private Context context;
|
||||
private SharedPreferences preferences;
|
||||
|
||||
public Notifications(Context context) {
|
||||
this.context = context;
|
||||
this.preferences = context.getSharedPreferences(PREFS_NAME, 0);
|
||||
}
|
||||
|
||||
public int getAlarmId(String tripId, String method) {
|
||||
return preferences.getInt(PREF_PREFIX_KEY + tripId + "_" + method, -1);
|
||||
}
|
||||
|
||||
public int getAlarmMinutes(String tripId, String method) {
|
||||
return preferences.getInt(PREF_PREFIX_KEY + tripId + "_" + method + "_minutes", -1);
|
||||
}
|
||||
|
||||
private void saveAlarmInfo(String tripId, String method, int alarmId, int minutes) {
|
||||
SharedPreferences.Editor editor = preferences.edit();
|
||||
editor.putInt(PREF_PREFIX_KEY + tripId + "_" + method, alarmId);
|
||||
editor.putInt(PREF_PREFIX_KEY + tripId + "_" + method + "_minutes", minutes);
|
||||
editor.apply();
|
||||
}
|
||||
|
||||
private void removeAlarms(String tripId, String method) {
|
||||
SharedPreferences.Editor editor = preferences.edit();
|
||||
editor.remove(PREF_PREFIX_KEY + tripId + "_" + method);
|
||||
editor.remove(PREF_PREFIX_KEY + tripId + "_" + method + "_minutes");
|
||||
editor.apply();
|
||||
}
|
||||
|
||||
private Intent makeIntent() {
|
||||
Intent notificationIntent = new Intent("android.media.action.DISPLAY_NOTIFICATION");
|
||||
notificationIntent.addCategory("android.intent.category.DEFAULT");
|
||||
|
||||
return notificationIntent;
|
||||
}
|
||||
|
||||
public void set(String tripId, LocalDateTime alarmTime, int minutesWarning, String method, Bundle bundle) {
|
||||
int alarmId = UUID.randomUUID().hashCode();
|
||||
Intent notificationIntent = makeIntent();
|
||||
notificationIntent.putExtras(bundle);
|
||||
|
||||
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
|
||||
PendingIntent arrivalIntent = PendingIntent.getBroadcast(context, alarmId, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
|
||||
|
||||
alarmManager.setExact(AlarmManager.RTC_WAKEUP, alarmTime.minusMinutes(minutesWarning).toDate().getTime(), arrivalIntent);
|
||||
saveAlarmInfo(tripId, method, alarmId, minutesWarning);
|
||||
}
|
||||
|
||||
public void cancel(String tripId, String method) {
|
||||
Intent notificationIntent = makeIntent();
|
||||
int alarmId = getAlarmId(tripId, method);
|
||||
|
||||
if (alarmId != -1) {
|
||||
PendingIntent.getBroadcast(context, alarmId, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT).cancel();
|
||||
removeAlarms(tripId, method);
|
||||
}
|
||||
}
|
||||
|
||||
public Notification build(String title, String content, String ticker, int drawableIconId, PendingIntent intent) {
|
||||
Bitmap bitmapIcon = DrawableUtils.getBitmapFromVectorDrawable(context.getApplicationContext(), drawableIconId, 0.25f);
|
||||
NotificationCompat.Builder builder = new NotificationCompat.Builder(context.getApplicationContext());
|
||||
return builder.setContentTitle(title)
|
||||
.setContentText(content)
|
||||
.setTicker(ticker)
|
||||
.setLargeIcon(bitmapIcon)
|
||||
.setDefaults(Notification.DEFAULT_ALL)
|
||||
.setSmallIcon(drawableIconId)
|
||||
.setContentIntent(intent).build();
|
||||
}
|
||||
|
||||
public void send(Notification notification, String tripId, String method) {
|
||||
NotificationManager notificationManager = (NotificationManager) context.getApplicationContext().getSystemService(Context.NOTIFICATION_SERVICE);
|
||||
notificationManager.notify(getAlarmId(tripId, method), notification);
|
||||
removeAlarms(tripId, method);
|
||||
}
|
||||
}
|
|
@ -27,7 +27,8 @@ public class RxMessageKeys {
|
|||
public static final String LOADED_TRIPS = "loadedTrips";
|
||||
public static final String LOADED_POSSIBLE_TRIP = "loadedPossibleTrip";
|
||||
public static final String LOADED_POSSIBLE_TRIPS = "loadedPossibleTrips";
|
||||
public static final String LOADED_STOPS_ON_TRIP = "laodedStopsOnTrip";
|
||||
public static final String LOADED_STOPS_ON_TRIP = "loadedStopsOnTrip";
|
||||
public static final String NOTIFICATION_SELECTED = "notificationSelected";
|
||||
|
||||
private static final Map<String, Class> keyToClassMap = createKeyMap();
|
||||
|
||||
|
@ -57,6 +58,7 @@ public class RxMessageKeys {
|
|||
map.put(LOADED_POSSIBLE_TRIP, RxMessagePossibleTrip.class);
|
||||
map.put(LOADED_STOPS_ON_TRIP, RxMessageStops.class);
|
||||
map.put(LOADED_POSSIBLE_TRIPS, RxMessagePossibleTrips.class);
|
||||
map.put(NOTIFICATION_SELECTED, RxMessageNotificationPair.class);
|
||||
|
||||
return Collections.unmodifiableMap(map);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
package com.eleith.calchoochoo.utils.RxBusMessage;
|
||||
|
||||
import android.support.v4.util.Pair;
|
||||
|
||||
public class RxMessageNotificationPair extends RxMessage<Pair<Integer, Integer>> {
|
||||
|
||||
public RxMessageNotificationPair(String key, Pair<Integer, Integer> message) {
|
||||
super(key, message);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="#FFffffff"
|
||||
android:pathData="M7.88,3.39L6.6,1.86 2,5.71l1.29,1.53 4.59,-3.85zM22,5.72l-4.6,-3.86 -1.29,1.53 4.6,3.86L22,5.72zM12,4c-4.97,0 -9,4.03 -9,9s4.02,9 9,9c4.97,0 9,-4.03 9,-9s-4.03,-9 -9,-9zM12,20c-3.87,0 -7,-3.13 -7,-7s3.13,-7 7,-7 7,3.13 7,7 -3.13,7 -7,7zM13,9h-2v3L8,12v2h3v3h2v-3h3v-2h-3L13,9z"/>
|
||||
</vector>
|
|
@ -0,0 +1,136 @@
|
|||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
tools:context=".fragments.TripFilterTimeAndMethodDialogFragment">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="top"
|
||||
android:background="?attr/colorAccent"
|
||||
android:padding="15dp">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/notification_for_train_num"
|
||||
android:textColor="@color/primary_text_material_light"
|
||||
android:textStyle="bold"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/alarm_dialog_trip_number"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="@color/primary_text_material_light"
|
||||
android:textStyle="bold"
|
||||
tools:text="145"/>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:orientation="vertical">
|
||||
|
||||
<Switch
|
||||
android:id="@+id/alarm_dialog_departure_enable"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="15dp"
|
||||
android:text="@string/notification_departure"/>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/alarm_dialog_departure_minutes_form"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:padding="15dp"
|
||||
android:visibility="gone">
|
||||
|
||||
<android.support.v7.widget.AppCompatSpinner
|
||||
android:id="@+id/alarm_dialog_departure_minutes"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:entries="@array/minutes"
|
||||
android:spinnerMode="dropdown"/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingEnd="6dp"
|
||||
android:text="@string/before"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/alarm_dialog_departure_text"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
tools:text="Mountain View"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<Switch
|
||||
android:id="@+id/alarm_dialog_arrival_enable"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="15dp"
|
||||
android:text="@string/notification_arriving"/>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/alarm_dialog_arrival_minutes_form"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:padding="15dp"
|
||||
android:visibility="gone">
|
||||
|
||||
<android.support.v7.widget.AppCompatSpinner
|
||||
android:id="@+id/alarm_dialog_arrival_minutes"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:entries="@array/minutes"
|
||||
android:spinnerMode="dropdown"/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingEnd="6dp"
|
||||
android:text="@string/before"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/alarm_dialog_arrival_text"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
tools:text="Palo Alto"/>
|
||||
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="end"
|
||||
android:orientation="horizontal"
|
||||
android:padding="5dp">
|
||||
|
||||
<Button
|
||||
android:id="@+id/alarm_dialog_cancel"
|
||||
style="@style/Widget.AppCompat.Button.Borderless"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/cancel"
|
||||
android:textColor="?attr/colorAccent"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/alarm_dialog_ok"
|
||||
style="@style/Widget.AppCompat.Button.Borderless"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/ok"
|
||||
android:textColor="?attr/colorAccent"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
|
@ -39,4 +39,18 @@
|
|||
<string name="transition_train_image">transition-train-image</string>
|
||||
<string name="transition_train_number_text">transition-train-number-text</string>
|
||||
<string name="transition_train_number">transition-train-number</string>
|
||||
|
||||
<string name="notification_for_train_num">Notifications For Train #</string>
|
||||
<string name="notification_departure">Departure notification</string>
|
||||
<string name="notification_arriving">Arrival notification</string>
|
||||
<string name="before">before</string>
|
||||
|
||||
<string-array name="minutes">
|
||||
<item>5 min</item>
|
||||
<item>10 min</item>
|
||||
<item>15 min</item>
|
||||
<item>20 min</item>
|
||||
<item>25 min</item>
|
||||
<item>30 min</item>
|
||||
</string-array>
|
||||
</resources>
|
||||
|
|
|
@ -5,7 +5,7 @@ buildscript {
|
|||
jcenter()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:2.3.0'
|
||||
classpath 'com.android.tools.build:gradle:2.3.1'
|
||||
classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
|
||||
// NOTE: Do not place your application dependencies here; they belong
|
||||
// in the individual module build.gradle files
|
||||
|
|
Reference in New Issue