【问题标题】:Permission for Broadcast receiver Telephony Manager on android Pie OSandroid Pie OS 上广播接收器电话管理器的权限
【发布时间】:2019-08-22 07:23:41
【问题描述】:

我正在开发一个应用程序,该应用程序有 OTP 电话来设置用户密码。所以我要做的是自动设置我从电话到 textview 的电话号码。问题是PhoneStateReceiver 类扩展了BroadcastReceiver 而不是在Pie 上工作,而是在Oreo 上工作。

它在我的 Oreo 手机上工作得非常好,但在 Pie 手机上却没有,我没有收到任何错误,除了在 Pie 上没有调用 PhoneStateReceiver 的 onReceive。

public class PhoneStateReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        final String action = intent.getAction();

        if (action.equals(TelephonyManager.ACTION_PHONE_STATE_CHANGED)) {
            String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
            String incomingNumber = intent.getStringExtra(TelephonyManager.EXTRA_INCOMING_NUMBER);

            if((state.equals(TelephonyManager.EXTRA_STATE_RINGING))){
                Toast.makeText(context,"Received State",Toast.LENGTH_SHORT).show();
            }

            if ((state.equals(TelephonyManager.EXTRA_STATE_OFFHOOK))){
                Intent local = new Intent();
                local.setAction("service.to.activity.transfer");
                local.setAction("android.intent.action.PHONE_STATE");
                local.setAction("android.intent.action.NEW_OUTGOING_CALL");
                local.putExtra("number", incomingNumber);
                context.sendBroadcast(local);

            }
            if (state.equals(TelephonyManager.EXTRA_STATE_IDLE)){
                Intent local = new Intent();
                local.setAction("service.to.activity.transfer");
                local.setAction("android.intent.action.PHONE_STATE");
                local.setAction("android.intent.action.NEW_OUTGOING_CALL");
                local.putExtra("number", incomingNumber);
                context.sendBroadcast(local);

            }
        }
    }

}

这是我的 Manifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="com.jpx.qur">

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

    <application
        android:name=".modules.App"
        android:allowBackup="false"
        android:icon="@mipmap/ic_launcher_square"
        android:label="@string/app_name"
        android:networkSecurityConfig="@xml/network_security_config"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme"
        tools:replace="android:allowBackup">

        <receiver android:name=".utils.phoneutil.PhoneStateReceiver">
            <intent-filter>

                <action android:name="android.intent.action.PHONE_STATE" />
            </intent-filter>

        </receiver>

    </application>

</manifest>

这就是我在我的 Activity 上处理注册接收器的方式

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

        getNumberPhone();

    }

    public void getNumberPhone(){

        IntentFilter filter = new IntentFilter();
        filter.addAction("service.to.activity.transfer");
        BroadcastReceiver updateUIReciver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {

            //UI update here
            if (intent != null){
                String message = intent.getStringExtra("number");

                if(message != null){
                    if(message.length() == DIGITLENGTH){
                        String asubstring = message.substring(1, message.length());
                        pin1.setText(""+asubstring.charAt(0));
                        pin2.setText(""+asubstring.charAt(1));
                        pin3.setText(""+asubstring.charAt(2));
                        pin4.setText(""+asubstring.charAt(3));
                    }

                }
            }
            }
        };
        registerReceiver(updateUIReciver, filter);

    }

它在我的 Oreo 手机上工作得非常好,但在 Pie 手机上却没有,我没有收到任何错误,除了在 Pie 上,PhoneStateReceiver 的 onReceive 没有被调用。请帮我解决这个问题

【问题讨论】:

  • 你检查过this吗?

标签: android broadcastreceiver telephonymanager


【解决方案1】:

在清单中添加 READ_CALL_LOG 权限,如下所示,并且还 获取运行时 权限:

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

根据 Android 文档:

限制访问通话记录

Android 9 引入了 CALL_LOG 权限组并将 READ_CALL_LOG、WRITE_CALL_LOG 和 PROCESS_OUTGOING_CALLS 权限 进这个组。在以前的 Android 版本中,这些权限 位于 PHONE 权限组中。

限制访问电话号码 在 Android 9 上运行的应用程序不能 无需先获取电话号码或电话状态 READ_CALL_LOG 权限,除了其他权限 您应用的用例需要。

与来电和去电关联的电话号码可见 在电话状态广播,例如用于来电和去电 并且可以从 PhoneStateListener 类访问。没有 READ_CALL_LOG 权限,但是,电话号码字段 在 PHONE_STATE_CHANGED 广播中提供并通过 PhoneStateListener 为空。

要从电话状态读取电话号码,请更新您的应用以请求 根据您的用例获得必要的权限:

要从 PHONE_STATE 意图操作中读取数字,您需要 READ_CALL_LOG 权限和 READ_PHONE_STATE 权限。阅读 来自 onCallStateChanged() 的数字,您需要 READ_CALL_LOG 仅限许可。您不需要 READ_PHONE_STATE 权限。

查看完整文档here

【讨论】:

  • 如果我使用 READ_CALL_LOG,我还需要 BroadcastReceiver,还是使用不同类型的方法?因为我正在尝试使用这种方法,但它不起作用stackoverflow.com/a/21237242/7908440。您能否使用广播接收器方法或其他方法进行更多解释。谢谢你:)
  • READ_CALL_LOG 权限,只是 android pie 中的安全权限,在 pie 版本中,如果没有此权限,您将无法读取手机状态。如果您获得运行时权限并且您的代码是正确的,那么您将获得完美的结果。
  • Android 文档提及:与来电和去电关联的电话号码在电话状态广播中可见,例如用于来电和去电,并可从 PhoneStateListener 类访问。但是,如果没有 READ_CALL_LOG 权限,在 PHONE_STATE_CHANGED 广播中并通过 PhoneStateListener 提供的电话号码字段为空。
猜你喜欢
  • 2016-03-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-14
  • 1970-01-01
  • 2018-01-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多