我想要来电者的号码,因为手机在 Android 中响起。由于“TelephonyManager”的“EXTRA_INCOMING_NUMBER”常量现在已被弃用,我不知道如何获得相同的功能。我用谷歌搜索并了解了“通话记录”上下文,但它不能完成相同的工作,因为它可以让您访问通话记录中的号码,但我想要电话响铃时的号码。
对于 Android >= 29,您应该使用
CallScreeningService
代替。官方文档:
以下是对我有用的步骤:
MyCallScreeningService
扩展 CallScreeningService
class MyCallScreeningService : CallScreeningService() {
override fun onScreenCall(callDetails: Call.Details) {
// Check if call is incoming and get the phone number
Log.d("MyCallScreeningService", "onScreenCall")
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
if (callDetails.callDirection == Call.Details.DIRECTION_INCOMING) {
val incomingNumber = extractPhoneNumber(callDetails)
Log.d("MyCallScreeningService", "Incoming Call = $incomingNumber")
val callResponse = CallResponse.Builder()
.setDisallowCall(false)
.setDisallowCall(false)
.setRejectCall(false)
.setSkipCallLog(false)
.setSkipNotification(false)
.build()
// call this to notify user immediately, otherwise there will be a delay
respondToCall(callDetails, callResponse)
}
}
}
private fun extractPhoneNumber(callDetails: Call.Details): String? {
val handle = callDetails.handle
if (handle != null) {
// Attempt to extract phone number from the handle
return handle.schemeSpecificPart
} else {
// Handle is null, try other methods if available
val gatewayInfo = callDetails.gatewayInfo
if (gatewayInfo != null) {
return gatewayInfo.originalAddress.schemeSpecificPart
}
}
return null
}
}
MyCallScreeningService
添加到 AndroidManifest.xml<service android:name=".MyCallScreeningService"
android:exported="true"
android:permission="android.permission.BIND_SCREENING_SERVICE">
<intent-filter>
<action android:name="android.telecom.CallScreeningService" />
</intent-filter>
</service>
MainActivity
或其他活动中请求角色并绑定服务:class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
val roleManager = getSystemService(ROLE_SERVICE) as RoleManager
val intent = roleManager.createRequestRoleIntent(RoleManager.ROLE_CALL_SCREENING)
val startForRequestRoleResult = registerForActivityResult(
ActivityResultContracts.StartActivityForResult()
) { result: androidx.activity.result.ActivityResult ->
if (result.resultCode == Activity.RESULT_OK) {
// you will get result here in result.data
bindMyService()
}
}
startForRequestRoleResult.launch(intent)
}
}
private fun bindMyService(){
Log.i("MainActivity", "binding my service")
val mCallServiceIntent = Intent("android.telecom.CallScreeningService")
mCallServiceIntent.setPackage(applicationContext.packageName)
val mServiceConnection: ServiceConnection = object : ServiceConnection {
override fun onServiceConnected(componentName: ComponentName, iBinder: IBinder) {
// iBinder is an instance of CallScreeningService.CallScreenBinder
// CallScreenBinder is an inner class present inside CallScreenService
}
override fun onServiceDisconnected(componentName: ComponentName) {}
override fun onBindingDied(name: ComponentName) {}
}
bindService(mCallServiceIntent, mServiceConnection, BIND_AUTO_CREATE)
}
}