1

我知道 Android 有一个内置系统,可让用户为单个电话簿联系人/组选择特殊铃声,但我必须在通话时动态更改铃声:

所以,我写了一个服务并在手机启动时加载它,设置一个捕获来电的电话监听器,保存默认电话铃声(在服务变量中)并在必要时用另一个铃声更改原始铃声,然后恢复原始铃声电话状态返回空闲时的铃声。好吧,我可以保存原音,设置新的,但听不到新的铃声,只能听到旧的:

看看我的代码并记住,当电话听众选择是否更改原始铃声时,电话已经响起。

那么,如何在电话已经响铃时更改铃声?

我在我的清单中有权限android.permission.WRITE_SETTINGSandroid.permission.READ_PHONE_STATE

服务:

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);
    }
}

电话监听器:

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;
        }
    }
}
4

1 回答 1

1

首先,使用路径和文件名创建一个文件:

File file = new File(path, songName); 

然后,准备查询:

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);

然后将其插入数据库:

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

最后,设置铃声:

RingtoneManager.setActualDefaultRingtoneUri(
  myActivity,
  RingtoneManager.TYPE_RINGTONE,
  newUri
);  

这假定您具有适当的权限。如果您以 API 23 或更高版本为目标,除了在清单中声明之外,您还必须在运行时请求权限

于 2016-07-04T10:57:46.170 回答