android13-settings[vibration&haptics]

247 阅读8分钟

1.简介

简单看下震动与触觉反馈的内容,看下对应的选项都由哪些配置控制的

1.2.vibration&haptics

image.png

2.VibrationSettings

2.1.getVibrationXmlResourceId

可以看到,布局有两种,一种支持设置震动强度的,一种不支持,配置里默认值是1,不支持

    private static int getVibrationXmlResourceId(Context context) {
        final int supportedIntensities = context.getResources().getInteger(
                R.integer.config_vibration_supported_intensity_levels);
        return supportedIntensities > 1
                ? R.xml.accessibility_vibration_intensity_settings
                : R.xml.accessibility_vibration_settings;

    }

2.2.accessibility_vibration_settings

对应图1.2上的6个开关

<PreferenceScreen
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:title="@string/accessibility_vibration_settings_title">

    <com.android.settingslib.widget.MainSwitchPreference
        android:key="vibration_main_switch"
        android:title="@string/accessibility_vibration_primary_switch_title"
        app:keywords="@string/keywords_accessibility_vibration_primary_switch"
        app:controller="com.android.settings.accessibility.VibrationMainSwitchPreferenceController"/>

    <PreferenceCategory
        android:key="accessibility_call_vibration_category"
        android:title="@string/accessibility_call_vibration_category_title">

        <SwitchPreference
            android:key="ring_vibration_preference_screen"
            android:title="@string/accessibility_ring_vibration_title"
            app:keywords="@string/keywords_ring_vibration"
            app:controller="com.android.settings.accessibility.RingVibrationTogglePreferenceController" />

        <SwitchPreference
            android:key="ramping_ringer"
            android:title="@string/vibrate_when_ringing_option_ramping_ringer"
            app:keywords="@string/keywords_ramping_ringer_vibration"
            app:controller="com.android.settings.accessibility.VibrationRampingRingerTogglePreferenceController"/>

    </PreferenceCategory>

    <PreferenceCategory
        android:key="accessibility_notification_alarm_vibration_category"
        android:title="@string/accessibility_notification_alarm_vibration_category_title">

        <SwitchPreference
            android:key="notification_vibration_preference_screen"
            android:title="@string/accessibility_notification_vibration_title"
            app:keywords="@string/keywords_notification_vibration"
            app:controller="com.android.settings.accessibility.NotificationVibrationTogglePreferenceController" />

        <SwitchPreference
            android:key="alarm_vibration_preference_screen"
            android:title="@string/accessibility_alarm_vibration_title"
            app:keywords="@string/keywords_alarm_vibration"
            app:controller="com.android.settings.accessibility.AlarmVibrationTogglePreferenceController" />

    </PreferenceCategory>

    <PreferenceCategory
        android:key="accessibility_interactive_haptics_category"
        android:title="@string/accessibility_interactive_haptics_category_title">

        <SwitchPreference
            android:key="touch_vibration_preference_screen"
            android:title="@string/accessibility_touch_vibration_title"
            app:keywords="@string/keywords_touch_vibration"
            app:controller="com.android.settings.accessibility.HapticFeedbackTogglePreferenceController" />

        <SwitchPreference
            android:key="media_vibration_preference_screen"
            android:title="@string/accessibility_media_vibration_title"
            app:keywords="@string/keywords_media_vibration"
            app:controller="com.android.settings.accessibility.MediaVibrationTogglePreferenceController" />

    </PreferenceCategory>

</PreferenceScreen>

2.3.accessibility_vibration_intensity_settings

效果图如下,这种没有开关了,都直接是拖动进度条可以修改震动强度的。 image.png

