diff options
author | Artem Chep <artemchep@gmail.com> | 2013-01-08 10:36:33 -0500 |
---|---|---|
committer | Danesh M <daneshm90@gmail.com> | 2014-12-04 10:57:48 -0800 |
commit | 8d54acdeaf29d17a7ce808ba2dbe8166773b9ff7 (patch) | |
tree | 36315f44f3737768dc0b5d1514a15e96950c222b | |
parent | b22620e20e9f71da68fe67ba34dcc12a1af2d90a (diff) | |
download | android_packages_apps_DeskClock-8d54acdeaf29d17a7ce808ba2dbe8166773b9ff7.tar.gz android_packages_apps_DeskClock-8d54acdeaf29d17a7ce808ba2dbe8166773b9ff7.tar.bz2 android_packages_apps_DeskClock-8d54acdeaf29d17a7ce808ba2dbe8166773b9ff7.zip |
DeskClock: Add back flip and shake actions
Cherry-picked and ported from:
* http://review.cyanogenmod.org/#/c/29894/
Change-Id: I222b6cd53a95db6f8662e7aef52aa6922d8a5d6a
Signed-off-by: Jorge Ruesga <jorge@ruesga.com>
-rw-r--r-- | res/xml/settings.xml | 17 | ||||
-rw-r--r-- | src/com/android/deskclock/SettingsActivity.java | 23 | ||||
-rwxr-xr-x | src/com/android/deskclock/alarms/AlarmService.java | 172 |
3 files changed, 212 insertions, 0 deletions
diff --git a/res/xml/settings.xml b/res/xml/settings.xml index f62a0a26c..a978d4912 100644 --- a/res/xml/settings.xml +++ b/res/xml/settings.xml @@ -42,6 +42,7 @@ <PreferenceCategory android:title="@string/alarm_settings"> + <ListPreference android:key="auto_silence" android:title="@string/auto_silence_title" @@ -74,5 +75,21 @@ android:title="@string/show_status_bar_icon_title" android:summary="@string/show_status_bar_icon_summary" android:defaultValue="true" /> + + <ListPreference + android:key="flip_action" + android:title="@string/flip_action_title" + android:dialogTitle="@string/flip_action_dialog_title" + android:entries="@array/action_summary_entries" + android:entryValues="@array/action_summary_values" + android:defaultValue="0" /> + + <ListPreference + android:key="shake_action" + android:title="@string/shake_action_title" + android:dialogTitle="@string/shake_action_dialog_title" + android:entries="@array/action_summary_entries" + android:entryValues="@array/action_summary_values" + android:defaultValue="0"/> </PreferenceCategory> </PreferenceScreen> diff --git a/src/com/android/deskclock/SettingsActivity.java b/src/com/android/deskclock/SettingsActivity.java index 3edaf8435..5fedd7feb 100644 --- a/src/com/android/deskclock/SettingsActivity.java +++ b/src/com/android/deskclock/SettingsActivity.java @@ -58,6 +58,10 @@ public class SettingsActivity extends PreferenceActivity "snooze_duration"; public static final String KEY_VOLUME_BEHAVIOR = "volume_button_setting"; + public static final String KEY_FLIP_ACTION = + "flip_action"; + public static final String KEY_SHAKE_ACTION = + "shake_action"; public static final String KEY_AUTO_SILENCE = "auto_silence"; public static final String KEY_CLOCK_STYLE = @@ -183,6 +187,12 @@ public class SettingsActivity extends PreferenceActivity final ListPreference listPref = (ListPreference) pref; final int idx = listPref.findIndexOfValue((String) newValue); listPref.setSummary(listPref.getEntries()[idx]); + } else if (KEY_FLIP_ACTION.equals(pref.getKey())) { + final ListPreference listPref = (ListPreference) pref; + updateActionSummary(listPref, (String) newValue, R.string.flip_action_summary); + } else if (KEY_SHAKE_ACTION.equals(pref.getKey())) { + final ListPreference listPref = (ListPreference) pref; + updateActionSummary(listPref, (String) newValue, R.string.shake_action_summary); } else if (KEY_SHOW_STATUS_BAR_ICON.equals(pref.getKey())) { // Check if any alarms are active. If yes and // we allow showing the alarm icon, the icon will be shown. @@ -212,6 +222,11 @@ public class SettingsActivity extends PreferenceActivity sendBroadcast(i); } + private void updateActionSummary(ListPreference listPref, String action, int summaryResId) { + int i = Integer.parseInt(action); + listPref.setSummary(getString(summaryResId, + getResources().getStringArray(R.array.action_summary_entries)[i])); + } private void refresh() { ListPreference listPref = (ListPreference) findPreference(KEY_AUTO_SILENCE); @@ -241,6 +256,14 @@ public class SettingsActivity extends PreferenceActivity listPref.setSummary(listPref.getEntry()); listPref.setOnPreferenceChangeListener(this); + listPref = (ListPreference) findPreference(KEY_FLIP_ACTION); + updateActionSummary(listPref, listPref.getValue(), R.string.flip_action_summary); + listPref.setOnPreferenceChangeListener(this); + + listPref = (ListPreference) findPreference(KEY_SHAKE_ACTION); + updateActionSummary(listPref, listPref.getValue(), R.string.shake_action_summary); + listPref.setOnPreferenceChangeListener(this); + CheckBoxPreference hideStatusbarIcon = (CheckBoxPreference) findPreference(KEY_SHOW_STATUS_BAR_ICON); hideStatusbarIcon.setOnPreferenceChangeListener(this); diff --git a/src/com/android/deskclock/alarms/AlarmService.java b/src/com/android/deskclock/alarms/AlarmService.java index 2f9d536fc..374a0b0ee 100755 --- a/src/com/android/deskclock/alarms/AlarmService.java +++ b/src/com/android/deskclock/alarms/AlarmService.java @@ -18,19 +18,27 @@ */ package com.android.deskclock.alarms; +import android.app.PendingIntent; import android.app.Profile; import android.app.ProfileManager; import android.app.Service; import android.content.ContentResolver; import android.content.Context; import android.content.Intent; +import android.content.SharedPreferences; +import android.hardware.Sensor; +import android.hardware.SensorEvent; +import android.hardware.SensorEventListener; +import android.hardware.SensorManager; import android.os.IBinder; +import android.preference.PreferenceManager; import android.provider.Settings; import android.telephony.PhoneStateListener; import android.telephony.TelephonyManager; import com.android.deskclock.AlarmAlertWakeLock; import com.android.deskclock.LogUtils; +import com.android.deskclock.SettingsActivity; import com.android.deskclock.provider.AlarmInstance; import com.android.deskclock.R; @@ -51,6 +59,14 @@ public class AlarmService extends Service { // Private action used to stop an alarm with this service. public static final String STOP_ALARM_ACTION = "STOP_ALARM"; + // default action for flip and shake + private static final String DEFAULT_ACTION = "0"; + + // 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; + /** * Utility method to help start alarm properly. If alarm is already firing, it * will mark it as missed and start the new one. @@ -85,6 +101,9 @@ public class AlarmService extends Service { private TelephonyManager mTelephonyManager; private int mInitialCallState; private AlarmInstance mCurrentAlarm = null; + private SensorManager mSensorManager; + private int mFlipAction; + private int mShakeAction; private PhoneStateListener mPhoneStateListener = new PhoneStateListener() { @Override @@ -158,6 +177,7 @@ public class AlarmService extends Service { AlarmKlaxon.start(this, mCurrentAlarm, inCall); changeToProfile(this, mCurrentAlarm); sendBroadcast(new Intent(ALARM_ALERT_ACTION)); + attachListeners(); } private void stopCurrentAlarm() { @@ -171,6 +191,7 @@ public class AlarmService extends Service { mTelephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_NONE); sendBroadcast(new Intent(ALARM_DONE_ACTION)); mCurrentAlarm = null; + detachListeners(); AlarmAlertWakeLock.releaseCpuLock(); } @@ -178,6 +199,12 @@ public class AlarmService extends Service { public void onCreate() { super.onCreate(); mTelephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE); + mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); + mFlipAction = Integer.parseInt(prefs.getString( + SettingsActivity.KEY_FLIP_ACTION, DEFAULT_ACTION)); + mShakeAction = Integer.parseInt(prefs.getString( + SettingsActivity.KEY_SHAKE_ACTION, DEFAULT_ACTION)); } @Override @@ -223,4 +250,149 @@ public class AlarmService extends Service { public IBinder onBind(Intent intent) { return null; } + + 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; + } + } + }; + + private void attachListeners() { + if (mFlipAction != ALARM_NO_ACTION) { + mSensorManager.registerListener(mFlipListener, + mSensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION), + SensorManager.SENSOR_DELAY_NORMAL, + 300 * 1000); //batch every 300 milliseconds + } + + if (mShakeAction != ALARM_NO_ACTION) { + mSensorManager.registerListener(mShakeListener, + mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), + SensorManager.SENSOR_DELAY_GAME, + 50 * 1000); //batch every 50 milliseconds + } + } + + private void detachListeners() { + if (mFlipAction != ALARM_NO_ACTION) { + mSensorManager.unregisterListener(mFlipListener); + } + if (mShakeAction != ALARM_NO_ACTION) { + mSensorManager.unregisterListener(mShakeListener); + } + } + + private void handleAction(int action) { + switch (action) { + case ALARM_SNOOZE: + // Setup Snooze Action + Intent snoozeIntent = AlarmStateManager.createStateChangeIntent(this, "SNOOZE_TAG", + mCurrentAlarm, AlarmInstance.SNOOZE_STATE); + sendBroadcast(snoozeIntent); + break; + case ALARM_DISMISS: + // Setup Dismiss Action + Intent dismissIntent = AlarmStateManager.createStateChangeIntent(this, "DISMISS_TAG", + mCurrentAlarm, AlarmInstance.DISMISSED_STATE); + sendBroadcast(dismissIntent); + break; + case ALARM_NO_ACTION: + default: + break; + } + } + } |