在前台工作正常但在后台无法工作时设置自定义铃声

问题描述 投票:0回答:1

嗨,我正在尝试在前台收到通知时实现自定义铃声,铃声播放正常,停止正常,但是当应用程序在后台时,铃声正在响起,但无法停止,我发现handleBackgroundMessage正在创建新实例,并且在MyApp中具有对象的不同实例和

  FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
  NotificationHandler().onSelectNotification(json.encode(message.data));
});

这个方法是从 Myapp 调用的,所以它有不同的实例,任何人都可以建议我在这里做错了什么,我的代码如下

   Future<void> handleBackgroundMessage(RemoteMessage message) async {
   if (Platform.isAndroid) {
      await Firebase.initializeApp(
        options: DefaultFirebaseOptions.currentPlatform);
   } else if (Platform.isIOS) {
    await Firebase.initializeApp();
    }
  final liveAstrologerController = Get.put(LiveAstrologerController());
 final walletController = Get.put(WalletController());
 final chatController = Get.put(ChatController);
  final callController = Get.put(CallController());
 final reportController = Get.put(ReportController());
 if (message.notification!.title == "For Live Streaming Chat") {
   Future.delayed(const Duration(milliseconds: 500)).then((value) async {
      await localNotifications.cancelAll();
    });
String sessionType = message.data["sessionType"];
if (sessionType == "start") {
  String? liveChatUserName2 = message.data['liveChatSUserName'];
  if (liveChatUserName2 != null) {
    liveAstrologerController.liveChatUserName = liveChatUserName2;
    liveAstrologerController.update();
  }
  String chatId = message.data["chatId"];
  liveAstrologerController.isUserJoinAsChat = true;
  liveAstrologerController.update();
  liveAstrologerController.chatId = chatId;
  int waitListId = int.parse(message.data["waitListId"].toString());
  String time = liveAstrologerController.waitList
      .where((element) => element.id == waitListId)
      .first
      .time;
     liveAstrologerController.endTime = DateTime.now().millisecondsSinceEpoch +
       1000 * int.parse(time.toString());
       liveAstrologerController.update();
   } else {}
     } else if (message.notification!.title ==
        "For timer and session start for live") {
     liveAstrologerController.update();
  } else if (message.notification!.title == "Start simple chat timer") {
 } else {
try {
  if (message.data.isNotEmpty) {
    var messageData = json.decode((message.data['body']));

    if (messageData['notificationType'] != null) {
      if (messageData['notificationType'] == 7) {
        // get wallet api call
        await walletController.getAmountList();
      } else if (messageData['notificationType'] == 8) {
        chatController.startRingTone();
        //AlarmHandler.scheduleAlarm();
        chatController.chatList.clear();
        chatController.update();

        await chatController.getChatList(false);
        debugPrint('chat resp-> $messageData');
      } else if (messageData['notificationType'] == 2) {
        //in background
        callController.startRingTone();

        await callController.getCallList(false);
      } else if (messageData['notificationType'] == 9) {
        reportController.reportList.clear();
        reportController.update();
        await reportController.getReportList(false);
      } else if (messageData['notificationType'] == 12 ||
          messageData['notificationType'] == 11 ||
          messageData['notificationType'] == 10) {
        liveAstrologerController.isUserJoinWaitList = true;
        liveAstrologerController.update();
      }
    }
  }
} catch (e) {
  debugPrint("Exception in _firebaseMessagingBackgroundHandler else $e");
}
 }
}

