老生常谈,推送接入已经不是什么难事,跟着文档走几小时就能搞定。不过我这里还是要记录一下,因为我在接入的时候还是有坑。希望这篇文章可以帮到你。

VVIO客户端

厂商推送,无非就是收到推送拉起通知。所以在最新版中,官方说明已经移除了透传部分,无需再用透传接收自行处理了,向华为小米看齐了。
数据接收需要在被拉起的Activity中使用getIntent接收 就等于你普通页面间传值。
依赖包也又jar升级为aar少了部分配置。
详细适配步骤请移步VIVO推送官方文档

这里只讲一下参数接收

在你想要点击通知后拉起的Activity配置

<activity android:name=".CustomActivity"   
    android:exported="true">
    <intent-filter>
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />
        <data
            android:host="com.vivo.push.notifysdk"
            android:path="/detail"
            android:scheme="vpushscheme" />
        </intent-filter>
</activity>

参数解析:
关于意图过滤器详解请移步这里只说服务端发送的参数Uri和客户端接收之间的对应关系
比如 <data /> 里
android:hostandroid:pathandroid:scheme
分别对应的值为:
com.vivo.push.notifysdk/detailvpushscheme

那么服务端的对应 Uri 也就是想客户端发送的数据 就应该这么写

intent://com.vivo.push.notifysdk/detail?#Intent;scheme=vpushscheme;end

OK!这样就可以拉起你的 CustomActivity 页面了。
那如果要传递参数 该怎么搞呢?
同理

intent://com.vivo.push.notifysdk/detail?customkey=param;#Intent;scheme=vpushscheme;end

其中customkey为你传参的键 param为键对应的值

对应Activity中的接收就是

getIntent().getStringExtra("customkey");

这样就可以在通知拉起 CustomActivity 页面时通过Intent接收到后台传递过来的值了。拿到值就可以做你自己想做的操作了。

关于混淆

-dontwarn com.vivo.push.** 

-keep class com.vivo.push.**{*; } 

-keep class com.vivo.vms.**{*; }

-keep class xxx.xxx.xxx.PushMessageReceiverImpl{*;}//这个是你需要透传的那个类,如果没实现透传接口 可以忽略。

VIVO服务端

服务端开发很少有人讲,因为推送服务器和app这快都是我一个搞的,所以这里顺带讲一下。
服务端一般分为SDK开发和API开发。说白了:就是服务器去请求第三方推送的接口来显示推送的点目的。
API开发和SDK开发怎么选仁者见仁智者见智。
我这里选择SDK开发,因为快。等于第三方已经帮你封装好了网络请求部分。
VIVO推送服务端文档

服务端VIVO的核心是Sender类 也就是一个网络封装类,你直接调用即可。

Sender sender = new Sender("appSecret");//注册登录开发平台网站获取到的appSecret

然后就是一个Token 我们自己推送服务器和第三方推送之间的一个登陆凭证。
按照官方的说法是本地做处理,最好4-6小时重新更新一次Token。

Result tokenResult = sender.getToken(appId, appKey);
String token = tokenResult.getAuthToken();

这里获取到的Token 需要你保存到本地。然后加个计时器或者时间戳什么的。反正触发条件是每隔4-6小时重新调用一次getToken即可。以避免Token失效。

OK!拿到Token后 就可以发送推送指令了。发送推送指令 就需要构造消息体:

Message.Builder vPushBuilder = new Message.Builder()
        .title("XXX")//标题
        .content("XXXXXX")//内容
        .notifyType(4)//响铃+震动
        .timeToLive(300)//存活时间 必填 单位/秒 这里根据你们APP的应用场景来定,我这里由于时效性,时间太久这条推送就没意义了,所以设置的5分钟。
        .skipType(3)//打开App指定页
        .classification(1)//消息类型 0运营消息 1系统消息(无限制)
        .pushMode(0)//消息类型 0正式推送 1测试推送(测试推送上限20个设备)
        .requestId(System.currentTimeMillis())//请求唯一id 标记当前 我这里用时间戳代替,请根据自己需求自行定制
        .pushMode(0);//0正式推送 1测试推送(基本没用)
        .skipContent("Intent URI")//跳转内容
        .regId("User Token")//发送推送
        .build();

这里参数只讲一下
skipContent(“Intent URI”)和regId(“User Token”)

skipConent 为 传递给App的参数 也就是 这段代码

intent://com.vivo.push.notifysdk/detail?#Intent;scheme=vpushscheme;end

