开发笔记-Android消息推送骚操作:亚马逊-SNS对接FCM和百度云推送

写在前面:

        之前使用阿里云的服务器用阿里消息推送好好的,然后因为国外业务需要使用亚马逊服务器,阿里云推送也不能用,用亚马逊的 SNS (短信消息推送服务),SNS 可以对接多家推送平台,其中 Android 的有 FCM 和百度云两家。FCM 是谷歌亲儿子但是没梯子进不来,百度国内可以用但是国外又出不去。出于这个原因两个推送都接入了。如果说单独接入百度推送或者FCM都是简单的事情。主要是接入亚马逊的SNS文档全是英文不说还描述不清楚,网上搜索到的资料又零零散散,所以将这次接入流程记录下来。

一、单渠道接入

        百度云推送官方文档 百度云推送需要先创建应用这些资料都是比较好找的不做赘述。创建成功后主要提供这些参数给到亚马逊。客户端密钥就是对应的SECRET KEY

 FCM官方文档 流程很清晰,感觉比百度的接入更加方便,不需要配置.so库啥的。创建应用啥的,创建完需要提供API密钥。其实就是图下的云消息传递中的服务器密钥。

 

 二、接入SNS

        到这里认为您的推送集成成功,在百度云/FCM自己的控制台测试推送没问题的前提下。准备将我们的设备与SNS连接起来。最主要的就是创建端点,然后将端点信息交给服务器。Android端需要引入SNS相关的包(当前最新版本)

    implementation 'com.amazonaws:aws-android-sdk-sns:2.6.20'

        百度云推送创建端点需要token和UserId两个属性,这两个参数再百度云推送服务绑定成功的时候会获取到。在官方代码里面属于拓展属性没有专门的方法添加,需要通过withAttributes()这个方法进行添加参数。FCM可以不用这个方法而是直接通过withToken()将FCM的onNewToken获取到的token传过去。同时也可以进行主题的订阅但是这里注释掉了,有需要可以放开。创建的端点信息需要交给服务器,服务器再做对应的推送。至于怎么给那就是前后端自己约定的事情了。创建端点成功后在亚马逊服务器后台就能看到了。

        

fun createBaiduEndpoint(userId:String?,token: String): String? {
    Log.e(PushMessageReceiver.TAG, "sendTokentoSNS: ")
    userId?:return null
    val access_id = "你的亚马逊access_id"
    val secret_key = "你的亚马逊secret_key"
    val appArn = "亚马逊创建的应用的ARN"
//  val topicArn= "亚马逊创建的应用的主题的ARN"
    val credentials: AWSCredentials = BasicAWSCredentials(access_id, secret_key)
    val provider: AWSCredentialsProvider = StaticCredentialsProvider(credentials)
    val snsClient = AmazonSNSClient(provider)
    
    snsClient.setRegion(Region.getRegion(Regions.EU_WEST_1))
    var endpointArn: String? = null
    endpointArn = try {
        println("Creating platform endpoint with token $token")
            //百度云推送在绑定的时候会返回的参数userId和channeId
        val mutableMapOf = mutableMapOf<String, String>()
        mutableMapOf["UserId"]=userId
        mutableMapOf["ChannelId"]=token
        val cpeReq = CreatePlatformEndpointRequest()
        .withPlatformApplicationArn(appArn)
        .withToken(token)
        .withAttributes(mutableMapOf)//百度需要FCM不用

         val cpeRes: CreatePlatformEndpointResult = snsClient
             .createPlatformEndpoint(cpeReq)
//        val subscribeRequest: SubscribeRequest = SubscribeRequest()
//            .withProtocol("application")
//            .withTopicArn(topicArn)
//            .withEndpoint(result.endpointArn)
//        snsClient.subscribe(subscribeRequest)
            return cpeRes.endpointArn
     } catch (ipe: InvalidParameterException) {
         val message: String = ipe.getErrorMessage()
         ipe.printStackTrace()
         val p: Pattern = Pattern
             .compile(
              ".*Endpoint (arn:aws:sns[^ ]+) already exists " +
                  "with the same [Tt]oken.*"
              )
         val m: Matcher = p.matcher(message)
         if (m.matches()) {
                // The platform endpoint already exists for this token, but with
                // additional custom data that
                // createEndpoint doesn't want to overwrite. Just use the
                // existing platform endpoint.
             m.group(1)
         } else {
                // Rethrow the exception, the input is actually bad.
             throw ipe
         }
     }
     return endpointArn
}

      写在后面:

        文章技术含量一点没有,主要是苦于网上没有一套完整的资料,我甚至连怎么引入依赖都百度了好久。上面的代码有些甚至于来自git上ruby端的issue通过自己的猜测写出来的。网上相对较多的还是有相关FCM(GCM)接入SNS的,我也主要借鉴于AWS SNS+Google FCM推送服务的使用这篇博客,稍稍可惜的是并没有讲如何引入依赖。但是关于百度接入SNS的简直凤毛麟角。写在这里方便自己以后回顾也希望能让别人少踩这样的坑。

猜你喜欢

转载自blog.csdn.net/qq_37841321/article/details/120078857