Neither user 10141 nor current process has android.permission.READ_PHONE_STATE.

问题:

之前在开发作业的时候,在Android 12的环境下,不做任何处理,alarm应用中,闹钟响铃时,alarm应用会crash。

报错信息:

java.lang.RuntimeException: Unable to start service 
com.android.deskclock.alarms.AlarmService@c351e33 with Intent { act=START_ALARM 
dat=content://com.android.deskclock/instances/44 
cmp=com.android.deskclock/.alarms.AlarmService }: java.lang.SecurityException: 
getCallState: Neither user 10141 nor current process has 
android.permission.READ_PHONE_STATE.

锁定出错位置:

AlarmService中,在startAlarm()中调用了getCallState()方法来获取phone的状态时出现了crash

解决方案:

在Android6.0以后,调用getCallState()需要动态授予READ_PHONE_STATE权限(危险权限)

先在权限清单中加入READ_PHONE_STATE权限

<uses-permission android:name="android.permission.READ_PHONE_STATE"/>

在应用的MainActivity中,加入动态授权的流程。一开始进入应用时,判断是否授予READ_PHONE_STATE权限。

建议在onResume(每次打开这个activity都会加载onResume)中加入权限检查,不要在onCreate中(只在第一次打开activity时,才会加载onCreate)加。第一次授予权限以后,在应用还没被杀死的时候,再将权限拒绝,后面的问题无法避免。

   @Override
    public void onResume() {
        super.onResume();

        //如果没有授予READ_PHONE_STATE权限
        if(ContextCompat.checkSelfPermission(AlarmMainActivity.this, Manifest.
                permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED){
            //跳转授权界面
            ActivityCompat.requestPermissions(AlarmMainActivity.this, new
                    String[]{ Manifest.permission.READ_PHONE_STATE}, 1);
        }else {
            // 如果有其他权限(非危险权限)的判断,可在这里进行操作
        }

    }
    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        switch (requestCode){
            case 1:
                if(grantResults.length > 0 && grantResults[0] != PackageManager.PERMISSION_GRANTED){
                    //如果没授予此权限,则结束应用
                    //也可以做其它处理
                    finish();
                }
                break;
            default:
        }
    }

附加问题:

本以为这个问题就这样愉快滴解决了。结果这两天,测试来找我说Monkey测试时,clock会发生crash

我看了一下log,发现还是这个问题。

我猜测要么是clock应用没打开就运行了AlarmService.java,调用了getCallState()方法导致的crash,要么是READ_PHONE_STATE权限没生效。

这个问题必须解决,如果clock发生crash太多次,会被杀死,程序就停止了。

ActivityManager: Force-killing crashed app com.android.deskclock at watcher's request

解决方法:

Android Q,去掉了READ_PHONE_STATE权限,取而代之的是一个系统级别的权限:READ_PHONE_STATE,这个权限不是危险权限,不需要动态授权,就不会出现crash了。

开发者网站请参考:

Android 10 中的隐私权变更  |  Android 开发者  |  Android Developers

Guess you like

Origin blog.csdn.net/m0_50408097/article/details/122346377