本文介绍了 YunBa Android SDK 的使用和故障排除。
如果未下载 Android SDK,请先阅读 Yunba Android SDK 快速入门 ,嵌入 Android SDK。确保完成了 AndroidManifest.xml 的添加权限、配置 AppKey、修改应用包名、添加 Service 和添加 Receiver 几个步骤。
进行订阅等操作之前,请先初始化 SDK,在您的 Application 子类的 OnCreate 方法中加入如下代码:
public class YunBaApplication extends Application {
public void onCreate() {
super.onCreate();
YunBaManager.start(getApplicationContext());
}
}
YunBaManager.start API 详细说明参考 Android SDK API 手册 。
订阅话题 subscribe()
Code Example
YunBaManager.subscribe(getApplicationContext(),topic,
new IMqttActionListener() {
@Override
public void onSuccess(IMqttToken asyncActionToken) {
DemoUtil.showToast( "Subscribe succeed : " + topic, getApplicationContext());
}
@Override
public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
if (exception instanceof MqttException) {
MqttException ex = (MqttException)exception;
String msg = "Subscribe failed with error code : " + ex.getReasonCode();
DemoUtil.showToast(msg, getApplicationContext());
}
}
}
);
发布消息 publish()
或 publish2()
以
publish2()
为例
JSONObject opts = new JSONObject();
JSONObject apn_json = new JSONObject();
JSONObject aps = new JSONObject();
aps.put("sound", "bingbong.aiff");
aps.put("badge", 9);
aps.put("alert", "msg from android中文");
apn_json.put("aps", aps);
opts.put("apn_json", apn_json);
YunBaManager.publish2(getApplicationContext(), topic, msg, opts,
new IMqttActionListener() {
@Override
public void onSuccess(IMqttToken asyncActionToken) {
String msgLog = "Publish2 succeed : " + topic;
DemoUtil.showToast(msgLog, getApplicationContext());
}
@Override
public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
if (exception instanceof MqttException) {
MqttException ex = (MqttException)exception;
String msg = "publish2 failed with error code : " + ex.getReasonCode();
DemoUtil.showToast(msg, getApplicationContext());
}
}
}
);
自定义 Receiver 接收 Publish 消息
在 AndroidManifest.xml 自定义 Receiver ,确保添加 <action android:name="io.yunba.android.MESSAGE_RECEIVED_ACTION" />
;在主程序中进行接收消息广播的处理。具体参考 Android SDK 快速入门 和 Android Demo 的示例。
处理接收消息广播的示例
public class MessageReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Log.i(TAG, "Action - " + intent.getAction());
if (YunBaManager.MESSAGE_RECEIVED_ACTION.equals(intent.getAction())) {
String topic = intent.getStringExtra(YunBaManager.MQTT_TOPIC);
String msg = intent.getStringExtra(YunBaManager.MQTT_MSG);
StringBuilder showMsg = new StringBuilder();
showMsg.append("[Message] ").append(YunBaManager.MQTT_TOPIC)
.append(" = ").append(topic).append(" ,")
.append(YunBaManager.MQTT_MSG).append(" = ").append(msg);
setCostomMsg(showMsg.toString());
}
}
}
publish()
和 publish2()
的区别
publish2()
的参数比 publish()
多了 opts (JSONObject) 参数,可用于封装
QoS (服务质量)、time_to_live (离线消息保留时间)、aps_json (设置 APNs 消息的通知方式) 。
如何停止接收订阅消息
调用 unsubscribe()
,传入 Topic 参数,将不再接收到该 Topic 下的消息。
设置别名、发送
先在发送方和接收方设置别名: setAlias() ;
再调用 publishToAlias()
或 publish2ToAlias()
发送消息到指定的 Alias。
同一 AppKey 下别名唯一存在;同一台设备,设置的新别名将替换旧别名。详见 频道与别名 。
可通过调用 getAlias()
获取当前用户的别名。
注: 确保自定义了 接收 Message 的Receiver ,才能接收到消息,可参考上文“自定义 Receiver 接收 Publish 消息”示例。
如何获取当前用户(Alias)订阅的频道列表
获取当前用户 (Alias) 所订阅的频道列表,可以调用 getTopicList()
,从回调函数获得。
publishToAlias()
和 publish2ToAlias()
的区别
publish2ToAlias ()
的参数比 publishToAlias ()
多了 opts(JSONObject) 参数,可用于封装
QoS (服务质量)、time_to_live(离线消息保留时间)、aps_json (设置 APNs 消息的通知方式) 。
可调用 stop()
停止接收消息,使所有的 API 都失效(包括 start API);
YunBaManager.stop(getApplicationContext());
当需要重新使用服务时,必须要调用 resume()
。
YunBaManager.resume(getApplicationContext());
如需检查推送服务是否被停止了,可调用 isStopped()
。
注:当调用了
stop()
,设备处于离线状态,只有调用resume()
才能恢复服务;当恢复服务时,在保留时间 (time_to_live) 以内的离线消息可以送达。
如果需要在接收消息时显示消息发送者的用户名 Alias,需要在发送时把 Msg 和 Alias 封装到 Message 进行发送;在接收消息广播的 onReceive()
进行解析。
注: 如果有其它平台的客户端,建议一并进行 Message 的封装。
发送消息代码示例:
JSONObject js = new JSONObject();
try {
js.put("user_name", userName);
js.put("msg", msg);
} catch (JSONException e) {
}
YunBaManager.publishToAlias(getApplicationContext(),userName, js.toString(),
new IMqttActionListener() {
public void onSuccess(IMqttToken asyncActionToken) {
}
@Override
public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
}
}
);
接收消息代码示例:
public class MessageReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (YunBaManager.MESSAGE_RECEIVED_ACTION.equals(intent.getAction())) {
String topic = intent.getStringExtra(YunBaManager.MQTT_TOPIC);
String msgJson = intent.getStringExtra(YunBaManager.MQTT_MSG);
try {
JSONObject js = new JSONObject(msgJson);
String message = js.optString("msg");
String user_name = js.optString("user_name");
showMsg.append(user_name+" said, ").append(message);
}
}
}
}
发送消息使用 publish2()
或 publish2ToAlias()
进行发送,需设置 opts(JSONObject) 封装的参数:
qos 设置为 1 或 2,保证离线消息的送达,默认为 1;设置 time_to_live,控制离线消息在云巴服务器上保留的时间(以秒为单位)。详见: 云巴的离线消息 。
Code Example
JSONObject opts=new JSONObject();
try {
opts.put("qos", 1);
opts.put("time_to_live", 2*24*3600); //保存两天
} catch (JSONException e) {
e.printStackTrace();
}
YunBaManager.publish2(getApplicationContext(), topic, msg, opts,
new IMqttActionListener() {
public void onSuccess(IMqttToken asyncActionToken) {
String msgLog = "Publish succeed : " + topic;
StringBuilder showMsg = new StringBuilder();
showMsg.append("[Demo] publish msg")
.append(" = ").append(msg).append(" to ")
.append(YunBaManager.MQTT_TOPIC).append(" = ").append(topic).append(" succeed");
setCostomMsg(showMsg.toString());
DemoUtil.showToast(msgLog, getApplicationContext());
}
@Override
public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
String msg = "[Demo] Publish topic = " + topic + " failed : " + exception.getMessage();
setCostomMsg(msg);
DemoUtil.showToast(msg, getApplicationContext());
}
}
);
使用 publish2()
或 publish2ToAlias()
进行消息发送,必须设置 opts(JSONObject) 参数封装的 apn_json 参数,该参数的作用和设置方法详见 iOS 官方文档 。
Code Example
JSONObject opts = new JSONObject();
JSONObject apn_json = new JSONObject();
JSONObject aps = new JSONObject();
aps.put("sound", "bingbong.aiff");
aps.put("badge", 9);
aps.put("alert", "msg from android中文");
apn_json.put("aps", aps);
opts.put("apn_json", apn_json);
YunBaManager.publish2(getApplicationContext(), topic, msg, opts,
new IMqttActionListener() {
@Override
public void onSuccess(IMqttToken asyncActionToken) {
String topic = DemoUtil.join(asyncActionToken.getTopics(), ", ");
String msgLog = "Publish2 succeed : " + topic;
DemoUtil.showToast(msgLog, getApplicationContext());
}
@Override
public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
if (exception instanceof MqttException) {
MqttException ex = (MqttException)exception;
String msg = "publish2 failed with error code : " + ex.getReasonCode();
DemoUtil.showToast(msg, getApplicationContext());
}
}
}
);
注: iOS 端需 注册 APNs 证书。APNs(Apple Push Notification Service) 消息的意义可参考 iOS 官方文档 。
调用 subscribePresence()
,传入监听的 Topic,将会监听 Topic 下所有用户别名的上下线状态变化。任何用户的状态变化时都会对 App 发起一个 <action android:name="io.yunba.android.PRESENCE_RECEIVED_ACTION" />
的广播,需要在 AndroidManifest 自定义 Receiver 接收该上下线广播,在主程序中进行广播的处理。
Code Example
YunBaManager.subscribePresence(getApplicationContext(), "t1",
new IMqttActionListener() {
@Override
public void onSuccess(IMqttToken mqttToken) {
DemoUtil.showToast("subscribePresence to topic succeed", getApplicationContext());
}
@Override
public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
if (exception instanceof MqttException) {
MqttException ex = (MqttException)exception;
String msg = "subscribePresence failed with error code : " + ex.getReasonCode();
DemoUtil.showToast(msg, getApplicationContext());
}
}
}
);
取消用户上下线通知的监听
调用 unsubscribePresence()
,传入取消监听的 Topic 即可。将取消监听该 Topic 下用户的状态变化,不再接收到<action android:name="io.yunba.android.PRESENCE_RECEIVED_ACTION"/>
的广播。
Code Example
YunBaManager.unsubscribePresence(getApplicationContext(), "t1",
new IMqttActionListener() {
@Override
public void onSuccess(IMqttToken mqttToken) {
String msg = "unsubscribePresence to topic succeed ";
DemoUtil.showToast(msg, getApplicationContext());
}
@Override
public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
if (exception instanceof MqttException) {
MqttException ex = (MqttException)exception;
String msg = "unsubscribePresence failed with error code : " + ex.getReasonCode();
DemoUtil.showToast(msg, getApplicationContext());
}
}
}
);
获取订阅人数
获取某 Topic下的所有用户,可调用 getAliasList()
,传入 Topic,从回调函数获得。
Code Example
YunBaManager.getAliasList(getApplicationContext(), "t1",
new IMqttActionListener() {
@Override
public void onSuccess(IMqttToken mqttToken) {
JSONObject result = mqttToken.getResult();
try {
JSONArray topics = result.getJSONArray("alias");
System.out.println(topics.toString());
} catch (JSONException e) {
}
}
@Override
public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
if (exception instanceof MqttException) {
MqttException ex = (MqttException)exception;
String msg = "getAliasList failed with error code : " + ex.getReasonCode();
DemoUtil.showToast(msg, getApplicationContext());
}
}
}
);
获取某用户的在线状态
获取某用户 Alias 的在线状态,可调用 getState()
,传入 Alias ,从回调函数获得。
Code Example
YunBaManager.getState(getApplicationContext(), "a1",
new IMqttActionListener() {
@Override
public void onSuccess(IMqttToken mqttToken) {
JSONObject result = mqttToken.getResult();
try {
String status = result.getString("status");
System.out.println("status = " + status);
} catch (JSONException e) {
}
}
@Override
public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
if (exception instanceof MqttException) {
MqttException ex = (MqttException)exception;
String msg = "getState failed with error code : " + ex.getReasonCode();
DemoUtil.showToast(msg, getApplicationContext());
}
}
}
);