我的应用程序是

 void main() async {
  WidgetsFlutterBinding.ensureInitialized();
 await EasyLocalization.ensureInitialized();
 await GetStorage.init();
 await AndroidAlarmManager.initialize();

 if (Platform.isAndroid) {
   await Firebase.initializeApp(
      options: DefaultFirebaseOptions.currentPlatform);
 } else if (Platform.isIOS) {
      await Firebase.initializeApp();
 }

 HttpOverrides.global = MyHttpOverrides();

runApp(
   EasyLocalization(
     supportedLocales: const [
       Locale('en', 'US'),
     ],
     path: 'assets/translations',
    fallbackLocale: const Locale('en', 'US'),
    startLocale: const Locale('en', 'US'),
   child: const MyApp(),
 ),
 );
 }

 class MyApp extends StatefulWidget {
      const MyApp({super.key});

    @override
    State<MyApp> createState() => _MyAppState();
   }

  class _MyAppState extends State<MyApp> {
     dynamic analytics;
     final apiHelper = APIHelper();

    dynamic observer;
    final liveAstrologerController = Get.put(LiveAstrologerController());
    final walletController = Get.put(WalletController());
    final chatController = Get.put(ChatController());
    final callController = Get.put(CallController());
    final timerController = Get.put(TimerController());
    final reportController = Get.put(ReportController());
    final networkController = Get.put(NetworkController());

 @override
  void initState() {
     super.initState();
     log('chat hascode MyApp ${chatController.hashCode}');
     log('call hascode MyApp ${callController.hashCode}');
    inthandlerbackgroudn();

  FirebaseMessaging.onMessage.listen((RemoteMessage message) async {
  if (message.notification!.title == "For Live Streaming Chat") {
    String sessionType = message.data["sessionType"];
    if (sessionType == "start") {
      String? liveChatUserName2 = message.data['liveChatSUserName'];
      if (liveChatUserName2 != null) {
        liveAstrologerController.liveChatUserName = liveChatUserName2;
        liveAstrologerController.update();
      }
      String chatId = message.data["chatId"];
      liveAstrologerController.isUserJoinAsChat = true;
      liveAstrologerController.update();
      liveAstrologerController.chatId = chatId;
      int waitListId = int.parse(message.data["waitListId"].toString());
      String time = liveAstrologerController.waitList
          .where((element) => element.id == waitListId)
          .first
          .time;
      liveAstrologerController.endTime =
          DateTime.now().millisecondsSinceEpoch +
              1000 * int.parse(time.toString());
      liveAstrologerController.update();
    } else {
      if (liveAstrologerController.isOpenPersonalChatDialog) {
        Get.back(); //if chat dialog opended
        liveAstrologerController.isOpenPersonalChatDialog = false;
      }
      liveAstrologerController.isUserJoinAsChat = false;
      liveAstrologerController.chatId = null;
      liveAstrologerController.update();
    }
  } else if (message.notification!.title ==
      "For timer and session start for live") {
    int waitListId = int.parse(message.data["waitListId"].toString());
    liveAstrologerController.joinedUserName =
        message.data["name"] ?? "User";
    liveAstrologerController.joinedUserProfile =
        message.data["profile"] ?? "";
    String time = liveAstrologerController.waitList
        .where((element) => element.id == waitListId)
        .first
        .time;
    liveAstrologerController.endTime =
        DateTime.now().millisecondsSinceEpoch +
            1000 * int.parse(time.toString());
    liveAstrologerController.update();
  } else if (message.notification!.title == "Start simple chat timer") {
    chatController.newIsStartTimer = true;
    chatController.update();

    timerController.endTime =
        DateTime.now().millisecondsSinceEpoch + 1000 * 300;
    timerController.update();
  } else if (message.notification!.title == "End chat from customer") {
    log('isInChatScreen ${chatController.isInChatScreen}');

    if (chatController.isInChatScreen) {
      chatController.updateChatScreen(false);
      apiHelper.setAstrologerOnOffBusyline("Online");
      chatController.update();

      //  Get.back();
    } else {
      log('do nothing chat dismiss');
    }
  } else if (message.notification!.title ==
      "Reject call request from astrologer") {
    print('user Rejected call request:-');
    callController.isRejectCall = true;
    callController.update();
    callController.rejectDialog();
  } else {
    try {
      if (message.data.isNotEmpty) {
        var messageData = json.decode((message.data['body']));

        log('noti body $messageData');
        if (messageData['notificationType'] != null) {
          if (messageData['notificationType'] == 7) {
            // get wallet api call
            await walletController.getAmountList();
            NotificationHandler().foregroundNotification(message);
            await FirebaseMessaging.instance
                .setForegroundNotificationPresentationOptions(
                    alert: true, badge: true, sound: true);
          } else if (messageData['notificationType'] == 8) {
            log('inside foreground noti type 8');
            chatController.startRingTone();
            chatController.chatList.clear();
            chatController.update();
            await chatController.getChatList(false);
            NotificationHandler().foregroundNotification(message);
            await FirebaseMessaging.instance
                .setForegroundNotificationPresentationOptions(
                    alert: true, badge: true, sound: true);

            //SHOW CHAT DIALOG
          } else if (messageData['notificationType'] == 2) {
            callController.startRingTone();

            log('iniside noti type 2');
            callController.callList.clear();
            callController.update();
            await callController.getCallList(false);
            NotificationHandler().foregroundNotification(message);
            await FirebaseMessaging.instance
                .setForegroundNotificationPresentationOptions(
                    alert: true, badge: true, sound: true);
          } else if (messageData['notificationType'] == 9) {
            reportController.reportList.clear();
            reportController.update();
            await reportController.getReportList(false);
            NotificationHandler().foregroundNotification(message);
            await FirebaseMessaging.instance
                .setForegroundNotificationPresentationOptions(
                    alert: true, badge: true, sound: true);
          } else if (messageData['notificationType'] == 12 ||
              messageData['notificationType'] == 11 ||
              messageData['notificationType'] == 10) {
            liveAstrologerController.isUserJoinWaitList = true;
            liveAstrologerController.update();
            NotificationHandler().foregroundNotification(message);
            await FirebaseMessaging.instance
                .setForegroundNotificationPresentationOptions(
                    alert: true, badge: true, sound: true);
          } else {
            NotificationHandler().foregroundNotification(message);
            await FirebaseMessaging.instance
                .setForegroundNotificationPresentationOptions(
                    alert: true, badge: true, sound: true);
          }

          NotificationHandler().foregroundNotification(message);
          await FirebaseMessaging.instance
              .setForegroundNotificationPresentationOptions(
                  alert: true, badge: true, sound: true);
        } else {
          NotificationHandler().foregroundNotification(message);
          await FirebaseMessaging.instance
              .setForegroundNotificationPresentationOptions(
                  alert: true, badge: true, sound: true);
        }
      } else {
        NotificationHandler().foregroundNotification(message);
        await FirebaseMessaging.instance
            .setForegroundNotificationPresentationOptions(
                alert: true, badge: true, sound: true);
      }
    } catch (e) {
      NotificationHandler().foregroundNotification(message);
      await FirebaseMessaging.instance
          .setForegroundNotificationPresentationOptions(
              alert: true, badge: true, sound: true);
    }
  }
});
FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
  NotificationHandler().onSelectNotification(json.encode(message.data));
   });
 }
 SplashController splashController = Get.put(SplashController());
  @override
  Widget build(BuildContext context) {
     return GetBuilder<SplashController>(builder: (s) {
       return Sizer(
         builder: (context, orientation, deviceType) => GetMaterialApp(
      debugShowCheckedModeBanner: false,
      navigatorKey: Get.key,
      enableLog: true,
      theme: Themes.light,
      darkTheme: Themes.dark,
      themeMode: ThemeService().theme,
      locale: context.locale,
      localizationsDelegates: [
        ...context.localizationDelegates,
        FallbackLocalizationDelegate()
      ],
      supportedLocales: context.supportedLocales,
      initialBinding: NetworkBinding(),
      title: global.appName,
      initialRoute: "SplashScreen",
      home: SplashScreen(
        a: analytics,
        o: observer,
         ),
      
       ),
     );
   });
}

