Amazon AWS使用Google GCM/FCM推送

简单梳理一下流程(链接可能需要Over the wall)

Google GCM的集成
国内大部分手机不支持google play服务,无法使用GCM 推送,针对的是支持Google Play 服务的移动设备
GCM过时了,迁移到FCM
在这里插入图片描述
Android FCM详情配置请参考:
在 Android 上设置 Firebase 云消息传递客户端应用

下面是简述流程:

  1. 将 Firebase 添加到您的 Android 项目
    需要登录Firebase 控制台创建项目
    Amazon AWS使用Google GCM/FCM推送_第1张图片
    2.添加项目成功以后,配置Firebase
    Amazon AWS使用Google GCM/FCM推送_第2张图片
    具体配置信息就不贴了 参考github firebase FCM: quickstart-android/messaging/
    github GCM:google-services/android/gcm/
    对于无法知道设备是否拥有兼容的 Google Play 服务,需要检查 Google Play 服务,通过GoogleApiAvailability.makeGooglePlayServicesAvailable()方法,这个方法在com.google.android.gms.common下如果用的FCM需要另导入相关API,这是我当前使用的版本
implementation 'com.google.firebase:firebase-messaging:17.3.4'//app/gradle
implementation 'com.google.android.gms:play-services-base:16.0.1' //app/gradle
classpath 'com.google.gms:google-services:4.0.1' //project gradle

若发生错误,需要注意版本问题
如果继续使用GCM,

compile "com.google.android.gms:play-services-gcm:16.0.0"

就不用再导入其他API

亚马逊服务配置
Amazon Simple Notification Service
吐槽一下,亚马逊把开发文档放在资源里面,一点都不好找
直接打开开发指南,推送概括
1.向 AWS 注册您的移动应用
参考:使用Amazon SNS向Android设备发送推送通知(日语的,用Google浏览器翻译一下)
所需要的GCM API Key 看第2步
2.Google Cloud Messaging for Android 入门
这一步有用的一点就是在 Google API 控制台网站上,创建 Google API 项目并启用 GCM 服务,获取服务器 API 密钥
Amazon AWS使用Google GCM/FCM推送_第3张图片
3.使用 Amazon SNS 移动推送
链接中的 1,2步 ,已经完成,其中令牌就是FCM返回的token,注册 ID参考第二步
要使用 Amazon SNS 将通知推送到应用程序,必须先通过调用创建平台终端节点操作,将该应用程序的设备令牌注册到 Amazon SNS。此操作以参数的形式获取平台应用程序的 Amazon 资源名称 (ARN) 以及设备令牌,并返回所创建平台终端节点的 ARN
网页中有一部分Java示例,给他补全了下,

  implementation 'com.amazonaws:aws-android-sdk-sns:2.6.10'
public class AmazonRegister {
    private String token;
    private String applicationArn = "";//Amazon 资源名称 (ARN)
    private String amazonkeyid="";//amazon keyid 
    private String serverKey="";//服务key
    private String arnStorage;
    AmazonSNSClient client;
    public AmazonRegister(String token){
     this.token = token;
    }

    public void registerWithSNS() {
            String endpointArn = retrieveEndpointArn();
//            String token = "Retrieved from the mobile operating system";
        AWSCredentials credentials = new BasicAWSCredentials(amazonkeyid,serverKey); //aws 验证
         client = new AmazonSNSClient(credentials); //provide credentials here
            boolean updateNeeded = false;
            boolean createNeeded = (null == endpointArn);
            if (createNeeded) {
                // No platform endpoint ARN is stored; need to call createEndpoint.
                endpointArn = createEndpoint();
                createNeeded = false;
            }
            System.out.println("Retrieving platform endpoint data...");
            // Look up the platform endpoint and make sure the data in it is current, even if
            // it was just created.
            try {
                GetEndpointAttributesRequest geaReq =
                        new GetEndpointAttributesRequest()
                                .withEndpointArn(endpointArn);
                GetEndpointAttributesResult geaRes =
                        client.getEndpointAttributes(geaReq);

                updateNeeded = !geaRes.getAttributes().get("Token").equals(token)
                        || !geaRes.getAttributes().get("Enabled").equalsIgnoreCase("true");

            } catch (NotFoundException nfe) {
                // We had a stored ARN, but the platform endpoint associated with it
                // disappeared. Recreate it.
                createNeeded = true;
            }
            if (createNeeded) {
                createEndpoint();
            }

            System.out.println("updateNeeded = " + updateNeeded);

            if (updateNeeded) {
                // The platform endpoint is out of sync with the current data;
                // update the token and enable it.
                System.out.println("Updating platform endpoint " + endpointArn);
                Map attribs = new HashMap();
                attribs.put("Token", token);
                attribs.put("Enabled", "true");
                SetEndpointAttributesRequest saeReq =
                        new SetEndpointAttributesRequest()
                                .withEndpointArn(endpointArn)
                                .withAttributes(attribs);
                client.setEndpointAttributes(saeReq);
            }
        }

        /**
         * @return never null
         * */
        private String createEndpoint() {
            String endpointArn = null;
            try {
                System.out.println("Creating platform endpoint with token " + token);

                CreatePlatformEndpointRequest cpeReq =
                        new CreatePlatformEndpointRequest()
                                .withPlatformApplicationArn(applicationArn)
                                .withToken(token);
                client.setRegion(Region.getRegion(Regions.US_WEST_2));

                CreatePlatformEndpointResult cpeRes = client
                        .createPlatformEndpoint(cpeReq);
                endpointArn = cpeRes.getEndpointArn();
            } catch (InvalidParameterException ipe) {
                String message = ipe.getErrorMessage();
                System.out.println("Exception message: " + message);
                Pattern p = Pattern
                        .compile(".*Endpoint (arn:aws:sns[^ ]+) already exists " +
                                "with the same token.*");
                Matcher m = 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.
                    endpointArn = m.group(1);
                } else {
                    // Rethrow the exception, the input is actually bad.
                    throw ipe;
                }
            }
            storeEndpointArn(endpointArn);
            return endpointArn;
        }

        /**
         * @return the ARN the app was registered under previously, or null if no
         *         platform endpoint ARN is stored.
         */
        private String retrieveEndpointArn() {
            // Retrieve the platform endpoint ARN from permanent storage,
            // or return null if null is stored.
            return arnStorage;
        }

        /**
         * Stores the platform endpoint ARN in permanent storage for lookup next time.
         * */
        private void storeEndpointArn(String endpointArn) {
            // Write the platform endpoint ARN to permanent storage.
            arnStorage = endpointArn;
        }
}

可以传入applicationArn ,amazonkeyid,serverKey在Amazon sns 控制台创建节点,然后
向移动设备发送直送消息

终于写完了—

资料:
snsmobilepush.zip
sns 示例(master主支上没有相关demo)
sns 源码
由于我们使用FCM获取的token(令牌)传入后台,后台向Amazon 发送令牌,Amazon SNS 使用该设备令牌来创建移动终端节点,再传递到FCM平台向设备发送通知,客户端来接收消息,就不需要接入amazon sns sdk了

相关资料:
日语环境
https://qiita.com/miyatay/items/b122ca1c019c985c78eb
https://qiita.com/papettoTV/items/f45f75ce00157f87e41a
http://kurochan-note.hatenablog.jp/entry/2014/02/14/235824
https://qiita.com/MJeeeey/items/3068f1e39ca074fa8e6e

创建平台终端节点和管理设备令牌
亚马逊SNS集成GCM的详细步骤
亚马逊AWS使用GCM推送

你可能感兴趣的:(GCM/FCM)