web-dev-qa-db-fra.com

Android - SMS Récepteur de diffusion

J'ai essayé de faire fonctionner le programme this _ mais je n'ai pas eu de chance jusqu'à présent. Je ne trouve pas où je vais mal. Je ne suis pas sûr si quelque chose ne va pas avec le code, ou le débogage.

J'essaie d'être averti si un nouveau SMS arrive.

Voici mon programme:

package Technicaljar.SMSBroadcastReceiver;

import Android.content.BroadcastReceiver;
import Android.content.Context;
import Android.content.Intent;
import Android.os.Bundle;
import Android.telephony.SmsMessage;
import Android.util.Log;

public class SMSBroadcastReceiver extends BroadcastReceiver {

        private static final String SMS_RECEIVED = "Android.provider.Telephony.SMS_RECEIVED";
        private static final String TAG = "SMSBroadcastReceiver";

        @Override
        public void onReceive(Context context, Intent intent) {
             Log.i(TAG, "Intent recieved: " + intent.getAction());

                if (intent.getAction() == SMS_RECEIVED) {
                    Bundle bundle = intent.getExtras();
                    if (bundle != null) {
                        Object[] pdus = (Object[])bundle.get("pdus");
                        final SmsMessage[] messages = new SmsMessage[pdus.length];
                        for (int i = 0; i < pdus.length; i++) {
                            messages[i] = SmsMessage.createFromPdu((byte[])pdus[i]);
                        }
                        if (messages.length > -1) {
                            Log.i(TAG, "Message recieved: " + messages[0].getMessageBody());
                        }
                    }
                }
           }
    }

Et le fichier manifeste:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:Android="http://schemas.Android.com/apk/res/Android"
      package="Technicaljar.SMSBroadcastReceiver"
      Android:versionCode="1"
      Android:versionName="1.0">
    <application Android:icon="@drawable/icon" Android:label="@string/app_name" Android:debuggable="true" >
        <receiver Android:name=".SMSBroadcastReceiver">
            <intent-filter>
                <action Android:name="Android.provider.telephony.SMS_RECEIVED"></action>
            </intent-filter>
        </receiver>

    </application>
    <uses-sdk Android:minSdkVersion="7" />
    <uses-permission Android:name="Android.permission.INTERNET"></uses-permission>
    <uses-permission Android:name="Android.permission.RECEIVE_SMS"></uses-permission>
</manifest> 

J'envoie SMS via Telnet et je ne vois aucun message d'intention reçu dans le logcat. Voici mon logcat à partir du moment de l'installation.

D/AndroidRuntime(  478): 
D/AndroidRuntime(  478): >>>>>>>>>>>>>> AndroidRuntime START <<<<<<<<<<<<<<
D/AndroidRuntime(  478): CheckJNI is ON
D/AndroidRuntime(  478): --- registering native functions ---
D/AndroidRuntime(  478): Shutting down VM
D/dalvikvm(  478): Debugger has detached; object registry had 1 entries
I/AndroidRuntime(  478): NOTE: attach of thread 'Binder Thread #3' failed
D/Mms:app (  220): getSmsNewMessageNotificationInfo: count=14, first addr=12345, thread_id=4
D/dalvikvm(  151): GC_EXPLICIT freed 391 objects / 22552 bytes in 65ms
D/dalvikvm(  220): GC_EXPLICIT freed 926 objects / 44840 bytes in 73ms

Ainsi, le SMS semble avoir été reçu par l'émulateur, mais il semble que le non-respect ait été déclenché . Après l’installation, dois-je en quelque sorte «démarrer» ce récepteur? Parce que lors de l’installation,

 [2010-11-07 21:24:41 - SMSBroadcastReceiver] No Launcher activity found!
[2010-11-07 21:24:41 - SMSBroadcastReceiver] The launch will only sync the application package on the device!

Je me demande donc si quelque chose ne va pas ici.

51
madu

Android.provider.Telephony.SMS_RECEIVED a une majuscule T, pas le vôtre dans le manifeste.

N'oubliez pas que cette action Intent n'est pas documentée.

70
CommonsWare

J'ai essayé votre code et constaté qu'il ne fonctionnait pas.

Je devais changer 

