如何在应用程序中添加自定义声音? Android Studio

问题描述 投票:-3回答:1

我正在学习几周的课程,我很绝望!我已经停止了这个问题:

我提出了一个选项,用户可以选择你想要的铃声消息通知,工作完美!但是,我想将我的铃声放在.mp3中,并将其设置为默认值。

我正在寻找几天,我仍然无法得到响应,.mp3我放在/ raw文件夹中

我将发送我拥有的代码,xml和Java。

pref_notification.xml

<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">

<!-- A 'parent' preference, which enables/disables child preferences (below)
     when checked/unchecked. -->
<SwitchPreference
    android:textColor="@color/colorAccent"
    android:defaultValue="true"
    android:key="notifications_new_message"
    android:title="@string/pref_title_new_message_notifications" />

<!-- Allows the user to choose a ringtone in the 'notify' category. -->
<!-- NOTE: This preference will be enabled only when the checkbox above is checked. -->
<!-- NOTE: RingtonePreference's summary should be set to its value by the activity code. -->
**<RingtonePreference**
    android:defaultValue="content://settings/system/notification_sound"
    android:dependency="notifications_new_message"
    android:key="notifications_new_message_ringtone"
    android:ringtoneType="notification"
    android:title="@string/pref_title_ringtone" />

<!-- NOTE: This preference will be enabled only when the checkbox above is checked. -->
<SwitchPreference
    android:defaultValue="false"
    android:dependency="notifications_new_message"
    android:key="notifications_new_message_vibrate"
    android:title="@string/pref_title_vibrate" />

ringtone preference.Java

public class RingtonePreference extends Preference implements
    PreferenceManager.OnActivityResultListener {

    private static final String TAG = "RingtonePreference";

    private int mRingtoneType;
    private boolean mShowDefault;
    private boolean mShowSilent;

    private int mRequestCode;

    public RingtonePreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);

        final TypedArray a = context.obtainStyledAttributes(attrs,
                com.android.internal.R.styleable.RingtonePreference, defStyleAttr, defStyleRes);
        mRingtoneType = a.getInt(com.android.internal.R.styleable.RingtonePreference_ringtoneType,
                RingtoneManager.TYPE_RINGTONE);
        mShowDefault = a.getBoolean(com.android.internal.R.styleable.RingtonePreference_showDefault,
                true);
        mShowSilent = a.getBoolean(com.android.internal.R.styleable.RingtonePreference_showSilent,
                true);
        a.recycle();
    }

    public RingtonePreference(Context context, AttributeSet attrs, int defStyleAttr) {
        this(context, attrs, defStyleAttr, 0);
    }

    public RingtonePreference(Context context, AttributeSet attrs) {
        this(context, attrs, com.android.internal.+R.);
    }

    public RingtonePreference(Context context) {
        this(context, null);
    }

    /**
     * Returns the sound type(s) that are shown in the picker.
     * 
     * @return The sound type(s) that are shown in the picker.
     * @see #setRingtoneType(int)
     */
    public int getRingtoneType() {
        return mRingtoneType;
    }

    /**
     * Sets the sound type(s) that are shown in the picker.
     * 
     * @param type The sound type(s) that are shown in the picker.
     * @see RingtoneManager#EXTRA_RINGTONE_TYPE
     */
    public void setRingtoneType(int type) {
        mRingtoneType = type;
    }

    /**
     * Returns whether to a show an item for the default sound/ringtone.
     * 
     * @return Whether to show an item for the default sound/ringtone.
     */
    public boolean getShowDefault() {
        return mShowDefault;
    }

    /**
     * Sets whether to show an item for the default sound/ringtone. The default
     * to use will be deduced from the sound type(s) being shown.
     * 
     * @param showDefault Whether to show the default or not.
     * @see RingtoneManager#EXTRA_RINGTONE_SHOW_DEFAULT
     */
    public void setShowDefault(boolean showDefault) {
        mShowDefault = showDefault;
    }

    /**
     * Returns whether to a show an item for 'Silent'.
     * 
     * @return Whether to show an item for 'Silent'.
     */
    public boolean getShowSilent() {
        return mShowSilent;
    }

    /**
     * Sets whether to show an item for 'Silent'.
     * 
     * @param showSilent Whether to show 'Silent'.
     * @see RingtoneManager#EXTRA_RINGTONE_SHOW_SILENT
     */
    public void setShowSilent(boolean showSilent) {
        mShowSilent = showSilent;
    }

    @Override
    protected void onClick() {
        // Launch the ringtone picker
        Intent intent = new Intent(RingtoneManager.ACTION_RINGTONE_PICKER);
        onPrepareRingtonePickerIntent(intent);
        PreferenceFragment owningFragment = getPreferenceManager().getFragment();
        if (owningFragment != null) {
            owningFragment.startActivityForResult(intent, mRequestCode);
        } else {
            getPreferenceManager().getActivity().startActivityForResult(intent, mRequestCode);
        }
    }

    /**
     * Prepares the intent to launch the ringtone picker. This can be modified
     * to adjust the parameters of the ringtone picker.
     * 
     * @param ringtonePickerIntent The ringtone picker intent that can be
     *            modified by putting extras.
     */
    protected void onPrepareRingtonePickerIntent(Intent ringtonePickerIntent) {
        ringtonePickerIntent.putExtra(RingtoneManager.EXTRA_RINGTONE_EXISTING_URI,
                onRestoreRingtone());

        ringtonePickerIntent.putExtra(RingtoneManager.EXTRA_RINGTONE_SHOW_DEFAULT, mShowDefault);
        if (mShowDefault) {
            ringtonePickerIntent.putExtra(RingtoneManager.EXTRA_RINGTONE_DEFAULT_URI,
                    RingtoneManager.getDefaultUri(getRingtoneType()));
        }

        ringtonePickerIntent.putExtra(RingtoneManager.EXTRA_RINGTONE_SHOW_SILENT, mShowSilent);
        ringtonePickerIntent.putExtra(RingtoneManager.EXTRA_RINGTONE_TYPE, mRingtoneType);
        ringtonePickerIntent.putExtra(RingtoneManager.EXTRA_RINGTONE_TITLE, getTitle());
        ringtonePickerIntent.putExtra(RingtoneManager.EXTRA_RINGTONE_AUDIO_ATTRIBUTES_FLAGS,
                AudioAttributes.FLAG_BYPASS_INTERRUPTION_POLICY);
    }

    /**
     * Called when a ringtone is chosen.
     * <p>
     * By default, this saves the ringtone URI to the persistent storage as a
     * string.
     * 
     * @param ringtoneUri The chosen ringtone's {@link Uri}. Can be null.
     */
    protected void onSaveRingtone(Uri ringtoneUri) {
        persistString(ringtoneUri != null ? ringtoneUri.toString() : "");
    }

    /**
     * Called when the chooser is about to be shown and the current ringtone
     * should be marked. Can return null to not mark any ringtone.
     * <p>
     * By default, this restores the previous ringtone URI from the persistent
     * storage.
     * 
     * @return The ringtone to be marked as the current ringtone.
     */
    protected Uri onRestoreRingtone() {
        final String uriString = getPersistedString(null);
        return !TextUtils.isEmpty(uriString) ? Uri.parse(uriString) : null;
    }

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

    @Override
    protected void onSetInitialValue(boolean restorePersistedValue, Object defaultValueObj) {
        String defaultValue = (String) defaultValueObj;

        /*
         * This method is normally to make sure the internal state and UI
         * matches either the persisted value or the default value. Since we
         * don't show the current value in the UI (until the dialog is opened)
         * and we don't keep local state, if we are restoring the persisted
         * value we don't need to do anything.
         */
        if (restorePersistedValue) {
            return;
        }

        // If we are setting to the default value, we should persist it.
        if (!TextUtils.isEmpty(defaultValue)) {
            onSaveRingtone(Uri.parse(defaultValue));
        }
    }

    @Override
    protected void onAttachedToHierarchy(PreferenceManager preferenceManager) {
        super.onAttachedToHierarchy(preferenceManager);

        preferenceManager.registerOnActivityResultListener(this);
        mRequestCode = preferenceManager.getNextRequestCode();
    }

    public boolean onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == mRequestCode) {
            if (data != null) {
                Uri uri = data.getParcelableExtra(RingtoneManager.EXTRA_RINGTONE_PICKED_URI);

                if (callChangeListener(uri != null ? uri.toString() : "")) {
                    onSaveRingtone(uri);
                }
            }

            return true;
        }

        return false;
    }

}
android
1个回答
0
投票

