我在我的/ raw文件夹中有声音,我希望我的用户能够在首选项中选择一个完全像RingtonePreference一样的声音,但仅限于我的声音。在喜好中,选择我的声音就像使用RingtonePreference
回答
因此,最后我查看了ListPreference的源代码,并对一些修改做了相同的修改。正如我不能使用com.android.internal.R.styleable.ListPreference我曾在attrs.xml创建自己的设置样式:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="ListPreference">
<attr name="entries" format="string"></attr>
<attr name="entryValues" format="string"></attr>
</declare-styleable>
<declare-styleable name="Preference">
<attr name="summary" format="string"></attr>
</declare-styleable>
</resources>
,然后导入它在像这样我的preferences.xml文件:
xmlns:foo="http://schemas.android.com/apk/res/com.abe.abemoto"
,并使用它:
<com.abe.abemoto.preference.CustomSoundListPreference
android:defaultValue="@string/pref_alert_ring_value_1"
android:key="@string/pref_alert_sound_choice_for_notif_key"
android:title="Sonnerie de notification"
foo:entries="@array/pref_alert_ring_entries"
foo:entryValues="@array/pref_alert_ring_values"
foo:summary="Choisissez la sonnerie pour les notifications" />
在我的课CustomSoundListPreference我修改onPrepareDialogBuilder玩我的声音就项目点击方法。
@Override
protected void onPrepareDialogBuilder(Builder builder) {
super.onPrepareDialogBuilder(builder);
mMediaPlayer = new MediaPlayer();
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();
Resources res = getContext().getResources();
int resId = res.getIdentifier(value, "raw",
getContext().getPackageName());
Uri uri = Uri.parse(String.format(getContext()
.getString(R.string.resource_sound),
getContext().getPackageName(), resId));
Log.d(TAG, "uri sound = " + uri);
try {
mMediaPlayer.reset();
mMediaPlayer.setDataSource(getContext(), uri);
mMediaPlayer.prepare();
mMediaPlayer.start();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
});
builder.setPositiveButton("Ok", this);
builder.setNegativeButton("Annuler", this);
}
下面是一个自定义ListPreference就像铃声偏好的完整代码:
import java.io.IOException;
import android.app.AlertDialog.Builder;
import android.content.Context;
import android.content.DialogInterface;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.database.Cursor;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Parcel;
import android.os.Parcelable;
import android.preference.ListPreference;
import android.provider.MediaStore;
import android.util.AttributeSet;
import android.util.Log;
public class CustomListPreference extends ListPreference{
private MediaPlayer mMediaPlayer;
private Context mContext;
CharSequence[] mEntries;
CharSequence[] mEntryValues;
private int mClickedDialogEntryIndex;
private String mValue;
public CustomListPreference(Context context) {
super(context);
mContext = 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();
String path = findPathFromName(value);
try {
playSong(path);
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
});
builder.setPositiveButton("Ok", this);
builder.setNegativeButton("Cancel", 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();
}
public String findPathFromName(String name) {
Cursor mCursor = getContext().getContentResolver().query(
MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, null,
MediaStore.Audio.Media.TITLE + "='" + name + "'", null, null);
String path = "";
if(mCursor.moveToFirst()){
path = mCursor.getString(mCursor.getColumnIndex(MediaStore.Audio.Media.DATA));
}
mCursor.close();
mCursor = null;
return path;
}
@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);
}
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;
}
}
希望这会有所帮助的人。
感谢这篇文章!奇妙地工作!救了我的时间:) – 2013-04-04 09:16:44
在这里我的RingtonePreference替换。 所有系统铃声和自定义铃声(定义在XML中,存储在RES/RAW)列:
ExtraRingtonePreference.java
package de.almisoft.test;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.TreeMap;
import de.almisoft.test.R;
import android.app.AlertDialog.Builder;
import android.content.Context;
import android.content.DialogInterface;
import android.content.res.TypedArray;
import android.database.Cursor;
import android.media.Ringtone;
import android.media.RingtoneManager;
import android.net.Uri;
import android.preference.DialogPreference;
import android.util.AttributeSet;
public class ExtraRingtonePreference extends DialogPreference {
private Context mContext;
private String mValue;
private Ringtone ringtone;
private int mRingtoneType;
private boolean mShowSilent;
private boolean mShowDefault;
private CharSequence[] mExtraRingtones;
private CharSequence[] mExtraRingtoneTitles;
public ExtraRingtonePreference(Context context, AttributeSet attrs) {
super(context, attrs);
mContext = context;
final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.ExtraRingtonePreference, 0, 0);
mRingtoneType = a.getInt(R.styleable.ExtraRingtonePreference_ringtoneType, RingtoneManager.TYPE_RINGTONE);
mShowDefault = a.getBoolean(R.styleable.ExtraRingtonePreference_showDefault, true);
mShowSilent = a.getBoolean(R.styleable.ExtraRingtonePreference_showSilent, true);
mExtraRingtones = a.getTextArray(R.styleable.ExtraRingtonePreference_extraRingtones);
mExtraRingtoneTitles = a.getTextArray(R.styleable.ExtraRingtonePreference_extraRingtoneTitles);
a.recycle();
}
public ExtraRingtonePreference(Context context) {
this(context, null);
}
public String getValue() {
return mValue;
}
private Map<String, Uri> getSounds(int type) {
RingtoneManager ringtoneManager = new RingtoneManager(mContext);
ringtoneManager.setType(type);
Cursor cursor = ringtoneManager.getCursor();
Map<String, Uri> list = new TreeMap<String, Uri>();
while (cursor.moveToNext()) {
String notificationTitle = cursor.getString(RingtoneManager.TITLE_COLUMN_INDEX);
Uri notificationUri = ringtoneManager.getRingtoneUri(cursor.getPosition());
list.put(notificationTitle, notificationUri);
}
return list;
}
private Uri uriFromRaw(String name) {
int resId = mContext.getResources().getIdentifier(name, "raw", mContext.getPackageName());
return Uri.parse("android.resource://" + mContext.getPackageName() + "/" + resId);
}
private String getExtraRingtoneTitle(CharSequence name) {
if (mExtraRingtones != null && mExtraRingtoneTitles != null) {
int index = Arrays.asList(mExtraRingtones).indexOf(name);
return mExtraRingtoneTitles[index].toString();
}
return null;
}
@Override
public CharSequence getSummary() {
String ringtoneTitle = null;
if (mValue != null) {
if (mValue.length() == 0)
ringtoneTitle = mContext.getString(R.string.silent);
if (ringtoneTitle == null && mExtraRingtones != null && mExtraRingtoneTitles != null) {
for (int i = 0; i < mExtraRingtones.length; i++) {
Uri uriExtra = uriFromRaw(mExtraRingtones[i].toString());
if (uriExtra.equals(Uri.parse(mValue))) {
ringtoneTitle = mExtraRingtoneTitles[i].toString();
break;
}
}
}
if (ringtoneTitle == null) {
Ringtone ringtone = RingtoneManager.getRingtone(mContext, Uri.parse(mValue));
String title = ringtone.getTitle(mContext);
if (title != null && title.length() > 0)
ringtoneTitle = title;
}
}
CharSequence summary = super.getSummary();
if (ringtoneTitle != null) {
if (summary != null)
return String.format(summary.toString(), ringtoneTitle);
else
return ringtoneTitle;
} else return summary;
}
@Override
protected void onPrepareDialogBuilder(Builder builder) {
final Map<String, Uri> sounds = new LinkedHashMap<String, Uri>();
if (mExtraRingtones != null) {
for (CharSequence extraRingtone : mExtraRingtones) {
Uri uri = uriFromRaw(extraRingtone.toString());
String title = getExtraRingtoneTitle(extraRingtone);
sounds.put(title, uri);
}
}
if (mShowDefault) {
Uri uriDefault = RingtoneManager.getDefaultUri(mRingtoneType);
if (uriDefault != null) {
Ringtone ringtoneDefault = RingtoneManager.getRingtone(mContext, uriDefault);
if (ringtoneDefault != null) {
sounds.put(ringtoneDefault.getTitle(mContext), uriDefault);
}
}
}
if (mShowSilent)
sounds.put(mContext.getString(R.string.silent), Uri.parse(""));
sounds.putAll(getSounds(RingtoneManager.TYPE_NOTIFICATION));
final String[] titleArray = sounds.keySet().toArray(new String[0]);
final Uri[] uriArray = sounds.values().toArray(new Uri[0]);
int index = mValue != null ? Arrays.asList(uriArray).indexOf(Uri.parse(mValue)) : -1;
builder.setSingleChoiceItems(titleArray, index, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
if (ringtone != null)
ringtone.stop();
String title = titleArray[which];
Uri uri = uriArray[which];
if (uri != null) {
if (uri.toString().length() > 0) {
ringtone = RingtoneManager.getRingtone(mContext, uri);
ringtone.play();
}
mValue = uri.toString();
} else mValue = null;
}
});
builder.setPositiveButton(R.string.ok, this);
builder.setNegativeButton(R.string.cancel, this);
}
@Override
protected void onDialogClosed(boolean positiveResult) {
super.onDialogClosed(positiveResult);
if (ringtone != null)
ringtone.stop();
if (positiveResult && callChangeListener(mValue)) {
persistString(mValue);
notifyChanged();
}
}
@Override
protected Object onGetDefaultValue(TypedArray a, int index) {
return a.getString(index);
}
@Override
protected void onSetInitialValue(boolean restoreValue, Object defaultValue) {
if (restoreValue)
mValue = getPersistedString("");
else {
if (mExtraRingtones != null && defaultValue != null && defaultValue.toString().length() > 0) {
int index = Arrays.asList(mExtraRingtones).indexOf((CharSequence) defaultValue);
if (index >= 0)
mValue = uriFromRaw(defaultValue.toString()).toString();
else mValue = (String) defaultValue;
} else mValue = (String) defaultValue;
persistString(mValue);
}
}
}
RES /价值/ attrs.xml
<?xml version="1.0" encoding="UTF-8"?>
<resources>
<declare-styleable name="ExtraRingtonePreference">
<attr name="ringtoneType">
<!-- Ringtones. -->
<flag name="ringtone" value="1" />
<!-- Notification sounds. -->
<flag name="notification" value="2" />
<!-- Alarm sounds. -->
<flag name="alarm" value="4" />
<!-- All available ringtone sounds. -->
<flag name="all" value="7" />
</attr>
<attr name="showSilent" format="boolean"/>
<attr name="showDefault" format="boolean"/>
<attr name="extraRingtones" format="reference"/>
<attr name="extraRingtoneTitles" format="reference"/>
</declare-styleable>
</resources>
res/values/strings.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="silent">Silent</string>
<string name="ok">OK</string>
<string name="cancel">Cancel</string>
<string name="ringtoneTitle">Ringtone</string>
<string name="ringtoneSummary">Ringtone: %s</string>
<string-array name="extraRingtones">
<item>deichkind_sone_musik</item>
<item>madonna_like_a_virgin</item>
</string-array>
<string-array name="extraRingtoneTitles">
<item>Sone Musik</item>
<item>Like A Virgin</item>
</string-array>
</resources>
RES /生
res
↳ raw
↳ deichkind_sone_musik.mp3
↳ madonna_like_a_virgin.mp3
RES/XML /的preferences.xml
制作铃声的偏好定制我喜欢的铃声,只能短距离,而玩的时候<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:auto="http://schemas.android.com/apk/res-auto">
<de.almisoft.test.ExtraRingtonePreference
android:key="ringtone"
android:title="@string/ringtoneTitle"
android:summary="@string/ringtoneSummary"
android:defaultValue="deichkind_sone_musik"
auto:ringtoneType="notification"
auto:showSilent="true"
auto:showDefault="true"
auto:extraRingtones="@array/extraRingtones"
auto:extraRingtoneTitles="@array/extraRingtoneTitles"/>
<!-- set android:defaultValue
to "deichkind_sone_musik" for your custom mp3
to "" for silent
to "content://settings/system/notification_sound" for system default ringtone -->
</PreferenceScreen>
作品几乎开箱,只是有点修复:删除uriFromRaw(context参数),并使用mContext 此外,作为一个功能要求,这将是很好的显示选择的铃声的名字偏好的二号线(介绍),这样用户就可以看到选择的铃声,而不需要输入完成弹出 – Gavriel 2015-06-24 07:17:28
!从uriFromRaw()中删除了上下文参数,add getSummary():-) – almisoft 2015-06-24 12:08:18
谢谢!它很快!它可以在手动将铃声手动更改为我选择的任何内容后生效。之后,即使只显示首选项屏幕,也会显示摘要。但是在我第一次设置铃声时,摘要是空的。我想,没关系,但可以在xml中添加默认值(或者以某种方式)?例如auto:defaultValue =“@ + id/madonna_like_a_virgin”,auto:defaultValue =“”(用于系统默认铃声)或auto:defaultValue =“null”(用于静音) – Gavriel 2015-06-24 14:04:18
,有点像样品的声音。如果用户只是从列表中选择声音,用户不需要听到整个声音播放。这是我如何做到这一点:
首先创建一个服务,将播放铃声(以及使用的铃声管理器来播放声音,而不是媒体播放器作为其处理为我们取消):
公共类PlayRingtoneService扩展服务{ static铃声r; 私人处理程序处理程序;
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
//activating alarm sound
if (r != null)
r.stop();
String filePath = intent.getStringExtra("uri");
r = RingtoneManager.getRingtone(this, Uri.parse(filePath));
r.play();
handler.removeCallbacksAndMessages(null);
handler.postDelayed(new Runnable() {
@Override
public void run() {
if(r!=null)
r.stop();
}
},6000L); //stop sound in 6 seconds
return super.onStartCommand(intent, flags, startId);
}
void setThreadPriority(int priority) {
try {
Process.setThreadPriority(priority);
} catch (Exception e) {
Timber.e(e);
}
}
@Override
public void onCreate() {
super.onCreate();
handler =new Handler();
setThreadPriority(Process.THREAD_PRIORITY_URGENT_AUDIO);
}
@Override
public void onDestroy() {
if (r != null)
r.stop();
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
}
也更新清单与服务:
<service android:name=".services.PlayRingtoneService" />
然后使用上面的解决方案,但修改后,你可以创建一个列表的偏好,其行为就像一个铃声偏好:
public class CustomRingtoneListPreference extends ListPreference {
CharSequence[] mEntries;
CharSequence[] mEntryValues;
private int mClickedDialogEntryIndex;
private String mValue;
public CustomRingtoneListPreference(Context context) {
super(context);
}
public CustomRingtoneListPreference(Context context, AttributeSet attrs) {
super(context, attrs);
}
/**
* 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;
}
/**
* 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);
}
/**
* 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);
}
/**
* 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());
}
}
@Override
protected void onPrepareDialogBuilder(AlertDialog.Builder builder) {
super.onPrepareDialogBuilder(builder);
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();
playSong(value);
}
});
builder.setPositiveButton("Ok", this);
builder.setNegativeButton("Cancel", this);
}
private void playSong(String path) {
Intent i = new Intent(getContext(), PlayRingtoneService.class);
i.putExtra("uri", path);
getContext().startService(i);
}
@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);
}
@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);
}
}
Intent i = new Intent(getContext(), PlayRingtoneService.class);
getContext().stopService(i);
}
@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;
}
private static class SavedState extends BaseSavedState {
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];
}
};
String value;
public SavedState(Parcel source) {
super(source);
value = source.readString();
}
public SavedState(Parcelable superState) {
super(superState);
}
@Override
public void writeToParcel(Parcel dest, int flags) {
super.writeToParcel(dest, flags);
dest.writeString(value);
}
}
}
现在在你的XML使用这样的:
<mypackage.blah.blah.CustomRingtoneListPreference
android:key="myRingtone"
android:title="my title"
android:summary="ringtone chosen %s"
android:defaultValue="0"
android:dependency="whatever you have"
/>
现值,以实际加载到我们创建了一个utils的方法,可以让所有内部和外部媒体,放入我们的模型类叫做歌曲列表这样定义的:
public class Song {
private long id;
private Uri filePath;
private boolean externalPath;
/**
* Creates a new Song, with specified `songID` and `filePath`.
*
* @note It's a unique Android identifier for a media file
* anywhere on the system.
*/
public Song(long id, String title, String artist, Uri fileUri, boolean externalPath) {
this.id = id;
this.title = title;
this.artist = artist;
this.filePath = fileUri;
this.externalPath = externalPath;
}
/**
* Identifier for the song on the Android system.
* (so we can locate the file anywhere)
*/
public long getId() {
return id;
}
public Uri getFilePath() {
return filePath;
}
public Song setFilePath(Uri filePath) {
this.filePath = filePath;
return this;
}
private String title = "";
private String artist = "";
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getArtist() {
return artist;
}
public void setArtist(String artist) {
this.artist = artist;
}
public boolean isExternalPath() {
return externalPath;
}
public Song setIsExternalPath(boolean externalPath) {
this.externalPath = externalPath;
return this;
}
}
现在,在您的Util类或只是如果你想这样做使这个类,将查询介质存储用于所有音频文件的静态方法:
个公共静态列表getAllExternalAudioSongs(上下文C){ 列表的SongList =新的ArrayList <>(); ContentResolver contentResolver = c.getContentResolver();
List<Uri> contentUriLists = new ArrayList<>();
contentUriLists.add(MediaStore.Audio.Media.INTERNAL_CONTENT_URI);
contentUriLists.add(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI);
String selection= MediaStore.Audio.Media.DURATION + ">= 3000";
boolean externalPath = false;
for (Uri uri : contentUriLists) {
Cursor cursor = contentResolver.query(uri, null, selection, null, android.provider.MediaStore.Audio.Media.TITLE+ " ASC");
if (cursor == null) {
// query failed, handle error.
} else if (!cursor.moveToFirst()) {
// no media on the device
} else {
int titleColumn = cursor.getColumnIndex(android.provider.MediaStore.Audio.Media.TITLE);
int idColumn = cursor.getColumnIndex(android.provider.MediaStore.Audio.Media._ID);
int artistColumn = cursor.getColumnIndex(MediaStore.Audio.Media.ARTIST);
do {
long id = cursor.getLong(idColumn);
String title = cursor.getString(titleColumn);
String artist = cursor.getString(artistColumn);
Uri contentUri = ContentUris.withAppendedId(
uri, id);
Song song = new Song(id, title, artist, contentUri, externalPath);
songList.add(song);
} while (cursor.moveToNext());
externalPath=true;
}
}
return songList;
}
注意:externalPath只是如果你想区分内部和外部的音频文件。
最后,在preferenceActivity(或片段)的onCreate,你可以这样做:
private void setRingtoneList() {
ListPreference listPreferenceCategory = (ListPreference) findPreference("myRingtone");
if (listPreferenceCategory != null) {
List<Song> songList = Utils.getAllExternalAudioSongs(getApplicationContext());
CharSequence entries[] = new String[songList.size()];
CharSequence entryValues[] = new String[songList.size()];
int i = 0;
for (Song song : songList) {
entries[i] = song.getTitle();
entryValues[i] = song.getFilePath().toString();
i++;
}
listPreferenceCategory.setEntries(entries);
listPreferenceCategory.setEntryValues(entryValues);
}
}
注意:您需要为外部存储运行权限。也更新总结,你必须在偏好活动中做到这一点,我相信。无论如何,这给了一个好主意,如何播放示例音频,而不是整个音频文件。
- 1. MySQL的选择就像
- 2. 在Java中选择用于播放声音的声卡
- 3. 在我的应用程序中选择用于推送通知的声音
- 4. 好的声音库?
- 5. 用actionscript选择MXML兄弟,就像javascript?
- 6. RingtonePreference和onActivityResult打得不好
- 7. 在Android中使用JAXBContext的好选择?
- 8. 在Sencha Touch 2中裁剪图像(选择区域)?就像Jcrop
- 9. 如何从D3js选择中的音频标签播放声音?
- 10. 如何选择声音设备播放声音?
- 11. 我有选择一个视频和音频文件,现在我想在加我选择的音频/声音我的视频
- 12. 让我喜欢的类型的工作就像一个列表
- 13. 更好的声音Twilio
- 14. 超长在何处/在声明中 - 更好的选择?
- 15. 在PyCharm中选择带有Ctrl/C的行就像Sublime Text
- 16. 选择声音文件+ iPhone SDK
- 17. iPhone UIPickerView不播放选择声音
- 18. MYSQL如果不喜欢,就像B
- 19. 我怎样才能邀请像声音应用程序的Facebook好友呢?
- 20. 从RingtonePreference获取铃声标题
- 21. 执行SQL喜欢选择在Java中
- 22. 使用系统声音播放声音
- 23. 全屏选择列表,如选择铃声或通知声音时
- 24. 的声音在我的应用程序
- 25. 如何使用PowerShell位置对象就像在声明
- 26. 如何使声音像whatsapp通知声音
- 27. RingtonePreference不保存在PreferenceActivity中
- 28. 在声音设置中禁用音量选项android
- 29. 如何计算MD5值,就好像您正在使用System.Security.Cryptography.MD5类
- 30. 设置位置,就好像不存在
嗨。 您可以发送或邮寄的全部源代码。 问候, 托尼 – toni 2012-11-09 09:20:00
请发表您的自定义列表偏好的全部代码。 – 2013-02-27 11:46:03