小米推送,华为推送,个推,阿里云推送集成(服务端JAVA开发)

原博客地址:https://blog.csdn.net/wendy_loves/article/details/78596995
小米推送,华为推送,个推,阿里云推送集成(服务端JAVA开发)
公司新任务中要求集成以上四种推送方式,所以我在这里做下随堂笔记:
这里是官方的文档url:
小米:https://dev.mi.com/mipush/docs/server-sdk/introduction/
华为:http://developer.huawei.com/consumer/cn/service/hms/catalog/huaweipush.html?page=hmssdk_huaweipush_devguide_s
个推:http://docs.getui.com/server/java/template/
阿里云:https://help.aliyun.com/document_detail/48048.html?spm=5176.doc30092.6.604.ivLvNV
博主:qq - 52331395(不喜勿喷,欢迎交流,下述内容来如有误,请留言指出,雷同的应该是没有,我自己写的)

java.jar(小米、个推、阿里云官方很直接给出了maven,个推的maven我本人无法引入,所以我将官方jar打包到私有库里,无法引用的朋友也可以学我使用)

<!--MiPush-->
    <dependency>
      <groupId>com.mi</groupId>
      <artifactId>mipush-sdk-server</artifactId>
      <version>2.2.18</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/com.googlecode.json-simple/json-simple -->
    <dependency>
      <groupId>com.googlecode.json-simple</groupId>
      <artifactId>json-simple</artifactId>
      <version>1.1.1</version>
    </dependency>
    <!--MiPush-->

<!--GePush-->
<dependency>
  <groupId>com.gexin</groupId>
  <artifactId>rp-sdk-base</artifactId>
  <version>4.0.0.14</version>
</dependency>
<dependency>
  <groupId>com.gexin</groupId>
  <artifactId>rp-fastjson</artifactId>
  <version>1.0.0.0</version>
</dependency>
<dependency>
  <groupId>com.gexin</groupId>
  <artifactId>rp-sdk-http</artifactId>
  <version>4.0.1.9</version>
</dependency>
<dependency>
  <groupId>com.gexin</groupId>
  <artifactId>rp-sdk-template</artifactId>
  <version>4.0.0.8</version>
</dependency>
<dependency>
  <groupId>com.protobuf</groupId>
  <artifactId>rp-protobuf-java</artifactId>
  <version>2.5.0</version>
</dependency>
<!--GePush-->

<!--alipush-->
    <dependency>
      <groupId>com.aliyun</groupId>
      <artifactId>aliyun-java-sdk-push</artifactId>
      <version>3.5.1</version>
    </dependency>
    <dependency>
      <groupId>com.aliyun</groupId>
      <artifactId>aliyun-java-sdk-core</artifactId>
      <version>3.2.5</version>
    </dependency>
<!--alipush-->

华为 有个自己的http/https方式很便捷
华为官方给出
String HV_TOKEN_URL= “https://login.vmall.com/oauth2/token“;
String HV_API_URL= “https://api.push.hicloud.com/pushsend.do“;
代码展示

1.小米推送(我只推送Android且只应用regId发起推送,所以下面只有推送Android的代码)
1.1构建message
private Message buildMessageForAndroid(String title, String description, String messagePayload,
                                           Integer passThrough, Integer actionType, String actionUrl, Integer notifyType, String extendContent) {
        Message message;
        Message.Builder builder = new Message.Builder()
                .title(title)//标题(注意16字真言限制长度,这段画上重点考)
                .description(description)//描述(注意128限制长度,这段画上重点考,这个描述,我理解为副标题,而且在手机客户端呈现的也是标题+描述,内容不会自己显示出来,如果只是为了通知用户信息,我们可以将信息内容放在此处,显示效果比较明显。但是三个文字区域都不可空。需要补充文字方可使用)
                .payload(messagePayload)//内容(这个长度够你用了)
                .restrictedPackageName(AggregationPushContent.MI_ANDROID_PACKAGE_NAME)//APP包名
                .passThrough(passThrough)//是否透传
                .notifyType(notifyType)//设置震动,响铃等等
                .extra("extend_content", extendContent);//这里要注意下,你可以通过自定义的key传给客户端一段透传参数

        if (actionType == 1) {//动作跳转根据自己定义的方式去跳转url,if里的两组.extra是必须要放入的,这段画上重点
            builder.extra(Constants.EXTRA_PARAM_NOTIFY_EFFECT, Constants.NOTIFY_ACTIVITY)
                    .extra(Constants.EXTRA_PARAM_INTENT_URI, actionUrl);
        } else if (actionType == 2) {
            builder.extra(Constants.EXTRA_PARAM_NOTIFY_EFFECT, Constants.NOTIFY_WEB)
                    .extra(Constants.EXTRA_PARAM_WEB_URI, actionUrl);
        }
        message = builder.build();
        return message;
    }