<PreferenceScreen
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:title="@string/accessibility_vibration_settings_title">

    <com.android.settingslib.widget.MainSwitchPreference
        android:key="vibration_main_switch"
        android:title="@string/accessibility_vibration_primary_switch_title"
        app:keywords="@string/keywords_accessibility_vibration_primary_switch"
        app:controller="com.android.settings.accessibility.VibrationMainSwitchPreferenceController"/>

    <PreferenceCategory
        android:key="accessibility_call_vibration_category"
        android:title="@string/accessibility_call_vibration_category_title">

        <com.android.settings.widget.SeekBarPreference
            android:key="ring_vibration_preference_screen"
            android:title="@string/accessibility_ring_vibration_title"
            app:keywords="@string/keywords_ring_vibration"
            app:controller="com.android.settings.accessibility.RingVibrationIntensityPreferenceController" />

        <SwitchPreference
            android:key="ramping_ringer"
            android:title="@string/vibrate_when_ringing_option_ramping_ringer"
            app:keywords="@string/keywords_ramping_ringer_vibration"
            app:controller="com.android.settings.accessibility.VibrationRampingRingerTogglePreferenceController"/>

    </PreferenceCategory>

    <PreferenceCategory
        android:key="accessibility_notification_alarm_vibration_category"
        android:title="@string/accessibility_notification_alarm_vibration_category_title">

        <com.android.settings.widget.SeekBarPreference
            android:key="notification_vibration_preference_screen"
            android:title="@string/accessibility_notification_vibration_title"
            app:keywords="@string/keywords_notification_vibration"
            app:controller="com.android.settings.accessibility.NotificationVibrationIntensityPreferenceController" />

        <com.android.settings.widget.SeekBarPreference
            android:key="alarm_vibration_preference_screen"
            android:title="@string/accessibility_alarm_vibration_title"
            app:keywords="@string/keywords_alarm_vibration"
            app:controller="com.android.settings.accessibility.AlarmVibrationIntensityPreferenceController" />

    </PreferenceCategory>

    <PreferenceCategory
        android:key="accessibility_interactive_haptics_category"
        android:title="@string/accessibility_interactive_haptics_category_title">

        <com.android.settings.widget.SeekBarPreference
            android:key="touch_vibration_preference_screen"
            android:title="@string/accessibility_touch_vibration_title"
            app:keywords="@string/keywords_touch_vibration"
            app:controller="com.android.settings.accessibility.HapticFeedbackIntensityPreferenceController" />

        <com.android.settings.widget.SeekBarPreference
            android:key="media_vibration_preference_screen"
            android:title="@string/accessibility_media_vibration_title"
            app:keywords="@string/keywords_media_vibration"
            app:controller="com.android.settings.accessibility.MediaVibrationIntensityPreferenceController" />

    </PreferenceCategory>

</PreferenceScreen>

2.4.VibrationConfig

震动强度的默认值配置

>VibrationConfig

    public VibrationConfig(@Nullable Resources resources) {
        mHapticChannelMaxVibrationAmplitude = loadFloat(resources,
                com.android.internal.R.dimen.config_hapticChannelMaxVibrationAmplitude, 0);
        mRampDownDurationMs = loadInteger(resources,
                com.android.internal.R.integer.config_vibrationWaveformRampDownDuration, 0);
        mRampStepDurationMs = loadInteger(resources,
                com.android.internal.R.integer.config_vibrationWaveformRampStepDuration, 0);

        mDefaultAlarmVibrationIntensity = loadDefaultIntensity(resources,
                com.android.internal.R.integer.config_defaultAlarmVibrationIntensity);
        mDefaultHapticFeedbackIntensity = loadDefaultIntensity(resources,
                com.android.internal.R.integer.config_defaultHapticFeedbackIntensity);
        mDefaultMediaVibrationIntensity = loadDefaultIntensity(resources,
                com.android.internal.R.integer.config_defaultMediaVibrationIntensity);
        mDefaultNotificationVibrationIntensity = loadDefaultIntensity(resources,
                com.android.internal.R.integer.config_defaultNotificationVibrationIntensity);
        mDefaultRingVibrationIntensity = loadDefaultIntensity(resources,
                com.android.internal.R.integer.config_defaultRingVibrationIntensity);
    }

