irpas技术客

华为云IOT Android应用开发详细教程_MR_J.YW_android iot

未知 8324

华为云IOT Android应用开发详细教程 (Android Studio开发) 第〇章??? 简介

? ? ? 大家好,上一期发布的教程叫大家如何利用华为云物联网平台提供的官方Java Demo去编写Java上位机程序,由于主要是用的是GET请求去查询设备影子和查询设备,之后接到了很多小伙伴私信咨询POST请求的实现,现在带着大家,写一个不基于官方Java Demo,而是完全参考于华为云帮助文档去写的一个Android应用,具体用到了POST请求获取鉴权的Token、设备命令下发,Get请求获取设备属性影子数据(依旧是用于解析属性)和查询设备(依旧是用于解析设备在线状态),先给大家看一下最终效果:

第一章??? 提前准备 Android Studio IDE(模拟器可联网)华为云设备接入IOTDAMQTT.fx 第二章??? 详细步骤 ? ? 1. 新建工程

? ?2. 新建一个类,实现我们需要的所有方法 认证鉴权

根据华为云官方提供的帮助文档,我们可以知道,在调用接口前,我们需要完成认证鉴权,我们本次教程采用的是Token认证(帮助文档参考链接:认证鉴权_设备接入 IoTDA_API参考_应用侧API参考_如何调用API_华为云)

?????? 上图的最后一行,我们可以看到,官方给出了一个调用IAM用户Token(使用密码)的帮助信息

????????????? 通过上述界面我们可以知道,该接口的URI以及需要准备的参数,大家可以仔细阅读,教程中我们直接查看页面中的示例:

我们需要准备的参数有:

? IAM用户所属帐号名、IAM用户名、IAM用户密码、项目名称所属

然后我们将准备的参数填入上述的JSON数据体

String postbody="{"+"\""+"auth"+"\""+": {"+"\""+"identity"+"\""+": {"+"\""+"methods"+"\""+": ["+"\""+"password"+"\""+"],"+"\""+"password"+"\""+": {"+"\""+"user"+"\""+":{"+"\""+"domain\": {\"name\": \"********\"},\"name\": \"********\",\"password\": \"********\"}}},\"scope\": {\"project\": {\"name\": \"cn-north-4\"}}}}"; String strurl="https://iam.cn-north-4.myhuaweicloud.com"+"/v3/auth/tokens?nocatalog=false";

现在我们写一个获取token的方法:

public static String gettoken() throws Exception { String postbody="{"+"\""+"auth"+"\""+": {"+"\""+"identity"+"\""+": {"+"\""+"methods"+"\""+": ["+"\""+"password"+"\""+"],"+"\""+"password"+"\""+": {"+"\""+"user"+"\""+":{"+"\""+"domain\": {\"name\": \"********\"},\"name\": \"********\",\"password\": \"********\"}}},\"scope\": {\"project\": {\"name\": \"cn-north-4\"}}}}"; String strurl="https://iam.cn-north-4.myhuaweicloud.com"+"/v3/auth/tokens?nocatalog=false"; URL url = new URL(strurl); HttpURLConnection urlCon = (HttpURLConnection)url.openConnection(); urlCon.addRequestProperty("Content-Type", "application/json;charset=utf8"); urlCon.setDoOutput(true); urlCon.setRequestMethod("POST"); urlCon.setUseCaches(false); urlCon.setInstanceFollowRedirects(true); urlCon.connect(); BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(urlCon.getOutputStream(),"UTF-8")); writer.write(postbody); writer.flush(); writer.close(); Map headers = urlCon.getHeaderFields(); Set<String> keys = headers.keySet(); for( String key : keys ){ String val = urlCon.getHeaderField(key); System.out.println(key+" "+val); } return null; }

然后我们在主函数中调用一下

public httpGetHuaweiIOT()throws Exception { gettoken(); }

我们选择运行

我们检查控制台的输出

接口返回的响应消息头中“X-Subject-Token”就是需要获取的用户Token,此时我们可以修改一下函数,在函数最后加上这两行:

String token = urlCon.getHeaderField("X-Subject-Token"); System.out.println("X-Subject-Token"+" : "+token);

返回值null改为return token;我们再run一下

此时我们的认证鉴权就完事了。(文章后面我们会修改类,把gettoken函数写在类的构造函数内调用)

【延伸】现在的postbody参数时我们写死的,大家也可以把参数做成变量传递进去;由于我们获取的TOKEN是有24小时有效期的,大家也可以学着华为云提供的java Demo在获取token以后去生成token.text文件,当过期时再重新获取,否则直接读取token保存的数据,本教程不在次延伸扩展。

接下来我们完成通过查询设备属性影子来获取设备属性信息。

获取设备影子解析属性

