如何从广播接收器发送短信并检查其状态?

问题描述 投票:0回答:2

所以这是我的

BroadcastReceiver

public class IncomingSMSListener extends BroadcastReceiver {
private static final String SMS_EXTRA_NAME = "pdus";

@Override
public void onReceive(Context context, Intent intent) {
    SmsMessage[] messages = fetchSMSMessagesFromIntent(intent);
}

private SmsMessage[] fetchSMSMessagesFromIntent(Intent intent) {
    ArrayList<SmsMessage> receivedMessages = new ArrayList<SmsMessage>();
    Object[] messages = (Object[]) intent.getExtras().get(SMS_EXTRA_NAME);
    for (Object message : messages) {
        SmsMessage finalMessage = SmsMessage
                .createFromPdu((byte[]) message);
        receivedMessages.add(finalMessage);
    }
    return receivedMessages.toArray(new SmsMessage[0]);
}

}

我能够很好地阅读收到的消息,但是假设从这里我想将消息转发到另一个电话号码并确保它已发送。我知道我可以做到

SmsManager.sendTextMessage()
但如何设置
PendingIntent
部分以通知短信是否已发送?

android sms broadcastreceiver android-pendingintent
2个回答
6
投票

好吧,最终找到了解决方案。由于传递到 BroadCastReceiver 中的 onReceive() 方法的上下文不允许我注册其他 BroadcastReceiver 来侦听“消息发送”事件,因此我最终掌握了应用程序上下文并执行以下操作:

在广播接收器中:

SmsManager smsManager = SmsManager.getDefault();
    Intent intent = new Intent(SENT_SMS_FLAG);
    PendingIntent sentIntent = PendingIntent.getBroadcast(context, 0,
            intent, 0);
    SMSForwarderApp.getAppContext().registerReceiver(
            new MessageSentListener(),
            new IntentFilter(SENT_SMS_FLAG));
    smsManager.sendTextMessage("Here goes the destination of the SMS", null,
            "Here goes the content of the SMS", sentIntent, null);

SENT_SMS_FLAG 只是一个静态字符串,唯一标识我刚刚发出的意图。我的 MessageSentListener 看起来像这样:

public class MessageSentListener extends BroadcastReceiver{

@Override
public void onReceive(Context context, Intent intent) {
    int resultCode = this.getResultCode();
    boolean successfullySent = resultCode == Activity.RESULT_OK;
    //That boolean up there indicates the status of the message
    SMSForwarderApp.getAppContext().unregisterReceiver(this);
            //Notice how I get the app context again here and unregister this broadcast
            //receiver to clear it from the system since it won't be used again
}

}


0
投票

如果其他人像我一样并试图找出如何在 Kotlin 中执行此操作,这里有一些代码可能会帮助您完成任务:

有几点需要注意:

  1. 您只需在模拟器中切换飞行模式即可测试 try/catch
  2. 您可以通过编写超出正常短信字符限制的文本来在模拟器中测试失败的短信
  3. 因为这一切都在 try/catch 块中,所以请注意,由于 API 更改而可能出现的任何异常都不会在 Logcat 窗口中以红色突出显示。
  4. 进一步注意,Google Play 最近对发送短信的应用程序收紧了要求,因此请注意,如果有人打算尝试将此类内容上传到 Google Play,他们可能需要提供大量额外的理由

这是代码(大量改编自美国海军学院网站):

package com.example.texter

import android.app.Activity
import android.app.PendingIntent
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.os.Build
import android.telephony.SmsManager
import android.widget.Toast

class ClassTexter {
    fun mmSendText(mvText: String, mvNumber: String, mvApplicationContext: Context): Boolean {
        //Note: Because The Following Section is wrapped in a try/catch:
        //Exceptions might be trickier to spot in the Logcat since they aren't highlighted red.
        try {
            val mvSmsManager: SmsManager =
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                    mvApplicationContext.getSystemService(SmsManager::class.java)
                } else {
                    SmsManager.getDefault()
                }
            val mvSentIntent = PendingIntent.getBroadcast(
                mvApplicationContext,
                0,
                Intent("SMS SENT"),
                PendingIntent.FLAG_IMMUTABLE
            )
            val mvDelvieredIntent = PendingIntent.getBroadcast(
                mvApplicationContext,
                0,
                Intent("SMS DELIVERED"),
                PendingIntent.FLAG_IMMUTABLE
            )

            val mvConfirmSentBroadcastReceiver: BroadcastReceiver =
                object : BroadcastReceiver() {
                    override fun onReceive(mvContext: Context, mvIntent: Intent) {
                        if (resultCode == Activity.RESULT_OK) {
                            Toast.makeText(
                                mvApplicationContext, "Text Dispatched!",
                                Toast.LENGTH_SHORT
                            ).show()
                        }
                        else
                        {
                            Toast.makeText(
                               mvApplicationContext, "Dispatch Failed!", //<-- This Part Can Be Tested By Exceeding SMS Character Limit
                               Toast.LENGTH_SHORT
                            ).show()
                        }
                    }
                }
            val mvConfirmDeliveryBroadcastReceiver: BroadcastReceiver =
                object : BroadcastReceiver() {
                    override fun onReceive(mvContext: Context, mvIntent: Intent) {
                        if (resultCode == Activity.RESULT_OK) {
                            Toast.makeText(
                                mvApplicationContext, "Text Delivered!",
                                Toast.LENGTH_SHORT
                            ).show()
                        }
                        else
                        {
                            Toast.makeText(
                                mvApplicationContext, "Delivery Failed!",
                                Toast.LENGTH_SHORT
                            ).show()
                        }
                    }
                }

            val mvSentIntentFilter = IntentFilter("SMS SENT")
            val mvDeliveredIntentFilter = IntentFilter("SMS DELIVERED")
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
                mvApplicationContext.registerReceiver(
                    mvConfirmSentBroadcastReceiver,
                    mvSentIntentFilter,
                    Context.RECEIVER_EXPORTED
                )
                mvApplicationContext.registerReceiver(
                    mvConfirmDeliveryBroadcastReceiver,
                    mvDeliveredIntentFilter,
                    Context.RECEIVER_EXPORTED
                )
            } else {
                mvApplicationContext.registerReceiver(
                    mvConfirmSentBroadcastReceiver,
                    mvSentIntentFilter
                )
                mvApplicationContext.registerReceiver(
                    mvConfirmDeliveryBroadcastReceiver,
                    mvDeliveredIntentFilter
                )
            }


            mvSmsManager.sendTextMessage(
                mvNumber.filter { it.isDigit() },
                null,
                mvText,
                mvSentIntent,
                mvDelvieredIntent
            )

            //Confirm With Toast
                Toast.makeText(
                    mvApplicationContext, "Please stand by!",
                    Toast.LENGTH_SHORT
                ).show()

            return true

        } catch (mvEx: Exception) {
            Toast.makeText(
                mvApplicationContext, "Please try again!", //<-- This Part Can Be Tested With "Airplane Mode"
                Toast.LENGTH_LONG
            ).show()
            mvEx.printStackTrace()
            return false
        }
    }
}

希望对路人有帮助!愿上帝保佑平安!

© www.soinside.com 2019 - 2024. All rights reserved.