Android, TelephonyManager, las alegrías de PhoneStateListener y los números entrantes

He llegado muy recientemente al desarrollo de Android , y decidí que mi primera conquista en este campo fresco sería comprender cómo reaccionó el teléfono a las llamadas entrantes.

Un poco de google más tarde me llevó a http://www.compiletimeerror.com/2013/08/android-call-state-listener-example.html#.Vi3Ren4vfwM (por lo que mi código comparte un parecido sorprendente a su / ella).

Mi actividad principal (y única) es la siguiente:

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

Ahora, aquí es donde la diversión se detiene. Conseguí la aplicación que funcionaba en el emulador, y DDMS usado para spoof algunas llamadas de teléfono a mi dispositivo emulado para ver donde las piezas aterrizaron.

Y seguramente bastante tostada apareció y MyLittleDebugger estalló encima de permutas del estado. El oyente estaba trabajando, sin embargo nunca se mostraba ningún número en mi registro o mi tostada.

Estaba en blanco donde el número debería haber sido! No nulo o nada, no, pero en blanco!

Después de un poco más de google, me di cuenta de que mi AndroidManifest.xml podría ser el problema. Es la siguiente:

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

Ahora, aquí está la pregunta: ¿qué me falta?

Claramente, una pequeña fracción de algo ha salido mal en alguna parte, porque puedo tener mi objeto .listen() TelephonyMgr para llamar a estados, pero no puedo conseguir el número para mostrar.

Nueva información:

También he probado esto en mi teléfono, sin emular al mismo resultado.

Es probable que tenga que hacer uso de receptor de difusión que puede ayudarle lo que está tratando de lograr. Crear la clase que extiende el receptor de la difusión y en ese intento para coger el número entrante.

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

Y en su manifiesto esta línea también.

  <receiver android:name=".MyReceiver" > <intent-filter> <action android:name="android.intent.action.PHONE_STATE" /> </intent-filter> </receiver> 

Le aconsejo que ejecute su aplicación en un teléfono de trabajo real!

Hay varias razones por las que un número de teléfono no está disponible en todas las notificaciones, pero usted tiene una probabilidad mucho mayor de que haya una si la llamada es de una red telefónica real que puede proporcionar el número.

No he utilizado la función de listen de TelephonyManager , pero he utilizado correctamente un BroadcastReceiver para obtener los cambios de estado del teléfono y el número de teléfono.

Registre su receptor en la Actividad o en el Manifiesto (si desea recibir actualizaciones cuando la aplicación esté en segundo plano):

Actividad:

 @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); } 

Manifiesto:

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

Y un receptor básico:

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

Y en esta respuesta de SO puede encontrar una buena implementación que también gestiona múltiples llamadas: https://stackoverflow.com/a/15564021/348378

  • Ya que Android 6.0 escuchando los cambios de PhoneStateListener.LISTEN_DATA_CONNECTION_STATE parece que ya no necesita permiso de READ_PHONE_STATE
  • Cómo detectar el estado contestado o rechazado en la llamada saliente
  • ¿Qué información proporciona Baseband en Android?
  • Obtener código de país
  • Cómo determinar una llamada realizada es local o STD O ISD
  • Hacer llamada utilizando una tarjeta SIM especificada en un dispositivo de doble tarjeta SIM
  • Cómo desconectar la llamada en android 4.1.2 nexus programmatically
  • Obtener la velocidad actual de Internet (móvil y Wifi) con Android
  • Recuperar el número de teléfono de la llamada entrante en Android
  • Android Cómo obtener el número de teléfono del teléfono Dual sim
  • Cómo obtener la fuerza de la señal de android
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.