Uso de BroadcastReceiver con funcionalidad de PhoneStateListener

Estoy tratando de hacer una aplicación MissCall que envía un mensaje automáticamente cuando se recibe una llamada perdida. Había completado mi aplicación y funcionó bien!
Aquí está el escenario completo:
Problema:
La aplicación estaba funcionando bien, pero cuando he reiniciado el dispositivo de la aplicación no funcionó! . Sólo funcionó cuando empecé mi aplicación al menos una vez después de que funcionó bien hasta que se apaga.
Aquí está mi código:

package com.example.misscallapp; import android.content.Context; import android.content.Intent; import android.os.Bundle; import android.preference.PreferenceActivity; import android.telephony.PhoneStateListener; import android.telephony.TelephonyManager; import android.widget.Toast; public class Pref_Main extends PreferenceActivity { int checkIt = 0; TelephonyManager tm; CallStateListener callStateListener = new CallStateListener(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); addPreferencesFromResource(R.xml.prefs); tm = (TelephonyManager) getBaseContext().getSystemService( Context.TELEPHONY_SERVICE); tm.listen(callStateListener, PhoneStateListener.LISTEN_CALL_STATE); } private class CallStateListener extends PhoneStateListener { @Override public void onCallStateChanged(int state, String incomingNumber) { // Is called whenever there is a change in call state switch (state) { case TelephonyManager.CALL_STATE_RINGING: // called when someone is ringing to this phone Toast.makeText(getBaseContext(), "Incoming: " + incomingNumber, Toast.LENGTH_LONG).show(); checkIt = 1; break; case TelephonyManager.CALL_STATE_OFFHOOK: checkIt = 0; break; case TelephonyManager.CALL_STATE_IDLE: if (checkIt == 1) { Intent i = new Intent(getBaseContext(),MyService.class); i.putExtra("phno", incomingNumber); startService(i); // service that sends the SMS } break; } } } } 

Solución:
Descubrí que la solución a esto es utilizar BroadcastReceiver . Así que registré un BroadcastReceiver pero no me dio la funcionalidad de PhoneStateListener
Por ejemplo, traté de usar el código siguiente, pero no funcionó, ya que BroadcastReceivers sólo se llaman cuando recibe algo en contraste con PhoneStateListener que llama al método onCallStateChanged siempre que haya un cambio en el estado de la llamada:

 package com.example.misscallapp; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.os.Bundle; import android.telephony.TelephonyManager; import android.widget.Toast; public class CallReceiverBroadcast extends BroadcastReceiver { int checkIt = 0; @Override public void onReceive(Context context, Intent intent) { Bundle extras = intent.getExtras(); if (extras != null) { String state = extras.getString(TelephonyManager.EXTRA_STATE); String incomingNumber = extras.getString(TelephonyManager.EXTRA_INCOMING_NUMBER); if (state.equals(TelephonyManager.EXTRA_STATE_RINGING)) { Toast.makeText(context , "Incoming: " + incomingNumber, Toast.LENGTH_LONG).show(); checkIt = 1; } if (state.equals(TelephonyManager.EXTRA_STATE_OFFHOOK)) { // Call received checkIt = 0; } if (state.equals(TelephonyManager.EXTRA_STATE_IDLE)) { if (checkIt == 1) { Toast.makeText(context , "This is not shown ", Toast.LENGTH_LONG).show(); Intent i = new Intent(context,MyService.class); i.putExtra("phno", incomingNumber); context.startService(i); } } } } } 

También intenté un trabajo alrededor pero demostró resultados negativos como:

 package com.example.misscallapp; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.telephony.PhoneStateListener; import android.telephony.TelephonyManager; import android.widget.Toast; public class CallReceiverBroadcast extends BroadcastReceiver { int checkIt = 0; Context contextt; TelephonyManager tm; CallStateListener callStateListener = new CallStateListener(); @Override public void onReceive(Context context, Intent intent) { contextt = context; tm = (TelephonyManager) context.getSystemService( Context.TELEPHONY_SERVICE); tm.listen(callStateListener, PhoneStateListener.LISTEN_CALL_STATE); } private class CallStateListener extends PhoneStateListener { @Override public void onCallStateChanged(int state, String incomingNumber) { switch (state) { case TelephonyManager.CALL_STATE_RINGING: // called when someone is ringing to this phone Toast.makeText(contextt, "Incoming: " + incomingNumber, Toast.LENGTH_LONG).show(); checkIt = 1; break; case TelephonyManager.CALL_STATE_OFFHOOK: checkIt = 0; break; case TelephonyManager.CALL_STATE_IDLE: if (checkIt == 1) { //startting the service break; } } } } } 

El código anterior cumple todos los requisitos pero envía la progresión en arithematic como si es la primera llamada de falta envía 1 y si es décima, entonces envía 10 mensajes!
Necesito seriamente ayuda en esto, Gracias de antemano.

Editar 1:
El problema es que cada vez que se llama al método onReceive() instance is created una nueva instance is created de TelphoneManager y se registra como un oyente en el estado de Phoone.
Solución:
Hice cada variable de la clase CallReceiverBroadcast estática ! Y resolvió el problema !! En cierta medida, pero todavía el servicio se llama dos veces cada vez que significa que algunos cómo hay 2 instancia de la clase registrada como un oyente, pero no sé por qué. Aunque puedo trabajar alrededor de él a través de alguna condición pero está causando la sobrecarga innecesaria y cualquier persona que tiene una mejor solución será muy apreciada .

Esto se debe a una vez que recibió la llamada de la falta entonces usted está en la etapa de TelephonyManager.CALL_STATE_IDLE y el mensaje enviará al mensaje apropiado pero su servicio está funcionando modo que es porqué él enviará 10 o sms múltiples.

Intente crear un receptor bootbroadcast, y en su inicio reciba el servicio para detectar llamadas. Esto garantiza que su servicio se active automáticamente después de cada reinicio del dispositivo.

En la primera versión, el oyente no se reinicia automáticamente en arranque (y también podría ser eliminado por el sistema) y es por eso que no funcionó en el arranque. También se olvidó de anular el registro del oyente.

En su segunda versión, onReceive() debe llamar siempre que haya cambios de estado del teléfono, siempre que su Manifiesto esté configurado correctamente, como

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

Sin embargo, Android puede reciclar el receptor de difusión entre las llamadas a onReceive() , lo que significa que su variable checkIt no se puede conservar entre las llamadas a onReceive() . Es posible que necesite utilizar una variable estática para que funcione.

En su tercera versión, está creando y registrando una versión múltiple del oyente de estado de llamada cuando se llama onReceive() . (Tenga en cuenta que tm debe apuntar a la misma instancia de administrador de telefonía), que puede ser la razón por la que se llaman varias veces.

Dependiendo de cómo se convierten las variables en estáticas, el problema puede no ser resuelto ya que todavía puede estar creando / registrar nuevas instancias de CallStateListener , aunque lo almacena en una variable estática.

Para solucionar estos problemas, debe anular el registro del detector de estado de llamada mediante la onDestroy() del receptor de difusión

 @Override public void onDestroy() { tm.listen(callStateListener, PhoneStateListener.LISTEN_NONE); } 

Sin embargo, tenga en cuenta que no hay garantías de que después de onReceive() devuelve, el proceso que aloja el receptor no se destruye. Su segunda versión que realiza todo el proceso antes de onReceive() es preferible, si puede arreglarlo.

  • SMS recibidos en mi aplicación de SMS y en Hangouts, aunque llamo a abortBroadcast ()
  • El receptor de difusión tarda demasiado en recibir en onReceive () después de que el modo de avión esté apagado / encendido
  • TIMEZONE_CHANGED intención que se recibe cada pocos segundos
  • Android: la actividad se ha filtrado IntentReceiver
  • El receptor de Broadcast de Android no se ejecuta en la aplicación
  • No se puede instanciar el receptor java.lang.ClassNotFoundException
  • Diferencia principal entre el Manifiesto y el Registro Programático de BroadcastReceiver
  • Xamarin.Forms: El receptor de difusión no funciona cuando la aplicación está cerrada
  • Error de Constructor vacío en DeviceAdminReceiver
  • ¿Cómo iniciar la actividad de intentservice?
  • GCM no recibe el mensaje de abajo Android 4
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.