Flutter推送通知插件fl_jpush的使用

发布于 1周前 作者 songsunli 来自 Flutter

Flutter推送通知插件fl_jpush的使用

配置

Android:

  1. android/app/src/main/res/values/strings.xml 中添加下列代码(如果没有此文件,则手动创建):
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="app_name">App 名称</string>
</resources>
  1. example/android/app/src/main/AndroidManifest.xml 中添加下列代码:
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.jpush.example">
    <application android:label="@string/app_name">
    </application>
</manifest>
  1. android/app/build.gradle 中添加下列代码:
android:
{
    defaultConfig {
        applicationId '自己应用 ID'
        manifestPlaceholders = [
                JPUSH_PKGNAME : applicationId,
                JPUSH_APPKEY  : 'appkey',
                JPUSH_CHANNEL : 'developer-default',

                // 如集成厂商通道,请添加以下信息
                MEIZU_APPKEY  : "MZ-",
                MEIZU_APPID   : "MZ-",
                XIAOMI_APPID  : "MI-",
                XIAOMI_APPKEY : "MI-",
                OPPO_APPKEY   : "OP-",
                OPPO_APPID    : "OP-",
                OPPO_APPSECRET: "OP-",
                VIVO_APPKEY   : "",
                VIVO_APPID    : "",
                HUAWEI_APPID  : "配置文件里的appid",
                HUAWEI_CPID   : "配置文件里的cp_id"
        ]
    }
}

集成厂商通道

  1. [华为、小米、OPPO、VIVO、魅族] 安装 fl_jpush_android
  2. [Google FCM] 安装 fl_jpush_android_fcm
  3. 如集成国内厂商SDK升级更新需参考 fl_jpush_android 升级

iOS:

  1. Capability 添加 “Background Modes” 和 “Push Notifications” 并保证"Remote notifications"处于选中状态。

使用

首先导入插件:

import 'package:fl_jpush/fl_jpush.dart';

初始化

initState 中初始化插件:

[@override](/user/override)
void initState() {
  super.initState();

  /// 初始化
  FlJPush().setup(
      iosKey: 'AppKey', // 你自己应用的 AppKey
      production: false,
      channel: 'channel',
      debug: false);
}

添加事件监听

Future<void> addEventHandler() async {
  FlJPush().addEventHandler(
      eventHandler: FlJPushEventHandler(
          onOpenNotification: (JPushNotificationMessage? message) {
            /// 点击通知栏消息回调
            log('onOpenNotification: ${message?.toMap()}');
          }, onReceiveNotification: (JPushNotificationMessage? message) {
        /// 接收普通消息
        log('onReceiveNotification: ${message?.toMap()}');
      }, onReceiveMessage: (JPushMessage? message) {
        /// 接收自定义消息
        log('onReceiveMessage: ${message?.toMap()}');
      }),
      androidEventHandler: FlJPushAndroidEventHandler(
          onCommandResult: (FlJPushCmdMessage message) {
            log('onCommandResult: ${message.toMap()}');
          }, onNotifyMessageDismiss: (JPushNotificationMessage? message) {
        /// 清除通知回调
        /// 1.同时删除多条通知,可能不会多次触发清除通知的回调
        /// 2.只有用户手动清除才有回调,调接口清除不会有回调
        log('onNotifyMessageDismiss: ${message?.toMap()}');
      }, onNotificationSettingsCheck:
          (FlJPushNotificationSettingsCheck? settingsCheck) {
        /// 通知开关状态回调
        /// 说明: SDK内部检测通知开关状态的方法因系统差异,在少部分机型上可能存在兼容问题(判断不准确)。
        /// source 触发场景,0 为 SDK 启动,1 为检测到通知开关状态变更
        log('onNotificationSettingsCheck: ${settingsCheck?.toMap()}');
      }),
      iosEventHandler: FlJPushIOSEventHandler(
          onReceiveNotificationAuthorization: (bool? state) {
            /// iOS 申请通知权限 回调
            log('onReceiveNotificationAuthorization: $state');
          }, onOpenSettingsForNotification: (JPushNotificationMessage? data) {
        /// 从应用外部通知界面进入应用是指 左滑通知->管理->在“某 App”中配置->进入应用 。
        /// 从通知设置界面进入应用是指 系统设置->对应应用->“某 App”的通知设置
        /// 需要先在授权的时候增加这个选项 JPAuthorizationOptionProvidesAppNotificationSettings
        log('onOpenSettingsForNotification: ${data?.toMap()}');
      }));
}

APIs

获取 registrationId

