Search code examples
androidmediastoreringtoneandroid-4.3-jelly-bean

How to set music files which are not in Media Store as ringtone


Before Jelly Bean level 18 I can use music files which are not in Media store (for example, a private .mp3 file in a folder contains .nomedia file, so Media Scanner does not scan this folder and does not know about this file) but from Android 4.3 (tested on Nexus 4) I can not do that, it only works for music files which are already scanned by Media Scanner.

The real reason of this problem is I cannot insert ContentValues with MediaColumns.DATA is a absolute path of a file not scanned by Media Scanner, insert method always return null.

Uri newUri = getCR().insert(uri, contentValues); // returns null in Android 4.3 

Does anyone have a workaround to use a private file (not scanned and not recognized by Media Scanner) as ringtone?

Here is how I set ringtone:

    File ringtoneFile = new File(audio.getPath());

    ContentValues cv = new ContentValues();
    cv.put(MediaColumns.DATA, ringtoneFile.getAbsolutePath());
    cv.put(MediaColumns.TITLE, audio.getTitle());

    cv.put(MediaColumns.MIME_TYPE, "audio/*");
    if (audio.getArtist() != null)
        cv.put(Media.ARTIST, audio.getArtist());

    cv.put(Media.IS_RINGTONE, true);
    cv.put(Media.IS_NOTIFICATION, false);
    cv.put(Media.IS_ALARM, false);
    cv.put(Media.IS_MUSIC, false);

    Uri uri = Media.getContentUriForPath(ringtoneFile.getAbsolutePath());
    Uri newUri = getCR().insert(uri, cv); ////return null in Android 4.3
    if (newUri == null)
    {
        Cursor c = getCR().query(uri, new String[] { Media._ID }, Media.DATA + "=?",
                new String[] { ringtoneFile.getAbsolutePath() }, null);
        long id = -1;
        if (c != null && c.moveToFirst())
        {
            id = c.getLong(c.getColumnIndex(Media._ID));
            newUri = Uri.parse(uri.toString() + "/" + id);
            c.close();
        }
    }       

    if (newUri != null)
    {
        RingtoneManager.setActualDefaultRingtoneUri(getAppContext(), RingtoneManager.TYPE_RINGTONE, newUri);            
    }       

Solution

  • This is my workaround:

    • Copy media file to Ringtones folder (Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_RINGTONES)), remember to create that folder if it does not exist.
    • Set that file as default ringtone using the same code in the question.