首先物聯網協議mqtt協議是基於tcp/ip協議的,使用了官方的mqttclient框架
/*
*初始化mqttclient
*/
private void init() {
try {
//MQTT的鏈接設置
options = new MqttConnectOptions();
//host爲主機名,test爲clientid即鏈接MQTT的客戶端ID,通常以客戶端惟一標識符表示,MemoryPersistence設置clientid的保存形式,默認爲之內存保存
client = new MqttClient(new Ip().host, username,
new MemoryPersistence());
//設置是否清空session,這裏若是設置爲false表示服務器會保留客戶端的鏈接記錄,這裏設置爲true表示每次鏈接到服務器都以新的身份鏈接
options.setCleanSession(false);
//options.setWill(myTopic,null,2,false);
//設置鏈接的用戶名
options.setUserName(login_token);
//設置鏈接的密碼
options.setPassword(passWord.toCharArray());
// 設置超時時間 單位爲秒
options.setConnectionTimeout(10);
// 設置會話心跳時間 單位爲秒 服務器會每隔1.5*20秒的時間向客戶端發送個消息判斷客戶端是否在線,但這個方法並無重連的機制
options.setKeepAliveInterval(60);
//設置回調
client.setCallback(new MqttCallback() {
@Override
public void connectionLost(Throwable cause) {
//鏈接丟失後,通常在這裏面進行重連
System.out.println("connectionLost----------");
}
@Override
public void deliveryComplete(IMqttDeliveryToken token) {
//publish後會執行到這裏
System.out.println("deliveryComplete---------"
+ token.isComplete());
}
@Override
public void messageArrived(String topicName, MqttMessage message)
throws Exception {
byte[] message1 = message.getPayload();
// subscribe後獲得的消息會執行到這裏面
System.out.println("messageArrived----------" + message1[0] + Arrays.toString(message1));
System.out.println(message1[0] == 5);
String id = new String(subBytes(message1, 1, 16), "UTF-8");
System.out.print("mqtt收到的id" + id);
DeviceList device = getBookById(id);
System.out.print("device" + device.getName());
String name = device.getName();
String gName = device.getgName();
String type = device.getType();
System.out.print("名字爲" + name + gName);
/**
* 使用handler發送matt接收的消息,格式爲二進制數據
* */
Message msg = new Message();
msg.what = 1;
if (message1[0] == 1) {
// msg.obj = name + "設備心跳";
// handler.sendMessage(msg);
return;
}
if (message1[0] == 2) {
msg.obj = gName + "" + name + "報警";
msg.arg1 = Integer.parseInt(type);
handler.sendMessage(msg);
return;
}
if (message1[0] == 3) {
msg.obj = gName + "" + name + "上線";
handler.sendMessage(msg);
return;
}
if (message1[0] == 4) {
msg.obj = gName + "" + name + "離線";
handler.sendMessage(msg);
return;
}
if (message1[0] == 5) {
if (message1[17] == 0) {
msg.obj = gName + "" + name + "關門";
} else {
msg.obj = gName + "" + name + "開門";
}
handler.sendMessage(msg);
return;
}
if (message1[0] == 20 && message1[17] > 0 && message1[17] < 20) {
msg.obj = name + "電池電量: " + message1[17] + "%";
handler.sendMessage(msg);
System.out.println("電池:" + name + "電池電量: " + message1[17] + "%");
return;
}
if (message1[17] > 0) {
SharedPreferences sp = getActivity().getSharedPreferences(id, getActivity().MODE_PRIVATE);
// 得到sp的編輯器
SharedPreferences.Editor ed = sp.edit();
// 以鍵值對的顯示將用戶名和密碼保存到sp中
ed.putString("battery", String.valueOf(message1[17]));
// 提交用戶名和密碼
ed.commit();
}
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
public byte[] subBytes(byte[] src, int begin, int count) {
byte[] bs = new byte[count];
System.arraycopy(src, begin, bs, 0, count);
return bs;
}
//根據id拿到屬性爲id的Book對象。
public static DeviceList getBookById(String id) {
DeviceList book = new DeviceList();
book.setId(id);//設置傳入的id值
//books.indexOf()根據id比較對象是否相等
return deviceList1.get(deviceList1.indexOf(book));
//返回關聯id的Book對象。
}
private void connect() {
new Thread(new Runnable() {
@Override
public void run() {
try {
client.connect(options);
Message msg = new Message();
msg.what = 2;
handler.sendMessage(msg);
} catch (Exception e) {
e.printStackTrace();
Message msg = new Message();
msg.what = 3;
handler.sendMessage(msg);
}
}
}).start();
}
protected boolean onKeyDown(int keyCode, KeyEvent event) {
if (client != null && keyCode == KeyEvent.KEYCODE_BACK) {
try {
client.disconnect();
} catch (Exception e) {
e.printStackTrace();
}
}
return super.getActivity().onKeyDown(keyCode, event);
}
@Override
public void onDestroy() {
super.onDestroy();
try {
scheduler.shutdown();
client.disconnect();
} catch (MqttException e) {
e.printStackTrace();
}
}
private void startReconnect() {
scheduler = Executors.newSingleThreadScheduledExecutor();
scheduler.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
if (!client.isConnected()) {
connect();
}
}
}, 0 * 1000, 10 * 1000, TimeUnit.MILLISECONDS);
}
其次使用handlermessage接收消息,並已notifacation的形式展現在通知欄頁面
handler = new Handler() { @Override public void handleMessage(Message msg) { super.handleMessage(msg); if (msg.what == 1) { NotificationManager manager = (NotificationManager) getActivity().getSystemService(Context.NOTIFICATION_SERVICE); Notification myNotify = new Notification(); myNotify.icon = R.drawable.logo; myNotify.tickerText = "新消息"; myNotify.when = System.currentTimeMillis(); //使用默認的聲音 myNotify.defaults |= Notification.DEFAULT_SOUND;//使用默認的震動 myNotify.defaults |= Notification.DEFAULT_VIBRATE;//使用默認的聲音、振動、閃光 myNotify.defaults = Notification.DEFAULT_ALL; // myNotify.flags=Notification.FLAG_AUTO_CANCEL; // myNotify.flags = Notification.FLAG_NO_CLEAR;// 不可以自動清除 RemoteViews rv = new RemoteViews(getActivity().getPackageName(), R.layout.activity_notification1); rv.setTextViewText(R.id.tv_desc, (String) msg.obj); myNotify.contentView = rv; Intent intent = new Intent(getActivity(), MainActivity.class); // intent.addCategory(Intent.CATEGORY_LAUNCHER); // intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); android.app.PendingIntent contentIntent = android.app.PendingIntent.getActivity(getActivity(), 0, intent, 0); myNotify.contentIntent = contentIntent; manager.notify(i1++, myNotify); PowerManager pm = (PowerManager) getActivity().getSystemService(Context.POWER_SERVICE); PowerManager.WakeLock wakeLock = pm.newWakeLock(PowerManager.ACQUIRE_CAUSES_WAKEUP | PowerManager.SCREEN_DIM_WAKE_LOCK, "target"); boolean screen = pm.isScreenOn(); if (!screen) {//若是滅屏 wakeLock.acquire(); wakeLock.release(); } refresh(); } else if (msg.what == 2) { System.out.println("鏈接成功"); System.out.print("鏈接成功大小" + listDatas2.size()); try { client.subscribe(myTopic, 1); client.subscribe(myTopic1, 1); } catch (MqttException e) { e.printStackTrace(); } } else if (msg.what == 3) { //Toast.makeText(MainActivity.this, "鏈接失敗,系統正在重連", Toast.LENGTH_SHORT).show(); System.out.println("鏈接失敗,系統正在重連"); } } };