Android, Téléphonymanager, les joies de PhoneStateListener et les numéros entrants

j'ai très récemment eu Android développement, et a décidé que ma première conquête sur ce nouveau champ d'appréhender la manière dont le téléphone a réagi aux appels entrants.

un petit googling plus tard m'a conduit à http://www.compiletimeerror.com/2013/08/android-call-state-listener-example.html#.Vi3Ren4vfwM (donc mon code Partage une ressemblance frappante avec le sien).

Ma principale (et unique) de l'activité ressemble à ceci:

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.view.Menu;
import android.widget.Toast;

public class MainActivity extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    TelephonyManager TelephonyMgr = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
    TelephonyMgr.listen(new TeleListener(),
            PhoneStateListener.LISTEN_CALL_STATE);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.activity_main, menu);
    return true;
}
class TeleListener extends PhoneStateListener {
    public void onCallStateChanged(int state, String incomingNumber) {
        super.onCallStateChanged(state, incomingNumber);
        switch (state) {
            case TelephonyManager.CALL_STATE_IDLE:
                // CALL_STATE_IDLE;
                Log.d("MyLittleDebugger", "I'm in " + state + " and the number is " + incomingNumber);
                Toast.makeText(getApplicationContext(), "CALL_STATE_IDLE",
                        Toast.LENGTH_LONG).show();
                break;
            case TelephonyManager.CALL_STATE_OFFHOOK:
                // CALL_STATE_OFFHOOK;
                Log.d("MyLittleDebugger", "I'm in " + state + " and the number is " + incomingNumber);
                Toast.makeText(getApplicationContext(), "CALL_STATE_OFFHOOK",
                        Toast.LENGTH_LONG).show();
                break;
            case TelephonyManager.CALL_STATE_RINGING:
                // CALL_STATE_RINGING
                Log.d("MyLittleDebugger", "I'm in " + state + " and the number is " + incomingNumber);
                Toast.makeText(getApplicationContext(), incomingNumber,
                        Toast.LENGTH_LONG).show();
                Toast.makeText(getApplicationContext(), "CALL_STATE_RINGING",
                        Toast.LENGTH_LONG).show();
                break;
            default:
                break;
        }
    }

}
}

Maintenant, voici où le plaisir s'arrête. J'ai eu l'app en cours d'exécution sur émulateur, et utilisé DDMS pour intercepter quelques appels à mon appareil émulé pour voir où les pièces ont atterri.

Et sûrement assez de pain grillé sauté vers le haut et MyLittleDebugger déferla sur l'état des swaps. L'auditeur travaillait, mais aucun numéro ne figurait dans mon journal de bord ou mon toast.

c'était juste un blanc où le numéro aurait dû être! Pas nul ou quoi que ce soit, non, mais vide!

après un peu plus de googling, Je rendu compte que mon AndroidManifest.xml pourrait être le problème. Elle est comme suit:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.x.xy" >

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

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:supportsRtl="true"
    android:theme="@style/AppTheme" >
    <activity android:name=".MainActivity" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
</application>

maintenant, voici la question: qu'est-ce que je rate?

clairement, une petite fraction d'un quelque chose a mal tourné quelque part, parce que je suis capable d'avoir mon TelephonyMgr objet .listen() pour appeler les États, mais je ne peux pas obtenir le numéro à montrer.

Nouvelles informations:

j'ai aussi essayé sur mon téléphone, sans l'émulation au même résultat.

13
demandé sur ViRALiC 2015-10-26 10:35:56

3 réponses

vous avez probablement besoin de faire usage du récepteur de radiodiffusion qui peut vous aider ce que vous essayez de réaliser. créer la classe étendant récepteur de radiodiffusion et dans cela essayer d'attraper le nombre entrant.

public class MyReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(final Context context, Intent intent) {
        TelephonyManager mtelephony = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
        mtelephony.listen(new PhoneStateListener(){
            @Override
            public void onCallStateChanged(int state, String incomingNumber) {
                super.onCallStateChanged(state, incomingNumber);
               switch (state) {
                 case TelephonyManager.CALL_STATE_RINGING:
                // CALL_STATE_RINGING
                Log.d("MyLittleDebugger", "I'm in " + state + " and the number is " + incomingNumber);
            Toast.makeText(getApplicationContext(), incomingNumber,
                    Toast.LENGTH_LONG).show();
            Toast.makeText(getApplicationContext(), "CALL_STATE_RINGING",
                    Toast.LENGTH_LONG).show();
            break;
        default:
            break;
               }   
            }
        },PhoneStateListener.LISTEN_CALL_STATE);
    }
        <receiver android:name=".MyReceiver" >
            <intent-filter>
                <action android:name="android.intent.action.PHONE_STATE" />
            </intent-filter>
        </receiver>
4
répondu dawncode 2015-11-02 09:17:53

je n'ai pas utilisé le listen fonction de TelephonyManager, mais j'ai utilisé avec succès un émetteur-récepteur pour obtenir les changements d'état du téléphone et le numéro de téléphone.

Enregistrer le récepteur dans l'Activité ou dans le Manifeste (si vous souhaitez recevoir des mises à jour lorsque l'application est en arrière-plan):

Activité:

@Override
protected void onResume() {
     super.onResume();
     BroadcastReceiver receiver = new PhoneStateBroadcastReceiver();
     IntentFilter filter= new IntentFilter();
     filter.addAction("android.intent.action.PHONE_STATE");
     filter.addAction("android.intent.action.NEW_OUTGOING_CALL");
     registerReceiver(reciever, filter);
}

@Override
protected void onPause() {
    super.onPause();
    unregisterReceiver(reciever);
 }  

manifeste:

<receiver
    android:name=".PhoneStateBroadcastReceiver"
    android:permission="android.permission.READ_PHONE_STATE" >
    <intent-filter>
        <action android:name="android.intent.action.PHONE_STATE" />
        <action android:name="android.intent.action.NEW_OUTGOING_CALL" />
    </intent-filter>
</receiver>

et un récepteur de base:

public class PhoneStateBroadcastReceiver extends BroadcastReceiver {
   private final String TAG = getClass().getName();
   private static String number = null;

   @Override
   public void onReceive(final Context context, final Intent intent) {
      if (intent.getAction().equals(TelephonyManager.ACTION_PHONE_STATE_CHANGED)) {
         String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
         Log.d(TAG, intent.getAction() + ", EXTRA_STATE: " + state);
         // on ringing get incoming number
         if (state.equals(TelephonyManager.EXTRA_STATE_RINGING)) {
            number = intent.getStringExtra(TelephonyManager.EXTRA_INCOMING_NUMBER);
            Log.d(TAG, "EXTRA_INCOMING_NUMBER: " + number);

         }
      }

      if (intent.getAction().equals(Intent.ACTION_NEW_OUTGOING_CALL)) {
         number = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
         Log.d(TAG, intent.getAction() + ", EXTRA_PHONE_NUMBER: " + number);
      }

   }

}

et dans cette SORTE de réponse, vous pouvez trouver une belle mise en œuvre qui traite également les appels multiples: https://stackoverflow.com/a/15564021/348378

4
répondu Raanan 2017-05-23 12:02:23

je vous conseille d'exécuter votre application sur un téléphone!

il y a plusieurs raisons pour lesquelles un numéro de téléphone n'est pas disponible sur toutes les notifications, mais vous avez une bien meilleure chance d'en avoir un si l'appel provient d'un réseau téléphonique réel qui peut fournir le numéro.

3
répondu zmarties 2015-10-29 09:57:48