描述:最近在弄iot设备,碰到一个需求,app是c端,硬件设备嵌入式程序是d端,服务器负责通信,然后c端发送配网指令,d端收到指令,进入配网状态,然后遥控器发送红外指令,硬件传感器收到红外指令,然后d端发送消息到c端,c端接收指令,并响应。
遇到问题:我app的c端,收不到d端发给我的指令,我一直以为是框架有问题,因为网页端日志是可以看到硬件收发指令是正常的,找了很久,发现app必须首先订阅d端,然后才能收到d端的指令,不然收不到,这非常尴尬,然后我订阅了d端的指令,再次请求,成功了。
教训:一定要弄懂mqtt的机制原理,然后再去做逻辑交互,不然你就会浪费许多时间,一头雾水,原地转圈圈。
step1:
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
android {
compileSdkVersion 28
defaultConfig {
applicationId "com.example.demoanalytic"
minSdkVersion 19
targetSdkVersion 28
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
ndk {
abiFilters 'arm64-v8a'
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation"org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
//noinspection GradleCompatible
implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
implementation 'com.google.firebase:firebase-core:16.0.9'
implementation project(':andmqtt')
implementation 'com.blankj:utilcode:1.22.0'
implementation("org.greenrobot:eventbus:3.3.1")
implementation 'com.google.code.gson:gson:2.8.0'
}
apply plugin: 'com.google.gms.google-services'
step2: D:\project\push\Infrared\mqtt\one_fice\v7\kotlin\DemoAnalytic\app\src\main\AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.demoanalytic">
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.FLASHLIGHT" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<!--ZXING END-->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CALL_PHONE" />
<!--esp touch-->
<uses-permission android:name="android.permission.GET_TASKS" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />
<!--对讲权限-->
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.RECORD_VIDEO" />
<!--检测网络状态权限-->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.BLUETOOTH" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<service android:name="com.example.demoanalytic.MQTTService" />
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
step3:
package com.example.demoanalytic
const val MQTT_SERVICE = "tcp://1.48.180"
const val MQTT_PORT = 180803
const val PLUG_TOPIC_REC = "/%s/%s/C1/"
const val SET_SWITCH = "WY+SWITCH=%s"
const val SET_IR_SMART = "WY+IR=match_start"
const val SET_IR_SMART_END = "WY+IR=match_end"
const val PLUG_TOPIC = "/%s/%s/D1/"
step4:
package com.example.demoanalytic
import android.content.Intent
import android.os.Build
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import com.blankj.utilcode.util.ServiceUtils
import kotlinx.android.synthetic.main.activity_main.*
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
class MainActivity : AppCompatActivity() {
private val productId = "zcz004"
private val equipmentId = "zcz004100629"
// https://github.com/Rairmmd/AndMqtt.git 参考网址,需要lib的自行去下载
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
EventBus.getDefault().register(this)
EventBus.getDefault().postSticky(MqttMsg(true))
if (ServiceUtils.isServiceRunning(MQTTService::class.java.name)) {
ServiceUtils.stopService(MQTTService::class.java.name)
}
val intent = Intent(this@MainActivity, MQTTService::class.java)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
this@MainActivity.startForegroundService(intent)
} else {
startService(intent)
}
btn_pub_d.setOnClickListener {
EventBus.getDefault().post(
MqttBean(
String.format(
PLUG_TOPIC,
productId,
equipmentId
), true
)
)
}
btn_open.setOnClickListener {
EventBus.getDefault().post(
MqttBean(
String.format(PLUG_TOPIC_REC, productId, equipmentId),
String.format(SET_SWITCH, "1")
)
)
}
btn_close.setOnClickListener {
EventBus.getDefault().post(
MqttBean(
String.format(PLUG_TOPIC_REC, productId, equipmentId),
String.format(SET_SWITCH, "0")
)
)
}
btn_smart_sure.setOnClickListener {
/*
* 连接肯定是正常的 我是不是没订阅d 端的数据 所以收不到呢 那么问题来了 应该怎么订阅呢
* */
EventBus.getDefault().post(
MqttBean(
String.format(
PLUG_TOPIC_REC,
productId,
equipmentId
),