Reputation: 519
I know that Android has a built-in system that lets the user choose a special ringtone for a single phonebook contact/group, but i have to change the ringtone dinamically while calling:
So, I wrote a Service and load it at phone startup, to set a phone listener that captures incoming call, that saves the default phone ringtone (in a Service variable) and change the original ringtone with another one if necessary, then restore the orignal ringtone when the phone state returns idle. Well, i can save the original tone, set the new one, but can't hear the new ringtone, only the old:
Take a look at my code and keep in mind that, when the phone listener chooses if to change the original ringtone or not, the phone is already ringing.
So, how can i change the ringtone while the phone is already ringing?
I have android.permission.WRITE_SETTINGS
and android.permission.READ_PHONE_STATE
permissions in my Manifest.
The Service:
public class CallFilterService extends Service {
private Uri originalRingtoneUri;
@Override
public IBinder onBind(Intent arg0) {
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
TelephonyManager telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
telephonyManager.listen(new CallFilterListener(this), PhoneStateListener.LISTEN_CALL_STATE);
return START_STICKY;
}
public void saveOriginalRingtone() {
originalRingtoneUri = RingtoneManager.getActualDefaultRingtoneUri(context, RingtoneManager.TYPE_RINGTONE);
}
public void restoreOriginalRingtone() {
RingtoneManager.setActualDefaultRingtoneUri(context, RingtoneManager.TYPE_RINGTONE, originalRingtoneUri);
}
}
The PhoneListener:
public class MyPhoneListener extends PhoneListener
{
private CallFilterService service;
private Uri specialRingtoneUri;
public CallFilterListener(CallFilterService service) {
super();
this.service = service;
specialRingtoneUri = setSpecialRingtone();
}
@Override
public void onCallStateChanged(int state, String incomingNumber) {
switch (state) {
case TelephonyManager.CALL_STATE_RINGING: {
service.saveOriginalRingtone();
if (canChangeRingtone(incomingNumber)) {
//When in this if block, the default phone ringtone is already playing.
RingtoneManager.setActualDefaultRingtoneUri(context, RingtoneManager.TYPE_RINGTONE, specialRingtoneUri);
}
break;
}
case TelephonyManager.CALL_STATE_IDLE:
{
service.restoreOriginalRingtone();
break;
}
default:
break;
}
}
}
Upvotes: 1
Views: 723
Reputation: 28228
First, create a file with the path and filename:
File file = new File(path, songName);
Then, prepare the query:
ContentValues values = new ContentValues();
values.put(MediaStore.MediaColumns.DATA, file.getAbsolutePath());
values.put(MediaStore.MediaColumns.TITLE, "My Song title");
values.put(MediaStore.MediaColumns.SIZE, 215454);
values.put(MediaStore.MediaColumns.MIME_TYPE, "audio/mp3");
values.put(MediaStore.Audio.Media.ARTIST, "Artist");
values.put(MediaStore.Audio.Media.DURATION, 230);
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);
Then insert it into the database:
Uri uri = MediaStore.Audio.Media.getContentUriForPath(file.getAbsolutePath());
Uri newUri = this.getContentResolver().insert(uri, values);
And finally, set the ringtone:
RingtoneManager.setActualDefaultRingtoneUri(
myActivity,
RingtoneManager.TYPE_RINGTONE,
newUri
);
This assumes you have the appropriate permissions. If you target API 23 or above, you have to request the permission at runtime in addition to declaring it in the manifest
Upvotes: 1