“這是我參與8月更文挑戰的第25天,活動詳情檢視: 8月更文挑戰” juejin.cn/post/698796…
我們每天都在接收各種推送訊息,而最初的 Flutter 推送主要是與原生互動進行;現階段極光推出了 Flutter JPush,雖不如原生強大,但日常需求均可滿足,小菜嘗試整合了 Flutter 版的 JPush;
前期準備
- 在 極光 後臺註冊賬號並【建立應用】;
- 在【推送設定】中設定 Android/iOS 基本資訊,小菜以 Android 為例,注意應用包名為 ApplicationID;
- 在【應用資訊】中獲取 AppKey 等關鍵引數;
中期整合
Android 配置
與原生接入 JPush 相同,需要在 Android Gradle 加入配置資訊;
defaultConfig {
applicationId "com.example.flutterapp01"
minSdkVersion 16
targetSdkVersion 28
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
ndk {
//選擇要新增的對應 cpu 型別的 .so 庫。
abiFilters 'armeabi', 'armeabi-v7a', 'x86', 'x86_64', 'mips', 'mips64', 'arm64-v8a'
}
manifestPlaceholders = [
JPUSH_PKGNAME : "com.example.flutterapp01",
JPUSH_APPKEY : "AppKey", // NOTE: JPush 上註冊的包名對應的 Appkey.
JPUSH_CHANNEL : "developer-default", //暫時填寫預設值即可.
]
}
複製程式碼
Flutter 配置
按照平常外掛接入的方法在工程 pubspec.yaml 中加入 jpush_flutter: 0.1.0 並同步即可;
dependencies:
jpush_flutter: 0.1.0
複製程式碼
API 呼叫
JPush 的使用方式很簡單,Demo 中都很全面,小菜僅嘗試常見的方法;
1. 初始化
在原生開發中各類三方的外掛幾乎均須在 Application 中初始化,同樣 Flutter 也需要先呼叫 JPush.setup 進行初始化;其中 channel 可自定義,小菜未從原始碼中獲取準確訊息,個人理解與高版本的 Android Channel 通道類似;
初始化成功之後即可獲取訊息推送,只是暫不能處理;
final JPush _jPush = JPush();
@override
void initState() {
super.initState();
initPlatformState();
}
Future<void> initPlatformState() async {
_jPush.setup(
appKey: "後臺獲取 AppKey",
channel: "flutter_channel",
production: false,
debug: true,
);
if (!mounted) return;
}
複製程式碼
2. RegistrationID
每個使用者均有作為接收訊息的唯一標識 RegistrationID,方便對單個或多個裝置進行推送測試;
_jPush.getRegistrationID().then((rid) {
setState(() {
_result = "JPush RegistrationID 唯一標識:\n $rid";
_registID = rid;
});
});
複製程式碼
3. 本地通知
JPush 提供了本地推送的方法,可以靈活呼叫獲取本地推送訊息;注意 id 為 int 型別,設定不能過長;
// 原始碼分析
const LocalNotification ({
@required this.id, // 通知 id, 可用於取消通知
@required this.title, // 通知標題
@required this.content, // 通知內容
@required this.fireTime, // 通知觸發時間(毫秒)
this.buildId, // 通知樣式:1 為基礎樣式,2 為自定義樣式(需先呼叫 'setStyleCustom' 設定自定義樣式)
this.extra, // 額外資訊
this.badge = 0, // iOS:本地推送觸發後應用角標值
this.soundName, // iOS:指定推送的音訊檔案
this.subtitle // iOS:子標題
}):
onTap: () {
var fireDate = DateTime.fromMillisecondsSinceEpoch(DateTime.now().millisecondsSinceEpoch + 3000);
var localNotification = LocalNotification(
id: 000001,
title: 'Local Push 本地標題',
buildId: 1,
content: 'Local Push 本地內容',
fireTime: fireDate,
extra: {"extra_key": "extra_value"});
_jPush.sendLocalNotification(localNotification).then((res) {
setState(() {
_result = res;
});
});
}
複製程式碼
4. 通知類訊息
小菜整合原生推送時分為 通知類訊息 和 透傳類訊息(自定義訊息),兩種推送略有不同;通知類訊息可以通過極光後臺配置訊息標題、訊息內容等多種資訊,且 App 接收到之後直接呼叫推送通道展現在通知欄中;
try {
_jPush.addEventHandler(
onReceiveNotification: (Map<String, dynamic> message) async {
// 獲取通知資料
print('Flutter JPush 獲取通知類資料:\n $message');
setState(() {
_result = 'Flutter JPush 獲取通知類資料:\n $message';
_message = message;
});
}
);
} on PlatformException {
platformVersion = 'Failed to get platform version.';
}
複製程式碼
5. 透傳類訊息
透傳類訊息通過極光後臺配置傳送,主要配置通知內容;App 接收到不會直接呼叫推送通道,獲取內容後我們可根據內容靈活使用,是否展示推送訊息或其他操作等;且通知類訊息與透傳類訊息獲取引數不同;
try {
_jPush.addEventHandler(
onReceiveMessage: (Map<String, dynamic> message) async {
// 獲取透傳資料
print('Flutter JPush 獲取透傳類資料:\n $message');
setState(() {
_result = 'Flutter JPush 獲取透傳類資料:\n $message';
_message = message;
});
}
);
} on PlatformException {
platformVersion = 'Failed to get platform version.';
}
複製程式碼
6. 推送點選監聽
獲取到推送之後註定要有點選操作,JPush 也同樣提供了監聽方法,包括通知類訊息和本地推送訊息;
try {
_jPush.addEventHandler(
onOpenNotification: (Map<String, dynamic> message) async {
// 點選通知資訊
print('Flutter JPush 點選通知訊息:\n $message');
setState(() {
_result = 'Flutter JPush 點選通知訊息:\n $message';
_message = message;
});
}
);
} on PlatformException {
platformVersion = 'Failed to get platform version.';
}
複製程式碼
7. 清空通知欄
在使用者收到推送通知後若未點選,原生 Android 可通過 NotificationManager.cancel() 清除通知,Flutter 也提供了清空通知欄方法;但小菜測試只可清空通知類推送訊息,本地傳送的通知訊息無法清空;
Future clearAllNotifications() async {
await _channel.invokeMethod('clearAllNotifications');
}
_jPush.clearAllNotifications();
複製程式碼
後期測試
1. 通知類訊息
- 在極光後臺【傳送通知】中按要求編輯目標平臺、通知標題、通知內容、傳送時間和選擇目標等基本資訊;
- App 接收訊息,並展示推送訊息,各引數如下:
2. 透傳類訊息
- 在極光後臺【自定義訊息】中按要求編輯目標平臺、通知內容、傳送時間和選擇目標等基本資訊;其中 Registration ID 為測試時獲取的唯一標識;
- App 接收訊息,不會展示推送訊息,若需要可呼叫本地通知;各引數如下:
onOpenNotification: (Map<String, dynamic> message) async {
setState(() {
_result = 'Flutter JPush 點選通知訊息:\n $message';
_message = message;
Map<String, dynamic> message2 = convert.jsonDecode(_message['extras']['cn.jpush.android.EXTRA']);
if (message2['type'] == "1") {
Toast.show('自定義通知訊息!', context, duration: Toast.LENGTH_SHORT, gravity: Toast.BOTTOM);
}
});
}
onReceiveMessage: (Map<String, dynamic> message) async {
setState(() {
_result = 'Flutter JPush 獲取透傳類資料:\n $message';
_message = message;
Map<String, dynamic> message2 = convert.jsonDecode(_message['message']);
var fireDate = DateTime.fromMillisecondsSinceEpoch(DateTime.now().millisecondsSinceEpoch + 2000);
var localNotification = LocalNotification(
id: message2['id'],
title: message2['title'],
buildId: 1,
content: message2['context'],
fireTime: fireDate,
extra: {"type": message2['type']});
_jPush.sendLocalNotification(localNotification).then((res) {
setState(() { _result = res; });
});
});
}
複製程式碼
小菜認為 Flutter 版的極光推送與 Android 原生版本的差異在於,大部分的配置有 App 端移到了極光後臺,包括圖示 icon,頁面處理,通知級別等;小菜僅嘗試了基本的訊息推送及處理,還是有很多細節需要認真學習;如有問題,請多多指導!
來源: 阿策小和尚