Как определить, когда телефон отвечает или отклонен

Мне удалось подготовить мероприятие, когда звонит телефон. Теперь мне нужно знать, как отменить эту активность, когда я прошу телефон или отклонить вызов. Я вызываю 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 } 

Solutions Collecting From Web of "Как определить, когда телефон отвечает или отклонен"

В вашем 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; } 

Ниже приведен код обнаружения исходящего вызова по событиям доступности –

Добавьте класс, который расширяет 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, поэтому создайте в своем проекте папку xml и добавьте xml-файл с именем serviceconfig.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" /> 

Вы можете найти больше о 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> 

И вы сделали, просто запустите приложение и перейдите к настройкам доступности в своем телефоне, вы найдете опцию, названную как обнаружение ( или любое другое имя, которое вы дали в качестве описания вашего сервиса ), включите это, чтобы предоставить разрешения на доступ к вашему приложению.

Теперь вы увидите тост, когда на вызов будет дан ответ.

Вы можете закодировать любой код, который вы хотите там, также вы можете вызвать функцию обратного вызова в своей деятельности

Самое главное – не вызывайте свое окно вызова (окно дозвона андроида), пока на него не будет дан ответ, иначе это не сработает.

Примечание. Поскольку андроид не предоставляет никакого решения для обнаружения ответа на вызов или нет, это лучшая альтернатива, которую я сделал, надеюсь, что это сработает для вас.