onenet鉴权信息、数据获取
在做毕设的时候我需要做一个APP获取云平台数据,在网上找了很多资料,down了很多代码试了才知道,onenet有两种数据格式,不同格式获取方法不太一样,下面我来讲讲。
1、关于数据格式
1.1数据流格式
关于网上的很多代码用的是数据流的数据协议,再app中加入json转JsonRootBean时会生成Data、DataPoints、Datastreams、JsonRootBean几个JAVA类,进行数据解析使用,所以再MainActivity中会有这几个文件。
- Data、DataPoints、Datastreams、JsonRootBean几个JAVA类获取
首先是进去开发者中心,在左侧找到运维监控,找到API调试,找到数据流使用,点击查询设备数据点,再填上 带*的必填项点击执行 ,复制右侧返回结果
- JSON在线解析数据
将上面复制的返回结果粘贴到Json在线解析
就会生成下面四个JAVA类,直接加入到你的app文件中,像我下面这样加入就可,然后再MainActivity中获取解析就可以了
1.2.oneJson格式
关于oneJson格式和数据流格式也差不多方法也类似
2.JSON在线解析数据
基本上也是一样
忘记说一点很重要的了,这里msg返回的要是succ才行,不然转换的java类就是有问题的
关于鉴权信息
onenet studio鉴权信息仔细看文档,照搬就行,修改一些自己的信息
这是我的可以使用的java鉴权信息获取:
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;
public class Token {
public static String assembleToken(String version, String resourceName, String expirationTime, String signatureMethod, String accessKey)
throws UnsupportedEncodingException, NoSuchAlgorithmException, InvalidKeyException {
StringBuilder sb = new StringBuilder();
String res = URLEncoder.encode(resourceName, "UTF-8");
String sig = URLEncoder.encode(generatorSignature(version, resourceName, expirationTime, accessKey, signatureMethod), "UTF-8");
sb.append("version=")
.append(version)
.append("&res=")
.append(res)
.append("&et=")
.append(expirationTime)
.append("&method=")
.append(signatureMethod)
.append("&sign=")
.append(sig);
return sb.toString();
}
public static String generatorSignature(String version, String resourceName, String expirationTime, String accessKey, String signatureMethod)
throws NoSuchAlgorithmException, InvalidKeyException {
String encryptText = expirationTime + "\n" + signatureMethod + "\n" + resourceName + "\n" + version;
String signature;
byte[] bytes = HmacEncrypt(encryptText, accessKey, signatureMethod);
signature = Base64.getEncoder().encodeToString(bytes);
return signature;
}
public static byte[] HmacEncrypt(String data, String key, String signatureMethod)
throws NoSuchAlgorithmException, InvalidKeyException {
//根据给定的字节数组构造一个密钥,第二参数指定一个密钥算法的名称
SecretKeySpec signinKey = null;
signinKey = new SecretKeySpec(Base64.getDecoder().decode(key),
"Hmac" + signatureMethod.toUpperCase());
//生成一个指定 Mac 算法 的 Mac 对象
Mac mac = null;
mac = Mac.getInstance("Hmac" + signatureMethod.toUpperCase());
//用给定密钥初始化 Mac 对象
mac.init(signinKey);
//完成 Mac 操作
return mac.doFinal(data.getBytes());
}
public enum SignatureMethod {
SHA1, MD5, SHA256;
}
public static String token() throws UnsupportedEncodingException, NoSuchAlgorithmException, InvalidKeyException {
String version = "2020-05-29";
String resourceName = "userid/******";//将*号处换成自己的用户id
String expirationTime = System.currentTimeMillis() / 1000 + 3600 + "";
String signatureMethod = SignatureMethod.SHA1.name().toLowerCase();
//这个也是换成自己的Accesskey
String accessKey = "********************************************";
String token = assembleToken(version, resourceName, expirationTime, signatureMethod, accessKey);
System.out.println("Authorization:" + token);
return token;
}
}
在这里我是直接创建成一个类,方便MainActivity调用,用户ID、Accesskey再用户中心查看
我down的代码时B站上的,大家也可以参考一下app参考,这是开源的
下面是我目前修改的地方,目前实现和获取云平台数据,即get(),post还未实现,我已经注释掉了
package com.example.*******;
import android.app.Activity;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import com.google.gson.Gson;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.List;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
public class MainActivity extends Activity implements View.OnClickListener {
private static final String Accept = "application/json, text/plain, */*";
private static String Authorization ;
Button GET, POST;
TextView data, data1, data2, data3, data4;
String value, value1, value2, value3;
long time_str;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
GET = findViewById(R.id.get);
POST = findViewById(R.id.post);
data = findViewById(R.id.data);//温度显示区域
data1 = findViewById(R.id.data1);//湿度显示区域
data2 = findViewById(R.id.data2);//温度修改值
data3 = findViewById(R.id.data3);//湿度修改值
data4 = findViewById(R.id.data4);//实现显示区域
GET.setOnClickListener(this);
POST.setOnClickListener(this);
requestPermissions(new String[]{"android.permission.INTERNET"}, 1);
// Get();
//wirte by lml
}
@Override
public void onClick(View v) {
int id = v.getId();
if (id == R.id.get) {
Get();
Toast.makeText(MainActivity.this, "数据接收成功", Toast.LENGTH_SHORT).show();
} else if (id == R.id.post) {
// Post();
Toast.makeText(MainActivity.this, "数据修改成功", Toast.LENGTH_SHORT).show();
}
}
public void Get() {
new Thread(new Runnable() {
@Override
public void run() {
//鉴权值获取
try {
Authorization = Token.token();
Log.d("Token", Authorization);
} catch (NoSuchAlgorithmException | InvalidKeyException |
UnsupportedEncodingException e) {
e.printStackTrace();
}
//接受温度
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder().url("https://iot-api.heclouds.com/thingmodel/query-device-property?product_id=产品id&device_name=设备名").addHeader("Authorization", Authorization).addHeader("Accept",Accept).build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
e.printStackTrace();
}
@Override
public void onResponse(Call call, Response response) throws IOException {
if(!response.isSuccessful()) {
throw new IOException("Unexpected code" +response);
}else {
String responseBody = response.body().string();
System.out.println(responseBody);//输出响应内容
//JSON数据提取
JsonRootBean app = new Gson().fromJson(responseBody, JsonRootBean.class);
List<Data> data_get = app.getData();
value = data_get.get(1).getValue();
time_str = data_get.get(1).getTime();
Date time = new Date(time_str);
data.post(new Runnable() {//温度显示区域
@Override
public void run() {
data.setText(String.format("温度:%s°C", value));
data4.setText(String.format("时间:%s", time));
}
});
}
}
});
try {
//接受湿度
OkHttpClient client1 = new OkHttpClient();
Request request1 = new Request.Builder().url("https://iot-api.heclouds.com/thingmodel/query-device-property?product_id=产品id&device_name=设备名").addHeader("Authorization", Authorization).addHeader("Accept",Accept).build();
Response response1 = client1.newCall(request1).execute();
String responseData1 = response1.body().string();
// parseJSONWithGSON(responseData1);
JsonRootBean app = new Gson().fromJson(responseData1, JsonRootBean.class);
List<Data> data_get = app.getData();
value1 = data_get.get(0).getValue();
time_str = data_get.get(0).getTime();
Date time = new Date(time_str);
data1.post(new Runnable() {
@Override
public void run() {
data1.setText(String.format("湿度:%s%%", value1));
}
});
} catch (IOException ex) {
ex.printStackTrace();
}
}
}).start();
}
//解析json
private void parseJSONWithGSON(String jsonData) {
JsonRootBean app = new Gson().fromJson(jsonData, JsonRootBean.class);
List<Data> data_get = app.getData();
//List<Data> points = streams.get(0).getDatapoints();
int count = data_get.size();//获取数据的数量
for (int i = 0; i < count; i++) {
long time = data_get.get(i).getTime();
String value = data_get.get(i).getValue();
Log.w("www", "time=" + time);
Log.w("www", "value=" + value);
}
}
}
关于Request.Builder().url("https://iot-api.heclouds.com/thingmodel/query-device-property?product_id=产品id&device_name=设备名").addHeader("Authorization", Authorization).addHeader("Accept",Accept).build();
url是根据下面这里来的:
好了,今天分享就到这了,可能写的有点乱,你们将就的看,希望对大家有帮助。
想起可以用百度网盘,
记得仔细看代码,和文章有点区别,因为我的app是已经做好了,加了很多东西,也修改了一些东西,我已经删掉一些没用的,但是和文章是有点不一样的,但是是可以实现云平台数据上传与接收的,下载之后记得自己在本地新建一个工程,把我的文件代码复制过去,否则会报错!!!!
还有就是需要修改成自己的设备id和产品id有标注释,仔细看看!
需要修改成自己的设备id和产品id有标注释,仔细看看!
需要修改成自己的设备id和产品id有标注释,仔细看看!
记得自己在本地新建一个工程,把我的文件代码复制过去,否则会报错!!!!
记得自己在本地新建一个工程,把我的文件代码复制过去,否则会报错!!!!
记得自己在本地新建一个工程,把我的文件代码复制过去,否则会报错!!!!
(重要的事情说三遍)
🔗在这链接:资源链接提取码:g32s