void inthandlerbackgroudn() async {
   FirebaseMessaging messaging = FirebaseMessaging.instance;
   FirebaseMessaging.onBackgroundMessage(handleBackgroundMessage);
   await messaging.requestPermission(
   alert: true,
   announcement: false,
   badge: true,
   carPlay: false,
   criticalAlert: false,
    provisional: false,
    sound: false,
   );
 }
 }

我的 NotificaitonHandler 类是

 class NotificationHandler {
      final localNotifications = FlutterLocalNotificationsPlugin();
      WalletController walletController = Get.put(WalletController());
      ReportController reportController = Get.put(ReportController());
      HomeController homecontroller = Get.put(HomeController());
      SignupController signupController = Get.put(SignupController());
      ChatController chatController = Get.find<ChatController>();
      CallController callController = Get.find<CallController>();

Future<void> onSelectNotification(String payload) async {
  Map<dynamic, dynamic> messageData;
  try {
    messageData = json.decode(payload);
  Map<dynamic, dynamic> body;
  body = jsonDecode(messageData['body']);
  if (body["notificationType"] == 7) {
    await walletController.getAmountList();
    Get.to(() => WalletScreen());
  } else if (body["notificationType"] == 8) {
    chatController.stopRingtone();
    Get.find<HomeController>().homeTabIndex = 0;
    Get.find<HomeController>().update();
    Get.to(() => const HomeScreen());
  } else if (body["notificationType"] == 2) {
    callController.stopRingtone();
    debugPrint('list length ${callController.callList.length}');
    callController.callList
        .removeWhere((call) => call.callId == body['callId']);
    callController.update();
    if (body['call_type'].toString() == '10') {
      callController.acceptCallRequest(
          body['callId'],
          body['profile'],
          body['name'],
          body['id'],
          body['fcmToken'],
          body['call_duration']);
    } else if (body['call_type'].toString() == '11') {
      callController.acceptVideoCallRequest(
          body['callId'],
          body['profile'],
          body['name'],
          body['id'],
          body['fcmToken'],
          body['call_duration']);
    }
    Get.find<HomeController>().homeTabIndex = 2; //pageview index
    Get.find<HomeController>().isSelectedBottomIcon = 1; // bottom bar index
    Get.find<HomeController>().update();
  } else if (body["notificationType"] == 9) {
  } else if (body["notificationType"] == 13) {
    if (Get.find<HomeController>().notificationHandlingremoteUID != 0) {
      global.showToast(message: 'You are already live, end call first');
    } else {}
  }
} catch (e) {
  debugPrint(
    'Exception in onSelectNotification main.dart:- ${e.toString()}',
  );
}

}

  Future<void> foregroundNotification(RemoteMessage payload) async {
     final DarwinInitializationSettings initializationSettingsDarwin =
        DarwinInitializationSettings(
      defaultPresentBadge: true,
      requestSoundPermission: true,
      requestBadgePermission: true,
     defaultPresentSound: true,
     onDidReceiveLocalNotification: (id, title, body, payload) async {
        debugPrint("object notification call");
      return;
    },
  );
   AndroidInitializationSettings android =
    const AndroidInitializationSettings('@mipmap/ic_launcher');
final InitializationSettings initialSetting = InitializationSettings(
    android: android, iOS: initializationSettingsDarwin);
final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
    FlutterLocalNotificationsPlugin();
flutterLocalNotificationsPlugin.initialize(initialSetting,
    onDidReceiveNotificationResponse: (_) {
  NotificationHandler().onSelectNotification(json.encode(payload.data));
});
AndroidNotificationChannel channel = const AndroidNotificationChannel(
  ' local notifications',
  'High Importance Notifications for ',
  importance: Importance.high,
);

AndroidNotificationDetails androidDetails = AndroidNotificationDetails(
  channel.id,
  channel.name,
  importance: Importance.max,
  priority: Priority.high,
  icon: "@mipmap/ic_launcher",
  playSound: false,
  styleInformation: const BigTextStyleInformation(''),
);
const DarwinNotificationDetails iOSDetails = DarwinNotificationDetails();
NotificationDetails platformChannelSpecifics =
    NotificationDetails(android: androidDetails, iOS: iOSDetails);
global.sp = await SharedPreferences.getInstance();
if (global.sp!.getString("currentUser") != null) {
  await flutterLocalNotificationsPlugin.show(
    0,
    payload.notification!.title,
    payload.notification!.body,
    platformChannelSpecifics,
    payload: json.encode(payload.data.toString()),
  );
}

} } 我在我的应用程序中收到两个不同的聊天控制器实例的 hascode,并且 onselected 通知有

