Flutter 在启动时阻止 iOS 上的推送通知权限

mas*_*ani 5 push-notification flutter

我正在部署一个 flutter 应用程序,但遇到了一个问题:在 iOS 设备中运行它时,我在启动时有推送通知请求权限,但我想在未来的屏幕中请求权限。\n详细信息我想在带有按钮的专用页面中请求用户许可:

\n
Future<NotificationSettings> checkPermissions() async {\n    settings = await FirebaseMessaging.instance.requestPermission(\n      announcement: true,\n      carPlay: true,\n      criticalAlert: true,\n    );\n    return settings;\n  }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

这是我的 main.dart

\n
import 'dart:async';\nimport 'package:firebase_core/firebase_core.dart';\nimport 'package:firebase_messaging/firebase_messaging.dart';\nimport 'package:flutter_local_notifications/flutter_local_notifications.dart';\n\n\nFuture<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {\n  await Firebase.initializeApp();\n  print('------- onBackgroundMessage ----------');\n}\n\n// ACTIVATE ANDROID NOTIFICATION IN FOREGROUND\nconst AndroidNotificationChannel channel = AndroidNotificationChannel(\n  'high_importance_channel', // id\n  'High Importance Notifications', // title\n  'This channel is used for important notifications.', // description\n  importance: Importance.high,\n);\n\n// ACTIVATE ANDROID NOTIFICATION IN FOREGROUND\nfinal FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =\n    FlutterLocalNotificationsPlugin();\n\n//RemoteMessage globalMessage;\n\nFuture<void> main() async {\n  WidgetsFlutterBinding.ensureInitialized();\n  await Firebase.initializeApp();\n  FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);\n\n  // ACTIVATE ANDROID NOTIFICATION IN FOREGROUND\n  await flutterLocalNotificationsPlugin\n      .resolvePlatformSpecificImplementation<\n          AndroidFlutterLocalNotificationsPlugin>()\n      ?.createNotificationChannel(channel);\n\n  // ACTIVATE IOS NOTIFICATION IN FOREGROUND\n  await FirebaseMessaging.instance.setForegroundNotificationPresentationOptions(\n    alert: true,\n    badge: true,\n    sound: true,\n  );\n\n  runApp(MyApp());\n}\n\nclass MyApp extends StatelessWidget {\n  @override\n  Widget build(BuildContext context) {\n    return MaterialApp(\n      routes: {\n        '/': (context) => Application(),\n        '/pushNotification': (context) => MessageScreen()\n      },\n    );\n  }\n}\n\nclass Application extends StatefulWidget {\n  @override\n  State<StatefulWidget> createState() => _Application();\n}\n\nclass _Application extends State<Application> {\n  var initializationSettings;\n  var initializationSettingsAndroid;\n  var initializationSettingsIOS;\n  RemoteMessage foregroundMessage;\n\n  @override\n  void initState() {\n    super.initState();\n\n    print("_Application : inizio initState()");\n\n    initializationSettingsAndroid =\n        AndroidInitializationSettings('launch_background');\n    initializationSettingsIOS = IOSInitializationSettings(\n      requestAlertPermission: true,\n      requestBadgePermission: true,\n      requestSoundPermission: false,\n      onDidReceiveLocalNotification: (id, title, body, payload) async {\n        // your call back to the UI\n      },\n    );\n    initializationSettings = InitializationSettings(\n        android: initializationSettingsAndroid, iOS: initializationSettingsIOS);\n\n    setOnNotificationClick(onNotificationClick);\n\n    FirebaseMessaging.instance\n        .getInitialMessage()\n        .then((RemoteMessage message) {\n      if (message != null) {\n        //Navigator.push(context,\n        //new MaterialPageRoute(builder: (context) => new LoginScreen()));\n        Navigator.pushNamed(context, '/pushNotification',\n            arguments: MessageArguments(message, true));\n      }\n    });\n\n    FirebaseMessaging.onMessage.listen((RemoteMessage message) {\n      RemoteNotification notification = message.notification;\n      AndroidNotification android = message.notification?.android;\n\n      foregroundMessage = message;\n\n      print('-------- onMessage ----------');\n\n      //serve per notificare in android quando l'app \xc3\xa8 in foreground\n      if (notification != null && android != null) {\n        flutterLocalNotificationsPlugin.show(\n            notification.hashCode,\n            notification.title,\n            notification.body,\n            NotificationDetails(\n              android: AndroidNotificationDetails(\n                channel.id,\n                channel.name,\n                channel.description,\n                // TODO add a proper drawable resource to android, for now using\n                //      one that already exists in example app.\n                icon: 'launch_background',\n              ),\n            ),\n            payload: message.data.toString());\n      }\n    });\n\n    FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {\n      print('---- onMessageOpenedApp ------------------');\n      //Navigator.push(context,\n      //  new MaterialPageRoute(builder: (context) => new LoginScreen()));\n      Navigator.pushNamed(context, '/pushNotification',\n          arguments: MessageArguments(message, true));\n    });\n  }\n\n  setOnNotificationClick(Function onNotificationClick) async {\n    await flutterLocalNotificationsPlugin.initialize(initializationSettings,\n        onSelectNotification: (String payload) async {\n      onNotificationClick(payload);\n    });\n  }\n\n  onNotificationClick(String payload) {\n    print('---- onNotificationClick ------------------');\n    print(payload);\n    Navigator.pushNamed(context, '/pushNotification',\n        arguments: MessageArguments(foregroundMessage, false));\n  }\n\n  @override\n  Widget build(BuildContext context) {\n    return MaterialApp(\n      title: 'XYZ',\n      debugShowCheckedModeBanner: false,\n      theme: ThemeData(\n        primarySwatch: Colors.blue,\n      ),\n      initialRoute: '/',\n      onGenerateRoute: RouteGenerator.generateRoute,\n    );\n  }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

你有什么想法?

\n

谢谢

\n

mas*_*ani 6

我是这样解决的:

initializationSettingsIOS = IOSInitializationSettings(
      requestAlertPermission: false,
      requestBadgePermission: false,
      requestSoundPermission: false,
Run Code Online (Sandbox Code Playgroud)

这是sdk关于初始化方法的建议:

/// Call this method on application before using the plugin further.
    ///
    /// Will return a [bool] value to indicate if initialization succeeded. On iOS this is dependent on if permissions have been granted to show
    /// notification When running in environment that is neither Android and iOS (e.g. when running tests), this will be a no-op and return true.
    ///
    /// Note that on iOS, initialisation may also request notification permissions where users will see a permissions prompt. This may be fine in
    /// cases where it's acceptable to do this when the application runs for the first time. However, if your application needs to do this at a
    /// later point in time, set the [IOSInitializationSettings.requestAlertPermission], [IOSInitializationSettings.requestBadgePermission] and
    /// [IOSInitializationSettings.requestSoundPermission] values to false. [IOSFlutterLocalNotificationsPlugin.requestPermissions] can then be
    /// called to request permissions when needed.



await flutterLocalNotificationsPlugin.initialize(initializationSettings,
        onSelectNotification: (String payload) async {
      onNotificationClick(payload);
Run Code Online (Sandbox Code Playgroud)