zmt
3 years ago
14 changed files with 1049 additions and 19 deletions
-
0uniplugin_module/.gitignore
-
4uniplugin_module/build.gradle
-
0uniplugin_module/proguard-rules.pro
-
17uniplugin_module/src/main/AndroidManifest.xml
-
455uniplugin_module/src/main/java/io/dcloud/uniplugin/MainActivity.java
-
4uniplugin_module/src/main/java/io/dcloud/uniplugin/NativePageActivity.java
-
4uniplugin_module/src/main/java/io/dcloud/uniplugin/TestModule.java
-
49uniplugin_module/src/main/java/io/dcloud/uniplugin/mqtt/MQTTRequest.java
-
403uniplugin_module/src/main/java/io/dcloud/uniplugin/mqtt/MQTTSample.java
-
84uniplugin_module/src/main/res/layout/activity_main.xml
-
0uniplugin_module/src/main/res/values/strings.xml
-
33zmt_module/src/main/java/io/dcloud/zmt_module/TcpServer.java
-
8zmt_module/src/main/java/io/dcloud/zmt_module/Zmt_AppProxy.java
-
7zmt_module/src/main/java/io/dcloud/zmt_module/zmtClass.java
@ -1,7 +1,12 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" |
|||
package="uni.dcloud.io.uniplugin_module" > |
|||
<application> |
|||
<activity android:name="io.dcloud.uniplugin.NativePageActivity" |
|||
android:theme="@android:style/Theme.DeviceDefault.Light.NoActionBar"></activity> |
|||
</application> |
|||
</manifest> |
|||
package="uni.dcloud.io.uniplugin_module"> |
|||
|
|||
<application> |
|||
<activity android:name="io.dcloud.uniplugin.MainActivity"></activity> |
|||
<activity |
|||
android:name="io.dcloud.uniplugin.NativePageActivity" |
|||
android:theme="@android:style/Theme.DeviceDefault.Light.NoActionBar" /> |
|||
</application> |
|||
|
|||
</manifest> |
@ -0,0 +1,455 @@ |
|||
package io.dcloud.uniplugin; |
|||
|
|||
|
|||
import android.app.Activity; |
|||
import android.content.Context; |
|||
import android.content.res.AssetManager; |
|||
import android.os.Bundle; |
|||
import android.os.Environment; |
|||
import android.util.Log; |
|||
import android.view.View; |
|||
import android.widget.Button; |
|||
import android.widget.TextView; |
|||
import android.widget.Toast; |
|||
|
|||
import com.tencent.iot.hub.device.android.core.util.TXLog; |
|||
import com.tencent.iot.hub.device.java.core.common.Status; |
|||
import com.tencent.iot.hub.device.java.core.log.TXMqttLogCallBack; |
|||
import com.tencent.iot.hub.device.java.core.mqtt.TXMqttActionCallBack; |
|||
|
|||
import org.eclipse.paho.client.mqttv3.IMqttToken; |
|||
import org.eclipse.paho.client.mqttv3.MqttMessage; |
|||
|
|||
import java.io.BufferedReader; |
|||
import java.io.BufferedWriter; |
|||
import java.io.File; |
|||
import java.io.FileReader; |
|||
import java.io.FileWriter; |
|||
import java.io.IOException; |
|||
import java.io.InputStreamReader; |
|||
import java.util.Arrays; |
|||
import java.util.HashMap; |
|||
import java.util.Map; |
|||
import java.util.concurrent.atomic.AtomicInteger; |
|||
|
|||
import io.dcloud.uniplugin.mqtt.MQTTRequest; |
|||
import io.dcloud.uniplugin.mqtt.MQTTSample; |
|||
import uni.dcloud.io.uniplugin_module.R; |
|||
|
|||
public class MainActivity extends Activity { |
|||
|
|||
private Context mContext; |
|||
|
|||
// Default testing parameters |
|||
private String mBrokerURL = null; //传入null,即使用腾讯云物联网通信默认地址 "${ProductId}.iotcloud.tencentdevices.com:8883" https://cloud.tencent.com/document/product/634/32546 |
|||
private String mProductID = "BE8N7UZ7OF";// |
|||
private String mDevName = "pad20220105";//BuildConfig.DEVICE_NAME; |
|||
private String mDevPSK = "7udrYcfTVThbzdMlLT9fHQ==";//BuildConfig.DEVICE_PSK; //若使用证书验证,设为null |
|||
private String mSubProductID = null;//BuildConfig.SUB_PRODUCT_ID; // If you wont test gateway, let this to be null |
|||
private String mSubDevName = null;//BuildConfig.SUB_DEV_NAME; |
|||
private String mSubDevPsk = null;//BuildConfig.SUB_DEVICE_PSK; |
|||
private String mTestTopic = "BE8N7UZ7OF/pad20220105/data";//BuildConfig.TEST_TOPIC; // productID/DeviceName/TopicName |
|||
private String mDevCertName = null;//"YOUR_DEVICE_NAME_cert.crt"; |
|||
private String mDevKeyName = null;//"YOUR_DEVICE_NAME_private.key"; |
|||
private String mProductKey = null;//BuildConfig.PRODUCT_KEY; // Used for dynamic register |
|||
private String mDevCert = ""; // Cert String |
|||
private String mDevPriv = ""; // Priv String |
|||
|
|||
|
|||
private static final String TAG = "TXMQTT"; |
|||
private MQTTSample mMQTTSample; |
|||
private TextView mLogInfoText; |
|||
private volatile boolean mIsConnected; //是否连接 |
|||
|
|||
private Button statusBtn, connectBtn, disconnectBtn, subscribeBtn, unSubscribeBtn, publishBtn, clearBtn; |
|||
|
|||
|
|||
/**日志保存的路径*/ |
|||
private final static String mLogPath = Environment.getExternalStorageDirectory().getPath() + "/tencent/"; |
|||
|
|||
private AtomicInteger temperature = new AtomicInteger(0); |
|||
|
|||
|
|||
@Override |
|||
protected void onCreate(Bundle savedInstanceState) { |
|||
super.onCreate(savedInstanceState); |
|||
setContentView(R.layout.activity_main); |
|||
|
|||
mContext = this; |
|||
|
|||
mLogInfoText =(TextView)findViewById(R.id.tv1); |
|||
statusBtn = (Button)findViewById(R.id.btn1); |
|||
connectBtn = (Button)findViewById(R.id.btn2); |
|||
disconnectBtn = (Button)findViewById(R.id.btn3); |
|||
subscribeBtn = (Button)findViewById(R.id.btn4); |
|||
unSubscribeBtn = (Button)findViewById(R.id.btn5); |
|||
publishBtn = (Button)findViewById(R.id.btn6); |
|||
clearBtn = (Button)findViewById(R.id.btn7); |
|||
|
|||
|
|||
|
|||
|
|||
statusBtn.setOnClickListener(new View.OnClickListener() { |
|||
@Override |
|||
public void onClick(View v) { |
|||
if(mIsConnected){ |
|||
Log.d(TAG, "连接成功"); |
|||
Toast.makeText(mContext,"连接成功",Toast.LENGTH_LONG).show(); |
|||
}else { |
|||
Log.d(TAG, "连接失败"); |
|||
Toast.makeText(MainActivity.this,"连接失败",Toast.LENGTH_LONG).show(); |
|||
} |
|||
|
|||
} |
|||
}); |
|||
|
|||
connectBtn.setOnClickListener(new View.OnClickListener() { |
|||
@Override |
|||
public void onClick(View v) { |
|||
getConnect(); |
|||
} |
|||
}); |
|||
disconnectBtn.setOnClickListener(new View.OnClickListener() { |
|||
@Override |
|||
public void onClick(View v) { |
|||
closeConnection(); |
|||
} |
|||
}); |
|||
subscribeBtn.setOnClickListener(new View.OnClickListener() { |
|||
@Override |
|||
public void onClick(View v) { |
|||
getSubscribe(); |
|||
} |
|||
}); |
|||
unSubscribeBtn.setOnClickListener(new View.OnClickListener() { |
|||
@Override |
|||
public void onClick(View v) { |
|||
getUnSubscribe(); |
|||
} |
|||
}); |
|||
publishBtn.setOnClickListener(new View.OnClickListener() { |
|||
@Override |
|||
public void onClick(View v) { |
|||
getPublish(); |
|||
} |
|||
}); |
|||
|
|||
clearBtn.setOnClickListener(new View.OnClickListener() { |
|||
@Override |
|||
public void onClick(View v) { |
|||
mLogInfoText.setText(""); |
|||
} |
|||
}); |
|||
|
|||
} |
|||
|
|||
|
|||
//MQTT 认证连接 |
|||
public void getConnect(){ |
|||
mMQTTSample = new MQTTSample(mContext, new SelfMqttActionCallBack(), mBrokerURL, mProductID, mDevName, mDevPSK, |
|||
mDevCert, mDevPriv, mSubProductID, mSubDevName, mTestTopic, null, null, true, new SelfMqttLogCallBack()); |
|||
mMQTTSample.setSubDevPsk(mSubDevPsk); |
|||
mMQTTSample.connect(); |
|||
} |
|||
|
|||
//断开 MQTT 连接 |
|||
public void closeConnection() { |
|||
if (mMQTTSample == null) |
|||
return; |
|||
mMQTTSample.disconnect(); |
|||
} |
|||
|
|||
//订阅主题 |
|||
public void getSubscribe(){ |
|||
// 在腾讯云控制台增加自定义主题(权限为订阅和发布):custom_data,用于接收IoT服务端转发的自定义数据。 |
|||
// 本例中,发布的自定义数据,IoT服务端会在发给当前设备。 |
|||
if (mMQTTSample == null) |
|||
return; |
|||
mMQTTSample.subscribeTopic(); |
|||
} |
|||
|
|||
//取消订阅主题 |
|||
public void getUnSubscribe(){ |
|||
// 在腾讯云控制台增加自定义主题(权限为订阅和发布):custom_data,用于接收IoT服务端转发的自定义数据。 |
|||
// 本例中,发布的自定义数据,IoT服务端会在发给当前设备。 |
|||
if (mMQTTSample == null) |
|||
return; |
|||
mMQTTSample.unSubscribeTopic(); |
|||
} |
|||
|
|||
// 发布主题 |
|||
public void getPublish(){ |
|||
if (mMQTTSample == null)return; |
|||
|
|||
// 要发布的数据 |
|||
Map<String, String> data = new HashMap<String, String>(); |
|||
// 车辆类型 |
|||
data.put("car_type", "suv"); |
|||
// 车辆油耗 |
|||
data.put("oil_consumption", "6.6"); |
|||
// 车辆最高速度 |
|||
data.put("maximum_speed", "205"); |
|||
// 温度信息 |
|||
data.put("temperature", String.valueOf(temperature.getAndIncrement())); |
|||
|
|||
// 需先在腾讯云控制台,增加自定义主题: data,用于更新自定义数据 |
|||
mMQTTSample.publishTopic("data", data); |
|||
} |
|||
|
|||
/** |
|||
* 实现TXMqttActionCallBack回调接口 |
|||
*/ |
|||
private class SelfMqttActionCallBack extends TXMqttActionCallBack { |
|||
|
|||
@Override |
|||
public void onConnectCompleted(Status status, boolean reconnect, Object userContext, String msg, Throwable cause) { |
|||
//MQTT Connect完成回调 |
|||
String userContextInfo = ""; |
|||
if (userContext instanceof MQTTRequest) { |
|||
userContextInfo = userContext.toString(); |
|||
} |
|||
String logInfo = String.format("onConnectCompleted, status[%s], reconnect[%b], userContext[%s], msg[%s]", |
|||
status.name(), reconnect, userContextInfo, msg); |
|||
printLogInfo(TAG, logInfo, mLogInfoText, TXLog.LEVEL_INFO); |
|||
mIsConnected = true; |
|||
} |
|||
|
|||
@Override |
|||
public void onConnectionLost(Throwable cause) { |
|||
//MQTT连接断开回调 |
|||
String logInfo = String.format("onConnectionLost, cause[%s]", cause.toString()); |
|||
printLogInfo(TAG, logInfo, mLogInfoText, TXLog.LEVEL_INFO); |
|||
} |
|||
|
|||
@Override |
|||
public void onDisconnectCompleted(Status status, Object userContext, String msg, Throwable cause) { |
|||
//MQTT Disconnect完成回调 |
|||
String userContextInfo = ""; |
|||
if (userContext instanceof MQTTRequest) { |
|||
userContextInfo = userContext.toString(); |
|||
} |
|||
String logInfo = String.format("onDisconnectCompleted, status[%s], userContext[%s], msg[%s]", status.name(), userContextInfo, msg); |
|||
printLogInfo(TAG, logInfo, mLogInfoText, TXLog.LEVEL_INFO); |
|||
mIsConnected = false; |
|||
} |
|||
|
|||
@Override |
|||
public void onPublishCompleted(Status status, IMqttToken token, Object userContext, String errMsg, Throwable cause) { |
|||
// 发布消息完成回调 |
|||
String userContextInfo = ""; |
|||
if (userContext instanceof MQTTRequest) { |
|||
userContextInfo = userContext.toString(); |
|||
} |
|||
String logInfo = String.format("onPublishCompleted, status[%s], topics[%s], userContext[%s], errMsg[%s]", |
|||
status.name(), Arrays.toString(token.getTopics()), userContextInfo, errMsg); |
|||
printLogInfo(TAG, logInfo, mLogInfoText,-1); |
|||
} |
|||
|
|||
@Override |
|||
public void onSubscribeCompleted(Status status, IMqttToken asyncActionToken, Object userContext, String errMsg, Throwable cause) { |
|||
//订阅主题完成的回调 |
|||
String userContextInfo = ""; |
|||
if (userContext instanceof MQTTRequest) { |
|||
userContextInfo = userContext.toString(); |
|||
} |
|||
String logInfo = String.format("onSubscribeCompleted, status[%s], topics[%s], userContext[%s], errMsg[%s]", |
|||
status.name(), Arrays.toString(asyncActionToken.getTopics()), userContextInfo, errMsg); |
|||
if (Status.ERROR == status) { |
|||
//失败的 |
|||
printLogInfo(TAG, logInfo, mLogInfoText, TXLog.LEVEL_ERROR); |
|||
Log.d(TAG, "订阅主题--失败的:"+ logInfo ); |
|||
} else { |
|||
//成功的 |
|||
printLogInfo(TAG, logInfo, mLogInfoText, -1); |
|||
Log.d(TAG, "订阅主题--成功的:"+ logInfo ); |
|||
|
|||
} |
|||
} |
|||
|
|||
@Override |
|||
public void onUnSubscribeCompleted(Status status, IMqttToken asyncActionToken, Object userContext, String errMsg, Throwable cause) { |
|||
//取消订阅主题完成回调 |
|||
String userContextInfo = ""; |
|||
if (userContext instanceof MQTTRequest) { |
|||
userContextInfo = userContext.toString(); |
|||
} |
|||
String logInfo = String.format("onUnSubscribeCompleted, status[%s], topics[%s], userContext[%s], errMsg[%s]", |
|||
status.name(), Arrays.toString(asyncActionToken.getTopics()), userContextInfo, errMsg); |
|||
printLogInfo(TAG, logInfo, mLogInfoText,-1); |
|||
} |
|||
|
|||
@Override |
|||
public void onMessageReceived(final String topic, final MqttMessage message) { |
|||
// 收到订阅主题的消息Push 即收到云中控下发的消息 |
|||
String logInfo = String.format("receive command, topic[%s], message[%s]", topic, message.toString()); |
|||
printLogInfo(TAG, logInfo, mLogInfoText, -1); |
|||
|
|||
Log.d(TAG, "收到订阅主题的消息: "+ message.toString()); |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* 打印日志信息 |
|||
* |
|||
* @param logInfo |
|||
*/ |
|||
protected void printLogInfo(final String tag, final String logInfo, final TextView textView, int logLevel) { |
|||
switch (logLevel) { |
|||
case TXLog.LEVEL_DEBUG: |
|||
TXLog.d(tag, logInfo); |
|||
break; |
|||
|
|||
case TXLog.LEVEL_INFO: |
|||
TXLog.i(tag, logInfo); |
|||
break; |
|||
|
|||
case TXLog.LEVEL_ERROR: |
|||
TXLog.e(tag, logInfo); |
|||
break; |
|||
|
|||
default: |
|||
TXLog.d(tag, logInfo); |
|||
break; |
|||
} |
|||
|
|||
runOnUiThread(new Runnable() { |
|||
@Override |
|||
public void run() { |
|||
textView.append("==> " + logInfo + "\n\n"); |
|||
} |
|||
}); |
|||
} |
|||
|
|||
/** |
|||
* 实现TXMqttLogCallBack回调接口 |
|||
*/ |
|||
private class SelfMqttLogCallBack extends TXMqttLogCallBack { |
|||
|
|||
@Override |
|||
public String setSecretKey() { |
|||
String secertKey; |
|||
if (mDevPSK != null && mDevPSK.length() != 0) { //密钥认证 |
|||
secertKey = mDevPSK; |
|||
secertKey = secertKey.length() > 24 ? secertKey.substring(0,24) : secertKey; |
|||
return secertKey; |
|||
} else { |
|||
StringBuilder builder = new StringBuilder(); |
|||
if (mDevPriv != null && mDevPriv.length() != 0) { //动态注册, 从DevPriv中读取 |
|||
builder.append(mDevPriv); |
|||
} else { //证书认证,从证书文件中读取 |
|||
AssetManager assetManager = mContext.getAssets(); |
|||
if (assetManager == null) { |
|||
return null; |
|||
} |
|||
BufferedReader reader = null; |
|||
try { |
|||
reader = new BufferedReader(new InputStreamReader(assetManager.open(mDevKeyName))); |
|||
String str; |
|||
while((str = reader.readLine()) != null){ |
|||
builder.append(str); |
|||
} |
|||
} catch (IOException e) { |
|||
printLogInfo(TAG, "Get Private Key failed, cannot open Private Key Files.",mLogInfoText, -1); |
|||
return null; |
|||
} finally { |
|||
if (reader != null) { |
|||
try { |
|||
reader.close(); |
|||
} catch (IOException e) { |
|||
e.printStackTrace(); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
String privateKey = builder.toString(); |
|||
if (privateKey.contains("-----BEGIN PRIVATE KEY-----")) { |
|||
secertKey = privateKey; |
|||
} else { |
|||
secertKey = null; |
|||
printLogInfo(TAG,"Invaild Private Key File.", mLogInfoText,-1); |
|||
} |
|||
} |
|||
return secertKey; |
|||
} |
|||
|
|||
@Override |
|||
public void printDebug(String message){ |
|||
printLogInfo(TAG, message, mLogInfoText, -1); |
|||
//TXLog.d(TAG,message); |
|||
} |
|||
|
|||
@Override |
|||
public boolean saveLogOffline(String log){ |
|||
//判断SD卡是否可用 |
|||
if (!Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) { |
|||
printLogInfo(TAG, "saveLogOffline not ready", mLogInfoText, -1); |
|||
return false; |
|||
} |
|||
|
|||
String logFilePath = mLogPath + mProductID + mDevName + ".log"; |
|||
|
|||
TXLog.i(TAG, "Save log to %s", logFilePath); |
|||
|
|||
try { |
|||
BufferedWriter wLog = new BufferedWriter(new FileWriter(new File(logFilePath), true)); |
|||
wLog.write(log); |
|||
wLog.flush(); |
|||
wLog.close(); |
|||
return true; |
|||
} catch (IOException e) { |
|||
String logInfo = String.format("Save log to [%s] failed, check the Storage permission!", logFilePath); |
|||
printLogInfo(TAG,logInfo, mLogInfoText, -1); |
|||
e.printStackTrace(); |
|||
return false; |
|||
} |
|||
} |
|||
|
|||
@Override |
|||
public String readOfflineLog(){ |
|||
//判断SD卡是否可用 |
|||
if (!Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) { |
|||
printLogInfo(TAG, "readOfflineLog not ready", mLogInfoText, -1); |
|||
return null; |
|||
} |
|||
|
|||
String logFilePath = mLogPath + mProductID + mDevName + ".log"; |
|||
|
|||
TXLog.i(TAG, "Read log from %s", logFilePath); |
|||
|
|||
try { |
|||
BufferedReader logReader = new BufferedReader(new FileReader(logFilePath)); |
|||
StringBuilder offlineLog = new StringBuilder(); |
|||
int data; |
|||
while (( data = logReader.read()) != -1 ) { |
|||
offlineLog.append((char)data); |
|||
} |
|||
logReader.close(); |
|||
return offlineLog.toString(); |
|||
} catch (IOException e) { |
|||
e.printStackTrace(); |
|||
return null; |
|||
} |
|||
} |
|||
|
|||
@Override |
|||
public boolean delOfflineLog(){ |
|||
|
|||
//判断SD卡是否可用 |
|||
if (!Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) { |
|||
printLogInfo(TAG, "delOfflineLog not ready", mLogInfoText, -1); |
|||
return false; |
|||
} |
|||
|
|||
String logFilePath = mLogPath + mProductID + mDevName + ".log"; |
|||
|
|||
File file = new File(logFilePath); |
|||
if (file.exists() && file.isFile()) { |
|||
if (file.delete()) { |
|||
return true; |
|||
} |
|||
} |
|||
return false; |
|||
} |
|||
|
|||
} |
|||
} |
@ -0,0 +1,49 @@ |
|||
package io.dcloud.uniplugin.mqtt; |
|||
|
|||
|
|||
public class MQTTRequest { |
|||
|
|||
private static final String TAG = MQTTRequest.class.getSimpleName(); |
|||
|
|||
/** |
|||
* 请求类型 |
|||
*/ |
|||
private String requestType = ""; |
|||
|
|||
/** |
|||
* 请求ID |
|||
*/ |
|||
private int requestId = 0; |
|||
|
|||
public MQTTRequest() { |
|||
} |
|||
|
|||
public MQTTRequest(String requestType, int requestId) { |
|||
this.requestType = requestType; |
|||
this.requestId = requestId; |
|||
} |
|||
|
|||
public String getRequestType() { |
|||
return requestType; |
|||
} |
|||
|
|||
public void setRequestType(String requestType) { |
|||
this.requestType = requestType; |
|||
} |
|||
|
|||
public int getRequestId() { |
|||
return requestId; |
|||
} |
|||
|
|||
public void setRequestId(int requestId) { |
|||
this.requestId = requestId; |
|||
} |
|||
|
|||
@Override |
|||
public String toString() { |
|||
return "MQTTRequest{" + |
|||
"requestType='" + requestType + '\'' + |
|||
", requestId=" + requestId + |
|||
'}'; |
|||
} |
|||
} |
@ -0,0 +1,403 @@ |
|||
package io.dcloud.uniplugin.mqtt; |
|||
|
|||
import android.content.Context; |
|||
import android.os.Environment; |
|||
import android.util.Log; |
|||
|
|||
import com.tencent.iot.hub.device.android.core.gateway.TXGatewayConnection; |
|||
import com.tencent.iot.hub.device.android.core.util.AsymcSslUtils; |
|||
import com.tencent.iot.hub.device.android.core.util.TXLog; |
|||
import com.tencent.iot.hub.device.java.core.log.TXMqttLogCallBack; |
|||
import com.tencent.iot.hub.device.java.core.mqtt.TXMqttActionCallBack; |
|||
import com.tencent.iot.hub.device.java.core.mqtt.TXMqttConstants; |
|||
import com.tencent.iot.hub.device.java.core.mqtt.TXOTACallBack; |
|||
import com.tencent.iot.hub.device.java.core.mqtt.TXOTAConstansts; |
|||
|
|||
import org.eclipse.paho.client.mqttv3.DisconnectedBufferOptions; |
|||
import org.eclipse.paho.client.mqttv3.MqttConnectOptions; |
|||
import org.eclipse.paho.client.mqttv3.MqttMessage; |
|||
import org.json.JSONException; |
|||
import org.json.JSONObject; |
|||
|
|||
import java.io.ByteArrayInputStream; |
|||
import java.util.Map; |
|||
import java.util.concurrent.atomic.AtomicInteger; |
|||
|
|||
|
|||
public class MQTTSample { |
|||
|
|||
private static final String TAG = "TXMQTT"; |
|||
// Default Value, should be changed in testing |
|||
private String mBrokerURL = null; //传入null,即使用腾讯云物联网通信默认地址 "${ProductId}.iotcloud.tencentdevices.com:8883" https://cloud.tencent.com/document/product/634/32546 |
|||
private String mProductID = "PRODUCT-ID"; |
|||
private String mDevName = "DEVICE-NAME"; |
|||
private String mDevPSK = "DEVICE-SECRET"; |
|||
|
|||
private String mDevCertName = "DEVICE_CERT-NAME "; |
|||
private String mDevKeyName = "DEVICE_KEY-NAME "; |
|||
|
|||
private String mSubProductID = "SUBDEV_PRODUCT-ID"; |
|||
private String mSubDevName = "SUBDEV_DEV-NAME"; |
|||
private String mSubDevPsk = "SUBDEV_DEVICE-SECRET"; |
|||
private String mTestTopic = "TEST_TOPIC_WITH_SUB_PUB"; |
|||
private String mDevCert; |
|||
private String mDevPriv; |
|||
|
|||
private boolean mMqttLogFlag; |
|||
private TXMqttLogCallBack mMqttLogCallBack; |
|||
|
|||
private Context mContext; |
|||
private String path2Store = ""; |
|||
|
|||
private TXMqttActionCallBack mMqttActionCallBack; |
|||
|
|||
/** |
|||
* MQTT连接实例 |
|||
*/ |
|||
private TXGatewayConnection mMqttConnection; |
|||
|
|||
/** |
|||
* 请求ID |
|||
*/ |
|||
private static AtomicInteger requestID = new AtomicInteger(0); |
|||
|
|||
public MQTTSample(Context context, TXMqttLogCallBack logCallBack, TXMqttActionCallBack callBack) { |
|||
mContext = context; |
|||
mMqttActionCallBack = callBack; |
|||
} |
|||
|
|||
public MQTTSample(Context context, TXMqttActionCallBack callBack, String brokerURL, String productId, |
|||
String devName, String devPSK, String subProductID, String subDevName, String testTopic, String devCertName, String devKeyName, |
|||
Boolean mqttLogFlag, TXMqttLogCallBack logCallBack) { |
|||
mBrokerURL = brokerURL; |
|||
mProductID = productId; |
|||
mDevName = devName; |
|||
mDevPSK = devPSK; |
|||
mSubProductID = subProductID; |
|||
mSubDevName = subDevName; |
|||
mTestTopic = testTopic; |
|||
mDevCertName = devCertName; |
|||
mDevKeyName = devKeyName; |
|||
|
|||
mMqttLogFlag = mqttLogFlag; |
|||
mMqttLogCallBack = logCallBack; |
|||
|
|||
mContext = context; |
|||
mMqttActionCallBack = callBack; |
|||
} |
|||
|
|||
public MQTTSample(Context context, TXMqttActionCallBack callBack, String brokerURL, String productId, |
|||
String devName, String devPsk, String devCert, String devPriv, String subProductID, String subDevName, String testTopic, String devCertName, String devKeyName, |
|||
Boolean mqttLogFlag, TXMqttLogCallBack logCallBack) { |
|||
mBrokerURL = brokerURL; |
|||
mProductID = productId; |
|||
mDevName = devName; |
|||
mDevPSK = devPsk; |
|||
mDevCert = devCert; |
|||
mDevPriv = devPriv; |
|||
mSubProductID = subProductID; |
|||
mSubDevName = subDevName; |
|||
mTestTopic = testTopic; |
|||
mDevCertName = devCertName; |
|||
mDevKeyName = devKeyName; |
|||
|
|||
mMqttLogFlag = mqttLogFlag; |
|||
mMqttLogCallBack = logCallBack; |
|||
|
|||
mContext = context; |
|||
mMqttActionCallBack = callBack; |
|||
path2Store = mContext.getCacheDir().getAbsolutePath(); |
|||
} |
|||
|
|||
public MQTTSample(Context context, TXMqttActionCallBack callBack, String brokerURL, String productId, |
|||
String devName, String devPsk, String devCert, String devPriv, String subProductID, String subDevName, String subDevPsk, String testTopic, String devCertName, String devKeyName, |
|||
Boolean mqttLogFlag, TXMqttLogCallBack logCallBack) { |
|||
this(context, callBack, brokerURL, productId, devName, devPsk, devCert, devPriv, subProductID, subDevName, testTopic, devCertName, devKeyName, mqttLogFlag, logCallBack); |
|||
mSubDevPsk = subDevPsk; |
|||
} |
|||
|
|||
public void setSubDevPsk(String val) { |
|||
mSubDevPsk = val; |
|||
} |
|||
|
|||
|
|||
public MQTTSample(Context context, TXMqttActionCallBack callBack, String brokerURL, String productId, |
|||
String devName, String devPSK, String subProductID, String subDevName, String testTopic) { |
|||
mBrokerURL = brokerURL; |
|||
mProductID = productId; |
|||
mDevName = devName; |
|||
mDevPSK = devPSK; |
|||
mSubProductID = subProductID; |
|||
mSubDevName = subDevName; |
|||
mTestTopic = testTopic; |
|||
|
|||
mContext = context; |
|||
mMqttActionCallBack = callBack; |
|||
} |
|||
|
|||
private TXOTACallBack oTACallBack = new TXOTACallBack() { |
|||
|
|||
@Override |
|||
public void onReportFirmwareVersion(int resultCode, String version, String resultMsg) { |
|||
|
|||
} |
|||
|
|||
@Override |
|||
public boolean onLastestFirmwareReady(String url, String md5, String version) { |
|||
System.out.println("onLastestFirmwareReady url=" + url + " version " + version); |
|||
mMqttConnection.gatewayDownSubdevApp(url, path2Store + "/" + md5, md5, version); |
|||
return true; // false 自动触发下载升级文件 true 需要手动触发下载升级文件 |
|||
} |
|||
|
|||
@Override |
|||
public void onDownloadProgress(int percent, String version) { |
|||
mMqttConnection.gatewaySubdevReportProgress(percent, version); |
|||
} |
|||
|
|||
@Override |
|||
public void onDownloadCompleted(String outputFile, String version) { |
|||
mMqttConnection.gatewaySubdevReportStart(version); |
|||
mMqttConnection.gatewaySubdevReportSuccess(version); |
|||
} |
|||
|
|||
@Override |
|||
public void onDownloadFailure(int errCode, String version) { |
|||
mMqttConnection.gatewaySubdevReportFail(errCode, "", version); |
|||
} |
|||
}; |
|||
|
|||
/** |
|||
* 建立MQTT连接 |
|||
*/ |
|||
public void connect() { |
|||
mMqttConnection = new TXGatewayConnection(mContext, mBrokerURL, mProductID, mDevName, mDevPSK,null,null ,mMqttLogFlag, mMqttLogCallBack, mMqttActionCallBack); |
|||
mMqttConnection.setSubDevName(mSubDevName); |
|||
mMqttConnection.setSubDevProductKey(mSubDevPsk); |
|||
mMqttConnection.setSubProductID(mSubProductID); |
|||
MqttConnectOptions options = new MqttConnectOptions(); |
|||
options.setConnectionTimeout(8); |
|||
options.setKeepAliveInterval(240); |
|||
options.setAutomaticReconnect(true); |
|||
|
|||
if (mDevPriv != null && mDevCert != null && mDevPriv.length() != 0 && mDevCert.length() != 0) { |
|||
TXLog.i(TAG, "Using cert stream " + mDevPriv + " " + mDevCert); |
|||
options.setSocketFactory(AsymcSslUtils.getSocketFactoryByStream(new ByteArrayInputStream(mDevCert.getBytes()), new ByteArrayInputStream(mDevPriv.getBytes()))); |
|||
} else if (mDevPSK != null && mDevPSK.length() != 0){ |
|||
TXLog.i(TAG, "Using PSK"); |
|||
// options.setSocketFactory(AsymcSslUtils.getSocketFactory()); 如果您使用的是3.3.0及以下版本的 hub-device-android sdk,由于密钥认证默认配置的ssl://的url,请添加此句setSocketFactory配置。 |
|||
} else { |
|||
TXLog.i(TAG, "Using cert assets file"); |
|||
options.setSocketFactory(AsymcSslUtils.getSocketFactoryByAssetsFile(mContext, mDevCertName, mDevKeyName)); |
|||
} |
|||
|
|||
MQTTRequest mqttRequest = new MQTTRequest("connect", requestID.getAndIncrement()); |
|||
mMqttConnection.connect(options, mqttRequest); |
|||
|
|||
DisconnectedBufferOptions bufferOptions = new DisconnectedBufferOptions(); |
|||
bufferOptions.setBufferEnabled(true); |
|||
bufferOptions.setBufferSize(1024); |
|||
bufferOptions.setDeleteOldestMessages(true); |
|||
mMqttConnection.setBufferOpts(bufferOptions); |
|||
} |
|||
|
|||
/** |
|||
* 断开MQTT连接 |
|||
*/ |
|||
public void disconnect() { |
|||
MQTTRequest mqttRequest = new MQTTRequest("disconnect", requestID.getAndIncrement()); |
|||
mMqttConnection.disConnect(mqttRequest); |
|||
} |
|||
|
|||
public void setSubdevOnline() { |
|||
// set subdev online |
|||
mMqttConnection.gatewaySubdevOnline(mSubProductID, mSubDevName); |
|||
} |
|||
|
|||
public void setSubDevOffline() { |
|||
mMqttConnection.gatewaySubdevOffline(mSubProductID, mSubDevName); |
|||
} |
|||
|
|||
public void setSubDevBinded() { |
|||
mMqttConnection.gatewayBindSubdev(mSubProductID, mSubDevName, mSubDevPsk); |
|||
} |
|||
|
|||
public void setSubDevUnbinded() { |
|||
mMqttConnection.gatewayUnbindSubdev(mSubProductID, mSubDevName); |
|||
} |
|||
|
|||
public void checkSubdevRelation() { |
|||
mMqttConnection.getGatewaySubdevRealtion(); |
|||
} |
|||
|
|||
public void getRemoteConfig() { |
|||
mMqttConnection.getRemoteConfig(); |
|||
} |
|||
|
|||
public void concernRemoteConfig() { |
|||
mMqttConnection.concernConfig(); |
|||
} |
|||
|
|||
public void reportSubDevVersion(String version) { |
|||
mMqttConnection.gatewaySubdevReportVer(version); |
|||
} |
|||
|
|||
public void subscribeNTPTopic() { |
|||
// QOS等级 |
|||
int qos = TXMqttConstants.QOS1; |
|||
// 用户上下文(请求实例) |
|||
MQTTRequest mqttRequest = new MQTTRequest("subscribeNTPTopic", requestID.getAndIncrement()); |
|||
mMqttConnection.subscribeNTPTopic(qos, mqttRequest); |
|||
} |
|||
|
|||
public void getNTPService() { |
|||
mMqttConnection.getNTPService(); |
|||
} |
|||
|
|||
public void initOTA() { |
|||
TXLog.e(TAG, "path2Store " + path2Store); |
|||
mMqttConnection.initOTA(path2Store, oTACallBack); |
|||
} |
|||
|
|||
/** |
|||
* 订阅广播主题 |
|||
*/ |
|||
public void subscribeBroadCastTopic() { |
|||
// 用户上下文(请求实例) |
|||
MQTTRequest mqttRequest = new MQTTRequest("subscribeTopic", requestID.getAndIncrement()); |
|||
// 订阅广播主题 |
|||
mMqttConnection.subscribeBroadcastTopic(TXMqttConstants.QOS1, mqttRequest); |
|||
} |
|||
|
|||
/** |
|||
* 订阅主题 |
|||
* |
|||
*/ |
|||
public void subscribeTopic() { |
|||
// 主题 |
|||
String topic = mTestTopic; |
|||
// QOS等级 |
|||
int qos = TXMqttConstants.QOS1; |
|||
// 用户上下文(请求实例) |
|||
MQTTRequest mqttRequest = new MQTTRequest("subscribeTopic", requestID.getAndIncrement()); |
|||
|
|||
Log.d(TAG, "sub topic is " + topic); |
|||
|
|||
// 订阅主题 |
|||
mMqttConnection.subscribe(topic, qos, mqttRequest); |
|||
|
|||
} |
|||
|
|||
/** |
|||
* 取消订阅主题 |
|||
* |
|||
*/ |
|||
public void unSubscribeTopic() { |
|||
// 主题 |
|||
String topic = mTestTopic; |
|||
// 用户上下文(请求实例) |
|||
MQTTRequest mqttRequest = new MQTTRequest("unSubscribeTopic", requestID.getAndIncrement()); |
|||
Log.d(TAG, "Start to unSubscribe" + topic); |
|||
// 取消订阅主题 |
|||
mMqttConnection.unSubscribe(topic, mqttRequest); |
|||
} |
|||
|
|||
/** |
|||
* 发布主题 |
|||
*/ |
|||
public void publishTopic(String topicName, Map<String, String> data) { |
|||
// 主题 |
|||
String topic = mTestTopic; |
|||
// MQTT消息 |
|||
MqttMessage message = new MqttMessage(); |
|||
|
|||
JSONObject jsonObject = new JSONObject(); |
|||
try { |
|||
for (Map.Entry<String, String> entrys : data.entrySet()) { |
|||
jsonObject.put(entrys.getKey(), entrys.getValue()); |
|||
} |
|||
} catch (JSONException e) { |
|||
TXLog.e(TAG, e, "pack json data failed!"); |
|||
} |
|||
message.setQos(TXMqttConstants.QOS1); |
|||
message.setPayload(jsonObject.toString().getBytes()); |
|||
|
|||
// 用户上下文(请求实例) |
|||
MQTTRequest mqttRequest = new MQTTRequest("publishTopic", requestID.getAndIncrement()); |
|||
|
|||
Log.d(TAG, "pub topic " + topic + message); |
|||
// 发布主题 |
|||
mMqttConnection.publish(topic, message, mqttRequest); |
|||
|
|||
} |
|||
|
|||
/** |
|||
* 订阅RRPC主题 |
|||
* |
|||
*/ |
|||
public void subscribeRRPCTopic() { |
|||
// 用户上下文(请求实例) |
|||
MQTTRequest mqttRequest = new MQTTRequest("subscribeTopic", requestID.getAndIncrement()); |
|||
// 订阅主题 |
|||
mMqttConnection.subscribeRRPCTopic(TXMqttConstants.QOS0, mqttRequest); |
|||
|
|||
} |
|||
|
|||
/** |
|||
* 生成一条日志 |
|||
* @param logLevel 日志级别: |
|||
* 错误:TXMqttLogConstants.LEVEL_ERROR |
|||
* 警告:TXMqttLogConstants.LEVEL_WARN |
|||
* 通知:TXMqttLogConstants.LEVEL_INFO |
|||
* 调试:TXMqttLogConstants.LEVEL_DEBUG |
|||
* @param tag |
|||
* @param format |
|||
* @param obj |
|||
*/ |
|||
public void mLog(int logLevel, final String tag,final String format, final Object... obj) { |
|||
if (mMqttLogFlag) |
|||
mMqttConnection.mLog(logLevel, tag, format, obj); |
|||
} |
|||
|
|||
/** |
|||
* 发起一次日志上传 |
|||
*/ |
|||
public void uploadLog() { |
|||
mMqttConnection.uploadLog(); |
|||
} |
|||
|
|||
public void checkFirmware() { |
|||
|
|||
mMqttConnection.initOTA(Environment.getExternalStorageDirectory().getAbsolutePath(), new TXOTACallBack() { |
|||
@Override |
|||
public void onReportFirmwareVersion(int resultCode, String version, String resultMsg) { |
|||
TXLog.e(TAG, "onReportFirmwareVersion:" + resultCode + ", version:" + version + ", resultMsg:" + resultMsg); |
|||
} |
|||
|
|||
@Override |
|||
public boolean onLastestFirmwareReady(String url, String md5, String version) { |
|||
TXLog.e(TAG, "MQTTSample onLastestFirmwareReady"); |
|||
return false; |
|||
} |
|||
|
|||
@Override |
|||
public void onDownloadProgress(int percent, String version) { |
|||
TXLog.e(TAG, "onDownloadProgress:" + percent); |
|||
} |
|||
|
|||
@Override |
|||
public void onDownloadCompleted(String outputFile, String version) { |
|||
TXLog.e(TAG, "onDownloadCompleted:" + outputFile + ", version:" + version); |
|||
|
|||
mMqttConnection.reportOTAState(TXOTAConstansts.ReportState.DONE, 0, "OK", version); |
|||
} |
|||
|
|||
@Override |
|||
public void onDownloadFailure(int errCode, String version) { |
|||
TXLog.e(TAG, "onDownloadFailure:" + errCode); |
|||
|
|||
mMqttConnection.reportOTAState(TXOTAConstansts.ReportState.FAIL, errCode, "FAIL", version); |
|||
} |
|||
}); |
|||
mMqttConnection.reportCurrentFirmwareVersion("0.0.1"); |
|||
} |
|||
} |
@ -0,0 +1,84 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" |
|||
xmlns:app="http://schemas.android.com/apk/res-auto" |
|||
xmlns:tools="http://schemas.android.com/tools" |
|||
android:layout_width="match_parent" |
|||
android:layout_height="match_parent" |
|||
android:orientation="vertical" |
|||
tools:context="io.dcloud.uniplugin.MainActivity"> |
|||
|
|||
<Button |
|||
android:id="@+id/btn1" |
|||
android:layout_width="wrap_content" |
|||
android:layout_height="wrap_content" |
|||
android:text="连接状态" /> |
|||
|
|||
<LinearLayout |
|||
android:layout_width="wrap_content" |
|||
android:layout_height="wrap_content" |
|||
android:orientation="horizontal"> |
|||
<Button |
|||
android:id="@+id/btn2" |
|||
android:layout_width="wrap_content" |
|||
android:layout_height="wrap_content" |
|||
android:text="连接MQTT" /> |
|||
|
|||
<Button |
|||
android:id="@+id/btn3" |
|||
android:layout_width="wrap_content" |
|||
android:layout_height="wrap_content" |
|||
android:layout_marginLeft="20dp" |
|||
android:text="断开连接MQTT" /> |
|||
</LinearLayout> |
|||
|
|||
<LinearLayout |
|||
android:layout_width="wrap_content" |
|||
android:layout_height="wrap_content" |
|||
android:orientation="horizontal"> |
|||
<Button |
|||
android:id="@+id/btn4" |
|||
android:layout_width="wrap_content" |
|||
android:layout_height="wrap_content" |
|||
android:text="订阅主题" /> |
|||
<Button |
|||
android:id="@+id/btn5" |
|||
android:layout_width="wrap_content" |
|||
android:layout_height="wrap_content" |
|||
android:layout_marginLeft="20dp" |
|||
android:text="取消订阅主题" /> |
|||
</LinearLayout> |
|||
|
|||
<LinearLayout |
|||
android:layout_width="wrap_content" |
|||
android:layout_height="wrap_content" |
|||
android:orientation="horizontal"> |
|||
<Button |
|||
android:id="@+id/btn6" |
|||
android:layout_width="wrap_content" |
|||
android:layout_height="wrap_content" |
|||
android:text="发布主题" /> |
|||
|
|||
<Button |
|||
android:id="@+id/btn7" |
|||
android:layout_width="wrap_content" |
|||
android:layout_height="wrap_content" |
|||
android:layout_marginLeft="20dp" |
|||
android:text="清空日志" /> |
|||
</LinearLayout> |
|||
|
|||
|
|||
<TextView |
|||
android:layout_width="wrap_content" |
|||
android:layout_height="wrap_content" |
|||
android:text="日志输出" /> |
|||
|
|||
<ScrollView |
|||
android:layout_width="match_parent" |
|||
android:layout_height="wrap_content"> |
|||
<TextView |
|||
android:id="@+id/tv1" |
|||
android:layout_width="match_parent" |
|||
android:layout_height="match_parent" /> |
|||
</ScrollView> |
|||
|
|||
</LinearLayout> |
Write
Preview
Loading…
Cancel
Save
Reference in new issue