[log] chat hascode MyApp 445182886
[log] chat hascode bghandler 668612596
[log] chat hascode NotificationHandler 445182886

                            
android flutter
1个回答
0
投票

好吧,第一件事是我的方法是完全错误的,我正在使用自己的音频播放器来响铃并停止,这不是个好主意,因为 firebase 消息处理程序已经是一个单独运行的隔离,因此在其中创建的实例具有与 myapp 中创建的不同的引用,因此我发现的解决方案是直接使用 firebase 消息传递和 flutter_notification 的内置功能,我在这里做了什么 第一个 api 端你必须通过

[
'title' => 'Hey User you received a chat request from John Doe',
'body' => [
    'description' => 'Hey you received a chat request from User' . $user[0]->name,
    'notificationType' => 8,
    'icon' => 'public/notification-icon/chat.png',
],
'android' => [
    'notification' => [
        'channel_id' => 'channel_id_13',
        'sound' =>'app_sound' // don't use app_sound.mp3 or .wav only name
    ]
],
'apns' =>[
        'payload' => [
                    'aps' => [
                        'sound' => 'app_sound.wav'
                    ]
                ]
  ]
  ];

请记下您必须设置声音和channel_id

 'android' => [
    'notification' => [
        'channel_id' => 'channel_id_13',
        'sound' =>'app_sound'
    ]
],

