可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I have been trying to get this program to work but so far having no luck. I cannot find where I am doing wrong. I\'m not sure if there\'s something wrong with the code, or debugging.
I\'m trying to be notified if a new SMS arrives.
Here is my program:
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());
}
}
}
}
}
And the manifest file:
<?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>
I am sending SMS through Telnet, and I cannot see any Intent received messages in the logcat. Here is my logcat from the time of installation.
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
So the SMS seems to be received by the emulator, but looks like the no intents are firing.
What am I doing wrong here? After installing, do I have to somehow \'start\' this receiver?
Because when I install, I get
[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!
So I\'m wondering if something\'s wrong here.
回答1:
android.provider.Telephony.SMS_RECEIVED
has a capital T
, and yours in the manifest does not.
Please bear in mind that this Intent
action is not documented.
回答2:
I tried your code and found it wasn\'t working.
I had to change
if (intent.getAction() == SMS_RECEIVED) {
to
if (intent.getAction().equals(SMS_RECEIVED)) {
Now it\'s working. It\'s just an issue with java checking equality.
回答3:
Also note that the Hangouts application will currently block my BroadcastReceiver from receiving SMS messages. I had to disable SMS functionality in the Hangouts application (Settings->SMS->Turn on SMS), before my SMS BroadcastReceived started getting fired.
Edit: It appears as though some applications will abortBroadcast() on the intent which will prevent other applications from receiving the intent. The solution is to increase the android:priority
attribute in the intent-filter
tag:
<receiver android:name=\"com.company.application.SMSBroadcastReceiver\" >
<intent-filter android:priority=\"500\">
<action android:name=\"android.provider.Telephony.SMS_RECEIVED\" />
</intent-filter>
</receiver>
See more details here: Enabling SMS support in Hangouts 2.0 breaks the BroadcastReceiver of SMS_RECEIVED in my app
回答4:
one important thing that should be mentioned with this thread is description aboud pdu
A PDU is a \"protocol discription unit\", which is the industry format for an SMS message. because SMSMessage reads/writes them you shouldn\'t need to dissect them.
A large message might be broken into many, which is why it is an array of objects.
回答5:
intent.getAction().equals(SMS_RECEIVED)
I have tried it out successfully.
回答6:
Your broadcast receiver must specify android:exported=\"true\"
to receive broadcasts created outside your own application. My broadcast receiver is defined in the manifest as follows:
<receiver
android:name=\".IncomingSmsBroadcastReceiver\"
android:enabled=\"true\"
android:exported=\"true\" >
<intent-filter>
<action android:name=\"android.provider.Telephony.SMS_RECEIVED\" />
</intent-filter>
</receiver>
As noted below, exported=\"true\" is the default, so you can omit this line. I\'ve left it in so that the discussion comments make sense.
回答7:
Stumbled across this today. For anyone coding an SMS receiver nowadays, use this code instead of the deprecated in OP:
SmsMessage[] msgs = Telephony.Sms.Intents.getMessagesFromIntent(intent);
SmsMessage smsMessage = msgs[0];
回答8:
For android 19+ you can get it in Telephony.Sms.Intents.SMS_RECEIVED_ACTION)
. There are more in the Intent
s class that \'re worth looking
at
回答9:
The Updated code is :
private class SMSReceiver extends BroadcastReceiver {
private Bundle bundle;
private SmsMessage currentSMS;
private String message;
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(\"android.provider.Telephony.SMS_RECEIVED\")) {
bundle = intent.getExtras();
if (bundle != null) {
Object[] pdu_Objects = (Object[]) bundle.get(\"pdus\");
if (pdu_Objects != null) {
for (Object aObject : pdu_Objects) {
currentSMS = getIncomingMessage(aObject, bundle);
String senderNo = currentSMS.getDisplayOriginatingAddress();
message = currentSMS.getDisplayMessageBody();
Toast.makeText(OtpActivity.this, \"senderNum: \" + senderNo + \" :\\n message: \" + message, Toast.LENGTH_LONG).show();
}
this.abortBroadcast();
// End of loop
}
}
} // bundle null
}
}
private SmsMessage getIncomingMessage(Object aObject, Bundle bundle) {
SmsMessage currentSMS;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
String format = bundle.getString(\"format\");
currentSMS = SmsMessage.createFromPdu((byte[]) aObject, format);
} else {
currentSMS = SmsMessage.createFromPdu((byte[]) aObject);
}
return currentSMS;
}
older code was :
Object [] pdus = (Object[]) myBundle.get(\"pdus\");
messages = new SmsMessage[pdus.length];
for (int i = 0; i < messages.length; i++)
{
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
String format = myBundle.getString(\"format\");
messages[i] = SmsMessage.createFromPdu((byte[]) pdus[i], format);
}
else {
messages[i] = SmsMessage.createFromPdu((byte[]) pdus[i]);
}
strMessage += \"SMS From: \" + messages[i].getOriginatingAddress();
strMessage += \" : \";
strMessage += messages[i].getMessageBody();
strMessage += \"\\n\";
}
The simple SYntax of code is :
private class SMSReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Telephony.Sms.Intents.SMS_RECEIVED_ACTION)) {
SmsMessage[] smsMessages = Telephony.Sms.Intents.getMessagesFromIntent(intent);
for (SmsMessage message : smsMessages) {
// Do whatever you want to do with SMS.
}
}
}
}
回答10:
I\'ve encountered such issue recently. Though code was correct, I didn\'t turn on permissions in app settings. So, all permissions hasn\'t been set by default on emulators, so you should do it yourself.
回答11:
android.provider.telephony.SMS_RECEIVED
is not correct because Telephony is a class and it should be capital as in android.provider.Telephony.SMS_RECEIVED