我正在使用OneSignal推送通知服务,我想在通知单击时直接将应用程序打开到特定页面。我正在通过数据发送页面。我尝试了navigator.push,但是由于上下文问题,我认为它不起作用。登录后我将调用_initializeonesignal(),其中包含一个信号初始化和以下代码。
OneSignal.shared.setNotificationOpenedHandler((notification) {
var notify = notification.notification.payload.additionalData;
if (notify["type"] == "message") {
//open DM(user: notify["id"])
}
if (notify["type"] == "user") {
//open Profileo(notify["id"])
}
if (notify["type"] == "post") {
//open ViewPost(notify["id"])
}
print('Opened');
});
答案 0 :(得分:0)
您将需要在主应用程序支架中注册一个全局Navigator句柄-然后可以在通知处理程序中使用它。.
所以-在我们的主应用程序中,我们有:
// Initialize our global NavigatorKey
globals.navigatorKey = GlobalKey<NavigatorState>();
...
return MaterialApp(
title: 'MissionMode Mobile',
theme: theme,
initialRoute: _initialRoute,
onGenerateRoute: globals.router.generator,
navigatorKey: globals.navigatorKey,
);
键是navigatorKey:部分,并将其保存到可以访问其他位置的位置。
然后在您的处理程序中:
OneSignal.shared.setNotificationOpenedHandler(_handleNotificationOpened); ...
// What to do when the user opens/taps on a notification
void _handleNotificationOpened(OSNotificationOpenedResult result) {
print('[notification_service - _handleNotificationOpened()');
print(
"Opened notification: ${result.notification.jsonRepresentation().replaceAll("\\n", "\n")}");
// Since the only thing we can get current are new Alerts -- go to the Alert screen
globals.navigatorKey.currentState.pushNamed('/home');
}
那应该可以解决问题-无论如何还是对我们有用:)
答案 1 :(得分:0)
很简单,通过使用onesignal,您可以创建从Kotlin到扑扑的系统调用
就我而言,我必须从WordPress的onesignal发出的通知中获取URL中的数据:
package packageName.com
import android.os.Bundle
import androidx.annotation.NonNull;
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.MethodChannel
import io.flutter.plugins.GeneratedPluginRegistrant
// import io.flutter.plugins.firebaseadmob.FirebaseAdMobPlugin;
private val CHANNEL = "poc.deeplink.flutter.dev/channel"
private var startString: String? = null
class MainActivity: FlutterActivity() {
override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
GeneratedPluginRegistrant.registerWith(flutterEngine);
MethodChannel(flutterEngine.dartExecutor, CHANNEL).setMethodCallHandler { call, result ->
if (call.method == "initialLink") {
if (startString != null) {
result.success(startString)
}
}
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val intent = getIntent()
startString = intent.data?.toString()
}
}
这是我从 onCreate 获取数据的方法,但是只有在单击通知时,我才会获取“意图” 数据,然后将其发送到我的以下类别中的颤动代码:
import 'dart:async';
import 'package:flutter/services.dart';
class MyNotificationHandler {
//Method channel creation
static const platform =
const MethodChannel('poc.deeplink.flutter.dev/channel');
//Method channel creation
static String url;
static String postID;
static onRedirected(String uri) {
url = uri;
postID = url.split('/').toList()[3];
}
static Future<String> startUri() async {
try {
return platform.invokeMethod('initialLink');
} on PlatformException catch (e) {
return "Failed to Invoke: '${e.message}'.";
}
}
//Adding the listener into contructor
MyNotificationHandler() {
//Checking application start by deep link
startUri().then(onRedirected);
}
}
在这里,我从WordPress URL中获取数据,该URL是4ed'/'之后的最后一个单词,这是帖子的ID。
现在如何使用它并调用它,因为我是静态创建它的,所以当第一页加载时,我将在代码中使用它,
import 'package:com/config/LocalNotification.dart';
class MyLoadingPage extends StatefulWidget {
MyLoadingPage() {
MyNotificationHandler.startUri().then(MyNotificationHandler.onRedirected);
}
@override
_MyLoadingPageState createState() => _MyLoadingPageState();
}
...
此页面将从我的WordPress API加载数据。
因此,从数据库加载数据之后,我将检查id的值,并导航到文章页面,即我的主页中的示例:
....
@override
void initState() {
MyViewWidgets.generalScaffoldKey = _scaffoldKey;
myWidgetPosts = MyPostsOnTheWall(MyPost.allMyPosts, loadingHandler);
MyHomePAge.myState = this;
super.initState();
if (MyNotificationHandler.postID != null) {
Future.delayed(Duration(milliseconds: 250)).then((value) {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => MyArticlePage(MyPost.allMyPosts
.firstWhere((element) =>
element.id == MyNotificationHandler.postID))));
});
}
}
....
通过使用从kotlin到fluter或从Java到flutter的调用,秘密就在kotlin或Java中,我认为您必须对ios做同样的事情,我会留下一篇对我有帮助的文章。
https://medium.com/flutter-community/deep-links-and-flutter-applications-how-to-handle-them-properly-8c9865af9283
答案 2 :(得分:0)
我解决了相同的问题,如下所示:
在主屏幕文件中 MyApp.dart
@override
void initState() {
OneSignalWapper.handleClickNotification(context);
}
OneSignalWapper.dart :
static void handleClickNotification(BuildContext context) {
OneSignal.shared
.setNotificationOpenedHandler((OSNotificationOpenedResult result) async {
try {
var id = await result.notification.payload.additionalData["data_id"];
Navigator.of(context).push(MaterialPageRoute(
builder: (context) => PostDetailsScreen.newInstance('$id')));
} catch (e, stacktrace) {
log(e);
}
});
}
答案 3 :(得分:0)
我找到了解决办法:
在您的主屏幕上,设置处理程序。并且,在此之前,以这种方式设置您的配置通知
首先:
Map<String, dynamic> additional = {
"route": 'detail',
"userId": widget.userId
};
await OneSignal.shared.postNotification(OSCreateNotification(
playerIds: userToken,
content: 'your content',
heading: 'your heading',
additionalData: additional,
androidLargeIcon:'any icon'));
第二:
OneSignal.shared.setNotificationOpenedHandler(
(OSNotificationOpenedResult action) async {
Map<String, dynamic> dataNotification =
action.notification.payload.additionalData;
if (dataNotification.containsValue('detailPage')) {
await Navigator.push(
context,
new MaterialPageRoute(
builder: (context) => new DetailScreen(
userId: dataNotification['userId'],
),
).catchError((onError) {
print(onError);
});
}