当前位置: 首页 > news >正文

Android App连接OneNET物联网平台实战:用OkHttp3获取MQTTS设备数据(附完整代码)

Android App连接OneNET物联网平台实战:用OkHttp3获取MQTTS设备数据(附完整代码)

在物联网应用开发中,设备数据的实时获取与展示是核心需求之一。本文将手把手带你完成一个完整的Android应用开发实战,通过OkHttp3库连接OneNET物联网平台,获取MQTTS协议设备数据并展示在UI上。无论你是刚接触物联网开发的Android程序员,还是需要快速集成OneNET平台的经验开发者,这篇指南都能提供可直接复用的代码模块和避坑经验。

1. 项目准备与环境配置

在开始编码前,我们需要完成基础环境配置。不同于简单的网络请求,物联网应用需要特别注意安全配置和权限管理。

首先在AndroidManifest.xml中添加网络权限:

<uses-permission android:name="android.permission.INTERNET" />

对于Android 9.0及以上版本,还需要配置网络安全策略。在res/xml目录下创建network_security_config.xml文件:

<?xml version="1.0" encoding="utf-8"?> <network-security-config> <base-config cleartextTrafficPermitted="true"> <trust-anchors> <certificates src="system" /> </trust-anchors> </base-config> </network-security-config>

然后在AndroidManifest.xml的application标签中引用这个配置:

android:networkSecurityConfig="@xml/network_security_config"

提示:虽然我们允许明文传输(cleartextTrafficPermitted="true")用于开发测试,但生产环境建议使用HTTPS加密通信。

2. 依赖引入与基础架构

我们将使用OkHttp3进行网络请求,在app/build.gradle中添加依赖:

implementation 'com.squareup.okhttp3:okhttp:4.9.3'

最新版本建议查看OkHttp官网。相比原文使用的3.10.0版本,4.x系列在性能和安全性上都有显著提升。

基础Activity布局(activity_main.xml)可以这样设计:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:padding="16dp"> <Button android:id="@+id/btnFetchData" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="获取设备数据" /> <TextView android:id="@+id/tvData1" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="16dp" android:textSize="16sp" /> <!-- 可根据需要添加更多TextView展示不同数据点 --> </LinearLayout>

3. OneNET平台认证机制解析

OneNET平台提供两种主要认证方式:

认证方式适用协议特点有效期
API-KeyHTTP/HTTPS简单直接,在header中传递永久有效
AuthorizationMQTTS需要生成token,安全性更高通常3小时

关键避坑点:对于MQTTS协议设备,必须使用Authorization token认证,API-Key方式将无法获取数据,这是官方文档中未明确说明的重要细节。

Token生成需要使用官方提供的算法,以下是Java版token生成工具类:

import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; import java.nio.charset.StandardCharsets; import java.util.Base64; public class TokenUtil { public static String generateToken(String productId, String deviceId, String accessKey, long expiry) { try { String version = "2022-05-01"; String resource = String.format("products/%s/devices/%s", productId, deviceId); String signatureMethod = "md5"; String data = String.join("\n", version, resource, String.valueOf(expiry), signatureMethod); Mac hmac = Mac.getInstance("HmacSHA1"); SecretKeySpec secretKey = new SecretKeySpec( accessKey.getBytes(StandardCharsets.UTF_8), "HmacSHA1"); hmac.init(secretKey); byte[] hash = hmac.doFinal(data.getBytes(StandardCharsets.UTF_8)); String signature = Base64.getEncoder().encodeToString(hash); return String.format("version=%s&res=%s&et=%d&method=%s&sign=%s", version, resource, expiry, signatureMethod, signature); } catch (Exception e) { e.printStackTrace(); return null; } } }

注意:官方提供的在线token计算工具可能存在兼容性问题,建议使用代码生成token以确保可靠性。

4. 数据请求与UI更新实现

现在我们可以实现核心的数据获取逻辑。在MainActivity中:

