19

I have save file in sdcard/media/audio/ringtones folder. That file will appear in list of ringtone selection from settings/sound/phone Ringtone.

But I want to set that file as a ringtone from my code. Here is my code.

  File k = new File(path, filename);

  ContentValues values = new ContentValues();
  values.put(MediaStore.MediaColumns.DATA, k.getAbsolutePath());
  values.put(MediaStore.MediaColumns.TITLE, "TwiAppclip");
  values.put(MediaStore.MediaColumns.MIME_TYPE, "audio/*");
  values.put(MediaStore.Audio.Media.ARTIST, "cssounds ");
  values.put(MediaStore.Audio.Media.IS_RINGTONE, true);
  values.put(MediaStore.Audio.Media.IS_NOTIFICATION, false);
  values.put(MediaStore.Audio.Media.IS_ALARM, false);
  values.put(MediaStore.Audio.Media.IS_MUSIC, false);

  Uri uri = MediaStore.Audio.Media.getContentUriForPath(k
       .getAbsolutePath());
  Uri newUri = getApplicationContext().getContentResolver().insert(uri, values);

  RingtoneManager.setActualDefaultRingtoneUri(getApplicationContext(),
      RingtoneManager.TYPE_RINGTONE, newUri);

here uri I am getting But I got newUri = null. I think that's why its is not setting as ringtone.

Anyone know where is the problem? how do I get newUri proper?

Toon Krijthe
  • 52,876
  • 38
  • 145
  • 202
djk
  • 3,671
  • 9
  • 31
  • 40

3 Answers3

36

Audio is set as ringtone only once, but solution to this problem is - If you are trying to run the same code again, you'll be inserting a duplicate entry into MediaStore's table, but the SQLite database won't allow you. You have to either rename your file and add another instance of it, or go in, remove the entry, and then try again. So I removed that entry every time and then insert it again.

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

RingtoneManager.setActualDefaultRingtoneUri(activity.this,
        RingtoneManager.TYPE_RINGTONE, newUri);
Ragunath Jawahar
  • 19,513
  • 22
  • 110
  • 155
djk
  • 3,671
  • 9
  • 31
  • 40
  • 2
    Genius! Thanks, I've been searching all over for the syntax on how to properly query for a duplicate. – Nick Mar 25 '12 at 20:43
  • Thanks man. That was great. I was looking for this for weeks and u know what. The catch block catches this exception but exception variable is null. I had no clue it could be this issue. Thanks :D – drulabs May 03 '12 at 05:44
  • 1
    -1 for this answer as it does not work! Lack of checking for delete, so this code surrounding getting the Uri and doing the delete is lazy code! The more correct answer would have been to obtain the media's _ID and this int nRowsDeleted = getContentResolver().delete(Uri.parse(MediaStore.Audio.Media.EXTERNAL_CONTENT_UR‌​I + "/" + _ID), null, null); if (nRowsDeleted > 0){ // delete worked }else{ // delete failed } – t0mm13b Jun 19 '12 at 12:39
  • Could not help noticing btw the similarity in the answer to this http://stackoverflow.com/questions/3029876/setting-ringtone-notification-from-sd-card-file/4613172#4613172... just saying :) – t0mm13b Jun 19 '12 at 15:03
  • 1
    both are same answers as i give answer which you give link. – djk Jun 22 '12 at 12:13
  • @djk could you help me? I am also getting insert uri as null only on specific device – moDev Jun 03 '14 at 07:19
  • gives me an error by android.permission.WRITE_SETTINGS missing – jairhumberto Dec 24 '19 at 19:30
3

Instead of deleting the previously inserted uri, you can reuse it:

    // check if file already exists in MediaStore
    String[] projection = {MediaStore.Audio.Media._ID};
    String selectionClause = MediaStore.Audio.Media.DATA + " = ? ";
    String[] selectionArgs = {ringtoneFile.getAbsolutePath()};
    Cursor cursor = context.getContentResolver().query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, projection, selectionClause, selectionArgs, null);
    Uri insertedUri;
    if (cursor == null || cursor.getCount() < 1) {
        // not exist, insert into MediaStore
        ContentValues cv = new ContentValues();
        cv.put(MediaStore.Audio.Media.DATA, ringtoneFile.getAbsolutePath());
        cv.put(MediaStore.MediaColumns.TITLE, ringtoneFile.getName());
        insertedUri = context.getContentResolver().insert(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, cv);
    } else {
        // already exist
        cursor.moveToNext();
        long id = cursor.getLong(0);
        insertedUri = ContentUris.withAppendedId(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, id);
    }
    RingtoneManager.setActualDefaultRingtoneUri(context, type, insertedUri);
Gen Liu
  • 655
  • 1
  • 6
  • 7
1
RingtoneManager.setActualDefaultRingtoneUri(
Context,
RingtoneManager.TYPE_RINGTONE,
Uri
.parse("Media file uri"));

I think this will solve ur problem.

gprathour
  • 14,813
  • 5
  • 66
  • 90
surya
  • 477
  • 1
  • 7
  • 19