void getRegistrationID() {
  FlJPush().getRegistrationID().then((String? rid) {
    print('get registration id : $rid');
  });
}

停止推送功能

void stopPush() {
  FlJPush().stop();
}

恢复推送

void resumePush() {
  FlJPush().resume();
}

设置别名

void setAlias() {
  FlJPush().setAlias('your alias').then((AliasResultModel? model) {});
}

删除别名

void deleteAlias() {
  FlJPush().deleteAlias().then((AliasResultModel? model) {});
}

获取别名

void getAlias() {
  FlJPush().getAlias().then((AliasResultModel? model) {});
}

添加标签

void addTags() {
  FlJPush().addTags(['tag1', 'tag2']).then((TagResultModel? model) {});
}

删除标签

void deleteTags() {
  FlJPush().deleteTags(['tag1', 'tag2']).then((TagResultModel? model) {});
}

重置标签

void setTags() {
  FlJPush().setTags(['tag1', 'tag2']).then((TagResultModel? model) {});
}

验证标签是否绑定

void validTag() {
  FlJPush().validTag('tag1').then((TagResultModel? model) {});
}

清空所有标签

void cleanTags() {
  FlJPush().cleanTags().then((TagResultModel? model) {});
}

获取当前标签列表

void getAllTags() {
  FlJPush().getAllTags().then((TagResultModel? model) {});
}

发送本地通知

/// 延时 3 秒后触发本地通知。
void sendLocalNotification() {
  final notificationID = DateTime.now().millisecondsSinceEpoch;
  var localNotification = LocalNotification(
      id: notificationID,
      title: 'title',
      content: 'content',
      fireTime: 3,
      badge: 5,
      extras: {'hh': '11'} // 设置 extras ,extras 需要是 Map<String, String>
  );
  FlJPush().sendLocalNotification(
      android: localNotification.toAndroid(buildId: 1,),
      ios: localNotification.toIOS(subtitle: 'subtitle',));
}

清空通知栏上的通知

Future<void> clearNotification() async {
  /// 清空通知栏上某个通知
  bool? status = await FlJPush().clearNotification(notificationId: notificationId);

  /// 清空通知栏上全部通知
  bool? status = await FlJPush().clearNotification();

  /// 清空通知栏上全部本地通知 仅支持android
  bool? status = await FlJPush().clearNotification(clearLocal: true);

  /// 清空通知栏上全部待推送的通知 仅支持ios
  bool? status = await FlJPush().clearNotification(delivered: false);
}

检测通知授权状态是否打开

Future<void> isNotificationEnabled() async {
  bool? status = await FlJPush().isNotificationEnabled();
}

Push Service 是否已经被停止

Future<void> isPushStopped() async {
  bool? status = await FlJPush().isPushStopped();
}

设置应用 badge 值

void setBadge() {
  FlJPush().setBadge(66).then((bool? status) {});
}

获取 UDID

Future<void> getAndroidUdID() async {
  String? udid = await FlJPush().getUDIDWithAndroid();
}

申请推送权限

void applyAuthorityWithIOS() {
  FlJPush().applyAuthorityWithIOS(NotificationSettingsWithIOS(
      sound: true,
      alert: true,
      badge: true));
}

获取 iOS 点击推送启动应用的那条通知

void getLaunchAppNotificationWithIOS() {
  FlJPush().getLaunchAppNotificationWithIOS().then((Map<dynamic, dynamic>? map) {});
}

示例代码

example/lib/main.dart

import 'package:fl_extended/fl_extended.dart';
import 'package:fl_jpush/fl_jpush.dart';
import 'package:flutter/material.dart';

void log(dynamic msg) => debugPrint(msg.toString());

