181 Stimmen

Android - Eingehende SMS-Nachrichten abhören

Ich versuche, eine Anwendung zur Überwachung eingehender SMS-Nachrichten zu erstellen und ein Programm über eingehende SMS zu starten, außerdem soll es den Inhalt der SMS lesen.

Arbeitsablauf:

  • SMS an Android-Gerät gesendet
  • selbst ausführbare Anwendung
  • Lesen Sie die SMS-Informationen

283voto

Vineet Shukla Punkte 23835
public class SmsListener extends BroadcastReceiver{

    private SharedPreferences preferences;

    @Override
    public void onReceive(Context context, Intent intent) {
        // TODO Auto-generated method stub

        if(intent.getAction().equals("android.provider.Telephony.SMS_RECEIVED")){
            Bundle bundle = intent.getExtras();           //---get the SMS message passed in---
            SmsMessage[] msgs = null;
            String msg_from;
            if (bundle != null){
                //---retrieve the SMS message received---
                try{
                    Object[] pdus = (Object[]) bundle.get("pdus");
                    msgs = new SmsMessage[pdus.length];
                    for(int i=0; i<msgs.length; i++){
                        msgs[i] = SmsMessage.createFromPdu((byte[])pdus[i]);
                        msg_from = msgs[i].getOriginatingAddress();
                        String msgBody = msgs[i].getMessageBody();
                    }
                }catch(Exception e){
//                            Log.d("Exception caught",e.getMessage());
                }
            }
        }
    }
}

Hinweis: Fügen Sie in Ihrer Manifestdatei die BroadcastReceiver-

<receiver android:name=".listener.SmsListener">
    <intent-filter>
        <action android:name="android.provider.Telephony.SMS_RECEIVED" />
    </intent-filter>
</receiver>

Fügen Sie diese Erlaubnis hinzu:

<uses-permission android:name="android.permission.RECEIVE_SMS" />

77voto

stefan.nsk Punkte 1715

Beachten Sie, dass Ihr Code auf einigen Geräten nicht funktioniert ohne Android:priority="1000" im Absichtsfilter:

<receiver android:name=".listener.SmsListener">
    <intent-filter android:priority="1000">
        <action android:name="android.provider.Telephony.SMS_RECEIVED" />
    </intent-filter>
</receiver>

Und hier sind einige Optimierungen:

public class SmsListener extends BroadcastReceiver{

    @Override
    public void onReceive(Context context, Intent intent) {
        if (Telephony.Sms.Intents.SMS_RECEIVED_ACTION.equals(intent.getAction())) {
            for (SmsMessage smsMessage : Telephony.Sms.Intents.getMessagesFromIntent(intent)) {
                String messageBody = smsMessage.getMessageBody();
            }
        }
    }
}

Hinweis :
Der Wert muss eine ganze Zahl sein, z. B. "100". Höhere Zahlen haben eine höhere Priorität. Der Standardwert ist 0. Der Wert muss größer als -1000 und kleiner als 1000 sein.

Hier ist ein Link.

8voto

Ruchir Baronia Punkte 7135

@Mike M. und ich haben ein Problem mit der akzeptierten Antwort gefunden (siehe unsere Kommentare):

Im Grunde ist es sinnlos, die for-Schleife zu durchlaufen, wenn wir die mehrteilige Nachricht nicht jedes Mal verketten:

for (int i = 0; i < msgs.length; i++) {
    msgs[i] = SmsMessage.createFromPdu((byte[])pdus[i]);
    msg_from = msgs[i].getOriginatingAddress();
    String msgBody = msgs[i].getMessageBody();
}

Beachten Sie, dass wir gerade die msgBody auf den String-Wert des jeweiligen Teils der Nachricht, egal auf welchem Index wir uns befinden, was den ganzen Sinn des Durchlaufens der verschiedenen Teile der SMS-Nachricht nutzlos macht, da er einfach auf den allerletzten Indexwert gesetzt wird. Stattdessen sollten wir verwenden += oder wie Mike bemerkte, StringBuilder :

Alles in allem sieht mein SMS-Empfangscode so aus:

if (myBundle != null) {
    Object[] pdus = (Object[]) myBundle.get("pdus"); // pdus is key for SMS in bundle

    //Object [] pdus now contains array of bytes
    messages = new SmsMessage[pdus.length];
    for (int i = 0; i < messages.length; i++) {
         messages[i] = SmsMessage.createFromPdu((byte[]) pdus[i]); //Returns one message, in array because multipart message due to sms max char
         Message += messages[i].getMessageBody(); // Using +=, because need to add multipart from before also
    }

    contactNumber = messages[0].getOriginatingAddress(); //This could also be inside the loop, but there is no need
}

Ich möchte diese Antwort nur für den Fall geben, dass jemand anderes die gleiche Verwirrung hat.

