web-dev-qa-db-fra.com

Comment détecter la réponse ou le rejet d'un téléphone

J'ai réussi à préparer une activité lorsque le téléphone sonne. Maintenant, je dois savoir comment annuler cette activité, lorsque je réponds au téléphone ou que je rejette l'appel. Dois-je appeler EXTRA_STATE_IDLE ou EXTRA_STATE_OFFHOOK?

Des idées?

Manifest

    <receiver Android:name=".IncomingBroadcastReceiver">
        <intent-filter>
            <action Android:name="Android.intent.action.PHONE_STATE" />
        </intent-filter>
    </receiver>

IncomingBroadcastReceiver Java Class

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 }
24
user1163234

dans votre réception:

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

classe séparée:

private class PhoneStateChangeListener extends PhoneStateListener {
    public static boolean wasRinging;
    String LOG_TAG = "PhoneListener";
    @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;
        }
    }
}

Tout ce que vous avez à faire est d'écrire du code pour vérifier si l'état précédent sonnait. Si l'état actuel est inactif et que l'état précédent sonnait, ils ont annulé l'appel. Si l'état actuel est décroché et que l'état précédent sonnait, ils ont répondu à l'appel.

21
Andreas

La réponse ci-dessus est complètement fausse en cas d'appels sortants. Dans Android il n'y a aucun moyen de détecter si l'appel a bien été répondu (en cas d'appels sortants). Au moment où vous composez un numéro, le off_hook l'état est déclenché. C'est l'un des inconvénients de la programmation Android.

25
kkreddy

Voici les états qu'il traverse dans différents scénarios:

1) Répondre à l'appel reçu

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

2) Rejeter/ne pas répondre (manqué) Appel reçu

CALL_STATE_RINGING => CALL_STATE_IDLE (After End call)  

3) Composition d'un appel

CALL_STATE_OFFHOOK (After dialing) => CALL_STATE_IDLE (After End call) 

Code

  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;  

            }  
        }  
    }  

Dans votre récepteur

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;  
 }  
7
Karthi

ci-dessous est un code de détection des appels sortants par les événements d'accessibilité -

Ajoutez une classe qui étend AccessibilityService dans vos projets -

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() {

}
}

Mais pour que la fonction event.getSource() fonctionne, vous devez spécifier une partie de votre configuration de service via xml, alors créez un dossier xml dans votre projetez et ajoutez un fichier xml appelé serviceconfig.xml (vous pouvez donner le nom que vous voulez.

Le contenu de serviceconfig est ci-dessous -

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

Vous pouvez en savoir plus sur serviceconfig dans Ici

Maintenant, ajoutez votre service en vous Fichier manifeste comme celui-ci -

<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>

Et vous avez terminé, lancez simplement l'application et accédez à Paramètres d'accessibilité dans votre téléphone, vous trouverez une option nommée détection ( ou quel que soit le nom que vous avez donné comme description de votre service), activez-le pour donner des autorisations d'accès à votre application.

Vous verrez maintenant un toast lorsque vous répondez à l'appel.

vous pouvez coder n'importe quel code que vous souhaitez, vous pouvez également appeler une fonction de rappel dans votre activité

Plus important - N'appelez pas votre fenêtre d'appel (fenêtre de numérotation Android) jusqu'à ce que l'appel soit répondu, sinon cela ne fonctionnera pas.

Remarque - Comme Android ne fournit aucune solution pour détecter si l'appel est répondu ou non, c'est le meilleure alternative que j'ai faite, j'espère que cela fonctionne pour vous.

1
kaustav07