如何在不创建自定义拨号界面的情况下获取Android 10的去电电话号码?

问题描述 投票:0回答:1

我正在开发一个 Android 应用程序,它需要跟踪拨出电话号码并执行到我应用程序中特定屏幕的深度链接。但是,我不能要求用户使用我的应用程序而不是使用默认拨号器来拨打电话。

从Android 10开始,PROCESS_OUTGOING_CALLS权限被弃用了,我没办法自己创建拨号接口获取呼出电话号码。是否有任何解决方法可以在不创建自定义拨号器界面的情况下获取 Android 10 上拨出电话的电话号码?

我尝试使用 BroadcastReceiver 来监听 NEW_OUTGOING_CALL 动作,但是 EXTRA_PHONE_NUMBER 字段为空,我无法获取拨出电话的电话号码。 我希望在 BroadcastReceiver 中获取电话号码,然后将其传递给处理深度链接的前台服务。

如果在 onCallStateChanged 中为空,如何获取电话号码?

下面我将分享我的代码:

  • 清单权限:
<uses-feature
        android:name="android.hardware.telephony"
        android:required="false" />

    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />
    <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
  • OutgoingCallReceiver:
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import androidx.core.content.ContextCompat

class OutgoingCallReceiver : BroadcastReceiver() {

    override fun onReceive(context: Context, intent: Intent) {
        if (intent.action == Intent.ACTION_NEW_OUTGOING_CALL) {
            val phoneNumber = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER)
            if (!phoneNumber.isNullOrEmpty()) {
                // Start the service for intercepting outgoing calls
                val serviceIntent = Intent(context, OutgoingCallService::class.java)
                ContextCompat.startForegroundService(context, serviceIntent)
            }
        }
    }
}
  • 传出呼叫服务:
import android.annotation.SuppressLint
import android.app.Service
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.os.IBinder
import android.telephony.PhoneStateListener
import android.telephony.TelephonyManager

class OutgoingCallService : Service() {

    private lateinit var telephonyManager: TelephonyManager
    private lateinit var phoneStateListener: PhoneStateListener

    override fun onBind(intent: Intent?): IBinder? {
        return null
    }

    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        telephonyManager = getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
        phoneStateListener = createPhoneStateListener()
        telephonyManager.listen(phoneStateListener, PhoneStateListener.LISTEN_CALL_STATE)
        return START_STICKY
    }

    override fun onDestroy() {
        super.onDestroy()
        telephonyManager.listen(phoneStateListener, PhoneStateListener.LISTEN_NONE)
    }

    @SuppressLint("MissingPermission")
    private fun createPhoneStateListener(): PhoneStateListener {
        return object : PhoneStateListener() {
            override fun onCallStateChanged(state: Int, phoneNumber: String?) {
                super.onCallStateChanged(state, phoneNumber)
                when (state) {
                    TelephonyManager.CALL_STATE_OFFHOOK -> {
                        if (phoneNumber == "SPECIFIC PHONE NUMBER") {
                            redirectToApp()
                        }
                    }
                }
            }
        }
    }

    private fun redirectToApp() {
        // Redirect application's specific screen using an Intent
        val context = applicationContext
        val deepLinkIntent = Intent(Intent.ACTION_VIEW, Uri.parse("scheme://host"))
        deepLinkIntent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
        context.startActivity(deepLinkIntent)
    }
}
  • 主要活动:
import android.Manifest
import android.content.Intent
import android.content.IntentFilter
import android.content.pm.PackageManager
import android.os.Build
import android.os.Bundle
import androidx.activity.ComponentActivity 
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import com.example.callinterceptor.ui.theme.CallInterceptorTheme

class MainActivity : ComponentActivity() {

    private val outgoingCallReceiver = OutgoingCallReceiver()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        // Check and request permissions if necessary
        checkAndRequestPermissions()

        // Register BroadcastReceiver to intercept outgoing calls
        registerOutgoingCallReceiver() 
    }

    private fun checkAndRequestPermissions() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            val permissions = arrayOf(
                Manifest.permission.READ_PHONE_STATE,
                Manifest.permission.PROCESS_OUTGOING_CALLS
            )

            val missingPermissions = ArrayList<String>()
            for (permission in permissions) {
                if (ContextCompat.checkSelfPermission(
                        this,
                        permission
                    ) != PackageManager.PERMISSION_GRANTED
                ) {
                    missingPermissions.add(permission)
                }
            }

            if (missingPermissions.isNotEmpty()) {
                ActivityCompat.requestPermissions(
                    this,
                    missingPermissions.toTypedArray(),
                    PERMISSIONS_REQUEST_CODE
                )
            }
        }
    }

    private fun registerOutgoingCallReceiver() {
        val intentFilter = IntentFilter(Intent.ACTION_NEW_OUTGOING_CALL)
        registerReceiver(outgoingCallReceiver, intentFilter)
    }

    private fun unregisterOutgoingCallReceiver() {
        unregisterReceiver(outgoingCallReceiver)
    }

    companion object {
        private const val PERMISSIONS_REQUEST_CODE = 123
    }

    override fun onDestroy() {
        super.onDestroy()

        // Unregister the BroadcastReceiver
        unregisterOutgoingCallReceiver()
    }
}
android android-intent android-permissions privacy outgoing-call
1个回答
0
投票

我设法通过实现一个简单的 BroadcastReceiver 解决了这个问题(代码是巨大的总结)!

internal class PhoneStateReceiver : BroadcastReceiver() {

    private var filters: IntentFilter = IntentFilter()

    init {
        filters.addAction(TelephonyManager.ACTION_PHONE_STATE_CHANGED)
        filters.addAction(Intent.ACTION_NEW_OUTGOING_CALL)
    }

    fun register(context: Context) = context.registerReceiver(this, filters)

    fun unregister(context: Context) = context.unregisterReceiver(this)

    override fun onReceive(context: Context, intent: Intent) {
        var phoneNumer = ""
        val a = intent.action
        if (a == TelephonyManager.ACTION_PHONE_STATE_CHANGED) {
            phoneNumer = intent.getStringExtra(TelephonyManager.EXTRA_INCOMING_NUMBER) ?: ""
        }
        if (a == Intent.ACTION_NEW_OUTGOING_CALL) {
            phoneNumer = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER) ?: ""
        } 
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.