Created AlarmController class and moved relevant AlarmUtils code

This commit is contained in:
Phillip Hsu
2016-07-11 02:28:20 -07:00
parent 08e12cd14f
commit 058d6c86b7
13 changed files with 359 additions and 117 deletions
@@ -18,6 +18,7 @@ import com.philliphsu.clock2.DaysOfWeek;
import com.philliphsu.clock2.OnListItemInteractionListener;
import com.philliphsu.clock2.R;
import com.philliphsu.clock2.model.AlarmsRepository;
import com.philliphsu.clock2.util.AlarmController;
import com.philliphsu.clock2.util.AlarmUtils;
import java.util.Date;
@@ -38,6 +39,8 @@ import static com.philliphsu.clock2.util.DateFormatUtils.formatTime;
public class AlarmViewHolder extends BaseViewHolder<Alarm> implements AlarmCountdown.OnTickListener {
private static final RelativeSizeSpan AMPM_SIZE_SPAN = new RelativeSizeSpan(0.5f);
private final AlarmController mAlarmController;
@Bind(R.id.time) TextView mTime;
@Bind(R.id.on_off_switch) SwitchCompat mSwitch;
@Bind(R.id.label) TextView mLabel;
@@ -45,8 +48,17 @@ public class AlarmViewHolder extends BaseViewHolder<Alarm> implements AlarmCount
@Bind(R.id.recurring_days) TextView mDays;
@Bind(R.id.dismiss) Button mDismissButton;
@Deprecated // TODO: Delete this, the only usage is from AlarmsAdapter (SortedList), which is not used anymore.
public AlarmViewHolder(ViewGroup parent, OnListItemInteractionListener<Alarm> listener) {
super(parent, R.layout.item_alarm, listener);
mAlarmController = null;
mCountdown.setOnTickListener(this);
}
public AlarmViewHolder(ViewGroup parent, OnListItemInteractionListener<Alarm> listener,
AlarmController alarmController) {
super(parent, R.layout.item_alarm, listener);
mAlarmController = alarmController;
mCountdown.setOnTickListener(this);
}
@@ -76,7 +88,7 @@ public class AlarmViewHolder extends BaseViewHolder<Alarm> implements AlarmCount
} else {
// Dismisses the current upcoming alarm and handles scheduling the next alarm for us.
// Since changes are saved to the database, this prompts a UI refresh.
AlarmUtils.cancelAlarm(getContext(), alarm, true);
mAlarmController.cancelAlarm(alarm, true);
}
// TOneverDO: AlarmUtils.cancelAlarm() otherwise it will be called twice
/*
@@ -127,11 +139,10 @@ public class AlarmViewHolder extends BaseViewHolder<Alarm> implements AlarmCount
alarm.setEnabled(checked);
if (alarm.isEnabled()) {
// TODO: On Moto X, upcoming notification doesn't post immediately
AlarmUtils.scheduleAlarm(getContext(), alarm, true);
AlarmUtils.sendShowSnackbarBroadcast(getContext(), AlarmUtils.getRingsInText(getContext(), alarm.ringsIn()));
AlarmUtils.save(getContext(), alarm);
mAlarmController.scheduleAlarm(alarm, true);
mAlarmController.save(alarm);
} else {
AlarmUtils.cancelAlarm(getContext(), alarm, true);
mAlarmController.cancelAlarm(alarm, true);
// cancelAlarm() already calls save() for you.
}
mSwitch.setPressed(false); // clear the pressed focus, esp. if setPressed(true) was called manually
@@ -8,6 +8,7 @@ import android.view.ViewGroup;
import com.philliphsu.clock2.Alarm;
import com.philliphsu.clock2.OnListItemInteractionListener;
import com.philliphsu.clock2.model.AlarmDatabaseHelper.AlarmCursor;
import com.philliphsu.clock2.util.AlarmController;
/**
* Created by Phillip Hsu on 6/29/2016.
@@ -18,10 +19,13 @@ public class AlarmsCursorAdapter extends RecyclerView.Adapter<AlarmViewHolder> {
private static final String TAG = "AlarmsCursorAdapter";
private final OnListItemInteractionListener<Alarm> mListener;
private final AlarmController mAlarmController;
private AlarmCursor mCursor;
public AlarmsCursorAdapter(OnListItemInteractionListener<Alarm> listener) {
public AlarmsCursorAdapter(OnListItemInteractionListener<Alarm> listener,
AlarmController alarmController) {
mListener = listener;
mAlarmController = alarmController;
// Excerpt from docs of notifyDataSetChanged():
// "RecyclerView will attempt to synthesize [artificially create?]
// visible structural change events [when items are inserted, removed or
@@ -34,7 +38,7 @@ public class AlarmsCursorAdapter extends RecyclerView.Adapter<AlarmViewHolder> {
@Override
public AlarmViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new AlarmViewHolder(parent, mListener);
return new AlarmViewHolder(parent, mListener, mAlarmController);
}
@Override
@@ -1,7 +1,6 @@
package com.philliphsu.clock2.alarms;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
@@ -23,8 +22,8 @@ import com.philliphsu.clock2.OnListItemInteractionListener;
import com.philliphsu.clock2.R;
import com.philliphsu.clock2.editalarm.EditAlarmActivity;
import com.philliphsu.clock2.model.AlarmsListCursorLoader;
import com.philliphsu.clock2.util.AlarmUtils;
import com.philliphsu.clock2.util.LocalBroadcastHelper;
import com.philliphsu.clock2.util.AlarmController;
import com.philliphsu.clock2.util.DelayedSnackbarHandler;
import butterknife.Bind;
import butterknife.ButterKnife;
@@ -37,14 +36,10 @@ public class AlarmsFragment extends Fragment implements LoaderCallbacks<Cursor>,
private static final int REQUEST_EDIT_ALARM = 0;
// Public because MainActivity needs to use it.
public static final int REQUEST_CREATE_ALARM = 1;
/**
* Local broadcast senders can tell us to show a snackbar with a message on their behalf.
*/
public static final String ACTION_SHOW_SNACKBAR_MSG = "com.philliphsu.clock2.alarms.action.SHOW_SNACKBAR_MSG";
public static final String EXTRA_MSG = "com.philliphsu.clock2.alarms.extra.MSG";
private AlarmsCursorAdapter mAdapter;
private AsyncItemChangeHandler mAsyncItemChangeHandler;
private AlarmController mAlarmController;
private Handler mHandler = new Handler();
private View mSnackbarAnchor;
private long mScrollToStableId = RecyclerView.NO_ID;
@@ -78,6 +73,9 @@ public class AlarmsFragment extends Fragment implements LoaderCallbacks<Cursor>,
// Will succeed because the activity is created at this point.
// See the Fragment lifecycle.
mSnackbarAnchor = getActivity().findViewById(R.id.main_content);
mAlarmController = new AlarmController(getActivity(), mSnackbarAnchor);
mAsyncItemChangeHandler = new AsyncItemChangeHandler(getActivity(),
mSnackbarAnchor, this, mAlarmController);
getLoaderManager().initLoader(0, null, this);
}
@@ -87,33 +85,22 @@ public class AlarmsFragment extends Fragment implements LoaderCallbacks<Cursor>,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_alarms, container, false);
ButterKnife.bind(this, view);
// Set the adapter
Context context = view.getContext();
mList.setLayoutManager(new LinearLayoutManager(context));
mAdapter = new AlarmsCursorAdapter(this);
mAdapter = new AlarmsCursorAdapter(this, mAlarmController);
mList.setAdapter(mAdapter);
mAsyncItemChangeHandler = new AsyncItemChangeHandler(
getActivity(), mSnackbarAnchor, this);
return view;
}
@Override
public void onStart() {
super.onStart();
LocalBroadcastHelper.registerReceiver(getActivity(),
mShowSnackbarReceiver, ACTION_SHOW_SNACKBAR_MSG);
}
@Override
public void onStop() {
// This will always be called when we leave this screen, either by exiting the app or
// by navigating elsewhere. Since we unregister the receiver here, we will never receive
// a "show alarm snoozed" broadcast, because the snooze action is always made elsewhere
// in the app.
super.onStop();
Log.e(TAG, "onStop()");
LocalBroadcastHelper.unregisterReceiver(getActivity(), mShowSnackbarReceiver);
public void onResume() {
super.onResume();
// Show the pending Snackbar, if any, that was prepared for us
// by another app component.
DelayedSnackbarHandler.makeAndShow(mSnackbarAnchor);
}
@Override
@@ -221,19 +208,6 @@ public class AlarmsFragment extends Fragment implements LoaderCallbacks<Cursor>,
// TODO: Delete this method.
}
private final BroadcastReceiver mShowSnackbarReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
// See Intent#putExtras(Bundle):
// Putting a Bundle of extras into an intent will have its
// contents added to the intent's collection of extras,
// so we can individually retrieve the Bundle's extras
// directly from the intent.
String message = intent.getStringExtra(EXTRA_MSG);
AlarmUtils.showSnackbar(mSnackbarAnchor, message);
}
};
private static abstract class BaseAsyncItemChangeRunnable {
// TODO: Will holding onto this cause a memory leak?
private final AsyncItemChangeHandler mAsyncItemChangeHandler;