- 2.2: Part 2 — Sending and Receiving SMS Messages
- Task 3. Receive SMS messages with a broadcast receiver
- 3.1 Add permission and create a broadcast receiver
- 3.2 Register the broadcast receiver
- 3.3 Implement the onReceive() method
- 3.4 Run the app and send a message
- Solution Code
- Coding challenge
- Android 11 android.permission.RECEIVE_SMS not working #1280
- Comments
- JonnyTech commented Nov 24, 2020
- mar-v-in commented Nov 25, 2020
- chris42 commented Nov 25, 2020
- JonnyTech commented Nov 25, 2020
- mar-v-in commented Nov 25, 2020
- chris42 commented Nov 25, 2020 •
- JonnyTech commented Nov 25, 2020
- chris42 commented Nov 25, 2020
- JonnyTech commented Nov 29, 2020
- iotY commented Dec 3, 2020
- iotY commented Dec 5, 2020 •
- JonnyTech commented Dec 5, 2020
- iotY commented Dec 7, 2020 •
- GitGangGuy commented Dec 21, 2020
- lss4 commented Jan 8, 2021 •
- starbrights commented Mar 10, 2021
- JonnyTech commented Mar 10, 2021
- stainlesspot commented Apr 9, 2021
- BroadcastReceiver + SMS_RECEIVED
- 7 Answers 7
- Things to be noticed
- How to send a sms message to the emulator
- How to listen to SMS_RECEIVED broadcasts
2.2: Part 2 — Sending and Receiving SMS Messages
Contents:
Task 3. Receive SMS messages with a broadcast receiver
To receive SMS messages, use the onReceive() method of the BroadcastReceiver class. The Android framework sends out system broadcasts of events such as receiving an SMS message, containing intents that are meant to be received using a BroadcastReceiver. You need to add the RECEIVE_SMS permission to your app’s AndroidManifest.xml file.
3.1 Add permission and create a broadcast receiver
To add RECEIVE_SMS permission and create a broadcast receiver, follow these steps:
Open the AndroidManifest.xml file and add the android.permission.RECEIVE_SMS permission below the other permission for SMS use:
Receiving an SMS message is permission-protected. Your app can’t receive SMS messages without the RECEIVE_SMS permission line in AndroidManifest.xml.
Name the class «MySmsReceiver» and make sure «Exported» and «Enabled» are checked.
The «Exported» option allows your app to respond to outside broadcasts, while «Enabled» allows it to be instantiated by the system.
3.2 Register the broadcast receiver
In order to receive any broadcasts, you must register for specific broadcast intents. In the Intent documentation, under «Standard Broadcast Actions», you can find some of the common broadcast intents sent by the system. In this app, you use the android.provider.Telephony.SMS_RECEIVED intent.
Add the following inside the tags to register your receiver:
3.3 Implement the onReceive() method
Once the BroadcastReceiver intercepts a broadcast for which it is registered ( SMS_RECEIVED ), the intent is delivered to the receiver’s onReceive() method, along with the context in which the receiver is running.
- Open MySmsReceiver and add under the class declaration a string constant TAG for log messages and a string constant pdu_type for identifying PDUs in a bundle:
- Delete the default implementation inside the supplied onReceive() method.
In the blank onReceive() method:
Add the @TargetAPI annotation for the method, because it performs a different action depending on the build version.
Retrieve a map of extended data from the intent to a bundle .
Define the msgs array and strMessage string.
Get the format for the message from the bundle .
As you enter SmsMessage[] , Android Studio automatically imports android.telephony.SmsMessage .
Initialize the msgs array, and use its length in the for loop:
Use createFromPdu(byte[] pdu, String format) to fill the msgs array for Android version 6.0 (Marshmallow) and newer versions. For earlier versions of Android, use the deprecated signature createFromPdu(byte[] pdu).
Build the strMessage to show in a toast message:
Get the originating address using the getOriginatingAddress() method.
Get the message body using the getMessageBody() method.
Add an ending character for an end-of-line.
The complete onReceive() method is shown below:
3.4 Run the app and send a message
Run the app on a device. If possible, have someone send you an SMS message from a different device.
You can also receive an SMS text message when testing on an emulator. Follow these steps:
- Run the app on an emulator.
Click the … (More) icon at the bottom of the emulator’s toolbar on the right side, as shown in the figure below:
Solution Code
Android Studio project: SmsMessaging
Coding challenge
Challenge: Create a simple app with one button, Choose Picture and Send, that enables the user to select an image from the Gallery and send it as a Multimedia Messaging Service (MMS) message. After tapping the button, a choice of apps may appear, including the Messenger app. The user can select the Messenger app, and select an existing conversation or create a new conversation, and then send the image as a message.
The following are hints:
- To access and share an image from the Gallery, you need the following permission in the AndroidManifest.xml file:
- To enable the above permission, follow the model shown previously in this chapter to check for the READ_EXTERNAL_STORAGE permission, and request permission if necessary.
- Use the following intent for picking an image:
- Override the onActivityResult method to retrieve the intent result, and use getData() to get the Uri of the image in the result:
- Set the image’s Uri, and use an intent with ACTION_SEND , putExtra() , and setType() :
- Android Studio emulators can’t pass MMS messages to and from each other. You must test this app on real Android devices.
- For more information about sending multimedia messages, see Sending MMS with Android.
Android Studio project: MMSChallenge
Источник
Android 11 android.permission.RECEIVE_SMS not working #1280
Comments
JonnyTech commented Nov 24, 2020
In self check, the permission to receive text messages (SMS) is always unchecked / denied.
In app info the SMS permission is denied. Changing it to allowed then reverts immediately back to denied.
Permissions xml file shows denied too. Changing to granted then reverts back to denied.
Android Version: 11
Custom ROM: LineageOS 18.0
This looks to be a problem with many apps requiring SMS access. Google advises the SMS Retriever API.
There is an article that discusses the issue.
Is this needed and does microG have a workaround?
The text was updated successfully, but these errors were encountered:
mar-v-in commented Nov 25, 2020
I can’t reproduce this on Android 11. Did you try disabling the «Remove permissions if app isn’t used» option at the bottom of app permissions enabled? Where did you install microG: /system/priv-app, /system/app or user app?
The SMS Retriever API is implemented in Play Services by using the SMS permission, it’s not an operation system API. Google again closes down an existing open source API and replaces it with a proprietary extension (although intention might be a good one here so that apps cannot read your private SMS anymore).
chris42 commented Nov 25, 2020
I could not verify this either. I am putting a prebuilt of microg in my aosp 11 build and granting that permission right away. SMS and all SMS related apps are just working fine.
JonnyTech commented Nov 25, 2020
Did you try disabling the «Remove permissions if app isn’t used» option at the bottom of app permissions enabled?
Where did you install microG: /system/priv-app, /system/app or user app?
Are there any logs to examine?
mar-v-in commented Nov 25, 2020
Maybe you need to add it to your privapp-permissions system configuration file? What build of LineageOS / patches are you using?
chris42 commented Nov 25, 2020 •
EDIT: Without the permission, my phone wouldn’t even boot and complain in the logs endlessly about the permission.
JonnyTech commented Nov 25, 2020
LineageOS 18.0 GSI on ARM device (clean flash). Previous LOS17.1 worked ok.
Maybe you need to add it to your privapp-permissions system configuration file?
FYI: In my prebuilt, I added it to my regular permissions, not priv-app.
Thanks guys, how do I do that? Where is the file(s) located?
chris42 commented Nov 25, 2020
It is copied to folder /system/etc/default-permissions/
Additionally the privapp-permissions and whitelists each have their own target. The .mk file defines it:
https://github.com/chris42/android_prebuilts_prebuiltapks/blob/master/GmsCore/Android.mk
$(TARGET_OUT_ETC) is normally /system/etc
With all three files copied, I have microg granted with all permissions on a new device from the start on.
JonnyTech commented Nov 29, 2020
This seems to be a known issue since MinMicroG references it:
If you are not able to grant some permissions to microG (background location or recieving SMS), refer to the the troubleshooting section of install.md
I shall investigate next week when I have more time, but maybe it helps others too, or the devs here can integrate it to microg.
iotY commented Dec 3, 2020
Same miss on aosp10_r40 with
com.android.permissioncontroller W/Role: com.google.android.gms not qualified for android.app.role.SMS due to missing RequiredComponent
May this be linked to api29 added: https://developer.android.com/reference/androidx/core/role/RoleManagerCompat#ROLE_SMS ? ; on Los 17.1 (with same implementation), it works fine but com.android.permissioncontroller is also rom-modified (?)
iotY commented Dec 5, 2020 •
@JonnyTech can you check whether or not your android11 logcat shows this com.android.permissioncontroller W/Role when attempting microG sms perm ?
Always resulting, for me, to false:
com.android.permissioncontroller V/GrantPermissionsActivity: Permission grant result . . callingPackage=com.google.android.gms permission=android.permission.RECEIVE_SMS isImplicit=false result=1
JonnyTech commented Dec 5, 2020
I have reverted back to LOS17.1 for now, shall test again with LOS18.0 in a few days. But iirc there were very similar messages in the log.
iotY commented Dec 7, 2020 •
@mar-v-in , for general-ui only test purpose, uploaded in previous post is magisk systemless module for AndroidStudio AVD Api30 once rooted with https://github.com/shakalaca/MagiskOnEmulator ( canary option): don’t have the sms W/Role on AVD Api30, but same resulting callingPackage=com.google.android.gms permission=android.permission.RECEIVE_SMS isImplicit=false result=1 when attempting sms permission .
(btw, anyone knows how to boot a treble GSIx86 raw image via AndroidStudio AVD ?)
EDIT: AVD Api30 also lists
system_process E/PackageManager: Cannot grant hard restricted non-exempt permission android.permission.ACCESS_BACKGROUND_LOCATION for package com.google.android.gms
GitGangGuy commented Dec 21, 2020
Hey, I’m running into the same issue. I installed MicroG using the MicroG Installer (Revived) magisk module. It won’t let me grant background location nor SMS permissions; does anyone have a clear solution that doesn’t involve fiddling with files in various system folders?
lss4 commented Jan 8, 2021 •
Hey, I’m running into the same issue. I installed MicroG using the MicroG Installer (Revived) magisk module. It won’t let me grant background location nor SMS permissions; does anyone have a clear solution that doesn’t involve fiddling with files in various system folders?
Can confirm this is also happening with microG 0.2.13 installed using NanoDroid 23.0.1, on phh AOSP GSI v300.l (Android 11). It’s not possible to grant SMS nor background location for microG Services Core anymore .
EDIT: Just updated to microG 0.2.16 and I can now enable background locations as well as SMS permissions. The issue might have been fixed there.
starbrights commented Mar 10, 2021
Had this issues (SMS, background location) in 0.2.17 too (Nanodroid 23.1.2) but it could be fixed by an upgrade via FDroid/microG repo to 0.2.18. 🙂
JonnyTech commented Mar 10, 2021
I can confirm that build 0.2.18 fixes the issue.
stainlesspot commented Apr 9, 2021
Installing through the MicroG Installer (Revived) Magisk module I had the same problems — couldn’t give SMS or background location permissions. I even unzipped the module to add chris42’s permissions files and download the newest GmsCore apk from microG’s github (version 0.2.18.204714).
That didn’t work, neither did the nanodroid perm script.
Источник
BroadcastReceiver + SMS_RECEIVED
I’d like my app to catch incoming SMS messages. There are a few examples of this around. Looks like we just need to do this:
is this correct? I’m sending my phone some sms messages, but the log statement never gets printed. I do have some other SMS applications installed on the phone, which display a popup when the sms is received — are they somehow blocking the intent from getting passed down to my app, they are just consuming it completely?
7 Answers 7
You would also need to specify a uses-permission in your manifest file:
The following tutorials should help:
There are a few gotchas on the way. You can find all the needed info on stackoverflow. I have gathered all the info in this answer, for convenience.
Things to be noticed
- I assume android kitkat and above.
- The intent for incomming sms is «android.provider.Telephony.SMS_RECEIVED»
- You can change the priority of the intent filter, but it’s not necessary.
- You need this permission «android.permission.RECEIVE_SMS» in manifest xml, in order to receive sms messages. In android 6 and above, you additionally need to ask for the permission in runtime.
- You do not need to set the MIME type of data in the intent filter. Intent filter should pass only on empty data if no MIME type is set, but fortunately it will still work without MIME.
- adb shell am broadcast will not work. Use telnet connection to simulator to test sms receiving.
- Long sms messages are divided into small sms chunks. We need to concatenate them.
How to send a sms message to the emulator
The most important thing is to have the possibility to send fake sms messages to the device, so we can test the code.
For this we will use a virtual device and a telnet connection to it.
- Create a virtual device in android studio and run the simulator
- Look at the title bar in the simulator window. There is the device name and a port number. We need to know this port number in the next steps.
Now connect to the port number shown in the simulator title bar with telnet
If you see this: Android Console: Authentication required , then you need to authenticate the connection with this command:
Replace the xxxxxx above with the token read from
Now you should be able to run all the commands. To send a sms message, type this command:
Where you can replace 555 with the sender telephone number and a message of your own.
How to listen to SMS_RECEIVED broadcasts
To get the broadcasts, you need to register a BroadcastReceiver object. You can do this in the manifest.xml OR just call registerReceiver function. I will show you the latter, as it is easier to reason about and yet more flexible.
Connecting the broadcast receiver with the main activity
The data flow is one way. From broadcast receiver to the main activity. So the simplest way to get them to talk is to use a function interface. The activity will implement such a function and the broadcast receiver will have the activity instance passed as a parameter in the constructor.
Implementing the broadcast receiver
The broadcast receiver will get the intent in a callback. We will use the function Telephony.Sms.Intents.getMessagesFromIntent(intent) to get the sms messages. Notice the SmsHandler parameter in the constructor. It will be the activity to which we will send the received sms.
The main activity
Finally we need to implement SmsHandler interface into the main activity and add registering the broadcast receiver and permission check to the onCreate function.
Finally remember to add RECEIVE_SMS permission to your manifest xml
Источник