void main() {
  runApp(MaterialApp(
      debugShowCheckedModeBanner: false,
      title: '极光推送',
      home: Scaffold(
          appBar: AppBar(title: const Text('极光推送 Flutter')),
          body: const SingleChildScrollView(child: HomePage()))));
}

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

  [@override](/user/override)
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  String text = 'Unknown';
  int notificationID = 222;

  [@override](/user/override)
  void initState() {
    super.initState();

    /// 初始化
    FlJPush()
        .setup(
            appKey: '3af087cca42c9f95df54ab89',
            // 你自己应用的 AppKey
            production: true,
            channel: 'channel',
            debug: true)
        .then((bool value) {
      log('初始化成功:$value');
      addEventHandler();
      if (isIOS) {
        FlJPush()
            .applyAuthorityWithIOS(const NotificationSettingsWithIOS(
                providesAppNotificationSettings: true))
            .then((value) {
          log('请求通知 $value');
        });
      }
      if (isAndroid) {
        FlJPush().requestPermission();
      }
    });
  }

  Future<void> addEventHandler() async {
    FlJPush().addEventHandler(
        eventHandler: FlJPushEventHandler(
            onOpenNotification: (JPushNotificationMessage? message) {
          /// 点击通知栏消息回调
          log('onOpenNotification: ${message?.toMap()}');
          text = 'onOpenNotification: ${message?.toMap()}';
          setState(() {});
        }, onReceiveNotification: (JPushNotificationMessage? message) {
          /// 接收普通消息
          log('onReceiveNotification: ${message?.toMap()}');
          text = 'onReceiveNotification: ${message?.toMap()}';
          setState(() {});
        }, onReceiveMessage: (JPushMessage? message) {
          /// 接收自定义消息
          log('onReceiveMessage: ${message?.toMap()}');
          text = 'onReceiveMessage: ${message?.toMap()}';
          setState(() {});
        }),
        androidEventHandler: FlJPushAndroidEventHandler(
            onCommandResult: (FlJPushCmdMessage message) {
          log('onCommandResult: ${message.toMap()}');
        }, onNotifyMessageDismiss: (JPushNotificationMessage? message) {
          /// 清除通知回调
          /// 1.同时删除多条通知,可能不会多次触发清除通知的回调
          /// 2.只有用户手动清除才有回调,调接口清除不会有回调
          log('onNotifyMessageDismiss: ${message?.toMap()}');
          text = 'onNotifyMessageDismiss: ${message?.toMap()}';
          setState(() {});
        }, onNotificationSettingsCheck:
                (FlJPushNotificationSettingsCheck? settingsCheck) {
          /// 通知开关状态回调
          /// 说明: SDK内部检测通知开关状态的方法因系统差异,在少部分机型上可能存在兼容问题(判断不准确)。
          /// source 触发场景,0 为 SDK 启动,1 为检测到通知开关状态变更
          log('onNotificationSettingsCheck: ${settingsCheck?.toMap()}');
          text = 'onNotificationSettingsCheck: ${settingsCheck?.toMap()}';
          setState(() {});
        }),
        iosEventHandler: FlJPushIOSEventHandler(
            onReceiveNotificationAuthorization: (bool? state) {
          /// iOS 申请通知权限 回调
          log('onReceiveNotificationAuthorization: $state');
          text = 'onReceiveNotificationAuthorization: $state';
          log("flutter: $text");
          setState(() {});
        }, onOpenSettingsForNotification: (JPushNotificationMessage? data) {
          /// 从应用外部通知界面进入应用是指 左滑通知->管理->在“某 App”中配置->进入应用 。
          /// 从通知设置界面进入应用是指 系统设置->对应应用->“某 App”的通知设置
          /// 需要先在授权的时候增加这个选项 JPAuthorizationOptionProvidesAppNotificationSettings
          log('onOpenSettingsForNotification: ${data?.toMap()}');
          text = 'onOpenSettingsForNotification: ${data?.toMap()}';
          setState(() {});
        }));
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Column(children: <Widget>[
      Container(
          alignment: Alignment.center,
          margin: const EdgeInsets.all(10),
          height: 100,
          child: Text(text)),
      Wrap(
          alignment: WrapAlignment.center,
          runSpacing: 10,
          spacing: 10,
          children: <Widget>[
            ElevatedText(
                text: 'getRegistrationID',
                onPressed: () {
                  FlJPush().getRegistrationID().then((String? rid) {
                    log('get registration id : $rid');
                    text = 'getRegistrationID: $rid';
                    setState(() {});
                  });
                }),
            ElevatedText(
                text: '发本地推送',
                onPressed: () async {
                  final localNotification = LocalNotification(
                      id: notificationID,
                      title: 'test',
                      content: 'flutter send LocalMessage',
                      fireTime: 2,
                      badge: 5);
                  final res = await FlJPush().sendLocalNotification(
                      android: localNotification.toAndroid(),
                      ios: localNotification.toIOS());
                  text = "$res";
                  setState(() {});
                }),
            ElevatedText(
                text: 'setTags',
                onPressed: () async {
                  final TagResultModel? map =
                      await FlJPush().setTags(<String>['test1', 'test2']);
                  if (map == null) return;
                  text = 'set tags success: ${map.toMap()}}';
                  setState(() {});
                }),
            ElevatedText(
                text: 'addTags',
                onPressed: () async {
                  final TagResultModel? map =
                      await FlJPush().addTags(<String>['test3', 'test4']);
                  text = 'addTags success: ${map?.toMap()}}';
                  setState(() {});
                }),
            ElevatedText(
                text: 'deleteTags',
                onPressed: () async {
                  final TagResultModel? map =
                      await FlJPush().deleteTags(<String>['test1', 'test2']);
                  text = 'deleteTags success: ${map?.toMap()}}';
                  setState(() {});
                }),
            ElevatedText(
                text: 'validTag',
                onPressed: () async {
                  final TagResultModel? map = await FlJPush().validTag('test1');
                  if (map == null) return;
                  text = 'valid tags success: ${map.toMap()}}';
                  setState(() {});
                }),
            ElevatedText(
                text: 'getAllTags',
                onPressed: () async {
                  final TagResultModel? map = await FlJPush().getAllTags();
                  text = 'getAllTags success: ${map?.toMap()}';
                  setState(() {});
                }),
            ElevatedText(
                text: 'cleanTags',
                onPressed: () async {
                  final TagResultModel? map = await FlJPush().cleanTags();
                  text = 'cleanTags success: ${map?.toMap()}}';
                  setState(() {});
                }),
            ElevatedText(
                text: 'setAlias',
                onPressed: () async {
                  final AliasResultModel? map =
                      await FlJPush().setAlias('alias1');
                  text = 'setAlias success: ${map?.toMap()}';
                  setState(() {});
                }),
            ElevatedText(
                text: 'getAlias',
                onPressed: () async {
                  final AliasResultModel? map = await FlJPush().getAlias();
                  text = 'getAlias success: ${map?.toMap()}';
                  setState(() {});
                }),
            ElevatedText(
                text: 'deleteAlias',
                onPressed: () async {
                  final AliasResultModel? map = await FlJPush().deleteAlias();
                  text = 'deleteAlias success: ${map?.toMap()}';
                  setState(() {});
                }),
            ElevatedText(
                text: 'stopPush',
                onPressed: () async {
                  final bool status = await FlJPush().stop();
                  text = 'stopPush success: $status';
                  setState(() {});
                }),
            ElevatedText(
                text: 'resumePush',
                onPressed: () async {
                  final bool status = await FlJPush().resume();
                  text = 'resumePush success: $status';
                  setState(() {});
                }),
            ElevatedText(
                text: 'clearNotification',
                onPressed: () async {
                  final bool data = await FlJPush()
                      .clearNotification(notificationId: notificationID);
                  text = 'clearNotification success: $data';
                  setState(() {});
                }),
            ElevatedText(
                text: 'setBadge 66',
                onPressed: () async {
                  final bool map = await FlJPush().setBadge(66);
                  text = 'setBadge success: $map';
                  setState(() {});
                }),
            ElevatedText(
                text: 'setBadge 0',
                onPressed: () async {
                  final bool map = await FlJPush().setBadge(0);
                  text = 'setBadge 0 success: $map';
                  setState(() {});
                }),
            ElevatedText(
                text: '打开系统设置',
                onPressed: () {
                  FlJPush().openSettingsForNotification();
                }),
            ElevatedText(
                text: '通知授权是否打开',
                onPressed: () {
                  FlJPush().isNotificationEnabled().then((bool? value) {
                    text = '通知授权是否打开: $value';
                    setState(() {});
                  });
                }),
          ]),
      if (isIOS)
        ElevatedText(
            text: 'getLaunchAppNotification',
            onPressed: () {
              FlJPush()
                  .getLaunchAppNotificationWithIOS()
                  .then((Map<dynamic, dynamic>? map) {
                log('getLaunchAppNotification:$map');
                text = 'getLaunchAppNotification success: $map';
                setState(() {});
              });
            }),
      if (isAndroid)
        Wrap(
            alignment: WrapAlignment.center,
            runSpacing: 10,
            spacing: 10,
            children: <Widget>[
              ElevatedText(
                  text: 'Push 是否已经被停止',
                  onPressed: () {
                    FlJPush().isPushStopped().then((bool? value) {
                      text = 'Push Service 是否已经被停止: $value';
                      setState(() {});
                    });
                  }),
              ElevatedText(
                  text: 'getAndroidUdID',
                  onPressed: () async {
                    final String? id = await FlJPush().getUDIDWithAndroid();
                    if (id == null) return;
                    text = 'getAndroidJPushUdID success: $id';
                    setState(() {});
                  }),
            ]),
      const SizedBox(height: 100),
    ]);
  }
}