5voto

Adnan Ahmed Punkte 123

Die akzeptierte Antwort ist richtig und funktioniert auf älteren Android-Versionen, bei denen das Android-Betriebssystem bei der Installation der App nach Berechtigungen fragt. Auf neueren Android-Versionen funktioniert es jedoch nicht sofort, da neuere Android-Betriebssysteme während der Laufzeit nach Berechtigungen fragen, wenn die App diese Funktion benötigt. Um also SMS auf neueren Android-Versionen mit der in der akzeptierten Antwort erwähnten Technik zu empfangen, muss der Programmierer auch Code implementieren, der den Benutzer während der Laufzeit überprüft und nach Berechtigungen fragt. In diesem Fall kann die Funktionalität/Code zur Überprüfung der Berechtigungen in onCreate() der ersten Aktivität der App implementiert werden. Kopieren Sie einfach die folgenden zwei Methoden und fügen Sie sie in Ihre erste Aktivität ein und rufen Sie die Methode checkForSmsReceivePermissions() am Ende von onCreate() auf.

    void checkForSmsReceivePermissions(){
    // Check if App already has permissions for receiving SMS
    if(ContextCompat.checkSelfPermission(getBaseContext(), "android.permission.RECEIVE_SMS") == PackageManager.PERMISSION_GRANTED) {
        // App has permissions to listen incoming SMS messages
        Log.d("adnan", "checkForSmsReceivePermissions: Allowed");
    } else {
        // App don't have permissions to listen incoming SMS messages
        Log.d("adnan", "checkForSmsReceivePermissions: Denied");

        // Request permissions from user 
        ActivityCompat.requestPermissions(this, new String[] {Manifest.permission.RECEIVE_SMS}, 43391);
    }
}

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    if(requestCode == 43391){
        if(grantResults.length>0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){
            Log.d("adnan", "Sms Receive Permissions granted");
        } else {
            Log.d("adnan", "Sms Receive Permissions denied");
        }
    }
}

4voto

Wenn jemand verweist, wie man die gleiche Funktion (Lesen OTP mit empfangenen SMS) auf Xamarin Android wie ich zu tun:

  1. Fügen Sie diesen Code zu Ihrer AndroidManifest.xml-Datei hinzu:

    <receiver android:name=".listener.BroadcastReveiverOTP">
    <intent-filter>
        <action android:name="android.provider.Telephony.SMS_RECEIVED" />
    </intent-filter>
    </receiver>
    <uses-permission android:name="android.permission.RECEIVE_SMS" />
    <uses-permission android:name="android.permission.BROADCAST_SMS" />
    <uses-permission android:name="android.permission.READ_SMS" />
  2. Erstellen Sie dann Ihre BroadcastReveiver-Klasse in Ihrem Android-Projekt.

    [BroadcastReceiver(Enabled = true)] [IntentFilter(new[] { "android.provider.Telephony.SMS_RECEIVED" }, Priority = (int)IntentFilterPriority.HighPriority)] 
    public class BroadcastReveiverOTP : BroadcastReceiver {
            public static readonly string INTENT_ACTION = "android.provider.Telephony.SMS_RECEIVED";
    
            protected string message, address = string.Empty;
    
            public override void OnReceive(Context context, Intent intent)
            {
                if (intent.HasExtra("pdus"))
                {
                    var smsArray = (Java.Lang.Object[])intent.Extras.Get("pdus");
                    foreach (var item in smsArray)
                    {
                        var sms = SmsMessage.CreateFromPdu((byte[])item);
                        address = sms.OriginatingAddress;
                        if (address.Equals("NotifyDEMO"))
                        {
                            message = sms.MessageBody;
                            string[] pin = message.Split(' ');
                            if (!string.IsNullOrWhiteSpace(pin[0]))
                            { 
                                    // NOTE : Here I'm passing received OTP to Portable Project using MessagingCenter. So I can display the OTP in the relevant entry field.
                                    MessagingCenter.Send<object, string>(this,MessengerKeys.OnBroadcastReceived, pin[0]);
                            }
                            }
                    }
                }
            }
    }
  3. Registrieren Sie diese BroadcastReceiver-Klasse in Ihrer MainActivity-Klasse im Android-Projekt:

    public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity {
    
            // Initialize your class
            private BroadcastReveiverOTP _receiver = new BroadcastReveiverOTP ();
    
            protected override void OnCreate(Bundle bundle) { 
                    base.OnCreate(bundle);
    
                    global::Xamarin.Forms.Forms.Init(this, bundle);
                    LoadApplication(new App());
    
                    // Register your receiver :  RegisterReceiver(_receiver, new IntentFilter("android.provider.Telephony.SMS_RECEIVED"));
    
            }
    }

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X