Почему SmsManager требует разрешения READ_PHONE_STATE на одних устройствах, но не на других?

Приложение использует 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, и приложение взрывается при попытке вызвать sendTextMessage() в API 23 (Marshmallow) с этим исключением:

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.

Почему для отправки SMS-сообщений на одних устройствах требуется разрешение READ_PHONE_STATE, а на других нет? Очевидно, что предпочтительнее не запрашивать это разрешение, поскольку от пользователя требуется предоставить такой уровень доступа.

Ответы на вопрос здесь Почему для sendTextMessage требуется разрешение READ_PHONE_STATE? предполагают, что некоторые версии Android содержат ошибку, которая запрашивает это разрешение, но это так или потому, что метод sendTextMessage() передал сообщение, превышающее ограничение длины, а затем продолжил его разделение с помощью DivisionMessage(), который затем запрашивает это разрешение? Хотя, сказав, что я не вижу доказательств, sendMessage() автоматически разбивает длинные сообщения на более мелкие части и отправляет их.


person Ollie C    schedule 14.05.2017    source источник
comment
Запрашивать оба разрешения на всех устройствах — очень плохое решение, поэтому сейчас я использую вызов SmsManager.divideMessage(), чтобы попробовать {}, требуется ли устройству разрешение READ_PHONE_STATE, и используя результат этого либо просто запросить разрешение SEND_SMS или запросить и то, и другое.   -  person Ollie C    schedule 16.05.2017
comment
По-видимому, это не всегда так — или, по крайней мере, не на устройствах с 8.0, divideMessage() отлично работает без READ_PHONE_STATE, но sendMultipartTextMessage() требует этого. См. stackoverflow.com/questions/46421412/   -  person jdepypere    schedule 12.12.2017


Ответы (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.

person user4215456    schedule 21.03.2018