RingtonePreference在安卓8.1上无法添加新铃声。

4
在xml文件中,我有以下代码。当我在铃声设置屏幕上点击广告铃声按钮时,我能够选择mp3音频,但是当我这样做时,会出现以下异常。在更新到Android 8之前,这个功能是正常的。如何解决?
 <RingtonePreference


android:defaultValue="content://settings/system/notification_sound"
        android:key="ringtone_pref"
        android:ringtoneType="all"
        android:title="@string/hr_beep_tone_title"
        android:summary="@string/hr_beep_tone_summary"/> 


 01-17 00:21:15.785 15503-16432/? E/RingtonePickerActivity: Unable to add new ringtone
        java.lang.IllegalArgumentException: Unsupported ringtone type: 7
            at android.media.RingtoneManager.getExternalDirectoryForType(RingtoneManager.java:1088)
            at android.media.RingtoneManager.addCustomExternalRingtone(RingtoneManager.java:1056)
            at com.android.providers.media.RingtonePickerActivity$2.doInBackground(RingtonePickerActivity.java:281)
            at com.android.providers.media.RingtonePickerActivity$2.doInBackground(RingtonePickerActivity.java:278)
            at android.os.AsyncTask$2.call(AsyncTask.java:333)
            at java.util.concurrent.FutureTask.run(FutureTask.java:266)
            at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:245)
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
            at java.lang.Thread.run(Thread.java:764)

是的,我想能够将任何声音设置为铃声。 - user93796
RingtonePickerActivity 不是我的代码。它是 Android 内置的类。 - user93796
你有没有检查它 >> https://www.chupamobile.com/tutorial-android/android-beginner-tutorial-part-81-ringtonepreference-359 - Adil
2个回答

1
我已经翻译了您的请求:

我挖掘了android-27源代码,似乎addCustomExternalRingtone正在复制您选择的声音文件,但是给定的参数TYPE_ALL不允许确定要保存的目录。

addCustomExternalRingtone

   @WorkerThread
    public Uri addCustomExternalRingtone(@NonNull final Uri fileUri, final int type)
            throws FileNotFoundException, IllegalArgumentException, IOException {

        ...

        // Choose a directory to save the ringtone. Only one type of installation at a time is
        // allowed. Throws IllegalArgumentException if anything else is given.
        final String subdirectory = getExternalDirectoryForType(type);

        // Find a filename. Throws FileNotFoundException if none can be found.
        final File outFile = Utils.getUniqueExternalFile(mContext, subdirectory,
                Utils.getFileDisplayNameFromUri(mContext, fileUri), mimeType);

        // Copy contents to external ringtone storage. Throws IOException if the copy fails.
        try (final InputStream input = mContext.getContentResolver().openInputStream(fileUri);
                final OutputStream output = new FileOutputStream(outFile)) {
            Streams.copy(input, output);
        }

        // Tell MediaScanner about the new file. Wait for it to assign a {@link Uri}.
        try (NewRingtoneScanner scanner =  new NewRingtoneScanner(outFile)) {
            return scanner.take();
        } catch (InterruptedException e) {
            throw new IOException("Audio file failed to scan as a ringtone", e);
        }
    }

getExternalDirectoryForType 是出错的位置。

    private static final String getExternalDirectoryForType(final int type) {
        switch (type) {
            case TYPE_RINGTONE:
                return Environment.DIRECTORY_RINGTONES;
            case TYPE_NOTIFICATION:
                return Environment.DIRECTORY_NOTIFICATIONS;
            case TYPE_ALARM:
                return Environment.DIRECTORY_ALARMS;
            default:
                throw new IllegalArgumentException("Unsupported ringtone type: " + type);
        }
    }

问题在于 RingtonePickerActivity 无法决定选择哪种类型进行保存,最终会给出 TYPE_ALL。
看起来你应该重写文件选择点,并将 uri 和 type 传递给 RingtoneManager.addCustomExternalRingtone,或者自己保存文件。

谢谢。我会试一下。 - user93796

0
根据安卓文档,类型7是TYPE_ALL,而不是TYPE_RINGTONE。我认为你从“铃声”以外的不同目录中选择了歌曲。我没有尝试过,但几乎所有的铃声选择器应用程序在选择自定义铃声时都会将歌曲文件移动到那个文件夹中,也许你可以试试。

是的,我希望用户可以使用任何声音文件作为铃声。我正在使用内置的RingtonePreference,但我猜它不能移动。您建议我构建自己的RingtonePreference吗?我不理解这种限制背后的原因。 - user93796
是的,您必须实现自己的方法(覆盖onPreferenceTreeClick方法),然后尝试在按钮被点击时移动歌曲文件,并将新路径提供给set方法。 - C. Soylu
移动到哪里?所有安卓手机的文件夹都一样吗? - user93796
检查是否插入SD卡,然后移动到外部存储器中的“铃声”文件夹,否则移动到内部存储器。如果该文件夹不存在,则创建。我说过,我不知道这是否与该问题有关,因为我找不到任何描述该问题的说明,只能尝试。 - C. Soylu

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接