为了账号安全,请及时绑定邮箱和手机立即绑定

如何在 Android Q 中检测拨出电话号码

如何在 Android Q 中检测拨出电话号码

慕丝7291255 2023-03-09 14:27:27
我无法在Android Q中获取拨出电话号码。我已经使用此意图过滤器在清单中注册了接收器android.intent.action.NEW_OUTGOING_CALL,并且在代码中我正在检测这样的传出电话号码@Overridepublic void onReceive(Context context, Intent intent) {    if(intent.getAction().equals("android.intent.action.NEW_OUTGOING_CALL"))        String nr = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);}但是我永远无法在Android Q中获取拨出电话号码,是否有解决方法可以不同地获取此号码,或者因为Android Q完全不可能检测到拨出电话号码?编辑:它适用于以前的安卓版本
查看完整描述

3 回答

?
侃侃尔雅

TA贡献1801条经验 获得超16个赞

您需要添加 PROCESS_OUTGOING_CALLS 权限


创建 OutgoingCallReceiver


import android.app.Service;

import android.content.BroadcastReceiver;

import android.content.Context;

import android.content.Intent;

import android.telephony.TelephonyManager;


public class OutgoingCallReceiver extends BroadcastReceiver {


    @Override

    public void onReceive(Context context, Intent intent) {


            TelephonyManager tm = (TelephonyManager)context.getSystemService(Service.TELEPHONY_SERVICE);

            if (tm.getCallState() == TelephonyManager.CALL_STATE_OFFHOOK) {


                String number = intent.getStringExtra(TelephonyManager.EXTRA_INCOMING_NUMBER);


            }


    }


}

在 AndroidManifest 文件中添加读取 outcoming 调用所需的权限


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

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

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

在运行时请求权限


if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE)

                != PackageManager.PERMISSION_GRANTED) {

            ActivityCompat.requestPermissions(this,

                    new String[]{Manifest.permission.PROCESS_OUTGOING_CALLS, Manifest.permission.READ_PHONE_STATE},

                    1);

        }

在 AndroidManifest 文件中添加 OutgoingCallReceiver


  <receiver

        android:name=".application.services.OutgoingCallReceiver"

        android:enabled="true"

        android:exported="true">

        <intent-filter>

            <action android:name="android.intent.action.NEW_OUTGOING_CALL" />

        </intent-filter>

        <intent-filter>

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

        </intent-filter>

    </receiver>

此代码适用于您,但是当您需要在 Google play 上上传您的应用程序时,可以使用 NEW_OUTGOING_CALL 和 READ_PHONE_STATE 权限,但是,您会收到来自 playStore 的政策通知,如下所示:


您的应用程序清单请求呼叫日志权限组(例如 PROCESS_OUTGOING_CALLS)它必须主动注册为设备上的默认电话或助理处理程序。


在这种情况下,只有当您想读取 OutCommingCall Number 时,您才有 2 个解决方案:


将申报表发送到谷歌申报表

或者制作您的应用程序拨号器应用程序

检查开发者政策中心


查看完整回答
反对 回复 2023-03-09
?
红颜莎娜

TA贡献1842条经验 获得超12个赞

用 Kotlin 而非 Java 回答:


从 sdk >=29(Android 10 及更高版本)开始,您可以将您的应用程序注册为 CallRedirectionService , “以便在 Telecom 与其实现者之间进行交互,以使用可选的重定向/取消目的进行拨出呼叫。”


这消除了创建自定义BroadcastReceiver的需要。


1. 在您的 AndroidManifest.xml 文件中:


<service

       android:name=".MyCallRedirectionService"

       android:exported="true"

       android:permission="android.permission.BIND_CALL_REDIRECTION_SERVICE">

       <intent-filter>

           <action android:name="android.telecom.CallRedirectionService" />

       </intent-filter>

</service>

2. 创建MyCallRedirectionService:


class MyCallRedirectionService : CallRedirectionService() {


    override fun onPlaceCall(

        handle: Uri,

        initialPhoneAccount: PhoneAccountHandle,

        allowInteractiveResponse: Boolean

    ) {


        // We can get the outgoing number from the handle parameter:

        Log.i("Phone Number:", handle.toString())

    }

}

3. 使用RoleManager类提示用户选择您的应用作为他们的 CallRedirectionService:


在这种情况下,我会在创建应用程序后立即请求方法MainActivity onCreate():


override fun onCreate(savedInstanceState: Bundle?) {

        super.onCreate(savedInstanceState)

        setContentView(R.layout.activity_main)


        if (!isRedirection())

            roleAcquire(RoleManager.ROLE_CALL_REDIRECTION)

}

以下是使用的函数:


    private fun isRedirection(): Boolean {

        return isRoleHeldByApp(RoleManager.ROLE_CALL_REDIRECTION)

    }


    private fun isRoleHeldByApp(roleName: String): Boolean {

        val roleManager: RoleManager? = getSystemService(RoleManager::class.java)

        return roleManager!!.isRoleHeld(roleName)


    }


    private fun roleAcquire(roleName: String) {

        val roleManager: RoleManager?

        if (roleAvailable(roleName)) {

            roleManager = getSystemService(RoleManager::class.java)

            val intent = roleManager.createRequestRoleIntent(roleName)

            startActivityForResult(intent, 1)

        } else {

            Toast.makeText(

                this,

                "Redirection call with role in not available",

                Toast.LENGTH_SHORT

            ).show()

        }


    }


    private fun roleAvailable(roleName: String): Boolean {

        val roleManager: RoleManager? = getSystemService(RoleManager::class.java)

        return roleManager!!.isRoleAvailable(roleName)

    }


查看完整回答
反对 回复 2023-03-09
?
元芳怎么了

TA贡献1798条经验 获得超7个赞

来自android.intent.action.NEW_OUTGOING_CALL的文档:

此常量在 API 级别 29 中已弃用。重定向传出呼叫的应用程序应使用 CallRedirectionService API。执行呼叫筛选的应用程序应使用 CallScreeningService API。

https://developer.android.com/reference/android/content/Intent

所以我会先实现这个 API 并检查它是否按预期工作。


查看完整回答
反对 回复 2023-03-09
  • 3 回答
  • 0 关注
  • 187 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信