简体   繁体   English

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

[英]How to detect outgoing call number in Android Q

I'm unable to get outgoing call number in Android Q .我无法在Android Q中获取拨出电话号码。

I've registered receiver in the manifest with this intent filter android.intent.action.NEW_OUTGOING_CALL and in code i'm detecting outgoing phone number like this我已经使用这个意图过滤器android.intent.action.NEW_OUTGOING_CALL在清单中注册了接收器,并且在代码中我正在检测这样的传出电话号码

@Override
public void onReceive(Context context, Intent intent) {
    if(intent.getAction().equals("android.intent.action.NEW_OUTGOING_CALL"))
        String nr = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
}

But i can never get the outgoing call number in Android Q , is there a workaround to get this number differently or since Android Q it is completely impossible to detect outgoing call number?但是我永远无法在Android Q中获取拨出电话号码,是否有一种解决方法可以以不同的方式获取此号码,或者由于Android Q完全不可能检测到拨出电话号码?

Edit: It works with previous android versions编辑:它适用于以前的 android 版本

You need to add PROCESS_OUTGOING_CALLS permission您需要添加 PROCESS_OUTGOING_CALLS 权限

Create OutgoingCallReceiver创建 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);

            }

    }

}

Add required permissions to read outcomming call in AndroidManifest file在 AndroidManifest 文件中添加读取输出调用所需的权限

  <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" />

Request permissions at runtime在运行时请求权限

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);
        }

Add OutgoingCallReceiver in AndroidManifest file在 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>

This code will work fine with you, but when you need to upload your application on Google play, It is ok with NEW_OUTGOING_CALL and READ_PHONE_STATE permission but, you will receive a policy notice from playStore as:此代码适用于您,但是当您需要在 Google Play 上上传您的应用程序时,可以使用 NEW_OUTGOING_CALL 和 READ_PHONE_STATE 权限,但是,您将收到来自 playStore 的政策通知:

Your app manifest requests the Call Log permission group (eg PROCESS_OUTGOING_CALLS) It must be actively registered as the default Phone or Assistant handler on the device.您的应用清单请求呼叫日志权限组(例如 PROCESS_OUTGOING_CALLS) 它必须主动注册为设备上的默认电话或助理处理程序。

in this case you have 2 solution only if you want to read OutCommingCall Number:在这种情况下,只有当您想读取 OutCommingCall 号码时,您才有 2 个解决方案:

Send declaration form to google declaration form发送申报表到谷歌申报表

Or Make your application dialer app或制作您的应用程序拨号器应用程序

Check Developer Policy Center检查开发者政策中心

From the documentation for android.intent.action.NEW_OUTGOING_CALL :android.intent.action.NEW_OUTGOING_CALL的文档中:

This constant was deprecated in API level 29. Apps that redirect outgoing calls should use the CallRedirectionService API.此常量在 API 级别 29 中已弃用。重定向传出调用的应用程序应使用 CallRedirectionService API。 Apps that perform call screening should use the CallScreeningService API.执行呼叫筛选的应用程序应使用 CallScreeningService API。

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

So I would implement this API first and check if it works as expected.所以我会先实现这个 API 并检查它是否按预期工作。

Answered in Kotlin, not Java:用 Kotlin 而不是 Java 回答:

From sdk >=29 (Android 10 and up) you can register your app as a CallRedirectionService , "to interact between Telecom and its implementor for making outgoing call with optional redirection/cancellation purposes."从 sdk >=29 (Android 10 及更高版本)开始,您可以将您的应用注册为CallRedirectionService“以便在 Telecom 与其实现者之间进行交互,以使用可选的重定向/取消目的进行拨出呼叫。”

This removes the need to create a custom BroadcastReceiver .这消除了创建自定义BroadcastReceiver的需要。

1. On your AndroidManifest.xml file: 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. Create MyCallRedirectionService : 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. Use the RoleManager class to prompt the user to select your app as their CallRedirectionService: 3. 使用RoleManager类提示用户选择您的应用作为他们的 CallRedirectionService:

In this case, I'm requesting as soon as the app is created, over on the MainActivity onCreate() method:在这种情况下,我在创建应用程序后立即请求MainActivity onCreate()方法:

override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        if (!isRedirection())
            roleAcquire(RoleManager.ROLE_CALL_REDIRECTION)
}

Here are the used functions:下面是用到的函数:

    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)
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM