blob: 3b732318ff6a35f5a2891c58f819f51444f939fa [file] [log] [blame]
/*
* Copyright (C) 2007 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.deskclock;
import android.app.ActionBar;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Vibrator;
import android.preference.CheckBoxPreference;
import android.preference.Preference;
import android.preference.PreferenceActivity;
import android.preference.PreferenceScreen;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
/**
* Manages each alarm
*/
public class SetAlarm extends PreferenceActivity implements Preference.OnPreferenceChangeListener,
AlarmTimePickerDialogFragment.AlarmTimePickerDialogHandler {
private static final String KEY_CURRENT_ALARM = "currentAlarm";
private static final String KEY_ORIGINAL_ALARM = "originalAlarm";
private static final String KEY_TIME_PICKER_BUNDLE = "timePickerBundle";
private EditText mLabel;
private CheckBoxPreference mEnabledPref;
private Preference mTimePref;
private AlarmPreference mAlarmPref;
private CheckBoxPreference mVibratePref;
private RepeatPreference mRepeatPref;
private int mId;
private int mHour;
private int mMinute;
private Alarm mOriginalAlarm;
@Override
protected void onCreate(Bundle icicle) {
super.onCreate(icicle);
// Override the default content view.
setContentView(R.layout.set_alarm);
EditText label = (EditText) getLayoutInflater().inflate(R.layout.alarm_label, null);
ListView list = (ListView) findViewById(android.R.id.list);
list.addFooterView(label);
// TODO Stop using preferences for this view. Save on done, not after
// each change.
addPreferencesFromResource(R.xml.alarm_prefs);
// Get each preference so we can retrieve the value later.
mLabel = label;
mEnabledPref = (CheckBoxPreference) findPreference("enabled");
mEnabledPref.setOnPreferenceChangeListener(this);
mTimePref = findPreference("time");
mAlarmPref = (AlarmPreference) findPreference("alarm");
mAlarmPref.setOnPreferenceChangeListener(this);
mVibratePref = (CheckBoxPreference) findPreference("vibrate");
mVibratePref.setOnPreferenceChangeListener(this);
Vibrator v = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
if (!v.hasVibrator()) {
getPreferenceScreen().removePreference(mVibratePref);
}
mRepeatPref = (RepeatPreference) findPreference("setRepeat");
mRepeatPref.setOnPreferenceChangeListener(this);
Intent i = getIntent();
Alarm alarm = i.getParcelableExtra(Alarms.ALARM_INTENT_EXTRA);
if (alarm == null) {
// No alarm means create a new alarm.
alarm = new Alarm();
}
mOriginalAlarm = alarm;
// Populate the prefs with the original alarm data. updatePrefs also
// sets mId so it must be called before checking mId below.
updatePrefs(mOriginalAlarm);
// We have to do this to get the save/cancel buttons to highlight on
// their own.
getListView().setItemsCanFocus(true);
ActionBar actionBar = getActionBar();
if (actionBar != null) {
actionBar.setDisplayOptions(
0, ActionBar.DISPLAY_SHOW_HOME | ActionBar.DISPLAY_SHOW_TITLE);
LayoutInflater inflater = (LayoutInflater) getSystemService
(Context.LAYOUT_INFLATER_SERVICE);
View customActionBarView = inflater.inflate(R.layout.set_alarm_action_bar, null);
actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM,
ActionBar.DISPLAY_SHOW_CUSTOM | ActionBar.DISPLAY_SHOW_HOME |
ActionBar.DISPLAY_SHOW_TITLE);
actionBar.setCustomView(customActionBarView);
View saveMenuItem = customActionBarView.findViewById(R.id.save_menu_item);
saveMenuItem.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
saveAndExit();
}
});
}
// Attach actions to each button.
Button b = (Button) findViewById(R.id.alarm_save);
if (b != null) {
b.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
long time = saveAlarm(null);
if(mEnabledPref.isChecked()) {
AlarmUtils.popAlarmSetToast(SetAlarm.this, time);
}
finish();
}
});
}
b = (Button) findViewById(R.id.alarm_revert);
if (b != null) {
b.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
revert();
finish();
}
});
}
b = (Button) findViewById(R.id.alarm_delete);
if (b != null) {
if (mId == -1) {
b.setEnabled(false);
b.setVisibility(View.GONE);
} else {
b.setVisibility(View.VISIBLE);
b.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
deleteAlarm();
}
});
}
}
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == R.id.menu_delete) {
deleteAlarm();
return true;
}
return super.onOptionsItemSelected(item);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.set_alarm_context, menu);
return true;
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putParcelable(KEY_ORIGINAL_ALARM, mOriginalAlarm);
outState.putParcelable(KEY_CURRENT_ALARM, buildAlarmFromUi());
}
@Override
protected void onRestoreInstanceState(Bundle state) {
super.onRestoreInstanceState(state);
Alarm alarmFromBundle = state.getParcelable(KEY_ORIGINAL_ALARM);
if (alarmFromBundle != null) {
mOriginalAlarm = alarmFromBundle;
}
alarmFromBundle = state.getParcelable(KEY_CURRENT_ALARM);
if (alarmFromBundle != null) {
updatePrefs(alarmFromBundle);
}
Bundle b = state.getParcelable(KEY_TIME_PICKER_BUNDLE);
if (b != null) {
showTimePicker();
}
}
// Used to post runnables asynchronously.
private static final Handler sHandler = new Handler();
public boolean onPreferenceChange(final Preference p, Object newValue) {
// Asynchronously save the alarm since this method is called _before_
// the value of the preference has changed.
sHandler.post(new Runnable() {
public void run() {
// Editing any preference (except enable) enables the alarm.
if (p != mEnabledPref) {
mEnabledPref.setChecked(true);
}
saveAlarm(null);
}
});
return true;
}
private void updatePrefs(Alarm alarm) {
mId = alarm.id;
mEnabledPref.setChecked(alarm.enabled);
mLabel.setText(alarm.label);
mHour = alarm.hour;
mMinute = alarm.minutes;
mRepeatPref.setDaysOfWeek(alarm.daysOfWeek);
mVibratePref.setChecked(alarm.vibrate);
// Give the alert uri to the preference.
mAlarmPref.setAlert(alarm.alert);
updateTime();
}
@Override
public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen,
Preference preference) {
if (preference == mTimePref) {
showTimePicker();
}
return super.onPreferenceTreeClick(preferenceScreen, preference);
}
@Override
public void onBackPressed() {
saveAndExit();
}
private void showTimePicker() {
AlarmUtils.showTimeEditDialog(getFragmentManager(), null);
}
@Override
public void onDialogTimeSet(Alarm alarm, int hourOfDay, int minute) {
// onTimeSet is called when the user clicks "Set"
mHour = hourOfDay;
mMinute = minute;
updateTime();
// If the time has been changed, enable the alarm.
mEnabledPref.setChecked(true);
saveAlarm(null);
}
private void updateTime() {
mTimePref.setSummary(Alarms.formatTime(this, mHour, mMinute,
mRepeatPref.getDaysOfWeek()));
}
private long saveAlarm(Alarm alarm) {
if (alarm == null) {
alarm = buildAlarmFromUi();
}
long time;
if (alarm.id == -1) {
time = Alarms.addAlarm(this, alarm);
// addAlarm populates the alarm with the new id. Update mId so that
// changes to other preferences update the new alarm.
mId = alarm.id;
} else {
time = Alarms.setAlarm(this, alarm);
}
return time;
}
private Alarm buildAlarmFromUi() {
Alarm alarm = new Alarm();
alarm.id = mId;
alarm.enabled = mEnabledPref.isChecked();
alarm.hour = mHour;
alarm.minutes = mMinute;
alarm.daysOfWeek = mRepeatPref.getDaysOfWeek();
alarm.vibrate = mVibratePref.isChecked();
alarm.label = mLabel.getText().toString();
alarm.alert = mAlarmPref.getAlert();
return alarm;
}
private void deleteAlarm() {
if (mId == -1) {
// Unedited, newly created alarms don't require confirmation
finish();
} else {
new AlertDialog.Builder(this)
.setTitle(getString(R.string.delete_alarm))
.setMessage(getString(R.string.delete_alarm_confirm))
.setPositiveButton(android.R.string.ok,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface d, int w) {
Alarms.deleteAlarm(SetAlarm.this, mId);
finish();
}
})
.setNegativeButton(android.R.string.cancel, null)
.show();
}
}
private void revert() {
int newId = mId;
// "Revert" on a newly created alarm should delete it.
if (mOriginalAlarm.id == -1) {
Alarms.deleteAlarm(SetAlarm.this, newId);
} else {
saveAlarm(mOriginalAlarm);
}
}
/**
* Store any changes to the alarm and exit the activity.
* Show a toast if the alarm is enabled with the time remaining until alarm
*/
private void saveAndExit() {
long time = saveAlarm(null);
if(mEnabledPref.isChecked()) {
AlarmUtils.popAlarmSetToast(SetAlarm.this, time);
}
finish();
}
/**
* format "Alarm set for 2 days 7 hours and 53 minutes from
* now"
*/
static String formatToast(Context context, long timeInMillis) {
long delta = timeInMillis - System.currentTimeMillis();
long hours = delta / (1000 * 60 * 60);
long minutes = delta / (1000 * 60) % 60;
long days = hours / 24;
hours = hours % 24;
String daySeq = (days == 0) ? "" :
(days == 1) ? context.getString(R.string.day) :
context.getString(R.string.days, Long.toString(days));
String minSeq = (minutes == 0) ? "" :
(minutes == 1) ? context.getString(R.string.minute) :
context.getString(R.string.minutes, Long.toString(minutes));
String hourSeq = (hours == 0) ? "" :
(hours == 1) ? context.getString(R.string.hour) :
context.getString(R.string.hours, Long.toString(hours));
boolean dispDays = days > 0;
boolean dispHour = hours > 0;
boolean dispMinute = minutes > 0;
int index = (dispDays ? 1 : 0) |
(dispHour ? 2 : 0) |
(dispMinute ? 4 : 0);
String[] formats = context.getResources().getStringArray(R.array.alarm_set);
return String.format(formats[index], daySeq, hourSeq, minSeq);
}
}