Reputation: 31
PhoneStateListener
's onCallStateChanged
took the state of the phone call and the number being called as parameters:
val telephonyManager =
context.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
telephonyManager.listen(
object : PhoneStateListener() {
override fun onCallStateChanged(state: Int, phoneNumber: String) {
super.onCallStateChanged(state, phoneNumber)
}
},
PhoneStateListener.LISTEN_CALL_STATE
)
After the deprecation of listen()
and PhoneStateListener
, the suggested way to listen to phone calls is through registerTelephonyCallback()
, that takes an Executor
and a TelephonyCallback
as parameters, the problem is that TelephonyCallback.CallStateListener
's onCallStateChanged
only takes the call state as parameter:
telephonyManager.registerTelephonyCallback(
context.mainExecutor,
object : TelephonyCallback(), TelephonyCallback.CallStateListener {
override fun onCallStateChanged(state: Int) {
// WHERE IS PHONE NUMBER?
}
}
)
I absolutely need to know the phone number being called in order to make my app work properly.
Does someone know how to obtain it using TelephonyCallback
or, at least, without using deprecated methods?
Upvotes: 2
Views: 3931
Reputation: 810
I have accessed it using intent:
val incomingNumber: String? = intent?.getStringExtra(TelephonyManager.EXTRA_INCOMING_NUMBER)
Upvotes: 0
Reputation: 31
I solved it using CallScreeningService
, that is available from API 24, but unusable until API 29 because of callDirection
:
@RequiresApi(Build.VERSION_CODES.N)
class PhoneCallScreening : CallScreeningService() {
override fun onScreenCall(callDetails: Call.Details) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
if (callDetails.callDirection == Call.Details.DIRECTION_OUTGOING) {
val phoneNumber = callDetails.handle.schemeSpecificPart
PreferenceManager
.getDefaultSharedPreferences(this)
.edit()
.putString(CALLED_PHONE_NUMBER_KEY, phoneNumber)
.apply()
}
}
}
}
In order to use this, your app has to become the default one for call screening:
@RequiresApi(api = Build.VERSION_CODES.Q)
public void requestRole() {
RoleManager roleManager = (RoleManager) getSystemService(ROLE_SERVICE);
Intent intent = roleManager.createRequestRoleIntent(RoleManager.ROLE_CALL_SCREENING);
startActivityForResult(intent, PHONE_SCREENING_REQUEST_ID);
}
I don't know if you can access any other information about the call besides the phone number, I currently save the phone number in SharedPreferences and then access it in the new PhoneStateListener
's onCallStateChanged
.
As I said before, this solution is only possible from API 29, for lower API versions you have to use the deprecated way, I think is the only one to achieve this.
Upvotes: 1