注册和消息处理
在此页面上,可以了解如何在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.ADMMessageHandlerJobBase
和com.amazon.device.messaging.ADMMessageHandlerBase
类中定义的下述回调方法与广播接收器进行通信:
回调方法 | 描述 |
---|---|
onRegistered |
在应用实例的注册ID准备就绪时调用。应用必须将此注册ID传输到您的服务器。这样做可让您的服务器向该应用实例发送消息。 |
onUnregistered |
在应用实例已从ADM注销时调用。 |
onRegistrationError |
在应用的ADM注册请求因任意原因(例如,没有亚马逊用户登录设备)而失败时调用。 |
onMessage |
在ADM客户端将消息传送到您的应用实例时调用。这类似于FCM中的onMessageReceived 回调,但不是传递RemoteMessage 对象,而是传递一个Intent 对象,从中提取消息内容。 |
实现com.amazon.device.messaging.ADMMessageHandlerJobBase
、com.amazon.device.messaging.ADMMessageHandlerBase
和com.amazon.device.messaging.ADMMessageReceiver
的子类时,应用必须覆盖这些回调,如以下代码示例所示:
-
检查是否已更新当前设备以支持新的ADM服务。
ADMLatestAvailable = false ; try{ Class.forName( "com.amazon.device.messaging.ADMMessageHandlerJobBase" ); ADMLatestAvailable = true ; } catch (ClassNotFoundException e) { // 处理异常。 }
-
创建您的接收器和服务实现。
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。
若想修改您的应用以正常降级,
-
请使用如下所示的代码检查ADM。
ADMAvailable = false ; try { Class.forName( "com.amazon.device.messaging.ADM" ); ADMAvailable = true ; } catch (ClassNotFoundException e) { // 处理异常。 }
-
将以下代码添加到所有需要ADM库运行时的代码中。
if (ADMAvailable) { // 在此处放置需要ADM的代码。 }
-
在AndroidManifest.xml文件中,确认应用元素指定了以下内容:
amazon:enable-feature android:name="com.amazon.device.messaging" android:required="false"
服务器端集成
请遵循以下指南,以确保服务器已设置为使用ADM。
要向单一设备发送消息,可以使用开发者控制台。有关更多详细信息,请参阅验证。
后续步骤
转到下一步: 步骤4: 验证 - 测试您的应用
Last updated: 2022年3月24日