如何在安卓手机上知道自己是否正在通话?

33

我想知道我是否在通话中。

如果我正在通话中,则启动服务(服务的部分很清楚)。我该怎么做?

在接听电话时,我需要调用服务... 我不知道如何做?有帮助吗?


4
你的意思是“电话呼叫”,“方法调用”或其他类型的调用?(求偶鸣叫?谢幕呼声?劳伦·巴考尔?:-)) - Stephen C
4个回答

59

你需要广播接收器 ...

在清单文件中声明广播接收器 ...

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

还要声明 uses-permission...

<uses-permission android:name="android.permission.READ_PHONE_STATE" />  

广播接收器类(Broadcast Receiver Class) ...

package x.y;

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

public class PhoneStateBroadcastReceiver extends BroadcastReceiver{

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

        TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
        telephonyManager.listen(new CustomPhoneStateListener(context), PhoneStateListener.LISTEN_CALL_STATE);

    }

}

还需要一个类来自定义电话状态监听器...

package x.y;
import android.content.Context;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;

public class CustomPhoneStateListener extends PhoneStateListener {

    //private static final String TAG = "PhoneStateChanged";
    Context context; //Context to make Toast if required 
    public CustomPhoneStateListener(Context context) {
        super();
        this.context = context;
    }

    @Override
    public void onCallStateChanged(int state, String incomingNumber) {
        super.onCallStateChanged(state, incomingNumber);

        switch (state) {
        case TelephonyManager.CALL_STATE_IDLE:
            //when Idle i.e no call
            Toast.makeText(context, "Phone state Idle", Toast.LENGTH_LONG).show();
            break;
        case TelephonyManager.CALL_STATE_OFFHOOK:
            //when Off hook i.e in call
            //Make intent and start your service here
            Toast.makeText(context, "Phone state Off hook", Toast.LENGTH_LONG).show();
            break;
        case TelephonyManager.CALL_STATE_RINGING:
            //when Ringing
            Toast.makeText(context, "Phone state Ringing", Toast.LENGTH_LONG).show();
            break;
        default:
            break;
        }
    }
}

在CALL_STATE_RINGING之后,我加入了system.out.println("rining")语句,并设置了断点进行调试。我从另一部手机拨打电话,此时状态为响铃,断点应该会被触发才对,但实际上并没有发生。 - Rockin
1
这是因为你的监听器泄漏了。 - jBilbo
每个状态确切地是什么意思?摘机?空闲?为什么不能是:响铃/添加呼叫/挂起呼叫/全部挂起? - android developer
如果我想要更改屏幕上来电的显示名称怎么办? - uniruddh
1
从Android O开始,您需要获取应用程序权限才能读取电话状态。 - ruben
显示剩余3条评论

33

TelephonyManager.getCallState() 返回以下其中一个:

  • CALL_STATE_IDLE:电话处于闲置状态
  • CALL_STATE_OFFHOOK:电话已摘机
  • CALL_STATE_RINGING:电话正在响铃

如果符合您的要求,与 Piper Pied 的更全面的解决方案相比,它需要的代码量少得多。


2
我认为这是一个更好的解决方案。 在第一种情况下,每次电话状态改变时都会添加一个新的监听器。 - Goo
+1 我不知道这个方法的存在。但是,如果我们只想知道特定时间的呼叫状态,那么这个方法将会有所帮助,但它无法一直监视电话呼叫状态。 - Vaibhav Jani
7
对于新手来说,((TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE)).getCallState() 的意思是获取当前电话的状态。 - Vivek Bansal

1

0

这是一个老问题,毫无疑问。但它在谷歌上排名第一。因此,我决定添加另一种有用的方法。

当手机状态改变时,系统会发送TelephonyManager.ACTION_PHONE_STATE_CHANGED广播。这个广播有一个额外的状态,可以使用TelephonyManager.EXTRA_STATE提取。

额外的状态可以有三种选择:

  • EXTRA_STATE_IDLE
  • EXTRA_STATE_OFFHOOK
  • EXTRA_STATE_RINGING

您可以设计一个广播接收器来处理所有这些:

public class PhoneStateReceiver extends BroadcastReceiver {

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

        if (intent.getAction().equals(TelephonyManager.ACTION_CALL_STATE_CHANGED){

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

            if (state.equals(TelephonyManager.EXTRA_STATE_IDLE){

                // No call currently active.

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

                // A call is ringing

            } else if (state.equals(TelephonyManager.EXTRA_STATE_OFFHOOK){

                // Call has been answered.

            }
        }
    }
}

您可以在这里阅读更多相关信息:

https://developer.android.com/reference/android/telephony/TelephonyManager#ACTION_PHONE_STATE_CHANGED

注意:广播接收器将在后台触发,从Android O+开始,您不能从后台进程启动后台服务。请考虑使用context.startForegroundService(intent)启动前台服务。在服务的onStartCommand(...)中调用startForeground(...)。否则,系统会引发致命异常。但是,在Android O以下版本中,您可以安全地使用context.startService(intent)而不是startForegroundService(...)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接