是否有类似于RingtonePreference的VibrationPreference?

时间:2013-09-23 03:44:22

标签: android android-preferences preferenceactivity preferencescreen android-vibration

我真的想让用户选择一个用于我的应用程序的振动,我已经在我的PreferenceScreen中使用了RingtonePreference,是否有任何类似的Vibrations,或者是一个库来做它?

编辑: 或者,如果没有库或现有类来执行它,是否有一些简单的方法来扩展类来执行它? ListPreference看起来是一个很好的候选者,但没有'onclick'处理程序来播放所选择的振动模式。

2 个答案:

答案 0 :(得分:2)

很容易设置自己的,ListPreference的源代码位于http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/1.5_r4/android/preference/ListPreference.java

这是我最终想出来的,这对我有用

VibrationPreference.java

package com.mypackagename;

import android.app.AlertDialog.Builder;
import android.content.Context;
import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.os.Vibrator;
import android.preference.ListPreference;
import android.util.AttributeSet;

public class VibrationPreference extends ListPreference {
    private int clickedIndex;


    // This example will cause the phone to vibrate "SOS" in Morse Code
    // In Morse Code, "s" = "dot-dot-dot", "o" = "dash-dash-dash"
    // There are pauses to separate dots/dashes, letters, and words
    // The following numbers represent millisecond lengths
    private static final int dot = 150;      // Length of a Morse Code "dot" in milliseconds
    private static final int dash = 375;     // Length of a Morse Code "dash" in milliseconds
    private static final int short_gap = 150;    // Length of Gap Between dots/dashes
    private static final int medium_gap = 375;   // Length of Gap Between Letters
    private static final int long_gap = 750;    // Length of Gap Between Words



    private static final long[] sos_pattern = {
        0,  // Start immediately
        dot, short_gap, dot, short_gap, dot,    // s
        medium_gap,
        dash, short_gap, dash, short_gap, dash, // o
        medium_gap,
        dot, short_gap, dot, short_gap, dot    // s
    };

    private static final int beat = 250;
    private static final int interbeat = 100;
    private static final int between_beat_pairs = 700;
    private static final long[] heartbeat_pattern = {
        0,  // Start immediately
        beat, interbeat, beat, // o
        between_beat_pairs,
        beat, interbeat, beat, // o
    };

    private static final long[] jackhammer_pattern = {
        0,  // Start immediately
        100, 100, 
        100, 100,
        100, 100,
        100, 100,
        100, 100,

        100, 100,
        100, 100,
        100, 100,
        100, 100,
        100, 100,

        100, 100,
        100, 100,
        100

    };


    public static final long[][] vibration_patterns = { null, sos_pattern, heartbeat_pattern, jackhammer_pattern};



    Vibrator vibrator;      

    public VibrationPreference(Context context, AttributeSet attrs) {
        super(context, attrs);
        vibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
    }

    public VibrationPreference(Context context) {
        super(context);
        vibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
    }

    @Override
    protected void onPrepareDialogBuilder(Builder builder) {
        super.onPrepareDialogBuilder(builder);

        if (getEntries() == null || getEntryValues() == null) {
            throw new IllegalStateException(
                    "ListPreference requires an entries array and an entryValues array.");
        }

        clickedIndex = findIndexOfValue(getValue());
        builder.setSingleChoiceItems(getEntries(), clickedIndex, 
                new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {
                        clickedIndex = which;
                        vibrator.cancel();
                        if (clickedIndex > 0) vibrator.vibrate(vibration_patterns[clickedIndex], -1);
                    }
        });

        builder.setPositiveButton("OK", this).setNegativeButton("Cancel", this);
    }

    @Override
    protected void onDialogClosed(boolean positiveResult) {
        vibrator.cancel();
        super.onDialogClosed(positiveResult);

        if (positiveResult && clickedIndex >= 0 && getEntryValues() != null) {
            String value = getEntryValues()[clickedIndex].toString();
            if (callChangeListener(value)) {
                setValue(value);
            }
        }
    }
}

然后在我的首选屏幕xml:

    <CheckBoxPreference android:title="Vibrate"
            android:key="do_vibrate" android:defaultValue="true"></CheckBoxPreference> 



    <com.mypackagename.VibrationPreference
        android:key="vibration_pattern_index"
        android:dependency="do_vibrate"
        android:title="Vibration Pattern"
        android:defaultValue="0"
        android:entries="@array/vibration_pattern_entries"
        android:entryValues="@array/vibration_pattern_values"
     />  

并且不要忘记在你的清单中设置:

<uses-permission android:name="android.permission.VIBRATE"/>

然后从你的首选项中获取你的“vibration_pattern_index”并使用它从VibrationPreference.vibration_patterns获取long [],你将获得用户选择的振动!大声笑我想知道是否有人会实际使用甚至读这个:)

答案 1 :(得分:0)

If you want to use an android.support.v7.preference.ListPreference instead of an android.preference.ListPreference, you'll need to extend PreferenceDialogFragmentCompat.

