Flutter来电通知插件notification_incoming_call的使用
Flutter来电通知插件notification_incoming_call的使用
功能特性 ⭐
- 显示来电
- 启动拨出电话
安装 🚀
1. 添加依赖包
运行以下命令:
flutter pub add notification_incoming_call
在 pubspec.yaml
文件中添加依赖项:
dependencies:
notification_incoming_call: any
2. 配置项目
Android
编辑 AndroidManifest.xml
文件:
<manifest...>
...
<!--
使用此权限从互联网加载图片
-->
<uses-permission android:name="android.permission.INTERNET"/>
</manifest>
iOS
编辑 Info.plist
文件:
<key>UIBackgroundModes</key>
<array>
<string>processing</string>
<string>remote-notification</string>
<string>voip</string>
</array>
3. 使用
导入库
import 'package:notification_incoming_call/notification_incoming_call.dart';
接收来电
this._currentUuid = _uuid.v4();
var params = <String, dynamic>{
'id': _currentUuid,
'nameCaller': 'Hien Nguyen',
'appName': 'Callkit',
'avatar': 'https://i.pravatar.cc/100',
'handle': '0123456789',
'type': 0,
'duration': 30000,
'extra': <String, dynamic>{'userId': '1a2b3c4d'},
'headers': <String, dynamic>{'apiKey': 'Abc@123!', 'platform': 'flutter'},
'android': <String, dynamic>{
'isCustomNotification': true,
'isShowLogo': false,
'backgroundColor': '#0955fa',
'backgroundUrl': 'https://i.pravatar.cc/500',
'actionColor': '#4CAF50'
},
'ios': <String, dynamic>{
'iconName': 'AppIcon40x40',
'handleType': 'generic',
'supportsVideo': true,
'maximumCallGroups': 2,
'maximumCallsPerCallGroup': 1,
'audioSessionMode': 'default',
'audioSessionActive': true,
'audioSessionPreferredSampleRate': 44100.0,
'audioSessionPreferredIOBufferDuration': 0.005,
'supportsDTMF': true,
'supportsHolding': true,
'supportsGrouping': false,
'supportsUngrouping': false,
'ringtonePath': 'Ringtone.caf'
}
};
await NotificationIncomingCall.showCallkitIncoming(params);
启动拨出电话
this._currentUuid = _uuid.v4();
var params = <String, dynamic>{
'id': this._currentUuid,
'nameCaller': 'Hien Nguyen',
'handle': '0123456789',
'type': 1,
'extra': <String, dynamic>{'userId': '1a2b3c4d'},
'ios': <String, dynamic>{'handleType': 'generic'}
};
await NotificationIncomingCall.startCall(params);
结束来电或拨出电话
var params = <String, dynamic>{'id': this._currentUuid};
await NotificationIncomingCall.endCall(params);
结束所有通话
await NotificationIncomingCall.endAllCalls();
获取活跃通话
await NotificationIncomingCall.activeCalls();
输出:
[{"id": "8BAA2B26-47AD-42C1-9197-1D75F662DF78", ...}]
监听事件
NotificationIncomingCall.onEvent.listen((event) {
switch (event!.name) {
case CallEvent.ACTION_CALL_INCOMING:
// TODO: 收到来电
break;
case CallEvent.ACTION_CALL_START:
// TODO: 启动拨出电话
// TODO: 在 Flutter 中显示呼叫界面
break;
case CallEvent.ACTION_CALL_ACCEPT:
// TODO: 接听来电
// TODO: 在 Flutter 中显示呼叫界面
break;
case CallEvent.ACTION_CALL_DECLINE:
// TODO: 拒接来电
break;
case CallEvent.ACTION_CALL_ENDED:
// TODO: 结束来电或拨出电话
break;
case CallEvent.ACTION_CALL_TIMEOUT:
// TODO: 未接听来电
break;
case CallEvent.ACTION_CALL_CALLBACK:
// TODO: 仅 Android - 点击漏接来电通知中的回拨按钮
break;
case CallEvent.ACTION_CALL_TOGGLE_HOLD:
// TODO: 仅 iOS
break;
case CallEvent.ACTION_CALL_TOGGLE_MUTE:
// TODO: 仅 iOS
break;
case CallEvent.ACTION_CALL_TOGGLE_DMTF:
// TODO: 仅 iOS
break;
case CallEvent.ACTION_CALL_TOGGLE_GROUP:
// TODO: 仅 iOS
break;
case CallEvent.ACTION_CALL_TOGGLE_AUDIO_SESSION:
// TODO: 仅 iOS
break;
}
});
从原生调用(iOS PushKit)
var info = [String: Any?]()
info["id"] = "44d915e1-5ff4-4bed-bf13-c423048ec97a"
info["nameCaller"] = "Hien Nguyen"
info["handle"] = "0123456789"
SwiftNotificationIncomingCallPlugin.sharedInstance?.showCallkitIncoming(notification_incoming_call.Data(args: info), fromPushKit: true)
示例代码
example/lib/main.dart
import 'package:flutter/material.dart';
import 'package:notification_incoming_call/notification_incoming_call.dart';
import 'dart:async';
import 'package:uuid/uuid.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
[@override](/user/override)
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
var _uuid = Uuid();
var _currentUuid;
var textEvents = "";
[@override](/user/override)
void initState() {
super.initState();
listenerEvent();
}
// 平台消息是异步的,所以我们初始化时使用异步方法。
Future<void> listenerEvent() async {
// 平台消息可能会失败,所以我们使用带有 PlatformException 的 try/catch。
// 我们还处理消息可能返回 null 的情况。
try {
NotificationIncomingCall.onEvent.listen((event) {
print(event);
if (!mounted) return;
switch (event!.name) {
case CallEvent.ACTION_CALL_INCOMING:
// TODO: 收到来电
break;
case CallEvent.ACTION_CALL_START:
// TODO: 启动拨出电话
// TODO: 在 Flutter 中显示呼叫界面
break;
case CallEvent.ACTION_CALL_ACCEPT:
// TODO: 接听来电
// TODO: 在 Flutter 中显示呼叫界面
break;
case CallEvent.ACTION_CALL_DECLINE:
// TODO: 拒接来电
break;
case CallEvent.ACTION_CALL_ENDED:
// TODO: 结束来电或拨出电话
break;
case CallEvent.ACTION_CALL_TIMEOUT:
// TODO: 未接听来电
break;
case CallEvent.ACTION_CALL_CALLBACK:
// TODO: 仅 Android - 点击漏接来电通知中的回拨按钮
break;
case CallEvent.ACTION_CALL_TOGGLE_HOLD:
// TODO: 仅 iOS
break;
case CallEvent.ACTION_CALL_TOGGLE_MUTE:
// TODO: 仅 iOS
break;
case CallEvent.ACTION_CALL_TOGGLE_DMTF:
// TODO: 仅 iOS
break;
case CallEvent.ACTION_CALL_TOGGLE_GROUP:
// TODO: 仅 iOS
break;
case CallEvent.ACTION_CALL_TOGGLE_AUDIO_SESSION:
// TODO: 仅 iOS
break;
}
setState(() {
textEvents += "${event.toString()}\n";
});
});
} on Exception {}
}
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('插件示例应用'),
actions: <Widget>[
IconButton(
icon: Icon(
Icons.call,
color: Colors.white,
),
onPressed: () async {
this.makeFakeCallInComing();
},
),
IconButton(
icon: Icon(
Icons.call_end,
color: Colors.white,
),
onPressed: () async {
this.endCurrentCall();
},
),
IconButton(
icon: Icon(
Icons.call_made,
color: Colors.white,
),
onPressed: () async {
this.startOutGoingCall();
},
),
IconButton(
icon: Icon(
Icons.call_merge,
color: Colors.white,
),
onPressed: () async {
this.activeCalls();
},
)
],
),
body: LayoutBuilder(
builder: (BuildContext context, BoxConstraints viewportConstraints) {
return SingleChildScrollView(
child: ConstrainedBox(
constraints: BoxConstraints(
minHeight: viewportConstraints.maxHeight,
),
child: Text('$textEvents'),
),
);
},
),
),
);
}
Future<void> makeFakeCallInComing() async {
await Future.delayed(const Duration(seconds: 7), () async {
this._currentUuid = _uuid.v4();
var params = <String, dynamic>{
'id': _currentUuid,
'nameCaller': 'Hien Nguyen',
'appName': 'Callkit',
'avatar': 'https://i.pravatar.cc/100',
'handle': '0123456789',
'type': 0,
'duration': 30000,
'extra': <String, dynamic>{'userId': '1a2b3c4d'},
'headers': <String, dynamic>{'apiKey': 'Abc@123!', 'platform': 'flutter'},
'android': <String, dynamic>{
'isCustomNotification': true,
'isShowLogo': false,
// 'ringtonePath': 'ringtone_default',
'backgroundColor': '#0955fa',
'backgroundUrl': 'https://i.pravatar.cc/500',
'actionColor': '#4CAF50'
},
'ios': <String, dynamic>{
'iconName': 'AppIcon40x40',
'handleType': '',
'supportsVideo': true,
'maximumCallGroups': 2,
'maximumCallsPerCallGroup': 1,
'audioSessionMode': 'default',
'audioSessionActive': true,
'audioSessionPreferredSampleRate': 44100.0,
'audioSessionPreferredIOBufferDuration': 0.005,
'supportsDTMF': true,
'supportsHolding': true,
'supportsGrouping': false,
'supportsUngrouping': false,
'ringtonePath': 'Ringtone.caf'
}
};
await NotificationIncomingCall.showCallkitIncoming(params);
});
}
Future<void> endCurrentCall() async {
var params = <String, dynamic>{'id': this._currentUuid};
await NotificationIncomingCall.endCall(params);
}
Future<void> startOutGoingCall() async {
this._currentUuid = _uuid.v4();
var params = <String, dynamic>{
'id': this._currentUuid,
'nameCaller': 'Hien Nguyen',
'handle': '0123456789',
'type': 1,
'extra': <String, dynamic>{'userId': '1a2b3c4d'},
'ios': <String, dynamic>{'handleType': 'number'} // number/email
};
await NotificationIncomingCall.startCall(params);
}
Future<void> activeCalls() async {
var calls = await NotificationIncomingCall.activeCalls();
print(calls);
}
}
更多关于Flutter来电通知插件notification_incoming_call的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter来电通知插件notification_incoming_call的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是如何在Flutter项目中使用notification_incoming_call
插件来处理来电通知的一个基本示例。这个插件允许你显示一个全屏的来电界面,并在来电时处理一些基本的通知逻辑。
首先,确保你已经在pubspec.yaml
文件中添加了notification_incoming_call
依赖:
dependencies:
flutter:
sdk: flutter
notification_incoming_call: ^x.y.z # 请替换为最新版本号
然后,运行flutter pub get
来安装依赖。
接下来,在你的Flutter项目中,你需要进行一些配置和代码实现。以下是一个基本的示例:
- 初始化插件
在你的主应用文件(通常是main.dart
)中,初始化NotificationIncomingCall
插件。
import 'package:flutter/material.dart';
import 'package:notification_incoming_call/notification_incoming_call.dart';
void main() {
WidgetsFlutterBinding.ensureInitialized();
NotificationIncomingCall().initialize(); // 初始化插件
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Incoming Call Notification Example'),
),
body: Center(
child: Text('Tap the button to simulate an incoming call'),
),
floatingActionButton: FloatingActionButton(
onPressed: () => simulateIncomingCall(),
tooltip: 'Incoming Call',
child: Icon(Icons.phone),
),
),
);
}
void simulateIncomingCall() {
NotificationIncomingCall().showNotification(
title: "Incoming Call",
body: "John Doe is calling",
payload: "call_payload_123", // 你可以传递任何你需要的附加数据
// 其他可选参数,如头像URL、铃声等
);
// 模拟接听或挂断的逻辑
Future.delayed(Duration(seconds: 5), () {
NotificationIncomingCall().cancelNotification();
});
}
}
- 处理来电通知的显示和取消
上面的代码示例中,我们定义了一个简单的Flutter应用,其中包含一个按钮,点击按钮时会模拟一个来电通知。通知会显示5秒钟后自动取消。
- 处理来电的实际逻辑
在实际应用中,你可能需要在接收到来电时执行更多逻辑,比如更新UI、播放铃声、处理接听/挂断操作等。这通常涉及到与你的后端服务进行通信,以及处理用户交互。
- 权限处理
请注意,显示全屏通知通常需要一些特定的系统权限。确保你的应用已经请求并获得了这些权限。在Android上,你可能需要在AndroidManifest.xml
中声明相关权限,并在运行时请求它们。
- 平台特定配置
对于iOS,你可能需要在Info.plist
中添加一些配置来支持全屏通知。对于Android,你可能需要在AndroidManifest.xml
中进行一些配置,并确保你的应用具有显示系统级通知的权限。
- 插件的具体使用
notification_incoming_call
插件提供了多种配置选项,如设置铃声、振动模式、全屏通知的布局等。你可以查阅插件的官方文档来了解更多详细信息和高级用法。
请注意,由于插件和Flutter框架的更新,上述代码可能需要根据你的Flutter环境和插件版本进行调整。始终参考插件的官方文档和示例代码来获取最新和最准确的信息。