Merge pull request #6 from FuegoFro/clean_up_your_train_view
Reorganize train info views and general code cleanup
This commit is contained in:
commit
4b8b7af55a
@ -17,6 +17,7 @@ import android.os.Handler;
|
||||
import android.os.IBinder;
|
||||
import android.os.Parcelable;
|
||||
import android.os.Vibrator;
|
||||
import android.support.v7.app.ActionBar;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.support.v7.view.ActionMode;
|
||||
import android.text.format.DateFormat;
|
||||
@ -48,6 +49,7 @@ import com.dougkeen.bart.services.EtdService;
|
||||
import com.dougkeen.bart.services.EtdService.EtdServiceBinder;
|
||||
import com.dougkeen.bart.services.EtdService.EtdServiceListener;
|
||||
import com.dougkeen.bart.services.EtdService_;
|
||||
import com.dougkeen.util.Assert;
|
||||
import com.dougkeen.util.Observer;
|
||||
import com.dougkeen.util.WakeLocker;
|
||||
|
||||
@ -86,8 +88,7 @@ public class ViewDeparturesActivity extends AppCompatActivity implements
|
||||
|
||||
mProgress = (ProgressBar) findViewById(android.R.id.progress);
|
||||
|
||||
mDeparturesAdapter = new DepartureArrayAdapter(this,
|
||||
R.layout.departure_listing);
|
||||
mDeparturesAdapter = new DepartureArrayAdapter(this);
|
||||
|
||||
setListAdapter(mDeparturesAdapter);
|
||||
final ListView listView = getListView();
|
||||
@ -127,9 +128,9 @@ public class ViewDeparturesActivity extends AppCompatActivity implements
|
||||
}
|
||||
|
||||
if (savedInstanceState != null) {
|
||||
if (savedInstanceState.containsKey("departures")) {
|
||||
for (Parcelable departure : savedInstanceState
|
||||
.getParcelableArray("departures")) {
|
||||
Parcelable[] departuresArray = savedInstanceState.getParcelableArray("departures");
|
||||
if (departuresArray != null) {
|
||||
for (Parcelable departure : departuresArray) {
|
||||
mDeparturesAdapter.add((Departure) departure);
|
||||
}
|
||||
mDeparturesAdapter.notifyDataSetChanged();
|
||||
@ -151,8 +152,9 @@ public class ViewDeparturesActivity extends AppCompatActivity implements
|
||||
}
|
||||
refreshBoardedDeparture(false);
|
||||
|
||||
getSupportActionBar().setHomeButtonEnabled(true);
|
||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||
ActionBar supportActionBar = Assert.notNull(getSupportActionBar());
|
||||
supportActionBar.setHomeButtonEnabled(true);
|
||||
supportActionBar.setDisplayHomeAsUpEnabled(true);
|
||||
|
||||
if (bartRunnerApplication.shouldPlayAlarmRingtone()) {
|
||||
soundTheAlarm();
|
||||
@ -440,7 +442,7 @@ public class ViewDeparturesActivity extends AppCompatActivity implements
|
||||
return;
|
||||
}
|
||||
|
||||
mYourTrainSection.updateFromBoardedDeparture();
|
||||
mYourTrainSection.updateFromBoardedDeparture(boardedDeparture);
|
||||
|
||||
if (currentVisibility != View.VISIBLE) {
|
||||
showYourTrainSection(animate);
|
||||
|
@ -0,0 +1,46 @@
|
||||
package com.dougkeen.bart.controls;
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.v7.widget.LinearLayoutCompat;
|
||||
import android.util.AttributeSet;
|
||||
import android.widget.Checkable;
|
||||
|
||||
import com.dougkeen.bart.R;
|
||||
|
||||
/**
|
||||
* A {@link android.widget.LinearLayout} that implements {@link Checkable} and changes
|
||||
* its background color when checked.
|
||||
*/
|
||||
public class CheckableLinearLayout extends LinearLayoutCompat implements Checkable {
|
||||
|
||||
private boolean mChecked;
|
||||
|
||||
public CheckableLinearLayout(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public CheckableLinearLayout(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
|
||||
public CheckableLinearLayout(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isChecked() {
|
||||
return mChecked;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setChecked(boolean checked) {
|
||||
mChecked = checked;
|
||||
int colorRes = isChecked() ? R.color.blue_selection : android.R.color.transparent;
|
||||
setBackgroundResource(colorRes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void toggle() {
|
||||
setChecked(!isChecked());
|
||||
}
|
||||
}
|
@ -1,42 +0,0 @@
|
||||
package com.dougkeen.bart.controls;
|
||||
|
||||
import android.content.Context;
|
||||
import android.view.LayoutInflater;
|
||||
import android.widget.Checkable;
|
||||
import android.widget.RelativeLayout;
|
||||
|
||||
import com.dougkeen.bart.R;
|
||||
|
||||
public class DepartureListItemLayout extends RelativeLayout implements
|
||||
Checkable {
|
||||
|
||||
public DepartureListItemLayout(Context context) {
|
||||
super(context);
|
||||
LayoutInflater.from(context).inflate(R.layout.departure_listing, this,
|
||||
true);
|
||||
}
|
||||
|
||||
private boolean mChecked;
|
||||
|
||||
@Override
|
||||
public boolean isChecked() {
|
||||
return mChecked;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setChecked(boolean checked) {
|
||||
mChecked = checked;
|
||||
if (isChecked()) {
|
||||
setBackgroundDrawable(getContext().getResources().getDrawable(
|
||||
R.color.blue_selection));
|
||||
} else {
|
||||
setBackgroundDrawable(getContext().getResources().getDrawable(
|
||||
android.R.color.transparent));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void toggle() {
|
||||
setChecked(!isChecked());
|
||||
}
|
||||
}
|
@ -10,8 +10,7 @@ import android.widget.TextSwitcher;
|
||||
import com.dougkeen.bart.R;
|
||||
import com.dougkeen.bart.model.TextProvider;
|
||||
|
||||
public class TimedTextSwitcher extends TextSwitcher implements
|
||||
Ticker.TickSubscriber {
|
||||
public class TimedTextSwitcher extends TextSwitcher implements Ticker.TickSubscriber {
|
||||
|
||||
public TimedTextSwitcher(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
|
@ -2,41 +2,51 @@ package com.dougkeen.bart.controls;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.drawable.GradientDrawable;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.widget.Checkable;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.dougkeen.bart.BartRunnerApplication;
|
||||
import com.dougkeen.bart.R;
|
||||
import com.dougkeen.bart.model.Departure;
|
||||
import com.dougkeen.bart.model.TextProvider;
|
||||
import com.dougkeen.util.Observer;
|
||||
|
||||
public class YourTrainLayout extends RelativeLayout implements Checkable {
|
||||
public class YourTrainLayout extends FrameLayout implements Checkable {
|
||||
|
||||
private final TextView destinationText;
|
||||
private final TextView trainLength;
|
||||
private final View colorBar;
|
||||
private final ImageView bikeIcon;
|
||||
private final View xferIcon;
|
||||
private final CountdownTextView departureCountdown;
|
||||
private final CountdownTextView arrivalCountdown;
|
||||
private final TextView alarmText;
|
||||
|
||||
public YourTrainLayout(Context context) {
|
||||
super(context);
|
||||
assignLayout(context);
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public YourTrainLayout(Context context, AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
|
||||
public YourTrainLayout(Context context, AttributeSet attrs, int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
assignLayout(context);
|
||||
}
|
||||
|
||||
public YourTrainLayout(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
assignLayout(context);
|
||||
}
|
||||
|
||||
public void assignLayout(Context context) {
|
||||
LayoutInflater.from(context).inflate(R.layout.your_train, this, true);
|
||||
|
||||
destinationText = (TextView) findViewById(R.id.yourTrainDestinationText);
|
||||
trainLength = (TextView) findViewById(R.id.yourTrainTrainLengthText);
|
||||
colorBar = findViewById(R.id.yourTrainDestinationColorBar);
|
||||
bikeIcon = (ImageView) findViewById(R.id.yourTrainBikeIcon);
|
||||
xferIcon = findViewById(R.id.yourTrainXferIcon);
|
||||
departureCountdown = (CountdownTextView) findViewById(R.id.yourTrainDepartureCountdown);
|
||||
arrivalCountdown = (CountdownTextView) findViewById(R.id.yourTrainArrivalCountdown);
|
||||
alarmText = (TextView) findViewById(R.id.alarmText);
|
||||
}
|
||||
|
||||
private boolean mChecked;
|
||||
@ -75,13 +85,8 @@ public class YourTrainLayout extends RelativeLayout implements Checkable {
|
||||
}
|
||||
|
||||
private void setBackground() {
|
||||
if (isChecked()) {
|
||||
setBackgroundDrawable(getContext().getResources().getDrawable(
|
||||
R.color.blue_selection));
|
||||
} else {
|
||||
setBackgroundDrawable(getContext().getResources().getDrawable(
|
||||
R.color.gray));
|
||||
}
|
||||
int colorRes = isChecked() ? R.color.blue_selection : R.color.gray;
|
||||
setBackgroundResource(colorRes);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -89,11 +94,10 @@ public class YourTrainLayout extends RelativeLayout implements Checkable {
|
||||
setChecked(!isChecked());
|
||||
}
|
||||
|
||||
public void updateFromBoardedDeparture() {
|
||||
final Departure boardedDeparture = ((BartRunnerApplication) ((Activity) getContext())
|
||||
.getApplication()).getBoardedDeparture();
|
||||
if (boardedDeparture == null)
|
||||
public void updateFromBoardedDeparture(final Departure boardedDeparture) {
|
||||
if (boardedDeparture == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!boardedDeparture.equals(mDeparture)) {
|
||||
if (mDeparture != null) {
|
||||
@ -110,36 +114,23 @@ public class YourTrainLayout extends RelativeLayout implements Checkable {
|
||||
|
||||
mDeparture = boardedDeparture;
|
||||
|
||||
((TextView) findViewById(R.id.yourTrainDestinationText))
|
||||
.setText(boardedDeparture.getTrainDestination().toString());
|
||||
destinationText.setText(boardedDeparture.getTrainDestination().toString());
|
||||
trainLength.setText(boardedDeparture.getTrainLengthAndPlatform());
|
||||
|
||||
((TextView) findViewById(R.id.yourTrainTrainLengthText))
|
||||
.setText(boardedDeparture.getTrainLengthAndPlatform());
|
||||
|
||||
ImageView colorBar = (ImageView) findViewById(R.id.yourTrainDestinationColorBar);
|
||||
((GradientDrawable) colorBar.getDrawable()).setColor(Color
|
||||
.parseColor(boardedDeparture.getTrainDestinationColor()));
|
||||
ImageView bikeIcon = (ImageView) findViewById(R.id.yourTrainBikeIcon);
|
||||
colorBar.setBackgroundColor(boardedDeparture.getTrainDestinationColor());
|
||||
if (boardedDeparture.isBikeAllowed()) {
|
||||
bikeIcon.setImageDrawable(getResources().getDrawable(
|
||||
R.drawable.bike));
|
||||
bikeIcon.setImageResource(R.drawable.bike);
|
||||
} else {
|
||||
bikeIcon.setImageDrawable(getResources().getDrawable(
|
||||
R.drawable.nobike));
|
||||
bikeIcon.setImageResource(R.drawable.nobike);
|
||||
}
|
||||
if (boardedDeparture.getRequiresTransfer()) {
|
||||
findViewById(R.id.yourTrainXferIcon)
|
||||
.setVisibility(View.VISIBLE);
|
||||
xferIcon.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
findViewById(R.id.yourTrainXferIcon)
|
||||
.setVisibility(View.INVISIBLE);
|
||||
xferIcon.setVisibility(View.INVISIBLE);
|
||||
}
|
||||
|
||||
updateAlarmIndicator();
|
||||
|
||||
CountdownTextView departureCountdown = (CountdownTextView) findViewById(R.id.yourTrainDepartureCountdown);
|
||||
CountdownTextView arrivalCountdown = (CountdownTextView) findViewById(R.id.yourTrainArrivalCountdown);
|
||||
|
||||
final TextProvider textProvider = new TextProvider() {
|
||||
@Override
|
||||
public String getText(long tickNumber) {
|
||||
@ -169,11 +160,10 @@ public class YourTrainLayout extends RelativeLayout implements Checkable {
|
||||
|
||||
private void updateAlarmIndicator() {
|
||||
if (!mDeparture.isAlarmPending()) {
|
||||
findViewById(R.id.alarmText).setVisibility(GONE);
|
||||
alarmText.setVisibility(GONE);
|
||||
} else {
|
||||
findViewById(R.id.alarmText).setVisibility(VISIBLE);
|
||||
((TextView) findViewById(R.id.alarmText)).setText(String
|
||||
.valueOf(mDeparture.getAlarmLeadTimeMinutes()));
|
||||
alarmText.setVisibility(VISIBLE);
|
||||
alarmText.setText(String.valueOf(mDeparture.getAlarmLeadTimeMinutes()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,13 +1,8 @@
|
||||
package com.dougkeen.bart.data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Color;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.graphics.drawable.GradientDrawable;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
@ -21,65 +16,36 @@ import android.widget.ViewSwitcher.ViewFactory;
|
||||
|
||||
import com.dougkeen.bart.R;
|
||||
import com.dougkeen.bart.controls.CountdownTextView;
|
||||
import com.dougkeen.bart.controls.DepartureListItemLayout;
|
||||
import com.dougkeen.bart.controls.CheckableLinearLayout;
|
||||
import com.dougkeen.bart.controls.TimedTextSwitcher;
|
||||
import com.dougkeen.bart.model.Departure;
|
||||
import com.dougkeen.bart.model.TextProvider;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
public class DepartureArrayAdapter extends ArrayAdapter<Departure> {
|
||||
|
||||
private Drawable noBikeDrawable;
|
||||
private Drawable bikeDrawable;
|
||||
|
||||
public DepartureArrayAdapter(Context context, int textViewResourceId,
|
||||
Departure[] objects) {
|
||||
super(context, textViewResourceId, objects);
|
||||
assignBikeDrawables();
|
||||
}
|
||||
|
||||
private void assignBikeDrawables() {
|
||||
noBikeDrawable = getContext().getResources().getDrawable(
|
||||
R.drawable.nobike);
|
||||
bikeDrawable = getContext().getResources().getDrawable(R.drawable.bike);
|
||||
}
|
||||
|
||||
public DepartureArrayAdapter(Context context, int resource,
|
||||
int textViewResourceId, Departure[] objects) {
|
||||
super(context, resource, textViewResourceId, objects);
|
||||
assignBikeDrawables();
|
||||
}
|
||||
|
||||
public DepartureArrayAdapter(Context context, int resource,
|
||||
int textViewResourceId, List<Departure> objects) {
|
||||
super(context, resource, textViewResourceId, objects);
|
||||
assignBikeDrawables();
|
||||
}
|
||||
|
||||
public DepartureArrayAdapter(Context context, int resource,
|
||||
int textViewResourceId) {
|
||||
super(context, resource, textViewResourceId);
|
||||
assignBikeDrawables();
|
||||
}
|
||||
|
||||
public DepartureArrayAdapter(Context context, int textViewResourceId,
|
||||
List<Departure> objects) {
|
||||
super(context, textViewResourceId, objects);
|
||||
assignBikeDrawables();
|
||||
}
|
||||
|
||||
public DepartureArrayAdapter(Context context, int textViewResourceId) {
|
||||
super(context, textViewResourceId);
|
||||
assignBikeDrawables();
|
||||
@SuppressWarnings("deprecation")
|
||||
public DepartureArrayAdapter(Context context) {
|
||||
super(context, 0 /* resource, unused since we override getView */);
|
||||
Resources resources = context.getResources();
|
||||
// We need to use the deprecated getDrawable since the newer version that
|
||||
// replaces it was only made available in API 21.
|
||||
noBikeDrawable = resources.getDrawable(R.drawable.nobike);
|
||||
bikeDrawable = resources.getDrawable(R.drawable.bike);
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getView(int position, View convertView, ViewGroup parent) {
|
||||
View view;
|
||||
if (convertView != null
|
||||
&& convertView instanceof DepartureListItemLayout) {
|
||||
if (convertView != null && convertView instanceof CheckableLinearLayout) {
|
||||
view = convertView;
|
||||
} else {
|
||||
view = new DepartureListItemLayout(getContext());
|
||||
view = LayoutInflater.from(getContext()).inflate(
|
||||
R.layout.departure_listing, parent, false /* attachToRoot */);
|
||||
}
|
||||
|
||||
final Departure departure = getItem(position);
|
||||
@ -132,10 +98,8 @@ public class DepartureArrayAdapter extends ArrayAdapter<Departure> {
|
||||
});
|
||||
}
|
||||
|
||||
ImageView colorBar = (ImageView) view
|
||||
.findViewById(R.id.destinationColorBar);
|
||||
((GradientDrawable) colorBar.getDrawable()).setColor(Color
|
||||
.parseColor(departure.getTrainDestinationColor()));
|
||||
view.findViewById(R.id.destinationColorBar)
|
||||
.setBackgroundColor(departure.getTrainDestinationColor());
|
||||
CountdownTextView countdownTextView = (CountdownTextView) view
|
||||
.findViewById(R.id.countdown);
|
||||
countdownTextView.setText(departure.getCountdownText());
|
||||
@ -171,7 +135,7 @@ public class DepartureArrayAdapter extends ArrayAdapter<Departure> {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
ImageView bikeIcon = (ImageView) view.findViewById(R.id.bikeIcon);
|
||||
if (departure.isBikeAllowed()) {
|
||||
bikeIcon.setImageDrawable(bikeDrawable);
|
||||
@ -179,11 +143,9 @@ public class DepartureArrayAdapter extends ArrayAdapter<Departure> {
|
||||
bikeIcon.setImageDrawable(noBikeDrawable);
|
||||
}
|
||||
if (departure.getRequiresTransfer()) {
|
||||
view.findViewById(R.id.xferIcon)
|
||||
.setVisibility(View.VISIBLE);
|
||||
view.findViewById(R.id.xferIcon).setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
view.findViewById(R.id.xferIcon)
|
||||
.setVisibility(View.INVISIBLE);
|
||||
view.findViewById(R.id.xferIcon).setVisibility(View.INVISIBLE);
|
||||
}
|
||||
|
||||
return view;
|
||||
|
@ -1,18 +1,14 @@
|
||||
package com.dougkeen.bart.model;
|
||||
|
||||
import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
|
||||
import org.apache.commons.lang3.time.DateFormatUtils;
|
||||
|
||||
import android.app.AlarmManager;
|
||||
import android.app.Notification;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Color;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.support.annotation.ColorInt;
|
||||
import android.support.v4.app.NotificationCompat;
|
||||
import android.support.v4.app.NotificationCompat.Builder;
|
||||
import android.util.Log;
|
||||
@ -23,6 +19,12 @@ import com.dougkeen.bart.activities.ViewDeparturesActivity;
|
||||
import com.dougkeen.bart.services.BoardedDepartureService;
|
||||
import com.dougkeen.util.Observable;
|
||||
|
||||
import org.apache.commons.lang3.time.DateFormatUtils;
|
||||
|
||||
import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
|
||||
public class Departure implements Parcelable, Comparable<Departure> {
|
||||
private static final int MINIMUM_MERGE_OVERLAP_MILLIS = 5000;
|
||||
private static final int EXPIRE_MINUTES_AFTER_ARRIVAL = 1;
|
||||
@ -133,8 +135,9 @@ public class Departure implements Parcelable, Comparable<Departure> {
|
||||
this.line = line;
|
||||
}
|
||||
|
||||
public String getTrainDestinationColor() {
|
||||
return destinationColor;
|
||||
@ColorInt
|
||||
public int getTrainDestinationColor() {
|
||||
return Color.parseColor(destinationColor);
|
||||
}
|
||||
|
||||
public void setTrainDestinationColor(String destinationColor) {
|
||||
@ -627,33 +630,36 @@ public class Departure implements Parcelable, Comparable<Departure> {
|
||||
final Intent cancelAlarmIntent = new Intent(context,
|
||||
BoardedDepartureService.class);
|
||||
cancelAlarmIntent.putExtra("cancelNotifications", true);
|
||||
String title = getOrigin().shortName + " to " + getPassengerDestination().shortName;
|
||||
|
||||
Builder notificationBuilder = new NotificationCompat.Builder(context)
|
||||
.setOngoing(true)
|
||||
.setSmallIcon(R.drawable.ic_stat_notification)
|
||||
.setContentTitle(
|
||||
getOrigin().shortName + " to "
|
||||
+ getPassengerDestination().shortName)
|
||||
.setContentTitle(title)
|
||||
.setContentIntent(getNotificationIntent(context)).setWhen(0);
|
||||
|
||||
if (android.os.Build.VERSION.SDK_INT >= 16) {
|
||||
notificationBuilder.setPriority(NotificationCompat.PRIORITY_HIGH)
|
||||
notificationBuilder
|
||||
.setPriority(NotificationCompat.PRIORITY_HIGH)
|
||||
.setContentText(minutesText + " until departure");
|
||||
|
||||
if (isAlarmPending()) {
|
||||
notificationBuilder.addAction(
|
||||
R.drawable.ic_action_cancel_alarm,
|
||||
"Cancel alarm",
|
||||
PendingIntent.getService(context, 0, cancelAlarmIntent,
|
||||
PendingIntent.FLAG_UPDATE_CURRENT)).setSubText(
|
||||
"Alarm " + getAlarmLeadTimeMinutes()
|
||||
+ " minutes before departure");
|
||||
PendingIntent pendingIntent = PendingIntent.getService(
|
||||
context, 0, cancelAlarmIntent, PendingIntent.FLAG_UPDATE_CURRENT);
|
||||
String subText = "Alarm " + getAlarmLeadTimeMinutes() + " minutes before departure";
|
||||
|
||||
notificationBuilder
|
||||
.addAction(R.drawable.ic_action_cancel_alarm, "Cancel alarm", pendingIntent)
|
||||
.setSubText(subText);
|
||||
}
|
||||
} else if (isAlarmPending()) {
|
||||
notificationBuilder.setContentText(minutesText
|
||||
String text = minutesText
|
||||
+ " to departure (alarm at " + getAlarmLeadTimeMinutes()
|
||||
+ " min" + ((getAlarmLeadTimeMinutes() == 1) ? "" : "s")
|
||||
+ ")");
|
||||
+ ")";
|
||||
notificationBuilder.setContentText(text);
|
||||
} else {
|
||||
notificationBuilder
|
||||
.setContentText(minutesText + " until departure");
|
||||
notificationBuilder.setContentText(minutesText + " until departure");
|
||||
}
|
||||
|
||||
return notificationBuilder.build();
|
||||
|
@ -4,7 +4,6 @@ import java.lang.ref.WeakReference;
|
||||
import java.util.List;
|
||||
|
||||
import android.app.AlarmManager;
|
||||
import android.app.NotificationManager;
|
||||
import android.app.Service;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
@ -15,6 +14,7 @@ import android.os.HandlerThread;
|
||||
import android.os.IBinder;
|
||||
import android.os.Looper;
|
||||
import android.os.Message;
|
||||
import android.support.v4.app.NotificationManagerCompat;
|
||||
|
||||
import com.dougkeen.bart.BartRunnerApplication;
|
||||
import com.dougkeen.bart.model.Departure;
|
||||
@ -34,7 +34,7 @@ public class BoardedDepartureService extends Service implements
|
||||
private boolean mBound = false;
|
||||
private EtdService mEtdService;
|
||||
private StationPair mStationPair;
|
||||
private NotificationManager mNotificationManager;
|
||||
private NotificationManagerCompat mNotificationManager;
|
||||
private AlarmManager mAlarmManager;
|
||||
private Handler mHandler;
|
||||
private boolean mHasShutDown = false;
|
||||
@ -91,7 +91,7 @@ public class BoardedDepartureService extends Service implements
|
||||
|
||||
bindService(EtdService_.intent(this).get(), mConnection,
|
||||
Context.BIND_AUTO_CREATE);
|
||||
mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
|
||||
mNotificationManager = NotificationManagerCompat.from(this);
|
||||
mAlarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
|
||||
mHandler = new Handler();
|
||||
super.onCreate();
|
||||
@ -302,8 +302,7 @@ public class BoardedDepartureService extends Service implements
|
||||
.getBoardedDeparture();
|
||||
if (boardedDeparture != null) {
|
||||
mNotificationManager.notify(DEPARTURE_NOTIFICATION_ID,
|
||||
boardedDeparture
|
||||
.createNotification(getApplicationContext()));
|
||||
boardedDeparture.createNotification(getApplicationContext()));
|
||||
}
|
||||
}
|
||||
|
||||
|
13
app/src/main/java/com/dougkeen/util/Assert.java
Normal file
13
app/src/main/java/com/dougkeen/util/Assert.java
Normal file
@ -0,0 +1,13 @@
|
||||
package com.dougkeen.util;
|
||||
|
||||
public final class Assert {
|
||||
// Uninstantiable
|
||||
private Assert() {}
|
||||
|
||||
public static <T> T notNull(T obj) {
|
||||
if (obj == null) {
|
||||
throw new AssertionError("Expected object to be non-null");
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
}
|
@ -1,77 +1,111 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<merge
|
||||
<com.dougkeen.bart.controls.CheckableLinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:bart="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent">
|
||||
android:layout_height="fill_parent"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal"
|
||||
>
|
||||
|
||||
<ImageView
|
||||
<!-- This layout is used when the height is >= 480 dp, eg usually in portrait mode. -->
|
||||
|
||||
<View
|
||||
android:id="@+id/destinationColorBar"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_width="15dp"
|
||||
android:layout_height="64dp"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:src="@drawable/basic_rectangle" />
|
||||
tools:background="#F00"
|
||||
/>
|
||||
|
||||
<!-- Holds the destination, the train info, and the arrival time -->
|
||||
<LinearLayout
|
||||
android:id="@+id/topRow"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_toRightOf="@id/destinationColorBar">
|
||||
android:layout_marginLeft="5dp"
|
||||
android:layout_marginRight="5dp"
|
||||
android:layout_weight="1"
|
||||
android:orientation="vertical"
|
||||
>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/destinationText"
|
||||
style="@style/DepartureDestinationText"
|
||||
android:layout_weight="1"
|
||||
android:ellipsize="marquee"
|
||||
android:singleLine="true" />
|
||||
android:singleLine="true"
|
||||
tools:text="Richmond"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/trainLengthText"
|
||||
style="@style/DepartureUncertaintyText"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
tools:text="9 cars, platform 2"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/estimatedArrival"
|
||||
style="@style/DepartureUncertaintyText"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
tools:text="Arrives ~11:12 AM (20 mins)"
|
||||
/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<!-- Holds the bike and xfer icons -->
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/bikeIcon"
|
||||
style="@style/BikeIcon" />
|
||||
style="@style/TrainInfoIcon"
|
||||
tools:src="@drawable/bike"
|
||||
/>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/xferIcon"
|
||||
style="@style/TrainInfoIcon"
|
||||
android:src="@drawable/xfer"
|
||||
/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<!-- Holds the departure countdown, uncertainty, and departure time -->
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="5dp"
|
||||
android:layout_marginRight="5dp"
|
||||
android:gravity="right"
|
||||
android:orientation="vertical"
|
||||
>
|
||||
|
||||
<com.dougkeen.bart.controls.CountdownTextView
|
||||
android:id="@+id/countdown"
|
||||
style="@style/DepartureCountdownText"
|
||||
android:gravity="right"
|
||||
android:width="90dp"
|
||||
bart:tickInterval="1" />
|
||||
android:gravity="right"
|
||||
bart:tickInterval="1"
|
||||
tools:text="9m, 57s"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/uncertainty"
|
||||
style="@style/DepartureUncertaintyText"
|
||||
tools:text="(+8s)"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/departureTime"
|
||||
style="@style/DepartureUncertaintyText"
|
||||
tools:text="11:20 AM"
|
||||
/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/xferIcon"
|
||||
style="@style/XferIcon"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_below="@id/topRow"
|
||||
android:src="@drawable/xfer" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/trainLengthText"
|
||||
style="@style/DepartureUncertaintyText"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/topRow"
|
||||
android:layout_toRightOf="@id/destinationColorBar" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/uncertainty"
|
||||
style="@style/DepartureUncertaintyText"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_below="@id/topRow" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/estimatedArrival"
|
||||
style="@style/DepartureUncertaintyText"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/trainLengthText"
|
||||
android:layout_toRightOf="@id/destinationColorBar" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/departureTime"
|
||||
style="@style/DepartureUncertaintyText"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_below="@id/uncertainty" />
|
||||
|
||||
</merge>
|
||||
</com.dougkeen.bart.controls.CheckableLinearLayout>
|
||||
|
@ -1,64 +1,98 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<merge
|
||||
<com.dougkeen.bart.controls.CheckableLinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:bart="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent">
|
||||
android:layout_height="fill_parent"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal"
|
||||
>
|
||||
|
||||
<ImageView
|
||||
<!-- This layout is used when the height is less than 480 dp (eg usually in landscape mode) -->
|
||||
|
||||
<View
|
||||
android:id="@+id/destinationColorBar"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_width="15dp"
|
||||
android:layout_height="45dp"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:src="@drawable/basic_rectangle" />
|
||||
tools:background="#F00"
|
||||
/>
|
||||
|
||||
<!-- Holds destination and train info/arrival -->
|
||||
<LinearLayout
|
||||
android:id="@+id/topRow"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_toRightOf="@id/destinationColorBar">
|
||||
android:layout_marginLeft="5dp"
|
||||
android:layout_marginRight="5dp"
|
||||
android:layout_weight="1"
|
||||
android:orientation="vertical"
|
||||
>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/destinationText"
|
||||
style="@style/DepartureDestinationText"
|
||||
android:layout_weight="1"
|
||||
android:ellipsize="marquee"
|
||||
android:singleLine="true" />
|
||||
android:singleLine="true"
|
||||
tools:text="Richmond"
|
||||
/>
|
||||
|
||||
<com.dougkeen.bart.controls.TimedTextSwitcher
|
||||
android:id="@+id/trainLengthText"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
bart:tickInterval="1"
|
||||
tools:text="9 cars, platform 2"
|
||||
/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<!-- Holds bike and xfer icons -->
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/bikeIcon"
|
||||
style="@style/BikeIcon" />
|
||||
style="@style/TrainInfoIcon"
|
||||
tools:src="@drawable/bike"
|
||||
/>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/xferIcon"
|
||||
style="@style/TrainInfoIcon"
|
||||
android:src="@drawable/xfer"
|
||||
/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<!-- Holds departure countdown and uncertainty/departure time-->
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="5dp"
|
||||
android:layout_marginRight="5dp"
|
||||
android:gravity="right"
|
||||
android:orientation="vertical"
|
||||
>
|
||||
|
||||
<com.dougkeen.bart.controls.CountdownTextView
|
||||
android:id="@+id/countdown"
|
||||
style="@style/DepartureCountdownText"
|
||||
android:gravity="right"
|
||||
android:width="90dp"
|
||||
bart:tickInterval="1" />
|
||||
android:gravity="right"
|
||||
bart:tickInterval="1"
|
||||
tools:text="9m, 57s"
|
||||
/>
|
||||
|
||||
<com.dougkeen.bart.controls.TimedTextSwitcher
|
||||
android:id="@+id/uncertainty"
|
||||
style="@style/DepartureUncertaintyText"
|
||||
bart:tickInterval="1"
|
||||
tools:text="(+8s)"
|
||||
/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/xferIcon"
|
||||
style="@style/XferIcon"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_below="@id/topRow"
|
||||
android:src="@drawable/xfer" />
|
||||
|
||||
<com.dougkeen.bart.controls.TimedTextSwitcher
|
||||
android:id="@+id/trainLengthText"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/topRow"
|
||||
android:layout_toRightOf="@id/destinationColorBar"
|
||||
bart:tickInterval="1" />
|
||||
|
||||
<com.dougkeen.bart.controls.TimedTextSwitcher
|
||||
android:id="@+id/uncertainty"
|
||||
style="@style/DepartureUncertaintyText"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_below="@id/topRow"
|
||||
bart:tickInterval="1" />
|
||||
|
||||
</merge>
|
||||
</com.dougkeen.bart.controls.CheckableLinearLayout>
|
||||
|
@ -1,82 +1,121 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<merge
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:bart="http://schemas.android.com/apk/res-auto" >
|
||||
xmlns:bart="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/alarmText"
|
||||
<!-- Holds the "Your Train" title and the alarm indicator -->
|
||||
<FrameLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/yourTrainHeader"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:text="@string/your_train"
|
||||
android:textAllCaps="true"
|
||||
android:textSize="20dp"
|
||||
android:textStyle="bold"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/alarmText"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="right"
|
||||
android:drawableLeft="@drawable/ic_action_alarm"
|
||||
android:gravity="center_vertical"
|
||||
android:textSize="16dp"
|
||||
android:visibility="gone"
|
||||
tools:text="5"
|
||||
/>
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
<!-- Holds the color bar, destination text, train info, bike icon, and xfer icon -->
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_alignParentTop="true"
|
||||
android:drawableLeft="@drawable/ic_action_alarm"
|
||||
android:gravity="center_vertical"
|
||||
android:textSize="16dp"
|
||||
android:visibility="gone"></TextView>
|
||||
android:orientation="horizontal"
|
||||
>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/yourTrainHeader"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:text="@string/your_train"
|
||||
android:textAllCaps="true"
|
||||
android:textSize="20dp"
|
||||
android:textStyle="bold" />
|
||||
<View
|
||||
android:id="@+id/yourTrainDestinationColorBar"
|
||||
android:layout_width="15dp"
|
||||
android:layout_height="45dp"
|
||||
android:layout_gravity="center_vertical"
|
||||
tools:background="#F00"
|
||||
/>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/yourTrainDestinationColorBar"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="45dp"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_below="@id/yourTrainHeader"
|
||||
android:src="@drawable/basic_rectangle" />
|
||||
<!-- Holds the destination text and train info -->
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:orientation="vertical"
|
||||
android:padding="5dp"
|
||||
>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/yourTrainDestinationText"
|
||||
style="@style/DepartureDestinationText"
|
||||
android:layout_below="@id/yourTrainHeader"
|
||||
android:layout_toRightOf="@id/yourTrainDestinationColorBar"
|
||||
android:ellipsize="marquee"
|
||||
android:singleLine="true" />
|
||||
<TextView
|
||||
android:id="@+id/yourTrainDestinationText"
|
||||
style="@style/DepartureDestinationText"
|
||||
android:ellipsize="marquee"
|
||||
android:singleLine="true"
|
||||
tools:text="Richmond"
|
||||
/>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/yourTrainBikeIcon"
|
||||
style="@style/BikeIcon"
|
||||
android:layout_below="@id/yourTrainHeader"
|
||||
android:layout_toRightOf="@id/yourTrainDestinationText" />
|
||||
<TextView
|
||||
android:id="@+id/yourTrainTrainLengthText"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
tools:text="9 cars, platform 2"
|
||||
/>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/yourTrainXferIcon"
|
||||
style="@style/XferIcon"
|
||||
android:layout_below="@id/yourTrainBikeIcon"
|
||||
android:layout_toRightOf="@id/yourTrainDestinationText"
|
||||
android:src="@drawable/xfer" />
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/yourTrainTrainLengthText"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/yourTrainDestinationText"
|
||||
android:layout_toRightOf="@id/yourTrainDestinationColorBar"
|
||||
android:paddingLeft="5dp" />
|
||||
<!-- Holds the bike icon and xfer icon -->
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/yourTrainBikeIcon"
|
||||
style="@style/TrainInfoIcon"
|
||||
tools:src="@drawable/bike"
|
||||
/>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/yourTrainXferIcon"
|
||||
style="@style/TrainInfoIcon"
|
||||
android:src="@drawable/xfer"
|
||||
/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<com.dougkeen.bart.controls.CountdownTextView
|
||||
android:id="@+id/yourTrainDepartureCountdown"
|
||||
style="@style/DepartureCountdownText"
|
||||
android:layout_alignLeft="@id/yourTrainSection"
|
||||
android:layout_alignRight="@id/yourTrainSection"
|
||||
android:layout_below="@id/yourTrainTrainLengthText"
|
||||
bart:tickInterval="1" />
|
||||
bart:tickInterval="1"
|
||||
tools:text="Leaves in 15 min, 20s (+8s)"
|
||||
/>
|
||||
|
||||
<com.dougkeen.bart.controls.CountdownTextView
|
||||
android:id="@+id/yourTrainArrivalCountdown"
|
||||
style="@style/DepartureCountdownText"
|
||||
android:layout_alignLeft="@id/yourTrainSection"
|
||||
android:layout_alignRight="@id/yourTrainSection"
|
||||
android:layout_below="@id/yourTrainDepartureCountdown"
|
||||
android:ellipsize="end"
|
||||
bart:tickInterval="5" />
|
||||
bart:tickInterval="5"
|
||||
tools:text="Arrives ~11:12 AM (20 mins)"
|
||||
/>
|
||||
|
||||
</merge>
|
||||
</LinearLayout>
|
||||
|
@ -92,18 +92,10 @@
|
||||
<item name="android:gravity">center</item>
|
||||
</style>
|
||||
|
||||
<style name="BikeIcon">
|
||||
<style name="TrainInfoIcon">
|
||||
<item name="android:layout_width">wrap_content</item>
|
||||
<item name="android:layout_height">wrap_content</item>
|
||||
<item name="android:layout_marginTop">5dp</item>
|
||||
<item name="android:layout_marginLeft">5dp</item>
|
||||
</style>
|
||||
|
||||
<style name="XferIcon">
|
||||
<item name="android:layout_width">wrap_content</item>
|
||||
<item name="android:layout_height">wrap_content</item>
|
||||
<item name="android:layout_marginRight">87dp</item>
|
||||
<item name="android:layout_marginBottom">5dp</item>
|
||||
<item name="android:layout_margin">5dp</item>
|
||||
</style>
|
||||
|
||||
</resources>
|
||||
|
Loading…
Reference in New Issue
Block a user