在Android 9中获取来电者ID

18

我一直在使用以下代码在 BroadcastReceiver 中获取来电的呼叫者ID:

@Override
public void onReceive(Context aContext, Intent aIntent) {
   String action = aIntent.getAction();

   if (action==null) return;
   if (!action.equals("android.intent.action.PHONE_STATE")) return;

   String curState = aIntent.getStringExtra(TelephonyManager.EXTRA_STATE);

   if ((TelephonyManager.EXTRA_STATE_RINGING.equals(curState))
      &&(TelephonyManager.EXTRA_STATE_IDLE.equals(oldState)))){
      String incNumber = aIntent.getStringExtra(TelephonyManager.EXTRA_INCOMING_NUMBER);

      // do something here
   }
   oldState=curState;
}

不幸的是,这在Android 9.0(API 28)中已经停止工作。 更具体地说, aIntent.getStringExtra(EXTRA_INCOMING_NUMBER)始终返回null。 在android版本<=API 27中,一切正常

我还在清单文件中添加了READ_PHONE_STATEREAD_CALL_LOG权限。

有什么想法吗? 还有其他人遇到同样的问题吗?


先生,请发布logcat错误。 - EL TEGANI MOHAMED HAMAD GABIR
嗨,没有logcat错误。代码似乎正常执行,但incNumber变量始终包含null。 - haris
对我来说,在Android9上始终是null。有人遇到过这个问题吗? - powder366
你有找到任何解决方案吗?我已经在运行时请求了两个权限,但incomingNumber仍然为空。 - GreenROBO
@GreenROBO - 抱歉回复晚了 - 请看下面的答案(以及答案下面的评论...)。 - haris
2个回答

30

我找到了我的问题的答案:

首先,在Android 9中,你必须显式地在运行时请求READ_PHONE_STATEREAD_CALL_LOG权限。在之前的Android版本中,你只需要请求READ_PHONE_STATE权限。两个权限都必须在运行时请求。

其次,如果以上两个权限都被授予,onReceive方法会被调用两次(!!)。第一次意图时“空的”(EXTRA_INCOMING_NUMBER为空),第二次意图正常填充。这在TelephonyManager文档中有记录。


是的,接收器已被调用。 - haris
2
抱歉,之前的评论发布时还没有完成。我想提醒您注意新的谷歌政策,自2019年1月9日起生效,限制使用READ_CALL_LOG权限(请参见先前评论中的链接)。 - haris
3
正如@haris所写,自2019年1月9日起,如果您的应用程序不是默认拨号器应用程序,则无法请求READ_CALL_LOG权限。在API 28及以上版本上,我该如何获取来电者身份信息而不需要此权限? - spajdo
读取通话记录的权限受到Google开发者控制台的限制。您无法请求此权限。您需要填写表格来获取访问权限,只有他们同意才能使用此权限。 - RushDroid
非常感谢,它正在运行。在第一次onReceive调用时我得到了一个错误,我加了一个条件来执行下一行,只有当传入的号码不为空时才会自动再次调用onReceive调用,幸好得到了传入的号码.. - Suhad Bin Zubair
显示剩余9条评论

4
在清单文件中添加以下代码来获取 READ_CALL_LOG 权限:
<uses-permission android:name="android.permission.READ_CALL_LOG" />

然后

应用程序 -> 您的应用程序 -> 权限 -> 授予通话日志权限

此后每次您的接收器被调用时,您应该能够获取到电话号码。


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