2 * Copyright (C) 2007 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 package com.android.settings;
19 import android.content.Context;
20 import android.content.Intent;
21 import android.content.res.TypedArray;
22 import android.media.AudioAttributes;
23 import android.media.RingtoneManager;
24 import android.net.Uri;
25 import android.provider.Settings.System;
26 import android.support.v7.preference.Preference;
27 import android.support.v7.preference.PreferenceManager;
28 import android.text.TextUtils;
29 import android.util.AttributeSet;
32 * A {@link Preference} that allows the user to choose a ringtone from those on the device.
33 * The chosen ringtone's URI will be persisted as a string.
35 * If the user chooses the "Default" item, the saved string will be one of
36 * {@link System#DEFAULT_RINGTONE_URI},
37 * {@link System#DEFAULT_NOTIFICATION_URI}, or
38 * {@link System#DEFAULT_ALARM_ALERT_URI}. If the user chooses the "Silent"
39 * item, the saved string will be an empty string.
41 * @attr ref android.R.styleable#RingtonePreference_ringtoneType
42 * @attr ref android.R.styleable#RingtonePreference_showDefault
43 * @attr ref android.R.styleable#RingtonePreference_showSilent
45 * Based of frameworks/base/core/java/android/preference/RingtonePreference.java
46 * but extends android.support.v7.preference.Preference instead.
48 public class RingtonePreference extends Preference {
50 private static final String TAG = "RingtonePreference";
52 private static int sRequestCode = 100;
54 private int mRingtoneType;
55 private boolean mShowDefault;
56 private boolean mShowSilent;
58 private int mRequestCode;
60 public RingtonePreference(Context context, AttributeSet attrs) {
61 super(context, attrs);
63 final TypedArray a = context.obtainStyledAttributes(attrs,
64 com.android.internal.R.styleable.RingtonePreference, 0, 0);
65 mRingtoneType = a.getInt(com.android.internal.R.styleable.RingtonePreference_ringtoneType,
66 RingtoneManager.TYPE_RINGTONE);
67 mShowDefault = a.getBoolean(com.android.internal.R.styleable.RingtonePreference_showDefault,
69 mShowSilent = a.getBoolean(com.android.internal.R.styleable.RingtonePreference_showSilent,
71 setIntent(new Intent(RingtoneManager.ACTION_RINGTONE_PICKER));
76 * Returns the sound type(s) that are shown in the picker.
78 * @return The sound type(s) that are shown in the picker.
79 * @see #setRingtoneType(int)
81 public int getRingtoneType() {
86 * Sets the sound type(s) that are shown in the picker.
88 * @param type The sound type(s) that are shown in the picker.
89 * @see RingtoneManager#EXTRA_RINGTONE_TYPE
91 public void setRingtoneType(int type) {
96 * Returns whether to a show an item for the default sound/ringtone.
98 * @return Whether to show an item for the default sound/ringtone.
100 public boolean getShowDefault() {
105 * Sets whether to show an item for the default sound/ringtone. The default
106 * to use will be deduced from the sound type(s) being shown.
108 * @param showDefault Whether to show the default or not.
109 * @see RingtoneManager#EXTRA_RINGTONE_SHOW_DEFAULT
111 public void setShowDefault(boolean showDefault) {
112 mShowDefault = showDefault;
116 * Returns whether to a show an item for 'Silent'.
118 * @return Whether to show an item for 'Silent'.
120 public boolean getShowSilent() {
125 * Sets whether to show an item for 'Silent'.
127 * @param showSilent Whether to show 'Silent'.
128 * @see RingtoneManager#EXTRA_RINGTONE_SHOW_SILENT
130 public void setShowSilent(boolean showSilent) {
131 mShowSilent = showSilent;
134 public int getRequestCode() {
139 * Prepares the intent to launch the ringtone picker. This can be modified
140 * to adjust the parameters of the ringtone picker.
142 * @param ringtonePickerIntent The ringtone picker intent that can be
143 * modified by putting extras.
145 public void onPrepareRingtonePickerIntent(Intent ringtonePickerIntent) {
147 ringtonePickerIntent.putExtra(RingtoneManager.EXTRA_RINGTONE_EXISTING_URI,
148 onRestoreRingtone());
150 ringtonePickerIntent.putExtra(RingtoneManager.EXTRA_RINGTONE_SHOW_DEFAULT, mShowDefault);
152 ringtonePickerIntent.putExtra(RingtoneManager.EXTRA_RINGTONE_DEFAULT_URI,
153 RingtoneManager.getDefaultUri(getRingtoneType()));
156 ringtonePickerIntent.putExtra(RingtoneManager.EXTRA_RINGTONE_SHOW_SILENT, mShowSilent);
157 ringtonePickerIntent.putExtra(RingtoneManager.EXTRA_RINGTONE_TYPE, mRingtoneType);
158 ringtonePickerIntent.putExtra(RingtoneManager.EXTRA_RINGTONE_TITLE, getTitle());
159 ringtonePickerIntent.putExtra(RingtoneManager.EXTRA_RINGTONE_AUDIO_ATTRIBUTES_FLAGS,
160 AudioAttributes.FLAG_BYPASS_INTERRUPTION_POLICY);
164 * Called when a ringtone is chosen.
166 * By default, this saves the ringtone URI to the persistent storage as a
169 * @param ringtoneUri The chosen ringtone's {@link Uri}. Can be null.
171 protected void onSaveRingtone(Uri ringtoneUri) {
172 persistString(ringtoneUri != null ? ringtoneUri.toString() : "");
176 * Called when the chooser is about to be shown and the current ringtone
177 * should be marked. Can return null to not mark any ringtone.
179 * By default, this restores the previous ringtone URI from the persistent
182 * @return The ringtone to be marked as the current ringtone.
184 protected Uri onRestoreRingtone() {
185 final String uriString = getPersistedString(null);
186 return !TextUtils.isEmpty(uriString) ? Uri.parse(uriString) : null;
190 protected Object onGetDefaultValue(TypedArray a, int index) {
191 return a.getString(index);
195 protected void onSetInitialValue(boolean restorePersistedValue, Object defaultValueObj) {
196 String defaultValue = (String) defaultValueObj;
199 * This method is normally to make sure the internal state and UI
200 * matches either the persisted value or the default value. Since we
201 * don't show the current value in the UI (until the dialog is opened)
202 * and we don't keep local state, if we are restoring the persisted
203 * value we don't need to do anything.
205 if (restorePersistedValue) {
209 // If we are setting to the default value, we should persist it.
210 if (!TextUtils.isEmpty(defaultValue)) {
211 onSaveRingtone(Uri.parse(defaultValue));
214 protected void onAttachedToHierarchy(PreferenceManager preferenceManager) {
215 super.onAttachedToHierarchy(preferenceManager);
217 mRequestCode = sRequestCode++;
220 public boolean onActivityResult(int requestCode, int resultCode, Intent data) {
221 if (requestCode == mRequestCode) {
223 Uri uri = data.getParcelableExtra(RingtoneManager.EXTRA_RINGTONE_PICKED_URI);
225 if (callChangeListener(uri != null ? uri.toString() : "")) {