使用 MQTT Android 服务从飞行模式重新连接

2024-01-05

我正在实现此处找到的 Dale Lane MQTT Android 服务示例http://dalelane.co.uk/blog/?p=1599 http://dalelane.co.uk/blog/?p=1599,这个例子对于我的特定目的来说工作得很好,但是我正在处理一个我似乎无法解决的问题。

经过相当广泛的测试,我发现手机完全失去连接后该服务不会重新连接。例如,如果手机处于飞行模式然后退出飞行模式,该服务将继续尝试 connectToBroker() 但永远不会连接。

如果我按下主屏幕上的“连接”按钮,该应用程序会正确连接,该按钮会使用给定的主机/主题参数启动服务。

我该如何解决这个问题?该应用程序从 Wifi 网络重新连接没有问题,反之亦然。

02-16 12:19:39.348: E/mqtt(23628): ping failed - MQTT exception
02-16 12:19:39.348: E/mqtt(23628): com.ibm.mqtt.MqttNotConnectedException
02-16 12:19:39.348: E/mqtt(23628):  at com.ibm.mqtt.Mqtt.writePacket(Unknown Source)
02-16 12:19:39.348: E/mqtt(23628):  at com.ibm.mqtt.Mqtt.pingOut(Unknown Source)
02-16 12:19:39.348: E/mqtt(23628):  at com.ibm.mqtt.MqttClient.ping(Unknown Source)
02-16 12:19:39.348: E/mqtt(23628):  at com.limosys.limosystestmqtt.MQTTService$PingSender.onReceive(MQTTService.java:919)
02-16 12:19:39.348: E/mqtt(23628):  at android.app.LoadedApk$ReceiverDispatcher$Args.run(LoadedApk.java:778)
02-16 12:19:39.348: E/mqtt(23628):  at android.os.Handler.handleCallback(Handler.java:733)
02-16 12:19:39.348: E/mqtt(23628):  at android.os.Handler.dispatchMessage(Handler.java:95)
02-16 12:19:39.348: E/mqtt(23628):  at android.os.Looper.loop(Looper.java:136)
02-16 12:19:39.348: E/mqtt(23628):  at android.app.ActivityThread.main(ActivityThread.java:5105)
02-16 12:19:39.348: E/mqtt(23628):  at java.lang.reflect.Method.invokeNative(Native Method)
02-16 12:19:39.348: E/mqtt(23628):  at java.lang.reflect.Method.invoke(Method.java:515)
02-16 12:19:39.348: E/mqtt(23628):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:792)
02-16 12:19:39.348: E/mqtt(23628):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:608)
02-16 12:19:39.348: E/mqtt(23628):  at dalvik.system.NativeStart.main(Native Method)

以下是 ping 失败时引发的异常的堆栈跟踪,应用程序将根据给定的 keepAliveSecond 值继续尝试每 10 秒进行连接。

失去连接

/*
   * callback - method called when we no longer have a connection to the message broker server
   */
  public void connectionLost() throws Exception {
    // we protect against the phone switching off while we're doing this
    // by requesting a wake lock - we request the minimum possible wake
    // lock - just enough to keep the CPU running until we've finished
    PowerManager pm = (PowerManager) getSystemService(POWER_SERVICE);
    WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "MQTT");
    wl.acquire();


    //
    // have we lost our data connection?
    //

    if (isOnline() == false) {
      Log.e("CONNECTION LOST", "LOST CONNECTION");
      connectionStatus = MQTTConnectionStatus.NOTCONNECTED_WAITINGFORINTERNET;

      // inform the app that we are not connected any more
      broadcastServiceStatus("Connection lost - no network connection");

      //
      // inform the user (for times when the Activity UI isn't running)
      // that we are no longer able to receive messages
      notifyUser("Connection lost - no network connection", "MQTT",
          "Connection lost - no network connection");

      //
      // wait until the phone has a network connection again, when we
      // the network connection receiver will fire, and attempt another
      // connection to the broker
    } else {
      //
      // we are still online
      // the most likely reason for this connectionLost is that we've
      // switched from wifi to cell, or vice versa
      // so we try to reconnect immediately
      //

      connectionStatus = MQTTConnectionStatus.NOTCONNECTED_UNKNOWNREASON;

      // inform the app that we are not connected any more, and are
      // attempting to reconnect
      broadcastServiceStatus("Connection lost - reconnecting...");

      // try to reconnect
      if (connectToBroker()) {
        subscribeToTopic(topicName);
      }
    }

    // we're finished - if the phone is switched off, it's okay for the CPU
    // to sleep now
    wl.release();
  }

