diff options
Diffstat (limited to 'src/com/android/deskclock/AlarmAlertFullScreen.java')
-rw-r--r-- | src/com/android/deskclock/AlarmAlertFullScreen.java | 177 |
1 files changed, 173 insertions, 4 deletions
diff --git a/src/com/android/deskclock/AlarmAlertFullScreen.java b/src/com/android/deskclock/AlarmAlertFullScreen.java index 0cf49f89e..76166a9d2 100644 --- a/src/com/android/deskclock/AlarmAlertFullScreen.java +++ b/src/com/android/deskclock/AlarmAlertFullScreen.java @@ -26,6 +26,11 @@ import android.content.Intent; import android.content.IntentFilter; import android.content.pm.ActivityInfo; import android.content.res.Configuration; +import android.content.SharedPreferences; +import android.hardware.Sensor; +import android.hardware.SensorEvent; +import android.hardware.SensorEventListener; +import android.hardware.SensorManager; import android.os.Bundle; import android.os.Handler; import android.os.Message; @@ -53,6 +58,9 @@ public class AlarmAlertFullScreen extends Activity implements GlowPadView.OnTrig // These defaults must match the values in res/xml/settings.xml private static final String DEFAULT_SNOOZE = "10"; private static final String DEFAULT_VOLUME_BEHAVIOR = "2"; + private static final String DEFAULT_FLIP_ACTION = "0"; + private static final String DEFAULT_SHAKE_ACTION = "1"; + protected static final String SCREEN_OFF = "screen_off"; protected Alarm mAlarm; @@ -67,6 +75,13 @@ public class AlarmAlertFullScreen extends Activity implements GlowPadView.OnTrig private static final long PING_AUTO_REPEAT_DELAY_MSEC = 1200; private boolean mPingEnabled = true; + private int mFlipAction; + private int mShakeAction; + + // constants for no action/snooze/dismiss + private static final int ALARM_NO_ACTION = 0; + private static final int ALARM_SNOOZE = 1; + private static final int ALARM_DISMISS = 2; // Receives the ALARM_KILLED action from the AlarmKlaxon, // and also ALARM_SNOOZE_ACTION / ALARM_DISMISS_ACTION from other applications @@ -101,6 +116,105 @@ public class AlarmAlertFullScreen extends Activity implements GlowPadView.OnTrig } }; + private final SensorEventListener mFlipListener = new SensorEventListener() { + private static final int FACE_UP_LOWER_LIMIT = -45; + private static final int FACE_UP_UPPER_LIMIT = 45; + private static final int FACE_DOWN_UPPER_LIMIT = 135; + private static final int FACE_DOWN_LOWER_LIMIT = -135; + private static final int TILT_UPPER_LIMIT = 45; + private static final int TILT_LOWER_LIMIT = -45; + private static final int SENSOR_SAMPLES = 3; + + private boolean mWasFaceUp; + private boolean[] mSamples = new boolean[SENSOR_SAMPLES]; + private int mSampleIndex; + + @Override + public void onAccuracyChanged(Sensor sensor, int acc) { + } + + @Override + public void onSensorChanged(SensorEvent event) { + // Add a sample overwriting the oldest one. Several samples + // are used + // to avoid the erroneous values the sensor sometimes + // returns. + float y = event.values[1]; + float z = event.values[2]; + + if (!mWasFaceUp) { + // Check if its face up enough. + mSamples[mSampleIndex] = y > FACE_UP_LOWER_LIMIT + && y < FACE_UP_UPPER_LIMIT + && z > TILT_LOWER_LIMIT && z < TILT_UPPER_LIMIT; + + // The device first needs to be face up. + boolean faceUp = true; + for (boolean sample : mSamples) { + faceUp = faceUp && sample; + } + if (faceUp) { + mWasFaceUp = true; + for (int i = 0; i < SENSOR_SAMPLES; i++) { + mSamples[i] = false; + } + } + } else { + // Check if its face down enough. Note that wanted + // values go from FACE_DOWN_UPPER_LIMIT to 180 + // and from -180 to FACE_DOWN_LOWER_LIMIT + mSamples[mSampleIndex] = (y > FACE_DOWN_UPPER_LIMIT || y < FACE_DOWN_LOWER_LIMIT) + && z > TILT_LOWER_LIMIT + && z < TILT_UPPER_LIMIT; + + boolean faceDown = true; + for (boolean sample : mSamples) { + faceDown = faceDown && sample; + } + if (faceDown) { + handleAction(mFlipAction); + } + } + + mSampleIndex = ((mSampleIndex + 1) % SENSOR_SAMPLES); + } + }; + + private final SensorEventListener mShakeListener = new SensorEventListener() { + private static final float SENSITIVITY = 16; + private static final int BUFFER = 5; + private float[] gravity = new float[3]; + private float average = 0; + private int fill = 0; + + @Override + public void onAccuracyChanged(Sensor sensor, int acc) { + } + + public void onSensorChanged(SensorEvent event) { + final float alpha = 0.8F; + + for (int i = 0; i < 3; i++) { + gravity[i] = alpha * gravity[i] + (1 - alpha) * event.values[i]; + } + + float x = event.values[0] - gravity[0]; + float y = event.values[1] - gravity[1]; + float z = event.values[2] - gravity[2]; + + if (fill <= BUFFER) { + average += Math.abs(x) + Math.abs(y) + Math.abs(z); + fill++; + } else { + if (average / BUFFER >= SENSITIVITY) { + handleAction(mShakeAction); + } + average = 0; + fill = 0; + } + } + }; + @Override protected void onCreate(Bundle icicle) { super.onCreate(icicle); @@ -254,12 +368,12 @@ public class AlarmAlertFullScreen extends Activity implements GlowPadView.OnTrig return (NotificationManager) getSystemService(NOTIFICATION_SERVICE); } + private SensorManager getSensorManager() { + return (SensorManager) getSystemService(Context.SENSOR_SERVICE); + } + // Dismiss the alarm. private void dismiss(boolean killed) { - if (LOG) { - Log.v("AlarmAlertFullScreen - dismiss"); - } - 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. @@ -272,6 +386,45 @@ public class AlarmAlertFullScreen extends Activity implements GlowPadView.OnTrig finish(); } + private void attachListeners() { + final SensorManager sm = getSensorManager(); + + if (mFlipAction != ALARM_NO_ACTION) { + sm.registerListener(mFlipListener, + sm.getDefaultSensor(Sensor.TYPE_ORIENTATION), + SensorManager.SENSOR_DELAY_NORMAL); + } + + if (mShakeAction != ALARM_NO_ACTION) { + sm.registerListener(mShakeListener, + sm.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), + SensorManager.SENSOR_DELAY_GAME); + } + } + + private void detachListeners() { + if (mFlipAction != ALARM_NO_ACTION) { + getSensorManager().unregisterListener(mFlipListener); + } + if (mShakeAction != ALARM_NO_ACTION) { + getSensorManager().unregisterListener(mShakeListener); + } + } + + private void handleAction(int action) { + switch (action) { + case ALARM_SNOOZE: + snooze(); + break; + case ALARM_DISMISS: + dismiss(false); + break; + case ALARM_NO_ACTION: + default: + break; + } + } + /** * this is called when a second alarm is triggered while a * previous alert window is still active. @@ -302,6 +455,14 @@ public class AlarmAlertFullScreen extends Activity implements GlowPadView.OnTrig if (LOG) { Log.v("AlarmAlertFullScreen - onResume"); } + + final SharedPreferences prefs = PreferenceManager. + getDefaultSharedPreferences(this); + mFlipAction = Integer.parseInt(prefs.getString( + SettingsActivity.KEY_FLIP_ACTION, DEFAULT_FLIP_ACTION)); + mShakeAction = Integer.parseInt(prefs.getString( + SettingsActivity.KEY_SHAKE_ACTION, DEFAULT_SHAKE_ACTION)); + // If the alarm was deleted at some point, disable snooze. if (Alarms.getAlarm(getContentResolver(), mAlarm.id) == null) { mGlowPadView.setTargetResources(R.array.dismiss_drawables); @@ -313,6 +474,8 @@ public class AlarmAlertFullScreen extends Activity implements GlowPadView.OnTrig if (getResources().getBoolean(R.bool.config_rotateAlarmAlert) || mIsDocked) { setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED); } + + attachListeners(); } @Override @@ -324,6 +487,12 @@ public class AlarmAlertFullScreen extends Activity implements GlowPadView.OnTrig } @Override + public void onPause() { + super.onPause(); + detachListeners(); + } + + @Override public boolean dispatchKeyEvent(KeyEvent event) { // Do this on key down to handle a few of the system keys. boolean up = event.getAction() == KeyEvent.ACTION_UP; |