Android - 短信广播接收器

61

我一直在尝试让这个程序工作,但至今没有成功。 我找不到我的错误之处。我不确定代码或调试是否有问题。

我正在尝试接收新短信的通知。

这是我的程序:

package Technicaljar.SMSBroadcastReceiver;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.telephony.SmsMessage;
import android.util.Log;

public class SMSBroadcastReceiver extends BroadcastReceiver {

        private static final String SMS_RECEIVED = "android.provider.Telephony.SMS_RECEIVED";
        private static final String TAG = "SMSBroadcastReceiver";

        @Override
        public void onReceive(Context context, Intent intent) {
             Log.i(TAG, "Intent recieved: " + intent.getAction());

                if (intent.getAction() == SMS_RECEIVED) {
                    Bundle bundle = intent.getExtras();
                    if (bundle != null) {
                        Object[] pdus = (Object[])bundle.get("pdus");
                        final SmsMessage[] messages = new SmsMessage[pdus.length];
                        for (int i = 0; i < pdus.length; i++) {
                            messages[i] = SmsMessage.createFromPdu((byte[])pdus[i]);
                        }
                        if (messages.length > -1) {
                            Log.i(TAG, "Message recieved: " + messages[0].getMessageBody());
                        }
                    }
                }
           }
    }

还有清单文件:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="Technicaljar.SMSBroadcastReceiver"
      android:versionCode="1"
      android:versionName="1.0">
    <application android:icon="@drawable/icon" android:label="@string/app_name" android:debuggable="true" >
        <receiver android:name=".SMSBroadcastReceiver">
            <intent-filter>
                <action android:name="android.provider.telephony.SMS_RECEIVED"></action>
            </intent-filter>
        </receiver>

    </application>
    <uses-sdk android:minSdkVersion="7" />
    <uses-permission android:name="android.permission.INTERNET"></uses-permission>
    <uses-permission android:name="android.permission.RECEIVE_SMS"></uses-permission>
</manifest> 

我正在通过Telnet发送短信,但在logcat中没有看到任何接收到的意图消息。这是从安装时开始的我的logcat。

D/AndroidRuntime(  478): 
D/AndroidRuntime(  478): >>>>>>>>>>>>>> AndroidRuntime START <<<<<<<<<<<<<<
D/AndroidRuntime(  478): CheckJNI is ON
D/AndroidRuntime(  478): --- registering native functions ---
D/AndroidRuntime(  478): Shutting down VM
D/dalvikvm(  478): Debugger has detached; object registry had 1 entries
I/AndroidRuntime(  478): NOTE: attach of thread 'Binder Thread #3' failed
D/Mms:app (  220): getSmsNewMessageNotificationInfo: count=14, first addr=12345, thread_id=4
D/dalvikvm(  151): GC_EXPLICIT freed 391 objects / 22552 bytes in 65ms
D/dalvikvm(  220): GC_EXPLICIT freed 926 objects / 44840 bytes in 73ms

看起来短信已经被模拟器接收了,但是似乎没有触发任何意图。我在这里做错了什么?安装后,我是否需要以某种方式“启动”此接收器?因为当我安装时,我得到的是

 [2010-11-07 21:24:41 - SMSBroadcastReceiver] No Launcher activity found!
[2010-11-07 21:24:41 - SMSBroadcastReceiver] The launch will only sync the application package on the device!

所以我想知道这里是否有什么问题。


我正在这里做类似的事情!!! https://dev59.com/j-o6XIcBkEYKwwoYORwV - Etienne Lawlor
你不应该使用 intent.getAction().equals(SMS_RECEIVED) 而不是 intent.getAction() == SMS_RECEIVED - Peter Chaula
9个回答

79

android.provider.Telephony.SMS_RECEIVED 的 T 是大写的,在你的清单文件中不是。

请注意,这个 Intent 操作没有记录在文档中。


