首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >BroadcastReceiver + SMS_RECEIVED

BroadcastReceiver + SMS_RECEIVED
EN

Stack Overflow用户
提问于 2009-12-29 13:28:02
回答 7查看 55.3K关注 0票数 21

我希望我的应用程序能够捕获传入的SMS消息。这里有几个这样的例子。看起来我们只需要这样做:

代码语言:javascript
复制
// AndroidManifest.xml
<receiver android:name=".SMSReceiver"> 
  <intent-filter> 
    <action android:name="android.provider.Telephony.SMS_RECEIVED" /> 
  </intent-filter> 
</receiver>        

// SMSReceiver.java
public class SMSReceiver extends BroadcastReceiver 
{ 
    @Override 
    public void onReceive(Context context, Intent intent) { 
        Log.i(TAG, "SMS received.");
        ....
    }
}

这是正确的吗?我给我的手机发了一些短信,但是日志语句从来没有打印出来。我确实在手机上安装了一些其他的短信应用程序,当收到短信时,它们会显示弹出窗口-它们是不是以某种方式阻止了意图传递到我的应用程序,他们只是完全消费了它?

谢谢

EN

回答 7

Stack Overflow用户

回答已采纳

发布于 2009-12-29 18:27:31

您还需要在清单文件中指定uses权限:

代码语言:javascript
复制
<uses-permission android:name="android.permission.RECEIVE_SMS"/>

以下教程应该会有所帮助:

React on incoming SMS

SMS messaging in Android

票数 30
EN

Stack Overflow用户

发布于 2016-11-12 09:56:39

在此过程中会遇到一些问题。你可以在stackoverflow上找到所有需要的信息。为了方便起见,我已经收集了这个答案中的所有信息。

注意事项

我假设是android

  • 和更高版本。

  • 进入短信的意图是kitkat可以改变意图过滤器的优先级,但这不是必须的。

  • 您需要在清单xml中使用此权限"android.permission.RECEIVE_SMS",才能接收短信。在android 6及以上版本中,你还需要在运行时请求权限。

  • 你不需要在意图过滤器中设置数据的MIME类型。如果没有设置MIME类型,意图过滤器应该只在空数据上传递,但幸运的是,如果MIME.

  • adb shell am broadcast不起作用,它仍然可以工作。使用telnet连接到模拟器来测试短信receiving.

  • Long短信被分成小的短信区块。我们需要将它们连接起来。

如何向仿真器发送sms消息

最重要的事情是有可能发送假短信到设备,所以我们可以测试代码。

为此,我们将使用虚拟设备和到它的telnet连接。

  1. 中创建一个虚拟设备,并在模拟器窗口的标题栏运行simulator
  2. Look。其中包含设备名称和端口号。在接下来的步骤中,我们需要知道此端口号。
  3. 现在使用telnet连接到模拟器标题栏中显示的端口号

$ telnet localhost 5554

  • 如果您看到以下内容:Android Console: Authentication required,则需要使用以下命令对连接进行身份验证:

验证xxxxxx

将上面的xxxxxx替换为从~/.emulator_console_auth_token文件读取的令牌。

  • 现在您应该能够运行所有命令。要发送sms消息,请键入以下命令:

短信发送555“这是一条消息”

您可以将555替换为发件人的电话号码和您自己的消息。

如何收听SMS_RECEIVED广播

要获得广播,您需要注册一个BroadcastReceiver对象。您可以在manifest.xml 中调用registerReceiver函数来完成此操作。我将向您展示后者,因为它更容易推理,也更灵活。

连接广播接收器和主活动的

数据流是单向的。从广播接收器到主要活动。所以让他们说话的最简单的方法就是使用函数接口。活动将实现这样的功能,广播接收器将在构造函数中将活动实例作为参数传递。

文件SmsHandler.java:

代码语言:javascript
复制
package ...

interface SmsHandler {
    void handleSms(String sender, String message);
}

实现广播接收器

广播接收器将在回调中获取意图。我们将使用Telephony.Sms.Intents.getMessagesFromIntent(intent)函数来获取短信。请注意构造函数中的SmsHandler参数。它将是我们将接收到的sms发送到的活动。

