为啥 SmsManager 在某些设备上需要 READ_PHONE_STATE 权限,而在其他设备上不需要?

Posted

技术标签:

【中文标题】为啥 SmsManager 在某些设备上需要 READ_PHONE_STATE 权限,而在其他设备上不需要?【英文标题】:Why is SmsManager requiring READ_PHONE_STATE permission on some devices but not others?为什么 SmsManager 在某些设备上需要 READ_PHONE_STATE 权限,而在其他设备上不需要? 【发布时间】:2017-10-13 06:36:51 【问题描述】:

该应用使用 SmsManager 发送 SMS 文本消息。以下方法仅在用户成功获取 SEND_SMS 运行时权限后调用。该应用面向 API 25。

public static void sendSmsTextMessage(Context context, String number, String message) 
    SmsManager sms = SmsManager.getDefault();
    int permissionCheck = ContextCompat.checkSelfPermission(context, Manifest.permission.SEND_SMS);
    if (permissionCheck == PERMISSION_DENIED) 
        Timber.e("Permission to send SMS denied");
     else 
        sms.sendTextMessage(number, null, message, null, null);
    


到目前为止,它在所有经过测试的设备上都运行良好。但它现在已在手机上使用,即 Logicom L-EMENT 553,当尝试在 API 23 (Marshmallow) 上调用 sendTextMessage() 时,应用程序崩溃了,但有以下例外:

Exception java.lang.RuntimeException: Failure delivering result
ResultInfowho=@android:requestPermissions:, request=1, result=-1,
data=Intent  act=android.content.pm.action.REQUEST_PERMISSIONS (has
extras)  to activity 
com.myapp.android/com.myapp.android.ui.bet.BetActivity: 
java.lang.SecurityException: Neither user 10108 nor current process
has android.permission.READ_PHONE_STATE.

为什么在某些设备上需要 READ_PHONE_STATE 权限,而在其他设备上发送 SMS 消息时不需要?显然,最好不要请求此权限,因为用户要求提供此级别的访问权限是一个很大的要求。

这里Why would sendTextMessage require READ_PHONE_STATE permission?的问题的答案表明某些Android版本包含一个请求此权限的错误,但是否是sendTextMessage()方法传递的消息超过了长度限制,然后继续拆分它使用divideMessage() 然后请求这个权限?虽然我说过我没有看到任何证据 sendMessage() 会自动将长消息分成更小的部分并发送它们。

【问题讨论】:

在所有设备上请求这两个权限是一个非常糟糕的解决方案,所以现在我正在使用对 SmsManager.divideMessage() 的调用来尝试设备是否需要 READ_PHONE_STATE 权限并使用其结果是要么只请求 SEND_SMS 权限,要么同时请求两者。 显然情况并非总是如此——或者至少不是在运行 8.0 的设备上,divideMessage() 在没有READ_PHONE_STATE 的情况下运行良好,但sendMultipartTextMessage() 确实需要它。见***.com/questions/46421412/… 【参考方案1】:

我认为这是因为一些制造商纠正了 Android 中的错误。我在模拟器(Android 8.0,API 26)中尝试过,它在 sendSmsTextMessage() 上抛出异常。所以我做了一个这样的解决方法:

try 
  SmsManager.getDefault().sendTextMessage(msisdn, null, text, null, null);
  return false;
 catch (Exception e) 
  if (e.toString().contains(Manifest.permission.READ_PHONE_STATE) && ContextCompat
      .checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE)!=
      PackageManager.PERMISSION_GRANTED) 
    ActivityCompat.requestPermissions(this, new String[] Manifest.permission
      .READ_PHONE_STATE, REQUEST_READ_PHONE_STATE);
    return true;
   // else it's some other exception

...在清单中:

  <uses-permission-sdk-23 android:maxSdkVersion="26"
     android:name="android.permission.READ_PHONE_STATE"/>

...因为它似乎在 API 27 中解决了,至少它不会在使用 API 27 的模拟器中发生。

【讨论】:

以上是关于为啥 SmsManager 在某些设备上需要 READ_PHONE_STATE 权限,而在其他设备上不需要?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 ping 在某些设备上有效,而在其他设备上无效?

为啥我的 UIBarButtonItem 按钮在某些设备上获得背景颜色?

使用 HTML 编码时,为啥视频在某些 Android 设备上加载,而在其他设备上不加载?

为啥 getExternalFilesDirs() 在某些设备上不起作用?

通知图标,在某些设备上是全白的,在其他设备上是彩色的。为啥?

为啥 android:colorBackground 在某些设备上不起作用?