Stopping & Starting music on incoming calls

我的梦境 提交于 2019-11-26 15:05:19

There are a few things you can do:

First of all, you can listen for changes in the call state using a PhoneStateListener. You can register the listener in the TelephonyManager:

PhoneStateListener phoneStateListener = new PhoneStateListener() {
    @Override
    public void onCallStateChanged(int state, String incomingNumber) {
        if (state == TelephonyManager.CALL_STATE_RINGING) {
            //Incoming call: Pause music
        } else if(state == TelephonyManager.CALL_STATE_IDLE) {
            //Not in call: Play music
        } else if(state == TelephonyManager.CALL_STATE_OFFHOOK) {
            //A call is dialing, active or on hold
        }
        super.onCallStateChanged(state, incomingNumber);
    }
};
TelephonyManager mgr = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
if(mgr != null) {
    mgr.listen(phoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);
}

Remember to unregister the listener when it's no longer needed using the PhoneStateListener.LISTEN_NONE:

TelephonyManager mgr = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
if(mgr != null) {
    mgr.listen(phoneStateListener, PhoneStateListener.LISTEN_NONE);
}

For more information read the documentation.

Another thing you can do is listening for the broadcast android.intent.action.PHONE_STATE. It will contain the extra TelephonyManager.EXTRA_STATE which will give you information about the call. Take a look at the documentation here.

Please note that you'll need the android.permission.READ_PHONE_STATE-permission in both cases.

I think that AudioManager is the best and fast solution. Here there is my implementation example:

public class MyActivity extends Activity implements OnAudioFocusChangeListener {

private AudioManager mAudioManager;

@Override
public void onCreate(Bundle savedInstanceState) {
    ...
    mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
    mAudioManager.requestAudioFocus(this, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN);
    ...
}

@Override
 public void onDestroy(){
     super.onDestroy();
     ...
     mAudioManager.abandonAudioFocus(this);
     ...
 }


@Override
public void onAudioFocusChange(int focusChange) {
    if(focusChange<=0) {
        //LOSS -> PAUSE
    } else {
        //GAIN -> PLAY
    }
}   

}

I hope it's helpful for you :-)

OR - You can try a Receiver Application.

Create a Receiver named CallRecord.java

package com.example.callreceiver;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;

public class CallReceiver extends BroadcastReceiver{
    TelephonyManager telManager;
    Context context;

@Override
public void onReceive(Context context, Intent intent) {


    this.context=context;

    telManager = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
    telManager.listen(phoneListener, PhoneStateListener.LISTEN_CALL_STATE);

}

private final PhoneStateListener phoneListener = new PhoneStateListener() {
    @Override
    public void onCallStateChanged(int state, String incomingNumber) {
        try {
            switch (state) {
            case TelephonyManager.CALL_STATE_RINGING: {
                //PAUSE
            break;
            }
            case TelephonyManager.CALL_STATE_OFFHOOK: {

            break;
            }
            case TelephonyManager.CALL_STATE_IDLE: {
                //PLAY
            break;
            }
            default: { }
            }
            } catch (Exception ex) {

            }
        }
    };
 }

Then Add this line in manifest.xml file to register it on the App

<receiver android:name="CallReceiver" >
        <intent-filter>
            <action android:name="android.intent.action.PHONE_STATE" >
            </action>
        </intent-filter>
    </receiver>

I think requestAudioFocus() should be able to handle this case automatically. You don't need to check call state explicitly.

Audio Focus is cooperative in nature. That is, applications are expected (and highly encouraged) to comply with the audio focus guidelines, but the rules are not enforced by the system. If an application wants to play loud music even after losing audio focus, nothing in the system will prevent that. However, the user is more likely to have a bad experience and will be more likely to uninstall the misbehaving application.

To request audio focus, you must call requestAudioFocus() from the AudioManager, as the example below demonstrates:

AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
int result = audioManager.requestAudioFocus(this, AudioManager.STREAM_MUSIC,
AudioManager.AUDIOFOCUS_GAIN);

if (result != AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
    // could not get audio focus.
}

For me idle state was coming while there was incoming call, the quick fix is to check in the broadcast receiver

BroadcastReceiver phonestatereceiver = new BroadcastReceiver() {
  @Override
  public void onReceive(Context context, Intent intent) {
    Bundle extras = intent.getExtras();
    if (extras != null) {
      String state = extras.getString(TelephonyManager.EXTRA_STATE);
      if (state.equals(TelephonyManager.EXTRA_STATE_RINGING)) {
        //pause here
      }
      else if (state.equals(TelephonyManager.EXTRA_STATE_OFFHOOK)) {
        //pause here
      }
      else if (state.equals(TelephonyManager.EXTRA_STATE_IDLE)) {
        //play here
      }
    }
  }
};
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!