Access phone number of incoming calls in flutter

2,542

You would have to implement it through platform channel:

Android

add to File 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>

create File 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

To provide identifying information about incoming callers, you use the addIdentificationEntry(withNextSequentialPhoneNumber:label:) method in the implementation of beginRequest(with:).

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

Now the bad news: For Iphone, as far as I know (2021), developers apps do not have access to the incoming phone number if its not part of the user's contact or social network, this is arguably something that would deserve to change.

Maybe you could potentially do something like a background process that takes a screen capture when you receive a call, and then process the image to extract the phone number. But I have very little experience with IOS so I don't even know if Apple would allow that. Anyways good luck and don't hesite to publish a package if you are successful with that, it would be definitely a great one!

Finally you have to implement typesafe platform channels via 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}');
}

Using Pigeon eliminates the need to match strings between host and client for the names and datatypes of messages. It supports: nested classes, grouping messages into APIs, generation of asynchronous wrapper code and sending messages in either direction. The generated code is readable and guarantees there will be no conflicts between multiple clients of different versions. Supported languages are Objective-C, Java, Kotlin and Swift (via Objective-C interop).

Share:
2,542
daddy_
Author by

daddy_

Hey sup?

Updated on December 27, 2022

Comments

  • daddy_
    daddy_ over 1 year

    How can we access the phone number of an incoming call in flutter, like the one Truecaller does.

    I referenced this query over the web and found that flutter currently doesn't supports that feature. Is it true or there is some way to access the phone number of an incoming call?

  • daddy_
    daddy_ about 3 years
    android/app/src/main/java/{your_package}/ServiceReceiver.jav‌​a What should be used there in your_package .
  • Antonin GAVREL
    Antonin GAVREL about 3 years
    the name of your package, like com.example.myapp you can find the exact name in build.gradle
  • daddy_
    daddy_ about 3 years
    And how to use/call that inside the main function?
  • Antonin GAVREL
    Antonin GAVREL about 3 years
    you have to follow the tutorial at flutter.dev/docs/development/platform-integration/…. I would recommend to use the pigeon package as it is typesafe, I edited the answer