1
非常感谢CommonsWare。那就是问题所在。现在它可以正常工作了。谢谢。另外,我可以问一下为什么这个Intent没有记录吗? - madu
5
@Janusz: 不幸的是,99%用于处理短信的代码已经存在于SDK中,而这个常量并不在其中,这表明这个常量不太可能改变。然而,我不记得有任何官方声明支持这种说法,尽管他们有充分的机会将其放入SDK中。短信客户端的开发人员只需要意识到这个问题,并密切关注新的Android发布版本。 - CommonsWare
@CommonsWare非常感谢您的帮助 :) 已经过去四天了,我的广播接收器一直没有被调用。问题很小,只是一个小写字母“t”的问题。这个问题似乎很常见。 - Zeeshan
1
@CommonsWare 发现'T'是Hawk Eye的工作!赞! - Aman Alam
3
这个现在已经在 API 19 中记录在这里:https://developer.android.com/reference/android/provider/Telephony.Sms.Intents.html#SMS_RECEIVED_ACTION - Muhammad Babar
显示剩余6条评论

18

我尝试了你的代码,但发现它并不起作用。

我不得不更改

if (intent.getAction() == SMS_RECEIVED) {

if (intent.getAction().equals(SMS_RECEIVED)) {

现在它正在工作。这只是Java检查相等性的问题。


8
请注意:最好从非空字符串调用.equals(..)方法。例如,if (SMS_RECEIVED.equals(intent.getAction())) { - Yaadm

5

注意,Hangouts应用程序目前将阻止我的广播接收器接收短信消息。在我的SMS BroadcastReceived开始触发之前,我不得不禁用Hangouts应用程序中的SMS功能(设置-> SMS-> 打开SMS)。

编辑:似乎有些应用程序会在意图上调用abortBroadcast(),这将阻止其他应用程序接收意图。解决方法是增加android:priority属性在标签中:

<receiver android:name="com.company.application.SMSBroadcastReceiver" >
  <intent-filter android:priority="500">
    <action android:name="android.provider.Telephony.SMS_RECEIVED" />
  </intent-filter>
</receiver>

查看更多详细信息请点击这里:启用Hangouts 2.0中的短信支持会打破我的应用程序中SMS_RECEIVED的广播接收器


1
请阅读关于查找其他应用程序所做更改的部分以及有关优先级“0”重要性的内容:http://android-developers.blogspot.no/2011/01/processing-ordered-broadcasts.html - Mr. Developerdude

3

intent.getAction().equals(SMS_RECEIVED)

我已经成功试用过了。


3

今天偶然发现了这个。对于现在编写短信接收器的任何人,使用此代码而不是 OP 中已弃用的代码:

SmsMessage[] msgs = Telephony.Sms.Intents.getMessagesFromIntent(intent);
SmsMessage smsMessage = msgs[0];

你需要为此启用运行时权限吗? - Harsha

2

您的广播接收器必须指定 android:exported="true" 才能接收来自应用程序外部创建的广播。我的广播接收器在清单文件中定义如下:

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

如下所述,exported="true" 是默认值,因此您可以省略此行。我保留了它,以使讨论评论有意义。

4
不行。当接收器拥有意图过滤器时,它会自动变为可导出状态。请参阅http://developer.android.com/guide/topics/manifest/receiver-element.html#exported。 - Adam Nybäck
公正的评论。我怀疑这可能在最近的Android版本中已经改变了,我的代码最初是针对Android 4.0开发的。我会更新答案。 - Phil Haigh

1

对于Android 19+,您可以在Telephony.Sms.Intents.SMS_RECEIVED_ACTION中获取它。在Intent类中还有更多值得一看的内容。


1

最近我遇到了这样的问题。尽管代码是正确的,但我没有在应用程序设置中开启权限。因此,默认情况下模拟器上没有设置所有权限,所以您需要自己设置。


0

android.provider.telephony.SMS_RECEIVED 不正确,因为 Telephony 是一个类,应该大写,如 android.provider.Telephony.SMS_RECEIVED


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接