Muting application during phonecall on Android(Call Popup)

Apparently there has been a new thing i wasn’t aware of, and that is call popups. What this essentially does is it prompts you to answer/mute/decline the call without never leaving the current app you are focused on. Of course, since the app doesn’t lose focus Unity doesn’t mute it. Does anyone have a possible workaround for this?

Experienced the same issue. There’s a setting on device under SettingsCallCall-related pop-ups called Call notification pop-ups which can be toggled to test this.

I wrote a native extension to get the phone call status of the device. This can be extended to mute your application during a call.


Java code

package com.your.app.package;

import android.content.Context;
import android.os.Bundle;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.util.Log;
import com.unity3d.player.UnityPlayerActivity;
import com.unity3d.player.UnityPlayer;

public class CallStatusBridge extends UnityPlayerActivity
{    
	private static int currentState = 0;
	private static String gameObject = "callstate";
	private static String callBackName = "OnCallStateChange";
	
	protected void onCreate(Bundle savedInstanceState) 
	{
		Log.d("Unity", "CallStatus created");
		
		super.onCreate(savedInstanceState);		
		TelephonyManager telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
		
		PhoneStateListener phoneStateListener = new PhoneStateListener()
		{	
			@Override
			public void onCallStateChanged(int state, String incomingNumber)
			{	
				switch (state)
				{
		            case TelephonyManager.CALL_STATE_IDLE:
		            	currentState = 0;
		            	break;
		            case TelephonyManager.CALL_STATE_RINGING:
		            	currentState = 1;
		                break;
		            case TelephonyManager.CALL_STATE_OFFHOOK:  
		            	currentState = 2;
		                break;
		            default:
		            	currentState = 0;
		            	break;
				}
				
				Log.d("Unity", "CurrentState:" + currentState);
				sendCallStateToUnity(currentState);
			}
		};
		telephonyManager.listen(phoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);
	 }

    public static int getCallStatus()
    {
        return currentState;
    }
    
    public static void setCallBack(String gameObject, String callBackName)
    {
    	Log.d("Unity", "setCallBack");
    	CallStatusBridge.gameObject = gameObject;
    	CallStatusBridge.callBackName = callBackName;
    }

    public static void sendCallStateToUnity(int state){
    	Log.d("Unity", "sendCallState");
    	UnityPlayer.UnitySendMessage(gameObject, callBackName, "" + state);
    }
}

C# code

using UnityEngine;
using System.Collections;

public class CallStateBridge : MonoBehaviour {

	#if UNITY_ANDROID
		AndroidJavaObject jc;
	#endif

	void Start ()
	{
		#if UNITY_ANDROID
			AndroidJNI.AttachCurrentThread();
			jc = new AndroidJavaClass("com.ea.android.theimpossibleline.rowsamsung.CallStatusBridge");
			jc.CallStatic("setCallBack", new object[2] {gameObject.name, "OnCallStateChange"});
		#endif
	}

	public void OnCallStateChange(string state){
		Debug.Log("call status:" + state);
	}

	#if UNITY_ANDROID
		public int CheckCallStatus(){
			return jc.CallStatic<int>("getCallStatus");
		}
	#endif
}

Add this to your Android Manifest in Unity

<!-- CallStatusBridge -->
<activity android:name=".CallStatusBridge"
          android:label="@string/app_name">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>

I ended up implementing a very similar solution to yours, but not having a bridge, just extending the unity activity and doing everything on the native side.

public class UnityPlayerNativeActivity extends NativeActivity
{
    protected UnityPlayer mUnityPlayer;  // don't change the name of this variable; referenced from native code
    private Boolean wasPlaying;
    // Setup activity layout
    @Override protected void onCreate (Bundle savedInstanceState)
    {
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        super.onCreate(savedInstanceState);

        getWindow().takeSurface(null);
        getWindow().setFormat(PixelFormat.RGBX_8888); // <--- This makes xperia play happy

        mUnityPlayer = new UnityPlayer(this);
        if (mUnityPlayer.getSettings ().getBoolean ("hide_status_bar", true))
            getWindow ().setFlags (WindowManager.LayoutParams.FLAG_FULLSCREEN,
                    WindowManager.LayoutParams.FLAG_FULLSCREEN);

        setContentView(mUnityPlayer);
        mUnityPlayer.requestFocus();
        wasPlaying=true;
        TelephonyManager mgr = (TelephonyManager)getSystemService(TELEPHONY_SERVICE);
        mgr.listen(mPhoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);
    }
    PhoneStateListener mPhoneStateListener = new PhoneStateListener()
    {

        @Override
        public void onCallStateChanged(int state, String incomingNumber)
        {
            AudioManager am = (AudioManager) getSystemService(Context.AUDIO_SERVICE);

            if( state == TelephonyManager.CALL_STATE_RINGING )
            {
                if(wasPlaying){
                    am.setStreamMute(AudioManager.STREAM_MUSIC, true);
                    wasPlaying=false;
                }
            }
            else if(state == TelephonyManager.CALL_STATE_IDLE )
            {  // Not in call: Play music
                if(wasPlaying==false){
                    am.setStreamMute(AudioManager.STREAM_MUSIC, false);
                    wasPlaying=true;
                }

            }
            else if( state == TelephonyManager.CALL_STATE_OFFHOOK )
            {
               if(wasPlaying==true){
                    am.setStreamMute(AudioManager.STREAM_MUSIC, true);
                    wasPlaying=false;
                }
            }

            super.onCallStateChanged(state, incomingNumber);
        }
    };

Try using “OnApplicationPause(bool PauseState)” based on the PauseStateboolean value try decreasing/increasing or switching off audio listener or making audio source mute.
Hope this may help you.