>loadDefaultIntensity

  • 震动强度有4个值,0是disable, 1是low,2是medium,3是high
  • 下边就是读取默认的配置值,并保证是这4个值里的一个
    private static int loadDefaultIntensity(@Nullable Resources res, int resId) {
        int defaultIntensity = Vibrator.VIBRATION_INTENSITY_MEDIUM;//2
        int value = loadInteger(res, resId, defaultIntensity);
        if (value < Vibrator.VIBRATION_INTENSITY_OFF || value > Vibrator.VIBRATION_INTENSITY_HIGH) {
            return defaultIntensity;
        }
        return value;
    }

>getDefaultVibrationIntensity

提供的方法,根据不同usage类型,返回各自的默认值

    public int getDefaultVibrationIntensity(@VibrationAttributes.Usage int usage) {
        switch (usage) {
            case USAGE_ALARM:
                return mDefaultAlarmVibrationIntensity;
            case USAGE_NOTIFICATION:
            case USAGE_COMMUNICATION_REQUEST:
                return mDefaultNotificationVibrationIntensity;
            case USAGE_RINGTONE:
                return mDefaultRingVibrationIntensity;
            case USAGE_TOUCH:
            case USAGE_HARDWARE_FEEDBACK:
            case USAGE_PHYSICAL_EMULATION:
            case USAGE_ACCESSIBILITY:
                return mDefaultHapticFeedbackIntensity;
            case USAGE_MEDIA:
            case USAGE_UNKNOWN:
                // fall through
            default:
                return mDefaultMediaVibrationIntensity;
        }
    }

下边挨个看下这6个开关如何控制

3.Ring vibration

3.1.RingVibrationTogglePreferenceController

preferenceKey从xml里获取的

public class RingVibrationTogglePreferenceController extends VibrationTogglePreferenceController {

    public RingVibrationTogglePreferenceController(Context context, String preferenceKey) {
        super(context, preferenceKey, new RingVibrationPreferenceConfig(context));
    }

    @Override
    public int getAvailabilityStatus() {
        return AVAILABLE;
    }
}

3.2.RingVibrationPreferenceConfig

/** General configuration for ringtone vibration intensity settings. */
public class RingVibrationPreferenceConfig extends VibrationPreferenceConfig {
    private final AudioManager mAudioManager;

    public RingVibrationPreferenceConfig(Context context) {
    //设置系统设置的key以及震动类型是ringtone
        super(context, Settings.System.RING_VIBRATION_INTENSITY,
                VibrationAttributes.USAGE_RINGTONE);
        mAudioManager = context.getSystemService(AudioManager.class);
    }

    @Override
    public boolean isRestrictedByRingerModeSilent() {
        // Incoming calls never vibrate when the phone is in silent mode.
        return true;
    }

    @Override//更新震动强度,有3级,下边有贴,
    public boolean updateIntensity(int intensity) {
        final boolean success = super.updateIntensity(intensity);
    //根据震动强度的值决定这个开关的状态,只要不是0都算打开
        Settings.System.putInt(mContentResolver, Settings.System.VIBRATE_WHEN_RINGING,
                (intensity == Vibrator.VIBRATION_INTENSITY_OFF) ? OFF : ON);

        return success;
    }
}

>Usage