public class MainActivity extends AppCompatActivity { private static final String TAG = "OneNETDemo"; private static final String DEVICE_ID = "your_device_id"; private static final String PRODUCT_ID = "your_product_id"; private static final String ACCESS_KEY = "your_access_key"; private OkHttpClient client; private TextView tvData1; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); client = new OkHttpClient(); tvData1 = findViewById(R.id.tvData1); Button btnFetch = findViewById(R.id.btnFetchData); btnFetch.setOnClickListener(v -> fetchDeviceData()); } private void fetchDeviceData() { new Thread(() -> { try { // 生成有效期为1小时的token long expiry = System.currentTimeMillis() / 1000 + 3600; String token = TokenUtil.generateToken( PRODUCT_ID, DEVICE_ID, ACCESS_KEY, expiry); if (token == null) { runOnUiThread(() -> Toast.makeText(this, "Token生成失败", Toast.LENGTH_SHORT).show()); return; } String url = String.format( "https://api.heclouds.com/devices/%s/datapoints?limit=1", DEVICE_ID); Request request = new Request.Builder() .url(url) .addHeader("Authorization", token) .build(); Response response = client.newCall(request).execute(); if (!response.isSuccessful()) { throw new IOException("Unexpected code " + response); } String responseData = response.body().string(); JSONObject json = new JSONObject(responseData); JSONArray datastreams = json.getJSONObject("data") .getJSONArray("datastreams"); // 解析第一个数据流 JSONObject datastream = datastreams.getJSONObject(0); String id = datastream.getString("id"); JSONArray datapoints = datastream.getJSONArray("datapoints"); String value = datapoints.getJSONObject(0).getString("value"); String displayText = String.format("%s: %s", id, value); runOnUiThread(() -> tvData1.setText(displayText)); } catch (Exception e) { Log.e(TAG, "请求失败", e); runOnUiThread(() -> Toast.makeText(this, "请求失败: " + e.getMessage(), Toast.LENGTH_SHORT).show()); } }).start(); } }

5. 高级功能与优化建议

5.1 多数据流处理

实际项目中,设备通常会有多个数据流。我们可以优化代码处理这种情况:

private void processMultipleDatastreams(JSONArray datastreams) { StringBuilder sb = new StringBuilder(); for (int i = 0; i < datastreams.length(); i++) { JSONObject datastream = datastreams.getJSONObject(i); String id = datastream.getString("id"); String value = datastream.getJSONArray("datapoints") .getJSONObject(0).getString("value"); sb.append(String.format("%s: %s\n", id, value)); } runOnUiThread(() -> tvData1.setText(sb.toString())); }

5.2 数据刷新机制

实现定时自动刷新数据:

private final Handler handler = new Handler(); private final Runnable refreshRunnable = new Runnable() { @Override public void run() { fetchDeviceData(); handler.postDelayed(this, 5000); // 每5秒刷新一次 } }; // 在onResume中启动刷新 @Override protected void onResume() { super.onResume(); handler.post(refreshRunnable); } // 在onPause中停止刷新 @Override protected void onPause() { super.onPause(); handler.removeCallbacks(refreshRunnable); }

5.3 错误处理与重试机制

健壮的网络请求需要完善的错误处理:

private void fetchWithRetry(int retryCount) { new Thread(() -> { int attempts = 0; while (attempts < retryCount) { try { fetchDeviceData(); return; } catch (Exception e) { attempts++; if (attempts == retryCount) { runOnUiThread(() -> Toast.makeText(this, "最终请求失败", Toast.LENGTH_SHORT).show()); } else { try { Thread.sleep(2000); // 等待2秒后重试 } catch (InterruptedException ie) { Thread.currentThread().interrupt(); } } } } }).start(); }

6. 性能优化与安全建议

  1. OkHttpClient复用:避免为每个请求创建新实例,使用单例模式管理
  2. 连接池配置:优化HTTP连接管理
  3. 缓存策略:对不常变的数据启用缓存
  4. HTTPS证书校验:生产环境应严格校验服务器证书
  5. 敏感信息保护:不要将设备ID和密钥硬编码在代码中

示例优化后的OkHttpClient配置:

private OkHttpClient createHttpClient() { return new OkHttpClient.Builder() .connectTimeout(10, TimeUnit.SECONDS) .readTimeout(30, TimeUnit.SECONDS) .connectionPool(new ConnectionPool(5, 5, TimeUnit.MINUTES)) .addInterceptor(new HttpLoggingInterceptor().setLevel( BuildConfig.DEBUG ? HttpLoggingInterceptor.Level.BODY : HttpLoggingInterceptor.Level.NONE)) .build(); }

在实际项目中,设备认证信息应该通过安全的方式获取,如后台API或Android Keystore系统。

http://www.jsqmd.com/news/644597/

相关文章:

  • vim9.1.2100的modeline导致的漏洞
  • 从Audition到Python:手把手教你用代码复刻一个参数均衡器(附完整源码)
  • 2026年中子剂量率仪选购指南:为何伽瑞科技是源头厂家的性价比之选 - 品牌推荐大师
  • GEO优化服务商评估:如何选择综合实力与口碑兼备的公司 - 品牌推荐大师1
  • 全国产传感器信号的实时处理-信号校准与标定调试
  • 如何完整解锁Cursor Pro功能:一键激活与无限使用的终极指南
  • 【OSG学习笔记】Day 52: FadeText
  • 去新疆旅游,找对领队太重要!我的真实经历:认准阿木,靠谱又省心 - 速递信息
  • 2026 年 3 月压力变送器十大品牌厂家盘点 - 仪表人小余
  • 终极指南:3分钟彻底卸载Microsoft Edge,还你干净Windows系统 [特殊字符]
  • 终极英雄联盟自动化工具指南:如何用LeagueAkari提升游戏效率与数据安全
  • 网络变压器选型:PoE场景下容易被忽视的三个参数
  • 3步免费获取百度文库文档:无需付费的终极解决方案
  • 【移动通信】从RSRP到SINR:深入解析信号质量评估的关键指标
  • 4月总结:成套气体分析系统哪家性价比高?生产商实力对比 - 品牌推荐大师
  • BDD100K:如何用10万小时驾驶数据解决自动驾驶的“长尾难题“?
  • Speechless:终极微博备份神器,5分钟掌握完整PDF导出指南
  • 2026年市面上水墨印刷开槽机生产商,印刷机/全伺服前缘送纸印刷开槽模切联动线,水墨印刷开槽机制造厂哪家好 - 品牌推荐师
  • 告别AI开发混乱:用Spec Workflow MCP + Cursor/Claude,实现从需求到代码的规范流水线
  • 性价比高的个人出书机构有哪些?2026年五家测评 - 科技焦点
  • 2026年六大租车平台推荐排行榜:车源与保障解析 - 科技焦点
  • 树上DS方法汇总
  • GeographicLib 技术指南:解决高精度地理计算的核心问题与架构解析
  • 如何在数字化课堂中实现自主学习的平衡?JiYuTrainer的教学优化方案
  • 热门的压力变送器厂家哪家靠谱? - 仪表人小余
  • JAVA 1.0 - 基础
  • 中国人饮食结构缺乏那些营养元素呢
  • 5分钟论文降AI实操指南 高效过审不丢核心 - 仙仙学姐测评
  • 2026奇点大会闭门报告首次流出(3D视觉大模型训练成本骤降67%的3个未公开架构设计)
  • 2026 年 3 月压力变送器品牌排行榜:优质生产厂家推荐与性价比选择指南 - 仪表人小余