Flutter 基于极光的第三方厂商推送 + 关闭app后台推送实践指南

4,936 阅读3分钟

万物之初-简单的前台推送

下面我们要实现一个简单的极光前台推送。

以下例子均在安卓上实现,因为安卓是最麻烦的。

安装 Jpush sdk

极光推送已经原生支持flutter sdk,可以以pub的形式安装

dependencies:
  jpush_flutter: x.x.x

配置

# /android/app/build.gradle

android: {
  ....
  defaultConfig {
    applicationId "替换成自己应用 ID"
    ...
    ndk {
	//选择要添加的对应 cpu 类型的 .so 库。
	abiFilters 'armeabi', 'armeabi-v7a', 'x86', 'x86_64', 'mips', 'mips64', 'arm64-v8a',        
    }

    manifestPlaceholders = [
        ...
        JPUSH_PKGNAME : applicationId,
        JPUSH_APPKEY : "appkey", // NOTE: JPush 上注册的包名对应的 Appkey.
        JPUSH_CHANNEL : "developer-default", //暂时填写默认值即可.
        ...
    ]
  }    
  
  dependencies {
        compile 'cn.jiguang.sdk:jpush:4.2.8'
    }
  
}

编写推送工具类

以下使用单例模式实现

// @/lib/utils/JMPush.dart

import 'package:jpush_flutter/jpush_flutter.dart';

class JMPush {

  static final JMPush _shared = JMPush._internal();
  factory JMPush() => _shared;

  JPush jPush;
  JMPush._internal() {
    if (jPush == null) {
      jPush = new JPush();
    }
  }

  void init () {
    jPush.setup(
      appKey: "xxxx",
      channel: "theChannel",
      production: false,
      debug: true, // 设置是否打印 debug 日志
    );
    // jPush.addTags(["dev"]); // 可以添加标签,针对开发环境推送
    jPush.addEventHandler(
      // 接收通知回调方法。
      onReceiveNotification: (Map<String, dynamic> message) async {
        print("flutter onReceiveNotification: $message");
      },
      // 点击通知回调方法。
      onOpenNotification: (Map<String, dynamic> message) async {
        print("flutter onOpenNotification: $message");
      },
      // 接收自定义消息回调方法。
      onReceiveMessage: (Map<String, dynamic> message) async {
        print("flutter onReceiveMessage: $message");
      },
    );
  }

}

main.dart 注册使用

// @/lib/main.dart
import 'package:[your package]/utils/JMPush.dart';

void main(){
  ...
  runApp(
    Entry()
  );

  new JMPush().init();
  ...
}

测试推送效果

注册极光账号

image.png

然后配置你的app图标和名称之类的,打开测试推送界面

image.png

然后大功告成了,我们推送了一条简单消息。不过,这是远远不够的,在第三方厂商的限制下,我们的app关闭就没法在后台推送了,这位客官不要急,请继续往下看。

神说要有光-第三方厂商适配之-小米

上面我们已经实现了简单的前台推送,但是我们关闭程序后,就没法继续推送了,下面我们基于极光,对接小米推送。

小米开放平台

这里默认大家都已经有小米开发者账号,我们在小米开放平台开启推送,此时我们讲拥有了AppIDAppKey

对接小米sdk

我们在原来的基础上继续修改

# android/app/build.gradle
...
    defaultConfig {
        manifestPlaceholders {
            ...
            XIAOMI_APPKEY : "MI-xxxx", // 小米平台注册的appkey
            XIAOMI_APPID : "MI-xxxxx", // 小米平台注册的appid
            // 注意,前面还有个 MI- 这个不能去掉
        }
    }
    
    dependencies {
        ...
        compile 'cn.jiguang.sdk.plugin:xiaomi:4.0.0' // 这个版本号对应最新的小米推送
        ...
    }
...
# android/app/src/main/AndroidManifest.xml
...
<application>
   ...
   <receiver
    android:name="cn.jpush.android.service.PushReceiver"
    android:enabled="true">
    <intent-filter android:priority="1000">
        <action android:name="cn.jpush.android.intent.NOTIFICATION_RECEIVED_PROXY" />
        <!--Required  显示通知栏 -->
        <category android:name="${applicationId}" />
    </intent-filter>
    <intent-filter>
        <action android:name="android.intent.action.USER_PRESENT" />
        <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
    </intent-filter>
    <!-- Optional -->
    <intent-filter>
        <action android:name="android.intent.action.PACKAGE_ADDED" />
        <action android:name="android.intent.action.PACKAGE_REMOVED" />

        <data android:scheme="package" />
    </intent-filter>
</receiver>
   ...
</application>
...

android/build.gradle 文件的 buildscriptallprojects 下的 repositories 都要开启 jcenter(), 因为我们配置的是自动部署模式