class ElevatedText extends ElevatedButton {
  ElevatedText({super.key, required super.onPressed, required String text})
      : super(child: Text(text));
}

更多关于Flutter推送通知插件fl_jpush的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter推送通知插件fl_jpush的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是一个关于如何在Flutter项目中使用fl_jpush插件来实现推送通知的示例代码。fl_jpush是一个用于集成JPush推送服务的Flutter插件。

1. 添加依赖

首先,你需要在pubspec.yaml文件中添加fl_jpush依赖:

dependencies:
  flutter:
    sdk: flutter
  fl_jpush: ^最新版本号  # 请替换为最新版本号

然后运行flutter pub get来安装依赖。

2. 配置Android

android/app/src/main/AndroidManifest.xml中配置JPush的必要权限和服务:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.yourapp">

    <!-- JPush权限和服务 -->
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.VIBRATE" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-permission android:name="android.permission.GET_TASKS" />

    <application
        ... >
        
        <!-- JPush服务 -->
        <meta-data
            android:name="JPUSH_APPKEY"
            android:value="你的JPush AppKey" />
        <meta-data
            android:name="JPUSH_CHANNEL"
            android:value="developer-default" />
        
        <service
            android:name="cn.jpush.android.service.JPushService"
            android:enabled="true"
            android:exported="false">
            <intent-filter>
                <action android:name="cn.jpush.android.intent.REGISTER" />
                <action android:name="cn.jpush.android.intent.UNREGISTER" />
                <action android:name="cn.jpush.android.intent.UPDATE_REGISTRATION" />
                <action android:name="cn.jpush.android.intent.MESSAGE_RECEIVED" />
                <action android:name="cn.jpush.android.intent.NOTIFICATION_RECEIVED" />
                <action android:name="cn.jpush.android.intent.NOTIFICATION_OPEN" />
                <action android:name="cn.jpush.android.intent.CONNECTION" />
                <category android:name="cn.jpush.android.category.JPUSH_SERVICE" />
            </intent-filter>
        </service>

        <receiver
            android:name="cn.jpush.android.service.JPushReceiver"
            android:enabled="true"
            android:exported="false">
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED" />
                <action android:name="android.intent.action.USER_PRESENT" />
                <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
                <action android:name="android.intent.action.PACKAGE_REMOVED" />
                <action android:name="android.intent.action.PACKAGE_ADDED" />
                <action android:name="android.intent.action.PACKAGE_REPLACED" />
                <category android:name="cn.jpush.android.category.JPUSH_RECEIVER" />
            </intent-filter>
        </receiver>
        
        <!-- 其他配置 -->
        ...
    </application>
