Ray-56 / m-dream

记录生活、学习
14 stars 5 forks source link

Flutter集成阿里云推送通知 #1

Open Ray-56 opened 4 years ago

Ray-56 commented 4 years ago

Flutter集成阿里云推送通知

这里我使用了 Rammus 来实现通知推送。由于是第一次做客户端的消息推送在使用的时候遇到了一些问题,通过不断调试最终使功能完备。

效果如下:

实现过程

首先一定要先阅读阿里云的官方文档Android SDK 配置

阿里云平台

这里需要拿到已注册好应用的aliyun-emas-services.json文件,这里面包含有AppKey,AppSecret等相关信息

添加插件

dependencies:
  ...
  rammus: ^1.0.3
  ...

配置Android

android/build.gradle文件中添加下面代码

  repositories {
        ...
      maven {
          url 'http://maven.aliyun.com/nexus/content/repositories/releases/'
      }
      ...
  }
  dependencies {
        ...
        classpath 'com.aliyun.ams:emas-services:1.0.1'
        ...
  }

  ...
  repositories {
        ...
        maven {
          url 'http://maven.aliyun.com/nexus/content/repositories/releases/'
      }
      ...
  }

android/app/build.gradle文件中添加下面代码

...
apply plugin: 'com.aliyun.ams.emas-services'
...
android {
    compileSdkVersion 28
    ndkVersion '21.1.6352462'
    ...
dependencies {
        ...
        // implementation 'com.aliyun.ams:alicloud-android-push:3.1.9.1' // 或者下面
    implementation 'com.aliyun.ams:alicloud-android-push:3.1.9.1@aar'
    implementation 'com.aliyun.ams:alicloud-android-utils:1.1.5'
    implementation 'com.aliyun.ams:alicloud-android-beacon:1.0.3'
    implementation 'com.aliyun.ams:alicloud-android-ut:5.4.3'
    implementation 'com.aliyun.ams:alicloud-android-utdid:1.5.2'
}

android/app/src/main/AndroidManifest.xml文件中修改 Application 属性

...
     <application
-        android:name="io.flutter.app.FlutterApplication"
+        android:name=".MyApplication"
+        android:allowBackup="true"
+        android:icon="@mipmap/ic_launcher"
+        tools:replace="android:icon, android:label, android:name, android:allowBackup"
+        tools:ignore="GoogleAppIndexingWarning"
+    >
...
            <meta-data
                android:name="com.alibaba.app.appkey"
                android:value="填写你自己的 appkey"
            />
            <meta-data
                android:name="com.alibaba.app.appsecret"
                android:value="填写你自己的appsecret"
            />
...
    <!-- 阿里云推送相关权限 -->
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-permission android:name="android.permission.GET_ACCOUNTS" />
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
    <uses-permission android:name="android.permission.VIBRATE" />
    <uses-permission android:name="android.permission.REORDER_TASKS" />
...

android/app/src/main/kotlin/com/example/eshop_app/MyApplication.kt添加文件


package com.example.app

import android.app.NotificationChannel
import android.app.NotificationManager
import android.content.Context
import android.graphics.Color
import android.os.AsyncTask
import android.os.Build
import android.util.Log
import com.alibaba.sdk.android.push.CloudPushService.LOG_INFO
import com.alibaba.sdk.android.push.CommonCallback
import com.alibaba.sdk.android.push.noonesdk.PushServiceFactory
import com.jarvanmo.rammus.RammusPushIntentService
import io.flutter.app.FlutterApplication

class MyApplication:FlutterApplication() {
    override fun onCreate() {
        super.onCreate()

        PushServiceFactory.init(applicationContext)
        val pushService = PushServiceFactory.getCloudPushService()
        val callback = object : CommonCallback {
            override fun onSuccess(response: String?) {
                Log.e("TAG","success $response")
            }

            override fun onFailed(errorCode: String?, errorMessage: String?) {
                Log.e("TAG","error $errorMessage")
            }
        }

        pushService.register(applicationContext,callback)
        pushService.setPushIntentService(RammusPushIntentService::class.java)
    }
}

配置 IOS

iOS 配置推送证书指南

Flutter lib代码

import 'package:rammus/rammus.dart' as rammus;
...
@override
  void initState() {
    super.initState();

    rammus.setupNotificationManager(
      description: "rammus test",
      name: "rammus",
      id: "通知通道,查看自己平台中具体的值", // 这里是阿里云平台中给的 Android8.0 特殊配置的 通知通道 给定的值
    );
    rammus.onNotification.listen((data) {
      print("----------->notification here ${data.summary}");
    });
    rammus.onNotificationOpened.listen((data) {
      print("-----------> ${data.title} 被点了");
      print("-----------> ${data.summary} 被点了");
      print("-----------> ${data.extras} 被点了");
      print("-----------> ${data.subtitle} 被点了");
      print("-----------> ${data.badge} 被点了");
      // 点击消息后这里处理项目具体业务
      // 例如:根据数据跳转指定页面
    });

    rammus.onNotificationRemoved.listen((data) {
      print("-----------> $data 被删除了");
    });

    rammus.onNotificationReceivedInApp.listen((data) {
      print("-----------> ${data.summary} In app");
    });

    rammus.onNotificationClickedWithNoAction.listen((data) {
      print("${data.summary} no action");
    });

    rammus.onMessageArrived.listen((data) {
      print("received data -> ${data.content}");
    });
  }
...
...
/// 获取绑定 device id
Future<void> _bindDeviceId() async {
  var _deviceId = await rammus.deviceId;
  SysAccountApi.bindDevice(_deviceId); // 我们项目自己定义的绑定方法
  // 拿到 device id 后,需要根据自己项目做处理
  // 发给后台进行指定设备的绑定
}
...

其它

至此,推送功能基本完备

感谢rammus的作者

jkLennon commented 4 years ago

请问有遇到过安卓原生接收到推送信息,但是在flutter里面添加的监听无效吗?

Ray-56 commented 4 years ago

@jkLennon 有的,刚开始做的时候 flutter 监听事件确实无效,问一下后台同学,看看当前这个设备是否在线

jkLennon commented 4 years ago

@jkLennon有的,刚开始做的时候flutter监听事件确实无效,问一下后台同学,看看当前这个设备是否在线

1、设备是在线的。 2、在编辑器里原生在console里已经打印出通知的信息,但是rammus插件的RammusPushIntentService.kt文件获取不到数据,无法调用RammusPushHandler.methodChannel.invokeMethod方法把数据推给flutter。我用的插件是rammus: ^1.2.1 3、这个问题在短时间多次推送时会出现 test

Ray-56 commented 4 years ago

@jkLennon ,原生的我不太懂,本职是做前端的,现在也大半年没有写过了,我是按照配置一步步完成之后遇见接受不到消息,就是因为当前设备没有绑定,或者显示设备不在线两种情况,多次推送我这边也是没有问题的,我的版本也是 1.2.1 ,你这个问题可能需要你自己再排查一下了,如果方便的话,最终的解决方案可以告诉我一下😜😜😜

jkLennon commented 4 years ago

@jkLennon,原生的我不太懂,本职是做前端的,现在也大半年没有写过了,我是按照配置一步步完成之后遇见接受不到消息,就是因为当前设备没有绑定,或者显示设备不在线两种情况,多次按下我这边也是没有问题的,我的版本也是1.2.1,你这个问题可能需要你自己再排查一下了,如果方便的话,最终的解决方案可以告诉我一下😜😜😜

好哦,谢谢😂要是后面有解决方案会再来留言的👌