简体   繁体   English

Android - 如何检测或接收拨出电话?

[英]Android - How to detect outgoing call is answered or received?

Is there any way to detect outgoing call is successfully received or answered ? 有没有办法检测成功接听或接听拨出电话? I am using Intent.ACTION_CALL for dialing a call and PhoneCallListener to find the state of a call when outgoing call answered but I couldn't have been achieving this. 我正在使用Intent.ACTION_CALL拨打电话,而PhoneCallListener在拨打电话时找到呼叫状态,但我无法实现此目的。 Is this possible in android ? 这在Android中是否可行?

After deeply working on this issue, I reached this conclusion: 在深入研究这个问题后,我得出了这样的结论:

  1. PhoneStateListener won't work for outgoing calls, it calls OFFHOOK instead of RINGING and OFFHOOK is never called on ANSWER. PhoneStateListener不会拨出电话的工作,它调用OFFHOOK ,而不是RINGINGOFFHOOK永远不会呼吁答案。

  2. Using NotificationListenerService , you can listen to posted notifications related to outgoing calls. 使用NotificationListenerService ,您可以收听与传出呼叫相关的已发布通知。 You can do something like the below code. 你可以做类似下面的代码。 The issue here is that I'm not able to get the notification text from some Samsung phones , also the text itself might change a lot from one phone to another. 这里的问题是我无法从一些三星手机上获取通知文本 ,而且文本本身可能会从一部手机变为另一部手机。 Also it requires API 18 and above . 它还需要API 18及更高版本

     public class NotificationListener extends NotificationListenerService { private String TAG = this.getClass().getSimpleName(); @Override public void onNotificationPosted(StatusBarNotification sbn) { Log.i(TAG, "Notification Posted"); Log.i(TAG, sbn.getPackageName() + "\\t" + sbn.getNotification().tickerText + "\\t" + sbn.getNotification().extras.getString(Notification.EXTRA_TEXT); Bundle extras = sbn.getNotification().extras; if ("Ongoing call".equals(extras.getString(Notification.EXTRA_TEXT))) { startService(new Intent(this, ZajilService.class).setAction(ZajilService.ACTION_CALL_ANSWERED)); } else if ("Dialing".equals(extras.getString(Notification.EXTRA_TEXT))) { startService(new Intent(this, ZajilService.class).setAction(ZajilService.ACTION_CALL_DIALING)); } } @Override public void onNotificationRemoved(StatusBarNotification sbn) { Log.i(TAG, "********** onNotificationRemoved"); Log.i(TAG, "ID :" + sbn.getId() + "\\t" + sbn.getNotification().tickerText + "\\t" + sbn.getPackageName()); } } 
  3. Using AccessibilityService , it is more basic than NotificationListenerService and I think it is supported by all APIs. 使用AccessibilityService ,它比NotificationListenerService更基本,我认为所有API都支持它。 But also using AccessibilityService, some phones don't publish useful events in case of call Answer . 但是也使用AccessibilityService, 一些电话在呼叫应答时不发布有用的事件 In most phones, an event wil be raised once the call answered, with call duration; 在大多数手机中,一旦呼叫应答,将提出一个事件,呼叫持续时间; Its printout looks like this: 它的打印输出如下:

onAccessibilityEvent EventType: TYPE_WINDOW_CONTENT_CHANGED; EventTime: 21715433; PackageName: com.android.incallui; MovementGranularity: 0; Action: 0 [ ClassName: android.widget.TextView; Text: []; ContentDescription: 0 minutes 0 seconds;

onAccessibilityEvent EventType: TYPE_WINDOW_CONTENT_CHANGED; EventTime: 21715533; PackageName: com.android.incallui; MovementGranularity: 0; Action: 0 [ ClassName: android.widget.TextView; Text: []; ContentDescription: 0 minutes 1 seconds;

  1. API 23 has a new class, Call . API 23有一个新类Call it has more detailed call states; 它有更详细的通话状态; STATE_ACTIVE . STATE_ACTIVE You can replace the default InCallUI of the phone by your own UI through InCallService I didn't try to use this yet, but anyway, it is just limited to API 23, Marshmallow. 您可以通过自己的UI替换手机的默认InCallUI通过InCallService我还没有尝试使用它,但无论如何,它仅限于API 23,Marshmallow。

As a conclusion, You need to build a solution combined with NotificationListener and AccessibilityService , in order to cover all phone, hopefully. 总之,您需要构建一个结合NotificationListenerAccessibilityService的解决方案,以便覆盖所有手机,希望如此。

You need to use a combination of RINGING state and OFFHOOK state to figure out if the call is answered. 您需要使用RINGING状态和OFFHOOK状态的组合来确定呼叫是否已应答。

See this thread for actual code on how to achieve this. 有关如何实现此目的的实际代码,请参阅此主题

I know its been a while but i hope to be helpful for someone still looking for a solution! 我知道它已经有一段时间但我希望对仍在寻找解决方案的人有所帮助!

I recently had to work on a similar project where i needed to capture the ringing state of an outgoing call and the only way i could find was using the hidden Api of native dial-up App. 我最近不得不在一个类似的项目上工作,我需要捕获拨出呼叫的振铃状态,我能找到的唯一方法是使用本机拨号应用程序的隐藏Api。 This would only be possible for android > 5.0 because of the api changes. 这仅适用于android> 5.0,因为api更改。 This was tested on Android 5.0.1, and worked like a charm. 这是在Android 5.0.1上测试过的,并且像魅力一样。 (ps you would need a rooted device for it to work, because you need to install your app as a System application (google how!) which will then be able to detect the outgoing call states). (ps你需要一个有根设备才能工作,因为你需要将你的应用程序安装为系统应用程序(谷歌如何!),然后才能检测到拨出呼叫状态)。

For the record, PhoneStateListener doesn't work for detecting the outgoing call states as mentioned in many posts. 对于记录,PhoneStateListener不能用于检测许多帖子中提到的传出呼叫状态。

First, add this permission in the manifest file, 首先,在清单文件中添加此权限,

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

Then define you broadcastreceiver, (here is a sample code!) 然后定义你broadcastreceiver,(这是一个示例代码!)

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

public class MyBroadcastReceiver extends BroadcastReceiver
{
    @Override
    public void onReceive(Context context, final Intent intent)
    {
        switch (intent.getIntExtra("foreground_state", -2)) {
            case 0: //  PreciseCallState.PRECISE_CALL_STATE_IDLE:
                System.out.println("IDLE");
                break;
            case 3: //  PreciseCallState.PRECISE_CALL_STATE_DIALING:
                System.out.println("DIALING");
                break;
            case 4: //  PreciseCallState.PRECISE_CALL_STATE_ALERTING:
                System.out.println("ALERTING");
                break;
            case 1: //  PreciseCallState.PRECISE_CALL_STATE_ACTIVE:
                System.out.println("ACTIVE");
                break;
        }

    }
} 

I replaced some of the constants with their values because i saw a lot of confusion among the folks unfamiliar with the concept of reflection (so for ease). 我用它们的值替换了一些常量,因为我看到不熟悉反射概念的人们之间有很多困惑(所以为了方便)。 Alerting is basically the state when receiver is actually ringing! 警报基本上是接收器实际响铃时的状态! and that does not include the call setup time which means that the call has been received successfully!. 并且不包括呼叫建立时间,这意味着呼叫已成功接收! There are other options in precise_call_state class (which i didn't explore), to help you with capturing the call being answered! 在precise_call_state类中还有其他选项(我没有探索过),以帮助您捕获正在回答的呼叫!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM