开发者控制台

注册和消息处理

注册和消息处理
1. 探索 - 了解您的选项 2. 选择 - 寻找解决方案 3. 适配 - 更新您的代码 4. 验证 - 测试您的应用 5. 推送 - 提交您的应用

在此页面上,可以了解如何在Amazon Device Messaging (ADM)中注册应用并处理传入的消息。

获取注册ID

应用必须获取注册ID,然后才能接收消息。ADM中的注册ID类似于Firebase中的设备注册令牌 - 它可以唯一标识应用在特定设备上的安装。在Firebase中,可以调用FirebaseMessaging.getInstance().getToken()检索设备注册令牌。ADM具有相似的方法:getRegistrationId()

以下代码显示了如何使用com.amazon.device.messaging.ADM类中的方法执行以下操作:

  • 创建ADM上下文的实例
  • 启动此应用实例在ADM的注册
final ADM adm = new ADM(this);
if (adm.getRegistrationId() == null)
{
   // startRegister()是异步的;当注册ID可用时,
   // 将通过onRegistered()回调通知您的应用。
   adm.startRegister();
}

每次您启动应用时都应运行此代码;例如,可通过将其放入您的onCreate()方法。如果您的应用已注册,getRegistrationId()会返回此应用实例的注册ID,且不会调用startRegister()。如果这是在给定设备上首次启动应用或者以前的注册失败,此代码便会开始注册过程。

实现注册和消息处理

ADM有三个类必须扩展。请参阅下表以了解每个类的功能。也可以查看ADM API参考

描述
com.amazon.device.messaging.ADMMessageHandlerJobBase 用于处理最新Fire设备上的消息
com.amazon.device.messaging.ADMMessageHandlerBase 用于处理较旧Fire设备上的消息
com.amazon.device.messaging.ADMMessageReceiver 用于将消息转发到相应的消息处理类

清单中所声明的广播接收器会侦听意图,并在意图到达时调用应用。应用通过com.amazon.device.messaging.ADMMessageHandlerJobBasecom.amazon.device.messaging.ADMMessageHandlerBase类中定义的下述回调方法与广播接收器进行通信:

回调方法 描述
onRegistered 在应用实例的注册ID准备就绪时调用。应用必须将此注册ID传输到您的服务器。这样做可让您的服务器向该应用实例发送消息
onUnregistered 在应用实例已从ADM注销时调用。
onRegistrationError 在应用的ADM注册请求因任意原因(例如,没有亚马逊用户登录设备)而失败时调用。
onMessage 在ADM客户端将消息传送到您的应用实例时调用。这类似于FCM中的onMessageReceived回调,但不是传递RemoteMessage对象,而是传递一个Intent对象,从中提取消息内容。

实现com.amazon.device.messaging.ADMMessageHandlerJobBasecom.amazon.device.messaging.ADMMessageHandlerBasecom.amazon.device.messaging.ADMMessageReceiver的子类时,应用必须覆盖这些回调,如以下代码示例所示:

  1. 检查是否已更新当前设备以支持新的ADM服务。

     ADMLatestAvailable = false ;
     try{
         Class.forName( "com.amazon.device.messaging.ADMMessageHandlerJobBase" );
         ADMLatestAvailable = true ;
     }
     catch (ClassNotFoundException e)
     {
         // 处理异常。
     }
    
  2. 创建您的接收器和服务实现。

     public class Receiver extends ADMMessageReceiver
     {   
         public Receiver()
         {   // 这是向后兼容所需的
            super(MyADMLegacyMessageHandler.class);
            // 若可能,推荐使用基于新作业的
            if (ADMLatestAvailable) {
                registerJobServiceClass(MyADMMessageHandler.class, <JOB_ID>)
            }
         }
         // 此处不需要其他内容;广播接收器会将意图自动
         // 转发到您的服务以进行处理。
     }
    
     public class MyADMMessageHandler extends ADMMessageHandlerJobBase
     {
    
         @Override
         protected void onRegistered(final Context context, final String newRegistrationId)
         {
             // 通过在主要活动中调用startRegister()来启动注册
             // 过程。当注册ID就绪时,ADM将对您的应用
             // 调用onRegistered()。将传入的注册ID传输到您的服务器,以便
             // 服务器可以将消息发送到此应用实例。如果
             // 您的注册ID因任何原因发生轮换或更改,ADM也会调用onRegistered();
             // 如果出现这种情况,您的应用应将新的注册ID传递到您的服务器。
             // 您的服务器需要能够处理长达1536个字符的
             // 注册ID。
    
             // 在以下示例中,注册ID通过HTTP标头键/值对
             // 发送到您的服务器。
             URL url = new URL(YOUR_WEBSERVER_URL);
             HttpURLConnection con = (HttpURLConnection) url.openConnection();
             con.setDoInput(true);
             con.setUseCaches(false);
             con.setRequestMethod("POST");
             con.setRequestProperty("RegistrationId", newRegistrationId);
             con.getResponse();
         }
    
         @Override
         protected void onUnregistered(final Context context, final String registrationId)
         {
             //如果您的应用在此台设备上已注销,请通知服务器
             // 此应用实例不再是有效的消息发送目标。
         }
    
         @Override
         protected void onRegistrationError(final Context context, final String errorId)
         {
             // 注册错误应视为严重错误。因此,您的应用可
             // 正常降级,或者您可通知用户
             // 应用的这项功能不可用。
         }
    
         @Override
         protected void onMessage(final Context context, final Intent intent)
         {
             // 从附加到com.amazon.device.messaging.intent.RECEIVE意图
             // 的额外信息集中提取消息内容。
    
             // 创建字符串以访问JSON数据中的message和timeStamp字段。
             final String msgKey = getString(R.string.json_data_msg_key);
             final String timeKey = getString(R.string.json_data_time_key);
    
             // 获取将在onMessage()回调中触发的意图操作。
             final String intentAction = getString(R.string.intent_msg_action);
    
             // 获取意图中包含的额外信息。
             final Bundle extras = intent.getExtras();
    
             // 从意图中的额外信息中提取消息和时间。
             // ADM既不会保证消息能够送达,也不会保证消息能够按顺序送达。
             // 由于网络条件的变化,消息可能会被多次传送。
             // 您的应用必须能够处理重复消息的实例。
             final String msg = extras.getString(msgKey);
             final String time = extras.getString(timeKey);
         }
     }
    

public class MyADMLegacyMessageHandler extends ADMMessageHandlerBase
{

    @Override
    protected void onRegistered(final String newRegistrationId)
    {
        // 通过在主要活动中调用startRegister()来启动注册
        // 过程。当注册ID就绪时,ADM将对您的应用
        // 调用onRegistered()。将传入的注册ID传输到您的服务器,以便
        // 服务器可以将消息发送到此应用实例。如果
        // 您的注册ID因任何原因发生轮换或更改,ADM也会调用onRegistered();
        // 如果出现这种情况,您的应用应将新的注册ID传递到您的服务器。
        // 您的服务器需要能够处理长达1536个字符的
        // 注册ID。

        // 在以下示例中,注册ID通过HTTP标头键/值对
        // 发送到您的服务器。
        URL url = new URL(YOUR_WEBSERVER_URL);
        HttpURLConnection con = (HttpURLConnection) url.openConnection();
        con.setDoInput(true);
        con.setUseCaches(false);
        con.setRequestMethod("POST");
        con.setRequestProperty("RegistrationId", newRegistrationId);
        con.getResponse();
    }

    @Override
    protected void onUnregistered(final String registrationId)
    {
        // 如果您的应用在此台设备上已注销,请通知服务器
        // 此应用实例不再是有效的消息发送目标。
    }

    @Override
    protected void onRegistrationError(final String errorId)
    {
        // 注册错误应视为严重错误。因此,您的应用可
        // 正常降级,或者您可通知用户
        // 应用的这项功能不可用。
    }

    @Override
    protected void onMessage(final Intent intent)
    {
        // 从附加到com.amazon.device.messaging.intent.RECEIVE意图
        // 的额外信息集中提取消息内容。

        // 创建字符串以访问JSON数据中的message和timeStamp字段。
        final String msgKey = getString(R.string.json_data_msg_key);
        final String timeKey = getString(R.string.json_data_time_key);

        // 获取将在onMessage()回调中触发的意图操作。
        final String intentAction = getString(R.string.intent_msg_action);

        // 获取意图中包含的额外信息。
        final Bundle extras = intent.getExtras();

        // 从意图中的额外信息中提取消息和时间。
        // ADM既不会保证消息能够送达,也不会保证消息能够按顺序送达。
        // 由于网络条件的变化,消息可能会被多次传送。
        // 您的应用必须能够处理重复消息的实例。
        final String msg = extras.getString(msgKey);
        final String time = extras.getString(timeKey);
    }
}

在ADM不可用时优雅降级

在清单文件中,请声明应用在没有ADM的情况下可以运行(android:required="false")还是无法运行(android:required="true")。如果您指定android:required="false",则您的应用必须在ADM不可用的情况下优雅降级。

将应用设计为可以适应缺少ADM的情况,这样即可让您在不一定包含ADM的设备中安装并运行单一APK。

若想修改您的应用以正常降级,

  1. 请使用如下所示的代码检查ADM。

    ADMAvailable = false ;
    try
    {
        Class.forName( "com.amazon.device.messaging.ADM" );
        ADMAvailable = true ;
    }
    catch (ClassNotFoundException e)
    {
        // 处理异常。
    }
    
  2. 将以下代码添加到所有需要ADM库运行时的代码中。

    if (ADMAvailable)
    {
        // 在此处放置需要ADM的代码。
    }
    
  3. AndroidManifest.xml文件中,确认应用元素指定了以下内容:

    amazon:enable-feature android:name="com.amazon.device.messaging" android:required="false"
    

服务器端集成

请遵循以下指南,以确保服务器已设置为使用ADM。

要向单一设备发送消息,可以使用开发者控制台。有关更多详细信息,请参阅验证

后续步骤

转到下一步: 步骤4: 验证 - 测试您的应用