</manifest>

3. 配置iOS

如果你也需要在iOS上集成JPush,需要完成以下步骤:

  1. ios/Runner/Info.plist中添加必要的权限配置。
  2. ios/Podfile中添加JPush的依赖。
  3. 在Xcode中配置相关的推送证书和AppID等。

由于iOS配置较为复杂,这里只给出Info.plist中的部分配置示例,具体请参考JPush的官方文档:

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsArbitraryLoads</key>
    <true/>
</dict>

<key>UIRequiredDeviceCapabilities</key>
<array>
    <string>armv7</string>
</array>

<key>UIBackgroundModes</key>
<array>
    <string>remote-notification</string>
</array>

4. 初始化JPush

在你的Flutter项目的main.dart或其他入口文件中初始化JPush:

import 'package:flutter/material.dart';
import 'package:fl_jpush/fl_jpush.dart';

void main() {
  runApp(MyApp());
  
  // 初始化JPush
  FlJPush.init(appKey: "你的JPush AppKey");
  
  // 监听通知点击事件
  FlJPush.addNotificationOpenedListener((result) {
    print("Notification opened: ${result}");
  });
  
  // 监听自定义消息接收事件
  FlJPush.addReceiveCustomMessageListener((message) {
    print("Received custom message: ${message}");
  });
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'You have pushed the button this many times:',
            ),
            // 其他UI组件
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          // 发送本地通知示例
          FlJPush.sendLocalNotification(
            id: 1,
            title: "Hello",
            content: "This is a local notification",
            extras: {"key": "value"},
          );
        },
        tooltip: 'Send Notification',
        child: Icon(Icons.send),
      ),
    );
  }
}

5. 运行项目

完成以上配置后,运行你的Flutter项目,确保一切正常工作。如果配置正确,你应该能够接收到来自JPush的推送通知,并且在点击通知时能够触发相应的监听器。

请注意,以上代码示例仅用于演示,具体使用时请根据你的实际需求进行调整和完善。

回到顶部