regId 为 app 端调用vivo推送的sdk后获取到的一个唯一设备token。可以理解为指定某一台设备。

//app端获取 regId
String regId = PushClient.getInstance(getApplicationContext()).getRegId();

消息构造完成。
接下来就是发送,这里使用单推,也就是单独推送(指定用户),也有群发和指定别名推送,这里请查阅官方文档根据自身需求操作。

sender.setAuthToken(IMServer.vPushToken);//设置推送的必要参数authToken(调用鉴权方法获得)
//发送单推消息
Result result = sender.sendSingle(builder.regId(userTokensJson).build());
//回调 其他回调参数请查阅官方文档
result.getResult()   // 获取平台返回的 0成功,非0失败
result.getDesc()    // 获取请求的服务器信息

result.getResult() == 0 表示推送成功,如果!=0 推送失败,可以做再次推送的处理。就看自身业务需求了。

到此 VIVO推送 要说的地方就整理完毕

接下来时OPPO推送 两个差不多,接了VIVO再集成OPPO就很快了。

OPPO 客户端

OPPO推送 范围比较广,接入OPPO推送就等于同时适配
OPPO Realme 和 一加(新机型) 因为它们的ROM都是Color OS
详情官方文档

权限

<uses-permission android:name="com.coloros.mcs.permission.RECIEVE_MCS_MESSAGE" />
<uses-permission android:name="com.heytap.mcs.permission.RECIEVE_MCS_MESSAGE" />

参数接收

和VIVO同理 这里不再赘述。

关于混淆

-keep public class * extends android.app.Service //app一般都会默认混淆
-keep class com.heytap.msp.** { *;}

推送通道适配

Andoird 8.0 引入了 通知通道的概念,具体请自行搜索 [ Android8.0通知适配 ]
这里只说一下通道id 因为服务器端需要用到

NotificationChannel channel = new NotificationChannel(channelId, channelName, NotificationManager.IMPORTANCE_HIGH);

其中 channelId 就是通道id 自定义 必须创建,否则无法接收OPPO推送

OPPO服务端

OPPO服务端也是Sender 注意两个包不一样,只是名字相同。

Sender sender = new Sender("appKey", "masterSecret");

这里Sender 内部进行了封装,内部维护了一个token时效,我问了OPPO的开发人员,他们说不用处理。会自动更新。

不过消息对象是 Notification 比较符合Android开发的概念

Notification notification = new Notification();
notification.setTitle("OPush->" + contentBean.getTitle());
notification.setContent(contentBean.getContent());
notification.setOffLineTtl(300);//存活时间 必填 单位/秒 这里 5分钟
notification.setStyle(1);//默认短文本1 长文本2 大图3
notification.setClickActionType(4);//点击动作 4为打开应用内页 也就是某个Activity
notification.setOffLine(false);//不要离线消息,这个推送是实时的。3天不登录就不推送了。
notification.setClickActionActivity("包名.CustomActivity");//设置内页地址
notification.setActionParameters("{\"key\":\"" + param+ "\"}");//传递的参数 json 格式 举例:{"key","param"}

不过 OPPO推送的 参数格式 不是Intent URI了,改为了JSON字符串。这里写的时候注意转码或者用 JsonObject 自行转换。

{"key":"param","key0":"param0"}

上面说了,无需操心token问题 那么数据构造完成,就需要发送了。

这里还是举例单推。

发送一条单推:

Target target = Target.build(userToken); //创建发送对象
Result result = IMServer.oPushSender.unicastNotification(messageObj, target);

result.getMessageId()   // 获取平台返回的messageId
result.getStatusCode()    // 获取http请求状态码
result.getReturnCode().getCode()    // 获取平台返回码

其中 userToken 为oppo推送的app端sdk生成。

HeytapPushManager.register(getApplicationContext(), OPPO_APP_KEY, OPPO_APP_SECRET, new ICallBackResultService() {
    @Override
    public void onRegister(int code, String s) {
        if (code == 0) {
            Log.i("注册成功", "registerId:" + s);
        } else {
            Log.i("itl-注册失败", "code=" + code + ",msg=" + s);
        }
    }
    
    public void onUnRegister(int code){...}
    public void onGetPushStatus(final int code, int status) {...}
    public void onGetNotificationStatus(final int code, final int status){...}
    
});

其中 onRegister为 回调类 中 向oppo推送注册成功后获取的唯一设备id

至此,OV推送基本大体流程基本完成。之前的小米华为也是类似。