RingtonePreference主题

时间:2013-05-16 13:58:16

标签: android android-preferences android-theme

我正在Holo.Light主题中创建一个Android应用程序。 除Ringtonepreference外,所有首选项都很简单!

我甚至尝试在Preferences.xml中设置BGColor和textColor:

<RingtonePreference
        android:icon="@drawable/ic_menu_note"
        android:key="ringtone"
        android:persistent="true"
        android:summary="@string/settings_ringtone2"            
        android:background="#000000"
        android:textColor="#ffffff"
        android:title="@string/settings_ringtone" />

Android无视一切......

有没有人知道如何将RingtonePreference的主题更改为Holo.Light?

2 个答案:

答案 0 :(得分:5)

我自己找到了答案,看起来似乎没有App可以触及Ringtonemanager的设置..

所以我做的是扩展Listpreference:

    package de.Psychologie.socialintelligence;

import java.io.IOException;

import android.app.AlertDialog.Builder;
import android.content.Context;
import android.content.DialogInterface;
import android.content.res.TypedArray;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.os.Parcel;
import android.os.Parcelable;
import android.preference.ListPreference;
import android.util.AttributeSet;

public class CustomRingtonepreference extends ListPreference{

private MediaPlayer mMediaPlayer;
CharSequence[] mEntries;
CharSequence[] mEntryValues;
private int mClickedDialogEntryIndex;
private String mValue;

public CustomRingtonepreference(Context context, AttributeSet attrs) {
    super(context, attrs);
}

public CustomRingtonepreference(Context context) {
    super(context);
}
/**
 * Sets the value of the key. This should be one of the entries in
 * {@link #getEntryValues()}.
 * 
 * @param value The value to set for the key.
 */
public void setValue(String value) {
    mValue = value;

    persistString(value);
}

/**
 * Sets the value to the given index from the entry values.
 * 
 * @param index The index of the value to set.
 */
public void setValueIndex(int index) {
    if (mEntryValues != null) {
        setValue(mEntryValues[index].toString());
    }
}

/**
 * Returns the value of the key. This should be one of the entries in
 * {@link #getEntryValues()}.
 * 
 * @return The value of the key.
 */
public String getValue() {
    return mValue; 
}

/**
 * Returns the entry corresponding to the current value.
 * 
 * @return The entry corresponding to the current value, or null.
 */
public CharSequence getEntry() {
    int index = getValueIndex();
    return index >= 0 && mEntries != null ? mEntries[index] : null;
}

