Home | History | Annotate | Download | only in preference
      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 
     17 package android.preference;
     18 
     19 import android.annotation.UnsupportedAppUsage;
     20 import android.content.Context;
     21 import android.content.Intent;
     22 import android.content.res.TypedArray;
     23 import android.media.AudioAttributes;
     24 import android.media.RingtoneManager;
     25 import android.net.Uri;
     26 import android.provider.Settings.System;
     27 import android.text.TextUtils;
     28 import android.util.AttributeSet;
     29 
     30 /**
     31  * A {@link Preference} that allows the user to choose a ringtone from those on the device.
     32  * The chosen ringtone's URI will be persisted as a string.
     33  * <p>
     34  * If the user chooses the "Default" item, the saved string will be one of
     35  * {@link System#DEFAULT_RINGTONE_URI},
     36  * {@link System#DEFAULT_NOTIFICATION_URI}, or
     37  * {@link System#DEFAULT_ALARM_ALERT_URI}. If the user chooses the "Silent"
     38  * item, the saved string will be an empty string.
     39  *
     40  * @attr ref android.R.styleable#RingtonePreference_ringtoneType
     41  * @attr ref android.R.styleable#RingtonePreference_showDefault
     42  * @attr ref android.R.styleable#RingtonePreference_showSilent
     43  *
     44  * @deprecated Use the <a href="{@docRoot}jetpack/androidx.html">AndroidX</a>
     45  *      <a href="{@docRoot}reference/androidx/preference/package-summary.html">
     46  *      Preference Library</a> for consistent behavior across all devices. For more information on
     47  *      using the AndroidX Preference Library see
     48  *      <a href="{@docRoot}guide/topics/ui/settings.html">Settings</a>.
     49  */
     50 @Deprecated
     51 public class RingtonePreference extends Preference implements
     52         PreferenceManager.OnActivityResultListener {
     53 
     54     private static final String TAG = "RingtonePreference";
     55 
     56     private int mRingtoneType;
     57     private boolean mShowDefault;
     58     private boolean mShowSilent;
     59 
     60     @UnsupportedAppUsage
     61     private int mRequestCode;
     62 
     63     public RingtonePreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
     64         super(context, attrs, defStyleAttr, defStyleRes);
     65 
     66         final TypedArray a = context.obtainStyledAttributes(attrs,
     67                 com.android.internal.R.styleable.RingtonePreference, defStyleAttr, defStyleRes);
     68         mRingtoneType = a.getInt(com.android.internal.R.styleable.RingtonePreference_ringtoneType,
     69                 RingtoneManager.TYPE_RINGTONE);
     70         mShowDefault = a.getBoolean(com.android.internal.R.styleable.RingtonePreference_showDefault,
     71                 true);
     72         mShowSilent = a.getBoolean(com.android.internal.R.styleable.RingtonePreference_showSilent,
     73                 true);
     74         a.recycle();
     75     }
     76 
     77     public RingtonePreference(Context context, AttributeSet attrs, int defStyleAttr) {
     78         this(context, attrs, defStyleAttr, 0);
     79     }
     80 
     81     public RingtonePreference(Context context, AttributeSet attrs) {
     82         this(context, attrs, com.android.internal.R.attr.ringtonePreferenceStyle);
     83     }
     84 
     85     public RingtonePreference(Context context) {
     86         this(context, null);
     87     }
     88 
     89     /**
     90      * Returns the sound type(s) that are shown in the picker.
     91      *
     92      * @return The sound type(s) that are shown in the picker.
     93      * @see #setRingtoneType(int)
     94      */
     95     public int getRingtoneType() {
     96         return mRingtoneType;
     97     }
     98 
     99     /**
    100      * Sets the sound type(s) that are shown in the picker.
    101      *
    102      * @param type The sound type(s) that are shown in the picker.
    103      * @see RingtoneManager#EXTRA_RINGTONE_TYPE
    104      */
    105     public void setRingtoneType(int type) {
    106         mRingtoneType = type;
    107     }
    108 
    109     /**
    110      * Returns whether to a show an item for the default sound/ringtone.
    111      *
    112      * @return Whether to show an item for the default sound/ringtone.
    113      */
    114     public boolean getShowDefault() {
    115         return mShowDefault;
    116     }
    117 
    118     /**
    119      * Sets whether to show an item for the default sound/ringtone. The default
    120      * to use will be deduced from the sound type(s) being shown.
    121      *
    122      * @param showDefault Whether to show the default or not.
    123      * @see RingtoneManager#EXTRA_RINGTONE_SHOW_DEFAULT
    124      */
    125     public void setShowDefault(boolean showDefault) {
    126         mShowDefault = showDefault;
    127     }
    128 
    129     /**
    130      * Returns whether to a show an item for 'Silent'.
    131      *
    132      * @return Whether to show an item for 'Silent'.
    133      */
    134     public boolean getShowSilent() {
    135         return mShowSilent;
    136     }
    137 
    138     /**
    139      * Sets whether to show an item for 'Silent'.
    140      *
    141      * @param showSilent Whether to show 'Silent'.
    142      * @see RingtoneManager#EXTRA_RINGTONE_SHOW_SILENT
    143      */
    144     public void setShowSilent(boolean showSilent) {
    145         mShowSilent = showSilent;
    146     }
    147 
    148     @Override
    149     protected void onClick() {
    150         // Launch the ringtone picker
    151         Intent intent = new Intent(RingtoneManager.ACTION_RINGTONE_PICKER);
    152         onPrepareRingtonePickerIntent(intent);
    153         PreferenceFragment owningFragment = getPreferenceManager().getFragment();
    154         if (owningFragment != null) {
    155             owningFragment.startActivityForResult(intent, mRequestCode);
    156         } else {
    157             getPreferenceManager().getActivity().startActivityForResult(intent, mRequestCode);
    158         }
    159     }
    160 
    161     /**
    162      * Prepares the intent to launch the ringtone picker. This can be modified
    163      * to adjust the parameters of the ringtone picker.
    164      *
    165      * @param ringtonePickerIntent The ringtone picker intent that can be
    166      *            modified by putting extras.
    167      */
    168     protected void onPrepareRingtonePickerIntent(Intent ringtonePickerIntent) {
    169 
    170         ringtonePickerIntent.putExtra(RingtoneManager.EXTRA_RINGTONE_EXISTING_URI,
    171                 onRestoreRingtone());
    172 
    173         ringtonePickerIntent.putExtra(RingtoneManager.EXTRA_RINGTONE_SHOW_DEFAULT, mShowDefault);
    174         if (mShowDefault) {
    175             ringtonePickerIntent.putExtra(RingtoneManager.EXTRA_RINGTONE_DEFAULT_URI,
    176                     RingtoneManager.getDefaultUri(getRingtoneType()));
    177         }
    178 
    179         ringtonePickerIntent.putExtra(RingtoneManager.EXTRA_RINGTONE_SHOW_SILENT, mShowSilent);
    180         ringtonePickerIntent.putExtra(RingtoneManager.EXTRA_RINGTONE_TYPE, mRingtoneType);
    181         ringtonePickerIntent.putExtra(RingtoneManager.EXTRA_RINGTONE_TITLE, getTitle());
    182         ringtonePickerIntent.putExtra(RingtoneManager.EXTRA_RINGTONE_AUDIO_ATTRIBUTES_FLAGS,
    183                 AudioAttributes.FLAG_BYPASS_INTERRUPTION_POLICY);
    184     }
    185 
    186     /**
    187      * Called when a ringtone is chosen.
    188      * <p>
    189      * By default, this saves the ringtone URI to the persistent storage as a
    190      * string.
    191      *
    192      * @param ringtoneUri The chosen ringtone's {@link Uri}. Can be null.
    193      */
    194     protected void onSaveRingtone(Uri ringtoneUri) {
    195         persistString(ringtoneUri != null ? ringtoneUri.toString() : "");
    196     }
    197 
    198     /**
    199      * Called when the chooser is about to be shown and the current ringtone
    200      * should be marked. Can return null to not mark any ringtone.
    201      * <p>
    202      * By default, this restores the previous ringtone URI from the persistent
    203      * storage.
    204      *
    205      * @return The ringtone to be marked as the current ringtone.
    206      */
    207     protected Uri onRestoreRingtone() {
    208         final String uriString = getPersistedString(null);
    209         return !TextUtils.isEmpty(uriString) ? Uri.parse(uriString) : null;
    210     }
    211 
    212     @Override
    213     protected Object onGetDefaultValue(TypedArray a, int index) {
    214         return a.getString(index);
    215     }
    216 
    217     @Override
    218     protected void onSetInitialValue(boolean restorePersistedValue, Object defaultValueObj) {
    219         String defaultValue = (String) defaultValueObj;
    220 
    221         /*
    222          * This method is normally to make sure the internal state and UI
    223          * matches either the persisted value or the default value. Since we
    224          * don't show the current value in the UI (until the dialog is opened)
    225          * and we don't keep local state, if we are restoring the persisted
    226          * value we don't need to do anything.
    227          */
    228         if (restorePersistedValue) {
    229             return;
    230         }
    231 
    232         // If we are setting to the default value, we should persist it.
    233         if (!TextUtils.isEmpty(defaultValue)) {
    234             onSaveRingtone(Uri.parse(defaultValue));
    235         }
    236     }
    237 
    238     @Override
    239     protected void onAttachedToHierarchy(PreferenceManager preferenceManager) {
    240         super.onAttachedToHierarchy(preferenceManager);
    241 
    242         preferenceManager.registerOnActivityResultListener(this);
    243         mRequestCode = preferenceManager.getNextRequestCode();
    244     }
    245 
    246     public boolean onActivityResult(int requestCode, int resultCode, Intent data) {
    247 
    248         if (requestCode == mRequestCode) {
    249 
    250             if (data != null) {
    251                 Uri uri = data.getParcelableExtra(RingtoneManager.EXTRA_RINGTONE_PICKED_URI);
    252 
    253                 if (callChangeListener(uri != null ? uri.toString() : "")) {
    254                     onSaveRingtone(uri);
    255                 }
    256             }
    257 
    258             return true;
    259         }
    260 
    261         return false;
    262     }
    263 
    264 }
    265