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).
- Cómo encontrar el número saliente en el administrador de telefonía
- Obtener los detalles del último registro de llamadas después de finalizar la llamada utilizando el receptor de difusión
- TelephonyManager devuelve null para el número IMEI: ¿qué puede causar esto?
- Llamada de teléfono de Android Handle
- ¿Cómo puedo enviar un archivo pregrabado (wav) durante una llamada de voz?
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.
- Cómo modificar la vista de la pantalla de llamadas entrantes y salientes en android
- ¿Cómo saber si estoy en una llamada en Android?
- Cómo proporcionar vibraciones personalizadas en las llamadas entrantes específicas
- Cómo averiguar qué SIM recibió SMS en Dual SIM Android Device
- Cómo obtener el número actual de la tarjeta SIM en Android?
- No se puede obtener cadena no vacía de PhoneStateListener :: onCallStateChanged
- ¿Cómo distinguir el estado de encendido / apagado de la pantalla durante la llamada entrante?
- ¿Cómo puedo comprobar si la tarjeta SIM está disponible en un dispositivo Android?
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
- Fragmento reemplazado todavía visible en el fondo
- Calcular el encabezado correcto correctamente en android