【问题标题】:Access phone number of incoming calls in flutter在颤动中访问来电的电话号码
【发布时间】:2021-05-12 16:34:05
【问题描述】:

我们如何像 Truecaller 那样在颤动中访问来电的电话号码。

我在网上引用了这个查询,发现 Flutter 目前不支持该功能。这是真的还是有什么方法可以访问来电的电话号码?

【问题讨论】:

    标签: java android flutter dart


    【解决方案1】:

    你必须通过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 里面应该用什么。
    • 你的包的名字,比如com.example.myapp你可以在build.gradle中找到确切的名字
    • 以及如何在主函数中使用/调用它?
    • 您必须按照flutter.dev/docs/development/platform-integration/… 的教程进行操作。我建议使用 pigeon 包,因为它是类型安全的,我编辑了答案
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-23
    • 2021-12-31
    • 2022-08-23
    • 1970-01-01
    相关资源
    最近更新 更多