VolumePreference.java revision 54b6cfa9a9e5b861a9930af873580d6dc20f773c
1/* 2 * Copyright (C) 2007 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package android.preference; 18 19import android.content.ContentResolver; 20import android.content.Context; 21import android.content.res.TypedArray; 22import android.database.ContentObserver; 23import android.media.Ringtone; 24import android.media.RingtoneManager; 25import android.media.AudioManager; 26import android.os.Handler; 27import android.preference.PreferenceManager; 28import android.provider.Settings; 29import android.provider.Settings.System; 30import android.util.AttributeSet; 31import android.view.View; 32import android.widget.SeekBar; 33import android.widget.SeekBar.OnSeekBarChangeListener; 34 35/** 36 * @hide 37 */ 38public class VolumePreference extends SeekBarPreference implements OnSeekBarChangeListener, 39 Runnable, PreferenceManager.OnActivityStopListener { 40 41 private static final String TAG = "VolumePreference"; 42 43 private ContentResolver mContentResolver; 44 private Handler mHandler = new Handler(); 45 46 private AudioManager mVolume; 47 private int mStreamType; 48 private int mOriginalStreamVolume; 49 private Ringtone mRingtone; 50 51 private int mLastProgress; 52 private SeekBar mSeekBar; 53 54 private ContentObserver mVolumeObserver = new ContentObserver(mHandler) { 55 @Override 56 public void onChange(boolean selfChange) { 57 super.onChange(selfChange); 58 59 if (mSeekBar != null) { 60 mSeekBar.setProgress(System.getInt(mContentResolver, 61 System.VOLUME_SETTINGS[mStreamType], 0)); 62 } 63 } 64 }; 65 66 public VolumePreference(Context context, AttributeSet attrs) { 67 super(context, attrs); 68 69 TypedArray a = context.obtainStyledAttributes(attrs, 70 com.android.internal.R.styleable.VolumePreference, 0, 0); 71 mStreamType = a.getInt(android.R.styleable.VolumePreference_streamType, 0); 72 a.recycle(); 73 74 mContentResolver = context.getContentResolver(); 75 76 mVolume = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE); 77 } 78 79 @Override 80 protected void onBindDialogView(View view) { 81 super.onBindDialogView(view); 82 83 final SeekBar seekBar = mSeekBar = (SeekBar) view.findViewById(com.android.internal.R.id.seekbar); 84 seekBar.setMax(mVolume.getStreamMaxVolume(mStreamType)); 85 mOriginalStreamVolume = mVolume.getStreamVolume(mStreamType); 86 seekBar.setProgress(mOriginalStreamVolume); 87 seekBar.setOnSeekBarChangeListener(this); 88 89 mContentResolver.registerContentObserver(System.getUriFor(System.VOLUME_SETTINGS[mStreamType]), false, mVolumeObserver); 90 91 getPreferenceManager().registerOnActivityStopListener(this); 92 mRingtone = RingtoneManager.getRingtone(getContext(), Settings.System.DEFAULT_RINGTONE_URI); 93 } 94 95 @Override 96 protected void onDialogClosed(boolean positiveResult) { 97 super.onDialogClosed(positiveResult); 98 99 if (!positiveResult) { 100 mVolume.setStreamVolume(mStreamType, mOriginalStreamVolume, 0); 101 } 102 103 cleanup(); 104 } 105 106 107 public void onActivityStop() { 108 cleanup(); 109 } 110 111 /** 112 * Do clean up. This can be called multiple times! 113 */ 114 private void cleanup() { 115 stopSample(); 116 if (mVolumeObserver != null) { 117 mContentResolver.unregisterContentObserver(mVolumeObserver); 118 } 119 getPreferenceManager().unregisterOnActivityStopListener(this); 120 mSeekBar = null; 121 } 122 123 public void onProgressChanged(SeekBar seekBar, int progress, boolean fromTouch) { 124 if (!fromTouch) { 125 return; 126 } 127 128 postSetVolume(progress); 129 } 130 131 private void postSetVolume(int progress) { 132 // Do the volume changing separately to give responsive UI 133 mLastProgress = progress; 134 mHandler.removeCallbacks(this); 135 mHandler.post(this); 136 } 137 138 public void onStartTrackingTouch(SeekBar seekBar) { 139 } 140 141 public void onStopTrackingTouch(SeekBar seekBar) { 142 if (mRingtone != null && !mRingtone.isPlaying()) { 143 sample(); 144 } 145 } 146 147 public void run() { 148 mVolume.setStreamVolume(mStreamType, mLastProgress, 0); 149 } 150 151 private void sample() { 152 mRingtone.play(); 153 } 154 155 private void stopSample() { 156 if (mRingtone != null) { 157 mRingtone.stop(); 158 } 159 } 160 161} 162