并在 Android 清单和代码中的应用程序端使用它们,就像我在下面所做的那样

 <meta-data
        android:name="flutterEmbedding"
        android:value="2" />
        <meta-data android:name="com.google.firebase.messaging.default_notification_icon" 
        android:resource="@mipmap/ic_launcher" />

    <meta-data
        android:name="com.google.firebase.messaging.default_notification_channel_id"
        android:value="channel_id_13"/>  

在你的清单应用程序标签中记住添加相同的频道 ID

android:value="channel_id_13"

现在在我们的代码中,我们可以创建支持后台和前台的通知是

Future<void> foregroundNotificatioCustomAuddio(RemoteMessage payload) async {
final initializationSettingsDarwin = DarwinInitializationSettings(
  defaultPresentBadge: true,
  requestSoundPermission: true,
  requestBadgePermission: true,
  defaultPresentSound: false,
  onDidReceiveLocalNotification: (id, title, body, payload) async {
    return;
  },
);
final android = const AndroidInitializationSettings('@mipmap/ic_launcher');
final initialSetting = InitializationSettings(
    android: android, iOS: initializationSettingsDarwin);

localNotifications.initialize(initialSetting,
    onDidReceiveNotificationResponse: (_) {
  onSelectNotification(json.encode(payload.data));
});

final customSound = 'app_sound.wav';
AndroidNotificationDetails androidDetails =
    const AndroidNotificationDetails(
  'channel_id_14',
  'channel.name',
  importance: Importance.max,
  icon: "@mipmap/ic_launcher",
  playSound: true,
  enableVibration: true,
  timeoutAfter: 10000,
  sound: RawResourceAndroidNotificationSound('app_sound'),
);

DarwinNotificationDetails iOSDetails = DarwinNotificationDetails(
  sound: customSound,
);
final platformChannelSpecifics =
    NotificationDetails(android: androidDetails, iOS: iOSDetails);
global.sp = await SharedPreferences.getInstance();

if (global.sp!.getString("currentUser") != null) {
  await localNotifications.show(
    10,
    payload.notification!.title,
    payload.notification!.body,
    platformChannelSpecifics,
    payload: json.encode(payload.data.toString()),
  );
  }
 }
final localNotifications = FlutterLocalNotificationsPlugin();

现在从

打电话
  FirebaseMessaging.onMessage.listen((RemoteMessage message) async {

          NotificationHandler()
                .foregroundNotificatioCustomAuddio(message);
                await FirebaseMessaging.instance
                .setForegroundNotificationPresentationOptions(
                     alert: true, badge: true, sound: true);

          }

对于背景,现在 firebase 自动处理通知,现在请记住在您的 android/app/src/main/res/raw/app_sound.wav 中添加 app_sound.wav 格式铃声,这样它就可以工作了,我已经在 android 9 和 android 10 中测试了这些

© www.soinside.com 2019 - 2024. All rights reserved.