android - telefono - porque no puedo enviar mensajes de texto a un numero
Tener un servicio recibe mensajes SMS (3)
He visto algunos ejemplos de mensajes SMS y las Actividades se utilizan normalmente para recibir un SMS. Sin embargo, lo que me gustaría hacer es que mi servicio en segundo plano reciba el SMS (el servicio procesará el mensaje y decidirá si es aplicable a la aplicación, luego informar al usuario)
En mi Manifiesto, el servicio se define de la siguiente manera:
<service android:name=".service.myService"
android:enabled="true">
<intent-filter>
<action android:name="package.com.service.myService"/>
</intent-filter>
</service>
Para que el servicio reciba el SMS, ¿funcionará?
<receiver android:name=".service.myService" android:exported="true" >
<intent-filter android:priority="999">
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>
El código de ejemplo que estudié proviene de: http://www.apriorit.com/our-company/dev-blog/227-handle-sms-on-android
No puedo probarlo todavía porque mi módulo de desarrollo no tiene un número de teléfono para enviar un SMS.
Encontré la solución. Para que un Servicio reciba mensajes SMS:
- Actualice el manifiesto para otorgar a su aplicación los permisos para recibir SMS (WRITE_SMS, READ_SMS, RECEIVE_SMS)
- ¡NO actualice el manifiesto con el filtro de intención del receptor! (lo que parece hacer cada código de muestra en línea)
En su Servicio, cree una clase de BroadcastReceiver anidada dentro de su clase de Servicio
private class SMSreceiver extends BroadcastReceiver { private final String TAG = this.getClass().getSimpleName(); @Override public void onReceive(Context context, Intent intent) { Bundle extras = intent.getExtras(); String strMessage = ""; if ( extras != null ) { Object[] smsextras = (Object[]) extras.get( "pdus" ); for ( int i = 0; i < smsextras.length; i++ ) { SmsMessage smsmsg = SmsMessage.createFromPdu((byte[])smsextras[i]); String strMsgBody = smsmsg.getMessageBody().toString(); String strMsgSrc = smsmsg.getOriginatingAddress(); strMessage += "SMS from " + strMsgSrc + " : " + strMsgBody; Log.i(TAG, strMessage); } } } }
En su clase de servicio, regístrese para recibir el filtro de intención
android.provider.Telephony.SMS_RECEIVED
:public class ServiceCommunicator extends Service { private SMSreceiver mSMSreceiver; private IntentFilter mIntentFilter; @Override public void onCreate() { super.onCreate(); //SMS event receiver mSMSreceiver = new SMSreceiver(); mIntentFilter = new IntentFilter(); mIntentFilter.addAction("android.provider.Telephony.SMS_RECEIVED"); registerReceiver(mSMSreceiver, mIntentFilter); } @Override public void onDestroy() { super.onDestroy(); // Unregister the SMS receiver unregisterReceiver(mSMSreceiver); } }
Eso es !
nota: encasado, se pregunta por qué no me vinculé a mi servicio desde una clase BroadcastReceiver por separado, no funciona porque bindService()
no está disponible.
Puede hacer el SmsReceiver por separado del Servicio mediante el contexto del método onReceive para iniciar el servicio. Eso te permite no ejecutar el servicio todo el tiempo. O incluso no iniciar actividad para registrar receptor. Aunque puedo equivocarme.
Algo como esto:
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(SMS_RECEIVED)) {
Bundle bundle = intent.getExtras();
if (bundle != null) {
Object[] pdus = (Object[]) bundle.get("pdus");
if (pdus.length == 0) {
return;
}
SmsMessage[] messages = new SmsMessage[pdus.length];
StringBuilder sb = new StringBuilder();
for (int i = 0; i < pdus.length; i++) {
messages[i] = SmsMessage.createFromPdu((byte[]) pdus[i]);
sb.append(messages[i].getMessageBody());
}
String number = messages[0].getOriginatingAddress();
String messageText = sb.toString();
Intent intent1 = new Intent(context, SMSreceiver.class);
intent1.putExtra(PHONE_NUMBER, number);
intent1.putExtra(SMS_TEXT, messageText);
context.startService(intent1);
}
}
}
Su código parece ser correcto. Podrías probar tu código con el emulador. El emulador también soporta el envío de sms al dispositivo virtual. Vea también la captura de pantalla:
Pantalla de esta respuesta .