Why would sendTextMessage require READ_PHONE_STATE permission?
Asked Answered
T

3

12

My app sent home this stack trace which seems as though something very wrong is going on under the hood.

phone_model=SKY IM-A630K, android_version=2.1-update1

java.lang.SecurityException: Requires READ_PHONE_STATE: Neither user 10089 nor current process has android.permission.READ_PHONE_STATE.

   at android.os.Parcel.readException(Parcel.java:1218)
   at android.os.Parcel.readException(Parcel.java:1206)
   at com.android.internal.telephony.IPhoneSubInfo$Stub$Proxy.getLine1Number(IPhoneSubInfo.java:223)
   at android.telephony.TelephonyManager.getLine1Number(TelephonyManager.java:764)
   at android.telephony.SmsManager.sendTextMessage(SmsManager.java:129)
   at android.telephony.SmsManager.sendTextMessage(SmsManager.java:108)
   at com.emergency.button.SMSSender.safeSendSMS(SMSSender.java:91)
   at com.emergency.button.EmergencyActivity$EmergencyThread.sendSMS(EmergencyActivity.java:294)
   at com.emergency.button.EmergencyActivity$EmergencyThread.sendMessages(EmergencyActivity.java:386)
   at com.emergency.button.EmergencyActivity$EmergencyThread.run(EmergencyActivity.java:266)

So should I just catch any and all exceptions around sendTextMessage? Who's fault is this?

Thorncombe answered 4/1, 2011 at 23:17 Comment(0)
T
2

My app sent home this stack trace which seems as though something very wrong is going on under the hood.

The way you say this, I assume this is the first time you've seen this problem and it doesn't happen on other phones.

Is it possible that in the Android implementation on this phone model, the SmsManager attempts to check the phone 'state' before attempting to send an SMS message. That's purely a guess but it doesn't seem an unreasonable thing to do although the Telephony API docs for SMS Manager don't mention it. Maybe not, I'm not sure.

As sending an SMS message is quite critical in your app, then yes you should certainly be doing all you can to catch any exceptions possibly related to sending the messae (and recovering from the exception state if possible).

As it seems this particular problem cannot be recovered from, why not declare uses-permission for READ_PHONE_STATE into your manifest?

