You've probably heard about the fact that it was possible to upload custom ringtones with NoDo (and even pre-NoDo), but that required a small reflection hack. With the release of the Mango (OS 7.5) tools, the capability to add ringtones to the system is built-in. The base class that you need to look at is called SaveRingtoneTask and it is the only one that allows the developer to access ringtone capabilities. There are a couple of things you have to remember, before we go any further:
- You cannot create ringtones from existing media on the phone. It is restricted to media available from the application itself. One of the reasons here is licensing for the musical content.
- You cannot alter/replace system ringtones. You can create your own, that will be listed in a separate category.
- You cannot export the ringtones you create unless you have the source of the ringtone saved for future re-use.
- There is no way to list existing custom ringtones, whether created by your application or by another third-party product.
First thing we need to do is go to the official MSDN article for SaveRingtoneTask and familiarize ourselves with general requirements for a ringtone to be valid. The article states:
- Ringtone files must be of type MP3 or WMA.
- Ringtone files must be less than 40 seconds in length - usually, when you are accepting a call, it won't ring for more than 30 seconds (depends on the carrier and device). Using a track that is more than 40 seconds long would be a pure waste of space.
- Ringtone files must not have digital rights management (DRM) protection.
- Ringtone files must be less than 1 MB in size.
So let's assume that you have a file ready. What's next? First of all, you have to initialize the class that will be handling everything.
SaveRingtoneTask task = new SaveRingtoneTask();
There is a property for the task instance, called Source. It requires the developer to specify a URI that points to a local file (inside the application XAP itself) or a file in the Isolated Storage, that will be used as the ringtone. External ringtones (with a URI that points outside the XAP) are not allowed for security reasons.
So you need to set the source and show the task:
task.Source = new Uri("/coffee.wma"); task.Show();
In my case, coffee.wma is a media file located in the project root:
IMPORTANT NOTE: You can specify local ringtones through isostore, appdata and file URI schemes, if necessary (will require an absolute path).
It's time to launch it on the phone. Or the emulator - whichever works better. I inserted the pieces of code above in the main page constructor, right when it is initialized. That way, I am not doing anything else in this application but add a new ringtone.
The user will be prompted to enter a name. The default value is set to the file name without the extension. It can be changed in code by modifying the DisplayName property.
task.DisplayName = "MyCoffee";
Once the user clicks OK, look at the status bar on top of the window to see the Saving... status and a progress bar.
If the ringtone is successfully saved, then you will see a label saying ...and your ringtone is saved.
When exactly the last label might not show up? If the ringtone does not fit the established requirements that were mentioned at the beginning of this article, the process will resume the application that invoked it. The user will not be alerted that the process failed, so it might look like everything went well. However, the ringtone will not show up on the list of custom ringtones. This brings up an important point:
Make sure that the ringtone you are trying to install abides to the outlined criteria. Otherwise, it will not be added, even if no error message is shown at runtime.
Even more interesting might be this - how exactly to check ringtones in the emulator? With the locked Settings app, it seems like experimentation in a PC sandbox is pointless. Not really. Let's invoke this task:
PhoneCallTask task = new PhoneCallTask(); task.PhoneNumber = "32434"; task.Show();
A completely random number here - you can type whatever you want as the PhoneNumber as long as it is callable. Once you get to the call, click on Add To Call and then select the phone book icon at the bottom.
This will get you to the People hub. Click on any contact listed there an pin it to the start screen. That way it will be easier to experiment later.
You can end the call now. Click on the contact and edit it (the pencil icon at the bottom). That's where you will see an option called ringtone. Click the plus sign and you will see the list of available ringtones.