diff options
author | Paul Sliwowski <psliwowski@google.com> | 2013-06-26 01:39:22 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2013-06-26 01:39:23 +0000 |
commit | fbb045399fd7b455c8fd17cfc23a2f53642ba16b (patch) | |
tree | 7040d82735dba096b32f7952733f421f5c541927 | |
parent | a954f39d3415af70ee44d93cacf4e29d2c52054c (diff) | |
parent | 3fc32c45f5efc4ce4b91cbcdd925d9b30f67046e (diff) | |
download | android_frameworks_opt_datetimepicker-fbb045399fd7b455c8fd17cfc23a2f53642ba16b.tar.gz android_frameworks_opt_datetimepicker-fbb045399fd7b455c8fd17cfc23a2f53642ba16b.tar.bz2 android_frameworks_opt_datetimepicker-fbb045399fd7b455c8fd17cfc23a2f53642ba16b.zip |
Merge "Fixed issue where we vibrate even when System setting has it disabled."
4 files changed, 125 insertions, 56 deletions
diff --git a/src/com/android/datetimepicker/HapticFeedbackController.java b/src/com/android/datetimepicker/HapticFeedbackController.java new file mode 100644 index 0000000..b9be63f --- /dev/null +++ b/src/com/android/datetimepicker/HapticFeedbackController.java @@ -0,0 +1,74 @@ +package com.android.datetimepicker; + +import android.app.Service; +import android.content.Context; +import android.database.ContentObserver; +import android.net.Uri; +import android.os.SystemClock; +import android.os.Vibrator; +import android.provider.Settings; + +/** + * A simple utility class to handle haptic feedback. + */ +public class HapticFeedbackController { + private static final int VIBRATE_DELAY_MS = 125; + private static final int VIBRATE_LENGTH_MS = 5; + + private static boolean checkGlobalSetting(Context context) { + return Settings.System.getInt(context.getContentResolver(), + Settings.System.HAPTIC_FEEDBACK_ENABLED, 0) == 1; + } + + private final Context mContext; + private final ContentObserver mContentObserver; + + private Vibrator mVibrator; + private boolean mIsGloballyEnabled; + private long mLastVibrate; + + public HapticFeedbackController(Context context) { + mContext = context; + mContentObserver = new ContentObserver(null) { + @Override + public void onChange(boolean selfChange) { + mIsGloballyEnabled = checkGlobalSetting(mContext); + } + }; + } + + /** + * Call to setup the controller. + */ + public void start() { + mVibrator = (Vibrator) mContext.getSystemService(Service.VIBRATOR_SERVICE); + + // Setup a listener for changes in haptic feedback settings + mIsGloballyEnabled = checkGlobalSetting(mContext); + Uri uri = Settings.System.getUriFor(Settings.System.HAPTIC_FEEDBACK_ENABLED); + mContext.getContentResolver().registerContentObserver(uri, false, mContentObserver); + } + + /** + * Call this when you don't need the controller anymore. + */ + public void stop() { + mVibrator = null; + mContext.getContentResolver().unregisterContentObserver(mContentObserver); + } + + /** + * Try to vibrate. To prevent this becoming a single continuous vibration, nothing will + * happen if we have vibrated very recently. + */ + public void tryVibrate() { + if (mVibrator != null && mIsGloballyEnabled) { + long now = SystemClock.uptimeMillis(); + // We want to try to vibrate each individual tick discretely. + if (now - mLastVibrate >= VIBRATE_DELAY_MS) { + mVibrator.vibrate(VIBRATE_LENGTH_MS); + mLastVibrate = now; + } + } + } +} diff --git a/src/com/android/datetimepicker/date/DatePickerDialog.java b/src/com/android/datetimepicker/date/DatePickerDialog.java index 84ef2f3..d16eedd 100644 --- a/src/com/android/datetimepicker/date/DatePickerDialog.java +++ b/src/com/android/datetimepicker/date/DatePickerDialog.java @@ -19,15 +19,9 @@ package com.android.datetimepicker.date; import android.animation.ObjectAnimator; import android.app.Activity; import android.app.DialogFragment; -import android.content.Context; import android.content.res.Resources; import android.os.Bundle; -import android.os.SystemClock; -import android.os.Vibrator; -import android.text.format.DateFormat; import android.text.format.DateUtils; -import android.text.format.Time; -import android.util.AttributeSet; import android.util.Log; import android.view.LayoutInflater; import android.view.View; @@ -35,14 +29,13 @@ import android.view.View.OnClickListener; import android.view.ViewGroup; import android.view.Window; import android.view.WindowManager; -import android.view.accessibility.AccessibilityEvent; import android.view.animation.AlphaAnimation; import android.view.animation.Animation; import android.widget.Button; import android.widget.LinearLayout; import android.widget.TextView; -import android.widget.ViewAnimator; +import com.android.datetimepicker.HapticFeedbackController; import com.android.datetimepicker.R; import com.android.datetimepicker.Utils; import com.android.datetimepicker.date.SimpleMonthAdapter.CalendarDay; @@ -105,8 +98,7 @@ public class DatePickerDialog extends DialogFragment implements private int mMinYear = DEFAULT_START_YEAR; private int mMaxYear = DEFAULT_END_YEAR; - private Vibrator mVibrator; - private long mLastVibrate; + private HapticFeedbackController mHapticFeedbackController; private boolean mDelayAnimation = true; @@ -171,7 +163,6 @@ public class DatePickerDialog extends DialogFragment implements final Activity activity = getActivity(); activity.getWindow().setSoftInputMode( WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN); - mVibrator = (Vibrator) activity.getSystemService(Context.VIBRATOR_SERVICE); if (savedInstanceState != null) { mCalendar.set(Calendar.YEAR, savedInstanceState.getInt(KEY_SELECTED_YEAR)); mCalendar.set(Calendar.MONTH, savedInstanceState.getInt(KEY_SELECTED_MONTH)); @@ -274,9 +265,23 @@ public class DatePickerDialog extends DialogFragment implements mYearPickerView.postSetSelectionFromTop(listPosition, listPositionOffset); } } + + mHapticFeedbackController = new HapticFeedbackController(activity); return view; } + @Override + public void onResume() { + super.onResume(); + mHapticFeedbackController.start(); + } + + @Override + public void onPause() { + super.onPause(); + mHapticFeedbackController.stop(); + } + private void setCurrentView(final int viewIndex) { long millis = mCalendar.getTimeInMillis(); @@ -453,19 +458,8 @@ public class DatePickerDialog extends DialogFragment implements mListeners.remove(listener); } - /** - * Try to vibrate. To prevent this becoming a single continuous vibration, nothing will - * happen if we have vibrated very recently. - */ @Override public void tryVibrate() { - if (mVibrator != null) { - long now = SystemClock.uptimeMillis(); - // We want to try to vibrate each individual tick discretely. - if (now - mLastVibrate >= 125) { - mVibrator.vibrate(5); - mLastVibrate = now; - } - } + mHapticFeedbackController.tryVibrate(); } } diff --git a/src/com/android/datetimepicker/time/RadialPickerLayout.java b/src/com/android/datetimepicker/time/RadialPickerLayout.java index e895e98..bad77ed 100644 --- a/src/com/android/datetimepicker/time/RadialPickerLayout.java +++ b/src/com/android/datetimepicker/time/RadialPickerLayout.java @@ -19,13 +19,11 @@ package com.android.datetimepicker.time; import android.animation.AnimatorSet; import android.animation.ObjectAnimator; import android.annotation.SuppressLint; -import android.app.Service; import android.content.Context; import android.content.res.Resources; import android.os.Bundle; import android.os.Handler; import android.os.SystemClock; -import android.os.Vibrator; import android.text.format.DateUtils; import android.text.format.Time; import android.util.AttributeSet; @@ -42,8 +40,6 @@ import android.widget.FrameLayout; import com.android.datetimepicker.R; -import java.util.HashMap; - public class RadialPickerLayout extends FrameLayout implements OnTouchListener { private static final String TAG = "RadialPickerLayout"; @@ -60,10 +56,9 @@ public class RadialPickerLayout extends FrameLayout implements OnTouchListener { private static final int AM = TimePickerDialog.AM; private static final int PM = TimePickerDialog.PM; - private Vibrator mVibrator; - private long mLastVibrate; private int mLastValueSelected; + private TimePickerDialog mController; private OnValueSelectedListener mListener; private boolean mTimeInitialized; private int mCurrentHoursOfDay; @@ -125,8 +120,6 @@ public class RadialPickerLayout extends FrameLayout implements OnTouchListener { // Prepare mapping to snap touchable degrees to selectable degrees. preparePrefer30sMap(); - mVibrator = (Vibrator) context.getSystemService(Service.VIBRATOR_SERVICE); - mLastVibrate = 0; mLastValueSelected = -1; mInputEnabled = true; @@ -168,12 +161,14 @@ public class RadialPickerLayout extends FrameLayout implements OnTouchListener { * @param initialMinutes * @param is24HourMode */ - public void initialize(Context context, int initialHoursOfDay, int initialMinutes, - boolean is24HourMode) { + public void initialize(Context context, TimePickerDialog controller, + int initialHoursOfDay, int initialMinutes, boolean is24HourMode) { if (mTimeInitialized) { Log.e(TAG, "Time has already been initialized."); return; } + + mController = controller; mIs24HourMode = is24HourMode; mHideAmPm = mAccessibilityManager.isTouchExplorationEnabled()? true : mIs24HourMode; @@ -582,7 +577,7 @@ public class RadialPickerLayout extends FrameLayout implements OnTouchListener { if (mIsTouchingAmOrPm == AM || mIsTouchingAmOrPm == PM) { // If the touch is on AM or PM, set it as "touched" after the TAP_TIMEOUT // in case the user moves their finger quickly. - tryVibrate(); + mController.tryVibrate(); mDownDegrees = -1; mHandler.postDelayed(new Runnable() { @Override @@ -600,7 +595,7 @@ public class RadialPickerLayout extends FrameLayout implements OnTouchListener { if (mDownDegrees != -1) { // If it's a legal touch, set that number as "selected" after the // TAP_TIMEOUT in case the user moves their finger quickly. - tryVibrate(); + mController.tryVibrate(); mHandler.postDelayed(new Runnable() { @Override public void run() { @@ -655,7 +650,7 @@ public class RadialPickerLayout extends FrameLayout implements OnTouchListener { if (degrees != -1) { value = reselectSelector(degrees, isInnerCircle[0], false, true); if (value != mLastValueSelected) { - tryVibrate(); + mController.tryVibrate(); mLastValueSelected = value; mListener.onValueSelected(getCurrentItemShowing(), value, false); } @@ -715,21 +710,6 @@ public class RadialPickerLayout extends FrameLayout implements OnTouchListener { } /** - * Try to vibrate. To prevent this becoming a single continuous vibration, nothing will - * happen if we have vibrated very recently. - */ - public void tryVibrate() { - if (mVibrator != null) { - long now = SystemClock.uptimeMillis(); - // We want to try to vibrate each individual tick discretely. - if (now - mLastVibrate >= 125) { - mVibrator.vibrate(5); - mLastVibrate = now; - } - } - } - - /** * Set touch input as enabled or disabled, for use with keyboard mode. */ public boolean trySettingInputEnabled(boolean inputEnabled) { diff --git a/src/com/android/datetimepicker/time/TimePickerDialog.java b/src/com/android/datetimepicker/time/TimePickerDialog.java index 4b67629..bdde56e 100644 --- a/src/com/android/datetimepicker/time/TimePickerDialog.java +++ b/src/com/android/datetimepicker/time/TimePickerDialog.java @@ -34,6 +34,7 @@ import android.view.Window; import android.widget.RelativeLayout; import android.widget.TextView; +import com.android.datetimepicker.HapticFeedbackController; import com.android.datetimepicker.R; import com.android.datetimepicker.Utils; import com.android.datetimepicker.time.RadialPickerLayout.OnValueSelectedListener; @@ -69,6 +70,8 @@ public class TimePickerDialog extends DialogFragment implements OnValueSelectedL private OnTimeSetListener mCallback; + private HapticFeedbackController mHapticFeedbackController; + private TextView mDoneButton; private TextView mHourView; private TextView mHourSpaceView; @@ -199,7 +202,8 @@ public class TimePickerDialog extends DialogFragment implements OnValueSelectedL mTimePicker = (RadialPickerLayout) view.findViewById(R.id.time_picker); mTimePicker.setOnValueSelectedListener(this); mTimePicker.setOnKeyListener(keyboardListener); - mTimePicker.initialize(getActivity(), mInitialHourOfDay, mInitialMinute, mIs24HourMode); + mTimePicker.initialize(getActivity(), this, mInitialHourOfDay, mInitialMinute, + mIs24HourMode); int currentItemShowing = HOUR_INDEX; if (savedInstanceState != null && savedInstanceState.containsKey(KEY_CURRENT_ITEM_SHOWING)) { @@ -208,18 +212,19 @@ public class TimePickerDialog extends DialogFragment implements OnValueSelectedL setCurrentItemShowing(currentItemShowing, false, true, true); mTimePicker.invalidate(); + mHapticFeedbackController = new HapticFeedbackController(getActivity()); mHourView.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { setCurrentItemShowing(HOUR_INDEX, true, false, true); - mTimePicker.tryVibrate(); + tryVibrate(); } }); mMinuteView.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { setCurrentItemShowing(MINUTE_INDEX, true, false, true); - mTimePicker.tryVibrate(); + tryVibrate(); } }); @@ -230,7 +235,7 @@ public class TimePickerDialog extends DialogFragment implements OnValueSelectedL if (mInKbMode && isTypedTimeFullyLegal()) { finishKbMode(false); } else { - mTimePicker.tryVibrate(); + tryVibrate(); } if (mCallback != null) { mCallback.onTimeSet(mTimePicker, @@ -257,7 +262,7 @@ public class TimePickerDialog extends DialogFragment implements OnValueSelectedL mAmPmHitspace.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { - mTimePicker.tryVibrate(); + tryVibrate(); int amOrPm = mTimePicker.getIsCurrentlyAmOrPm(); if (amOrPm == AM) { amOrPm = PM; @@ -291,6 +296,22 @@ public class TimePickerDialog extends DialogFragment implements OnValueSelectedL return view; } + @Override + public void onResume() { + super.onResume(); + mHapticFeedbackController.start(); + } + + @Override + public void onPause() { + super.onPause(); + mHapticFeedbackController.stop(); + } + + public void tryVibrate() { + mHapticFeedbackController.tryVibrate(); + } + private void updateAmPmDisplay(int amOrPm) { if (amOrPm == AM) { mAmPmTextView.setText(mAmText); |