Android 8 requires READ_PHONE_STATE when calling SmsManager.sendTextMessage()
Asked Answered
P

2

22

My application can't send sms on new android 8 update. I get error that I don't have READ_PHONE_STATE permission.

java.lang.SecurityException: Neither user 10179 nor current process has android.permission.READ_PHONE_STATE.
    at android.os.Parcel.readException(Parcel.java:1942)
    at android.os.Parcel.readException(Parcel.java:1888)
    at com.android.internal.telephony.ISms$Stub$Proxy.sendTextForSubscriber(ISms.java:789)
    at android.telephony.SmsManager.sendTextMessageInternal(SmsManager.java:329)
    at android.telephony.SmsManager.sendTextMessage(SmsManager.java:312)
    at com.cordova.plugins.sms.Sms.send(Sms.java:192)
    at com.cordova.plugins.sms.Sms.access$400(Sms.java:22)
    at com.cordova.plugins.sms.Sms$1.run(Sms.java:102)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
    at java.lang.Thread.run(Thread.java:764)

usually this kind of error is fine - I just realise I need a permission and ask for it. But in this case I can't find any documentation that I should need READ_PHONE_STATE to use SmsManager. Neither here sendTextMessage nor in new Android 8 update notes. The latter one mentions that to get hardware serial number I now need READ_PHONE_STATE permission.

Researching further I found that many other people have ran into this issue, but no one has any details or solutions beyond just asking for said permission.

So today I recreated the problem with simple pure application that just asks for SEND_SMS permission and sends sms. And got the exact same problem. It works on everything below Android 8. But crashes with permission error on android 8. Here is source code if anyone wants to recreate it.

compileSdkVersion 26
buildToolsVersion "26.0.2"
defaultConfig {
  applicationId "com.example.usr.smstest"
  minSdkVersion 21
  targetSdkVersion 26
}
package com.example.usr.smstest;

import android.Manifest;
import android.content.pm.PackageManager;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.telephony.SmsManager;

public class MainActivity extends AppCompatActivity {

    private static final int MY_PERMISSIONS_REQUEST_SEND_SMS = 1;

    @Override
    public void onRequestPermissionsResult(int requestCode,
                                           String permissions[], int[] grantResults) {
        switch (requestCode) {
            case MY_PERMISSIONS_REQUEST_READ_CONTACTS: {
                if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    sendSms();
                }
            }
        }
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        if (ContextCompat.checkSelfPermission(MainActivity.this,
                Manifest.permission.SEND_SMS)
                != PackageManager.PERMISSION_GRANTED) {

                ActivityCompat.requestPermissions(MainActivity.this,
                        new String[]{Manifest.permission.SEND_SMS},
                        MY_PERMISSIONS_REQUEST_SEND_SMS);
        }else{
            sendSms();
        }
    }

    private void sendSms(){
        SmsManager manager = SmsManager.getDefault();
        manager.sendTextMessage("22222222", null, "msg", null, null);
    }

}

Submitted it on google issue tracker

Pren answered 26/9, 2017 at 8:28 Comment(2)
I was looking into the Android source code and found this: android.googlesource.com/platform/frameworks/opt/telephony/+/… (method: sendTextMessage, line 263) There is a call to getSubscriptionId(), which is protected with READ_PHONE_STATE_PERMISSION, then if the app does not have this permission checked/granted, calling this method will cause the SecurityException and the app will crash. Workaround is (when app declared usage of READ_PHONE_STATE) is to grant the permission manually from the settings.Magnuson
So apparently this is fixed in 8.1 update. Haven't confirmed yet. Still no official response from googlePren
A
3

This is a bug in android O that so much annoying. if you check SmsManager.java you can see getSubscriptionId method that in body need READ_PHONE_STATE_PERMISSION and if you don't give READ_PHONE_STATE throw SecurityException

So all you can do is generate READ_PHONE_STATE and explain it to play store if you've been warned or wait to fix by google developers

Angleaangler answered 22/7, 2018 at 9:21 Comment(1)
Alternatively, catch Security Exception and ask users to grant the permission. That way users that don't have that bug on their system won't need to grant the ugly READ_PHONE_STATE.Hog
B
-6
You need to check the permissions in android nougat devices.

 if (ContextCompat.checkSelfPermission(this, Manifest.permission.SEND_SMS)
         != PackageManager.PERMISSION_GRANTED) {
            if (ActivityCompat.shouldShowRequestPermissionRationale(this,
               Manifest.permission.SEND_SMS)) {
            } else {
               ActivityCompat.requestPermissions(this,
                  new String[]{Manifest.permission.SEND_SMS},
                  MY_PERMISSIONS_REQUEST_SEND_SMS);
            }
      }

Link - https://www.tutorialspoint.com/android/android_sending_sms.htm
Blah answered 2/1, 2018 at 9:57 Comment(1)
this is totally off topicPren

© 2022 - 2024 — McMap. All rights reserved.