Android – Listen For Incoming SMS Messages

后端 未结 9 1459
情话喂你
情话喂你 2020-11-22 07:06

I am trying to create an application for monitoring incoming SMS messages, and launch a program via incoming SMS, also it should read the content from the SMS.

Workf

相关标签:
9条回答
  • 2020-11-22 07:23

    If someone referring how to do the same feature (reading OTP using received SMS) on Xamarin Android like me :

    1. Add this code to your AndroidManifest.xml file :

      <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. Then create your BroadcastReveiver class in your Android Project.

      [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. Register this BroadcastReceiver class in your MainActivity class on Android Project:

      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"));
      
              }
      }
      
    0 讨论(0)
  • 2020-11-22 07:29
    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());
                    }
                }
            }
        }
    }
    

    Note: In your manifest file add the BroadcastReceiver-

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

    Add this permission:

    <uses-permission android:name="android.permission.RECEIVE_SMS" />
    
    0 讨论(0)
  • 2020-11-22 07:29

    broadcast implementation on Kotlin:

     private class SmsListener : BroadcastReceiver() {
        override fun onReceive(context: Context?, intent: Intent?) {
            Log.d(TAG, "SMS Received!")
    
            val txt = getTextFromSms(intent?.extras)
            Log.d(TAG, "message=" + txt)
        }
    
        private fun getTextFromSms(extras: Bundle?): String {
            val pdus = extras?.get("pdus") as Array<*>
            val format = extras.getString("format")
            var txt = ""
            for (pdu in pdus) {
                val smsmsg = getSmsMsg(pdu as ByteArray?, format)
                val submsg = smsmsg?.displayMessageBody
                submsg?.let { txt = "$txt$it" }
            }
            return txt
        }
    
        private fun getSmsMsg(pdu: ByteArray?, format: String?): SmsMessage? {
            return when {
                SDK_INT >= Build.VERSION_CODES.M -> SmsMessage.createFromPdu(pdu, format)
                else -> SmsMessage.createFromPdu(pdu)
            }
        }
    
        companion object {
            private val TAG = SmsListener::class.java.simpleName
        }
    }
    

    Note: In your manifest file add the BroadcastReceiver-

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

    Add this permission:

    <uses-permission android:name="android.permission.RECEIVE_SMS" />
    
    0 讨论(0)
  • 2020-11-22 07:30

    Thank to @Vineet Shukla (the accepted answer) and @Ruchir Baronia (found the issue in the accepted answer), below is the Kotlin version:

    Add permission:

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

    Register BroadcastReceiver in AndroidManifest:

    <receiver
        android:name=".receiver.SmsReceiver"
        android:enabled="true"
        android:exported="true">
        <intent-filter android:priority="2332412">
            <action android:name="android.provider.Telephony.SMS_RECEIVED" />
        </intent-filter>
    </receiver>
    

    Add implementation for BroadcastReceiver:

    class SmsReceiver : BroadcastReceiver() {
        private var mLastTimeReceived = System.currentTimeMillis()
    
        override fun onReceive(p0: Context?, intent: Intent?) {
            val currentTimeMillis = System.currentTimeMillis()
            if (currentTimeMillis - mLastTimeReceived > 200) {
                mLastTimeReceived = currentTimeMillis
    
                val pdus: Array<*>
                val msgs: Array<SmsMessage?>
                var msgFrom: String?
                var msgText: String?
                val strBuilder = StringBuilder()
                intent?.extras?.let {
                    try {
                        pdus = it.get("pdus") as Array<*>
                        msgs = arrayOfNulls(pdus.size)
                        for (i in msgs.indices) {
                            msgs[i] = SmsMessage.createFromPdu(pdus[i] as ByteArray)
                            strBuilder.append(msgs[i]?.messageBody)
                        }
    
                        msgText = strBuilder.toString()
                        msgFrom = msgs[0]?.originatingAddress
    
                        if (!msgFrom.isNullOrBlank() && !msgText.isNullOrBlank()) {
                            //
                            // Do some thing here
                            //
                        }
                    } catch (e: Exception) {
                    }
                }
            }
        }
    }
    

    Sometime event fires twice so I add mLastTimeReceived = System.currentTimeMillis()

    0 讨论(0)
  • 2020-11-22 07:33

    In case you want to handle intent on opened activity, you can use PendintIntent (Complete steps below):

    public class SMSReciver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            final Bundle bundle = intent.getExtras();
            try {
                if (bundle != null) {
                    final Object[] pdusObj = (Object[]) bundle.get("pdus");
                    for (int i = 0; i < pdusObj.length; i++) {
                        SmsMessage currentMessage = SmsMessage.createFromPdu((byte[]) pdusObj[i]);
                        String phoneNumber = currentMessage.getDisplayOriginatingAddress();
                        String senderNum = phoneNumber;
                        String message = currentMessage.getDisplayMessageBody();
                        try {
                            if (senderNum.contains("MOB_NUMBER")) {
                                Toast.makeText(context,"",Toast.LENGTH_SHORT).show();
    
                                Intent intentCall = new Intent(context, MainActivity.class);
                                intentCall.putExtra("message", currentMessage.getMessageBody());
    
                                PendingIntent pendingIntent= PendingIntent.getActivity(context, 0, intentCall, PendingIntent.FLAG_UPDATE_CURRENT);
                                pendingIntent.send();
                            }
                        } catch (Exception e) {
                        }
                    }
                }
            } catch (Exception e) {
            }
        }
    } 
    

    manifest:

    <activity android:name=".MainActivity"
                android:launchMode="singleTask"/>
    <receiver android:name=".SMSReciver">
                <intent-filter android:priority="1000">
                    <action android:name="android.provider.Telephony.SMS_RECEIVED"/>
                </intent-filter>
            </receiver>
    

    onNewIntent:

     @Override
             protected void onNewIntent(Intent intent) {
                    super.onNewIntent(intent);
                    Toast.makeText(this, "onNewIntent", Toast.LENGTH_SHORT).show();
    
                    onSMSReceived(intent.getStringExtra("message"));
    
                }
    

    permissions:

    <uses-permission android:name="android.permission.RECEIVE_SMS" />
    <uses-permission android:name="android.permission.READ_SMS" />
    <uses-permission android:name="android.permission.SEND_SMS" />
    
    0 讨论(0)
  • 2020-11-22 07:34

    The accepted answer is correct and works on older versions of Android where Android OS asks for permissions at the app install, However on newer versions Android it doesn't work straight away because newer Android OS asks for permissions during runtime when the app requires that feature. Therefore in order to receive SMS on newer versions of Android using technique mentioned in accepted answer programmer must also implement code that will check and ask for permissions from user during runtime. In this case permissions checking functionality/code can be implemented in onCreate() of app's first activity. Just copy and paste following two methods in your first activity and call checkForSmsReceivePermissions() method at the end of onCreate().

        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");
            }
        }
    }
    
    0 讨论(0)
提交回复
热议问题