简体   繁体   中英

Telephonymanager.EXTRA_INCOMING_NUMBER is deprecated in API level 29

I am in situation where I need to identify incoming call phone number in Android but when using TelephonyManager.EXTRA_INCOMING_NUMBER android studio warning EXTRA_INCOMING_NUMBER is deprecated .I gone through the developers.android.com, it shows apps performing call screening should use the CallScreeningService API instead. But I can't figure out how to use CallScreeningService to get incoming call phone number. Anyone can help me?

As @Saurabh said, the new way to screen calls is through the CallScreeningService . However, for the service to work on Android Q and up, the user needs to set your app as the default caller ID & spam app (which is done by using the new RoleManager class)

  1. Register your screening service:

     <service android:name="com.example.ScreeningService" android:permission="android.permission.BIND_SCREENING_SERVICE"> <intent-filter> <action android:name="android.telecom.CallScreeningService"/> </intent-filter> </service>
  2. Create you service class:

     @RequiresApi(api = Build.VERSION_CODES.N) class ScreeningService: CallScreeningService() { override fun onScreenCall(details: Details) { //code here } }
  3. Request the screening role from the user in your main activity (or where ever you see as fit):

     @RequiresApi(Build.VERSION_CODES.Q) private fun requestScreeningRole(){ val roleManager = getSystemService(Context.ROLE_SERVICE) as RoleManager val isHeld = roleManager.isRoleHeld(RoleManager.ROLE_CALL_SCREENING) if(.isHeld){ //ask the user to set your app as the default screening app val intent = roleManager.createRequestRoleIntent(RoleManager,ROLE_CALL_SCREENING) startActivityForResult(intent, 123) } else { //you are already the default screening app! } }
  4. Catch the user's response:

     override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { super.onActivityResult(requestCode, resultCode, data) when (requestCode) { 123 -> { if (resultCode == Activity.RESULT_OK) { //The user set you as the default screening app. } else { //the user didn't set you as the default screening app... } } else -> {} } }

Apologies for using a hard coded request code >.<

Create a CallScreeningService like this:

class ScreeningService : CallScreeningService() {

    override fun onScreenCall(callDetails: Call.Details) {
        val phoneNumber = callDetails.handle.schemeSpecificPart
        // Do stuff with phone number
    }
}

And register this service in your AndroidManifest.xml :

<service android:name="your.package.ScreeningService"
         android:permission="android.permission.BIND_SCREENING_SERVICE">
     <intent-filter>
         <action android:name="android.telecom.CallScreeningService"/>
     </intent-filter>
</service>

I know it's pretty late but if someone has simillar problem I found a solution that works on API 28+ for TelephonyManager. For just identifing phone number CallScreeningService is an overkill, and you could probably override users private settings or another app that blocks spam calls.

You need to add android.permission.READ_CALL_LOG in your manifest and request it in a runtime.

 if (Build.VERSION.SdkInt >= BuildVersionCodes.P) {
            if (ApplicationContext.CheckSelfPermission(Manifest.Permission.ReadCallLog) != Permission.Granted)
            {
                ActivityCompat.RequestPermissions(this, new string[] { Manifest.Permission.ReadCallLog }, ACTION_READ_CALL_LOG);
            }
        }

Provided user allows your app to read call log, after broad cast receiver hits OnReceive => ActionPhoneStateChanged phone number will be empty at the first instance, but second time it should be populated. So be prepared that on Api 28+ phone number could be identified at the second time.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM