0

I want my app to set a ringtone. The user has selected one from the existing library entries before using the system picker and gets this extra back: RingtoneManager.EXTRA_RINGTONE_PICKED_URI

In this example I have picked "Andromeda" from the default ringtones and get this path: content://media/internal/audio/media/103

When I try to set it at a given time I run this code:

Uri ur = Uri.parse(ringtoneFile.getAbsolutePath()); RingtoneManager.setActualDefaultRingtoneUri(context, ringtoneType, uri);

I have also tried this version:

Uri ur = Uri.parse(ringtoneFile.getAbsolutePath()); android.provider.Settings.System.putString(context.getContentResolver(), android.provider.Settings.System.RINGTONE, uri.toString());

Neither works. The system's sound settings will look like this:

[1]: https://i.stack.imgur.com/ZWj1H.png

Only 103 is shown, not "Andromeda" as I would expect. When I have the emulator called it just makes a ding sound, so it probably can't play the desired file and uses some fallback one.

There are plenty of examples here where people pick a custom file from the filesystem and add that to the library anew using "ContentValues". But I do not want to add anything myself, I just want to set one from the default ringtones.

As an alternative I have tried to code as well. It does add an additional entry to the library. Unfortunately old ones are not deleted, but pile up. Also I get the same ding sound when calling the emulator, not the one I selected.

private boolean applyRingTone(File ringtoneFile, int ringtoneType, Context context)
{
    Miscellaneous.logEvent("i", "Profile", "Request to set ringtone to " + ringtoneFile.getAbsolutePath(), 3);

    ContentValues values = new ContentValues();
    values.put(MediaStore.MediaColumns.DATA, ringtoneFile.getAbsolutePath());
    values.put(MediaStore.MediaColumns.TITLE, context.getResources().getString(R.string.app_name) + " ringtone");
    values.put(MediaStore.MediaColumns.MIME_TYPE, "audio/*");
    values.put(MediaStore.MediaColumns.SIZE, ringtoneFile.length());
    values.put(MediaStore.Audio.Media.ARTIST, R.string.app_name);
    values.put(MediaStore.Audio.Media.IS_RINGTONE, ringtoneType == RingtoneManager.TYPE_RINGTONE);
    values.put(MediaStore.Audio.Media.IS_NOTIFICATION, ringtoneType == RingtoneManager.TYPE_NOTIFICATION);
    values.put(MediaStore.Audio.Media.IS_ALARM, false);
    values.put(MediaStore.Audio.Media.IS_MUSIC, false);

    Uri ur = MediaStore.Audio.Media.getContentUriForPath(ringtoneFile.getAbsolutePath());
    context.getContentResolver().delete(ur, MediaStore.MediaColumns.DATA + "=\"" + ringtoneFile.getAbsolutePath() + "\"", null);
    Uri uri = context.getContentResolver().insert(ur, values);

    try
    {
        RingtoneManager.setActualDefaultRingtoneUri(context, ringtoneType, uri);
        Miscellaneous.logEvent("i", "Profile", "Ringtone set to: " + uri.toString(), 1);
        return true;
    }
    catch (Throwable t)
    {
        String message = "Error setting ringtone: " + Log.getStackTraceString(t);
        Miscellaneous.logEvent("e", "Profile", message, 1);
    }
    
    return false;
}
Jens
  • 1,157
  • 1
  • 8
  • 17

1 Answers1

0

I haven't quite solved my problem, yet, but at least spotted the culprit.

The way to set the file as ringtone does work. However the path of the source file is incorrect. That is pretty weird because it is determined by using a filepicker:

Intent fileIntent = new Intent(Intent.ACTION_GET_CONTENT);
fileIntent.setType("audio/*");
startActivityForResult(Intent.createChooser(fileIntent, "Select a ringtone"), intentCodeRingtonePickerCallsFile);

This returns as path:

content://com.android.externalstorage.documents/document/primary%3AMusic%2Fmusicfile.mp3

After converting it to a File object it'll become

/document/primary%3AMusic%2F04.%20Elevator%20Girl.mp3

When just hard-coding the path into the sourcecode (in a format a regular Linux user would assume it needs to have) it is actually simply:

/sdcard/Music/musicfile.mp3

And that works flawlessly. I'll have to figure out how to correctly determine the path, but the method to set a file as ringtone is functional.

UPDATE: I have an answer to my path problem: Get Real Path For Uri Android

Jens
  • 1,157
  • 1
  • 8
  • 17