文件SmsInterceptor.java:

代码语言:javascript
复制
package ...

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.provider.Telephony;
import android.telephony.SmsMessage;

public class SmsInterceptor extends BroadcastReceiver {

    private SmsHandler handler;

    /* Constructor. Handler is the activity  *
     * which will show the messages to user. */
    public SmsInterceptor(SmsHandler handler) {
        this.handler = handler;
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        /* Retrieve the sms message chunks from the intent */
        SmsMessage[] rawSmsChunks;
        try {
            rawSmsChunks = Telephony.Sms.Intents.getMessagesFromIntent(intent);
        } catch (NullPointerException ignored) { return; }

        /* Gather all sms chunks for each sender separately */
        Map<String, StringBuilder> sendersMap = new HashMap<>();
        for (SmsMessage rawSmsChunk : rawSmsChunks) {
            if (rawSmsChunk != null) {
                String sender = rawSmsChunk.getDisplayOriginatingAddress();
                String smsChunk = rawSmsChunk.getDisplayMessageBody();
                StringBuilder smsBuilder;
                if ( ! sendersMap.containsKey(sender) ) {
                    /* For each new sender create a separate StringBuilder */
                    smsBuilder = new StringBuilder();
                    sendersMap.put(sender, smsBuilder);
                } else {
                    /* Sender already in map. Retrieve the StringBuilder */
                    smsBuilder = sendersMap.get(sender);
                }
                /* Add the sms chunk to the string builder */
                smsBuilder.append(smsChunk);
            }
        }

        /* Loop over every sms thread and concatenate the sms chunks to one piece */
        for ( Map.Entry<String, StringBuilder> smsThread : sendersMap.entrySet() ) {
            String sender  = smsThread.getKey();
            StringBuilder smsBuilder = smsThread.getValue();
            String message = smsBuilder.toString();
            handler.handleSms(sender, message);
        }
    }
}

主活动

最后,我们需要在主活动中实现SmsHandler接口,并在onCreate函数中添加注册广播接收器和权限检查。

文件MainActivity.java:

代码语言:javascript
复制
package ...

import ...

public class MainActivity extends AppCompatActivity implements SmsHandler {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        /* Register the broadcast receiver */
        registerSmsListener();

        /* Make sure, we have the permissions */
        requestSmsPermission();
    }

    /* This function will be called by the broadcast receiver */
    @Override
    public void handleSms(String sender, String message) {
        /* Here you can display the message to the user */
    }

    private void registerSmsListener() {
        IntentFilter filter = new IntentFilter();
        filter.addAction("android.provider.Telephony.SMS_RECEIVED");
        /* filter.setPriority(999); This is optional. */
        SmsInterceptor receiver = new SmsInterceptor(this);
        registerReceiver(receiver, filter);
    }

    private void requestSmsPermission() {
        String permission = Manifest.permission.RECEIVE_SMS;
        int grant = ContextCompat.checkSelfPermission(this, permission);
        if ( grant != PackageManager.PERMISSION_GRANTED) {
            String[] permission_list = new String[1];
            permission_list[0] = permission;
            ActivityCompat.requestPermissions(this, permission_list, 1);
        }
    }
}

最后记得将RECEIVE_SMS权限添加到清单xml中

代码语言:javascript
复制
<?xml version="1.0" encoding="utf-8"?>
<manifest ...>
    <uses-permission android:name="android.permission.RECEIVE_SMS"/>
    <application>
        ...
    </application>
</manifest>
票数 12
EN

Stack Overflow用户

发布于 2013-02-06 11:33:13

还有一件事,这些答案没有提到-你应该需要权限android.permission.BROADCAST_SMS。如果你不这样做,任何应用程序都可以欺骗你的应用程序中的消息。

代码语言:javascript
复制
<receiver android:name=".SMSReceiver"
              android:exported="true"
              android:permission="android.permission.BROADCAST_SMS">
             <intent-filter>
                 <action android:name="android.provider.Telephony.SMS_RECEIVED"/>
             </intent-filter>
 </receiver>
票数 9
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1973071

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档