 public int findIndexOfValue(String value) {
    if (value != null && mEntryValues != null) {
        for (int i = mEntryValues.length - 1; i >= 0; i--) {
            if (mEntryValues[i].equals(value)) {
                return i;
            }
        }
    }
    return -1;
}

private int  getValueIndex() {

    return findIndexOfValue(mValue);
}

@Override
protected void onPrepareDialogBuilder(Builder builder) {
    super.onPrepareDialogBuilder(builder);

    mMediaPlayer = new MediaPlayer();
    mEntries = getEntries();
    mEntryValues = getEntryValues();

    if (mEntries == null || mEntryValues == null) {
        throw new IllegalStateException(
                "ListPreference requires an entries array and an entryValues array.");
    }

    mClickedDialogEntryIndex = getValueIndex();
    builder.setSingleChoiceItems(mEntries, mClickedDialogEntryIndex,
            new DialogInterface.OnClickListener() {

                public void onClick(DialogInterface dialog, int which) {
                    mClickedDialogEntryIndex = which;

                    String value = mEntryValues[which].toString();
                    try {
                        playSong(value);
                    } catch (IllegalStateException e) {
                        e.printStackTrace();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            });

    builder.setPositiveButton("OK", this);
    builder.setNegativeButton("Abbrechen", this);
}

private void playSong(String path) throws IllegalArgumentException,
    IllegalStateException, IOException {

    //Log.d("ringtone", "playSong :: " + path);

    mMediaPlayer.reset();
    mMediaPlayer.setDataSource(path);
    mMediaPlayer.setAudioStreamType(AudioManager.STREAM_RING);
//  mMediaPlayer.setLooping(true);
    mMediaPlayer.prepare();
    mMediaPlayer.start();
}

@Override
protected void onRestoreInstanceState(Parcelable state) {
    if (state == null || !state.getClass().equals(SavedState.class)) {
        // Didn't save state for us in onSaveInstanceState
        super.onRestoreInstanceState(state);
        return;
    }

    SavedState myState = (SavedState) state;
    super.onRestoreInstanceState(myState.getSuperState());
    setValue(myState.value);
}

private static class SavedState extends BaseSavedState {
    String value;

    public SavedState(Parcel source) {
        super(source);
        value = source.readString();
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        super.writeToParcel(dest, flags);
        dest.writeString(value);
    }

    public SavedState(Parcelable superState) {
        super(superState);
    }

    @SuppressWarnings("unused")
    public static final Parcelable.Creator<SavedState> CREATOR =
            new Parcelable.Creator<SavedState>() {
        public SavedState createFromParcel(Parcel in) {
            return new SavedState(in);
        }

        public SavedState[] newArray(int size) {
            return new SavedState[size];
        }
    };
}

 @Override
protected void onDialogClosed(boolean positiveResult) {
    super.onDialogClosed(positiveResult);

    if (positiveResult && mClickedDialogEntryIndex >= 0 && mEntryValues != null) {
        String value = mEntryValues[mClickedDialogEntryIndex].toString();
        if (callChangeListener(value)) {
            setValue(value);
        }
    }

    mMediaPlayer.stop();
    mMediaPlayer.release();
}

@Override
protected Object onGetDefaultValue(TypedArray a, int index) {
    return a.getString(index);
}

@Override
protected void onSetInitialValue(boolean restoreValue, Object defaultValue) {
    setValue(restoreValue ? getPersistedString(mValue) : (String) defaultValue);
}

@Override
protected Parcelable onSaveInstanceState() {
    final Parcelable superState = super.onSaveInstanceState();
    if (isPersistent()) {
        // No need to save instance state since it's persistent
        return superState;
    }

    final SavedState myState = new SavedState(superState);
    myState.value = getValue();
    return myState;
}
}

并且我添加了值我选择了Programmatical方式:

//Import All Ringtones
    RingtoneManager rm = new RingtoneManager(UserSettingActivity.this);
    rm.setType(RingtoneManager.TYPE_ALARM|RingtoneManager.TYPE_RINGTONE );
    final Cursor ringtones = rm.getCursor();

    List<String> mEntries = new ArrayList<String>();
    List<String> mEntryValues = new ArrayList<String>();

    for (ringtones.moveToFirst(); !ringtones.isAfterLast(); ringtones.moveToNext()) {
        mEntries.add(ringtones.getString(RingtoneManager.TITLE_COLUMN_INDEX));
        mEntryValues.add(ringtones.getString(RingtoneManager.URI_COLUMN_INDEX));
    }
    ringtonepref.setEntryValues(mEntryValues.toArray(new CharSequence[mEntryValues.size()]));
    ringtonepref.setEntries(mEntries.toArray(new CharSequence[mEntries.size()]));

对于使用默认铃声的初始启动:

//Sets the default Alarm to the chosen Value
            ringtonepref.setValue(RingtoneManager.getActualDefaultRingtoneUri(getBaseContext(), RingtoneManager.TYPE_ALARM).toString());

我希望它可以帮到某人;)

答案 1 :(得分:1)

嗯,花了半个晚上才能让它运转起来,我得到了一个合适的解决方案。我接受了Trinitrotoluol在这里写的建议,并将其与我自己的功能合并。这是我的CustomListPreference(完整,没有丢失步骤)......

import android.app.AlertDialog.Builder;
import android.content.Context;
import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.media.MediaPlayer;
import android.media.RingtoneManager;
import android.net.Uri;
import android.preference.ListPreference;
import android.preference.PreferenceManager;
import android.provider.MediaStore;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.widget.RadioButton;

import java.util.ArrayList;
import java.util.List;

public class CustomListPreference extends ListPreference {

    /* Konstante */
    private final String TAG = ((Object) this).getClass().getSimpleName();

    Context mContext;
    LayoutInflater mInflater;
    ArrayList<RadioButton> mButtonList;

    private MediaPlayer mMediaPlayer;
    CharSequence[] mEntries;
    CharSequence[] mEntryValues;
    private int mActivePositionInList;
    private int mTmpActivePositionInList;
    private String mValue;
    private String mPath;
    private String mTmpPath;