1.2开始发送
public Result sendMessageToRegId(String messageId, String title, String description,
                                     String messagePayload, Integer passThrough, Integer actionType, String actionUrl, Integer notifyType,
                                     String extendContent, String regId) {

        Constants.useOfficial();//这里要注意,这是正式-启动方式,支持IOS跟Android,Constants.useSandbox();这是测试-启动方式,不支持Android,尽量申请正式APP,利用正式环境测试
        Sender sender = new Sender("你需要传入你所申请appsecret");
        Message message = buildMessageForAndroid(title, description, messagePayload, passThrough, actionType, actionUrl, notifyType, extendContent);
        Result result = null;
        try {
            result = sender.send(message, regId, RETRIES);
        } catch (Exception e) {
            //log
        }
        return result;
    }

1.3返回值 根据下述返回值自己定义成功与失败吧!
        /**
         * 发送消息返回的错误码,如果返回ErrorCode.Success表示发送成功,其他表示发送失败。
         */
        ErrorCode errorMessage = result.getErrorCode();
        /**
         * 如果消息发送成功,服务器返回消息的ID;如果发送失败,返回null。
         */
        String platformMessageId = result.getMessageId();

        /**
         *  如果消息发送失败,服务器返回错误原因的文字描述;如果发送成功,返回null。
         */
        String reason = result.getReason(); 

2.华为推送(我只推送Android且只应用deviceToken发起推送,所以下面只有推送Android的代码)

2.1获取应用accessToken(这个token放在redis或者数据库里保存,失效时重新获取,不要发一次,获取一次,因为频繁获取token很有可能获取失败,这也是好的开发规则,自定义失效时间要比实际失效时间减少3-5分钟,把系统耗时放在内,规避掉巧合失效的情况)
 /**
     * 获取下发通知消息的认证Token
     */
    public Map<String, String> refreshToken() {
        String accessToken;//下发通知消息的认证Token
        long tokenExpiredTime;  //accessToken的过期时间
        Map<String, String> data = Maps.newHashMap();
        try {
            String msgBody = MessageFormat.format(
                    "grant_type=client_credentials&client_secret={0}&client_id={1}",
                    URLEncoder.encode(appSecret, "UTF-8"), appId);
            String response = HttpUtil.post(tokenUrl, msgBody);
            JSONObject obj = JSONObject.parseObject(response);
            accessToken = obj.getString("access_token");
            tokenExpiredTime = obj.getLong("expires_in");

            data.put(redisKey, accessToken);
            data.put(tokenTimeKey, tokenExpiredTime + "");
        } catch (Exception e) {
            logger.error("HvPush -- >> 认证Token获取失败!原因:e = {}", ExceptionUtil.getMessage(e));
        }
        return data;
    }

2.2构建payLoad
这里发一张我的payLoad结构,官方有现成的内容,我的比较实惠