myNotificationNameInRawraw文件夹中音频文件的名称

    String name = "myNotificationNameInRaw";
    File file = new File(Environment.getExternalStorageDirectory(), "/myRingtonFolder/Audio/");
    if (!file.exists()) {
        file.mkdirs();
    }
    String path = Environment.getExternalStorageDirectory().getAbsolutePath() + "/myRingtonFolder/Audio/";
    File f = new File(path + "/", name + ".mp3");
    Uri mUri = Uri.parse("android.resource://" + context.getPackageName() + "/raw/" + name);
    ContentResolver mCr = context.getContentResolver();
    AssetFileDescriptor soundFile;
    try {
        soundFile = mCr.openAssetFileDescriptor(mUri, "r");
    } catch (FileNotFoundException e) {
        soundFile = null;
        e.printStackTrace();
    }
    try {
        byte[] readData = new byte[1024];
        FileInputStream fis = soundFile.createInputStream();
        FileOutputStream fos = new FileOutputStream(f);
        int i = fis.read(readData);

        while (i != -1) {
            fos.write(readData, 0, i);
            i = fis.read(readData);
        }
        fos.close();
    } catch (IOException io) {
        io.printStackTrace();
    }
    ContentValues values = new ContentValues();
    values.put(MediaStore.MediaColumns.DATA, f.getAbsolutePath());
    values.put(MediaStore.MediaColumns.TITLE, name);
    values.put(MediaStore.MediaColumns.MIME_TYPE, "audio/mp3");
    values.put(MediaStore.MediaColumns.SIZE, f.length());
    values.put(MediaStore.Audio.Media.ARTIST, R.string.app_name);
    values.put(MediaStore.Audio.Media.IS_RINGTONE, false);
    values.put(MediaStore.Audio.Media.IS_NOTIFICATION, true);
    values.put(MediaStore.Audio.Media.IS_ALARM, false);
    values.put(MediaStore.Audio.Media.IS_MUSIC, false);
    Uri uri = MediaStore.Audio.Media.getContentUriForPath(f.getAbsolutePath());
    Uri newUri = mCr.insert(uri, values);
    try {
        RingtoneManager.setActualDefaultRingtoneUri(context, RingtoneManager.TYPE_NOTIFICATION, newUri);
        Settings.System.putString(mCr, Settings.System.NOTIFICATION_SOUND, newUri.toString());
    } catch (Throwable t) {
        t.printStackTrace();
    }

还要确保添加权限

<uses-permission android:name="android.permission.WRITE_SETTINGS" ></uses-permission>
© www.soinside.com 2019 - 2024. All rights reserved.