/* * Copyright (C) 2009 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.androsz.electricsleepbeta.alarmclock; import java.util.Calendar; import android.app.Activity; 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.content.IntentFilter; import android.os.AsyncTask; import android.os.Build; import android.os.Bundle; import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.View; import android.view.Window; import android.view.WindowManager; import android.widget.Button; import android.widget.TextView; import android.widget.Toast; import com.androsz.electricsleepbeta.R; import com.androsz.electricsleepbeta.app.SettingsActivity; /** * Alarm Clock alarm alert: pops visible indicator and plays alarm tone. This * activity is the full screen version which shows over the lock screen with the * wallpaper as the background. */ public class AlarmAlertFullScreen extends Activity { // These defaults must match the values in res/xml/settings.xml private static final String DEFAULT_SNOOZE = "5"; private static final String DEFAULT_VOLUME_BEHAVIOR = "0"; protected static final String SCREEN_OFF = "screen_off"; protected Alarm mAlarm; // Receives the ALARM_KILLED action from the AlarmKlaxon, // and also ALARM_SNOOZE_ACTION / ALARM_DISMISS_ACTION from other // applications private final BroadcastReceiver mReceiver = new BroadcastReceiver() { @Override public void onReceive(final Context context, final Intent intent) { final String action = intent.getAction(); if (action.equals(Alarms.ALARM_SNOOZE_ACTION)) { snooze(); } else if (action.equals(Alarms.ALARM_DISMISS_ACTION)) { dismiss(false); } else if (action.equals(Alarms.ALARM_KILLED)) { final Alarm alarm = intent.getParcelableExtra(Alarms.ALARM_INTENT_EXTRA); if (alarm != null && mAlarm.id == alarm.id) { dismiss(true); } } } }; private int mVolumeBehavior; // Dismiss the alarm. private void dismiss(final boolean killed) { Log.i(killed ? "Alarm killed" : "Alarm dismissed by user"); // The service told us that the alarm has been killed, do not modify // the notification or stop the service. if (!killed) { // Cancel the notification and stop playing the alarm final NotificationManager nm = getNotificationManager(); nm.cancel(mAlarm.id); stopService(new Intent(Alarms.ALARM_ALERT_ACTION)); sendBroadcast(new Intent(Alarms.ALARM_DISMISSED_BY_USER_ACTION)); } finish(); } @Override public boolean dispatchKeyEvent(final KeyEvent event) { // Do this on key down to handle a few of the system keys. final boolean up = event.getAction() == KeyEvent.ACTION_UP; switch (event.getKeyCode()) { // Volume keys and camera keys dismiss the alarm case KeyEvent.KEYCODE_VOLUME_UP: case KeyEvent.KEYCODE_VOLUME_DOWN: case KeyEvent.KEYCODE_CAMERA: case KeyEvent.KEYCODE_FOCUS: if (up) { switch (mVolumeBehavior) { case 1: snooze(); break; case 2: dismiss(false); break; default: break; } } return true; default: break; } return super.dispatchKeyEvent(event); } private NotificationManager getNotificationManager() { return (NotificationManager) getSystemService(NOTIFICATION_SERVICE); } @Override public void onBackPressed() { // Don't allow back to dismiss. This method is overriden by AlarmAlert // so that the dialog is dismissed. return; } @Override protected void onCreate(final Bundle icicle) { super.onCreate(icicle); setTheme(R.style.Theme_Sherlock); mAlarm = getIntent().getParcelableExtra(Alarms.ALARM_INTENT_EXTRA); // Get the volume/camera button behavior setting final String vol = getSharedPreferences(SettingsActivity.PREFERENCES, 0).getString( SettingsActivity.KEY_VOLUME_BEHAVIOR, DEFAULT_VOLUME_BEHAVIOR); mVolumeBehavior = Integer.parseInt(vol); requestWindowFeature(android.view.Window.FEATURE_NO_TITLE); final Window win = getWindow(); win.addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD); // Turn on the screen unless we are being launched from the AlarmAlert // subclass. final boolean screenOff = getIntent().getBooleanExtra(SCREEN_OFF, false); if (!screenOff) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.FROYO) { // API 8+ win.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON | WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON); } else { // API 7 or less win.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON); } } updateLayout(); // Register to get the alarm killed/snooze/dismiss intent. final IntentFilter filter = new IntentFilter(Alarms.ALARM_KILLED); filter.addAction(Alarms.ALARM_SNOOZE_ACTION); filter.addAction(Alarms.ALARM_DISMISS_ACTION); registerReceiver(mReceiver, filter); } @Override public void onDestroy() { super.onDestroy(); if (Log.LOGV) { Log.v("AlarmAlert.onDestroy()"); } // No longer care about the alarm being killed. unregisterReceiver(mReceiver); } /** * this is called when a second alarm is triggered while a previous alert * window is still active. */ @Override protected void onNewIntent(final Intent intent) { super.onNewIntent(intent); if (Log.LOGV) { Log.v("AlarmAlert.OnNewIntent()"); } mAlarm = intent.getParcelableExtra(Alarms.ALARM_INTENT_EXTRA); setTitle(); } @Override protected void onResume() { super.onResume(); // If the alarm was deleted at some point, disable snooze. if (Alarms.getAlarm(getContentResolver(), mAlarm.id) == null) { final Button snooze = (Button) findViewById(R.id.snooze); snooze.setEnabled(false); } } private void setTitle() { final String label = mAlarm.getLabelOrDefault(this); final TextView title = (TextView) findViewById(R.id.alertTitle); title.setText(label); } // Attempt to snooze this alert. private void snooze() { // Do not snooze if the snooze button is disabled. if (!findViewById(R.id.snooze).isEnabled()) { dismiss(false); return; } new AsyncTask<Void, Void, Integer>() { final Calendar c = Calendar.getInstance(); @Override protected Integer doInBackground(Void... params) { final String snooze = getSharedPreferences(SettingsActivity.PREFERENCES, 0) .getString(SettingsActivity.KEY_ALARM_SNOOZE, DEFAULT_SNOOZE); final int snoozeMinutes = Integer.parseInt(snooze); final long snoozeTime = System.currentTimeMillis() + 1000 * 60 * snoozeMinutes; Alarms.saveSnoozeAlert(AlarmAlertFullScreen.this, mAlarm.id, snoozeTime); // Get the display time for the snooze and update the // notification. c.setTimeInMillis(snoozeTime); return snoozeMinutes; } @Override protected void onPostExecute(Integer snoozeMinutes) { // Append (snoozed) to the label. String label = mAlarm.getLabelOrDefault(AlarmAlertFullScreen.this); label = getString(R.string.alarm_notify_snooze_label, label); // Notify the user that the alarm has been snoozed. final Intent cancelSnooze = new Intent(AlarmAlertFullScreen.this, AlarmReceiver.class); cancelSnooze.setAction(Alarms.CANCEL_SNOOZE); cancelSnooze.putExtra(Alarms.ALARM_ID, mAlarm.id); final PendingIntent broadcast = PendingIntent.getBroadcast( AlarmAlertFullScreen.this, mAlarm.id, cancelSnooze, 0); final NotificationManager nm = getNotificationManager(); final Notification n = new Notification(R.drawable.ic_alarm_neutral, label, 0); n.setLatestEventInfo( AlarmAlertFullScreen.this, label, getString(R.string.alarm_notify_snooze_text, Alarms.formatTime(AlarmAlertFullScreen.this, c)), broadcast); n.flags |= Notification.FLAG_AUTO_CANCEL | Notification.FLAG_ONGOING_EVENT; nm.notify(mAlarm.id, n); final String displayTime = getString(R.string.alarm_alert_snooze_set, snoozeMinutes); // Intentionally log the snooze time for debugging. Log.v(displayTime); // Display the snooze minutes in a toast. Toast.makeText(AlarmAlertFullScreen.this, displayTime, Toast.LENGTH_LONG).show(); stopService(new Intent(Alarms.ALARM_ALERT_ACTION)); finish(); } }.execute(); } private void updateLayout() { final LayoutInflater inflater = LayoutInflater.from(this); setContentView(inflater.inflate(R.layout.alarm_alert, null)); /* * snooze behavior: pop a snooze confirmation view, kick alarm manager. */ final Button snooze = (Button) findViewById(R.id.snooze); snooze.requestFocus(); snooze.setOnClickListener(new Button.OnClickListener() { @Override public void onClick(final View v) { snooze(); } }); /* dismiss button: close notification */ findViewById(R.id.dismiss).setOnClickListener(new Button.OnClickListener() { @Override public void onClick(final View v) { dismiss(false); } }); /* Set the title from the passed in alarm */ setTitle(); } }