Create a Ringtone Randomizer on Android

Android users are always on the lookout for apps that can alter the behavior of their devices in new and innovative ways. The Android platform gives its developers a lot of freedom to build such apps. In this tutorial, you will learn how to create an app that randomizes the ringtone of an Android phone every time it receives a call.

Prerequisites

If you'd like to follow along, then make sure you have the latest version of Android Studio installed. You can get it from the Android Developer website.

Because this is an intermediate tutorial, I won't cover the basics in too much detail. I assume that you have already created one or more Android apps and are familiar with the basics of the Android SDK.

1. Create a New Project

Start Android Studio and create a new project. Set the name of the application to RingtoneRandomizer. Make sure you choose a unique package name.

This app can run on all phones that have API level 8 or higher, so set the minimum SDK to Android 2.2.

Next, choose Add No Activity and click Finish.

2. Edit Manifest

Our app will need the following permissions:

  • android.permission.READ_PHONE_STATE to detect incoming calls
  • android.permission.WRITE_SETTINGS to change the default ringtone setting
  • android.permission.READ_EXTERNAL_STORAGE to fetch the list of available ringtones

Add the following to AndroidManifest.xml:

This app has one Activity, to allow the user to activate/deactivate the ringtone changing behavior.

It also has a BroadcastReceiver to detect call state changes. As shown below, the intent action that it listens to is android.intent.action.PHONE_STATE.

3. Edit strings.xml

The strings.xml file contains the strings the app uses. Update values/strings.xml as shown below:

4. Create Activity Layout

The Activity needs the following views:

  • ToggleButton to activate/deactivate the ringtone randomizer
  • ListView to display all available ringtones
  • TextView that acts as a label

Create a file named layout/activity_main.xml and replace its contents with the following. As you can see, the layout is pretty simple and straightforward.

5. Create RingtoneHelper Helper Class

In order to avoid dealing with the RingtoneManager directly in the Activity or the BroadcastReceiver, we're going to create a helper class named RingtoneHelper.

The RingtoneHelper class will have two static methods that make use of the RingtoneManager class.

fetchAvailableRingtones

The fetchAvailableRingtones method fetches the list of available ringtones, returning a List of Ringtone objects.

In fetchAvailableRingtones method, we start by creating an instance of the RingtoneManager class. The RingtoneManager object can list all the sounds available on the device. This includes the sounds for alarms and other notifications.

We use the setType method to set its type to TYPE_RINGTONE as we are only interested in ringtones.

We then invoke the getCount method to know how many ringtones are available and call the getRingtone method in a for loop, adding each ringtone to ringtones.

changeRingtone

The changeRingtone method is responsible for changing the ringtone of the device, the core feature of our app.

We first check in SharedPreferences if the user has activated the ringtone randomizer. We then use the Random class to pick a random number that's less than the number of available ringtones.

The getRingtoneUri method is invoked to fetch the URI of the corresponding ringtone and pass it to the setActualDefaultRingtoneUri method to change the ringtone.

6. Create Broadcast Receiver

Create a new class named RingReceiver that inherits from BroadcastReceiver. The new class will have only one method named onReceive. In this method, all we do is call the helper class's changeRingtone method if the following criteria are met:

  • the action of the received Intent is equal to TelephonyManager.ACTION_PHONE_STATE_CHANGED
  • the value of the lookup key EXTRA_STATE is equal to TelephonyManager.EXTRA_STATE_RINGING

This is what the RingReceiver class should look like:

7. Create Activity

Create a new class named MainActivity that inherits from Activity. We override the onCreate method and perform the following actions:

  • invoke setContentView to use the layout defined in activity_main.xml
  • call the helper class's fetchAvailableRingtones method to populate a List of ringtones
  • initialize the ListView
  • initialize the ToggleButton

The MainActivity class should now look something like this:

initializeToggle

In the initializeToggle method we set the state of the toggle button based on a boolean value named active in SharedPreferences. This value is set to false by default.

We also add an OnCheckedChangeListener to the toggle button to update the value in SharedPreferences. The putBoolean and commit methods of the Editor are used to accomplish this.

initializeList

The initializeList method creates an Adapter based on the List of ringtones. Use android.R.layout.simple_list_item_1 as the layout of the items of the ListView. It is nothing but a TextView. It should display the title of the ringtone, using the Ringtone class's getTitle method. This should be done inside the getView method of the Adapter, after overriding it.

Once the Adapter is ready, assign it to the ListView by using the ListView's setAdapter method.

8. Compile and Run

Our app is now ready to be deployed on an Android phone. You should be able to see all the ringtones available on your phone when you start the app. Click on the toggle button to activate the randomizer.

This is what the final result could look like

Call yourself from another phone a couple of times. The first time you receive a call, your original ringtone will be played. From the next call onwards, you will hear a random ringtone every time.

Note that this app changes the default ringtone of your phone. If you have assigned a specific ringtone to a contact or a group of contacts, that ringtone will still be used.

Conclusion

You now know how to make use of functionality available in the RingtoneManager class. You have also learned how to detect incoming calls. Feel free to build on this app to randomize other notifications in a similar manner. Visit the Android Developer website to learn more about the RingtoneManager class.

Tags:

Comments

Related Articles