    public CustomListPreference(Context context, AttributeSet attrs) {
        super(context, attrs);
        mContext = context;
        mInflater = LayoutInflater.from(context);
        mButtonList = new ArrayList<RadioButton>();
        Log.d(TAG, "Konstruktor");

        // Manager für Benachrichtigungstöne
        RingtoneManager ringtoneManager = new RingtoneManager(context);
        ringtoneManager.setType(RingtoneManager.TYPE_NOTIFICATION);

        final Cursor ringtones = ringtoneManager.getCursor();

        List<String> entries = new ArrayList<String>();
        List<String> entryValues = new ArrayList<String>();

        loadData();

        // keine Töne (disabled notification / "warnings")
        entries.add("Keine");
        entryValues.add("NONE");


        for (ringtones.moveToFirst(); !ringtones.isAfterLast(); ringtones.moveToNext()) {

            // Anzeige (displays data to screen)
            entries.add(ringtones.getString(RingtoneManager.TITLE_COLUMN_INDEX));

            // ID beziehen (getting the ID to add it at the end of the path)
            int id = ringtones.getInt(ringtones.getColumnIndex(MediaStore.MediaColumns._ID));

            // ID ans Ende anfügen (attach ID to the end of the path)
            entryValues.add(ringtones.getString(RingtoneManager.URI_COLUMN_INDEX) + "/" + id);

            Log.d(TAG, "Tone: " + ringtones.getString(RingtoneManager.URI_COLUMN_INDEX) + "/" + id);
        }

        setEntryValues(entryValues.toArray(new CharSequence[entryValues.size()]));
        setEntries(entries.toArray(new CharSequence[entries.size()]));

    }


    public CustomListPreference(Context context) {
        super(context);
    }


    public void loadData() {

        SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext());
        SharedPreferences.Editor edit = sp.edit();

        if (sp.contains("audio_path")) {
            mTmpPath = mPath = sp.getString("audio_path", "NONE");
        } else {
            edit.putString("audio_path", mPath);
            edit.commit();
        }



        if (sp.contains("audio_id")) {
            mTmpActivePositionInList = mActivePositionInList = sp.getInt("audio_id", 0);
        } else {
            edit.putInt("audio_id", 0);
            edit.commit();
        }
    }


    public void setValue(String audioPath, int cursorPosition) {

        SharedPreferences sp = getPreferenceManager()
                .getDefaultSharedPreferences(getContext());

        SharedPreferences.Editor edit = sp.edit();

        edit.putString("audio_path", audioPath);
        edit.putInt("audio_id", cursorPosition);

        edit.commit();
    }


    public void setOldValues() {

        SharedPreferences sp = getPreferenceManager()
                .getDefaultSharedPreferences(getContext());

        SharedPreferences.Editor edit = sp.edit();

        edit.putString("audio_path", mTmpPath);
        edit.putInt("audio_id", mTmpActivePositionInList);

        edit.commit();
    }


    public void setValueIndex(int index) {
        if (mEntryValues != null) {
            setValue(mEntryValues[index].toString());
        }
    }


    public String getValue() {
        return mValue;
    }


    public CharSequence getEntry() {
        int index = getValueIndex();
        return index >= 0 && mEntries != null ? mEntries[index] : null;
    }


    public int findIndexOfValue(String value) {
        if (value != null && mEntryValues != null) {
            for (int i = mEntryValues.length - 1; i >= 0; i--) {
                if (mEntryValues[i].equals(value)) {
                    return i;
                }
            }
        }
        return -1;
    }


    private int getValueIndex() {
        return findIndexOfValue(mValue);
    }


    @Override
    protected void onPrepareDialogBuilder(Builder builder) {
        super.onPrepareDialogBuilder(builder);

        mMediaPlayer = new MediaPlayer();
        mEntries = getEntries();
        mEntryValues = getEntryValues();

        if (mEntries == null || mEntryValues == null) {
            throw new IllegalStateException(
                    "ListPreference requires an entries array and an entryValues array.");
        }


        builder.setSingleChoiceItems(mEntries, mActivePositionInList,
                new DialogInterface.OnClickListener() {

                    public void onClick(DialogInterface dialog, int which) {
                        mActivePositionInList = which;

                        String path = mEntryValues[which].toString();
                        try {
                            RingtoneManager.getRingtone(getContext(), Uri.parse(path)).play();
                            mPath = path;
                        } catch (Exception e) {
                            Log.e(TAG, "Fehler beim Abspielen (Error) : " + e);
                        }
                    }
                });

        builder.setPositiveButton("OK", this);
        builder.setNegativeButton("Abbrechen", this);

    }


    @Override
    protected void onDialogClosed(boolean positiveResult) {
        super.onDialogClosed(positiveResult);
        if (positiveResult) {
            Log.d(TAG, "pos");
            setValue(mPath, mActivePositionInList);
        }
        if (!positiveResult) {
            Log.d(TAG, "neg");
            mPath = mTmpPath;
            mActivePositionInList = mTmpActivePositionInList;
            setOldValues();
        }
    }

}

要在屏幕前方将其正确显示,您可以将此代码段添加到prefs.xml

 <de.yourpackage.right.activities.CustomListPreference
            android:dialogTitle="Some text"
            android:summary="some text too"
            android:title="and more text"
            />

最后,我很高兴让它现在正常运作..

PS:如果您有疑问,请随时提出。