连接至经纪商在服务可用后(即退出飞行模式并连接到 4G/Wifi),此代码会被多次调用

 /*
   * (Re-)connect to the message broker
   */
  private boolean connectToBroker() {
    try {
      // try to connect
      Log.e("CONNECTTOBROKER", "TRYING TO CONNECT");
      Log.e("SERVICE HOST - CONNECT TO BROKER", "" + brokerHostName);
      Log.e("SERVICE TOPIC - CONNECT TO BROKER", "" + topicName);

      mqttClient.connect(generateClientId(), cleanStart, keepAliveSeconds);

      //
      // inform the app that the app has successfully connected
      broadcastServiceStatus("Connected");

      // we are connected
      connectionStatus = MQTTConnectionStatus.CONNECTED;

      // we need to wake up the phone's CPU frequently enough so that the
      // keep alive messages can be sent
      // we schedule the first one of these now
      scheduleNextPing();


      return true;
    } catch (MqttException e) {
      // something went wrong!

      connectionStatus = MQTTConnectionStatus.NOTCONNECTED_UNKNOWNREASON;

      //
      // inform the app that we failed to connect so that it can update
      // the UI accordingly
      broadcastServiceStatus("Unable to connect");

      //
      // inform the user (for times when the Activity UI isn't running)
      // that we failed to connect
      notifyUser("Unable to connect", "MQTT", "Unable to connect - will retry later");

      // if something has failed, we wait for one keep-alive period before
      // trying again
      // in a real implementation, you would probably want to keep count
      // of how many times you attempt this, and stop trying after a
      // certain number, or length of time - rather than keep trying
      // forever.
      // a failure is often an intermittent network issue, however, so
      // some limited retry is a good idea
      scheduleNextPing();

      return false;
    }
  }

从 paho 下载最新的 android 服务 jar(1.02) 和 java 客户端(1.02)。 最新的 Android 服务 jar 已修复此问题。一旦网络连接恢复,它就会负责重新连接。

将其添加到 Activity 的 onResume() 中

mqttclient.registerResources(this);     

这在同一个 Activity 的 onDestroy() 中

mqttclient.unregisterResources();

