1/* 2 * Copyright (C) 2014 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 com.android.settings.notification; 18 19import android.content.ContentResolver; 20import android.content.Context; 21import android.media.AudioManager; 22import android.net.Uri; 23import android.preference.PreferenceManager; 24import android.preference.SeekBarPreference; 25import android.preference.SeekBarVolumizer; 26import android.util.AttributeSet; 27import android.util.Log; 28import android.view.View; 29import android.widget.ImageView; 30import android.widget.SeekBar; 31 32import com.android.settings.R; 33 34/** A slider preference that directly controls an audio stream volume (no dialog) **/ 35public class VolumeSeekBarPreference extends SeekBarPreference 36 implements PreferenceManager.OnActivityStopListener { 37 private static final String TAG = "VolumeSeekBarPreference"; 38 39 private int mStream; 40 private SeekBar mSeekBar; 41 private SeekBarVolumizer mVolumizer; 42 private Callback mCallback; 43 private ImageView mIconView; 44 45 public VolumeSeekBarPreference(Context context, AttributeSet attrs, int defStyleAttr, 46 int defStyleRes) { 47 super(context, attrs, defStyleAttr, defStyleRes); 48 } 49 50 public VolumeSeekBarPreference(Context context, AttributeSet attrs, int defStyleAttr) { 51 this(context, attrs, defStyleAttr, 0); 52 } 53 54 public VolumeSeekBarPreference(Context context, AttributeSet attrs) { 55 this(context, attrs, 0); 56 } 57 58 public VolumeSeekBarPreference(Context context) { 59 this(context, null); 60 } 61 62 public void setStream(int stream) { 63 mStream = stream; 64 } 65 66 public void setCallback(Callback callback) { 67 mCallback = callback; 68 } 69 70 @Override 71 public void onActivityStop() { 72 if (mVolumizer != null) { 73 mVolumizer.stop(); 74 } 75 } 76 77 @Override 78 protected void onBindView(View view) { 79 super.onBindView(view); 80 if (mStream == 0) { 81 Log.w(TAG, "No stream found, not binding volumizer"); 82 return; 83 } 84 getPreferenceManager().registerOnActivityStopListener(this); 85 final SeekBar seekBar = (SeekBar) view.findViewById(com.android.internal.R.id.seekbar); 86 if (seekBar == mSeekBar) return; 87 mSeekBar = seekBar; 88 final SeekBarVolumizer.Callback sbvc = new SeekBarVolumizer.Callback() { 89 @Override 90 public void onSampleStarting(SeekBarVolumizer sbv) { 91 if (mCallback != null) { 92 mCallback.onSampleStarting(sbv); 93 } 94 } 95 }; 96 final Uri sampleUri = mStream == AudioManager.STREAM_MUSIC ? getMediaVolumeUri() : null; 97 if (mVolumizer == null) { 98 mVolumizer = new SeekBarVolumizer(getContext(), mStream, sampleUri, sbvc) { 99 // we need to piggyback on SBV's SeekBar listener to update our icon 100 @Override 101 public void onProgressChanged(SeekBar seekBar, int progress, 102 boolean fromTouch) { 103 super.onProgressChanged(seekBar, progress, fromTouch); 104 mCallback.onStreamValueChanged(mStream, progress); 105 } 106 }; 107 } 108 mVolumizer.setSeekBar(mSeekBar); 109 mIconView = (ImageView) view.findViewById(com.android.internal.R.id.icon); 110 mCallback.onStreamValueChanged(mStream, mSeekBar.getProgress()); 111 } 112 113 // during initialization, this preference is the SeekBar listener 114 @Override 115 public void onProgressChanged(SeekBar seekBar, int progress, 116 boolean fromTouch) { 117 super.onProgressChanged(seekBar, progress, fromTouch); 118 mCallback.onStreamValueChanged(mStream, progress); 119 } 120 121 public void showIcon(int resId) { 122 // Instead of using setIcon, which will trigger listeners, this just decorates the 123 // preference temporarily with a new icon. 124 if (mIconView != null) { 125 mIconView.setImageResource(resId); 126 } 127 } 128 129 private Uri getMediaVolumeUri() { 130 return Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE + "://" 131 + getContext().getPackageName() 132 + "/" + R.raw.media_volume); 133 } 134 135 public interface Callback { 136 void onSampleStarting(SeekBarVolumizer sbv); 137 void onStreamValueChanged(int stream, int progress); 138 } 139} 140