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