Android 离线推送与消息提醒(已废弃)
更新时间: 2024/11/25 10:11:32
本文已废弃,请前往实现离线推送等推送文档查看相关说明。
推送与消息提醒
Android推送
为了提高消息送达率,云信在 Android 进程保活上做了很多努力,但是在国内 Android 系统的大环境下,厂家的深度定制 ROM 对系统做了越来越严格的限制,想要在所有机型上做到永久保活是不可能实现的,并且保活也会使额外功耗增加。
因此,云信引入手机系统厂商推送,当用户清理掉应用进程、网络不稳定等导致客户端SDK无法与云信服务器保持正常连接时,将使用手机厂商系统级推送来提醒用户有消息需要接收。
手机系统级别的厂商推送(如小米、华为、VIVO、OPPO、魅族等)的优势于其拥有稳定的系统级长连接,可以做到随时接受推送。测试推送时,可以编译apk安装到支持该系统级推送的手机上,登陆成功后杀掉进程,使用其他账号对其发送消息,查看推送接收情况。
推送渠道的选择
如果NIMAndroidSDKOptions.mixPushConfig.autoSelectPushType
为 false(默认),则 SDK 直接选择服务端推荐的推送渠道
如果配置NIMAndroidSDKOptions.mixPushConfig.autoSelectPushType
为 true,则 SDK 根据实际上的 token 的获取情况确定推送渠道,此时服务端推荐的推送渠道为最高优先级。需要确定推送渠道时,先进行本地支持性判断,然后将向所有可能支持的推送厂商申请token,并在成功拿到的token中选择优先级更高的渠道。
小米推送
准备工作
-
前往小米消息推送服务注册账号并通过认证,创建应用并获取推送的AppID、AppKey、AppSecret。
-
前往云信控制台添加小米推送证书。具体配置步骤如下:
单击展开查看具体步骤
- 选择应用,进入应用详情界面。
- 在应用详情界面的右上角选择更多 > 证书管理 > Android 推送证书 > 添加证书,弹出如下对话框。
- 根据界面提示,在该对话框内配置证书类型和证书名称等信息。
其中的“证书名称”即为初始化 SDK 时需传入的推送证书信息中的 xmCertificateName
。 -
将小米推送的 SDK 导入到工程中,当前兼容的版本为
MiPush_SDK_Client_5_1_0
。
接入配置
- AndroidManifest.xml 配置
有两处需要改成开发者自己的 APP 包名,已经配置过的条目则无须添加。
xml<!--配置权限,已经配置过的条目则无须添加-->
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.VIBRATE"/>
<!--以下两处 {你的包名} 改开发者App的包名-->
<permission android:name="{你的包名}.permission.MIPUSH_RECEIVE"
android:protectionLevel="signature" />
<uses-permission android:name="{你的包名}.permission.MIPUSH_RECEIVE" />
下面这些配置直接拷贝到 AndroidManifest.xml ,不需要做任何改动。
xml<!--配置的service和receiver-->
<service
android:name="com.xiaomi.push.service.XMPushService"
android:enabled="true"
android:process=":pushservice"/>
<service
android:name="com.xiaomi.push.service.XMJobService"
android:enabled="true"
android:exported="false"
android:permission="android.permission.BIND_JOB_SERVICE"
android:process=":pushservice" />
<!--注:此service必须在3.0.1版本以后(包括3.0.1版本)加入-->
<service
android:enabled="true"
android:exported="true"
android:name="com.xiaomi.mipush.sdk.PushMessageHandler" />
<service android:enabled="true"
android:name="com.xiaomi.mipush.sdk.MessageHandleService" />
<!--注:此service必须在2.2.5版本以后(包括2.2.5版本)加入-->
<receiver
android:exported="true"
android:name="com.xiaomi.push.service.receivers.NetworkStatusReceiver" >
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
<receiver
android:exported="false"
android:process=":pushservice"
android:name="com.xiaomi.push.service.receivers.PingReceiver" >
<intent-filter>
<action android:name="com.xiaomi.push.PING_TIMER" />
</intent-filter>
</receiver>
<receiver
android:name="com.netease.nimlib.mixpush.mi.MiPushReceiver"
android:exported="true">
<intent-filter android:priority="0x7fffffff">
<action android:name="com.xiaomi.mipush.RECEIVE_MESSAGE"/>
<action android:name="com.xiaomi.mipush.MESSAGE_ARRIVED"/>
<action android:name="com.xiaomi.mipush.ERROR"/>
</intent-filter>
</receiver>
- 证书信息配置
在SDK初始化时,需要将推送相关证书信息配置到 NIMAndroidSDKOptions.mixPushConfig
中。
示例:
dart // 创建小米推送配置
// 传入从小米推送平台获取到的AppId与AppKey
// 传入云信控制台上小米推送对应的证书名
final xmPushConfig = NIMMixPushConfig(
xmAppId: '小米AppId',
xmAppKey: '小米AppKey',
xmCertificateName: '小米证书',
);
// 初始化时指定推送配置
NimCore.instance.initialize(
NIMAndroidSDKOptions(
appKey: appKey,
// 其他初始化参数
// ...
mixPushConfig: xmPushConfig,
),
);
如果构建 APP 时有使用代码混淆,需要在 proguard.cfg 中加入
java-dontwarn com.xiaomi.push.**
-keep class com.xiaomi.** {*;}
至此,小米推送接入完成,现在可以在小米设备上进行消息推送的测试。
推送兼容性
若开发者自身业务体系中,也需要接入小米推送,则需要考虑开发者自身业务体系的小米推送与云信消息的小米推送兼容 需要做好以下2点,其余配置、逻辑都不需要修改。
- 对于小米推送,为了接收推送消息,小米推送SDK 要求开发者自定义一个继承自
PushMessageReceiver
的BroadcastReceiver
,并注册到AndroidManifest.xml
。由于小米的特殊处理,同时注册多个继承自PushMessageReceiver
的BroadcastReceiver
会存在收不到消息的情况,要保证开发者自身业务体系的小米推送与云信消息的小米推送兼容,开发者需要新建广播接收器,从继承PushMessageReceiver
改为继承MiPushMessageReceiver
。MiPushMessageReceiver
为云信提供,推送消息首先被MiPushReceiver
接收,如果是开发者自身体系的推送消息,MiPushReceiver
会将消息传递给MiPushMessageReceiver
。
java/**
* 以下这些方法运行在非 UI 线程中, 与小米SDK PushMessageReceiver 方法一一对应。
* 开发者如果自身也需要接入小米推送,则应将继承 PushMessageReceiver 改为继承 MiPushMessageReceiver
*/
public class MiPushMessageReceiver extends BroadcastReceiver{
@Override
public final void onReceive(Context context, Intent intent) {
}
public void onReceivePassThroughMessage(Context context, MiPushMessage message) {
}
public void onNotificationMessageClicked(Context context, MiPushMessage message) {
}
public void onNotificationMessageArrived(Context context, MiPushMessage message) {
}
public void onReceiveRegisterResult(Context context, MiPushCommandMessage message) {
}
public void onCommandResult(Context context, MiPushCommandMessage message) {
}
}
- 在将广播接收器改为继承
MiPushMessageReceiver
之后,将该广播在AndroidManifest
中配置如下,开发者只需将广播名称MiPushMessageReceiver
替换成自身的广播名。此外,请不要为此 Receiver 配置priority
。
xml<receiver android:name="xxx.MiPushMessageReceiver">
<intent-filter>
<action android:name="com.xiaomi.mipush.RECEIVE_MESSAGE"/>
<action android:name="com.xiaomi.mipush.MESSAGE_ARRIVED"/>
<action android:name="com.xiaomi.mipush.ERROR"/>
</intent-filter>
</receiver>
华为推送
华为推送从新版 HMS 包开始采用了和小米推送相似的系统级连接方案,但是依赖于 EMUI 版本和 华为移动服务 版本,经过大量测试表明,EMUI4.1及以上并同时满足华为移动服务版本5.3.0.304
以上时比较稳定能收到推送。
准备工作
参考华为开发准备文档进行如下工作:
-
前往华为推送服务注册账号并通过认证,创建应用并获取
APP ID
、APP SECRET
。 -
前往云信控制台添加华为推送证书。具体步骤如下:
单击展开查看具体步骤
- 选择应用,进入应用详情界面。
- 在应用详情界面的右上角选择更多 > 证书管理 > Android 推送证书 > 添加证书,弹出如下对话框。
- 根据界面提示,在该对话框内配置证书类型和证书名称等信息。
其中的“证书名称”即为初始化 SDK 时需传入的推送信息中的 hwCertificateName
。
-
将
agconnect-services.json
文件拷贝到应用级根目录下,配置HMSSDK
的maven
仓库地址,并添加编译依赖。 -
将华为推送的 SDK 导入到工程中,当前兼容的版本为 `com.huawei.hms:push:6.5.0.300 。
接入配置
首先,Application#onCreate
中,主进程下进行如下操作:
javapublic class FlutterIMApplication extends Application {
...
@Override
public void onCreate() {
...
if (NIMUtil.isMainProcess(this)) {
...
// 在此处添加以下代码
com.huawei.hms.support.common.ActivityMgr.INST.init(this);
...
}
}
}
- AndroidManifest.xml 配置
xml<application
android:name=".FlutterIMApplication"
android:label="flutter_nim"
android:icon="@mipmap/ic_launcher">
<service
android:name="com.netease.nimlib.mixpush.hw.HWPushService"
android:exported="false">
<intent-filter>
<action android:name="com.huawei.push.action.MESSAGING_EVENT" />
</intent-filter>
</service>
</application>
- 证书信息配置
在SDK初始化时,需要将推送相关证书信息配置到 SDKOptions.mixPushConfig
中。
dart // 创建华为推送配置
// 传入华为推送的APP ID
// 传入云信控制台上华为推送证书名
final hwPushConfig = NIMMixPushConfig(
hwAppId: '华为AppId',
hwCertificateName: '华为证书',
);
// 初始化时指定推送配置
NimCore.instance.initialize(
NIMAndroidSDKOptions(
appKey: appKey,
// 其他初始化参数
// ...
mixPushConfig: hwPushConfig,
),
);
如果构建 APP 时有使用代码混淆,需要在 proguard.cfg
中加入排除 HMS SDK 的混淆配置:
java-ignorewarning
-keepattributes *Annotation*
-keepattributes Exceptions
-keepattributes InnerClasses
-keepattributes Signature
-keepattributes SourceFile,LineNumberTable
-keep class com.hianalytics.android.**{*;}
-keep class com.huawei.updatesdk.**{*;}
-keep class com.huawei.hms.**{*;}
如果开发者使用了AndResGuard,需要在混淆配置文件中加入AndResGuard白名单:
java"R.string.hms*",
"R.string.connect_server_fail_prompt_toast",
"R.string.getting_message_fail_prompt_toast",
"R.string.no_available_network_prompt_toast",
"R.string.third_app_*",
"R.string.upsdk_*",
"R.layout.hms*",
"R.layout.upsdk_*",
"R.drawable.upsdk*",
"R.color.upsdk*",
"R.dimen.upsdk*",
"R.style.upsdk*",
"R.string.agc*"
至此,华为推送接入完成,现在可以在满足条件的华为设备上进行消息推送测试。
推送兼容性
若开发者自身业务体系中,也需要接入华为推送,则需要考虑开发者自身业务体系的华为推送与云信消息的华为推送兼容需要做好以下2点,其余配置、逻辑都不需要修改。
- 对于华为推送,为了接收推送消息,华为 SDK 要求开发者自定义一个继承自
HmsMessageService
类的Service
,并注册到AndroidManifest.xml
。开发者需要将自身的华为推送服务,从继承HmsMessageService
改为继承HWPushMessageService
。开发者自行处理自身体系的推送消息,云信不做处理。
java/**
* 以下这些方法运行在非 UI 线程中, 与HuaWei的PHmsMessageService 方法一一对应。
* 当开发者自身也接入HuaWei推送,则应将继承 HmsMessageService 改为继承 HWPushMessageService,其他不变
*/
public class HWPushMessageService extends Service {
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
public void onNewToken(String token) {
MixPushPlatforms.getPushPlatform(PushType.HUA_WEI).onToken(token);
}
/**
* 透传消息, 需要用户自己弹出通知
*
* @param remoteMessage
*/
public void onMessageReceived(RemoteMessage remoteMessage) {
}
public void onMessageSent(String s) {
}
public void onDeletedMessages() {
}
public void onSendError(String var1, Exception var2) {
}
}
- 在将服务改为继承
HWPushMessageService
之后,将该服务在AndroidManifest
中配置如下,开发者只需将服务名称HWPushMessageService
替换成自身的服务名。
xml<service
android:name="xxx.HWPushMessageService"
android:exported="false">
<intent-filter>
<action android:name="com.netease.nimlib.mixpush.hw.action.MESSAGING_EVENT" />
</intent-filter>
</service>
VIVO推送
准备工作
-
前往vivo消息推送服务注册账号并通过认证,创建应用并获取AppID、AppKey、AppSecret。
-
前往云信控制台,添加 VIVO 推送证书。具体配置步骤如下:
单击展开查看具体步骤
- 选择应用,进入应用详情界面。
- 在应用详情界面的右上角选择更多 > 证书管理 > Android 推送证书 > 添加证书,弹出如下对话框。
- 根据界面提示,在该对话框内配置证书类型和证书名称等信息。
其中的“证书名称”即为初始化 SDK 时需传入的推送信息中的 vivoCertificateName
-
将VIVO推送的 SDK 导入到工程中,当前兼容的版本为 vivo_pushsdk_v3.0.0.4_484。
接入配置
- AndroidManifest.xml 配置
下面这些配置直接拷贝到AndroidManifest.xml。
xml<!--配置的service, activity, receiver-->
<service
android:name="com.vivo.push.sdk.service.CommandClientService"
android:exported="true"/>
<activity
android:name="com.vivo.push.sdk.LinkProxyClientActivity"
android:exported="false"
android:screenOrientation="portrait"
android:theme="@android:style/Theme.Translucent.NoTitleBar"/>
<receiver android:name="com.netease.nimlib.mixpush.vivo.VivoPushReceiver">
<intent-filter>
<!-- 接收 push 消息 -->
<action android:name="com.vivo.pushclient.action.RECEIVE"/>
</intent-filter>
</receiver>
- 证书信息配置
同样在AndroidManifest.xml中,添加配置app_id与api_key:
xml<meta-data
android:name="com.vivo.push.api_key"
android:value="{你的vivo推送app key}"/>
<meta-data
android:name="com.vivo.push.app_id"
android:value="{你的vivo推送的app id}"/>
在SDK初始化时,需要将推送相关证书信息配置到 NIMAndroidSDKOptions.mixPushConfig
中。
dart // 创建vivo推送配置
// 传入云信控制台上配置的vivo推送证书名
final vivoPushConfig = NIMMixPushConfig(
vivoCertificateName: 'vivo证书',
);
/// 初始化时指定推送配置
NimCore.instance.initialize(
NIMAndroidSDKOptions(
appKey: appKey,
/// 其他初始化参数
mixPushConfig: vivoPushConfig,
),
);
如果构建 APP 时有使用代码混淆,需要在proguard.cfg
中加入:
java-dontwarn com.vivo.push.**
-keep class com.vivo.push.**{*; }
-keep class com.vivo.vms.**{*; }
-keep class com.netease.nimlib.mixpush.vivo.VivoPush* {*;}
-keep class com.netease.nimlib.mixpush.vivo.VivoPushReceiver{*;}
至此,VIVO推送接入完成,现在可以在VIVO设备上进行消息推送的测试。
推送兼容性
- 开发者需要新建广播接收器,从继承
OpenClientPushMessageReceiver
改为继承VivoPushMessageReceiver
。VivoPushMessageReceiver
为云信提供。
java
/**
* 以下这些方法运行在非 UI 线程中, 与VIVO SDK 的 OpenClientPushMessageReceiver 方法一一对应。
* 当开发者自身也接入VIVO推送,则应将继承 OpenClientPushMessageReceiver 改为继承 VivoPushMessageReceiver,其他不变
*/
public class VivoPushMessageReceiver extends BroadcastReceiver {
@Override
public final void onReceive(Context context, Intent intent) {
}
public void onNotificationMessageClicked(Context context, UPSNotificationMessage upsNotificationMessage) {
}
public void onReceiveRegId(Context context, String s) {
}
}
- 在将广播接收器改为继承
VivoPushMessageReceiver
之后,将该广播在AndroidManifest
中配置如下,开发者只需将广播名称VivoPushMessageReceiver
替换成自身的广播名。此外,请不要为此 Receiver 配置priority
。
xml<receiver android:name="xxx.VivoPushMessageReceiver">
<intent-filter>
<action android:name="com.vivo.pushclient.action.RECEIVE" />
</intent-filter>
</receiver>
消息类型配置
VIVO的推送消息分为运营消息和系统消息,需要在推送时进行指定,否则按照运营消息处理。
该字段的配置点为消息体的NIMMessage.pushPayload
,在其中添加以vivoField
为key的Map,数据格式参照VIVO文档
- 示例
dart final vivoField = {
//消息类型 0:运营类消息,1:系统类消息
'classification': 1,
};
final message = await MessageBuilder.createTextMessage(...);
message.pushPayload = {
'vivoField': vivoField,
};
NimCore.instance.messageService.sendMessage(message: message);
OPPO推送
准备工作
-
前往OPPO PUSH平台注册账号并通过认证,创建应用并获取AppId,AppKey,AppSecret,MasterSecret。注意区分 AppSercet 与 MasterSecret 。
-
前往云信控制台添加 OPPO 推送证书,具体步骤如下。
-
参考OPPO PUSH SDK接口文档将 OPPO 推送的 SDK 导入到工程中,当前兼容的版本为
com.heytap.msp-push-3.1.0.aar
。
接入配置
首先,Application#onCreate
中,主进程下进行如下操作:
javapublic class FlutterIMApplication extends Application {
...
@Override
public void onCreate() {
...
if (NIMUtil.isMainProcess(this)) {
...
// 在此处添加以下代码
com.heytap.msp.push.HeytapPushManager.init(this, true);
...
}
}
}
- AndroidManifest.xml 配置
先声明推送权限:
xml<!-- oppo推送配置权限-->
<uses-permission android:name="com.coloros.mcs.permission.RECIEVE_MCS_MESSAGE"/>
<uses-permission android:name="com.heytap.mcs.permission.RECIEVE_MCS_MESSAGE"/>
<application
android:name=".FlutterIMApplication"
android:label="flutter_nim"
android:icon="@mipmap/ic_launcher">
<!--Oppo推送配置项 需要配置以下两项-->
<service
android:name="com.netease.nimlib.mixpush.oppo.OppoPushService"
android:permission="com.coloros.mcs.permission.SEND_MCS_MESSAGE">
<intent-filter>
<action android:name="com.coloros.mcs.action.RECEIVE_MCS_MESSAGE"/>
</intent-filter>
</service> <!--兼容Q以下版本-->
<service
android:name="com.netease.nimlib.mixpush.oppo.OppoAppPushService"
android:permission="com.heytap.mcs.permission.SEND_PUSH_MESSAGE">
<intent-filter>
<action android:name="com.heytap.mcs.action.RECEIVE_MCS_MESSAGE"/>
<action android:name="com.heytap.msp.push.RECEIVE_MCS_MESSAGE"/>
</intent-filter>
</service> <!--兼容Q版本-->
</application>
- 证书信息配置
在SDK初始化时,需要将推送相关证书信息配置到 SDKOptions.mixPushConfig
中。
dart /// 创建oppo推送配置
final oppoPushConfig = NIMMixPushConfig(
oppoAppId: 'oppoAppId',
oppoAppKey: 'oppoAppKey',
oppoAppSecret: 'oppoAppSecret',
oppoCertificateName: 'oppo证书',
);
/// 初始化时指定推送配置
NimCore.instance.initialize(
NIMAndroidSDKOptions(
appKey: appKey,
/// 其他初始化参数
mixPushConfig: oppoPushConfig,
),
);
如果构建 APP 时有使用代码混淆,需要在 proguard.cfg 中加入:
java-keep public class * extends android.app.Service
目前OPPO推送不支持透传消息。
至此,OPPO推送接入完成,现在可以在OPPO设备上进行消息推送的测试。
推送兼容性
与小米推送兼容性类似
- 开发者需要新建广播接收器,从继承
PushService
和AppPushService
改为继承OppoPushMessageService
和OppoAppPushMessageService
。OppoPushMessageService
和OppoAppPushMessageService
为云信提供。
java/**
* 以下这些方法运行在非 UI 线程中, 与Oppo的PushService 方法一一对应。
* 当开发者自身也接入Oppo推送,则应将继承 PushService 改为继承 OppoPushMessageService,其他不变
*/
public class OppoPushMessageService extends Service {
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
/**
* 普通消息
* @param context
* @param appMessage
*/
public void processMessage(Context context, AppMessage appMessage) {
}
/**
* oppo 官方目前还不支持透传消息
*
* @param context
* @param sptDataMessage
*/
public void processMessage(Context context, SptDataMessage sptDataMessage) {
}
}
java/**
* 以下这些方法运行在非 UI 线程中, 与Oppo的PushService 方法一一对应。
* 当开发者自身也接入Oppo推送,则应将继承 AppPushService 改为继承 OppoAppPushMessageService,其他不变
*/
public class OppoAppPushMessageService extends Service {
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
/**
* 普通消息
* @param context
* @param appMessage
*/
public void processMessage(Context context, AppMessage appMessage) {
}
/**
* oppo 官方目前还不支持透传消息
*
* @param context
* @param sptDataMessage
*/
public void processMessage(Context context, SptDataMessage sptDataMessage) {
}
}
- 在将服务改为继承
OppoPushMessageService
和OppoAppPushMessageService
之后,将该服务在AndroidManifest
中都按如下配置,开发者只需将服务名称OppoService
替换成自身的服务名。
xml<service android:name="xxx.OppoService"
android:permission="com.coloros.mcs.permission.SEND_MCS_MESSAGE">
<intent-filter>
<action android:name="com.coloros.mcs.action.RECEIVE_MCS_MESSAGE"/>
</intent-filter>
</service>
魅族推送
准备工作
- 前往魅族消息推送服务注册账号并通过认证,创建应用并获取AppID、AppKey、AppSecret。
获取方式:推送后台 - 选择你的应用(若无应用请新建应用) - 打开应用 - 配置管理 - 应用配置 - 渠道(若无渠道请添加多渠道) - App ID/App Key
-
前往云信控制台添加推送证书,配置步骤如下:
单击展开查看具体步骤
- 选择应用,进入应用详情界面。
- 在应用详情界面的右上角选择更多 > 证书管理 > Android 推送证书 > 添加证书,弹出如下对话框。
- 根据界面提示,在该对话框内配置证书类型和证书名称等信息。
其中的“证书名称”即为初始化 SDK 时需传入的推送信息中的 mzCertificateName
-
将魅族推送的 SDK 导入到工程中,当前兼容的版本为
com.meizu.flyme.internet:push-internal:4.1.0
。
接入配置
- AndroidManifest.xml 配置
有2处需要改成开发者自己的 APP 包名。
xml<!-- 兼容 Flyme5 以下版本,魅族内部接入 PushSDK 必填,不然无法收到消息-->
<uses-permission android:name="com.meizu.flyme.push.permission.RECEIVE"/>
<permission
android:name="{你的包名}.permission.MESSAGE"
android:protectionLevel="signature"/>
<uses-permission android:name="{你的包名}.push.permission.MESSAGE"/>
<!-- 兼容 Flyme3 配置权限-->
<uses-permission android:name="com.meizu.c2dm.permission.RECEIVE" />
<permission
android:name="{你的包名}.permission.C2D_MESSAGE"
android:protectionLevel="signature"/>
<uses-permission android:name="{你的包名}.permission.C2D_MESSAGE"/>
下面这些配置直接拷贝到AndroidManifest.xml,并替换你自己的包名。
xml<!--魅族推送配置项-->
<receiver android:name="com.netease.nimlib.mixpush.mz.MZPushReceiver">
<intent-filter android:priority="0x7fffffff">
<!-- 接收 push 消息 -->
<action android:name="com.meizu.flyme.push.intent.MESSAGE" />
<!-- 接收 register 消息 -->
<action android:name="com.meizu.flyme.push.intent.REGISTER.FEEDBACK" />
<!-- 接收 unregister 消息-->
<action android:name="com.meizu.flyme.push.intent.UNREGISTER.FEEDBACK"/>
<!-- 兼容低版本 Flyme3 推送服务配置 -->
<action android:name="com.meizu.c2dm.intent.REGISTRATION" />
<action android:name="com.meizu.c2dm.intent.RECEIVE" />
<category android:name="com.netease.nim.demo"/>
</intent-filter>
</receiver>
- 证书信息配置
在SDK初始化时,需要将推送相关证书信息配置到 SDKOptions.mixPushConfig
中。
dart /// 创建mz推送配置
final mzPushConfig = NIMMixPushConfig(
mzAppId: 'mzAppId',
mzAppKey: 'mzAppKey',
mzCertificateName: 'mz证书',
);
/// 初始化时指定推送配置
NimCore.instance.initialize(
NIMAndroidSDKOptions(
appKey: appKey,
/// 其他初始化参数
mixPushConfig: mzPushConfig,
),
);
如果构建 APP 时有使用代码混淆,需要在 proguard.cfg 中加入:
java-dontwarn com.meizu.cloud.**
-keep class com.meizu.cloud.** {*;}
至此,魅族推送接入完成,现在可以在魅族设备上进行消息推送的测试。
推送兼容性
- 开发者需要新建广播接收器,从继承
MzPushMessageReceiver
改为继承MeiZuPushReceiver
。MeiZuPushReceiver
为云信提供。
java
/**
* 以下这些方法运行在非 UI 线程中, 与魅族 SDK 的 MzPushMessageReceiver 方法一一对应。
* 当开发者自身也接入魅族推送,则应将继承 MzPushMessageReceiver 改为继承 MeiZuPushReceiver,其他不变
*/
public class MeiZuPushReceiver extends BroadcastReceiver {
@Override
public final void onReceive(Context context, Intent intent) {
}
public void onRegister(Context context, String pushId) {
}
public void onUnRegister(Context context, boolean success) {
}
public void onPushStatus(Context context, PushSwitchStatus pushSwitchStatus) {
}
public void onRegisterStatus(Context context, RegisterStatus registerStatus) {
}
public void onUnRegisterStatus(Context context, UnRegisterStatus unRegisterStatus) {
}
public void onSubTagsStatus(Context context, SubTagsStatus subTagsStatus) {
}
public void onSubAliasStatus(Context context, SubAliasStatus subAliasStatus) {
}
public void onNotificationClicked(Context context, String title, String content, String selfDefineContentString) {
}
public void onNotificationArrived(Context context, String title, String content, String selfDefineContentString) {
}
public void onNotifyMessageArrived(Context context, String message) {
}
public void onNotificationDeleted(Context context, String title, String content, String selfDefineContentString) {
}
public void onUpdateNotificationBuilder(PushNotificationBuilder pushNotificationBuilder) {
}
}
- 在将广播接收器改为继承
MeiZuPushReceiver
之后,将该广播在AndroidManifest
中配置如下,开发者只需将广播名称MeiZuPushReceiver
替换成自身的广播名。此外,请不要为此 Receiver 配置priority
。
xml<receiver android:name="xxx.MeiZuPushReceiver">
<intent-filter>
<action android:name="com.meizu.flyme.push.intent.MESSAGE" />
<action android:name="com.meizu.flyme.push.intent.REGISTER.FEEDBACK" />
<action android:name="com.meizu.flyme.push.intent.UNREGISTER.FEEDBACK" />
</intent-filter>
</receiver>
谷歌推送
谷歌推送FCM 是 GCM 的升级版,适用于海外用户,FCM 成功推送需要两个条件:
- 手机安装并成功运行谷歌移动框架
- 手机连接海外网络,不被墙掉。
需要说明的是,在某些国产手机上,虽然满足以上两个条件,FCM 推送成功了,但是仍然是没能看到推送通知栏的。如果应用面向国内用户,则不需要集成FCM。
准备工作
-
前往FCM官网注册账号并通过认证,创建应用并获取AppID、AppKey、AppSecret,添加证书指纹。
获取方法:
-
前往Firebase控制台/Console ,单击你的项目/Project ,进入项目界面。
-
单击界面左上角的项目概览右侧的,并单击项目设置,进入项目设置界面。
-
如果您的项目设置界面上显示 Cloud Messaging API (旧版)已停用,则需要先启用 Cloud Messaging。
-
单击,并单击在Google Cloud Console 中管理 API。
-
填写信息,并启用 Cloud Messaging。
-
-
单击云消息传递,显示的服务器密钥即为所需的 AppSecret。
-
-
前往云信控制台添加 FCM 推送证书,配置步骤如下:
单击展开查看具体步骤
- 选择应用,进入应用详情界面。
- 在应用详情界面的右上角选择更多 > 证书管理 > Android 推送证书 > 添加证书,弹出如下对话框。
- 根据界面提示,在该对话框内配置证书类型和证书名称等信息。
其中的“证书名称”即为初始化 SDK 时需传入的推送信息中的 fcmCertificateName
-
将 FCM 生成
google-services.json
拷贝到工程中。 -
将谷歌推送的 SDK 导入到工程中,当前兼容的版本如下:
java
implementation 'com.google.firebase:firebase-messaging:23.0.0' implementation 'com.google.firebase:firebase-analytics:20.0.0'
接入配置
- 如果使用的是
'com.google.android.gms:play-services-base:17.1.0'
,在项目的android/app/build.gradle
路径下添加如下依赖:
implementation platform('com.google.firebase:firebase-bom:28.4.2')
implementation 'com.google.firebase:firebase-messaging'
implementation 'com.google.firebase:firebase-analytics'
-
在
Application
的onCreate
中,调用FirebaseApp.initializeApp(this)
,对 Firebase SDK 做初始化。 -
配置
AndroidManifest.xml
。将下面这些配置直接拷贝到AndroidManifest.xml。
xml
<!-- fcm --> <service android:name="com.netease.nimlib.mixpush.fcm.FCMTokenService"> <intent-filter> <action android:name="com.google.firebase.INSTANCE_ID_EVENT" /> </intent-filter> </service>
-
设置收到 FCM 通知展示的图标和颜色。
xml
<!--设置收到 fcm 通知展示的图标和颜色--> <meta-data android:name="com.google.firebase.messaging.default_notification_icon" android:resource="@drawable/改成你的通知图标" /> <meta-data android:name="com.google.firebase.messaging.default_notification_color" android:resource="@color/改成你的通知字体颜色" />
-
配置证书信息。
在 IM SDK 初始化时,需要将推送相关证书信息配置到
SDKOptions.mixPushConfig
中。dart
/// 创建fcm推送配置 final fcmPushConfig = NIMMixPushConfig( fcmCertificateName: 'fcm证书', ); /// 初始化时指定推送配置 NimCore.instance.initialize( NIMAndroidSDKOptions( appKey: appKey, /// 其他初始化参数 mixPushConfig: fcmPushConfig, ), );
-
如果构建 APP 时有使用代码混淆,需要在 proguard.cfg 中加入:
java
-dontwarn com.google.** -keep class com.google.** {*;}
至此,FCM 推送接入完成,现在可以进行消息推送的测试。
自定义配置
在 NIMMessage.pushPayload
字段可配置一个key为fcmField
,值为map
消息提醒
云信 SDK 提供内置的消息提醒功能,其作用的场景与推送不同,一般对即时通讯的场景来说,主要作用在:
-
APP 处于后台,且 SDK 进程未被清理时
-
在前台与 A 聊天但收到非 A 的发来的消息时
-
在非聊天界面且非最近会话列表界面时。
以下场景一般不需要消息提醒:
-
如果用户正处于聊天界面,且收到当前会话的消息。
-
如果用户停留在最近联系人列表界面,收到消息也不应该有消息提醒(但会有未读数变更通知)。
启用消息提醒
dartclass SettingsService {
/// 配置 Android 通知栏消息提醒,iOS通过通知权限配置
///
/// <p>[enableRegularNotification] - 普通消息提醒开关
/// <p>[enableRevokeMessageNotification] - 消息撤回是否提醒
Future<NIMResult<void>> enableNotification({
required bool enableRegularNotification,
required bool enableRevokeMessageNotification,
});
}
- 示例
dart NimCore.instance.settingsService.enableNotification(
enableRegularNotification: true,
enableRevokeMessageNotification: true,
).then((result) {
print('SettingsService##enableNotification: ${result.code} ${result.errorDetails}');
});
启用后,需要依据当前页面环境动态调整是否需要消息提醒。此处,需要结合未读数相关接口进行处理:
dart// 进入聊天界面,表示来自sessionId的消息无需进行消息提醒。
NimCore.instance.messageService.setChattingAccount(
sessionId: 'sessionId',
sessionType: NIMSessionType.p2p,
);
// 进入最近联系人列表界面,表示所有消息无需进行消息提醒。
NimCore.instance.messageService.setChattingAccount(
sessionId: 'all',
sessionType: NIMSessionType.p2p,
);
// 退出聊天界面或离开最近联系人列表界面,表示所有消息都可以进行消息提醒。
NimCore.instance.messageService.setChattingAccount(
sessionId: 'none',
sessionType: NIMSessionType.p2p,
);
消息提醒配置
- API 原型
dartclass SettingsService {
/// 更新通知栏设置,仅支持Android平台
Future<NIMResult<void>> updateNotificationConfig(
NIMStatusBarNotificationConfig config);
}
- NIMStatusBarNotificationConfig 参数说明
NIMStatusBarNotificationConfig 参数 | 说明 |
---|---|
ring | 是否需要响铃提醒。 默认为 true |
notificationSound | 响铃提醒的声音资源,如果不提供,使用系统默认提示音 |
vibrate | 是否需要振动提醒。 默认为 true |
ledARGB | 呼吸灯的颜色。 建议尽量使用绿色、蓝色、红色等基本颜色,不要去用混合色 |
ledOnMs | 呼吸灯亮时的持续时间(毫秒) |
ledOffMs | 呼吸灯熄灭时的持续时间(毫秒) |
hideContent | 不显示消息详情开关。 默认为 false |
downTimeToggle | 免打扰设置开关。默认为关闭 |
downTimeBegin | 免打扰的开始时间, 格式为HH:mm(24小时制)。 |
downTimeEnd | 免打扰的结束时间, 格式为HH:mm(24小时制)。 如果结束时间小于开始时间,免打扰时间为开始时间-24:00-结束时间。 |
notificationEntranceClassName | 通知栏提醒的响应intent的activity类型。 可以为null。如果未提供,将使用包的launcher的入口intent的activity。 |
titleOnlyShowAppName | 通知栏提醒的标题是否只显示应用名。 默认是 false,当有一个会话发来消息时,显示会话名; 当有多个会话发来时,显示应用名。 修改为true,那么无论一个还是多个会话发来消息,标题均显示应用名。 应用名称请在 AndroidManifest 的 application 节点下设置 android:label |
notificationColor | 消息通知栏颜色,将应用到 NotificationCompat.Builder 的 setColor 方法。 对Android 5.0 以后机型会影响到smallIcon |
downTimeEnableNotification | 免打扰期间,是否显示通知,默认为显示 |
notificationFoldStyle | 通知栏合并方式: 全部折叠:NIMNotificationFoldStyle.ALL 全部不折叠:NIMNotificationFoldStyle.EXPAND 按会话折叠:NIMNotificationFoldStyle.CONTACT |
notificationExtraType | 点击在线通知的通知栏传递的extra类型 返回ArrayList<IMMessage>格式: NIMNotificationExtraType.MESSAGE,key为NimIntent#EXTRA_NOTIFY_CONTENT 返回String格式的JSONArray: NIMNotificationExtraType.JSON_ARR_STR,key为NimIntent#EXTRA_NOTIFY_SESSION_CONTENT |
- 示例
java// 更新消息提醒配置,以设置不响铃为例。
final config = NIMStatusBarNotificationConfig(
ring: false,
notificationExtraType: NIMNotificationExtraType.MESSAGE,
);
NimCore.instance.settingsService.updateNotificationConfig(config);
点击在线通知的通知栏传递的extra类型
点击在线通知的通知栏,会回调消息的信息,方便进行页面跳转等操作。
- 枚举体原型
dart/// 通知传递的extra类型
enum NIMNotificationExtraType {
/// 传递消息对象
message,
/// 将消息转为JsonArray的字符串格式
jsonArrStr,
}
- 配置效果
配置 | Extra的key | Extra的value格式 |
---|---|---|
message | NimIntent#EXTRA_NOTIFY_CONTENT | ArrayList |
jsonArrStr | NimIntent#EXTRA_NOTIFY_SESSION_CONTENT | String // JSONArray格式,每个JSONObject包含的key有"uuid", "sessionId", "sessionType"和"time |
多端提醒策略配置
当桌面端在线时,SDK 支持设置同账号所在的手机端是否需要产生推送与消息提醒。
该功能由 SettingsService
提供:
dartclass SettingsService {
///
/// 设置桌面端(PC/WEB)在线时,移动端是否需要推送
///
/// [enable] true 桌面端在线时移动端需推送;false 桌面端在线时移动端不需推送
Future<NIMResult<void>> enableMobilePushWhenPCOnline({
required bool enable,
});
///
/// 查询桌面端(PC/WEB)在线时,移动端推送开关状态
///
Future<NIMResult<bool>> isMobilePushEnabledWhenPCOnline();
}
示例:
dart
/// 设置
NimCore.instance.settingsService
.enableMobilePushWhenPCOnline(enable: true);
/// 查询
NimCore.instance.settingsService
.isMobilePushEnabledWhenPCOnline()
.then(
(result) {
// 处理结果
}
);
全局免打扰
关闭推送服务
当要直接关闭推送与消息提醒时,需要同时关闭推送服务与消息提醒。
关闭推送服务
使用 SettingsService
提供的 enablePushService
方法可以实现。当设置为 false 时,该客户端将接收不到来自云信体系内的推送。
dartclass SettingsService {
/// 开启或关闭消息推送;当设置为 false 时,该客户端将接收不到来自云信体系内的推送。
Future<NIMResult<void>> enablePushService(bool enable);
/// 查询当前推送服务开关
Future<NIMResult<bool>> isPushServiceEnabled();
}
调用示例:
dart/// 关闭推送服务
NimCore.instance.settingsService.enablePushService(false);
关闭消息提醒
dartclass SettingsService {
/// 配置 Android 通知栏消息提醒,iOS通过通知权限配置
///
/// <p>[enableRegularNotification] - 普通消息提醒开关
/// <p>[enableRevokeMessageNotification] - 消息撤回是否提醒
Future<NIMResult<void>> enableNotification({
required bool enableRegularNotification,
required bool enableRevokeMessageNotification,
});
}
调用示例:
dart/// 关闭推送服务
NimCore.instance.settingsService.enableNotification(
enableRegularNotification: false,
enableRevokeMessageNotification: false,
);
设置免打扰时段
推送免打扰时段
使用 SettingsService
提供的 setPushNoDisturbConfig
方法设置推送免打扰时间。
dartclass SettingsService {
/// 设置免打扰配置
Future<NIMResult<void>> setPushNoDisturbConfig(
NIMPushNoDisturbConfig config);
}
使用 SettingsService
提供的 getPushNoDisturbConfig()
方法获取推送免打扰时间。
dartclass SettingsService {
/// 获取当前免打扰设置
Future<NIMResult<NIMPushNoDisturbConfig>> getPushNoDisturbConfig();
}
消息提醒免打扰时段
通过设置 NIMPushNoDisturbConfig 的免打扰属性来设置:
NIMPushNoDisturbConfig 参数 | 说明 |
---|---|
enable | 免打扰设置开关 |
startTime | 免打扰的开始时间, 格式为HH:mm(24小时制)。 |
endTime | 免打扰的结束时间, 格式为HH:mm(24小时制)。 如果结束时间小于开始时间,免打扰时间为开始时间-24:00-结束时间。 |
示例:
dart NIMPushNoDisturbConfig config = NIMPushNoDisturbConfig(
enable: true,
startTime: '22:00',
endTime: '08:00'
);
NimCore.instance.settingsService.setPushNoDisturbConfig(config);
消息配置
是否推送与消息提醒
如果需要指定某条消息无需推送和消息提醒,可将NIMCustomMessageConfig
中的enablePush
设置为false
。更多NIMCustomMessageConfig
说明,参见消息配置选项。
设置推送文案前缀
如果需要某条消息被离线推送时附带前缀(默认为消息发送者的昵称),可将NIMCustomMessageConfig
中的enablePushNick
设置为 true。更多NIMCustomMessageConfig
说明,参见消息配置选项。
该设置仅在接收端为 iOS 客户端时生效。
推送标题设置
- 如果通过
NIMMessage.pushPayload
配置了"pushTitle":"标题内容"
,则以此显示(优先级最高)。 - 如果没有配置,则点对点消息推送标题为用户昵称,群消息推送标题为群名称。
- 如果没有设置用户昵称,则点对点消息推送标题为新消息。
通知栏文案
推送文案
需要显示详情的推送文案
可以通过NIMMessage.pushContent
属性来设置推送文案。如果不设置推送文案,将使用云信内置文案。
不显示详情的推送文案
-
调用
enablePushShowDetail
方法设置推送不展示文案详情。如果调用成功后不展示推送详情,默认的推送文案为“你收到一条新消息”。示例代码如下:
java
NimCore.instance.settingsService.enablePushShowDetail(true);
-
如需在不显示推送详情的情况下自定义推送文案(例如基于系统语言等场景),您可按如下步骤进行配置。
-
前往云信控制台,选择应用,并点击功能配置->添加推送文案添加自定义推送文案(见如下动图,可单击放大查看)。可配置最多 100 种自定义文案,每种自定义文案用一个自定义类型来标识。
该自定义推送文案需满足如下条件才能生效:
- 需要联系商务经理申请开通自定义推送文案功能后,不显示推送详情的自定义推送文案才能生效。如未开通,您可通过云信官网首页提供的联系方式咨询商务经理开通。
- 已调用
enablePushShowNoDetail
方法设置不显示推送详情。
-
将自定义类型设置为初始化配置参数
NIMAndroidSDKOptions.customPushContentType
的值,下发自定义推送文案至客户端。初始化相关说明,请参见初始化。
-
群消息强制推送
用户在发消息的时候,可以通过配置 NIMMessage.memberPushOption
属性实现群消息强制推送。即接收者屏蔽了当前会话(如免打扰),仍能够推送当前这条推送。
- 参数说明
NIMMemberPushOption 接口说明
类型 | NIMMemberPushOption 属性 | 说明 |
---|---|---|
List |
forcePushList | 强制推送的账号列表 填 null 表示强推给该会话所有成员, 不为 null 时最大上限账号为100个 |
String? | forcePushContent | 强推文案(可扩展为区别与普通推送的推送文案),长度目前限制为500 |
bool | isForcePush | 是否强制推送 针对 forcePushList 里的帐号, false 为不强推,true 为强推,默认为 true。 对于 forcePushList 中的用户,推送文案为 forcePushContent; 对于不在 forcePushList 中的用户,推送文案为 pushContent; 针对在 forcePushList 中的账号: isForcePush 为true 时,推送文案中不会包含发送者 nick,直接为 forcePushContent; isForcePush 为 false 时,推送文案中目前包含了发送者 nick(暂定),即为 fromNick:forcePushContent |
- 示例
dartvoid sendForcePushMessage() async {
NIMMessage message = (await MessageBuilder.createTextMessage(
sessionId: 'testAccount',
sessionType: NIMSessionType.team,
text: '指定推送消息',
)).data!;
final memberPushOption = NIMMemberPushOption(
isForcePush: true,
forcePushContent: message.content,
forcePushList: ['account1', 'account2']
);
NimCore.instance.messageService.sendMessage(
message: message..memberPushOption = memberPushOption
);
}
点击通知栏跳转
当收到推送与通知栏提醒后,用户点击通知栏,希望进入指定的聊天界面时,需要跳转到对应的聊天界面。
推送通知栏跳转
华为推送
发送消息前,在云信消息体的 pushPayload 中传入 key 为 hwField
的Map类型的数据,通常为 发送者的account/ 群聊id 与类型(单聊或群聊)等信息,这些信息将被透传到推送的接收方。数据的参数填写方法请参考华为开放平台:HTTPS下行消息
- 示例
dart String sessionId;
String sessionType;
final clickAction = {
'type': 1,
'intent': 'pushscheme://com.huawei.codelabpush/deeplink?sessionID=$sessionId&sessionType=$sessionType';
};
NIMMessage message = (await MessageBuilder.createTextMessage(
sessionId: 'testAccount',
sessionType: NIMSessionType.p2p,
text: 'text',
)).data!;
message.pushPayload = {
'hwField': clickAction,
};
final result = await NimCore.instance.messageService.sendMessage(message: message);
当接收方收到华为推送时,处理方式请参考华为开放平台:点击通知消息。
OPPO推送
发送消息前,在云信消息体的 pushPayload 中传入 key 为 oppoField
的Map或者JsonObject类型的数据,通常为 发送者的account/ 群聊id 与类型(单聊或群聊)等信息,这些信息将被透传到推送的接收方。数据的参数请参考OPPO开放平台:通知栏消息
dart // oppoField
final oppoField = {
'click_action_type': 1,
'click_action_activity': 'com.oppo.codelabpush.intent.action.test',
'action_parameters': '{"sessionID":"id", "sessionType":"1"}'
};
NIMMessage message = (await MessageBuilder.createTextMessage(
sessionId: 'testAccount',
sessionType: NIMSessionType.p2p,
text: 'text',
)).data!;
message.pushPayload = {
'oppoField': oppoField,
};
final result = await NimCore.instance.messageService.sendMessage(message: message);
当接收方收到OPPO推送时,处理方式请参考OPPO开放平台:通知栏消息。
谷歌推送
点击谷歌推送通知栏之后,直接启动应用入口Activity,通过Intent 携带数据,SDK 提供接口判断是否是云信侧集成的 FCM Intent。
MixPushService
提供两个接口处理 FCM payload:
java/**
* Activity是否是由点击 fcm 通知启动
*
* @param intent activity intent
* @return 判断结果
*/
boolean isFCMIntent(Intent intent);
/**
* 从 FCM 中解出 payload 字符串
*
* @param intent activity intent
* @return
*/
String parseFCMPayload(Intent intent);
即时通讯Demo中,在 WelcomeActivity.java 的 onIntent 中判断:if (NIMClient.getService(MixPushService.class).isFCMIntent(intent))
,具体代码请参考Demo。
其他推送
对于推送,发送方在构造消息对象时,需要通过NIMMessage.pushPayload
插入表示会话标识的信息(如自身的账号、群id、会话类型等),便于接收端获取到 payload 时解析出来。
消息提醒通知栏跳转
可以通过NIMStatusBarNotificationConfig.notificationEntranceClassName
参数来设置通知栏提醒的响应Intent的Activity,通过SettingsService.updateNotificationConfig(NIMStatusBarNotificationConfig config)
来更新通知栏消息提醒设置。
- 在对应 Activity 类的
onNewIntent
中判断if (intent.hasExtra(NimIntent.EXTRA_NOTIFY_CONTENT))
调用parseNotifyIntent(intent)
,具体代码请参考Demo。
[注意] 关于EXTRA_NOTIFY_CONTENT
的含义请参考EXTRA_NOTIFY_CONTENT。