前言
主要介绍如何集成阿里云的消息推送服务。以及一些需要注意的要点。
以及一些相关辅助通道的概念介绍。让我们弄懂阿里云消息推送到底是个什么东西
官方说明文档:单纯的推送SDK文档。
https://help.aliyun.com/document_detail/51056.html?source=5176.11533457&userCode=w5jkvc5z
集成方法
我们如果是集成了整个阿里云的emas全部功能: 移动测试,移动热修复,崩溃分析,性能分析,远程日志,消息推送等,建议你直接下载aliyun-emas-services.json 文件,存储到项目之中,采用阿里推荐的方法进行集成。https://help.aliyun.com/document_detail/164998.html#title-7jv-hp5-z2u?source=5176.11533457&userCode=w5jkvc5z 具体文档你可以参考这个进行查询。
我这里只是单纯介绍集成推送的方案:
https://www.aliyun.com/product/cps?source=5176.11533457&userCode=w5jkvc5z
请注意,推送集成是收费的。
介绍
优势
阿里官网介绍的优势:
- 到达率高:客户试验环境实测高于竞品20-25%;
- 推送延迟低:客户试验环境实测低于竞品50%;
- 稳定性高:保障通道容量,业务高峰期保持稳定送达率;
- 基础设施强:与手淘、高德、优酷等阿里系超级APP使用相同基础设施和技术,享有相同品质;
- 隐私保护严:坚决捍卫用户隐私数据,绝不从用户数据衍生产品及报告。
限制
最低支持Android 4.1及以上系统。
Android推送服务器在国内,国外可能会存在推送延迟,一般在100~300ms,可以接入辅助使用的Google通道。
推送的消息内容不能超过1800B,就是推送Title+Body <=1800B 。单位转换后就是:不能超过1.8KB。
所以我们要注意消息内容不要太长。
还有推送次数的限制。我们通常集成之后都是后台接口调用阿里提供的OpenAPI进行推消息。
该API也有调用限制。如果批量推送每次最多给1000个设备推送。
全推,也就是给所有用户推送,十分钟内只允许发送10次通知推送。30次消息推送。
下面是官网的描述,我只是按照自己的理解进行了归纳。
基本也能满足我们的推送需求了。问题不大
集成
1.配置maven
在Project根目录build.gradle 项目文件中进行配置:
allprojects {
repositories {
jcenter()
maven {
url 'http://maven.aliyun.com/nexus/content/repositories/releases/'
}
// 配置HMS Core SDK的Maven仓地址。 你如果需要华为辅助通道的话,就加上,否则可以不用加。在下面将会介绍辅助通道的意义。
maven {
url 'https://developer.huawei.com/repo/'
}
}
}
在你的module 的build.gradle 之中配置NDK
android {
......
defaultConfig {
applicationId "com.xxx.xxx" //包名 这个包名必须和你在阿里云后台配置的包名一致。
......
ndk {
//选择要添加的对应cpu类型的.so库。
abiFilters 'armeabi'
}
......
}
......
}
添加push 的maven库。
//阿里推送库
compile 'com.aliyun.ams:alicloud-android-push:3.7.0'
//辅助通道基础依赖
implementation 'com.aliyun.ams:alicloud-android-third-push:3.7.0'
//华为依赖
compile 'com.aliyun.ams:alicloud-android-third-push-huawei:3.7.0'
//小米依赖
compile 'com.aliyun.ams:alicloud-android-third-push-xiaomi:3.7.0'
//OPPO依赖
compile 'com.aliyun.ams:alicloud-android-third-push-oppo:3.7.0'
//vivo依赖
compile 'com.aliyun.ams:alicloud-android-third-push-vivo:3.7.0'
//魅族依赖
compile 'com.aliyun.ams:alicloud-android-third-push-meizu:3.7.0'
//谷歌依赖
compile 'com.aliyun.ams:alicloud-android-third-push-fcm:3.7.0'
如果你只使用阿里的渠道进行推送,那么下面的一连串的依赖都可以取消,不用依赖也能实现消息的推送送达。
2.配置AndroidManifest.xml
<application android:name="*****">
<!--推送库需要的权限-->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<meta-data android:name="com.alibaba.app.appkey" android:value="*****"/> <!-- 请填写你自己的- appKey -->
<meta-data android:name="com.alibaba.app.appsecret" android:value="****"/> <!-- 请填写你自己的appSecret -->
</application>
在你的主项目下,添加meta-data 参数,分别是appkey,和appsecret。都是在阿里云管理台上可以看到的信息。
你如果不想通过AndroidManifest 进行处理的话,也可以在代码中动态配置
效果:
// 需要代码动态配置appKey和appSecret
PushInitConfig config = new PushInitConfig.Builder()
.application(this)
.appKey("填入应用的appKey")
.appSecret("填入应用的appSecret")
.build();
PushServiceFactory.init(config);
3.配置Receiver 接收
阿里推送过来的消息是通过广播分发给我们的应用的。所以我们需要注册广播接收对象。
<!-- 消息接收监听器 (用户可自主扩展) -->
<receiver
android:name=".ZinyanMessageReceiver"
android:exported="false"> <!-- 为保证receiver安全,建议设置不可导出,如需对其他应用开放可通过android:permission进行限制 -->
<!--下面结果filter建议不要修改,保持-->
<intent-filter>
<action android:name="com.alibaba.push2.action.NOTIFICATION_OPENED" />
</intent-filter>
<intent-filter>
<action android:name="com.alibaba.push2.action.NOTIFICATION_REMOVED" />
</intent-filter>
<intent-filter>
<action android:name="com.alibaba.sdk.android.push.RECEIVE" />
</intent-filter>
</receiver>
然后我们创建ZinyanMessageReceiver 对象
import com.alibaba.sdk.android.push.MessageReceiver;
import com.alibaba.sdk.android.push.notification.CPushMessage;
public class ZinyanMessageReceiver extends MessageReceiver {
// 消息接收部分的LOG_TAG
public static final String REC_TAG = "receiver";
@Override
public void onNotification(Context context, String title, String summary, Map<String, String> extraMap) {
// TODO 处理推送通知
Log.e("MyMessageReceiver", "Receive notification, title: " + title + ", summary: " + summary + ", extraMap: " + extraMap);
}
@Override
public void onMessage(Context context, CPushMessage cPushMessage) {
// TODO 处理推送的消息
Log.e("MyMessageReceiver", "onMessage, messageId: " + cPushMessage.getMessageId() + ", title: " + cPushMessage.getTitle() + ", content:" + cPushMessage.getContent());
}
@Override
public void onNotificationOpened(Context context, String title, String summary, String extraMap) {
Log.e("MyMessageReceiver", "onNotificationOpened, title: " + title + ", summary: " + summary + ", extraMap:" + extraMap);
}
@Override
protected void onNotificationClickedWithNoAction(Context context, String title, String summary, String extraMap) {
Log.e("MyMessageReceiver", "onNotificationClickedWithNoAction, title: " + title + ", summary: " + summary + ", extraMap:" + extraMap);
}
@Override
protected void onNotificationReceivedInApp(Context context, String title, String summary, Map<String, String> extraMap, int openType, String openActivity, String openUrl) {
Log.e("MyMessageReceiver", "onNotificationReceivedInApp, title: " + title + ", summary: " + summary + ", extraMap:" + extraMap + ", openType:" + openType + ", openActivity:" + openActivity + ", openUrl:" + openUrl);
}
@Override
protected void onNotificationRemoved(Context context, String messageId) {
Log.e("MyMessageReceiver", "onNotificationRemoved");
}
}
到这里我们的环境和接受对象就全部配置完毕了。
下面我们开始初始化
4.初始化Push SDK
public class ZinyanApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
initCloudChannel(this);
}
/**
* 初始化云推送通道
*/
private void initCloudChannel(Context applicationContext) {
PushServiceFactory.init(applicationContext);
CloudPushService pushService = PushServiceFactory.getCloudPushService();
pushService.register(applicationContext, new CommonCallback() {
@Override
public void onSuccess(String response) {
Log.d(TAG, "阿里云推送 服务器初始化成功");
}
@Override
public void onFailed(String errorCode, String errorMessage) {
Log.d(TAG, "阿里云推送 服务器初始化失败: 失败代码:" + errorCode + " -- 错误消息:" + errorMessage);
}
});
}
}
调用上面的初始化就可以了。
推送成功后,我们就可以通过
PushServiceFactory.getCloudPushService().getDeviceId()
得到当前设备的DeviceId 了。
这个DeviceId 是阿里云自动生成的。并不是我们自己的账户。然后将该DeviceId给我们的后台进行记录。后面后台推送就直接调用阿里提供的OpenId 接口 传递DeviceId 进行推送了。
我们如果初始化出现了onFailed 怎么办?不用担心,阿里云提供了自动重试。在你切换网络等时机会自动触发。
阿里云推送错误代码:错误处理 (aliyun.com) 你可以通过官网查询错误信息。
5. 延迟初始化-针对隐私政策同意后
现在所有应用都会需要用户同意了隐私政策之后,才会正常往下执行。
pushSDK 也支持这个功能特效。可以调整在政策同意之后再进行推送注册。
PushServiceFactory.init(this)
必须在Application 的OnCreate中进行初始化
但是PushServiceFactory.getCloudPushService().registe()
是可以在之后进行调用的。
不一定必须在Application 的OnCreate方法中进行初始化。
6.NotificationChannel 配置
因为从Android 8.0开始,你如果不配置的话,那么推送消息能够发送到手机上,但是手机顶部状态栏上没有消息提示
public class ZinyanApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
initCloudChannel(this);
createNotificationChannel()
}
private void createNotificationChannel() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationManager mNotificationManager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
// 通知渠道的id
String id = "1";
// 用户可以看到的通知渠道的名字.
CharSequence name = "notification channel";
// 用户可以看到的通知渠道的描述
String description = "notification description";
int importance = NotificationManager.IMPORTANCE_HIGH;
NotificationChannel mChannel = new NotificationChannel(id, name, importance);
// 配置通知渠道的属性
mChannel.setDescription(description);
// 设置通知出现时的闪灯(如果 android 设备支持的话)
mChannel.enableLights(true);
mChannel.setLightColor(Color.RED);
// 设置通知出现时的震动(如果 android 设备支持的话)
mChannel.enableVibration(true);
mChannel.setVibrationPattern(new long[]{100, 200, 300, 400, 500, 400, 300, 200, 400});
//最后在notificationmanager中创建该通知渠道
mNotificationManager.createNotificationChannel(mChannel);
}
}
}
你需要记住上的id 值NotificationChannel ID值。这个值也需要发送给后台小伙伴。他们推送的时候传递该值。手机就能收到状态了。
到这里,手机端的整个集成过程就结束了。
后面就调试能否消息抵达了。
7.动态关闭推送和打开推送
我们如果使用DeviceId 进行绑定推送的话。如果app退出登陆了。不再希望给该设备进行消息推送的话。那么使用方法如下
mPushService = PushServiceFactory.getCloudPushService();
//打开推送通道
mPushService.turnOnPushChannel(new CommonCallback() {
@Override
public void onSuccess(String s) {
tvConsoleText.append("推送通到打开\n");
}
@Override
public void onFailed(String errorCode, String errorMsg) {
tvConsoleText.append("turn on push channel failed." +
"errorCode: " + errorCode + ", errorMsg:" + errorMsg + "\n");
}
});
//关闭推送通道
mPushService.turnOffPushChannel(new CommonCallback() {
@Override
public void onSuccess(String s) {
tvConsoleText.append("turn off push channel success\n");
}
@Override
public void onFailed(String errorCode, String errorMsg) {
tvConsoleText.append("turn off push channel failed." +
"errorCode: " + errorCode + ", errorMsg:" + errorMsg + "\n");
}
});
//判断推送通道是否打开
mPushService.checkPushChannelStatus(new CommonCallback() {
@Override
public void onSuccess(String response) {
if (response.equals("on")) {
// 当前是打开状态
} else {
// 当前是关闭状态
}
}
@Override
public void onFailed(String errorCode, String errorMessage) {
}
});
绑定账户进行推送
不使用DeviceId 而是使用自有账户进行注册
DeviceId 这个值通常情况下是不变的。什么意思?这个值是阿里sdk 读取手机识别码后生成的唯一码
触发app发生了卸载重装操作,否则默认情况下你跟换账户。两个账户的DeviceId 是一样的。
我们如果不想使用DeviceId ,而是想使用我们自己账户体系的用户ID作为推送设备识别对象。
注意事项:
- 设备只能绑定一个账号,同一账号可以绑定到多个设备。
- 同一设备更换绑定账号时无需进行解绑,重新调用绑定账号接口即可生效。
- 若业务场景需要先解绑后再绑定,在解绑账号成功回调中进行绑定操作,以此保证执行的顺序性。
- 账号名长度最大支持64字节。
mPushService = PushServiceFactory.getCloudPushService();
//绑定 accout 就是我们自己的账户了。
mPushService.bindAccount(account, new CommonCallback() {
@Override
public void onSuccess(String s) {
tvConsoleText.append("bind account " + account + " success\n");
}
@Override
public void onFailed(String errorCode, String errorMsg) {
tvConsoleText.append("bind account " + account + " failed." +
"errorCode: " + errorCode + ", errorMsg:" + errorMsg);
}
});
//取消绑定。如果你需要手动触发的话。那么可以调用该接口进行处理
mPushService.unbindAccount(new CommonCallback() {
@Override
public void onSuccess(String s) {
tvConsoleText.append("unbind account success\n");
}
@Override
public void onFailed(String errorCode, String errorMsg) {
tvConsoleText.append("bind account failed." +
"errorCode: " + errorCode + ", errorMsg:" + errorMsg + "\n");
}
});
辅助通道
我们都知道要想推送消息直达指定的手机,那么手机一定和远程服务器有一个长连接在维持。消息才能够通过这个连接通道发送到手机端。
而要保持长连接,那么一定要调用网络进行访问。就会造成流量和电量的消耗。同时也会有后台服务保持活动状态。
而手机厂商,为了优化。可能就会关闭这些长连接服务。
但是推送又是刚需。所以通常手机厂商会在自家的ROM中做系统级别的推送长连接管理。它收到消息后,再分发给各app处理。
其实苹果就是一个这样的模式。但是Android 由于是开放模式。所以没有统一的标准。
这就是阿里云推送的辅助通道了。
阿里推送默认是使用它自有的推送通道进行推送,如果自有推送通道关闭了,它就会切换到辅助通道进行尝试。
所以:我们如果不开辅助通道,唯一的缺陷就是,app关闭后。手机可能无法收到推送。推送不稳定而已。
阿里的辅助通道集成介绍:
你如果要开通哪个辅助通道,你就需要在厂商指定的开发者平台进行申请相关的key才行了。
-
厂商通道原生SDK集成 : 上面几种推送SDK,阿里云都有maven可以依赖导入。这个主要是针对阿里没有集成的
你需要自己导入该厂商的推送SDK。然后配置到阿里上。
错误
针对集成过程中,出现的错误,阿里云上有很丰富的常用错误解决。
[常见问题 (aliyun.com)](https://help.aliyun.com/document_detail/171711.html#Android 端)
我们碰见的大部分问题,上面都有帮助说明。如果没有,那么你可以将错误情况反馈给阿里云。
其他
阿里推送,你如果要测试厂商通道,建议让后台小伙伴配合你使用API接口进行推送。
因为如果我们使用阿里云的后台管理台进行推送的话,貌似它只会走阿里云的自身通道,而不会走厂商通道。
评论区