上边用到的枚举类型

    @IntDef(prefix = { "USAGE_" }, value = {
            USAGE_UNKNOWN,
            USAGE_ACCESSIBILITY,
            USAGE_ALARM,
            USAGE_COMMUNICATION_REQUEST,
            USAGE_HARDWARE_FEEDBACK,
            USAGE_MEDIA,
            USAGE_NOTIFICATION,
            USAGE_PHYSICAL_EMULATION,
            USAGE_RINGTONE,
            USAGE_TOUCH,
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface Usage {}

>RING_VIBRATION_INTENSITY

震动强度分3级

/**
 * The intensity of ringtone vibrations, if configurable.
 *
 * Not all devices are capable of changing their vibration intensity; on these devices
 * there will likely be no difference between the various vibration intensities except for
 * intensity 0 (off) and the rest.
 *
 * <b>Values:</b><br/>
 * 0 - Vibration is disabled<br/>
 * 1 - Weak vibrations<br/>
 * 2 - Medium vibrations<br/>
 * 3 - Strong vibrations
 * @hide
 */
@Readable
public static final String RING_VIBRATION_INTENSITY =
        "ring_vibration_intensity";

>VIBRATE_WHEN_RINGING

/**
 * Whether the phone vibrates when it is ringing due to an incoming call. This will
 * be used by Phone and Setting apps; it shouldn't affect other apps.
 * The value is boolean (1 or 0).
 *
 * Note: this is not same as "vibrate on ring", which had been available until ICS.
 * It was about AudioManager's setting and thus affected all the applications which
 * relied on the setting, while this is purely about the vibration setting for incoming
 * calls.
 *
 * @deprecated Replaced by using {@link android.os.VibrationAttributes#USAGE_RINGTONE} on
 * vibrations for incoming calls. User settings are applied automatically by the service and
 * should not be applied by individual apps.
 */
@Deprecated
@Readable
public static final String VIBRATE_WHEN_RINGING = "vibrate_when_ringing";

3.2.1.VibrationPreferenceConfig

>isMainVibrationSwitchEnabled

判断震动反馈总开关的状态

    public static final String MAIN_SWITCH_SETTING_KEY = Settings.System.VIBRATE_ON;

    public static boolean isMainVibrationSwitchEnabled(ContentResolver contentResolver) {
        return Settings.System.getInt(contentResolver, MAIN_SWITCH_SETTING_KEY, ON) == ON;
    }

>VibrationPreferenceConfig

  • settingKey:子类传递过来的,这里是RING_VIBRATION_INTENSITY
  • vibrationUsage:子类传递过来的,这里是ringtone
    public VibrationPreferenceConfig(Context context, String settingKey,
            @VibrationAttributes.Usage int vibrationUsage) {
        mContentResolver = context.getContentResolver();
        mVibrator = context.getSystemService(Vibrator.class);
        mAudioManager = context.getSystemService(AudioManager.class);
        mRingerModeSilentSummary = context.getString(
                R.string.accessibility_vibration_setting_disabled_for_silent_mode_summary);
        mSettingKey = settingKey;
        //获取对应usage下的默认震动强度
        mDefaultIntensity = mVibrator.getDefaultVibrationIntensity(vibrationUsage);
        //震动预览参数
        mPreviewVibrationAttributes = createPreviewVibrationAttributes(vibrationUsage);
    }

>isPreferenceEnabled

是否可用,总开关打开并且非手机静音模式才可用

    /** Returns true if this setting preference is enabled for user update. */
    public boolean isPreferenceEnabled() {
        return isMainVibrationSwitchEnabled(mContentResolver)
                && (!isRestrictedByRingerModeSilent() || !isRingerModeSilent());
    }

//

    /**
     * Returns true if this setting preference should be disabled when the device is in silent mode.
     */
    public boolean isRestrictedByRingerModeSilent() {
        return false;//子类覆写为true了
    }

//

    private boolean isRingerModeSilent() {
        // AudioManager.isSilentMode() also returns true when ringer mode is VIBRATE.
        // The vibration preferences are only disabled when the ringer mode is SILENT.
        return mAudioManager.getRingerModeInternal() == AudioManager.RINGER_MODE_SILENT;
    }

>readIntensity

获取震动强度

    /** Returns the default intensity to be displayed when the setting value is not set. */
    public int getDefaultIntensity() {
        return mDefaultIntensity;
    }

    /** Reads setting value for corresponding {@link VibrationPreferenceConfig} */
    public int readIntensity() {
        return Settings.System.getInt(mContentResolver, mSettingKey, mDefaultIntensity);
    }

>updateIntensity

更新震动强度

    /** Update setting value for corresponding {@link VibrationPreferenceConfig} */
    public boolean updateIntensity(int intensity) {
        return Settings.System.putInt(mContentResolver, mSettingKey, intensity);
    }

3.3.VibrationTogglePreferenceController

>updateState

    public void updateState(Preference preference) {
        super.updateState(preference);
        if (preference != null) {
        //是否可用,由config控制,也就是3.2小节
            preference.setEnabled(mPreferenceConfig.isPreferenceEnabled());
            preference.setSummary(mPreferenceConfig.getSummary());
        }
    }

>isChecked

开关状态由config里的震动强度决定,只要不是0就算打开状态。

    @Override
    public boolean isChecked() {
        return mPreferenceConfig.isPreferenceEnabled()
                && (mPreferenceConfig.readIntensity() != Vibrator.VIBRATION_INTENSITY_OFF);
    }

>setChecked

    public boolean setChecked(boolean isChecked) {
        if (!mPreferenceConfig.isPreferenceEnabled()) {
         选项不可用,不用管
            return false;
        }
        //开关打开,震动强度设置为默认值,关闭的话强度设置为0
        final int newIntensity = isChecked
                ? mPreferenceConfig.getDefaultIntensity()
                : Vibrator.VIBRATION_INTENSITY_OFF;
       //修改震动强度,见3.2.1里的方法       
        final boolean success = mPreferenceConfig.updateIntensity(newIntensity);

        if (success && isChecked) {
            mPreferenceConfig.playVibrationPreview();
        }

        return success;
    }

3.4.总结

"Ring vibration" 准确点说是2合一的操作:

  • "Ring vibration"开关打开,"ring_vibration_intensity"被修改为2,同时"vibrate_when_ringing"也被修改为1

  • "Ring vibration"开关关闭,"ring_vibration_intensity"被修改为0,同时"vibrate_when_ringing"也被修改为0

  • 进入设置页面,"Ring vibration"的开关状态,判断"ring_vibration_intensity"不为0即为打开状态。

  • 所以要修改这个值,直接修改"ring_vibration_intensity"的值就可以了。

4.vibrate first then ring gradually

4.1.VibrationRampingRingerTogglePreferenceController

public class VibrationRampingRingerTogglePreferenceController
        extends TogglePreferenceController implements LifecycleObserver, OnStart, OnStop {
        //..
        

4.2.isRingVibrationEnabled

震动反馈总开关是否打开,以及震动强度是否非off状态

    private boolean isRingVibrationEnabled() {
        return mRingVibrationPreferenceConfig.isPreferenceEnabled()
                && (mRingVibrationPreferenceConfig.readIntensity()
                != Vibrator.VIBRATION_INTENSITY_OFF);
    }

4.3.setChecked

    public boolean setChecked(boolean isChecked) {
    //大前提,震动可用
        if (isRingVibrationEnabled()) {
            //更新设置
            mAudioManager.setRampingRingerEnabled(isChecked);

            if (isChecked) {
                //选中转台,播放震动效果
                mRingVibrationPreferenceConfig.playVibrationPreview();
            }
        }
        return true;
    }

>mAudioManager

    public void setRampingRingerEnabled(boolean enabled) {
        Settings.System.putInt(getContext().getContentResolver(),
                Settings.System.APPLY_RAMPING_RINGER, enabled ? 1 : 0);
    }

4.4.isChecked

    public boolean isChecked() {
        return isRingVibrationEnabled() && mAudioManager.isRampingRingerEnabled();
    }

4.5.getAvailabilityStatus

    public int getAvailabilityStatus
    () {
        //测试用条件,默认false
        final boolean rampingRingerEnabledOnTelephonyConfig =
                mDeviceConfigProvider.isRampingRingerEnabledOnTelephonyConfig();
        return (Utils.isVoiceCapable(mContext) && !rampingRingerEnabledOnTelephonyConfig)
                ? AVAILABLE
                : UNSUPPORTED_ON_DEVICE;
    }

4.6.onStart

监听settings的改变刷新状态

    public void onStart
    () {
        mRingSettingObserver.register(mContext);
        mContext.getContentResolver().registerContentObserver(
                Settings.System.getUriFor(Settings.System.APPLY_RAMPING_RINGER),
                /* notifyForDescendants= */ false,
                mSettingObserver);
    }

5.Notification vibration

5.1.NotificationVibrationTogglePreferenceController

public class NotificationVibrationTogglePreferenceController
        extends VibrationTogglePreferenceController {

    public NotificationVibrationTogglePreferenceController(Context context, String preferenceKey) {
        super(context, preferenceKey, new NotificationVibrationPreferenceConfig(context));
    }

    @Override
    public int getAvailabilityStatus() {
        return AVAILABLE;
    }
}

5.2.NotificationVibrationPreferenceConfig

    public static final class NotificationVibrationPreferenceConfig
            extends VibrationPreferenceConfig {

        public NotificationVibrationPreferenceConfig(Context context) {
        //这里传递settings存储用到的key值
            super(context, Settings.System.NOTIFICATION_VIBRATION_INTENSITY,
                    VibrationAttributes.USAGE_NOTIFICATION);
        }

        @Override
        public boolean isRestrictedByRingerModeSilent() {
            // Notifications never vibrate when the phone is in silent mode.
            return true;
        }
    }

6.alarm vibration

6.1.AlarmVibrationTogglePreferenceController

public class AlarmVibrationTogglePreferenceController extends VibrationTogglePreferenceController {

    public AlarmVibrationTogglePreferenceController(Context context, String preferenceKey) {
        super(context, preferenceKey, new AlarmVibrationPreferenceConfig(context));
    }

    @Override
    public int getAvailabilityStatus() {
        return AVAILABLE;
    }
}

6.2.AlarmVibrationPreferenceConfig

    public static final class AlarmVibrationPreferenceConfig extends VibrationPreferenceConfig {

        public AlarmVibrationPreferenceConfig(Context context) {
        //都差不多,key不一样
            super(context, Settings.System.ALARM_VIBRATION_INTENSITY,
                    VibrationAttributes.USAGE_ALARM);
        }
    }

7.touch feedback

7.1.HapticFeedbackTogglePreferenceController

public class HapticFeedbackTogglePreferenceController extends VibrationTogglePreferenceController {

    public HapticFeedbackTogglePreferenceController(Context context, String preferenceKey) {
        super(context, preferenceKey, new HapticFeedbackVibrationPreferenceConfig(context));
    }

    @Override
    public int getAvailabilityStatus() {
        return AVAILABLE;
    }
}

7.2.HapticFeedbackVibrationPreferenceConfig

    public static final class HapticFeedbackVibrationPreferenceConfig
            extends VibrationPreferenceConfig {

        public HapticFeedbackVibrationPreferenceConfig(Context context) {
        //key值
            super(context, Settings.System.HAPTIC_FEEDBACK_INTENSITY,
                    VibrationAttributes.USAGE_TOUCH);
        }

        @Override
        public int readIntensity() {
        //先获取enable状态,如果是off的话,强度直接返回0
            final int hapticFeedbackEnabled = Settings.System.getInt(mContentResolver,
                    Settings.System.HAPTIC_FEEDBACK_ENABLED, ON);

            if (hapticFeedbackEnabled == OFF) {
                // HAPTIC_FEEDBACK_ENABLED is deprecated but should still be applied if the user has
                // turned it off already.
                return Vibrator.VIBRATION_INTENSITY_OFF;
            }

            return super.readIntensity();
        }

        @Override
        public boolean updateIntensity(int intensity) {
            final boolean success = super.updateIntensity(intensity);
            final boolean isIntensityOff = intensity == Vibrator.VIBRATION_INTENSITY_OFF;
        //同步更新enable状态
            Settings.System.putInt(mContentResolver, Settings.System.HAPTIC_FEEDBACK_ENABLED,
                    isIntensityOff ? OFF : ON);
            // HAPTIC_FEEDBACK_ENABLED is deprecated but should still reflect the intensity setting.

            // HARDWARE_HAPTIC_FEEDBACK_INTENSITY is dependent on this setting, but should not be
            // disabled by it.
            //off状态存储的是默认震动强度
            Settings.System.putInt(mContentResolver,
                    Settings.System.HARDWARE_HAPTIC_FEEDBACK_INTENSITY的值,不为0这开关打开,
                    isIntensityOff ? getDefaultIntensity() : intensity);

            return success;
        }
    }

7.3.总结

  • HAPTIC_FEEDBACK_ENABLED的值为off,那么这个开关就是关闭状态
  • HAPTIC_FEEDBACK_ENABLED的值为on,再继续读取HARDWARE_HAPTIC_FEEDBACK_INTENSITY的值,不为0这开关打开
  • 开关

8.media vibration

8.1.MediaVibrationTogglePreferenceController

/** Preference controller for alarm vibration with only a toggle for on/off states. */
public class MediaVibrationTogglePreferenceController extends VibrationTogglePreferenceController {

    public MediaVibrationTogglePreferenceController(Context context, String preferenceKey) {
        super(context, preferenceKey, new MediaVibrationPreferenceConfig(context));
    }

    @Override
    public int getAvailabilityStatus() {
    //这个是否可见是由配置决定的
        return mContext.getResources().getBoolean(R.bool.config_media_vibration_supported) ?
                AVAILABLE : UNSUPPORTED_ON_DEVICE;
    }
}

8.2.MediaVibrationPreferenceConfig

    public static final class MediaVibrationPreferenceConfig extends VibrationPreferenceConfig {

        public MediaVibrationPreferenceConfig(Context context) {
        //key值
            super(context, Settings.System.MEDIA_VIBRATION_INTENSITY,
                    VibrationAttributes.USAGE_MEDIA);
        }
    }

9.VibrationTogglePreferenceController

9.1.构造方法

    protected VibrationTogglePreferenceController(Context context, String preferenceKey,
            VibrationPreferenceConfig preferenceConfig) {
        super(context, preferenceKey);
        mPreferenceConfig = preferenceConfig;
        mSettingsContentObserver = new VibrationPreferenceConfig.SettingObserver(
                preferenceConfig);
    }

9.2.updateState

    public void updateState(Preference preference) {
        super.updateState(preference);
        if (preference != null) {
        //数据由config获取
            preference.setEnabled(mPreferenceConfig.isPreferenceEnabled());
            preference.setSummary(mPreferenceConfig.getSummary());
        }
    }

9.3.isChecked

开关打开的条件:选项可用,并且读取的强度值不是off

    public boolean isChecked() {
        return mPreferenceConfig.isPreferenceEnabled()
                && (mPreferenceConfig.readIntensity() != Vibrator.VIBRATION_INTENSITY_OFF);
    }

9.4.setChecked

    public boolean setChecked(boolean isChecked) {
        if (!mPreferenceConfig.isPreferenceEnabled()) {
            //选项不可用,忽略
            return false;
        }
        //开关打开,强度为默认值,关闭为0
        final int newIntensity = isChecked
                ? mPreferenceConfig.getDefaultIntensity()
                : Vibrator.VIBRATION_INTENSITY_OFF;
        final boolean success = mPreferenceConfig.updateIntensity(newIntensity);

        if (success && isChecked) {
            mPreferenceConfig.playVibrationPreview();
        }

        return success;
    }

10.总结

  • 就小节3(ring vibration)以及小节7(touch feedback)稍微特殊点,有2个settings的值控制,其他的都是一个