簡體   English   中英

如何在Android Q中檢測撥出電話號碼

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

我無法在Android Q中獲取撥出電話號碼。

我已經使用這個意圖過濾器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);
}

但是我永遠無法在Android Q中獲取撥出電話號碼,是否有一種解決方法可以以不同的方式獲取此號碼,或者由於Android Q完全不可能檢測到撥出電話號碼?

編輯:它適用於以前的 android 版本

您需要添加 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 文件中添加讀取輸出調用所需的權限

  <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 號碼時,您才有 2 個解決方案:

發送申報表到谷歌申報表

或制作您的應用程序撥號器應用程序

檢查開發者政策中心

android.intent.action.NEW_OUTGOING_CALL的文檔中:

此常量在 API 級別 29 中已棄用。重定向傳出調用的應用程序應使用 CallRedirectionService API。 執行呼叫篩選的應用程序應使用 CallScreeningService API。

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

所以我會先實現這個 API 並檢查它是否按預期工作。

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM