Impossible de détecter quand l'appel sortant est répondu dans Android

Pour détecter quand un appel sortant est répondu, j'ai essayé de créer un PhoneStateListener et d'écouter CALL_STATE_RINGING , CALL_STATE_OFFHOOK et CALL_STATE_IDLE , à partir de cette question , mais cela ne semble pas fonctionner, comme expliqué ci-dessous.

Tout d'abord, j'ai enregistré la permission suivante dans le manifeste:

  • Comment rediriger vers la page html locale dans l'application Android phonegap?
  • Changer l'emplacement de sauvegarde par défaut des projets (ou Espace de travail) dans Android Studio
  • Existe-t-il un moyen pour une activité de savoir quel fragment vient d'être créé?
  • Puis-je créer une mise en forme imbriquée comme celle-ci?
  • Comment écrire une application multi-puces Android avec une navigation très profonde
  • Livres sur la conception de l'interface utilisateur Android
  •  <uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" /> 

    Ensuite, un BroadcastReceiver appelé OutCallLogger qui capture l'événement NEW_OUTGOING_CALL chaque fois qu'un appel sortant est effectué:

     <receiver android:name=".listener.OutCallLogger"> <intent-filter> <action android:name="android.intent.action.NEW_OUTGOING_CALL" /> </intent-filter> </receiver> 

    Ensuite, ma mise en œuvre de OutCallLogger . J'ai configuré un boolean appelé noCallListenerYet pour éviter de joindre un PhoneStateListener nouveau au TelephonyManager lorsque onReceive() est invoqué.

     public class OutCallLogger extends BroadcastReceiver { private static boolean noCallListenerYet = true; @Override public void onReceive(final Context context, Intent intent) { number = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER); if (noCallListenerYet) { final TelephonyManager tm = (TelephonyManager) context.getSystemService( Context.TELEPHONY_SERVICE); tm.listen(new PhoneStateListener() { @Override public void onCallStateChanged(int state, String incomingNumber) { switch (state) { case TelephonyManager.CALL_STATE_RINGING: Log.d(This.LOG_TAG, "RINGING"); break; case TelephonyManager.CALL_STATE_OFFHOOK: Log.d(This.LOG_TAG, "OFFHOOK"); break; case TelephonyManager.CALL_STATE_IDLE: Log.d(This.LOG_TAG, "IDLE"); break; default: Log.d(This.LOG_TAG, "Default: " + state); break; } } }, PhoneStateListener.LISTEN_CALL_STATE); noCallListenerYet = false; } } } 

    Maintenant, lorsque je fais un appel sortant dans mon appareil, CALL_STATE_RINGING JAMAIS invoqué. Je ne reçois toujours que les impressions de "IDLE" sur "OFFHOOK" lorsque l'autre ligne commence à sonner, rien lorsque l'appel est répondu et une impression de "IDLE" à nouveau lorsque l'appel est terminé.

    Comment puis-je détecter de manière fiable quand un appel sortant est répondu dans Android, ou est-ce même possible?

  • Activités synchrones et asynchrones
  • React Native: target with hash string 'android-X' introuvable
  • Ouvrez le fichier KML local dans Google Maps sur Android
  • Java.lang.RuntimeException: Méthode appelée après la publication ()
  • Comment inclure des paquets javax. * Supplémentaires dans une application Android avec Eclipse?
  • EventBus - Classe d'abonné et ses super classes n'ont pas de méthodes publiques avec l'annotation @subscribe
  • 6 Solutions collect form web for “Impossible de détecter quand l'appel sortant est répondu dans Android”

    Depuis Android 5.0, cela est possible pour les applications système. Mais vous devez utiliser l'API Android cachée.

    Je l'ai fait fonctionner comme ceci:

     <uses-permission android:name="android.permission.READ_PRECISE_PHONE_STATE" /> 
     <receiver android:name=".listener.OutCallLogger"> <intent-filter> <action android:name="android.intent.action.PRECISE_CALL_STATE" /> </intent-filter> </receiver> 
     public class OutCallLogger extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { switch (intent.getIntExtra(TelephonyManager.EXTRA_FOREGROUND_CALL_STATE, -2) { case PreciseCallState.PRECISE_CALL_STATE_IDLE: Log.d(This.LOG_TAG, "IDLE"); break; case PreciseCallState.PRECISE_CALL_STATE_DIALING: Log.d(This.LOG_TAG, "DIALING"); break; case PreciseCallState.PRECISE_CALL_STATE_ALERTING: Log.d(This.LOG_TAG, "ALERTING"); break; case PreciseCallState.PRECISE_CALL_STATE_ACTIVE: Log.d(This.LOG_TAG, "ACTIVE"); break; } } } 

    Vous pouvez trouver tous les états d'appel possibles dans PreciseCallState.java et tous les extras que l'intention contient dans TelephonyRegistry.java .

    Il semble que l'état RINGING ne soit atteint que par les appels entrants. Les appels sortants changent d'IDLE à OFFHOOK, alors, regarder l'Etat du téléphone peut-être n'est-il pas possible d'y parvenir.

    Je pense qu'il pourrait être possible d'utiliser des fonctions internes, regardez ceci: qu'est ce que représentent les différents états d'appel dans la paire de téléphonie Android?

    Peut-être essayer d'utiliser CallManager? Consultez http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/2.3.3_r1/com/android/internal/telephony/CallManager.java . J'ai également trouvé CallManager.java parmi les fichiers SDK sur mon ordinateur. Le texte suivant de la page liée semble prometteur:

     Register for getting notifications for change in the Call State Call.State This is called PreciseCallState because the call state is more precise than the Phone.State which can be obtained using the android.telephony.PhoneStateListener Resulting events will have an AsyncResult in Message.obj. AsyncResult.userData will be set to the obj argument here. The h parameter is held only by a weak reference. 1051 1052 public void registerForPreciseCallStateChanged(Handler h, int what, Object obj){ 1053 mPreciseCallStateRegistrants.addUnique(h, what, obj); 1054 } 

    Je n'ai pas essayé de coder quoi que ce soit, alors je ne sais vraiment pas si cela peut faire ce que vous voulez, mais je suis curieux de le savoir.

    Veuillez attirer votre attention sur:

     tm.listen(new PhoneStateListener() { @Override public void onCallStateChanged(int state, String incomingNumber) { switch (state) { case TelephonyManager.CALL_STATE_RINGING: Log.d(This.LOG_TAG, "RINGING"); break; case TelephonyManager.CALL_STATE_OFFHOOK: Log.d(This.LOG_TAG, "OFFHOOK"); break; case TelephonyManager.CALL_STATE_IDLE: Log.d(This.LOG_TAG, "IDLE"); break; default: Log.d(This.LOG_TAG, "Default: " + state); break; } } }, PhoneStateListener.LISTEN_CALL_STATE); 

    Voyez-vous l'argument "incomingNumber"? Oui, ce code ne peut que détecter votre état d'appel téléphonique lorsqu'il y a un appel entrant dans votre appareil.

    Vous pourriez faire ce qui suit … pas très précis mais pourrait faire l'affaire:

    1. Vous utilisez le récepteur pour l'action android.intent.action.NEW_OUTGOING_CALL
    2. Lorsque le récepteur est appelé vous stockez quelque part (par exemple, un var statique), l'état NEW_OUTGOIN_CALL et l'heure en ms lorsque cela s'est produit (c.-à-d. Nouvelle Date (). GetTime ())
    3. Vous utilisez l'autre récepteur pour android.intent.action.PHONE_STATE et dans la rubrique Recevoir, procédez comme suit:

       if (intent.getAction().equals("android.intent.action.PHONE_STATE")) { TelephonyManager telephony = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); telephony.listen(new PhoneStateListener() { public void onCallStateChanged(int state, String incomingNumber) { switch(state) { case TelephonyManager.CALL_STATE_IDLE: break; case TelephonyManager.CALL_STATE_OFFHOOK: break; case TelephonyManager.CALL_STATE_RINGING: break; } } }, PhoneStateListener.LISTEN_CALL_STATE); } 

    Dans l'affaire CALL_STATE_OFFHOOK, vous vérifiez que le dernier état stocké était NEW_OUTGOING_CALL et que le maximum d'aprox. 10 secondes se sont écoulées depuis le dernier changement d'état. Cela signifie que le téléphone a lancé un appel il y a environ 10 secondes et que maintenant il est dans l'état offhook (c'est-à-dire l'appel actif) sans passer par le ralenti ou la sonnerie. Cela pourrait signifier que l'appel a été répondu.

    Ici, votre réponse est que vous avez implémenté CallStateListener dans OutGoingCallReceiver qui est faux. Vous devez implémenter CallStateListener dans PhoneStateListener

    J'ai également essayé cette chose dans mon projet précédent, j'avais fait face au même problème, alors je l'ai résolu comme ci-dessous. J'ai pris 3 classes comme ci-dessous.

    1. AutoCallReceiver: Enregistrez le TelephonyManager avec PhoneStateListener.LISTEN_CALL_STATE

    2. CallStateListener qui écoute trois états comme TelephonyManager.CALL_STATE_IDLE, TelephonyManager.CALL_STATE_OFFHOOK, TelephonyManager.CALL_STATE_RINGING

    3.OutGoingCallReceiver qui traite l'appel

     public class OutGoingCallReceiver extends BroadcastReceiver { /* onReceive will execute on out going call */ @Override public void onReceive(Context context, Intent intent) { Toast.makeText(context, "OutGoingCallReceiver", Toast.LENGTH_SHORT).show(); } } 

     public class CallStateListener extends PhoneStateListener { String number=""; // variable for storing incoming/outgoing number Context mContext; // Application Context //Constructor that will accept Application context as argument public CallStateListener(Context context) { mContext=context; } // This function will automatically invoke when call state changed public void onCallStateChanged(int state,String incomingNumber) { boolean end_call_state=false; // this variable when true indicate that call is disconnected switch(state) { case TelephonyManager.CALL_STATE_IDLE: // Handling Call disconnect state after incoming/outgoing call Toast.makeText(mContext, "idle", Toast.LENGTH_SHORT).show(); break; case TelephonyManager.CALL_STATE_OFFHOOK: // Handling outgoing call Toast.makeText(mContext, "OFFHOOK", Toast.LENGTH_SHORT).show(); // saving outgoing call state so that after disconnect idle state can act accordingly break; case TelephonyManager.CALL_STATE_RINGING: Toast.makeText(mContext, "RINGING", Toast.LENGTH_SHORT).show(); break; } } } 

     public class AutoCallReceiver extends BroadcastReceiver { /* onReceive will execute on call state change */ @Override public void onReceive(Context context, Intent intent) { // Instantiating PhoneStateListener CallStateListener phoneListener=new CallStateListener(context); // Instantiating TelephonyManager TelephonyManager telephony = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); // Registering the telephony to listen CALL STATE change telephony.listen(phoneListener,PhoneStateListener.LISTEN_CALL_STATE); } 

    }

      <receiver android:name=".OutGoingCallReceiver"> <intent-filter> <action android:name="android.intent.action.NEW_OUTGOING_CALL" /> </intent-filter> </receiver> <receiver android:name=".AutoCallReceiver"> <intent-filter> <action android:name="android.intent.action.PHONE_STATE" /> </intent-filter> </receiver> </application> <uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS"/> 
    coAndroid est un fan Android de Google, tout sur les téléphones Android, Android Wear, Android Dev et Android Games Apps.