开启极光第三方配置

image.png

开启后,就会在小米后台发现有一个连接已经建立

image.png

这时候我们打包运行到手机。开启日志后(debug: true),从输出上我们可以看到 xiao mi push register success

image.png 然后关闭app,推送测试。 image.png

注意,小米是会折叠不重要的通知。这个无解,只能用户手动设置成重要的通知。

然后就大功告成了!本文还未完结,接下来我还会去适配其他厂商的推送,请拭目以待。

华为适配

注册开发者

这里默认你已经注册了华为开发者,并且创建了应用。
把在华为开发者注册应用后,获得agconnect-services.json文件放置到/Android/app/目录下

集成sdk

# android/app/build.gradle
dependencies {
    ...

    //华为推送证书添加

    implementation 'cn.jiguang.sdk.plugin:huawei:3.6.8'

    implementation 'com.huawei.hms:push:4.0.2.300'
    ...

}

//华为推送证书添加

apply plugin: 'com.huawei.agconnect'

# android/build.gradle
buildscript {

    repositories {

        google()

        jcenter()

        //华为推送证书添加

        maven {url 'http://developer.huawei.com/repo/'}

    }

    dependencies {

        classpath 'com.android.tools.build:gradle:3.5.0'

        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"

        //华为推送证书添加

        classpath 'com.huawei.agconnect:agcp:1.2.1.301'

    }

}

allprojects {

    repositories {

        google()

        jcenter()

        //华为推送证书添加

        maven {url 'http://developer.huawei.com/repo/'}

    }

}

证书绑定

这里把你应用的证书*.jks 绑定到应用上,已经绑定请忽略

# android/app/build.gradle
signingConfigs {

    release {

        storeFile file("key/key.jks")//签名文件的path

        storePassword "123456"

        keyAlias "key"

        keyPassword "123456"

    }

}

获取证书的 sha256 绑定到华为后台

keytool -list -v -keystore xxx.jks

填写极光的对应厂商 app key 和秘钥,就大功告成了

OPPO

到这里就简单了,因为最麻烦的小米和华为都搞定了,下面跟着做就行了。

这里默认 jcenter 自动集成
上面我们已经添加过了 center

buildscript {
    repositories {
        jcenter()
    }
        ......
}

allprojets {
    repositories {
        jcenter()
    }
}

添加 oppo 依赖

# /android/app/build.gradle
dependencies {
    compile 'cn.jiguang.sdk.plugin:oppo:4.0.5'
}

manifestPlaceholders = [
    // 设置manifest.xml中的变量
    OPPO_APPKEY : "OP-您的应用对应的OPPO的APPKEY", // OPPO平台注册的appkey
    OPPO_APPID : "OP-您的应用对应的OPPO的APPID", // OPPO平台注册的appid
    OPPO_APPSECRET: "OP-您的应用对应的OPPO的APPSECRET"//OPPO平台注册的appsecret
]

VIVO

这里仍然默认 jcenter 自动集成
上面我们已经已经已经已经添加过了 center

buildscript {
    repositories {
        jcenter()
    }
        ......
}

allprojets {
    repositories {
        jcenter()
    }
}

添加 vivo 依赖

# /android/app/build.gradle
dependencies {
    compile 'cn.jiguang.sdk.plugin:vivo:4.0.5' 
}

manifestPlaceholders = [
    // 设置manifest.xml中的变量
    VIVO_APPKEY : "您的应用对应的VIVO的APPKEY", // VIVO平台注册的appkey
    VIVO_APPID : "您的应用对应的VIVO的APPID", // VIVO平台注册的appid
]

Q&A

关于flutter冷启动后,部分机型拿不到极光参数的问题

  • MainActivity.kt中注册通知事件

  override fun configureFlutterEngine(flutterEngine: FlutterEngine) {

        super.configureFlutterEngine(flutterEngine)
        
        
        // 获取推送,发给flutter

        var extrasString: String = ""


        if (intent.extras != null) {

            // 兼容小米参数

            extrasString = intent.extras!!.get("JMessageExtra").toString()

        } else if (intent.dataString != null) {

            // 兼容华为参数

            extrasString = intent.dataString!!

        }



        try {

            // 通过MethodChannel调用通知flutter开启参数

            MethodChannel(

                    flutterEngine.dartExecutor.binaryMessenger,

                    pushChannel

            ).setMethodCallHandler { _: MethodCall, result: MethodChannel.Result ->

                result.success(extrasString)

            }

        } catch (err: Exception) {

            //

        }


  }

关于flutter冷启动后,打开通知如何跳转到指定页面

  • 启动后根据MethodChannel拿到通知的参数,解析数据出后使用 Navigator.push() 跳转到指定页面