无论何时收到呼叫类型的通知,设备都应该像来电一样响起,当应用程序处于前台状态时,它就会工作。但当应用程序处于后台时无法工作,处于关闭状态。
我正在使用";flatter_callkit_incoming";但它只有在应用程序处于前台状态时才起作用。我在IOS设备中遇到了这个问题。
这是AppDelegate
import UIKit
import Flutter
import GoogleMaps
import PushKit
import flutter_callkit_incoming
@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate, PKPushRegistryDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
GeneratedPluginRegistrant.register(with: self)
GMSServices.provideAPIKey("AIzaSyC9A8pXDMI_uJ450kTtBrZEca90McarPPg")
//Setup VOIP
let mainQueue = DispatchQueue.main
let voipRegistry: PKPushRegistry = PKPushRegistry(queue: mainQueue)
voipRegistry.delegate = self
voipRegistry.desiredPushTypes = [PKPushType.voIP]
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
// Call back from Recent history
override func application(_ application: UIApplication,
continue userActivity: NSUserActivity,
restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
guard let handleObj = userActivity.handle else {
return false
}
guard let isVideo = userActivity.isVideo else {
return false
}
let nameCaller = handleObj.getDecryptHandle()[""] as? String ?? ""
let handle = handleObj.getDecryptHandle()["handle"] as? String ?? ""
let data = flutter_callkit_incoming.Data(id: UUID().uuidString, nameCaller: nameCaller, handle: handle, type: isVideo ? 1 : 0)
//set more data...
data.nameCaller = "Johnny"
SwiftFlutterCallkitIncomingPlugin.sharedInstance?.startCall(data, fromPushKit: true)
return super.application(application, continue: userActivity, restorationHandler: restorationHandler)
}
// Handle updated push credentials
func pushRegistry(_ registry: PKPushRegistry, didUpdate credentials: PKPushCredentials, for type: PKPushType) {
print(credentials.token)
let deviceToken = credentials.token.map { String(format: "%02x", $0) }.joined()
print(deviceToken)
//Save deviceToken to your server
SwiftFlutterCallkitIncomingPlugin.sharedInstance?.setDevicePushTokenVoIP(deviceToken)
}
func pushRegistry(_ registry: PKPushRegistry, didInvalidatePushTokenFor type: PKPushType) {
print("didInvalidatePushTokenFor")
SwiftFlutterCallkitIncomingPlugin.sharedInstance?.setDevicePushTokenVoIP("")
}
// Handle incoming pushes
func pushRegistry(_ registry: PKPushRegistry, didReceiveIncomingPushWith payload: PKPushPayload, for type: PKPushType, completion: @escaping () -> Void) {
print("didReceiveIncomingPushWith")
guard type == .voIP else { return }
let id = payload.dictionaryPayload["id"] as? String ?? ""
let nameCaller = payload.dictionaryPayload["user_name"] as? String ?? ""
let token = payload.dictionaryPayload["token"] as? String ?? ""
let channelName = payload.dictionaryPayload["channel_name"] as? String ?? ""
let handle = payload.dictionaryPayload["handle"] as? String ?? ""
let isVideo = payload.dictionaryPayload["isVideo"] as? Bool ?? false
let data = flutter_callkit_incoming.Data(id: id, nameCaller: nameCaller, handle: handle, type: isVideo ? 1 : 0)
//set more data
data.extra = ["name": nameCaller, "token": token, "channelName" :channelName]
//data.iconName = ...
//data.....
SwiftFlutterCallkitIncomingPlugin.sharedInstance?.showCallkitIncoming(data, fromPushKit: true)
}
}
这是main.dart
Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
print("Handling a background message: ${message.messageId}");
showCallkitIncoming(Uuid().v4());
}
Future<void> showCallkitIncoming(String uuid) async {
var params = <String, dynamic>{
'id': uuid,
'nameCaller': 'Hien Nguyen',
'appName': 'Callkit',
'avatar': 'https://i.pravatar.cc/100',
'handle': '0123456789',
'type': 0,
'duration': 30000,
'textAccept': 'Accept',
'textDecline': 'Decline',
'textMissedCall': 'Missed call',
'textCallback': 'Call back',
'extra': <String, dynamic>{'userId': '1a2b3c4d'},
'headers': <String, dynamic>{'apiKey': 'Abc@123!', 'platform': 'flutter'},
'android': <String, dynamic>{
'isCustomNotification': true,
'isShowLogo': false,
'isShowCallback': false,
'ringtonePath': 'system_ringtone_default',
'backgroundColor': '#0955fa',
'backgroundUrl': 'https://i.pravatar.cc/500',
'actionColor': '#4CAF50'
},
'ios': <String, dynamic>{
'iconName': 'CallKitLogo',
'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': 'system_ringtone_default'
}
};
await FlutterCallkitIncoming.showCallkitIncoming(params);
}
void main() {
WidgetsFlutterBinding.ensureInitialized();
runApp(MyApp());
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> with WidgetsBindingObserver {
var _uuid;
var _currentUuid;
late final FirebaseMessaging _firebaseMessaging;
@override
void initState() {
super.initState();
_uuid = Uuid();
initFirebase();
WidgetsBinding.instance?.addObserver(this);
//Check call when open app from terminated
checkAndNavigationCallingPage();
}
getCurrentCall() async {
//check current call from pushkit if possible
var calls = await FlutterCallkitIncoming.activeCalls();
if (calls is List) {
if (calls.isNotEmpty) {
print('DATA: $calls');
this._currentUuid = calls[0]['id'];
return calls[0];
} else {
this._currentUuid = "";
return null;
}
}
}
checkAndNavigationCallingPage() async {
var currentCall = await getCurrentCall();
if (currentCall != null) {
NavigationService.instance
.pushNamedIfNotCurrent(AppRoute.callingPage, args: currentCall);
}
}
@override
Future<void> didChangeAppLifecycleState(AppLifecycleState state) async {
print(state);
if (state == AppLifecycleState.resumed) {
//Check call when open app from background
checkAndNavigationCallingPage();
}
}
@override
void dispose() {
WidgetsBinding.instance?.removeObserver(this);
super.dispose();
}
initFirebase() async {
await Firebase.initializeApp();
_firebaseMessaging = FirebaseMessaging.instance;
FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
FirebaseMessaging.onMessage.listen((RemoteMessage message) async {
print(
'Message title: ${message.notification?.title}, body: ${message.notification?.body}, data: ${message.data}');
this._currentUuid = _uuid.v4();
showCallkitIncoming(this._currentUuid);
});
_firebaseMessaging.getToken().then((token) {
print('Device Token FCM: $token');
});
}
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData.light(),
onGenerateRoute: AppRoute.generateRoute,
initialRoute: AppRoute.homePage,
navigatorKey: NavigationService.instance.navigationKey,
navigatorObservers: <NavigatorObserver>[
NavigationService.instance.routeObserver
],
);
}
Future<void> getDevicePushTokenVoIP() async {
var devicePushTokenVoIP =
await FlutterCallkitIncoming.getDevicePushTokenVoIP();
print(devicePushTokenVoIP);
}
}
我正在使用fluft_callkit_incoming:^1.0.2+2
发生这种情况是因为您的应用程序在后台状态下未处于活动状态,并且未侦听您的呼叫类型通知。您的应用程序也应该在后台处于活动状态。
为了使应用程序在后台保持活动状态,您可以使用此颤振包
Flutter_background