这对我有用。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 MQTT Android 服务从飞行模式重新连接 的相关文章

  • Java OR 运算符优先级

    如何在 Java 中以 if 的方式链接条件语句b是假的 不如不检查c If a and c是假的 并且b是真的 确实c会被检查吗 if a b c 我正在寻找 PHP 所拥有的类似功能 但两者之间存在差异OR and 爪哇 如果左操作数是
  • Java Sound可以用来控制系统音量吗?

    Java 声音优惠FloatControl各种声音线路功能的实例 以及MASTER GAIN http docs oracle com javase 7 docs api javax sound sampled FloatControl T
  • 如何将两个 APK 合并为一个,以便两个应用程序可以同时安装

    如何将 2 个 Android 应用程序合并到捆绑包中 以便在安装捆绑包时同时安装两个应用程序 我想将 2 个 APK 合并到一个捆绑包中 以便我可以将其上传到 Android Market 当有人将其安装到设备上时 这两个应用程序都应该安
  • 如何从 Jackson 中的自定义解串器调用默认解串器

    我在杰克逊的自定义解串器有问题 我想访问默认序列化器来填充我要反序列化的对象 在填充之后 我将做一些自定义的事情 但首先我想使用默认的 Jackson 行为反序列化对象 这是我目前拥有的代码 public class UserEventDe
  • 从多个地方绘制 JPanel

    我目前正在为学校开发一款 Java 2D 游戏 我们必须使用抽象工厂设计模式 对于 2D 实现 我使用工厂如下 public class Java2DFact extends AbstractFactory public Display d
  • 在 Android 应用程序中使用传单来显示在线地图

    是否有任何示例项目展示如何正确使用传单在 Android 应用程序中显示在线地图 因为我尝试了很多示例 但每次我的应用程序中都有一个空的网络视图 这是我的代码 private WebView mWebView Override protec
  • 使用枚举变量切换字符串

    我有一个具有不同值的枚举 并且想要切换字符串变量 现在 我在尝试将枚举值转换为字符串 可以用作大小写常量 时遇到了困难 我最好的尝试是将枚举转换为字符串数组 但开关似乎不接受数组值作为大小写常量 IntelliJ 说 需要恒定的表达 Enu
  • 字节流和字符流

    请解释一下什么是字节流和字符流 这些究竟意味着什么 Microsoft Word 文档是面向字节的还是面向字符的 Thanks 流是一种顺序访问文件的方式 字节流逐字节访问文件 字节流适用于任何类型的文件 但不太适合文本文件 例如 如果文件
  • 调用 MediaScannerConnection.scanFile 后,MediaStore 内的 Android 缩略图不会刷新

    我正在尝试构建一个类似画廊的应用程序 它将在外部存储上执行以下功能 列出所有包含图像的文件夹 列出所有可供公众使用的图像 不会探测里面的文件Android data 到目前为止 我可以列出所有图像以及包含图像的文件夹 然而 我后来发现这些图
  • android Analytics v4 最简化

    我正在尝试以最简单的方式将谷歌分析连接到我的应用程序 我想实现analytics v4 因为google说他们很快就会强制升级到它 所以我不想做两次同样的工作 在这种情况下 谷歌的教程不是很有效 合并他们在那里所说的内容和我在互联网上找到的
  • 启动 Activity 时自动弹出键盘

    我有一个相对简单的问题 我有一个包含很多 EditText 的活动 当我打开活动时 它会自动聚焦到第一个 EditText 并显示虚拟键盘 我怎样才能防止这种情况发生 在 XML 文件的布局标签中使用此属性 android focusabl
  • 在JAVA中将数据写入.txt文件?

    我想知道是否是在JAVA中将计算的数据写入文本文件 我的 JAVA 代码是一个基于 GUI 的 gpa 计算器 我只想添加一个 JButton 和 ActionListener 它将类名 GPA 点和计算出的 GPA 写入 txt 文件 这
  • 使用 JPA 存储库保留 Spring Batch ItemWriter 的问题

    我对春季批次有疑问ItemWriter它依赖于 JPA 存储库来更新数据 这里是 Component public class MessagesDigestMailerItemWriter implements ItemWriter
  • API级别29 Intent.ACTION_GET_CONTENT从下载文件夹返回错误的ID

    我正在尝试查找从文件选择器意图返回的 URI 的完整文件路径 我从互联网下载了一张图像 该图像保存在浏览器默认下载文件夹中 问题是 DocumentsContract getDocumentId content describer 返回的
  • 有没有办法防止 Spring Boot 覆盖 bean?

    与春天的抽象可刷新应用程序上下文 http docs spring io spring docs current javadoc api org springframework context support AbstractRefresh
  • 如何组织课程、课程包[关闭]

    Closed 这个问题是无关 help closed questions 目前不接受答案 您如何决定包名称应该是什么以及什么类应该放入哪个包中 我正在开发一个项目 在该项目中 我不断添加 删除类 并且不确定我是否需要一个新包 或者应该将其添
  • 无法放置双重 SharedPreferences

    出现错误 这种类型的共享首选项编辑器的 put double 方法未定义 Eclipse 提供了一种快速修复方法 将强制类型转换添加到编辑器 但是当我这样做时 它仍然给出错误 为什么我不能 put double 代码 Override pr
  • 将 .NET 类库(主要定义 CRUD 操作)公开为服务

    公开现有内容的最佳 有效和最快的方法是什么 类 图书馆 主要定义 CRUD 操作 作为service 周转基金服务 or WCF数据服务 以便它可以与银光 or Ajax 在那儿tools 代码生成器 RAD 工具 哪些可以支持这个 预先感
  • 自动将通配符导入重构为 IntelliJ 中的显式导入(适用于 Scala/Java)

    考虑下面的代码 是否可以让 IntelliJ 自动将每个通配符导入重构为显式导入 无论范围内使用什么 例如import scalatags JsDom all into import scalatags JsDom all ol li di
  • 使用 OnContextItemSelected 从 ListView 项目中检索文本

    我有一个带有 经典 上下文菜单的 ListView 其中包含删除和类似选项 由于我要从 SharedPreferences 对象中删除 因此我需要检索键 即设置到 ListView 项目中的文本 我尝试过以下代码 Override publ

