在flutter中获取来电号码

12

我们如何在Flutter中访问来电的电话号码,就像Truecaller一样。

我查阅了网上的资料并发现Flutter目前不支持此功能。这是真的吗?还是有办法获取来电的电话号码?

1个回答

11
你需要通过平台通道来实现它:platform channel

Android

将以下内容添加到文件android/app/src/main/AndroidManifest.xml中。

<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<receiver android:name=".ServiceReceiver" >
<intent-filter>
    <action android:name="android.intent.action.PHONE_STATE" />
</intent-filter>

创建文件 android/app/src/main/java/{your_package}/ServiceReceiver.java

public class ServiceReceiver extends BroadcastReceiver {

@Override
public void onReceive(final Context context, Intent intent) {
    TelephonyManager telephony = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
    telephony.listen(new PhoneStateListener(){
        @Override
        public void onCallStateChanged(int state, String incomingNumber) {
            super.onCallStateChanged(state, incomingNumber);
            System.out.println("incomingNumber : "+incomingNumber);
        }
    },PhoneStateListener.LISTEN_CALL_STATE);
}

Iphone

您可以在beginRequest(with:)的实现中使用addIdentificationEntry(withNextSequentialPhoneNumber:label:)方法来提供有关来电者的身份信息。

class CustomCallDirectoryProvider: CXCallDirectoryProvider {
    override func beginRequest(with context: CXCallDirectoryExtensionContext) {
        let labelsKeyedByPhoneNumber: [CXCallDirectoryPhoneNumber: String] = [  ]
        for (phoneNumber, label) in labelsKeyedByPhoneNumber.sorted(by: <) {
            context.addIdentificationEntry(withNextSequentialPhoneNumber: phoneNumber, label: label)        
        }

        context.completeRequest()
    }
}

现在有个不太好的消息:就我所知(2021年),对于iPhone来说,如果来电号码不是用户联系人或社交网络的一部分,开发者应用程序没有访问权限。这可以说是需要改变的事情。

也许你可以尝试做一个后台进程,当你接到电话时自动截屏,然后处理图像以提取电话号码。但我对iOS的经验很少,甚至不知道苹果是否会允许这样做。无论如何,祝你好运,如果成功了,请毫不犹豫地发布一个软件包,这肯定会是一个伟大的产品!

最后你必须通过Pigeon实现类型安全的平台通道:

import 'generated_pigeon.dart'

void onClick() async {
  SearchRequest request = SearchRequest()..query = 'test';
  Api api = Api();
  SearchReply reply = await api.search(request);
  print('reply: ${reply.result}');
}
使用Pigeon可以消除主机和客户端之间匹配消息名称和数据类型的需求。它支持:嵌套类,将消息分组成API,生成异步封装代码以及在任一方向发送消息。生成的代码可读性强,并保证不同版本的多个客户端之间不会发生冲突。支持的语言包括Objective-C,Java,Kotlin和Swift(通过Objective-C交互)。

android/app/src/main/java/{your_package}/ServiceReceiver.java 中应该使用什么来代替 your_package。 - daddy_
你的包名,例如com.example.myapp,你可以在build.gradle文件中找到确切的名称。 - Antonin GAVREL
如何在主函数中使用/调用它? - daddy_
你需要按照 https://flutter.dev/docs/development/platform-integration/platform-channels?tab=android-channel-java-tab 的教程进行操作。我建议使用pigeon包,因为它是类型安全的。我已经修改了答案。 - Antonin GAVREL

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