Access phone number of incoming calls in flutter
You would have to implement it through platform channel:
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);
}
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).
Comments
-
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_ about 3 yearsandroid/app/src/main/java/{your_package}/ServiceReceiver.java What should be used there in your_package .
-
Antonin GAVREL about 3 yearsthe name of your package, like
com.example.myapp
you can find the exact name in build.gradle -
daddy_ about 3 yearsAnd how to use/call that inside the main function?
-
Antonin GAVREL about 3 yearsyou 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