如何在 onesignal 通知上打开特定页面点击颤动?

Ash*_*rma 6 dart onesignal flutter

我正在使用 OneSignal 推送通知服务,我想在点击通知时直接将应用程序打开到特定页面。我正在通过数据发送页面。我试过 navigator.push 但我猜它没有用,因为上下文问题。我在登录后调用 _initializeonesignal() ,其中包含 onesignal init 和以下代码。

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');
});
Run Code Online (Sandbox Code Playgroud)

sjm*_*all 5

您需要在主应用程序脚手架中注册一个全局导航器句柄——然后您可以在通知处理程序中使用它。

所以 - 在我们主应用程序的应用程序中,我们有:

    // Initialize our global NavigatorKey
    globals.navigatorKey = GlobalKey<NavigatorState>();

...
            return MaterialApp(
              title: 'MissionMode Mobile',
              theme: theme,
              initialRoute: _initialRoute,
              onGenerateRoute: globals.router.generator,
              navigatorKey: globals.navigatorKey,
            );
Run Code Online (Sandbox Code Playgroud)

关键是 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');
}
Run Code Online (Sandbox Code Playgroud)

那应该可以解决问题 - 无论如何对我们有用:)

  • 什么是“globals.navigatorKey” 在到达这里之前我们是否遗漏了一些代码? (3认同)

Nim*_*fta 1

很简单,通过使用onesignal,你可以创建从kotlin到flutter的系统调用

就我而言,我必须从来自 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()
    }
}
Run Code Online (Sandbox Code Playgroud)

我从onCreate获取数据,但只有在单击通知时,我才会获取“意图”数据,然后将其发送到以下类中的 flutter 代码:

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);
  }
}
Run Code Online (Sandbox Code Playgroud)

在这里,我从 WordPress URL 获取数据,即 4ed '/' 后面的最后一个单词,即帖子的 id。

现在如何使用它并调用它,因为我将它创建为静态的,所以我将在加载第一页时在我的代码中使用它,

import 'package:com/config/LocalNotification.dart';

class MyLoadingPage extends StatefulWidget {
  MyLoadingPage() {
    MyNotificationHandler.startUri().then(MyNotificationHandler.onRedirected);
  }
  @override
  _MyLoadingPageState createState() => _MyLoadingPageState();
}

...
Run Code Online (Sandbox Code Playgroud)

此页面将从我的 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))));
      });
    }
  }
....
Run Code Online (Sandbox Code Playgroud)

秘密是在 kotlin 或 Java 中通过使用从 kotlin 到 flutter 或从 java 到 flutter 的调用,我想你必须对 ios 做同样的事情,我将留下一篇对我有帮助的文章。

https://medium.com/flutter-community/deep-links-and-flutter-applications-how-to-handle-them-properly-8c9865af9283
Run Code Online (Sandbox Code Playgroud)