【问题标题】:RingtonePreference fails to add new ringtones on android 8.1RingtonePreference 无法在 android 8.1 上添加新铃声
【发布时间】:2019-01-17 08:28:39
【问题描述】:

在 xml 文件中,我有以下代码。我可以通过单击 ringtonepref 屏幕中的广告铃声按钮来选择 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)

【问题讨论】:

标签: android android-preferences ringtonemanager


【解决方案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,或者自己保存文件。

【讨论】:

  • 谢谢。会试试这个。
【解决方案2】:

根据 android 文档,类型 7 是 TYPE_ALL,而不是 TYPE_RINGTONE。我认为您从“铃声”中选择了不同目录中的歌曲。 I didn't try but almost all ringtone selector applications are moving song file to that folder when custom ringtone is selected, maybe you can try.

【讨论】:

  • 是的,我希望用户使用任何声音文件作为铃声。我正在使用内置的 RingtonePreference,我猜它不会移动它。你建议建立我自己的 RingtonePreference 吗? .我不明白这个限制背后的原因。
  • 是的,你必须自己实现(重写onPreferenceTreeClick方法),然后在点击按钮时尝试移动歌曲文件,并给出新的路径来设置。
  • 搬到哪里?所有安卓手机的文件夹都一样吗?
  • 检查是否插入了sdcard,然后移动到外部存储器中的“铃声”文件夹,否则在内部。如果该文件夹不存在,请创建。我说,我不知道是不是和那个情况有关,因为我找不到问题的描述,你试试吧。
猜你喜欢
  • 2011-05-28
  • 2012-05-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-02
  • 1970-01-01
相关资源
最近更新 更多