Android-прослушивание входящих SMS сообщений
Я пытаюсь создать приложение для мониторинга входящих SMS-сообщений, и запустить программу через входящие SMS, также он должен прочитать содержимое из SMS.
документооборот:
- SMS отправляется на Android устройство
- самостоятельное исполняемое приложение
- прочитайте информацию SMS
6 ответов:
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()); } } } } }Примечание: в файле манифеста добавьте BroadcastReceiver -
<receiver android:name=".listener.SmsListener"> <intent-filter> <action android:name="android.provider.Telephony.SMS_RECEIVED" /> </intent-filter> </receiver>добавить эти разрешения:
<uses-permission android:name="android.permission.RECEIVE_SMS" />
обратите внимание, что на некоторых устройствах код не будет работать без android: приоритет= "1000" в фильтр намерений:
<receiver android:name=".listener.SmsListener"> <intent-filter android:priority="1000"> <action android:name="android.provider.Telephony.SMS_RECEIVED" /> </intent-filter> </receiver>и вот некоторые оптимизации:
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(); } } } }Примечание:
Значение должно быть целым числом, например "100". Более высокие числа имеют более высокий приоритет. Значение по умолчанию-0. Значение должно быть больше 1000 и меньше 1000.
@Mike M. И я нашел проблему с принятым ответом (см. наши комментарии):
в принципе, нет смысла проходить через цикл for, если мы не объединяем составное сообщение каждый раз:
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(); }обратите внимание, что мы только что установили
msgBodyк строковому значению соответствующей части сообщения независимо от того, какой индекс мы находимся, что делает весь смысл циклического перебора различных частей SMS-сообщения бесполезным, так как он будет просто установлен в последнее значение индекса. Вместо этого мы должны использовать+=, или как заметил Майк,StringBuilder:в целом, вот как выглядит мой код получения SMS:
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 }просто положить этот ответ там в случае, если кто-то еще имеет такую же путаницу.
Это то, что я использовал!
public class SMSListener extends BroadcastReceiver { // Get the object of SmsManager final SmsManager sms = SmsManager.getDefault(); String mobile,body; public void onReceive(Context context, Intent intent) { // Retrieves a map of extended data from the 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(); mobile=senderNum.replaceAll("\s",""); body=message.replaceAll("\s","+"); Log.i("SmsReceiver", "senderNum: "+ senderNum + "; message: " + body); // Show Alert int duration = Toast.LENGTH_LONG; Toast toast = Toast.makeText(context, "senderNum: "+ mobile+ ", message: " + message, duration); toast.show(); } // end for loop } // bundle is null } catch (Exception e) { Log.e("SmsReceiver", "Exception smsReceiver" +e); } } }
Если кто-то ссылается, как сделать ту же функцию (чтение OTP с помощью полученного SMS) на Xamarin Android, как я :
добавьте этот код в свой AndroidManifest.xml-файл:
<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" />затем создайте свой класс BroadcastReveiver в своем проекте Android.
[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]); } } } } } }зарегистрируйте этот класс BroadcastReceiver в своем классе MainActivity на 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")); } }
в случае, если вы хотите обрабатывать намерение на открытой деятельности, вы можете использовать PendintIntent (полные шаги ниже):
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) { } } }манифест:
<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" />
Comments