安卓ߝ监听传入的短信

发布于 2024-11-30 08:50:22 字数 141 浏览 3 评论 0原文

我正在尝试创建一个应用程序来监视传入的短信,并通过传入的短信启动一个程序,它也应该从短信中读取内容。

工作流程:

  • 短信发送到Android设备
  • 自可执行应用程序
  • 读取短信信息

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.

Workflow:

  • SMS sent to Android device
  • self executable Application
  • Read the SMS information

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(10

甩你一脸翔 2024-12-07 08:50:22
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" />
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" />
妄断弥空 2024-12-07 08:50:22

请注意,在某些设备上,如果意图过滤器中没有 android:priority="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。

这里是一个链接。

Note that on some devices your code wont work without android:priority="1000" in intent filter:

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

And here is some optimizations:

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();
            }
        }
    }
}

Note:
The value must be an integer, such as "100". Higher numbers have a higher priority. The default value is 0. The value must be greater than -1000 and less than 1000.

Here's a link.

旧话新听 2024-12-07 08:50:22

@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 消息的不同部分的整个点毫无用处,因为它只会被设置为最最后的索引值。相反,我们应该使用 +=,或者如 Mike 所说,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
}

只是把这个答案放在那里以防其他人有同样的困惑。

@Mike M. and I found an issue with the accepted answer (see our comments):

Basically, there is no point in going through the for loop if we are not concatenating the multipart message each time:

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();
}

Notice that we just set msgBody to the string value of the respective part of the message no matter what index we are on, which makes the entire point of looping through the different parts of the SMS message useless, since it will just be set to the very last index value. Instead we should use +=, or as Mike noted, StringBuilder:

All in all, here is what my SMS receiving code looks like:

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
}

Just putting this answer out there in case anyone else has the same confusion.

や三分注定 2024-12-07 08:50:22

接受的答案是正确的,并且适用于旧版本的 Android,其中 Android 操作系统在应用程序安装时请求权限,但是在较新版本的 Android 上,它不能立即工作,因为当应用程序需要该功能时,较新的 Android 操作系统会在运行时请求权限。因此,为了使用接受的答案中提到的技术在较新版本的 Android 上接收短信,程序员还必须实现在运行时检查并请求用户权限的代码。在这种情况下,权限检查功能/代码可以在应用程序第一个活动的 onCreate() 中实现。只需在第一个活动中复制并粘贴以下两个方法,然后在 onCreate() 末尾调用 checkForSmsReceivePermissions() 方法。

    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");
        }
    }
}

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");
        }
    }
}
じ违心 2024-12-07 08:50:22

如果有人像我一样在 Xamarin Android 上参考如何执行相同的功能(使用收到的短信读取 OTP):

  1. 将此代码添加到您的 AndroidManifest.xml 文件中:

    <接收器 android:name=".listener.BroadcastReveiverOTP">
    <意图过滤器>
        />
    
    
    >
    >
    >
    
  2. 然后在您的 Android 项目中创建您的 BroadcastReveiver 类。

    [BroadcastReceiver(Enabled = true)] [IntentFilter(new[] { "android.provider.Telephony.SMS_RECEIVED" }, Priority = (int)IntentFilterPriority.HighPriority)] 
    公共类 BroadcastReveiverOTP : BroadcastReceiver {
            公共静态只读字符串 INTENT_ACTION = "android.provider.Telephony.SMS_RECEIVED";
    
            受保护的字符串消息,地址= string.Empty;
    
            公共覆盖无效OnReceive(上下文上下文,意图意图)
            {
                if (intent.HasExtra("pdus"))
                {
                    var smsArray = (Java.Lang.Object[])intent.Extras.Get("pdus");
                    foreach(smsArray 中的 var 项目)
                    {
                        var sms = SmsMessage.CreateFromPdu((byte[])item);
                        地址 = sms.OriginatingAddress;
                        if (地址.Equals("NotifyDEMO"))
                        {
                            消息 = sms.MessageBody;
                            string[] pin = message.Split(' ');
                            if (!string.IsNullOrWhiteSpace(pin[0]))
                            { 
                                    // 注意:这里我使用 MessagingCenter 将收到的 OTP 传递到 Portable Project。这样我就可以在相关输入字段中显示 OTP。
                                    MessagingCenter.Send(this,MessengerKeys.OnBroadcastReceived, pin[0]);
                            }
                            }
                    }
                }
            }
    }
    
  3. 在 Android 项目的 MainActivity 类中注册此 BroadcastReceiver 类:

    公共类MainActivity:global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity {
    
            // 初始化你的类
            私有 BroadcastReveiverOTP _receiver = new BroadcastReveiverOTP ();
    
            受保护的覆盖无效OnCreate(Bundle捆绑){ 
                    Base.OnCreate(bundle);
    
                    全局::Xamarin.Forms.Forms.Init(this,bundle);
                    加载应用程序(新应用程序());
    
                    // 注册您的接收器 : RegisterReceiver(_receiver, new IntentFilter("android.provider.Telephony.SMS_RECEIVED"));
    
            }
    }
    

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"));
    
            }
    }
    
