Search code examples
androidandroid-preferencespreferenceactivitypreferencescreenandroid-vibration

Is there something like a VibrationPreference similar to RingtonePreference?


I'd really like to let a user pick out a vibration to use for my app, I'm already using RingtonePreference in my PreferenceScreen, is there anything similar for Vibrations, or a library that does it?

EDIT: Or, if there isn't a library or existing class that does it, is there some easy way to extend a class to do it? ListPreference looks like a good candidate but doesnt have an 'onclick' handler to play the vibration pattern chosen.


Solution

  • its pretty easy to set up your own, the source code for ListPreference is at http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/1.5_r4/android/preference/ListPreference.java

    Here's what i eventually came up with that is working for me

    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);
                }
            }
        }
    }
    

    and then in my preference screen 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"
         />  
    

    and don't forget to set in you manifest:

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

    and then just get your "vibration_pattern_index" from your prefs and use it to get the long[] out of VibrationPreference.vibration_patterns, and you'll have your user's chosen vibration! Lol i wonder if anyone will actually use or even read this:)