VibrationPreferenceDialogFragmentCompat.java:

public class VibrationPreferenceDialogFragmentCompat extends   PreferenceDialogFragmentCompat
{

    // This example will cause the phone to vibrate "SOS" in Morse Code
    // In Morse Code, "s" = "dot-dot-dot", "o" = "dash-dash-dash"
    // There are pauses to separate dots/dashes, letters, and words
    // The following numbers represent millisecond lengths
    private static final int dot = 150;      // Length of a Morse Code "dot" in milliseconds
    private static final int dash = 375;     // Length of a Morse Code "dash" in milliseconds
    private static final int short_gap = 150;    // Length of Gap Between dots/dashes
    private static final int medium_gap = 375;   // Length of Gap Between Letters
    private static final int long_gap = 750;    // Length of Gap Between Words
    private static final long[] sos_pattern = {
        0,  // Start immediately
        dot, short_gap, dot, short_gap, dot,    // s
        medium_gap,
        dash, short_gap, dash, short_gap, dash, // o
        medium_gap,
        dot, short_gap, dot, short_gap, dot    // s
    };

    private static final int beat = 250;
    private static final int interbeat = 100;
    private static final int between_beat_pairs = 700;
    private static final long[] heartbeat_pattern = {
        0,  // Start immediately
        beat, interbeat, beat, // o
        between_beat_pairs,
        beat, interbeat, beat, // o
};

    private static final long[] jackhammer_pattern = {
        0,  // Start immediately
        100, 100,
        100, 100,
        100, 100,
        100, 100,
        100, 100,

        100, 100,
        100, 100,
        100, 100,
        100, 100,
        100, 100,

        100, 100,
        100, 100,
        100

};

    public static final long[][] VIBRATION_PATTERNS = {sos_pattern, heartbeat_pattern, jackhammer_pattern};

private int mClickedIndex;
private Vibrator mVibrator;
private ListPreference mPreference;

@Override
protected View onCreateDialogView(Context context) {
    mVibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
    return super.onCreateDialogView(context);
}


@Override
protected void onPrepareDialogBuilder(AlertDialog.Builder builder) {
    super.onPrepareDialogBuilder(builder);

    mPreference = (ListPreference) getPreference();

    if (mPreference.getEntries() == null || mPreference.getEntryValues() == null) {
        throw new IllegalStateException(
                "ListPreference requires an entries array and an entryValues array.");
    }

    mClickedIndex = mPreference.findIndexOfValue(mPreference.getValue());
    builder.setSingleChoiceItems(mPreference.getEntries(), mClickedIndex,
            new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int which) {
                    mClickedIndex = which;
                    mVibrator.cancel();
                    if (mClickedIndex >= 0) mVibrator.vibrate(VIBRATION_PATTERNS[mClickedIndex], -1);
                }
            });

    builder.setPositiveButton("OK", this).setNegativeButton("Cancel", this);
}

@Override
public void onDialogClosed(boolean positiveResult) {
    mVibrator.cancel();

    if (positiveResult && mClickedIndex >= 0 && mPreference.getEntryValues() != null) {
        String value = mPreference.getEntryValues()[mClickedIndex].toString();
        if (mPreference.callChangeListener(value)) {
            mPreference.setValue(value);
            mPreference.setSummary(getResources().getStringArray(R.array.vibration_pattern_entries)[mClickedIndex]);
        }
    }
}

}

SettingsFragment.java:

public class SettingsFragment extends PreferenceFragmentCompat {
...
    @Override
    public void onDisplayPreferenceDialog(Preference preference) {
        DialogFragment dialogFragment = null;
        if (preference.getKey().equals("pref_vibrate_pattern"))
        {
            dialogFragment = new VibrationPreferenceDialogFragmentCompat();
            Bundle bundle = new Bundle(1);
            bundle.putString("key", preference.getKey());
            dialogFragment.setArguments(bundle);
        }

        if (dialogFragment != null)
        {
            dialogFragment.setTargetFragment(this, 0);
            dialogFragment.show(this.getFragmentManager(), "android.support.v7.preference.PreferenceFragment.DIALOG");
        }
        else
        {
            super.onDisplayPreferenceDialog(preference);
        }
    }
...
}

settings.xml:

<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
...
        <ListPreference
            android:key="pref_vibrate_pattern"
            android:title="Vibration pattern"
            android:entries="@array/vibration_pattern_entries"
            android:entryValues="@array/vibration_pattern_values"
            android:summary="Select the vibration pattern"/>
...
</PreferenceScreen>

strings.xml:

<resources>
    <string-array name="vibration_pattern_entries">
        <item>SOS pattern</item>
        <item>Heartbeat</item>
        <item>JackHammer</item>
    </string-array>

    <string-array name="vibration_pattern_values">
        <item>0</item>
        <item>1</item>
        <item>2</item>
    </string-array>
</resources>