androidbroadcastreceiverandroid-broadcastandroid-audiomanagerphone-state-listener

After Unmute phone when call came only vibrate phone, not able to play ringtone


I'm building an Android app that unmute phone when an Incoming call came in phone.

I use BroadcastReceiver to receive incoming call events. I switch phone from mute mode to Ring Mode when BroadcastReceiver receive incoming call events.

And expect Phone will vibrate and Play ringtone.

But Phone only vibrate, can't play ringtone though phone ring set to max sound.

I found many apps on play store those can unmute before call and play ringtone and vibrate both. Example: One App Link

My code Below:

public void onReceive(Context context, Intent intent) {
    AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
    int maxVolume = audioManager.getStreamMaxVolume(AudioManager.STREAM_RING);

    if (intent.getAction()!=null && intent.getAction().equals("android.intent.action.PHONE_STATE")){

        String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE);

        if (state.equals(TelephonyManager.EXTRA_STATE_RINGING)){

            audioManager.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
            audioManager.setStreamVolume(AudioManager.STREAM_RING, maxVolume/2, AudioManager.FLAG_PLAY_SOUND);
        }
    }
}

Solution

  • I'm working on something very similar. You actually have to play a ringtone after overriding the audio settings. But you only need to do this on Android 6.0+ Get an instance of the ringtone and play it when phone state is ringing else just stop it.

    public void onReceive(Context context, Intent intent) {
        AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
        int maxVolume = audioManager.getStreamMaxVolume(AudioManager.STREAM_RING);
    
        Uri uri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_RINGTONE);
        Ringtone r = RingtoneManager.getRingtone(context, uri);
    
        if (intent.getAction()!=null && intent.getAction().equals("android.intent.action.PHONE_STATE")){
    
            String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
    
            if (state.equals(TelephonyManager.EXTRA_STATE_RINGING)){
    
            audioManager.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
            audioManager.setStreamVolume(AudioManager.STREAM_RING, maxVolume/2, AudioManager.FLAG_PLAY_SOUND);
    
            r.play();
    
            }else {
    
            r.stop();
    
            }
        }
    }
    

    Problems you'll run into with this implementation. You will get multiple ringtones playing because the onReceive method is called many times during Phone State changes. The provides a different context each time onReceive is called and creates a different instance of Ringtone each time. I launched a background service to fix this issue so I could hold a single reference to a context and thus a single reference to Ringtone.