首先我们查看华为云官方提供的帮助文档(https://support.huaweicloud.com/api-iothub/iot_06_v5_0079.html)

????????????? 我们需要的URI

我们可以这么拼接URI

String strurl="https://iotda.cn-north-4.myhuaweicloud.com"+"/v5/iot/%s/devices/%s/shadow"; String project_id="*********"; String device_id="*********"; strurl = String.format(strurl, project_id,device_id);

需要注意的是,除了上述两个必备参数以外,我们的token在这就派上用场了

写程序之前,我们先导入安装一个jackson-databind、jackson-core、jackson-annotations的jar,我用的是jackson-databind-2.8.1.jar、 jackson-core-2.8.1.jar 和jackson-annotations-2.8.1.jar (大家可在网站上搜索下载,或者在文章末尾下载)

我们切换为Java的project目录,在app/libs中粘贴并载入jar包

剩下的两个jar包也是这样操作,如下图所示

然后我们在类头中引入我们用到的路径

接下来我们编写获取设备影子数据函数:

public static String getdev() throws Exception { String strurl="https://iotda.cn-north-4.myhuaweicloud.com"+"/v5/iot/%s/devices/%s/shadow"; String project_id="*********"; String device_id="********* "; strurl = String.format(strurl, project_id,device_id); String token=gettoken(); URL url = new URL(strurl); HttpURLConnection urlCon = (HttpURLConnection)url.openConnection(); urlCon.addRequestProperty("Content-Type", "application/json"); urlCon.addRequestProperty("X-Auth-Token",token); urlCon.connect(); InputStreamReader is = new InputStreamReader(urlCon.getInputStream()); BufferedReader bufferedReader = new BufferedReader(is); StringBuffer strBuffer = new StringBuffer(); String line = null; while ((line = bufferedReader.readLine()) != null) { strBuffer.append(line); } is.close(); urlCon.disconnect(); String result = strBuffer.toString(); System.out.println(result); return null; }

主函数中run一下

public static void main(String[] args)throws Exception { //gettoken(); getdevshadow(); }

我们在控制台可以看到第一行是获取的token,第二行是我们得到的设备影子json数据

大家可以在华为云设备接入IOTDA的控制台修改产品:

我们检查一下我们需要的数据:

在华为云控制台那可以看一下:

为了清楚的查看,我们格式化一下:

其中的“report”->”properties”内的数据为我们要解析的设备属性,我们在函数中加上下面几句进行提取

比如我们获取temp属性

String pro="temp"; ObjectMapper objectMapper = new ObjectMapper(); JsonNode jsonNode = objectMapper.readValue(result, JsonNode.class); JsonNode tempNode = jsonNode.get("shadow").get(0).get("reported").get("properties").get(pro); String attvaluestr = tempNode.asText(); System.out.println(pro+"=" + attvaluestr);

运行一下

为了方便调用,我们改造一下函数定义,给他添上参数,改为:

public static String getdev(String pro) throws Exception{} 主函数这么调用: getdev("temp"); getdev("humi"); getdev("light"); 我们跑一下:

为了能够调用,我们最后要把return null;改为return attvaluestr; 查询设备在线状态

同样我们查看华为云的帮助文档

? ?? 我们可以得主要区别是 URI不同: "https://iotda.cn-north-4.myhuaweicloud.com"+"/v5/iot/%s/devices/%s; 解析的数据不同,我们还是在getdev函数中进行修改,再给他加一个参数,如 public static String getdev(String mode,String pro) throws Exception { String strurl=""; if(mode.equals("shadow")) strurl="https://iotda.cn-north-4.myhuaweicloud.com"+"/v5/iot/%s/devices/%s/shadow"; else if(mode.equals("status")) strurl="https://iotda.cn-north-4.myhuaweicloud.com"+"/v5/iot/%s/devices/%s"; //-----下面的程序不做变化 //-----省略 } 主函数调用就改为: getdev("shadow","temp"); getdev("shadow","humi"); getdev("shadow","light"); 运行结果是一样的 然后我们把最后的影子解析先注释掉: //String pro="temp"; /*ObjectMapper objectMapper = new ObjectMapper(); JsonNode jsonNode = objectMapper.readValue(result, JsonNode.class); JsonNode tempNode = jsonNode.get("shadow").get(0).get("reported").get("properties").get(pro); String attvaluestr = tempNode.asText(); System.out.println(pro+"=" + attvaluestr);*/ //return attvaluestr; 加上return null;然后主函数添加: getdev("status",""); 运行一下:

? 我们把最后的数据格式化一下

其中status是我们需要提取的,我们取消原来的注释,改造一下解析数据的代码 ObjectMapper objectMapper = new ObjectMapper(); JsonNode jsonNode = objectMapper.readValue(result, JsonNode.class); if(mode=="shadow") { JsonNode tempNode = jsonNode.get("shadow").get(0).get("reported").get("properties").get(pro); String attvaluestr = tempNode.asText(); System.out.println(pro+"=" + attvaluestr); return attvaluestr; } if(mode=="status") { JsonNode statusNode = jsonNode.get("status"); String statusstr = statusNode.asText(); System.out.println("status = " + statusstr); return statusstr; } return "something is error "; 我们运行一下:

命令下发

老样子,我们依旧查看华为云帮助文档

我们得到的信息: URI为: strurl="https://iotda.cn-north-4.myhuaweicloud.com"+"/v5/iot/%s/devices/%s/commands"; 消息体是: String body="{\"paras\":{\""+"*****"+"\""+":"+"*****"+"},\"service_id\":\"***** \",\"command_name\":\"*****\"}"; 我们写一下实现方法: public String setCom(String com,String value) throws Exception{ String strurl=""; strurl="https://iotda.cn-north-4.myhuaweicloud.com"+"/v5/iot/%s/devices/%s/commands"; String project_id="*****"; String device_id="*****"; strurl = String.format(strurl, project_id,device_id); URL url = new URL(strurl); HttpURLConnection urlCon = (HttpURLConnection)url.openConnection(); urlCon.addRequestProperty("Content-Type", "application/json"); String token=gettoken(); urlCon.addRequestProperty("X-Auth-Token",token); urlCon.setDoOutput(true); urlCon.setRequestMethod("POST"); urlCon.setUseCaches(false); urlCon.setInstanceFollowRedirects(true); urlCon.connect(); String body = "{\"paras\":{\""+com+"\""+":"+value+"},\"service_id\":\"*****\",\"command_name\":\"*****\"}"; BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(urlCon.getOutputStream(),"UTF-8")); writer.write(body); writer.flush(); writer.close(); InputStreamReader is = new InputStreamReader(urlCon.getInputStream()); BufferedReader bufferedReader = new BufferedReader(is); StringBuffer strBuffer = new StringBuffer(); String line = null; while ((line = bufferedReader.readLine()) != null) { strBuffer.append(line); } is.close(); urlCon.disconnect(); String result = strBuffer.toString(); System.out.println(result); return result; } 在主函数调用一下 setCom("led","1"); 我们在华为云控制台的设备那查看

? 我们可以发现命令是成功的,但还有一个错误代码,那是因为设备不在线或没有对命令进行处理响应,这个我们交给设备处理,不在此介绍 另外设备需要订阅topic: $oc/devices/{device_id}/sys/commands/request_id={request_id}

同样在控制台也可以看到数据:

最后我们可以看到这个token每次都要调用,其实是没必要的,我们在这里把放到构造函数里: String token=""; public huaweiIOT()throws Exception { token= gettoken(); }

最后我们删除的getdev的static声明,getdev函数的String? token=gettoken();,删除main函数,现在我们的函数结构是:

public class httpGetHuaweiIOT {

String token=""; public httpGetHuaweiIOT()throws Exception { token=gettoken(); } public String getAtt(String att,String mode) throws Exception{} public String setCom(String com,String value) throws Exception{}

?这样我们的核心功能就完成了,接下来是安卓界面与逻辑部分

? ? 3. MainActivity中调用方法

我们在protected void onCreate(Bundle savedInstanceState) {}添加一个线程用于获取数据和命令下次测试

Thread t = new Thread() { @Override public void run() { try { huaweiIOT hwiot=new huaweiIOT(); System.out.println("获取状态"); String str=""; str=hwiot.getdev("status",""); if(str.equals("ONLINE")) { str="设备在线"; } else if(str.equals("OFFLINE")) { str="设备离线"; } System.out.println("获取成功,状态:"+str); System.out.println("获取温度"); str=hwiot.getdev("shadow","temp"); System.out.println("获取成功,温度:"+str); str=hwiot.getdev("shadow","humi"); System.out.println("获取成功,湿度:"+str); str=hwiot.getdev("shadow","light"); System.out.println("获取成功,光照强度:"+str); } catch (Exception e) { e.printStackTrace(); System.out.println("获取失败:"+e.toString()); } } }; t.start(); 注意,在run app之前我们要加入联网的权限,我们打开AndroidManifest文件,在<application>前添加下述: <uses-permission android:name="android.permission.INTERNET"></uses-permission> <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"></uses-permission> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"></uses-permission> <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"></uses-permission> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission> <uses-permission android:name="android.permission.INTERNET"/> 然后我们run一下app:

最后就是就是创建界面显示与逻辑设计啦

? ? ? 5.结语

? ? ? 到这里大家已经学习到了华为云物联网平台Android应用开发的基础操作啦,本期教程就到这里啦,大家可以完成自己的华为云物联网平台的Android应用开发; ? ? ? 如果有需要上述参考工程,请微信搜索公众号“IOT趣制作”,回复关键字“华为云安卓”,领取教程的实例Demo,然后在HuaweiIOT类文件中填写参数信息运行即可。


1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,会注明原创字样,如未注明都非原创,如有侵权请联系删除!;3.作者投稿可能会经我们编辑修改或补充;4.本站不提供任何储存功能只提供收集或者投稿人的网盘链接。

标签: #Android #IoT #华为云IOT #Studio开发第〇章 #简介