申请权限
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
添加依赖
compile 'org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.1.0'
compile 'org.eclipse.paho:org.eclipse.paho.android.service:1.1.1'
创建mqtt服务
package com.yf.sms.service;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;
import com.yf.sms.R;
import com.yf.sms.vo.ActivityId;
import org.eclipse.paho.android.service.MqttAndroidClient;
import org.eclipse.paho.client.mqttv3.IMqttActionListener;
import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
import org.eclipse.paho.client.mqttv3.IMqttToken;
import org.eclipse.paho.client.mqttv3.MqttCallback;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import java.util.HashMap;
import java.util.Map;
import androidx.core.app.NotificationCompat;
public class MQTTService extends Service {
public static final String TAG = MQTTService.class.getSimpleName();
private static MqttAndroidClient client;
private MqttConnectOptions conOpt;
private String host = "tcp://服务ip:1883";
private String userName = "admin";
private String passWord = "public";
String[]myTopic =null;
// private static String myTopic = "topic_ticket_user_1"; //要订阅的主题
private String clientId = "mqttid";//客户端标识
private IGetMessageCallBack IGetMessageCallBack;
@Override
public void onCreate() {
myTopic= new String[]{"topic_message_1"};
super.onCreate();
Log.e(getClass().getName(), "onCreate");
init();
}
public void publish(String msg){
String[]topic = myTopic;
Integer qos = 0;
Boolean retained = false;
try {
if (client != null){
for (String toic:topic) {
client.publish(toic, msg.getBytes(), qos.intValue(), retained.booleanValue());
}
}
} catch (MqttException e) {
e.printStackTrace();
}
}
public static void publish(String msg, String topic){
Integer qos = 0;
Boolean retained = false;
try {
if (client != null){
System.out.println("等待推送。。。");
client.publish(topic, msg.getBytes(), qos.intValue(), retained.booleanValue());
System.out.println("推送成功");
}
} catch (MqttException e) {
e.printStackTrace();
}
}
private void init() {
// 服务器地址(协议+地址+端口号)
String uri = host;
client = new MqttAndroidClient(this, uri, clientId);
// 设置MQTT监听并且接受消息
client.setCallback(mqttCallback);
conOpt = new MqttConnectOptions();
// 清除缓存
conOpt.setCleanSession(true);
// 设置超时时间,单位:秒
conOpt.setConnectionTimeout(10);
// 心跳包发送间隔,单位:秒
conOpt.setKeepAliveInterval(20);
// 用户名
conOpt.setUserName(userName);
// 密码
conOpt.setPassword(passWord.toCharArray()); //将字符串转换为字符串数组
// last will message
boolean doConnect = true;
String message = "{\"terminal_uid\":\"" + clientId + "\"}";
Log.e(getClass().getName(), "message是:" + message);
String[]topic = myTopic;
Integer qos = 0;
Boolean retained = false;
if ((!message.equals("")) || (!topic.equals(""))) {
// 最后的遗嘱
// MQTT本身就是为信号不稳定的网络设计的,所以难免一些客户端会无故的和Broker断开连接。
//当客户端连接到Broker时,可以指定LWT,Broker会定期检测客户端是否有异常。
//当客户端异常掉线时,Broker就往连接时指定的topic里推送当时指定的LWT消息。
try {
for (String topi:topic
) {
conOpt.setWill(topi, message.getBytes(), qos.intValue(), retained.booleanValue());
}
} catch (Exception e) {
Log.i(TAG, "Exception Occured", e);
doConnect = false;
iMqttActionListener.onFailure(null, e);
}
}
if (doConnect) {
doClientConnection();
}
}
@Override
public void onDestroy() {
stopSelf();
try {
client.disconnect();
} catch (MqttException e) {
e.printStackTrace();
}
super.onDestroy();
}
/** 连接MQTT服务器 */
private void doClientConnection() {
if (!client.isConnected() && isConnectIsNormal()) {
try {
client.connect(conOpt, null, iMqttActionListener);
} catch (MqttException e) {
e.printStackTrace();
}
}
}
// MQTT是否连接成功
private IMqttActionListener iMqttActionListener = new IMqttActionListener() {
@Override
public void onSuccess(IMqttToken arg0) {
Log.i(TAG, "连接成功 ");
try {
// 订阅myTopic话题
int b[]={0};
client.subscribe(myTopic,b);
} catch (MqttException e) {
e.printStackTrace();
}
}
@Override
public void onFailure(IMqttToken arg0, Throwable arg1) {
arg1.printStackTrace();
// 连接失败,重连
}
};
// MQTT监听并且接受消息
private MqttCallback mqttCallback = new MqttCallback() {
@Override
public void messageArrived(String topic, MqttMessage message) throws Exception {
String str1 = new String(message.getPayload());
// if (IGetMessageCallBack != null){
// IGetMessageCallBack.setMessage(str1);
// }
// String str2 = topic + ";qos:" + message.getQos() + ";retained:" + message.isRetained();
String str2 = topic + ";qos:" + message.getQos() + ";retained:" + new String(message.getPayload());
Map<String, String> getinfomessage=new HashMap<>();
getinfomessage.put(topic,new String(message.getPayload()));
if (IGetMessageCallBack != null){
IGetMessageCallBack.setMessage(getinfomessage);
}
// Log.i(TAG, "messageArrived:" + str1);
// Log.i(TAG, str2);
}
@Override
public void deliveryComplete(IMqttDeliveryToken arg0) {
}
@Override
public void connectionLost(Throwable arg0) {
// 失去连接,重连
}
};
/** 判断网络是否连接 */
private boolean isConnectIsNormal() {
ConnectivityManager connectivityManager = (ConnectivityManager) this.getApplicationContext()
.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo info = connectivityManager.getActiveNetworkInfo();
if (info != null && info.isAvailable()) {
String name = info.getTypeName();
Log.i(TAG, "MQTT当前网络名称:" + name);
return true;
} else {
Log.i(TAG, "MQTT 没有可用网络");
return false;
}
}
@Override
public IBinder onBind(Intent intent) {
Log.e(getClass().getName(), "onBind");
return new CustomBinder();
}
public void setIGetMessageCallBack(IGetMessageCallBack IGetMessageCallBack){
this.IGetMessageCallBack = IGetMessageCallBack;
}
public class CustomBinder extends Binder {
public MQTTService getService(){
return MQTTService.this;
}
}
public void toCreateNotification(String message){
PendingIntent pendingIntent = PendingIntent.getActivity(this, 1, new Intent(this, MQTTService.class), PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this);//3、创建一个通知,属性太多,使用构造器模式
Notification notification = builder
.setTicker("测试标题")
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle("")
.setContentText(message)
.setContentInfo("")
.setContentIntent(pendingIntent)//点击后才触发的意图,“挂起的”意图
.setAutoCancel(true) //设置点击之后notification消失
.build();
NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
startForeground(888, notification);
notificationManager.notify(1, notification);
}
}
创建回调
package com.yf.sms.service;
import java.util.Map;
public interface IGetMessageCallBack {
public void setMessage(Map<String, String> message);
}
package com.yf.sms.service;
import android.content.ComponentName;
import android.content.ServiceConnection;
import android.os.IBinder;
public class MyServiceConnection implements ServiceConnection {
private MQTTService mqttService;
private IGetMessageCallBack IGetMessageCallBack;
@Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
mqttService = ((MQTTService.CustomBinder)iBinder).getService();
mqttService.setIGetMessageCallBack(IGetMessageCallBack);
}
@Override
public void onServiceDisconnected(ComponentName componentName) {
}
public MQTTService getMqttService(){
return mqttService;
}
public void setIGetMessageCallBack(IGetMessageCallBack IGetMessageCallBack){
this.IGetMessageCallBack = IGetMessageCallBack;
}
}
注册服务
<service android:name="org.eclipse.paho.android.service.MqttService" /> <!--MqttService-->
<service android:name="com.yf.sms.service.MQTTService"/> <!--MyMqttService-->
Activity 引入接口(并创建方法)
implements IGetMessageCallBack, View.OnTouchListener, GestureDetector.OnGestureListener
服务调用
private MyServiceConnection serviceConnection;
serviceConnection = new MyServiceConnection();
serviceConnection.setIGetMessageCallBack(MainActivity.this);
Intent intent = new Intent(this, MQTTService.class);
boolean a = bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);
System.out.println(a);
public void setMessage(Map<String, String> message) {
System.out.println("得到msqkdkd");
}
存要android 端mqtt服务息屏后会断了的情况下,做了保活的功能
01.创建前台服务
//创建前台通知
private Notification createForegroundNotification(){
//前台通知的id名,任意
String channelId = "ForegroundService";
//前台通知的名称,任意
String channelName = "Service";
//发送通知的等级,此处为高,根据业务情况而定
int importance = NotificationManager.IMPORTANCE_HIGH;
//判断Android版本,不同的Android版本请求不一样,以下代码为官方写法
if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.O){
NotificationChannel channel = new NotificationChannel(channelId,channelName,importance);
channel.setLightColor(Color.BLUE);
NotificationManager notificationManager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.createNotificationChannel(channel);
}
//点击通知时可进入的Activity
Intent notificationIntent = new Intent(this, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this,0,notificationIntent,0);
//最终创建的通知,以下代码为官方写法
//注释部分是可扩展的参数,根据自己的功能需求添加
return new NotificationCompat.Builder(this,channelId)
.setContentTitle("元沣智瞳")
.setContentText("报警服务实时监听中...")
.setSmallIcon(R.drawable.ic_logo)//通知显示的图标
.setContentIntent(pendingIntent)//点击通知进入Activity
.setTicker("报警服务开启")
.build();
//.setOngoing(true)
//.setPriority(NotificationCompat.PRIORITY_MAX)
//.setCategory(Notification.CATEGORY_TRANSPORT)
//.setLargeIcon(Icon)
//.setWhen(System.currentTimeMillis())
}
02.修改 MQTTservice 中的oncreat方法
@Override
public void onCreate() {
super.onCreate();
myTopic= new String[]{"xxxx"};
acquireWakeLock();
//服务创建时创建前台通知
Notification notification = createForegroundNotification();
//启动前台服务
startForeground(1,notification);
}
03.以上方式有时候起不到作用,CPU会进入sleep状态,可以使用电源锁来辅助
@SuppressLint("InvalidWakeLockTag")
private void acquireWakeLock() {
if (null == wakeLock) {
PowerManager pm = (PowerManager) this.getSystemService(Context.POWER_SERVICE);
wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK | PowerManager.ON_AFTER_RELEASE, "MQTTService");
if (null != wakeLock) {
wakeLock.acquire();
}
}
}
//释放设备电源锁
private void releaseWakeLock() {
if (null != wakeLock) {
wakeLock.release();
wakeLock = null;
}
}
03..修改 MQTTservice 中的onDestroy方法
@Override
public void onDestroy() {
stopSelf();
releaseWakeLock();
//在服务被销毁时,关闭前台服务
stopForeground(true);
try {
client.disconnect();
} catch (MqttException e) {
e.printStackTrace();
}
super.onDestroy();
}