如何在Android 10上获取呼出电话号码而无需创建自定义拨号器界面?

pbpqsu0x  于 2023-05-15  发布在  Android
关注(0)|答案(1)|浏览(198)

我正在开发一个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" />
  • 呼出呼叫接收方:
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()
    }
}
mtb9vblg

mtb9vblg1#

我通过实现一个简单的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) ?: ""
        } 
    }
}

相关问题