TelephonyManager.EXTRA_INCOMING_NUMBER 在API级别29中已被弃用。

3

我处于一种情况中,需要在Android中识别来电电话号码,但是使用 TelephonyManager.EXTRA_INCOMING_NUMBER 时,Android Studio 警告 EXTRA_INCOMING_NUMBER 已过时。我查看了 developers.android.com,它显示执行通话筛选的应用程序应改为使用 CallScreeningService API。但我无法弄清如何使用 CallScreeningService 来获取来电电话号码。有人可以帮我吗?

3个回答

6
正如 @Saurabh 所说,筛选通话的新方式是通过 CallScreeningService。但是,为了使服务在 Android Q 及以上版本上正常工作,用户必须将您的应用设置为默认的来电显示和垃圾短信应用(这可以使用新的 RoleManager 类完成)。
  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 -> {}
             }
         }
    

很抱歉使用了硬编码的请求代码 >.<


2
像这样创建一个CallScreeningService

class ScreeningService : CallScreeningService() {

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

并在您的 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>

2
这个服务类“ScreeningService”在呼入电话时没有被调用,重写的方法也没有被调用。我已经按照您提到的在清单文件中注册了它。你试过了吗?感谢您的回复。 - eliot
你正在测试哪个Android版本? - Saurabh Thorat
我正在使用Android R并在API 29中进行测试。 - eliot
我不确定,但只有默认拨号应用程序的CallScreeningService被调用。在Android Q之后可能已经发生了改变。尝试将您的应用程序设置为默认拨号器。 - Saurabh Thorat
我也遇到同样的问题。我的手机是三星S9。可能需要更多的东西…… - Jarda Pavlíček
这只会在Android 10(Q)及以上版本中调用。 - Peter Fam

0

我知道现在有点晚了,但如果有人遇到类似的问题,我发现一个适用于API 28+的解决方法,用于识别电话号码,CallScreeningService太过复杂了,您可能可以覆盖用户的私人设置或其他阻止垃圾电话的应用程序。

您需要在清单中添加android.permission.READ_CALL_LOG并在运行时请求它。

 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);
            }
        }

如果用户允许您的应用程序读取通话记录,在广播接收器触发 OnReceive => ActionPhoneStateChanged 后,电话号码将在第一次为空,但第二次应该会填充。 因此,请准备好在 Api 28+ 上识别电话号码的第二次出现。


READ_CALL_LOG 权限是一项受限制的权限。除非您的应用程序可以设置为默认的来电筛选器或默认的拨号器,否则您将不被允许发布具有 READ_CALL_LOG 权限的应用程序,除非填写一个要求并给出充分理由的表格来请求此权限。 - Leknesh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接