随机推荐

  • 如何在 Subversion 下包含/排除某种类型的文件?

    我对包含 排除术语感到困惑 并且我实际的 SVN 客户端似乎没有 或者我无法轻松找到它 一个简单的选项来添加或删除某种类型的文件以进行版本控制 比方说 我已经添加了整个 Visual Studio 文件夹及其解决方案 项目 调试文件等 但我
  • 在 Woocommerce 中结账后更改订单总额

    在用户单击结帐后 我似乎无法找到使用哪个挂钩来更改总数 或购物车的任何变量 例如 用户提交结帐表单 然后我需要进行一些检查并相应地更改总数 我应该怎么做 我应该使用哪个钩子 这可以在woocommerce checkout create o
  • 显示包中所有内容的名称

    Is there an easy way to list everything in a package from within R For example if I type foreach and hit tab twice I can
  • 未找到类异常 - 在 Kohana 3.1 上制作 Helper

    全新安装了 Kohana 3 1 尝试着打造自己的帮手 我在 application classes helpers 目录中创建了一个助手 我已将文件称为 javascript php 该类称为 Helper Javascript 并且有一
  • 如何为所有按钮添加一个事件监听器

    如何向多个按钮添加事件侦听器并根据单击的按钮获取每个按钮的值 例如
  • 为 apache commons 快速傅立叶变换算法构建示例数据

    我想使用 Apache math commons 实现 FFT 快速傅里叶变换器类 来处理一些虚拟数据 这些数据的 8 个数据样本构成一个完整的正弦波 最大振幅为 230 我尝试的代码片段如下 private double transfor
  • 我应该在什么上下文中使用 AlertDialog.Builder?

    谁能解释一下我应该使用 AlertDialog Builder 类的上下文吗 我是 Android 应用程序开发的新手 坦率地说 我不明白何时使用哪个上下文 比如说 我想为 AlertDialog Builder 类创建一个对象 Alert
  • 隐藏 WinForms TreeView 加号

    我有一个 WinForms TreeView 有一个主节点和几个子节点 如何隐藏主节点中的 加号 审查财产 ShowRootLines false When ShowRootLines为 false 时 根节点不会显示加号 减号 但必要时仍
  • 如何以编程方式实现摇动动画?

    如何以编程方式在 android 中实现摇动 摆动动画 有一个AndroidView动画 https github com daimajia AndroidViewAnimations通过这个库我们就可以得到效果了 但我不想为此目的使用任何
  • 导出为 PDF 时表格行没有分页符

    将表格导出为 PDF 时 表格行不会分页 我尝试使用以下方法在每个表行上进行分页 tr 表格行中断如下 导出为 PDF 在浏览器内查看 我希望表行 Vrsta blaga storitve 保持紧凑 因此 单元格不会显示在不可打印区域中 如
  • 如何更改复选框选择时行的背景颜色

    我有 html 表 还有一些带有复选框的行 在选择复选框时 我想用一些背景颜色突出显示该行 table tr td td tr table
  • java.io.FileNotFoundException:/storage/emulated/0/Notes/fact50Result.txt:打开失败的ENOENT(没有这样的文件或目录)

    我正在尝试将阶乘计算的结果导出到 txt 文件中 我发现这段代码从这篇文章中看起来非常简单here https stackoverflow com questions 8152125 how to create text file and
  • 用层次结构和类替换数组可以吗?

    在我的实现中 我应该使用一个长数组 但数组的问题是它的索引对我来说没有多大意义 相反 我想使用层次结构类 然而 有时我需要以批量方式处理它们 例如在计算差异和导数或平均值时 所有成员都是double并且看起来对齐不会产生任何问题 下面是一个
  • MomentJS 设置时区而不更改时间

    我正在尝试在 moment js 中设置日期的时区而不更改时间值 我得到一个 UTC 日期 date toString Sun Sep 27 2015 00 00 00 GMT 0000 我需要设置时区而不更改时间 Sun Sep 27 2
  • WeakHashMap 的 keySet 条目永远不会为空吗?

    如果我迭代 WeakHashMap 的键集 是否需要检查 null 值 WeakHashMap
  • Objective-C++ 的缺点? [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 照片上传 CodeIgniter

    当我使用 CodeIgniter 上传照片时 图像的名称会更改为随机名称 例如 107fb08f4a11cc37a040237cdcf0e48a jpg 我在视图中显示数据库中的图像时遇到问题 因为它显示的是原始上传名称而不是新名称 如何禁
  • Vaadin - 根据内容为表格单元格着色

    我在这里有一个非常基本的示例 我尝试根据该单元格中存在的特定字符串值为特定单元格着色 我输入打印语句 然后点击返回 绿色 返回 橙色 等点 但在运行时我只得到灰色和白色交替的行颜色 而不是我的特定单元格颜色 我使用的 css 是直接从 va
  • Octave 中的折叠功能

    Octave 中的一维向量是否有折叠 减少 聚合等 的标准实现 如果没有 有没有办法在不使用循环语句的情况下表达折叠 The miscellaneous http octave sourceforge net miscellaneous i
  • 使用 MQTT Android 服务从飞行模式重新连接

    我正在实现此处找到的 Dale Lane MQTT Android 服务示例http dalelane co uk blog p 1599 http dalelane co uk blog p 1599 这个例子对于我的特定目的来说工作得很