Talca answered 4/1, 2011 at 23:59 Comment(2)
I thought READ_PHONE_STATE might scare off users who wouldn't want me to know their phone number. Oh well... I think I'll just catch and ignore this exception (I'll report to the user) as it happened exactly once in the entire app's lifetime...Thorncombe
@ubershmekel: Yes, I understand about not using READ_PHONE_STATE if you can avoid it. Maybe this was just a one-off and hopefully catching the exception will help.Talca
R
9

I now see that in Lollipop (API 21), even using a benign function like SmsManager.getDefault().divideMessage(String) - requires the READ_PHONE_STATE permission. I am sure that it was not required before, and that it is an OS issue, since I tested it on Nexus 5 devices before, and after upgrade to Lollipop. Before, when running KitKat, SMS worked just fine without the READ_PHONE_STATE permission. And after, it was required.

The reason is that, I guess, telephony functions try to make wise decisions about, well, everything. So a simple task like splitting an SMS (not even sending it) runs all the way to the SmsManager to query it about the phone state.

I think it is a design bug. And as you said above, it can, and should scare users. Why on earth do they have so many ambiguous permissions on Android?

This is my stack trace, just for fun:

java.lang.SecurityException: Requires READ_PHONE_STATE: Neither user 10078 nor current process has android.permission.READ_PHONE_STATE.
at android.os.Parcel.readException(Parcel.java:1540)
at android.os.Parcel.readException(Parcel.java:1493)
at com.android.internal.telephony.IPhoneSubInfo$Stub$Proxy.getGroupIdLevel1(IPhoneSubInfo.java:465)
at android.telephony.TelephonyManager.getGroupIdLevel1(TelephonyManager.java:1666)
at android.telephony.SmsMessage.hasEmsSupport(SmsMessage.java:776)
at com.android.internal.telephony.gsm.SmsMessage.calculateLength(SmsMessage.java:808)
at android.telephony.SmsMessage.fragmentText(SmsMessage.java:322)
at android.telephony.SmsManager.divideMessage(SmsManager.java:328)
at mobi.chatfish.utils.CFCommunications.sendSMSDirect(CFCommunications.java:138)
Relative answered 4/12, 2014 at 17:43 Comment(10)
Yep, I'm seeing a similar stacktrace (slightly different line numbers) on a OnePlus One running Loolipop. Reported as code.google.com/p/android/issues/detail?id=81758 Please star :)Signboard
I am getting this error on a Y550, but my app DOES have READ_PHONE_STATE declared as a permission in the manifest??Cockiness
I have the exact same problem with the SmsManager.getDefault().divideMessage(String) requiring READ_PHONE_STATE for Lollipop. It's very irritating!Ge
This seems to be fixed in Android 6Inflatable
I am getting the same SecurityException and requiring READ_PHONE_STATE on a Y625-U21 (HWY625-U) just for calling android.text.format.DateFormat.getDateFormat(context)Redness
@Inflatable Any link to show it has been fixed in Android 6?Randy
Same problem on Pixel XL Android O 8.0 :/Amish
Same problem on OnePlus A5010 (5T) Android O 8.0.0Austral
Huawei Mate 9 MHA-L29 Android 8 too.Karoline
The same problem on the Android emulator API 26.Alright
G
3

I had the same problem with an HTC phone (Desire 728G) Dual Sim and I had to include "READ_PHONE_STATE" but now Google is asking for a privacy policy, and because I am too lazy to do it :) I did some research and I found a better way without the use of "READ_PHONE_STATE". The problem is that some devices (mainly dual sim) need the "READ_PHONE_STATE" permission to look for the default "SubscriptionId" that is what happens when you call "SmsManager.getDefault()". Below is the code I am using to avoid this issue by assigning the value (1) to SubscriptionId if any exception accrued:

            SmsManager smsManager = SmsManager.getDefault();

            if (android.os.Build.VERSION.SDK_INT >= 22){
                Log.e("Alert","Checking SubscriptionId");
            try {
                Log.e("Alert","SubscriptionId is " + smsManager.getSubscriptionId());
            } catch (Exception e) {
                Log.e("Alert",e.getMessage());
                Log.e("Alert","Fixed SubscriptionId to 1");
                smsManager = SmsManager.getSmsManagerForSubscriptionId(1);
            }
            }

            smsManager.sendTextMessage(mobileNumber, null, msgStr, null, null);
Godoy answered 25/2, 2017 at 0:20 Comment(0)
T
2

My app sent home this stack trace which seems as though something very wrong is going on under the hood.

The way you say this, I assume this is the first time you've seen this problem and it doesn't happen on other phones.

Is it possible that in the Android implementation on this phone model, the SmsManager attempts to check the phone 'state' before attempting to send an SMS message. That's purely a guess but it doesn't seem an unreasonable thing to do although the Telephony API docs for SMS Manager don't mention it. Maybe not, I'm not sure.

As sending an SMS message is quite critical in your app, then yes you should certainly be doing all you can to catch any exceptions possibly related to sending the messae (and recovering from the exception state if possible).

As it seems this particular problem cannot be recovered from, why not declare uses-permission for READ_PHONE_STATE into your manifest?

Talca answered 4/1, 2011 at 23:59 Comment(2)
I thought READ_PHONE_STATE might scare off users who wouldn't want me to know their phone number. Oh well... I think I'll just catch and ignore this exception (I'll report to the user) as it happened exactly once in the entire app's lifetime...Thorncombe
@ubershmekel: Yes, I understand about not using READ_PHONE_STATE if you can avoid it. Maybe this was just a one-off and hopefully catching the exception will help.Talca

© 2022 - 2024 — McMap. All rights reserved.