将军与妓 2024-12-07 08:50:22

如果您想处理打开的活动的意图,您可以使用 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) {
        }
    }
} 

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" />

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" />
給妳壹絲溫柔 2024-12-07 08:50:22

感谢@Vineet Shukla(已接受的答案)和@Ruchir Baronia(在已接受的答案中发现了问题),以下是 Kotlin 版本:

添加权限:

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

在 AndroidManifest 中注册 BroadcastReceiver:

<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>

添加 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) {
                }
            }
        }
    }
}

有时事件会触发两次,因此我添加 mLastTimeReceived = System.currentTimeMillis()

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()

太傻旳人生 2024-12-07 08:50:22

从现在开始,如果您不是默认的短信应用程序,则几乎不可能发布具有 android.permission.RECEIVE_SMS 权限的应用程序。谷歌提供了一个新的短信捕获工具==> 使用 SMS Retriever API 进行自动短信验证

Since some time now, it becomes nearly impossible to publish an app with the android.permission.RECEIVE_SMS permission, if you are not a default sms app. Google provide a new tool for SMS catching ==> Automatic SMS Verification with the SMS Retriever API

荒人说梦 2024-12-07 08:50:22

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
    }
}

注意:在清单文件中添加 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" />

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" />
陌上芳菲 2024-12-07 08:50:22

如果您使用 Kotlin,这里是一个示例

package com.smsforall.smsforall.receivesms

import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.provider.Telephony
import android.provider.Telephony.Sms.Intents.SMS_RECEIVED_ACTION
import com.smsforall.smsforall.data.local.AppPreferences

class IncomingSMSBroadcastReceiver : BroadcastReceiver() {

    override fun onReceive(context: Context, intent: Intent) {
        if (intent.action == SMS_RECEIVED_ACTION) {

            val smsMessages =
                Telephony.Sms.Intents.getMessagesFromIntent(intent)

            val phoneNumber = smsMessages[0].displayOriginatingAddress

            val smsMessageBuilder = StringBuilder()

            for (message in smsMessages) {
                smsMessageBuilder.append(message.displayMessageBody)
                smsMessageBuilder.append("\n")
            }

            val firebaseToken = AppPreferences(context).firebaseToken

            PostReceivedSMSWorkManager.run(phoneNumber, smsMessageBuilder.toString(), firebaseToken)
        }
    }
}

权限

        <receiver
            android:name="com.smsforall.smsforall.receivesms.IncomingSMSBroadcastReceiver"
            android:enabled="true"
            android:exported="true"
            android:permission="android.permission.BROADCAST_SMS">
            <intent-filter>
                <category android:name="android.intent.category.DEFAULT" />
                <action android:name="android.provider.Telephony.SMS_RECEIVED" />
            </intent-filter>
        </receiver>

在这个示例中,我将收到的相同短信发布到外部 API 中,以便我可以在浏览器中查看它们,您可以在以下存储库中获取所有源代码:

< a href="https://github.com/heridev/sms-mobile-hub" rel="nofollow noreferrer">https://github.com/heridev/sms-mobile-hub

如果您愿意安装所有后端 API 和前端您可以访问官方下载部分 https://smsforall.org

If you are using Kotlin, here is an example

package com.smsforall.smsforall.receivesms

import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.provider.Telephony
import android.provider.Telephony.Sms.Intents.SMS_RECEIVED_ACTION
import com.smsforall.smsforall.data.local.AppPreferences

class IncomingSMSBroadcastReceiver : BroadcastReceiver() {

    override fun onReceive(context: Context, intent: Intent) {
        if (intent.action == SMS_RECEIVED_ACTION) {

            val smsMessages =
                Telephony.Sms.Intents.getMessagesFromIntent(intent)

            val phoneNumber = smsMessages[0].displayOriginatingAddress

            val smsMessageBuilder = StringBuilder()

            for (message in smsMessages) {
                smsMessageBuilder.append(message.displayMessageBody)
                smsMessageBuilder.append("\n")
            }

            val firebaseToken = AppPreferences(context).firebaseToken

            PostReceivedSMSWorkManager.run(phoneNumber, smsMessageBuilder.toString(), firebaseToken)
        }
    }
}

And the permissions

        <receiver
            android:name="com.smsforall.smsforall.receivesms.IncomingSMSBroadcastReceiver"
            android:enabled="true"
            android:exported="true"
            android:permission="android.permission.BROADCAST_SMS">
            <intent-filter>
                <category android:name="android.intent.category.DEFAULT" />
                <action android:name="android.provider.Telephony.SMS_RECEIVED" />
            </intent-filter>
        </receiver>

In this example I'm posting the same SMS received into an external API so I can see them in a browser, you can get all the source code in the following repository:

https://github.com/heridev/sms-mobile-hub

and if you want to install all the backend API and frontend application you can visit the official download section at https://smsforall.org

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文