为什么sendTextMessage需要READ_PHONE_STATE权限?

时间:2011-01-04 23:17:25

标签: android permissions sms

我的应用程序将这个堆栈跟踪发送回家,看起来好像发生了一些非常错误的事情。

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)

那么我应该捕获sendTextMessage周围的所有异常吗?这是谁的错?

3 个答案:

答案 0 :(得分:9)

我现在看到在Lollipop(API 21)中,即使使用像SmsManager.getDefault().divideMessage(String)这样的良性函数 - 也需要READ_PHONE_STATE权限。我确信以前不需要它,并且这是一个操作系统问题,因为我在之前和升级到Lollipop之后在Nexus 5设备上进行了测试。之前,当运行KitKat时,SMS工作正常,没有READ_PHONE_STATE权限。之后,它是必需的。

原因是,我猜,电话功能试图做出明智的决定。因此,分割短信(甚至不发送短信)这样的简单任务一直运行到SmsManager,以查询有关手机状态的信息。

我认为这是一个设计错误。正如你上面所说,它可以,并且应该吓唬用户。为什么他们在Android上拥有如此多的模棱两可的权限?

这是我的堆栈追踪,只是为了好玩:

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)

答案 1 :(得分:2)

  

我的应用程序将这个堆栈跟踪发送回家,看起来好像发生了一些非常错误的事情。

你这样说的方式,我认为这是你第一次看到这个问题,但在其他手机上却没有。

在此手机型号的Android实施中,SmsManager是否有可能在尝试发送短信之前检查手机的“状态”。这纯粹是一个猜测但是,尽管SMS Manager的Telephony API文档没有提到它,但这似乎不是一件不合理的事情。也许不是,我不确定。

因为在您的应用中发送短信非常关键,所以是的,你当然应该尽力捕捉可能与发送信息有关的任何异常(如果可能的话,从异常状态恢复)。

由于似乎无法恢复此特定问题,为什么不将READ_PHONE_STATE的uses-permission声明为清单?

答案 2 :(得分:1)

我遇到了与HTC手机(Desire 728G)相同的问题 Dual Sim 而我必须包含“READ_PHONE_STATE”,但现在Google要求制定隐私政策,因为我太懒了做到了:)我做了一些研究,没有使用“READ_PHONE_STATE”我找到了更好的方法。 问题是某些设备(主要是双SIM卡)需要“READ_PHONE_STATE”权限才能查找默认的“SubscriptionId”,即调用“SmsManager.getDefault()”时会发生的情况。 以下是我用来避免此问题的代码,如果产生任何异常,则将值(1)分配给SubscriptionId:

ghci> pairmap' @Num (Just . (+1)) (1 :: Int , 1.0 :: Float)
(Just 2,Just 2.0)