如何检测电话何时应答或拒绝

手机响了,我准备好了一个活动。 现在我需要知道如何取消这个活动,当我打电话或拒绝电话。我打电话EXTRA_STATE_IDLE?EXTRA_STATE_OFFHOOK?

有任何想法吗?

<receiver android:name=".IncomingBroadcastReceiver"> <intent-filter> <action android:name="android.intent.action.PHONE_STATE"/> </intent-filter> </receiver> public class IncomingBroadcastReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE); // If an incoming call arrives if (state.equals(TelephonyManager.EXTRA_STATE_RINGING)) { //Did my work } 

在你的onReceive:

 PhoneStateChangeListener pscl = new PhoneStateChangeListener; TelephonyManager tm = (TelephonyManager)this.getSystemService(Context.TELEPHONY_SERVICE); tm.listen(pscl, PhoneStateListener.LISTEN_CALL_STATE); 

单独的课程:

 private class PhoneStateChangeListener extends PhoneStateListener { public static boolean wasRinging; @Override public void onCallStateChanged(int state, String incomingNumber) { switch(state){ case TelephonyManager.CALL_STATE_RINGING: Log.i(LOG_TAG, "RINGING"); wasRinging = true; break; case TelephonyManager.CALL_STATE_OFFHOOK: Log.i(LOG_TAG, "OFFHOOK"); if (!wasRinging) { // Start your new activity } else { // Cancel your old activity } // this should be the last piece of code before the break wasRinging = true; break; case TelephonyManager.CALL_STATE_IDLE: Log.i(LOG_TAG, "IDLE"); // this should be the last piece of code before the break wasRinging = false; break; } } } 

所有你需要做的是写一些代码来检查以前的状态是否“响了”。 如果当前状态是空闲状态并且以前的状态正在响起,他们取消了呼叫。 如果当前状态为摘机状态,并且前一个状态正在响铃,则他们应答该呼叫。

上述的答案在拨打电话的情况下是完全错误的。 在android中,没有办法检测是否实际接听了电话(在打出电话的情况下)。 拨号的那一刻, off_hook状态就会被触发。 这是android编程的一个缺点。

以下是在不同情况下经历的状态:

1)接听已接电话

 CALL_STATE_RINGING => CALL_STATE_OFFHOOK (After Answering call) => CALL_STATE_IDLE (After End call) 

2)拒绝/未接听(未接听)已接来电

 CALL_STATE_RINGING => CALL_STATE_IDLE (After End call) 

3)拨打电话

 CALL_STATE_OFFHOOK (After dialing) => CALL_STATE_IDLE (After End call) int prev_state=0; public class CustomPhoneStateListener extends PhoneStateListener { private static final String TAG = "CustomPhoneStateListener"; @Override public void onCallStateChanged(int state, String incomingNumber){ if(incomingNumber!=null&&incomingNumber.length()>0) incoming_nr=incomingNumber; switch(state){ case TelephonyManager.CALL_STATE_RINGING: Log.d(TAG, "CALL_STATE_RINGING"); prev_state=state; break; case TelephonyManager.CALL_STATE_OFFHOOK: Log.d(TAG, "CALL_STATE_OFFHOOK"); prev_state=state; break; case TelephonyManager.CALL_STATE_IDLE: Log.d(TAG, "CALL_STATE_IDLE==>"+incoming_nr); NumberDatabase database=new NumberDatabase(mContext); if((prev_state==TelephonyManager.CALL_STATE_OFFHOOK)){ prev_state=state; //Answered Call which is ended } if((prev_state==TelephonyManager.CALL_STATE_RINGING)){ prev_state=state; //Rejected or Missed call } break; } } } 

在你的接收器

 onReceive(Context context, Intent intent) { TelephonyManager telephony = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE); //TelephonyManager object CustomPhoneStateListener customPhoneListener = new CustomPhoneStateListener(); telephony.listen(customPhoneListener, PhoneStateListener.LISTEN_CALL_STATE); //Register our listener with TelephonyManager Bundle bundle = intent.getExtras(); String phoneNr= bundle.getString("incoming_number"); mContext=context; } 

下面是通过辅助function事件检测传出的代码 –

添加一个在您的项目中扩展AccessibilityService的类 –

 public class CallDetection extends AccessibilityService { @Override public void onAccessibilityEvent(AccessibilityEvent event) { acquireLock(this); Log.d("myaccess","after lock"); if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED) { Log.d("myaccess","in window changed"); AccessibilityNodeInfo info = event.getSource(); if (info != null && info.getText() != null) { String duration = info.getText().toString(); String zeroSeconds = String.format("%02d:%02d", new Object[]{Integer.valueOf(0), Integer.valueOf(0)}); String firstSecond = String.format("%02d:%02d", new Object[]{Integer.valueOf(0), Integer.valueOf(1)}); Log.d("myaccess","after calculation - "+ zeroSeconds + " --- "+ firstSecond + " --- " + duration); if (zeroSeconds.equals(duration) || firstSecond.equals(duration)) { Toast.makeText(getApplicationContext(),"Call answered",Toast.LENGTH_SHORT).show(); // Your Code goes here } info.recycle(); } } } @Override protected void onServiceConnected() { super.onServiceConnected(); Toast.makeText(this,"Service connected",Toast.LENGTH_SHORT).show(); AccessibilityServiceInfo info = new AccessibilityServiceInfo(); info.eventTypes = AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED; info.feedbackType = AccessibilityServiceInfo.FEEDBACK_GENERIC; info.notificationTimeout = 0; info.packageNames = null; setServiceInfo(info); } @Override public void onInterrupt() { } } 

但是为了使event.getSource()函数正常工作,你必须通过xml指定一些你的服务configuration,所以在你的项目中创build一个xml文件夹并添加一个叫做serviceconfig.xml的xml文件(你可以给出你想要的任何名字。

serviceconfig的内容如下 –

 <accessibility-service xmlns:android="http://schemas.android.com/apk/res/android" android:description="@string/callDetection" android:accessibilityEventTypes="typeWindowContentChanged" android:notificationTimeout="100" android:canRetrieveWindowContent="true" /> 

你可以在这里find更多关于serviceconfig的信息

现在把你的服务添加到你这样清单文件 –

 <service android:name=".CallDetection" android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE" android:label="@string/callDetection"> <intent-filter> <action android:name="android.accessibilityservice.AccessibilityService" /> </intent-filter> <meta-data android:name="android.accessibilityservice" android:resource="@xml/serviceconfig" /> </service> 

完成后,只需运行应用程序,然后转到手机的“ 辅助function”设置 ,就会find一个名为检测的选项( 或者您提供的任何名称作为服务描述 ),然后将其切换为为您的应用程序授予访问权限。

现在,当接听电话时,您将看到敬酒。

你可以在那里编写你想要的任何代码,也可以在你的活动中调用一个callback函数

最重要的 – 不要打电话给你的电话窗口(android拨号窗口),直到通话被回答,否则这将无法正常工作。

注意 – 由于android并没有提供任何解决scheme来检测电话是否被回答,这是我所做的最好的select,希望它适合你。