我的 flutter 应用程序使用 Urban Airship 接收通知。我希望这些通知根据通知类型将用户带到自定义页面。目前,这与应用程序完全关闭时的情况不同。例如,如果我在应用程序尚未通过在后台向上滑动而关闭时点击通知,那么它只会打开应用程序,而不运行我的
内的代码Airship.push.onNotificationResponse.listen((event){}
为了测试这个,我克隆了 flutterairship git repo
https://github.com/urbanairship/airship-flutter
我所做的唯一更改是在单击通知时以动画方式显示到第 1 页
Airship.push.onNotificationResponse.listen((event) {
debugPrint('Notification Response $event');
controller.animateTo(1);
});
这仅在应用程序未关闭时有效(我在发布模式下运行我的应用程序,然后关闭它,然后点击我使用邮递员向自己发送的通知来测试此功能)
当程序打开或在后台但未关闭时,此功能仍然有效。
这是main.dart中的代码
import 'package:airship_example/screens/message_center.dart';
import 'package:airship_example/screens/message_view.dart';
import 'package:airship_example/screens/preference_center.dart';
import 'package:airship_example/screens/settings.dart';
import 'package:airship_example/screens/test.dart';
import 'package:flutter/material.dart' hide Notification;
import 'package:airship_example/styles.dart';
import 'package:flutter/services.dart' show DeviceOrientation, SystemChrome;
import 'package:airship_example/screens/home.dart';
// ignore: depend_on_referenced_packages
import 'package:airship_flutter/airship_flutter.dart';
// Supported deep links
const String home_deep_link = "home";
const String message_center_deep_link = "message_center";
const String settings_deep_link = "settings";
@pragma('vm:entry-point')
Future<void> backgroundMessageHandler(PushReceivedEvent event) async {
debugPrint("Background Push Received $event");
}
void main() {
WidgetsFlutterBinding.ensureInitialized();
SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitUp,
DeviceOrientation.portraitDown,
]);
var config = AirshipConfig(
androidConfig: AndroidConfig(
notificationConfig: AndroidNotificationConfig(
icon: "ic_notification",
)),
defaultEnvironment: ConfigEnvironment(
appKey: KEY,
appSecret: SECRET,
logLevel: LogLevel.verbose,
ios: IOSEnvironment(logPrivacyLevel: AirshipLogPrivacyLevel.public)),
);
Airship.takeOff(config);
Airship.push.android
.setBackgroundPushReceivedHandler(backgroundMessageHandler);
Airship.push.iOS.setForegroundPresentationOptions([
IOSForegroundPresentationOption.banner,
IOSForegroundPresentationOption.list
]);
Airship.contact.identify(USERID);
Airship.messageCenter.setAutoLaunchDefaultMessageCenter(false);
runApp(MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({super.key});
@override
// ignore: library_private_types_in_public_api
_MyAppState createState() => _MyAppState();
}
// SingleTickerProviderStateMixin is used for animation
class _MyAppState extends State<MyApp> with SingleTickerProviderStateMixin {
late TabController controller;
final GlobalKey<NavigatorState> key = GlobalKey();
@override
void initState() {
super.initState();
controller = TabController(length: 4, vsync: this);
initPlatformState();
addFlutterTag();
trackFeatureFlagInteraction();
// Uncomment to enable Hybrid Composition on Android
// InboxMessageView.hybridComposition = true;
}
static void trackFeatureFlagInteraction() {
Airship.featureFlagManager.flag("rad_flag").then((flag) {
Airship.featureFlagManager.trackInteraction(flag);
}).catchError((e) {
debugPrint('Error: $e');
});
}
static void addFlutterTag() {
Airship.channel.addTags(["flutter"]);
}
// Platform messages are asynchronous, so we initialize in an async method.
Future<void> initPlatformState() async {
Airship.push.onPushReceived.listen((event) {
debugPrint('Push Received $event');
});
Airship.push.onNotificationResponse.listen((event) {
debugPrint('Notification Response $event');
controller.animateTo(1);
});
Airship.push.onPushTokenReceived.listen((event) {
debugPrint('Push token received $event');
});
Airship.push.onNotificationStatusChanged.listen((event) {
debugPrint('Notification status changed $event');
});
Airship.push.iOS.onAuthorizedSettingsChanged.listen((event) {
debugPrint('Authorized settings changed $event');
});
Airship.push.iOS.authorizedNotificationSettings
.then((value) => debugPrint("authorizedNotificationSettings $value"));
Airship.push.iOS.authorizedNotificationStatus
.then((value) => debugPrint("authorizedNotificationStatus $value"));
Airship.onDeepLink.listen((event) {
const home_tab = 0;
const message_tab = 1;
const settings_tab = 2;
switch (event.deepLink) {
case home_deep_link:
{
controller.animateTo(home_tab);
break;
}
case message_center_deep_link:
{
controller.animateTo(message_tab);
break;
}
case settings_deep_link:
{
controller.animateTo(settings_tab);
break;
}
}
});
Airship.inApp.onEmbeddedInfoUpdated
.listen((event) => debugPrint('Embedded info updated $event'));
Airship.messageCenter.onInboxUpdated
.listen((event) => debugPrint('Inbox updated $event'));
Airship.messageCenter.onDisplay
.listen((event) => debugPrint('Show inbox $event'));
Airship.messageCenter.onDisplay.listen((event) {
key.currentState
?.push(MaterialPageRoute<void>(builder: (BuildContext context) {
return event.messageId != null
? MessageView(
messageId: event.messageId ?? "",
)
: SizedBox();
}));
});
Airship.channel.onChannelCreated.listen((event) {
debugPrint('Channel created $event');
});
}
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
navigatorKey: key,
title: "Airship Sample App ",
theme: ThemeData(
primaryColor: Styles.borders,
colorScheme: ColorScheme.fromSwatch().copyWith(
secondary: Styles.airshipBlue, // Set the accent color to airshipBlue
),
switchTheme: SwitchThemeData(
trackColor:
WidgetStateProperty.all(Styles.airshipBlue), // Set track color
),
),
initialRoute: "/",
routes: {
'/': (context) => tabBarView(),
},
);
}
Widget bottomNavigationBar() {
return Container(
color: Styles.borders, // Set the same color as the tab bar
child: SafeArea(
bottom: true,
child: Material(
color: Colors.transparent,
child: Container(
color: Styles.borders,
child: TabBar(
indicatorColor: Styles.airshipRed,
unselectedLabelColor: Colors.grey, // Set unselected label color
labelColor:
Styles.airshipBlue, // Set selected label color to airshipBlue
tabs: const <Tab>[
Tab(
icon: Icon(Icons.home),
),
Tab(
icon: Icon(Icons.inbox),
),
Tab(
icon: Icon(Icons.menu),
),
Tab(
icon: Icon(Icons.settings),
),
],
controller: controller,
),
),
),
),
);
}
Widget tabBarView() {
return PopScope(
// ignore: deprecated_member_use
onPopInvoked: null,
child: Scaffold(
backgroundColor: Styles.borders,
body: TabBarView(
controller: controller,
children: const <Widget>[
Home(),
MessageCenter(),
PreferenceCenter(),
Settings()
],
),
bottomNavigationBar: bottomNavigationBar(),
),
);
}
}
完整代码可以在 git repo 上找到 https://github.com/urbanairship/airship-flutter
根据Airship 开发者的说法,不幸的是,如果应用程序完全关闭或在后台太长,它将无法在iOS上运行。这是iOS平台本身的行为,Airship无法控制。
但是,有一些想法可以更接近实现您的目标。
content_available: 1
来尝试唤醒应用程序。await Airship.push.activeNotifications;
访问通知的有效负载。