Skip to content

Android: Saving a sound file to SD from resource and setting as ringtone

by mat on January 26th, 2010

Quite a few people have been asking how to save a file to the SD card in order to register it as a ringtone. The following example creates a function that will save a resource to the SD card (ie: from R.raw.soundfile to /sdcard/media/audio/ringtones/soundfile.ogg) and register it as a ringtone.

I have split this example into two parts, the first part goes through the code a section at a time with a brief explanation of what it does, the second half is just the code that you can copy and paste and then edit to your hearts content.

Parts

We first setup our function to return a boolean depicting if we have failed or if we are successful. We accept in an integer which corresponds to the raw sound file.

public boolean saveas(int ressound){

}

So this function would be called in the following fashion:

saveas(R.raw.soundfile);

or utilising its boolean return:

if (saveas(R.raw.soundfile)){
// Code if successful
}
else
{
// Code if unsuccessful
}

The following chunk of code creates an inputstream from the raw sound resource and loads it into a buffer. We add in the mandatory try/catch clause around these operations and return false if an exception is raised (to indicate failure to the rest of our program and to prevent trying to continue act upon this sound).

 byte[] buffer=null;
 InputStream fIn = getBaseContext().getResources().openRawResource(ressound);
 int size=0;

 try {
  size = fIn.available();
  buffer = new byte[size];
  fIn.read(buffer);
  fIn.close();
 } catch (IOException e) {
  // TODO Auto-generated catch block
  return false;
 }

The following saves the buffer to a file on the SD card. It first ensures the folder exists and if not it is created. Then as before the writing operations are surrounded with try/catches

 String path="/sdcard/media/audio/ringtones/";
 String filename="examplefile"+".ogg";

 boolean exists = (new File(path)).exists();
 if (!exists){new File(path).mkdirs();}

 FileOutputStream save;
 try {
  save = new FileOutputStream(path+filename);
  save.write(buffer);
  save.flush();
  save.close();
 } catch (FileNotFoundException e) {
  // TODO Auto-generated catch block
  return false;
 } catch (IOException e) {
  // TODO Auto-generated catch block
  return false;
 }    

The following code sends an intent to tell the Media Scanner that we have added a new file, and sets up its properties in the media database:

 sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.parse("file://"+path+filename)));

 File k = new File(path, filename);

 ContentValues values = new ContentValues();
 values.put(MediaStore.MediaColumns.DATA, k.getAbsolutePath());
 values.put(MediaStore.MediaColumns.TITLE, "exampletitle");
 values.put(MediaStore.MediaColumns.MIME_TYPE, "audio/ogg");
 values.put(MediaStore.Audio.Media.ARTIST, "cssounds ");
 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);

 //Insert it into the database
 this.getContentResolver().insert(MediaStore.Audio.Media.getContentUriForPath(k.getAbsolutePath()), values);

Final code
Putting all this code together gives us our final functions:

public boolean saveas(int ressound){
 byte[] buffer=null;
 InputStream fIn = getBaseContext().getResources().openRawResource(ressound);
 int size=0;

 try {
  size = fIn.available();
  buffer = new byte[size];
  fIn.read(buffer);
  fIn.close();
 } catch (IOException e) {
  // TODO Auto-generated catch block
  return false;
 }

 String path="/sdcard/media/audio/ringtones/";
 String filename="examplefile"+".ogg";

 boolean exists = (new File(path)).exists();
 if (!exists){new File(path).mkdirs();}

 FileOutputStream save;
 try {
  save = new FileOutputStream(path+filename);
  save.write(buffer);
  save.flush();
  save.close();
 } catch (FileNotFoundException e) {
  // TODO Auto-generated catch block
  return false;
 } catch (IOException e) {
  // TODO Auto-generated catch block
  return false;
 }    

 sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.parse("file://"+path+filename)));

 File k = new File(path, filename);

 ContentValues values = new ContentValues();
 values.put(MediaStore.MediaColumns.DATA, k.getAbsolutePath());
 values.put(MediaStore.MediaColumns.TITLE, "exampletitle");
 values.put(MediaStore.MediaColumns.MIME_TYPE, "audio/ogg");
 values.put(MediaStore.Audio.Media.ARTIST, "cssounds ");
 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);

 //Insert it into the database
 this.getContentResolver().insert(MediaStore.Audio.Media.getContentUriForPath(k.getAbsolutePath()), values);


 return true;
}

Comments, suggestions etc. are always welcome. Hope this has been helpful.

