Why is SmsManager requiring READ_PHONE_STATE permission on some devices but not others?
Asked Answered
L

1

7

The app uses SmsManager to send SMS text messages. The following method is only called after the SEND_SMS runtime permission has been successfully acquired from the user. The app targets 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);
    }

}

Until now it had worked fine on all the devices it has been tested on. But it has now been used on a phone, the Logicom L-EMENT 553, and the app blows up when trying to call sendTextMessage() on API 23 (Marshmallow) with this exception:

Exception java.lang.RuntimeException: Failure delivering result
ResultInfo{who=@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.

Why would the READ_PHONE_STATE permission be required on some devices, but not others when sending SMS messages? Obviously it is preferable to not request this permission as it is a big ask of the user to provide this level of access.

The answers to a question here Why would sendTextMessage require READ_PHONE_STATE permission? suggest some Android versions contain a bug that requests this permission, but is it that or that the sendTextMessage() method was passed a message over the length limit, and then went on to split it using divideMessage() which then requests this permission? Although having said that I see no evidence sendMessage() automatically splits long messages into smaller pieces and sends them.

Limitless answered 14/5, 2017 at 11:8 Comment(2)
It's a very poor solution to ask for both permissions on all devices, so for now I am using a call to SmsManager.divideMessage() to try{} whether the device is requiring the READ_PHONE_STATE permission and using the result of that to either just request the SEND_SMS permission, or to request both.Limitless
Apparently this is not always the case - or at least not on devices running 8.0, divideMessage() runs fine without READ_PHONE_STATE, but sendMultipartTextMessage() does require it. See #46421912Committal
E
2

I think it's because some manufacturers corrected the bug in Android. I tried it in emulator (Android 8.0, API 26), and it throws exception on sendSmsTextMessage(). So I made a workarround like this:

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
}

...and in manifest:

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

...cause it seems solved in API 27, at least it doesn't happen in emulator with API 27.

Electricity answered 21/3, 2018 at 20:28 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.