4

In xml file i have following code. I am able to select mp3 sound by clicking on ad ringtone button in ringtonepref screen, but when i do so i see following exception. This used to work before but after updating to android 8 its not working.

How can

 <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
  • 18,749
  • 31
  • 94
  • 150

2 Answers2

1

Digged android-27 source code, it seems that addCustomExternalRingtone is copying the sound file you choosed, but the given parameter TYPE_ALL is not allowed to determine the directory to save.

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);
        }
    }

And getExternalDirectoryForType, where error actually occurs.

    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);
        }
    }

The matter is that RingtonePickerActivity cannot decide which type to choose for saving, and finally give TYPE_ALL.

It seems that you should override the point of choosing file, and pass uri and type to RingtoneManager.addCustomExternalRingtone, or save file by yourself.

taka
  • 1,407
  • 5
  • 7
0

According to android documentation, type 7 is TYPE_ALL, not TYPE_RINGTONE. I think you selected the song from different directory out of "ringtones". 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.

C. Soylu
  • 44
  • 3
  • Yes, i want the user to use any sound file as ringtone. Am using inbuilt RingtonePreference, which doesnot move it i guess. Do u suggest building my own RingtonePreference? . I dont understand the reason behind this limitation. – user93796 Jan 19 '19 at 20:17
  • Yes, you have to implement your own (override the onPreferenceTreeClick method), then just try to move the song file when button is clicked, and give the new path to set. – C. Soylu Jan 19 '19 at 20:37
  • Move to where? Is the folder same for all android phones? – user93796 Jan 19 '19 at 20:54
  • Check if an sdcard inserted, then move to "ringtones" folder placed in external memory, otherwise internal. If the folder doesn't exist, create. I said, I don't know if it's related to that situation because I couldn't find any description for the problem, just try. – C. Soylu Jan 19 '19 at 21:07