{
            "hps": {
                "msg": {
                    "action": {
                        "type": 3,
                        "param": {
                            "appPkgName": "自定义的路径"
                        },
                    },
                    "type": 1,//这里要注意,华为暂时推荐133就是通知,1是透传模式,有的小朋友用的方式1,是收不到通知消息的,可以自己多自测下,画上波浪线是重点
                    "body": {
                        "extend_content": "透传参数",
                        "title": "消息标题",
                        "content": "消息内容"
                    }
                },
                "ext": {
                    "biTag": "Trump",
                    "icon": "自定义推送消息在通知栏的图标,value为一个公网可以访问的URL"
                }
            }

2.3发起推送请求并解析返回值
String postBody;

        Map<String, Object> req = Maps.newHashMap();
        try {
            postBody = MessageFormat.format(
                    "access_token={0}&nsp_svc={1}&nsp_ts={2}&device_token_list={3}&payload={4}",
                    URLEncoder.encode(accessToken, "UTF-8"),
                    URLEncoder.encode("openpush.message.api.send", "UTF-8"),
                    URLEncoder.encode(String.valueOf(System.currentTimeMillis() / 1000), "UTF-8"),
                    URLEncoder.encode(deviceTokens.toString(), "UTF-8"),
                    URLEncoder.encode(payload.toString(), "UTF-8"));


            String postUrl = apiUrl + "?nsp_ctx=" + URLEncoder.encode("{\"ver\":\"1\", \"appId\":\"" + appId + "\"}", "UTF-8");

            String request = HttpUtil.post(postUrl, postBody);

            logger.info("HvPush ---- >> 推送结果:messageId = {}, result = {}", messageId, request);

            req = JSON.parseObject(request);

        } catch (Exception e) {
            logger.error("HvPush -- 华为推送失败!messageId = {}, 原因:e = {}", messageId, ExceptionUtil.getMessage(e));
        }

        if (req.get("code").equals("80000000") && req.get("msg").equals("success")) {
            return ResultModel.success("推送成功!");
        } else {
            return ResultModel.commonError("推送失败!");
        }

3.个推官方给的太详细了http://docs.getui.com/server/java/template/大家自己复制吧,可能出现的问题就是官方jar引用问题。
4.阿里云推送(官方SDK,哪来即用)

IClientProfile profile = DefaultProfile.getProfile("cn-hangzhou", accessKeyId, accessKeySecret);
        DefaultAcsClient client = new DefaultAcsClient(profile);
        PushRequest pushRequest = new PushRequest();
        // 推送目标
        pushRequest.setAppKey(appKey);
        pushRequest.setTarget("DEVICE"); //推送目标: DEVICE:按设备推送 ALIAS : 按别名推送 ACCOUNT:按帐号推送  TAG:按标签推送; ALL: 广播推送
        pushRequest.setTargetValue(deviceIds); //根据Target来设定,如Target=DEVICE, 则对应的值为 设备id1,设备id2. 多个值使用逗号分隔.(帐号与设备有一次最多100个的限制)
//        pushRequest.setTarget("ALL"); //推送目标: DEVICE:推送给设备; ACCOUNT:推送给指定帐号,TAG:推送给自定义标签; ALL: 推送给全部
//        pushRequest.setTargetValue("ALL"); //根据Target来设定,如Target=DEVICE, 则对应的值为 设备id1,设备id2. 多个值使用逗号分隔.(帐号与设备有一次最多100个的限制)
        pushRequest.setPushType("NOTICE"); // 消息类型 MESSAGE NOTICE
        pushRequest.setDeviceType("ALL"); // 设备类型 ANDROID iOS ALL.
        // 推送配置
        pushRequest.setTitle("ALi Push Title"); // 消息的标题
        pushRequest.setBody("Ali Push Body"); // 消息的内容
        // 推送配置: iOS
        pushRequest.setIOSBadge(5); // iOS应用图标右上角角标
        pushRequest.setIOSMusic("default"); // iOS通知声音
        pushRequest.setIOSSubtitle("iOS10 subtitle");//iOS10通知副标题的内容
        pushRequest.setIOSNotificationCategory("iOS10 Notification Category");//指定iOS10通知Category
        pushRequest.setIOSMutableContent(true);//是否允许扩展iOS通知内容
        pushRequest.setIOSApnsEnv("DEV");//iOS的通知是通过APNs中心来发送的,需要填写对应的环境信息。"DEV" : 表示开发环境 "PRODUCT" : 表示生产环境
        pushRequest.setIOSRemind(true); // 消息推送时设备不在线(既与移动推送的服务端的长连接通道不通),则这条推送会做为通知,通过苹果的APNs通道送达一次。注意:离线消息转通知仅适用于生产环境
        pushRequest.setIOSRemindBody("iOSRemindBody");//iOS消息转通知时使用的iOS通知内容,仅当iOSApnsEnv=PRODUCT && iOSRemind为true时有效
        pushRequest.setIOSExtParameters("{\"_ENV_\":\"DEV\",\"k2\":\"v2\"}"); //通知的扩展属性(注意 : 该参数要以json map的格式传入,否则会解析出错)
        // 推送配置: Android
        pushRequest.setAndroidNotifyType("NONE");//通知的提醒方式 "VIBRATE" : 震动 "SOUND" : 声音 "BOTH" : 声音和震动 NONE : 静音
        pushRequest.setAndroidNotificationBarType(1);//通知栏自定义样式0-100
        pushRequest.setAndroidNotificationBarPriority(1);//通知栏自定义样式0-100
        pushRequest.setAndroidOpenType("URL"); //点击通知后动作 "APPLICATION" : 打开应用 "ACTIVITY" : 打开AndroidActivity "URL" : 打开URL "NONE" : 无跳转
        pushRequest.setAndroidOpenUrl("http://www.aliyun.com"); //Android收到推送后打开对应的url,仅当AndroidOpenType="URL"有效
        pushRequest.setAndroidActivity("com.alibaba.push2.demo.XiaoMiPushActivity"); // 设定通知打开的activity,仅当AndroidOpenType="Activity"有效
        pushRequest.setAndroidMusic("default"); // Android通知音乐
        pushRequest.setAndroidPopupActivity("com.ali.demo.PopupActivity");//设置该参数后启动辅助弹窗功能, 此处指定通知点击后跳转的Activity(辅助弹窗的前提条件:1. 集成第三方辅助通道;2. StoreOffline参数设为true)
        pushRequest.setAndroidPopupTitle("Popup Title");
        pushRequest.setAndroidPopupBody("Popup Body");
        pushRequest.setAndroidExtParameters("{\"k1\":\"android\",\"k2\":\"v2\"}"); //设定通知的扩展属性。(注意 : 该参数要以 json map 的格式传入,否则会解析出错)
        // 推送控制
        Date pushDate = new Date(System.currentTimeMillis()) ; // 30秒之间的时间点, 也可以设置成你指定固定时间
        String pushTime = ParameterHelper.getISO8601Time(pushDate);
        pushRequest.setPushTime(pushTime); // 延后推送。可选,如果不设置表示立即推送
        String expireTime = ParameterHelper.getISO8601Time(new Date(System.currentTimeMillis() + 12 * 3600 * 1000)); // 12小时后消息失效, 不会再发送
        pushRequest.setExpireTime(expireTime);
        pushRequest.setStoreOffline(true); // 离线消息是否保存,若保存, 在推送时候,用户即使不在线,下一次上线则会收到
        PushResponse pushResponse = client.getAcsResponse(pushRequest);
        System.out.printf("RequestId: %s, MessageID: %s\n",
        pushResponse.getRequestId(), pushResponse.getMessageId());

以上四种推送,针对Android&IOS都做到了很优质的推送服务,在开发中可能要满足多样式的产品需求,去变动传输参数,例如:透传给APP客户端的订单信息,需要播报,需要跳转链接等等。其中小米设备,华为设备也有自己的强硬的推送。我个人认为服务端这边坑还是很小的,至少淹不死人,开发前别急于求成,想找文档,把最官方最全面的API都拿出来,我想都会迎刃而解,服务端需要注意的事项:
1.透传方式(通知 - 服务端直接唤醒APP客户端的通知栏;透传模式 - 服务端将配置的参数传给APP客户端,由开发者自定义)
2.动作&路径
3.设备号要正确,且APP在各个相应平台已经上线
4.透传参数要对正放入,阿里云推送中,对应的透传JSON-MAP 格式要符合客户端的需要

文章标签: 阿里云 小米 华为 推送 个推-java

猜你喜欢

转载自blog.csdn.net/yueaini10000/article/details/81331852