From 72799fadefbac1d389abba70575b1c202b2008a0 Mon Sep 17 00:00:00 2001 From: sheedon Date: Mon, 2 May 2022 22:49:31 +0800 Subject: [PATCH] =?UTF-8?q?=E8=A1=A5=E5=85=85samples?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/org/sheedon/app/MainActivity.kt | 76 --------- .../org/sheedon/app/factory/MqttClient.kt | 61 -------- app/src/main/res/layout/activity_main.xml | 19 --- app/src/main/res/values/strings.xml | 3 - {app => samples}/.gitignore | 0 {app => samples}/build.gradle | 24 +++ {app => samples}/proguard-rules.pro | 0 .../sheedon/app/ExampleInstrumentedTest.kt | 0 {app => samples}/src/main/AndroidManifest.xml | 17 +- .../org/sheedon/sample/OkMqttActivity.java | 21 +++ .../sheedon/sample/OkMqttContributors.java | 71 +++++++++ .../sample/fragment/OkMqttFragment.java | 43 +++++ .../fragment/PublishMessageFragment.java | 76 +++++++++ .../fragment/RequestAndResponseFragment.java | 104 +++++++++++++ .../fragment/SubscribeArrayFragment.java | 147 ++++++++++++++++++ .../fragment/SubscribeTopicFragment.java | 101 ++++++++++++ .../viewmodel/SubscribeTopicViewModel.java | 16 ++ .../src/main/kotlin}/org/sheedon/app/App.kt | 1 + .../kotlin/org/sheedon/app/MainActivity.kt | 18 +++ .../main/kotlin}/org/sheedon/app/RspModel.kt | 0 .../app/factory/CallbackNameConverter.kt | 0 .../org/sheedon/app/factory/MqttClient.kt | 56 +++++++ .../sheedon/app/fragment/OkMqttFragment.kt | 53 +++++++ .../app/fragment/PublishMessageFragment.kt | 69 ++++++++ .../fragment/RequestAndResponseFragment.kt | 90 +++++++++++ .../app/fragment/SubscribeArrayFragment.kt | 124 +++++++++++++++ .../app/fragment/SubscribeTopicFragment.kt | 88 +++++++++++ .../drawable-v24/ic_launcher_foreground.xml | 0 .../res/drawable/ic_launcher_background.xml | 0 samples/src/main/res/layout/activity_main.xml | 24 +++ .../src/main/res/layout/activity_ok_mqtt.xml | 24 +++ .../src/main/res/layout/fragment_ok_mqtt.xml | 42 +++++ .../res/layout/fragment_publish_message.xml | 54 +++++++ .../res/layout/fragment_request_response.xml | 93 +++++++++++ .../res/layout/fragment_subscribe_array.xml | 38 +++++ .../res/layout/fragment_subscribe_topic.xml | 70 +++++++++ .../res/mipmap-anydpi-v26/ic_launcher.xml | 0 .../mipmap-anydpi-v26/ic_launcher_round.xml | 0 .../src/main/res/mipmap-hdpi/ic_launcher.webp | Bin .../res/mipmap-hdpi/ic_launcher_round.webp | Bin .../src/main/res/mipmap-mdpi/ic_launcher.webp | Bin .../res/mipmap-mdpi/ic_launcher_round.webp | Bin .../main/res/mipmap-xhdpi/ic_launcher.webp | Bin .../res/mipmap-xhdpi/ic_launcher_round.webp | Bin .../main/res/mipmap-xxhdpi/ic_launcher.webp | Bin .../res/mipmap-xxhdpi/ic_launcher_round.webp | Bin .../main/res/mipmap-xxxhdpi/ic_launcher.webp | Bin .../res/mipmap-xxxhdpi/ic_launcher_round.webp | Bin .../main/res/navigation/nav_graph_java.xml | 40 +++++ .../main/res/navigation/nav_graph_kotlin.xml | 40 +++++ .../src/main/res/values-night/themes.xml | 0 samples/src/main/res/values-zh-rCN/arrays.xml | 12 ++ .../src/main/res/values-zh-rCN/strings.xml | 30 ++++ samples/src/main/res/values/arrays.xml | 13 ++ .../src/main/res/values/colors.xml | 0 samples/src/main/res/values/strings.xml | 30 ++++ .../src/main/res/values/themes.xml | 0 .../main/res/xml/network_security_config.xml | 0 .../java/org/sheedon/app/ExampleUnitTest.kt | 0 settings.gradle | 2 +- 60 files changed, 1626 insertions(+), 164 deletions(-) delete mode 100644 app/src/main/java/org/sheedon/app/MainActivity.kt delete mode 100644 app/src/main/java/org/sheedon/app/factory/MqttClient.kt delete mode 100644 app/src/main/res/layout/activity_main.xml delete mode 100644 app/src/main/res/values/strings.xml rename {app => samples}/.gitignore (100%) rename {app => samples}/build.gradle (68%) rename {app => samples}/proguard-rules.pro (100%) rename {app => samples}/src/androidTest/java/org/sheedon/app/ExampleInstrumentedTest.kt (100%) rename {app => samples}/src/main/AndroidManifest.xml (60%) create mode 100644 samples/src/main/java/org/sheedon/sample/OkMqttActivity.java create mode 100644 samples/src/main/java/org/sheedon/sample/OkMqttContributors.java create mode 100644 samples/src/main/java/org/sheedon/sample/fragment/OkMqttFragment.java create mode 100644 samples/src/main/java/org/sheedon/sample/fragment/PublishMessageFragment.java create mode 100644 samples/src/main/java/org/sheedon/sample/fragment/RequestAndResponseFragment.java create mode 100644 samples/src/main/java/org/sheedon/sample/fragment/SubscribeArrayFragment.java create mode 100644 samples/src/main/java/org/sheedon/sample/fragment/SubscribeTopicFragment.java create mode 100644 samples/src/main/java/org/sheedon/sample/viewmodel/SubscribeTopicViewModel.java rename {app/src/main/java => samples/src/main/kotlin}/org/sheedon/app/App.kt (95%) create mode 100644 samples/src/main/kotlin/org/sheedon/app/MainActivity.kt rename {app/src/main/java => samples/src/main/kotlin}/org/sheedon/app/RspModel.kt (100%) rename {app/src/main/java => samples/src/main/kotlin}/org/sheedon/app/factory/CallbackNameConverter.kt (100%) create mode 100644 samples/src/main/kotlin/org/sheedon/app/factory/MqttClient.kt create mode 100644 samples/src/main/kotlin/org/sheedon/app/fragment/OkMqttFragment.kt create mode 100644 samples/src/main/kotlin/org/sheedon/app/fragment/PublishMessageFragment.kt create mode 100644 samples/src/main/kotlin/org/sheedon/app/fragment/RequestAndResponseFragment.kt create mode 100644 samples/src/main/kotlin/org/sheedon/app/fragment/SubscribeArrayFragment.kt create mode 100644 samples/src/main/kotlin/org/sheedon/app/fragment/SubscribeTopicFragment.kt rename {app => samples}/src/main/res/drawable-v24/ic_launcher_foreground.xml (100%) rename {app => samples}/src/main/res/drawable/ic_launcher_background.xml (100%) create mode 100644 samples/src/main/res/layout/activity_main.xml create mode 100644 samples/src/main/res/layout/activity_ok_mqtt.xml create mode 100644 samples/src/main/res/layout/fragment_ok_mqtt.xml create mode 100644 samples/src/main/res/layout/fragment_publish_message.xml create mode 100644 samples/src/main/res/layout/fragment_request_response.xml create mode 100644 samples/src/main/res/layout/fragment_subscribe_array.xml create mode 100644 samples/src/main/res/layout/fragment_subscribe_topic.xml rename {app => samples}/src/main/res/mipmap-anydpi-v26/ic_launcher.xml (100%) rename {app => samples}/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml (100%) rename {app => samples}/src/main/res/mipmap-hdpi/ic_launcher.webp (100%) rename {app => samples}/src/main/res/mipmap-hdpi/ic_launcher_round.webp (100%) rename {app => samples}/src/main/res/mipmap-mdpi/ic_launcher.webp (100%) rename {app => samples}/src/main/res/mipmap-mdpi/ic_launcher_round.webp (100%) rename {app => samples}/src/main/res/mipmap-xhdpi/ic_launcher.webp (100%) rename {app => samples}/src/main/res/mipmap-xhdpi/ic_launcher_round.webp (100%) rename {app => samples}/src/main/res/mipmap-xxhdpi/ic_launcher.webp (100%) rename {app => samples}/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp (100%) rename {app => samples}/src/main/res/mipmap-xxxhdpi/ic_launcher.webp (100%) rename {app => samples}/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp (100%) create mode 100644 samples/src/main/res/navigation/nav_graph_java.xml create mode 100644 samples/src/main/res/navigation/nav_graph_kotlin.xml rename {app => samples}/src/main/res/values-night/themes.xml (100%) create mode 100644 samples/src/main/res/values-zh-rCN/arrays.xml create mode 100644 samples/src/main/res/values-zh-rCN/strings.xml create mode 100644 samples/src/main/res/values/arrays.xml rename {app => samples}/src/main/res/values/colors.xml (100%) create mode 100644 samples/src/main/res/values/strings.xml rename {app => samples}/src/main/res/values/themes.xml (100%) rename {app => samples}/src/main/res/xml/network_security_config.xml (100%) rename {app => samples}/src/test/java/org/sheedon/app/ExampleUnitTest.kt (100%) diff --git a/app/src/main/java/org/sheedon/app/MainActivity.kt b/app/src/main/java/org/sheedon/app/MainActivity.kt deleted file mode 100644 index 1b23b15..0000000 --- a/app/src/main/java/org/sheedon/app/MainActivity.kt +++ /dev/null @@ -1,76 +0,0 @@ -package org.sheedon.app - -import androidx.appcompat.app.AppCompatActivity -import android.os.Bundle -import android.util.Log -import android.view.View -import org.json.JSONException -import org.json.JSONObject -import org.sheedon.app.factory.MqttClient -import org.sheedon.mqtt.* - -class MainActivity : AppCompatActivity() { - - val client: OkMqttClient = MqttClient.getInstance().getClient()!! - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - setContentView(R.layout.activity_main) - - val request: Request = Request.Builder() - .backTopic("get_manager_list") - .topic("yh_classify/device/recyclable/data/yhkhs20181029046") - .delaySecond(10) - .build() - - val observable = client.newObservable(request) - observable.enqueue(object :Callback{ - override fun onResponse(call: Call, response: Response) { - Log.v("TAG", "response:${response.body}") - } - - override fun onFailure(e: Throwable?) { - Log.v("TAG", "e:$e") - } - - }) - - } - - fun onTouchClick(view: View) { - - val jsonObject = JSONObject() - try { - jsonObject.put("type", "get_manager_list") - jsonObject.put("upStartTime", "") - } catch (e: JSONException) { - e.printStackTrace() - } - - val request = Request.Builder() - .delaySecond(100) - .topic("yh_classify/device/recyclable/data/yhkhs20181029046") - .backTopic("yh_classify/clouds/recyclable/cmd/yhkhs20181029046") -// .keyword("get_manager_list") - .data(jsonObject.toString()) - .build() - - val call = client.newCall(request) - call.enqueue(object :Callback{ - - override fun onResponse(call: Call, response: Response) { - Log.v("TAG", "response:${response.body}") - } - - override fun onFailure(e: Throwable?) { - Log.v("TAG", "e:$e") - } - }) - -// MqttClient.getInstance().getClient()?.subscribe(Topics.build( -// "yh_classify/clouds/recyclable/cmd/yhkhs20181029046", -// 1 -// )) - - } -} \ No newline at end of file diff --git a/app/src/main/java/org/sheedon/app/factory/MqttClient.kt b/app/src/main/java/org/sheedon/app/factory/MqttClient.kt deleted file mode 100644 index 4be49bd..0000000 --- a/app/src/main/java/org/sheedon/app/factory/MqttClient.kt +++ /dev/null @@ -1,61 +0,0 @@ -package org.sheedon.app.factory - -import com.google.gson.Gson -import org.sheedon.app.App -import org.sheedon.mqtt.* -import kotlin.collections.ArrayList - -/** - * java类作用描述 - * @Author: sheedon - * @Email: sheedonsun@163.com - * @Date: 2022/2/1 10:51 上午 - */ -class MqttClient { - - private var mClient: OkMqttClient? = null - - companion object { - private val instance = MqttClient() - - @JvmStatic - fun getInstance() = instance - } - - init { - createClient() - } - - fun getClient() = mClient - - private fun createClient() { - - // 创建MqttClient - val clientId = "**" // 设置设备编号 - val serverUri = "tcp://***" // 设置服务器地址 - val topicsBodies: MutableList = ArrayList() - topicsBodies.add( - Topics.build( - "yh_classify/clouds/garbage/cmd/LJTF2020072001", - 1 - ) - ) // 添加需要订阅主题 - topicsBodies.add( - Topics.build( - "yh_classify/clouds/recyclable/cmd/yhkhs20181029046", - 1 - ) - ) // 添加需要订阅主题 - - if (mClient == null) { - mClient = OkMqttClient.Builder() - .clientInfo(App.instance, serverUri, clientId) - .subscribeBodies(topicsBodies = topicsBodies.toTypedArray()) - .keywordConverter(CallbackNameConverter(Gson())) - .openLog(showMqttLog = true, openRRBindLog = true) - .build() - } - } - - -} \ No newline at end of file diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml deleted file mode 100644 index dd22e60..0000000 --- a/app/src/main/res/layout/activity_main.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml deleted file mode 100644 index 61e5c6a..0000000 --- a/app/src/main/res/values/strings.xml +++ /dev/null @@ -1,3 +0,0 @@ - - app - \ No newline at end of file diff --git a/app/.gitignore b/samples/.gitignore similarity index 100% rename from app/.gitignore rename to samples/.gitignore diff --git a/app/build.gradle b/samples/build.gradle similarity index 68% rename from app/build.gradle rename to samples/build.gradle index 202c92f..e42f7f7 100644 --- a/app/build.gradle +++ b/samples/build.gradle @@ -1,6 +1,7 @@ plugins { id 'com.android.application' id 'kotlin-android' + id 'kotlin-kapt' } android { @@ -29,6 +30,19 @@ android { kotlinOptions { jvmTarget = '1.8' } + sourceSets { + main { + java { + java.srcDirs += 'src/main/kotlin' + } + } + } + + + buildFeatures { + dataBinding true + } + } dependencies { @@ -41,6 +55,16 @@ dependencies { androidTestImplementation 'androidx.test.ext:junit:1.1.2' androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0' + def nav_version = "2.4.2" + + // Java language implementation + implementation "androidx.navigation:navigation-fragment-ktx:$nav_version" + implementation "androidx.navigation:navigation-ui-ktx:$nav_version" + + // Kotlin + implementation "androidx.navigation:navigation-fragment-ktx:$nav_version" + implementation "androidx.navigation:navigation-ui-ktx:$nav_version" + implementation project(':mqtt') // gson implementation 'com.google.code.gson:gson:2.8.6' diff --git a/app/proguard-rules.pro b/samples/proguard-rules.pro similarity index 100% rename from app/proguard-rules.pro rename to samples/proguard-rules.pro diff --git a/app/src/androidTest/java/org/sheedon/app/ExampleInstrumentedTest.kt b/samples/src/androidTest/java/org/sheedon/app/ExampleInstrumentedTest.kt similarity index 100% rename from app/src/androidTest/java/org/sheedon/app/ExampleInstrumentedTest.kt rename to samples/src/androidTest/java/org/sheedon/app/ExampleInstrumentedTest.kt diff --git a/app/src/main/AndroidManifest.xml b/samples/src/main/AndroidManifest.xml similarity index 60% rename from app/src/main/AndroidManifest.xml rename to samples/src/main/AndroidManifest.xml index f5458cd..6cfc7c8 100644 --- a/app/src/main/AndroidManifest.xml +++ b/samples/src/main/AndroidManifest.xml @@ -1,6 +1,6 @@ + package="org.sheedon.app" > + android:theme="@style/Theme.MqttDispatcher" > + android:name="org.sheedon.sample.OkMqttActivity" + android:exported="true" > + + + + + + + \ No newline at end of file diff --git a/samples/src/main/java/org/sheedon/sample/OkMqttActivity.java b/samples/src/main/java/org/sheedon/sample/OkMqttActivity.java new file mode 100644 index 0000000..3b4d099 --- /dev/null +++ b/samples/src/main/java/org/sheedon/sample/OkMqttActivity.java @@ -0,0 +1,21 @@ +package org.sheedon.sample; + +import androidx.appcompat.app.AppCompatActivity; +import androidx.databinding.DataBindingUtil; + +import android.os.Bundle; +import android.view.View; + +import org.sheedon.app.R; + +public class OkMqttActivity extends AppCompatActivity { + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_ok_mqtt); + + // 连接mqtt + OkMqttContributors.getInstance().loadOkMqttClient(this); + } +} \ No newline at end of file diff --git a/samples/src/main/java/org/sheedon/sample/OkMqttContributors.java b/samples/src/main/java/org/sheedon/sample/OkMqttContributors.java new file mode 100644 index 0000000..7411479 --- /dev/null +++ b/samples/src/main/java/org/sheedon/sample/OkMqttContributors.java @@ -0,0 +1,71 @@ +package org.sheedon.sample; + +import android.content.Context; + +import com.google.gson.Gson; + +import org.sheedon.app.factory.CallbackNameConverter; +import org.sheedon.mqtt.OkMqttClient; +import org.sheedon.mqtt.Topics; + +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +/** + * OkMqttClient java code Contributor + * + * @Author: sheedon + * @Email: sheedonsun@163.com + * @Date: 2022/4/25 22:35 + */ +public class OkMqttContributors { + + // current client id + private static final String clientId = UUID.randomUUID().toString(); + // It is recommended that developers change to their own mqtt-Broker +// private static final String serverUri = "tcp://test.mosquitto.org:1883"; + private static final String serverUri = "tcp://broker-cn.emqx.io:1883"; + // Topic to subscribe to by default. + private static final List topicsBodies = new ArrayList() { + { + // Contents in order: topic, message quality, attachRecord + // attachRecord: whether additional records are required, + // if necessary, the subscription will be automatically added after reconnection + add(Topics.build("mq/clouds/cmd/test", 0, true)); + } + }; + + private static final OkMqttContributors instance = new OkMqttContributors(); + + private volatile OkMqttClient okMqttClient; + + public static OkMqttContributors getInstance() { + return instance; + } + + private OkMqttContributors() { + + } + + /** + * 创建OkMqttClient + */ + public OkMqttClient loadOkMqttClient(Context context) { + if (okMqttClient != null) { + return okMqttClient; + } + + Context clientContext = context.getApplicationContext(); + okMqttClient = new OkMqttClient.Builder() + // Configure the basic parameters of mqtt connection + .clientInfo(clientContext, serverUri, clientId) + .subscribeBodies(topicsBodies.toArray(new Topics[0])) + // 作用于关键字关联的响应信息解析器 + .keywordConverter(new CallbackNameConverter(new Gson())) + .build(); + + return okMqttClient; + } + +} diff --git a/samples/src/main/java/org/sheedon/sample/fragment/OkMqttFragment.java b/samples/src/main/java/org/sheedon/sample/fragment/OkMqttFragment.java new file mode 100644 index 0000000..bbdebf3 --- /dev/null +++ b/samples/src/main/java/org/sheedon/sample/fragment/OkMqttFragment.java @@ -0,0 +1,43 @@ +package org.sheedon.sample.fragment; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.databinding.DataBindingUtil; +import androidx.fragment.app.Fragment; +import androidx.navigation.Navigation; +import androidx.navigation.fragment.NavHostFragment; + +import org.sheedon.app.R; +import org.sheedon.app.databinding.FragmentOkMqttBinding; + +/** + * okMqtt使用 + * + * @Author: sheedon + * @Email: sheedonsun@163.com + * @Date: 2022/4/26 22:12 + */ +public class OkMqttFragment extends Fragment { + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + FragmentOkMqttBinding binding = DataBindingUtil.inflate(inflater, R.layout.fragment_ok_mqtt, container, false); + + // 到发送mqtt消息页面 + binding.btnPublishMessage.setOnClickListener(v -> NavHostFragment.findNavController(OkMqttFragment.this).navigate(R.id.action_to_publish_message)); + // 到订阅消息页面 + binding.btnSubscribeTopic.setOnClickListener(v -> NavHostFragment.findNavController(OkMqttFragment.this).navigate(R.id.action_to_subscribe_topic)); + // 到请求响应页面 + binding.btnRr.setOnClickListener(v -> NavHostFragment.findNavController(OkMqttFragment.this).navigate(R.id.action_to_request_and_response)); + // 到订阅一个组页面 + binding.btnSubscribeArray.setOnClickListener(v -> NavHostFragment.findNavController(OkMqttFragment.this).navigate(R.id.action_to_subscribe_array)); + + return binding.getRoot(); + } +} diff --git a/samples/src/main/java/org/sheedon/sample/fragment/PublishMessageFragment.java b/samples/src/main/java/org/sheedon/sample/fragment/PublishMessageFragment.java new file mode 100644 index 0000000..bf1e221 --- /dev/null +++ b/samples/src/main/java/org/sheedon/sample/fragment/PublishMessageFragment.java @@ -0,0 +1,76 @@ +package org.sheedon.sample.fragment; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.databinding.DataBindingUtil; +import androidx.fragment.app.Fragment; + +import org.sheedon.app.R; +import org.sheedon.app.databinding.FragmentPublishMessageBinding; +import org.sheedon.mqtt.Call; +import org.sheedon.mqtt.OkMqttClient; +import org.sheedon.mqtt.Request; +import org.sheedon.sample.OkMqttContributors; + +import java.util.Objects; + +/** + * 提交Mqtt message 消息 + * + * @Author: sheedon + * @Email: sheedonsun@163.com + * @Date: 2022/4/26 22:07 + */ +public class PublishMessageFragment extends Fragment { + + @Override + public void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + requireActivity().setTitle(R.string.label_publish_message); + } + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + FragmentPublishMessageBinding binding = DataBindingUtil.inflate(inflater, R.layout.fragment_publish_message, container, false); + + // 提交mqtt消息 + binding.btnPublish.setOnClickListener(v -> + publish(binding.etTopic.getText().toString(), + binding.spinnerQos.getSelectedItem().toString(), + binding.spinnerRetain.getSelectedItem().toString(), + binding.etMessage.getText().toString())); + + + return binding.getRoot(); + } + + /** + * 发送Mqtt消息请求 + * + * @param topic 主题 + * @param qos 消息质量 + * @param retain 是否保留 + * @param message 消息 + */ + private void publish(String topic, String qos, String retain, String message) { + int qosValue = Integer.parseInt(qos); + boolean retainValue = Objects.equals(retain, "true"); + + OkMqttClient client = OkMqttContributors.getInstance().loadOkMqttClient(getContext()); + + // 构建请求类 + Request request = new Request.Builder() + .topic(topic, qosValue, retainValue) + .data(message) + .build(); + // 得到Call + Call call = client.newCall(request); + call.publish(); + } +} diff --git a/samples/src/main/java/org/sheedon/sample/fragment/RequestAndResponseFragment.java b/samples/src/main/java/org/sheedon/sample/fragment/RequestAndResponseFragment.java new file mode 100644 index 0000000..927eae4 --- /dev/null +++ b/samples/src/main/java/org/sheedon/sample/fragment/RequestAndResponseFragment.java @@ -0,0 +1,104 @@ +package org.sheedon.sample.fragment; + +import android.os.Bundle; +import android.text.Editable; +import android.text.TextUtils; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Toast; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.databinding.DataBindingUtil; +import androidx.fragment.app.Fragment; + +import org.sheedon.app.R; +import org.sheedon.app.databinding.FragmentRequestResponseBinding; +import org.sheedon.mqtt.Call; +import org.sheedon.mqtt.Callback; +import org.sheedon.mqtt.Observable; +import org.sheedon.mqtt.OkMqttClient; +import org.sheedon.mqtt.Request; +import org.sheedon.mqtt.Response; +import org.sheedon.sample.OkMqttContributors; +import org.sheedon.sample.viewmodel.SubscribeTopicViewModel; + +import java.util.Objects; + +/** + * mqtt请求响应 + * + * @Author: sheedon + * @Email: sheedonsun@163.com + * @Date: 2022/4/26 22:09 + */ +public class RequestAndResponseFragment extends Fragment { + + private FragmentRequestResponseBinding binding; + + private OkMqttClient okMqttClient = OkMqttContributors.getInstance().loadOkMqttClient(getContext()); + + + @Override + public void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + requireActivity().setTitle(R.string.label_request_and_response); + } + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + binding = DataBindingUtil.inflate(inflater, R.layout.fragment_request_response, container, false); + binding.btnPublish.setOnClickListener(v -> requestAndResponse()); + return binding.getRoot(); + } + + private void requestAndResponse() { + Editable topicText = binding.etTopic.getText(); + Editable backTopicText = binding.etBackTopic.getText(); + Editable keywordText = binding.etKeyword.getText(); + + if (topicText == null || TextUtils.isEmpty(topicText.toString())) { + Toast.makeText(getContext(), R.string.hint_topic, Toast.LENGTH_LONG).show(); + return; + } + + if ((backTopicText == null || TextUtils.isEmpty(backTopicText.toString())) + && (keywordText == null || TextUtils.isEmpty(keywordText.toString()))) { + Toast.makeText(getContext(), R.string.hint_topic_keyword, Toast.LENGTH_LONG).show(); + return; + } + String topicStr = backTopicText != null ? backTopicText.toString() : ""; + String keywordStr = keywordText != null ? keywordText.toString() : ""; + + int qosValue = Integer.parseInt(binding.spinnerQos.getSelectedItem().toString()); + boolean retainValue = Objects.equals(binding.spinnerRetain.getSelectedItem().toString(), "true"); + String message = binding.etMessage.getText().toString(); + + OkMqttClient client = OkMqttContributors.getInstance().loadOkMqttClient(getContext()); + + // 构建请求类 + Request request = new Request.Builder() + .topic(topicText.toString(), qosValue, retainValue) + .backTopic(topicStr) + .keyword(keywordStr) + .data(message) + .build(); + // 得到Call + Call call = client.newCall(request); + call.enqueue(new Callback() { + @Override + public void onResponse(@NonNull Call call, @NonNull Response response) { + binding.tvMessage.setText(response.getBody().getData()); + } + + @Override + public void onFailure(@Nullable Throwable e) { + binding.tvMessage.setText(e.toString()); + } + }); + + } + +} diff --git a/samples/src/main/java/org/sheedon/sample/fragment/SubscribeArrayFragment.java b/samples/src/main/java/org/sheedon/sample/fragment/SubscribeArrayFragment.java new file mode 100644 index 0000000..7db5efd --- /dev/null +++ b/samples/src/main/java/org/sheedon/sample/fragment/SubscribeArrayFragment.java @@ -0,0 +1,147 @@ +package org.sheedon.sample.fragment; + +import android.os.Bundle; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.databinding.DataBindingUtil; +import androidx.fragment.app.Fragment; + +import org.eclipse.paho.client.mqttv3.internal.wire.MqttWireMessage; +import org.sheedon.app.R; +import org.sheedon.app.databinding.FragmentSubscribeArrayBinding; +import org.sheedon.mqtt.FullCallback; +import org.sheedon.mqtt.Observable; +import org.sheedon.mqtt.ObservableBack; +import org.sheedon.mqtt.OkMqttClient; +import org.sheedon.mqtt.Relation; +import org.sheedon.mqtt.Response; +import org.sheedon.mqtt.Subscribe; +import org.sheedon.mqtt.SubscribeBack; +import org.sheedon.mqtt.Topics; +import org.sheedon.sample.OkMqttContributors; +import org.sheedon.sample.viewmodel.SubscribeTopicViewModel; + +import java.util.ArrayList; +import java.util.List; + +/** + * 订阅一组主题 + * + * @Author: sheedon + * @Email: sheedonsun@163.com + * @Date: 2022/4/26 22:10 + */ +public class SubscribeArrayFragment extends Fragment { + + private FragmentSubscribeArrayBinding binding; + private SubscribeTopicViewModel viewModel = new SubscribeTopicViewModel(); + + private Observable observable; + + private OkMqttClient okMqttClient = OkMqttContributors.getInstance().loadOkMqttClient(getContext()); + + @Override + public void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + requireActivity().setTitle(R.string.label_subscribe_topic_array); + } + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + binding = DataBindingUtil.inflate(inflater, R.layout.fragment_subscribe_array, container, false); + binding.setVm(viewModel); + binding.button.setOnClickListener(v -> subscribeAndUnSubscribe()); + return binding.getRoot(); + } + + private void subscribeAndUnSubscribe() { + boolean isSubscribe = viewModel.isSubscribe.get(); + if (!isSubscribe) { + subscribe(); + return; + } + + observable.cancel(); + viewModel.isSubscribe.set(false); + } + + private void subscribe() { + + viewModel.isSubscribe.set(true); + + // 单一关联内容 + Relation relation = new Relation.Builder() + .topics(new Topics("sheedon/open_ack")) + .build(); + + // 关联集合 + List relations = new ArrayList() { + { + add(new Relation.Builder().topics(new Topics("sheedon/alarm_ack")).build()); + add(new Relation.Builder().keyword("test_ack").build()); + } + }; + + // 订阅对象 + Subscribe subscribe = new Subscribe.Builder() + // 标准配置 + .add("sheedon/test_ack") + // 通过Relation配置 + .add(relation) + // 添加Relation集合 + .addAll(relations) + .build(); + + observable = okMqttClient.newObservable(subscribe); + // 订阅全监听,响应+订阅+错误 + observable.enqueue(new FullCallback() { + @Override + public void onResponse(@NonNull Observable observable, @NonNull Response response) { + binding.tvMessage.setText(response.getBody().getData()); + } + + @Override + public void onResponse(@Nullable MqttWireMessage response) { + binding.tvMessage.setText(response != null ? response.toString() : "onResponse"); + } + + @Override + public void onFailure(@Nullable Throwable e) { + binding.tvMessage.setText(e.getMessage()); + } + }); + + // 订阅响应信息监听 +// observable.enqueue(new ObservableBack() { +// @Override +// public void onResponse(@NonNull Observable observable, @NonNull Response response) { +// +// } +// +// @Override +// public void onFailure(@Nullable Throwable e) { +// +// } +// }); + + // 订阅情况监听 +// observable.enqueue(new SubscribeBack() { +// @Override +// public void onResponse(@Nullable MqttWireMessage response) { +// +// } +// +// @Override +// public void onFailure(@Nullable Throwable e) { +// +// } +// }); + + } +} diff --git a/samples/src/main/java/org/sheedon/sample/fragment/SubscribeTopicFragment.java b/samples/src/main/java/org/sheedon/sample/fragment/SubscribeTopicFragment.java new file mode 100644 index 0000000..d000803 --- /dev/null +++ b/samples/src/main/java/org/sheedon/sample/fragment/SubscribeTopicFragment.java @@ -0,0 +1,101 @@ +package org.sheedon.sample.fragment; + +import android.os.Bundle; +import android.text.Editable; +import android.text.TextUtils; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Toast; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.databinding.DataBindingUtil; +import androidx.fragment.app.Fragment; + +import org.sheedon.app.R; +import org.sheedon.app.databinding.FragmentSubscribeTopicBinding; +import org.sheedon.mqtt.Observable; +import org.sheedon.mqtt.ObservableBack; +import org.sheedon.mqtt.OkMqttClient; +import org.sheedon.mqtt.Request; +import org.sheedon.mqtt.Response; +import org.sheedon.sample.OkMqttContributors; +import org.sheedon.sample.viewmodel.SubscribeTopicViewModel; + +/** + * 订阅一个主题 + * + * @Author: sheedon + * @Email: sheedonsun@163.com + * @Date: 2022/4/26 22:09 + */ +public class SubscribeTopicFragment extends Fragment { + + private FragmentSubscribeTopicBinding binding; + private SubscribeTopicViewModel viewModel = new SubscribeTopicViewModel(); + + private Observable observable; + + private OkMqttClient okMqttClient = OkMqttContributors.getInstance().loadOkMqttClient(getContext()); + + @Override + public void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + requireActivity().setTitle(R.string.label_subscribe_topic); + } + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + binding = DataBindingUtil.inflate(inflater, R.layout.fragment_subscribe_topic, container, false); + binding.setVm(viewModel); + binding.button.setOnClickListener(v -> subscribeAndUnSubscribe()); + return binding.getRoot(); + } + + private void subscribeAndUnSubscribe() { + boolean isSubscribe = viewModel.isSubscribe.get(); + if (!isSubscribe) { + subscribe(); + return; + } + + observable.cancel(); + viewModel.isSubscribe.set(false); + } + + private void subscribe() { + + Editable topicText = binding.etTopic.getText(); + Editable keywordText = binding.etKeyword.getText(); + if ((topicText == null || TextUtils.isEmpty(topicText.toString())) + && (keywordText == null || TextUtils.isEmpty(keywordText.toString()))) { + Toast.makeText(getContext(), R.string.hint_topic_keyword, Toast.LENGTH_LONG).show(); + return; + } + + viewModel.isSubscribe.set(true); + + String topicStr = topicText != null ? topicText.toString() : ""; + String keywordStr = keywordText != null ? keywordText.toString() : ""; + + Request request = new Request.Builder() + .backTopic(topicStr) + .keyword(keywordStr) + .build(); + + observable = okMqttClient.newObservable(request); + observable.enqueue(new ObservableBack() { + @Override + public void onResponse(@NonNull Observable observable, @NonNull Response response) { + binding.tvMessage.setText(response.getBody().getData()); + } + + @Override + public void onFailure(@Nullable Throwable e) { + + } + }); + } +} diff --git a/samples/src/main/java/org/sheedon/sample/viewmodel/SubscribeTopicViewModel.java b/samples/src/main/java/org/sheedon/sample/viewmodel/SubscribeTopicViewModel.java new file mode 100644 index 0000000..6f9132d --- /dev/null +++ b/samples/src/main/java/org/sheedon/sample/viewmodel/SubscribeTopicViewModel.java @@ -0,0 +1,16 @@ +package org.sheedon.sample.viewmodel; + +import androidx.databinding.ObservableBoolean; +import androidx.lifecycle.ViewModel; + +/** + * java类作用描述 + * + * @Author: sheedon + * @Email: sheedonsun@163.com + * @Date: 2022/4/27 22:00 + */ +public class SubscribeTopicViewModel extends ViewModel { + + public ObservableBoolean isSubscribe = new ObservableBoolean(false); +} diff --git a/app/src/main/java/org/sheedon/app/App.kt b/samples/src/main/kotlin/org/sheedon/app/App.kt similarity index 95% rename from app/src/main/java/org/sheedon/app/App.kt rename to samples/src/main/kotlin/org/sheedon/app/App.kt index af6d49f..c65a20b 100644 --- a/app/src/main/java/org/sheedon/app/App.kt +++ b/samples/src/main/kotlin/org/sheedon/app/App.kt @@ -13,6 +13,7 @@ class App : Application() { companion object { + @JvmStatic lateinit var instance: Application private set } diff --git a/samples/src/main/kotlin/org/sheedon/app/MainActivity.kt b/samples/src/main/kotlin/org/sheedon/app/MainActivity.kt new file mode 100644 index 0000000..c61e2bf --- /dev/null +++ b/samples/src/main/kotlin/org/sheedon/app/MainActivity.kt @@ -0,0 +1,18 @@ +package org.sheedon.app + +import androidx.appcompat.app.AppCompatActivity +import android.os.Bundle +import org.sheedon.app.factory.MqttClient + +class MainActivity : AppCompatActivity() { + + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(R.layout.activity_main) + + // 连接mqtt + MqttClient.getInstance().loadOkMqttClient(this) + + } +} \ No newline at end of file diff --git a/app/src/main/java/org/sheedon/app/RspModel.kt b/samples/src/main/kotlin/org/sheedon/app/RspModel.kt similarity index 100% rename from app/src/main/java/org/sheedon/app/RspModel.kt rename to samples/src/main/kotlin/org/sheedon/app/RspModel.kt diff --git a/app/src/main/java/org/sheedon/app/factory/CallbackNameConverter.kt b/samples/src/main/kotlin/org/sheedon/app/factory/CallbackNameConverter.kt similarity index 100% rename from app/src/main/java/org/sheedon/app/factory/CallbackNameConverter.kt rename to samples/src/main/kotlin/org/sheedon/app/factory/CallbackNameConverter.kt diff --git a/samples/src/main/kotlin/org/sheedon/app/factory/MqttClient.kt b/samples/src/main/kotlin/org/sheedon/app/factory/MqttClient.kt new file mode 100644 index 0000000..95b3890 --- /dev/null +++ b/samples/src/main/kotlin/org/sheedon/app/factory/MqttClient.kt @@ -0,0 +1,56 @@ +package org.sheedon.app.factory + +import android.content.Context +import com.google.gson.Gson +import org.sheedon.mqtt.OkMqttClient +import org.sheedon.mqtt.Topics +import org.sheedon.mqtt.Topics.Companion.build +import java.util.* + +/** + * java类作用描述 + * @Author: sheedon + * @Email: sheedonsun@163.com + * @Date: 2022/2/1 10:51 上午 + */ +class MqttClient { + + private var mClient: OkMqttClient? = null + + companion object { + private val instance = MqttClient() + + @JvmStatic + fun getInstance() = instance + + // current client id + private val clientId = UUID.randomUUID().toString() + + // It is recommended that developers change to their own mqtt-Broker + // private static final String serverUri = "tcp://test.mosquitto.org:1883"; + private const val serverUri = "tcp://broker-cn.emqx.io:1883" + + // Topic to subscribe to by default. + private val topicsBodies: List = mutableListOf(build("mq/clouds/cmd/test", 0, true)) + } + + /** + * 创建OkMqttClient + */ + fun loadOkMqttClient(context: Context): OkMqttClient { + if (mClient != null) { + return mClient!! + } + val clientContext = context.applicationContext + mClient = OkMqttClient.Builder() // Configure the basic parameters of mqtt connection + .clientInfo(clientContext, serverUri, clientId) + // 作用于关键字关联的响应信息解析器 + .subscribeBodies(topicsBodies = topicsBodies.toTypedArray()) + .keywordConverter(CallbackNameConverter(Gson())) + .openLog(true) + .build() + return mClient!! + } + + +} \ No newline at end of file diff --git a/samples/src/main/kotlin/org/sheedon/app/fragment/OkMqttFragment.kt b/samples/src/main/kotlin/org/sheedon/app/fragment/OkMqttFragment.kt new file mode 100644 index 0000000..a0e70ce --- /dev/null +++ b/samples/src/main/kotlin/org/sheedon/app/fragment/OkMqttFragment.kt @@ -0,0 +1,53 @@ +package org.sheedon.app.fragment + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.databinding.DataBindingUtil +import androidx.fragment.app.Fragment +import androidx.navigation.NavController +import androidx.navigation.fragment.NavHostFragment +import org.sheedon.app.R +import org.sheedon.app.databinding.FragmentOkMqttBinding + +/** + * okMqtt使用 + * + * @Author: sheedon + * @Email: sheedonsun@163.com + * @Date: 2022/4/26 22:12 + */ +class OkMqttFragment : Fragment() { + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + val binding: FragmentOkMqttBinding = + DataBindingUtil.inflate(inflater, R.layout.fragment_ok_mqtt, container, false) + + // 到发送mqtt消息页面 + binding.btnPublishMessage.setOnClickListener { + nav().navigate(R.id.action_to_publish_message) + } + // 到订阅消息页面 + binding.btnSubscribeTopic.setOnClickListener { + nav().navigate(R.id.action_to_subscribe_topic) + } + // 到请求响应页面 + binding.btnRr.setOnClickListener { + nav().navigate(R.id.action_to_request_and_response) + } + // 到订阅一个组页面 + binding.btnSubscribeArray.setOnClickListener { + nav().navigate(R.id.action_to_subscribe_array) + } + + return binding.root + } + + private fun nav(): NavController { + return NavHostFragment.findNavController(this) + } +} \ No newline at end of file diff --git a/samples/src/main/kotlin/org/sheedon/app/fragment/PublishMessageFragment.kt b/samples/src/main/kotlin/org/sheedon/app/fragment/PublishMessageFragment.kt new file mode 100644 index 0000000..d45ebe7 --- /dev/null +++ b/samples/src/main/kotlin/org/sheedon/app/fragment/PublishMessageFragment.kt @@ -0,0 +1,69 @@ +package org.sheedon.app.fragment + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.databinding.DataBindingUtil +import androidx.fragment.app.Fragment +import org.sheedon.app.R +import org.sheedon.app.databinding.FragmentPublishMessageBinding +import org.sheedon.app.factory.MqttClient +import org.sheedon.mqtt.* + +/** + * 提交Mqtt message 消息 + * + * @Author: sheedon + * @Email: sheedonsun@163.com + * @Date: 2022/4/26 22:07 + */ +class PublishMessageFragment : Fragment() { + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + requireActivity().setTitle(R.string.label_publish_message) + } + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + val binding: FragmentPublishMessageBinding = + DataBindingUtil.inflate(inflater, R.layout.fragment_publish_message, container, false) + + // 提交mqtt消息 + binding.btnPublish.setOnClickListener { + publish( + binding.etTopic.text.toString(), + binding.spinnerQos.selectedItem.toString(), + binding.spinnerRetain.selectedItem.toString(), + binding.etMessage.text.toString() + ) + } + return binding.root + } + + /** + * 发送Mqtt消息请求 + * + * @param topic 主题 + * @param qos 消息质量 + * @param retain 是否保留 + * @param message 消息 + */ + private fun publish(topic: String, qos: String, retain: String, message: String) { + val qosValue = qos.toInt() + val retainValue = retain == "true" + val client = MqttClient.getInstance().loadOkMqttClient(requireContext()) + + // 构建请求类 + val request = Request.Builder() + .topic(topic, qosValue, retainValue) + .data(message) + .build() + // 得到Call + val call = client.newCall(request) + call.publish() + } +} \ No newline at end of file diff --git a/samples/src/main/kotlin/org/sheedon/app/fragment/RequestAndResponseFragment.kt b/samples/src/main/kotlin/org/sheedon/app/fragment/RequestAndResponseFragment.kt new file mode 100644 index 0000000..e4d41c5 --- /dev/null +++ b/samples/src/main/kotlin/org/sheedon/app/fragment/RequestAndResponseFragment.kt @@ -0,0 +1,90 @@ +package org.sheedon.app.fragment + +import android.os.Bundle +import android.text.TextUtils +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.Toast +import androidx.databinding.DataBindingUtil +import androidx.fragment.app.Fragment +import org.sheedon.app.R +import org.sheedon.app.databinding.FragmentRequestResponseBinding +import org.sheedon.app.factory.MqttClient +import org.sheedon.mqtt.* + +/** + * mqtt请求响应 + * + * @Author: sheedon + * @Email: sheedonsun@163.com + * @Date: 2022/4/26 22:09 + */ +class RequestAndResponseFragment : Fragment() { + + private lateinit var binding: FragmentRequestResponseBinding + private val okMqttClient = MqttClient.getInstance().loadOkMqttClient(requireContext()) + + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + requireActivity().setTitle(R.string.label_request_and_response) + } + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + binding = + DataBindingUtil.inflate(inflater, R.layout.fragment_request_response, container, false) + binding.btnPublish.setOnClickListener { requestAndResponse() } + + return binding.root + } + + private fun requestAndResponse() { + val topicText = binding.etTopic.text + val backTopicText = binding.etBackTopic.text + val keywordText = binding.etKeyword.text + if (topicText == null || TextUtils.isEmpty(topicText.toString())) { + Toast.makeText(context, R.string.hint_topic, Toast.LENGTH_LONG).show() + return + } + if ((backTopicText == null || TextUtils.isEmpty(backTopicText.toString())) + && (keywordText == null || TextUtils.isEmpty(keywordText.toString())) + ) { + Toast.makeText(context, R.string.hint_topic_keyword, Toast.LENGTH_LONG).show() + return + } + + val topicStr = backTopicText?.toString() ?: "" + val keywordStr = keywordText?.toString() ?: "" + val qosValue = binding.spinnerQos.selectedItem.toString().toInt() + val retainValue = binding.spinnerRetain.selectedItem.toString() == "true" + val message = binding.etMessage.text.toString() + + + val client = MqttClient.getInstance().loadOkMqttClient(requireContext()) + + // 构建请求类 + val request = Request.Builder() + .topic(topicText.toString(), qosValue, retainValue) + .backTopic(topicStr) + .keyword(keywordStr) + .data(message) + .build() + + // 得到Call + val call = client.newCall(request) + call.enqueue(object : Callback { + override fun onResponse(call: Call, response: Response) { + binding.tvMessage.text = response.body!!.data + } + + override fun onFailure(e: Throwable?) { + binding.tvMessage.text = e.toString() + } + }) + } +} \ No newline at end of file diff --git a/samples/src/main/kotlin/org/sheedon/app/fragment/SubscribeArrayFragment.kt b/samples/src/main/kotlin/org/sheedon/app/fragment/SubscribeArrayFragment.kt new file mode 100644 index 0000000..f0deeae --- /dev/null +++ b/samples/src/main/kotlin/org/sheedon/app/fragment/SubscribeArrayFragment.kt @@ -0,0 +1,124 @@ +package org.sheedon.app.fragment + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.databinding.DataBindingUtil +import androidx.fragment.app.Fragment +import org.sheedon.sample.viewmodel.SubscribeTopicViewModel +import org.eclipse.paho.client.mqttv3.internal.wire.MqttWireMessage +import org.sheedon.app.R +import org.sheedon.app.databinding.FragmentSubscribeArrayBinding +import org.sheedon.app.factory.MqttClient +import org.sheedon.mqtt.* + +/** + * 订阅一组主题 + * + * @Author: sheedon + * @Email: sheedonsun@163.com + * @Date: 2022/4/26 22:10 + */ +class SubscribeArrayFragment : Fragment() { + + + private lateinit var binding: FragmentSubscribeArrayBinding + private val viewModel = SubscribeTopicViewModel() + private var observable: Observable? = null + private val okMqttClient = MqttClient.getInstance().loadOkMqttClient(requireContext()) + + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + requireActivity().setTitle(R.string.label_subscribe_topic_array) + } + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + binding = + DataBindingUtil.inflate(inflater, R.layout.fragment_subscribe_array, container, false) + binding.vm = viewModel + binding.button.setOnClickListener { subscribeAndUnSubscribe() } + return binding.root + } + + private fun subscribeAndUnSubscribe() { + val isSubscribe = viewModel.isSubscribe.get() + if (!isSubscribe) { + subscribe() + return + } + observable?.cancel() + viewModel.isSubscribe.set(false) + } + + private fun subscribe() { + viewModel.isSubscribe.set(true) + + // 单一关联内容 + val relation = Relation.Builder() + .topics(Topics("sheedon/open_ack")) + .build() + + // 关联集合 + val relations: List = arrayListOf( + Relation.Builder().topics(Topics("sheedon/alarm_ack")).build(), + Relation.Builder().keyword("test_ack").build() + ) + + // 订阅对象 + val subscribe = Subscribe.Builder() // 标准配置 + .add("sheedon/test_ack") // 通过Relation配置 + .add(relation) // 添加Relation集合 + .addAll(relations) + .build() + + + observable = okMqttClient.newObservable(subscribe) + + // 订阅全监听,响应+订阅+错误 + observable!!.enqueue(object : FullCallback { + override fun onResponse(observable: Observable, response: Response) { + binding.tvMessage.text = response.body!!.data + } + + override fun onResponse(response: MqttWireMessage?) { + binding.tvMessage.text = response?.toString() ?: "onResponse" + } + + override fun onFailure(e: Throwable?) { + binding.tvMessage.text = e!!.message + } + }) + + // 订阅响应信息监听 +// observable.enqueue(new ObservableBack() { +// @Override +// public void onResponse(@NonNull Observable observable, @NonNull Response response) { +// +// } +// +// @Override +// public void onFailure(@Nullable Throwable e) { +// +// } +// }); + + // 订阅情况监听 +// observable.enqueue(new SubscribeBack() { +// @Override +// public void onResponse(@Nullable MqttWireMessage response) { +// +// } +// +// @Override +// public void onFailure(@Nullable Throwable e) { +// +// } +// }); + } +} \ No newline at end of file diff --git a/samples/src/main/kotlin/org/sheedon/app/fragment/SubscribeTopicFragment.kt b/samples/src/main/kotlin/org/sheedon/app/fragment/SubscribeTopicFragment.kt new file mode 100644 index 0000000..aa6b82f --- /dev/null +++ b/samples/src/main/kotlin/org/sheedon/app/fragment/SubscribeTopicFragment.kt @@ -0,0 +1,88 @@ +package org.sheedon.app.fragment + +import android.os.Bundle +import android.text.TextUtils +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.Toast +import androidx.databinding.DataBindingUtil +import androidx.fragment.app.Fragment +import org.sheedon.sample.viewmodel.SubscribeTopicViewModel +import org.sheedon.app.R +import org.sheedon.app.databinding.FragmentSubscribeTopicBinding +import org.sheedon.app.factory.MqttClient +import org.sheedon.mqtt.* + +/** + * 订阅一个主题 + * + * @Author: sheedon + * @Email: sheedonsun@163.com + * @Date: 2022/4/26 22:09 + */ +class SubscribeTopicFragment : Fragment() { + + private lateinit var binding: FragmentSubscribeTopicBinding + private val viewModel = SubscribeTopicViewModel() + private var observable: Observable? = null + private val okMqttClient = MqttClient.getInstance().loadOkMqttClient(requireContext()) + + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + requireActivity().setTitle(R.string.label_subscribe_topic) + } + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + binding = + DataBindingUtil.inflate(inflater, R.layout.fragment_subscribe_topic, container, false) + binding.vm = viewModel + binding.button.setOnClickListener { subscribeAndUnSubscribe() } + return binding.root + } + + private fun subscribeAndUnSubscribe() { + val isSubscribe = viewModel.isSubscribe.get() + if (!isSubscribe) { + subscribe() + return + } + observable!!.cancel() + viewModel.isSubscribe.set(false) + } + + private fun subscribe() { + val topicText = binding.etTopic.text + val keywordText = binding.etKeyword.text + if ((topicText == null || TextUtils.isEmpty(topicText.toString())) + && (keywordText == null || TextUtils.isEmpty(keywordText.toString())) + ) { + Toast.makeText(context, R.string.hint_topic_keyword, Toast.LENGTH_LONG).show() + return + } + + viewModel.isSubscribe.set(true) + val topicStr = topicText?.toString() ?: "" + val keywordStr = keywordText?.toString() ?: "" + val request = Request.Builder() + .backTopic(topicStr) + .keyword(keywordStr) + .build() + + + observable = okMqttClient.newObservable(request) + + observable?.enqueue(object : ObservableBack { + override fun onResponse(observable: Observable, response: Response) { + binding.tvMessage.text = response.body!!.data + } + + override fun onFailure(e: Throwable?) {} + }) + } +} \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/samples/src/main/res/drawable-v24/ic_launcher_foreground.xml similarity index 100% rename from app/src/main/res/drawable-v24/ic_launcher_foreground.xml rename to samples/src/main/res/drawable-v24/ic_launcher_foreground.xml diff --git a/app/src/main/res/drawable/ic_launcher_background.xml b/samples/src/main/res/drawable/ic_launcher_background.xml similarity index 100% rename from app/src/main/res/drawable/ic_launcher_background.xml rename to samples/src/main/res/drawable/ic_launcher_background.xml diff --git a/samples/src/main/res/layout/activity_main.xml b/samples/src/main/res/layout/activity_main.xml new file mode 100644 index 0000000..751301b --- /dev/null +++ b/samples/src/main/res/layout/activity_main.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/samples/src/main/res/layout/activity_ok_mqtt.xml b/samples/src/main/res/layout/activity_ok_mqtt.xml new file mode 100644 index 0000000..225cec7 --- /dev/null +++ b/samples/src/main/res/layout/activity_ok_mqtt.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/samples/src/main/res/layout/fragment_ok_mqtt.xml b/samples/src/main/res/layout/fragment_ok_mqtt.xml new file mode 100644 index 0000000..d51e135 --- /dev/null +++ b/samples/src/main/res/layout/fragment_ok_mqtt.xml @@ -0,0 +1,42 @@ + + + + + + + + + + +