13

Possible Duplicate:
How to set ringtone in Android from my activity?

I have sounds files in my res/raw folder and i want to select a sound to set as a ringtone on the click of a button. Wonder how can i do that?

Community
  • 1
  • 1
Muhammad Maqsoodur Rehman
  • 33,681
  • 34
  • 84
  • 124
  • have you ever found a solution? – vondip Jan 04 '10 at 19:46
  • 1
    This is not a duplicate! this talks about setting a ringtone from a raw file. The other one is just how to set a ringtone already on the sd card. Please reopen i have a full solution. – ozmike Jan 12 '13 at 05:22

4 Answers4

28

@Maxood

The code from @Clive is what you need to set the ringtone. You will need the absolute path to the file, which you can't get from a raw resource.

The solution is to get the resource file asset and write it to the sdcard 1st, before you give it to the content resolver for insertion.

File newSoundFile = new File("/sdcard/media/ringtone", "myringtone.oog");
Uri mUri = Uri.parse("android.resource://com.your.package/R.raw.your_resource_id");
ContentResolver mCr = app.getContentResolver();
AssetFileDescriptor soundFile;
try {
       soundFile= mCr.openAssetFileDescriptor(mUri, "r");
   } catch (FileNotFoundException e) {
       soundFile=null;   
   }

   try {
      byte[] readData = new byte[1024];
      FileInputStream fis = soundFile.createInputStream();
      FileOutputStream fos = new FileOutputStream(newSoundFile);
      int i = fis.read(readData);

      while (i != -1) {
        fos.write(readData, 0, i);
        i = fis.read(readData);
      }

      fos.close();
   } catch (IOException io) {
   }

Then you can use the previously posted solution

       ContentValues values = new ContentValues();
   values.put(MediaStore.MediaColumns.DATA, newSoundFile.getAbsolutePath());
   values.put(MediaStore.MediaColumns.TITLE, "my ringtone");
   values.put(MediaStore.MediaColumns.MIME_TYPE, "audio/oog");
   values.put(MediaStore.MediaColumns.SIZE, newSoundFile.length());
   values.put(MediaStore.Audio.Media.ARTIST, R.string.app_name);
   values.put(MediaStore.Audio.Media.IS_RINGTONE, true);
   values.put(MediaStore.Audio.Media.IS_NOTIFICATION, true);
   values.put(MediaStore.Audio.Media.IS_ALARM, true);
   values.put(MediaStore.Audio.Media.IS_MUSIC, false);

   Uri uri = MediaStore.Audio.Media.getContentUriForPath(newSoundFile.getAbsolutePath());
   Uri newUri = mCr.insert(uri, values);


   try {
       RingtoneManager.setActualDefaultRingtoneUri(getContext(), RingtoneManager.TYPE_RINGTONE, newUri);
   } catch (Throwable t) {
       Log.d(TAG, "catch exception");
   }

Don't forget to write the the permission

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

in your manifest

hope this helps

Shailendra Madda
  • 20,649
  • 15
  • 100
  • 138
Chiatar
  • 389
  • 3
  • 4
  • 5
    Not trying to beat a dead horse here, but make sure you have the permission in your manifest if you're writing to the SD card or else you will get an error. – dell116 Nov 18 '11 at 19:45
  • 2
    Also to note: Be sure to set the uri like so - Uri uri = Uri.parse("android.resource://com.example.myapp/" + R.raw.my_resource); or Uri uri = Uri.parse("android.resource://com.example.myapp/raw/my_resource"); http://developer.android.com/reference/android/content/ContentResolver.html#openAssetFileDescriptor%28android.net.Uri,%20java.lang.String%29 – worked Nov 28 '11 at 22:07
  • You must create a raw directory in your project under res directory obvious maybe but not for me , my_resource is the file name minus the .extension – ozmike Jan 11 '13 at 13:13
  • +1 works like a charm, please edit and add comment of @dell116 in the post. – mprabhat Jan 28 '13 at 21:00
  • I tried it as it is in `onCallStateChanged` method. I am getting newUri as `null` why I don't no please help me.. – Shailendra Madda May 20 '14 at 09:57
  • soundFile= mCr.openAssetFileDescriptor(mUri, "r"); please tell me the meaning of this line... – Sritam Jagadev Mar 02 '15 at 11:35
  • mcr is a getContentResolver() – Petros Mosoyan May 18 '20 at 14:02
5

Try this, it works for me:

ContentValues values = new ContentValues();
values.put(MediaStore.MediaColumns.DATA, <<asbolutePathToYourAudioFileHere>>);
values.put(MediaStore.MediaColumns.TITLE, "<<yourRingToneNameHere>>");
values.put(MediaStore.MediaColumns.SIZE, k);
values.put(MediaStore.MediaColumns.MIME_TYPE, "audio/mpeg");    // assuming it's an mpeg, of course
values.put(MediaStore.Audio.Media.ARTIST, "<<yourArtistNameHere>>");
// values.put(MediaStore.Audio.Media.DURATION, duration);  // doesn't appear to be necessary if you don't know
values.put(MediaStore.Audio.Media.IS_RINGTONE, true);

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

RingtoneManager.setActualDefaultRingtoneUri(
                                <<MyActivity>>.this,
                                RingtoneManager.TYPE_RINGTONE,
                                newUri);
Clive
  • 93
  • 1
  • 5
1

Hopefully by now you have gotten your program working the way you wanted. Just for the record though, you should look into saving the file to the sdcard under a ringtones folder. Make sure it is lower cased as that does matter in Android.

NetApex
  • 95
  • 1
  • 10
-1

I use "Rings Extended" http://www.androidapps.com/t/rings-extended

With that app installed when you go to change your ringtone you will have the option to select Rings Extended. Also use "Ringdroid" to edit ringtones.

SuperJames
  • 767
  • 4
  • 14