if (intent.getAction() == SMS_RECEIVED) {

à 

if (intent.getAction().equals(SMS_RECEIVED)) {

Maintenant ça marche. C'est juste un problème avec Java vérifiant l'égalité.

17
anshul

Notez également que l'application Hangouts empêchera actuellement mon BroadcastReceiver de recevoir des messages SMS. Je devais désactiver la fonctionnalité SMS dans l'application Hangouts (Paramètres-> SMS-> Activer SMS) avant que mon SMS BroadcastReceived ne soit déclenché.

Edit: Il semble que certaines applications abandonneront l'intention (abortBroadcast ()), ce qui empêchera d'autres applications de le recevoir. La solution consiste à augmenter l'attribut Android:priority dans la balise intent-filter:

<receiver Android:name="com.company.application.SMSBroadcastReceiver" >
  <intent-filter Android:priority="500">
    <action Android:name="Android.provider.Telephony.SMS_RECEIVED" />
  </intent-filter>
</receiver>

Voir plus de détails ici: L'activation de la prise en charge de SMS dans Hangouts 2.0 interrompt la diffusion du récepteur de SMS_RECEIVED dans mon application

5
TheIT

intent.getAction().equals(SMS_RECEIVED)

J'ai essayé avec succès.

3
Cathy

Je suis tombé sur cela aujourd'hui. Pour ceux qui codent un récepteur SMS de nos jours, utilisez ce code au lieu du code obsolète dans OP:

SmsMessage[] msgs = Telephony.Sms.Intents.getMessagesFromIntent(intent);
SmsMessage smsMessage = msgs[0];
2
kjdion84

Votre récepteur de diffusion doit spécifier Android:exported="true" pour recevoir les émissions créées en dehors de votre propre application. Mon récepteur de diffusion est défini dans le manifeste comme suit:

<receiver
    Android:name=".IncomingSmsBroadcastReceiver"
    Android:enabled="true"
    Android:exported="true" >
    <intent-filter>
        <action Android:name="Android.provider.Telephony.SMS_RECEIVED" />
    </intent-filter>
</receiver>

Comme indiqué ci-dessous, exports = "true" est la valeur par défaut, vous pouvez donc omettre cette ligne. Je l'ai laissé dans pour que les commentaires de discussion aient un sens.

2
Phil

Pour Android 19+, vous pouvez l'obtenir dans Telephony.Sms.Intents.SMS_RECEIVED_ACTION). Il y a plus dans la classe Intents qui vaut la peine d'être regardé

1
peter

Le code mis à jour est:

 private class SMSReceiver extends BroadcastReceiver {
                private Bundle bundle;
                private SmsMessage currentSMS;
                private String message;

                @Override
                public void onReceive(Context context, Intent intent) {

                    if (intent.getAction().equals("Android.provider.Telephony.SMS_RECEIVED")) {
                        bundle = intent.getExtras();
                        if (bundle != null) {
                            Object[] pdu_Objects = (Object[]) bundle.get("pdus");
                            if (pdu_Objects != null) {

                                for (Object aObject : pdu_Objects) {

                                    currentSMS = getIncomingMessage(aObject, bundle);

                                    String senderNo = currentSMS.getDisplayOriginatingAddress();

                                    message = currentSMS.getDisplayMessageBody();
                                    Toast.makeText(OtpActivity.this, "senderNum: " + senderNo + " :\n message: " + message, Toast.LENGTH_LONG).show();
                                }
                                this.abortBroadcast();
                                // End of loop
                            }
                        }
                    } // bundle null
                }
            }

        private SmsMessage getIncomingMessage(Object aObject, Bundle bundle) {
            SmsMessage currentSMS;
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                String format = bundle.getString("format");
                currentSMS = SmsMessage.createFromPdu((byte[]) aObject, format);
            } else {
                currentSMS = SmsMessage.createFromPdu((byte[]) aObject);
            }
    return currentSMS;
}

l'ancien code était:

Object [] pdus = (Object[]) myBundle.get("pdus");

    messages = new SmsMessage[pdus.length];

    for (int i = 0; i < messages.length; i++)
    {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            String format = myBundle.getString("format");
            messages[i] = SmsMessage.createFromPdu((byte[]) pdus[i], format);
        }
        else {
            messages[i] = SmsMessage.createFromPdu((byte[]) pdus[i]);
        }
        strMessage += "SMS From: " + messages[i].getOriginatingAddress();
        strMessage += " : ";
        strMessage += messages[i].getMessageBody();
        strMessage += "\n";
    } 

Le SYntax simple du code est:

private class SMSReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        if (intent.getAction().equals(Telephony.Sms.Intents.SMS_RECEIVED_ACTION)) {
            SmsMessage[] smsMessages = Telephony.Sms.Intents.getMessagesFromIntent(intent);
            for (SmsMessage message : smsMessages) {
                // Do whatever you want to do with SMS.
            }
        }
    }
}
1
Pradeep Sheoran

J'ai rencontré un tel problème récemment. Bien que le code soit correct, je n’ai pas activé les autorisations dans les paramètres de l’application. Ainsi, toutes les autorisations n'ont pas été définies par défaut sur les émulateurs, vous devez donc le faire vous-même. 

1
Dracontis

Android.provider.telephony.SMS_RECEIVED n'est pas correct car la téléphonie est une classe et il devrait être majuscule comme dans Android.provider.Telephony.SMS_RECEIVED

0