66 Comments
  1. mrj05hua permalink

    so i declared them globally as
    int[] soundids = {R.raw.sound1, R.raw.sound2, R.raw.sound3};
    that part works but how do i function call into them in the save as or play feature? Is there a link I missed I will gladly do whatever research you send me too.

  2. mrj05hua permalink

    I have gotten some of the code compiled and changed, I got it to pass an integer to the save as functions, it even saves the number of the resource id. But has some debugging errors, how can i get to use the name. Or am I going in the wrong direction.

    I passed the int as
    int[ ] soundid ={raw files, raw file, raw file};
    int j = 0;

    then in the button clicks it assigns the int to the corresponding number. But in the saveas it saves the resource location IE 2693889.mp3. How can I change this.

  3. Just make a matching string array.

    String[] name ={ “Sound 1″, “Sound name 2″, “Chainsaw!”};
    int[] sounds = {R.raw.sound1, R.raw.sound2, R.raw.chainsaw};

    then just have saveas(0); using the passed integer to correspond to the name and sound in the arrays.

  4. satish permalink

    hi i tried this code. this code doesnt shows any error when i run this program. but it does not set it as a ringtone i dont know y…if save as true i have user the toast. but the toast itslf is not being displayed . pls help me i need this code working becase i need to submit my project

  5. mrj05hua permalink

    @mat how do you assign an integer to that specific spot of the string or int arrays. I say a few ways to code it but I keep messing it up.

  6. mrj05hua permalink

    nevermind lol figured it out thank you so so much!!!!!

  7. Tommy permalink

    @mrJ05hua I am encountering the same problem you were and I can not figure it out. After googling I found this site. How did you set up the call of your arrays in the function that saves the file, well chooses the file the save? I know this is old but hey maybe you will reply :) Thanks.

  8. Excellent post, help me a lot!

  9. Patry permalink

    Hi,

    I have a problem related to that but in a differente way. I am trying to do a recorder player in Android. I got the file “example.3gp” in the SD card but then, I would like to give an option to discard or save the sound with a different name. Is there any idea of that? How can I use just the example.3gp as a temporal var?

    Thanks in advance.

  10. I am thankful that I found this blog , exactly the right information that I was searching for! .

  11. John permalink

    I implemented your code, very helpful thanks!!!!!
    After that i added ringtonemanager to set it as a ringtone.
    But on a android 2.3.3 device it will not work.
    I posted my question on stackoverflow.

    If you have time, could you take a look at it?

    http://stackoverflow.com/questions/10105877/ringtone-set-as-silent-on-android-2-3-but-works-on-4-0-3

  12. Why use Hostgator Web Hosting to host your website.
    Host gator also provide set up of worth additional companies cost-free to all their buyers.
    The over two million domains hosted by Host -
    Gator make up approximately 1% of the world.

  13. Strona świadczy o ciekawych wydarzeniach, zapraszam do rozmowy

  14. Spiritually speaking: What do you think of this guide to mabsartute for ex-Catholics?Read the whole thing please. Tips on how to mabsartute;If you’re a girl1) Get something small if it’s your first time, like a lip gloss container. Make sure it’s got a rounded tip.2) Put a little water on it.3) Get yourself on the ground or your bed. Make sure you’re comfortable.4) Put your feet up on something. Make sure they are higher than your head. Spread your legs.5) For the ultimate experience, relax first. Just lay there. Think about nothing. And DONT BE NERVOUS.6) Slowly begin to touch your breasts. Feel them (have your eyes closed or open but if they are open make sure you’re not focusing on anything)7) Keep one hand on your breast and slowly move the other one down to your thigh. (I did not have underwear but I was wearing pants and a shirt, loose pants.) Move your hand up and down your thigh while massaging your breast. With your breast hand, slowly take the lip gloss container or your object of choice. Your clit might start to get a weird feeling like you really want to touch it. DON’T.9) Tease yourself with the object by gently rubbing the spot between your poophole and vagina. This will drive you nuts. Slowly begin to touch and massage the part right above the hole. (I suggest you know where it is before you start all this.)10) Rub for a while. Gently, occasionally harder but not too hard yet.11) At this point you should be aching to rub harder and just get going. Again, don’t. If you do not feel this yet, continue the teasing, very gently.12) Slowly move your fingers to the hole, don’t put them in, but just finger it softly.13) Take your object and place it near the hole and your other hand. Take your free hand off the hole and start to massage your clit harder. (That’s the spot above the hole)14) Slowly stick the object in. Gently, it shouldn’t feel good yet. It might hurt a small amount going in. That means you’ve bumped a sensitive spot. That’s not a bad thing, just angle it a little and keep going.15) Once it’s in as far as it can be without losing it to your pussy, begin slowly moving it in and out a little. Don’t take it all the way out, just a little. Get faster, and faster. Start massaging your clit HARD. Go nuts. You might feel like your on the brink of an orgasm. You might have one. This feels very good.16) Then stick it in all the way and start pushing it back and forth hitting the sides of your hole. Faster, faster. Massage clit again.17) Repeat steps 15 and 16 as much as you want. If you take it out for longer than 30 seconds, I suggest you excite yourself again with the teasing. If you do, it will be worse. Since you have already done it, you’re going to want it worse.18) I would stop with the lip gloss for now, don’t go on to something bigger. Save that for another night. You could be sore after this but you shouldn’t be unless you used something large.If you’re a boy1)Read this.2)Rub penis.

Trackbacks & Pingbacks

  1. Tweets that mention stealthcopter.com » Android: Saving a sound file to SD from resource and setting as ringtone -- Topsy.com
  2. Save Bitmap for a future use in the application | Learn Android Today

Leave a Reply

Note: XHTML is allowed. Your email address will never be published.

Subscribe to this comment feed via RSS