Use loader to load single alarm

This commit is contained in:
Phillip Hsu 2016-06-30 02:58:34 -07:00
parent d042891e51
commit 43e9c20468
5 changed files with 112 additions and 16 deletions

View File

@ -4,11 +4,10 @@ import android.app.IntentService;
import android.content.Context;
import android.content.Intent;
import com.philliphsu.clock2.model.AlarmDatabaseHelper.AlarmCursor;
import com.philliphsu.clock2.model.DatabaseManager;
import com.philliphsu.clock2.util.AlarmUtils;
import java.util.List;
/**
* An {@link IntentService} subclass for handling asynchronous task requests in
* a service on a separate handler thread.
@ -60,12 +59,15 @@ public class OnBootUpAlarmScheduler extends IntentService {
@Override
protected void onHandleIntent(Intent intent) {
if (intent != null) {
List<Alarm> alarms = DatabaseManager.getInstance(this).getAlarms();
for (Alarm a : alarms) {
if (a.isEnabled()) {
AlarmUtils.scheduleAlarm(this, a, false);
// IntentService already works in a background thread, so we don't need to use a loader.
AlarmCursor cursor = DatabaseManager.getInstance(this).queryAlarms();
while (cursor.moveToNext()) {
Alarm alarm = cursor.getAlarm();
if (alarm.isEnabled()) {
AlarmUtils.scheduleAlarm(this, alarm, false);
}
}
cursor.close();
/* final String action = intent.getAction();
if (ACTION_FOO.equals(action)) {

View File

@ -5,6 +5,8 @@ import android.media.RingtoneManager;
import android.net.Uri;
import android.os.Bundle;
import android.support.annotation.StringRes;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.Loader;
import android.support.v7.app.ActionBar;
import android.support.v7.widget.SwitchCompat;
import android.text.SpannableString;
@ -28,6 +30,7 @@ import com.philliphsu.clock2.BaseActivity;
import com.philliphsu.clock2.DaysOfWeek;
import com.philliphsu.clock2.R;
import com.philliphsu.clock2.SharedPreferencesHelper;
import com.philliphsu.clock2.model.AlarmLoader;
import com.philliphsu.clock2.model.DatabaseManager;
import com.philliphsu.clock2.ringtone.RingtoneActivity;
import com.philliphsu.clock2.util.AlarmUtils;
@ -51,14 +54,16 @@ import static com.philliphsu.clock2.util.Preconditions.checkNotNull;
public class EditAlarmActivity extends BaseActivity implements AlarmNumpad.KeyListener,
EditAlarmContract.View, // TODO: Remove @Override from the methods
AlarmUtilsHelper,
SharedPreferencesHelper {
SharedPreferencesHelper,
LoaderManager.LoaderCallbacks<Alarm> {
private static final String TAG = "EditAlarmActivity";
public static final String EXTRA_ALARM_ID = "com.philliphsu.clock2.editalarm.extra.ALARM_ID";
private static final RelativeSizeSpan AMPM_SIZE_SPAN = new RelativeSizeSpan(0.5f);
private static final int REQUEST_PICK_RINGTONE = 0;
private static final int ID_MENU_ITEM = 0;
private long mOldAlarmId;
private Uri mSelectedRingtoneUri;
private Alarm mOldAlarm;
private DatabaseManager mDatabaseManager;
@ -80,7 +85,17 @@ public class EditAlarmActivity extends BaseActivity implements AlarmNumpad.KeyLi
setWeekDaysText();
mNumpad.setKeyListener(this);
mDatabaseManager = DatabaseManager.getInstance(this); // MUST be before loading alarm
loadAlarm(getIntent().getLongExtra(EXTRA_ALARM_ID, -1));
mOldAlarmId = getIntent().getLongExtra(EXTRA_ALARM_ID, -1);
if (mOldAlarmId != -1) {
// getLoaderManager() for support fragments by default returns the
// support version of LoaderManager. However, since this is an Activity,
// we have both the native getLoaderManager() and getSupportLoaderManager().
// Use the latter to remain consistent with the rest of our current code base.
getSupportLoaderManager().initLoader(0, null, this);
} else {
// Nothing to load, so show default values
showDetails();
}
setTimeTextHint(); // TODO: private access
}
@ -503,11 +518,22 @@ public class EditAlarmActivity extends BaseActivity implements AlarmNumpad.KeyLi
return AlarmUtils.readPreference(this, key, defaultValue);
}
private void loadAlarm(long alarmId) {
mOldAlarm = alarmId > -1 ? mDatabaseManager.getAlarm(alarmId) : null;
@Override
public Loader<Alarm> onCreateLoader(int id, Bundle args) {
return new AlarmLoader(this, mOldAlarmId);
}
@Override
public void onLoadFinished(Loader<Alarm> loader, Alarm data) {
mOldAlarm = data;
showDetails();
}
@Override
public void onLoaderReset(Loader<Alarm> loader) {
// nothing to reset
}
// TODO: Privatize access of each method called here.
private void showDetails() {
if (mOldAlarm != null) {

View File

@ -0,0 +1,23 @@
package com.philliphsu.clock2.model;
import android.content.Context;
import com.philliphsu.clock2.Alarm;
/**
* Created by Phillip Hsu on 6/30/2016.
*/
public class AlarmLoader extends DataLoader<Alarm> {
private long mAlarmId;
public AlarmLoader(Context context, long alarmId) {
super(context);
mAlarmId = alarmId;
}
@Override
public Alarm loadInBackground() {
return DatabaseManager.getInstance(getContext()).getAlarm(mAlarmId);
}
}

