文章目录
概要
最近做了个大作业,是用AndroidStudio获取Onenet上面数据的。
本文介绍两个方法,GET()和POST()。用的是java语言,kotlin语言可以直接搜kotlin,get方法,和java的没什么区别。
整体架构流程
首先要引入依赖和库,比如联网的,Okhttp的库
然后是核心的GET和POST代码,这里要注意的是鉴权,我找了好久才在官网找到安全鉴权的方式。(这里吐槽一下Onenet的开发者文档的可查询性实在是太弱了)
最后是获取到返回数据。
技术名词解释
1,Okhttp:OkHttp是一个开源的Java库,用于处理HTTP请求。它是Square公司开发的,设计简单而灵活,是Android开发中广泛使用的HTTP客户端。
示例代码:
importokhttp3.OkHttpClient;importokhttp3.Request;importokhttp3.Response;publicclassOkHttpExample{publicstaticvoidmain(String[] args)throwsException{OkHttpClient client =newOkHttpClient();Request request =newRequest.Builder().url("https://www.baidu.com").build();try(Response response = client.newCall(request).execute()){System.out.println(response.body().string());}}}
2,安全鉴权:在OkHttp中,.header 方法用于设置HTTP请求头。通过这个方法,你可以添加自定义的请求头信息。以下是一个简单的示例,演示如何在OkHttp中使用.header方法:
importokhttp3.OkHttpClient;importokhttp3.Request;importokhttp3.Response;publicclassOkHttpHeaderExample{publicstaticvoidmain(String[] args)throwsException{OkHttpClient client =newOkHttpClient();// 构建请求时使用 .header 方法添加自定义的请求头Request request =newRequest.Builder().url("https://www.example.com").header("Authorization","Bearer your_access_token")// 添加 Authorization 请求头.build();try(Response response = client.newCall(request).execute()){System.out.println(response.body().string());}}}
两个类的声明
第一个是JsonRootBean.java文件(这个文件和MainActivity平行)
packagecom.example.myapplication;importjava.util.List;publicclassJsonRootBean{//Json转换int code;List<Data> data;String msg;String request_id;}
第二个是data.java
packagecom.example.myapplication;importandroidx.annotation.VisibleForTesting;importjava.util.List;publicclassData{//用list存放获取的数据流String identifier;String time;String value;String data_type;String access_mode;String name;String description;}
鉴权生成(Token)
Onenet的鉴权介绍网址:安全鉴权
鉴权码生成代码:API鉴权
我贴一下我的代码token.java
packagecom.example.myapplication;importandroid.os.Build;importjava.io.UnsupportedEncodingException;importjava.net.URLEncoder;importjava.security.InvalidKeyException;importjava.security.NoSuchAlgorithmException;importjava.util.Base64;importjavax.crypto.Mac;importjavax.crypto.spec.SecretKeySpec;publicclassToken{publicstaticStringTOKEN="默认值";publicstaticvoidsetMyString(String newValue){TOKEN= newValue;}publicstaticStringassembleToken(String version,String resourceName,String expirationTime,String signatureMethod,String accessKey)throwsUnsupportedEncodingException,NoSuchAlgorithmException,InvalidKeyException{StringBuilder sb =newStringBuilder();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();}publicstaticStringgeneratorSignature(String version,String resourceName,String expirationTime,String accessKey,String signatureMethod)throwsNoSuchAlgorithmException,InvalidKeyException{String encryptText = expirationTime +"\n"+ signatureMethod +"\n"+ resourceName +"\n"+ version;String signature =null;byte[] bytes =HmacEncrypt(encryptText, accessKey, signatureMethod);if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.O){
signature =Base64.getEncoder().encodeToString(bytes);}return signature;}publicstaticbyte[]HmacEncrypt(String data,String key,String signatureMethod)throwsNoSuchAlgorithmException,InvalidKeyException{//根据给定的字节数组构造一个密钥,第二参数指定一个密钥算法的名称SecretKeySpec signinKey =null;if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.O){
signinKey =newSecretKeySpec(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());}publicenumSignatureMethod{SHA1,MD5,SHA256;}publicstaticvoidmain(String args)throwsUnsupportedEncodingException,NoSuchAlgorithmException,InvalidKeyException{String version ="2022-05-01";String resourceName ="userid/这里写你的用户id";String expirationTime =System.currentTimeMillis()/1000+100*24*60*60+"";String signatureMethod =SignatureMethod.SHA1.name().toLowerCase();String accessKey ="这里放你的AccessKey(在Onenet官网的账户信息里面)";String token =assembleToken(version, resourceName, expirationTime, signatureMethod, accessKey);setMyString(token);}}
MainActivity代码(Java)
publicclassMainActivityextendsAppCompatActivity{String token="鉴权参数";protectedvoidonCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);//UI的基本布局try{Token.main("拿鉴权码,这里参数无所谓的");}catch(UnsupportedEncodingException|NoSuchAlgorithmException|InvalidKeyException e){thrownewRuntimeException(e);}
token=Token.TOKEN;//赋值Token,把鉴权信息拿到
` requestPermissions(newString[]{"android.permission.INTERNET"},1);Get();}
如图上面是主函数代码,获取网络请求后直接GET就好了。
publicvoidGet(){newThread(newRunnable(){@Overridepublicvoidrun(){while(true){try{OkHttpClient client =newOkHttpClient();//http(s)://iot-api.heclouds.com/thingmodel/query-device-property?product_id=w50WLDzGBb&device_name=light//http://iot-api.heclouds.com/thingmodel/query-thing-model?product_id=w50WLDzGBbRequest request =newRequest.Builder().url("http://iot-api.heclouds.com/thingmodel/query-device-property?product_id=这里输入你的产品id&device_name=你的设备名称").header("Authorization",token).build();Response response = client.newCall(request).execute();String responseData = response.body().string();JsonRootBean app =newGson().fromJson(responseData,JsonRootBean.class);
value=app.data.get(0).value.toString();//获得亮度
brightnessDisplay.post(newRunnable(){@Overridepublicvoidrun(){
brightnessDisplay.setText(String.format("BrightnessRightNow:%s", value));}});}catch(IOException e){
e.printStackTrace();}try{Thread.sleep(1000);}catch(InterruptedException e){thrownewRuntimeException(e);}//延时一秒获取一次亮度}}}).start();
在.header后面这个token,就是我们要的鉴权码。
上面代码中的jsonRootbean是我自己的一个类,我GET获取的数据是一段json格式的数组
{"code":0,"data":[{"identifier":"bright","time":1700127636130,"value":"0.600000","data_type":"float","access_mode":"读写","name":"bright"},{"identifier":"setbright","data_type":"int32","access_mode":"读写","name":"setbright"},{"identifier":"state","time":1698234341316,"value":"2","data_type":"enum","access_mode":"读写","name":"state","description":"工作模式"},{"identifier":"time","data_type":"date","access_mode":"读写","name":"time"}],"msg":"succ","request_id":"f97096fb25a94f2884a043c510821485"}
ONENET官网关于GET方法的返回数组
可以看到有4个大参数,code,data,msg,request_id
data是一个数组,在数组的每一个项里面又包含4个小参数(如下图),
所以我们核心的是获取到data里面的这个value值,因此GET获取到数据后,采用了下面这个方式提取到value
Response response = client.newCall(request).execute();String responseData = response.body().string();JsonRootBean app =newGson().fromJson(responseData,JsonRootBean.class);
value=app.data.get(0).value.toString();//获得亮度
小结
搞定鉴权就简单了很多很多。有问题私信问
版权归原作者 JessicRobert 所有, 如有侵权,请联系我们删除。