Android - SMS Broadcast receiver
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.
SMS Broadcast Receiver in Oreo+
I finally figured out what was wrong. Apparently, Android version Oreo+ does not deliver implicit broadcasts any more* (i.e., those specified in the manifest file <receiver>). You now must explicitly register your receiver (i.e., with registerReceiver()) in your code.
(*Note: Mike M correctly pointed out that received SMS broadcasts are excluded from this restriction according to Android doc, but nonetheless this was not so for me in practice).
So what I did to make this work was:
- Completely Remove <receiver> from manifest.
Create an instance of my receiver and an intentFilter in my activities onCreate();
MyReceiver = new SmsRecv();
MyFilter = new IntentFilter(Telephony.Sms.Intents.SMS_RECEIVED_ACTION );Register the receiver in my Activity's onResume().
i = registerReceiver( MyReceiver, MyFilter);
Unregister the receiver in my Activity's onPause(). (This is neccessary to prevent leaks).
unregisterReceiver( MyReceiver );
With the changes, the app worked perfectly.
How to get sms data in a Broadcast receiver
Here's your problem:
registerReceiver(..., new IntentFilter(SENT));
You're registering that Receiver for the action you're using for the sent confirmation, not for the SMS_RECEIVED
action, which is what is broadcast when a message arrives.
The sent PendingIntent
is used to confirm that the message has successfully left the device. The resulting Intent
from that will not have any message PDUs on it, which is why you're crashing.
The action you need to register an incoming SMS Receiver for is "android.provider.Telephony.SMS_RECEIVED"
, or the constant Telephony.Sms.Intents.SMS_RECEIVED_ACTION
, if you're compiling with API 19 or above.
To address the specific questions:
- Do I need the Receiver/Intent-filter block in my manifest, and if so, how do I name the listener in the first line?
Registering a Receiver in the manifest will allow your app to receive messages even when it's not already running, or in the foreground. If you don't need to do that, you don't necessarily need to register in the manifest. However, if the user navigates away from your Activity
before receiving the message, the paused Activity
won't get the broadcast.
The "safest" way to handle it would be to register in the manifest, but there you're registering a class, not a dynamic instance. You would need to create a MyBroadcastListener
class, and somehow notify the Activity
from that upon receipt; e.g., using startActivity()
, or LocalBroadcastManager
, or some other event bus implementation, etc.
- What is the likely reason I can not receive a copy of the incoming message in onReceive(), and what should I do to correct it?
As mentioned above, the PendingIntent
passed in the sendTextMessage()
call is for sent confirmation. Its resulting Intent
won't have the incoming message on it. You just need to listen for the correct broadcast.
- Do I need to send a message and "catch it" in onReceive() in order to reliably get the devices phone number, or can I request permission to read SMS from the user, and just read the first message to get the incoming phone number?
You need to actually send a message. Incoming messages won't have the recipient number attached.
SMS receiver stops working after sometime
Finally, made it working in higher versions too, just by adding
android:permission="android.permission.BROADCAST_SMS"
in the receiver tag in AndroidManifest.xml
and made it something like -
<receiver android:name=".receiver.SmsListener"
android:permission="android.permission.BROADCAST_SMS"
>
<intent-filter android:priority="999">
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>
SMS BroadcastReceiver stops working after sometime
The issue was the the EMUI, MIUI etc were killing the background tasks. After whitelisting the app, it works fine now.
Related Topics
How to Parse the Androidmanifest.Xml File Inside an .Apk Package
Determine If Android App Is Being Used For the First Time
Animate the Transition Between Fragments
How to Disable Bottomnavigationview Shift Mode
How to Make Surfaceview Transparent
How to Solve Java.Lang.Outofmemoryerror Trouble in Android
How to Create a Closed (Circular) Listview
Where Does Android Emulator Store SQLite Database
How to Store(Bitmap Image) and Retrieve Image from SQLite Database in Android
How to Display Toast in Android
Sending Message Through Whatsapp
Checkbox in Recyclerview Keeps on Checking Different Items
How to Find Out Which Keystore Was Used to Sign an App
How to Lay Out Views in Relativelayout Programmatically
Check Android Application Is in Foreground or Not
Receiving Package Install and Uninstall Events
Runtimeexception: Unable to Instantiate Application
The Setmobiledataenabled Method Is No Longer Callable as of Android L and Later