View File

@ -0,0 +1,34 @@
package com.philliphsu.clock2.model;
import android.content.Context;
import android.support.v4.content.AsyncTaskLoader;
/**
* Created by Phillip Hsu on 6/30/2016.
*/
public abstract class DataLoader<D> extends AsyncTaskLoader<D> {
private D mData;
public DataLoader(Context context) {
super(context);
}
@Override
protected void onStartLoading() {
if (mData != null) {
deliverResult(mData);
} else {
forceLoad();
}
}
@Override
public void deliverResult(D data) {
mData = data;
if (isStarted()) {
super.deliverResult(data);
}
}
}

View File

@ -21,7 +21,6 @@ import static android.app.PendingIntent.FLAG_CANCEL_CURRENT;
import static android.app.PendingIntent.FLAG_NO_CREATE;
import static android.app.PendingIntent.getActivity;
import static com.philliphsu.clock2.util.DateFormatUtils.formatTime;
import static com.philliphsu.clock2.util.Preconditions.checkNotNull;
import static java.util.concurrent.TimeUnit.HOURS;
/**
@ -75,12 +74,16 @@ public final class AlarmUtils {
AlarmManager am = (AlarmManager) c.getSystemService(Context.ALARM_SERVICE);
PendingIntent pi = alarmIntent(c, a, true);
am.cancel(pi);
pi.cancel();
if (pi != null) {
am.cancel(pi);
pi.cancel();
}
pi = notifyUpcomingAlarmIntent(c, a, true);
am.cancel(pi);
pi.cancel();
if (pi != null) {
am.cancel(pi);
pi.cancel();
}
removeUpcomingAlarmNotification(c, a);
@ -159,9 +162,13 @@ public final class AlarmUtils {
.putExtra(RingtoneActivity.EXTRA_ITEM_ID, alarm.id());
int flag = retrievePrevious ? FLAG_NO_CREATE : FLAG_CANCEL_CURRENT;
PendingIntent pi = getActivity(context, alarm.intId(), intent, flag);
// Even when we try to retrieve a previous instance that actually did exist,
// null can be returned for some reason.
/*
if (retrievePrevious) {
checkNotNull(pi);
}
*/
return pi;
}
@ -176,9 +183,13 @@ public final class AlarmUtils {
}
int flag = retrievePrevious ? FLAG_NO_CREATE : FLAG_CANCEL_CURRENT;
PendingIntent pi = PendingIntent.getBroadcast(context, alarm.intId(), intent, flag);
// Even when we try to retrieve a previous instance that actually did exist,
// null can be returned for some reason.
/*
if (retrievePrevious) {
checkNotNull(pi);
}
*/
return pi;
}